Author: kib
Date: Wed Jun 23 11:12:58 2010
New Revision: 209461
URL: http://svn.freebsd.org/changeset/base/209461

Log:
  Remove the support for int13 FPU exception reporting on i386. It is
  believed that all 486-class CPUs FreeBSD is capable to run on, either
  have no FPU and cannot use external coprocessor, or have FPU on the
  package and can use #MF.
  
  Reviewed by:  bde
  Tested by:    pho (previous version)

Modified:
  head/sys/i386/i386/vm_machdep.c
  head/sys/i386/include/npx.h
  head/sys/i386/include/pcb.h
  head/sys/i386/isa/npx.c
  head/sys/kern/subr_trap.c
  head/sys/pc98/include/npx.h

Modified: head/sys/i386/i386/vm_machdep.c
==============================================================================
--- head/sys/i386/i386/vm_machdep.c     Wed Jun 23 10:40:28 2010        
(r209460)
+++ head/sys/i386/i386/vm_machdep.c     Wed Jun 23 11:12:58 2010        
(r209461)
@@ -441,7 +441,7 @@ cpu_set_upcall(struct thread *td, struct
         * values here.
         */
        bcopy(td0->td_pcb, pcb2, sizeof(*pcb2));
-       pcb2->pcb_flags &= ~(PCB_NPXTRAP|PCB_NPXINITDONE|PCB_NPXUSERINITDONE);
+       pcb2->pcb_flags &= ~(PCB_NPXINITDONE | PCB_NPXUSERINITDONE);
        pcb2->pcb_save = &pcb2->pcb_user_save;
 
        /*

Modified: head/sys/i386/include/npx.h
==============================================================================
--- head/sys/i386/include/npx.h Wed Jun 23 10:40:28 2010        (r209460)
+++ head/sys/i386/include/npx.h Wed Jun 23 11:12:58 2010        (r209461)
@@ -138,11 +138,6 @@ union      savefpu {
 
 #ifdef _KERNEL
 
-#define        IO_NPX          0x0F0           /* Numeric Coprocessor */
-#define        IO_NPXSIZE      16              /* 80387/80487 NPX registers */
-
-#define        IRQ_NPX         13
-
 struct fpu_kern_ctx {
        union savefpu hwstate;
        union savefpu *prev;
@@ -152,9 +147,6 @@ struct fpu_kern_ctx {
 
 #define        PCB_USER_FPU(pcb) (((pcb)->pcb_flags & PCB_KERNNPX) == 0)
 
-/* full reset on some systems, NOP on others */
-#define npx_full_reset() outb(IO_NPX + 1, 0)
-
 int    npxdna(void);
 void   npxdrop(void);
 void   npxexit(struct thread *td);

Modified: head/sys/i386/include/pcb.h
==============================================================================
--- head/sys/i386/include/pcb.h Wed Jun 23 10:40:28 2010        (r209460)
+++ head/sys/i386/include/pcb.h Wed Jun 23 11:12:58 2010        (r209461)
@@ -65,7 +65,6 @@ struct pcb {
        u_int   pcb_flags;
 #define        FP_SOFTFP       0x01    /* process using software fltng pnt 
emulator */
 #define        PCB_DBREGS      0x02    /* process using debug registers */
-#define        PCB_NPXTRAP     0x04    /* npx trap pending */
 #define        PCB_NPXINITDONE 0x08    /* fpu state is initialized */
 #define        PCB_VM86CALL    0x10    /* in vm86 call */
 #define        PCB_NPXUSERINITDONE 0x20 /* user fpu state is initialized */

Modified: head/sys/i386/isa/npx.c
==============================================================================
--- head/sys/i386/isa/npx.c     Wed Jun 23 10:40:28 2010        (r209460)
+++ head/sys/i386/isa/npx.c     Wed Jun 23 11:12:58 2010        (r209461)
@@ -161,21 +161,15 @@ static    void    fpusave(union savefpu *);
 static void    fpurstor(union savefpu *);
 static int     npx_attach(device_t dev);
 static void    npx_identify(driver_t *driver, device_t parent);
-static int     npx_intr(void *);
 static int     npx_probe(device_t dev);
 
-int    hw_float;               /* XXX currently just alias for npx_exists */
+int    hw_float;
 
 SYSCTL_INT(_hw, HW_FLOATINGPT, floatingpoint, CTLFLAG_RD,
     &hw_float, 0, "Floating point instructions executed in hardware");
 
-static volatile u_int          npx_intrs_while_probing;
 static volatile u_int          npx_traps_while_probing;
-
 static union savefpu           npx_initialstate;
-static bool_t                  npx_ex16;
-static bool_t                  npx_exists;
-static bool_t                  npx_irq13;
 
 alias_for_inthand_t probetrap;
 __asm("                                                                \n\
@@ -205,58 +199,14 @@ npx_identify(driver, parent)
 }
 
 /*
- * Do minimal handling of npx interrupts to convert them to traps.
- */
-static int
-npx_intr(dummy)
-       void *dummy;
-{
-       struct thread *td;
-
-       npx_intrs_while_probing++;
-
-       /*
-        * The BUSY# latch must be cleared in all cases so that the next
-        * unmasked npx exception causes an interrupt.
-        */
-       outb(IO_NPX, 0);
-
-       /*
-        * fpcurthread is normally non-null here.  In that case, schedule an
-        * AST to finish the exception handling in the correct context
-        * (this interrupt may occur after the thread has entered the
-        * kernel via a syscall or an interrupt).  Otherwise, the npx
-        * state of the thread that caused this interrupt must have been
-        * pushed to the thread's pcb, and clearing of the busy latch
-        * above has finished the (essentially null) handling of this
-        * interrupt.  Control will eventually return to the instruction
-        * that caused it and it will repeat.  We will eventually (usually
-        * soon) win the race to handle the interrupt properly.
-        */
-       td = PCPU_GET(fpcurthread);
-       if (td != NULL) {
-               td->td_pcb->pcb_flags |= PCB_NPXTRAP;
-               thread_lock(td);
-               td->td_flags |= TDF_ASTPENDING;
-               thread_unlock(td);
-       }
-       return (FILTER_HANDLED);
-}
-
-/*
  * Probe routine.  Set flags to tell npxattach() what to do.  Set up an
  * interrupt handler if npx needs to use interrupts.
  */
 static int
-npx_probe(dev)
-       device_t dev;
+npx_probe(device_t dev)
 {
        struct gate_descriptor save_idt_npxtrap;
-       struct resource *ioport_res, *irq_res;
-       void *irq_cookie;
-       int ioport_rid, irq_num, irq_rid;
-       u_short control;
-       u_short status;
+       u_short control, status;
 
        device_set_desc(dev, "math processor");
 
@@ -266,8 +216,7 @@ npx_probe(dev)
         * common case right away.
         */
        if (cpu_feature & CPUID_FPU) {
-               hw_float = npx_exists = 1;
-               npx_ex16 = 1;
+               hw_float = 1;
                device_quiet(dev);
                return (0);
        }
@@ -275,28 +224,6 @@ npx_probe(dev)
        save_idt_npxtrap = idt[IDT_MF];
        setidt(IDT_MF, probetrap, SDT_SYS386TGT, SEL_KPL,
            GSEL(GCODE_SEL, SEL_KPL));
-       ioport_rid = 0;
-       ioport_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &ioport_rid,
-           IO_NPX, IO_NPX + IO_NPXSIZE - 1, IO_NPXSIZE, RF_ACTIVE);
-       if (ioport_res == NULL)
-               panic("npx: can't get ports");
-       if (resource_int_value("npx", 0, "irq", &irq_num) != 0)
-               irq_num = IRQ_NPX;
-       irq_rid = 0;
-       irq_res = bus_alloc_resource(dev, SYS_RES_IRQ, &irq_rid, irq_num,
-           irq_num, 1, RF_ACTIVE);
-       if (irq_res != NULL) {
-               if (bus_setup_intr(dev, irq_res, INTR_TYPE_MISC,
-                       npx_intr, NULL, NULL, &irq_cookie) != 0)
-                       panic("npx: can't create intr");
-       }
-
-       /*
-        * Partially reset the coprocessor, if any.  Some BIOS's don't reset
-        * it after a warm boot.
-        */
-       npx_full_reset();
-       outb(IO_NPX, 0);
 
        /*
         * Don't trap while we're probing.
@@ -317,9 +244,6 @@ npx_probe(dev)
         */
        DELAY(1000);            /* wait for any IRQ13 */
 #ifdef DIAGNOSTIC
-       if (npx_intrs_while_probing != 0)
-               printf("fninit caused %u bogus npx interrupt(s)\n",
-                      npx_intrs_while_probing);
        if (npx_traps_while_probing != 0)
                printf("fninit caused %u bogus npx trap(s)\n",
                       npx_traps_while_probing);
@@ -336,7 +260,6 @@ npx_probe(dev)
                control = 0x5a5a;
                fnstcw(&control);
                if ((control & 0x1f3f) == 0x033f) {
-                       hw_float = npx_exists = 1;
                        /*
                         * We have an npx, now divide by 0 to see if exception
                         * 16 works.
@@ -348,70 +271,46 @@ npx_probe(dev)
                         * FPU error signal doesn't work on some CPU
                         * accelerator board.
                         */
-                       npx_ex16 = 1;
+                       hw_float = 1;
                        return (0);
 #endif
-                       npx_traps_while_probing = npx_intrs_while_probing = 0;
+                       npx_traps_while_probing = 0;
                        fp_divide_by_0();
-                       DELAY(1000);    /* wait for any IRQ13 */
                        if (npx_traps_while_probing != 0) {
                                /*
                                 * Good, exception 16 works.
                                 */
-                               npx_ex16 = 1;
-                               goto no_irq13;
-                       }
-                       if (npx_intrs_while_probing != 0) {
-                               /*
-                                * Bad, we are stuck with IRQ13.
-                                */
-                               npx_irq13 = 1;
-                               idt[IDT_MF] = save_idt_npxtrap;
-#ifdef SMP
-                               if (mp_ncpus > 1)
-                                       panic("npx0 cannot use IRQ 13 on an SMP 
system");
-#endif
-                               return (0);
+                               hw_float = 1;
+                               goto cleanup;
                        }
-                       /*
-                        * Worse, even IRQ13 is broken.
-                        */
+                       device_printf(dev,
+       "FPU does not use exception 16 for error reporting\n");
+                       goto cleanup;
                }
        }
 
-       /* Probe failed.  Floating point simply won't work. */
+       /*
+        * Probe failed.  Floating point simply won't work.
+        * Notify user and disable FPU/MMX/SSE instruction execution.
+        */
        device_printf(dev, "WARNING: no FPU!\n");
+       __asm __volatile("smsw %%ax; orb %0,%%al; lmsw %%ax" : :
+           "n" (CR0_EM | CR0_MP) : "ax");
 
-       /* FALLTHROUGH */
-no_irq13:
+cleanup:
        idt[IDT_MF] = save_idt_npxtrap;
-       if (irq_res != NULL) {
-               bus_teardown_intr(dev, irq_res, irq_cookie);
-               bus_release_resource(dev, SYS_RES_IRQ, irq_rid, irq_res);
-       }
-       bus_release_resource(dev, SYS_RES_IOPORT, ioport_rid, ioport_res);
-       return (npx_exists ? 0 : ENXIO);
+       return (hw_float ? 0 : ENXIO);
 }
 
 /*
  * Attach routine - announce which it is, and wire into system
  */
 static int
-npx_attach(dev)
-       device_t dev;
+npx_attach(device_t dev)
 {
-       int flags;
        register_t s;
 
-       flags = device_get_flags(dev);
-
-       if (npx_irq13)
-               device_printf(dev, "IRQ 13 interface\n");
-       else if (!device_is_quiet(dev) || bootverbose)
-               device_printf(dev, "INT 16 interface\n");
-
        npxinit();
-
        s = intr_disable();
        stop_emulating();
        fpusave(&npx_initialstate);
@@ -447,7 +346,7 @@ npxinit(void)
        register_t savecrit;
        u_short control;
 
-       if (!npx_exists)
+       if (!hw_float)
                return;
        /*
         * fninit has the same h/w bugs as fnsave.  Use the detoxified
@@ -482,7 +381,7 @@ npxexit(td)
                npxsave(PCPU_GET(curpcb)->pcb_save);
        intr_restore(savecrit);
 #ifdef NPX_DEBUG
-       if (npx_exists) {
+       if (hw_float) {
                u_int   masked_exceptions;
 
                masked_exceptions = GET_FPU_CW(td) & GET_FPU_SW(td) & 0x7f;
@@ -503,7 +402,7 @@ int
 npxformat()
 {
 
-       if (!npx_exists)
+       if (!hw_float)
                return (_MC_FPFMT_NODEV);
 #ifdef CPU_ENABLE_SSE
        if (cpu_fxsr)
@@ -706,9 +605,9 @@ npxtrap()
        register_t savecrit;
        u_short control, status;
 
-       if (!npx_exists) {
-               printf("npxtrap: fpcurthread = %p, curthread = %p, npx_exists = 
%d\n",
-                      PCPU_GET(fpcurthread), curthread, npx_exists);
+       if (!hw_float) {
+               printf("npxtrap: fpcurthread = %p, curthread = %p, hw_float = 
%d\n",
+                      PCPU_GET(fpcurthread), curthread, hw_float);
                panic("npxtrap from nowhere");
        }
        savecrit = intr_disable();
@@ -748,7 +647,7 @@ npxdna(void)
        struct pcb *pcb;
        register_t s;
 
-       if (!npx_exists)
+       if (!hw_float)
                return (0);
        if (PCPU_GET(fpcurthread) == curthread) {
                printf("npxdna: fpcurthread == curthread %d times\n",
@@ -879,7 +778,7 @@ npxgetregs(struct thread *td, union save
        struct pcb *pcb;
        register_t s;
 
-       if (!npx_exists)
+       if (!hw_float)
                return (_MC_FPOWNED_NONE);
 
        pcb = td->td_pcb;
@@ -915,7 +814,7 @@ npxgetuserregs(struct thread *td, union 
        struct pcb *pcb;
        register_t s;
 
-       if (!npx_exists)
+       if (!hw_float)
                return (_MC_FPOWNED_NONE);
 
        pcb = td->td_pcb;
@@ -954,7 +853,7 @@ npxsetregs(struct thread *td, union save
        struct pcb *pcb;
        register_t s;
 
-       if (!npx_exists)
+       if (!hw_float)
                return;
 
        pcb = td->td_pcb;
@@ -981,7 +880,7 @@ npxsetuserregs(struct thread *td, union 
        struct pcb *pcb;
        register_t s;
 
-       if (!npx_exists)
+       if (!hw_float)
                return;
 
        pcb = td->td_pcb;

Modified: head/sys/kern/subr_trap.c
==============================================================================
--- head/sys/kern/subr_trap.c   Wed Jun 23 10:40:28 2010        (r209460)
+++ head/sys/kern/subr_trap.c   Wed Jun 23 11:12:58 2010        (r209461)
@@ -46,9 +46,6 @@ __FBSDID("$FreeBSD$");
 
 #include "opt_ktrace.h"
 #include "opt_kdtrace.h"
-#ifdef __i386__
-#include "opt_npx.h"
-#endif
 #include "opt_sched.h"
 
 #include <sys/param.h>
@@ -75,7 +72,6 @@ __FBSDID("$FreeBSD$");
 #include <security/audit/audit.h>
 
 #include <machine/cpu.h>
-#include <machine/pcb.h>
 
 #ifdef XEN
 #include <vm/vm.h>
@@ -147,10 +143,6 @@ ast(struct trapframe *framep)
        struct proc *p;
        int flags;
        int sig;
-#if defined(DEV_NPX) && !defined(SMP)
-       int ucode;
-       ksiginfo_t ksi;
-#endif
 
        td = curthread;
        p = td->td_proc;
@@ -190,19 +182,6 @@ ast(struct trapframe *framep)
                psignal(p, SIGVTALRM);
                PROC_UNLOCK(p);
        }
-#if defined(DEV_NPX) && !defined(SMP)
-       if (PCPU_GET(curpcb)->pcb_flags & PCB_NPXTRAP) {
-               atomic_clear_int(&PCPU_GET(curpcb)->pcb_flags,
-                   PCB_NPXTRAP);
-               ucode = npxtrap();
-               if (ucode != -1) {
-                       ksiginfo_init_trap(&ksi);
-                       ksi.ksi_signo = SIGFPE;
-                       ksi.ksi_code = ucode;
-                       trapsignal(td, &ksi);
-               }
-       }
-#endif
        if (flags & TDF_PROFPEND) {
                PROC_LOCK(p);
                psignal(p, SIGPROF);

Modified: head/sys/pc98/include/npx.h
==============================================================================
--- head/sys/pc98/include/npx.h Wed Jun 23 10:40:28 2010        (r209460)
+++ head/sys/pc98/include/npx.h Wed Jun 23 11:12:58 2010        (r209461)
@@ -1,49 +1,6 @@
 /*-
- * Copyright (C) 2005 TAKAHASHI Yoshihiro. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
+ * This file is in the public domain.
  */
-
-#ifndef _PC98_INCLUDE_NPX_H_
-#define _PC98_INCLUDE_NPX_H_
+/* $FreeBSD$ */
 
 #include <i386/npx.h>
-
-#ifdef _KERNEL
-
-#undef IO_NPX
-#define        IO_NPX          0x0F8           /* Numeric Coprocessor */
-#undef IO_NPXSIZE
-#define        IO_NPXSIZE      8               /* 80387/80487 NPX registers */
-
-#undef IRQ_NPX
-#define        IRQ_NPX         8
-
-/* full reset of npx: not needed on pc98 */
-#undef npx_full_reset
-#define npx_full_reset()
-
-#endif /* _KERNEL */
-
-#endif /* _PC98_INCLUDE_NPX_H_ */
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to