summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/x86/machine/boot.c7
-rw-r--r--arch/x86/machine/boot.h29
-rw-r--r--arch/x86/machine/boot_asm.S43
-rw-r--r--arch/x86/machine/cpu.c13
-rw-r--r--arch/x86/machine/cpu.h3
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);