summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>2003-11-08 04:37:54 +0000
committerpeter <peter@FreeBSD.org>2003-11-08 04:37:54 +0000
commitc32b37e0ed347935853a6f7eb1b28051e1208c4a (patch)
treebf131e3d51dea5dbd452ba369d5ccf1d3a0e8cb6 /sys
parente971307a02bf6106e82a91cafe6d9e73cc8e4a69 (diff)
downloadFreeBSD-src-c32b37e0ed347935853a6f7eb1b28051e1208c4a.zip
FreeBSD-src-c32b37e0ed347935853a6f7eb1b28051e1208c4a.tar.gz
Switch from having a fpu "device" to something that is more like the
integrated part of the cpu core that it is.
Diffstat (limited to 'sys')
-rw-r--r--sys/amd64/amd64/fpu.c157
-rw-r--r--sys/amd64/amd64/machdep.c2
-rw-r--r--sys/amd64/include/fpu.h2
3 files changed, 32 insertions, 129 deletions
diff --git a/sys/amd64/amd64/fpu.c b/sys/amd64/amd64/fpu.c
index 2b6b8e1..1e4890c 100644
--- a/sys/amd64/amd64/fpu.c
+++ b/sys/amd64/amd64/fpu.c
@@ -37,8 +37,6 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#include "opt_isa.h"
-
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
@@ -66,9 +64,6 @@ __FBSDID("$FreeBSD$");
#include <machine/ucontext.h>
#include <amd64/isa/intr_machdep.h>
-#ifdef DEV_ISA
-#include <isa/isavar.h>
-#endif
/*
* Floating point support.
@@ -106,10 +101,6 @@ void stop_emulating(void);
typedef u_char bool_t;
-static int fpu_attach(device_t dev);
-static void fpu_identify(driver_t *driver, device_t parent);
-static int fpu_probe(device_t dev);
-
int hw_float = 1;
SYSCTL_INT(_hw,HW_FLOATINGPT, floatingpoint,
CTLFLAG_RD, &hw_float, 0,
@@ -119,101 +110,33 @@ static struct savefpu fpu_cleanstate;
static bool_t fpu_cleanstate_ready;
/*
- * Identify routine. Create a connection point on our parent for probing.
- */
-static void
-fpu_identify(driver_t *driver, device_t parent)
-{
- device_t child;
-
- child = BUS_ADD_CHILD(parent, 0, "fpu", 0);
- if (child == NULL)
- panic("fpu_identify");
-}
-
-/*
- * Probe routine. Initialize cr0 to give correct behaviour for [f]wait
- * whether the device exists or not (XXX should be elsewhere).
- * Modify device struct if fpu doesn't need to use interrupts.
- * Return 0 if device exists.
- */
-static int
-fpu_probe(device_t dev)
-{
-
- /*
- * Prepare to trap all ESC (i.e., FPU) instructions and all WAIT
- * instructions. We must set the CR0_MP bit and use the CR0_TS
- * bit to control the trap, because setting the CR0_EM bit does
- * not cause WAIT instructions to trap. It's important to trap
- * WAIT instructions - otherwise the "wait" variants of no-wait
- * control instructions would degenerate to the "no-wait" variants
- * after FP context switches but work correctly otherwise. It's
- * particularly important to trap WAITs when there is no FPU -
- * otherwise the "wait" variants would always degenerate.
- *
- * Try setting CR0_NE to get correct error reporting on 486DX's.
- * Setting it should fail or do nothing on lesser processors.
- */
- load_cr0(rcr0() | CR0_MP | CR0_NE);
- /*
- * But don't trap while we're probing.
- */
- stop_emulating();
- /*
- * Finish resetting the coprocessor.
- */
- fninit();
-
- device_set_desc(dev, "math processor");
- device_quiet(dev);
-
- return (0);
-}
-
-/*
- * Attach routine - announce which it is, and wire into system
- */
-static int
-fpu_attach(device_t dev)
-{
- register_t s;
-
- fpuinit(__INITIAL_FPUCW__);
-
- if (fpu_cleanstate_ready == 0) {
- s = intr_disable();
- stop_emulating();
- fxsave(&fpu_cleanstate);
- start_emulating();
- fpu_cleanstate_ready = 1;
- intr_restore(s);
- }
- return (0); /* XXX unused */
-}
-
-/*
* Initialize floating point unit.
*/
void
-fpuinit(u_short control)
+fpuinit()
{
- static struct savefpu dummy;
register_t savecrit;
+ u_short control;
/*
- * fninit has the same h/w bugs as fnsave. Use the detoxified
- * fnsave to throw away any junk in the fpu. fpusave() initializes
- * the fpu and sets fpcurthread = NULL as important side effects.
+ * fpusave() initializes the fpu and sets fpcurthread = NULL
*/
savecrit = intr_disable();
- fpusave(&dummy);
+ fpusave(&fpu_cleanstate); /* XXX borrow for now */
stop_emulating();
/* XXX fpusave() doesn't actually initialize the fpu in the SSE case. */
fninit();
+ control = __INITIAL_FPUCW__;
fldcw(&control);
start_emulating();
intr_restore(savecrit);
+
+ savecrit = intr_disable();
+ stop_emulating();
+ fxsave(&fpu_cleanstate);
+ start_emulating();
+ fpu_cleanstate_ready = 1;
+ intr_restore(savecrit);
}
/*
@@ -597,64 +520,43 @@ fpusetregs(struct thread *td, struct savefpu *addr)
curthread->td_pcb->pcb_flags |= PCB_FPUINITDONE;
}
-static device_method_t fpu_methods[] = {
- /* Device interface */
- DEVMETHOD(device_identify, fpu_identify),
- DEVMETHOD(device_probe, fpu_probe),
- DEVMETHOD(device_attach, fpu_attach),
- DEVMETHOD(device_detach, bus_generic_detach),
- DEVMETHOD(device_shutdown, bus_generic_shutdown),
- DEVMETHOD(device_suspend, bus_generic_suspend),
- DEVMETHOD(device_resume, bus_generic_resume),
-
- { 0, 0 }
-};
-
-static driver_t fpu_driver = {
- "fpu",
- fpu_methods,
- 1, /* no softc */
-};
-
-static devclass_t fpu_devclass;
-
/*
- * We prefer to attach to the root nexus so that the usual case (exception 16)
- * doesn't describe the processor as being `on isa'.
+ * This really sucks. We want the acpi version only, but it requires
+ * the isa_if.h file in order to get the definitions.
*/
-DRIVER_MODULE(fpu, nexus, fpu_driver, fpu_devclass, 0, 0);
-
+#include "opt_isa.h"
#ifdef DEV_ISA
+#include <isa/isavar.h>
/*
* This sucks up the legacy ISA support assignments from PNPBIOS/ACPI.
*/
-static struct isa_pnp_id fpuisa_ids[] = {
+static struct isa_pnp_id fpupnp_ids[] = {
{ 0x040cd041, "Legacy ISA coprocessor support" }, /* PNP0C04 */
{ 0 }
};
static int
-fpuisa_probe(device_t dev)
+fpupnp_probe(device_t dev)
{
int result;
- result = ISA_PNP_PROBE(device_get_parent(dev), dev, fpuisa_ids);
+ result = ISA_PNP_PROBE(device_get_parent(dev), dev, fpupnp_ids);
if (result <= 0)
device_quiet(dev);
return (result);
}
static int
-fpuisa_attach(device_t dev)
+fpupnp_attach(device_t dev)
{
return (0);
}
-static device_method_t fpuisa_methods[] = {
+static device_method_t fpupnp_methods[] = {
/* Device interface */
- DEVMETHOD(device_probe, fpuisa_probe),
- DEVMETHOD(device_attach, fpuisa_attach),
+ DEVMETHOD(device_probe, fpupnp_probe),
+ DEVMETHOD(device_attach, fpupnp_attach),
DEVMETHOD(device_detach, bus_generic_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD(device_suspend, bus_generic_suspend),
@@ -663,14 +565,13 @@ static device_method_t fpuisa_methods[] = {
{ 0, 0 }
};
-static driver_t fpuisa_driver = {
- "fpuisa",
- fpuisa_methods,
+static driver_t fpupnp_driver = {
+ "fpupnp",
+ fpupnp_methods,
1, /* no softc */
};
-static devclass_t fpuisa_devclass;
+static devclass_t fpupnp_devclass;
-DRIVER_MODULE(fpuisa, isa, fpuisa_driver, fpuisa_devclass, 0, 0);
-DRIVER_MODULE(fpuisa, acpi, fpuisa_driver, fpuisa_devclass, 0, 0);
-#endif /* DEV_ISA */
+DRIVER_MODULE(fpupnp, acpi, fpupnp_driver, fpupnp_devclass, 0, 0);
+#endif /* DEV_ISA */
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
index 1a81e74..8272f72 100644
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -1,4 +1,5 @@
/*-
+ * Copyright (c) 2003 Peter Wemm.
* Copyright (c) 1992 Terrence R. Lambert.
* Copyright (c) 1982, 1987, 1990 The Regents of the University of California.
* All rights reserved.
@@ -1254,6 +1255,7 @@ hammer_time(u_int64_t modulep, u_int64_t physfree)
pmap_kenter((vm_offset_t)msgbufp + off, avail_end + off);
msgbufinit(msgbufp, MSGBUF_SIZE);
+ fpuinit();
/* transfer to user mode */
diff --git a/sys/amd64/include/fpu.h b/sys/amd64/include/fpu.h
index dfe5945..7c79912 100644
--- a/sys/amd64/include/fpu.h
+++ b/sys/amd64/include/fpu.h
@@ -105,7 +105,7 @@ void fpudrop(void);
void fpuexit(struct thread *td);
int fpuformat(void);
int fpugetregs(struct thread *td, struct savefpu *addr);
-void fpuinit(u_short control);
+void fpuinit(void);
void fpusave(struct savefpu *addr);
void fpusetregs(struct thread *td, struct savefpu *addr);
int fputrap(void);
OpenPOWER on IntegriCloud