build: board/ soc: introduce hw model v2 scheme

Hw model v2 scheme offers SoC and  maintainers the possibility to define
promptless SoCs settings which must be selected by the board Kconfig.

Having a board doing `select SOC_<name>` is a much cleaner approach then
selecting the SoC in a configuration file.

It furthermore removes the need to present all SoCs in choice groups, as
the SoC is now an internal setting to Kconfig.

This further has the benefit of not presenting users, especially
new-comers to Zephyr, with SoC selection options in menuconfig which
has potential to cause confusion.

It moves the SOC, SOC_SERIES, and SOC_FAMILY from arch/Kconfig into the
soc Kconfig tree, where they rightfully belongs.

With hw model v2, BOARD name is now passed from the build system to
Kconfig which ensures that the board name used in CMake is always in
sync with the board name used in Kconfig for hw model v2.

Signed-off-by: Torsten Rasmussen <Torsten.Rasmussen@nordicsemi.no>
This commit is contained in:
Torsten Rasmussen
2022-09-14 22:23:15 +02:00
committed by Jamie McCrae
parent 0051731a41
commit a4d1980c35
19 changed files with 260 additions and 87 deletions

View File

@@ -21,12 +21,11 @@ osource "$(KCONFIG_BINARY_DIR)/Kconfig.shield.defconfig"
# This loads Zephyr base shield defconfigs
source "boards/shields/*/Kconfig.defconfig"
source "$(BOARD_DIR)/Kconfig.defconfig"
osource "$(BOARD_DIR)/Kconfig.defconfig"
# This loads Zephyr specific SoC root defconfigs
source "$(KCONFIG_BINARY_DIR)/soc/Kconfig.defconfig"
# This loads custom SoC root defconfigs
osource "$(KCONFIG_BINARY_DIR)/Kconfig.soc.defconfig"
# This loads Zephyr base SoC root defconfigs
osource "soc/$(ARCH)/*/Kconfig.defconfig"
# This loads the toolchain defconfigs
osource "$(TOOLCHAIN_KCONFIG_DIR)/Kconfig.defconfig"
# This loads the testsuite defconfig

View File

@@ -524,7 +524,7 @@ Board/SoC configuration:
- nordicjm
- "57300"
files:
- soc/Kconfig
- soc/Kconfig*
- boards/Kconfig
labels:
- "area: Board/SoC configuration"

View File

@@ -1019,27 +1019,6 @@ config ARCH
help
System architecture string.
config SOC
string
help
SoC name which can be found under soc/<arch>/<soc name>.
This option holds the directory name used by the build system to locate
the correct linker and header files for the SoC.
config SOC_SERIES
string
help
SoC series name which can be found under soc/<arch>/<family>/<series>.
This option holds the directory name used by the build system to locate
the correct linker and header files.
config SOC_FAMILY
string
help
SoC family name which can be found under soc/<arch>/<family>.
This option holds the directory name used by the build system to locate
the correct linker and header files.
config TOOLCHAIN_HAS_BUILTIN_FFS
bool
default y if !(64BIT && RISCV)

View File

@@ -2,6 +2,8 @@
config BOARD
string
# When using hw model v2, then the board is inherited from CMake.
default "$(BOARD)" if "$(HWM_SCHEME)" = "v2"
help
This option holds the name of the board and is used to locate the files
related to the board in the source tree (under boards/).
@@ -38,14 +40,7 @@ config NET_DRIVERS
When building for a qemu target then NET_DRIVERS will be default
enabled to allow for easy use of SLIP or PPP
# Note: $BOARD_DIR might be a glob pattern
choice
prompt "Board Selection"
source "$(BOARD_DIR)/Kconfig.board"
endchoice
rsource "Kconfig.$(HWM_SCHEME)"
# Parse shields references
# Don't do it as a menuconfig, as shield selection is a CMake feature.

10
boards/Kconfig.v1 Normal file
View File

@@ -0,0 +1,10 @@
# Copyright (c) 2022 Nordic Semiconductor ASA
# SPDX-License-Identifier: Apache-2.0
choice
prompt "Board Selection"
source "$(BOARD_DIR)/Kconfig.board"
endchoice

18
boards/Kconfig.v2 Normal file
View File

@@ -0,0 +1,18 @@
# Copyright (c) 2022 Nordic Semiconductor ASA
# SPDX-License-Identifier: Apache-2.0
BOARD_STRING := $(sanitize_upper,$(BOARD))
BOARD_FULL_STRING := $(sanitize_upper,$(BOARD)$(BOARD_IDENTIFIER))
config BOARD_$(BOARD_STRING)
def_bool y
help
Kconfig symbol identifying the board.
config BOARD_$(BOARD_FULL_STRING)
def_bool y
help
Kconfig symbol identifying the board including full board identifier.
osource "$(BOARD_DIR)/Kconfig.$(BOARD)"

View File

@@ -122,11 +122,19 @@ set(DTS_CMAKE ${PROJECT_BINARY_DIR}/dts.cmake)
# modules.
set(VENDOR_PREFIXES dts/bindings/vendor-prefixes.txt)
set_ifndef(DTS_SOURCE ${BOARD_DIR}/${BOARD}.dts)
zephyr_build_string(dts_board_string BOARD ${BOARD} BOARD_IDENTIFIER ${BOARD_IDENTIFIER})
set_ifndef(DTS_SOURCE ${BOARD_DIR}/${dts_board_string}.dts)
if(EXISTS ${DTS_SOURCE})
# We found a devicetree. Check for a board revision overlay.
if(DEFINED BOARD_REVISION AND EXISTS ${BOARD_DIR}/${BOARD}_${BOARD_REVISION_STRING}.overlay)
list(APPEND DTS_SOURCE ${BOARD_DIR}/${BOARD}_${BOARD_REVISION_STRING}.overlay)
if(DEFINED BOARD_REVISION)
zephyr_build_string(dts_board_string BOARD ${BOARD}
BOARD_IDENTIFIER ${BOARD_IDENTIFIER}
BOARD_REVISION ${BOARD_REVISION}
)
if(EXISTS ${BOARD_DIR}/${dts_board_string}.overlay)
list(APPEND DTS_SOURCE ${BOARD_DIR}/${dts_board_string}.overlay)
endif()
endif()
else()
# If we don't have a devicetree, provide an empty stub

View File

@@ -1514,6 +1514,7 @@ endfunction()
# Usage:
# zephyr_build_string(<out-variable>
# BOARD <board>
# [BOARD_IDENTIFIER <identifier>]
# [BOARD_REVISION <revision>]
# [BUILD <type>]
# )
@@ -1533,7 +1534,7 @@ endfunction()
# will return the string `alpha_1_0_0_debug` in `build_string` parameter.
#
function(zephyr_build_string outvar)
set(single_args BOARD BOARD_REVISION BUILD)
set(single_args BOARD BOARD_IDENTIFIER BOARD_REVISION BUILD)
cmake_parse_arguments(BUILD_STR "" "${single_args}" "" ${ARGN})
if(BUILD_STR_UNPARSED_ARGUMENTS)
@@ -1550,8 +1551,20 @@ function(zephyr_build_string outvar)
)
endif()
if(DEFINED BUILD_STR_BOARD_IDENTIFIER AND NOT BUILD_STR_BOARD)
message(FATAL_ERROR
"zephyr_build_string(${ARGV0} <list> BOARD_IDENTIFIER ${BUILD_STR_BOARD_IDENTIFIER} ...)"
" given without BOARD argument, please specify BOARD"
)
endif()
set(${outvar} ${BUILD_STR_BOARD})
if(DEFINED BUILD_STR_BOARD_IDENTIFIER)
string(REPLACE "/" "_" variant_string ${BUILD_STR_BOARD_IDENTIFIER})
set(${outvar} "${${outvar}}${variant_string}")
endif()
if(DEFINED BUILD_STR_BOARD_REVISION)
string(REPLACE "." "_" revision_string ${BUILD_STR_BOARD_REVISION})
set(${outvar} "${${outvar}}_${revision_string}")

View File

@@ -22,23 +22,30 @@ set_ifndef(KCONFIG_NAMESPACE "CONFIG")
set_ifndef(KCONFIG_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/Kconfig)
file(MAKE_DIRECTORY ${KCONFIG_BINARY_DIR})
# Support multiple SOC_ROOT, remove ZEPHYR_BASE as that is always sourced.
set(kconfig_soc_root ${SOC_ROOT})
list(REMOVE_ITEM kconfig_soc_root ${ZEPHYR_BASE})
set(OPERATION WRITE)
foreach(root ${kconfig_soc_root})
file(${OPERATION} ${KCONFIG_BINARY_DIR}/Kconfig.soc.defconfig
"osource \"${root}/soc/$(ARCH)/*/Kconfig.defconfig\"\n"
)
file(${OPERATION} ${KCONFIG_BINARY_DIR}/Kconfig.soc
"osource \"${root}/soc/$(ARCH)/*/Kconfig.soc\"\n"
)
file(${OPERATION} ${KCONFIG_BINARY_DIR}/Kconfig.soc.arch
"osource \"${root}/soc/$(ARCH)/Kconfig\"\n"
"osource \"${root}/soc/$(ARCH)/*/Kconfig\"\n"
)
set(OPERATION APPEND)
endforeach()
if(HWMv1)
# Support multiple SOC_ROOT
file(MAKE_DIRECTORY ${KCONFIG_BINARY_DIR}/soc)
set(kconfig_soc_root ${BOARD_ROOT})
list(REMOVE_ITEM kconfig_soc_root ${ZEPHYR_BASE})
set(soc_defconfig_file ${KCONFIG_BINARY_DIR}/soc/Kconfig.defconfig)
# This loads Zephyr base SoC root defconfigs
file(WRITE ${soc_defconfig_file} "osource \"soc/$(ARCH)/*/Kconfig.defconfig\"\n")
set(OPERATION WRITE)
foreach(root ${kconfig_soc_root})
file(APPEND ${soc_defconfig_file}
"osource \"${root}/soc/$(ARCH)/*/Kconfig.defconfig\"\n")
file(${OPERATION} ${KCONFIG_BINARY_DIR}/soc/Kconfig.soc.choice
"osource \"${root}/soc/$(ARCH)/*/Kconfig.soc\"\n"
)
file(${OPERATION} ${KCONFIG_BINARY_DIR}/soc/Kconfig.soc.arch
"osource \"${root}/soc/$(ARCH)/Kconfig\"\n"
"osource \"${root}/soc/$(ARCH)/*/Kconfig\"\n"
)
set(OPERATION APPEND)
endforeach()
endif()
# Support multiple shields in BOARD_ROOT, remove ZEPHYR_BASE as that is always sourced.
set(kconfig_board_root ${BOARD_ROOT})
@@ -67,9 +74,13 @@ else()
set(KCONFIG_ROOT ${ZEPHYR_BASE}/Kconfig)
endif()
set_ifndef(BOARD_DEFCONFIG ${BOARD_DIR}/${BOARD}_defconfig)
if((DEFINED BOARD_REVISION) AND EXISTS ${BOARD_DIR}/${BOARD}_${BOARD_REVISION_STRING}.conf)
set_ifndef(BOARD_REVISION_CONFIG ${BOARD_DIR}/${BOARD}_${BOARD_REVISION_STRING}.conf)
zephyr_build_string(config_board_string BOARD ${BOARD} BOARD_IDENTIFIER ${BOARD_IDENTIFIER})
if(NOT DEFINED BOARD_DEFCONFIG)
set(BOARD_DEFCONFIG ${BOARD_DIR}/${config_board_string}_defconfig)
endif()
if((DEFINED BOARD_REVISION) AND EXISTS ${BOARD_DIR}/${config_board_string}_${BOARD_REVISION_STRING}.conf)
set_ifndef(BOARD_REVISION_CONFIG ${BOARD_DIR}/${config_board_string}_${BOARD_REVISION_STRING}.conf)
endif()
set(DOTCONFIG ${PROJECT_BINARY_DIR}/.config)
set(PARSED_KCONFIG_SOURCES_TXT ${PROJECT_BINARY_DIR}/kconfig/sources.txt)
@@ -137,12 +148,11 @@ set(COMMON_KCONFIG_ENV_SETTINGS
APP_VERSION_TWEAK_STRING=${APP_VERSION_TWEAK_STRING}
CONFIG_=${KCONFIG_NAMESPACE}_
KCONFIG_CONFIG=${DOTCONFIG}
# Set environment variables so that Kconfig can prune Kconfig source
# files for other architectures
ARCH=${ARCH}
ARCH_DIR=${ARCH_DIR}
BOARD_DIR=${BOARD_DIR}
BOARD=${BOARD}
BOARD_REVISION=${BOARD_REVISION}
BOARD_IDENTIFIER=${BOARD_IDENTIFIER}
HWM_SCHEME=${HWM}
KCONFIG_BINARY_DIR=${KCONFIG_BINARY_DIR}
APPLICATION_SOURCE_DIR=${APPLICATION_SOURCE_DIR}
ZEPHYR_TOOLCHAIN_VARIANT=${ZEPHYR_TOOLCHAIN_VARIANT}
@@ -154,6 +164,21 @@ set(COMMON_KCONFIG_ENV_SETTINGS
${ZEPHYR_KCONFIG_MODULES_DIR}
)
if(HWMv1)
list(APPEND COMMON_KCONFIG_ENV_SETTINGS
ARCH=${ARCH}
ARCH_DIR=${ARCH_DIR}
)
else()
# For HWMv2 we should in future generate a Kconfig.arch.v2 which instead
# glob-sources all arch roots, but for Zephyr itself, the current approach is
# sufficient.
list(APPEND COMMON_KCONFIG_ENV_SETTINGS
ARCH=*
ARCH_DIR=${ZEPHYR_BASE}/arch
)
endif()
# Allow out-of-tree users to add their own Kconfig python frontend
# targets by appending targets to the CMake list
# 'EXTRA_KCONFIG_TARGETS' and setting variables named

View File

@@ -62,6 +62,14 @@ function(pre_dt_module_run)
# Finalize DTS_ROOT.
list(REMOVE_DUPLICATES DTS_ROOT)
if(HWMv1)
set(arch_include dts/${ARCH})
else()
foreach(arch ${ARCH_V2_NAME_LIST})
list(APPEND arch_include dts/${arch})
endforeach()
endif()
# Finalize DTS_ROOT_SYSTEM_INCLUDE_DIRS.
set(DTS_ROOT_SYSTEM_INCLUDE_DIRS)
foreach(dts_root ${DTS_ROOT})
@@ -69,7 +77,7 @@ function(pre_dt_module_run)
include
include/zephyr
dts/common
dts/${ARCH}
${arch_include}
dts
)
get_filename_component(full_path ${dts_root}/${dts_root_path} REALPATH)

View File

@@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.20.0)
include(root)
include(boards)
include(arch)
include(arch_v1)
include(configuration_files)
include(west)

View File

@@ -83,6 +83,10 @@ def kconfig_load(app: Sphinx) -> Tuple[kconfiglib.Kconfig, Dict[str, str]]:
with open(Path(td) / "Kconfig.dts", "w") as f:
f.write(kconfig)
(Path(td) / 'soc').mkdir(exist_ok=True)
with open(Path(td) / "soc" / "Kconfig.defconfig", "w") as f:
f.write('')
# base environment
os.environ["ZEPHYR_BASE"] = str(ZEPHYR_BASE)
os.environ["srctree"] = str(ZEPHYR_BASE)
@@ -91,8 +95,9 @@ def kconfig_load(app: Sphinx) -> Tuple[kconfiglib.Kconfig, Dict[str, str]]:
# include all archs and boards
os.environ["ARCH_DIR"] = "arch"
os.environ["ARCH"] = "*"
os.environ["ARCH"] = "[!v][!2]*"
os.environ["BOARD_DIR"] = "boards/*/*"
os.environ["HWM_SCHEME"] = "v1"
# insert external Kconfigs to the environment
module_paths = dict()

View File

@@ -6,6 +6,7 @@
import inspect
import os
import pickle
import re
import sys
from pathlib import Path
@@ -840,6 +841,17 @@ def dt_gpio_hogs_enabled(kconf, _):
return "n"
def sanitize_upper(kconf, _, string):
"""
Sanitize the string, so that the string only contains alpha-numeric
characters or underscores. All non-alpha-numeric characters are replaced
with an underscore, '_'.
When string has been sanitized it will be converted into upper case.
"""
return re.sub(r'[^a-zA-Z0-9_]', '_', string).upper()
def shields_list_contains(kconf, _, shield):
"""
Return "n" if cmake environment variable 'SHIELD_AS_LIST' doesn't exist.
@@ -907,5 +919,6 @@ functions = {
"dt_gpio_hogs_enabled": (dt_gpio_hogs_enabled, 0, 0),
"dt_chosen_partition_addr_int": (dt_chosen_partition_addr, 1, 3),
"dt_chosen_partition_addr_hex": (dt_chosen_partition_addr, 1, 3),
"sanitize_upper": (sanitize_upper, 1, 1),
"shields_list_contains": (shields_list_contains, 1, 1),
}

View File

@@ -11,8 +11,38 @@ unset(_SOC_IS_IN_TREE)
add_subdirectory(common)
if(EXISTS ${SOC_DIR}/${ARCH}/CMakeLists.txt)
add_subdirectory(${SOC_DIR}/${ARCH} soc/${ARCH})
else()
add_subdirectory(${SOC_DIR}/${ARCH}/${SOC_PATH} soc/${ARCH}/${SOC_PATH})
if(HWMv1)
if(EXISTS ${SOC_DIR}/${ARCH}/CMakeLists.txt)
add_subdirectory(${SOC_DIR}/${ARCH} soc/${ARCH})
else()
add_subdirectory(${SOC_DIR}/${ARCH}/${SOC_PATH} soc/${ARCH}/${SOC_PATH})
endif()
elseif(HWMv2)
# Below is inclusion of HWMv2 SoC CMake lists.
string(TOUPPER SOC_FAMILY_${SOC_FAMILY}_DIR family_setting_dir)
string(TOUPPER SOC_SERIES_${SOC_SERIES}_DIR series_setting_dir)
string(TOUPPER SOC_${SOC_NAME}_DIR soc_setting_dir)
if(DEFINED ${soc_setting_dir})
add_subdirectory(${${soc_setting_dir}} soc/${SOC_NAME})
elseif(DEFINED ${series_setting_dir})
add_subdirectory(${${series_setting_dir}} soc/${SOC_SERIES})
elseif(DEFINED ${family_setting_dir})
add_subdirectory(${${family_setting_dir}} soc/${SOC_FAMILY})
else()
message(FATAL_ERROR "No CMakeLists.txt file found for SoC: ${SOC_NAME}, "
"series: ${SOC_SERIES}, family: ${SOC_FAMILY}")
endif()
# Include all SoC roots except Zephyr, as we are already in the Zephyr SoC root.
set(local_soc_root ${SOC_ROOT})
list(REMOVE_ITEM local_soc_root ${ZEPHYR_BASE})
foreach(root ${local_soc_root})
cmake_path(GET root FILENAME name)
# A SoC root for HWMv1 may not contain a CMakeLists.txt file on this so
# let's check for existence before including.
if(EXISTS ${root}/soc/CMakeLists.txt)
add_subdirectory(${root}/soc soc/${name})
endif()
endforeach()
endif()

View File

@@ -1,21 +1,19 @@
# SPDX-License-Identifier: Apache-2.0
choice
prompt "SoC/CPU/Configuration Selection"
# This loads custom SoC root Kconfig (only available if custom SoC root are defined)
osource "$(KCONFIG_BINARY_DIR)/Kconfig.soc"
# This loads Zephyr base SoC root Kconfig
osource "soc/$(ARCH)/*/Kconfig.soc"
endchoice
# Only v1 model has choice for SoC selection, therefore the optional source
# Sourced here and not in Kconfig.v1 to keep current SoC/CPU selection menu
# side-by-side with "Hardware Configuration" in the menu structure.
orsource "Kconfig.$(HWM_SCHEME).choice"
menu "Hardware Configuration"
# This loads custom SoC root Kconfig (only available if custom SoC root are defined)
osource "$(KCONFIG_BINARY_DIR)/Kconfig.soc.arch"
# This loads Zephyr base SoC Kconfigs
rsource "Kconfig.$(HWM_SCHEME)"
# This loads Zephyr base SoC Kconfigs for both hw model v1 and v2
osource "soc/$(ARCH)/Kconfig"
osource "soc/$(ARCH)/*/Kconfig"
# Source Zephyr Kconfig specifics from SoC roots.
osource "$(KCONFIG_BINARY_DIR)/soc/Kconfig"
module = SOC
module-str = SOC
@@ -44,10 +42,6 @@ config SOC_COMPATIBLE_NRF5340_CPUNET
config SOC_COMPATIBLE_NRF5340_CPUAPP
bool
#
# SOC_*_LD: SoC specific Linker script additions
#
config SOC_DEPRECATED_RELEASE
string
help

27
soc/Kconfig.v1 Normal file
View File

@@ -0,0 +1,27 @@
# Copyright (c) 2023 Nordic Semiconductor ASA
# SPDX-License-Identifier: Apache-2.0
config SOC
string
help
SoC name. The value of this setting must be defined by the selected
SoC for hw model v2.
config SOC_SERIES
string
help
SoC series. The value of this setting must be defined by the selected
SoC if the SoC belongs to a common series.
config SOC_FAMILY
string
help
SoC family. The value of this setting must be defined by the selected
SoC if the SoC belongs to a SoC family. Usually a SoC family also
indicates the vendor of the SoC.
# This loads custom SoC root Kconfig (only available if custom SoC root are defined)
osource "$(KCONFIG_BINARY_DIR)/soc/Kconfig.soc.arch"
# This loads Zephyr base SoC Kconfigs
osource "soc/$(ARCH)/*/Kconfig"

13
soc/Kconfig.v1.choice Normal file
View File

@@ -0,0 +1,13 @@
# Copyright (c) 2023 Nordic Semiconductor ASA
# SPDX-License-Identifier: Apache-2.0
choice
prompt "SoC/CPU/Configuration Selection"
# This loads custom SoC root Kconfig (only available if custom SoC root are defined)
osource "$(KCONFIG_BINARY_DIR)/soc/Kconfig.soc.choice"
# This loads Zephyr base SoC scheme v1 root Kconfig
osource "soc/$(ARCH)/*/Kconfig.soc"
endchoice

32
soc/Kconfig.v2 Normal file
View File

@@ -0,0 +1,32 @@
# Copyright (c) 2022 Nordic Semiconductor ASA
# SPDX-License-Identifier: Apache-2.0
# Load all SoCs.
# SoCs that has transitioned to SoC scheme v2 are promptless, and thus
# unselectable by the user or through configuration files.
#
# SoC that are still using scheme v1 are still having a prompt but is loaded as
# they offer board maintainers the possibility to use board scheme v2.
config SOC
string
help
SoC name. The value of this setting must be defined by the selected
SoC for hw model v2.
config SOC_SERIES
string
help
SoC series. The value of this setting must be defined by the selected
SoC if the SoC belongs to a common series.
config SOC_FAMILY
string
help
SoC family. The value of this setting must be defined by the selected
SoC if the SoC belongs to a SoC family. Usually a SoC family also
indicates the vendor of the SoC.
# Source all Kconfig HWMv2 from SoC roots.
source "$(KCONFIG_BINARY_DIR)/soc/Kconfig.soc"

View File

@@ -0,0 +1,4 @@
# Copyright (c) 2023 Nordic Semiconductor ASA
# SPDX-License-Identifier: Apache-2.0
rsource "unit_testing/Kconfig"