svn commit: r209461 - in head/sys: i386/i386 i386/include i386/isa kern pc98/include

Konstantin Belousov kib at FreeBSD.org
Wed Jun 23 11:12:59 UTC 2010


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_ */


More information about the svn-src-head mailing list