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
This commit is contained in:
John Baldwin 2009-03-05 16:56:16 +00:00
parent 9edc34f864
commit a8346a9865
3 changed files with 22 additions and 33 deletions

View File

@ -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();

View File

@ -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;

View File

@ -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);