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:
parent
9edc34f864
commit
a8346a9865
@ -102,10 +102,11 @@ SYSCTL_INT(_hw, HW_FLOATINGPT, floatingpoint, CTLFLAG_RD,
|
|||||||
NULL, 1, "Floating point instructions executed in hardware");
|
NULL, 1, "Floating point instructions executed in hardware");
|
||||||
|
|
||||||
static struct savefpu fpu_cleanstate;
|
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
|
void
|
||||||
fpuinit(void)
|
fpuinit(void)
|
||||||
@ -115,22 +116,22 @@ fpuinit(void)
|
|||||||
u_short control;
|
u_short control;
|
||||||
|
|
||||||
savecrit = intr_disable();
|
savecrit = intr_disable();
|
||||||
PCPU_SET(fpcurthread, 0);
|
|
||||||
stop_emulating();
|
stop_emulating();
|
||||||
fninit();
|
fninit();
|
||||||
control = __INITIAL_FPUCW__;
|
control = __INITIAL_FPUCW__;
|
||||||
fldcw(&control);
|
fldcw(&control);
|
||||||
mxcsr = __INITIAL_MXCSR__;
|
mxcsr = __INITIAL_MXCSR__;
|
||||||
ldmxcsr(mxcsr);
|
ldmxcsr(mxcsr);
|
||||||
fxsave(&fpu_cleanstate);
|
if (PCPU_GET(cpuid) == 0) {
|
||||||
if (fpu_cleanstate.sv_env.en_mxcsr_mask)
|
fxsave(&fpu_cleanstate);
|
||||||
cpu_mxcsr_mask = fpu_cleanstate.sv_env.en_mxcsr_mask;
|
if (fpu_cleanstate.sv_env.en_mxcsr_mask)
|
||||||
else
|
cpu_mxcsr_mask = fpu_cleanstate.sv_env.en_mxcsr_mask;
|
||||||
cpu_mxcsr_mask = 0xFFBF;
|
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();
|
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);
|
intr_restore(savecrit);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -384,8 +385,8 @@ fputrap()
|
|||||||
|
|
||||||
static int err_count = 0;
|
static int err_count = 0;
|
||||||
|
|
||||||
int
|
void
|
||||||
fpudna()
|
fpudna(void)
|
||||||
{
|
{
|
||||||
struct pcb *pcb;
|
struct pcb *pcb;
|
||||||
register_t s;
|
register_t s;
|
||||||
@ -395,7 +396,7 @@ fpudna()
|
|||||||
printf("fpudna: fpcurthread == curthread %d times\n",
|
printf("fpudna: fpcurthread == curthread %d times\n",
|
||||||
++err_count);
|
++err_count);
|
||||||
stop_emulating();
|
stop_emulating();
|
||||||
return (1);
|
return;
|
||||||
}
|
}
|
||||||
if (PCPU_GET(fpcurthread) != NULL) {
|
if (PCPU_GET(fpcurthread) != NULL) {
|
||||||
printf("fpudna: fpcurthread = %p (%d), curthread = %p (%d)\n",
|
printf("fpudna: fpcurthread = %p (%d), curthread = %p (%d)\n",
|
||||||
@ -428,8 +429,6 @@ fpudna()
|
|||||||
} else
|
} else
|
||||||
fxrstor(&pcb->pcb_save);
|
fxrstor(&pcb->pcb_save);
|
||||||
intr_restore(s);
|
intr_restore(s);
|
||||||
|
|
||||||
return (1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -457,10 +456,7 @@ fpugetregs(struct thread *td, struct savefpu *addr)
|
|||||||
register_t s;
|
register_t s;
|
||||||
|
|
||||||
if ((td->td_pcb->pcb_flags & PCB_FPUINITDONE) == 0) {
|
if ((td->td_pcb->pcb_flags & PCB_FPUINITDONE) == 0) {
|
||||||
if (fpu_cleanstate_ready)
|
bcopy(&fpu_cleanstate, addr, sizeof(fpu_cleanstate));
|
||||||
bcopy(&fpu_cleanstate, addr, sizeof(fpu_cleanstate));
|
|
||||||
else
|
|
||||||
bzero(addr, sizeof(*addr));
|
|
||||||
return (_MC_FPOWNED_NONE);
|
return (_MC_FPOWNED_NONE);
|
||||||
}
|
}
|
||||||
s = intr_disable();
|
s = intr_disable();
|
||||||
|
@ -416,13 +416,8 @@ trap(struct trapframe *frame)
|
|||||||
|
|
||||||
case T_DNA:
|
case T_DNA:
|
||||||
/* transparent fault (due to context switch "late") */
|
/* transparent fault (due to context switch "late") */
|
||||||
if (fpudna())
|
fpudna();
|
||||||
goto userout;
|
goto userout;
|
||||||
printf("pid %d killed due to lack of floating point\n",
|
|
||||||
p->p_pid);
|
|
||||||
i = SIGKILL;
|
|
||||||
ucode = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case T_FPOPFLT: /* FPU operand fetch fault */
|
case T_FPOPFLT: /* FPU operand fetch fault */
|
||||||
ucode = ILL_COPROC;
|
ucode = ILL_COPROC;
|
||||||
@ -450,11 +445,9 @@ trap(struct trapframe *frame)
|
|||||||
* XXX this should be fatal unless the kernel has
|
* XXX this should be fatal unless the kernel has
|
||||||
* registered such use.
|
* registered such use.
|
||||||
*/
|
*/
|
||||||
if (fpudna()) {
|
fpudna();
|
||||||
printf("fpudna in kernel mode!\n");
|
printf("fpudna in kernel mode!\n");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case T_STKFLT: /* stack fault */
|
case T_STKFLT: /* stack fault */
|
||||||
break;
|
break;
|
||||||
|
@ -97,7 +97,7 @@ struct savefpu {
|
|||||||
#define __INITIAL_MXCSR_MASK__ 0xFFBF
|
#define __INITIAL_MXCSR_MASK__ 0xFFBF
|
||||||
|
|
||||||
#ifdef _KERNEL
|
#ifdef _KERNEL
|
||||||
int fpudna(void);
|
void fpudna(void);
|
||||||
void fpudrop(void);
|
void fpudrop(void);
|
||||||
void fpuexit(struct thread *td);
|
void fpuexit(struct thread *td);
|
||||||
int fpuformat(void);
|
int fpuformat(void);
|
||||||
|
Loading…
Reference in New Issue
Block a user