summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--console.c2
-rw-r--r--lapic.c16
-rw-r--r--main.c6
-rw-r--r--mp.c10
-rw-r--r--proc.h2
-rw-r--r--trap.c8
6 files changed, 26 insertions, 18 deletions
diff --git a/console.c b/console.c
index 298a6e7..d84c7ff 100644
--- 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 4bf2618..7507f97 100644
--- 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 2972b21..47c36cc 100644
--- 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 977a823..ade8930 100644
--- 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 d1597cf..7352805 100644
--- 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 20ae62d..e6b3784 100644
--- 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;
}