M gnot/dat.h => gnot/dat.h +1 -0
@@ 219,6 219,7 @@ struct User
Note note[NNOTE];
short nnote;
short notified; /* sysnoted is due */
+ Note lastnote;
int (*notify)(void*, char*);
void *ureg;
ushort svsr;
M gnot/lib.h => gnot/lib.h +3 -0
@@ 74,6 74,9 @@ extern long end;
#define OCEXEC 32 /* or'ed in, close on exec */
#define ORCLOSE 64 /* or'ed in, remove on close */
+#define NCONT 0 /* continue after note */
+#define NTERM 1 /* terminate after note */
+
typedef struct Qid Qid;
typedef struct Dir Dir;
typedef struct Waitmsg Waitmsg;
M gnot/main.c => gnot/main.c +0 -1
@@ 132,7 132,6 @@ init0(void)
}
poperror();
- kickpager();
touser();
}
M gnot/trap.c => gnot/trap.c +24 -6
@@ 8,7 8,7 @@
#include "errno.h"
void notify(Ureg*);
-void noted(Ureg*);
+void noted(Ureg*, ulong);
void rfnote(Ureg*);
char *regname[]={
@@ 174,6 174,7 @@ notify(Ureg *ur)
ur->pc = (ulong)u->notify;
u->notified = 1;
u->nnote--;
+ memmove(&u->lastnote, &u->note[0], sizeof(Note));
memmove(&u->note[0], &u->note[1], u->nnote*sizeof(Note));
}
unlock(&u->p->debug);
@@ 183,7 184,7 @@ notify(Ureg *ur)
* Return user to state before notify()
*/
void
-noted(Ureg *ur)
+noted(Ureg *ur, ulong arg0)
{
Ureg *nur;
@@ 201,9 202,26 @@ noted(Ureg *ur)
}
u->notified = 0;
memmove(ur, u->ureg, sizeof(Ureg));
- unlock(&u->p->debug);
- splhi();
- rfnote(ur);
+ ur->r0 = -1; /* return error from the interrupted call */
+ switch(arg0){
+ case NCONT:
+ splhi();
+ unlock(&u->p->debug);
+ rfnote(ur);
+ break;
+ /* never returns */
+
+ default:
+ pprint("unknown noted arg 0x%lux\n", arg0);
+ u->lastnote.flag = NDebug;
+ /* fall through */
+
+ case NTERM:
+ if(u->lastnote.flag == NDebug)
+ pprint("suicide: %s\n", u->lastnote.msg);
+ unlock(&u->p->debug);
+ pexit(u->lastnote.msg, u->lastnote.flag!=NDebug);
+ }
}
#undef CHDIR /* BUG */
@@ 316,7 334,7 @@ syscall(Ureg *aur)
u->p->insyscall = 0;
if(r0 == NOTED) /* ugly hack */
- noted(aur); /* doesn't return */
+ noted(aur, *(ulong*)(sp+BY2WD)); /* doesn't return */
if(u->nnote){
ur->r0 = ret;
notify(ur);
M pc/dat.h => pc/dat.h +5 -1
@@ 4,6 4,7 @@ typedef struct Label Label;
typedef struct Lock Lock;
typedef struct MMU MMU;
typedef struct Mach Mach;
+typedef struct Page Page;
typedef struct PMMU PMMU;
typedef struct Segdesc Segdesc;
typedef struct Ureg Ureg;
@@ 96,9 97,11 @@ struct Conf
/*
* MMU stuff in proc
*/
+#define MAXMMU 4
struct PMMU
{
- MMU *mmu;
+ ulong mmuent[MAXMMU]; /* a process' mmu entries */
+ Page *mmupg[MAXMMU]; /* mmu pages */
};
#include "../port/portdat.h"
@@ 157,6 160,7 @@ struct User
Note note[NNOTE];
short nnote;
short notified; /* sysnoted is due */
+ Note lastnote;
int (*notify)(void*, char*);
void *ureg;
ushort svvo;
M pc/fns.h => pc/fns.h +5 -0
@@ 45,9 45,14 @@ void kbdinit(void);
void kbdintr(Ureg*);
void lgdt(Segdesc*, int);
void lidt(Segdesc*, int);
+void lcr3(ulong);
+void ltr(ulong);
void mmuinit(void);
void outb(int, int);
void prhex(ulong);
+void procrestore(Proc*, uchar*);
+void procsave(uchar*, int);
+void procsetup(Proc*);
void screeninit(void);
void screenputc(int);
void screenputs(char*, int);
M pc/l.s => pc/l.s +23 -5
@@ 133,6 133,15 @@ setpte:
MOVL AX,CR0
/*
+ * use a jump to an absolute location to get the PC into
+ * KZERO.
+ */
+ LEAL tokzero(SB),AX
+ JMP* AX
+
+TEXT tokzero(SB),$0
+
+ /*
* stack and mach
*/
MOVL $mach0(SB),SP
@@ 206,7 215,7 @@ TEXT tas(SB),$0
RET
/*
- * load the idt
+ * routines to load various system registers
*/
GLOBL idtptr(SB),$6
TEXT lidt(SB),$0
@@ 217,9 226,6 @@ TEXT lidt(SB),$0
MOVL idtptr(SB),IDTR
RET
-/*
- * load the gdt
- */
GLOBL gdtptr(SB),$6
TEXT lgdt(SB),$0
MOVL t+0(FP),AX
@@ 229,6 235,16 @@ TEXT lgdt(SB),$0
MOVL gdtptr(SB),GDTR
RET
+TEXT lcr3(SB),$0
+ MOVL t+0(FP),AX
+ MOVL AX,CR3
+ RET
+
+TEXT ltr(SB),$0
+ MOVL t+0(FP),AX
+ MOVW AX,TASK
+ RET
+
/*
* special traps
*/
@@ 403,13 419,15 @@ TEXT setlabel(SB),$0
RET
TEXT touser(SB),$0
- MOVL $(USERADDR+BY2PG-5*BY2WD),AX
+ MOVL $(USERADDR+BY2PG-6*BY2WD),AX
MOVL $(UTZERO+32),0(AX) /* header is in text */
MOVL $(UESEL),4(AX)
MOVL $(IFLAG|2),8(AX)
MOVL $(USTKTOP-4*BY2WD),12(AX)
MOVL $(UDSEL),16(AX)
MOVL AX,SP
+ MOVL $(UDSEL),AX /* set up data segment */
+ MOVW AX,DS
IRETL
/*
M pc/main.c => pc/main.c +15 -14
@@ 20,7 20,9 @@ main(void)
print("%d pages in bank0, %d pages in bank1\n", conf.npage0, conf.npage1);
print("edata == %lux, end == %lux\n", &edata, &end);
mmuinit();
+print("mmu inited\n");
procinit0();
+print("proc inited\n");
initseg();
grpinit();
chaninit();
@@ 31,6 33,7 @@ main(void)
swapinit();
pageinit();
userinit();
+print("user inited\n");
schedinit();
}
@@ 94,9 97,12 @@ userinit(void)
/*
* Kernel Stack
+ *
+ * N.B. The -4 for the stack pointer is important. Gotolabel
+ * uses the bottom 4 bytes of stack to store it's return pc.
*/
p->sched.pc = (ulong)init0;
- p->sched.sp = USERADDR + BY2PG - 24;
+ p->sched.sp = USERADDR + BY2PG - 4;
p->upage = newpage(1, 0, USERADDR|(p->pid&0xFFFF));
/*
@@ 126,18 132,6 @@ userinit(void)
ready(p);
}
-void
-exit(void)
-{
- int i;
-
- u = 0;
- splhi();
- print("exiting\n");
- for(;;)
- ;
-}
-
Conf conf;
void
@@ 185,7 179,7 @@ confinit(void)
conf.base1 = 1024/4;
conf.npage = conf.npage0 + conf.npage1;
- conf.maxialloc = (640*1024-256*1024-BY2PG);
+ conf.maxialloc = (conf.npage0*BY2PG-PGROUND((ulong)&end));
mul = 1;
conf.nproc = 20 + 50*mul;
@@ 269,3 263,10 @@ void
lights(int val)
{
}
+
+int
+mouseputc(IOQ *q, int c)
+{
+ return c;
+}
+
M pc/mem.h => pc/mem.h +4 -1
@@ 59,7 59,8 @@
#define UESEG 4 /* user executable */
#define SYSGATE 5 /* system call gate */
#define RDSEG 6 /* reboot data/stack */
-#define RESEG 7 /* reboot executable */
+#define RESEG 7 /* reboot executable */
+#define TSSSEG 8 /* task segment */
#define SELGDT (0<<3) /* selector is in gdt */
#define SELLDT (1<<3) /* selector is in ldt */
@@ 73,12 74,14 @@
#define UDSEL SELECTOR(UDSEG, SELGDT, 3)
#define RDSEL SELECTOR(RDSEG, SELGDT, 0)
#define RESEL SELECTOR(RESEG, SELGDT, 0)
+#define TSSSEL SELECTOR(TSSSEG, SELGDT, 0)
/*
* fields in segment descriptors
*/
#define SEGDATA (0x10<<8) /* data/stack segment */
#define SEGEXEC (0x18<<8) /* executable segment */
+#define SEGTSS (0x9<<8) /* TSS segment */
#define SEGCG (0x0C<<8) /* call gate */
#define SEGIG (0x0E<<8) /* interrupt gate */
#define SEGTG (0x0F<<8) /* task gate */
M pc/mmu.c => pc/mmu.c +80 -19
@@ 16,11 16,11 @@ typedef struct Tss Tss;
struct Tss
{
ulong backlink; /* unused */
- ulong esp0; /* pl0 stack pointer */
+ ulong sp0; /* pl0 stack pointer */
ulong ss0; /* pl0 stack selector */
- ulong esp1; /* pl1 stack pointer */
+ ulong sp1; /* pl1 stack pointer */
ulong ss1; /* pl1 stack selector */
- ulong esp2; /* pl2 stack pointer */
+ ulong sp2; /* pl2 stack pointer */
ulong ss2; /* pl2 stack selector */
ulong cr3; /* page table descriptor */
ulong eip; /* instruction pointer */
@@ 42,15 42,18 @@ struct Tss
ulong ldt; /* local descriptor table */
ulong iomap; /* io map base */
};
+Tss tss;
/*
* segment descriptor initializers
*/
-#define DATASEG(p) { 0xFFFF, SEGG|SEGB|(0xF<<16)|SEGP|SEGPL(p)|SEGDATA|SEGW }
-#define EXECSEG(p) { 0xFFFF, SEGG|SEGD|(0xF<<16)|SEGP|SEGPL(p)|SEGEXEC|SEGR }
-#define CALLGATE(s,o,p) { (o)&0xFFFF|((s)<<16), (o)&0xFFFF0000|SEGP|SEGPL(p)|SEGCG }
-#define D16SEG(p) { 0xFFFF, (0x0<<16)|SEGP|SEGPL(p)|SEGDATA|SEGW }
-#define E16SEG(p) { 0xFFFF, (0x0<<16)|SEGP|SEGPL(p)|SEGEXEC|SEGR }
+#define DATASEGM(p) { 0xFFFF, SEGG|SEGB|(0xF<<16)|SEGP|SEGPL(p)|SEGDATA|SEGW }
+#define EXECSEGM(p) { 0xFFFF, SEGG|SEGD|(0xF<<16)|SEGP|SEGPL(p)|SEGEXEC|SEGR }
+#define CALLGATE(s,o,p) { ((o)&0xFFFF)|((s)<<16), (o)&0xFFFF0000|SEGP|SEGPL(p)|SEGCG }
+#define D16SEGM(p) { 0xFFFF, (0x0<<16)|SEGP|SEGPL(p)|SEGDATA|SEGW }
+#define E16SEGM(p) { 0xFFFF, (0x0<<16)|SEGP|SEGPL(p)|SEGEXEC|SEGR }
+#define TSSSEGM(b,p) { ((b)<<16)|sizeof(Tss),\
+ ((b)&0xFF000000)|(((b)<<16)&0xFF)|SEGTSS|SEGPL(p)|SEGP }
/*
* global descriptor table describing all segments
@@ 58,39 61,85 @@ struct Tss
Segdesc gdt[] =
{
[NULLSEG] { 0, 0}, /* null descriptor */
-[KDSEG] DATASEG(0), /* kernel data/stack */
-[KESEG] EXECSEG(0), /* kernel code */
-[UDSEG] DATASEG(3), /* user data/stack */
-[UESEG] EXECSEG(3), /* user code */
+[KDSEG] DATASEGM(0), /* kernel data/stack */
+[KESEG] EXECSEGM(0), /* kernel code */
+[UDSEG] DATASEGM(3), /* user data/stack */
+[UESEG] EXECSEGM(3), /* user code */
[SYSGATE] CALLGATE(KESEL,0,3), /* call gate for system calls */
-[RDSEG] D16SEG(0), /* reboot data/stack */
-[RESEG] E16SEG(0), /* reboot code */
+[RDSEG] D16SEGM(0), /* reboot data/stack */
+[RESEG] E16SEGM(0), /* reboot code */
+[TSSSEG] TSSSEGM(0,0), /* tss segment */
};
-extern ulong tpt[];
+static ulong *toppt; /* top level page table */
+static ulong *kpt; /* kernel level page tables */
+static ulong *upt; /* page table for struct User */
+
+#define ROUNDUP(s,v) (((s)+(v-1))&~(v-1))
void
mmuinit(void)
{
+ int i, n, nkpt;
+ ulong x;
+ ulong y;
+
/*
* set up the global descriptor table
*/
- gdt[SYSGATE].d0 = ((ulong)systrap)&0xFFFF|(KESEL<<16);
- gdt[SYSGATE].d1 = ((ulong)systrap)&0xFFFF0000|SEGP|SEGPL(3)|SEGCG;
+ x = (ulong)systrap;
+ gdt[SYSGATE].d0 = (x&0xFFFF)|(KESEL<<16);
+ gdt[SYSGATE].d1 = (x&0xFFFF0000)|SEGP|SEGPL(3)|SEGCG;
+ x = (long)&tss;
+ gdt[TSSSEG].d0 = (x<<16)|sizeof(Tss);
+ gdt[TSSSEG].d1 = (x&0xFF000000)|((x>>16)&0xFF)|SEGTSS|SEGPL(0)|SEGP;
lgdt(gdt, sizeof gdt);
/*
- * set up system page tables
+ * set up system page tables.
+ * map all of physical memory to start at KZERO.
+ * leave a map for a user area.
*/
+ /* allocate and fill low level page tables for physical mem */
+ nkpt = ROUNDUP(conf.npage0+conf.npage1, 4*1024*1024);
+ nkpt = nkpt/(4*1024*1024);
+ kpt = ialloc(nkpt*BY2PG, 1);
+ n = ROUNDUP(conf.npage0+conf.npage1, 1*1024*1024);
+ n = n/(4*1024);
+ for(i = 0; i < n; i++){
+ kpt[i] = (i<<PGSHIFT)|PTEVALID|PTEKERNEL|PTEWRITE;
+ }
+
+ /* allocate page table for u-> */
+ upt = ialloc(BY2PG, 1);
+
+ /* allocate top level table and put pointers to lower tables in it */
+ toppt = ialloc(BY2PG, 1);
+ x = KZERO>>(2*PGSHIFT-2);
+ y = ((ulong)kpt)&~KZERO;
+ for(i = 0; i < nkpt; i++){
+/* toppt[i] = (y+i*BY2PG)|PTEVALID|PTEKERNEL|PTEWRITE;/**/
+ toppt[x+i] = (y+i*BY2PG)|PTEVALID|PTEKERNEL|PTEWRITE;
+ }
+ x = USERADDR>>(2*PGSHIFT-2);
+ y = ((ulong)upt)&~KZERO;
+ toppt[x] = y|PTEVALID|PTEKERNEL|PTEWRITE;
+ lcr3(((ulong)toppt)&~KZERO);
+
/*
* set up the task segment
*/
+ tss.sp0 = USERADDR;
+ tss.ss0 = KDSEL;
+ tss.cr3 = (ulong)toppt;
+ ltr(TSSSEL);
}
void
mapstack(Proc *p)
{
+
}
void
@@ 104,7 153,7 @@ mmurelease(Proc *p)
}
void
-putmmu(ulong x, ulong y, Page*z)
+putmmu(ulong x, ulong y, Page *z)
{
}
@@ 118,3 167,15 @@ systrap(void)
{
panic("system trap from user");
}
+
+void
+exit(void)
+{
+ int i;
+
+ u = 0;
+ print("exiting\n");
+ for(i = 0; i < WD2PG; i++)
+ toppt[i] = 0;
+ lcr3(((ulong)toppt)&~KZERO);
+}
M port/devcons.c => port/devcons.c +1 -0
@@ 727,6 727,7 @@ conswrite(Chan *c, void *va, long n, ulong offset)
fd = strtoul(buf, 0, 0);
swc = fdtochan(fd, -1);
setswapchan(swc);
+ kickpager();
return n;
default:
M port/lib.h => port/lib.h +3 -0
@@ 74,6 74,9 @@ extern long end;
#define OCEXEC 32 /* or'ed in, close on exec */
#define ORCLOSE 64 /* or'ed in, remove on close */
+#define NCONT 0 /* continue after note */
+#define NTERM 1 /* terminate after note */
+
typedef struct Qid Qid;
typedef struct Dir Dir;
typedef struct Waitmsg Waitmsg;
M port/proc.c => port/proc.c +17 -10
@@ 67,7 67,7 @@ schedinit(void) /* never returns */
p->pid = 0;
mmurelease(p);
/*
- * Holding locks:
+ * Holding locks from pexit:
* procalloc, debug, palloc
*/
pg = p->upage;
@@ 473,7 473,7 @@ freebroken(void)
}
void
-pexit(char *s, int freemem)
+pexit(char *exitstr, int freemem)
{
ulong mypid;
Proc *p, *c, *k, *l;
@@ 481,9 481,10 @@ pexit(char *s, int freemem)
Chan *ch;
char msg[ERRLEN];
ulong *up, *ucp, *wp;
+ Segment **s, **es, *os;
- if(s) /* squirrel away; we'll lose our address space */
- strcpy(msg, s);
+ if(exitstr) /* squirrel away before we lose our address space */
+ strcpy(msg, exitstr);
else
msg[0] = 0;
@@ 496,9 497,12 @@ pexit(char *s, int freemem)
if(freemem){
flushvirt();
- for(i = 0; i < NSEG; i++)
- if(c->seg[i])
- putseg(c->seg[i]);
+ es = &c->seg[NSEG];
+ for(s = c->seg; s < es; s++)
+ if(os = *s) {
+ *s = 0;
+ putseg(os);
+ }
closepgrp(c->pgrp);
if(c->egrp)
closeegrp(c->egrp);
@@ 552,9 556,12 @@ pexit(char *s, int freemem)
if(!freemem){
addbroken(c);
flushvirt();
- for(i = 0; i < NSEG; i++)
- if(c->seg[i])
- putseg(c->seg[i]);
+ es = &c->seg[NSEG];
+ for(s = c->seg; s < es; s++)
+ if(os = *s) {
+ *s = 0;
+ putseg(os);
+ }
closepgrp(c->pgrp);
closeegrp(c->egrp);
close(u->dot);
M power/dat.h => power/dat.h +1 -0
@@ 224,6 224,7 @@ struct User
Note note[NNOTE];
short nnote;
short notified; /* sysnoted is due */
+ Note lastnote;
int (*notify)(void*, char*);
void *ureg;
ulong svstatus;
M power/main.c => power/main.c +0 -1
@@ 230,7 230,6 @@ init0(void)
sp = (ulong*)(USTKTOP - argsize);
- kickpager();
touser(sp);
}
M power/trap.c => power/trap.c +24 -12
@@ 12,7 12,7 @@
*/
void (*vmevec[256])(int);
-void noted(Ureg**);
+void noted(Ureg**, ulong);
void rfnote(Ureg**);
#define LSYS 0x01
@@ 409,6 409,7 @@ notify(Ureg *ur)
ur->pc = (ulong)u->notify;
u->notified = 1;
u->nnote--;
+ memmove(&u->lastnote, &u->note[0], sizeof(Note));
memmove(&u->note[0], &u->note[1], u->nnote*sizeof(Note));
}
unlock(&u->p->debug);
@@ 418,20 419,15 @@ notify(Ureg *ur)
* Return user to state before notify()
*/
void
-noted(Ureg **urp)
+noted(Ureg **urp, ulong arg0)
{
Ureg *nur;
nur = u->ureg;
- if(waserror()){
- pprint("suicide: trap in noted\n");
- pexit("Suicide", 0);
- }
validaddr(nur->pc, 1, 0);
validaddr(nur->usp, BY2WD, 0);
- poperror();
if(nur->status!=u->svstatus){
- pprint("bad noted ureg status %ux\n", nur->status);
+ pprint("bad noted ureg status %lux\n", nur->status);
pexit("Suicide", 0);
}
lock(&u->p->debug);
@@ 442,9 438,25 @@ noted(Ureg **urp)
u->notified = 0;
memmove(*urp, u->ureg, sizeof(Ureg));
(*urp)->r1 = -1; /* return error from the interrupted call */
- unlock(&u->p->debug);
- splhi();
- rfnote(urp);
+ switch(arg0){
+ case NCONT:
+ splhi();
+ unlock(&u->p->debug);
+ rfnote(urp);
+ break;
+ /* never returns */
+
+ default:
+ pprint("unknown noted arg 0x%lux\n", arg0);
+ u->lastnote.flag = NDebug;
+ /* fall through */
+
+ case NTERM:
+ if(u->lastnote.flag == NDebug)
+ pprint("suicide: %s\n", u->lastnote.msg);
+ unlock(&u->p->debug);
+ pexit(u->lastnote.msg, u->lastnote.flag!=NDebug);
+ }
}
@@ 558,7 570,7 @@ syscall(Ureg *aur)
splhi();
u->p->insyscall = 0;
if(r1 == NOTED) /* ugly hack */
- noted(&aur); /* doesn't return */
+ noted(&aur, *(ulong*)(sp+BY2WD)); /* doesn't return */
if(u->nnote){
ur->r1 = ret;
notify(ur);
M ss/dat.h => ss/dat.h +2 -0
@@ 162,9 162,11 @@ struct User
* Rest of structure controlled by devproc.c and friends.
* lock(&p->debug) to modify.
*/
+ ulong svpsr;
Note note[NNOTE];
short nnote;
short notified; /* sysnoted is due */
+ Note lastnote;
int (*notify)(void*, char*);
void *ureg;
};
M ss/faultsparc.c => ss/faultsparc.c +6 -3
@@ 10,6 10,7 @@ void
faultsparc(Ureg *ur)
{
ulong addr, badvaddr;
+ char buf[ERRLEN];
int user, read;
ulong tbr;
@@ 36,9 37,11 @@ faultsparc(Ureg *ur)
if(fault(addr, read) < 0){
if(user){
- pprint("user %s error addr=0x%lux\n", read? "read" : "write", badvaddr);
- pprint("psr=0x%lux pc=0x%lux sp=0x%lux\n", ur->psr, ur->pc, ur->sp);
- pexit("Suicide", 0);
+ sprint(buf, "sys: fault %s pc=0x%lux addr=0x%lux",
+ read? "read" : "write", ur->pc, badvaddr);
+ postnote(u->p, 1, buf, NDebug);
+ notify(ur);
+ return;
}
u->p->state = MMUing;
dumpregs(ur);
M ss/main.c => ss/main.c +0 -1
@@ 110,7 110,6 @@ init0(void)
u->slash = (*devtab[0].attach)(0);
u->dot = clone(u->slash, 0);
- kickpager(); /**/
touser(USTKTOP-(1+MAXSYSARG)*BY2WD);
}
M ss/trap.c => ss/trap.c +33 -6
@@ 8,7 8,7 @@
#include "errno.h"
void notify(Ureg*);
-void noted(Ureg**);
+void noted(Ureg**, ulong);
void rfnote(Ureg**);
extern void traplink(void);
@@ 232,6 232,7 @@ notify(Ureg *ur)
if(!u->notified){
if(!u->notify)
goto Die;
+ u->svpsr = ur->psr;
sp = ur->usp;
sp -= sizeof(Ureg);
u->ureg = (void*)sp;
@@ 247,6 248,7 @@ notify(Ureg *ur)
ur->npc = (ulong)u->notify+4;
u->notified = 1;
u->nnote--;
+ memmove(&u->lastnote, &u->note[0], sizeof(Note));
memmove(&u->note[0], &u->note[1], u->nnote*sizeof(Note));
}
unlock(&u->p->debug);
@@ 256,8 258,17 @@ notify(Ureg *ur)
* Return user to state before notify()
*/
void
-noted(Ureg **urp)
+noted(Ureg **urp, ulong arg0)
{
+ Ureg *nur;
+
+ nur = u->ureg;
+ validaddr(nur->pc, 1, 0);
+ validaddr(nur->usp, BY2WD, 0);
+ if(nur->psr!=u->svpsr){
+ pprint("bad noted ureg psr %lux\n", nur->psr);
+ pexit("Suicide", 0);
+ }
lock(&u->p->debug);
if(!u->notified){
unlock(&u->p->debug);
@@ 266,9 277,25 @@ noted(Ureg **urp)
u->notified = 0;
memmove(*urp, u->ureg, sizeof(Ureg));
(*urp)->r7 = -1; /* return error from the interrupted call */
- unlock(&u->p->debug);
- splhi();
- rfnote(urp);
+ switch(arg0){
+ case NCONT:
+ splhi();
+ unlock(&u->p->debug);
+ rfnote(urp);
+ break;
+ /* never returns */
+
+ default:
+ pprint("unknown noted arg 0x%lux\n", arg0);
+ u->lastnote.flag = NDebug;
+ /* fall through */
+
+ case NTERM:
+ if(u->lastnote.flag == NDebug)
+ pprint("suicide: %s\n", u->lastnote.msg);
+ unlock(&u->p->debug);
+ pexit(u->lastnote.msg, u->lastnote.flag!=NDebug);
+ }
}
#undef CHDIR /* BUG */
@@ 376,7 403,7 @@ syscall(Ureg *aur)
}
u->p->insyscall = 0;
if(r7 == NOTED) /* ugly hack */
- noted(&aur); /* doesn't return */
+ noted(&aur, *(ulong*)(sp+1*BY2WD)); /* doesn't return */
if(u->nnote){
ur->r7 = ret;
notify(ur);