Skip to content

Commit

Permalink
arch/riscv: Implement cpuid mapping
Browse files Browse the repository at this point in the history
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)
  • Loading branch information
pussuw committed Oct 15, 2024
1 parent 319f0ea commit e2cb2f5
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 7 deletions.
1 change: 1 addition & 0 deletions arch/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
---help---
RISC-V 32 and 64-bit RV32 / RV64 architectures.

Expand Down
15 changes: 13 additions & 2 deletions arch/risc-v/include/irq.h
Original file line number Diff line number Diff line change
Expand Up @@ -709,14 +709,25 @@ 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
****************************************************************************/

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
Expand All @@ -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
Expand Down
44 changes: 43 additions & 1 deletion arch/risc-v/src/common/riscv_cpuindex.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
2 changes: 1 addition & 1 deletion arch/risc-v/src/common/riscv_cpustart.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,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
Expand Down
22 changes: 22 additions & 0 deletions arch/risc-v/src/common/riscv_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions arch/risc-v/src/common/riscv_ipi.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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);
}
Expand Down

0 comments on commit e2cb2f5

Please sign in to comment.