init: s/ARCH/EARLY, call it just before arch kernel init
The `ARCH` init level was added to solve a specific problem, call init code (SYS_INIT/devices) before `z_cstart` in the `intel_adsp` platform. The documentation claims it runs before `z_cstart`, but this is only true if the SoC/arch takes care of calling: ```c z_sys_init_run_level(_SYS_INIT_LEVEL_ARCH); ``` Which is only true for `intel_adsp` nowadays. So in practice, we now have a platform specific init level. This patch proposes to do things in a slightly different way. First, level name is renamed to `EARLY`, to emphasize it runs in the early stage of the boot process. Then, it is handled by the Kernel (inside `z_cstart()` before calling `arch_kernel_init()`). This means that any platform can now use this level. For `intel_adsp`, there should be no changes, other than `gcov_static_init()` will be called before (I assume this will allow to obtain coverage for code called in EARLY?). Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
This commit is contained in:
parent
b219b5cba7
commit
e42f58ec94
10 changed files with 25 additions and 17 deletions
|
|
@ -1,7 +1,7 @@
|
|||
# originates from common-rom.ld
|
||||
|
||||
zephyr_linker_section(NAME init KVMA RAM_REGION GROUP RODATA_REGION)
|
||||
zephyr_linker_section_obj_level(SECTION init LEVEL ARCH)
|
||||
zephyr_linker_section_obj_level(SECTION init LEVEL EARLY)
|
||||
zephyr_linker_section_obj_level(SECTION init LEVEL PRE_KERNEL_1)
|
||||
zephyr_linker_section_obj_level(SECTION init LEVEL PRE_KERNEL_2)
|
||||
zephyr_linker_section_obj_level(SECTION init LEVEL POST_KERNEL)
|
||||
|
|
@ -9,7 +9,7 @@ zephyr_linker_section_obj_level(SECTION init LEVEL APPLICATION)
|
|||
zephyr_linker_section_obj_level(SECTION init LEVEL SMP)
|
||||
|
||||
zephyr_linker_section(NAME device KVMA RAM_REGION GROUP RODATA_REGION)
|
||||
zephyr_linker_section_obj_level(SECTION device LEVEL ARCH)
|
||||
zephyr_linker_section_obj_level(SECTION device LEVEL EARLY)
|
||||
zephyr_linker_section_obj_level(SECTION device LEVEL PRE_KERNEL_1)
|
||||
zephyr_linker_section_obj_level(SECTION device LEVEL PRE_KERNEL_2)
|
||||
zephyr_linker_section_obj_level(SECTION device LEVEL POST_KERNEL)
|
||||
|
|
|
|||
|
|
@ -343,11 +343,12 @@ allow the user to specify at what time during the boot sequence the init
|
|||
function will be executed. Any driver will specify one of four
|
||||
initialization levels:
|
||||
|
||||
``ARCH``
|
||||
Used very early in the boot process before ``z_cstart()`` is
|
||||
called. This can be used in architectures and SoCs that extend or
|
||||
implement architecture code and use drivers or system services that have
|
||||
to be initialized before calling ``z_cstart()``.
|
||||
``EARLY``
|
||||
Used very early in the boot process, right after entering the C domain
|
||||
(``z_cstart()``). This can be used in architectures and SoCs that extend
|
||||
or implement architecture code and use drivers or system services that
|
||||
have to be initialized before the Kernel calls any architecture specific
|
||||
initialization code.
|
||||
|
||||
``PRE_KERNEL_1``
|
||||
Used for devices that have no dependencies, such as those that rely
|
||||
|
|
|
|||
|
|
@ -62,4 +62,4 @@ static int winstream_console_init(const struct device *d)
|
|||
return 0;
|
||||
}
|
||||
|
||||
SYS_INIT(winstream_console_init, ARCH, CONFIG_CONSOLE_INIT_PRIORITY);
|
||||
SYS_INIT(winstream_console_init, EARLY, CONFIG_CONSOLE_INIT_PRIORITY);
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ extern "C" {
|
|||
* stack. The remaining levels are executed in the kernel's main task.
|
||||
*/
|
||||
|
||||
#define _SYS_INIT_LEVEL_ARCH 0
|
||||
#define _SYS_INIT_LEVEL_EARLY 0
|
||||
#define _SYS_INIT_LEVEL_PRE_KERNEL_1 1
|
||||
#define _SYS_INIT_LEVEL_PRE_KERNEL_2 2
|
||||
#define _SYS_INIT_LEVEL_POST_KERNEL 3
|
||||
|
|
@ -112,6 +112,12 @@ void z_sys_init_run_level(int32_t level);
|
|||
* Must be one of the following symbols, which are listed in the order
|
||||
* they are performed by the kernel:
|
||||
* \n
|
||||
* \li EARLY: Used very early in the boot process, right after entering the C
|
||||
* domain (``z_cstart()``). This can be used in architectures and SoCs that
|
||||
* extend or implement architecture code and use drivers or system services that
|
||||
* have to be initialized before the Kernel calls any architecture specific
|
||||
* initialization code.
|
||||
* \n
|
||||
* \li PRE_KERNEL_1: Used for initialization objects that have no dependencies,
|
||||
* such as those that rely solely on hardware present in the processor/SOC.
|
||||
* These objects cannot use any kernel services during configuration, since
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
* by level, sorted by priority within a level)
|
||||
*/
|
||||
__init_start = .;
|
||||
CREATE_OBJ_LEVEL(init, ARCH)
|
||||
CREATE_OBJ_LEVEL(init, EARLY)
|
||||
CREATE_OBJ_LEVEL(init, PRE_KERNEL_1)
|
||||
CREATE_OBJ_LEVEL(init, PRE_KERNEL_2)
|
||||
CREATE_OBJ_LEVEL(init, POST_KERNEL)
|
||||
|
|
@ -25,7 +25,7 @@
|
|||
* object parent. See above and include/device.h.
|
||||
*/
|
||||
__device_start = .;
|
||||
CREATE_OBJ_LEVEL(device, ARCH)
|
||||
CREATE_OBJ_LEVEL(device, EARLY)
|
||||
CREATE_OBJ_LEVEL(device, PRE_KERNEL_1)
|
||||
CREATE_OBJ_LEVEL(device, PRE_KERNEL_2)
|
||||
CREATE_OBJ_LEVEL(device, POST_KERNEL)
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
#include <zephyr/syscall_handler.h>
|
||||
|
||||
extern const struct init_entry __init_start[];
|
||||
extern const struct init_entry __init_ARCH_start[];
|
||||
extern const struct init_entry __init_EARLY_start[];
|
||||
extern const struct init_entry __init_PRE_KERNEL_1_start[];
|
||||
extern const struct init_entry __init_PRE_KERNEL_2_start[];
|
||||
extern const struct init_entry __init_POST_KERNEL_start[];
|
||||
|
|
@ -56,7 +56,7 @@ void z_device_state_init(void)
|
|||
void z_sys_init_run_level(int32_t level)
|
||||
{
|
||||
static const struct init_entry *levels[] = {
|
||||
__init_ARCH_start,
|
||||
__init_EARLY_start,
|
||||
__init_PRE_KERNEL_1_start,
|
||||
__init_PRE_KERNEL_2_start,
|
||||
__init_POST_KERNEL_start,
|
||||
|
|
|
|||
|
|
@ -427,6 +427,9 @@ FUNC_NORETURN void z_cstart(void)
|
|||
/* gcov hook needed to get the coverage report.*/
|
||||
gcov_static_init();
|
||||
|
||||
/* initialize early init calls */
|
||||
z_sys_init_run_level(_SYS_INIT_LEVEL_EARLY);
|
||||
|
||||
/* perform any architecture-specific initialization */
|
||||
arch_kernel_init();
|
||||
|
||||
|
|
|
|||
|
|
@ -152,8 +152,6 @@ __imr void boot_core0(void)
|
|||
parse_manifest();
|
||||
z_xtensa_cache_flush_all();
|
||||
|
||||
z_sys_init_run_level(_SYS_INIT_LEVEL_ARCH);
|
||||
|
||||
/* Zephyr! */
|
||||
extern FUNC_NORETURN void z_cstart(void);
|
||||
z_cstart();
|
||||
|
|
|
|||
|
|
@ -29,4 +29,4 @@ int boot_complete(const struct device *d)
|
|||
return 0;
|
||||
}
|
||||
|
||||
SYS_INIT(boot_complete, ARCH, CONFIG_KERNEL_INIT_PRIORITY_DEVICE);
|
||||
SYS_INIT(boot_complete, EARLY, CONFIG_KERNEL_INIT_PRIORITY_DEVICE);
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ __imr int mem_win_init(const struct device *dev)
|
|||
.mem_base = DT_REG_ADDR(DT_PHANDLE(MEM_WINDOW_NODE(n), memory)) + WIN_OFFSET(n), \
|
||||
.initialize = DT_PROP(MEM_WINDOW_NODE(n), initialize), \
|
||||
}; \
|
||||
DEVICE_DT_DEFINE(MEM_WINDOW_NODE(n), mem_win_init, NULL, NULL, &mem_win_config_##n, ARCH, \
|
||||
DEVICE_DT_DEFINE(MEM_WINDOW_NODE(n), mem_win_init, NULL, NULL, &mem_win_config_##n, EARLY, \
|
||||
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, NULL);
|
||||
|
||||
#if DT_NODE_HAS_STATUS(MEM_WINDOW_NODE(0), okay)
|
||||
|
|
|
|||
Loading…
Reference in a new issue