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)
This commit is contained in:
parent
2195b47655
commit
737dc4fcdd
6 changed files with 83 additions and 7 deletions
|
@ -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 if ARCH_HAVE_MULTICPU
|
||||
---help---
|
||||
RISC-V 32 and 64-bit RV32 / RV64 architectures.
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -86,7 +86,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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue