diff --git a/arch/arc/core/smp.c b/arch/arc/core/smp.c index e8463b7b53b35..1b06c2ac7d111 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 ca382a274f4b1..73bd352a24980 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 df9d0a686df53..d0e31acb1ed83 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 3486d7d4d4e02..ecd467f3c91eb 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 132c056c91022..bb79e3941066d 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 bbb7f9634317d..fd9d457ea7df5 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 d2c346be1f02c..c37ea6257a50d 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 b01cc1a4c65da..7c35d1bf864a3 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 2df268a1c6245..464ba32a7a738 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 bb8d36a089c62..98289d5d7c68a 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/Kconfig b/arch/riscv/Kconfig index 575c9871c1304..b762f64526328 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -37,6 +37,38 @@ config RISCV_ALWAYS_SWITCH_THROUGH_ECALL and most people should say n here to minimize context switching overhead. +choice RISCV_SMP_IPI_IMPL + prompt "RISC-V SMP IPI implementation" + depends on SMP + default RISCV_SMP_IPI_CLINT if DT_HAS_SIFIVE_CLINT0_ENABLED + default RISCV_SMP_IPI_PLIC if PLIC_SUPPORTS_SOFT_INTERRUPT && PLIC_IRQ_AFFINITY + default RISCV_SMP_IPI_CUSTOM + +config RISCV_SMP_IPI_CLINT + bool "CLINT-based IPI" + depends on DT_HAS_SIFIVE_CLINT0_ENABLED + help + Use CLINT-based IPI implementation. + +config RISCV_SMP_IPI_PLIC + bool "PLIC-based IPI" + depends on PLIC_SUPPORTS_SOFT_INTERRUPT + depends on PLIC_IRQ_AFFINITY + help + Use PLIC-based IPI implementation. + +config RISCV_SMP_IPI_CUSTOM + bool "Custom IPI implementation" + help + Allow custom IPI implementation. + + When this is selected, the following functions must be provided: + - z_riscv_ipi_send() + - z_riscv_ipi_clear() + - arch_smp_init() + +endchoice # RISCV_SMP_IPI_IMPL + menu "RISCV Processor Options" config INCLUDE_RESET_VECTOR diff --git a/arch/riscv/core/ipi_clint.h b/arch/riscv/core/ipi_clint.h new file mode 100644 index 0000000000000..5698f3d2a5f4b --- /dev/null +++ b/arch/riscv/core/ipi_clint.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2021 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_ARCH_RISCV_CORE_IPI_CLINT_H_ +#define ZEPHYR_ARCH_RISCV_CORE_IPI_CLINT_H_ + +#include + +#define MSIP_BASE 0x2000000UL +#define MSIP(hartid) ((volatile uint32_t *)MSIP_BASE)[hartid] + +static ALWAYS_INLINE void z_riscv_ipi_send(unsigned int cpu) +{ + MSIP(_kernel.cpus[cpu].arch.hartid) = 1; +} + +static ALWAYS_INLINE void z_riscv_ipi_clear(unsigned int cpu) +{ + MSIP(_kernel.cpus[cpu].arch.hartid) = 0; +} + +static void sched_ipi_handler(const void *unused) +{ + ARG_UNUSED(unused); + + z_riscv_sched_ipi_handler(_current_cpu->id); +} + +int arch_smp_init(void) +{ + IRQ_CONNECT(RISCV_IRQ_MSOFT, 0, sched_ipi_handler, NULL, 0); + irq_enable(RISCV_IRQ_MSOFT); + + return 0; +} + +#endif /* ZEPHYR_ARCH_RISCV_CORE_IPI_CLINT_H_ */ diff --git a/arch/riscv/core/ipi_impl.h b/arch/riscv/core/ipi_impl.h new file mode 100644 index 0000000000000..0ab598d67e0ab --- /dev/null +++ b/arch/riscv/core/ipi_impl.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2024 Meta Platforms + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_ARCH_RISCV_CORE_IPI_IMPL_H_ +#define ZEPHYR_ARCH_RISCV_CORE_IPI_IMPL_H_ + +void z_riscv_sched_ipi_handler(unsigned int cpu_id); + +#ifdef CONFIG_RISCV_SMP_IPI_CLINT +#include "ipi_clint.h" +#elif defined(CONFIG_RISCV_SMP_IPI_PLIC) +#include "ipi_plic.h" +#else /* CONFIG_RISCV_SMP_IPI_CUSTOM */ +inline void z_riscv_ipi_send(unsigned int cpu); +inline void z_riscv_ipi_clear(unsigned int cpu); +int arch_smp_init(void); +#endif + +#endif /* ZEPHYR_ARCH_RISCV_CORE_IPI_IMPL_H_ */ diff --git a/arch/riscv/core/ipi_plic.h b/arch/riscv/core/ipi_plic.h new file mode 100644 index 0000000000000..7b56f0f733d48 --- /dev/null +++ b/arch/riscv/core/ipi_plic.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2024 Meta Platforms + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_ARCH_RISCV_CORE_IPI_PLIC_H_ +#define ZEPHYR_ARCH_RISCV_CORE_IPI_PLIC_H_ + +#include +#include +#include +#include +#include + +#define DT_DRV_COMPAT zephyr_ipi_plic + +#define IPI_PLIC_IRQS(n, _) DT_INST_IRQN_BY_IDX(0, n) + +/* Should get this from the devicetree, placeholder now */ +static const uint32_t ipi_irqs[CONFIG_MP_MAX_NUM_CPUS] = { + LISTIFY(CONFIG_MP_MAX_NUM_CPUS, IPI_PLIC_IRQS, (,)), +}; + +static ALWAYS_INLINE void z_riscv_ipi_send(unsigned int cpu) +{ + riscv_plic_irq_set_pending(ipi_irqs[cpu]); +} + +static ALWAYS_INLINE void z_riscv_ipi_clear(unsigned int cpu) +{ + ARG_UNUSED(cpu); + /* IRQ will be cleared by PLIC */ +} + +static void sched_ipi_handler(const void *arg) +{ + unsigned int cpu_id = POINTER_TO_UINT(arg); + + z_riscv_sched_ipi_handler(cpu_id); +} + +#define IPI_PLIC_IRQ_CONNECT(n, _) \ + IRQ_CONNECT(DT_INST_IRQN_BY_IDX(0, n), 1, sched_ipi_handler, UINT_TO_POINTER(n), 0); \ + irq_enable(n); \ + riscv_plic_irq_set_affinity(n, BIT(n)) + +int arch_smp_init(void) +{ + LISTIFY(CONFIG_MP_MAX_NUM_CPUS, IPI_PLIC_IRQ_CONNECT, (;)); + + return 0; +} + +#endif /* ZEPHYR_ARCH_RISCV_CORE_IPI_PLIC_H_ */ diff --git a/arch/riscv/core/smp.c b/arch/riscv/core/smp.c index 15cb006395019..26a9148061cd7 100644 --- a/arch/riscv/core/smp.c +++ b/arch/riscv/core/smp.c @@ -4,6 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include "ipi_impl.h" + #include #include #include @@ -12,6 +14,7 @@ #include #include #include +#include volatile struct { arch_cpustart_t fn; @@ -79,14 +82,14 @@ 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); } #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 @@ -101,7 +104,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); } } @@ -117,17 +120,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) +void z_riscv_sched_ipi_handler(unsigned int cpu_id) { - ARG_UNUSED(unused); + z_riscv_ipi_clear(cpu_id); - MSIP(csr_read(mhartid)) = 0; - - atomic_val_t pending_ipi = atomic_clear(&cpu_pending_ipi[_current_cpu->id]); + atomic_val_t pending_ipi = atomic_clear(&cpu_pending_ipi[cpu_id]); if (pending_ipi & ATOMIC_MASK(IPI_SCHED)) { z_sched_ipi(); @@ -168,12 +169,4 @@ void arch_spin_relax(void) } #endif -int arch_smp_init(void) -{ - - IRQ_CONNECT(RISCV_IRQ_MSOFT, 0, sched_ipi_handler, NULL, 0); - irq_enable(RISCV_IRQ_MSOFT); - - return 0; -} #endif /* CONFIG_SMP */ diff --git a/arch/riscv/include/kernel_arch_func.h b/arch/riscv/include/kernel_arch_func.h index c5ed6ff3f7f42..a8fc863c75d06 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 8b79b130ad655..fc59fdf7aa69e 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 a0521fca3da79..878281c7ba896 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 abf022fe5fd55..da553fd08ac72 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 c422494ee2b36..5e735dedffff7 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/boards/andestech/adp_xc7k_ae350/adp_xc7k_ae350.dts b/boards/andestech/adp_xc7k_ae350/adp_xc7k_ae350.dts index 09763df9fffb3..441abd6a69209 100644 --- a/boards/andestech/adp_xc7k_ae350/adp_xc7k_ae350.dts +++ b/boards/andestech/adp_xc7k_ae350/adp_xc7k_ae350.dts @@ -140,6 +140,19 @@ zephyr,code = ; }; }; + + ipi_plic: ipi_plic { + compatible = "zephyr,ipi-plic"; + interrupt-parent = <&plic_sw>; + interrupts = <1 1>, /* CPU 0 */ + <2 1>, /* CPU 1 */ + <3 1>, /* CPU 2 */ + <4 1>, /* CPU 3 */ + <5 1>, /* CPU 4 */ + <6 1>, /* CPU 5 */ + <7 1>, /* CPU 6 */ + <8 1>; /* CPU 7 */ + }; }; &l2_cache { diff --git a/dts/bindings/misc/zephyr,ipi-plic.yaml b/dts/bindings/misc/zephyr,ipi-plic.yaml new file mode 100644 index 0000000000000..2787c90888977 --- /dev/null +++ b/dts/bindings/misc/zephyr,ipi-plic.yaml @@ -0,0 +1,15 @@ +# Copyright (c) 2024 Meta Platforms +# SPDX-License-Identifier: Apache-2.0 + +description: IPI PLIC pseudo device + +compatible: "zephyr,ipi-plic" + +include: [base.yaml] + +properties: + interrupt-parent: + required: true + + interrupts: + required: true diff --git a/include/zephyr/platform/hooks.h b/include/zephyr/platform/hooks.h index 765b886a63803..d310b0c37ca47 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 21cb5d9d8f120..495381638fb08 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 583134a91ce2d..a7dfd256f8783 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 4d466048e847c..d82c22e3819d3 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 71da2248b728b..326bdf372b9bf 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 0000000000000..459db7c98d946 --- /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 0000000000000..852da6d811342 --- /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 */