Skip to content
Snippets Groups Projects
Commit ae15515d authored by Frans Kaashoek's avatar Frans Kaashoek
Browse files

APIC IDs may not be consecutive and start from zero, so we cannot really use it

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.
parent 37939f24
No related branches found
No related tags found
No related merge requests found
......@@ -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);
......
// 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.
......
......@@ -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)
......
......@@ -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){
......
// 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
......
......@@ -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;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment