> jhb         2006-04-06 17:17:45 UTC
>
>   FreeBSD src repository
>
>   Modified files:
>     sys/i386/i386        machdep.c
>     sys/i386/isa         npx.c
>   Log:
>   - Don't set CR0_NE and CR0_MP in npx_probe() as they are already set
>     earlier in cpu_setregs().
>   - If we know this CPU has a FPU via cpuid, then just assume the INT16
>     interface and make the npx device quiet to not clutter the dmesg.  This
>     is true for all Pentium and later CPUs and even some of the later 486dx
>     CPUs.
>
>   Reviewed by:    bde
>   Tested by:      ps
>   MFC after:      1 week
>
>   Path				Revision
>   src/sys/i386/i386/machdep.c		1.625
>   src/sys/i386/isa/npx.c		1.164

Requested by:	jhb
Approved by:	re (scottl)
This commit is contained in:
kensmith 2006-04-30 05:15:20 +00:00
parent 6e25448c70
commit be1694875d
2 changed files with 36 additions and 27 deletions

View File

@ -1222,9 +1222,22 @@ cpu_setregs(void)
unsigned int cr0;
cr0 = rcr0();
/*
* CR0_MP, CR0_NE and CR0_TS are also set by npx_probe() for the
* BSP. See the comments there about why we set them.
* CR0_MP, CR0_NE and CR0_TS are set for NPX (FPU) support:
*
* Prepare to trap all ESC (i.e., NPX) 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 NPX -
* 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.
*/
cr0 |= CR0_MP | CR0_NE | CR0_TS | CR0_WP | CR0_AM;
load_cr0(cr0);

View File

@ -238,10 +238,8 @@ npx_intr(dummy)
}
/*
* Probe routine. Initialize cr0 to give correct behaviour for [f]wait
* whether the device exists or not (XXX should be elsewhere). Set flags
* to tell npxattach() what to do. Modify device struct if npx doesn't
* need to use interrupts. Return 0 if device exists.
* Probe routine. Set flags to tell npxattach() what to do. Set up an
* interrupt handler if npx needs to use interrupts.
*/
static int
npx_probe(dev)
@ -254,6 +252,20 @@ npx_probe(dev)
u_short control;
u_short status;
device_set_desc(dev, "math processor");
/*
* Modern CPUs all have an FPU that uses the INT16 interface
* and provide a simple way to verify that, so handle the
* common case right away.
*/
if (cpu_feature & CPUID_FPU) {
hw_float = npx_exists = 1;
npx_ex16 = 1;
device_quiet(dev);
return (0);
}
save_idt_npxtrap = idt[IDT_MF];
setidt(IDT_MF, probetrap, SDT_SYS386TGT, SEL_KPL,
GSEL(GCODE_SEL, SEL_KPL));
@ -281,24 +293,10 @@ npx_probe(dev)
outb(IO_NPX, 0);
/*
* Prepare to trap all ESC (i.e., NPX) 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 NPX -
* 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.
* Don't trap while we're probing.
*/
stop_emulating();
/*
* Finish resetting the coprocessor, if any. If there is an error
* pending, then we may get a bogus IRQ13, but npx_intr() will handle
@ -307,8 +305,6 @@ npx_probe(dev)
*/
fninit();
device_set_desc(dev, "math processor");
/*
* Don't use fwait here because it might hang.
* Don't use fnop here because it usually hangs if there is no FPU.
@ -410,10 +406,10 @@ npx_attach(dev)
if (npx_irq13)
device_printf(dev, "IRQ 13 interface\n");
else if (npx_ex16)
device_printf(dev, "INT 16 interface\n");
else
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__);