diff options
author | jhb <jhb@FreeBSD.org> | 2009-03-05 16:56:16 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2009-03-05 16:56:16 +0000 |
commit | 059d33034711cd836d72958de8f1d7a5654d067f (patch) | |
tree | eb0c61351211605f31be2d4ab4e7160345e897cb /sys | |
parent | 0f16fc12d50334c0ec1c559860a07fd2c8747e0f (diff) | |
download | FreeBSD-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
Diffstat (limited to 'sys')
-rw-r--r-- | sys/amd64/amd64/fpu.c | 36 | ||||
-rw-r--r-- | sys/amd64/amd64/trap.c | 17 | ||||
-rw-r--r-- | sys/amd64/include/fpu.h | 2 |
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); |