boot more than two CPUs, each on own initial stack
This commit is contained in:
parent
7df1310b2a
commit
89eb5fbe6d
4 changed files with 35 additions and 24 deletions
15
bootother.S
15
bootother.S
|
@ -10,6 +10,10 @@
|
|||
* CS limit set to 64KB;
|
||||
* CPL and IP set to 0.
|
||||
*
|
||||
* mp.c causes each non-boot CPU in turn to jump to start.
|
||||
* mp.c puts the correct %esp in start-4, and the place to jump
|
||||
* to in start-8.
|
||||
*
|
||||
* Credit: Cliff Frey
|
||||
*/
|
||||
|
||||
|
@ -28,8 +32,8 @@ start: .code16 # This runs in real mode
|
|||
movw %ax,%es # -> Extra Segment
|
||||
movw %ax,%ss # -> Stack Segment
|
||||
|
||||
# Set up the stack pointer, growing downward from 0x7000.
|
||||
movw $start,%sp # Stack Pointer
|
||||
# Set up the stack pointer, growing downward from 0x7000-8.
|
||||
movw $start-8,%sp # Stack Pointer
|
||||
|
||||
#### Switch from real to protected mode
|
||||
#### The descriptors in our GDT allow all physical memory to be accessed.
|
||||
|
@ -61,10 +65,9 @@ protcseg:
|
|||
movw %ax, %gs # -> GS
|
||||
movw %ax, %ss # -> SS: Stack Segment
|
||||
|
||||
# XXX hack
|
||||
movl 0x10018, %eax # elfhdr->entry (left over in scratch space)
|
||||
# subl $KERNBASE, %eax
|
||||
jmp *%eax # this jumps to _start in kern/entry.S
|
||||
movl start-8, %eax
|
||||
movl start-4, %esp
|
||||
jmp *%eax
|
||||
|
||||
.p2align 2 # force 4 byte alignment
|
||||
gdt:
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
#define EXTPHYSMEM 0x100000
|
||||
|
||||
#define KADDR(a) ((void *) a)
|
37
mp.c
37
mp.c
|
@ -101,6 +101,10 @@ static struct cpu {
|
|||
static int ncpu;
|
||||
static struct cpu *bcpu;
|
||||
|
||||
// per-cpu start-up stack, only used to get into main()
|
||||
#define MPSTACK 512
|
||||
char mpstacks[NCPU * MPSTACK];
|
||||
|
||||
static int
|
||||
lapic_read(int r)
|
||||
{
|
||||
|
@ -230,17 +234,17 @@ mp_search(void)
|
|||
* 2) in the last KB of system base memory;
|
||||
* 3) in the BIOS ROM between 0xE0000 and 0xFFFFF.
|
||||
*/
|
||||
bda = KADDR(0x400);
|
||||
bda = (uint8_t*) 0x400;
|
||||
if((p = (bda[0x0F]<<8)|bda[0x0E])){
|
||||
if((mp = mp_scan(KADDR(p), 1024)))
|
||||
if((mp = mp_scan((uint8_t*) p, 1024)))
|
||||
return mp;
|
||||
}
|
||||
else{
|
||||
p = ((bda[0x14]<<8)|bda[0x13])*1024;
|
||||
if((mp = mp_scan(KADDR(p-1024), 1024)))
|
||||
if((mp = mp_scan((uint8_t*)p-1024, 1024)))
|
||||
return mp;
|
||||
}
|
||||
return mp_scan(KADDR(0xF0000), 0x10000);
|
||||
return mp_scan((uint8_t*)0xF0000, 0x10000);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -260,7 +264,7 @@ mp_detect(void)
|
|||
if((mp = mp_search()) == 0 || mp->physaddr == 0)
|
||||
return 1;
|
||||
|
||||
pcmp = KADDR(mp->physaddr);
|
||||
pcmp = (struct MPCTB *) mp->physaddr;
|
||||
if(memcmp(pcmp, "PCMP", 4))
|
||||
return 2;
|
||||
|
||||
|
@ -290,7 +294,8 @@ mp_init()
|
|||
uint8_t *p, *e;
|
||||
struct MPCTB *mpctb;
|
||||
struct MPPE *proc;
|
||||
struct cpu *c;
|
||||
int c;
|
||||
extern int main();
|
||||
|
||||
ncpu = 0;
|
||||
if ((r = mp_detect()) != 0) return;
|
||||
|
@ -302,8 +307,8 @@ mp_init()
|
|||
* application processors and initialising any I/O APICs. The table
|
||||
* is guaranteed to be in order such that only one pass is necessary.
|
||||
*/
|
||||
mpctb = KADDR(mp->physaddr);
|
||||
lapicaddr = KADDR(mpctb->lapicaddr);
|
||||
mpctb = (struct MPCTB *) mp->physaddr;
|
||||
lapicaddr = (uint32_t *) mpctb->lapicaddr;
|
||||
cprintf("apicaddr: %x\n", lapicaddr);
|
||||
p = ((uint8_t*)mpctb)+sizeof(struct MPCTB);
|
||||
e = ((uint8_t*)mpctb)+mpctb->length;
|
||||
|
@ -348,16 +353,18 @@ mp_init()
|
|||
lapic_online();
|
||||
|
||||
extern uint8_t _binary_bootother_start[], _binary_bootother_size[];
|
||||
memmove(KADDR(APBOOTCODE),_binary_bootother_start,
|
||||
memmove((void *) APBOOTCODE,_binary_bootother_start,
|
||||
(uint32_t) _binary_bootother_size);
|
||||
|
||||
acquire_spinlock(&kernel_lock);
|
||||
for (c = cpus; c < &cpus[ncpu]; c++) {
|
||||
if (c == bcpu) continue;
|
||||
cprintf ("starting processor %d\n", c - cpus);
|
||||
release_grant_spinlock(&kernel_lock, c - cpus);
|
||||
lapic_startap(c, (uint32_t) KADDR(APBOOTCODE));
|
||||
for(c = 0; c < ncpu; c++){
|
||||
if (cpus+c == bcpu) continue;
|
||||
cprintf ("starting processor %d\n", c);
|
||||
release_grant_spinlock(&kernel_lock, c);
|
||||
*(unsigned *)(APBOOTCODE-4) = (unsigned) mpstacks + (c + 1) * MPSTACK; // tell it what to use for %esp
|
||||
*(unsigned *)(APBOOTCODE-8) = (unsigned)&main; // tell it where to jump to
|
||||
lapic_startap(cpus + c, (uint32_t) APBOOTCODE);
|
||||
acquire_spinlock(&kernel_lock);
|
||||
cprintf ("done starting processor %d\n", c - cpus);
|
||||
cprintf ("done starting processor %d\n", c);
|
||||
}
|
||||
}
|
||||
|
|
4
proc.c
4
proc.c
|
@ -112,6 +112,10 @@ swtch()
|
|||
acquire_spinlock(&kernel_lock);
|
||||
}
|
||||
|
||||
// XXX this may be too late, should probably save on the way
|
||||
// in, in case some other CPU decided to run curproc
|
||||
// before we got here. in fact setting state=WAITING and
|
||||
// setting these variables had better be atomic w.r.t. other CPUs.
|
||||
op->ebp = read_ebp();
|
||||
op->esp = read_esp();
|
||||
|
||||
|
|
Loading…
Reference in a new issue