diff options
author | Richard Braun <rbraun@sceen.net> | 2018-07-07 16:16:33 +0200 |
---|---|---|
committer | Richard Braun <rbraun@sceen.net> | 2018-07-07 16:16:33 +0200 |
commit | bf1ee95728d81204b0cb30aa8d59d67c6c699138 (patch) | |
tree | 3bfdafa1d0e2ca80472ff6d9a452551519e59681 | |
parent | b17e3aa862e30b66e93dba70aaf3ece1e5e2ed3f (diff) |
x86/{boot,cpu}: rework AP boot stack management
-rw-r--r-- | arch/x86/machine/boot.c | 47 | ||||
-rw-r--r-- | arch/x86/machine/boot.h | 9 | ||||
-rw-r--r-- | arch/x86/machine/boot_asm.S | 4 | ||||
-rw-r--r-- | arch/x86/machine/cpu.c | 24 | ||||
-rw-r--r-- | arch/x86/machine/cpu.h | 7 | ||||
-rw-r--r-- | arch/x86/machine/cpu_i.h | 1 | ||||
-rw-r--r-- | arch/x86/machine/pmap.c | 4 | ||||
-rw-r--r-- | arch/x86/machine/pmap.h | 2 |
8 files changed, 60 insertions, 38 deletions
diff --git a/arch/x86/machine/boot.c b/arch/x86/machine/boot.c index c1970f5d..f62ad09b 100644 --- a/arch/x86/machine/boot.c +++ b/arch/x86/machine/boot.c @@ -75,7 +75,6 @@ alignas(CPU_DATA_ALIGN) char boot_stack[BOOT_STACK_SIZE] __bootdata; alignas(CPU_DATA_ALIGN) char boot_ap_stack[BOOT_STACK_SIZE] __bootdata; -unsigned int boot_ap_id __bootdata; #ifdef __LP64__ alignas(PAGE_SIZE) pmap_pte_t boot_pml4[PMAP_L3_PTES_PER_PT] __bootdata; @@ -122,6 +121,12 @@ static char boot_panic_meminfo_msg[] __bootdata static char boot_panic_cmdline_msg[] __bootdata = "boot: command line too long"; +static volatile unsigned int boot_ap_id __bootdata; +static char *boot_ap_stacks[CONFIG_MAX_CPUS - 1] __initdata; + +pmap_pte_t * boot_ap_setup(void); +char * boot_get_ap_stack(void); + void * __boot boot_memcpy(void *dest, const void *src, size_t n) { @@ -500,9 +505,47 @@ boot_main(void) } void __init +boot_alloc_ap_stacks(void) +{ + char *stack; + + for (unsigned int i = 1; i < cpu_count(); i++) { + stack = kmem_alloc(BOOT_STACK_SIZE); + + if (!stack) { + panic("boot: unable to allocate stack for cpu%u", i); + } + + boot_ap_stacks[i - 1] = stack; + } +} + +void __init +boot_set_ap_id(unsigned int ap_id) +{ + boot_ap_id = ap_id; +} + +pmap_pte_t * __boot +boot_ap_setup(void) +{ + return pmap_ap_setup_paging(boot_ap_id); +} + +char * __init +boot_get_ap_stack(void) +{ + unsigned int index; + + index = boot_ap_id - 1; + assert(boot_ap_id < ARRAY_SIZE(boot_ap_stacks)); + return boot_ap_stacks[index]; +} + +void __init boot_ap_main(void) { - cpu_ap_setup(); + cpu_ap_setup(boot_ap_id); thread_ap_setup(); pmap_ap_setup(); percpu_ap_setup(); diff --git a/arch/x86/machine/boot.h b/arch/x86/machine/boot.h index 087f0c2a..a3f4ecb8 100644 --- a/arch/x86/machine/boot.h +++ b/arch/x86/machine/boot.h @@ -79,11 +79,6 @@ extern char _boot; extern char _boot_end; /* - * This variable contains the CPU ID of an AP during early initialization. - */ -extern unsigned int boot_ap_id; - -/* * Size of the trampoline code used for APs. */ extern uint32_t boot_mp_trampoline_size; @@ -123,6 +118,10 @@ void boot_main(void); */ void boot_ap_main(void); +void boot_alloc_ap_stacks(void); + +void boot_set_ap_id(unsigned int ap_id); + /* * Log kernel version and other architecture-specific information. */ diff --git a/arch/x86/machine/boot_asm.S b/arch/x86/machine/boot_asm.S index d9bdc3df..bfec4483 100644 --- a/arch/x86/machine/boot_asm.S +++ b/arch/x86/machine/boot_asm.S @@ -313,7 +313,7 @@ ASM_ENTRY(boot_ap_start32) .code64 #endif /* __LP64__ */ - call pmap_ap_setup_paging + call boot_ap_setup #ifdef __LP64__ movq %rax, %cr3 @@ -327,7 +327,7 @@ ASM_ENTRY(boot_ap_start32) 1: #endif /* __LP64__ */ - call cpu_get_boot_stack + call boot_get_ap_stack #ifdef __LP64__ movq %rax, %rsp diff --git a/arch/x86/machine/cpu.c b/arch/x86/machine/cpu.c index 5eb9ce2d..f2acd77d 100644 --- a/arch/x86/machine/cpu.c +++ b/arch/x86/machine/cpu.c @@ -420,12 +420,6 @@ cpu_delay(unsigned long usecs) } while (total > 0); } -void * __init -cpu_get_boot_stack(void) -{ - return percpu_var(cpu_desc.boot_stack, boot_ap_id); // TODO Pass as argument -} - void * cpu_get_intr_stack(void) { @@ -1254,7 +1248,6 @@ cpu_mp_setup(void) { uint16_t reset_vector[2]; struct cpu *cpu; - unsigned int i; void *ptr; if (cpu_count() == 1) { @@ -1279,14 +1272,7 @@ cpu_mp_setup(void) io_write_byte(CPU_MP_CMOS_PORT_REG, CPU_MP_CMOS_REG_RESET); io_write_byte(CPU_MP_CMOS_PORT_DATA, CPU_MP_CMOS_DATA_RESET_WARM); - for (i = 1; i < cpu_count(); i++) { - cpu = percpu_ptr(cpu_desc, i); - cpu->boot_stack = kmem_alloc(BOOT_STACK_SIZE); - - if (!cpu->boot_stack) { - panic("cpu: unable to allocate boot stack for cpu%u", i); - } - } + boot_alloc_ap_stacks(); /* * This function creates per-CPU copies of the page tables. Just in case, @@ -1294,9 +1280,9 @@ cpu_mp_setup(void) */ pmap_mp_setup(); - for (i = 1; i < cpu_count(); i++) { + for (unsigned int i = 1; i < cpu_count(); i++) { cpu = percpu_ptr(cpu_desc, i); - boot_ap_id = i; + boot_set_ap_id(i); /* Perform the "Universal Start-up Algorithm" */ lapic_ipi_init_assert(cpu->apic_id); @@ -1315,11 +1301,11 @@ cpu_mp_setup(void) } void __init -cpu_ap_setup(void) +cpu_ap_setup(unsigned int ap_id) { struct cpu *cpu; - cpu = percpu_ptr(cpu_desc, boot_ap_id); + cpu = percpu_ptr(cpu_desc, ap_id); cpu_build(cpu); cpu_check(cpu_current()); lapic_ap_setup(); diff --git a/arch/x86/machine/cpu.h b/arch/x86/machine/cpu.h index b94c149d..94291acc 100644 --- a/arch/x86/machine/cpu.h +++ b/arch/x86/machine/cpu.h @@ -600,11 +600,6 @@ uint64_t cpu_get_freq(void); void cpu_delay(unsigned long usecs); /* - * Return the address of the boot stack allocated for the current processor. - */ -void * cpu_get_boot_stack(void); - -/* * Log processor information. */ void cpu_log_info(const struct cpu *cpu); @@ -629,7 +624,7 @@ void cpu_mp_setup(void); /* * CPU initialization on APs. */ -void cpu_ap_setup(void); +void cpu_ap_setup(unsigned int ap_id); static inline unsigned int cpu_apic_id(unsigned int cpu) diff --git a/arch/x86/machine/cpu_i.h b/arch/x86/machine/cpu_i.h index 2c28573e..f877fce3 100644 --- a/arch/x86/machine/cpu_i.h +++ b/arch/x86/machine/cpu_i.h @@ -158,7 +158,6 @@ struct cpu { #endif /* __LP64__ */ volatile int state; // TODO Atomic accessors - void *boot_stack; alignas(CPU_DATA_ALIGN) char intr_stack[CPU_INTR_STACK_SIZE]; alignas(CPU_DATA_ALIGN) char df_stack[CPU_INTR_STACK_SIZE]; diff --git a/arch/x86/machine/pmap.c b/arch/x86/machine/pmap.c index c8f0437d..73c31ca4 100644 --- a/arch/x86/machine/pmap.c +++ b/arch/x86/machine/pmap.c @@ -484,7 +484,7 @@ pmap_setup_paging(void) } pmap_pte_t * __boot -pmap_ap_setup_paging(void) +pmap_ap_setup_paging(unsigned int ap_id) { struct pmap_cpu_table *cpu_table; struct pmap *pmap; @@ -494,7 +494,7 @@ pmap_ap_setup_paging(void) pmap_boot_enable_pgext(pgsize); pmap = (void *)BOOT_VTOP((uintptr_t)&pmap_kernel_pmap); - cpu_table = (void *)BOOT_VTOP((uintptr_t)pmap->cpu_tables[boot_ap_id]); + cpu_table = (void *)BOOT_VTOP((uintptr_t)pmap->cpu_tables[ap_id]); #ifdef CONFIG_X86_PAE return (void *)(uint32_t)cpu_table->root_ptp_pa; diff --git a/arch/x86/machine/pmap.h b/arch/x86/machine/pmap.h index 3a6a1209..d3a0d251 100644 --- a/arch/x86/machine/pmap.h +++ b/arch/x86/machine/pmap.h @@ -203,7 +203,7 @@ pmap_pte_t * pmap_setup_paging(void); /* * This function is called by the AP bootstrap code before paging is enabled. */ -pmap_pte_t * pmap_ap_setup_paging(void); +pmap_pte_t * pmap_ap_setup_paging(unsigned int ap_id); /* * Initialize the pmap module on APs. |