arch/riscv: Boot secondary CPUs for SMP support

Secondary CPUs are now initialised and made available to the system. If
the system has more CPUs than configured via CONFIG_MP_NUM_CPUS, those
are still left looping as before.

Some implementations of `soc_interrupt_init` also changed to use
`arch_irq_lock` instead of `irq_lock`.

Signed-off-by: Ederson de Souza <ederson.desouza@intel.com>
This commit is contained in:
Ederson de Souza 2021-12-29 10:22:48 -08:00 committed by Anas Nashif
commit d9ab35577b
5 changed files with 66 additions and 10 deletions

View file

@ -13,6 +13,7 @@ zephyr_library_sources(
reboot.c reboot.c
reset.S reset.S
switch.S switch.S
smp.c
thread.c thread.c
) )

View file

@ -15,6 +15,9 @@ GTEXT(__reset)
/* imports */ /* imports */
GTEXT(_PrepC) GTEXT(_PrepC)
GTEXT(riscv_cpu_wake_flag)
GTEXT(riscv_cpu_sp)
GTEXT(z_riscv_secondary_cpu_init)
#if CONFIG_INCLUDE_RESET_VECTOR #if CONFIG_INCLUDE_RESET_VECTOR
SECTION_FUNC(reset, __reset) SECTION_FUNC(reset, __reset)
@ -33,18 +36,17 @@ SECTION_FUNC(reset, __reset)
* the C domain * the C domain
*/ */
SECTION_FUNC(TEXT, __initialize) SECTION_FUNC(TEXT, __initialize)
/*
* This will boot master core, just halt other cores.
* Note: need to be updated for complete SMP support
*/
csrr a0, mhartid csrr a0, mhartid
beqz a0, boot_master_core beqz a0, boot_first_core
loop_slave_core: li t0, CONFIG_MP_NUM_CPUS
blt a0, t0, boot_secondary_core
loop_unconfigured_cores:
wfi wfi
j loop_slave_core j loop_unconfigured_cores
boot_master_core: boot_first_core:
#ifdef CONFIG_FPU #ifdef CONFIG_FPU
/* /*
@ -93,3 +95,16 @@ aa_loop:
* and then enters kernel z_cstart * and then enters kernel z_cstart
*/ */
call _PrepC call _PrepC
boot_secondary_core:
la t0, riscv_cpu_wake_flag
RV_OP_LOADREG t0, 0x00(t0)
bne a0, t0, boot_secondary_core
/* Set up stack */
la t0, riscv_cpu_sp
RV_OP_LOADREG sp, 0x00(t0)
la t0, riscv_cpu_wake_flag
RV_OP_STOREREG x0, 0x00(t0)
j z_riscv_secondary_cpu_init

40
arch/riscv/core/smp.c Normal file
View file

@ -0,0 +1,40 @@
/*
* Copyright (c) 2021 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <kernel.h>
volatile struct {
arch_cpustart_t fn;
void *arg;
} riscv_cpu_init[CONFIG_MP_NUM_CPUS];
volatile uintptr_t riscv_cpu_wake_flag;
volatile void *riscv_cpu_sp;
void arch_start_cpu(int cpu_num, k_thread_stack_t *stack, int sz,
arch_cpustart_t fn, void *arg)
{
riscv_cpu_init[cpu_num].fn = fn;
riscv_cpu_init[cpu_num].arg = arg;
riscv_cpu_sp = Z_THREAD_STACK_BUFFER(stack) + sz;
riscv_cpu_wake_flag = cpu_num;
while (riscv_cpu_wake_flag != 0U) {
;
}
}
void z_riscv_secondary_cpu_init(int cpu_num)
{
#if defined(CONFIG_RISCV_SOC_INTERRUPT_INIT)
soc_interrupt_init();
#endif
#ifdef CONFIG_PMP_STACK_GUARD
z_riscv_configure_interrupt_stack_guard();
#endif
riscv_cpu_init[cpu_num].fn(riscv_cpu_init[cpu_num].arg);
}

View file

@ -107,7 +107,7 @@ int arch_irq_is_enabled(unsigned int irq)
__weak void soc_interrupt_init(void) __weak void soc_interrupt_init(void)
{ {
/* ensure that all interrupts are disabled */ /* ensure that all interrupts are disabled */
(void)irq_lock(); (void)arch_irq_lock();
__asm__ volatile ("csrwi mie, 0\n" __asm__ volatile ("csrwi mie, 0\n"
"csrwi mip, 0\n"); "csrwi mip, 0\n");

View file

@ -10,7 +10,7 @@
#if defined(CONFIG_RISCV_SOC_INTERRUPT_INIT) #if defined(CONFIG_RISCV_SOC_INTERRUPT_INIT)
void soc_interrupt_init(void) void soc_interrupt_init(void)
{ {
(void)irq_lock(); (void)arch_irq_lock();
__asm__ volatile ("csrwi mie, 0\n"); __asm__ volatile ("csrwi mie, 0\n");
} }