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