• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <assert.h>
8 #include <string.h>
9 
10 #include <common/debug.h>
11 #include <drivers/arm/cci.h>
12 #include <drivers/arm/ccn.h>
13 #include <drivers/arm/gicv2.h>
14 #include <drivers/arm/sp804_delay_timer.h>
15 #include <drivers/generic_delay_timer.h>
16 #include <fconf_hw_config_getter.h>
17 #include <lib/mmio.h>
18 #include <lib/smccc.h>
19 #include <lib/xlat_tables/xlat_tables_compat.h>
20 #include <platform_def.h>
21 #include <services/arm_arch_svc.h>
22 #include <services/rmm_core_manifest.h>
23 #if SPM_MM
24 #include <services/spm_mm_partition.h>
25 #endif
26 
27 #include <plat/arm/common/arm_config.h>
28 #include <plat/arm/common/plat_arm.h>
29 #include <plat/common/platform.h>
30 
31 #include "fvp_private.h"
32 
33 /* Defines for GIC Driver build time selection */
34 #define FVP_GICV2		1
35 #define FVP_GICV3		2
36 
37 /* Defines for RMM Console*/
38 #define FVP_RMM_CONSOLE_BASE		UL(0x1c0c0000)
39 #define FVP_RMM_CONSOLE_BAUD		UL(115200)
40 #define FVP_RMM_CONSOLE_CLK_IN_HZ	UL(14745600)
41 #define FVP_RMM_CONSOLE_NAME		"pl011"
42 
43 #define FVP_RMM_CONSOLE_COUNT		UL(1)
44 
45 /*******************************************************************************
46  * arm_config holds the characteristics of the differences between the three FVP
47  * platforms (Base, A53_A57 & Foundation). It will be populated during cold boot
48  * at each boot stage by the primary before enabling the MMU (to allow
49  * interconnect configuration) & used thereafter. Each BL will have its own copy
50  * to allow independent operation.
51  ******************************************************************************/
52 arm_config_t arm_config;
53 
54 #define MAP_DEVICE0	MAP_REGION_FLAT(DEVICE0_BASE,			\
55 					DEVICE0_SIZE,			\
56 					MT_DEVICE | MT_RW | MT_SECURE)
57 
58 #define MAP_DEVICE1	MAP_REGION_FLAT(DEVICE1_BASE,			\
59 					DEVICE1_SIZE,			\
60 					MT_DEVICE | MT_RW | MT_SECURE)
61 
62 #if FVP_GICR_REGION_PROTECTION
63 #define MAP_GICD_MEM	MAP_REGION_FLAT(BASE_GICD_BASE,			\
64 					BASE_GICD_SIZE,			\
65 					MT_DEVICE | MT_RW | MT_SECURE)
66 
67 /* Map all core's redistributor memory as read-only. After boots up,
68  * per-core map its redistributor memory as read-write */
69 #define MAP_GICR_MEM	MAP_REGION_FLAT(BASE_GICR_BASE,			\
70 					(BASE_GICR_SIZE * PLATFORM_CORE_COUNT),\
71 					MT_DEVICE | MT_RO | MT_SECURE)
72 #endif /* FVP_GICR_REGION_PROTECTION */
73 
74 /*
75  * Need to be mapped with write permissions in order to set a new non-volatile
76  * counter value.
77  */
78 #define MAP_DEVICE2	MAP_REGION_FLAT(DEVICE2_BASE,			\
79 					DEVICE2_SIZE,			\
80 					MT_DEVICE | MT_RW | MT_SECURE)
81 
82 #if TRANSFER_LIST
83 #ifdef FW_NS_HANDOFF_BASE
84 #define MAP_FW_NS_HANDOFF                                             \
85 	MAP_REGION_FLAT(FW_NS_HANDOFF_BASE, PLAT_ARM_FW_HANDOFF_SIZE, \
86 			MT_MEMORY | MT_RW | MT_NS)
87 #endif
88 #ifdef PLAT_ARM_EL3_FW_HANDOFF_BASE
89 #define MAP_EL3_FW_HANDOFF                            \
90 	MAP_REGION_FLAT(PLAT_ARM_EL3_FW_HANDOFF_BASE, \
91 			PLAT_ARM_FW_HANDOFF_SIZE, MT_MEMORY | MT_RW | EL3_PAS)
92 #endif
93 #endif
94 
95 /*
96  * Table of memory regions for various BL stages to map using the MMU.
97  * This doesn't include Trusted SRAM as setup_page_tables() already takes care
98  * of mapping it.
99  */
100 #ifdef IMAGE_BL1
101 const mmap_region_t plat_arm_mmap[] = {
102 	ARM_MAP_SHARED_RAM,
103 	V2M_MAP_FLASH0_RO,
104 	V2M_MAP_IOFPGA,
105 	MAP_DEVICE0,
106 #if FVP_INTERCONNECT_DRIVER == FVP_CCN
107 	MAP_DEVICE1,
108 #endif
109 #if TRUSTED_BOARD_BOOT
110 	/* To access the Root of Trust Public Key registers. */
111 	MAP_DEVICE2,
112 	/* Map DRAM to authenticate NS_BL2U image. */
113 	ARM_MAP_NS_DRAM1,
114 #endif
115 	{0}
116 };
117 #endif
118 #ifdef IMAGE_BL2
119 const mmap_region_t plat_arm_mmap[] = {
120 	ARM_MAP_SHARED_RAM,
121 	V2M_MAP_FLASH0_RW,
122 	V2M_MAP_IOFPGA,
123 	MAP_DEVICE0,
124 #if FVP_INTERCONNECT_DRIVER == FVP_CCN
125 	MAP_DEVICE1,
126 #endif
127 	ARM_MAP_NS_DRAM1,
128 #ifdef __aarch64__
129 	ARM_MAP_DRAM2,
130 #endif
131 	/*
132 	 * Required to load HW_CONFIG, SPMC and SPs to trusted DRAM.
133 	 */
134 	ARM_MAP_TRUSTED_DRAM,
135 
136 	/*
137 	 * Required to load Event Log in TZC secured memory
138 	 */
139 #if MEASURED_BOOT && (defined(SPD_tspd) || defined(SPD_opteed) || \
140 defined(SPD_spmd))
141 	ARM_MAP_EVENT_LOG_DRAM1,
142 #endif /* MEASURED_BOOT && (SPD_tspd || SPD_opteed || SPD_spmd) */
143 
144 #if ENABLE_RME
145 	ARM_MAP_RMM_DRAM,
146 	ARM_MAP_GPT_L1_DRAM,
147 #endif /* ENABLE_RME */
148 #ifdef SPD_tspd
149 	ARM_MAP_TSP_SEC_MEM,
150 #endif
151 #if TRUSTED_BOARD_BOOT
152 	/* To access the Root of Trust Public Key registers. */
153 	MAP_DEVICE2,
154 #endif /* TRUSTED_BOARD_BOOT */
155 
156 #if CRYPTO_SUPPORT && !RESET_TO_BL2
157 	/*
158 	 * To access shared the Mbed TLS heap while booting the
159 	 * system with Crypto support
160 	 */
161 	ARM_MAP_BL1_RW,
162 #endif /* CRYPTO_SUPPORT && !RESET_TO_BL2 */
163 #if SPM_MM || SPMC_AT_EL3
164 	ARM_SP_IMAGE_MMAP,
165 #endif
166 #if ARM_BL31_IN_DRAM
167 	ARM_MAP_BL31_SEC_DRAM,
168 #endif
169 #ifdef SPD_opteed
170 	ARM_MAP_OPTEE_CORE_MEM,
171 	ARM_OPTEE_PAGEABLE_LOAD_MEM,
172 #endif
173 #ifdef MAP_EL3_FW_HANDOFF
174 	MAP_EL3_FW_HANDOFF,
175 #endif
176 	{ 0 }
177 };
178 #endif
179 #ifdef IMAGE_BL2U
180 const mmap_region_t plat_arm_mmap[] = {
181 	MAP_DEVICE0,
182 	V2M_MAP_IOFPGA,
183 	{0}
184 };
185 #endif
186 #ifdef IMAGE_BL31
187 const mmap_region_t plat_arm_mmap[] = {
188 	ARM_MAP_SHARED_RAM,
189 #if USE_DEBUGFS
190 	/* Required by devfip, can be removed if devfip is not used */
191 	V2M_MAP_FLASH0_RW,
192 #endif /* USE_DEBUGFS */
193 	ARM_MAP_EL3_TZC_DRAM,
194 	V2M_MAP_IOFPGA,
195 	MAP_DEVICE0,
196 #if FVP_GICR_REGION_PROTECTION
197 	MAP_GICD_MEM,
198 	MAP_GICR_MEM,
199 #else
200 	MAP_DEVICE1,
201 #endif /* FVP_GICR_REGION_PROTECTION */
202 	ARM_V2M_MAP_MEM_PROTECT,
203 #if SPM_MM
204 	ARM_SPM_BUF_EL3_MMAP,
205 #endif
206 #if ENABLE_RME
207 	ARM_MAP_GPT_L1_DRAM,
208 	ARM_MAP_EL3_RMM_SHARED_MEM,
209 #endif
210 #ifdef MAP_FW_NS_HANDOFF
211 	MAP_FW_NS_HANDOFF,
212 #endif
213 #if defined(MAP_EL3_FW_HANDOFF) && !RESET_TO_BL31
214 	MAP_EL3_FW_HANDOFF,
215 #endif
216 	{ 0 }
217 };
218 
219 #if defined(IMAGE_BL31) && SPM_MM
220 const mmap_region_t plat_arm_secure_partition_mmap[] = {
221 	V2M_MAP_IOFPGA_EL0, /* for the UART */
222 	V2M_MAP_SECURE_SYSTEMREG_EL0, /* for initializing flash */
223 #if PSA_FWU_SUPPORT
224 	V2M_MAP_FLASH0_RW_EL0, /* for firmware update service in standalone mm */
225 #endif
226 	V2M_MAP_FLASH1_RW_EL0, /* for secure variable service in standalone mm */
227 	MAP_REGION_FLAT(DEVICE0_BASE,
228 			DEVICE0_SIZE,
229 			MT_DEVICE | MT_RO | MT_SECURE | MT_USER),
230 	ARM_SP_IMAGE_MMAP,
231 	ARM_SP_IMAGE_NS_BUF_MMAP,
232 	ARM_SP_IMAGE_RW_MMAP,
233 	ARM_SPM_BUF_EL0_MMAP,
234 	{0}
235 };
236 #endif
237 #endif
238 #ifdef IMAGE_BL32
239 const mmap_region_t plat_arm_mmap[] = {
240 #ifndef __aarch64__
241 	ARM_MAP_SHARED_RAM,
242 	ARM_V2M_MAP_MEM_PROTECT,
243 #endif
244 	V2M_MAP_IOFPGA,
245 	MAP_DEVICE0,
246 	MAP_DEVICE1,
247 	{0}
248 };
249 #endif
250 
251 #ifdef IMAGE_RMM
252 const mmap_region_t plat_arm_mmap[] = {
253 	V2M_MAP_IOFPGA,
254 	MAP_DEVICE0,
255 	MAP_DEVICE1,
256 	{0}
257 };
258 #endif
259 
260 ARM_CASSERT_MMAP
261 
262 #if FVP_INTERCONNECT_DRIVER != FVP_CCN
263 static const int fvp_cci400_map[] = {
264 	PLAT_FVP_CCI400_CLUS0_SL_PORT,
265 	PLAT_FVP_CCI400_CLUS1_SL_PORT,
266 };
267 
268 static const int fvp_cci5xx_map[] = {
269 	PLAT_FVP_CCI5XX_CLUS0_SL_PORT,
270 	PLAT_FVP_CCI5XX_CLUS1_SL_PORT,
271 };
272 
get_interconnect_master(void)273 static unsigned int get_interconnect_master(void)
274 {
275 	unsigned int master;
276 	u_register_t mpidr;
277 
278 	mpidr = read_mpidr_el1();
279 	master = ((arm_config.flags & ARM_CONFIG_FVP_SHIFTED_AFF) != 0U) ?
280 		MPIDR_AFFLVL2_VAL(mpidr) : MPIDR_AFFLVL1_VAL(mpidr);
281 
282 	assert(master < FVP_CLUSTER_COUNT);
283 	return master;
284 }
285 #endif
286 
287 #if defined(IMAGE_BL31) && SPM_MM
288 /*
289  * Boot information passed to a secure partition during initialisation. Linear
290  * indices in MP information will be filled at runtime.
291  */
292 static spm_mm_mp_info_t sp_mp_info[] = {
293 	[0] = {0x80000000, 0},
294 	[1] = {0x80000001, 0},
295 	[2] = {0x80000002, 0},
296 	[3] = {0x80000003, 0},
297 	[4] = {0x80000100, 0},
298 	[5] = {0x80000101, 0},
299 	[6] = {0x80000102, 0},
300 	[7] = {0x80000103, 0},
301 };
302 
303 const spm_mm_boot_info_t plat_arm_secure_partition_boot_info = {
304 	.h.type              = PARAM_SP_IMAGE_BOOT_INFO,
305 	.h.version           = VERSION_1,
306 	.h.size              = sizeof(spm_mm_boot_info_t),
307 	.h.attr              = 0,
308 	.sp_mem_base         = ARM_SP_IMAGE_BASE,
309 	.sp_mem_limit        = ARM_SP_IMAGE_LIMIT,
310 	.sp_image_base       = ARM_SP_IMAGE_BASE,
311 	.sp_stack_base       = PLAT_SP_IMAGE_STACK_BASE,
312 	.sp_heap_base        = ARM_SP_IMAGE_HEAP_BASE,
313 	.sp_ns_comm_buf_base = PLAT_SP_IMAGE_NS_BUF_BASE,
314 	.sp_shared_buf_base  = PLAT_SPM_BUF_BASE,
315 	.sp_image_size       = ARM_SP_IMAGE_SIZE,
316 	.sp_pcpu_stack_size  = PLAT_SP_IMAGE_STACK_PCPU_SIZE,
317 	.sp_heap_size        = ARM_SP_IMAGE_HEAP_SIZE,
318 	.sp_ns_comm_buf_size = PLAT_SP_IMAGE_NS_BUF_SIZE,
319 	.sp_shared_buf_size  = PLAT_SPM_BUF_SIZE,
320 	.num_sp_mem_regions  = ARM_SP_IMAGE_NUM_MEM_REGIONS,
321 	.num_cpus            = PLATFORM_CORE_COUNT,
322 	.mp_info             = &sp_mp_info[0],
323 };
324 
plat_get_secure_partition_mmap(void * cookie)325 const struct mmap_region *plat_get_secure_partition_mmap(void *cookie)
326 {
327 	return plat_arm_secure_partition_mmap;
328 }
329 
plat_get_secure_partition_boot_info(void * cookie)330 const struct spm_mm_boot_info *plat_get_secure_partition_boot_info(
331 		void *cookie)
332 {
333 	return &plat_arm_secure_partition_boot_info;
334 }
335 #endif
336 
337 /*******************************************************************************
338  * A single boot loader stack is expected to work on both the Foundation FVP
339  * models and the two flavours of the Base FVP models (AEMv8 & Cortex). The
340  * SYS_ID register provides a mechanism for detecting the differences between
341  * these platforms. This information is stored in a per-BL array to allow the
342  * code to take the correct path.Per BL platform configuration.
343  ******************************************************************************/
fvp_config_setup(void)344 void __init fvp_config_setup(void)
345 {
346 	unsigned int rev, hbi, bld, arch, sys_id;
347 
348 	sys_id = mmio_read_32(V2M_SYSREGS_BASE + V2M_SYS_ID);
349 	rev = (sys_id >> V2M_SYS_ID_REV_SHIFT) & V2M_SYS_ID_REV_MASK;
350 	hbi = (sys_id >> V2M_SYS_ID_HBI_SHIFT) & V2M_SYS_ID_HBI_MASK;
351 	bld = (sys_id >> V2M_SYS_ID_BLD_SHIFT) & V2M_SYS_ID_BLD_MASK;
352 	arch = (sys_id >> V2M_SYS_ID_ARCH_SHIFT) & V2M_SYS_ID_ARCH_MASK;
353 
354 	if (arch != ARCH_MODEL) {
355 		ERROR("This firmware is for FVP models\n");
356 		panic();
357 	}
358 
359 	/*
360 	 * The build field in the SYS_ID tells which variant of the GIC
361 	 * memory is implemented by the model.
362 	 */
363 	switch (bld) {
364 	case BLD_GIC_VE_MMAP:
365 		ERROR("Legacy Versatile Express memory map for GIC peripheral"
366 				" is not supported\n");
367 		panic();
368 		break;
369 	case BLD_GIC_A53A57_MMAP:
370 		break;
371 	default:
372 		ERROR("Unsupported board build %x\n", bld);
373 		panic();
374 	}
375 
376 	/*
377 	 * The hbi field in the SYS_ID is 0x020 for the Base FVP & 0x010
378 	 * for the Foundation FVP.
379 	 */
380 	switch (hbi) {
381 	case HBI_FOUNDATION_FVP:
382 		arm_config.flags = 0;
383 
384 		/*
385 		 * Check for supported revisions of Foundation FVP
386 		 * Allow future revisions to run but emit warning diagnostic
387 		 */
388 		switch (rev) {
389 		case REV_FOUNDATION_FVP_V2_0:
390 		case REV_FOUNDATION_FVP_V2_1:
391 		case REV_FOUNDATION_FVP_v9_1:
392 		case REV_FOUNDATION_FVP_v9_6:
393 			break;
394 		default:
395 			WARN("Unrecognized Foundation FVP revision %x\n", rev);
396 			break;
397 		}
398 		break;
399 	case HBI_BASE_FVP:
400 		arm_config.flags |= (ARM_CONFIG_BASE_MMAP | ARM_CONFIG_HAS_TZC);
401 
402 		/*
403 		 * Check for supported revisions
404 		 * Allow future revisions to run but emit warning diagnostic
405 		 */
406 		switch (rev) {
407 		case REV_BASE_FVP_V0:
408 			arm_config.flags |= ARM_CONFIG_FVP_HAS_CCI400;
409 			break;
410 		case REV_BASE_FVP_REVC:
411 			arm_config.flags |= (ARM_CONFIG_FVP_HAS_SMMUV3 |
412 					ARM_CONFIG_FVP_HAS_CCI5XX);
413 			break;
414 		default:
415 			WARN("Unrecognized Base FVP revision %x\n", rev);
416 			break;
417 		}
418 		break;
419 	default:
420 		ERROR("Unsupported board HBI number 0x%x\n", hbi);
421 		panic();
422 	}
423 
424 	/*
425 	 * We assume that the presence of MT bit, and therefore shifted
426 	 * affinities, is uniform across the platform: either all CPUs, or no
427 	 * CPUs implement it.
428 	 */
429 	if ((read_mpidr_el1() & MPIDR_MT_MASK) != 0U)
430 		arm_config.flags |= ARM_CONFIG_FVP_SHIFTED_AFF;
431 }
432 
433 
fvp_interconnect_init(void)434 void __init fvp_interconnect_init(void)
435 {
436 #if FVP_INTERCONNECT_DRIVER == FVP_CCN
437 	if (ccn_get_part0_id(PLAT_ARM_CCN_BASE) != CCN_502_PART0_ID) {
438 		ERROR("Unrecognized CCN variant detected. Only CCN-502 is supported");
439 		panic();
440 	}
441 
442 	plat_arm_interconnect_init();
443 #else
444 	uintptr_t cci_base = 0U;
445 	const int *cci_map = NULL;
446 	unsigned int map_size = 0U;
447 
448 	/* Initialize the right interconnect */
449 	if ((arm_config.flags & ARM_CONFIG_FVP_HAS_CCI5XX) != 0U) {
450 		cci_base = PLAT_FVP_CCI5XX_BASE;
451 		cci_map = fvp_cci5xx_map;
452 		map_size = ARRAY_SIZE(fvp_cci5xx_map);
453 	} else if ((arm_config.flags & ARM_CONFIG_FVP_HAS_CCI400) != 0U) {
454 		cci_base = PLAT_FVP_CCI400_BASE;
455 		cci_map = fvp_cci400_map;
456 		map_size = ARRAY_SIZE(fvp_cci400_map);
457 	} else {
458 		return;
459 	}
460 
461 	assert(cci_base != 0U);
462 	assert(cci_map != NULL);
463 	cci_init(cci_base, cci_map, map_size);
464 #endif
465 }
466 
fvp_interconnect_enable(void)467 void fvp_interconnect_enable(void)
468 {
469 #if FVP_INTERCONNECT_DRIVER == FVP_CCN
470 	plat_arm_interconnect_enter_coherency();
471 #else
472 	unsigned int master;
473 
474 	if ((arm_config.flags & (ARM_CONFIG_FVP_HAS_CCI400 |
475 				 ARM_CONFIG_FVP_HAS_CCI5XX)) != 0U) {
476 		master = get_interconnect_master();
477 		cci_enable_snoop_dvm_reqs(master);
478 	}
479 #endif
480 }
481 
fvp_interconnect_disable(void)482 void fvp_interconnect_disable(void)
483 {
484 #if FVP_INTERCONNECT_DRIVER == FVP_CCN
485 	plat_arm_interconnect_exit_coherency();
486 #else
487 	unsigned int master;
488 
489 	if ((arm_config.flags & (ARM_CONFIG_FVP_HAS_CCI400 |
490 				 ARM_CONFIG_FVP_HAS_CCI5XX)) != 0U) {
491 		master = get_interconnect_master();
492 		cci_disable_snoop_dvm_reqs(master);
493 	}
494 #endif
495 }
496 
497 #if CRYPTO_SUPPORT
plat_get_mbedtls_heap(void ** heap_addr,size_t * heap_size)498 int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
499 {
500 	assert(heap_addr != NULL);
501 	assert(heap_size != NULL);
502 
503 	return arm_get_mbedtls_heap(heap_addr, heap_size);
504 }
505 #endif /* CRYPTO_SUPPORT */
506 
fvp_timer_init(void)507 void fvp_timer_init(void)
508 {
509 #if USE_SP804_TIMER
510 	/* Enable the clock override for SP804 timer 0, which means that no
511 	 * clock dividers are applied and the raw (35MHz) clock will be used.
512 	 */
513 	mmio_write_32(V2M_SP810_BASE, FVP_SP810_CTRL_TIM0_OV);
514 
515 	/* Initialize delay timer driver using SP804 dual timer 0 */
516 	sp804_timer_init(V2M_SP804_TIMER0_BASE,
517 			SP804_TIMER_CLKMULT, SP804_TIMER_CLKDIV);
518 #else
519 	generic_delay_timer_init();
520 
521 	/* Enable System level generic timer */
522 	mmio_write_32(ARM_SYS_CNTCTL_BASE + CNTCR_OFF,
523 			CNTCR_FCREQ(0U) | CNTCR_EN);
524 #endif /* USE_SP804_TIMER */
525 }
526 
527 /*****************************************************************************
528  * plat_is_smccc_feature_available() - This function checks whether SMCCC
529  *                                     feature is availabile for platform.
530  * @fid: SMCCC function id
531  *
532  * Return SMC_ARCH_CALL_SUCCESS if SMCCC feature is available and
533  * SMC_ARCH_CALL_NOT_SUPPORTED otherwise.
534  *****************************************************************************/
plat_is_smccc_feature_available(u_register_t fid)535 int32_t plat_is_smccc_feature_available(u_register_t fid)
536 {
537 	switch (fid) {
538 	case SMCCC_ARCH_SOC_ID:
539 		return SMC_ARCH_CALL_SUCCESS;
540 	default:
541 		return SMC_ARCH_CALL_NOT_SUPPORTED;
542 	}
543 }
544 
545 /* Get SOC version */
plat_get_soc_version(void)546 int32_t plat_get_soc_version(void)
547 {
548 	return (int32_t)
549 		(SOC_ID_SET_JEP_106(ARM_SOC_CONTINUATION_CODE,
550 				    ARM_SOC_IDENTIFICATION_CODE) |
551 		 (FVP_SOC_ID & SOC_ID_IMPL_DEF_MASK));
552 }
553 
554 /* Get SOC revision */
plat_get_soc_revision(void)555 int32_t plat_get_soc_revision(void)
556 {
557 	unsigned int sys_id;
558 
559 	sys_id = mmio_read_32(V2M_SYSREGS_BASE + V2M_SYS_ID);
560 	return (int32_t)(((sys_id >> V2M_SYS_ID_REV_SHIFT) &
561 			  V2M_SYS_ID_REV_MASK) & SOC_ID_REV_MASK);
562 }
563 
564 #if ENABLE_RME
565 /*
566  * Get a pointer to the RMM-EL3 Shared buffer and return it
567  * through the pointer passed as parameter.
568  *
569  * This function returns the size of the shared buffer.
570  */
plat_rmmd_get_el3_rmm_shared_mem(uintptr_t * shared)571 size_t plat_rmmd_get_el3_rmm_shared_mem(uintptr_t *shared)
572 {
573 	*shared = (uintptr_t)RMM_SHARED_BASE;
574 
575 	return (size_t)RMM_SHARED_SIZE;
576 }
577 
578 /*
579  * Calculate checksum of 64-bit words @buffer with @size length
580  */
checksum_calc(uint64_t * buffer,size_t size)581 static uint64_t checksum_calc(uint64_t *buffer, size_t size)
582 {
583 	uint64_t sum = 0UL;
584 
585 	assert(((uintptr_t)buffer & (sizeof(uint64_t) - 1UL)) == 0UL);
586 	assert((size & (sizeof(uint64_t) - 1UL)) == 0UL);
587 
588 	for (unsigned long i = 0UL; i < (size / sizeof(uint64_t)); i++) {
589 		sum += buffer[i];
590 	}
591 
592 	return sum;
593 }
594 
plat_rmmd_load_manifest(struct rmm_manifest * manifest)595 int plat_rmmd_load_manifest(struct rmm_manifest *manifest)
596 {
597 	uint64_t checksum, num_banks, num_consoles;
598 	struct ns_dram_bank *bank_ptr;
599 	struct console_info *console_ptr;
600 
601 	assert(manifest != NULL);
602 
603 	/* Get number of DRAM banks */
604 	num_banks = FCONF_GET_PROPERTY(hw_config, dram_layout, num_banks);
605 	assert(num_banks <= ARM_DRAM_NUM_BANKS);
606 
607 	/* Set number of consoles */
608 	num_consoles = FVP_RMM_CONSOLE_COUNT;
609 
610 	manifest->version = RMMD_MANIFEST_VERSION;
611 	manifest->padding = 0U; /* RES0 */
612 	manifest->plat_data = (uintptr_t)NULL;
613 	manifest->plat_dram.num_banks = num_banks;
614 	manifest->plat_console.num_consoles = num_consoles;
615 
616 	/*
617 	 * Boot Manifest structure illustration, with two dram banks and
618 	 * a single console.
619 	 *
620 	 * +----------------------------------------+
621 	 * | offset |     field      |    comment   |
622 	 * +--------+----------------+--------------+
623 	 * |   0    |    version     |  0x00000003  |
624 	 * +--------+----------------+--------------+
625 	 * |   4    |    padding     |  0x00000000  |
626 	 * +--------+----------------+--------------+
627 	 * |   8    |   plat_data    |     NULL     |
628 	 * +--------+----------------+--------------+
629 	 * |   16   |   num_banks    |              |
630 	 * +--------+----------------+              |
631 	 * |   24   |     banks      |   plat_dram  |
632 	 * +--------+----------------+              |
633 	 * |   32   |    checksum    |              |
634 	 * +--------+----------------+--------------+
635 	 * |   40   |  num_consoles  |              |
636 	 * +--------+----------------+              |
637 	 * |   48   |    consoles    | plat_console |
638 	 * +--------+----------------+              |
639 	 * |   56   |    checksum    |              |
640 	 * +--------+----------------+--------------+
641 	 * |   64   |     base 0     |              |
642 	 * +--------+----------------+    bank[0]   |
643 	 * |   72   |     size 0     |              |
644 	 * +--------+----------------+--------------+
645 	 * |   80   |     base 1     |              |
646 	 * +--------+----------------+    bank[1]   |
647 	 * |   88   |     size 1     |              |
648 	 * +--------+----------------+--------------+
649 	 * |   96   |     base       |              |
650 	 * +--------+----------------+              |
651 	 * |   104  |   map_pages    |              |
652 	 * +--------+----------------+              |
653 	 * |   112  |     name       |              |
654 	 * +--------+----------------+  consoles[0] |
655 	 * |   120  |   clk_in_hz    |              |
656 	 * +--------+----------------+              |
657 	 * |   128  |   baud_rate    |              |
658 	 * +--------+----------------+              |
659 	 * |   136  |     flags      |              |
660 	 * +--------+----------------+--------------+
661 	 */
662 
663 	bank_ptr = (struct ns_dram_bank *)
664 			(((uintptr_t)manifest) + sizeof(*manifest));
665 	console_ptr = (struct console_info *)
666 			((uintptr_t)bank_ptr + (num_banks * sizeof(*bank_ptr)));
667 
668 	manifest->plat_dram.banks = bank_ptr;
669 	manifest->plat_console.consoles = console_ptr;
670 
671 	/* Ensure the manifest is not larger than the shared buffer */
672 	assert((sizeof(struct rmm_manifest) +
673 		(sizeof(struct console_info) * manifest->plat_console.num_consoles) +
674 		(sizeof(struct ns_dram_bank) * manifest->plat_dram.num_banks)) <= ARM_EL3_RMM_SHARED_SIZE);
675 
676 	/* Calculate checksum of plat_dram structure */
677 	checksum = num_banks + (uint64_t)bank_ptr;
678 
679 	/* Store FVP DRAM banks data in Boot Manifest */
680 	for (unsigned long i = 0UL; i < num_banks; i++) {
681 		bank_ptr[i].base = FCONF_GET_PROPERTY(hw_config, dram_layout, dram_bank[i].base);
682 		bank_ptr[i].size = FCONF_GET_PROPERTY(hw_config, dram_layout, dram_bank[i].size);
683 	}
684 
685 	/* Update checksum */
686 	checksum += checksum_calc((uint64_t *)bank_ptr, sizeof(struct ns_dram_bank) * num_banks);
687 
688 	/* Checksum must be 0 */
689 	manifest->plat_dram.checksum = ~checksum + 1UL;
690 
691 	/* Calculate the checksum of the plat_consoles structure */
692 	checksum = num_consoles + (uint64_t)console_ptr;
693 
694 	/* Zero out the console info struct */
695 	(void)memset((void *)console_ptr, '\0', sizeof(struct console_info) * num_consoles);
696 
697 	console_ptr[0].base = FVP_RMM_CONSOLE_BASE;
698 	console_ptr[0].map_pages = 1UL;
699 	console_ptr[0].clk_in_hz = FVP_RMM_CONSOLE_CLK_IN_HZ;
700 	console_ptr[0].baud_rate = FVP_RMM_CONSOLE_BAUD;
701 
702 	(void)strlcpy(console_ptr[0].name, FVP_RMM_CONSOLE_NAME, RMM_CONSOLE_MAX_NAME_LEN - 1UL);
703 
704 	/* Update checksum */
705 	checksum += checksum_calc((uint64_t *)console_ptr,
706 					sizeof(struct console_info) * num_consoles);
707 
708 	/* Checksum must be 0 */
709 	manifest->plat_console.checksum = ~checksum + 1UL;
710 
711 	return 0;
712 }
713 #endif	/* ENABLE_RME */
714