From aba632f7dd1264c6b18c05e5117ecebc62ab3a38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Bergman?= Date: Mon, 3 Mar 2025 16:18:18 +0100 Subject: [PATCH 1/2] cmake: linker generator: Add recursive @variables@ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To allow funcitonallity like #define MPU_ALIGN(region_size) we need some more power from @variables@. This adds two things: * Recursive expansion of variables, if V1=foo and V2=@V1@ then @V2@ will expand to foo * @WITH_ARG,arg=foo@ defines arg=foo during the expansion of WITH_ARG. Together these two features allows one to do things similar to preprocessor macros with arguments, e.g. MPU_ALIGN(reg_size): zephyr_linker_include_var(VAR MPU_ALIGN VALUE "1 << LOG2CEIL(@rs@)") zephyr_linker_section(NAME foo ALIGN @MPU_ALIGN,rs=foo_end-foo_start@) Signed-off-by: Björn Bergman --- cmake/linker/linker_script_common.cmake | 41 ++++++++++++++++++------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/cmake/linker/linker_script_common.cmake b/cmake/linker/linker_script_common.cmake index 272fe7977779f..e7cdfb9dfa9ca 100644 --- a/cmake/linker/linker_script_common.cmake +++ b/cmake/linker/linker_script_common.cmake @@ -713,27 +713,46 @@ foreach(file IN LISTS PREPROCESSOR_FILES ) endforeach() # To pickup information gathered by the scripts from the previous pass, we use -# the syntax @FOO@ where FOO is a cmake variable name +# the syntax @FOO[,undef:VALUE][,var=VALUE]@ +# The expansion is recursive so if FOO contains @BAR@ it @BAR will also be +# expanded +# Where the undef:VALUE gets picked if we dont find FOO +# and foo=bar defines a (local) variable in the coming expansion +# The variable values are kept in cmake varaiables, MOSTLY with the +# AT_VAR_ prefix to avoid name-clashes function(do_var_replace_in res_ptr src) - string(REGEX MATCHALL "@([^@]*)@" match_res "${src}") + string(REGEX MATCHALL "@[^@]*@" match_res "${src}") foreach(match IN LISTS match_res) - string(REPLACE "@" "" expr ${match}) - # the variable expression is as follows: - # @NAME[,undef:VALUE]@ Where the VALUE gets picked if we dont find NAME - string(REPLACE "," ";" expr ${expr}) - list(GET expr 0 var) + #Drop the leading and closing @ + string(REGEX MATCH "@([^@]*)@" expr ${match}) + + # Turn the , into ; to treat it as a list: + string(REPLACE "," ";" expr ${CMAKE_MATCH_1}) + unset(undef_value) + list(POP_FRONT expr var) + foreach(e IN LISTS expr) + if(e MATCHES "undef:([^,]*)") + set(undef_value ${CMAKE_MATCH_1}) + elseif(e MATCHES "([^=;]+)=([^=;]+)") + set(AT_VAR_${CMAKE_MATCH_1} ${CMAKE_MATCH_2}) + endif() + endforeach() + if(DEFINED "AT_VAR_${var}") set(value "${AT_VAR_${var}}") - elseif(DEFINED ${var}) # set by zephyr_linker_include_generated files + elseif(DEFINED ${var}) set(value "${${var}}") - elseif("${expr}" MATCHES ";undef:([^,]*)") - set(value "${CMAKE_MATCH_1}") + elseif(DEFINED undef_value) + set(value "${undef_value}") else() - set(value "${match}") # can't warn here because we can't check for what is relevant in this pass # message(WARNING "Missing definition for ${match}") + continue() endif() + #Resolve variables inside variables + do_var_replace_in(value "${value}") + if(CMAKE_VERBOSE_MAKEFILE) message("Using variable ${match} with value ${value}") endif() From 684d252922b2defe00520ab460425c4e2a3cca50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Bergman?= Date: Mon, 3 Mar 2025 17:22:20 +0100 Subject: [PATCH 2/2] cmake: linker generator: MPU_ALIGN for CONFIG_CMAKE_LINKER_GENERATOR MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make gen_app_partitions.py pass size argument to SMEM_PARTIOTION_ALIGN Implement MPU_ALIGN for CONFIG_CMAKE_LINKER_GENERATOR for cortex-m, and setup SMEM_PARTITION_ALIGN to use MPU_ALIGN. Following the pattern of how it is setup in the non-generator scrips. Signed-off-by: Björn Bergman --- cmake/linker_script/arm/linker.cmake | 13 ++++++------- scripts/build/gen_app_partitions.py | 11 ++++++----- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/cmake/linker_script/arm/linker.cmake b/cmake/linker_script/arm/linker.cmake index 94c2af6e4c5a2..739a320ec199f 100644 --- a/cmake/linker_script/arm/linker.cmake +++ b/cmake/linker_script/arm/linker.cmake @@ -22,16 +22,15 @@ if((NOT DEFINED CONFIG_CUSTOM_SECTION_ALIGN) AND DEFINED CONFIG_MPU_REQUIRES_PO # . = ALIGN( 1 << LOG2CEIL(region_size)) # Handling this requires us to handle log2ceil() in iar linker since the size # isn't known until then. - set(MPU_ALIGN_BYTES ${region_min_align}) + zephyr_linker_include_var(VAR MPU_ALIGN VALUE "MAX(${region_min_align} , 1 << LOG2CEIL(@region_size@) )") #message(WARNING "We can not handle . = ALIGN( 1 << LOG2CEIL(region_size)) ") else() - set(MPU_ALIGN_BYTES ${region_min_align}) + zephyr_linker_include_var(VAR MPU_ALIGN VALUE "${region_min_align}") endif() -# The APP_SHARED_ALIGN and SMEM_PARTITION_ALIGN macros are defined as -# ". = ALIGN(...)" things. -# the cmake generator stuff needs an align-size in bytes so: -zephyr_linker_include_var(VAR APP_SHARED_ALIGN_BYTES VALUE ${region_min_align}) -zephyr_linker_include_var(VAR SMEM_PARTITION_ALIGN_BYTES VALUE ${MPU_ALIGN_BYTES}) + +zephyr_linker_include_var(VAR APP_SHARED_ALIGN VALUE ${region_min_align}) +# Note that MPU_ALIGN (may) require an argument (region_size +zephyr_linker_include_var(VAR SMEM_PARTITION_ALIGN VALUE "@MPU_ALIGN@") # Note, the `+ 0` in formulas below avoids errors in cases where a Kconfig # variable is undefined and thus expands to nothing. diff --git a/scripts/build/gen_app_partitions.py b/scripts/build/gen_app_partitions.py index 4a178762afcc5..2aecf979e7b22 100755 --- a/scripts/build/gen_app_partitions.py +++ b/scripts/build/gen_app_partitions.py @@ -279,8 +279,9 @@ def zephyr_linker_symbol(symbol, expr) : class CmakeTemplate: section_name = "@_APP_SMEM{SECTION}_SECTION_NAME@" + smem_partition_align = "@SMEM_PARTITION_ALIGN,region_size=z_data_smem_{partition}_bss_end - z_data_smem_{partition}_part_start@" data_template = ( - zephyr_linker_section_configure(section=section_name, align="@SMEM_PARTITION_ALIGN_BYTES@")+ + zephyr_linker_section_configure(section=section_name, align=smem_partition_align)+ zephyr_linker_section_configure(section=section_name, input="data_smem_{partition}_data*", symbols="z_data_smem_{partition}_part_start", keep=True) ) @@ -294,20 +295,20 @@ class CmakeTemplate: footer_template = ( zephyr_linker_section_configure(section=section_name, symbols="z_data_smem_{partition}_bss_end", keep=True) + - zephyr_linker_section_configure(section=section_name, align="@SMEM_PARTITION_ALIGN_BYTES@") + + zephyr_linker_section_configure(section=section_name, align=smem_partition_align) + zephyr_linker_section_configure(section=section_name, symbols="z_data_smem_{partition}_part_end", keep=True) ) linker_start_seq = ( zephyr_linker_section(name=section_name, group="APP_SMEM_GROUP", noinput=True, align_with_input=True) + - zephyr_linker_section_configure(section=section_name, align="@APP_SHARED_ALIGN_BYTES@", symbols="_app_smem{section}_start")) + zephyr_linker_section_configure(section=section_name, align="@APP_SHARED_ALIGN@", symbols="_app_smem{section}_start")) linker_end_seq = ( - zephyr_linker_section_configure(section=section_name, align="@APP_SHARED_ALIGN_BYTES@") + + zephyr_linker_section_configure(section=section_name, align="@APP_SHARED_ALIGN@") + zephyr_linker_section_configure(section=section_name, symbols="_app_smem{section}_end") ) empty_app_smem = ( - zephyr_linker_section(name=section_name, group="APP_SMEM_GROUP", align="@APP_SHARED_ALIGN_BYTES@", noinput=True, align_with_input=True) + + zephyr_linker_section(name=section_name, group="APP_SMEM_GROUP", align="@APP_SHARED_ALIGN@", noinput=True, align_with_input=True) + zephyr_linker_section_configure(section = section_name, symbols="_app_smem{section}_start") + zephyr_linker_section_configure(section = section_name, symbols="_app_smem{section}_end") )