From e2cb2f55c239dcc36dd8591059175584d14db294 Mon Sep 17 00:00:00 2001 From: Ville Juven Date: Tue, 15 Oct 2024 15:57:29 +0300 Subject: [PATCH] arch/riscv: Implement cpuid mapping Implement hartid<->cpuid mapping for RISC-V. This is necessary for some platforms which cannot use 1:1 mapping between logical and physical CPU / core IDs. One example is MPFS where hart0 cannot be used for NuttX SMP as it is a less capable "monitor" core (E51) compared to the application cores hart1...3 (E54). Why not just use a generic offset then? We also need the physical hart ID for many things: - Communication between harts (IPI) - External interrupt acknowledgment (interrupt claim for specific CPU) - Communication to SBI Thus, create procedures that can do this translation: - The default mapping is still logical=physical. - Another flavor is to use the existing CONFIG_ARCH_RV_HARTID_BASE config variable, which is just a simple offset - The final flavor is to overload hartid<->cpuid on a per chip basis (no example for this is provided yet) --- arch/Kconfig | 1 + arch/risc-v/include/irq.h | 15 +++++++-- arch/risc-v/src/common/riscv_cpuindex.c | 44 ++++++++++++++++++++++++- arch/risc-v/src/common/riscv_cpustart.c | 2 +- arch/risc-v/src/common/riscv_internal.h | 22 +++++++++++++ arch/risc-v/src/common/riscv_ipi.h | 6 ++-- 6 files changed, 83 insertions(+), 7 deletions(-) diff --git a/arch/Kconfig b/arch/Kconfig index 584df27d4ded8..a6affb1d076e8 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -95,6 +95,7 @@ config ARCH_RISCV select ARCH_HAVE_THREAD_LOCAL select ARCH_HAVE_POWEROFF select ARCH_HAVE_LAZYFPU if ARCH_HAVE_FPU + select ARCH_HAVE_CPUID_MAPPING ---help--- RISC-V 32 and 64-bit RV32 / RV64 architectures. diff --git a/arch/risc-v/include/irq.h b/arch/risc-v/include/irq.h index e497f65720bd4..0b03e2652fc70 100644 --- a/arch/risc-v/include/irq.h +++ b/arch/risc-v/include/irq.h @@ -709,6 +709,17 @@ irqstate_t up_irq_enable(void); int up_cpu_index(void) noinstrument_function; #endif /* CONFIG_ARCH_HAVE_MULTICPU */ +/**************************************************************************** + * Name: up_this_cpu + * + * Description: + * Return the logical core number. Default implementation is 1:1 mapping, + * i.e. physical=logical. + * + ****************************************************************************/ + +int up_this_cpu(void); + /**************************************************************************** * Inline Functions ****************************************************************************/ @@ -716,7 +727,7 @@ int up_cpu_index(void) noinstrument_function; static inline_function uintreg_t *up_current_regs(void) { #ifdef CONFIG_SMP - return (uintreg_t *)g_current_regs[up_cpu_index()]; + return (uintreg_t *)g_current_regs[up_this_cpu()]; #else return (uintreg_t *)g_current_regs[0]; #endif @@ -725,7 +736,7 @@ static inline_function uintreg_t *up_current_regs(void) static inline_function void up_set_current_regs(uintreg_t *regs) { #ifdef CONFIG_SMP - g_current_regs[up_cpu_index()] = regs; + g_current_regs[up_this_cpu()] = regs; #else g_current_regs[0] = regs; #endif diff --git a/arch/risc-v/src/common/riscv_cpuindex.c b/arch/risc-v/src/common/riscv_cpuindex.c index c5db4151e7dc8..b7d3d9d53cbbc 100644 --- a/arch/risc-v/src/common/riscv_cpuindex.c +++ b/arch/risc-v/src/common/riscv_cpuindex.c @@ -45,5 +45,47 @@ int up_cpu_index(void) { - return (int)riscv_mhartid() - CONFIG_ARCH_RV_HARTID_BASE; + return (int)riscv_mhartid(); +} + +/**************************************************************************** + * Name: up_this_cpu + * + * Description: + * Return the logical core number. Default implementation is 1:1 mapping, + * i.e. physical=logical. + * + ****************************************************************************/ + +int up_this_cpu(void) +{ + return riscv_hartid_to_cpuid((int)riscv_mhartid()); +} + +/**************************************************************************** + * Name: riscv_hartid_to_cpuid + * + * Description: + * Convert physical core number to logical core number. Default + * implementation is 1:1 mapping, i.e. physical=logical. + * + ****************************************************************************/ + +int weak_function riscv_hartid_to_cpuid(int cpu) +{ + return cpu + CONFIG_ARCH_RV_HARTID_BASE; +} + +/**************************************************************************** + * Name: riscv_cpuid_to_hartid + * + * Description: + * Convert logical core number to physical core number. Default + * implementation is 1:1 mapping, i.e. physical=logical. + * + ****************************************************************************/ + +int weak_function riscv_cpuid_to_hartid(int cpu) +{ + return cpu - CONFIG_ARCH_RV_HARTID_BASE; } diff --git a/arch/risc-v/src/common/riscv_cpustart.c b/arch/risc-v/src/common/riscv_cpustart.c index a3141aff9ab89..35c11df14c25c 100644 --- a/arch/risc-v/src/common/riscv_cpustart.c +++ b/arch/risc-v/src/common/riscv_cpustart.c @@ -82,7 +82,7 @@ void riscv_cpu_boot(int cpu) #ifdef CONFIG_RISCV_PERCPU_SCRATCH /* Initialize the per CPU areas */ - riscv_percpu_add_hart((uintptr_t)cpu); + riscv_percpu_add_hart(riscv_cpuid_to_hartid(cpu)); #endif #ifdef CONFIG_BUILD_KERNEL diff --git a/arch/risc-v/src/common/riscv_internal.h b/arch/risc-v/src/common/riscv_internal.h index 1846bb8708a5e..bb6737f4a4f8d 100644 --- a/arch/risc-v/src/common/riscv_internal.h +++ b/arch/risc-v/src/common/riscv_internal.h @@ -427,6 +427,28 @@ int riscv_smp_call_handler(int irq, void *c, void *arg); uintptr_t riscv_mhartid(void); +/**************************************************************************** + * Name: riscv_hartid_to_cpuid + * + * Description: + * Convert physical core number to logical core number. Default + * implementation is 1:1 mapping, i.e. physical=logical. + * + ****************************************************************************/ + +int riscv_hartid_to_cpuid(int cpu); + +/**************************************************************************** + * Name: riscv_cpuid_to_hartid + * + * Description: + * Convert logical core number to physical core number. Default + * implementation is 1:1 mapping, i.e. physical=logical. + * + ****************************************************************************/ + +int riscv_cpuid_to_hartid(int cpu); + /* If kernel runs in Supervisor mode, a system call trampoline is needed */ #ifdef CONFIG_ARCH_USE_S_MODE diff --git a/arch/risc-v/src/common/riscv_ipi.h b/arch/risc-v/src/common/riscv_ipi.h index 5d8d2a400bdbb..9f61e5879860a 100644 --- a/arch/risc-v/src/common/riscv_ipi.h +++ b/arch/risc-v/src/common/riscv_ipi.h @@ -36,9 +36,9 @@ static inline void riscv_ipi_send(int cpu) { #if defined(CONFIG_ARCH_USE_S_MODE) - riscv_sbi_send_ipi(0x1, cpu); + riscv_sbi_send_ipi(0x1, riscv_cpuid_to_hartid(cpu)); #elif defined(RISCV_IPI) - putreg32(1, (uintptr_t)RISCV_IPI + (4 * cpu)); + putreg32(1, (uintptr_t)RISCV_IPI + (4 * riscv_cpuid_to_hartid(cpu))); #else # error "No IPI support for this SoC" #endif @@ -47,7 +47,7 @@ static inline void riscv_ipi_send(int cpu) static inline void riscv_ipi_clear(int cpu) { #if defined(RISCV_IPI) && !defined(CONFIG_ARCH_USE_S_MODE) - putreg32(0, (uintptr_t)RISCV_IPI + (4 * cpu)); + putreg32(0, (uintptr_t)RISCV_IPI + (4 * riscv_cpuid_to_hartid(cpu))); #endif CLEAR_CSR(CSR_IP, IP_SIP); }