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