From 3a8680326098800670b849cc6026eac9a4e30472 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sat, 24 Aug 2002 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2002-08-24 --- alphapc/dat.h | 6 +++++- alphapc/trap.c | 9 +++++++++ pc/dat.h | 10 +++++++--- pc/main.c | 5 +++++ pc/pci.c | 24 +++++++++++++----------- pc/trap.c | 15 +++++++++++++-- port/portdat.h | 2 +- 7 files changed, 53 insertions(+), 18 deletions(-) diff --git a/alphapc/dat.h b/alphapc/dat.h index 637bcc1008c5a523911f917779045f649bc7535a..d863118c998c4fd13f85111066878489e1842bc2 100644 --- a/alphapc/dat.h +++ b/alphapc/dat.h @@ -47,9 +47,13 @@ struct Label */ enum { + /* floating point states */ FPinit, FPactive, FPinactive, + + /* bit or'd with the state */ + FPillegal= 0x100, }; struct FPsave @@ -243,7 +247,7 @@ typedef struct { struct DevConf { - ulong interrupt; /* interrupt number */ + ulong intnum; /* interrupt number */ char *type; /* card type, malloced */ int nports; /* Number of ports */ port_t *ports; /* The ports themselves */ diff --git a/alphapc/trap.c b/alphapc/trap.c index a066ee5f81d7731a404b184002a1158af7ae1bc9..bdc13bb7809dd5c1679c2b97b124849835b80d4a 100644 --- a/alphapc/trap.c +++ b/alphapc/trap.c @@ -521,6 +521,13 @@ notify(Ureg *ur) spllo(); qlock(&up->debug); up->notepending = 0; + + if(up->fpstate == FPactive){ + savefpregs(&up->fpsave); + up->fpstate = FPinactive; + } + up->fpstate |= FPillegal; + n = &up->note[0]; if(strncmp(n->msg, "sys:", 4) == 0) { l = strlen(n->msg); @@ -611,6 +618,8 @@ print("call to noted() when not notified\n"); } up->notified = 0; + up->fpstate &= ~FPillegal; + nur = up->ureg; oureg = (ulong)nur; diff --git a/pc/dat.h b/pc/dat.h index 7e93d7c14db51b56df65c6b4010385e56e2a870b..0532f1f18d7822dda12deb82bc9576a53badaaf5 100644 --- a/pc/dat.h +++ b/pc/dat.h @@ -45,9 +45,13 @@ struct Label */ enum { - FPinit, - FPactive, - FPinactive, + /* this is a state */ + FPinit= 0, + FPactive= 1, + FPinactive= 2, + + /* the following is a bit that can be or'd into the state */ + FPillegal= 0x100, }; struct FPsave diff --git a/pc/main.c b/pc/main.c index 1d9642965a83f8d167af5c401c412163c818fd73..874ed425d2ebd333e0451a4b75a1b31c56091bf9 100644 --- a/pc/main.c +++ b/pc/main.c @@ -487,6 +487,11 @@ matherror(Ureg *ur, void*) static void mathemu(Ureg*, void*) { + if(up->fpstate & FPillegal){ + /* someone did floating point in a note handler */ + postnote(up, 1, "sys: floating point in note handler", NDebug); + return; + } switch(up->fpstate){ case FPinit: fpinit(); diff --git a/pc/pci.c b/pc/pci.c index e67eca9a657742aa2e76edb6bfdd5f1f8584770e..59370ef5ea30bc06f29740a172c1b6a18fd211a9 100644 --- a/pc/pci.c +++ b/pc/pci.c @@ -762,19 +762,19 @@ pcicfginit(void) * Mode2 uses a byte at 0xCF8 and another at 0xCFA; Mode1 uses * a DWORD at 0xCF8 and another at 0xCFC and will pass through * any non-DWORD accesses as normal I/O cycles. There shouldn't be - * a device behind these addresses so if Mode2 accesses fail try - * for Mode1 (which is preferred, Mode2 is deprecated). + * a device behind these addresses so if Mode1 accesses fail try + * for Mode2 (Mode2 is deprecated). */ - outb(PciCSE, 0); - if(inb(PciCSE) == 0){ - pcicfgmode = 2; - pcimaxdno = 15; + outl(PciADDR, 0); + if(inl(PciADDR) == 0){ + pcicfgmode = 1; + pcimaxdno = 31; } - else { - outl(PciADDR, 0); - if(inl(PciADDR) == 0){ - pcicfgmode = 1; - pcimaxdno = 31; + else{ + outb(PciCSE, 0); + if(inb(PciCSE) == 0){ + pcicfgmode = 2; + pcimaxdno = 15; } } @@ -853,6 +853,8 @@ pcicfginit(void) out: unlock(&pcicfginitlock); + if(getconf("*pcihinv")) + pcihinv(nil); } static int diff --git a/pc/trap.c b/pc/trap.c index 5fde0cd9308d36ec1d74be4f33609eef932b6dd0..0f827a541620c6cd8f2e5a4736a8870387fdd6dc 100644 --- a/pc/trap.c +++ b/pc/trap.c @@ -652,6 +652,12 @@ notify(Ureg* ureg) if(up->nnote == 0) return 0; + if(user && up->fpstate == FPactive){ + fpsave(&up->fpsave); + up->fpstate = FPinactive; + } + up->fpstate |= FPillegal; + s = spllo(); qlock(&up->debug); up->notepending = 0; @@ -697,9 +703,9 @@ notify(Ureg* ureg) sp -= BY2WD+ERRMAX; memmove((char*)sp, up->note[0].msg, ERRMAX); sp -= 3*BY2WD; - *(ulong*)(sp+2*BY2WD) = sp+3*BY2WD; /* arg 2 is string */ + *(ulong*)(sp+2*BY2WD) = sp+3*BY2WD; /* arg 2 is string */ *(ulong*)(sp+1*BY2WD) = (ulong)up->ureg; /* arg 1 is ureg* */ - *(ulong*)(sp+0*BY2WD) = 0; /* arg 0 is pc */ + *(ulong*)(sp+0*BY2WD) = 0; /* arg 0 is pc */ ureg->usp = sp; ureg->pc = (ulong)up->notify; up->notified = 1; @@ -731,6 +737,8 @@ noted(Ureg* ureg, ulong arg0) nureg = up->ureg; /* pointer to user returned Ureg struct */ + up->fpstate &= ~FPillegal; + /* sanity clause */ oureg = (ulong)nureg; if(!okaddr((ulong)oureg-BY2WD, BY2WD+sizeof(Ureg), 0)){ @@ -807,6 +815,9 @@ execregs(ulong entry, ulong ssize, ulong nargs) ulong *sp; Ureg *ureg; + up->fpstate = FPinit; + fpoff(); + sp = (ulong*)(USTKTOP - ssize); *--sp = nargs; diff --git a/port/portdat.h b/port/portdat.h index 558fd6662273d284ab40e5622457842ba4fd03ca..406131b2ab3d255fc59eab610eb409cbb74e2965 100644 --- a/port/portdat.h +++ b/port/portdat.h @@ -589,7 +589,7 @@ struct Proc ulong parentpid; ulong time[6]; /* User, Sys, Real; child U, S, R */ - short insyscall; + int insyscall; int fpstate; QLock debug; /* to access debugging elements of User */