xref: /rk3399_ARM-atf/plat/arm/common/arm_bl31_setup.c (revision d9712f9cae10fdeb8696ffcd3ca35d58666ea9dd)
1 /*
2  * Copyright (c) 2015-2025, Arm Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <assert.h>
8 
9 #include <arch.h>
10 #include <arch_features.h>
11 #include <arch_helpers.h>
12 #include <common/bl_common.h>
13 #include <common/debug.h>
14 #include <drivers/console.h>
15 #include <lib/debugfs.h>
16 #include <lib/extensions/ras.h>
17 #include <lib/fconf/fconf.h>
18 #include <lib/gpt_rme/gpt_rme.h>
19 #include <lib/mmio.h>
20 #if TRANSFER_LIST
21 #include <transfer_list.h>
22 #endif
23 #include <lib/xlat_tables/xlat_tables_compat.h>
24 #include <plat/arm/common/plat_arm.h>
25 #include <plat/common/platform.h>
26 #include <platform_def.h>
27 
28 struct transfer_list_header *secure_tl;
29 struct transfer_list_header *ns_tl __unused;
30 
31 /*
32  * Placeholder variables for copying the arguments that have been passed to
33  * BL31 from BL2.
34  */
35 static entry_point_info_t bl32_image_ep_info;
36 static entry_point_info_t bl33_image_ep_info;
37 
38 #if ENABLE_RME
39 static entry_point_info_t rmm_image_ep_info;
40 #if (RME_GPT_BITLOCK_BLOCK == 0)
41 #define BITLOCK_BASE	UL(0)
42 #define BITLOCK_SIZE	UL(0)
43 #else
44 /*
45  * Number of bitlock_t entries in bitlocks array for PLAT_ARM_PPS
46  * with RME_GPT_BITLOCK_BLOCK * 512MB per bitlock.
47  */
48 #if (PLAT_ARM_PPS > (RME_GPT_BITLOCK_BLOCK * SZ_512M * UL(8)))
49 #define BITLOCKS_NUM	(PLAT_ARM_PPS) /	\
50 			(RME_GPT_BITLOCK_BLOCK * SZ_512M * UL(8))
51 #else
52 #define BITLOCKS_NUM	U(1)
53 #endif
54 /*
55  * Bitlocks array
56  */
57 static bitlock_t gpt_bitlock[BITLOCKS_NUM];
58 #define BITLOCK_BASE	(uintptr_t)gpt_bitlock
59 #define BITLOCK_SIZE	sizeof(gpt_bitlock)
60 #endif /* RME_GPT_BITLOCK_BLOCK */
61 #endif /* ENABLE_RME */
62 
63 #if !RESET_TO_BL31
64 /*
65  * Check that BL31_BASE is above ARM_FW_CONFIG_LIMIT. The reserved page
66  * is required for SOC_FW_CONFIG/TOS_FW_CONFIG passed from BL2.
67  */
68 #if TRANSFER_LIST
69 CASSERT(BL31_BASE >= PLAT_ARM_EL3_FW_HANDOFF_LIMIT, assert_bl31_base_overflows);
70 #else
71 CASSERT(BL31_BASE >= ARM_FW_CONFIG_LIMIT, assert_bl31_base_overflows);
72 #endif /* TRANSFER_LIST */
73 #endif /* RESET_TO_BL31 */
74 
75 /* Weak definitions may be overridden in specific ARM standard platform */
76 #pragma weak bl31_early_platform_setup2
77 #pragma weak bl31_platform_setup
78 #pragma weak bl31_plat_arch_setup
79 #pragma weak bl31_plat_get_next_image_ep_info
80 #pragma weak bl31_plat_runtime_setup
81 
82 #define MAP_BL31_TOTAL		MAP_REGION_FLAT(			\
83 					BL31_START,			\
84 					BL31_END - BL31_START,		\
85 					MT_MEMORY | MT_RW | EL3_PAS)
86 #if RECLAIM_INIT_CODE
87 IMPORT_SYM(unsigned long, __INIT_CODE_START__, BL_INIT_CODE_BASE);
88 IMPORT_SYM(unsigned long, __INIT_CODE_END__, BL_CODE_END_UNALIGNED);
89 IMPORT_SYM(unsigned long, __STACKS_END__, BL_STACKS_END_UNALIGNED);
90 
91 #define	BL_INIT_CODE_END	((BL_CODE_END_UNALIGNED + PAGE_SIZE - 1) & \
92 					~(PAGE_SIZE - 1))
93 #define	BL_STACKS_END		((BL_STACKS_END_UNALIGNED + PAGE_SIZE - 1) & \
94 					~(PAGE_SIZE - 1))
95 
96 #define MAP_BL_INIT_CODE	MAP_REGION_FLAT(			\
97 					BL_INIT_CODE_BASE,		\
98 					BL_INIT_CODE_END		\
99 						- BL_INIT_CODE_BASE,	\
100 					MT_CODE | EL3_PAS)
101 #endif
102 
103 #if SEPARATE_NOBITS_REGION
104 #define MAP_BL31_NOBITS		MAP_REGION_FLAT(			\
105 					BL31_NOBITS_BASE,		\
106 					BL31_NOBITS_LIMIT 		\
107 						- BL31_NOBITS_BASE,	\
108 					MT_MEMORY | MT_RW | EL3_PAS)
109 
110 #endif
111 /*******************************************************************************
112  * Return a pointer to the 'entry_point_info' structure of the next image for the
113  * security state specified. BL33 corresponds to the non-secure image type
114  * while BL32 corresponds to the secure image type. A NULL pointer is returned
115  * if the image does not exist.
116  ******************************************************************************/
117 struct entry_point_info *bl31_plat_get_next_image_ep_info(uint32_t type)
118 {
119 	entry_point_info_t *next_image_info;
120 
121 	assert(sec_state_is_valid(type));
122 	if (type == NON_SECURE) {
123 #if TRANSFER_LIST && !RESET_TO_BL31
124 		next_image_info = transfer_list_set_handoff_args(
125 			ns_tl, &bl33_image_ep_info);
126 #else
127 		next_image_info = &bl33_image_ep_info;
128 #endif
129 	}
130 #if ENABLE_RME
131 	else if (type == REALM) {
132 		next_image_info = &rmm_image_ep_info;
133 	}
134 #endif
135 	else {
136 #if TRANSFER_LIST && !RESET_TO_BL31
137 		next_image_info = transfer_list_set_handoff_args(
138 			secure_tl, &bl32_image_ep_info);
139 #else
140 		next_image_info = &bl32_image_ep_info;
141 #endif
142 	}
143 
144 	/*
145 	 * None of the images on the ARM development platforms can have 0x0
146 	 * as the entrypoint
147 	 */
148 	if (next_image_info->pc)
149 		return next_image_info;
150 	else
151 		return NULL;
152 }
153 
154 /*******************************************************************************
155  * Perform any BL31 early platform setup common to ARM standard platforms.
156  * Here is an opportunity to copy parameters passed by the calling EL (S-EL1
157  * in BL2 & EL3 in BL1) before they are lost (potentially). This needs to be
158  * done before the MMU is initialized so that the memory layout can be used
159  * while creating page tables. BL2 has flushed this information to memory, so
160  * we are guaranteed to pick up good data.
161  ******************************************************************************/
162 void __init arm_bl31_early_platform_setup(u_register_t arg0, u_register_t arg1,
163 					  u_register_t arg2, u_register_t arg3)
164 {
165 #if TRANSFER_LIST
166 #if RESET_TO_BL31
167 	/* Populate entry point information for BL33 */
168 	SET_PARAM_HEAD(&bl33_image_ep_info, PARAM_EP, VERSION_1, 0);
169 	/*
170 	 * Tell BL31 where the non-trusted software image
171 	 * is located and the entry state information
172 	 */
173 	bl33_image_ep_info.pc = plat_get_ns_image_entrypoint();
174 
175 	bl33_image_ep_info.spsr = arm_get_spsr(BL33_IMAGE_ID);
176 	SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
177 
178 	bl33_image_ep_info.args.arg0 = PLAT_ARM_TRANSFER_LIST_DTB_OFFSET;
179 	bl33_image_ep_info.args.arg1 =
180 		TRANSFER_LIST_HANDOFF_X1_VALUE(REGISTER_CONVENTION_VERSION);
181 	bl33_image_ep_info.args.arg3 = FW_NS_HANDOFF_BASE;
182 #else
183 	struct transfer_list_entry *te = NULL;
184 	struct entry_point_info *ep;
185 
186 	secure_tl = (struct transfer_list_header *)arg3;
187 
188 	/*
189 	 * Populate the global entry point structures used to execute subsequent
190 	 * images.
191 	 */
192 	while ((te = transfer_list_next(secure_tl, te)) != NULL) {
193 		ep = transfer_list_entry_data(te);
194 
195 		if (te->tag_id == TL_TAG_EXEC_EP_INFO64) {
196 			switch (GET_SECURITY_STATE(ep->h.attr)) {
197 			case NON_SECURE:
198 				bl33_image_ep_info = *ep;
199 				break;
200 #if ENABLE_RME
201 			case REALM:
202 				rmm_image_ep_info = *ep;
203 				break;
204 #endif
205 			case SECURE:
206 				bl32_image_ep_info = *ep;
207 				break;
208 			default:
209 				ERROR("Unrecognized Image Security State %lu\n",
210 				      GET_SECURITY_STATE(ep->h.attr));
211 				panic();
212 			}
213 		}
214 	}
215 #endif /* RESET_TO_BL31 */
216 #else /* (!TRANSFER_LIST) */
217 #if RESET_TO_BL31
218 	/* There are no parameters from BL2 if BL31 is a reset vector */
219 	assert((uintptr_t)arg0 == 0U);
220 	assert((uintptr_t)arg3 == 0U);
221 
222 # ifdef BL32_BASE
223 	/* Populate entry point information for BL32 */
224 	SET_PARAM_HEAD(&bl32_image_ep_info,
225 				PARAM_EP,
226 				VERSION_1,
227 				0);
228 	SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE);
229 	bl32_image_ep_info.pc = BL32_BASE;
230 	bl32_image_ep_info.spsr = arm_get_spsr(BL32_IMAGE_ID);
231 
232 #if defined(SPD_spmd)
233 	bl32_image_ep_info.args.arg0 = ARM_SPMC_MANIFEST_BASE;
234 #endif
235 
236 # endif /* BL32_BASE */
237 
238 	/* Populate entry point information for BL33 */
239 	SET_PARAM_HEAD(&bl33_image_ep_info,
240 				PARAM_EP,
241 				VERSION_1,
242 				0);
243 	/*
244 	 * Tell BL31 where the non-trusted software image
245 	 * is located and the entry state information
246 	 */
247 	bl33_image_ep_info.pc = plat_get_ns_image_entrypoint();
248 
249 #if ARM_LINUX_KERNEL_AS_BL33
250 	bl33_image_ep_info.args.arg0 = ARM_PRELOADED_DTB_BASE;
251 	bl33_image_ep_info.args.arg1 = 0U;
252 	bl33_image_ep_info.args.arg2 = 0U;
253 	bl33_image_ep_info.args.arg3 = 0U;
254 #endif /* ARM_LINUX_KERNEL_AS_BL33 */
255 
256 	bl33_image_ep_info.spsr = arm_get_spsr(BL33_IMAGE_ID);
257 	SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
258 
259 #if ENABLE_RME
260 	/*
261 	 * Populate entry point information for RMM.
262 	 * Only PC needs to be set as other fields are determined by RMMD.
263 	 */
264 	rmm_image_ep_info.pc = RMM_BASE;
265 #endif /* ENABLE_RME */
266 #else /* RESET_TO_BL31 */
267 	/*
268 	 * In debug builds, we pass a special value in 'arg3'
269 	 * to verify platform parameters from BL2 to BL31.
270 	 * In release builds, it's not used.
271 	 */
272 #if DEBUG
273 	assert(((uintptr_t)arg3) == ARM_BL31_PLAT_PARAM_VAL);
274 #endif
275 
276 	/*
277 	 * Check params passed from BL2 should not be NULL,
278 	 */
279 	bl_params_t *params_from_bl2 = (bl_params_t *)(uintptr_t)arg0;
280 	assert(params_from_bl2 != NULL);
281 	assert(params_from_bl2->h.type == PARAM_BL_PARAMS);
282 	assert(params_from_bl2->h.version >= VERSION_2);
283 
284 	bl_params_node_t *bl_params = params_from_bl2->head;
285 
286 	/*
287 	 * Copy BL33, BL32 and RMM (if present), entry point information.
288 	 * They are stored in Secure RAM, in BL2's address space.
289 	 */
290 	while (bl_params != NULL) {
291 		if (bl_params->image_id == BL32_IMAGE_ID) {
292 			bl32_image_ep_info = *bl_params->ep_info;
293 #if SPMC_AT_EL3
294 			/*
295 			 * Populate the BL32 image base, size and max limit in
296 			 * the entry point information, since there is no
297 			 * platform function to retrieve them in generic
298 			 * code. We choose arg2, arg3 and arg4 since the generic
299 			 * code uses arg1 for stashing the SP manifest size. The
300 			 * SPMC setup uses these arguments to update SP manifest
301 			 * with actual SP's base address and it size.
302 			 */
303 			bl32_image_ep_info.args.arg2 =
304 				bl_params->image_info->image_base;
305 			bl32_image_ep_info.args.arg3 =
306 				bl_params->image_info->image_size;
307 			bl32_image_ep_info.args.arg4 =
308 				bl_params->image_info->image_base +
309 				bl_params->image_info->image_max_size;
310 #endif
311 		}
312 #if ENABLE_RME
313 		else if (bl_params->image_id == RMM_IMAGE_ID) {
314 			rmm_image_ep_info = *bl_params->ep_info;
315 		}
316 #endif
317 		else if (bl_params->image_id == BL33_IMAGE_ID) {
318 			bl33_image_ep_info = *bl_params->ep_info;
319 		}
320 
321 		bl_params = bl_params->next_params_info;
322 	}
323 
324 	if (bl33_image_ep_info.pc == 0U)
325 		panic();
326 #if ENABLE_RME
327 	if (rmm_image_ep_info.pc == 0U)
328 		panic();
329 #endif
330 #endif /* RESET_TO_BL31 */
331 #endif /* TRANSFER_LIST */
332 }
333 
334 void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
335 		u_register_t arg2, u_register_t arg3)
336 {
337 	arm_bl31_early_platform_setup(arg0, arg1, arg2, arg3);
338 
339 	/*
340 	 * Initialize Interconnect for this cluster during cold boot.
341 	 * No need for locks as no other CPU is active.
342 	 */
343 	plat_arm_interconnect_init();
344 
345 	/*
346 	 * Enable Interconnect coherency for the primary CPU's cluster.
347 	 * Earlier bootloader stages might already do this (e.g. Trusted
348 	 * Firmware's BL1 does it) but we can't assume so. There is no harm in
349 	 * executing this code twice anyway.
350 	 * Platform specific PSCI code will enable coherency for other
351 	 * clusters.
352 	 */
353 	plat_arm_interconnect_enter_coherency();
354 }
355 
356 /*******************************************************************************
357  * Perform any BL31 platform setup common to ARM standard platforms
358  ******************************************************************************/
359 void arm_bl31_platform_setup(void)
360 {
361 	struct transfer_list_entry *te __unused;
362 
363 #if TRANSFER_LIST && !RESET_TO_BL31
364 	ns_tl = transfer_list_init((void *)FW_NS_HANDOFF_BASE,
365 				   PLAT_ARM_FW_HANDOFF_SIZE);
366 	if (ns_tl == NULL) {
367 		ERROR("Non-secure transfer list initialisation failed!\n");
368 		panic();
369 	}
370 	/* BL31 may modify the HW_CONFIG so defer copying it until later. */
371 	te = transfer_list_find(secure_tl, TL_TAG_FDT);
372 	assert(te != NULL);
373 
374 	/*
375 	 * A pre-existing assumption is that FCONF is unsupported w/ RESET_TO_BL2 and
376 	 * RESET_TO_BL31. In the case of RESET_TO_BL31 this makes sense because there
377 	 * isn't a prior stage to load the device tree, but the reasoning for RESET_TO_BL2 is
378 	 * less clear. For the moment hardware properties that would normally be
379 	 * derived from the DT are statically defined.
380 	 */
381 #if !RESET_TO_BL2
382 	fconf_populate("HW_CONFIG", (uintptr_t)transfer_list_entry_data(te));
383 #endif
384 
385 	te = transfer_list_add(ns_tl, TL_TAG_FDT, te->data_size,
386 			       transfer_list_entry_data(te));
387 	assert(te != NULL);
388 
389 	te = transfer_list_find(secure_tl, TL_TAG_TPM_EVLOG);
390 	if (te != NULL) {
391 		te = transfer_list_add(ns_tl, TL_TAG_TPM_EVLOG, te->data_size,
392 				  transfer_list_entry_data(te));
393 		if (te == NULL) {
394 			ERROR("Failed to load event log in Non-Secure transfer list\n");
395 			panic();
396 		}
397 	}
398 #endif /* TRANSFER_LIST && !RESET_TO_BL31 */
399 
400 #if RESET_TO_BL31
401 	/*
402 	 * Do initial security configuration to allow DRAM/device access
403 	 * (if earlier BL has not already done so).
404 	 */
405 	plat_arm_security_setup();
406 
407 #if defined(PLAT_ARM_MEM_PROT_ADDR)
408 	arm_nor_psci_do_dyn_mem_protect();
409 #endif /* PLAT_ARM_MEM_PROT_ADDR */
410 
411 #endif /* RESET_TO_BL31 */
412 
413 	/* Enable and initialize the System level generic timer */
414 	mmio_write_32(ARM_SYS_CNTCTL_BASE + CNTCR_OFF,
415 			CNTCR_FCREQ(0U) | CNTCR_EN);
416 
417 	/* Allow access to the System counter timer module */
418 	arm_configure_sys_timer();
419 
420 	/* Initialize power controller before setting up topology */
421 	plat_arm_pwrc_setup();
422 
423 #if ENABLE_FEAT_RAS && FFH_SUPPORT
424 	ras_init();
425 #endif
426 
427 #if USE_DEBUGFS
428 	debugfs_init();
429 #endif /* USE_DEBUGFS */
430 }
431 
432 /*******************************************************************************
433  * Perform any BL31 platform runtime setup prior to BL31 exit common to ARM
434  * standard platforms
435  ******************************************************************************/
436 void arm_bl31_plat_runtime_setup(void)
437 {
438 	struct transfer_list_entry *te __unused;
439 	/* Initialize the runtime console */
440 	arm_console_runtime_init();
441 
442 #if TRANSFER_LIST && !RESET_TO_BL31
443 	/*
444 	 * We assume BL31 has added all TE's required by BL33 at this stage, ensure
445 	 * that data is visible to all observers by performing a flush operation, so
446 	 * they can access the updated data even if caching is not enabled.
447 	 */
448 	flush_dcache_range((uintptr_t)ns_tl, ns_tl->size);
449 #endif /* TRANSFER_LIST && !RESET_TO_BL31 */
450 
451 #if RECLAIM_INIT_CODE
452 	arm_free_init_memory();
453 #endif
454 
455 #if PLAT_RO_XLAT_TABLES
456 	arm_xlat_make_tables_readonly();
457 #endif
458 }
459 
460 #if RECLAIM_INIT_CODE
461 /*
462  * Make memory for image boot time code RW to reclaim it as stack for the
463  * secondary cores, or RO where it cannot be reclaimed:
464  *
465  *            |-------- INIT SECTION --------|
466  *  -----------------------------------------
467  * |  CORE 0  |  CORE 1  |  CORE 2  | EXTRA  |
468  * |  STACK   |  STACK   |  STACK   | SPACE  |
469  *  -----------------------------------------
470  *             <-------------------> <------>
471  *                MAKE RW AND XN       MAKE
472  *                  FOR STACKS       RO AND XN
473  */
474 void arm_free_init_memory(void)
475 {
476 	int ret = 0;
477 
478 	if (BL_STACKS_END < BL_INIT_CODE_END) {
479 		/* Reclaim some of the init section as stack if possible. */
480 		if (BL_INIT_CODE_BASE < BL_STACKS_END) {
481 			ret |= xlat_change_mem_attributes(BL_INIT_CODE_BASE,
482 					BL_STACKS_END - BL_INIT_CODE_BASE,
483 					MT_RW_DATA);
484 		}
485 		/* Make the rest of the init section read-only. */
486 		ret |= xlat_change_mem_attributes(BL_STACKS_END,
487 				BL_INIT_CODE_END - BL_STACKS_END,
488 				MT_RO_DATA);
489 	} else {
490 		/* The stacks cover the init section, so reclaim it all. */
491 		ret |= xlat_change_mem_attributes(BL_INIT_CODE_BASE,
492 				BL_INIT_CODE_END - BL_INIT_CODE_BASE,
493 				MT_RW_DATA);
494 	}
495 
496 	if (ret != 0) {
497 		ERROR("Could not reclaim initialization code");
498 		panic();
499 	}
500 }
501 #endif
502 
503 void __init bl31_platform_setup(void)
504 {
505 	arm_bl31_platform_setup();
506 }
507 
508 void bl31_plat_runtime_setup(void)
509 {
510 	arm_bl31_plat_runtime_setup();
511 }
512 
513 /*******************************************************************************
514  * Perform the very early platform specific architectural setup shared between
515  * ARM standard platforms. This only does basic initialization. Later
516  * architectural setup (bl31_arch_setup()) does not do anything platform
517  * specific.
518  ******************************************************************************/
519 void __init arm_bl31_plat_arch_setup(void)
520 {
521 	const mmap_region_t bl_regions[] = {
522 		MAP_BL31_TOTAL,
523 #if ENABLE_RME
524 		ARM_MAP_L0_GPT_REGION,
525 #endif
526 #if RECLAIM_INIT_CODE
527 		MAP_BL_INIT_CODE,
528 #endif
529 #if SEPARATE_NOBITS_REGION
530 		MAP_BL31_NOBITS,
531 #endif
532 		ARM_MAP_BL_RO,
533 #if USE_ROMLIB
534 		ARM_MAP_ROMLIB_CODE,
535 		ARM_MAP_ROMLIB_DATA,
536 #endif
537 #if USE_COHERENT_MEM
538 		ARM_MAP_BL_COHERENT_RAM,
539 #endif
540 		{0}
541 	};
542 
543 	setup_page_tables(bl_regions, plat_arm_get_mmap());
544 
545 	enable_mmu_el3(0);
546 
547 #if ENABLE_RME
548 #if RESET_TO_BL31
549 	/*  initialize GPT only when RME is enabled. */
550 	assert(is_feat_rme_present());
551 
552 	/* Initialise and enable granule protection after MMU. */
553 	arm_gpt_setup();
554 #endif /* RESET_TO_BL31 */
555 	/*
556 	 * Initialise Granule Protection library and enable GPC for the primary
557 	 * processor. The tables have already been initialized by a previous BL
558 	 * stage, so there is no need to provide any PAS here. This function
559 	 * sets up pointers to those tables.
560 	 */
561 	if (gpt_runtime_init(BITLOCK_BASE, BITLOCK_SIZE) < 0) {
562 		ERROR("gpt_runtime_init() failed!\n");
563 		panic();
564 	}
565 #endif /* ENABLE_RME */
566 
567 	arm_setup_romlib();
568 }
569 
570 void __init bl31_plat_arch_setup(void)
571 {
572 	arm_bl31_plat_arch_setup();
573 }
574