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