Deleted Added
full compact
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 ---