diff --git a/cmake/linker/iar/config_file_script.cmake b/cmake/linker/iar/config_file_script.cmake index 1dfc5ab2b701..6699f4bf7e34 100644 --- a/cmake/linker/iar/config_file_script.cmake +++ b/cmake/linker/iar/config_file_script.cmake @@ -352,7 +352,7 @@ function(group_to_string) endif() set(${STRING_STRING} "${${STRING_STRING}}\"${name}\": place in ${ILINK_CURRENT_NAME} { block ${name_clean} };\n") - if(DEFINED vma AND DEFINED lma AND NOT ${noinit}) + if(CONFIG_IAR_ZEPHYR_INIT AND DEFINED vma AND DEFINED lma AND NOT ${noinit}) set(${STRING_STRING} "${${STRING_STRING}}\"${name}_init\": place in ${lma} { block ${name_clean}_init };\n") endif() @@ -811,32 +811,51 @@ function(section_to_string) list(JOIN current_sections ", " SELECTORS) set(TEMP "${TEMP}\ndo not initialize {\n${SELECTORS}\n};") else() - # Generate the _init block and the initialize manually statement. - # Note that we need to have the X_init block defined even if we have - # no sections, since there will come a "place in XXX" statement later. - - # "${TEMP}" is there too keep the ';' else it will be a list - string(REGEX REPLACE "(block[ \t\r\n]+)([^ \t\r\n]+)" "\\1\\2_init" INIT_TEMP "${TEMP}") - string(REGEX REPLACE "(rw)([ \t\r\n]+)(section[ \t\r\n]+)([^ \t\r\n,]+)" "\\1\\2\\3\\4_init" INIT_TEMP "${INIT_TEMP}") - string(REGEX REPLACE "(rw)([ \t\r\n]+)(section[ \t\r\n]+)" "ro\\2\\3" INIT_TEMP "${INIT_TEMP}") - string(REGEX REPLACE "alphabetical order, " "" INIT_TEMP "${INIT_TEMP}") - string(REGEX REPLACE "{ readwrite }" "{ }" INIT_TEMP "${INIT_TEMP}") - - # If any content is marked as keep, is has to be applied to the init block - # too, esp. for blocks that are not referenced (e.g. empty blocks wiht min_size) - if(to_be_kept) - list(APPEND to_be_kept "block ${name_clean}_init") - endif() - set(TEMP "${TEMP}\n${INIT_TEMP}\n") + if(DEFINED current_sections) - set(TEMP "${TEMP}\ninitialize manually with copy friendly\n") - set(TEMP "${TEMP}{\n") - foreach(section ${current_sections}) - set(TEMP "${TEMP} ${section},\n") - endforeach() - set(TEMP "${TEMP}};") - set(current_sections) + if(CONFIG_IAR_DATA_INIT) + set(TEMP "${TEMP}\ninitialize by copy\n") + set(TEMP "${TEMP}{\n") + foreach(section ${current_sections}) + set(TEMP "${TEMP} ${section},\n") + endforeach() + set(TEMP "${TEMP}};") + + set(TEMP "${TEMP}\n\"${name}_init\": place in ${group_parent_lma} {\n") + foreach(section ${current_sections}) + set(TEMP "${TEMP} ${section}_init,\n") + endforeach() + set(TEMP "${TEMP}};") + elseif(CONFIG_IAR_ZEPHYR_INIT) + # Generate the _init block and the initialize manually statement. + # Note that we need to have the X_init block defined even if we have + # no sections, since there will come a "place in XXX" statement later. + + # "${TEMP}" is there too keep the ';' else it will be a list + string(REGEX REPLACE "(block[ \t\r\n]+)([^ \t\r\n]+)" "\\1\\2_init" INIT_TEMP "${TEMP}") + string(REGEX REPLACE "(rw)([ \t\r\n]+)(section[ \t\r\n]+)([^ \t\r\n,]+)" "\\1\\2\\3\\4_init" INIT_TEMP "${INIT_TEMP}") + string(REGEX REPLACE "(rw)([ \t\r\n]+)(section[ \t\r\n]+)" "ro\\2\\3" INIT_TEMP "${INIT_TEMP}") + string(REGEX REPLACE "alphabetical order, " "" INIT_TEMP "${INIT_TEMP}") + string(REGEX REPLACE "{ readwrite }" "{ }" INIT_TEMP "${INIT_TEMP}") + + # If any content is marked as keep, is has to be applied to the init block + # too, esp. for blocks that are not referenced (e.g. empty blocks wiht min_size) + if(to_be_kept) + list(APPEND to_be_kept "block ${name_clean}_init") + endif() + set(TEMP "${TEMP}\n${INIT_TEMP}\n") + set(TEMP "${TEMP}\ninitialize manually with copy friendly\n") + set(TEMP "${TEMP}{\n") + foreach(section ${current_sections}) + set(TEMP "${TEMP} ${section},\n") + endforeach() + set(TEMP "${TEMP}};") + set(current_sections) + endif() endif() + + set(current_sections) + endif() endif() diff --git a/cmake/linker/iar/linker_flags.cmake b/cmake/linker/iar/linker_flags.cmake index f65925ff8a89..96710e4cc90d 100644 --- a/cmake/linker/iar/linker_flags.cmake +++ b/cmake/linker/iar/linker_flags.cmake @@ -4,8 +4,11 @@ # Override the default CMake's IAR ILINK linker signature -string(APPEND CMAKE_C_LINK_FLAGS --no-wrap-diagnostics ) +string(APPEND CMAKE_C_LINK_FLAGS --no-wrap-diagnostics) +if(CONFIG_IAR_DATA_INIT) + string(APPEND CMAKE_C_LINK_FLAGS " --redirect z_data_copy=__iar_data_init3") +endif() foreach(lang C CXX ASM) set(commands "--log modules,libraries,initialization,redirects,sections") set(CMAKE_${lang}_LINK_EXECUTABLE diff --git a/cmake/linker/iar/target.cmake b/cmake/linker/iar/target.cmake index f2326b60491a..3553b1f196c5 100644 --- a/cmake/linker/iar/target.cmake +++ b/cmake/linker/iar/target.cmake @@ -10,6 +10,10 @@ find_program(CMAKE_LINKER NO_DEFAULT_PATH ) +if(CONFIG_IAR_DATA_INIT) + zephyr_linker_section(NAME .iar.init_table KVMA RAM_REGION GROUP RODATA_REGION) +endif() + add_custom_target(${IAR_LINKER}) set(ILINK_THUMB_CALLS_WARNING_SUPPRESSED) set(IAR_LIB_USED) @@ -61,6 +65,8 @@ macro(configure_linker_script linker_script_gen linker_pass_define) ${STEERING_FILE_ARG} -DCONFIG_LINKER_LAST_SECTION_ID=${CONFIG_LINKER_LAST_SECTION_ID} -DCONFIG_LINKER_LAST_SECTION_ID_PATTERN=${CONFIG_LINKER_LAST_SECTION_ID_PATTERN} + -DCONFIG_IAR_DATA_INIT=${CONFIG_IAR_DATA_INIT} + -DCONFIG_IAR_ZEPHYR_INIT=${CONFIG_IAR_ZEPHYR_INIT} -DOUT_FILE=${CMAKE_CURRENT_BINARY_DIR}/${linker_script_gen} ${IAR_LIB_USED} -P ${ZEPHYR_BASE}/cmake/linker/iar/config_file_script.cmake diff --git a/cmake/toolchain/iar/Kconfig b/cmake/toolchain/iar/Kconfig index 056fa5d499f4..c522523549e7 100644 --- a/cmake/toolchain/iar/Kconfig +++ b/cmake/toolchain/iar/Kconfig @@ -9,7 +9,28 @@ choice LINKER_SCRIPT default CMAKE_LINKER_GENERATOR endchoice -menu "IAR library options" +menu "IAR options" + +choice IAR_INIT + bool "Static initialization method" + depends on XIP + default IAR_ZEPHYR_INIT + +config IAR_DATA_INIT + bool "IAR handles initialization of static variables" + select SKIP_BSS_CLEAR # IAR also handles zero initialization? + help + Instead of `z_prep_c` calling Zephyrs `z_data_copy` + we call IARs own proprietary initialization method + which can save time and space. + +config IAR_ZEPHYR_INIT + bool "Zephyr handles initialization of static variables" + help + The traditional `z_data_copy` + +endchoice + config IAR_SEMIHOSTING bool "Use the IAR semihosting implementation." diff --git a/scripts/ci/check_compliance.py b/scripts/ci/check_compliance.py index 0d670792b805..f35705a660d0 100755 --- a/scripts/ci/check_compliance.py +++ b/scripts/ci/check_compliance.py @@ -1060,8 +1060,10 @@ def check_no_undef_outside_kconfig(self, kconf): "HEAP_MEM_POOL_ADD_SIZE_", # Used as an option matching prefix "HUGETLBFS", # Linux, in boards/xtensa/intel_adsp_cavs25/doc "IAR_BUFFERED_WRITE", + "IAR_DATA_INIT", "IAR_LIBCPP", "IAR_SEMIHOSTING", + "IAR_ZEPHYR_INIT", "IPC_SERVICE_ICMSG_BOND_NOTIFY_REPEAT_TO_MS", # Used in ICMsg tests for intercompatibility # with older versions of the ICMsg. "LIBGCC_RTLIB",