From 0c132ec3c5acfc131b2f9005c68e3262a0f4a040 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Wed, 17 Jul 1991 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1991-07-17 --- gnot/dat.h | 1 + gnot/lib.h | 3 ++ gnot/main.c | 1 - gnot/trap.c | 30 ++++++++++++--- pc/dat.h | 6 ++- pc/fns.h | 5 +++ pc/l.s | 28 +++++++++++--- pc/main.c | 29 ++++++++------- pc/mem.h | 5 ++- pc/mmu.c | 99 +++++++++++++++++++++++++++++++++++++++---------- port/devcons.c | 1 + port/lib.h | 3 ++ port/proc.c | 27 +++++++++----- power/dat.h | 1 + power/main.c | 1 - power/trap.c | 36 ++++++++++++------ ss/dat.h | 2 + ss/faultsparc.c | 9 +++-- ss/main.c | 1 - ss/trap.c | 39 ++++++++++++++++--- 20 files changed, 247 insertions(+), 80 deletions(-) diff --git a/gnot/dat.h b/gnot/dat.h index 500929f05a444d97f97c97d384227495939444cb..a26445cc5eb721a74fdff7a0d222b19c72106aac 100644 --- a/gnot/dat.h +++ b/gnot/dat.h @@ -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; diff --git a/gnot/lib.h b/gnot/lib.h index 1d2c96d5a7448893b62604ec1397a811153d8f44..6c6a30ddadc54aa4b368979a58a37aed8433f95c 100644 --- a/gnot/lib.h +++ b/gnot/lib.h @@ -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; diff --git a/gnot/main.c b/gnot/main.c index d4ecb0897ead2a0cb8e0fec99e25a80fe31cd864..b822e5ecdf7d3f986d86364c568f5bc1ad2ec869 100644 --- a/gnot/main.c +++ b/gnot/main.c @@ -132,7 +132,6 @@ init0(void) } poperror(); - kickpager(); touser(); } diff --git a/gnot/trap.c b/gnot/trap.c index 0c15b2087bf75ac344e7eef7fe209d68e5ca1363..21661c136f1ad08d40963a87a56e90d82aa588a1 100644 --- a/gnot/trap.c +++ b/gnot/trap.c @@ -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); diff --git a/pc/dat.h b/pc/dat.h index 634624e77ea836340f065f8bc4a37bd78c55cc20..98a43e6d521c6ed9a94e6b769f4c05e7394ba175 100644 --- a/pc/dat.h +++ b/pc/dat.h @@ -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; diff --git a/pc/fns.h b/pc/fns.h index 54abf061b7c21580915c523fb3ef661c67b9e90f..dc98a71f75862f07572c506edfbad63d478398bc 100644 --- a/pc/fns.h +++ b/pc/fns.h @@ -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); diff --git a/pc/l.s b/pc/l.s index d159aaf6bb5bbb6f47587efc92ae757b51a05de2..ca822f1750f3d3802a9bceb0b6c91ec5d81618d2 100644 --- a/pc/l.s +++ b/pc/l.s @@ -132,6 +132,15 @@ setpte: ORL $0X80000000,AX 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 */ @@ -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 /* diff --git a/pc/main.c b/pc/main.c index 5e81a30fbcfccb09aa2f7b916c2afd65eb2d7293..fe241f4ee27becaccdd34d557c65c7917020a3e9 100644 --- a/pc/main.c +++ b/pc/main.c @@ -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; +} + diff --git a/pc/mem.h b/pc/mem.h index 649b9ee0977c3dd716d94a5d3b3bc223ab478503..3b0a78f9ad0f3f8faea3dc310dec4bdfe58b848d 100644 --- a/pc/mem.h +++ b/pc/mem.h @@ -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 */ diff --git a/pc/mmu.c b/pc/mmu.c index 231511181e12d3eec101ee2cfb729a987d5bfcc5..35197efb75febbf88f009564e086ac45a8026f79 100644 --- a/pc/mmu.c +++ b/pc/mmu.c @@ -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< */ + 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); +} diff --git a/port/devcons.c b/port/devcons.c index 7f6353268074d9a23bba0aa7067c16f0e6733df3..7ec301232c94af71e8584644942add60516f7e26 100644 --- a/port/devcons.c +++ b/port/devcons.c @@ -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: diff --git a/port/lib.h b/port/lib.h index 8d5d195f1795ab8687954117e0055b2a5ce0d92d..d7be09489f12e9bf2285007a52b3a3a5890c5dd8 100644 --- a/port/lib.h +++ b/port/lib.h @@ -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; diff --git a/port/proc.c b/port/proc.c index efaac997b0185087262c154cd5af43cbf460ee0a..6d8ed6ee6aeec8a3b2518f9ed38839f1e8557dfa 100644 --- a/port/proc.c +++ b/port/proc.c @@ -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); diff --git a/power/dat.h b/power/dat.h index 08d7c2afb17c8e7d2d12136e93b2929ac0aa4773..8e26790eea52360d2e3aca4ebed752ab7efdd942 100644 --- a/power/dat.h +++ b/power/dat.h @@ -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; diff --git a/power/main.c b/power/main.c index c6137435f0990f72590032ef39ab229a0f1bc58d..6dbaf98caed805d26d0648c2e680cd6108ad5bf3 100644 --- a/power/main.c +++ b/power/main.c @@ -230,7 +230,6 @@ init0(void) sp = (ulong*)(USTKTOP - argsize); - kickpager(); touser(sp); } diff --git a/power/trap.c b/power/trap.c index f3948fad4b5a98acca8a803422f2321463161488..ad93269b9099df2ff7bd48582fd56ace8fd48d55 100644 --- a/power/trap.c +++ b/power/trap.c @@ -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); diff --git a/ss/dat.h b/ss/dat.h index 1cceac208a46b8325102f3de9b75ddeea8e2eb4c..397840a1104f928f33c65a798ab755d53c8c0ad5 100644 --- a/ss/dat.h +++ b/ss/dat.h @@ -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; }; diff --git a/ss/faultsparc.c b/ss/faultsparc.c index a2c2f5b932de6ef30dbe131e3166f0618362a20c..2f38bb7ae4385d29ece1c14797ee828cdb2ffed7 100644 --- a/ss/faultsparc.c +++ b/ss/faultsparc.c @@ -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); diff --git a/ss/main.c b/ss/main.c index 91818ae2620825958573f51c7c02f8957e891a10..ad8396308acf4971c77002014c9a49fec95706cc 100644 --- a/ss/main.c +++ b/ss/main.c @@ -110,7 +110,6 @@ init0(void) u->slash = (*devtab[0].attach)(0); u->dot = clone(u->slash, 0); - kickpager(); /**/ touser(USTKTOP-(1+MAXSYSARG)*BY2WD); } diff --git a/ss/trap.c b/ss/trap.c index bb7702e15d9a14a85933af14adafb0f2e88e88f8..671219b6771b86ff2ef34d71799ee26207e3122b 100644 --- a/ss/trap.c +++ b/ss/trap.c @@ -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);