|
|
| version 1.18, 2004/05/04 12:22:46 | version 1.19, 2004/05/05 19:26:44 |
|---|---|
| Line 208 __asm(" \n\ | Line 208 __asm(" \n\ |
| * Identify routine. Create a connection point on our parent for probing. | * Identify routine. Create a connection point on our parent for probing. |
| */ | */ |
| static void | static void |
| npx_identify(driver, parent) | npx_identify(driver_t *driver, device_t parent) |
| driver_t *driver; | |
| device_t parent; | |
| { | { |
| device_t child; | device_t child; |
| Line 226 npx_identify(driver, parent) | Line 224 npx_identify(driver, parent) |
| * need to use interrupts. Return 1 if device exists. | * need to use interrupts. Return 1 if device exists. |
| */ | */ |
| static int | static int |
| npx_probe(dev) | npx_probe(device_t dev) |
| device_t dev; | |
| { | { |
| #ifdef SMP | #ifdef SMP |
| Line 278 npx_probe(dev) | Line 275 npx_probe(dev) |
| } | } |
| static int | static int |
| npx_probe1(dev) | npx_probe1(device_t dev) |
| device_t dev; | |
| { | { |
| #ifndef SMP | #ifndef SMP |
| u_short control; | u_short control; |
| Line 427 npx_probe1(dev) | Line 423 npx_probe1(dev) |
| * Attach routine - announce which it is, and wire into system | * Attach routine - announce which it is, and wire into system |
| */ | */ |
| int | int |
| npx_attach(dev) | npx_attach(device_t dev) |
| device_t dev; | |
| { | { |
| int flags; | int flags; |
| #if (defined(I586_CPU) || defined(I686_CPU)) && !defined(CPU_DISABLE_SSE) | #if (defined(I586_CPU) || defined(I686_CPU)) && !defined(CPU_DISABLE_SSE) |
| Line 523 npx_attach(dev) | Line 518 npx_attach(dev) |
| } | } |
| /* | /* |
| * Initialize floating point unit. | * Initialize the floating point unit. |
| */ | */ |
| void | void |
| npxinit(control) | npxinit(u_short control) |
| u_short control; | |
| { | { |
| static union savefpu dummy; | static union savefpu dummy; |
| Line 539 npxinit(control) | Line 533 npxinit(control) |
| * the fpu and sets npxthread = NULL as important side effects. | * the fpu and sets npxthread = NULL as important side effects. |
| */ | */ |
| npxsave(&dummy); | npxsave(&dummy); |
| crit_enter(); | |
| stop_emulating(); | stop_emulating(); |
| #ifndef CPU_DISABLE_SSE | |
| /* XXX npxsave() doesn't actually initialize the fpu in the SSE case. */ | |
| if (cpu_fxsr) | |
| fninit(); | |
| #endif | |
| fldcw(&control); | fldcw(&control); |
| fpusave(curthread->td_savefpu); | fpusave(curthread->td_savefpu); |
| mdcpu->gd_npxthread = NULL; | |
| start_emulating(); | start_emulating(); |
| crit_exit(); | |
| } | } |
| /* | /* |
| Line 556 npxinit(control) | Line 548 npxinit(control) |
| void | void |
| npxexit(struct proc *p) | npxexit(struct proc *p) |
| { | { |
| if (p->p_thread == mdcpu->gd_npxthread) | if (p->p_thread == mdcpu->gd_npxthread) |
| npxsave(curthread->td_savefpu); | npxsave(curthread->td_savefpu); |
| #ifdef NPX_DEBUG | #ifdef NPX_DEBUG |
| Line 770 static char fpetable[128] = { | Line 761 static char fpetable[128] = { |
| * should not be held on exit. | * should not be held on exit. |
| */ | */ |
| void | void |
| npx_intr(dummy) | npx_intr(void *dummy) |
| void *dummy; | |
| { | { |
| int code; | int code; |
| u_short control; | u_short control; |
| Line 844 npx_intr(dummy) | Line 834 npx_intr(dummy) |
| } | } |
| /* | /* |
| * Implement device not available (DNA) exception | * Implement the device not available (DNA) exception. gd_npxthread had |
| * | * better be NULL. Restore the current thread's FP state and set gd_npxthread |
| * It would be better to switch FP context here (if curthread != npxthread) | * to curthread. |
| * and not necessarily for every context switch, but it is too hard to | |
| * access foreign pcb's. | |
| */ | */ |
| int | int |
| npxdna() | npxdna(void) |
| { | { |
| u_long *exstat; | u_long *exstat; |
| Line 862 npxdna() | Line 850 npxdna() |
| mdcpu->gd_npxthread, curthread); | mdcpu->gd_npxthread, curthread); |
| panic("npxdna"); | panic("npxdna"); |
| } | } |
| /* | |
| * The setting of gd_npxthread and the call to fpurstor() must not | |
| * be preempted by an interrupt thread or we will take an npxdna | |
| * trap and potentially save our current fpstate (which is garbage) | |
| * and then restore the garbage rather then the originally saved | |
| * fpstate. | |
| */ | |
| crit_enter(); | crit_enter(); |
| stop_emulating(); | stop_emulating(); |
| /* | /* |
| Line 889 npxdna() | Line 884 npxdna() |
| } | } |
| /* | /* |
| * Wrapper for fnsave instruction to handle h/w bugs. If there is an error | * Wrapper for the fnsave instruction to handle h/w bugs. If there is an error |
| * pending, then fnsave generates a bogus IRQ13 on some systems. Force | * pending, then fnsave generates a bogus IRQ13 on some systems. Force |
| * any IRQ13 to be handled immediately, and then ignore it. This routine is | * any IRQ13 to be handled immediately, and then ignore it. This routine is |
| * often called at splhigh so it must not use many system services. In | * often called at splhigh so it must not use many system services. In |
| Line 900 npxdna() | Line 895 npxdna() |
| * setup for the new target thread rather then the current thread, so we | * setup for the new target thread rather then the current thread, so we |
| * cannot do anything here that depends on the *_mplock() functions as | * cannot do anything here that depends on the *_mplock() functions as |
| * we may trip over their assertions. | * we may trip over their assertions. |
| * | |
| * WARNING! When using fxsave we MUST fninit after saving the FP state. The | |
| * kernel will always assume that the FP state is 'safe' (will not cause | |
| * exceptions) for mmx/xmm use if npxthread is NULL. The kernel must still | |
| * setup a custom save area before actually using the FP unit, but it will | |
| * not bother calling fninit. This greatly improves kernel performance when | |
| * it wishes to use the FP unit. | |
| */ | */ |
| void | void |
| npxsave(addr) | npxsave(union savefpu *addr) |
| union savefpu *addr; | |
| { | { |
| #if defined(SMP) || !defined(CPU_DISABLE_SSE) | #if defined(SMP) || !defined(CPU_DISABLE_SSE) |
| crit_enter(); | |
| stop_emulating(); | stop_emulating(); |
| fpusave(addr); | fpusave(addr); |
| /* fnop(); */ | |
| mdcpu->gd_npxthread = NULL; | mdcpu->gd_npxthread = NULL; |
| fninit(); | |
| start_emulating(); | start_emulating(); |
| crit_exit(); | |
| #else /* !SMP and CPU_DISABLE_SSE */ | #else /* !SMP and CPU_DISABLE_SSE */ |
| Line 952 npxsave(addr) | Line 954 npxsave(addr) |
| } | } |
| static void | static void |
| fpusave(addr) | fpusave(union savefpu *addr) |
| union savefpu *addr; | |
| { | { |
| #ifndef CPU_DISABLE_SSE | #ifndef CPU_DISABLE_SSE |
| if (cpu_fxsr) | if (cpu_fxsr) |
| fxsave(addr); | fxsave(addr); |
| Line 965 fpusave(addr) | Line 965 fpusave(addr) |
| } | } |
| static void | static void |
| fpurstor(addr) | fpurstor(union savefpu *addr) |
| union savefpu *addr; | |
| { | { |
| #ifndef CPU_DISABLE_SSE | #ifndef CPU_DISABLE_SSE |
| if (cpu_fxsr) | if (cpu_fxsr) |
| fxrstor(addr); | fxrstor(addr); |