diff --git a/CMakeLists.txt b/CMakeLists.txt index 59f861039eb22c..ea473b688c172a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -77,6 +77,8 @@ zephyr_include_directories( ${STDINCLUDE} ) +include(${ZEPHYR_BASE}/cmake/linker_script/${ARCH}/linker.cmake OPTIONAL) + # Don't add non-existing include directories, it creates noise and # warnings in some tooling foreach(optional_include_dir @@ -795,6 +797,7 @@ if(CONFIG_HAS_DTS) --output-source dev_handles.c --kernel $ --zephyr-base ${ZEPHYR_BASE} + --start-symbol "$" DEPENDS ${ZEPHYR_PREBUILT_EXECUTABLE} ) set_property(GLOBAL APPEND PROPERTY GENERATED_KERNEL_SOURCE_FILES dev_handles.c) diff --git a/Kconfig.zephyr b/Kconfig.zephyr index 383e91c10efe3a..0141bfde6490e0 100644 --- a/Kconfig.zephyr +++ b/Kconfig.zephyr @@ -25,6 +25,8 @@ source "$(BOARD_DIR)/Kconfig.defconfig" 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" menu "Modules" @@ -132,8 +134,36 @@ config ROM_START_OFFSET alignment requirements on most ARM targets, although some targets may require smaller or larger values. +config LD_LINKER_SCRIPT_SUPPORTED + bool + default y + +choice LINKER_SCRIPT + prompt "Linker script" + default LD_LINKER_TEMPLATE if LD_LINKER_SCRIPT_SUPPORTED + +config LD_LINKER_TEMPLATE + bool "LD template" + depends on LD_LINKER_SCRIPT_SUPPORTED + help + Select this option to use the LD linker script templates. + The templates are pre-processed by the C pre-processor to create the + final LD linker script. + +config CMAKE_LINKER_GENERATOR + bool "CMake generator" + depends on ARM + help + Select this option to use the Zephyr CMake linker script generator. + The linker configuration is written in CMake and the final linker + script will be generated by the toolchain specific linker generator. + For LD based linkers, this will be the ld generator, for ARMClang / + armlink based linkers it will be the scatter generator. + +endchoice + config HAVE_CUSTOM_LINKER_SCRIPT - bool "Custom linker scripts provided" + bool "Custom linker script provided" help Set this option if you have a custom linker script which needed to be define in CUSTOM_LINKER_SCRIPT. diff --git a/arch/arm/core/aarch32/cortex_m/vector_table.S b/arch/arm/core/aarch32/cortex_m/vector_table.S index 8dcd4e06417922..d73aabdcb544ec 100644 --- a/arch/arm/core/aarch32/cortex_m/vector_table.S +++ b/arch/arm/core/aarch32/cortex_m/vector_table.S @@ -22,6 +22,10 @@ #include "vector_table.h" _ASM_FILE_PROLOGUE +/* + * Tell armclang that stack alignment are ensured. + */ +.eabi_attribute Tag_ABI_align_preserved, 1 GDATA(z_main_stack) diff --git a/arch/arm/core/aarch32/isr_wrapper.S b/arch/arm/core/aarch32/isr_wrapper.S index f62ad0fc1b634d..0f60ade2ca36c8 100644 --- a/arch/arm/core/aarch32/isr_wrapper.S +++ b/arch/arm/core/aarch32/isr_wrapper.S @@ -12,6 +12,10 @@ * Wrapper installed in vector table for handling dynamic interrupts that accept * a parameter. */ +/* + * Tell armclang that stack alignment are ensured. + */ +.eabi_attribute Tag_ABI_align_preserved, 1 #include #include diff --git a/arch/common/CMakeLists.txt b/arch/common/CMakeLists.txt index 3f6e5984c26bf5..ca0062a317f697 100644 --- a/arch/common/CMakeLists.txt +++ b/arch/common/CMakeLists.txt @@ -24,6 +24,15 @@ zephyr_linker_sources_ifdef(CONFIG_GEN_ISR_TABLES ${ZEPHYR_BASE}/include/linker/intlist.ld ) +if(CONFIG_GEN_ISR_TABLES) + zephyr_linker_section(NAME .intList VMA IDT_LIST LMA IDT_LIST NOINPUT PASS 1) + zephyr_linker_section_configure(SECTION .intList KEEP INPUT ".irq_info" FIRST) + zephyr_linker_section_configure(SECTION .intList KEEP INPUT ".intList") + + zephyr_linker_section_configure(SECTION /DISCARD/ KEEP INPUT ".irq_info" PASS 2) + zephyr_linker_section_configure(SECTION /DISCARD/ KEEP INPUT ".intList" PASS 2) +endif() + zephyr_linker_sources_ifdef(CONFIG_ARCH_HAS_RAMFUNC_SUPPORT RAM_SECTIONS ramfunc.ld @@ -38,6 +47,7 @@ zephyr_linker_sources_ifdef(CONFIG_NOCACHE_MEMORY if (DEFINED CONFIG_ARM OR DEFINED CONFIG_X86 OR DEFINED CONFIG_ARM64 OR DEFINED CONFIG_SOC_OPENISA_RV32M1_RISCV32) zephyr_linker_sources(ROM_START SORT_KEY 0x0 rom_start_offset.ld) + # Handled in ld.cmake endif() diff --git a/cmake/bintools/armclang/elfconvert_command.cmake b/cmake/bintools/armclang/elfconvert_command.cmake new file mode 100644 index 00000000000000..6a5549b96fceb3 --- /dev/null +++ b/cmake/bintools/armclang/elfconvert_command.cmake @@ -0,0 +1,54 @@ +# For armclang the elfconvert command is made into a script. +# Reason for that is because not a single command covers all use cases, +# and it must therefore be possible to call individual commands, depending +# on the arguments used. +cmake_minimum_required(VERSION 3.13) + +# Handle stripping +if (STRIP_DEBUG OR STRIP_ALL) + set(obj_copy_target_output "--elf") + if(STRIP_ALL) + set(obj_copy_strip "--strip=all") + elseif(STRIP_DEBUG) + set(obj_copy_strip "--strip=debug") + endif() +endif() + +# Unknown support of --srec-len in arm-ds + +# Handle Input and Output target types +if(DEFINED OUTTARGET) + if(${OUTTARGET} STREQUAL "srec") + set(obj_copy_target_output "--m32") + elseif(${OUTTARGET} STREQUAL "ihex") + set(obj_copy_target_output "--i32combined") + elseif(${OUTTARGET} STREQUAL "binary") + set(obj_copy_target_output "--bincombined") + if(GAP_FILL) + set(obj_copy_gap_fill "--bincombined_padding=1,${GAP_FILL}") + endif() + endif() +endif() + +if(DEFINED ONLY_SECTION AND "${OUTTARGET}" STREQUAL "binary") + set(obj_copy_target_output "--bin") + set(outfile_dir .dir) + string(REGEX REPLACE "^[\.]" "" only_section_clean "${ONLY_SECTION}") +endif() + +# Note: fromelf is a little special regarding bin output, as each section gets +# its own file. This means that when only a specific section is required +# then that section must be moved to correct location. +execute_process( + COMMAND ${FROMELF} + ${obj_copy_strip} + ${obj_copy_gap_fill} ${obj_copy_target_output} + --output ${OUTFILE}${outfile_dir} ${INFILE} +) + +if(DEFINED ONLY_SECTION AND "${OUTTARGET}" STREQUAL "binary") + execute_process( + COMMAND ${CMAKE_COMMAND} -E copy + ${OUTFILE}${outfile_dir}/${only_section_clean} ${OUTFILE} + ) +endif() diff --git a/cmake/bintools/armclang/target.cmake b/cmake/bintools/armclang/target.cmake new file mode 100644 index 00000000000000..529028f736723e --- /dev/null +++ b/cmake/bintools/armclang/target.cmake @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: Apache-2.0 + +# Configures binary tools as mwdt binutils + +find_program(CMAKE_FROMELF fromelf PATH ${TOOLCHAIN_HOME}/bin NO_DEFAULT_PATH) +find_program(CMAKE_AS armasm PATH ${TOOLCHAIN_HOME}/bin NO_DEFAULT_PATH) +find_program(CMAKE_AR armar PATH ${TOOLCHAIN_HOME}/bin NO_DEFAULT_PATH) + +SET(CMAKE_CXX_ARCHIVE_CREATE " -rq ") +SET(CMAKE_C_ARCHIVE_CREATE " -rq ") +SET(CMAKE_CXX_ARCHIVE_FINISH " -sq ") +SET(CMAKE_C_ARCHIVE_FINISH " -sq ") + +find_program(CMAKE_GDB ${CROSS_COMPILE}mdb PATH ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) + +include(${CMAKE_CURRENT_LIST_DIR}/target_bintools.cmake) diff --git a/cmake/bintools/armclang/target_bintools.cmake b/cmake/bintools/armclang/target_bintools.cmake new file mode 100644 index 00000000000000..677d702c636e3e --- /dev/null +++ b/cmake/bintools/armclang/target_bintools.cmake @@ -0,0 +1,71 @@ +# List of format the tool supports for converting, for example, +# GNU tools uses objectcopyy, which supports the following: ihex, srec, binary +set_property(TARGET bintools PROPERTY elfconvert_formats ihex binary) + +# armclang toolchain does not support all options in a single command +# Therefore a CMake script is used, so that multiple commands can be executed +# successively. +set_property(TARGET bintools PROPERTY elfconvert_command ${CMAKE_COMMAND}) + +set_property(TARGET bintools PROPERTY elfconvert_flag + -DFROMELF=${CMAKE_FROMELF} +) + +set_property(TARGET bintools PROPERTY elfconvert_flag_final + -P ${CMAKE_CURRENT_LIST_DIR}/elfconvert_command.cmake) + +set_property(TARGET bintools PROPERTY elfconvert_flag_strip_all "-DSTRIP_ALL=True") +set_property(TARGET bintools PROPERTY elfconvert_flag_strip_debug "-DSTRIP_DEBUG=True") + +set_property(TARGET bintools PROPERTY elfconvert_flag_intarget "-DINTARGET=") +set_property(TARGET bintools PROPERTY elfconvert_flag_outtarget "-DOUTTARGET=") + +set_property(TARGET bintools PROPERTY elfconvert_flag_section_remove "-DREMOVE_SECTION=") +set_property(TARGET bintools PROPERTY elfconvert_flag_section_only "-DONLY_SECTION=") + +# mwdt doesn't handle rename, consider adjusting abstraction. +set_property(TARGET bintools PROPERTY elfconvert_flag_section_rename "-DRENAME_SECTION=") + +set_property(TARGET bintools PROPERTY elfconvert_flag_gapfill "-DGAP_FILL=") +set_property(TARGET bintools PROPERTY elfconvert_flag_srec_len "-DSREC_LEN=") + +set_property(TARGET bintools PROPERTY elfconvert_flag_infile "-DINFILE=") +set_property(TARGET bintools PROPERTY elfconvert_flag_outfile "-DOUTFILE=") + +# +# - disassembly : Name of command for disassembly of files +# In this implementation `fromelf` is used +# disassembly_flag : --disassemble +# disassembly_flag_final : empty +# disassembly_flag_inline_source : --interleave=source +# disassembly_flag_all : empty, fromelf does not differentiate on this. +# disassembly_flag_infile : empty, fromelf doesn't take arguments for filenames +# disassembly_flag_outfile : --output + +set_property(TARGET bintools PROPERTY disassembly_command ${CMAKE_FROMELF}) +set_property(TARGET bintools PROPERTY disassembly_flag --disassemble) +set_property(TARGET bintools PROPERTY disassembly_flag_final "") +set_property(TARGET bintools PROPERTY disassembly_flag_inline_source --interleave=source) +set_property(TARGET bintools PROPERTY disassembly_flag_all "") + +set_property(TARGET bintools PROPERTY disassembly_flag_infile "") +set_property(TARGET bintools PROPERTY disassembly_flag_outfile "--output=" ) + +# +# - readelf : Name of command for reading elf files. +# In this implementation `fromelf` is used +# readelf_flag : empty +# readelf_flag_final : empty +# readelf_flag_headers : --text +# readelf_flag_infile : empty, fromelf doesn't take arguments for filenames +# readelf_flag_outfile : --output + +# This is using fromelf from arm-ds / Keil. +set_property(TARGET bintools PROPERTY readelf_command ${CMAKE_FROMELF}) + +set_property(TARGET bintools PROPERTY readelf_flag "") +set_property(TARGET bintools PROPERTY readelf_flag_final "") +set_property(TARGET bintools PROPERTY readelf_flag_headers --text) + +set_property(TARGET bintools PROPERTY readelf_flag_infile "") +set_property(TARGET bintools PROPERTY readelf_flag_outfile "--output=") diff --git a/cmake/compiler/armclang/compiler_flags.cmake b/cmake/compiler/armclang/compiler_flags.cmake new file mode 100644 index 00000000000000..3d0f713da4f40a --- /dev/null +++ b/cmake/compiler/armclang/compiler_flags.cmake @@ -0,0 +1,9 @@ +# First step is to inherit all properties from gcc, as clang is compatible with most flags. +include(${ZEPHYR_BASE}/cmake/compiler/clang/compiler_flags.cmake) + +# Required ASM flags when using armclang, this should be handled by CMake, but +# fails because of: https://gitlab.kitware.com/cmake/cmake/-/issues/19963 +set_property(TARGET asm APPEND PROPERTY required "--target=${triple}") + +# Only the ARM Compiler C library is currently supported. +set_compiler_property(PROPERTY nostdinc) diff --git a/cmake/compiler/armclang/generic.cmake b/cmake/compiler/armclang/generic.cmake new file mode 100644 index 00000000000000..44d34ddcdbe5f3 --- /dev/null +++ b/cmake/compiler/armclang/generic.cmake @@ -0,0 +1,38 @@ +# SPDX-License-Identifier: Apache-2.0 + +# Configures CMake for using ccac + +find_program(CMAKE_C_COMPILER ${CROSS_COMPILE}armclang PATH ${TOOLCHAIN_HOME}/bin NO_DEFAULT_PATH) + +set(triple arm-arm-none-eabi) + +set(CMAKE_DTS_PREPROCESSOR + ${CMAKE_C_COMPILER} + "--target=${triple}" + # -march=armv6-m is added to silence the warnings: + # 'armv4t' and 'arm7tdmi' is unsupported. + # We only do preprocessing so the actual arch is not important. + "-march=armv6-m" +) + +set(CMAKE_C_COMPILER_TARGET ${triple}) +set(CMAKE_ASM_COMPILER_TARGET ${triple}) +set(CMAKE_CXX_COMPILER_TARGET ${triple}) + +if(CMAKE_C_COMPILER STREQUAL CMAKE_C_COMPILER-NOTFOUND) + message(FATAL_ERROR "Zephyr was unable to find the armclang compiler") +endif() + +execute_process( + COMMAND ${CMAKE_C_COMPILER} --version + RESULT_VARIABLE ret + OUTPUT_QUIET + ERROR_QUIET + ) + +if(ret) + message(FATAL_ERROR "Executing the below command failed. " + "Are permissions set correctly? '${CMAKE_C_COMPILER} --version' " + "And is the license setup correctly ?" + ) +endif() diff --git a/cmake/compiler/armclang/target.cmake b/cmake/compiler/armclang/target.cmake new file mode 100644 index 00000000000000..c84089fa1ae79f --- /dev/null +++ b/cmake/compiler/armclang/target.cmake @@ -0,0 +1,77 @@ +# find the compilers for C, CPP, assembly +find_program(CMAKE_C_COMPILER ${CROSS_COMPILE}armclang PATH ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) +find_program(CMAKE_CXX_COMPILER ${CROSS_COMPILE}armclang PATH ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) +find_program(CMAKE_ASM_COMPILER ${CROSS_COMPILE}armclang PATH ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) + +# The CMAKE_REQUIRED_FLAGS variable is used by check_c_compiler_flag() +# (and other commands which end up calling check_c_source_compiles()) +# to add additional compiler flags used during checking. These flags +# are unused during "real" builds of Zephyr source files linked into +# the final executable. +# +include(${ZEPHYR_BASE}/cmake/gcc-m-cpu.cmake) +set(CMAKE_SYSTEM_PROCESSOR ${GCC_M_CPU}) + +list(APPEND TOOLCHAIN_C_FLAGS + -fshort-enums + ) + +if(CONFIG_ARM64) + list(APPEND TOOLCHAIN_C_FLAGS -mcpu=${GCC_M_CPU}) + + list(APPEND TOOLCHAIN_C_FLAGS -mabi=lp64) + list(APPEND TOOLCHAIN_LD_FLAGS -mabi=lp64) +else() + list(APPEND TOOLCHAIN_C_FLAGS -mcpu=${GCC_M_CPU}) + + if(CONFIG_COMPILER_ISA_THUMB2) + list(APPEND TOOLCHAIN_C_FLAGS -mthumb) + endif() + + list(APPEND TOOLCHAIN_C_FLAGS -mabi=aapcs) + + # Defines a mapping from GCC_M_CPU to FPU + + if(CONFIG_CPU_HAS_FPU_DOUBLE_PRECISION) + set(PRECISION_TOKEN) + else() + set(PRECISION_TOKEN sp-) + endif() + + set(FPU_FOR_cortex-m4 fpv4-${PRECISION_TOKEN}d16) + set(FPU_FOR_cortex-m7 fpv5-${PRECISION_TOKEN}d16) + set(FPU_FOR_cortex-m33 fpv5-${PRECISION_TOKEN}d16) + + if(CONFIG_FPU) + list(APPEND TOOLCHAIN_C_FLAGS -mfpu=${FPU_FOR_${GCC_M_CPU}}) + if (CONFIG_FP_SOFTABI) + list(APPEND TOOLCHAIN_C_FLAGS -mfloat-abi=softfp) + elseif(CONFIG_FP_HARDABI) + list(APPEND TOOLCHAIN_C_FLAGS -mfloat-abi=hard) + endif() + endif() +endif() + +foreach(file_name include/stddef.h) + execute_process( + COMMAND ${CMAKE_C_COMPILER} --print-file-name=${file_name} + OUTPUT_VARIABLE _OUTPUT + ) + get_filename_component(_OUTPUT "${_OUTPUT}" DIRECTORY) + string(REGEX REPLACE "\n" "" _OUTPUT ${_OUTPUT}) + + list(APPEND NOSTDINC ${_OUTPUT}) +endforeach() + +foreach(isystem_include_dir ${NOSTDINC}) + list(APPEND isystem_include_flags -isystem ${isystem_include_dir}) +endforeach() + +set(CMAKE_REQUIRED_FLAGS ${isystem_include_flags}) +string(REPLACE ";" " " CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") + +if(CONFIG_ARMCLANG_STD_LIBC) + # Zephyr requires AEABI portability to ensure correct functioning of the C + # library, for example error numbers, errno.h. + list(APPEND TOOLCHAIN_C_FLAGS -D_AEABI_PORTABILITY_LEVEL=1) +endif() diff --git a/cmake/extensions.cmake b/cmake/extensions.cmake index 9fe246f31ee47c..b5fe2898be1fd4 100644 --- a/cmake/extensions.cmake +++ b/cmake/extensions.cmake @@ -21,6 +21,8 @@ # 3.5. File system management # 4. Devicetree extensions # 4.1 dt_* +# 5. Zephyr linker functions +# 5.1. zephyr_linker* ######################################################## # 1. Zephyr-aware extensions @@ -1248,6 +1250,38 @@ function(check_dtc_flag flag ok) endif() endfunction() +# Function to round number to next power of two. +# +# Usage: +# pow2round() +# +# Example: +# set(test 2) +# pow2round(test) +# # test is still 2 +# +# set(test 5) +# pow2round(test) +# # test is now 8 +# +# Arguments: +# n = Variable containing the number to round +function(pow2round n) + math(EXPR x "${${n}} & (${${n}} - 1)") + if(${x} EQUAL 0) + return() + endif() + + math(EXPR ${n} "${${n}} | (${${n}} >> 1)") + math(EXPR ${n} "${${n}} | (${${n}} >> 2)") + math(EXPR ${n} "${${n}} | (${${n}} >> 4)") + math(EXPR ${n} "${${n}} | (${${n}} >> 8)") + math(EXPR ${n} "${${n}} | (${${n}} >> 16)") + math(EXPR ${n} "${${n}} | (${${n}} >> 32)") + math(EXPR ${n} "${${n}} + 1") + set(${n} ${${n}} PARENT_SCOPE) +endfunction() + ######################################################## # 2. Kconfig-aware extensions ######################################################## @@ -2809,3 +2843,689 @@ function(dt_chosen var) set(${var} ${${var}} PARENT_SCOPE) endif() endfunction() + +######################################################## +# 5. Zephyr linker function +######################################################## +# 5.1. zephyr_linker* +# +# The following methods are for defining linker structure using CMake functions. +# +# This allows Zephyr developers to define linker sections and their content and +# have this configuration rendered into an appropriate linker script based on +# the toolchain in use. +# For example: +# ld linker scripts with GNU ld +# ARM scatter files with ARM linker. +# +# Example usage: +# zephyr_linker_section( +# NAME my_data +# VMA RAM +# LMA FLASH +# ) +# +# and to configure special input sections for the section +# zephyr_linker_section_configure( +# SECTION my_data +# INPUT "my_custom_data" +# KEEP +# ) + + +# Usage: +# zephyr_linker([FORMAT ] +# [ENTRY ] +# ) +# +# Zephyr linker general settings. +# This function specifies general settings for the linker script to be generated. +# +# FORMAT : The output format of the linked executable. +# ENTRY : The code entry symbol. +# +function(zephyr_linker) + set(single_args "ENTRY;FORMAT") + cmake_parse_arguments(LINKER "" "${single_args}" "" ${ARGN}) + + if(LINKER_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "zephyr_linker(${ARGV0} ...) given unknown " + "arguments: ${LINKER_UNPARSED_ARGUMENTS}" + ) + endif() + + if(DEFINED LINKER_FORMAT) + get_property(format_defined TARGET linker PROPERTY FORMAT SET) + if(format_defined) + message(FATAL_ERROR "zephyr_linker(FORMAT ...) already configured.") + else() + set_property(TARGET linker PROPERTY FORMAT ${LINKER_FORMAT}) + endif() + endif() + + if(DEFINED LINKER_ENTRY) + get_property(entry_defined TARGET linker PROPERTY ENTRY SET) + if(entry_defined) + message(FATAL_ERROR "zephyr_linker(ENTRY ...) already configured.") + else() + set_property(TARGET linker PROPERTY ENTRY ${LINKER_ENTRY}) + endif() + endif() +endfunction() + +# Usage: +# zephyr_linker_memory(NAME START
SIZE FLAGS ) +# +# Zephyr linker memory. +# This function specifies a memory region for the platform in use. +# +# Note: +# This function should generally be called with values obtained from +# devicetree or Kconfig. +# +# NAME : Name of the memory region, for example FLASH. +# START
: Start address of the memory region. +# Start address can be given as decimal or hex value. +# SIZE : Size of the memory region. +# Size can be given as decimal value, hex value, or decimal with postfix k or m. +# All the following are valid values: +# 1048576, 0x10000, 1024k, 1024K, 1m, and 1M. +# FLAGS : Flags describing properties of the memory region. +# Currently supported: +# r: Read-only region +# w: Read-write region +# x: Executable region +# The flags r and x, or w and x may be combined like: rx, wx. +function(zephyr_linker_memory) + set(single_args "FLAGS;NAME;SIZE;START") + cmake_parse_arguments(MEMORY "" "${single_args}" "" ${ARGN}) + + if(MEMORY_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "zephyr_linker_memory(${ARGV0} ...) given unknown " + "arguments: ${MEMORY_UNPARSED_ARGUMENTS}" + ) + endif() + + foreach(arg ${single_args}) + if(NOT DEFINED MEMORY_${arg}) + message(FATAL_ERROR "zephyr_linker_memory(${ARGV0} ...) missing required " + "argument: ${arg}" + ) + endif() + endforeach() + + set(MEMORY) + zephyr_linker_arg_val_list(MEMORY "${single_args}") + + string(REPLACE ";" "\;" MEMORY "${MEMORY}") + set_property(TARGET linker + APPEND PROPERTY MEMORY_REGIONS "{${MEMORY}}" + ) +endfunction() + +# Usage: +# zephyr_linker_memory_ifdef( NAME START
SIZE FLAGS ) +# +# Will create memory region if is enabled. +# +# : Setting to check for True value before invoking +# zephyr_linker_memory() +# +# See zephyr_linker_memory() description for other supported arguments. +# +macro(zephyr_linker_memory_ifdef feature_toggle) + if(${${feature_toggle}}) + zephyr_linker_memory(${ARGN}) + endif() +endmacro() + +# Usage: +# zephyr_linker_dts_memory(NAME PATH FLAGS ) +# zephyr_linker_dts_memory(NAME NODELABEL FLAGS ) +# zephyr_linker_dts_memory(NAME CHOSEN FLAGS ) +# +# Zephyr linker devicetree memory. +# This function specifies a memory region for the platform in use based on its +# devicetree configuration. +# +# The memory will only be defined if the devicetree node or a devicetree node +# matching the nodelabel exists and has status okay. +# +# Only one of PATH, NODELABEL, and CHOSEN parameters may be given. +# +# NAME : Name of the memory region, for example FLASH. +# PATH : Devicetree node identifier. +# NODELABEL