M alphapc/dat.h => alphapc/dat.h +5 -1
@@ 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 */
M alphapc/trap.c => alphapc/trap.c +9 -0
@@ 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;
M pc/dat.h => pc/dat.h +7 -3
@@ 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
M pc/main.c => pc/main.c +5 -0
@@ 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();
M pc/pci.c => pc/pci.c +13 -11
@@ 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
M pc/trap.c => pc/trap.c +13 -2
@@ 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;
M port/portdat.h => port/portdat.h +1 -1
@@ 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 */