Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/sommerfeld_i386mp_1]: src/sys/arch/i386 Deal more sanely with ioapic sof...
details: https://anonhg.NetBSD.org/src/rev/22a95d55b265
branches: sommerfeld_i386mp_1
changeset: 482298:22a95d55b265
user: sommerfeld <sommerfeld%NetBSD.org@localhost>
date: Thu Sep 21 13:24:08 2000 +0000
description:
Deal more sanely with ioapic softc lookup in an attempt to deal with
systems which use weird id's for the ioapics.
- Use a linked list rather a fixed-size array indexed by ioapic id.
On all MP systems I've found so far, we only have one, and we only need to
look for them by id when establishing/disestablishing interrupt handlers; this
is not a performance-critical path..
- similarly, use ioapic_find() in mpbios.c rather than reaching into
ioapic.c's data.
While we're here, support single-apic systems which have interrupts
wired to "all ioapics".
diffstat:
sys/arch/i386/i386/ioapic.c | 144 +++++++++++++++++++++----------------
sys/arch/i386/i386/mpbios.c | 14 +-
sys/arch/i386/include/i82093var.h | 6 +-
3 files changed, 92 insertions(+), 72 deletions(-)
diffs (truncated from 323 to 300 lines):
diff -r 13180f511fbc -r 22a95d55b265 sys/arch/i386/i386/ioapic.c
--- a/sys/arch/i386/i386/ioapic.c Tue Sep 19 14:26:08 2000 +0000
+++ b/sys/arch/i386/i386/ioapic.c Thu Sep 21 13:24:08 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ioapic.c,v 1.1.2.7 2000/08/30 14:20:30 sommerfeld Exp $ */
+/* $NetBSD: ioapic.c,v 1.1.2.8 2000/09/21 13:24:08 sommerfeld Exp $ */
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -91,16 +91,14 @@
#include <machine/mpbiosvar.h>
/*
- * maps an IO-apic
- * TODO locking, export of interrupt functions
- * and mapping of interrupts.
+ * XXX locking
*/
int ioapic_match __P((struct device *, struct cfdata *, void *));
void ioapic_attach __P((struct device *, struct device *, void *));
-int i386_mem_add_mapping __P((bus_addr_t, bus_size_t,
- int, bus_space_handle_t *)); /* XXX */
+extern int i386_mem_add_mapping __P((bus_addr_t, bus_size_t,
+ int, bus_space_handle_t *)); /* XXX XXX */
void apic_vectorset __P((struct ioapic_softc *, int, int));
@@ -109,13 +107,19 @@
int ioapic_bsp_id = 0;
int ioapic_cold = 1;
+static struct ioapic_softc *ioapics; /* head of linked list */
+static int nioapics = 0; /* number attached */
+
+/*
+ * Register read/write routines.
+ */
static __inline u_int32_t
ioapic_read(struct ioapic_softc *sc,int regid)
{
u_int32_t val;
/*
- * TODO: lock apic
+ * XXX lock apic
*/
*(sc->sc_reg) = regid;
val = *sc->sc_data;
@@ -128,23 +132,54 @@
ioapic_write(struct ioapic_softc *sc,int regid, int val)
{
/*
- * todo lock apic
+ * XXX lock apic
*/
-
*(sc->sc_reg) = regid;
*(sc->sc_data) = val;
}
+struct ioapic_softc *
+ioapic_find(int apicid)
+{
+ struct ioapic_softc *sc;
+
+ if (apicid == 0xff) {
+ /*
+ * XXX kludge for all-ioapics interrupt support
+ * on single ioapic systems
+ */
+ if (nioapics <= 1)
+ return ioapics;
+ panic("unsupported: all-ioapics interrupt with >1 ioapic");
+ }
+
+ for (sc = ioapics; sc != NULL; sc = sc->sc_next)
+ if (sc->sc_apicid == apicid)
+ return sc;
+
+ return NULL;
+}
+
+static __inline void
+ioapic_add(struct ioapic_softc *sc)
+{
+ sc->sc_next = ioapics;
+ ioapics = sc;
+ nioapics++;
+}
+
+void ioapic_print_redir (struct ioapic_softc *sc, char *why, int pin)
+{
+ u_int32_t redirlo = ioapic_read(sc, IOAPIC_REDLO(pin));
+ u_int32_t redirhi = ioapic_read(sc, IOAPIC_REDHI(pin));
+
+ apic_format_redir(sc->sc_dev.dv_xname, why, pin, redirhi, redirlo);
+}
+
struct cfattach ioapic_ca = {
sizeof(struct ioapic_softc), ioapic_match, ioapic_attach
};
-/*
- * table of ioapics indexed by apic id.
- */
-
-struct ioapic_softc *ioapics[16] = { 0 };
-
int
ioapic_match(parent, match, aux)
struct device *parent;
@@ -158,14 +193,6 @@
return 0;
}
-void ioapic_print_redir (struct ioapic_softc *sc, char *why, int pin)
-{
- u_int32_t redirlo = ioapic_read(sc, IOAPIC_REDLO(pin));
- u_int32_t redirhi = ioapic_read(sc, IOAPIC_REDHI(pin));
-
- apic_format_redir(sc->sc_dev.dv_xname, why, pin, redirhi, redirlo);
-}
-
/*
* can't use bus_space_xxx as we don't have a bus handle ...
@@ -187,13 +214,13 @@
printf(" apid %d (I/O APIC)\n", aaa->apic_id);
- if (ioapics[aaa->apic_id] != NULL) {
+ if (ioapic_find(aaa->apic_id) != NULL) {
printf("%s: duplicate apic id (ignored)\n",
sc->sc_dev.dv_xname);
return;
}
- ioapics[aaa->apic_id] = sc;
+ ioapic_add(sc);
printf("%s: pa 0x%lx", sc->sc_dev.dv_xname, aaa->apic_address);
@@ -436,54 +463,42 @@
void
ioapic_enable ()
{
- int a, p, maxlevel;
+ int p, maxlevel;
+ struct ioapic_softc *sc;
struct intrhand *q;
extern void intr_calculatemasks __P((void)); /* XXX */
- int did_imcr = 0;
-
intr_calculatemasks(); /* for softints, AST's */
ioapic_cold = 0;
lapic_set_lvt();
- for (a=0; a<16; a++) {
- struct ioapic_softc *sc = ioapics[a];
- if (sc != NULL) {
- printf("%s: enabling\n", sc->sc_dev.dv_xname);
+ if (ioapics == NULL)
+ return;
- if (!did_imcr &&
- (sc->sc_flags & IOAPIC_PICMODE)) {
- /*
- * XXX not tested yet..
- */
- printf("%s: writing to IMCR to disable pics\n",
- sc->sc_dev.dv_xname);
- outb (IMCR_ADDR, IMCR_REGISTER);
- outb (IMCR_DATA, IMCR_APIC);
- printf("%s: here's hoping it works\n",
- sc->sc_dev.dv_xname);
- did_imcr = 1;
+ if (ioapics->sc_flags & IOAPIC_PICMODE) {
+ printf("%s: writing to IMCR to disable pics\n",
+ ioapics->sc_dev.dv_xname);
+ outb (IMCR_ADDR, IMCR_REGISTER);
+ outb (IMCR_DATA, IMCR_APIC);
+ }
+
+ for (sc = ioapics; sc != NULL; sc = sc->sc_next) {
+ printf("%s: enabling\n", sc->sc_dev.dv_xname);
+
+ for (p=0; p<sc->sc_apic_sz; p++) {
+ maxlevel = 0;
+
+ for (q = sc->sc_pins[p].ip_handler; q != NULL;
+ q = q->ih_next) {
+ if (q->ih_level > maxlevel)
+ maxlevel = q->ih_level;
}
-
- for (p=0; p<sc->sc_apic_sz; p++) {
- maxlevel = 0;
-
- for (q = sc->sc_pins[p].ip_handler;
- q != NULL;
- q = q->ih_next) {
- if (q->ih_level > maxlevel)
- maxlevel = q->ih_level;
- }
- apic_vectorset (sc, p, maxlevel);
- }
+ apic_vectorset (sc, p, maxlevel);
}
}
}
-
-
-
/*
* Interrupt handler management with the apic is radically different from the
* good old 8259.
@@ -514,7 +529,7 @@
{
unsigned int ioapic = APIC_IRQ_APIC(irq);
unsigned int intr = APIC_IRQ_PIN(irq);
- struct ioapic_softc *sc = ioapics[ioapic];
+ struct ioapic_softc *sc = ioapic_find(ioapic);
struct ioapic_pin *pin;
struct intrhand **p, *q, *ih;
static struct intrhand fakehand = {fakeintr};
@@ -522,7 +537,7 @@
int maxlevel;
if (sc == NULL)
- panic("unknown ioapic id %d", ioapic);
+ panic("apic_intr_establish: unknown ioapic %d", ioapic);
if ((irq & APIC_INT_VIA_APIC) == NULL)
panic("apic_intr_establish of non-apic interrupt 0x%x", irq);
@@ -625,13 +640,16 @@
int irq = ih->ih_irq;
unsigned int ioapic = APIC_IRQ_APIC(irq);
unsigned int intr = APIC_IRQ_PIN(irq);
- struct ioapic_softc *sc = ioapics[ioapic];
+ struct ioapic_softc *sc = ioapic_find(ioapic);
struct ioapic_pin *pin = &sc->sc_pins[intr];
struct intrhand **p, *q;
int maxlevel;
+ if (sc == NULL)
+ panic("apic_intr_disestablish: unknown ioapic %d", ioapic);
+
if (intr >= sc->sc_apic_sz)
- panic("apic_intr_establish: bogus irq");
+ panic("apic_intr_disestablish: bogus irq");
/*
* Remove the handler from the chain.
diff -r 13180f511fbc -r 22a95d55b265 sys/arch/i386/i386/mpbios.c
--- a/sys/arch/i386/i386/mpbios.c Tue Sep 19 14:26:08 2000 +0000
+++ b/sys/arch/i386/i386/mpbios.c Thu Sep 21 13:24:08 2000 +0000
@@ -95,7 +95,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: mpbios.c,v 1.1.2.7 2000/08/21 02:25:15 sommerfeld Exp $
+ * $Id: mpbios.c,v 1.1.2.8 2000/09/21 13:24:08 sommerfeld Exp $
*/
/*
@@ -454,7 +454,6 @@
struct mp_bus *mp_busses;
struct mp_intr_map *mp_intrs;
-extern struct ioapic_softc *ioapics[]; /* XXX */
struct mp_intr_map *lapic_ints[2]; /* XXX */
int mp_isa_bus = -1; /* XXX */
@@ -1023,11 +1022,12 @@
(*mpb->mb_intr_cfg)(entry, &mpi->redir);
if (enttype == MPS_MCT_IOINT) {
- /* XXX */
- if (id == 0xff)
- panic("can't deal with all-ioapics interrupt yet!");
-
- sc = ioapics[id]; /* XXX XXX XXX */
+ sc = ioapic_find(id);
+ if (sc == NULL) {
+ printf("mpbios: can't find ioapic %d\n", id);
+ return;
+ }
+
mpi->ioapic = sc;
mpi->ioapic_pin = pin;
diff -r 13180f511fbc -r 22a95d55b265 sys/arch/i386/include/i82093var.h
--- a/sys/arch/i386/include/i82093var.h Tue Sep 19 14:26:08 2000 +0000
+++ b/sys/arch/i386/include/i82093var.h Thu Sep 21 13:24:08 2000 +0000
@@ -1,4 +1,4 @@
Home |
Main Index |
Thread Index |
Old Index