npx.c (67365) | npx.c (70861) |
---|---|
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 67365 2000-10-20 07:58:15Z jhb $ | 35 * $FreeBSD: head/sys/i386/isa/npx.c 70861 2001-01-10 04:43:51Z jake $ |
36 */ 37 38#include "opt_debug_npx.h" 39#include "opt_math_emulate.h" 40 41#include <sys/param.h> 42#include <sys/systm.h> 43#include <sys/bus.h> --- 444 unchanged lines hidden (view full) --- 488 /* 489 * fninit has the same h/w bugs as fnsave. Use the detoxified 490 * fnsave to throw away any junk in the fpu. npxsave() initializes 491 * the fpu and sets npxproc = NULL as important side effects. 492 */ 493 npxsave(&dummy); 494 stop_emulating(); 495 fldcw(&control); | 36 */ 37 38#include "opt_debug_npx.h" 39#include "opt_math_emulate.h" 40 41#include <sys/param.h> 42#include <sys/systm.h> 43#include <sys/bus.h> --- 444 unchanged lines hidden (view full) --- 488 /* 489 * fninit has the same h/w bugs as fnsave. Use the detoxified 490 * fnsave to throw away any junk in the fpu. npxsave() initializes 491 * the fpu and sets npxproc = NULL as important side effects. 492 */ 493 npxsave(&dummy); 494 stop_emulating(); 495 fldcw(&control); |
496 if (curpcb != NULL) 497 fnsave(&curpcb->pcb_savefpu); | 496 if (PCPU_GET(curpcb) != NULL) 497 fnsave(&PCPU_GET(curpcb)->pcb_savefpu); |
498 start_emulating(); 499} 500 501/* 502 * Free coprocessor (if we have it). 503 */ 504void 505npxexit(p) 506 struct proc *p; 507{ 508 | 498 start_emulating(); 499} 500 501/* 502 * Free coprocessor (if we have it). 503 */ 504void 505npxexit(p) 506 struct proc *p; 507{ 508 |
509 if (p == npxproc) 510 npxsave(&curpcb->pcb_savefpu); | 509 if (p == PCPU_GET(npxproc)) 510 npxsave(&PCPU_GET(curpcb)->pcb_savefpu); |
511#ifdef NPX_DEBUG 512 if (npx_exists) { 513 u_int masked_exceptions; 514 | 511#ifdef NPX_DEBUG 512 if (npx_exists) { 513 u_int masked_exceptions; 514 |
515 masked_exceptions = curpcb->pcb_savefpu.sv_env.en_cw 516 & curpcb->pcb_savefpu.sv_env.en_sw & 0x7f; | 515 masked_exceptions = PCPU_GET(curpcb)->pcb_savefpu.sv_env.en_cw 516 &PCPU_GET(curpcb)->pcb_savefpu.sv_env.en_sw & 0x7f; |
517 /* 518 * Log exceptions that would have trapped with the old 519 * control word (overflow, divide by 0, and invalid operand). 520 */ 521 if (masked_exceptions & 0x0d) 522 log(LOG_ERR, 523 "pid %d (%s) exited with masked floating point exceptions 0x%02x\n", 524 p->p_pid, p->p_comm, masked_exceptions); --- 192 unchanged lines hidden (view full) --- 717void 718npx_intr(dummy) 719 void *dummy; 720{ 721 int code; 722 u_short control; 723 struct intrframe *frame; 724 | 517 /* 518 * Log exceptions that would have trapped with the old 519 * control word (overflow, divide by 0, and invalid operand). 520 */ 521 if (masked_exceptions & 0x0d) 522 log(LOG_ERR, 523 "pid %d (%s) exited with masked floating point exceptions 0x%02x\n", 524 p->p_pid, p->p_comm, masked_exceptions); --- 192 unchanged lines hidden (view full) --- 717void 718npx_intr(dummy) 719 void *dummy; 720{ 721 int code; 722 u_short control; 723 struct intrframe *frame; 724 |
725 if (npxproc == NULL || !npx_exists) { | 725 if (PCPU_GET(npxproc) == NULL || !npx_exists) { |
726 printf("npxintr: npxproc = %p, curproc = %p, npx_exists = %d\n", | 726 printf("npxintr: npxproc = %p, curproc = %p, npx_exists = %d\n", |
727 npxproc, curproc, npx_exists); | 727 PCPU_GET(npxproc), curproc, npx_exists); |
728 panic("npxintr from nowhere"); 729 } | 728 panic("npxintr from nowhere"); 729 } |
730 if (npxproc != curproc) { | 730 if (PCPU_GET(npxproc) != curproc) { |
731 printf("npxintr: npxproc = %p, curproc = %p, npx_exists = %d\n", | 731 printf("npxintr: npxproc = %p, curproc = %p, npx_exists = %d\n", |
732 npxproc, curproc, npx_exists); | 732 PCPU_GET(npxproc), curproc, npx_exists); |
733 panic("npxintr from non-current process"); 734 } 735 736 outb(0xf0, 0); | 733 panic("npxintr from non-current process"); 734 } 735 736 outb(0xf0, 0); |
737 fnstsw(&curpcb->pcb_savefpu.sv_ex_sw); | 737 fnstsw(&PCPU_GET(curpcb)->pcb_savefpu.sv_ex_sw); |
738 fnstcw(&control); 739 fnclex(); 740 741 /* 742 * Pass exception to process. 743 */ 744 frame = (struct intrframe *)&dummy; /* XXX */ 745 if ((ISPL(frame->if_cs) == SEL_UPL) || (frame->if_eflags & PSL_VM)) { --- 9 unchanged lines hidden (view full) --- 755 * just before it is used). 756 */ 757 curproc->p_md.md_regs = INTR_TO_TRAPFRAME(frame); 758 /* 759 * Encode the appropriate code for detailed information on 760 * this exception. 761 */ 762 code = | 738 fnstcw(&control); 739 fnclex(); 740 741 /* 742 * Pass exception to process. 743 */ 744 frame = (struct intrframe *)&dummy; /* XXX */ 745 if ((ISPL(frame->if_cs) == SEL_UPL) || (frame->if_eflags & PSL_VM)) { --- 9 unchanged lines hidden (view full) --- 755 * just before it is used). 756 */ 757 curproc->p_md.md_regs = INTR_TO_TRAPFRAME(frame); 758 /* 759 * Encode the appropriate code for detailed information on 760 * this exception. 761 */ 762 code = |
763 fpetable[(curpcb->pcb_savefpu.sv_ex_sw & ~control & 0x3f) | 764 (curpcb->pcb_savefpu.sv_ex_sw & 0x40)]; | 763 fpetable[(PCPU_GET(curpcb)->pcb_savefpu.sv_ex_sw & ~control & 0x3f) | 764 (PCPU_GET(curpcb)->pcb_savefpu.sv_ex_sw & 0x40)]; |
765 trapsignal(curproc, SIGFPE, code); 766 } else { 767 /* 768 * Nested interrupt. These losers occur when: 769 * o an IRQ13 is bogusly generated at a bogus time, e.g.: 770 * o immediately after an fnsave or frstor of an 771 * error state. 772 * o a couple of 386 instructions after --- 16 unchanged lines hidden (view full) --- 789 * and not necessarily for every context switch, but it is too hard to 790 * access foreign pcb's. 791 */ 792int 793npxdna() 794{ 795 if (!npx_exists) 796 return (0); | 765 trapsignal(curproc, SIGFPE, code); 766 } else { 767 /* 768 * Nested interrupt. These losers occur when: 769 * o an IRQ13 is bogusly generated at a bogus time, e.g.: 770 * o immediately after an fnsave or frstor of an 771 * error state. 772 * o a couple of 386 instructions after --- 16 unchanged lines hidden (view full) --- 789 * and not necessarily for every context switch, but it is too hard to 790 * access foreign pcb's. 791 */ 792int 793npxdna() 794{ 795 if (!npx_exists) 796 return (0); |
797 if (npxproc != NULL) { | 797 if (PCPU_GET(npxproc) != NULL) { |
798 printf("npxdna: npxproc = %p, curproc = %p\n", | 798 printf("npxdna: npxproc = %p, curproc = %p\n", |
799 npxproc, curproc); | 799 PCPU_GET(npxproc), curproc); |
800 panic("npxdna"); 801 } 802 stop_emulating(); 803 /* 804 * Record new context early in case frstor causes an IRQ13. 805 */ 806 PCPU_SET(npxproc, CURPROC); | 800 panic("npxdna"); 801 } 802 stop_emulating(); 803 /* 804 * Record new context early in case frstor causes an IRQ13. 805 */ 806 PCPU_SET(npxproc, CURPROC); |
807 curpcb->pcb_savefpu.sv_ex_sw = 0; | 807 PCPU_GET(curpcb)->pcb_savefpu.sv_ex_sw = 0; |
808 /* 809 * The following frstor may cause an IRQ13 when the state being 810 * restored has a pending error. The error will appear to have been 811 * triggered by the current (npx) user instruction even when that 812 * instruction is a no-wait instruction that should not trigger an 813 * error (e.g., fnclex). On at least one 486 system all of the 814 * no-wait instructions are broken the same as frstor, so our 815 * treatment does not amplify the breakage. On at least one 816 * 386/Cyrix 387 system, fnclex works correctly while frstor and 817 * fnsave are broken, so our treatment breaks fnclex if it is the 818 * first FPU instruction after a context switch. 819 */ | 808 /* 809 * The following frstor may cause an IRQ13 when the state being 810 * restored has a pending error. The error will appear to have been 811 * triggered by the current (npx) user instruction even when that 812 * instruction is a no-wait instruction that should not trigger an 813 * error (e.g., fnclex). On at least one 486 system all of the 814 * no-wait instructions are broken the same as frstor, so our 815 * treatment does not amplify the breakage. On at least one 816 * 386/Cyrix 387 system, fnclex works correctly while frstor and 817 * fnsave are broken, so our treatment breaks fnclex if it is the 818 * first FPU instruction after a context switch. 819 */ |
820 frstor(&curpcb->pcb_savefpu); | 820 frstor(&PCPU_GET(curpcb)->pcb_savefpu); |
821 822 return (1); 823} 824 825/* 826 * Wrapper for fnsave instruction to handle h/w bugs. If there is an error 827 * pending, then fnsave generates a bogus IRQ13 on some systems. Force 828 * any IRQ13 to be handled immediately, and then ignore it. This routine is --- 156 unchanged lines hidden --- | 821 822 return (1); 823} 824 825/* 826 * Wrapper for fnsave instruction to handle h/w bugs. If there is an error 827 * pending, then fnsave generates a bogus IRQ13 on some systems. Force 828 * any IRQ13 to be handled immediately, and then ignore it. This routine is --- 156 unchanged lines hidden --- |