From 1c0c1723856195d10ee2b43e6d1e2e2728dc7523 Mon Sep 17 00:00:00 2001 From: "Peter H. Froehlich" Date: Sun, 18 Oct 2015 03:10:42 -0400 Subject: [PATCH] Detect first IOAPIC instead of hardcoding it. --- defs.h | 2 ++ ioapic.c | 9 ++++++--- mp.c | 16 +++++++++++----- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/defs.h b/defs.h index 34ed633..3758232 100644 --- a/defs.h +++ b/defs.h @@ -8,6 +8,7 @@ struct rtcdate; struct spinlock; struct stat; struct superblock; +struct ioapic; // bio.c void binit(void); @@ -60,6 +61,7 @@ void iderw(struct buf*); // ioapic.c void ioapicenable(int irq, int cpu); extern uchar ioapicid; +extern volatile struct ioapic* ioapic; void ioapicinit(void); // kalloc.c diff --git a/ioapic.c b/ioapic.c index d343611..fc3fc5e 100644 --- a/ioapic.c +++ b/ioapic.c @@ -13,7 +13,7 @@ #define REG_TABLE 0x10 // Redirection table base // The redirection table starts at REG_TABLE and uses -// two registers to configure each interrupt. +// two registers to configure each interrupt. // The first (low) register in a pair contains configuration bits. // The second (high) register contains a bitmask telling which // CPUs can serve that interrupt. @@ -22,7 +22,7 @@ #define INT_ACTIVELOW 0x00002000 // Active low (vs high) #define INT_LOGICAL 0x00000800 // Destination is CPU id (vs APIC ID) -volatile struct ioapic *ioapic; +volatile struct ioapic *ioapic; // Initialized in mp.c // IO APIC MMIO structure: write reg, then read or write data. struct ioapic { @@ -53,7 +53,10 @@ ioapicinit(void) if(!ismp) return; - ioapic = (volatile struct ioapic*)IOAPIC; + if(ioapic == 0) { + ioapic = (volatile struct ioapic*)IOAPIC; + cprintf("ioapicinit: falling back to default ioapic address\n"); + } maxintr = (ioapicread(REG_VER) >> 16) & 0xFF; id = ioapicread(REG_ID) >> 24; if(id != ioapicid) diff --git a/mp.c b/mp.c index 3500e27..60c8a5a 100644 --- a/mp.c +++ b/mp.c @@ -96,7 +96,7 @@ mpinit(void) struct mp *mp; struct mpconf *conf; struct mpproc *proc; - struct mpioapic *ioapic; + struct mpioapic *mioapic; if((conf = mpconfig(&mp)) == 0) return; @@ -131,13 +131,18 @@ mpinit(void) p += sizeof(struct mpproc); continue; case MPIOAPIC: - ioapic = (struct mpioapic*)p; - if(!(ioapic->flags & MP_APIC_ENABLED)){ - cprintf("mpinit: ioapic %d disabled, ignored\n", ioapic->apicid); + mioapic = (struct mpioapic*)p; + if(!(mioapic->flags & MP_APIC_ENABLED)){ + cprintf("mpinit: ioapic %d disabled, ignored\n", mioapic->apicid); p += sizeof(struct mpioapic); continue; } - ioapicid = ioapic->apicid; + if(ioapic == 0){ + ioapic = (volatile struct ioapic*)mioapic->addr; + ioapicid = mioapic->apicid; + } else { + cprintf("mpinit: ignored extra ioapic %d\n", mioapic->apicid); + } p += sizeof(struct mpioapic); continue; case MPBUS: @@ -154,6 +159,7 @@ mpinit(void) // Didn't like what we found; fall back to no MP. ncpu = 1; lapic = 0; + ioapic = 0; ioapicid = 0; return; } -- 2.50.1