/* * Copyright (c) 2017-2023 Arm Limited. All rights reserved. * Copyright (c) 2022 Cypress Semiconductor Corporation (an Infineon company) * or an affiliate of Cypress Semiconductor Corporation. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /***********{{utilities.donotedit_warning}}***********/ /* * Customized region name prefix abbreviation: * LR : A Load region. * ER : A typical execution region. * PT : An empty execution region used as position-tag/address-alignment. * * No applying customzied prefixes on linker/system reserved/intentional * names, such as 'ARM_LIB_STACK'. */ #include "region_defs.h" /* Include file with definitions for section alignments. * Note: it should be included after region_defs.h to let platform define * default values if needed. */ #include "tfm_s_linker_alignments.h" /* position tag block : code + RO-data */ define block PT_RO_START with alignment = TFM_LINKER_PT_RO_ALIGNMENT, size = 0 { }; define block PT_RO_END with alignment = TFM_LINKER_PT_RO_ALIGNMENT, size = 0 { }; define block ER_VECTORS with size = S_CODE_VECTOR_TABLE_SIZE { readonly section .intvec }; #ifdef CONFIG_TFM_USE_TRUSTZONE /* * Place the CMSE Veneers (containing the SG instruction) in a separate * at least 32 bytes aligned region so that the SAU can be programmed to * just set this region as Non-Secure Callable. */ define block ER_VENEER with alignment = TFM_LINKER_VENEERS_ALIGNMENT {section Veneer$$CMSE}; define block VENEER_ALIGN with alignment = TFM_LINKER_VENEERS_ALIGNMENT, size = 0 { }; #endif define block ER_TFM_CODE with fixed order, alignment = 8 { ro section *startup*, ro section .text object *libplatform_s*, ro section .rodata object *libplatform_s*, ro object *libtfm_spm* }; /**** Section for holding partition RO load data */ /* * Sort the partition info by priority to guarantee the initing order. * The first loaded partition will be inited at last in SFN model. */ define block TFM_SP_LOAD_LIST with alignment = 4 { ro section .part_load_priority_00 object load_info_*.o, ro section .part_load_priority_01 object load_info_*.o, ro section .part_load_priority_02 object load_info_*.o, ro section .part_load_priority_03 object load_info_*.o, }; #if defined(S_RAM_CODE_START) /* Flash drivers code that gets copied from Flash */ initialize by copy { ro object *libflash_drivers*, }; define block ER_CODE_SRAM with fixed order, alignment = 4, maximum size = S_RAM_CODE_SIZE { rw section .text, rw section .rodata, rw section .textrw, /* __ramfunc */ }; place at address S_RAM_CODE_START { block ER_CODE_SRAM }; #endif /**** blocks CODE + RO-data definition starts here */ {% for partition in partitions %} define 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' }} { {% if partition.attr.linker_pattern.library_list %} {% for pattern in partition.attr.linker_pattern.library_list %} ro section .text object {{pattern}}, ro section .rodata object {{pattern}}, {% endfor %} {% endif %} {% if partition.attr.linker_pattern.object_list %} {% for pattern in partition.attr.linker_pattern.object_list %} ro object {{pattern}}, {% endfor %} {% endif %} {% if partition.manifest.type == 'PSA-ROT' %} section {{partition.manifest.name}}_PSA-ROT_ATTR_FN, {% endif %} {% if partition.manifest.type == 'APPLICATION-ROT' %} section {{partition.manifest.name}}_APP-ROT_ATTR_FN, {% endif %} }; {% endfor %} /**** blocks CODE + RO-data definition ends here*/ /**** Block Unprivileged Secure code + RO-data definition starts here */ define block TFM_UNPRIV_CODE_START with alignment = TFM_LINKER_UNPRIV_CODE_ALIGNMENT { readonly }; /* * This empty, zero long execution region is here to mark the end address * of TFM unprivileged code. */ define block TFM_UNPRIV_CODE_END with alignment = TFM_LINKER_UNPRIV_CODE_ALIGNMENT, size = 0 { }; /* position tag block : base address of secure data area ( S_DATA_START)*/ define block PT_SECURE_DATA_START with alignment = TFM_LINKER_SECURE_DATA_ALIGNMENT, size = 0 { }; define block PT_PRIV_RWZI_START with alignment = TFM_LINKER_PT_PRIV_RWZI_ALIGNMENT, size = 0 { }; define block TFM_SHARED_DATA with alignment = TFM_LINKER_BL2_SHARED_DATA_ALIGNMENT, size = BOOT_TFM_SHARED_DATA_SIZE { }; define block ARM_LIB_STACK with alignment = TFM_LINKER_MSP_STACK_ALIGNMENT, size = S_MSP_STACK_SIZE - 0x8 { }; define block STACKSEAL with size = 0x8 { }; #if defined(ENABLE_HEAP) define block HEAP with alignment = 8, size = S_HEAP_SIZE { }; define block ARM_LIB_HEAP {block HEAP}; keep {block HEAP, block ARM_LIB_HEAP}; #endif define block ER_TFM_DATA with alignment = 8 {readwrite}; /* The runtime partition placed order is same as load partition */ define block ER_PART_RT_POOL with alignment = 4 { zi section .bss.part_runtime_priority_00, zi section .bss.part_runtime_priority_01, zi section .bss.part_runtime_priority_02, zi section .bss.part_runtime_priority_03, }; /* The runtime service placed order is same as load partition */ define block ER_SERV_RT_POOL with alignment = 4 { zi section .bss.serv_runtime_priority_00, zi section .bss.serv_runtime_priority_01, zi section .bss.serv_runtime_priority_02, zi section .bss.serv_runtime_priority_03, }; keep {block ER_PART_RT_POOL, block ER_SERV_RT_POOL}; /**** Blocks RWZI definition starts here */ {% for partition in partitions %} {% if partition.manifest.type == 'PSA-ROT' %} /* Position tag : start Block :*/ define block PT_{{partition.manifest.name}}_PRIVATE_DATA_START with alignment = TFM_LINKER_PSA_ROT_LINKER_DATA_ALIGNMENT, size = 0 { }; define block ER_{{partition.manifest.name}}_RWZI with alignment = TFM_LINKER_PSA_ROT_LINKER_DATA_ALIGNMENT { {% if partition.attr.linker_pattern.library_list %} {% for pattern in partition.attr.linker_pattern.library_list %} rw section .data object {{pattern}}, rw section .bss object {{pattern}}, {% endfor %} {% endif %} {% if partition.attr.linker_pattern.object_list %} {% for pattern in partition.attr.linker_pattern.object_list %} rw object {{pattern}}, {% endfor %} {% endif %} section {{partition.manifest.name}}_PSA-ROT_ATTR_RW, section {{partition.manifest.name}}_PSA-ROT_ATTR_ZI, }; /* Position tag : start Block :*/ define block PT_{{partition.manifest.name}}_PRIVATE_DATA_END with alignment = TFM_LINKER_PSA_ROT_LINKER_DATA_ALIGNMENT, size = 0 { }; {% endif %} {% endfor %} /**** block Position tag PSA RoT RWZI ends definition */ define block PT_PRIV_RWZI_END with alignment = TFM_LINKER_PT_PRIV_RWZI_ALIGNMENT, size = 0 { }; {% for partition in partitions %} {% if partition.manifest.type == 'APPLICATION-ROT' %} /* Position tag : start Block :*/ define block PT_{{partition.manifest.name}}_PRIVATE_DATA_START with alignment = TFM_LINKER_APP_ROT_LINKER_DATA_ALIGNMENT, size = 0 { }; define block ER_{{partition.manifest.name}}_RWZI with alignment = TFM_LINKER_APP_ROT_LINKER_DATA_ALIGNMENT { {% if partition.attr.linker_pattern.library_list %} {% for pattern in partition.attr.linker_pattern.library_list %} rw section .data object {{pattern}}, rw section .bss object {{pattern}}, {% endfor %} {% endif %} {% if partition.attr.linker_pattern.object_list %} {% for pattern in partition.attr.linker_pattern.object_list %} rw object {{pattern}}, {% endfor %} {% endif %} section {{partition.manifest.name}}_APP-ROT_ATTR_RW, section {{partition.manifest.name}}_APP-ROT_ATTR_ZI, }; /* Position tag : start Block :*/ define block PT_{{partition.manifest.name}}_PRIVATE_DATA_END with alignment = TFM_LINKER_APP_ROT_LINKER_DATA_ALIGNMENT, size = 0 { }; {% endif %} {% endfor %} #if defined(CONFIG_TFM_PARTITION_META) define block TFM_SP_META_PTR with alignment = TFM_LINKER_SP_META_PTR_ALIGNMENT { zi section .bss.SP_META_PTR_SPRTL_INST }; /* * This empty, zero long execution region is here to mark the end address * of TFM partition metadata pointer region. */ define block TFM_SP_META_PTR_END with alignment = TFM_LINKER_SP_META_PTR_ALIGNMENT, size = 0 { }; #endif #ifdef RAM_VECTORS_SUPPORT define block ER_RAM_VECTORS with alignment = TFM_LINKER_RAM_VECTORS_ALIGNMENT { section .ramvec }; #endif define block PT_SRAM_WATERMARK with alignment = TFM_LINKER_SECURE_DATA_ALIGNMENT, size = 0 { }; /* Define Flash content */ define block LR_CODE with fixed order { block ER_VECTORS, #ifdef CONFIG_TFM_USE_TRUSTZONE block ER_VENEER, block VENEER_ALIGN, #endif block PT_RO_START, block ER_TFM_CODE, block TFM_SP_LOAD_LIST, /**** PSA RoT CODE + RO-data starts here */ {% for partition in partitions %} {% if partition.manifest.type == 'PSA-ROT' %} block ER_{{partition.manifest.name}}_RO, {% endif %} {% endfor %} /**** APPLICATION RoT RO CODE + data starts here */ {% for partition in partitions %} {% if partition.manifest.type == 'APPLICATION-ROT' %} block ER_{{partition.manifest.name}}_RO, {% endif %} {% endfor %} block TFM_UNPRIV_CODE_START, block TFM_UNPRIV_CODE_END, block PT_RO_END, }; do not initialize { section .noinit, rw section .ramvec }; initialize by copy with packing = none { readwrite } #ifndef S_RAM_CODE_START except { section .textrw } #endif ; if (isdefinedsymbol(__USE_DLIB_PERTHREAD)) { // Required in a multi-threaded application initialize by copy { section __DLIB_PERTHREAD }; } /* Place Flash content */ place at address S_CODE_START { block LR_CODE }; /* Define RAM content */ define block DATA with fixed order { /**** Base address of secure data area */ block PT_SECURE_DATA_START, block PT_PRIV_RWZI_START, block TFM_SHARED_DATA, block ARM_LIB_STACK, block STACKSEAL, #if defined(ENABLE_HEAP) block ARM_LIB_HEAP, #endif block ER_TFM_DATA, block ER_PART_RT_POOL, block ER_SERV_RT_POOL, /* place PSA-ROT data */ {% for partition in partitions %} {% if partition.manifest.type == 'PSA-ROT' %} block PT_{{partition.manifest.name}}_PRIVATE_DATA_START, block ER_{{partition.manifest.name}}_RWZI, block PT_{{partition.manifest.name}}_PRIVATE_DATA_END, {% endif %} {% endfor %} block PT_PRIV_RWZI_END, /* place APP-ROT data */ {% for partition in partitions %} {% if partition.manifest.type == 'APPLICATION-ROT' %} block PT_{{partition.manifest.name}}_PRIVATE_DATA_START, block ER_{{partition.manifest.name}}_RWZI, block PT_{{partition.manifest.name}}_PRIVATE_DATA_END, {% endif %} {% endfor %} #if defined(CONFIG_TFM_PARTITION_META) block TFM_SP_META_PTR, block TFM_SP_META_PTR_END, #endif #ifdef RAM_VECTORS_SUPPORT block ER_RAM_VECTORS, #endif block PT_SRAM_WATERMARK, /* Make sure that the sections allocated in the SRAM does not exceed the * size of the SRAM available. */ }; place at address S_DATA_START { block DATA }; /* Reserved place for NS application. * No code will be placed here, just address of this region is used in the * secure code to configure certain HW components. This generates an empty * execution region description warning during linking. */ define block LR_NS_PARTITION with size = NS_PARTITION_SIZE { }; place at address NS_PARTITION_START { block LR_NS_PARTITION }; #ifdef BL2 /* Reserved place for new image in case of firmware upgrade. * No code will be placed here, just address of this region is used in the * secure code to configure certain HW components. This generates an empty * execution region description warning during linking. */ define block LR_SECONDARY_PARTITION with size = SECONDARY_PARTITION_SIZE { }; place at address SECONDARY_PARTITION_START { block LR_SECONDARY_PARTITION }; #endif /* BL2 */