mirror of
https://github.com/apache/nuttx.git
synced 2025-01-12 22:08:35 +08:00
arch/risc-v: Make CPU index handling based on ARCH_RV_CPUID_MAP
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 <huangqi3@xiaomi.com>
This commit is contained in:
parent
cd83dc1317
commit
40bd8f9ad4
6 changed files with 75 additions and 47 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -26,8 +26,6 @@
|
|||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/irq.h>
|
||||
|
||||
|
@ -45,12 +43,10 @@
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_RISCV_PERCPU_SCRATCH
|
||||
int up_cpu_index(void)
|
||||
{
|
||||
return (int)riscv_mhartid();
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_this_cpu
|
||||
|
|
|
@ -362,6 +362,22 @@ 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
|
||||
*
|
||||
|
@ -369,27 +385,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 */
|
||||
|
||||
|
|
Loading…
Reference in a new issue