/* * math coprocessor error */ static void matherror(Ureg *ur, void*) { ulong status, pc; /* * a write cycle to port 0xF0 clears the interrupt latch attached * to the error# line from the 387 */ if(!(m->cpuiddx & Fpuonchip)) outb(0xF0, 0xFF); /* * save floating point state to check out error */ fpenv(&up->fpsave); /* result ignored, but masks fp exceptions */ fpsave(&up->fpsave); /* also turns fpu off */ fpon(); mathnote(); if((ur->pc & 0xf0000000) == KZERO){ mathstate(&status, &pc, nil); panic("fp: status %#lux fppc=%#lux pc=%#lux", status, pc, ur->pc); } }
static void mathnote(void) { int i; ulong status, pc; char *msg, note[ERRMAX]; mathstate(&status, &pc, nil); /* * Some attention should probably be paid here to the * exception masks and error summary. */ msg = "unknown exception"; for(i = 1; i <= 5; i++){ if(!((1<<i) & status)) continue; msg = mathmsg[i]; break; } if(status & 0x01){ if(status & 0x40){ if(status & 0x200) msg = "stack overflow"; else msg = "stack underflow"; }else msg = "invalid operation"; } snprint(note, sizeof note, "sys: fp: %s fppc=%#lux status=%#lux", msg, pc, status); postnote(up, 1, note, NDebug); }
/* * math coprocessor error */ static void matherror(Ureg *ur, void*) { ulong status, pc; /* * a write cycle to port 0xF0 clears the interrupt latch attached * to the error# line from the 387 */ if(!(m->cpuiddx & 0x01)) outb(0xF0, 0xFF); fpalloc(); /* * save floating point state to check out error */ fpenv(&up->fpsave); mathnote(); if((ur->pc & 0xf0000000) == KZERO){ mathstate(&status, &pc, nil); panic("fp: status %#lux fppc=%#lux pc=%#lux", status, pc, ur->pc); } }
/* * math coprocessor emulation fault */ static void mathemu(Ureg *ureg, void*) { ulong status, control; 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: fpalloc(); fpinit(); up->fpstate = FPactive; break; case FPinactive: /* * Before restoring the state, check for any pending * exceptions, there's no way to restore the state without * generating an unmasked exception. * More attention should probably be paid here to the * exception masks and error summary. */ mathstate(&status, nil, &control); if((status & ~control) & 0x07F){ mathnote(); break; } fprestore(&up->fpsave); up->fpstate = FPactive; break; case FPactive: panic("math emu pid %ld %s pc 0x%lux", up->pid, up->text, ureg->pc); break; } }