diff options
-rw-r--r-- | arch/x86/machine/boot.c | 7 | ||||
-rw-r--r-- | arch/x86/machine/boot.h | 29 | ||||
-rw-r--r-- | arch/x86/machine/boot_asm.S | 43 | ||||
-rw-r--r-- | arch/x86/machine/cpu.c | 13 | ||||
-rw-r--r-- | arch/x86/machine/cpu.h | 3 |
5 files changed, 36 insertions, 59 deletions
diff --git a/arch/x86/machine/boot.c b/arch/x86/machine/boot.c index f42f9bbf..63141886 100644 --- a/arch/x86/machine/boot.c +++ b/arch/x86/machine/boot.c @@ -75,11 +75,8 @@ #define INIT_CGACHARS (80 * 25) #define INIT_CGACOLOR 0x7 -char boot_stack[BOOT_STACK_SIZE] __aligned(DATA_ALIGN) __initdata; - -char boot_ap_stack[BOOT_STACK_SIZE] __aligned(DATA_ALIGN) __bootdata; -unsigned long boot_ap_id __bootdata; -unsigned long boot_ap_stack_addr __bootdata; +char boot_stacks[MAX_CPUS][BOOT_STACK_SIZE] __aligned(DATA_ALIGN) __initdata; +unsigned int boot_ap_id __bootdata; #ifdef __LP64__ pmap_pte_t boot_pml4[PMAP_L4_NR_PTES] __aligned(PAGE_SIZE) __bootdata; diff --git a/arch/x86/machine/boot.h b/arch/x86/machine/boot.h index bea98fff..5b85c14a 100644 --- a/arch/x86/machine/boot.h +++ b/arch/x86/machine/boot.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2012 Richard Braun. + * Copyright (c) 2010, 2012, 2013 Richard Braun. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -36,10 +36,8 @@ */ #define BOOT_VTOP(addr) ((addr) - KERNEL_OFFSET) -/* - * Size of the stack used to bootstrap the kernel. - */ -#define BOOT_STACK_SIZE PAGE_SIZE +#define BOOT_STACK_SHIFT PAGE_SHIFT +#define BOOT_STACK_SIZE (1 << BOOT_STACK_SHIFT) /* * Address where the MP trampoline code is copied and run at. @@ -68,27 +66,12 @@ extern char _boot; extern char _eboot; -/* - * Stack used to bootstrap the kernel. - */ -extern char boot_stack[BOOT_STACK_SIZE]; - -/* - * Common stack used by APs to bootstrap. - */ -extern char boot_ap_stack[BOOT_STACK_SIZE]; - -/* - * This variable contains the CPU ID of an AP during its early boot. - */ -extern unsigned long boot_ap_id; +extern char boot_stacks[MAX_CPUS][BOOT_STACK_SIZE]; /* - * After its early boot, an AP enables paging and jumps to virtual - * addresses. At this point, it switches to a per-AP preallocated - * stack. This variable contains the (virtual) address of that stack. + * This variable contains the CPU ID of an AP during early initialization. */ -extern unsigned long boot_ap_stack_addr; +extern unsigned int boot_ap_id; /* * Size of the trampoline code used for APs. diff --git a/arch/x86/machine/boot_asm.S b/arch/x86/machine/boot_asm.S index fc8ab5e2..f0c1b04f 100644 --- a/arch/x86/machine/boot_asm.S +++ b/arch/x86/machine/boot_asm.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2012 Richard Braun. + * Copyright (c) 2010, 2012, 2013 Richard Braun. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -58,7 +58,7 @@ ASM_ENTRY(_start) ljmp $8, $1f 1: - movl $(boot_stack - KERNEL_OFFSET + BOOT_STACK_SIZE), %esp + movl $(boot_stacks - KERNEL_OFFSET + BOOT_STACK_SIZE), %esp #ifdef __LP64__ call boot_check_long_mode @@ -73,6 +73,7 @@ ASM_ENTRY(_start) lret 1: + .code64 movl %ebx, %edi movl %eax, %esi #else /* __LP64__ */ @@ -81,21 +82,20 @@ ASM_ENTRY(_start) #endif /* __LP64__ */ call boot_setup_paging - movl %eax, %cr3 #ifdef __LP64__ - .code64 - movq $(boot_stack + BOOT_STACK_SIZE), %rsp + movq %rax, %cr3 + movq $(boot_stacks + BOOT_STACK_SIZE), %rsp xorq %rbp, %rbp - .code32 #else /* __LP64__ */ + movl %eax, %cr3 movl %cr0, %eax orl $CPU_CR0_PG, %eax movl %eax, %cr0 ljmp $8, $1f 1: - movl $(boot_stack + BOOT_STACK_SIZE), %esp + movl $(boot_stacks + BOOT_STACK_SIZE), %esp xorl %ebp, %ebp #endif /* __LP64__ */ @@ -105,6 +105,8 @@ ASM_ENTRY(_start) nop ASM_END(_start) +.code32 + ASM_DATA(boot_gdtr) .word boot_gdt_end - boot_gdt - 1 .long boot_gdt @@ -208,7 +210,10 @@ ASM_ENTRY(boot_ap_start32) ljmp $8, $1f 1: - movl $(boot_ap_stack + BOOT_STACK_SIZE), %esp + movl boot_ap_id, %esp + incl %esp + shll $BOOT_STACK_SHIFT, %esp + addl $(boot_stacks - KERNEL_OFFSET), %esp #ifdef __LP64__ call boot_setup_long_mode @@ -217,12 +222,15 @@ ASM_ENTRY(boot_ap_start32) lret 1: + .code64 #endif /* __LP64__ */ call pmap_ap_setup_paging - movl %eax, %cr3 -#ifndef __LP64__ +#ifdef __LP64__ + movq %rax, %cr3 +#else /* __LP64__ */ + movl %eax, %cr3 movl %cr0, %eax orl $CPU_CR0_PG, %eax movl %eax, %cr0 @@ -231,16 +239,15 @@ ASM_ENTRY(boot_ap_start32) 1: #endif /* __LP64__ */ - /* Switch to the boot stack preallocated for this AP by the BSP */ + movl boot_ap_id, %esp + incl %esp + shll $BOOT_STACK_SHIFT, %esp + #ifdef __LP64__ - .code64 - movq boot_ap_stack_addr, %rsp - addq $BOOT_STACK_SIZE, %rsp + addq $boot_stacks, %rsp xorq %rbp, %rbp - .code32 #else /* __LP64__ */ - movl boot_ap_stack_addr, %esp - addl $BOOT_STACK_SIZE, %esp + addl $boot_stacks, %esp xorl %ebp, %ebp #endif /* __LP64__ */ @@ -250,6 +257,8 @@ ASM_ENTRY(boot_ap_start32) nop ASM_END(boot_ap_start32) +.code32 + /* * This part, including the GDT, is the MP trampoline code run by APs * on startup. It is copied at a fixed location in the first segment and diff --git a/arch/x86/machine/cpu.c b/arch/x86/machine/cpu.c index eb0eb7e1..4190a65f 100644 --- a/arch/x86/machine/cpu.c +++ b/arch/x86/machine/cpu.c @@ -506,30 +506,21 @@ cpu_mp_start_aps(void) /* * Preallocate stacks now, as the kernel mappings shouldn't change while - * the APs are bootstrapping. + * the APs are starting. */ for (i = 1; i < cpu_boot_array_size; i++) { cpu = &cpu_array[i]; - cpu->boot_stack = vm_kmem_alloc(BOOT_STACK_SIZE); - - if (cpu->boot_stack == 0) - panic("cpu: unable to allocate boot stack for cpu%u", i); - cpu->double_fault_stack = vm_kmem_alloc(STACK_SIZE); if (cpu->double_fault_stack == 0) panic("cpu: unable to allocate double fault stack for cpu%u", i); } - /* Perform the "Universal Start-up Algorithm" */ for (i = 1; i < cpu_boot_array_size; i++) { cpu = &cpu_array[i]; - boot_ap_id = i; - boot_ap_stack_addr = cpu->boot_stack; - - barrier(); + /* Perform the "Universal Start-up Algorithm" */ lapic_ipi_init_assert(cpu->apic_id); cpu_delay(200); lapic_ipi_init_deassert(cpu->apic_id); diff --git a/arch/x86/machine/cpu.h b/arch/x86/machine/cpu.h index 24d4ef48..205036e3 100644 --- a/arch/x86/machine/cpu.h +++ b/arch/x86/machine/cpu.h @@ -250,9 +250,6 @@ struct cpu { struct cpu_tss double_fault_tss; #endif /* __LP64__ */ volatile int state; - - /* The following members have special initialization paths */ - unsigned long boot_stack; unsigned long double_fault_stack; } __aligned(CPU_ALIGN); |