shithub: riscv

Download patch

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