pc, pc64: handle sse simd exceptions

This commit is contained in:
cinap_lenrek 2014-05-11 05:59:10 +02:00
parent edca217bb9
commit a9155014c0
7 changed files with 39 additions and 8 deletions

View file

@ -41,6 +41,7 @@ enum {
enum { enum {
CR4Osfxsr = 1 << 9, CR4Osfxsr = 1 << 9,
CR4Oxmmex = 1 << 10,
}; };
enum { /* cpuid standard function codes */ enum { /* cpuid standard function codes */
@ -860,7 +861,7 @@ cpuidentify(void)
if(m->cpuiddx & Fxsr){ /* have sse fp? */ if(m->cpuiddx & Fxsr){ /* have sse fp? */
fpsave = fpssesave; fpsave = fpssesave;
fprestore = fpsserestore; fprestore = fpsserestore;
putcr4(getcr4() | CR4Osfxsr); putcr4(getcr4() | CR4Osfxsr|CR4Oxmmex);
} else { } else {
fpsave = fpx87save; fpsave = fpx87save;
fprestore = fpx87restore; fprestore = fpx87restore;

View file

@ -94,6 +94,7 @@ void* kaddr(ulong);
void kbdenable(void); void kbdenable(void);
void kbdinit(void); void kbdinit(void);
#define kmapinval() #define kmapinval()
void ldmxcsr(ulong);
void lgdt(ushort[3]); void lgdt(ushort[3]);
void lldt(ulong); void lldt(ulong);
void lidt(ushort[3]); void lidt(ushort[3]);

View file

@ -15,6 +15,9 @@ enum {
VectorPF = 14, /* page fault */ VectorPF = 14, /* page fault */
Vector15 = 15, /* reserved */ Vector15 = 15, /* reserved */
VectorCERR = 16, /* coprocessor error */ VectorCERR = 16, /* coprocessor error */
VectorAC = 17, /* alignment check */
VectorMC = 18, /* machine check */
VectorSIMD = 19, /* simd error */
VectorPIC = 32, /* external i8259 interrupts */ VectorPIC = 32, /* external i8259 interrupts */
IrqCLOCK = 0, IrqCLOCK = 0,

View file

@ -645,6 +645,10 @@ TEXT fpsserestore0(SB), $0 /* enable and restore state */
WAIT WAIT
RET RET
TEXT ldmxcsr(SB), $0 /* Load MXCSR */
LDMXCSR mxcsr+0(FP)
RET
/* /*
*/ */
TEXT splhi(SB), $0 TEXT splhi(SB), $0
@ -983,7 +987,7 @@ TEXT vectortable(SB), $0
CALL _strayintr(SB); BYTE $0x10 /* coprocessor error */ CALL _strayintr(SB); BYTE $0x10 /* coprocessor error */
CALL _strayintrx(SB); BYTE $0x11 /* alignment check */ CALL _strayintrx(SB); BYTE $0x11 /* alignment check */
CALL _strayintr(SB); BYTE $0x12 /* machine check */ CALL _strayintr(SB); BYTE $0x12 /* machine check */
CALL _strayintr(SB); BYTE $0x13 CALL _strayintr(SB); BYTE $0x13 /* simd error */
CALL _strayintr(SB); BYTE $0x14 CALL _strayintr(SB); BYTE $0x14
CALL _strayintr(SB); BYTE $0x15 CALL _strayintr(SB); BYTE $0x15
CALL _strayintr(SB); BYTE $0x16 CALL _strayintr(SB); BYTE $0x16

View file

@ -731,6 +731,17 @@ matherror(Ureg*, void*)
mathnote(up->fpsave.status, up->fpsave.pc); mathnote(up->fpsave.status, up->fpsave.pc);
} }
/*
* SIMD error
*/
static void
simderror(Ureg *ureg, void*)
{
fpsave(&up->fpsave);
up->fpstate = FPinactive;
mathnote(up->fpsave.mxcsr & 0x3f, ureg->pc);
}
/* /*
* math coprocessor emulation fault * math coprocessor emulation fault
*/ */
@ -747,6 +758,8 @@ mathemu(Ureg *ureg, void*)
switch(up->fpstate){ switch(up->fpstate){
case FPinit: case FPinit:
fpinit(); fpinit();
if(fpsave == fpssesave)
ldmxcsr(0); /* no simd exceptions on 386 */
up->fpstate = FPactive; up->fpstate = FPactive;
break; break;
case FPinactive: case FPinactive:
@ -790,6 +803,7 @@ mathinit(void)
intrenable(IrqIRQ13, matherror, 0, BUSUNKNOWN, "matherror"); intrenable(IrqIRQ13, matherror, 0, BUSUNKNOWN, "matherror");
trapenable(VectorCNA, mathemu, 0, "mathemu"); trapenable(VectorCNA, mathemu, 0, "mathemu");
trapenable(VectorCSO, mathover, 0, "mathover"); trapenable(VectorCSO, mathover, 0, "mathover");
trapenable(VectorSIMD, simderror, 0, "simderror");
} }
/* /*

View file

@ -892,7 +892,7 @@ TEXT vectortable(SB), $0
CALL _strayintr(SB); BYTE $0x10 /* coprocessor error */ CALL _strayintr(SB); BYTE $0x10 /* coprocessor error */
CALL _strayintrx(SB); BYTE $0x11 /* alignment check */ CALL _strayintrx(SB); BYTE $0x11 /* alignment check */
CALL _strayintr(SB); BYTE $0x12 /* machine check */ CALL _strayintr(SB); BYTE $0x12 /* machine check */
CALL _strayintr(SB); BYTE $0x13 CALL _strayintr(SB); BYTE $0x13 /* simd error */
CALL _strayintr(SB); BYTE $0x14 CALL _strayintr(SB); BYTE $0x14
CALL _strayintr(SB); BYTE $0x15 CALL _strayintr(SB); BYTE $0x15
CALL _strayintr(SB); BYTE $0x16 CALL _strayintr(SB); BYTE $0x16

View file

@ -731,6 +731,17 @@ matherror(Ureg*, void*)
mathnote(up->fpsave.fsw, up->fpsave.rip); mathnote(up->fpsave.fsw, up->fpsave.rip);
} }
/*
* SIMD error
*/
static void
simderror(Ureg *ureg, void*)
{
fpsave(&up->fpsave);
up->fpstate = FPinactive;
mathnote(up->fpsave.mxcsr & 0x3f, ureg->pc);
}
/* /*
* math coprocessor emulation fault * math coprocessor emulation fault
*/ */
@ -758,11 +769,7 @@ mathemu(Ureg *ureg, void*)
_fninit(); _fninit();
_fwait(); _fwait();
_fldcw(0x0232); _fldcw(0x0232);
/* _ldmxcsr(0x1900);
* TODO: sse exceptions
* _ldmxcsr(m->mxcsr);
*
*/
up->fpstate = FPactive; up->fpstate = FPactive;
break; break;
case FPinactive: case FPinactive:
@ -806,6 +813,7 @@ mathinit(void)
intrenable(IrqIRQ13, matherror, 0, BUSUNKNOWN, "matherror"); intrenable(IrqIRQ13, matherror, 0, BUSUNKNOWN, "matherror");
trapenable(VectorCNA, mathemu, 0, "mathemu"); trapenable(VectorCNA, mathemu, 0, "mathemu");
trapenable(VectorCSO, mathover, 0, "mathover"); trapenable(VectorCSO, mathover, 0, "mathover");
trapenable(VectorSIMD, simderror, 0, "simderror");
} }
void void