From a5c7f6681074788e0a7bc1cb202162ceec67f36e Mon Sep 17 00:00:00 2001 From: Aaron Durbin Date: Wed, 27 Aug 2014 14:45:59 -0500 Subject: [PATCH] arm64: include stack storage within ramstage Instead of defining the stacks by Kconfig options include the stack sizes for all the CPUs including each of their exception stacks. This allows for providing each CPU on startup a stack to work with. Note: this currently inherits CONFIG_STACK_SIZE from x86 because of the Kconfig mess of options not being guarded. BUG=chrome-os-partner:31545 BRANCH=None TEST=Built and booted into the kernel on ryu. Change-Id: Ie5fa1a8b78ed808a14efeb1717b98d6b0dd85eef Signed-off-by: Patrick Georgi Original-Commit-Id: 6524993f016aac2ac8cd9dba9fbdd9a59260a2b6 Original-Change-Id: Ica09dc256e6ce1dd032433d071894af5f445acdb Original-Signed-off-by: Aaron Durbin Original-Reviewed-on: https://chromium-review.googlesource.com/214669 Original-Reviewed-by: Furquan Shaikh Reviewed-on: http://review.coreboot.org/9013 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer --- src/arch/arm64/include/armv8/arch/cpu.h | 6 ++ src/arch/arm64/stage_entry.S | 77 ++++++++++++++++++------- 2 files changed, 62 insertions(+), 21 deletions(-) diff --git a/src/arch/arm64/include/armv8/arch/cpu.h b/src/arch/arm64/include/armv8/arch/cpu.h index 70311dd194..e80e739133 100644 --- a/src/arch/arm64/include/armv8/arch/cpu.h +++ b/src/arch/arm64/include/armv8/arch/cpu.h @@ -52,4 +52,10 @@ struct cpu_info *cpu_info(void); */ unsigned int smp_processor_id(void); +/* Return the top of the stack for the specified cpu. */ +void *cpu_get_stack(unsigned int cpu); + +/* Return the top of the exception stack for the specified cpu. */ +void *cpu_get_exception_stack(unsigned int cpu); + #endif /* __ARCH_CPU_H__ */ diff --git a/src/arch/arm64/stage_entry.S b/src/arch/arm64/stage_entry.S index 2d4b26dac9..1de8894f2a 100644 --- a/src/arch/arm64/stage_entry.S +++ b/src/arch/arm64/stage_entry.S @@ -30,13 +30,58 @@ #error Need to know what ELx processor starts up in. #endif +#define STACK_SZ CONFIG_STACK_SIZE +#define EXCEPTION_STACK_SZ CONFIG_STACK_SIZE + +/* + * The stacks for each of the armv8 cores grows down from _estack. It is sized + * according to MAX_CPUS. Additionally provide exception stacks for each CPU. + */ +.section .bss, "aw", @nobits +.global _stack +.global _estack +.balign STACK_SZ +_stack: +.space CONFIG_MAX_CPUS*STACK_SZ +_estack: + +.global _stack_exceptions +.global _estack_exceptions +.balign EXCEPTION_STACK_SZ +_stack_exceptions: +.space CONFIG_MAX_CPUS*EXCEPTION_STACK_SZ +_estack_exceptions: + +ENTRY(cpu_get_stack) + mov x1, #STACK_SZ + mul x0, x0, x1 + ldr x1, 1f + sub x0, x1, x0 + ret +.align 3 +1: + .quad _estack +ENDPROC(cpu_get_stack) + +ENTRY(cpu_get_exception_stack) + mov x1, #EXCEPTION_STACK_SZ + mul x0, x0, x1 + ldr x1, 1f + sub x0, x1, x0 + ret +.align 3 +1: + .quad _estack_exceptions +ENDPROC(cpu_get_exception_stack) + + ENTRY(seed_stack) /* * Initialize the stack to a known value. This is used to check for * stack overflow later in the boot process. */ ldr x0, .stack_bottom - ldr x1, .stack_top + mov x1, sp ldr x2, =0xdeadbeefdeadbeef ldr x3, =0x8 @@ -59,36 +104,26 @@ ENDPROC(seed_stack) * stack while keeping SP_ELx reserved for exception entry. */ ENTRY(arm64_c_environment) - ldr x0, .exception_stack_top - cmp x0, #0 - b.eq 2f + bl smp_processor_id /* x0 = cpu */ + mov x24, x0 + + + /* Set the exception stack for this cpu. */ + bl cpu_get_exception_stack msr SPSel, #1 isb - mov sp, x0 - 2: /* Have stack pointer use SP_EL0. */ msr SPSel, #0 isb - /* Load up the stack if non-zero. */ - ldr x0, .stack_top - cmp x0, #0 - b.eq 1f + /* Set stack for this cpu. */ + mov x0, x24 /* x0 = cpu */ + bl cpu_get_stack mov sp, x0 - 1: - ldr x1, .entry - br x1 - - .align 4 - .exception_stack_top: - .quad CONFIG_EXCEPTION_STACK_TOP - .stack_top: - .quad _estack - .entry: - .quad seed_stack + b seed_stack ENDPROC(arm64_c_environment) CPU_RESET_ENTRY(arm64_cpu_startup)