]> hydra-www.ietfng.org Git - xv6-public/commitdiff
Detect first IOAPIC instead of hardcoding it.
authorPeter H. Froehlich <peter.hans.froehlich@gmail.com>
Sun, 18 Oct 2015 07:10:42 +0000 (03:10 -0400)
committerPeter H. Froehlich <peter.hans.froehlich@gmail.com>
Sun, 18 Oct 2015 07:10:42 +0000 (03:10 -0400)
defs.h
ioapic.c
mp.c

diff --git a/defs.h b/defs.h
index 34ed633ac02e2cfbe74d88c234ab24fd6773f5c0..3758232033f6b102c943f229b17e67de09b49b4c 100644 (file)
--- 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
index d34361199c2c3b8ea99a5e689039b765f1783287..fc3fc5ee237cd34193a46da07fe55d87d997adcf 100644 (file)
--- 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 3500e2703b298c64d6fca225f2464bb68ef2d3d2..60c8a5a26d8803b3ce4cb37b72b7fe43714c8b13 100644 (file)
--- 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;
   }