Skip to content

Commit

Permalink
arch/risc-v: Make CPU index handling based on ARCH_RV_CPUID_MAP
Browse files Browse the repository at this point in the history
This patch refactors the CPU index handling in the RISC-V architecture to be based on the ARCH_RV_CPUID_MAP configuration.

Signed-off-by: Huang Qi <[email protected]>
  • Loading branch information
no1wudi authored and pussuw committed Jan 8, 2025
1 parent cd83dc1 commit 40bd8f9
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 47 deletions.
49 changes: 40 additions & 9 deletions arch/risc-v/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
28 changes: 9 additions & 19 deletions arch/risc-v/include/irq.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion arch/risc-v/src/common/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand Down
2 changes: 1 addition & 1 deletion arch/risc-v/src/common/Make.defs
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
4 changes: 0 additions & 4 deletions arch/risc-v/src/common/riscv_cpuindex.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@

#include <nuttx/config.h>

#include <stdint.h>

#include <nuttx/arch.h>
#include <nuttx/irq.h>

Expand All @@ -45,12 +43,10 @@
*
****************************************************************************/

#ifdef CONFIG_RISCV_PERCPU_SCRATCH
int up_cpu_index(void)
{
return (int)riscv_mhartid();
}
#endif

/****************************************************************************
* Name: up_this_cpu
Expand Down
37 changes: 24 additions & 13 deletions arch/risc-v/src/common/riscv_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -362,34 +362,45 @@ int riscv_smp_call_handler(int irq, void *c, void *arg);
* Description:
* Context aware way to query hart id (physical core ID)
*
* The function riscv_mhartid is designed to retrieve the hardware thread
* ID (hartid) in different execution modes of RISC-V. Its behavior depends
* on the configuration and execution mode:
*
* - In machine mode, riscv_mhartid reads directly from the CSR mhartid.
* - In supervisor mode, the hartid is stored in the percpu structure
* during boot because supervisor mode does not have access to CSR
* `shartid`. The SBI (Supervisor Binary Interface) provides the hartid
* in the a0 register (as per SBI ABI requirements), and it is the
* responsibility of the payload OS to store this value internally.
* We use the percpu scratch register for this purpose, as it is the only
* location that is unique for each CPU and non-volatile.
*
* Note: In flat (machine) mode, you could still read the hartid from CSR
* mhartid even if CONFIG_RISCV_PERCPU_SCRATCH is enabled.
*
* Returned Value:
* Hart id
*
****************************************************************************/

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 */

Expand Down

0 comments on commit 40bd8f9

Please sign in to comment.