arch: riscv: fix hangup of multicore boot
This patch fixes hangup of RISC-V multicore boot. Currently boot sequence uses a riscv_cpu_wake_flag to notify wakeup request for secondary core(s). But initial value of riscv_cpu_wake_flag is undefined, so current mechanism is going to hangup if riscv_cpu_wake_flag and mhartid of secondary core have the same value. This is an example situation of this problem: - hart1: check riscv_cpu_wake_flag (value is 1) and end the loop - hart1: set riscv_cpu_wake_flag to 0 - hart0: set riscv_cpu_wake_flag to 1 hart0 expects it will be changed to 0 by hart1 but it has never happened Note: - hart0's mhartid is 0, hart1's mhartid is 1 - hart0 is main, hart1 is secondary in this example Signed-off-by: Katsuhiro Suzuki <katsuhiro@katsuster.net>
This commit is contained in:
parent
bcaa7c2bdb
commit
4ce5f7ebe1
2 changed files with 15 additions and 6 deletions
|
@ -93,16 +93,24 @@ aa_loop:
|
|||
|
||||
boot_secondary_core:
|
||||
#if CONFIG_MP_MAX_NUM_CPUS > 1
|
||||
la t0, riscv_cpu_wake_flag
|
||||
li t1, -1
|
||||
sr t1, 0(t0)
|
||||
la t0, riscv_cpu_boot_flag
|
||||
sr zero, 0(t0)
|
||||
|
||||
wait_secondary_wake_flag:
|
||||
la t0, riscv_cpu_wake_flag
|
||||
lr t0, 0(t0)
|
||||
bne a0, t0, boot_secondary_core
|
||||
bne a0, t0, wait_secondary_wake_flag
|
||||
|
||||
/* Set up stack */
|
||||
la t0, riscv_cpu_sp
|
||||
lr sp, 0(t0)
|
||||
|
||||
la t0, riscv_cpu_wake_flag
|
||||
sr zero, 0(t0)
|
||||
la t0, riscv_cpu_boot_flag
|
||||
li t1, 1
|
||||
sr t1, 0(t0)
|
||||
j z_riscv_secondary_cpu_init
|
||||
#else
|
||||
j loop_unconfigured_cores
|
||||
|
|
|
@ -17,6 +17,7 @@ volatile struct {
|
|||
} riscv_cpu_init[CONFIG_MP_MAX_NUM_CPUS];
|
||||
|
||||
volatile uintptr_t riscv_cpu_wake_flag;
|
||||
volatile uintptr_t riscv_cpu_boot_flag;
|
||||
volatile void *riscv_cpu_sp;
|
||||
|
||||
extern void __start(void);
|
||||
|
@ -28,7 +29,7 @@ void arch_start_cpu(int cpu_num, k_thread_stack_t *stack, int sz,
|
|||
riscv_cpu_init[cpu_num].arg = arg;
|
||||
|
||||
riscv_cpu_sp = Z_KERNEL_STACK_BUFFER(stack) + sz;
|
||||
riscv_cpu_wake_flag = _kernel.cpus[cpu_num].arch.hartid;
|
||||
riscv_cpu_boot_flag = 0U;
|
||||
|
||||
#ifdef CONFIG_PM_CPU_OPS
|
||||
if (pm_cpu_on(cpu_num, (uintptr_t)&__start)) {
|
||||
|
@ -37,8 +38,8 @@ void arch_start_cpu(int cpu_num, k_thread_stack_t *stack, int sz,
|
|||
}
|
||||
#endif
|
||||
|
||||
while (riscv_cpu_wake_flag != 0U) {
|
||||
;
|
||||
while (riscv_cpu_boot_flag == 0U) {
|
||||
riscv_cpu_wake_flag = _kernel.cpus[cpu_num].arch.hartid;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue