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