xref: /rk3399_ARM-atf/bl31/bl31.ld.S (revision 6fb6bee1dfd7fd896c44cc21b02b4ef3aad3bbd0)
1/*
2 * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <common/bl_common.ld.h>
8#include <lib/xlat_tables/xlat_tables_defs.h>
9
10OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT)
11OUTPUT_ARCH(PLATFORM_LINKER_ARCH)
12ENTRY(bl31_entrypoint)
13
14MEMORY {
15    RAM (rwx): ORIGIN = BL31_BASE, LENGTH = BL31_LIMIT - BL31_BASE
16
17#if SEPARATE_NOBITS_REGION
18    NOBITS (rw!a): ORIGIN = BL31_NOBITS_BASE, LENGTH = BL31_NOBITS_LIMIT - BL31_NOBITS_BASE
19#else /* SEPARATE_NOBITS_REGION */
20#   define NOBITS RAM
21#endif /* SEPARATE_NOBITS_REGION */
22
23#if SEPARATE_RWDATA_REGION
24    RAM_RW (rw): ORIGIN = BL31_RWDATA_BASE, LENGTH = BL31_RWDATA_LIMIT - BL31_RWDATA_BASE
25#else /* SEPARATE_RWDATA_REGION */
26#define RAM_RW RAM
27#endif /* SEPARATE_RWDATA_REGION */
28}
29
30#if PLAT_EXTRA_LD_SCRIPT
31#   include <plat.ld.S>
32#endif /* PLAT_EXTRA_LD_SCRIPT */
33
34SECTIONS {
35    RAM_REGION_START = ORIGIN(RAM);
36    RAM_REGION_LENGTH = LENGTH(RAM);
37    . = BL31_BASE;
38
39    ASSERT(. == ALIGN(PAGE_SIZE),
40        "BL31_BASE address is not aligned on a page boundary.")
41
42    __BL31_START__ = .;
43
44#if SEPARATE_CODE_AND_RODATA
45    .text . : {
46        ASSERT(. == ALIGN(PAGE_SIZE),
47        ".text is not aligned on a page boundary.");
48
49        __TEXT_START__ = .;
50
51        *bl31_entrypoint.o(.text*)
52        *(SORT_BY_ALIGNMENT(SORT(.text*)))
53        *(.vectors)
54        __TEXT_END_UNALIGNED__ = .;
55
56        . = ALIGN(PAGE_SIZE);
57
58        __TEXT_END__ = .;
59    } >RAM
60
61    .rodata . : {
62        __RODATA_START__ = .;
63
64        *(SORT_BY_ALIGNMENT(.rodata*))
65
66#   if PLAT_EXTRA_RODATA_INCLUDES
67#       include <plat.ld.rodata.inc>
68#   endif /* PLAT_EXTRA_RODATA_INCLUDES */
69
70        RODATA_COMMON
71
72        . = ALIGN(8);
73
74#   include <lib/el3_runtime/pubsub_events.h>
75        __RODATA_END_UNALIGNED__ = .;
76
77        . = ALIGN(PAGE_SIZE);
78
79        __RODATA_END__ = .;
80    } >RAM
81#else /* SEPARATE_CODE_AND_RODATA */
82    .ro . : {
83        ASSERT(. == ALIGN(PAGE_SIZE),
84        ".ro is not aligned on a page boundary.");
85
86        __RO_START__ = .;
87
88        *bl31_entrypoint.o(.text*)
89        *(SORT_BY_ALIGNMENT(.text*))
90        *(SORT_BY_ALIGNMENT(.rodata*))
91
92        RODATA_COMMON
93
94        . = ALIGN(8);
95
96#   include <lib/el3_runtime/pubsub_events.h>
97
98        *(.vectors)
99
100        __RO_END_UNALIGNED__ = .;
101
102        /*
103         * Memory page(s) mapped to this section will be marked as read-only,
104         * executable. No RW data from the next section must creep in. Ensure
105         * that the rest of the current memory page is unused.
106         */
107        . = ALIGN(PAGE_SIZE);
108
109        __RO_END__ = .;
110    } >RAM
111#endif /* SEPARATE_CODE_AND_RODATA */
112
113    ASSERT(__CPU_OPS_END__ > __CPU_OPS_START__,
114        "cpu_ops not defined for this platform.")
115
116#if SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP)
117#   ifndef SPM_SHIM_EXCEPTIONS_VMA
118#       define SPM_SHIM_EXCEPTIONS_VMA RAM
119#   endif /* SPM_SHIM_EXCEPTIONS_VMA */
120
121    /*
122     * Exception vectors of the SPM shim layer. They must be aligned to a 2K
123     * address but we need to place them in a separate page so that we can set
124     * individual permissions on them, so the actual alignment needed is the
125     * page size.
126     *
127     * There's no need to include this into the RO section of BL31 because it
128     * doesn't need to be accessed by BL31.
129     */
130    .spm_shim_exceptions : ALIGN(PAGE_SIZE) {
131        __SPM_SHIM_EXCEPTIONS_START__ = .;
132
133        *(.spm_shim_exceptions)
134
135        . = ALIGN(PAGE_SIZE);
136
137        __SPM_SHIM_EXCEPTIONS_END__ = .;
138    } >SPM_SHIM_EXCEPTIONS_VMA AT>RAM
139
140    PROVIDE(__SPM_SHIM_EXCEPTIONS_LMA__ = LOADADDR(.spm_shim_exceptions));
141
142    . = LOADADDR(.spm_shim_exceptions) + SIZEOF(.spm_shim_exceptions);
143#endif /* SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP) */
144
145#if SEPARATE_RWDATA_REGION
146    . = BL31_RWDATA_BASE;
147    ASSERT(BL31_RWDATA_BASE == ALIGN(PAGE_SIZE),
148           "BL31_RWDATA_BASE address is not aligned on a page boundary.")
149
150    /*
151     * Define a linker symbol to mark the start of the RW memory area for this
152     * image.
153     */
154    __RW_START__ = . ;
155
156    DATA_SECTION >RAM_RW AT>RAM
157    __DATA_RAM_START__ = __DATA_START__;
158    __DATA_RAM_END__ = __DATA_END__;
159    __DATA_ROM_START__ = LOADADDR(.data);
160
161    . = ALIGN(PAGE_SIZE);
162    __RW_END__ = .;
163
164    RELA_SECTION >RAM
165#else /* SEPARATE_RWDATA_REGION */
166    /*
167     * Define a linker symbol to mark the start of the RW memory area for this
168     * image.
169     */
170    __RW_START__ = . ;
171
172    DATA_SECTION >RAM
173    RELA_SECTION >RAM
174#endif /* SEPARATE_RWDATA_REGION */
175
176#ifdef BL31_PROGBITS_LIMIT
177    ASSERT(
178        . <= BL31_PROGBITS_LIMIT,
179        "BL31 progbits has exceeded its limit. Consider disabling some features."
180    )
181#endif /* BL31_PROGBITS_LIMIT */
182
183#if SEPARATE_NOBITS_REGION
184    . = ALIGN(PAGE_SIZE);
185
186#if !SEPARATE_RWDATA_REGION
187    __RW_END__ = .;
188#endif /* SEPARATE_RWDATA_REGION */
189    __BL31_END__ = .;
190
191    ASSERT(. <= BL31_LIMIT, "BL31 image has exceeded its limit.")
192
193    . = BL31_NOBITS_BASE;
194
195    ASSERT(. == ALIGN(PAGE_SIZE),
196        "BL31 NOBITS base address is not aligned on a page boundary.")
197
198    __NOBITS_START__ = .;
199#endif /* SEPARATE_NOBITS_REGION */
200
201    STACK_SECTION >NOBITS
202    BSS_SECTION >NOBITS
203    XLAT_TABLE_SECTION >NOBITS
204
205#if USE_COHERENT_MEM
206    /*
207     * The base address of the coherent memory section must be page-aligned to
208     * guarantee that the coherent data are stored on their own pages and are
209     * not mixed with normal data.  This is required to set up the correct
210     * memory attributes for the coherent data page tables.
211     */
212    .coherent_ram (NOLOAD) : ALIGN(PAGE_SIZE) {
213        __COHERENT_RAM_START__ = .;
214
215        /*
216         * Bakery locks are stored in coherent memory. Each lock's data is
217         * contiguous and fully allocated by the compiler.
218         */
219        *(.bakery_lock)
220        *(.tzfw_coherent_mem)
221
222        __COHERENT_RAM_END_UNALIGNED__ = .;
223
224        /*
225         * Memory page(s) mapped to this section will be marked as device
226         * memory. No other unexpected data must creep in. Ensure the rest of
227         * the current memory page is unused.
228         */
229        . = ALIGN(PAGE_SIZE);
230
231        __COHERENT_RAM_END__ = .;
232    } >NOBITS
233#endif /* USE_COHERENT_MEM */
234
235#if SEPARATE_NOBITS_REGION
236    __NOBITS_END__ = .;
237
238    ASSERT(. <= BL31_NOBITS_LIMIT, "BL31 NOBITS region has exceeded its limit.")
239#else /* SEPARATE_NOBITS_REGION */
240    /*
241     * Define a linker symbol to mark the end of the RW memory area for this
242     * image.
243     */
244#if !SEPARATE_RWDATA_REGION
245    __RW_END__ = .;
246#endif /* SEPARATE_RWDATA_REGION */
247    __BL31_END__ = .;
248
249    ASSERT(. <= BL31_LIMIT, "BL31 image has exceeded its limit.")
250#endif /* SEPARATE_NOBITS_REGION */
251    RAM_REGION_END = .;
252
253    /DISCARD/ : {
254        *(.dynsym .dynstr .hash .gnu.hash)
255    }
256}
257