Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 20 Sep 2002 20:10:50 -0700 (PDT)
From:      Peter Wemm <peter@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 17814 for review
Message-ID:  <200209210310.g8L3AorZ003880@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://people.freebsd.org/~peter/p4db/chv.cgi?CH=17814

Change 17814 by peter@peter_daintree on 2002/09/20 20:09:58

	bring npx.c into the 1990's.  Admit that FPU's exist as
	part of the cpu core and are not optional.  This should get
	folded into the machdep area, rather than isa.

Affected files ...

.. //depot/projects/hammer/sys/x86_64/isa/npx.c#4 edit

Differences ...

==== //depot/projects/hammer/sys/x86_64/isa/npx.c#4 (text+ko) ====

@@ -59,26 +59,16 @@
 #include <sys/signalvar.h>
 #include <sys/user.h>
 
-#ifndef SMP
-#include <machine/asmacros.h>
-#endif
 #include <machine/cputypes.h>
 #include <machine/frame.h>
 #include <machine/md_var.h>
 #include <machine/pcb.h>
 #include <machine/psl.h>
-#ifndef SMP
-#include <machine/clock.h>
-#endif
 #include <machine/resource.h>
 #include <machine/specialreg.h>
 #include <machine/segments.h>
 #include <machine/ucontext.h>
 
-#ifndef SMP
-#include <i386/isa/icu.h>
-#include <i386/isa/isa.h>
-#endif
 #include <i386/isa/intr_machdep.h>
 #ifdef DEV_ISA
 #include <isa/isavar.h>
@@ -158,9 +148,6 @@
 
 static	int	npx_attach(device_t dev);
 static	void	npx_identify(driver_t *driver, device_t parent);
-#ifndef SMP
-static	void	npx_intr(void *);
-#endif
 static	int	npx_probe(device_t dev);
 static	void	fpusave(union savefpu *);
 static	void	fpurstor(union savefpu *);
@@ -169,36 +156,13 @@
 		    void (*func)(void *buf, size_t len));
 #endif /* I586_CPU */
 
-int	hw_float;		/* XXX currently just alias for npx_exists */
-
+int	hw_float = 1;
 SYSCTL_INT(_hw,HW_FLOATINGPT, floatingpoint,
 	CTLFLAG_RD, &hw_float, 0, 
 	"Floatingpoint instructions executed in hardware");
 
-#ifndef SMP
-static	volatile u_int		npx_intrs_while_probing;
-static	volatile u_int		npx_traps_while_probing;
-#endif
-
 static	union savefpu		npx_cleanstate;
 static	bool_t			npx_cleanstate_ready;
-static	bool_t			npx_ex16;
-static	bool_t			npx_exists;
-static	bool_t			npx_irq13;
-
-#ifndef SMP
-alias_for_inthand_t probetrap;
-__asm("								\n\
-	.text							\n\
-	.p2align 2,0x90						\n\
-	.type	" __XSTRING(CNAME(probetrap)) ",@function	\n\
-" __XSTRING(CNAME(probetrap)) ":				\n\
-	ss							\n\
-	incl	" __XSTRING(CNAME(npx_traps_while_probing)) "	\n\
-	fnclex							\n\
-	iret							\n\
-");
-#endif /* SMP */
 
 /*
  * Identify routine.  Create a connection point on our parent for probing.
@@ -215,49 +179,7 @@
 		panic("npx_identify");
 }
 
-#ifndef SMP
 /*
- * Do minimal handling of npx interrupts to convert them to traps.
- */
-static void
-npx_intr(dummy)
-	void *dummy;
-{
-	struct thread *td;
-
-#ifndef SMP
-	npx_intrs_while_probing++;
-#endif
-
-	/*
-	 * The BUSY# latch must be cleared in all cases so that the next
-	 * unmasked npx exception causes an interrupt.
-	 */
-	outb(0xf0, 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;
-		mtx_lock_spin(&sched_lock);
-		td->td_kse->ke_flags |= KEF_ASTPENDING;
-		mtx_unlock_spin(&sched_lock);
-	}
-}
-#endif /* !SMP */
-
-/*
  * Probe routine.  Initialize cr0 to give correct behaviour for [f]wait
  * whether the device exists or not (XXX should be elsewhere).  Set flags
  * to tell npxattach() what to do.  Modify device struct if npx doesn't
@@ -267,32 +189,6 @@
 npx_probe(dev)
 	device_t dev;
 {
-#ifndef SMP
-	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;
-
-	save_idt_npxtrap = idt[16];
-	setidt(16, 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, RF_ACTIVE);
-	if (ioport_res == NULL)
-		panic("npx: can't get ports");
-	if (resource_int_value("npx", 0, "irq", &irq_num) != 0)
-		irq_num = 13;
-	irq_rid = 0;
-	irq_res = bus_alloc_resource(dev, SYS_RES_IRQ, &ioport_rid, irq_num,
-	    irq_num, 1, RF_ACTIVE);
-	if (irq_res == NULL)
-		panic("npx: can't get IRQ");
-	if (bus_setup_intr(dev, irq_res, INTR_TYPE_MISC | INTR_FAST, npx_intr,
-	    NULL, &irq_cookie) != 0)
-		panic("npx: can't create intr");
-#endif /* !SMP */
 
 	/*
 	 * Partially reset the coprocessor, if any.  Some BIOS's don't reset
@@ -320,116 +216,13 @@
 	 */
 	stop_emulating();
 	/*
-	 * Finish resetting the coprocessor, if any.  If there is an error
-	 * pending, then we may get a bogus IRQ13, but npx_intr() will handle
-	 * it OK.  Bogus halts have never been observed, but we enabled
-	 * IRQ13 and cleared the BUSY# latch early to handle them anyway.
+	 * Finish resetting the coprocessor.
 	 */
 	fninit();
 
 	device_set_desc(dev, "math processor");
 
-#ifdef SMP
-
-	/*
-	 * Exception 16 MUST work for SMP.
-	 */
-	npx_ex16 = hw_float = npx_exists = 1;
 	return (0);
-
-#else /* !SMP */
-
-	/*
-	 * Don't use fwait here because it might hang.
-	 * Don't use fnop here because it usually hangs if there is no FPU.
-	 */
-	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);
-#endif
-	/*
-	 * Check for a status of mostly zero.
-	 */
-	status = 0x5a5a;
-	fnstsw(&status);
-	if ((status & 0xb8ff) == 0) {
-		/*
-		 * Good, now check for a proper control word.
-		 */
-		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.
-			 */
-			control &= ~(1 << 2);	/* enable divide by 0 trap */
-			fldcw(&control);
-#ifdef FPU_ERROR_BROKEN
-			/*
-			 * FPU error signal doesn't work on some CPU
-			 * accelerator board.
-			 */
-			npx_ex16 = 1;
-			return (0);
-#endif
-			npx_traps_while_probing = npx_intrs_while_probing = 0;
-			fp_divide_by_0();
-			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[16] = save_idt_npxtrap;
-				return (0);
-			}
-			/*
-			 * Worse, even IRQ13 is broken.  Use emulator.
-			 */
-		}
-	}
-	/*
-	 * Probe failed, but we want to get to npxattach to initialize the
-	 * emulator and say that it has been installed.  XXX handle devices
-	 * that aren't really devices better.
-	 */
-	/* FALLTHROUGH */
-no_irq13:
-	idt[16] = save_idt_npxtrap;
-	bus_teardown_intr(dev, irq_res, irq_cookie);
-
-	/*
-	 * XXX hack around brokenness of bus_teardown_intr().  If we left the
-	 * irq active then we would get it instead of exception 16.
-	 */
-	{
-		register_t crit;
-
-		crit = intr_disable();
-		mtx_lock_spin(&icu_lock);
-		INTRDIS(1 << irq_num);
-		mtx_unlock_spin(&icu_lock);
-		intr_restore(crit);
-	}
-
-	bus_release_resource(dev, SYS_RES_IRQ, irq_rid, irq_res);
-	bus_release_resource(dev, SYS_RES_IOPORT, ioport_rid, ioport_res);
-	return (0);
-
-#endif /* SMP */
 }
 
 /*
@@ -447,34 +240,7 @@
 
 	if (flags)
 		device_printf(dev, "flags 0x%x ", flags);
-	if (npx_irq13) {
-		device_printf(dev, "using IRQ 13 interface\n");
-	} else {
-#if defined(MATH_EMULATE) || defined(GPL_MATH_EMULATE)
-		if (npx_ex16) {
-			if (!(flags & NPX_PREFER_EMULATOR))
-				device_printf(dev, "INT 16 interface\n");
-			else {
-				device_printf(dev, "FPU exists, but flags request "
-				    "emulator\n");
-				hw_float = npx_exists = 0;
-			}
-		} else if (npx_exists) {
-			device_printf(dev, "error reporting broken; using 387 emulator\n");
-			hw_float = npx_exists = 0;
-		} else
-			device_printf(dev, "387 emulator\n");
-#else
-		if (npx_ex16) {
-			device_printf(dev, "INT 16 interface\n");
-			if (flags & NPX_PREFER_EMULATOR) {
-				device_printf(dev, "emulator requested, but none compiled "
-				    "into kernel, using FPU\n");
-			}
-		} else
-			device_printf(dev, "no 387 emulator in kernel and no FPU!\n");
-#endif
-	}
+	device_printf(dev, "INT 16 interface\n");
 	npxinit(__INITIAL_NPXCW__);
 
 	if (npx_cleanstate_ready == 0) {
@@ -485,23 +251,6 @@
 		npx_cleanstate_ready = 1;
 		intr_restore(s);
 	}
-#ifdef I586_CPU_XXX
-	if (cpu_class == CPUCLASS_586 && npx_ex16 && npx_exists &&
-	    timezero("i586_bzero()", i586_bzero) <
-	    timezero("bzero()", bzero) * 4 / 5) {
-		if (!(flags & NPX_DISABLE_I586_OPTIMIZED_BCOPY)) {
-			bcopy_vector = i586_bcopy;
-			ovbcopy_vector = i586_bcopy;
-		}
-		if (!(flags & NPX_DISABLE_I586_OPTIMIZED_BZERO))
-			bzero = i586_bzero;
-		if (!(flags & NPX_DISABLE_I586_OPTIMIZED_COPYIO)) {
-			copyin_vector = i586_copyin;
-			copyout_vector = i586_copyout;
-		}
-	}
-#endif
-
 	return (0);		/* XXX unused */
 }
 
@@ -515,8 +264,6 @@
 	static union savefpu dummy;
 	register_t savecrit;
 
-	if (!npx_exists)
-		return;
 	/*
 	 * fninit has the same h/w bugs as fnsave.  Use the detoxified
 	 * fnsave to throw away any junk in the fpu.  npxsave() initializes
@@ -542,6 +289,9 @@
 npxexit(td)
 	struct thread *td;
 {
+#ifdef NPX_DEBUG
+	u_int	masked_exceptions;
+#endif
 	register_t savecrit;
 
 	savecrit = intr_disable();
@@ -549,20 +299,16 @@
 		npxsave(&PCPU_GET(curpcb)->pcb_save);
 	intr_restore(savecrit);
 #ifdef NPX_DEBUG
-	if (npx_exists) {
-		u_int	masked_exceptions;
-
-		masked_exceptions = GET_FPU_CW(td) & GET_FPU_SW(td) & 0x7f;
-		/*
-		 * Log exceptions that would have trapped with the old
-		 * control word (overflow, divide by 0, and invalid operand).
-		 */
-		if (masked_exceptions & 0x0d)
-			log(LOG_ERR,
-	"pid %d (%s) exited with masked floating point exceptions 0x%02x\n",
-			    td->td_proc->p_pid, td->td_proc->p_comm,
-			    masked_exceptions);
-	}
+	masked_exceptions = GET_FPU_CW(td) & GET_FPU_SW(td) & 0x7f;
+	/*
+	 * Log exceptions that would have trapped with the old
+	 * control word (overflow, divide by 0, and invalid operand).
+	 */
+	if (masked_exceptions & 0x0d)
+		log(LOG_ERR,
+"pid %d (%s) exited with masked floating point exceptions 0x%02x\n",
+		    td->td_proc->p_pid, td->td_proc->p_comm,
+		    masked_exceptions);
 #endif
 }
 
@@ -570,8 +316,6 @@
 npxformat()
 {
 
-	if (!npx_exists)
-		return (_MC_FPFMT_NODEV);
 #ifdef	CPU_ENABLE_SSE
 	if (cpu_fxsr)
 		return (_MC_FPFMT_XMM);
@@ -773,11 +517,6 @@
 	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);
-		panic("npxtrap from nowhere");
-	}
 	savecrit = intr_disable();
 
 	/*
@@ -816,8 +555,6 @@
 	register_t s;
 	u_short control;
 
-	if (!npx_exists)
-		return (0);
 	if (PCPU_GET(fpcurthread) == curthread) {
 		printf("npxdna: fpcurthread == curthread %d times\n",
 		    ++err_count);
@@ -932,9 +669,6 @@
 {
 	register_t s;
 
-	if (!npx_exists)
-		return (_MC_FPOWNED_NONE);
-
 	if ((td->td_pcb->pcb_flags & PCB_NPXINITDONE) == 0) {
 		if (npx_cleanstate_ready)
 			bcopy(&npx_cleanstate, addr, sizeof(npx_cleanstate));
@@ -974,9 +708,6 @@
 {
 	register_t s;
 
-	if (!npx_exists)
-		return;
-
 	s = intr_disable();
 	if (curthread == PCPU_GET(fpcurthread)) {
 		fpurstor(addr);

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe p4-projects" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200209210310.g8L3AorZ003880>