summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorBo Gan <ganboing@gmail.com>2023-06-12 02:54:17 +0300
committerLeo Yu-Chi Liang <ycliang@andestech.com>2023-07-24 08:17:26 +0300
commit28ff3f16c432f53670d4f3867f003e0a86a5e1e6 (patch)
treed5b8649cab72a057c2b44e223bbbcd12107ff3e4 /arch
parent247aa5a191159ea7e03bf1918e22fbbb784cd410 (diff)
downloadu-boot-28ff3f16c432f53670d4f3867f003e0a86a5e1e6.tar.xz
riscv: setup per-hart stack earlier
Harts need to use per-hart stack before any function call, even if that function is a simple one. When the callee uses stack for register save/ restore, especially RA, if nested call, concurrent access by multiple harts on the same stack will cause data-race. This patch sets up SP before `board_init_f_alloc_reserve`. A side effect of this is that the memory layout has changed as the following: +----------------+ +----------------+ <----- SPL_STACK/ | ...... | | hart 0 stack | SYS_INIT_SP_ADDR | malloc_base | +----------------+ +----------------+ | hart 1 stack | | GD | +----------------+ If not SMP, N=1 +----------------+ | ...... | | hart 0 stack | +----------------+ +----------------+ ==> | hart N-1 stack| | hart 1 stack | +----------------+ +----------------+ | ...... | | ...... | | malloc_base | +----------------+ +----------------+ | hart N-1 stack| | GD | +----------------+ +----------------+ | | | | Signed-off-by: Bo Gan <ganboing@gmail.com> Cc: Rick Chen <rick@andestech.com> Cc: Leo <ycliang@andestech.com> Cc: Sean Anderson <seanga2@gmail.com> Cc: Bin Meng <bmeng.cn@gmail.com> Cc: Lukas Auer <lukas.auer@aisec.fraunhofer.de> Reviewed-by: Rick Chen <rick@andestech.com> Reviewed-by: Leo Yu-Chi Liang <ycliang@andestech.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/riscv/cpu/start.S37
1 files changed, 24 insertions, 13 deletions
diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S
index dad22bfea8..59d58a5a57 100644
--- a/arch/riscv/cpu/start.S
+++ b/arch/riscv/cpu/start.S
@@ -91,16 +91,35 @@ _start:
* Set stackpointer in internal/ex RAM to call board_init_f
*/
call_board_init_f:
- li t0, -16
#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK)
- li t1, CONFIG_SPL_STACK
+ li t0, CONFIG_SPL_STACK
#else
- li t1, SYS_INIT_SP_ADDR
+ li t0, SYS_INIT_SP_ADDR
#endif
- and sp, t1, t0 /* force 16 byte alignment */
+ and t0, t0, -16 /* force 16 byte alignment */
+
+ /* setup stack */
+#if CONFIG_IS_ENABLED(SMP)
+ /* tp: hart id */
+ slli t1, tp, CONFIG_STACK_SIZE_SHIFT
+ sub sp, t0, t1
+#else
+ mv sp, t0
+#endif
+/*
+ * Now sp points to the right stack belonging to current CPU.
+ * It's essential before any function call, otherwise, we get data-race.
+ */
call_board_init_f_0:
- mv a0, sp
+ /* find top of reserve space */
+#if CONFIG_IS_ENABLED(SMP)
+ li t1, CONFIG_NR_CPUS
+#else
+ li t1, 1
+#endif
+ slli t1, t1, CONFIG_STACK_SIZE_SHIFT
+ sub a0, t0, t1 /* t1 -> size of all CPU stacks */
jal board_init_f_alloc_reserve
/*
@@ -109,14 +128,6 @@ call_board_init_f_0:
*/
mv s0, a0
- /* setup stack */
-#if CONFIG_IS_ENABLED(SMP)
- /* tp: hart id */
- slli t0, tp, CONFIG_STACK_SIZE_SHIFT
- sub sp, a0, t0
-#else
- mv sp, a0
-#endif
/* Configure proprietary settings and customized CSRs of harts */
call_harts_early_init: