From d439b1d60c475b5675ce04d92b5509c6271953fa Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sat, 28 Nov 1992 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1992-11-28 --- power/debugger.c | 9 +- power/fptrap.c | 2 - power/io.h | 4 + power/trap.c | 219 ++++++++++++++++++++++++++--------------------- 4 files changed, 132 insertions(+), 102 deletions(-) diff --git a/power/debugger.c b/power/debugger.c index 6e944d6160115ef17b4a1a0ba752812497b8c48d..7e5331b68ba264aa4e44ebc0585a4debf76a445e 100644 --- a/power/debugger.c +++ b/power/debugger.c @@ -3,6 +3,7 @@ #include "mem.h" #include "dat.h" #include "fns.h" +#include "io.h" IOQ dkbdq; IOQ dprintq; @@ -78,9 +79,11 @@ printlog(char *cpu) return; s = &syslogbuf[i]; + if(s->next < s->buf || s->next >= &s->buf[sizeof(s->buf)]) + s->next = s->buf; end = s->next; p = end + 1; - if(p >= &s->buf[sizeof(s->buf)]) + if(p >= &s->buf[sizeof(s->buf)] || p < s->buf) p = s->buf; while(p != end){ c = *p & 0xff; @@ -202,11 +205,15 @@ debugger(void *arg) case 'i': printinfo(); break; + case 'q': + firmware(cpuserver ? PROM_AUTOBOOT : PROM_REINIT); + break; default: dprint("!commands are:\r\n"); dprint("! l - print cpu log\r\n"); dprint("! h - hex display\r\n"); dprint("! i - display some addresses\r\n"); + dprint("! q - quit/rebooot\r\n"); break; } } diff --git a/power/fptrap.c b/power/fptrap.c index efa8944bf974fc60f96d02d35cce3b9829e21880..a95fa6a232d23fff226989688e06e9ea6b90bfe4 100644 --- a/power/fptrap.c +++ b/power/fptrap.c @@ -29,8 +29,6 @@ fptrap(Ureg *ur, ulong fcr31) { ulong iw, npc; - savefpregs(&u->fpsave); - u->p->fpstate = FPinactive; /* will get turned on again in trap() */ if((fcr31&(1<<17)) == 0) return 0; if(ur->cause & (1<<31)) diff --git a/power/io.h b/power/io.h index 72c532047ee480ddeee27a2076f0949036a936d3..ea351baae92d92e17da64127e8532c965586ffc3 100644 --- a/power/io.h +++ b/power/io.h @@ -15,8 +15,12 @@ enum LEDfault= 1<<6, LEDpulse= 1<<7, }; +/* #define LEDON(x) (m->ledval &= ~(x), *LED = m->ledval) #define LEDOFF(x) (m->ledval |= (x), *LED = m->ledval) +*/ +#define LEDON(x) +#define LEDOFF(x) typedef struct SBCC SBCC; typedef struct Timer Timer; diff --git a/power/trap.c b/power/trap.c index 46f9e25655147de4084ec78794d3679da846b0a7..e98cc86c7a8d02bbccebc6b2bbaa87bf333bf3dd 100644 --- a/power/trap.c +++ b/power/trap.c @@ -75,109 +75,116 @@ void trap(Ureg *ur) { int ecode; - int user, x; + int user, cop, x; ulong fcr31; - char buf[2*ERRLEN], buf1[ERRLEN]; - - SET(fcr31); + char buf[2*ERRLEN], buf1[ERRLEN], *fpexcep; +*LED=~1; ecode = EXCCODE(ur->cause); LEDON(ecode); user = ur->status&KUP; if(u) u->dbgreg = ur; +*LED=~2; + + if(u && u->p->fpstate == FPactive) { + savefpregs(&u->fpsave); + u->p->fpstate = FPinactive; + ur->status &= ~CU1; + } +*LED=~3; switch(ecode){ case CINT: - if(u && u->p->state==Running){ - if(u->p->fpstate == FPactive) { - if(ur->cause & INTR3){ /* FP trap */ - fcr31 = clrfpintr(); - if(user && fptrap(ur, fcr31)) - goto Return; - ecode = FPEXC; - goto Default; - } - savefpregs(&u->fpsave); - u->p->fpstate = FPinactive; - ur->status &= ~CU1; +*LED=~4; + if(ur->cause&INTR3) { /* FP trap */ +*LED=~5; + if(u == 0 || u->p->fpstate != FPinactive) + panic("fp intr3 no u or not inactive pc=%lux", ur->pc); + + fcr31 = clrfpintr(); + if(user == 0) + panic("kernel floating point trap pc=%lux", ur->pc); +*LED=~6; + + ur->cause &= ~INTR3; + if(!fptrap(ur, fcr31)) { + intr(ur); + spllo(); + fpexcep = fpexcname(ur, fcr31, buf1); + sprint(buf, "sys: fp: %s", fpexcep); + postnote(u->p, 1, buf, NDebug); + break; } +*LED=~7; } intr(ur); +*LED=~8; break; case CTLBM: case CTLBL: case CTLBS: +*LED=~9; if(u == 0) panic("fault u==0 pc %lux addr %lux", ur->pc, ur->badvaddr); - if(u->p->fpstate == FPactive) { - savefpregs(&u->fpsave); - u->p->fpstate = FPinactive; - ur->status &= ~CU1; - } +*LED=~10; spllo(); x = u->p->insyscall; u->p->insyscall = 1; faultmips(ur, user, ecode); u->p->insyscall = x; +*LED=~11; break; case CCPU: - if(u && u->p && u->p->fpstate == FPinit) { - restfpregs(&initfp, u->fpsave.fpstatus); - u->p->fpstate = FPactive; - ur->status |= CU1; - break; - } - if(u && u->p && u->p->fpstate == FPinactive) { - restfpregs(&u->fpsave, u->fpsave.fpstatus); - u->p->fpstate = FPactive; - ur->status |= CU1; - break; +*LED=~12; + cop = (ur->cause>>28)&3; + if(u && cop == 1) { + if(u->p->fpstate == FPinit) { + restfpregs(&initfp, u->fpsave.fpstatus); + u->p->fpstate = FPactive; + ur->status |= CU1; + break; + } + if(u->p->fpstate == FPinactive) { + restfpregs(&u->fpsave, u->fpsave.fpstatus); + u->p->fpstate = FPactive; + ur->status |= CU1; + break; + } } - goto Default; +*LED=~13; + /* Fallthrough */ default: - if(u && u->p && u->p->fpstate == FPactive){ - savefpregs(&u->fpsave); - u->p->fpstate = FPinactive; - ur->status &= ~CU1; - } - Default: - /* - * This isn't good enough; can still deadlock because we may - * hold print's locks in this processor. - */ - if(user){ + if(user) { spllo(); - if(ecode == FPEXC) - sprint(buf, "sys: fp: %s", fpexcname(ur, fcr31, buf1)); - else - sprint(buf, "sys: %s", excname[ecode]); - + sprint(buf, "sys: %s", excname[ecode]); postnote(u->p, 1, buf, NDebug); - }else{ - print("%s %s pc=%lux\n", user? "user": "kernel", excname[ecode], ur->pc); - if(ecode == FPEXC) - print("fp: %s\n", fpexcname(ur, fcr31, buf1)); - dumpregs(ur); - dumpstack(); - if(m->machno == 0) - spllo(); - exit(1); + break; } + print("kernel %s pc=%lux\n", excname[ecode], ur->pc); + dumpregs(ur); + dumpstack(); + if(m->machno == 0) + spllo(); + exit(1); } +*LED=~14; splhi(); - Return: if(user) { +*LED=~15; notify(ur); +*LED=~16; if(u->p->fpstate == FPinactive) { restfpregs(&u->fpsave, u->fpsave.fpstatus); u->p->fpstate = FPactive; ur->status |= CU1; } +*LED=~17; } +*LED=~0; LEDOFF(ecode); } @@ -193,20 +200,17 @@ intr(Ureg *ur) m->intr++; cause = ur->cause&(INTR5|INTR4|INTR3|INTR2|INTR1); - if(cause & (INTR2|INTR4)){ - LEDON(LEDclock); - clock(ur); - LEDOFF(LEDclock); - cause &= ~(INTR2|INTR4); - } + if(cause & INTR1){ duartintr(); cause &= ~INTR1; } + if(cause & INTR5){ any = 0; if(!(*MPBERR1 & (1<<8))){ print("MP bus error %lux %lux\n", *MPBERR0, *MPBERR1); + print("PC %lux R31 %lux\n", ur->pc, ur->r31); *MPBERR0 = 0; i = *SBEADDR; USED(i); @@ -258,8 +262,8 @@ intr(Ureg *ur) if(pend & 1) { v = INTVECREG->i[0].vec; if(!(v & (1<<12))){ - print("io2 mp bus error %d %lux %lux\n", 0, - *MPBERR0, *MPBERR1); + print("ioberr %lux %lux\n", *MPBERR0, *MPBERR1); + print("PC %lux R31 %lux\n", ur->pc, ur->r31); *MPBERR0 = 0; any = 1; } @@ -315,6 +319,14 @@ intr(Ureg *ur) *IO2SETMASK = 0xff000000; cause &= ~INTR5; } + + if(cause & (INTR2|INTR4)){ + LEDON(LEDclock); + clock(ur); + LEDOFF(LEDclock); + cause &= ~(INTR2|INTR4); + } + if(cause) panic("cause %lux %lux\n", u, cause); } @@ -408,48 +420,57 @@ notify(Ureg *ur) l = strlen(n->msg); if(l > ERRLEN-15) /* " pc=0x12345678\0" */ l = ERRLEN-15; + sprint(n->msg+l, " pc=0x%lux", ur->pc); } + if(n->flag!=NUser && (u->notified || u->notify==0)){ if(n->flag == NDebug) pprint("suicide: %s\n", n->msg); - Die: + qunlock(&u->p->debug); pexit(n->msg, n->flag!=NDebug); } - sent = 0; - if(!u->notified){ - if(!u->notify) - goto Die; - sent = 1; - u->svstatus = ur->status; - sp = ur->usp; - sp -= sizeof(Ureg); - if(!okaddr((ulong)u->notify, 1, 0) - || !okaddr(sp-ERRLEN-3*BY2WD, sizeof(Ureg)+ERRLEN-3*BY2WD, 0)){ - pprint("suicide: bad address in notify\n"); - qunlock(&u->p->debug); - pexit("Suicide", 0); - } - 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 */ - u->svr1 = ur->r1; /* save away r1 */ - ur->r1 = (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)); + + if(u->notified) { + qunlock(&u->p->debug); + splx(s); + return 0; } + + if(!u->notify) { + qunlock(&u->p->debug); + pexit(n->msg, n->flag!=NDebug); + } + u->svstatus = ur->status; + sp = ur->usp; + sp -= sizeof(Ureg); + + if(sp&0x3 || !okaddr((ulong)u->notify, 1, 0) + || !okaddr(sp-ERRLEN-3*BY2WD, sizeof(Ureg)+ERRLEN-3*BY2WD, 0)){ + pprint("suicide: bad address or sp in notify\n"); + qunlock(&u->p->debug); + pexit("Suicide", 0); + } + 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 */ + u->svr1 = ur->r1; /* save away r1 */ + ur->r1 = (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)); + qunlock(&u->p->debug); splx(s); - return sent; + return 1; } /* @@ -568,7 +589,7 @@ syscall(Ureg *aur) noted(&aur, *(ulong*)(sp+BY2WD)); /* doesn't return */ splhi(); if(u->scallnr!=RFORK && (p->procctl || u->nnote)){ - ur->r1 = ret; /* load up for noted() */ + ur->r1 = ret; /* load up for noted() */ if(notify(ur)) return ur->r1; }