Skip to content

Commit

Permalink
arch: riscv: smp: refactor IPI functions and guard with "sifive,clint0"
Browse files Browse the repository at this point in the history
Currently, the RISC-V SMP IPI implementation is CLINT-based.
However, IPI in RISC-V is not necessarily always done through a
CLINT, in SoC with PLIC connected to the MSIP
(i.e. Andes AE350), IPI has to be routed through the PLIC.

This patch refactor the IPI delivery into functions and guard
it with `DT_HAS_COMPAT_STATUS_OKAY(sifive_clint0)`, so that
for SoC that do not have a `sifive,clint0` device, and has a
different IPI mechanism, they can implement their own
`z_riscv_ipi_send()` & `z_riscv_ipi_clear()`.

Signed-off-by: Yong Cong Sin <ycsin@meta.com>
Signed-off-by: Yong Cong Sin <yongcong.sin@gmail.com>
  • Loading branch information
ycsin committed Sep 16, 2024
1 parent 4c6b1e5 commit cd58558
Showing 1 changed file with 23 additions and 6 deletions.
29 changes: 23 additions & 6 deletions arch/riscv/core/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <zephyr/sys/atomic.h>
#include <zephyr/arch/riscv/irq.h>
#include <zephyr/drivers/pm_cpu_ops.h>
#include <zephyr/devicetree.h>

volatile struct {
arch_cpustart_t fn;
Expand Down Expand Up @@ -80,13 +81,13 @@ void arch_secondary_cpu_init(int hartid)

#ifdef CONFIG_SMP

#define MSIP_BASE 0x2000000UL
#define MSIP(hartid) ((volatile uint32_t *)MSIP_BASE)[hartid]

static atomic_val_t cpu_pending_ipi[CONFIG_MP_MAX_NUM_CPUS];
#define IPI_SCHED 0
#define IPI_FPU_FLUSH 1

void z_riscv_ipi_send(unsigned int cpu);
void z_riscv_ipi_clear(unsigned int cpu);

void arch_sched_directed_ipi(uint32_t cpu_bitmap)
{
unsigned int key = arch_irq_lock();
Expand All @@ -97,7 +98,7 @@ void arch_sched_directed_ipi(uint32_t cpu_bitmap)
if ((i != id) && _kernel.cpus[i].arch.online &&
((cpu_bitmap & BIT(i)) != 0)) {
atomic_set_bit(&cpu_pending_ipi[i], IPI_SCHED);
MSIP(_kernel.cpus[i].arch.hartid) = 1;
z_riscv_ipi_send(i);
}
}

Expand All @@ -113,15 +114,15 @@ void arch_sched_broadcast_ipi(void)
void arch_flush_fpu_ipi(unsigned int cpu)
{
atomic_set_bit(&cpu_pending_ipi[cpu], IPI_FPU_FLUSH);
MSIP(_kernel.cpus[cpu].arch.hartid) = 1;
z_riscv_ipi_send(cpu);
}
#endif

static void sched_ipi_handler(const void *unused)
{
ARG_UNUSED(unused);

MSIP(csr_read(mhartid)) = 0;
z_riscv_ipi_clear(_current_cpu->id);

atomic_val_t pending_ipi = atomic_clear(&cpu_pending_ipi[_current_cpu->id]);

Expand Down Expand Up @@ -164,6 +165,20 @@ void arch_spin_relax(void)
}
#endif

#if DT_HAS_COMPAT_STATUS_OKAY(sifive_clint0)
#define MSIP_BASE 0x2000000UL
#define MSIP(hartid) ((volatile uint32_t *)MSIP_BASE)[hartid]

Check notice on line 170 in arch/riscv/core/smp.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

arch/riscv/core/smp.c:170 -#define MSIP_BASE 0x2000000UL +#define MSIP_BASE 0x2000000UL

Check notice on line 170 in arch/riscv/core/smp.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

arch/riscv/core/smp.c:170 -#define MSIP_BASE 0x2000000UL +#define MSIP_BASE 0x2000000UL

Check notice on line 170 in arch/riscv/core/smp.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

arch/riscv/core/smp.c:170 -#define MSIP_BASE 0x2000000UL +#define MSIP_BASE 0x2000000UL

Check notice on line 170 in arch/riscv/core/smp.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

arch/riscv/core/smp.c:170 -#define MSIP_BASE 0x2000000UL +#define MSIP_BASE 0x2000000UL

Check notice on line 170 in arch/riscv/core/smp.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

arch/riscv/core/smp.c:170 -#define MSIP_BASE 0x2000000UL +#define MSIP_BASE 0x2000000UL

void z_riscv_ipi_send(unsigned int cpu)
{
MSIP(_kernel.cpus[cpu].arch.hartid) = 1;
}

void z_riscv_ipi_clear(unsigned int cpu)
{
MSIP(_kernel.cpus[cpu].arch.hartid) = 0;
}

int arch_smp_init(void)
{

Expand All @@ -172,4 +187,6 @@ int arch_smp_init(void)

return 0;
}
#endif /* DT_HAS_COMPAT_STATUS_OKAY(sifive_clint0) */

#endif /* CONFIG_SMP */

0 comments on commit cd58558

Please sign in to comment.