From 6acdc4ee90a39557b92a9a17c87fbda51b0ad8da Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Wed, 30 Oct 2024 22:26:58 +0800 Subject: [PATCH 1/4] soc: andestech: soc_per_core_init_hook() shouldn't return value The `soc_per_core_init_hook()` function now has `void` type after da118b9, so it should just return without any value. Signed-off-by: Yong Cong Sin Signed-off-by: Yong Cong Sin --- soc/andestech/ae350/pma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soc/andestech/ae350/pma.c b/soc/andestech/ae350/pma.c index 71da2248b728be..7e1e07111adf4f 100644 --- a/soc/andestech/ae350/pma.c +++ b/soc/andestech/ae350/pma.c @@ -216,7 +216,7 @@ 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(); From 6a6b4f5a2edd67b91b7faac29f24be24af448c45 Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Wed, 30 Oct 2024 22:19:51 +0800 Subject: [PATCH 2/4] init: support per-core init hook Allow SoC to implement their custom per-core initialization function by selecting `CONFIG_SOC_PER_CORE_INIT_HOOK` and implement `soc_per_core_init_hook()`. Signed-off-by: Maxim Adelman Signed-off-by: Yong Cong Sin Signed-off-by: Yong Cong Sin --- arch/arc/core/smp.c | 6 ++++++ arch/arc/include/kernel_arch_func.h | 6 ++++++ arch/arm/core/cortex_a_r/smp.c | 5 +++++ arch/arm/include/cortex_a_r/kernel_arch_func.h | 5 +++++ arch/arm/include/cortex_m/kernel_arch_func.h | 6 ++++++ arch/arm64/core/smp.c | 5 +++++ arch/arm64/include/kernel_arch_func.h | 6 ++++++ arch/mips/include/kernel_arch_func.h | 5 +++++ arch/nios2/include/kernel_arch_func.h | 5 +++++ arch/posix/include/kernel_arch_func.h | 6 +++++- arch/riscv/core/smp.c | 4 ++++ arch/riscv/include/kernel_arch_func.h | 5 +++++ arch/sparc/include/kernel_arch_func.h | 5 +++++ arch/x86/include/ia32/kernel_arch_func.h | 6 +++++- arch/x86/include/intel64/kernel_arch_func.h | 6 +++++- arch/xtensa/include/kernel_arch_func.h | 5 ++++- include/zephyr/platform/hooks.h | 8 ++++++++ kernel/Kconfig.init | 9 +++++++++ 18 files changed, 99 insertions(+), 4 deletions(-) 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 From b0e995594a184566f680719ed1e2cfe8462d2545 Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Wed, 30 Oct 2024 22:42:27 +0800 Subject: [PATCH 3/4] soc: andestech: run pma_init_per_core() with soc_per_core_init_hook() The function `pma_init_per_core()`, as its name suggest, should be run from every core, so call it from `soc_per_core_init_hook()` Signed-off-by: Yong Cong Sin Signed-off-by: Yong Cong Sin --- soc/andestech/ae350/CMakeLists.txt | 1 + soc/andestech/ae350/Kconfig | 1 + soc/andestech/ae350/pma.c | 9 --------- soc/andestech/ae350/pma.h | 15 +++++++++++++++ soc/andestech/ae350/soc.c | 16 ++++++++++++++++ 5 files changed, 33 insertions(+), 9 deletions(-) create mode 100644 soc/andestech/ae350/pma.h create mode 100644 soc/andestech/ae350/soc.c 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 7e1e07111adf4f..d880e7130973ca 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 @@ -218,6 +211,4 @@ void soc_early_init_hook(void) #endif 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..9f6db1c655c7de --- /dev/null +++ b/soc/andestech/ae350/pma.h @@ -0,0 +1,15 @@ +/* + * 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); diff --git a/soc/andestech/ae350/soc.c b/soc/andestech/ae350/soc.c new file mode 100644 index 00000000000000..2decfe4082651b --- /dev/null +++ b/soc/andestech/ae350/soc.c @@ -0,0 +1,16 @@ +/* + * 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 */ From b81917644261bd6c104c8c4431591297b2efb451 Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Fri, 1 Nov 2024 14:13:29 +0800 Subject: [PATCH 4/4] soc: andestech: refactor out soc_early_init_hook() from pma.c Refactor out the `soc_early_init_hook()` function from `pma.c` to `soc.c` which is always compiled so that it can be extended to run other init functions easily in the future. Then, restore the function in `pma.c` to `pma_init()`. Signed-off-by: Yong Cong Sin --- soc/andestech/ae350/pma.c | 2 +- soc/andestech/ae350/pma.h | 3 +++ soc/andestech/ae350/soc.c | 9 +++++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/soc/andestech/ae350/pma.c b/soc/andestech/ae350/pma.c index d880e7130973ca..326bdf372b9bfd 100644 --- a/soc/andestech/ae350/pma.c +++ b/soc/andestech/ae350/pma.c @@ -194,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; diff --git a/soc/andestech/ae350/pma.h b/soc/andestech/ae350/pma.h index 9f6db1c655c7de..459db7c98d9468 100644 --- a/soc/andestech/ae350/pma.h +++ b/soc/andestech/ae350/pma.h @@ -13,3 +13,6 @@ * (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 index 2decfe4082651b..852da6d8113426 100644 --- a/soc/andestech/ae350/soc.c +++ b/soc/andestech/ae350/soc.c @@ -14,3 +14,12 @@ void soc_per_core_init_hook(void) #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 */