ref: a9155014c064a6a58568d355194acf416ca8efe2
parent: edca217bb99f7c32413c117239d12acdc223e811
author: cinap_lenrek <[email protected]>
date: Sun May 11 01:59:10 EDT 2014
pc, pc64: handle sse simd exceptions
--- a/sys/src/9/pc/devarch.c
+++ b/sys/src/9/pc/devarch.c
@@ -41,6 +41,7 @@
enum {
CR4Osfxsr = 1 << 9,
+ CR4Oxmmex = 1 << 10,
};
enum { /* cpuid standard function codes */
@@ -860,7 +861,7 @@
if(m->cpuiddx & Fxsr){ /* have sse fp? */
fpsave = fpssesave;
fprestore = fpsserestore;
- putcr4(getcr4() | CR4Osfxsr);
+ putcr4(getcr4() | CR4Osfxsr|CR4Oxmmex);
} else {
fpsave = fpx87save;
fprestore = fpx87restore;
--- a/sys/src/9/pc/fns.h
+++ b/sys/src/9/pc/fns.h
@@ -94,6 +94,7 @@
void kbdenable(void);
void kbdinit(void);
#define kmapinval()
+void ldmxcsr(ulong);
void lgdt(ushort[3]);
void lldt(ulong);
void lidt(ushort[3]);
--- a/sys/src/9/pc/io.h
+++ b/sys/src/9/pc/io.h
@@ -15,6 +15,9 @@
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,
--- a/sys/src/9/pc/l.s
+++ b/sys/src/9/pc/l.s
@@ -645,6 +645,10 @@
WAIT
RET
+TEXT ldmxcsr(SB), $0 /* Load MXCSR */
+ LDMXCSR mxcsr+0(FP)
+ RET
+
/*
*/
TEXT splhi(SB), $0
@@ -983,7 +987,7 @@
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
--- a/sys/src/9/pc/main.c
+++ b/sys/src/9/pc/main.c
@@ -732,6 +732,17 @@
}
/*
+ * 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 @@
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 @@
intrenable(IrqIRQ13, matherror, 0, BUSUNKNOWN, "matherror");
trapenable(VectorCNA, mathemu, 0, "mathemu");
trapenable(VectorCSO, mathover, 0, "mathover");
+ trapenable(VectorSIMD, simderror, 0, "simderror");
}
/*
--- a/sys/src/9/pc64/l.s
+++ b/sys/src/9/pc64/l.s
@@ -892,7 +892,7 @@
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
--- a/sys/src/9/pc64/main.c
+++ b/sys/src/9/pc64/main.c
@@ -732,6 +732,17 @@
}
/*
+ * 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 @@
_fninit();
_fwait();
_fldcw(0x0232);
- /*
- * TODO: sse exceptions
- * _ldmxcsr(m->mxcsr);
- *
- */
+ _ldmxcsr(0x1900);
up->fpstate = FPactive;
break;
case FPinactive:
@@ -806,6 +813,7 @@
intrenable(IrqIRQ13, matherror, 0, BUSUNKNOWN, "matherror");
trapenable(VectorCNA, mathemu, 0, "mathemu");
trapenable(VectorCSO, mathover, 0, "mathover");
+ trapenable(VectorSIMD, simderror, 0, "simderror");
}
void