From 9584dbf140aab3d221ec0028d0df1e422aa63a6d Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Fri, 14 Jun 1991 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1991-06-14 --- gnot/clock.c | 8 +- gnot/devduart.c | 2 +- gnot/lock.c | 8 ++ gnot/trap.c | 13 ++- pc/dat.h | 20 ---- pc/fns.h | 2 + pc/l.s | 292 ++++++++++++++++++++++++++++++++++++++++++++++++ pc/mem.h | 2 +- pc/trap.c | 21 +++- port/devbit.c | 1 + port/devcons.c | 1 + port/devproc.c | 3 + port/portdat.h | 2 + port/qlock.c | 5 +- port/stream.c | 1 + port/sysfile.c | 9 +- port/sysproc.c | 5 +- power/clock.c | 8 +- power/lock.c | 8 ++ ss/trap.c | 13 ++- 20 files changed, 387 insertions(+), 37 deletions(-) create mode 100644 pc/fns.h create mode 100644 pc/l.s diff --git a/gnot/clock.c b/gnot/clock.c index 7a4445a7f5c4575982f55b981d96fc7c568dea11..59e2efd7c873ed076c2cb25a12c7c0635ec393b9 100644 --- a/gnot/clock.c +++ b/gnot/clock.c @@ -35,8 +35,12 @@ clock(Ureg *ur) kbdclock(); mouseclock(); if((ur->sr&SPL(7)) == 0 && p && p->state==Running){ - if(anyready()) - sched(); + if(anyready()){ + if(p->hasspin) + p->hasspin = 0; + else + sched(); + } if(u->nnote && (ur->sr&SUPER)==0) notify(ur); } diff --git a/gnot/devduart.c b/gnot/devduart.c index 48b1f86986ea0bb733c8f8853a342b6c81dfdb55..47f7e0b42fcfa15867e8b00852f9c564dffd47b7 100644 --- a/gnot/devduart.c +++ b/gnot/devduart.c @@ -747,8 +747,8 @@ duartoput(Queue *q, Block *bp) (*cq->puts)(cq, bp->rptr, n); bp->rptr += n; } - freeb(bp); poperror(); + freeb(bp); } /* diff --git a/gnot/lock.c b/gnot/lock.c index f46a7e1b54130c0df4e38da824026c991d429557..a9776572cd6b7367683e13c5cce3bd1a42fc500b 100644 --- a/gnot/lock.c +++ b/gnot/lock.c @@ -28,12 +28,16 @@ lock(Lock *l) if(ll->key >= 0){ ll->key |= 0x80; ll->pc = ((ulong*)&l)[PCOFF]; + if(u && u->p) + u->p->hasspin = 1; return; } for(i=0; i<10000000; i++) if(ll->key >= 0){ ll->key |= 0x80; ll->pc = ((ulong*)&l)[PCOFF]; + if(u && u->p) + u->p->hasspin = 1; return; } ll->key = 0; @@ -47,6 +51,8 @@ canlock(Lock *l) if(ll->key >= 0){ ll->key |= 0x80; ll->pc = ((ulong*)&l)[PCOFF]; + if(u && u->p) + u->p->hasspin = 1; return 1; } return 0; @@ -57,6 +63,8 @@ unlock(Lock *l) { l->pc = 0; l->key = 0; + if(u && u->p) + u->p->hasspin = 0; } void diff --git a/gnot/trap.c b/gnot/trap.c index 2ecf45c287ad7e5788a98a303f65a2f8320fe69b..0c113c505b472e6b1bee42c43b0e8d7443341591 100644 --- a/gnot/trap.c +++ b/gnot/trap.c @@ -250,6 +250,7 @@ Syscall *systab[]={ long syscall(Ureg *aur) { + int i; long ret; ulong sp; ulong r0; @@ -292,11 +293,17 @@ syscall(Ureg *aur) msg = "sys: odd stack"; goto Bad; } - if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-5*BY2WD)) - validaddr(sp, 5*BY2WD, 0); + if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-(1+MAXSYSARG)*BY2WD)) + validaddr(sp, (1+MAXSYSARG)*BY2WD, 0); ret = (*systab[r0])((ulong*)(sp+BY2WD)); + poperror(); + } + if(u->nerrlab){ + print("unbalanced error stack: %d extra\n", u->nerrlab); + for(i = 0; i < NERR; i++) + print("sp=%lux pc=%lux\n", u->errlab[i].sp, u->errlab[i].pc); + panic("bad rob"); } - u->nerrlab = 0; u->p->insyscall = 0; if(r0 == NOTED) /* ugly hack */ noted(aur); /* doesn't return */ diff --git a/pc/dat.h b/pc/dat.h index a65313e09c41f662b2ab138b095595fb550ec98d..7c9cb4c919a5e8afbd8b5204962c0f87fa7b108e 100644 --- a/pc/dat.h +++ b/pc/dat.h @@ -27,26 +27,6 @@ struct Label { ulong sp; ulong pc; - ushort sr; -}; - -/* - * floating point registers - */ -enum -{ - FPinit, - FPactive, - FPdirty, -}; - -struct FPsave -{ - uchar type; - uchar size; - short reserved; - char junk[212]; /* 68881: sizes 24, 180; 68882: 56, 212 */ - char reg[3*4+8*12]; }; struct Conf diff --git a/pc/fns.h b/pc/fns.h new file mode 100644 index 0000000000000000000000000000000000000000..68dc97b891aa757a7ce68ae6cf864a32fcfeda4a --- /dev/null +++ b/pc/fns.h @@ -0,0 +1,2 @@ +void restregs(void); +void saveregs(void); diff --git a/pc/l.s b/pc/l.s new file mode 100644 index 0000000000000000000000000000000000000000..e4e287c95144dbae4db927f821ec6068bd96e644 --- /dev/null +++ b/pc/l.s @@ -0,0 +1,292 @@ + +/* + * Boot first processor + */ +TEXT start(SB),$0 + + /* clear bss */ + CALL main(SB) + /* never returns */ + + +TEXT traptab(SB),$0 + + CALL noerrcode(SB) /* divide */ + CALL noerrcode(SB) /* debug */ + CALL noerrcode(SB) /* non maskable interrupt */ + CALL noerrcode(SB) /* breakpoint */ + CALL noerrcode(SB) /* overflow */ + CALL noerrcode(SB) /* bounds check */ + CALL noerrcode(SB) /* invalid opcode */ + CALL noerrcode(SB) /* coprocessor not available */ + CALL errcode(SB) /* double fault */ + CALL noerrcode(SB) /* coprocessor segment overrun */ + CALL errcode(SB) /* invalid tss */ + CALL errcode(SB) /* segment not present */ + CALL errcode(SB) /* stack exception */ + CALL errcode(SB) /* general protection exception */ + CALL errcode(SB) /* page fault */ + CALL noerrcode(SB) /* coprocessor error */ + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + CALL noerrcode(SB) + +TEXT noerrcode(SB),$0 + PUSH EAX + /* drop through */ +TEXT errcode(SB),$0 + PUSH EAX + PUSH EBX + PUSH ECX + PUSH EDX + PUSH EBP + PUSH ESI + PUSH EDI + CALL trap(SB) + POP EDI + POP ESI + POP EBP + POP EDX + POP ECX + POP EBX + POP EAX + ADD $8,ESP /* jump over error code + return addr */ + IRET diff --git a/pc/mem.h b/pc/mem.h index f5544c967165a100c6433391e7b71e3fcc6dbcea..4340b3cb5f0f343ee503bc5d937752a22af108ac 100644 --- a/pc/mem.h +++ b/pc/mem.h @@ -37,7 +37,7 @@ struct Segdesc /* * segment descriptor initializers */ -#define DATASEG(p) { SEGG|(0xF<<16)|SEGP|SEGPL(p)|SEGDATA|SEGW, 0xFFFF } +#define DATASEG(p) { SEGG|SEGB|(0xF<<16)|SEGP|SEGPL(p)|SEGDATA|SEGW, 0xFFFF } #define EXECSEG(p) { SEGG|SEGD|(0xF<<16)|SEGP|SEGPL(p)|SEGEXEC|SEGR, 0xFFFF } /* diff --git a/pc/trap.c b/pc/trap.c index 8df4c90e110ea6a24fb5fe1aecb4b827b5cb7110..f88da5eb40175ad39d56d5682d800959c2f226d4 100644 --- a/pc/trap.c +++ b/pc/trap.c @@ -43,7 +43,7 @@ enum { }; /* - * exception/trap gates + * trap/interrupt gates */ Segdesc ilt[256] = { @@ -63,3 +63,22 @@ Segdesc ilt[256] = [Efault] TRAPGATE(KESEL, efault, 3), [Eco] TRAPGATE(KESEL, eco, 3), }; + +/* + * trap table + */ +uchar traptab[4096]; + +/* + * set up some basic vectored interrupts + */ +trapinit( + +/* + * j-random uncaught trap or interrupt + */ +void +trap(void) +{ + panic("unknown trap"); +} diff --git a/port/devbit.c b/port/devbit.c index 64f5794aa86dd22a84412a6d2052214754d4b7ff..e3eb10dec8182b13d598f076b39b9bdff9b06f87 100644 --- a/port/devbit.c +++ b/port/devbit.c @@ -1017,6 +1017,7 @@ bitwrite(Chan *c, void *va, long n, ulong offset) break; } + poperror(); if(isoff) cursoron(1); return n; diff --git a/port/devcons.c b/port/devcons.c index 3ffcd37f75e0331391ecfeff0b3c0b63fa2c1926..2ba17c2e7f346b90a18be50930e909b04f30721a 100644 --- a/port/devcons.c +++ b/port/devcons.c @@ -497,6 +497,7 @@ consread(Chan *c, void *buf, long n, ulong offset) *cbuf++ = ch; --n; } + poperror(); qunlock(&kbdq); return i; diff --git a/port/devproc.c b/port/devproc.c index 4d86b365725c47f281e9203e1f38764706cfa2a5..0c459223ee46345a9b0eb313df76655d4898a3ee 100644 --- a/port/devproc.c +++ b/port/devproc.c @@ -328,6 +328,7 @@ procread(Chan *c, void *va, long n, ulong offset) n = ERRLEN; } kunmap(k); + poperror(); unlock(&p->debug); return n; @@ -387,6 +388,7 @@ procwrite(Chan *c, void *va, long n, ulong offset) goto Died; } pgrpnote(pg, va, n, NUser); + poperror(); qunlock(&pg->debug); return n; } @@ -429,6 +431,7 @@ procwrite(Chan *c, void *va, long n, ulong offset) pprint("unknown qid in procwrite\n"); error(Egreg); } + poperror(); unlock(&p->debug); return n; } diff --git a/port/portdat.h b/port/portdat.h index 08123baa09d8c1768e8b17223a4c21238411af47..31545362cc8d7a952ae1b8218b18490fbb5e54f1 100644 --- a/port/portdat.h +++ b/port/portdat.h @@ -400,6 +400,7 @@ struct Proc int kp; /* true if a kernel process */ Proc *palarm; /* Next alarm time */ ulong alarm; /* Time of call */ + int hasspin; /* * machine specific MMU goo @@ -491,6 +492,7 @@ enum { Streambhi= 32, /* block count high water mark */ }; +#define MAXSYSARG 6 /* for mount(fd, mpt, flag, arg, srv, authfd) */ #define PRINTSIZE 256 #define NUMSIZE 12 /* size of formatted number */ diff --git a/port/qlock.c b/port/qlock.c index ed4b1ff32205595817d99618acca46c43a0b3d8d..61add69891a964e5d6ecdf7f107ad839a966eb43 100644 --- a/port/qlock.c +++ b/port/qlock.c @@ -10,8 +10,11 @@ qlock(QLock *q) { Proc *p; - if(canlock(&q->use)) + if(canlock(&q->use)){ + if(u) + u->p->hasspin = 0; return; + } lock(&q->queue); if(canlock(&q->use)){ unlock(&q->queue); diff --git a/port/stream.c b/port/stream.c index 0e8b1ed7248cabb2aebfd4d189d3f7efd0d71ccc..487a3d99413d52253414469b06a28f4a9019ce2e 100644 --- a/port/stream.c +++ b/port/stream.c @@ -419,6 +419,7 @@ popq(Stream *s) (*q->info->close)(RD(q)); s->procq->next = q->next; RD(q->next)->next = RD(s->procq); + poperror(); qunlock(s); freeq(q); } diff --git a/port/sysfile.c b/port/sysfile.c index d1edd79409d333ebfd84c2bbe52eec9c4e97e69b..63bfe099918a9ef28a7e8625a4ac3e8ffbfe9b7f 100644 --- a/port/sysfile.c +++ b/port/sysfile.c @@ -243,6 +243,7 @@ sysread(ulong *arg) else n = (*devtab[c->type].read)(c, (void*)arg[1], n, c->offset); c->offset += n; + poperror(); qunlock(&c->rdl); return n; } @@ -265,6 +266,7 @@ syswrite(ulong *arg) error(Eisdir); n = (*devtab[c->type].write)(c, (void*)arg[1], arg[2], c->offset); c->offset += n; + poperror(); qunlock(&c->wrl); return n; } @@ -305,9 +307,9 @@ sysseek(ulong *arg) break; } off = c->offset; + poperror(); qunlock(&c->rdl); qunlock(&c->wrl); - poperror(); return off; } @@ -412,8 +414,10 @@ bindmount(ulong *arg, int ismount) if(flag && !(c0->qid.path&CHDIR)) error(Ebadmount); ret = mount(c0, c1, flag); - close(c0); + poperror(); close(c1); + poperror(); + close(c0); if(ismount){ close(bogus.chan); fdclose(arg[0]); @@ -465,6 +469,7 @@ sysremove(ulong *arg) * so fake it up. rootclose() is known to be a nop. */ c->type = 0; + poperror(); close(c); return 0; } diff --git a/port/sysproc.c b/port/sysproc.c index 9ca1d3b1d2855aa42f4345a1e9ccd3e960ffdd93..b1052d685634a988f3fccab095e94e20610b6cce 100644 --- a/port/sysproc.c +++ b/port/sysproc.c @@ -204,8 +204,8 @@ sysexec(ulong *arg) arg[1] += BY2WD; file = progarg[0]; progarg[0] = elem; - close(tc); poperror(); + close(tc); goto Header; Binary: @@ -335,6 +335,7 @@ sysexec(ulong *arg) s->maxva = b; s->mod = 0; + poperror(); close(tc); p->seg[BSEG].endseg = bssend; @@ -435,6 +436,7 @@ sysexits(ulong *arg) validaddr((ulong)status, 1, 0); vmemchr(status, 0, ERRLEN); } + poperror(); } pexit(status, 1); } @@ -496,6 +498,7 @@ sysforkpgrp(ulong *arg) memset(u->note, 0, sizeof(u->note)); } + poperror(); closepgrp(u->p->pgrp); u->p->pgrp = pg; return pg->pgrpid; diff --git a/power/clock.c b/power/clock.c index 9e38d1fb79d2dd7e6164595318fb0e671de2ec5f..04b6387efc6653feb29e956c159c5b4b07c16e0f 100644 --- a/power/clock.c +++ b/power/clock.c @@ -109,8 +109,12 @@ clock(Ureg *ur) } checkalarms(); if(u && (ur->status&IEP) && u->p && u->p->state==Running){ - if(anyready()) - sched(); + if(anyready()){ + if(u->p->hasspin) + u->p->hasspin = 0; /* just in case */ + else + sched(); + } if(u->nnote && (ur->status&KUP)) notify(ur); } diff --git a/power/lock.c b/power/lock.c index 924a76197b68a4a488df3f6d8817e2ea9d1b0d7b..5ba14936a6079ec0a64f7d94377c1561254d8e2a 100644 --- a/power/lock.c +++ b/power/lock.c @@ -135,11 +135,15 @@ lock(Lock *ll) */ if((*sbsem&1) == 0){ l->pc = ((ulong*)&ll)[PCOFF]; + if(u && u->p) + u->p->hasspin = 1; return; } for(i=0; i<10000000; i++) if((*sbsem&1) == 0){ l->pc = ((ulong*)&ll)[PCOFF]; + if(u && u->p) + u->p->hasspin = 1; return; } *sbsem = 0; @@ -168,6 +172,8 @@ canlock(Lock *l) } if(*sbsem & 1) return 0; + if(u && u->p) + u->p->hasspin = 1; return 1; } @@ -176,6 +182,8 @@ unlock(Lock *l) { l->pc = 0; *l->sbsem = 0; + if(u && u->p) + u->p->hasspin = 0; } void diff --git a/ss/trap.c b/ss/trap.c index 2dc03e0563415e473d2f4aa05f4e8b8062309062..ac2804dbf5452b0e4895d328a5fb140c4f31af53 100644 --- a/ss/trap.c +++ b/ss/trap.c @@ -309,6 +309,7 @@ Syscall *systab[]={ long syscall(Ureg *aur) { + int i; long ret; ulong sp; ulong r7; @@ -349,13 +350,19 @@ syscall(Ureg *aur) msg = "sys: odd stack"; goto Bad; } - if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-5*BY2WD)) - validaddr(sp, 5*BY2WD, 0); + if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-(2+MAXSYSARG)*BY2WD)) + validaddr(sp, ((2+MAXSYSARG)*BY2WD), 0); ret = (*systab[r7])((ulong*)(sp+2*BY2WD)); + poperror(); } ur->pc += 4; ur->npc = ur->pc+4; - u->nerrlab = 0; + if(u->nerrlab){ + print("unbalanced error stack: %d extra\n", u->nerrlab); + for(i = 0; i < NERR; i++) + print("sp=%lux pc=%lux\n", u->errlab[i].sp, u->errlab[i].pc); + panic("bad rob"); + } u->p->insyscall = 0; if(r7 == NOTED) /* ugly hack */ noted(&aur); /* doesn't return */