summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Braun <rbraun@sceen.net>2018-07-07 16:16:33 +0200
committerRichard Braun <rbraun@sceen.net>2018-07-07 16:16:33 +0200
commitbf1ee95728d81204b0cb30aa8d59d67c6c699138 (patch)
tree3bfdafa1d0e2ca80472ff6d9a452551519e59681
parentb17e3aa862e30b66e93dba70aaf3ece1e5e2ed3f (diff)
x86/{boot,cpu}: rework AP boot stack management
-rw-r--r--arch/x86/machine/boot.c47
-rw-r--r--arch/x86/machine/boot.h9
-rw-r--r--arch/x86/machine/boot_asm.S4
-rw-r--r--arch/x86/machine/cpu.c24
-rw-r--r--arch/x86/machine/cpu.h7
-rw-r--r--arch/x86/machine/cpu_i.h1
-rw-r--r--arch/x86/machine/pmap.c4
-rw-r--r--arch/x86/machine/pmap.h2
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.