diff --git a/cmake/modules/hwm_v2.cmake b/cmake/modules/hwm_v2.cmake index 38af4083fb1a9..49989833cae9b 100644 --- a/cmake/modules/hwm_v2.cmake +++ b/cmake/modules/hwm_v2.cmake @@ -22,6 +22,8 @@ if(NOT HWMv2) return() endif() +add_custom_target(hardware_model) + # Internal helper function for creation of Kconfig files. function(kconfig_gen bin_dir file dirs) file(MAKE_DIRECTORY "${bin_dir}") @@ -44,7 +46,7 @@ list(TRANSFORM SOC_ROOT PREPEND "--soc-root=" OUTPUT_VARIABLE soc_root_args) execute_process(COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/list_hardware.py ${arch_root_args} ${soc_root_args} --archs --socs - --cmakeformat={TYPE}\;{NAME}\;{DIR}\;{HWM} + --cmakeformat={TYPE}\;{HWM}\;{NAME}\;{SERIES}\;{FAMILY}\;{DIR} OUTPUT_VARIABLE ret_hw ERROR_VARIABLE err_hw RESULT_VARIABLE ret_val @@ -70,14 +72,19 @@ while(TRUE) string(TOUPPER "${ARCH_V2_NAME}" ARCH_V2_NAME_UPPER) set(ARCH_V2_${ARCH_V2_NAME_UPPER}_DIR ${ARCH_V2_DIR}) elseif(HWM_TYPE MATCHES "^soc|^series|^family") - cmake_parse_arguments(SOC_V2 "" "NAME;DIR;HWM" "" ${line}) + cmake_parse_arguments(SOC_V2 "" "NAME;DIR;HWM;SERIES;FAMILY" "" ${line}) list(APPEND kconfig_soc_source_dir "${SOC_V2_DIR}") if(HWM_TYPE STREQUAL "soc") set(setting_name SOC_${SOC_V2_NAME}_DIR) + set_property(TARGET hardware_model APPEND PROPERTY SOCS ${SOC_V2_NAME}) + set_property(TARGET hardware_model PROPERTY ${SOC_V2_NAME}_SERIES ${SOC_V2_SERIES}) + set_property(TARGET hardware_model PROPERTY ${SOC_V2_NAME}_FAMILY ${SOC_V2_FAMILY}) else() set(setting_name SOC_${HWM_TYPE}_${SOC_V2_NAME}_DIR) + string(TOUPPER ${HWM_TYPE} HWM_TYPE_UPPER) + set_property(TARGET hardware_model APPEND PROPERTY SOC_${HWM_TYPE_UPPER} ${SOC_V2_NAME}) endif() # We support both SOC_foo_DIR and SOC_FOO_DIR. set(${setting_name} ${SOC_V2_DIR}) diff --git a/cmake/modules/kconfig.cmake b/cmake/modules/kconfig.cmake index ae11892750a42..36b560a685f57 100644 --- a/cmake/modules/kconfig.cmake +++ b/cmake/modules/kconfig.cmake @@ -130,6 +130,23 @@ foreach(module_name ${ZEPHYR_MODULE_NAMES}) endif() endforeach() +set(hardware_model_kconfig_env) +get_target_property(socs hardware_model SOCS) +get_target_property(families hardware_model SOC_FAMILY) +get_target_property(series hardware_model SOC_SERIES) +foreach(soc ${socs}) + get_property(s_series TARGET hardware_model PROPERTY ${soc}_SERIES) + get_property(s_family TARGET hardware_model PROPERTY ${soc}_FAMILY) + list(APPEND hardware_model_kconfig_env "${soc}_SERIES=${s_series}") + list(APPEND hardware_model_kconfig_env "${soc}_FAMILY=${s_family}") +endforeach() +list(JOIN socs "," socs) +list(JOIN families "," families) +list(JOIN series "," series) +list(APPEND hardware_model_kconfig_env "SOCS=${socs}") +list(APPEND hardware_model_kconfig_env "SOC_SERIES=${series}") +list(APPEND hardware_model_kconfig_env "SOC_FAMILIES=${families}") + # A list of common environment settings used when invoking Kconfig during CMake # configure time or menuconfig and related build target. string(REPLACE ";" "\\\;" SHIELD_AS_LIST_ESCAPED "${SHIELD_AS_LIST}") @@ -171,6 +188,7 @@ set(COMMON_KCONFIG_ENV_SETTINGS EDT_PICKLE=${EDT_PICKLE} # Export all Zephyr modules to Kconfig ${ZEPHYR_KCONFIG_MODULES_DIR} + ${hardware_model_kconfig_env} ) if(HWMv1) diff --git a/misc/Kconfig.empty b/misc/Kconfig.empty new file mode 100644 index 0000000000000..2fbfb389ffc43 --- /dev/null +++ b/misc/Kconfig.empty @@ -0,0 +1,9 @@ +# Intentionally left empty. +# +# This file can be used when loading Kconfig files conditionally. +# Note, the snippet: +# if FOO +# source "bar/Kconfig" +# endif +# is not a conditional load in Kconfig, but simply applies `if FOO` on all +# entries in bar/Kconfig. diff --git a/scripts/kconfig/kconfigfunctions.py b/scripts/kconfig/kconfigfunctions.py index bb4b4dd519f17..8e9490a80f09c 100644 --- a/scripts/kconfig/kconfigfunctions.py +++ b/scripts/kconfig/kconfigfunctions.py @@ -852,6 +852,43 @@ def sanitize_upper(kconf, _, string): return re.sub(r'[^a-zA-Z0-9_]', '_', string).upper() +def defined(kconf, _, variable, true_value, false_value): + """ + Check if the variable is defined with a value. + If the variable defines a value, then is returned + Else is returned. + """ + if variable == "": + return false_value + return true_value + + +def get(kconf, _, list, index): + """ + Get the value from the list at + This list is a comma separated string. + """ + local_list = list.split(',') + return local_list[int(index)] + + +def get_env_list(kconf, _, name): + """ + Return the environment list setting matching name. + """ + return os.environ.get(f"{name}") + + +def remove(kconf, _, inlist, element): + """ + Remove the element from the list. + This list is a comma separated string. + """ + local_list = inlist.split(',') + local_list.remove(element) + return ','.join(local_list) + + def shields_list_contains(kconf, _, shield): """ Return "n" if cmake environment variable 'SHIELD_AS_LIST' doesn't exist. @@ -921,4 +958,8 @@ def shields_list_contains(kconf, _, shield): "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), + "defined": (defined, 3, 3), + "remove": (remove, 2, 2), + "get": (get, 2, 2), + "get_env_list": (get_env_list, 1, 1), } diff --git a/scripts/list_hardware.py b/scripts/list_hardware.py index d43cfb29c3930..6f700b84e281e 100755 --- a/scripts/list_hardware.py +++ b/scripts/list_hardware.py @@ -248,6 +248,8 @@ def dump_v2_system(args, type, system): info = args.cmakeformat.format( TYPE='TYPE;' + type, NAME='NAME;' + system.name, + SERIES='SERIES;' + str(system.series if type == 'soc' else ''), + FAMILY='FAMILY;' + str(system.family if type == 'soc' or type == 'series' else ''), DIR='DIR;' + Path(system.folder).as_posix(), HWM='HWM;' + 'v2' ) @@ -255,6 +257,8 @@ def dump_v2_system(args, type, system): info = args.format.format( type=type, name=system.name, + series=system.series if type == 'soc' else '', + family=system.family if type == 'soc' or type == 'series' else '', dir=system.folder, hwm='v2' ) diff --git a/soc/Kconfig.soc b/soc/Kconfig.soc new file mode 100644 index 0000000000000..c0b279b1eee52 --- /dev/null +++ b/soc/Kconfig.soc @@ -0,0 +1,20 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA + +# SPDX-License-Identifier: Apache-2.0 + +# Convert list of SoCs into Kconfig settings + +SOC := $(get,$(SOCS),0) +SOC_UPPER := $(sanitize_upper,$(SOC)) +SOCS := $(remove,$(SOCS),$(SOC)) + +config SOC_$(SOC_UPPER) + bool + select SOC_SERIES_$(defined,$($(SOC)_SERIES),$(sanitize_upper,$($(SOC)_SERIES)),NONE) + select SOC_FAMILY_$(defined,$($(SOC)_FAMILY),$(sanitize_upper,$($(SOC)_FAMILY)),NONE) + +config SOC + default "$(SOC)" if SOC_$(SOC_UPPER) + +RECURSIVE_SOURCE := ./$(RECURSIVE_SOURCE) +source "$(defined,$(SOCS),soc/$(RECURSIVE_SOURCE)Kconfig.soc,misc/Kconfig.empty)" diff --git a/soc/Kconfig.soc.family b/soc/Kconfig.soc.family new file mode 100644 index 0000000000000..91867e62904b6 --- /dev/null +++ b/soc/Kconfig.soc.family @@ -0,0 +1,18 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA + +# SPDX-License-Identifier: Apache-2.0 + +# Convert list of SoCs into Kconfig settings + +FAMILY := $(get,$(SOC_FAMILIES),0) +FAMILY_UPPER := $(sanitize_upper,$(FAMILY)) +SOC_FAMILIES := $(remove,$(SOC_FAMILIES),$(FAMILY)) + +config SOC_FAMILY_$(FAMILY_UPPER) + bool + +config SOC_FAMILY + default "$(FAMILY)" if SOC_FAMILY_$(FAMILY_UPPER) + +RECURSIVE_SOURCE := ./$(RECURSIVE_SOURCE) +source "$(defined,$(SOC_FAMILIES),soc/$(RECURSIVE_SOURCE)Kconfig.soc.family,misc/Kconfig.empty)" diff --git a/soc/Kconfig.soc.select b/soc/Kconfig.soc.select new file mode 100644 index 0000000000000..d87923316e3fe --- /dev/null +++ b/soc/Kconfig.soc.select @@ -0,0 +1,5 @@ + +SERIES_UPPER := $(sanitize_upper,$($(SOC)_SERIES)) + +config SOC_$(SOC_UPPER) + select SOC_SERIES_$(SERIES_UPPER) diff --git a/soc/Kconfig.soc.series b/soc/Kconfig.soc.series new file mode 100644 index 0000000000000..2cf4cb3d0eb30 --- /dev/null +++ b/soc/Kconfig.soc.series @@ -0,0 +1,18 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA + +# SPDX-License-Identifier: Apache-2.0 + +# Convert list of SoCs into Kconfig settings + +SERIES := $(get,$(SOC_SERIES),0) +SERIES_UPPER := $(sanitize_upper,$(SERIES)) +SOC_SERIES := $(remove,$(SOC_SERIES),$(SERIES)) + +config SOC_SERIES_$(SERIES_UPPER) + bool + +config SOC_SERIES + default "$(SERIES)" if SOC_SERIES_$(SERIES_UPPER) + +RECURSIVE_SOURCE := ./$(RECURSIVE_SOURCE) +source "$(defined,$(SOC_SERIES),soc/$(RECURSIVE_SOURCE)Kconfig.soc.series,misc/Kconfig.empty)" diff --git a/soc/Kconfig.v2 b/soc/Kconfig.v2 index 40008123a0288..ebdd23299df02 100644 --- a/soc/Kconfig.v2 +++ b/soc/Kconfig.v2 @@ -37,3 +37,26 @@ config SOC_PART_NUMBER # Source all Kconfig HWMv2 from SoC roots. source "$(KCONFIG_BINARY_DIR)/soc/Kconfig.soc" + +config SOC_SERIES_NONE + bool + help + Setting selected when the SoC is not part of a SoC series + +config SOC_FAMILY_NONE + bool + help + Setting selected when the SoC is not part of a SoC family + +SOCS := $(get_env_list,SOCS) +SOC_SERIES := $(get_env_list,SOC_SERIES) +SOC_FAMILIES := $(get_env_list,SOC_FAMILIES) + +RECURSIVE_SOURCE := +rsource "Kconfig.soc" + +RECURSIVE_SOURCE := +rsource "Kconfig.soc.series" + +RECURSIVE_SOURCE := +rsource "Kconfig.soc.family"