Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RFC] Init entries: Automatically computing priorities #73836

Open
wants to merge 19 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
15cfb1e
scripts: Add the generic base script for handling firmware config
tbursztyka Apr 22, 2024
9b5b992
scripts/edtlib: Add the same accessor as chosen but for aliases
tbursztyka Apr 23, 2024
d6cc1a8
scripts/fwconfig: Add Zephyr initalization priority generator module
tbursztyka Apr 25, 2024
a1b4773
include: Add init utility macro specific header
tbursztyka Apr 12, 2024
9f2dbd9
cmake: Add support for ([.]+_)?fwconfig.yaml files in zephyr_file()
tbursztyka May 29, 2024
b8e3965
cmake: Add a fwconfig module in order to run its script properly
tbursztyka Apr 12, 2024
9ac0bdd
init: Integrate ZINIT_ computed macros to fill-in init entries
tbursztyka Apr 12, 2024
dbd8882
init: Add a "MANUAL" level of initialization
tbursztyka Apr 15, 2024
48354e2
linker: Add an extra number to check for sorting levels sections
tbursztyka Jun 3, 2024
a6f6d44
init: Add an extra '_' between level names and priority in sections
tbursztyka Jun 3, 2024
1c83d3c
root dir: Add default fw_config.yaml
tbursztyka Jun 4, 2024
ace85e6
arch/x86: Add relevant fwconfig.yaml
tbursztyka Jun 3, 2024
932e7ee
tests: Provide the relevant fw_config.yaml for the tests requiring it
tbursztyka May 31, 2024
0b7b0ae
devicetree: Define DT_NODE_HAS_STATUS if not ZTEST_UNITTEST
tbursztyka Jun 7, 2024
04696e6
tests: Fix devicetree's device test
tbursztyka Jun 7, 2024
ec7b3b8
tests: Fix DTS overlay for build_all/input
tbursztyka Jun 8, 2024
62c44de
twister: A q&d fix for CI to pass (not to be merged as it is)
tbursztyka Jun 10, 2024
9ff80dd
scripts/build: Removing check_init_priorities.py
tbursztyka Jun 11, 2024
4949b41
cmake: unitest module needs to generate an empty zinit.h
tbursztyka Jun 11, 2024
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
31 changes: 0 additions & 31 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1898,37 +1898,6 @@ if (CONFIG_LLEXT AND CONFIG_LLEXT_EXPORT_BUILTINS_BY_SLID)

endif()

if(NOT CMAKE_C_COMPILER_ID STREQUAL "ARMClang")
set(check_init_priorities_input
$<IF:$<TARGET_EXISTS:native_runner_executable>,${BYPRODUCT_KERNEL_EXE_NAME},${BYPRODUCT_KERNEL_ELF_NAME}>
)
set(check_init_priorities_command
${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/build/check_init_priorities.py
--elf-file=${check_init_priorities_input}
)
set(check_init_priorities_dependencies
${logical_target_for_zephyr_elf}
$<$<TARGET_EXISTS:native_runner_executable>:native_runner_executable>
)

if(CONFIG_CHECK_INIT_PRIORITIES)
if(TARGET native_runner_executable)
add_custom_command(TARGET native_runner_executable POST_BUILD
COMMAND ${check_init_priorities_command}
)
else()
list(APPEND post_build_commands COMMAND ${check_init_priorities_command})
endif()
endif()

add_custom_target(
initlevels
COMMAND ${check_init_priorities_command} --initlevels
DEPENDS ${check_init_priorities_dependencies}
USES_TERMINAL
)
endif()

# Generate signed (MCUboot or other) related artifacts as needed. Priority is:
# * Sysbuild (if set)
# * SIGNING_SCRIPT target property (if set)
Expand Down
15 changes: 0 additions & 15 deletions Kconfig.zephyr
Original file line number Diff line number Diff line change
Expand Up @@ -894,21 +894,6 @@ config BUILD_OUTPUT_STRIP_PATHS
Debuggers usually have a path mapping feature to ensure the files are
still found.

config CHECK_INIT_PRIORITIES
bool "Build time initialization priorities check"
default y
# If we are building a native_simulator target, we can only check the init priorities
# if we are building the final output but we are not assembling several images together
depends on !(NATIVE_LIBRARY && (!BUILD_OUTPUT_EXE || NATIVE_SIMULATOR_EXTRA_IMAGE_PATHS != ""))
depends on "$(ZEPHYR_TOOLCHAIN_VARIANT)" != "armclang"
help
Check the build for initialization priority issues by comparing the
initialization priority in the build with the device dependency
derived from the devicetree definition.

Fails the build on priority errors (dependent devices, inverted
priority).

config EMIT_ALL_SYSCALLS
bool "Emit all possible syscalls in the tree"
help
Expand Down
1 change: 0 additions & 1 deletion MAINTAINERS.yml
Original file line number Diff line number Diff line change
Expand Up @@ -758,7 +758,6 @@ Device Driver Model:
- include/zephyr/init.h
- tests/kernel/device/
- doc/kernel/drivers/
- tests/misc/check_init_priorities/
labels:
- "area: Device Model"
tests:
Expand Down
15 changes: 15 additions & 0 deletions arch/x86/fw_config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Copyright (c) 2024, Tomasz Bursztyka
#
# SPDX-License-Identifier: Apache-2.0
#
# X86 specific scripts/fwconfig file

init:
arch_smp_init:
dependencies:
- ioapic@fec00000
- loapic@fee00000

pcie_init:
dependencies:
- arch_smp_init
12 changes: 12 additions & 0 deletions boards/native/nrf_bsim/fw_config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Copyright (c) 2024, Tomasz Bursztyka
#
# SPDX-License-Identifier: Apache-2.0

init:
sync_rtc_setup:
dependencies:
- k_sys_work_q_init

k_sys_work_q_init:
dependencies:
- mbox
1 change: 1 addition & 0 deletions cmake/linker_script/common/common-rom.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ 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)
zephyr_linker_section_obj_level(SECTION init LEVEL APPLICATION)
zephyr_linker_section_obj_level(SECTION init LEVEL MANUAL)
zephyr_linker_section_obj_level(SECTION init LEVEL SMP)

zephyr_linker_section(NAME deferred_init_list KVMA RAM_REGION GROUP RODATA_REGION)
Expand Down
89 changes: 82 additions & 7 deletions cmake/modules/extensions.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -2555,7 +2555,7 @@ endfunction()
# returns an updated list of absolute paths
#
# Usage:
# zephyr_file(CONF_FILES <paths> [DTS <list>] [KCONF <list>]
# zephyr_file(CONF_FILES <paths> [DTS <list>] [KCONF <list>] [FWCONF <list>]
# [BOARD <board> [BOARD_REVISION <revision>] | NAMES <name> ...]
# [BUILD <type>] [SUFFIX <suffix>] [REQUIRED]
# )
Expand All @@ -2566,6 +2566,7 @@ endfunction()
# - DTS: Overlay files (.overlay)
# - Kconfig: Config fragments (.conf)
# - defconfig: defconfig files (_defconfig)
# - firmware config: [_]fw_config.yaml files
# The conf file search will return existing configuration
# files for the current board.
# CONF_FILES takes the following additional arguments:
Expand All @@ -2584,6 +2585,7 @@ endfunction()
# DTS <list>: List to append DTS overlay files in <path> to
# KCONF <list>: List to append Kconfig fragment files in <path> to
# DEFCONF <list>: List to append _defconfig files in <path> to
# FWCONF <list>: List to append [_]fwconfig.yaml files in <path> to
# BUILD <type>: Build type to include for search.
# For example:
# BUILD debug, will look for <board>_debug.conf
Expand All @@ -2593,7 +2595,7 @@ endfunction()
# For example:
# SUFFIX fish, will look for <file>_fish.conf and use
# if found but will use <file>.conf if not found
# REQUIRED: Option to indicate that the <list> specified by DTS or KCONF
# REQUIRED: Option to indicate that the <list> specified by DTS, KCONF or FCONF
# must contain at least one element, else an error will be raised.
#
function(zephyr_file)
Expand All @@ -2607,7 +2609,7 @@ Please provide one of following: APPLICATION_ROOT, CONF_FILES")
set(single_args APPLICATION_ROOT BASE_DIR)
elseif(${ARGV0} STREQUAL CONF_FILES)
set(options QUALIFIERS REQUIRED)
set(single_args BOARD BOARD_REVISION BOARD_QUALIFIERS DTS KCONF DEFCONFIG BUILD SUFFIX)
set(single_args BOARD BOARD_REVISION BOARD_QUALIFIERS DTS KCONF DEFCONFIG FWCONF BUILD SUFFIX)
set(multi_args CONF_FILES NAMES)
endif()

Expand Down Expand Up @@ -2679,6 +2681,7 @@ Relative paths are only allowed with `-D${ARGV1}=<path>`")
if(ZFILE_NAMES)
set(dts_filename_list ${ZFILE_NAMES})
set(kconf_filename_list ${ZFILE_NAMES})
set(fwconf_filename_list ${ZFILE_NAMES})
else()
if(NOT ZFILE_QUALIFIERS)
zephyr_build_string(filename_list
Expand Down Expand Up @@ -2706,6 +2709,11 @@ Relative paths are only allowed with `-D${ARGV1}=<path>`")
set(kconf_shortened_filename_list ${shortened_filename_list})
list(TRANSFORM kconf_filename_list APPEND ".conf")
list(TRANSFORM kconf_shortened_filename_list APPEND ".conf")

set(fwconf_filename_list ${filename_list})
set(fwconf_shortened_filename_list ${shortened_filename_list})
list(TRANSFORM fwconf_filename_list APPEND "_fw_config.yaml")
list(TRANSFORM fwconf_shortened_filename_list APPEND "_fw_config.yaml")
endif()

if(ZFILE_DTS)
Expand Down Expand Up @@ -2858,6 +2866,68 @@ Relative paths are only allowed with `-D${ARGV1}=<path>`")
# This updates the provided list in parent scope (callers scope)
set(${ZFILE_DEFCONFIG} ${${ZFILE_DEFCONFIG}} PARENT_SCOPE)
endif()

if(ZFILE_FWCONF)
set(found_fwconf_files)
foreach(path ${ZFILE_CONF_FILES})
set(test_file ${path}/fw_config.yaml)
if(EXISTS ${test_file})
list(APPEND found_fwconf_files ${test_file})
else()
zephyr_file_suffix(test_file SUFFIX ${ZFILE_SUFFIX})
if(EXISTS ${test_file})
list(APPEND found_fwconf_files ${test_file})
endif()
endif()

foreach(filename IN ZIP_LISTS fwconf_filename_list fwconf_shortened_filename_list)
foreach(i RANGE 1)
if(NOT IS_ABSOLUTE filename_${i} AND DEFINED filename_${i})
set(test_file_${i} ${path}/${filename_${i}})
else()
set(test_file_${i} ${filename_${i}})
endif()
zephyr_file_suffix(test_file_${i} SUFFIX ${ZFILE_SUFFIX})


if(NOT EXISTS ${test_file_${i}})
set(test_file_${i})
endif()
endforeach()

if(test_file_0 OR test_file_1)
list(APPEND found_fwconf_files ${test_file_0})
list(APPEND found_fwconf_files ${test_file_1})

if(DEFINED ZFILE_BUILD)
set(deprecated_file_found y)
endif()

if(ZFILE_NAMES)
break()
endif()
endif()

if(test_file_1 AND NOT BOARD_${ZFILE_BOARD}_SINGLE_SOC)
message(FATAL_ERROR "Board ${ZFILE_BOARD} defines multiple SoCs.\nShortened file name "
"(${filename_1}) not allowed, use '<board>_<soc>_fwconfig.yaml' naming"
)
endif()

if(test_file_0 AND test_file_1)
message(FATAL_ERROR "Conflicting file names discovered. Cannot use both ${filename_0} "
"and ${filename_1}. Please choose one naming style, "
"${filename_0} is recommended."
)
endif()
endforeach()
endforeach()

list(APPEND ${ZFILE_FWCONF} ${found_fwconf_files})

# This updates the provided list in parent scope (callers scope)
set(${ZFILE_FWCONF} ${${ZFILE_FWCONF}} PARENT_SCOPE)
endif()
endif()
endfunction()

Expand Down Expand Up @@ -4971,8 +5041,8 @@ endfunction()
# This is useful content such as struct devices.
#
# For example: zephyr_linker_section_obj_level(SECTION init LEVEL PRE_KERNEL_1)
# will create an input section matching `.z_init_PRE_KERNEL_1?_` and
# `.z_init_PRE_KERNEL_1??_`.
# will create an input section matching `.z_init_PRE_KERNEL_1?_`,
# `.z_init_PRE_KERNEL_1??_` and `.z_init_PRE_KERNEL_1???_`
#
# SECTION <section>: Section in which the objects shall be placed
# LEVEL <level> : Priority level, all input sections matching the level
Expand All @@ -4996,13 +5066,18 @@ function(zephyr_linker_section_obj_level)

zephyr_linker_section_configure(
SECTION ${OBJ_SECTION}
INPUT ".z_${OBJ_SECTION}_${OBJ_LEVEL}?_*"
INPUT ".z_${OBJ_SECTION}_${OBJ_LEVEL}_?_*"
SYMBOLS __${OBJ_SECTION}_${OBJ_LEVEL}_start
KEEP SORT NAME
)
zephyr_linker_section_configure(
SECTION ${OBJ_SECTION}
INPUT ".z_${OBJ_SECTION}_${OBJ_LEVEL}??_*"
INPUT ".z_${OBJ_SECTION}_${OBJ_LEVEL}_??_*"
KEEP SORT NAME
)
zephyr_linker_section_configure(
SECTION ${OBJ_SECTION}
INPUT ".z_${OBJ_SECTION}_${OBJ_LEVEL}_???_*"
KEEP SORT NAME
)
endfunction()
Expand Down
79 changes: 79 additions & 0 deletions cmake/modules/fwconfig.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# Copyright (c) 2024, Tomasz Bursztyka
#
# SPDX-License-Identifier: Apache-2.0

include_guard(GLOBAL)

include(extensions)
include(python)
include(arch_v1)
include(arch_v2)
include(soc_v1)
include(soc_v2)
include(boards)

#
# ToDo DOC
#

# The directory containing fwconfig script and files.
set(FWCONFIG_BASE ${ZEPHYR_BASE}/scripts/fwconfig)

# Fwconfig script that will generate a header about soft/hard init nodes
# priority and - whene relevant - levels too.
set(FWCONFIG_SCRIPT ${FWCONFIG_BASE}/fwconfig)

# The edtlib.EDT object in pickle format.
set(EDT_PICKLE ${PROJECT_BINARY_DIR}/edt.pickle)

# The .config file generated by Kconfig
set(DOTCONFIG ${PROJECT_BINARY_DIR}/.config)

# The generated C header needed by <zephyr/init.h>
set(FWCONFIG_INIT_H ${BINARY_DIR_INCLUDE_GENERATED}/zinit.h)

# Predefined directories where to look for fw_config.yaml files
# 1 - Default:
list(APPEND fwconfig_lookup_dirs ${ZEPHYR_BASE})

# 2 - Arch:
list(APPEND fwconfig_lookup_dirs ${ARCH_DIR}/${ARCH})

# 3 - SoC:
list(APPEND fwconfig_lookup_dirs ${SOC_FULL_DIR})

# 4 - Modules:
zephyr_get(ZEPHYR_MODULES)
zephyr_get(EXTRA_ZEPHYR_MODULES VAR EXTRA_ZEPHYR_MODULES ZEPHYR_EXTRA_MODULES)
list(APPEND fwconfig_lookup_dirs ${ZEPHYR_MODULES} ${EXTRA_ZEPHYR_MODULES})

# 5 - Board:
list(APPEND fwconfig_lookup_dirs ${BOARD_DIR} ${BOARD_EXTENSION_DIRS})

# 6 - Application:
list(APPEND fwconfig_lookup_dirs ${APPLICATION_CONFIG_DIR} ${APPLICATION_CONFIG_DIR}/boards)

# Now looking up for the actual files:
zephyr_file(CONF_FILES ${fwconfig_lookup_dirs} FWCONF fwconfig_files)

message(STATUS "Found fwconfig files: ${fwconfig_files}")

#
# Run FWCONFIG_SCRIPT
#
execute_process(
COMMAND ${PYTHON_EXECUTABLE} ${FWCONFIG_SCRIPT}
--fwconfig-files ${fwconfig_files}
-
init
--dotconfig-file ${DOTCONFIG}
--edt-pickle ${EDT_PICKLE}
--header-out ${FWCONFIG_INIT_H}
OUTPUT_QUIET # Discard stdout
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
RESULT_VARIABLE ret
)

if(NOT "${ret}" STREQUAL "0")
message(FATAL_ERROR "command failed with return code: ${ret}")
endif()
1 change: 1 addition & 0 deletions cmake/modules/unittest.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ set(INCL_GENERATED_DIR ${APPLICATION_BINARY_DIR}/zephyr/include/generated/zephyr
set(INCL_GENERATED_SYSCALL_DIR ${INCL_GENERATED_DIR}/syscalls)
list(APPEND INCL_GENERATED_HEADERS
${INCL_GENERATED_DIR}/devicetree_generated.h
${INCL_GENERATED_DIR}/zinit.h
${INCL_GENERATED_DIR}/offsets.h
${INCL_GENERATED_DIR}/syscall_list.h
${INCL_GENERATED_DIR}/syscall_macros.h
Expand Down
1 change: 1 addition & 0 deletions cmake/modules/zephyr_default.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ list(APPEND zephyr_cmake_modules kconfig)
list(APPEND zephyr_cmake_modules arch_v2)
list(APPEND zephyr_cmake_modules soc_v1)
list(APPEND zephyr_cmake_modules soc_v2)
list(APPEND zephyr_cmake_modules fwconfig)

foreach(component ${SUB_COMPONENTS})
if(NOT ${component} IN_LIST zephyr_cmake_modules)
Expand Down
9 changes: 0 additions & 9 deletions doc/build/cmake/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -409,12 +409,3 @@ The following is a detailed description of the scripts used during the build pro
.. include:: ../../../scripts/build/gen_app_partitions.py
:start-after: """
:end-before: """

.. _check_init_priorities.py:

:zephyr_file:`scripts/build/check_init_priorities.py`
-----------------------------------------------------

.. include:: ../../../scripts/build/check_init_priorities.py
:start-after: """
:end-before: """
Loading
Loading