1#------------------------------------------------------------------------------- 2# Copyright (c) 2023-2024, Arm Limited. All rights reserved. 3# 4# SPDX-License-Identifier: BSD-3-Clause 5# 6#------------------------------------------------------------------------------- 7 8cmake_minimum_required(VERSION 3.22) 9cmake_policy(SET CMP0115 NEW) 10 11SET(CMAKE_SYSTEM_NAME Generic) 12set(CMAKE_SYSTEM_PROCESSOR ${TFM_SYSTEM_PROCESSOR}) 13 14if(CROSS_COMPILE) 15 set(CMAKE_C_COMPILER_TARGET arm-${CROSS_COMPILE}) 16 set(CMAKE_ASM_COMPILER_TARGET arm-${CROSS_COMPILE}) 17else() 18 set(CMAKE_C_COMPILER_TARGET arm-arm-none-eabi) 19 set(CMAKE_ASM_COMPILER_TARGET arm-arm-none-eabi) 20endif() 21 22set(CMAKE_C_COMPILER iccarm) 23set(CMAKE_CXX_COMPILER iccarm) 24set(CMAKE_ASM_COMPILER iasmarm) 25 26set(CMAKE_C_FLAGS_DEBUG "-r -On") 27 28# This variable name is a bit of a misnomer. The file it is set to is included 29# at a particular step in the compiler initialisation. It is used here to 30# configure the extensions for object files. Despite the name, it also works 31# with the Ninja generator. 32set(CMAKE_USER_MAKE_RULES_OVERRIDE ${CMAKE_CURRENT_LIST_DIR}/set_extensions.cmake) 33 34macro(tfm_toolchain_reset_compiler_flags) 35 set_property(DIRECTORY PROPERTY COMPILE_OPTIONS "") 36 37 add_compile_options( 38 $<$<COMPILE_LANGUAGE:C,CXX>:-e> 39 $<$<COMPILE_LANGUAGE:C,CXX>:--dlib_config=full> 40 $<$<COMPILE_LANGUAGE:C,CXX>:--silent> 41 $<$<COMPILE_LANGUAGE:C,CXX>:-DNO_TYPEOF> 42 $<$<COMPILE_LANGUAGE:C,CXX>:-D_NO_DEFINITIONS_IN_HEADER_FILES> 43 $<$<COMPILE_LANGUAGE:C,CXX>:--diag_suppress=Pe546,Pe940,Pa082,Pa084> 44 $<$<COMPILE_LANGUAGE:C,CXX>:--no_path_in_file_macros> 45 $<$<AND:$<COMPILE_LANGUAGE:C,CXX,ASM>,$<BOOL:${TFM_DEBUG_SYMBOLS}>,$<CONFIG:Release,MinSizeRel>>:-r> 46 ) 47endmacro() 48 49macro(tfm_toolchain_reset_linker_flags) 50 set_property(DIRECTORY PROPERTY LINK_OPTIONS "") 51 52 add_link_options( 53 --silent 54 --semihosting 55 --redirect __write=__write_buffered 56 --diag_suppress=lp005 57 ) 58endmacro() 59 60macro(tfm_toolchain_set_processor_arch) 61 if(${TFM_SYSTEM_PROCESSOR} STREQUAL "cortex-m0plus") 62 set(CMAKE_SYSTEM_PROCESSOR Cortex-M0+) 63 else() 64 set(CMAKE_SYSTEM_PROCESSOR ${TFM_SYSTEM_PROCESSOR}) 65 endif() 66 67 if (DEFINED TFM_SYSTEM_DSP) 68 if(NOT TFM_SYSTEM_DSP) 69 string(APPEND CMAKE_SYSTEM_PROCESSOR ".no_dsp") 70 endif() 71 endif() 72endmacro() 73 74macro(tfm_toolchain_reload_compiler) 75 tfm_toolchain_set_processor_arch() 76 tfm_toolchain_reset_compiler_flags() 77 tfm_toolchain_reset_linker_flags() 78 79 unset(CMAKE_C_FLAGS_INIT) 80 unset(CMAKE_C_LINK_FLAGS) 81 unset(CMAKE_ASM_FLAGS_INIT) 82 unset(CMAKE_ASM_LINK_FLAGS) 83 84 set(CMAKE_C_FLAGS_INIT "--cpu ${CMAKE_SYSTEM_PROCESSOR}") 85 set(CMAKE_ASM_FLAGS_INIT "--cpu ${CMAKE_SYSTEM_PROCESSOR}") 86 set(CMAKE_C_LINK_FLAGS "--cpu ${CMAKE_SYSTEM_PROCESSOR}") 87 set(CMAKE_ASM_LINK_FLAGS "--cpu ${CMAKE_SYSTEM_PROCESSOR}") 88 89 set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS_INIT}) 90 set(CMAKE_ASM_FLAGS ${CMAKE_ASM_FLAGS_INIT}) 91 92 # Can't use the highest optimization with IAR on v8.1m arch because of the 93 # compilation bug in mbedcrypto 94 if ((CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL "9.20") AND 95 (CMAKE_C_COMPILER_VERSION VERSION_LESS_EQUAL "9.32.1") AND 96 ((TFM_SYSTEM_PROCESSOR STREQUAL "cortex-m85") OR 97 (TFM_SYSTEM_PROCESSOR STREQUAL "cortex-m55")) AND 98 (NOT (CMAKE_BUILD_TYPE STREQUAL "Debug"))) 99 message(FATAL_ERROR "Only debug build available for M55 and M85" 100 " cores with IAR version between 9.20 and 9.32.1") 101 endif() 102 103 if (CONFIG_TFM_FLOAT_ABI STREQUAL "hard") 104 if (CONFIG_TFM_ENABLE_FP) 105 set(COMPILER_CP_C_FLAG "--fpu=${CONFIG_TFM_FP_ARCH_ASM}") 106 set(COMPILER_CP_ASM_FLAG "--fpu=${CONFIG_TFM_FP_ARCH_ASM}") 107 # armasm and armlink have the same option "--fpu" and are both used to 108 # specify the target FPU architecture. So the supported FPU architecture 109 # names can be shared by armasm and armlink. 110 set(LINKER_CP_OPTION "--fpu=${CONFIG_TFM_FP_ARCH_ASM}") 111 endif() 112 else() 113 set(COMPILER_CP_C_FLAG "--fpu=none") 114 set(COMPILER_CP_ASM_FLAG "--fpu=none") 115 set(LINKER_CP_OPTION "--fpu=none") 116 endif() 117 118 string(APPEND CMAKE_C_FLAGS " " ${COMPILER_CP_C_FLAG}) 119 string(APPEND CMAKE_ASM_FLAGS " " ${COMPILER_CP_ASM_FLAG}) 120 string(APPEND CMAKE_C_LINK_FLAGS " " ${LINKER_CP_OPTION}) 121 string(APPEND CMAKE_ASM_LINK_FLAGS " " ${LINKER_CP_OPTION}) 122 123 add_compile_definitions( 124 $<$<STREQUAL:${TFM_SYSTEM_ARCHITECTURE},armv6-m>:__ARM_ARCH_6M__=1> 125 $<$<STREQUAL:${TFM_SYSTEM_ARCHITECTURE},armv7-m>:__ARM_ARCH_7M__=1> 126 $<$<AND:$<STREQUAL:${TFM_SYSTEM_ARCHITECTURE},armv7-m>,$<BOOL:__ARM_FEATURE_DSP>>:__ARM_ARCH_7EM__=1> 127 $<$<STREQUAL:${TFM_SYSTEM_ARCHITECTURE},armv8-m.base>:__ARM_ARCH_8M_BASE__=1> 128 $<$<STREQUAL:${TFM_SYSTEM_ARCHITECTURE},armv8-m.main>:__ARM_ARCH_8M_MAIN__=1> 129 $<$<STREQUAL:${TFM_SYSTEM_ARCHITECTURE},armv8.1-m.main>:__ARM_ARCH_8_1M_MAIN__=1> 130 ) 131endmacro() 132 133# Configure environment for the compiler setup run by cmake at the first 134# `project` call in <tfm_root>/CMakeLists.txt. After this mandatory setup is 135# done, all further compiler setup is done via tfm_toolchain_reload_compiler() 136tfm_toolchain_reload_compiler() 137 138# Specify the scatter file used to link `target`. 139# Behaviour for handling scatter files is so wildly divergent between compilers 140# that this macro is required. 141# 142# Vendor platform can set a scatter file as property INTERFACE_LINK_DEPENDS of platform_ns. 143# `target` can fetch the scatter file from platform_ns. 144# 145# Alternatively, NS build can call target_add_scatter_file() with the install directory of 146# scatter files. 147# target_add_scatter_file(target, install_dir) 148# 149# target_add_scatter_file() fetch a scatter file from the install directory. 150macro(target_add_scatter_file target) 151 # Try if scatter_file is passed from platform_ns 152 get_target_property(scatter_file 153 platform_ns 154 INTERFACE_LINK_DEPENDS 155 ) 156 157 # If scatter_file is not passed from platform_ns 158 # Try if any scatter file is exported in install directory 159 # The intall directory is passed as an optinal argument 160 if(${scatter_file} STREQUAL "scatter_file-NOTFOUND") 161 set(install_dir ${ARGN}) 162 list(LENGTH install_dir nr_install_dir) 163 164 # If nr_install_dir == 1, search for .icf file under install dir 165 if(${nr_install_dir} EQUAL 1) 166 file(GLOB scatter_file "${install_dir}/*.icf") 167 endif() 168 endif() 169 170 if(NOT EXISTS ${scatter_file}) 171 message(FATAL_ERROR "Unable to find NS scatter file ${scatter_file}") 172 endif() 173 174 add_library(${target}_scatter OBJECT) 175 target_sources(${target}_scatter 176 PRIVATE 177 ${scatter_file} 178 ) 179 # Cmake cannot use generator expressions in the 180 # set_source_file_properties command, so instead we just parse the regex 181 # for the filename and set the property on all files, regardless of if 182 # the generator expression would evaluate to true or not. 183 string(REGEX REPLACE ".*>:(.*)>$" "\\1" SCATTER_FILE_PATH "${scatter_file}") 184 set_source_files_properties(${SCATTER_FILE_PATH} 185 PROPERTIES 186 LANGUAGE C 187 ) 188 189 target_link_options(${target} 190 PRIVATE 191 --config $<TARGET_OBJECTS:${target}_scatter> 192 ) 193 194 add_dependencies(${target} 195 ${target}_scatter 196 ) 197 198 set_target_properties(${target} PROPERTIES LINK_DEPENDS $<TARGET_OBJECTS:${target}_scatter>) 199 200 target_link_libraries(${target}_scatter 201 PRIVATE 202 platform_region_defs 203 ) 204 205 target_compile_options(${target}_scatter 206 PRIVATE 207 --preprocess=sn $<TARGET_OBJECTS:${target}_scatter> 208 ) 209endmacro() 210 211macro(add_convert_to_bin_target target) 212 get_target_property(bin_dir ${target} RUNTIME_OUTPUT_DIRECTORY) 213 214 add_custom_target(${target}_bin 215 SOURCES ${bin_dir}/${target}.bin 216 ) 217 add_custom_command(OUTPUT ${bin_dir}/${target}.bin 218 DEPENDS ${target} 219 COMMAND ielftool 220 --silent 221 --bin $<TARGET_FILE:${target}> 222 ${bin_dir}/${target}.bin 223 ) 224 225 add_custom_target(${target}_elf 226 SOURCES ${bin_dir}/${target}.elf 227 ) 228 add_custom_command(OUTPUT ${bin_dir}/${target}.elf 229 DEPENDS ${target} 230 COMMAND ielftool 231 --silent 232 $<TARGET_FILE:${target}> 233 ${bin_dir}/${target}.elf 234 ) 235 236 add_custom_target(${target}_hex 237 SOURCES ${bin_dir}/${target}.hex 238 ) 239 add_custom_command(OUTPUT ${bin_dir}/${target}.hex 240 DEPENDS ${target} 241 COMMAND ielftool 242 --silent 243 --ihex $<TARGET_FILE:${target}> 244 ${bin_dir}/${target}.hex 245 ) 246 247 add_custom_target(${target}_binaries 248 ALL 249 DEPENDS ${target}_bin 250 DEPENDS ${target}_elf 251 DEPENDS ${target}_hex 252 ) 253endmacro() 254