summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordas <das@FreeBSD.org>2005-03-17 22:21:36 +0000
committerdas <das@FreeBSD.org>2005-03-17 22:21:36 +0000
commit148ae38eee2646f9d2d22da1a63f0b571335fc28 (patch)
tree02d672fc466df122f7cc51b42bad867abbacc25b
parent8435db4dc6c0ca01c1b393e6d924363df25ca227 (diff)
downloadFreeBSD-src-148ae38eee2646f9d2d22da1a63f0b571335fc28.zip
FreeBSD-src-148ae38eee2646f9d2d22da1a63f0b571335fc28.tar.gz
Initialize the mxcsr properly, so the initial value in a process isn't
just the value that was left over from some other application.
-rw-r--r--sys/i386/include/npx.h1
-rw-r--r--sys/i386/isa/npx.c10
2 files changed, 11 insertions, 0 deletions
diff --git a/sys/i386/include/npx.h b/sys/i386/include/npx.h
index 27e5dd7..484061e 100644
--- a/sys/i386/include/npx.h
+++ b/sys/i386/include/npx.h
@@ -134,6 +134,7 @@ union savefpu {
* intermediate values are stored in memory or in FPU registers.
*/
#define __INITIAL_NPXCW__ 0x127F
+#define __INITIAL_MXCSR__ 0x1F80
#ifdef _KERNEL
int npxdna(void);
diff --git a/sys/i386/isa/npx.c b/sys/i386/isa/npx.c
index 50241b6..9e65106 100644
--- a/sys/i386/isa/npx.c
+++ b/sys/i386/isa/npx.c
@@ -108,6 +108,7 @@ __FBSDID("$FreeBSD$");
#ifdef CPU_ENABLE_SSE
#define fxrstor(addr) __asm("fxrstor %0" : : "m" (*(addr)))
#define fxsave(addr) __asm __volatile("fxsave %0" : "=m" (*(addr)))
+#define ldmxcsr(__csr) __asm __volatile("ldmxcsr %0" : : "m" (__csr))
#endif
#define start_emulating() __asm("smsw %%ax; orb %0,%%al; lmsw %%ax" \
: : "n" (CR0_TS) : "ax")
@@ -754,6 +755,9 @@ npxdna()
{
struct pcb *pcb;
register_t s;
+#ifdef CPU_ENABLE_SSE
+ int mxcsr;
+#endif
u_short control;
if (!npx_exists)
@@ -788,6 +792,12 @@ npxdna()
fninit();
control = __INITIAL_NPXCW__;
fldcw(&control);
+#ifdef CPU_ENABLE_SSE
+ if (cpu_fxsr) {
+ mxcsr = __INITIAL_MXCSR__;
+ ldmxcsr(mxcsr);
+ }
+#endif
pcb->pcb_flags |= PCB_NPXINITDONE;
} else {
/*
OpenPOWER on IntegriCloud