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

iar: toolchain: Implement IAR static init routine #86465

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
69 changes: 44 additions & 25 deletions cmake/linker/iar/config_file_script.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand Down Expand Up @@ -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()

Expand Down
5 changes: 4 additions & 1 deletion cmake/linker/iar/linker_flags.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 6 additions & 0 deletions cmake/linker/iar/target.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down
23 changes: 22 additions & 1 deletion cmake/toolchain/iar/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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."
Expand Down
2 changes: 2 additions & 0 deletions scripts/ci/check_compliance.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
Loading