diff --git a/arch/Kconfig b/arch/Kconfig index 4a4e22efea9..f68669c0f4e 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -109,6 +109,7 @@ config RISCV select ARCH_HAS_THREAD_LOCAL_STORAGE select USE_SWITCH select USE_SWITCH_SUPPORTED + select SCHED_IPI_SUPPORTED if SMP imply XIP help RISCV architecture diff --git a/arch/riscv/core/smp.c b/arch/riscv/core/smp.c index ded7102c85b..22ed3d00fa1 100644 --- a/arch/riscv/core/smp.c +++ b/arch/riscv/core/smp.c @@ -4,7 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include #include +#include volatile struct { arch_cpustart_t fn; @@ -35,6 +37,61 @@ void z_riscv_secondary_cpu_init(int cpu_num) #endif #ifdef CONFIG_PMP_STACK_GUARD z_riscv_configure_interrupt_stack_guard(); +#endif +#ifdef CONFIG_SMP + irq_enable(RISCV_MACHINE_SOFT_IRQ); #endif riscv_cpu_init[cpu_num].fn(riscv_cpu_init[cpu_num].arg); } + +#ifdef CONFIG_SMP +static uintptr_t *get_hart_msip(int hart_id) +{ +#ifdef CONFIG_64BIT + return (uintptr_t *)(uint64_t)(RISCV_MSIP_BASE + (hart_id * 4)); +#else + return (uintptr_t *)(RISCV_MSIP_BASE + (hart_id * 4)); +#endif +} + +void arch_sched_ipi(void) +{ + unsigned int key; + uint32_t i; + uint8_t id; + + key = arch_irq_lock(); + + id = _current_cpu->id; + for (i = 0U; i < CONFIG_MP_NUM_CPUS; i++) { + if (i != id) { + volatile uint32_t *r = (uint32_t *)get_hart_msip(i); + *r = 1U; + } + } + + arch_irq_unlock(key); +} + +static void sched_ipi_handler(const void *unused) +{ + ARG_UNUSED(unused); + + volatile uint32_t *r = (uint32_t *)get_hart_msip(_current_cpu->id); + *r = 0U; + + z_sched_ipi(); +} + +static int riscv_smp_init(const struct device *dev) +{ + ARG_UNUSED(dev); + + IRQ_CONNECT(RISCV_MACHINE_SOFT_IRQ, 0, sched_ipi_handler, NULL, 0); + irq_enable(RISCV_MACHINE_SOFT_IRQ); + + return 0; +} + +SYS_INIT(riscv_smp_init, PRE_KERNEL_2, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); +#endif /* CONFIG_SMP */ diff --git a/soc/riscv/riscv-privilege/virt/soc.h b/soc/riscv/riscv-privilege/virt/soc.h index 48022407825..66dae5f5880 100644 --- a/soc/riscv/riscv-privilege/virt/soc.h +++ b/soc/riscv/riscv-privilege/virt/soc.h @@ -12,5 +12,6 @@ #define SIFIVE_SYSCON_TEST 0x00100000 #define RISCV_MTIME_BASE 0x0200BFF8 #define RISCV_MTIMECMP_BASE 0x02004000 +#define RISCV_MSIP_BASE 0x02000000 #endif