diff --git a/arch/arc/core/prep_c.c b/arch/arc/core/prep_c.c index 0e4975cd3fc..2eb93730b31 100644 --- a/arch/arc/core/prep_c.c +++ b/arch/arc/core/prep_c.c @@ -23,6 +23,7 @@ #include #include #include +#include /* XXX - keep for future use in full-featured cache APIs */ #if 0 @@ -121,6 +122,10 @@ extern FUNC_NORETURN void z_cstart(void); void z_prep_c(void) { +#if defined(CONFIG_SOC_PREP_HOOK) + soc_prep_hook(); +#endif + #ifdef CONFIG_ISA_ARCV3 arc_cluster_scm_enable(); #endif diff --git a/arch/arm/core/cortex_a_r/prep_c.c b/arch/arm/core/cortex_a_r/prep_c.c index e510d06ee95..e3ae589f76e 100644 --- a/arch/arm/core/cortex_a_r/prep_c.c +++ b/arch/arm/core/cortex_a_r/prep_c.c @@ -21,6 +21,7 @@ #include #include #include +#include #if defined(CONFIG_ARMV7_R) || defined(CONFIG_ARMV7_A) #include @@ -147,6 +148,9 @@ extern FUNC_NORETURN void z_cstart(void); */ void z_prep_c(void) { +#if defined(CONFIG_SOC_PREP_HOOK) + soc_prep_hook(); +#endif /* Initialize tpidruro with our struct _cpu instance address */ write_tpidruro((uintptr_t)&_kernel.cpus[0]); diff --git a/arch/arm/core/cortex_m/prep_c.c b/arch/arm/core/cortex_m/prep_c.c index 422d45b57e1..d5fd0bbd498 100644 --- a/arch/arm/core/cortex_m/prep_c.c +++ b/arch/arm/core/cortex_m/prep_c.c @@ -20,6 +20,7 @@ #include #include #include +#include #if defined(__GNUC__) /* @@ -181,6 +182,10 @@ extern FUNC_NORETURN void z_cstart(void); */ void z_prep_c(void) { +#if defined(CONFIG_SOC_PREP_HOOK) + soc_prep_hook(); +#endif + relocate_vector_table(); #if defined(CONFIG_CPU_HAS_FPU) z_arm_floating_point_init(); diff --git a/arch/arm64/core/prep_c.c b/arch/arm64/core/prep_c.c index 1aca46f2376..261824b7928 100644 --- a/arch/arm64/core/prep_c.c +++ b/arch/arm64/core/prep_c.c @@ -16,6 +16,7 @@ #include #include +#include extern void z_arm64_mm_init(bool is_primary_core); @@ -30,6 +31,10 @@ __weak void z_arm64_mm_init(bool is_primary_core) { } */ void z_prep_c(void) { +#if defined(CONFIG_SOC_PREP_HOOK) + soc_prep_hook(); +#endif + /* Initialize tpidrro_el0 with our struct _cpu instance address */ write_tpidrro_el0((uintptr_t)&_kernel.cpus[0]); diff --git a/arch/mips/core/prep_c.c b/arch/mips/core/prep_c.c index 19673273b8a..bad0cc81de1 100644 --- a/arch/mips/core/prep_c.c +++ b/arch/mips/core/prep_c.c @@ -11,6 +11,7 @@ #include #include +#include static void interrupt_init(void) { @@ -44,6 +45,9 @@ static void interrupt_init(void) void z_prep_c(void) { +#if defined(CONFIG_SOC_PREP_HOOK) + soc_prep_hook(); +#endif z_bss_zero(); interrupt_init(); diff --git a/arch/nios2/core/prep_c.c b/arch/nios2/core/prep_c.c index 74a3454af48..dec82a67645 100644 --- a/arch/nios2/core/prep_c.c +++ b/arch/nios2/core/prep_c.c @@ -21,6 +21,7 @@ #include #include #include +#include /** * @brief Prepare to and run C code @@ -30,6 +31,10 @@ void z_prep_c(void) { +#if defined(CONFIG_SOC_PREP_HOOK) + soc_prep_hook(); +#endif + z_bss_zero(); z_data_copy(); /* In most XIP scenarios we copy the exception code into RAM, so need diff --git a/arch/riscv/core/prep_c.c b/arch/riscv/core/prep_c.c index b0fdd3a0569..645dfa7f4ff 100644 --- a/arch/riscv/core/prep_c.c +++ b/arch/riscv/core/prep_c.c @@ -19,6 +19,7 @@ #include #include #include +#include #if defined(CONFIG_RISCV_SOC_INTERRUPT_INIT) void soc_interrupt_init(void); @@ -33,6 +34,10 @@ void soc_interrupt_init(void); void z_prep_c(void) { +#if defined(CONFIG_SOC_PREP_HOOK) + soc_prep_hook(); +#endif + z_bss_zero(); z_data_copy(); #if defined(CONFIG_RISCV_SOC_INTERRUPT_INIT) diff --git a/arch/sparc/core/prep_c.c b/arch/sparc/core/prep_c.c index 9ad3955a190..981b2d57d1e 100644 --- a/arch/sparc/core/prep_c.c +++ b/arch/sparc/core/prep_c.c @@ -10,6 +10,7 @@ */ #include +#include /** * @brief Prepare to and run C code @@ -19,6 +20,9 @@ void z_prep_c(void) { +#if defined(CONFIG_SOC_PREP_HOOK) + soc_prep_hook(); +#endif z_data_copy(); z_cstart(); CODE_UNREACHABLE; diff --git a/arch/x86/core/prep_c.c b/arch/x86/core/prep_c.c index 4ff5ffcdc7e..e71dcfc7883 100644 --- a/arch/x86/core/prep_c.c +++ b/arch/x86/core/prep_c.c @@ -9,6 +9,7 @@ #include #include #include +#include extern FUNC_NORETURN void z_cstart(void); extern void x86_64_irq_init(void); @@ -25,6 +26,9 @@ FUNC_NORETURN void z_prep_c(void *arg) { x86_boot_arg_t *cpu_arg = arg; +#if defined(CONFIG_SOC_PREP_HOOK) + soc_prep_hook(); +#endif _kernel.cpus[0].nested = 0; #ifdef CONFIG_MMU diff --git a/arch/xtensa/core/prep_c.c b/arch/xtensa/core/prep_c.c index 63c774f0cef..3050f57a353 100644 --- a/arch/xtensa/core/prep_c.c +++ b/arch/xtensa/core/prep_c.c @@ -5,6 +5,7 @@ */ #include #include +#include extern FUNC_NORETURN void z_cstart(void); @@ -20,6 +21,9 @@ extern void soc_num_cpus_init(void); */ void z_prep_c(void) { +#if defined(CONFIG_SOC_PREP_HOOK) + soc_prep_hook(); +#endif #if CONFIG_SOC_HAS_RUNTIME_NUM_CPUS soc_num_cpus_init(); #endif diff --git a/include/zephyr/platform/hooks.h b/include/zephyr/platform/hooks.h new file mode 100644 index 00000000000..765b886a638 --- /dev/null +++ b/include/zephyr/platform/hooks.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2024 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_PLATFORM_PLATFORM_H_ +#define ZEPHYR_INCLUDE_PLATFORM_PLATFORM_H_ + +/** + * @file + * @brief Soc and Board hooks + * + * This header file contains function prototypes for the interfaces between + * zephyr architecture and initialization code and the SoC and board specific logic + * that resides under boards/ and soc/ + * + * @note These are all standard soc and board interfaces that are exported from + * soc and board specific logic to OS internal logic. These should never be accessed + * directly from application code but may be freely used within the OS. + */ + + +/** + * @brief SoC hook executed at the beginning of the reset vector. + * + * This hook is implemented by the SoC and can be used to perform any + * SoC-specific initialization. + */ +void soc_reset_hook(void); + +/** + * @brief SoC hook executed after the reset vector. + * + * + * This hook is implemented by the SoC and can be used to perform any + * SoC-specific initialization. + */ +void soc_prep_hook(void); + +/* + * @brief SoC hook executed before the kernel and devices are initialized. + * + * This hook is implemented by the SoC and can be used to perform any + * SoC-specific initialization. + */ +void soc_early_init_hook(void); + +/* + * @brief SoC hook executed after the kernel and devices are initialized. + * + * This hook is implemented by the SoC and can be used to perform any + * SoC-specific initialization. + */ +void soc_late_init_hook(void); + +/* + * @brief Board hook executed before the kernel starts. + * + * This is called before the kernel has started. This hook + * is implemented by the board and can be used to perform any board-specific + * initialization. + */ +void board_early_init_hook(void); + +/* + * @brief Board hook executed after the kernel starts. + + * This is called after the kernel has started, but before the main function is + * called. This hook is implemented by the board and can be used to perform + * any board-specific initialization. + */ +void board_late_init_hook(void); + +#endif diff --git a/kernel/Kconfig b/kernel/Kconfig index 27a8fbbb3fd..54e0ccf1f2d 100644 --- a/kernel/Kconfig +++ b/kernel/Kconfig @@ -1027,3 +1027,4 @@ endmenu rsource "Kconfig.device" rsource "Kconfig.vm" +rsource "Kconfig.init" diff --git a/kernel/Kconfig.init b/kernel/Kconfig.init new file mode 100644 index 00000000000..79121a96128 --- /dev/null +++ b/kernel/Kconfig.init @@ -0,0 +1,45 @@ +# Kernel init hook options + +# Copyright (c) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + + +menu "SoC and Board Hooks" + +config SOC_RESET_HOOK + bool "Run early SoC reset hook" + help + Run an early SoC reset hook. + + A custom hook soc_reset_hook() is executed at the beginning of the + startup code (__start). soc_reset_hook() must be implemented by the SoC. + +config SOC_PREP_HOOK + bool "Run early SoC preparation hook" + help + Run an early SoC preparation hook. + + A custom hook soc_prep_hook() is executed at the beginning of the + c prep code (prep_c). soc_prep_hook() must be implemented by the SoC. + +config SOC_EARLY_INIT_HOOK + bool "Run early SoC hook" + help + Run an early SoC initialization hook. + +config SOC_LATE_INIT_HOOK + bool "Run late SoC hook" + help + Run a late SoC initialization hook. + +config BOARD_EARLY_INIT_HOOK + bool "Run early board hook" + help + Run an early board initialization hook. + +config BOARD_LATE_INIT_HOOK + bool "Run late board hook" + help + Run a late board initialization hook. + +endmenu diff --git a/kernel/init.c b/kernel/init.c index 14a48c26e12..a6afabc2a2e 100644 --- a/kernel/init.c +++ b/kernel/init.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -516,6 +517,13 @@ static void bg_thread_main(void *unused1, void *unused2, void *unused3) z_sys_post_kernel = true; z_sys_init_run_level(INIT_LEVEL_POST_KERNEL); +#if CONFIG_SOC_LATE_INIT_HOOK + soc_late_init_hook(); +#endif +#if CONFIG_BOARD_LATE_INIT_HOOK + board_late_init_hook(); +#endif + #if defined(CONFIG_STACK_POINTER_RANDOM) && (CONFIG_STACK_POINTER_RANDOM != 0) z_stack_adjust_initialized = 1; #endif /* CONFIG_STACK_POINTER_RANDOM */ @@ -757,6 +765,12 @@ FUNC_NORETURN void z_cstart(void) /* do any necessary initialization of static devices */ z_device_state_init(); +#if CONFIG_SOC_EARLY_INIT_HOOK + soc_early_init_hook(); +#endif +#if CONFIG_BOARD_EARLY_INIT_HOOK + board_early_init_hook(); +#endif /* perform basic hardware initialization */ z_sys_init_run_level(INIT_LEVEL_PRE_KERNEL_1); #if defined(CONFIG_SMP)