1/* 2 * Copyright (c) 2017-2023 Arm Limited. All rights reserved. 3 * Copyright (c) 2022 Cypress Semiconductor Corporation (an Infineon company) 4 * or an affiliate of Cypress Semiconductor Corporation. All rights reserved. 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19/***********{{utilities.donotedit_warning}}***********/ 20 21/* 22 * Customized region name prefix abbreviation: 23 * LR : A Load region. 24 * ER : A typical execution region. 25 * PT : An empty execution region used as position-tag/address-alignment. 26 * 27 * No applying customzied prefixes on linker/system reserved/intentional 28 * names, such as 'ARM_LIB_STACK'. 29 */ 30 31#include "region_defs.h" 32 33/* Include file with definitions for section alignments. 34 * Note: it should be included after region_defs.h to let platform define 35 * default values if needed. */ 36#include "tfm_s_linker_alignments.h" 37 38/* position tag block : code + RO-data */ 39define block PT_RO_START with alignment = TFM_LINKER_PT_RO_ALIGNMENT, size = 0 { }; 40define block PT_RO_END with alignment = TFM_LINKER_PT_RO_ALIGNMENT, size = 0 { }; 41 42define block ER_VECTORS with size = S_CODE_VECTOR_TABLE_SIZE { 43 readonly section .intvec 44}; 45 46#ifdef CONFIG_TFM_USE_TRUSTZONE 47 /* 48 * Place the CMSE Veneers (containing the SG instruction) in a separate 49 * at least 32 bytes aligned region so that the SAU can be programmed to 50 * just set this region as Non-Secure Callable. 51 */ 52define block ER_VENEER with alignment = TFM_LINKER_VENEERS_ALIGNMENT {section Veneer$$CMSE}; 53 54define block VENEER_ALIGN with alignment = TFM_LINKER_VENEERS_ALIGNMENT, size = 0 { }; 55#endif 56 57define block ER_TFM_CODE with fixed order, alignment = 8 { 58 ro section *startup*, 59 ro section .text object *libplatform_s*, 60 ro section .rodata object *libplatform_s*, 61 ro object *libtfm_spm* 62}; 63 /**** Section for holding partition RO load data */ 64 /* 65 * Sort the partition info by priority to guarantee the initing order. 66 * The first loaded partition will be inited at last in SFN model. 67 */ 68define block TFM_SP_LOAD_LIST with alignment = 4 { 69 ro section .part_load_priority_00 object load_info_*.o, 70 ro section .part_load_priority_01 object load_info_*.o, 71 ro section .part_load_priority_02 object load_info_*.o, 72 ro section .part_load_priority_03 object load_info_*.o, 73}; 74 75#if defined(S_RAM_CODE_START) 76 /* Flash drivers code that gets copied from Flash */ 77 initialize by copy { 78 ro object *libflash_drivers*, 79 }; 80 81 define block ER_CODE_SRAM with fixed order, alignment = 4, maximum size = S_RAM_CODE_SIZE { 82 rw section .text, 83 rw section .rodata, 84 rw section .textrw, /* __ramfunc */ 85 }; 86 87place at address S_RAM_CODE_START { block ER_CODE_SRAM }; 88#endif 89 90/**** blocks CODE + RO-data definition starts here */ 91{% for partition in partitions %} 92define block ER_{{partition.manifest.name}}_RO with alignment = {{ 'TFM_LINKER_PSA_ROT_LINKER_CODE_ALIGNMENT' if partition.manifest.type == 'PSA-ROT' else 'TFM_LINKER_APP_ROT_LINKER_CODE_ALIGNMENT' }} 93{ 94 {% if partition.attr.linker_pattern.library_list %} 95 {% for pattern in partition.attr.linker_pattern.library_list %} 96 ro section .text object {{pattern}}, 97 ro section .rodata object {{pattern}}, 98 {% endfor %} 99 {% endif %} 100 {% if partition.attr.linker_pattern.object_list %} 101 {% for pattern in partition.attr.linker_pattern.object_list %} 102 ro object {{pattern}}, 103 {% endfor %} 104 {% endif %} 105 {% if partition.manifest.type == 'PSA-ROT' %} 106 section {{partition.manifest.name}}_PSA-ROT_ATTR_FN, 107 {% endif %} 108 {% if partition.manifest.type == 'APPLICATION-ROT' %} 109 section {{partition.manifest.name}}_APP-ROT_ATTR_FN, 110 {% endif %} 111}; 112{% endfor %} 113/**** blocks CODE + RO-data definition ends here*/ 114 115/**** Block Unprivileged Secure code + RO-data definition starts here */ 116define block TFM_UNPRIV_CODE_START with alignment = TFM_LINKER_UNPRIV_CODE_ALIGNMENT { 117 readonly 118}; 119 120 /* 121 * This empty, zero long execution region is here to mark the end address 122 * of TFM unprivileged code. 123 */ 124define block TFM_UNPRIV_CODE_END with alignment = TFM_LINKER_UNPRIV_CODE_ALIGNMENT, size = 0 { }; 125 126/* position tag block : base address of secure data area ( S_DATA_START)*/ 127define block PT_SECURE_DATA_START with alignment = TFM_LINKER_SECURE_DATA_ALIGNMENT, size = 0 { }; 128define block PT_PRIV_RWZI_START with alignment = TFM_LINKER_PT_PRIV_RWZI_ALIGNMENT, size = 0 { }; 129 130define block TFM_SHARED_DATA with alignment = TFM_LINKER_BL2_SHARED_DATA_ALIGNMENT, size = BOOT_TFM_SHARED_DATA_SIZE { }; 131define block ARM_LIB_STACK with alignment = TFM_LINKER_MSP_STACK_ALIGNMENT, size = S_MSP_STACK_SIZE - 0x8 { }; 132define block STACKSEAL with size = 0x8 { }; 133 134#if defined(ENABLE_HEAP) 135 define block HEAP with alignment = 8, size = S_HEAP_SIZE { }; 136 define block ARM_LIB_HEAP {block HEAP}; 137 keep {block HEAP, block ARM_LIB_HEAP}; 138#endif 139 140define block ER_TFM_DATA with alignment = 8 {readwrite}; 141 142/* The runtime partition placed order is same as load partition */ 143define block ER_PART_RT_POOL with alignment = 4 { 144 zi section .bss.part_runtime_priority_00, 145 zi section .bss.part_runtime_priority_01, 146 zi section .bss.part_runtime_priority_02, 147 zi section .bss.part_runtime_priority_03, 148}; 149 150/* The runtime service placed order is same as load partition */ 151define block ER_SERV_RT_POOL with alignment = 4 { 152 zi section .bss.serv_runtime_priority_00, 153 zi section .bss.serv_runtime_priority_01, 154 zi section .bss.serv_runtime_priority_02, 155 zi section .bss.serv_runtime_priority_03, 156}; 157 158keep {block ER_PART_RT_POOL, block ER_SERV_RT_POOL}; 159 160 /**** Blocks RWZI definition starts here */ 161{% for partition in partitions %} 162 {% if partition.manifest.type == 'PSA-ROT' %} 163 /* Position tag : start Block :*/ 164 define block PT_{{partition.manifest.name}}_PRIVATE_DATA_START with alignment = TFM_LINKER_PSA_ROT_LINKER_DATA_ALIGNMENT, size = 0 { }; 165 166 define block ER_{{partition.manifest.name}}_RWZI with alignment = TFM_LINKER_PSA_ROT_LINKER_DATA_ALIGNMENT { 167 {% if partition.attr.linker_pattern.library_list %} 168 {% for pattern in partition.attr.linker_pattern.library_list %} 169 rw section .data object {{pattern}}, 170 rw section .bss object {{pattern}}, 171 {% endfor %} 172 {% endif %} 173 {% if partition.attr.linker_pattern.object_list %} 174 {% for pattern in partition.attr.linker_pattern.object_list %} 175 rw object {{pattern}}, 176 {% endfor %} 177 {% endif %} 178 section {{partition.manifest.name}}_PSA-ROT_ATTR_RW, 179 section {{partition.manifest.name}}_PSA-ROT_ATTR_ZI, 180}; 181/* Position tag : start Block :*/ 182 define block PT_{{partition.manifest.name}}_PRIVATE_DATA_END with alignment = TFM_LINKER_PSA_ROT_LINKER_DATA_ALIGNMENT, size = 0 { }; 183 {% endif %} 184{% endfor %} 185 186/**** block Position tag PSA RoT RWZI ends definition */ 187define block PT_PRIV_RWZI_END with alignment = TFM_LINKER_PT_PRIV_RWZI_ALIGNMENT, size = 0 { }; 188 189{% for partition in partitions %} 190 {% if partition.manifest.type == 'APPLICATION-ROT' %} 191 /* Position tag : start Block :*/ 192 define block PT_{{partition.manifest.name}}_PRIVATE_DATA_START with alignment = TFM_LINKER_APP_ROT_LINKER_DATA_ALIGNMENT, size = 0 { }; 193 194 define block ER_{{partition.manifest.name}}_RWZI with alignment = TFM_LINKER_APP_ROT_LINKER_DATA_ALIGNMENT { 195 {% if partition.attr.linker_pattern.library_list %} 196 {% for pattern in partition.attr.linker_pattern.library_list %} 197 rw section .data object {{pattern}}, 198 rw section .bss object {{pattern}}, 199 {% endfor %} 200 {% endif %} 201 {% if partition.attr.linker_pattern.object_list %} 202 {% for pattern in partition.attr.linker_pattern.object_list %} 203 rw object {{pattern}}, 204 {% endfor %} 205 {% endif %} 206 section {{partition.manifest.name}}_APP-ROT_ATTR_RW, 207 section {{partition.manifest.name}}_APP-ROT_ATTR_ZI, 208}; 209/* Position tag : start Block :*/ 210 define block PT_{{partition.manifest.name}}_PRIVATE_DATA_END with alignment = TFM_LINKER_APP_ROT_LINKER_DATA_ALIGNMENT, size = 0 { }; 211 {% endif %} 212{% endfor %} 213 214#if defined(CONFIG_TFM_PARTITION_META) 215define block TFM_SP_META_PTR with alignment = TFM_LINKER_SP_META_PTR_ALIGNMENT { 216 zi section .bss.SP_META_PTR_SPRTL_INST 217 }; 218 219 /* 220 * This empty, zero long execution region is here to mark the end address 221 * of TFM partition metadata pointer region. 222 */ 223define block TFM_SP_META_PTR_END with alignment = TFM_LINKER_SP_META_PTR_ALIGNMENT, size = 0 { }; 224#endif 225 226#ifdef RAM_VECTORS_SUPPORT 227define block ER_RAM_VECTORS with alignment = TFM_LINKER_RAM_VECTORS_ALIGNMENT { section .ramvec }; 228#endif 229 230define block PT_SRAM_WATERMARK with alignment = TFM_LINKER_SECURE_DATA_ALIGNMENT, size = 0 { }; 231 232/* Define Flash content */ 233define block LR_CODE with fixed order { 234 block ER_VECTORS, 235#ifdef CONFIG_TFM_USE_TRUSTZONE 236 block ER_VENEER, 237 block VENEER_ALIGN, 238#endif 239 block PT_RO_START, 240 block ER_TFM_CODE, 241 block TFM_SP_LOAD_LIST, 242 /**** PSA RoT CODE + RO-data starts here */ 243{% for partition in partitions %} 244 {% if partition.manifest.type == 'PSA-ROT' %} 245 block ER_{{partition.manifest.name}}_RO, 246 {% endif %} 247{% endfor %} 248 /**** APPLICATION RoT RO CODE + data starts here */ 249{% for partition in partitions %} 250 {% if partition.manifest.type == 'APPLICATION-ROT' %} 251 block ER_{{partition.manifest.name}}_RO, 252 {% endif %} 253{% endfor %} 254 block TFM_UNPRIV_CODE_START, 255 block TFM_UNPRIV_CODE_END, 256 block PT_RO_END, 257}; 258 259 260do not initialize { 261 section .noinit, 262 rw section .ramvec 263 }; 264initialize by copy with packing = none { readwrite } 265#ifndef S_RAM_CODE_START 266 except { section .textrw } 267#endif 268 ; 269if (isdefinedsymbol(__USE_DLIB_PERTHREAD)) 270{ 271 // Required in a multi-threaded application 272 initialize by copy { section __DLIB_PERTHREAD }; 273} 274 275 276/* Place Flash content */ 277place at address S_CODE_START { block LR_CODE }; 278/* Define RAM content */ 279define block DATA with fixed order { 280 /**** Base address of secure data area */ 281 block PT_SECURE_DATA_START, 282 block PT_PRIV_RWZI_START, 283 block TFM_SHARED_DATA, 284 block ARM_LIB_STACK, 285 block STACKSEAL, 286#if defined(ENABLE_HEAP) 287 block ARM_LIB_HEAP, 288#endif 289 block ER_TFM_DATA, 290 block ER_PART_RT_POOL, 291 block ER_SERV_RT_POOL, 292 /* place PSA-ROT data */ 293{% for partition in partitions %} 294 {% if partition.manifest.type == 'PSA-ROT' %} 295 block PT_{{partition.manifest.name}}_PRIVATE_DATA_START, 296 block ER_{{partition.manifest.name}}_RWZI, 297 block PT_{{partition.manifest.name}}_PRIVATE_DATA_END, 298 {% endif %} 299{% endfor %} 300 301 block PT_PRIV_RWZI_END, 302 303 /* place APP-ROT data */ 304{% for partition in partitions %} 305 {% if partition.manifest.type == 'APPLICATION-ROT' %} 306 block PT_{{partition.manifest.name}}_PRIVATE_DATA_START, 307 block ER_{{partition.manifest.name}}_RWZI, 308 block PT_{{partition.manifest.name}}_PRIVATE_DATA_END, 309 {% endif %} 310{% endfor %} 311 312#if defined(CONFIG_TFM_PARTITION_META) 313 block TFM_SP_META_PTR, 314 block TFM_SP_META_PTR_END, 315#endif 316 317#ifdef RAM_VECTORS_SUPPORT 318 block ER_RAM_VECTORS, 319#endif 320 321 block PT_SRAM_WATERMARK, 322 /* Make sure that the sections allocated in the SRAM does not exceed the 323 * size of the SRAM available. 324 */ 325}; 326 327place at address S_DATA_START { block DATA }; 328 329 /* Reserved place for NS application. 330 * No code will be placed here, just address of this region is used in the 331 * secure code to configure certain HW components. This generates an empty 332 * execution region description warning during linking. 333 */ 334define block LR_NS_PARTITION with size = NS_PARTITION_SIZE { }; 335place at address NS_PARTITION_START { block LR_NS_PARTITION }; 336 337#ifdef BL2 338 /* Reserved place for new image in case of firmware upgrade. 339 * No code will be placed here, just address of this region is used in the 340 * secure code to configure certain HW components. This generates an empty 341 * execution region description warning during linking. 342 */ 343define block LR_SECONDARY_PARTITION with size = SECONDARY_PARTITION_SIZE { }; 344place at address SECONDARY_PARTITION_START { block LR_SECONDARY_PARTITION }; 345#endif /* BL2 */ 346