summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--defs.h1
-rw-r--r--main.c2
-rw-r--r--proc.c16
-rw-r--r--proc.h1
-rw-r--r--vm.c7
5 files changed, 21 insertions, 6 deletions
diff --git a/defs.h b/defs.h
index 763eb75..3735f6f 100644
--- a/defs.h
+++ b/defs.h
@@ -110,6 +110,7 @@ int fork(void);
int growproc(int);
int kill(int);
struct cpu* mycpu(void);
+struct cpu* getmycpu(void);
struct proc* myproc();
void pinit(void);
void procdump(void);
diff --git a/main.c b/main.c
index a900e9d..3127b15 100644
--- a/main.c
+++ b/main.c
@@ -45,6 +45,8 @@ main(uint64 mbmagic, uint64 mbaddr)
return 0;
}
+extern struct cpu* getmycpu();
+
// Common CPU setup code.
static void
mpmain(void)
diff --git a/proc.c b/proc.c
index 55e435c..3c0acbd 100644
--- a/proc.c
+++ b/proc.c
@@ -37,16 +37,15 @@ cpuid() {
// Must be called with interrupts disabled to avoid the caller being
// rescheduled between reading lapicid and running through the loop.
struct cpu*
-mycpu(void)
+getmycpu(void)
{
int apicid, i;
if(readeflags()&FL_IF)
- panic("mycpu called with interrupts enabled\n");
+ panic("getmycpu called with interrupts enabled\n");
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].
+ // APIC IDs are not guaranteed to be contiguous.
for (i = 0; i < ncpu; ++i) {
if (cpus[i].apicid == apicid)
return &cpus[i];
@@ -54,6 +53,15 @@ mycpu(void)
panic("unknown apicid\n");
}
+// Return this core's cpu struct using %gs. %gs points this core's struct
+// cpu. Offet 24 in struct cpu is cpu.
+struct cpu*
+mycpu(void) {
+ struct cpu *c;
+ asm volatile("mov %%gs:24, %0" : "=r" (c));
+ return c;
+}
+
// Disable interrupts so that we are not rescheduled
// while reading proc from the cpu structure
struct proc*
diff --git a/proc.h b/proc.h
index 9261766..0b01b75 100644
--- a/proc.h
+++ b/proc.h
@@ -3,6 +3,7 @@ struct cpu {
uint64 syscallno; // Temporary used by sysentry
uint64 usp; // Temporary used by sysentry
struct proc *proc; // The process running on this cpu or null
+ struct cpu *cpu; // XXX
uchar apicid; // Local APIC ID
struct context *scheduler; // swtch() here to enter scheduler
struct taskstate ts; // Used by x86 to find stack for interrupt
diff --git a/vm.c b/vm.c
index ebb6749..c0276a1 100644
--- a/vm.c
+++ b/vm.c
@@ -39,7 +39,8 @@ seginit(void)
struct cpu *c;
struct desctr dtr;
- c = mycpu();
+ c = getmycpu();
+
memmove(c->gdt, bootgdt, sizeof bootgdt);
dtr.limit = sizeof(c->gdt)-1;
dtr.base = (uint64) c->gdt;
@@ -54,10 +55,12 @@ seginit(void)
writemsr(MSR_LSTAR, (uint64)&sysentry);
writemsr(MSR_SFMASK, FL_TF | FL_IF);
- // Initialize cpu-local storage.
+ // Initialize cpu-local storage so that each core can easily
+ // find its struct cpu using %gs.
writegs(SEG_KDATA);
writemsr(MSR_GS_BASE, (uint64)c);
writemsr(MSR_GS_KERNBASE, (uint64)c);
+ c->cpu = c;
}
// Return the address of the PTE in page table pgdir