From 89eb5fbe6d120f19d69c3c84bed69611a746ff03 Mon Sep 17 00:00:00 2001 From: rtm Date: Sat, 24 Jun 2006 22:47:06 +0000 Subject: [PATCH] boot more than two CPUs, each on own initial stack --- bootother.S | 15 +++++++++------ memlayout.h | 3 --- mp.c | 37 ++++++++++++++++++++++--------------- proc.c | 4 ++++ 4 files changed, 35 insertions(+), 24 deletions(-) diff --git a/bootother.S b/bootother.S index cba4a5f..eee5ebe 100644 --- a/bootother.S +++ b/bootother.S @@ -9,6 +9,10 @@ * CS base set to startup memory address; * 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: diff --git a/memlayout.h b/memlayout.h index a33f347..e69de29 100644 --- a/memlayout.h +++ b/memlayout.h @@ -1,3 +0,0 @@ -#define EXTPHYSMEM 0x100000 - -#define KADDR(a) ((void *) a) diff --git a/mp.c b/mp.c index e797f81..d4284dc 100644 --- a/mp.c +++ b/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); } } diff --git a/proc.c b/proc.c index e771c4d..45696a2 100644 --- a/proc.c +++ b/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();