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