From cd58558edbe89e4789b0325e1d6e66316975e284 Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Mon, 16 Sep 2024 16:26:01 +0800 Subject: [PATCH] arch: riscv: smp: refactor IPI functions and guard with "sifive,clint0" Currently, the RISC-V SMP IPI implementation is CLINT-based. However, IPI in RISC-V is not necessarily always done through a CLINT, in SoC with PLIC connected to the MSIP (i.e. Andes AE350), IPI has to be routed through the PLIC. This patch refactor the IPI delivery into functions and guard it with `DT_HAS_COMPAT_STATUS_OKAY(sifive_clint0)`, so that for SoC that do not have a `sifive,clint0` device, and has a different IPI mechanism, they can implement their own `z_riscv_ipi_send()` & `z_riscv_ipi_clear()`. Signed-off-by: Yong Cong Sin Signed-off-by: Yong Cong Sin --- arch/riscv/core/smp.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/arch/riscv/core/smp.c b/arch/riscv/core/smp.c index 4ef287c4a7a561b..3dc35bd0dcf8a6c 100644 --- a/arch/riscv/core/smp.c +++ b/arch/riscv/core/smp.c @@ -12,6 +12,7 @@ #include #include #include +#include volatile struct { arch_cpustart_t fn; @@ -80,13 +81,13 @@ void arch_secondary_cpu_init(int hartid) #ifdef CONFIG_SMP -#define MSIP_BASE 0x2000000UL -#define MSIP(hartid) ((volatile uint32_t *)MSIP_BASE)[hartid] - static atomic_val_t cpu_pending_ipi[CONFIG_MP_MAX_NUM_CPUS]; #define IPI_SCHED 0 #define IPI_FPU_FLUSH 1 +void z_riscv_ipi_send(unsigned int cpu); +void z_riscv_ipi_clear(unsigned int cpu); + void arch_sched_directed_ipi(uint32_t cpu_bitmap) { unsigned int key = arch_irq_lock(); @@ -97,7 +98,7 @@ void arch_sched_directed_ipi(uint32_t cpu_bitmap) if ((i != id) && _kernel.cpus[i].arch.online && ((cpu_bitmap & BIT(i)) != 0)) { atomic_set_bit(&cpu_pending_ipi[i], IPI_SCHED); - MSIP(_kernel.cpus[i].arch.hartid) = 1; + z_riscv_ipi_send(i); } } @@ -113,7 +114,7 @@ void arch_sched_broadcast_ipi(void) void arch_flush_fpu_ipi(unsigned int cpu) { atomic_set_bit(&cpu_pending_ipi[cpu], IPI_FPU_FLUSH); - MSIP(_kernel.cpus[cpu].arch.hartid) = 1; + z_riscv_ipi_send(cpu); } #endif @@ -121,7 +122,7 @@ static void sched_ipi_handler(const void *unused) { ARG_UNUSED(unused); - MSIP(csr_read(mhartid)) = 0; + z_riscv_ipi_clear(_current_cpu->id); atomic_val_t pending_ipi = atomic_clear(&cpu_pending_ipi[_current_cpu->id]); @@ -164,6 +165,20 @@ void arch_spin_relax(void) } #endif +#if DT_HAS_COMPAT_STATUS_OKAY(sifive_clint0) +#define MSIP_BASE 0x2000000UL +#define MSIP(hartid) ((volatile uint32_t *)MSIP_BASE)[hartid] + +void z_riscv_ipi_send(unsigned int cpu) +{ + MSIP(_kernel.cpus[cpu].arch.hartid) = 1; +} + +void z_riscv_ipi_clear(unsigned int cpu) +{ + MSIP(_kernel.cpus[cpu].arch.hartid) = 0; +} + int arch_smp_init(void) { @@ -172,4 +187,6 @@ int arch_smp_init(void) return 0; } +#endif /* DT_HAS_COMPAT_STATUS_OKAY(sifive_clint0) */ + #endif /* CONFIG_SMP */