]> hydra-www.ietfng.org Git - xv6-public/commitdiff
More sanity checks, slightly improved header.
authorPeter H. Froehlich <peter.hans.froehlich@gmail.com>
Sun, 18 Oct 2015 04:40:12 +0000 (00:40 -0400)
committerPeter H. Froehlich <peter.hans.froehlich@gmail.com>
Sun, 18 Oct 2015 04:40:12 +0000 (00:40 -0400)
mp.c
mp.h

diff --git a/mp.c b/mp.c
index 90fa48afcb3f7a9aa27709c22d7a33edd28048e2..3500e2703b298c64d6fca225f2464bb68ef2d3d2 100644 (file)
--- a/mp.c
+++ b/mp.c
@@ -45,7 +45,7 @@ mpsearch1(uint a, int len)
 // spec is in one of the following three locations:
 // 1) in the first KB of the EBDA;
 // 2) in the last KB of system base memory;
-// 3) in the BIOS ROM between 0xE0000 and 0xFFFFF.
+// 3) in the BIOS ROM between 0xF0000 and 0xFFFFF.
 static struct mp*
 mpsearch(void)
 {
@@ -81,7 +81,7 @@ mpconfig(struct mp **pmp)
   conf = (struct mpconf*) P2V((uint) mp->physaddr);
   if(memcmp(conf, "PCMP", 4) != 0)
     return 0;
-  if(conf->version != 1 && conf->version != 4)
+  if(conf->specrev != 1 && conf->specrev != 4)
     return 0;
   if(sum((uchar*)conf, conf->length) != 0)
     return 0;
@@ -106,7 +106,17 @@ mpinit(void)
     switch(*p){
     case MPPROC:
       proc = (struct mpproc*)p;
-      if (ncpu >= NCPU) {
+      if(!(proc->flags & MP_PROC_ENABLED)){
+        cprintf("mpinit: ignoring cpu %d, not enabled\n", proc->apicid);
+        p += sizeof(struct mpproc);
+        continue;
+      }
+      if(!(proc->feature & MP_PROC_APIC)){
+        cprintf("mpinit: cpu %d has no working APIC, ignored\n", proc->apicid);
+        p += sizeof(struct mpproc);
+        continue;
+      }
+      if(ncpu >= NCPU){
         cprintf("mpinit: more than %d cpus, ignoring cpu%d\n",
           NCPU, proc->apicid);
         p += sizeof(struct mpproc);
@@ -122,7 +132,12 @@ mpinit(void)
       continue;
     case MPIOAPIC:
       ioapic = (struct mpioapic*)p;
-      ioapicid = ioapic->apicno;
+      if(!(ioapic->flags & MP_APIC_ENABLED)){
+        cprintf("mpinit: ioapic %d disabled, ignored\n", ioapic->apicid);
+        p += sizeof(struct mpioapic);
+        continue;
+      }
+      ioapicid = ioapic->apicid;
       p += sizeof(struct mpioapic);
       continue;
     case MPBUS:
diff --git a/mp.h b/mp.h
index 4d172839bbd594ee3535d901af7c9c7a93f81c8e..7b83a6849b2436eb8aa4615ed4332a3515976898 100644 (file)
--- a/mp.h
+++ b/mp.h
@@ -14,9 +14,10 @@ struct mp {             // floating pointer
 struct mpconf {         // configuration table header
   uchar signature[4];           // "PCMP"
   ushort length;                // total table length
-  uchar version;                // [14]
+  uchar specrev;                // [14]
   uchar checksum;               // all bytes must add up to 0
-  uchar product[20];            // product id
+  uchar oemid[8];               // OEM id
+  uchar productid[12];          // product id
   uint *oemtable;               // OEM table pointer
   ushort oemlength;             // OEM table length
   ushort entry;                 // entry count
@@ -31,18 +32,24 @@ struct mpproc {         // processor table entry
   uchar apicid;                 // local APIC id
   uchar version;                // local APIC verison
   uchar flags;                  // CPU flags
-    #define MPBOOT 0x02           // This proc is the bootstrap processor.
+    #define MP_PROC_ENABLED (1 << 0)  // Usable by the OS.
+    #define MP_PROC_BOOT (1 << 1)     // Bootstrap processor.
   uchar signature[4];           // CPU signature
   uint feature;                 // feature flags from CPUID instruction
+    #define MP_PROC_FPU (1 << 0)      // Has a floating point unit.
+    #define MP_PROC_MCE (1 << 7)      // Supports machine check exception.
+    #define MP_PROC_CX8 (1 << 8)      // Supports 8-byte compare-and-exchange.
+    #define MP_PROC_APIC (1 << 9)     // Integrated APIC present and enabled.
   uchar reserved[8];
 };
 
 struct mpioapic {       // I/O APIC table entry
   uchar type;                   // entry type (2)
-  uchar apicno;                 // I/O APIC id
+  uchar apicid;                 // I/O APIC id
   uchar version;                // I/O APIC version
   uchar flags;                  // I/O APIC flags
-  uint *addr;                  // I/O APIC address
+    #define MP_APIC_ENABLED (1 << 0)  // Usable by the OS.
+  uint *addr;                   // I/O APIC address
 };
 
 // Table entry types