diff --git a/arch/risc-v/Kconfig b/arch/risc-v/Kconfig index 99d52ae8fa26c..a796f48b9d92d 100644 --- a/arch/risc-v/Kconfig +++ b/arch/risc-v/Kconfig @@ -461,19 +461,50 @@ 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" 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 23d2986b075d8..d3f1ea4af4a7b 100644 --- a/arch/risc-v/include/irq.h +++ b/arch/risc-v/include/irq.h @@ -697,27 +697,17 @@ irqstate_t up_irq_enable(void); * 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 +#ifdef CONFIG_ARCH_RV_CPUID_MAP 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_RV_CPUID_MAP */ #endif /* CONFIG_ARCH_HAVE_MULTICPU */ /**************************************************************************** diff --git a/arch/risc-v/src/common/riscv_cpuindex.c b/arch/risc-v/src/common/riscv_cpuindex.c index 891a554517854..b1d3baa020ce4 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 @@ -38,32 +36,31 @@ ****************************************************************************/ /**************************************************************************** - * Name: up_cpu_index + * Name: up_this_cpu * * Description: - * Return the real core number regardless CONFIG_SMP setting + * Return the logical core number. Default implementation is 1:1 mapping, + * i.e. physical=logical. * ****************************************************************************/ -#ifdef CONFIG_RISCV_PERCPU_SCRATCH -int up_cpu_index(void) +int up_this_cpu(void) { - return (int)riscv_mhartid(); + return riscv_hartid_to_cpuid((int)riscv_mhartid()); } -#endif +#ifdef CONFIG_ARCH_RV_CPUID_MAP /**************************************************************************** - * Name: up_this_cpu + * Name: up_cpu_index * * Description: - * Return the logical core number. Default implementation is 1:1 mapping, - * i.e. physical=logical. + * Return the real core number regardless CONFIG_SMP setting * ****************************************************************************/ -int up_this_cpu(void) +int up_cpu_index(void) { - return riscv_hartid_to_cpuid((int)riscv_mhartid()); + return (int)riscv_mhartid(); } /**************************************************************************** @@ -101,3 +98,4 @@ int weak_function riscv_cpuid_to_hartid(int cpu) return (int)riscv_mhartid(); #endif } +#endif /* CONFIG_ARCH_RV_CPUID_MAP */ diff --git a/arch/risc-v/src/common/riscv_internal.h b/arch/risc-v/src/common/riscv_internal.h index e94688214db35..653d889b9313f 100644 --- a/arch/risc-v/src/common/riscv_internal.h +++ b/arch/risc-v/src/common/riscv_internal.h @@ -356,40 +356,24 @@ void riscv_cpu_boot(int cpu); int riscv_smp_call_handler(int irq, void *c, void *arg); #endif +#ifdef CONFIG_ARCH_RV_CPUID_MAP /**************************************************************************** - * Name: riscv_mhartid + * Name: riscv_mhartid / riscv_hartid_to_cpuid / riscv_cpuid_to_hartid * * Description: - * Context aware way to query hart id (physical core ID) - * - * Returned Value: - * Hart id + * CPU ID mapping functions for systems where physical hart IDs don't match + * logical CPU IDs. * ****************************************************************************/ 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 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_mhartid() (up_cpu_index()) +#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 */ diff --git a/arch/risc-v/src/common/riscv_macros.S b/arch/risc-v/src/common/riscv_macros.S index 11c246cef22a6..2273d8fff7ddc 100644 --- a/arch/risc-v/src/common/riscv_macros.S +++ b/arch/risc-v/src/common/riscv_macros.S @@ -359,7 +359,7 @@ ****************************************************************************/ .macro riscv_mhartid out -#ifdef CONFIG_RISCV_PERCPU_SCRATCH +#ifdef CONFIG_ARCH_RV_CPUID_MAP csrr \out, CSR_SCRATCH REGLOAD \out, RISCV_PERCPU_HARTID(\out) #else