diff --git a/arch/arc/core/smp.c b/arch/arc/core/smp.c index e8463b7b53b355..1b06c2ac7d1119 100644 --- a/arch/arc/core/smp.c +++ b/arch/arc/core/smp.c @@ -16,6 +16,7 @@ #include #include #include +#include #include volatile struct { @@ -115,6 +116,11 @@ void arch_secondary_cpu_init(int cpu_num) DT_IRQ(DT_NODELABEL(ici), priority), 0); irq_enable(DT_IRQN(DT_NODELABEL(ici))); #endif + +#ifdef CONFIG_SOC_PER_CORE_INIT_HOOK + soc_per_core_init_hook(); +#endif /* CONFIG_SOC_PER_CORE_INIT_HOOK */ + /* call the function set by arch_cpu_start */ fn = arc_cpu_init[cpu_num].fn; diff --git a/arch/arc/include/kernel_arch_func.h b/arch/arc/include/kernel_arch_func.h index ca382a274f4b1b..73bd352a249806 100644 --- a/arch/arc/include/kernel_arch_func.h +++ b/arch/arc/include/kernel_arch_func.h @@ -26,6 +26,8 @@ #include +#include + #ifdef __cplusplus extern "C" { #endif @@ -33,6 +35,10 @@ extern "C" { static ALWAYS_INLINE void arch_kernel_init(void) { z_irq_setup(); + +#ifdef CONFIG_SOC_PER_CORE_INIT_HOOK + soc_per_core_init_hook(); +#endif /* CONFIG_SOC_PER_CORE_INIT_HOOK */ } diff --git a/arch/arm/core/cortex_a_r/smp.c b/arch/arm/core/cortex_a_r/smp.c index df9d0a686df537..d0e31acb1ed832 100644 --- a/arch/arm/core/cortex_a_r/smp.c +++ b/arch/arm/core/cortex_a_r/smp.c @@ -12,6 +12,7 @@ #include "zephyr/cache.h" #include "zephyr/kernel/thread_stack.h" #include "zephyr/toolchain/gcc.h" +#include #define INV_MPID UINT32_MAX @@ -198,6 +199,10 @@ void arch_secondary_cpu_init(void) */ #endif +#ifdef CONFIG_SOC_PER_CORE_INIT_HOOK + soc_per_core_init_hook(); +#endif /* CONFIG_SOC_PER_CORE_INIT_HOOK */ + fn = arm_cpu_boot_params.fn; arg = arm_cpu_boot_params.arg; barrier_dsync_fence_full(); diff --git a/arch/arm/include/cortex_a_r/kernel_arch_func.h b/arch/arm/include/cortex_a_r/kernel_arch_func.h index 3486d7d4d4e02d..ecd467f3c91eb3 100644 --- a/arch/arm/include/cortex_a_r/kernel_arch_func.h +++ b/arch/arm/include/cortex_a_r/kernel_arch_func.h @@ -20,6 +20,8 @@ #ifndef ZEPHYR_ARCH_ARM_INCLUDE_CORTEX_A_R_KERNEL_ARCH_FUNC_H_ #define ZEPHYR_ARCH_ARM_INCLUDE_CORTEX_A_R_KERNEL_ARCH_FUNC_H_ +#include + #ifdef __cplusplus extern "C" { #endif @@ -28,6 +30,9 @@ extern "C" { static ALWAYS_INLINE void arch_kernel_init(void) { +#ifdef CONFIG_SOC_PER_CORE_INIT_HOOK + soc_per_core_init_hook(); +#endif /* CONFIG_SOC_PER_CORE_INIT_HOOK */ } #ifndef CONFIG_USE_SWITCH diff --git a/arch/arm/include/cortex_m/kernel_arch_func.h b/arch/arm/include/cortex_m/kernel_arch_func.h index 132c056c91022c..bb79e3941066de 100644 --- a/arch/arm/include/cortex_m/kernel_arch_func.h +++ b/arch/arm/include/cortex_m/kernel_arch_func.h @@ -20,6 +20,8 @@ #ifndef ZEPHYR_ARCH_ARM_INCLUDE_CORTEX_M_KERNEL_ARCH_FUNC_H_ #define ZEPHYR_ARCH_ARM_INCLUDE_CORTEX_M_KERNEL_ARCH_FUNC_H_ +#include + #ifdef __cplusplus extern "C" { #endif @@ -53,6 +55,10 @@ static ALWAYS_INLINE void arch_kernel_init(void) */ z_arm_configure_static_mpu_regions(); #endif /* CONFIG_ARM_MPU */ + +#ifdef CONFIG_SOC_PER_CORE_INIT_HOOK + soc_per_core_init_hook(); +#endif /* CONFIG_SOC_PER_CORE_INIT_HOOK */ } static ALWAYS_INLINE void diff --git a/arch/arm64/core/smp.c b/arch/arm64/core/smp.c index bbb7f9634317d8..fd9d457ea7df55 100644 --- a/arch/arm64/core/smp.c +++ b/arch/arm64/core/smp.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include "boot.h" @@ -163,6 +164,10 @@ void arch_secondary_cpu_init(int cpu_num) #endif #endif +#ifdef CONFIG_SOC_PER_CORE_INIT_HOOK + soc_per_core_init_hook(); +#endif /* CONFIG_SOC_PER_CORE_INIT_HOOK */ + fn = arm64_cpu_boot_params.fn; arg = arm64_cpu_boot_params.arg; barrier_dsync_fence_full(); diff --git a/arch/arm64/include/kernel_arch_func.h b/arch/arm64/include/kernel_arch_func.h index d2c346be1f02c3..c37ea6257a50da 100644 --- a/arch/arm64/include/kernel_arch_func.h +++ b/arch/arm64/include/kernel_arch_func.h @@ -22,6 +22,8 @@ #include +#include + #ifdef __cplusplus extern "C" { #endif @@ -35,6 +37,10 @@ static ALWAYS_INLINE void arch_kernel_init(void) #ifdef CONFIG_XEN xen_enlighten_init(); #endif + +#ifdef CONFIG_SOC_PER_CORE_INIT_HOOK + soc_per_core_init_hook(); +#endif /* CONFIG_SOC_PER_CORE_INIT_HOOK */ } static inline void arch_switch(void *switch_to, void **switched_from) diff --git a/arch/mips/include/kernel_arch_func.h b/arch/mips/include/kernel_arch_func.h index b01cc1a4c65daa..7c35d1bf864a3c 100644 --- a/arch/mips/include/kernel_arch_func.h +++ b/arch/mips/include/kernel_arch_func.h @@ -19,6 +19,8 @@ #include +#include + #ifdef __cplusplus extern "C" { #endif @@ -26,6 +28,9 @@ extern "C" { #ifndef _ASMLANGUAGE static ALWAYS_INLINE void arch_kernel_init(void) { +#ifdef CONFIG_SOC_PER_CORE_INIT_HOOK + soc_per_core_init_hook(); +#endif /* CONFIG_SOC_PER_CORE_INIT_HOOK */ } static ALWAYS_INLINE void diff --git a/arch/nios2/include/kernel_arch_func.h b/arch/nios2/include/kernel_arch_func.h index 2df268a1c62454..464ba32a7a7388 100644 --- a/arch/nios2/include/kernel_arch_func.h +++ b/arch/nios2/include/kernel_arch_func.h @@ -22,6 +22,8 @@ #include +#include + #ifdef __cplusplus extern "C" { #endif @@ -30,6 +32,9 @@ extern "C" { static ALWAYS_INLINE void arch_kernel_init(void) { +#ifdef CONFIG_SOC_PER_CORE_INIT_HOOK + soc_per_core_init_hook(); +#endif /* CONFIG_SOC_PER_CORE_INIT_HOOK */ } static ALWAYS_INLINE void diff --git a/arch/posix/include/kernel_arch_func.h b/arch/posix/include/kernel_arch_func.h index bb8d36a089c624..98289d5d7c68ad 100644 --- a/arch/posix/include/kernel_arch_func.h +++ b/arch/posix/include/kernel_arch_func.h @@ -12,6 +12,8 @@ #include +#include + #ifndef _ASMLANGUAGE #ifdef __cplusplus @@ -20,7 +22,9 @@ extern "C" { static inline void arch_kernel_init(void) { - /* Nothing to be done */ +#ifdef CONFIG_SOC_PER_CORE_INIT_HOOK + soc_per_core_init_hook(); +#endif /* CONFIG_SOC_PER_CORE_INIT_HOOK */ } static ALWAYS_INLINE void diff --git a/arch/riscv/core/smp.c b/arch/riscv/core/smp.c index 15cb0063950194..208865ce5d47ab 100644 --- a/arch/riscv/core/smp.c +++ b/arch/riscv/core/smp.c @@ -12,6 +12,7 @@ #include #include #include +#include volatile struct { arch_cpustart_t fn; @@ -79,6 +80,9 @@ void arch_secondary_cpu_init(int hartid) /* Enable on secondary cores so that they can respond to PLIC */ irq_enable(RISCV_IRQ_MEXT); #endif /* CONFIG_PLIC_IRQ_AFFINITY */ +#ifdef CONFIG_SOC_PER_CORE_INIT_HOOK + soc_per_core_init_hook(); +#endif /* CONFIG_SOC_PER_CORE_INIT_HOOK */ riscv_cpu_init[cpu_num].fn(riscv_cpu_init[cpu_num].arg); } diff --git a/arch/riscv/include/kernel_arch_func.h b/arch/riscv/include/kernel_arch_func.h index c5ed6ff3f7f42e..a8fc863c75d064 100644 --- a/arch/riscv/include/kernel_arch_func.h +++ b/arch/riscv/include/kernel_arch_func.h @@ -18,6 +18,8 @@ #include #include +#include + #ifdef __cplusplus extern "C" { #endif @@ -53,6 +55,9 @@ static ALWAYS_INLINE void arch_kernel_init(void) #ifdef CONFIG_RISCV_PMP z_riscv_pmp_init(); #endif +#ifdef CONFIG_SOC_PER_CORE_INIT_HOOK + soc_per_core_init_hook(); +#endif /* CONFIG_SOC_PER_CORE_INIT_HOOK */ } static ALWAYS_INLINE void diff --git a/arch/sparc/include/kernel_arch_func.h b/arch/sparc/include/kernel_arch_func.h index 8b79b130ad6557..fc59fdf7aa69ee 100644 --- a/arch/sparc/include/kernel_arch_func.h +++ b/arch/sparc/include/kernel_arch_func.h @@ -17,6 +17,8 @@ #include +#include + #ifdef __cplusplus extern "C" { #endif @@ -24,6 +26,9 @@ extern "C" { #ifndef _ASMLANGUAGE static ALWAYS_INLINE void arch_kernel_init(void) { +#ifdef CONFIG_SOC_PER_CORE_INIT_HOOK + soc_per_core_init_hook(); +#endif /* CONFIG_SOC_PER_CORE_INIT_HOOK */ } void z_sparc_context_switch(struct k_thread *newt, struct k_thread *oldt); diff --git a/arch/x86/include/ia32/kernel_arch_func.h b/arch/x86/include/ia32/kernel_arch_func.h index a0521fca3da794..878281c7ba8961 100644 --- a/arch/x86/include/ia32/kernel_arch_func.h +++ b/arch/x86/include/ia32/kernel_arch_func.h @@ -14,13 +14,17 @@ #include /* For size_t */ +#include + #ifdef __cplusplus extern "C" { #endif static inline void arch_kernel_init(void) { - /* No-op on this arch */ +#ifdef CONFIG_SOC_PER_CORE_INIT_HOOK + soc_per_core_init_hook(); +#endif /* CONFIG_SOC_PER_CORE_INIT_HOOK */ } static ALWAYS_INLINE void diff --git a/arch/x86/include/intel64/kernel_arch_func.h b/arch/x86/include/intel64/kernel_arch_func.h index abf022fe5fd556..da553fd08ac725 100644 --- a/arch/x86/include/intel64/kernel_arch_func.h +++ b/arch/x86/include/intel64/kernel_arch_func.h @@ -8,6 +8,8 @@ #include +#include + #ifndef _ASMLANGUAGE extern void z_x86_switch(void *switch_to, void **switched_from); @@ -27,7 +29,9 @@ extern void z_x86_ipi_setup(void); static inline void arch_kernel_init(void) { - /* nothing */; +#ifdef CONFIG_SOC_PER_CORE_INIT_HOOK + soc_per_core_init_hook(); +#endif /* CONFIG_SOC_PER_CORE_INIT_HOOK */ } FUNC_NORETURN void z_x86_cpu_init(struct x86_cpuboot *cpuboot); diff --git a/arch/xtensa/include/kernel_arch_func.h b/arch/xtensa/include/kernel_arch_func.h index c422494ee2b36b..5e735dedffff76 100644 --- a/arch/xtensa/include/kernel_arch_func.h +++ b/arch/xtensa/include/kernel_arch_func.h @@ -14,6 +14,7 @@ #include #include #include +#include #include #ifdef __cplusplus @@ -25,7 +26,9 @@ K_KERNEL_STACK_ARRAY_DECLARE(z_interrupt_stacks, CONFIG_MP_MAX_NUM_CPUS, static ALWAYS_INLINE void arch_kernel_init(void) { - +#ifdef CONFIG_SOC_PER_CORE_INIT_HOOK + soc_per_core_init_hook(); +#endif /* CONFIG_SOC_PER_CORE_INIT_HOOK */ } void xtensa_switch(void *switch_to, void **switched_from); diff --git a/include/zephyr/platform/hooks.h b/include/zephyr/platform/hooks.h index 765b886a638034..d310b0c37ca477 100644 --- a/include/zephyr/platform/hooks.h +++ b/include/zephyr/platform/hooks.h @@ -53,6 +53,14 @@ void soc_early_init_hook(void); */ void soc_late_init_hook(void); +/** + * @brief SoC per-core initialization + * + * This hook is implemented by the SoC and can be used to perform any + * SoC-specific per-core initialization + */ +void soc_per_core_init_hook(void); + /* * @brief Board hook executed before the kernel starts. * diff --git a/kernel/Kconfig.init b/kernel/Kconfig.init index 21cb5d9d8f1209..495381638fb087 100644 --- a/kernel/Kconfig.init +++ b/kernel/Kconfig.init @@ -38,6 +38,15 @@ config SOC_LATE_INIT_HOOK A custom SoC hook soc_late_init_hook() is executed after the kernel and devices are initialized +config SOC_PER_CORE_INIT_HOOK + bool "Run SoC per-core initialization hook" + help + Run an SoC initialization hook for every core + + A custom SoC hook soc_per_core_init_hook() is executeds at the end of + arch_kernel_init() for the primary core, and at the end of arch_secondary_cpu_init() + for secondary cores. + config BOARD_EARLY_INIT_HOOK bool "Run early board hook" help diff --git a/soc/andestech/ae350/CMakeLists.txt b/soc/andestech/ae350/CMakeLists.txt index 583134a91ce2d2..a7dfd256f87832 100644 --- a/soc/andestech/ae350/CMakeLists.txt +++ b/soc/andestech/ae350/CMakeLists.txt @@ -3,6 +3,7 @@ zephyr_include_directories(.) zephyr_sources( + soc.c start.S soc_irq.S ) diff --git a/soc/andestech/ae350/Kconfig b/soc/andestech/ae350/Kconfig index 4d466048e847ce..d82c22e3819d35 100644 --- a/soc/andestech/ae350/Kconfig +++ b/soc/andestech/ae350/Kconfig @@ -92,6 +92,7 @@ config SOC_ANDES_V5_PMA bool "Andes V5 Physical Memory Attribute (PMA)" select ARCH_HAS_NOCACHE_MEMORY_SUPPORT select SOC_EARLY_INIT_HOOK + select SOC_PER_CORE_INIT_HOOK help This option enables the Andes V5 PMA, in order to support SW to configure physical memory attribute by PMA CSRs. The address diff --git a/soc/andestech/ae350/pma.c b/soc/andestech/ae350/pma.c index 71da2248b728be..326bdf372b9bfd 100644 --- a/soc/andestech/ae350/pma.c +++ b/soc/andestech/ae350/pma.c @@ -187,13 +187,6 @@ static void configure_nocache_region(void) } #endif /* CONFIG_NOCACHE_MEMORY */ -/* - * @brief Init PMA CSRs of each CPU core - * - * In SMP, each CPU has it's own PMA CSR and PMA CSR only affect one CPU. - * We should configure CSRs of all CPUs to make memory attribute - * (e.g. uncacheable) affects all CPUs. - */ void pma_init_per_core(void) { #ifdef CONFIG_NOCACHE_MEMORY @@ -201,7 +194,7 @@ void pma_init_per_core(void) #endif /* CONFIG_NOCACHE_MEMORY */ } -void soc_early_init_hook(void) +void pma_init(void) { unsigned long mmsc_cfg; @@ -216,8 +209,6 @@ void soc_early_init_hook(void) LOG_ERR("CPU doesn't support PMA. " "Please disable CONFIG_SOC_ANDES_V5_PMA"); #endif - return -ENODEV; + return; } - - pma_init_per_core(); } diff --git a/soc/andestech/ae350/pma.h b/soc/andestech/ae350/pma.h new file mode 100644 index 00000000000000..459db7c98d9468 --- /dev/null +++ b/soc/andestech/ae350/pma.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2021 Andes Technology Corporation + * Copyright (c) 2024 Meta Platforms + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * @brief Init PMA CSRs of each CPU core + * + * In SMP, each CPU has it's own PMA CSR and PMA CSR only affect one CPU. + * We should configure CSRs of all CPUs to make memory attribute + * (e.g. uncacheable) affects all CPUs. + */ +void pma_init_per_core(void); + +/* Initialize PMA */ +void pma_init(void); diff --git a/soc/andestech/ae350/soc.c b/soc/andestech/ae350/soc.c new file mode 100644 index 00000000000000..852da6d8113426 --- /dev/null +++ b/soc/andestech/ae350/soc.c @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2024 Meta Platforms + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "pma.h" + +#ifdef CONFIG_SOC_PER_CORE_INIT_HOOK +void soc_per_core_init_hook(void) +{ +#ifdef CONFIG_SOC_ANDES_V5_PMA + pma_init_per_core(); +#endif /* SOC_ANDES_V5_PMA */ +} +#endif /* CONFIG_SOC_PER_CORE_INIT_HOOK */ + +#ifdef CONFIG_SOC_EARLY_INIT_HOOK +void soc_early_init_hook(void) +{ +#ifdef CONFIG_SOC_ANDES_V5_PMA + pma_init(); +#endif /* CONFIG_SOC_ANDES_V5_PMA */ +} +#endif /* CONFIG_SOC_EARLY_INIT_HOOK */