summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2009-03-05 16:56:16 +0000
committerjhb <jhb@FreeBSD.org>2009-03-05 16:56:16 +0000
commit059d33034711cd836d72958de8f1d7a5654d067f (patch)
treeeb0c61351211605f31be2d4ab4e7160345e897cb
parent0f16fc12d50334c0ec1c559860a07fd2c8747e0f (diff)
downloadFreeBSD-src-059d33034711cd836d72958de8f1d7a5654d067f.zip
FreeBSD-src-059d33034711cd836d72958de8f1d7a5654d067f.tar.gz
A few cleanups to the FPU code on amd64:
- fpudna() always returned 1 since amd64 CPUs always have FPUs. Change the function to return void and adjust the calling code in trap() to assume the return 1 case is the only case. - Remove fpu_cleanstate_ready as it is always true when it is tested. Also, only initialize fpu_cleanstate when fpuinit() is called on the BSP. Reviewed by: bde
-rw-r--r--sys/amd64/amd64/fpu.c36
-rw-r--r--sys/amd64/amd64/trap.c17
-rw-r--r--sys/amd64/include/fpu.h2
3 files changed, 22 insertions, 33 deletions
diff --git a/sys/amd64/amd64/fpu.c b/sys/amd64/amd64/fpu.c
index 85e5ec9..111d6d8 100644
--- a/sys/amd64/amd64/fpu.c
+++ b/sys/amd64/amd64/fpu.c
@@ -102,10 +102,11 @@ SYSCTL_INT(_hw, HW_FLOATINGPT, floatingpoint, CTLFLAG_RD,
NULL, 1, "Floating point instructions executed in hardware");
static struct savefpu fpu_cleanstate;
-static bool_t fpu_cleanstate_ready;
/*
- * Initialize floating point unit.
+ * Initialize the floating point unit. On the boot CPU we generate a
+ * clean state that is used to initialize the floating point unit when
+ * it is first used by a process.
*/
void
fpuinit(void)
@@ -115,22 +116,22 @@ fpuinit(void)
u_short control;
savecrit = intr_disable();
- PCPU_SET(fpcurthread, 0);
stop_emulating();
fninit();
control = __INITIAL_FPUCW__;
fldcw(&control);
mxcsr = __INITIAL_MXCSR__;
ldmxcsr(mxcsr);
- fxsave(&fpu_cleanstate);
- if (fpu_cleanstate.sv_env.en_mxcsr_mask)
- cpu_mxcsr_mask = fpu_cleanstate.sv_env.en_mxcsr_mask;
- else
- cpu_mxcsr_mask = 0xFFBF;
+ if (PCPU_GET(cpuid) == 0) {
+ fxsave(&fpu_cleanstate);
+ if (fpu_cleanstate.sv_env.en_mxcsr_mask)
+ cpu_mxcsr_mask = fpu_cleanstate.sv_env.en_mxcsr_mask;
+ else
+ cpu_mxcsr_mask = 0xFFBF;
+ bzero(fpu_cleanstate.sv_fp, sizeof(fpu_cleanstate.sv_fp));
+ bzero(fpu_cleanstate.sv_xmm, sizeof(fpu_cleanstate.sv_xmm));
+ }
start_emulating();
- bzero(fpu_cleanstate.sv_fp, sizeof(fpu_cleanstate.sv_fp));
- bzero(fpu_cleanstate.sv_xmm, sizeof(fpu_cleanstate.sv_xmm));
- fpu_cleanstate_ready = 1;
intr_restore(savecrit);
}
@@ -384,8 +385,8 @@ fputrap()
static int err_count = 0;
-int
-fpudna()
+void
+fpudna(void)
{
struct pcb *pcb;
register_t s;
@@ -395,7 +396,7 @@ fpudna()
printf("fpudna: fpcurthread == curthread %d times\n",
++err_count);
stop_emulating();
- return (1);
+ return;
}
if (PCPU_GET(fpcurthread) != NULL) {
printf("fpudna: fpcurthread = %p (%d), curthread = %p (%d)\n",
@@ -428,8 +429,6 @@ fpudna()
} else
fxrstor(&pcb->pcb_save);
intr_restore(s);
-
- return (1);
}
/*
@@ -457,10 +456,7 @@ fpugetregs(struct thread *td, struct savefpu *addr)
register_t s;
if ((td->td_pcb->pcb_flags & PCB_FPUINITDONE) == 0) {
- if (fpu_cleanstate_ready)
- bcopy(&fpu_cleanstate, addr, sizeof(fpu_cleanstate));
- else
- bzero(addr, sizeof(*addr));
+ bcopy(&fpu_cleanstate, addr, sizeof(fpu_cleanstate));
return (_MC_FPOWNED_NONE);
}
s = intr_disable();
diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c
index 8d710cd..ccd6c39 100644
--- a/sys/amd64/amd64/trap.c
+++ b/sys/amd64/amd64/trap.c
@@ -416,13 +416,8 @@ trap(struct trapframe *frame)
case T_DNA:
/* transparent fault (due to context switch "late") */
- if (fpudna())
- goto userout;
- printf("pid %d killed due to lack of floating point\n",
- p->p_pid);
- i = SIGKILL;
- ucode = 0;
- break;
+ fpudna();
+ goto userout;
case T_FPOPFLT: /* FPU operand fetch fault */
ucode = ILL_COPROC;
@@ -450,11 +445,9 @@ trap(struct trapframe *frame)
* XXX this should be fatal unless the kernel has
* registered such use.
*/
- if (fpudna()) {
- printf("fpudna in kernel mode!\n");
- goto out;
- }
- break;
+ fpudna();
+ printf("fpudna in kernel mode!\n");
+ goto out;
case T_STKFLT: /* stack fault */
break;
diff --git a/sys/amd64/include/fpu.h b/sys/amd64/include/fpu.h
index 9b99fd8..272f94a 100644
--- a/sys/amd64/include/fpu.h
+++ b/sys/amd64/include/fpu.h
@@ -97,7 +97,7 @@ struct savefpu {
#define __INITIAL_MXCSR_MASK__ 0xFFBF
#ifdef _KERNEL
-int fpudna(void);
+void fpudna(void);
void fpudrop(void);
void fpuexit(struct thread *td);
int fpuformat(void);
OpenPOWER on IntegriCloud