diff --git a/console.c b/console.c index da28f9f..ca00a5f 100644 --- a/console.c +++ b/console.c @@ -112,7 +112,7 @@ panic(char *s) 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); diff --git a/defs.h b/defs.h index c4870d0..82fb982 100644 --- a/defs.h +++ b/defs.h @@ -74,7 +74,7 @@ void kbdintr(void); // lapic.c void cmostime(struct rtcdate *r); -int lapiccpunum(void); +int lapicid(void); extern volatile uint* lapic; void lapiceoi(void); void lapicinit(void); diff --git a/lapic.c b/lapic.c index 9a12f17..dc69eb6 100644 --- a/lapic.c +++ b/lapic.c @@ -9,7 +9,6 @@ #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 @@ -98,22 +97,12 @@ lapicinit(void) 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. diff --git a/proc.c b/proc.c index ca343cb..aac7523 100644 --- a/proc.c +++ b/proc.c @@ -32,13 +32,24 @@ cpuid() { 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