]> Devi Nivas Git - cs3210-lab1.git/commitdiff
APIC IDs may not be consecutive and start from zero, so we cannot really use it
authorFrans Kaashoek <kaashoek@mit.edu>
Fri, 2 Sep 2016 12:31:13 +0000 (08:31 -0400)
committerFrans Kaashoek <kaashoek@mit.edu>
Fri, 2 Sep 2016 12:31:13 +0000 (08:31 -0400)
as a direct index into cpus.  Record apicid in struct cpu and have cpunum() look
for it. Replace cpu->id with cpunum() everywhere, and replace cpu->id with cpu->apicid.
Thanks to Xi Wang.

console.c
lapic.c
main.c
mp.c
proc.h
trap.c

index 298a6e76e87116edcb4ad8cc022644a1d1c72d02..d84c7ffd7230b7116e31ae1788f29e56e869cc42 100644 (file)
--- a/console.c
+++ b/console.c
@@ -110,7 +110,7 @@ panic(char *s)
 
   cli();
   cons.locking = 0;
-  cprintf("cpu%d: panic: ", cpu->id);
+  cprintf("cpu with apicid %d: panic: ", cpu->apicid);
   cprintf(s);
   cprintf("\n");
   getcallerpcs(&s, pcs);
diff --git a/lapic.c b/lapic.c
index 4bf2618360b5e9a1078034b3df48142c8e2ebaa1..7507f97439472ec477377c92c7c232a3c655957d 100644 (file)
--- a/lapic.c
+++ b/lapic.c
@@ -1,6 +1,7 @@
 // The local APIC manages internal (non-I/O) interrupts.
 // See Chapter 8 & Appendix C of Intel processor manual volume 3.
 
+#include "param.h"
 #include "types.h"
 #include "defs.h"
 #include "date.h"
@@ -8,6 +9,7 @@
 #include "traps.h"
 #include "mmu.h"
 #include "x86.h"
+#include "proc.h"  // ncpu
 
 // Local APIC registers, divided by 4 for use as uint[] indices.
 #define ID      (0x0020/4)   // ID
@@ -99,6 +101,8 @@ lapicinit(void)
 int
 cpunum(void)
 {
+  int apicid, i;
+  
   // Cannot call cpu when interrupts are enabled:
   // result not guaranteed to last long enough to be used!
   // Would prefer to panic but even printing is chancy here:
@@ -111,9 +115,15 @@ cpunum(void)
         __builtin_return_address(0));
   }
 
-  if(lapic)
-    return lapic[ID]>>24;
-  return 0;
+  if (!lapic)
+    return 0;
+
+  apicid = lapic[ID] >> 24;
+  for (i = 0; i < ncpu; ++i) {
+    if (cpus[i].apicid == apicid)
+      return i;
+  }
+  panic("unknown apicid\n");
 }
 
 // Acknowledge interrupt.
diff --git a/main.c b/main.c
index 2972b216a3f9cf7191a14afd0c8cbe04dc617712..47c36cc69f4888b8cfb8bf79d7041ea4c2213267 100644 (file)
--- a/main.c
+++ b/main.c
@@ -22,7 +22,7 @@ main(void)
   mpinit();        // detect other processors
   lapicinit();     // interrupt controller
   seginit();       // segment descriptors
-  cprintf("\ncpu%d: starting xv6\n\n", cpu->id);
+  cprintf("\ncpu%d: starting xv6\n\n", cpunum());
   picinit();       // another interrupt controller
   ioapicinit();    // another interrupt controller
   consoleinit();   // console hardware
@@ -54,7 +54,7 @@ mpenter(void)
 static void
 mpmain(void)
 {
-  cprintf("cpu%d: starting\n", cpu->id);
+  cprintf("cpu%d: starting\n", cpunum());
   idtinit();       // load idt register
   xchg(&cpu->started, 1); // tell startothers() we're up
   scheduler();     // start running processes
@@ -89,7 +89,7 @@ startothers(void)
     *(void**)(code-8) = mpenter;
     *(int**)(code-12) = (void *) V2P(entrypgdir);
 
-    lapicstartap(c->id, V2P(code));
+    lapicstartap(c->apicid, V2P(code));
 
     // wait for cpu to finish mpmain()
     while(c->started == 0)
diff --git a/mp.c b/mp.c
index 977a8237bc7415bf77b0cdf6f9465c7e9fb39f96..ade8930b37b2800b66343e6d8078ad0b1226428e 100644 (file)
--- a/mp.c
+++ b/mp.c
@@ -106,12 +106,10 @@ mpinit(void)
     switch(*p){
     case MPPROC:
       proc = (struct mpproc*)p;
-      if(ncpu != proc->apicid){
-        cprintf("mpinit: ncpu=%d apicid=%d\n", ncpu, proc->apicid);
-        ismp = 0;
+      if(ncpu < NCPU) {
+        cpus[ncpu].apicid = proc->apicid;  // apicid may differ from ncpu
+        ncpu++;
       }
-      cpus[ncpu].id = ncpu;
-      ncpu++;
       p += sizeof(struct mpproc);
       continue;
     case MPIOAPIC:
@@ -125,8 +123,8 @@ mpinit(void)
       p += 8;
       continue;
     default:
-      cprintf("mpinit: unknown config type %x\n", *p);
       ismp = 0;
+      break;
     }
   }
   if(!ismp){
diff --git a/proc.h b/proc.h
index d1597cf6823b70aad1b459676a4a645771058b9b..735280527ef887df5d1ce7ecb5b0bb73c866d517 100644 (file)
--- a/proc.h
+++ b/proc.h
@@ -1,6 +1,6 @@
 // Per-CPU state
 struct cpu {
-  uchar id;                    // Local APIC ID; index into cpus[] below
+  uchar apicid;                // Local APIC ID
   struct context *scheduler;   // swtch() here to enter scheduler
   struct taskstate ts;         // Used by x86 to find stack for interrupt
   struct segdesc gdt[NSEGS];   // x86 global descriptor table
diff --git a/trap.c b/trap.c
index 20ae62d3fea95ccb0d911b467240c45745c17a2a..e6b37848b8d384767a23b4c130040b5cba46484d 100644 (file)
--- a/trap.c
+++ b/trap.c
@@ -48,7 +48,7 @@ trap(struct trapframe *tf)
 
   switch(tf->trapno){
   case T_IRQ0 + IRQ_TIMER:
-    if(cpu->id == 0){
+    if(cpunum() == 0){
       acquire(&tickslock);
       ticks++;
       wakeup(&ticks);
@@ -74,7 +74,7 @@ trap(struct trapframe *tf)
   case T_IRQ0 + 7:
   case T_IRQ0 + IRQ_SPURIOUS:
     cprintf("cpu%d: spurious interrupt at %x:%x\n",
-            cpu->id, tf->cs, tf->eip);
+            cpunum(), tf->cs, tf->eip);
     lapiceoi();
     break;
 
@@ -83,13 +83,13 @@ trap(struct trapframe *tf)
     if(proc == 0 || (tf->cs&3) == 0){
       // In kernel, it must be our mistake.
       cprintf("unexpected trap %d from cpu %d eip %x (cr2=0x%x)\n",
-              tf->trapno, cpu->id, tf->eip, rcr2());
+              tf->trapno, cpunum(), tf->eip, rcr2());
       panic("trap");
     }
     // In user space, assume process misbehaved.
     cprintf("pid %d %s: trap %d err %d on cpu %d "
             "eip 0x%x addr 0x%x--kill proc\n",
-            proc->pid, proc->name, tf->trapno, tf->err, cpu->id, tf->eip,
+            proc->pid, proc->name, tf->trapno, tf->err, cpunum(), tf->eip,
             rcr2());
     proc->killed = 1;
   }