diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2014-05-11 05:59:10 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2014-05-11 05:59:10 +0200 |
commit | a9155014c064a6a58568d355194acf416ca8efe2 (patch) | |
tree | 64d9fb64d479963005e9fe3f76dea4edb6b7f128 /sys/src | |
parent | edca217bb99f7c32413c117239d12acdc223e811 (diff) |
pc, pc64: handle sse simd exceptions
Diffstat (limited to 'sys/src')
-rw-r--r-- | sys/src/9/pc/devarch.c | 3 | ||||
-rw-r--r-- | sys/src/9/pc/fns.h | 1 | ||||
-rw-r--r-- | sys/src/9/pc/io.h | 3 | ||||
-rw-r--r-- | sys/src/9/pc/l.s | 6 | ||||
-rw-r--r-- | sys/src/9/pc/main.c | 14 | ||||
-rw-r--r-- | sys/src/9/pc64/l.s | 2 | ||||
-rw-r--r-- | sys/src/9/pc64/main.c | 18 |
7 files changed, 39 insertions, 8 deletions
diff --git a/sys/src/9/pc/devarch.c b/sys/src/9/pc/devarch.c index 4c1ecb691..71c59ffff 100644 --- a/sys/src/9/pc/devarch.c +++ b/sys/src/9/pc/devarch.c @@ -41,6 +41,7 @@ enum { enum { CR4Osfxsr = 1 << 9, + CR4Oxmmex = 1 << 10, }; enum { /* cpuid standard function codes */ @@ -860,7 +861,7 @@ cpuidentify(void) if(m->cpuiddx & Fxsr){ /* have sse fp? */ fpsave = fpssesave; fprestore = fpsserestore; - putcr4(getcr4() | CR4Osfxsr); + putcr4(getcr4() | CR4Osfxsr|CR4Oxmmex); } else { fpsave = fpx87save; fprestore = fpx87restore; diff --git a/sys/src/9/pc/fns.h b/sys/src/9/pc/fns.h index 8ed2e8566..c3bd2e58c 100644 --- a/sys/src/9/pc/fns.h +++ b/sys/src/9/pc/fns.h @@ -94,6 +94,7 @@ void* kaddr(ulong); void kbdenable(void); void kbdinit(void); #define kmapinval() +void ldmxcsr(ulong); void lgdt(ushort[3]); void lldt(ulong); void lidt(ushort[3]); diff --git a/sys/src/9/pc/io.h b/sys/src/9/pc/io.h index 17ccee519..754085cf7 100644 --- a/sys/src/9/pc/io.h +++ b/sys/src/9/pc/io.h @@ -15,6 +15,9 @@ enum { VectorPF = 14, /* page fault */ Vector15 = 15, /* reserved */ VectorCERR = 16, /* coprocessor error */ + VectorAC = 17, /* alignment check */ + VectorMC = 18, /* machine check */ + VectorSIMD = 19, /* simd error */ VectorPIC = 32, /* external i8259 interrupts */ IrqCLOCK = 0, diff --git a/sys/src/9/pc/l.s b/sys/src/9/pc/l.s index 3a6eab1d0..e4e8de195 100644 --- a/sys/src/9/pc/l.s +++ b/sys/src/9/pc/l.s @@ -645,6 +645,10 @@ TEXT fpsserestore0(SB), $0 /* enable and restore state */ WAIT RET +TEXT ldmxcsr(SB), $0 /* Load MXCSR */ + LDMXCSR mxcsr+0(FP) + RET + /* */ TEXT splhi(SB), $0 @@ -983,7 +987,7 @@ TEXT vectortable(SB), $0 CALL _strayintr(SB); BYTE $0x10 /* coprocessor error */ CALL _strayintrx(SB); BYTE $0x11 /* alignment 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 $0x15 CALL _strayintr(SB); BYTE $0x16 diff --git a/sys/src/9/pc/main.c b/sys/src/9/pc/main.c index c947bb816..2aac28073 100644 --- a/sys/src/9/pc/main.c +++ b/sys/src/9/pc/main.c @@ -732,6 +732,17 @@ matherror(Ureg*, void*) } /* + * 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 */ static void @@ -747,6 +758,8 @@ mathemu(Ureg *ureg, void*) switch(up->fpstate){ case FPinit: fpinit(); + if(fpsave == fpssesave) + ldmxcsr(0); /* no simd exceptions on 386 */ up->fpstate = FPactive; break; case FPinactive: @@ -790,6 +803,7 @@ mathinit(void) intrenable(IrqIRQ13, matherror, 0, BUSUNKNOWN, "matherror"); trapenable(VectorCNA, mathemu, 0, "mathemu"); trapenable(VectorCSO, mathover, 0, "mathover"); + trapenable(VectorSIMD, simderror, 0, "simderror"); } /* diff --git a/sys/src/9/pc64/l.s b/sys/src/9/pc64/l.s index a1c17aa91..c050940c2 100644 --- a/sys/src/9/pc64/l.s +++ b/sys/src/9/pc64/l.s @@ -892,7 +892,7 @@ TEXT vectortable(SB), $0 CALL _strayintr(SB); BYTE $0x10 /* coprocessor error */ CALL _strayintrx(SB); BYTE $0x11 /* alignment 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 $0x15 CALL _strayintr(SB); BYTE $0x16 diff --git a/sys/src/9/pc64/main.c b/sys/src/9/pc64/main.c index 75b835c36..0464bad6b 100644 --- a/sys/src/9/pc64/main.c +++ b/sys/src/9/pc64/main.c @@ -732,6 +732,17 @@ matherror(Ureg*, void*) } /* + * 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 */ static void @@ -758,11 +769,7 @@ mathemu(Ureg *ureg, void*) _fninit(); _fwait(); _fldcw(0x0232); - /* - * TODO: sse exceptions - * _ldmxcsr(m->mxcsr); - * - */ + _ldmxcsr(0x1900); up->fpstate = FPactive; break; case FPinactive: @@ -806,6 +813,7 @@ mathinit(void) intrenable(IrqIRQ13, matherror, 0, BUSUNKNOWN, "matherror"); trapenable(VectorCNA, mathemu, 0, "mathemu"); trapenable(VectorCSO, mathover, 0, "mathover"); + trapenable(VectorSIMD, simderror, 0, "simderror"); } void |