svn commit: r189418 - in head/sys/i386: i386 include isa
John Baldwin
jhb at FreeBSD.org
Thu Mar 5 10:32:44 PST 2009
Author: jhb
Date: Thu Mar 5 18:32:43 2009
New Revision: 189418
URL: http://svn.freebsd.org/changeset/base/189418
Log:
Some cleanups to the i386 FPU support:
- Remove the control word parameter to npxinit(). It was always set
to __INITIAL_NPXCW__.
- Remove npx_cleanstate_ready as the cleanstate is always initalized
when it is used.
- Improve the handling of the case when the FPU isn't present. Now
the npx0 device no longer succeeds in its probe so all of npx_attach()
is skipped. Also, we allow this case with SMP (though that shouldn't
actually occur as all i386 systems that support SMP have FPUs) now.
SMP was only an issue back when we had an FPU emulator which was not
per-CPU.
- MFamd64: Clear some of the state in npx_cleanstate rather than leaving
it as garbage.
- MFamd64: When a user thread first uses the FPU, use npx_cleanstate for
the initial FPU state.
Reviewed by: bde
Modified:
head/sys/i386/i386/mp_machdep.c
head/sys/i386/include/npx.h
head/sys/i386/isa/npx.c
Modified: head/sys/i386/i386/mp_machdep.c
==============================================================================
--- head/sys/i386/i386/mp_machdep.c Thu Mar 5 18:30:50 2009 (r189417)
+++ head/sys/i386/i386/mp_machdep.c Thu Mar 5 18:32:43 2009 (r189418)
@@ -575,7 +575,7 @@ init_secondary(void)
cpu_setregs();
/* set up FPU state on the AP */
- npxinit(__INITIAL_NPXCW__);
+ npxinit();
/* set up SSE registers */
enable_sse();
Modified: head/sys/i386/include/npx.h
==============================================================================
--- head/sys/i386/include/npx.h Thu Mar 5 18:30:50 2009 (r189417)
+++ head/sys/i386/include/npx.h Thu Mar 5 18:32:43 2009 (r189418)
@@ -151,7 +151,7 @@ void npxdrop(void);
void npxexit(struct thread *td);
int npxformat(void);
int npxgetregs(struct thread *td, union savefpu *addr);
-void npxinit(u_short control);
+void npxinit(void);
void npxsave(union savefpu *addr);
void npxsetregs(struct thread *td, union savefpu *addr);
int npxtrap(void);
Modified: head/sys/i386/isa/npx.c
==============================================================================
--- head/sys/i386/isa/npx.c Thu Mar 5 18:30:50 2009 (r189417)
+++ head/sys/i386/isa/npx.c Thu Mar 5 18:32:43 2009 (r189418)
@@ -174,7 +174,6 @@ static volatile u_int npx_intrs_while_p
static volatile u_int npx_traps_while_probing;
static union savefpu npx_cleanstate;
-static bool_t npx_cleanstate_ready;
static bool_t npx_ex16;
static bool_t npx_exists;
static bool_t npx_irq13;
@@ -376,19 +375,14 @@ npx_probe(dev)
return (0);
}
/*
- * Worse, even IRQ13 is broken. Use emulator.
+ * Worse, even IRQ13 is broken.
*/
}
}
- /*
- * Probe failed, but we want to get to npxattach to initialize the
- * emulator and say that it has been installed. XXX handle devices
- * that aren't really devices better.
- */
-#ifdef SMP
- if (mp_ncpus > 1)
- panic("npx0 cannot be emulated on an SMP system");
-#endif
+
+ /* Probe failed. Floating point simply won't work. */
+ device_printf(dev, "WARNING: no FPU!\n");
+
/* FALLTHROUGH */
no_irq13:
idt[IDT_MF] = save_idt_npxtrap;
@@ -397,7 +391,7 @@ no_irq13:
bus_release_resource(dev, SYS_RES_IRQ, irq_rid, irq_res);
}
bus_release_resource(dev, SYS_RES_IOPORT, ioport_rid, ioport_res);
- return (0);
+ return (npx_exists ? 0 : ENXIO);
}
/*
@@ -414,32 +408,34 @@ npx_attach(dev)
if (npx_irq13)
device_printf(dev, "IRQ 13 interface\n");
- else if (!npx_ex16)
- device_printf(dev, "WARNING: no FPU!\n");
else if (!device_is_quiet(dev) || bootverbose)
device_printf(dev, "INT 16 interface\n");
- npxinit(__INITIAL_NPXCW__);
+ npxinit();
- if (npx_cleanstate_ready == 0) {
- s = intr_disable();
- stop_emulating();
- fpusave(&npx_cleanstate);
- start_emulating();
+ s = intr_disable();
+ stop_emulating();
+ fpusave(&npx_cleanstate);
+ start_emulating();
#ifdef CPU_ENABLE_SSE
- if (cpu_fxsr) {
- if (npx_cleanstate.sv_xmm.sv_env.en_mxcsr_mask)
- cpu_mxcsr_mask =
- npx_cleanstate.sv_xmm.sv_env.en_mxcsr_mask;
- else
- cpu_mxcsr_mask = 0xFFBF;
- }
+ if (cpu_fxsr) {
+ if (npx_cleanstate.sv_xmm.sv_env.en_mxcsr_mask)
+ cpu_mxcsr_mask =
+ npx_cleanstate.sv_xmm.sv_env.en_mxcsr_mask;
+ else
+ cpu_mxcsr_mask = 0xFFBF;
+ bzero(npx_cleanstate.sv_xmm.sv_fp,
+ sizeof(npx_cleanstate.sv_xmm.sv_fp));
+ bzero(npx_cleanstate.sv_xmm.sv_xmm,
+ sizeof(npx_cleanstate.sv_xmm.sv_xmm));
+ /* XXX might need even more zeroing. */
+ } else
#endif
- npx_cleanstate_ready = 1;
- intr_restore(s);
- }
+ bzero(npx_cleanstate.sv_87.sv_ac,
+ sizeof(npx_cleanstate.sv_87.sv_ac));
+ intr_restore(s);
#ifdef I586_CPU_XXX
- if (cpu_class == CPUCLASS_586 && npx_ex16 && npx_exists &&
+ if (cpu_class == CPUCLASS_586 && npx_ex16 &&
timezero("i586_bzero()", i586_bzero) <
timezero("bzero()", bzero) * 4 / 5) {
if (!(flags & NPX_DISABLE_I586_OPTIMIZED_BCOPY))
@@ -460,10 +456,11 @@ npx_attach(dev)
* Initialize floating point unit.
*/
void
-npxinit(u_short control)
+npxinit(void)
{
static union savefpu dummy;
register_t savecrit;
+ u_short control;
if (!npx_exists)
return;
@@ -480,6 +477,7 @@ npxinit(u_short control)
if (cpu_fxsr)
fninit();
#endif
+ control = __INITIAL_NPXCW__;
fldcw(&control);
start_emulating();
intr_restore(savecrit);
@@ -760,14 +758,10 @@ npxtrap()
static int err_count = 0;
int
-npxdna()
+npxdna(void)
{
struct pcb *pcb;
register_t s;
-#ifdef CPU_ENABLE_SSE
- int mxcsr;
-#endif
- u_short control;
if (!npx_exists)
return (0);
@@ -796,17 +790,9 @@ npxdna()
/*
* This is the first time this thread has used the FPU or
* the PCB doesn't contain a clean FPU state. Explicitly
- * initialize the FPU and load the default control word.
+ * load sanitized registers.
*/
- fninit();
- control = __INITIAL_NPXCW__;
- fldcw(&control);
-#ifdef CPU_ENABLE_SSE
- if (cpu_fxsr) {
- mxcsr = __INITIAL_MXCSR__;
- ldmxcsr(mxcsr);
- }
-#endif
+ fpurstor(&npx_cleanstate);
pcb->pcb_flags |= PCB_NPXINITDONE;
} else {
/*
@@ -904,10 +890,7 @@ npxgetregs(td, addr)
return (_MC_FPOWNED_NONE);
if ((td->td_pcb->pcb_flags & PCB_NPXINITDONE) == 0) {
- if (npx_cleanstate_ready)
- bcopy(&npx_cleanstate, addr, sizeof(npx_cleanstate));
- else
- bzero(addr, sizeof(*addr));
+ bcopy(&npx_cleanstate, addr, sizeof(npx_cleanstate));
return (_MC_FPOWNED_NONE);
}
s = intr_disable();
More information about the svn-src-head
mailing list