1 /*
2  * Copyright (c) 2020-2022, ARM Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #ifndef BL_COMMON_LD_H
8 #define BL_COMMON_LD_H
9 
10 #include <platform_def.h>
11 
12 #ifdef __aarch64__
13 #define STRUCT_ALIGN	8
14 #define BSS_ALIGN	16
15 #else
16 #define STRUCT_ALIGN	4
17 #define BSS_ALIGN	8
18 #endif
19 
20 #ifndef DATA_ALIGN
21 #define DATA_ALIGN	1
22 #endif
23 
24 #define CPU_OPS						\
25 	. = ALIGN(STRUCT_ALIGN);			\
26 	__CPU_OPS_START__ = .;				\
27 	KEEP(*(cpu_ops))				\
28 	__CPU_OPS_END__ = .;
29 
30 #define PARSER_LIB_DESCS				\
31 	. = ALIGN(STRUCT_ALIGN);			\
32 	__PARSER_LIB_DESCS_START__ = .;			\
33 	KEEP(*(.img_parser_lib_descs))			\
34 	__PARSER_LIB_DESCS_END__ = .;
35 
36 #define RT_SVC_DESCS					\
37 	. = ALIGN(STRUCT_ALIGN);			\
38 	__RT_SVC_DESCS_START__ = .;			\
39 	KEEP(*(rt_svc_descs))				\
40 	__RT_SVC_DESCS_END__ = .;
41 
42 #if SPMC_AT_EL3
43 #define EL3_LP_DESCS					\
44 	. = ALIGN(STRUCT_ALIGN);			\
45 	__EL3_LP_DESCS_START__ = .;			\
46 	KEEP(*(el3_lp_descs))				\
47 	__EL3_LP_DESCS_END__ = .;
48 #else
49 #define EL3_LP_DESCS
50 #endif
51 
52 #define PMF_SVC_DESCS					\
53 	. = ALIGN(STRUCT_ALIGN);			\
54 	__PMF_SVC_DESCS_START__ = .;			\
55 	KEEP(*(pmf_svc_descs))				\
56 	__PMF_SVC_DESCS_END__ = .;
57 
58 #define FCONF_POPULATOR					\
59 	. = ALIGN(STRUCT_ALIGN);			\
60 	__FCONF_POPULATOR_START__ = .;			\
61 	KEEP(*(.fconf_populator))			\
62 	__FCONF_POPULATOR_END__ = .;
63 
64 /*
65  * Keep the .got section in the RO section as it is patched prior to enabling
66  * the MMU and having the .got in RO is better for security. GOT is a table of
67  * addresses so ensure pointer size alignment.
68  */
69 #define GOT						\
70 	. = ALIGN(STRUCT_ALIGN);			\
71 	__GOT_START__ = .;				\
72 	*(.got)						\
73 	__GOT_END__ = .;
74 
75 /*
76  * The base xlat table
77  *
78  * It is put into the rodata section if PLAT_RO_XLAT_TABLES=1,
79  * or into the bss section otherwise.
80  */
81 #define BASE_XLAT_TABLE					\
82 	. = ALIGN(16);					\
83 	__BASE_XLAT_TABLE_START__ = .;			\
84 	*(base_xlat_table)				\
85 	__BASE_XLAT_TABLE_END__ = .;
86 
87 #if PLAT_RO_XLAT_TABLES
88 #define BASE_XLAT_TABLE_RO		BASE_XLAT_TABLE
89 #define BASE_XLAT_TABLE_BSS
90 #else
91 #define BASE_XLAT_TABLE_RO
92 #define BASE_XLAT_TABLE_BSS		BASE_XLAT_TABLE
93 #endif
94 
95 #define RODATA_COMMON					\
96 	RT_SVC_DESCS					\
97 	FCONF_POPULATOR					\
98 	PMF_SVC_DESCS					\
99 	PARSER_LIB_DESCS				\
100 	CPU_OPS						\
101 	GOT						\
102 	BASE_XLAT_TABLE_RO				\
103 	EL3_LP_DESCS
104 
105 /*
106  * .data must be placed at a lower address than the stacks if the stack
107  * protector is enabled. Alternatively, the .data.stack_protector_canary
108  * section can be placed independently of the main .data section.
109  */
110 #define DATA_SECTION					\
111 	.data . : ALIGN(DATA_ALIGN) {			\
112 		__DATA_START__ = .;			\
113 		*(SORT_BY_ALIGNMENT(.data*))		\
114 		__DATA_END__ = .;			\
115 	}
116 
117 /*
118  * .rela.dyn needs to come after .data for the read-elf utility to parse
119  * this section correctly.
120  */
121 #if __aarch64__
122 #define RELA_DYN_NAME		.rela.dyn
123 #define RELOC_SECTIONS_PATTERN	*(.rela*)
124 #else
125 #define RELA_DYN_NAME		.rel.dyn
126 #define RELOC_SECTIONS_PATTERN	*(.rel*)
127 #endif
128 
129 #define RELA_SECTION					\
130 	RELA_DYN_NAME : ALIGN(STRUCT_ALIGN) {		\
131 		__RELA_START__ = .;			\
132 		RELOC_SECTIONS_PATTERN			\
133 		__RELA_END__ = .;			\
134 	}
135 
136 #if !(defined(IMAGE_BL31) && RECLAIM_INIT_CODE)
137 #define STACK_SECTION					\
138 	stacks (NOLOAD) : {				\
139 		__STACKS_START__ = .;			\
140 		*(tzfw_normal_stacks)			\
141 		__STACKS_END__ = .;			\
142 	}
143 #endif
144 
145 /*
146  * If BL doesn't use any bakery lock then __PERCPU_BAKERY_LOCK_SIZE__
147  * will be zero. For this reason, the only two valid values for
148  * __PERCPU_BAKERY_LOCK_SIZE__ are 0 or the platform defined value
149  * PLAT_PERCPU_BAKERY_LOCK_SIZE.
150  */
151 #ifdef PLAT_PERCPU_BAKERY_LOCK_SIZE
152 #define BAKERY_LOCK_SIZE_CHECK				\
153 	ASSERT((__PERCPU_BAKERY_LOCK_SIZE__ == 0) ||	\
154 	       (__PERCPU_BAKERY_LOCK_SIZE__ == PLAT_PERCPU_BAKERY_LOCK_SIZE), \
155 	       "PLAT_PERCPU_BAKERY_LOCK_SIZE does not match bakery lock requirements");
156 #else
157 #define BAKERY_LOCK_SIZE_CHECK
158 #endif
159 
160 /*
161  * Bakery locks are stored in normal .bss memory
162  *
163  * Each lock's data is spread across multiple cache lines, one per CPU,
164  * but multiple locks can share the same cache line.
165  * The compiler will allocate enough memory for one CPU's bakery locks,
166  * the remaining cache lines are allocated by the linker script
167  */
168 #if !USE_COHERENT_MEM
169 #define BAKERY_LOCK_NORMAL				\
170 	. = ALIGN(CACHE_WRITEBACK_GRANULE);		\
171 	__BAKERY_LOCK_START__ = .;			\
172 	__PERCPU_BAKERY_LOCK_START__ = .;		\
173 	*(bakery_lock)					\
174 	. = ALIGN(CACHE_WRITEBACK_GRANULE);		\
175 	__PERCPU_BAKERY_LOCK_END__ = .;			\
176 	__PERCPU_BAKERY_LOCK_SIZE__ = ABSOLUTE(__PERCPU_BAKERY_LOCK_END__ - __PERCPU_BAKERY_LOCK_START__); \
177 	. = . + (__PERCPU_BAKERY_LOCK_SIZE__ * (PLATFORM_CORE_COUNT - 1)); \
178 	__BAKERY_LOCK_END__ = .;			\
179 	BAKERY_LOCK_SIZE_CHECK
180 #else
181 #define BAKERY_LOCK_NORMAL
182 #endif
183 
184 /*
185  * Time-stamps are stored in normal .bss memory
186  *
187  * The compiler will allocate enough memory for one CPU's time-stamps,
188  * the remaining memory for other CPUs is allocated by the
189  * linker script
190  */
191 #define PMF_TIMESTAMP					\
192 	. = ALIGN(CACHE_WRITEBACK_GRANULE);		\
193 	__PMF_TIMESTAMP_START__ = .;			\
194 	KEEP(*(pmf_timestamp_array))			\
195 	. = ALIGN(CACHE_WRITEBACK_GRANULE);		\
196 	__PMF_PERCPU_TIMESTAMP_END__ = .;		\
197 	__PERCPU_TIMESTAMP_SIZE__ = ABSOLUTE(. - __PMF_TIMESTAMP_START__); \
198 	. = . + (__PERCPU_TIMESTAMP_SIZE__ * (PLATFORM_CORE_COUNT - 1)); \
199 	__PMF_TIMESTAMP_END__ = .;
200 
201 
202 /*
203  * The .bss section gets initialised to 0 at runtime.
204  * Its base address has bigger alignment for better performance of the
205  * zero-initialization code.
206  */
207 #define BSS_SECTION					\
208 	.bss (NOLOAD) : ALIGN(BSS_ALIGN) {		\
209 		__BSS_START__ = .;			\
210 		*(SORT_BY_ALIGNMENT(.bss*))		\
211 		*(COMMON)				\
212 		BAKERY_LOCK_NORMAL			\
213 		PMF_TIMESTAMP				\
214 		BASE_XLAT_TABLE_BSS			\
215 		__BSS_END__ = .;			\
216 	}
217 
218 /*
219  * The xlat_table section is for full, aligned page tables (4K).
220  * Removing them from .bss avoids forcing 4K alignment on
221  * the .bss section. The tables are initialized to zero by the translation
222  * tables library.
223  */
224 #define XLAT_TABLE_SECTION				\
225 	xlat_table (NOLOAD) : {				\
226 		__XLAT_TABLE_START__ = .;		\
227 		*(xlat_table)				\
228 		__XLAT_TABLE_END__ = .;			\
229 	}
230 
231 #endif /* BL_COMMON_LD_H */
232