diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index cbe566f8b7..70a7af9081 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -136,6 +136,17 @@ config ARCH_SINGLE_SECURITY_STATE GIC or other ARM architecture feature will with different configure +config ARM64_SMP_BUSY_WAIT + bool "Busy wait when SMP boot" + default n + depends on SMP + ---help--- + Enables busy wait when SMP boot + +config ARM64_SMP_BUSY_WAIT_FLAG_ADDR + hex "Busy wait flag address" + depends on ARM64_SMP_BUSY_WAIT + config ARCH_HAVE_EL3 bool default n diff --git a/arch/arm64/src/common/arm64_cpustart.c b/arch/arm64/src/common/arm64_cpustart.c index baa9ec8128..bee962f99c 100644 --- a/arch/arm64/src/common/arm64_cpustart.c +++ b/arch/arm64/src/common/arm64_cpustart.c @@ -207,6 +207,12 @@ int up_cpu_start(int cpu) sched_note_cpu_start(this_task(), cpu); #endif +#ifdef CONFIG_ARM64_SMP_BUSY_WAIT + uint32_t *address = (uint32_t *)CONFIG_ARM64_SMP_BUSY_WAIT_FLAG_ADDR; + *address = 1; + up_flush_dcache((uintptr_t)address, sizeof(address)); +#endif + arm64_start_cpu(cpu); return 0; diff --git a/arch/arm64/src/common/arm64_head.S b/arch/arm64/src/common/arm64_head.S index 320e4bc1e5..db415f4276 100644 --- a/arch/arm64/src/common/arm64_head.S +++ b/arch/arm64/src/common/arm64_head.S @@ -144,6 +144,16 @@ real_start: cmp x1, #0 beq primary_core + /* Wait until cpu0 notify */ + +#ifdef CONFIG_ARM64_SMP_BUSY_WAIT + ldr x2, =CONFIG_ARM64_SMP_BUSY_WAIT_FLAG_ADDR +1: + ldr x3, [x2, #0] + cmp x3, #0 + beq 1b +#endif + /* we can now load our stack pointer value and move on */ ldr x24, =g_cpu_idlestackalloc