Skip to content
Open
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
2 changes: 0 additions & 2 deletions arch/arc/core/prep_c.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,7 @@ extern void arc_secureshield_init(void);

FUNC_NORETURN void z_prep_c(void)
{
#if defined(CONFIG_SOC_PREP_HOOK)
soc_prep_hook();
#endif

#ifdef CONFIG_ISA_ARCV3
arc_cluster_scm_enable();
Expand Down
3 changes: 1 addition & 2 deletions arch/arm/core/cortex_a_r/prep_c.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,8 @@ extern FUNC_NORETURN void z_cstart(void);
*/
FUNC_NORETURN 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]);

Expand Down
2 changes: 0 additions & 2 deletions arch/arm/core/cortex_m/prep_c.c
Original file line number Diff line number Diff line change
Expand Up @@ -197,9 +197,7 @@ extern FUNC_NORETURN void z_cstart(void);
*/
FUNC_NORETURN void z_prep_c(void)
{
#if defined(CONFIG_SOC_PREP_HOOK)
soc_prep_hook();
#endif

relocate_vector_table();
#if defined(CONFIG_CPU_HAS_FPU)
Expand Down
2 changes: 0 additions & 2 deletions arch/arm64/core/prep_c.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,7 @@ __weak void z_arm64_mm_init(bool is_primary_core) { }
*/
FUNC_NORETURN 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]);
Expand Down
3 changes: 1 addition & 2 deletions arch/mips/core/prep_c.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,8 @@ static void interrupt_init(void)

FUNC_NORETURN void z_prep_c(void)
{
#if defined(CONFIG_SOC_PREP_HOOK)
soc_prep_hook();
#endif

arch_bss_zero();

interrupt_init();
Expand Down
2 changes: 0 additions & 2 deletions arch/riscv/core/prep_c.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,7 @@ void soc_interrupt_init(void);

FUNC_NORETURN void z_prep_c(void)
{
#if defined(CONFIG_SOC_PREP_HOOK)
soc_prep_hook();
#endif

arch_bss_zero();
arch_data_copy();
Expand Down
3 changes: 1 addition & 2 deletions arch/sparc/core/prep_c.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,8 @@

FUNC_NORETURN void z_prep_c(void)
{
#if defined(CONFIG_SOC_PREP_HOOK)
soc_prep_hook();
#endif

arch_data_copy();
#if CONFIG_ARCH_CACHE
arch_cache_init();
Expand Down
3 changes: 1 addition & 2 deletions arch/x86/core/prep_c.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,8 @@ 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
Expand Down
3 changes: 1 addition & 2 deletions arch/xtensa/core/prep_c.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,8 @@ BUILD_ASSERT(CONFIG_DCACHE_LINE_SIZE == XCHAL_DCACHE_LINESIZE);
*/
FUNC_NORETURN 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
Expand Down
63 changes: 63 additions & 0 deletions doc/hardware/porting/arch.rst
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,69 @@ Some examples of architecture-specific steps that have to be taken:
race conditions.
* Setup FIRQ and regular IRQ handling on ARCv2.

Early Boot Sequence Hooks
=========================

Zephyr exposes several hooks (described in :zephyr_file:`include/zephyr/platform/hooks.h`)
that allow execution of SoC- or board-specific code at precise moments of the boot process.

The kernel takes care of calling most of the hooks from architecture-agnostic
code. However, some hooks must be called during the early boot process; since
this is implemented in architecture-specific code, the call to the hooks must
be implemented there too. The following gives a rough overview of the early
boot sequence and when hooks should be called by architecture-specific code:

* Execution begins in the function named :kconfig:option:`CONFIG_KERNEL_ENTRY`

* Architecture-specific state is re-initialized immediately if
:kconfig:option:`CONFIG_INIT_ARCH_HW_AT_BOOT` is enabled

* :c:func:`soc_early_reset_hook()` is called

* Providing a valid stack to this hook is not necessary.
However, the stack pointer register *may* be overwritten by
the hook before returning.

* On architectures with multiple stack pointers, there is usually a
"primary" register accessible directly and other "secondary" stack
pointer registers. The hook *may* only overwrite the "primary" stack
pointer register and must leave "secondary" stack pointer registers
untouched.

* For example, the ARM Cortex-A architecture defines one ``sp_<mode>``
register for each of the processor's execution modes; the ``sp``
general-purpose register internally corresponds to ``sp_<mode>``
of the processor's current execution mode. On this architecture,
:c:func:`soc_early_reset_hook()` is allowed to overwrite ``sp``
but not ``sp_<mode>`` of a different execution mode.

* This allows architecture-specific code to set up exception stacks
(when applicable) before calling :c:func:`soc_early_reset_hook`

* An initial stack for use during the rest of the early boot sequence is setup

* The architecture-specific "resume from suspend-to-RAM" logic is executed

* Refer to :kconfig:option:`CONFIG_PM_S2RAM` for more details, but note
that the rest of the early boot sequence is not executed if this
logic determines that an exit from suspend-to-RAM is ongoing

* :c:func:`soc_reset_hook()` is called

* *Architecture-specific work (in assembly) occurs here...*

* :c:func:`z_prep_c` is called

* This function is implemented in C by the architecture layer

* :c:func:`z_prep_c()` immediately calls :c:func:`soc_prep_hook()`

* *Architecture-specific work (in C) occurs here...*

* :c:func:`z_cstart` is called

* Architecture-agnostic code takes over when this function is called

Interrupt and Exception Handling
********************************

Expand Down
18 changes: 9 additions & 9 deletions include/zephyr/platform/hooks.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
* directly from application code but may be freely used within the OS.
*/

#ifdef CONFIG_SOC_EARLY_RESET_HOOK
#if defined(CONFIG_SOC_EARLY_RESET_HOOK) || defined(__DOXYGEN__)
/**
* @brief SoC hook executed before data RAM initialization, at the beginning
* of the reset vector.
Expand All @@ -33,9 +33,9 @@ void soc_early_reset_hook(void);
#define soc_early_reset_hook() do { } while (0)
#endif

#ifdef CONFIG_SOC_RESET_HOOK
#if defined(CONFIG_SOC_RESET_HOOK) || defined(__DOXYGEN__)
/**
* @brief SoC hook executed at the beginning of the reset vector.
* @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.
Expand All @@ -45,7 +45,7 @@ void soc_reset_hook(void);
#define soc_reset_hook() do { } while (0)
#endif

#ifdef CONFIG_SOC_PREP_HOOK
#if defined(CONFIG_SOC_PREP_HOOK) || defined(__DOXYGEN__)
/**
* @brief SoC hook executed after the reset vector.
*
Expand All @@ -57,7 +57,7 @@ void soc_prep_hook(void);
#define soc_prep_hook() do { } while (0)
#endif

#ifdef CONFIG_SOC_EARLY_INIT_HOOK
#if defined(CONFIG_SOC_EARLY_INIT_HOOK) || defined(__DOXYGEN__)
/**
* @brief SoC hook executed before the kernel and devices are initialized.
*
Expand All @@ -69,7 +69,7 @@ void soc_early_init_hook(void);
#define soc_early_init_hook() do { } while (0)
#endif

#ifdef CONFIG_SOC_LATE_INIT_HOOK
#if defined(CONFIG_SOC_LATE_INIT_HOOK) || defined(__DOXYGEN__)
/**
* @brief SoC hook executed after the kernel and devices are initialized.
*
Expand All @@ -81,7 +81,7 @@ void soc_late_init_hook(void);
#define soc_late_init_hook() do { } while (0)
#endif

#ifdef CONFIG_SOC_PER_CORE_INIT_HOOK
#if defined(CONFIG_SOC_PER_CORE_INIT_HOOK) || defined(__DOXYGEN__)
/**
* @brief SoC per-core initialization
*
Expand All @@ -93,7 +93,7 @@ void soc_per_core_init_hook(void);
#define soc_per_core_init_hook() do { } while (0)
#endif

#ifdef CONFIG_BOARD_EARLY_INIT_HOOK
#if defined(CONFIG_BOARD_EARLY_INIT_HOOK) || defined(__DOXYGEN__)
/**
* @brief Board hook executed before the kernel starts.
*
Expand All @@ -106,7 +106,7 @@ void board_early_init_hook(void);
#define board_early_init_hook() do { } while (0)
#endif

#ifdef CONFIG_BOARD_LATE_INIT_HOOK
#if defined(CONFIG_BOARD_LATE_INIT_HOOK) || defined(__DOXYGEN__)
/**
* @brief Board hook executed after the kernel starts.
*
Expand Down