summaryrefslogtreecommitdiff
path: root/sys/src
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2014-05-11 05:59:10 +0200
committercinap_lenrek <cinap_lenrek@felloff.net>2014-05-11 05:59:10 +0200
commita9155014c064a6a58568d355194acf416ca8efe2 (patch)
tree64d9fb64d479963005e9fe3f76dea4edb6b7f128 /sys/src
parentedca217bb99f7c32413c117239d12acdc223e811 (diff)
pc, pc64: handle sse simd exceptions
Diffstat (limited to 'sys/src')
-rw-r--r--sys/src/9/pc/devarch.c3
-rw-r--r--sys/src/9/pc/fns.h1
-rw-r--r--sys/src/9/pc/io.h3
-rw-r--r--sys/src/9/pc/l.s6
-rw-r--r--sys/src/9/pc/main.c14
-rw-r--r--sys/src/9/pc64/l.s2
-rw-r--r--sys/src/9/pc64/main.c18
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