Skip to content

Commit

Permalink
APIC IDs may not be consecutive and start from zero, so we cannot rea…
Browse files Browse the repository at this point in the history
…lly 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.
  • Loading branch information
kaashoek committed Sep 2, 2016
1 parent 37939f2 commit ae15515
Show file tree
Hide file tree
Showing 6 changed files with 26 additions and 18 deletions.
2 changes: 1 addition & 1 deletion console.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
16 changes: 13 additions & 3 deletions lapic.c
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
// 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"
#include "memlayout.h"
#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
Expand Down Expand Up @@ -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:
Expand All @@ -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.
Expand Down
6 changes: 3 additions & 3 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down
10 changes: 4 additions & 6 deletions mp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -125,8 +123,8 @@ mpinit(void)
p += 8;
continue;
default:
cprintf("mpinit: unknown config type %x\n", *p);
ismp = 0;
break;
}
}
if(!ismp){
Expand Down
2 changes: 1 addition & 1 deletion proc.h
Original file line number Diff line number Diff line change
@@ -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
Expand Down
8 changes: 4 additions & 4 deletions trap.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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;

Expand All @@ -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;
}
Expand Down

0 comments on commit ae15515

Please sign in to comment.