xv6

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

commit 9946b51c909edc0e79529971d104282dcdc77814
parent 6c8e36b21b75ce984120b1eb8a701961bc60dfa2
Author: Brian Swetland <swetland@frotz.net>
Date:   Sat,  4 Jan 2014 16:26:56 -0800

enable SMP in 64bit build

- in startothers() we pass entry32mp instead of entrymp as the
  address that entryother will jump to in 32bit mode
- don't initialize paging in entryother in the 64bit build
  since we defer that until we switch to 64bit mode
- entry32mp is an entrypoint midway through entry64.S that
  shares much of the startup code for the secondary core(s)
  with the bootstrap core

Diffstat:
Mkernel/entry64.S | 18++++++++++++++++++
Mkernel/entryother.S | 6++++++
Mkernel/main.c | 9++++++++-
3 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/kernel/entry64.S b/kernel/entry64.S @@ -75,6 +75,14 @@ ptbl_loop: dec %ecx jnz ptbl_loop +# Clear ebx for initial processor boot. +# When secondary processors boot, they'll call through +# entry32mp (from entryother), but with a nonzero ebx. +# We'll reuse these bootstrap pagetables and GDT. + xor %ebx, %ebx + +.global entry32mp +entry32mp: # CR3 -> 0x1000 (P4ML) mov $0x1000, %eax mov %eax, %cr3 @@ -133,6 +141,10 @@ entry64high: mov %ax, %fs mov %ax, %gs +# check to see if we're booting a secondary core + test %ebx, %ebx + jnz entry64mp + # setup initial stack mov $0xFFFFFFFF80010000, %rax mov %rax, %rsp @@ -145,6 +157,12 @@ __deadloop: # we should never return here... jmp . +entry64mp: +# obtain kstack from data block before entryother + mov $0x7000, %rax + mov -16(%rax), %rsp + jmp mpenter + .global wrmsr wrmsr: mov %rdi, %rcx # arg0 -> msrnum diff --git a/kernel/entryother.S b/kernel/entryother.S @@ -49,6 +49,11 @@ start32: movw %ax, %fs movw %ax, %gs +#if X64 + # defer paging until we switch to 64bit mode + # set ebx=1 so shared boot code knows we're booting a secondary core + mov $1, %ebx +#else # Turn on page size extension for 4Mbyte pages movl %cr4, %eax orl $(CR4_PSE), %eax @@ -60,6 +65,7 @@ start32: movl %cr0, %eax orl $(CR0_PE|CR0_PG|CR0_WP), %eax movl %eax, %cr0 +#endif # Switch to the stack allocated by startothers() movl (start-4), %esp diff --git a/kernel/main.c b/kernel/main.c @@ -44,7 +44,7 @@ main(void) } // Other CPUs jump here from entryother.S. -static void +void mpenter(void) { switchkvm(); @@ -64,6 +64,7 @@ mpmain(void) } pde_t entrypgdir[]; // For entry.S +void entry32mp(void); // Start the non-boot (AP) processors. static void @@ -88,9 +89,15 @@ startothers(void) // pgdir to use. We cannot use kpgdir yet, because the AP processor // is running in low memory, so we use entrypgdir for the APs too. stack = kalloc(); +#if X64 + *(uint32*)(code-4) = 0x8000; // just enough stack to get us to entry64mp + *(uint32*)(code-8) = v2p(entry32mp); + *(uint64*)(code-16) = (uint64) (stack + KSTACKSIZE); +#else *(void**)(code-4) = stack + KSTACKSIZE; *(void**)(code-8) = mpenter; *(int**)(code-12) = (void *) v2p(entrypgdir); +#endif lapicstartap(c->id, v2p(code));