xv6

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 3121e29fbb5db64ed76b5682d9f99633776de500
parent 8bb7079c6bce55bab6c85408b33c56644e6930b0
Author: Brian Swetland <swetland@frotz.net>
Date:   Sat,  4 Jan 2014 18:35:00 -0800

support systems where cpu# != apicid

- add an apicid field to struct cpu, don't assume id == apicid
- startothers() uses cpu->apicid when calling lapicstartap()
- cpunum() now walks the cpu table to back-map apicid to id
  this isn't too bad because cpunum() is only called from
  seginit() to initialize the cpu-local pointer to its struct cpu.
  Everywhere else uses cpu->id.

Now booting with two cores on an i3-4010u.

Diffstat:
Minclude/proc.h | 3++-
Mkernel/lapic.c | 16++++++++++++++--
Mkernel/main.c | 2+-
Mkernel/mp.c | 6++----
4 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/include/proc.h b/include/proc.h @@ -3,7 +3,8 @@ // Per-CPU state struct cpu { - uchar id; // Local APIC ID; index into cpus[] below + uchar 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 diff --git a/kernel/lapic.c b/kernel/lapic.c @@ -7,6 +7,8 @@ #include "traps.h" #include "mmu.h" #include "x86.h" +#include "param.h" +#include "proc.h" // Local APIC registers, divided by 4 for use as uint[] indices. #define ID (0x0020/4) // ID @@ -95,9 +97,13 @@ lapicinit(void) lapicw(TPR, 0); } +// This is only used during secondary processor startup. +// cpu->id is the fast way to get the cpu number, once the +// processor is fully started. int cpunum(void) { + int n, id; // 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: @@ -110,8 +116,14 @@ cpunum(void) __builtin_return_address(0)); } - if(lapic) - return lapic[ID]>>24; + if(!lapic) + return 0; + + id = lapic[ID]>>24; + for (n = 0; n < ncpu; n++) + if (id == cpus[n].apicid) + return n; + return 0; } diff --git a/kernel/main.c b/kernel/main.c @@ -99,7 +99,7 @@ startothers(void) *(int**)(code-12) = (void *) v2p(entrypgdir); #endif - lapicstartap(c->id, v2p(code)); + lapicstartap(c->apicid, v2p(code)); // wait for cpu to finish mpmain() while(c->started == 0) diff --git a/kernel/mp.c b/kernel/mp.c @@ -114,13 +114,11 @@ 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; - } + cprintf("mpinit ncpu=%d apicid=%d\n", ncpu, proc->apicid); if(proc->flags & MPBOOT) bcpu = &cpus[ncpu]; cpus[ncpu].id = ncpu; + cpus[ncpu].apicid = proc->apicid; ncpu++; p += sizeof(struct mpproc); continue;