diff --git a/arch/risc-v/Kconfig b/arch/risc-v/Kconfig index 99d52ae8fa26c..0f5d213d57175 100644 --- a/arch/risc-v/Kconfig +++ b/arch/risc-v/Kconfig @@ -461,19 +461,51 @@ config ARCH_RV_MMIO_BITS default 32 if ARCH_RV32 default 64 if ARCH_RV64 +config ARCH_RV_CPUID_MAP + bool "Enable CPUID mapping" + default n + ---help--- + Enable CPUID mapping for systems where the hardware CPU IDs + need to be mapped to logical CPU IDs. This is useful for + systems with non-contiguous or non-linear CPU numbering. + config ARCH_RV_HARTID_BASE int "Base hartid of this cluster" + depends on ARCH_RV_CPUID_MAP default 0 ---help--- - Some RV chips have multiple cluster of harts with - globally numbered mhartids, like qemu-rv, mpfs and - jh7110 etc. Clusters with SMP ability can be managed - by NuttX. As NuttX expects cluster-local hart ids, - we can shift mhartid by this value to derive such - local ids. The SMP_NCPUS still defines number of - harts in the cluster. Note that we assume that global - ids for each cluster are continuous. Note that there - are chips like k230 which don't have global mhartid. + This setting is used in multi-cluster RISC-V systems where each hardware + thread (hart) has a globally unique mhartid value. + + Purpose: + - Maps global hardware thread IDs (mhartid) to cluster-local IDs + - Enables NuttX to work with cluster-local hart IDs while maintaining + global uniqueness across the system + + Example: + In a system with: + - Cluster A: harts 100-103 + - Cluster B: harts 200-203 + - Cluster C: harts 300-303 + + If this is Cluster B's configuration, set ARCH_RV_HARTID_BASE=200. + NuttX will then map: + - Global hart 200 -> Local hart 0 + - Global hart 201 -> Local hart 1 + - Global hart 202 -> Local hart 2 + - Global hart 203 -> Local hart 3 + + Key Points: + 1. SMP_NCPUS defines the number of harts in this cluster + 2. Global hart IDs within a cluster must be consecutive + 3. Some chips like K230 don't use global mhartid numbering + 4. The base value should match the starting mhartid of this cluster + 5. Local hart IDs always start from 0 within each cluster + + Special Cases: + - For chips like K230 that don't use global mhartid numbering, + this value should typically be set to 0 + - In single-cluster systems, this can usually remain at default (0) config ARCH_FAMILY string diff --git a/arch/risc-v/include/irq.h b/arch/risc-v/include/irq.h index 7d21cdce5cd0d..a06a57f276f6d 100644 --- a/arch/risc-v/include/irq.h +++ b/arch/risc-v/include/irq.h @@ -691,34 +691,16 @@ EXTERN volatile bool g_interrupt_context[CONFIG_SMP_NCPUS]; irqstate_t up_irq_enable(void); +#ifdef CONFIG_ARCH_RV_CPUID_MAP /**************************************************************************** * Name: up_cpu_index * * Description: * Return the real core number regardless CONFIG_SMP setting * - * When CONFIG_RISCV_PERCPU_SCRATCH is enabled, this uses the percpu - * scratch area to store the hart ID. This is needed when the CSR_MHARTID - * register may not contain the actual hart ID. - * - * When CONFIG_RISCV_PERCPU_SCRATCH is not enabled, this directly reads - * the CSR_MHARTID register. Use this version when you can guarantee - * CSR_MHARTID contains the actual hart ID. This is the default behavior - * that can be achieved by single instruction to provide better - * performance. - * ****************************************************************************/ -#ifdef CONFIG_ARCH_HAVE_MULTICPU -#ifdef CONFIG_RISCV_PERCPU_SCRATCH int up_cpu_index(void) noinstrument_function; -#else -noinstrument_function static inline int up_cpu_index(void) -{ - return READ_CSR(CSR_MHARTID); -} -#endif -#endif /* CONFIG_ARCH_HAVE_MULTICPU */ /**************************************************************************** * Name: up_this_cpu @@ -730,6 +712,14 @@ noinstrument_function static inline int up_cpu_index(void) ****************************************************************************/ int up_this_cpu(void); +#else +noinstrument_function static inline int up_cpu_index(void) +{ + return READ_CSR(CSR_MHARTID); +} + +#define up_this_cpu() up_cpu_index() +#endif /* CONFIG_ARCH_RV_CPUID_MAP */ /**************************************************************************** * Inline Functions diff --git a/arch/risc-v/src/common/CMakeLists.txt b/arch/risc-v/src/common/CMakeLists.txt index b7713708e0372..8044dd5d97f44 100644 --- a/arch/risc-v/src/common/CMakeLists.txt +++ b/arch/risc-v/src/common/CMakeLists.txt @@ -49,7 +49,7 @@ if(CONFIG_SMP) list(APPEND SRCS riscv_smpcall.c riscv_cpustart.c) endif() -if(CONFIG_ARCH_HAVE_MULTICPU) +if(CONFIG_ARCH_RV_CPUID_MAP) list(APPEND SRCS riscv_cpuindex.c) endif() diff --git a/arch/risc-v/src/common/Make.defs b/arch/risc-v/src/common/Make.defs index 7b1cafdaa0263..a812ecd4017f1 100644 --- a/arch/risc-v/src/common/Make.defs +++ b/arch/risc-v/src/common/Make.defs @@ -52,7 +52,7 @@ ifeq ($(CONFIG_SMP),y) CMN_CSRCS += riscv_smpcall.c riscv_cpustart.c endif -ifeq ($(CONFIG_ARCH_HAVE_MULTICPU),y) +ifeq ($(CONFIG_ARCH_RV_CPUID_MAP),y) CMN_CSRCS += riscv_cpuindex.c endif diff --git a/arch/risc-v/src/common/riscv_cpuindex.c b/arch/risc-v/src/common/riscv_cpuindex.c index 891a554517854..fc6f51b01728f 100644 --- a/arch/risc-v/src/common/riscv_cpuindex.c +++ b/arch/risc-v/src/common/riscv_cpuindex.c @@ -26,8 +26,6 @@ #include -#include - #include #include @@ -45,12 +43,10 @@ * ****************************************************************************/ -#ifdef CONFIG_RISCV_PERCPU_SCRATCH int up_cpu_index(void) { return (int)riscv_mhartid(); } -#endif /**************************************************************************** * Name: up_this_cpu diff --git a/arch/risc-v/src/common/riscv_internal.h b/arch/risc-v/src/common/riscv_internal.h index e94688214db35..bd0a85e9599e5 100644 --- a/arch/risc-v/src/common/riscv_internal.h +++ b/arch/risc-v/src/common/riscv_internal.h @@ -369,27 +369,22 @@ int riscv_smp_call_handler(int irq, void *c, void *arg); uintptr_t riscv_mhartid(void); +#ifdef CONFIG_ARCH_RV_CPUID_MAP /**************************************************************************** - * Name: riscv_hartid_to_cpuid + * Name: riscv_hartid_to_cpuid / riscv_cpuid_to_hartid * * Description: - * Convert physical core number to logical core number. Default - * implementation is 1:1 mapping, i.e. physical=logical. + * CPU ID mapping functions for systems where physical hart IDs don't match + * logical CPU IDs. * ****************************************************************************/ int riscv_hartid_to_cpuid(int hart); - -/**************************************************************************** - * 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); +#else +#define riscv_hartid_to_cpuid(hart) (hart) +#define riscv_cpuid_to_hartid(cpu) (cpu) +#endif /* CONFIG_ARCH_RV_CPUID_MAP */ /* If kernel runs in Supervisor mode, a system call trampoline is needed */