mycpu() in proc.c.
cli();
cons.locking = 0;
// use lapiccpunum so that we can call panic from mycpu()
- cprintf("cpu %d: panic: ", lapiccpunum());
+ cprintf("lapicid %d: panic: ", lapicid());
cprintf(s);
cprintf("\n");
getcallerpcs(&s, pcs);
// lapic.c
void cmostime(struct rtcdate *r);
-int lapiccpunum(void);
+int lapicid(void);
extern volatile uint* lapic;
void lapiceoi(void);
void lapicinit(void);
#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
lapicw(TPR, 0);
}
-// Should be called with interrupts disabled: the calling thread shouldn't be
-// rescheduled between reading lapic[ID] and checking against cpu array.
int
-lapiccpunum(void)
+lapicid(void)
{
- int apicid, i;
-
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");
+ return lapic[ID] >> 24;
}
// Acknowledge interrupt.
return mycpu()-cpus;
}
-// Must be called with interrupts disabled
+// Must be called with interrupts disabled to avoid the caller being rescheduled
+// between reading lapicid and running through the loop.
struct cpu*
mycpu(void)
{
+ int apicid, i;
+
if(readeflags()&FL_IF)
panic("mycpu called with interrupts enabled\n");
- return &cpus[lapiccpunum()];
+
+ apicid = lapicid();
+ // APIC IDs are not guaranteed to be contiguous. Maybe we should have
+ // a reverse map, or reserve a register to store &cpus[i].
+ for (i = 0; i < ncpu; ++i) {
+ if (cpus[i].apicid == apicid)
+ return &cpus[i];
+ }
+ panic("unknown apicid\n");
}
// Disable interrupts so that we are not rescheduled