From 4d8c533e33bf91d700db485b68b64d76586666e2 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sat, 20 Jul 1991 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1991-07-20 --- pc/dat.h | 5 +- pc/fault386.c | 14 ++-- pc/headland.c | 1 - pc/l.s | 15 ++-- pc/main.c | 19 ++--- pc/mmu.c | 5 +- pc/trap.c | 198 ++++++++++++++++++++++++++++++++++++++++++++++++- port/devcons.c | 7 +- port/proc.c | 5 +- port/swap.c | 1 - 10 files changed, 234 insertions(+), 36 deletions(-) diff --git a/pc/dat.h b/pc/dat.h index b445a294d057253d9867f84954e4d1bb46434922..fa39abd6f9dbb99c2dc8bff8725de74693f00c26 100644 --- a/pc/dat.h +++ b/pc/dat.h @@ -165,8 +165,9 @@ struct User Note lastnote; int (*notify)(void*, char*); void *ureg; - ushort svvo; - ushort svsr; + ulong svcs; /* cs before a notify */ + ulong svss; /* ss before a notify */ + ulong svflags; /* flags before a notify */ }; /* diff --git a/pc/fault386.c b/pc/fault386.c index 72ff0917e1cb9db26a5c4eb1db0746fdc90cd49e..12876bf867ec8b95d3db568ac7f0e9e0039c398e 100644 --- a/pc/fault386.c +++ b/pc/fault386.c @@ -15,24 +15,27 @@ fault386(Ureg *ur) int read; int user; int n; + int insyscall; static int times; + insyscall = u->p->insyscall; + u->p->insyscall = 1; addr = getcr2(); print("fault386 %lux ur %lux\n", addr, ur); dumpregs(ur); -if(++times==3) - panic("3rd time"); if(faulting) panic("double fault\n"); faulting = 1; read = !(ur->ecode & 2); user = (ur->ecode & 4); n = fault(addr, read); -print("fault returns %d\n", n); +if(++times==3) + panic("3rd time in fault"); if(n < 0){ if(user){ - pprint("user %s error addr=0x%lux\n", read? "read" : "write", addr); - pprint("status=0x%lux pc=0x%lux sp=0x%lux\n", ur->flags, ur->pc, ur->usp); + pprint("user %s error addr=0x%lux\n", read?"read":"write", addr); + pprint("status=0x%lux pc=0x%lux sp=0x%lux\n", ur->flags, + ur->pc, ur->usp); pexit("Suicide", 0); } u->p->state = MMUing; @@ -40,6 +43,7 @@ print("fault returns %d\n", n); panic("fault: 0x%lux", addr); } faulting = 0; + u->p->insyscall = insyscall; } void diff --git a/pc/headland.c b/pc/headland.c index 12e875bc56c6d732619d25f7d34f496b4c847b7d..0febe9874cb4d64989af73470c0659ca01354b03 100644 --- a/pc/headland.c +++ b/pc/headland.c @@ -36,6 +36,5 @@ exit(void) u = 0; print("exiting\n"); - delay(5000); outb(Head, Reset); } diff --git a/pc/l.s b/pc/l.s index 47df2b5024c5358a6fcd21a1c3ead7bd60819e98..fbce3cfa236604c5a64ef0683c750bf4a264d574 100644 --- a/pc/l.s +++ b/pc/l.s @@ -8,6 +8,11 @@ TEXT origin(SB),$0 CLI #ifdef BOOT +/* + * This part of l.s is used only in the boot kernel. + * It assumes that we are in real address mode, i.e., + * that we look like an 8086. + */ /* * relocate everything to a half meg and jump there * - looks wierd because it is being assembled by a 32 bit @@ -431,11 +436,11 @@ TEXT setlabel(SB),$0 * Set up an interrupt return frame and IRET to user level. */ TEXT touser(SB),$0 - PUSHL $(UDSEL) /* old ss */ - PUSHL $(USTKTOP-16) /* old sp */ - PUSHFL /* old flags */ - PUSHL $(UESEL) /* old cs */ - PUSHL $(UTZERO+32) /* old pc */ + PUSHL $(UDSEL) /* old ss */ + PUSHL $(USTKTOP) /* old sp */ + PUSHFL /* old flags */ + PUSHL $(UESEL) /* old cs */ + PUSHL $(UTZERO+32) /* old pc */ MOVL $(UDSEL),AX MOVW AX,DS MOVW AX,ES diff --git a/pc/main.c b/pc/main.c index 468e1253fd7cde063fc67d676a3333eeb6db807d..707678e3bdedcb1fb0ea5ad5e986753b1d7b7c5a 100644 --- a/pc/main.c +++ b/pc/main.c @@ -65,6 +65,9 @@ init0(void) u->p->state = Running; u->p->mach = m; +print("go low\n"); + spllo(); + /* * These are o.k. because rootinit is null. * Then early kproc's will have a root and dot. @@ -74,17 +77,8 @@ init0(void) chandevinit(); - /* - * fault in the first executable page and user stack - */ - print("text is %lux\n", *((ulong *)(UTZERO+32))); - - /* fault in the first stack page - */ - print("stack is %lux\n", *((ulong *)(USTKTOP-4))); - *((ulong *)(USTKTOP-4)) = 0xdeadbeef; - print("stack is %lux\n", *((ulong *)(USTKTOP-4))); - delay(5000); +print("going to user\n"); +delay(1000); touser(); } @@ -110,10 +104,9 @@ userinit(void) * * N.B. The -12 for the stack pointer is important. * 4 bytes for gotolabel's return PC - * 8 bytes for optional sp and ss pushed during interrupts */ p->sched.pc = (ulong)init0; - p->sched.sp = USERADDR + BY2PG - 12; + p->sched.sp = USERADDR + BY2PG - 4; p->upage = newpage(1, 0, USERADDR|(p->pid&0xFFFF)); /* diff --git a/pc/mmu.c b/pc/mmu.c index ffc66473c651df09976decce6e82d6b3282303be..9cc03d3c91c29ea9ce4f27eec48c84e49e111459 100644 --- a/pc/mmu.c +++ b/pc/mmu.c @@ -242,15 +242,16 @@ print("putmmu %lux %lux\n", va, pa); /**/ pg = p->mmu[i] = newpage(1, 0, 0); p->mmue[i] = PPN(pg->pa) | PTEVALID | PTEUSER | PTEWRITE; toppt[topoff] = p->mmue[i]; -print("toppt[%d] = %lux\n", topoff, p->mmue[i]); +print("toppt[%d] = %lux\n", topoff, toppt[topoff]); } /* * fill in the bottom level page table */ +print("%lux[%d] was %lux\n", pt, BTMOFF(va), pt[BTMOFF(va)]); pt = (ulong*)(p->mmu[i]->pa|KZERO); pt[BTMOFF(va)] = pa | PTEUSER; -print("%lux[%d] = %lux\n", pt, BTMOFF(va), pa | PTEUSER); +print("%lux[%d] now %lux\n", pt, BTMOFF(va), pt[BTMOFF(va)]); /* flush cached mmu entries */ putcr3(((ulong)toppt)&~KZERO); diff --git a/pc/trap.c b/pc/trap.c index e2a81cc67aeea7f1fd1fc904dd0151304bdb5995..563045fd4b41467cb589a10af0070ba0fc2189a5 100644 --- a/pc/trap.c +++ b/pc/trap.c @@ -5,6 +5,10 @@ #include "fns.h" #include "io.h" #include "ureg.h" +#include "errno.h" + +void noted(Ureg*, ulong); +void notify(Ureg*); /* * 8259 interrupt controllers @@ -155,25 +159,211 @@ dumpregs(Ureg *ur) ur->si, ur->di, ur->bp, ur->ds); } +void +dumpstack(void) +{ +} + +void +execpc(ulong entry) +{ + ((Ureg*)UREGADDR)->pc = entry; +} + /* * system calls */ +#undef CHDIR /* BUG */ +#include "/sys/src/libc/9syscall/sys.h" + +typedef long Syscall(ulong*); +Syscall sysr1, sysfork, sysexec, sysgetpid, syssleep, sysexits, sysdeath, syswait; +Syscall sysopen, sysclose, sysread, syswrite, sysseek, syserrstr, sysaccess, sysstat, sysfstat; +Syscall sysdup, syschdir, sysforkpgrp, sysbind, sysmount, syspipe, syscreate; +Syscall sysbrk_, sysremove, syswstat, sysfwstat, sysnotify, sysnoted, sysalarm; + +Syscall *systab[]={ + sysr1, + syserrstr, + sysbind, + syschdir, + sysclose, + sysdup, + sysalarm, + sysexec, + sysexits, + sysfork, + sysforkpgrp, + sysfstat, + sysdeath, + sysmount, + sysopen, + sysread, + sysseek, + syssleep, + sysstat, + syswait, + syswrite, + syspipe, + syscreate, + sysdeath, + sysbrk_, + sysremove, + syswstat, + sysfwstat, + sysnotify, + sysnoted, + sysdeath, /* sysfilsys */ +}; + long syscall(Ureg *ur) { + ulong ax; + ulong sp; + long ret; + int i; + static int times; +ulong *z; + u->p->insyscall = 1; u->p->pc = ur->pc; + if((ur->cs)&0xffff == KESEL) + panic("recursive system call"); + u->p->insyscall = 0; + + /* + * do something about floating point!!! + */ - panic("syscall"); + ax = ur->ax; + sp = ur->usp; + u->nerrlab = 0; + ret = -1; +z = (ulong *)sp; +print("syscall %lux %lux %lux %lux\n", *z, *(z+1), *(z+2), *(z+3)); +dumpregs(ur); +if(++times==3) + panic("3rd time in syscall"); + if(!waserror()){ + if(ax >= sizeof systab/BY2WD){ + pprint("bad sys call number %d pc %lux\n", ax, ur->pc); + postnote(u->p, 1, "sys: bad sys call", NDebug); + error(Ebadarg); + } + if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-(1+MAXSYSARG)*BY2WD)) + validaddr(sp, (1+MAXSYSARG)*BY2WD, 0); + ret = (*systab[ax])((ulong*)(sp+BY2WD)); + poperror(); + } +print("return from syscall\n"); + if(u->nerrlab){ + print("bad errstack [%d]: %d extra\n", ax, u->nerrlab); + for(i = 0; i < NERR; i++) + print("sp=%lux pc=%lux\n", u->errlab[i].sp, u->errlab[i].pc); + panic("error stack"); + } + u->p->insyscall = 0; + if(ax == NOTED){ + noted(ur, *(ulong*)(sp+BY2WD)); + ret = -1; + } else if(u->nnote){ + ur->ax = ret; + notify(ur); + } + return ret; } +/* + * Call user, if necessary, with note. + * Pass user the Ureg struct and the note on his stack. + */ void -dumpstack(void) +notify(Ureg *ur) { + ulong sp; + + lock(&u->p->debug); + if(u->nnote==0){ + unlock(&u->p->debug); + return; + } + if(u->note[0].flag!=NUser && (u->notified || u->notify==0)){ + if(u->note[0].flag == NDebug) + pprint("suicide: %s\n", u->note[0].msg); + Die: + unlock(&u->p->debug); + pexit(u->note[0].msg, u->note[0].flag!=NDebug); + } + if(!u->notified){ + if(!u->notify) + goto Die; + u->svcs = ur->cs; + u->svss = ur->ss; + u->svflags = ur->flags; + sp = ur->usp; + sp -= sizeof(Ureg); + u->ureg = (void*)sp; + memmove((Ureg*)sp, ur, sizeof(Ureg)); + sp -= ERRLEN; + memmove((char*)sp, u->note[0].msg, ERRLEN); + sp -= 3*BY2WD; + *(ulong*)(sp+2*BY2WD) = sp+3*BY2WD; /* arg 2 is string */ + *(ulong*)(sp+1*BY2WD) = (ulong)u->ureg; /* arg 1 is ureg* */ + *(ulong*)(sp+0*BY2WD) = 0; /* arg 0 is pc */ + ur->usp = sp; + 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); } +/* + * Return user to state before notify() + */ void -execpc(ulong entry) +noted(Ureg *ur, ulong arg0) { - ((Ureg*)UREGADDR)->pc = entry; + Ureg *nur; + + nur = u->ureg; + validaddr(nur->pc, 1, 0); + validaddr(nur->usp, BY2WD, 0); + if(nur->cs!=u->svcs || nur->ss!=u->svss + || (nur->flags&0xff)!=(u->svflags&0xff)){ + pprint("bad noted ureg cs %ux ss %ux flags %ux\n", nur->cs, nur->ss, + nur->flags); + pexit("Suicide", 0); + } + lock(&u->p->debug); + if(!u->notified){ + unlock(&u->p->debug); + return; + } + u->notified = 0; + nur->flags = (u->svflags&0xffffff00) | (ur->flags&0xff); + memmove(ur, u->ureg, sizeof(Ureg)); + ur->ax = -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 NDFLT: + if(u->lastnote.flag == NDebug) + pprint("suicide: %s\n", u->lastnote.msg); + unlock(&u->p->debug); + pexit(u->lastnote.msg, u->lastnote.flag!=NDebug); + } } diff --git a/port/devcons.c b/port/devcons.c index 7ec301232c94af71e8584644942add60516f7e26..580f1dd8246b957ad7db71f811dc3dc96558906a 100644 --- a/port/devcons.c +++ b/port/devcons.c @@ -159,6 +159,9 @@ pprint(char *fmt, ...) Chan *c; int n; + if(u->p->fgrp == 0) + return 0; + c = u->p->fgrp->fd[2]; if(c==0 || (c->mode!=OWRITE && c->mode!=ORDWR)) return 0; @@ -418,6 +421,9 @@ consopen(Chan *c, int omode) unlock(&lineq); } break; + case Qswap: + kickpager(); /* start a pager if not already started */ + break; } return devopen(c, omode, consdir, NCONS, devgen); } @@ -727,7 +733,6 @@ 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/proc.c b/port/proc.c index 6d8ed6ee6aeec8a3b2518f9ed38839f1e8557dfa..6fc8b5525ff86e5b531c44c30084a73e1119ad5e 100644 --- a/port/proc.c +++ b/port/proc.c @@ -634,15 +634,16 @@ procdump(void) int i; Proc *p; - print("process table:\n"); + print("process table %d:\n", conf.nproc); for(i=0; istate != Dead){ print("%d:%s %s upc %lux %s ut %ld st %ld r %lux\n", - p->pid, p->text, p->pgrp->user, p->pc, + p->pid, p->text, p->pgrp ? p->pgrp->user : "pgrp=0", p->pc, statename[p->state], p->time[0], p->time[1], p->r); } } + print("procdump: ret\n"); } void diff --git a/port/swap.c b/port/swap.c index 6fefcc95707a45cf26f378fd07ed6ec98d0d2f23..96d467b01a0be9a2bc387aa94769024122002af4 100644 --- a/port/swap.c +++ b/port/swap.c @@ -124,7 +124,6 @@ pager(void *junk) else { /* Emulate the old system if no swap channel */ print("no physical memory\n"); - pprint("no physical memory\n"); tsleep(&swapalloc.r, return0, 0, 1000); wakeup(&palloc.r); }