kernel: init: introduce a new init level: ARCH

We have cases where some devices needs to be initialized very early and
before c_start is call, i.e. to setup very early console or to setup
memory. Traditionally this would be hardcoded as part of the soc layer
and not using device model or the init levels.

This patch adds a new level ARCH, which will be called in early
architecture code and before we jump to the kernel code.

Signed-off-by: Anas Nashif <anas.nashif@intel.com>
This commit is contained in:
Anas Nashif 2022-08-10 07:54:07 -04:00
parent d9a64b7b23
commit e8395351e6
5 changed files with 13 additions and 6 deletions

View file

@ -1,6 +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 PRE_KERNEL_1)
zephyr_linker_section_obj_level(SECTION init LEVEL PRE_KERNEL_2)
zephyr_linker_section_obj_level(SECTION init LEVEL POST_KERNEL)
@ -8,6 +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 PRE_KERNEL_1)
zephyr_linker_section_obj_level(SECTION device LEVEL PRE_KERNEL_2)
zephyr_linker_section_obj_level(SECTION device LEVEL POST_KERNEL)

View file

@ -21,13 +21,14 @@ extern "C" {
* stack. The remaining levels are executed in the kernel's main task.
*/
#define _SYS_INIT_LEVEL_PRE_KERNEL_1 0
#define _SYS_INIT_LEVEL_PRE_KERNEL_2 1
#define _SYS_INIT_LEVEL_POST_KERNEL 2
#define _SYS_INIT_LEVEL_APPLICATION 3
#define _SYS_INIT_LEVEL_ARCH 0
#define _SYS_INIT_LEVEL_PRE_KERNEL_1 1
#define _SYS_INIT_LEVEL_PRE_KERNEL_2 2
#define _SYS_INIT_LEVEL_POST_KERNEL 3
#define _SYS_INIT_LEVEL_APPLICATION 4
#ifdef CONFIG_SMP
#define _SYS_INIT_LEVEL_SMP 4
#define _SYS_INIT_LEVEL_SMP 5
#endif
struct device;

View file

@ -9,6 +9,7 @@
* by level, sorted by priority within a level)
*/
__init_start = .;
CREATE_OBJ_LEVEL(init, ARCH)
CREATE_OBJ_LEVEL(init, PRE_KERNEL_1)
CREATE_OBJ_LEVEL(init, PRE_KERNEL_2)
CREATE_OBJ_LEVEL(init, POST_KERNEL)
@ -24,6 +25,7 @@
* object parent. See above and include/device.h.
*/
__device_start = .;
CREATE_OBJ_LEVEL(device, ARCH)
CREATE_OBJ_LEVEL(device, PRE_KERNEL_1)
CREATE_OBJ_LEVEL(device, PRE_KERNEL_2)
CREATE_OBJ_LEVEL(device, POST_KERNEL)

View file

@ -10,6 +10,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_PRE_KERNEL_1_start[];
extern const struct init_entry __init_PRE_KERNEL_2_start[];
extern const struct init_entry __init_POST_KERNEL_start[];
@ -54,6 +55,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_PRE_KERNEL_1_start,
__init_PRE_KERNEL_2_start,
__init_POST_KERNEL_start,

View file

@ -95,7 +95,7 @@ FOR_EACH(SYS_INIT_CREATE, (;), PRE_KERNEL_1, PRE_KERNEL_2, POST_KERNEL);
ZTEST(no_multithreading, test_sys_init)
{
zassert_equal(init_order, 3, "SYS_INIT failed");
zassert_equal(init_order, _SYS_INIT_LEVEL_PRE_KERNEL_2, "SYS_INIT failed: %d", init_order);
}
ZTEST_SUITE(no_multithreading, NULL, NULL, NULL, NULL, NULL);