summaryrefslogtreecommitdiffstats
path: root/sys/i386/isa/npx.c
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2003-11-03 21:53:38 +0000
committerjhb <jhb@FreeBSD.org>2003-11-03 21:53:38 +0000
commitdcec7e1907fe867da713052f8c91d79bbfe68000 (patch)
treec7dc6abe8f136cde7b0dbbc6ce1152f91bb42ad1 /sys/i386/isa/npx.c
parentaac4b7181cbed34861c76ff9d9142c7fdf212008 (diff)
downloadFreeBSD-src-dcec7e1907fe867da713052f8c91d79bbfe68000.zip
FreeBSD-src-dcec7e1907fe867da713052f8c91d79bbfe68000.tar.gz
New APIC support code:
- The apic interrupt entry points have been rewritten so that each entry point can serve 32 different vectors. When the entry is executed, it uses one of the 32-bit ISR registers to determine which vector in its assigned range was triggered. Thus, the apic code can support 159 different interrupt vectors with only 5 entry points. - We now always to disable the local APIC to work around an errata in certain PPros and then re-enable it again if we decide to use the APICs to route interrupts. - We no longer map IO APICs or local APICs using special page table entries. Instead, we just use pmap_mapdev(). We also no longer export the virtual address of the local APIC as a global symbol to the rest of the system, but only in local_apic.c. To aid this, the APIC ID of each CPU is exported as a per-CPU variable. - Interrupt sources are provided for each intpin on each IO APIC. Currently, each source is given a unique interrupt vector meaning that PCI interrupts are not shared on most machines with an I/O APIC. That mapping for interrupt sources to interrupt vectors is up to the APIC enumerator driver however. - We no longer probe to see if we need to use mixed mode to route IRQ 0, instead we always use mixed mode to route IRQ 0 for now. This can be disabled via the 'NO_MIXED_MODE' kernel option. - The npx(4) driver now always probes to see if a built-in FPU is present since this test can now be performed with the new APIC code. However, an SMP kernel will panic if there is more than one CPU and a built-in FPU is not found. - PCI interrupts are now properly routed when using APICs to route interrupts, so remove the hack to psuedo-route interrupts when the intpin register was read. - The apic.h header was moved to apicreg.h and a new apicvar.h header that declares the APIs used by the new APIC code was added.
Diffstat (limited to 'sys/i386/isa/npx.c')
-rw-r--r--sys/i386/isa/npx.c50
1 files changed, 13 insertions, 37 deletions
diff --git a/sys/i386/isa/npx.c b/sys/i386/isa/npx.c
index fbd4643..9e5a7ee 100644
--- a/sys/i386/isa/npx.c
+++ b/sys/i386/isa/npx.c
@@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$");
#include <sys/mutex.h>
#include <sys/mutex.h>
#include <sys/proc.h>
+#include <sys/smp.h>
#include <sys/sysctl.h>
#include <machine/bus.h>
#include <sys/rman.h>
@@ -61,31 +62,25 @@ __FBSDID("$FreeBSD$");
#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>
#ifdef PC98
#include <pc98/pc98/pc98.h>
#else
#include <i386/isa/isa.h>
#endif
-#endif
-#include <i386/isa/intr_machdep.h>
+#include <machine/intr_machdep.h>
#ifdef DEV_ISA
#include <isa/isavar.h>
#endif
@@ -165,9 +160,7 @@ 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);
-#ifndef SMP
static void npx_intr(void *);
-#endif
static int npx_probe(device_t dev);
#ifdef I586_CPU_XXX
static long timezero(const char *funcname,
@@ -180,10 +173,8 @@ 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;
@@ -191,7 +182,6 @@ 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\
@@ -203,7 +193,6 @@ __asm(" \n\
fnclex \n\
iret \n\
");
-#endif /* SMP */
/*
* Identify routine. Create a connection point on our parent for probing.
@@ -220,7 +209,6 @@ npx_identify(driver, parent)
panic("npx_identify");
}
-#ifndef SMP
/*
* Do minimal handling of npx interrupts to convert them to traps.
*/
@@ -230,9 +218,7 @@ npx_intr(dummy)
{
struct thread *td;
-#ifndef SMP
npx_intrs_while_probing++;
-#endif
/*
* The BUSY# latch must be cleared in all cases so that the next
@@ -264,7 +250,6 @@ npx_intr(dummy)
mtx_unlock_spin(&sched_lock);
}
}
-#endif /* !SMP */
/*
* Probe routine. Initialize cr0 to give correct behaviour for [f]wait
@@ -276,7 +261,6 @@ static int
npx_probe(dev)
device_t dev;
{
-#ifndef SMP
struct gate_descriptor save_idt_npxtrap;
struct resource *ioport_res, *irq_res;
void *irq_cookie;
@@ -307,7 +291,6 @@ npx_probe(dev)
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
@@ -348,16 +331,6 @@ npx_probe(dev)
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.
@@ -413,6 +386,10 @@ npx_probe(dev)
*/
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);
}
/*
@@ -425,6 +402,10 @@ npx_probe(dev)
* emulator and say that it has been installed. XXX handle devices
* that aren't really devices better.
*/
+#ifdef SMP
+ if (mp_ncpus > 1)
+ panic("npx0 cannot be emulated on an SMP system");
+#endif
/* FALLTHROUGH */
no_irq13:
idt[IDT_MF] = save_idt_npxtrap;
@@ -435,20 +416,15 @@ no_irq13:
* irq active then we would get it instead of exception 16.
*/
{
- register_t crit;
+ struct intsrc *isrc;
- crit = intr_disable();
- mtx_lock_spin(&icu_lock);
- INTRDIS(1 << irq_num);
- mtx_unlock_spin(&icu_lock);
- intr_restore(crit);
+ isrc = intr_lookup_source(irq_num);
+ isrc->is_pic->pic_disable_source(isrc);
}
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 */
}
/*
OpenPOWER on IntegriCloud