npx.c (87702) | npx.c (88088) |
---|---|
1/*- 2 * Copyright (c) 1990 William Jolitz. 3 * Copyright (c) 1991 The Regents of the University of California. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 18 unchanged lines hidden (view full) --- 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * 34 * from: @(#)npx.c 7.2 (Berkeley) 5/12/91 | 1/*- 2 * Copyright (c) 1990 William Jolitz. 3 * Copyright (c) 1991 The Regents of the University of California. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 18 unchanged lines hidden (view full) --- 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * 34 * from: @(#)npx.c 7.2 (Berkeley) 5/12/91 |
35 * $FreeBSD: head/sys/i386/isa/npx.c 87702 2001-12-11 23:33:44Z jhb $ | 35 * $FreeBSD: head/sys/i386/isa/npx.c 88088 2001-12-18 00:27:18Z jhb $ |
36 */ 37 38#include "opt_cpu.h" 39#include "opt_debug_npx.h" 40#include "opt_math_emulate.h" 41#include "opt_npx.h" 42 43#include <sys/param.h> --- 466 unchanged lines hidden (view full) --- 510 511 if (!npx_exists) 512 return; 513 /* 514 * fninit has the same h/w bugs as fnsave. Use the detoxified 515 * fnsave to throw away any junk in the fpu. npxsave() initializes 516 * the fpu and sets fpcurthread = NULL as important side effects. 517 */ | 36 */ 37 38#include "opt_cpu.h" 39#include "opt_debug_npx.h" 40#include "opt_math_emulate.h" 41#include "opt_npx.h" 42 43#include <sys/param.h> --- 466 unchanged lines hidden (view full) --- 510 511 if (!npx_exists) 512 return; 513 /* 514 * fninit has the same h/w bugs as fnsave. Use the detoxified 515 * fnsave to throw away any junk in the fpu. npxsave() initializes 516 * the fpu and sets fpcurthread = NULL as important side effects. 517 */ |
518 savecrit = critical_enter(); | 518 savecrit = cpu_critical_enter(); |
519 npxsave(&dummy); 520 stop_emulating(); 521#ifdef CPU_ENABLE_SSE 522 /* XXX npxsave() doesn't actually initialize the fpu in the SSE case. */ 523 if (cpu_fxsr) 524 fninit(); 525#endif 526 fldcw(&control); 527 if (PCPU_GET(curpcb) != NULL) 528 fpusave(&PCPU_GET(curpcb)->pcb_save); 529 start_emulating(); | 519 npxsave(&dummy); 520 stop_emulating(); 521#ifdef CPU_ENABLE_SSE 522 /* XXX npxsave() doesn't actually initialize the fpu in the SSE case. */ 523 if (cpu_fxsr) 524 fninit(); 525#endif 526 fldcw(&control); 527 if (PCPU_GET(curpcb) != NULL) 528 fpusave(&PCPU_GET(curpcb)->pcb_save); 529 start_emulating(); |
530 critical_exit(savecrit); | 530 cpu_critical_exit(savecrit); |
531} 532 533/* 534 * Free coprocessor (if we have it). 535 */ 536void 537npxexit(td) 538 struct thread *td; 539{ 540 critical_t savecrit; 541 | 531} 532 533/* 534 * Free coprocessor (if we have it). 535 */ 536void 537npxexit(td) 538 struct thread *td; 539{ 540 critical_t savecrit; 541 |
542 savecrit = critical_enter(); | 542 savecrit = cpu_critical_enter(); |
543 if (td == PCPU_GET(fpcurthread)) 544 npxsave(&PCPU_GET(curpcb)->pcb_save); | 543 if (td == PCPU_GET(fpcurthread)) 544 npxsave(&PCPU_GET(curpcb)->pcb_save); |
545 critical_exit(savecrit); | 545 cpu_critical_exit(savecrit); |
546#ifdef NPX_DEBUG 547 if (npx_exists) { 548 u_int masked_exceptions; 549 550 masked_exceptions = PCPU_GET(curpcb)->pcb_save.sv_87.sv_env.en_cw 551 & PCPU_GET(curpcb)->pcb_save.sv_87.sv_env.en_sw & 0x7f; 552 /* 553 * Log exceptions that would have trapped with the old --- 203 unchanged lines hidden (view full) --- 757 u_short control, status; 758 u_long *exstat; 759 760 if (!npx_exists) { 761 printf("npxtrap: fpcurthread = %p, curthread = %p, npx_exists = %d\n", 762 PCPU_GET(fpcurthread), curthread, npx_exists); 763 panic("npxtrap from nowhere"); 764 } | 546#ifdef NPX_DEBUG 547 if (npx_exists) { 548 u_int masked_exceptions; 549 550 masked_exceptions = PCPU_GET(curpcb)->pcb_save.sv_87.sv_env.en_cw 551 & PCPU_GET(curpcb)->pcb_save.sv_87.sv_env.en_sw & 0x7f; 552 /* 553 * Log exceptions that would have trapped with the old --- 203 unchanged lines hidden (view full) --- 757 u_short control, status; 758 u_long *exstat; 759 760 if (!npx_exists) { 761 printf("npxtrap: fpcurthread = %p, curthread = %p, npx_exists = %d\n", 762 PCPU_GET(fpcurthread), curthread, npx_exists); 763 panic("npxtrap from nowhere"); 764 } |
765 savecrit = critical_enter(); | 765 savecrit = cpu_critical_enter(); |
766 767 /* 768 * Interrupt handling (for another interrupt) may have pushed the 769 * state to memory. Fetch the relevant parts of the state from 770 * wherever they are. 771 */ 772 if (PCPU_GET(fpcurthread) != curthread) { 773 control = GET_FPU_CW(curthread); --- 4 unchanged lines hidden (view full) --- 778 } 779 780 exstat = GET_FPU_EXSW_PTR(curthread->td_pcb); 781 *exstat = status; 782 if (PCPU_GET(fpcurthread) != curthread) 783 GET_FPU_SW(curthread) &= ~0x80bf; 784 else 785 fnclex(); | 766 767 /* 768 * Interrupt handling (for another interrupt) may have pushed the 769 * state to memory. Fetch the relevant parts of the state from 770 * wherever they are. 771 */ 772 if (PCPU_GET(fpcurthread) != curthread) { 773 control = GET_FPU_CW(curthread); --- 4 unchanged lines hidden (view full) --- 778 } 779 780 exstat = GET_FPU_EXSW_PTR(curthread->td_pcb); 781 *exstat = status; 782 if (PCPU_GET(fpcurthread) != curthread) 783 GET_FPU_SW(curthread) &= ~0x80bf; 784 else 785 fnclex(); |
786 critical_exit(savecrit); | 786 cpu_critical_exit(savecrit); |
787 return (fpetable[status & ((~control & 0x3f) | 0x40)]); 788} 789 790/* 791 * Implement device not available (DNA) exception 792 * 793 * It would be better to switch FP context here (if curthread != fpcurthread) 794 * and not necessarily for every context switch, but it is too hard to --- 7 unchanged lines hidden (view full) --- 802 803 if (!npx_exists) 804 return (0); 805 if (PCPU_GET(fpcurthread) != NULL) { 806 printf("npxdna: fpcurthread = %p, curthread = %p\n", 807 PCPU_GET(fpcurthread), curthread); 808 panic("npxdna"); 809 } | 787 return (fpetable[status & ((~control & 0x3f) | 0x40)]); 788} 789 790/* 791 * Implement device not available (DNA) exception 792 * 793 * It would be better to switch FP context here (if curthread != fpcurthread) 794 * and not necessarily for every context switch, but it is too hard to --- 7 unchanged lines hidden (view full) --- 802 803 if (!npx_exists) 804 return (0); 805 if (PCPU_GET(fpcurthread) != NULL) { 806 printf("npxdna: fpcurthread = %p, curthread = %p\n", 807 PCPU_GET(fpcurthread), curthread); 808 panic("npxdna"); 809 } |
810 s = critical_enter(); | 810 s = cpu_critical_enter(); |
811 stop_emulating(); 812 /* 813 * Record new context early in case frstor causes an IRQ13. 814 */ 815 PCPU_SET(fpcurthread, curthread); 816 817 exstat = GET_FPU_EXSW_PTR(PCPU_GET(curpcb)); 818 *exstat = 0; --- 5 unchanged lines hidden (view full) --- 824 * error (e.g., fnclex). On at least one 486 system all of the 825 * no-wait instructions are broken the same as frstor, so our 826 * treatment does not amplify the breakage. On at least one 827 * 386/Cyrix 387 system, fnclex works correctly while frstor and 828 * fnsave are broken, so our treatment breaks fnclex if it is the 829 * first FPU instruction after a context switch. 830 */ 831 fpurstor(&PCPU_GET(curpcb)->pcb_save); | 811 stop_emulating(); 812 /* 813 * Record new context early in case frstor causes an IRQ13. 814 */ 815 PCPU_SET(fpcurthread, curthread); 816 817 exstat = GET_FPU_EXSW_PTR(PCPU_GET(curpcb)); 818 *exstat = 0; --- 5 unchanged lines hidden (view full) --- 824 * error (e.g., fnclex). On at least one 486 system all of the 825 * no-wait instructions are broken the same as frstor, so our 826 * treatment does not amplify the breakage. On at least one 827 * 386/Cyrix 387 system, fnclex works correctly while frstor and 828 * fnsave are broken, so our treatment breaks fnclex if it is the 829 * first FPU instruction after a context switch. 830 */ 831 fpurstor(&PCPU_GET(curpcb)->pcb_save); |
832 critical_exit(s); | 832 cpu_critical_exit(s); |
833 834 return (1); 835} 836 837/* 838 * Wrapper for fnsave instruction, partly to handle hardware bugs. When npx 839 * exceptions are reported via IRQ13, spurious IRQ13's may be triggered by 840 * no-wait npx instructions. See the Intel application note AP-578 for --- 163 unchanged lines hidden --- | 833 834 return (1); 835} 836 837/* 838 * Wrapper for fnsave instruction, partly to handle hardware bugs. When npx 839 * exceptions are reported via IRQ13, spurious IRQ13's may be triggered by 840 * no-wait npx instructions. See the Intel application note AP-578 for --- 163 unchanged lines hidden --- |