Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

arch: riscv: Add support for custom SOC IPI, per-core init #65824

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions arch/riscv/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,16 @@ config RISCV_SOC_HAS_CUSTOM_SYS_IO
the RISC-V SoC needs to do something different and more than reading and
writing the registers.

config RISCV_SOC_HAS_CUSTOM_SMP_IPI
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current implementation is using CLINT, I wonder if we should name this RISCV_SOC_SMP_IPI_CLINT instead to pave the way for the intro of RISCV_SOC_SMP_IPI_PLIC in the future, so that it is a choice between CLINT & PLIC, instead of default vs custom?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would make sense if we upstream our implementation as the default PLIC implementation, otherwise it would be unclear as to what the behavior would be if RISCV_SOC_SMP_IPI_CLINT was not set

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it should be fine as this is an arch-level Kconfig, would like to hear from @fkokosinski @npitre and others as well

bool
select SCHED_IPI_SUPPORTED
help
Hidden option to allow SoC to overwrite SMP IPI implementation
Enable this hidden option and do the following:
- implement arch_smp_init() which registers a custom SW IRQ handler
- implement arch_sched_directed_ipi()
- implement arch_flush_fpu_ipi()

config RISCV_SOC_CONTEXT_SAVE
bool "SOC-based context saving in IRQ handlers"
select RISCV_SOC_OFFSETS
Expand Down
19 changes: 14 additions & 5 deletions arch/riscv/core/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@
#include <ipi.h>
#include <zephyr/irq.h>
#include <zephyr/sys/atomic.h>
#include <zephyr/arch/arch_interface.h>
#include <zephyr/arch/riscv/irq.h>
#include <zephyr/drivers/pm_cpu_ops.h>
#include <zephyr/platform/hooks.h>

volatile struct {
arch_cpustart_t fn;
Expand Down Expand Up @@ -74,12 +76,17 @@ void arch_secondary_cpu_init(int hartid)
#endif
#ifdef CONFIG_SMP
irq_enable(RISCV_IRQ_MSOFT);
#endif
#ifdef CONFIG_SOC_SMP_PER_CORE_INIT_HOOK
soc_smp_per_core_init_hook();
Copy link
Member

@ycsin ycsin Sep 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should run this for the main core, probably by adding an invocation of this in arch_kernel_init() similar to the z_riscv_pmp_init(), so that the function is ran by the main core as well, otherwise this would be a per_secondary_core_init_hook

I also think that it would be nice to generalize this new hook as soc_per_core_init_hook() so that it is not SMP-specific. Any soc that would like some additional core initialization code can use this hook

#endif
riscv_cpu_init[cpu_num].fn(riscv_cpu_init[cpu_num].arg);
}

#ifdef CONFIG_SMP

#ifndef CONFIG_RISCV_SOC_HAS_CUSTOM_SMP_IPI

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

Expand All @@ -104,11 +111,6 @@ void arch_sched_directed_ipi(uint32_t cpu_bitmap)
arch_irq_unlock(key);
}

void arch_sched_broadcast_ipi(void)
{
arch_sched_directed_ipi(IPI_ALL_CPUS_MASK);
}

#ifdef CONFIG_FPU_SHARING
void arch_flush_fpu_ipi(unsigned int cpu)
{
Expand Down Expand Up @@ -172,4 +174,11 @@ int arch_smp_init(void)

return 0;
}

#endif /* CONFIG_RISCV_SOC_HAS_CUSTOM_SMP_IPI */

void arch_sched_broadcast_ipi(void)
{
arch_sched_directed_ipi(IPI_ALL_CPUS_MASK);
}
#endif /* CONFIG_SMP */
8 changes: 8 additions & 0 deletions include/zephyr/platform/hooks.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,14 @@ void soc_early_init_hook(void);
*/
void soc_late_init_hook(void);

/**
* @brief SoC per-core initialization during SMP bringup
*
* This hook is implemented by the SoC and can be used to perform any
* SoC-specific per-core initialization during SMP bringup
*/
void soc_smp_per_core_init_hook(void);

/*
* @brief Board hook executed before the kernel starts.
*
Expand Down
5 changes: 5 additions & 0 deletions kernel/Kconfig.init
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ config SOC_LATE_INIT_HOOK
help
Run a late SoC initialization hook.

config SOC_SMP_PER_CORE_INIT_HOOK
bool "Per-core initialization during SMP bringup SoC hook"
help
Per-core initialization during SMP bringup SoC hook

config BOARD_EARLY_INIT_HOOK
bool "Run early board hook"
help
Expand Down
Loading