xref: /rk3399_ARM-atf/plat/arm/board/fvp/fvp_common.c (revision b57724806143e36ae17be7e33e5792863c5c026c)
13e4b8fdcSSoby Mathew /*
2bef44f60SAlexeiFedorov  * Copyright (c) 2013-2025, Arm Limited and Contributors. All rights reserved.
33e4b8fdcSSoby Mathew  *
482cb2c1aSdp-arm  * SPDX-License-Identifier: BSD-3-Clause
53e4b8fdcSSoby Mathew  */
63e4b8fdcSSoby Mathew 
709d40e0eSAntonio Nino Diaz #include <assert.h>
832904472SSoby Mathew #include <string.h>
909d40e0eSAntonio Nino Diaz 
1009d40e0eSAntonio Nino Diaz #include <common/debug.h>
1109d40e0eSAntonio Nino Diaz #include <drivers/arm/cci.h>
1209d40e0eSAntonio Nino Diaz #include <drivers/arm/ccn.h>
1309d40e0eSAntonio Nino Diaz #include <drivers/arm/gicv2.h>
141b597c22SAlexei Fedorov #include <drivers/arm/sp804_delay_timer.h>
151b597c22SAlexei Fedorov #include <drivers/generic_delay_timer.h>
1682685904SAlexeiFedorov #include <fconf_hw_config_getter.h>
1709d40e0eSAntonio Nino Diaz #include <lib/mmio.h>
18ed9653ffSManish V Badarkhe #include <lib/smccc.h>
1909d40e0eSAntonio Nino Diaz #include <lib/xlat_tables/xlat_tables_compat.h>
20234bc7f8SAntonio Nino Diaz #include <platform_def.h>
21ed9653ffSManish V Badarkhe #include <services/arm_arch_svc.h>
221d0ca40eSJavier Almansa Sobrino #include <services/rmm_core_manifest.h>
239d9ae976SOlivier Deprez #if SPM_MM
24aeaa225cSPaul Beesley #include <services/spm_mm_partition.h>
259d9ae976SOlivier Deprez #endif
2609d40e0eSAntonio Nino Diaz 
27ed9653ffSManish V Badarkhe #include <plat/arm/common/arm_config.h>
28ed9653ffSManish V Badarkhe #include <plat/arm/common/plat_arm.h>
29ed9653ffSManish V Badarkhe #include <plat/common/platform.h>
30ed9653ffSManish V Badarkhe 
311af540efSRoberto Vargas #include "fvp_private.h"
323e4b8fdcSSoby Mathew 
333e4b8fdcSSoby Mathew /* Defines for GIC Driver build time selection */
343e4b8fdcSSoby Mathew #define FVP_GICV2		1
353e4b8fdcSSoby Mathew #define FVP_GICV3		2
363e4b8fdcSSoby Mathew 
3732904472SSoby Mathew /* Defines for RMM Console */
3832904472SSoby Mathew #define FVP_RMM_CONSOLE_BASE		UL(0x1c0c0000)
3932904472SSoby Mathew #define FVP_RMM_CONSOLE_BAUD		UL(115200)
4032904472SSoby Mathew #define FVP_RMM_CONSOLE_CLK_IN_HZ	UL(14745600)
4132904472SSoby Mathew #define FVP_RMM_CONSOLE_NAME		"pl011"
4232904472SSoby Mathew #define FVP_RMM_CONSOLE_COUNT		UL(1)
4332904472SSoby Mathew 
443e4b8fdcSSoby Mathew /*******************************************************************************
453e4b8fdcSSoby Mathew  * arm_config holds the characteristics of the differences between the three FVP
463e4b8fdcSSoby Mathew  * platforms (Base, A53_A57 & Foundation). It will be populated during cold boot
473e4b8fdcSSoby Mathew  * at each boot stage by the primary before enabling the MMU (to allow
483e4b8fdcSSoby Mathew  * interconnect configuration) & used thereafter. Each BL will have its own copy
493e4b8fdcSSoby Mathew  * to allow independent operation.
503e4b8fdcSSoby Mathew  ******************************************************************************/
513e4b8fdcSSoby Mathew arm_config_t arm_config;
523e4b8fdcSSoby Mathew 
533e4b8fdcSSoby Mathew #define MAP_DEVICE0	MAP_REGION_FLAT(DEVICE0_BASE,			\
543e4b8fdcSSoby Mathew 					DEVICE0_SIZE,			\
55*b5772480SAlexeiFedorov 					MT_DEVICE | MT_RW | EL3_PAS)
563e4b8fdcSSoby Mathew 
573e4b8fdcSSoby Mathew #define MAP_DEVICE1	MAP_REGION_FLAT(DEVICE1_BASE,			\
583e4b8fdcSSoby Mathew 					DEVICE1_SIZE,			\
593e4b8fdcSSoby Mathew 					MT_DEVICE | MT_RW | MT_SECURE)
603e4b8fdcSSoby Mathew 
61f98630fbSManish V Badarkhe #if FVP_GICR_REGION_PROTECTION
62f98630fbSManish V Badarkhe #define MAP_GICD_MEM	MAP_REGION_FLAT(BASE_GICD_BASE,			\
63f98630fbSManish V Badarkhe 					BASE_GICD_SIZE,			\
64f98630fbSManish V Badarkhe 					MT_DEVICE | MT_RW | MT_SECURE)
65f98630fbSManish V Badarkhe 
66f98630fbSManish V Badarkhe /* Map all core's redistributor memory as read-only. After boots up,
67f98630fbSManish V Badarkhe  * per-core map its redistributor memory as read-write */
68f98630fbSManish V Badarkhe #define MAP_GICR_MEM	MAP_REGION_FLAT(BASE_GICR_BASE,			\
69f98630fbSManish V Badarkhe 					(BASE_GICR_SIZE * PLATFORM_CORE_COUNT),\
70f98630fbSManish V Badarkhe 					MT_DEVICE | MT_RO | MT_SECURE)
71f98630fbSManish V Badarkhe #endif /* FVP_GICR_REGION_PROTECTION */
72f98630fbSManish V Badarkhe 
73284c3d67SSandrine Bailleux /*
74284c3d67SSandrine Bailleux  * Need to be mapped with write permissions in order to set a new non-volatile
75284c3d67SSandrine Bailleux  * counter value.
76284c3d67SSandrine Bailleux  */
773e4b8fdcSSoby Mathew #define MAP_DEVICE2	MAP_REGION_FLAT(DEVICE2_BASE,			\
783e4b8fdcSSoby Mathew 					DEVICE2_SIZE,			\
79fe7de035SAntonio Nino Diaz 					MT_DEVICE | MT_RW | MT_SECURE)
803e4b8fdcSSoby Mathew 
8194c90ac8SHarrison Mutai #if TRANSFER_LIST
8294c90ac8SHarrison Mutai #ifdef FW_NS_HANDOFF_BASE
83a5566f65SHarrison Mutai #define MAP_FW_NS_HANDOFF                                             \
84a5566f65SHarrison Mutai 	MAP_REGION_FLAT(FW_NS_HANDOFF_BASE, PLAT_ARM_FW_HANDOFF_SIZE, \
8594c90ac8SHarrison Mutai 			MT_MEMORY | MT_RW | MT_NS)
8694c90ac8SHarrison Mutai #endif
87a5566f65SHarrison Mutai #ifdef PLAT_ARM_EL3_FW_HANDOFF_BASE
88a5566f65SHarrison Mutai #define MAP_EL3_FW_HANDOFF                            \
89a5566f65SHarrison Mutai 	MAP_REGION_FLAT(PLAT_ARM_EL3_FW_HANDOFF_BASE, \
90a5566f65SHarrison Mutai 			PLAT_ARM_FW_HANDOFF_SIZE, MT_MEMORY | MT_RW | EL3_PAS)
91a5566f65SHarrison Mutai #endif
9294c90ac8SHarrison Mutai #endif
9394c90ac8SHarrison Mutai 
943e4b8fdcSSoby Mathew /*
95b5fa6563SSandrine Bailleux  * Table of memory regions for various BL stages to map using the MMU.
960916c38dSRoberto Vargas  * This doesn't include Trusted SRAM as setup_page_tables() already takes care
970916c38dSRoberto Vargas  * of mapping it.
983e4b8fdcSSoby Mathew  */
993d8256b2SMasahiro Yamada #ifdef IMAGE_BL1
1003e4b8fdcSSoby Mathew const mmap_region_t plat_arm_mmap[] = {
1013e4b8fdcSSoby Mathew 	ARM_MAP_SHARED_RAM,
10279d8be3cSManish V Badarkhe 	V2M_MAP_FLASH0_RO,
1033e4b8fdcSSoby Mathew 	V2M_MAP_IOFPGA,
1043e4b8fdcSSoby Mathew 	MAP_DEVICE0,
105e0cea783SManish V Badarkhe #if FVP_INTERCONNECT_DRIVER == FVP_CCN
1063e4b8fdcSSoby Mathew 	MAP_DEVICE1,
107e0cea783SManish V Badarkhe #endif
1083e4b8fdcSSoby Mathew #if TRUSTED_BOARD_BOOT
109284c3d67SSandrine Bailleux 	/* To access the Root of Trust Public Key registers. */
110284c3d67SSandrine Bailleux 	MAP_DEVICE2,
111284c3d67SSandrine Bailleux 	/* Map DRAM to authenticate NS_BL2U image. */
1123e4b8fdcSSoby Mathew 	ARM_MAP_NS_DRAM1,
1133e4b8fdcSSoby Mathew #endif
1143e4b8fdcSSoby Mathew 	{0}
1153e4b8fdcSSoby Mathew };
1163e4b8fdcSSoby Mathew #endif
1173d8256b2SMasahiro Yamada #ifdef IMAGE_BL2
1183e4b8fdcSSoby Mathew const mmap_region_t plat_arm_mmap[] = {
1193e4b8fdcSSoby Mathew 	ARM_MAP_SHARED_RAM,
1203e4b8fdcSSoby Mathew 	V2M_MAP_FLASH0_RW,
1213e4b8fdcSSoby Mathew 	V2M_MAP_IOFPGA,
1223e4b8fdcSSoby Mathew 	MAP_DEVICE0,
123e0cea783SManish V Badarkhe #if FVP_INTERCONNECT_DRIVER == FVP_CCN
1243e4b8fdcSSoby Mathew 	MAP_DEVICE1,
125e0cea783SManish V Badarkhe #endif
1263e4b8fdcSSoby Mathew 	ARM_MAP_NS_DRAM1,
127402b3cf8SJulius Werner #ifdef __aarch64__
128b09ba056SRoberto Vargas 	ARM_MAP_DRAM2,
129b09ba056SRoberto Vargas #endif
13039f0b86aSManish V Badarkhe 	/*
13139f0b86aSManish V Badarkhe 	 * Required to load HW_CONFIG, SPMC and SPs to trusted DRAM.
13239f0b86aSManish V Badarkhe 	 */
13364758c97SAchin Gupta 	ARM_MAP_TRUSTED_DRAM,
1346b2e961fSManish V Badarkhe 
1356b2e961fSManish V Badarkhe 	/*
1366b2e961fSManish V Badarkhe 	 * Required to load Event Log in TZC secured memory
1376b2e961fSManish V Badarkhe 	 */
1386b2e961fSManish V Badarkhe #if MEASURED_BOOT && (defined(SPD_tspd) || defined(SPD_opteed) || \
1396b2e961fSManish V Badarkhe defined(SPD_spmd))
1406b2e961fSManish V Badarkhe 	ARM_MAP_EVENT_LOG_DRAM1,
1416b2e961fSManish V Badarkhe #endif /* MEASURED_BOOT && (SPD_tspd || SPD_opteed || SPD_spmd) */
1426b2e961fSManish V Badarkhe 
143c8720729SZelalem Aweke #if ENABLE_RME
144c8720729SZelalem Aweke 	ARM_MAP_RMM_DRAM,
145c8720729SZelalem Aweke 	ARM_MAP_GPT_L1_DRAM,
146c8720729SZelalem Aweke #endif /* ENABLE_RME */
1473eb2d672SSandrine Bailleux #ifdef SPD_tspd
1483e4b8fdcSSoby Mathew 	ARM_MAP_TSP_SEC_MEM,
1493eb2d672SSandrine Bailleux #endif
150284c3d67SSandrine Bailleux #if TRUSTED_BOARD_BOOT
151284c3d67SSandrine Bailleux 	/* To access the Root of Trust Public Key registers. */
152284c3d67SSandrine Bailleux 	MAP_DEVICE2,
153ba597da7SJohn Tsichritzis #endif /* TRUSTED_BOARD_BOOT */
15488c51c3fSManish V Badarkhe 
15542d4d3baSArvind Ram Prakash #if CRYPTO_SUPPORT && !RESET_TO_BL2
15688c51c3fSManish V Badarkhe 	/*
15788c51c3fSManish V Badarkhe 	 * To access shared the Mbed TLS heap while booting the
15888c51c3fSManish V Badarkhe 	 * system with Crypto support
15988c51c3fSManish V Badarkhe 	 */
16088c51c3fSManish V Badarkhe 	ARM_MAP_BL1_RW,
16142d4d3baSArvind Ram Prakash #endif /* CRYPTO_SUPPORT && !RESET_TO_BL2 */
16244639ab7SMarc Bonnici #if SPM_MM || SPMC_AT_EL3
163e29efeb1SAntonio Nino Diaz 	ARM_SP_IMAGE_MMAP,
164e29efeb1SAntonio Nino Diaz #endif
1653e4b8fdcSSoby Mathew #if ARM_BL31_IN_DRAM
1663e4b8fdcSSoby Mathew 	ARM_MAP_BL31_SEC_DRAM,
1673e4b8fdcSSoby Mathew #endif
168810d9213SJens Wiklander #ifdef SPD_opteed
169b3ba6fdaSSoby Mathew 	ARM_MAP_OPTEE_CORE_MEM,
170810d9213SJens Wiklander 	ARM_OPTEE_PAGEABLE_LOAD_MEM,
171810d9213SJens Wiklander #endif
172a5566f65SHarrison Mutai #ifdef MAP_EL3_FW_HANDOFF
173a5566f65SHarrison Mutai 	MAP_EL3_FW_HANDOFF,
174a5566f65SHarrison Mutai #endif
1753e4b8fdcSSoby Mathew 	{ 0 }
1763e4b8fdcSSoby Mathew };
1773e4b8fdcSSoby Mathew #endif
1783d8256b2SMasahiro Yamada #ifdef IMAGE_BL2U
1793e4b8fdcSSoby Mathew const mmap_region_t plat_arm_mmap[] = {
1803e4b8fdcSSoby Mathew 	MAP_DEVICE0,
1813e4b8fdcSSoby Mathew 	V2M_MAP_IOFPGA,
1823e4b8fdcSSoby Mathew 	{0}
1833e4b8fdcSSoby Mathew };
1843e4b8fdcSSoby Mathew #endif
1853d8256b2SMasahiro Yamada #ifdef IMAGE_BL31
1863e4b8fdcSSoby Mathew const mmap_region_t plat_arm_mmap[] = {
1873e4b8fdcSSoby Mathew 	ARM_MAP_SHARED_RAM,
188992f091bSAmbroise Vincent #if USE_DEBUGFS
189992f091bSAmbroise Vincent 	/* Required by devfip, can be removed if devfip is not used */
190992f091bSAmbroise Vincent 	V2M_MAP_FLASH0_RW,
191992f091bSAmbroise Vincent #endif /* USE_DEBUGFS */
192e35a3fb5SSoby Mathew 	ARM_MAP_EL3_TZC_DRAM,
1933e4b8fdcSSoby Mathew 	V2M_MAP_IOFPGA,
1943e4b8fdcSSoby Mathew 	MAP_DEVICE0,
195f98630fbSManish V Badarkhe #if FVP_GICR_REGION_PROTECTION
196f98630fbSManish V Badarkhe 	MAP_GICD_MEM,
197f98630fbSManish V Badarkhe 	MAP_GICR_MEM,
198f98630fbSManish V Badarkhe #else
1993e4b8fdcSSoby Mathew 	MAP_DEVICE1,
200f98630fbSManish V Badarkhe #endif /* FVP_GICR_REGION_PROTECTION */
201f145403cSRoberto Vargas 	ARM_V2M_MAP_MEM_PROTECT,
2023f3c341aSPaul Beesley #if SPM_MM
203e29efeb1SAntonio Nino Diaz 	ARM_SPM_BUF_EL3_MMAP,
204e29efeb1SAntonio Nino Diaz #endif
205c8720729SZelalem Aweke #if ENABLE_RME
206c8720729SZelalem Aweke 	ARM_MAP_GPT_L1_DRAM,
2078c980a4aSJavier Almansa Sobrino 	ARM_MAP_EL3_RMM_SHARED_MEM,
208c8720729SZelalem Aweke #endif
20994c90ac8SHarrison Mutai #ifdef MAP_FW_NS_HANDOFF
21094c90ac8SHarrison Mutai 	MAP_FW_NS_HANDOFF,
21194c90ac8SHarrison Mutai #endif
2121a0ebff7SHarrison Mutai #if defined(MAP_EL3_FW_HANDOFF) && !RESET_TO_BL31
213a5566f65SHarrison Mutai 	MAP_EL3_FW_HANDOFF,
214a5566f65SHarrison Mutai #endif
2153e4b8fdcSSoby Mathew 	{ 0 }
2163e4b8fdcSSoby Mathew };
217e29efeb1SAntonio Nino Diaz 
2183f3c341aSPaul Beesley #if defined(IMAGE_BL31) && SPM_MM
219e29efeb1SAntonio Nino Diaz const mmap_region_t plat_arm_secure_partition_mmap[] = {
220e29efeb1SAntonio Nino Diaz 	V2M_MAP_IOFPGA_EL0, /* for the UART */
2219fb76763Slevi.yun 	V2M_MAP_SECURE_SYSTEMREG_EL0, /* for initializing flash */
2229fb76763Slevi.yun #if PSA_FWU_SUPPORT
2239fb76763Slevi.yun 	V2M_MAP_FLASH0_RW_EL0, /* for firmware update service in standalone mm */
2249fb76763Slevi.yun #endif
2259fb76763Slevi.yun 	V2M_MAP_FLASH1_RW_EL0, /* for secure variable service in standalone mm */
2269a90d720SElyes Haouas 	MAP_REGION_FLAT(DEVICE0_BASE,
2279a90d720SElyes Haouas 			DEVICE0_SIZE,
228c4fa1739SSandrine Bailleux 			MT_DEVICE | MT_RO | MT_SECURE | MT_USER),
229e29efeb1SAntonio Nino Diaz 	ARM_SP_IMAGE_MMAP,
230e29efeb1SAntonio Nino Diaz 	ARM_SP_IMAGE_NS_BUF_MMAP,
231e29efeb1SAntonio Nino Diaz 	ARM_SP_IMAGE_RW_MMAP,
232e29efeb1SAntonio Nino Diaz 	ARM_SPM_BUF_EL0_MMAP,
233e29efeb1SAntonio Nino Diaz 	{0}
234e29efeb1SAntonio Nino Diaz };
235e29efeb1SAntonio Nino Diaz #endif
2363e4b8fdcSSoby Mathew #endif
2373d8256b2SMasahiro Yamada #ifdef IMAGE_BL32
2383e4b8fdcSSoby Mathew const mmap_region_t plat_arm_mmap[] = {
239402b3cf8SJulius Werner #ifndef __aarch64__
240877cf3ffSSoby Mathew 	ARM_MAP_SHARED_RAM,
241950c6956SJoel Hutton 	ARM_V2M_MAP_MEM_PROTECT,
242877cf3ffSSoby Mathew #endif
2433e4b8fdcSSoby Mathew 	V2M_MAP_IOFPGA,
2443e4b8fdcSSoby Mathew 	MAP_DEVICE0,
2453e4b8fdcSSoby Mathew 	MAP_DEVICE1,
2463e4b8fdcSSoby Mathew 	{0}
2473e4b8fdcSSoby Mathew };
2483e4b8fdcSSoby Mathew #endif
2493e4b8fdcSSoby Mathew 
2509d870b79SZelalem Aweke #ifdef IMAGE_RMM
2519d870b79SZelalem Aweke const mmap_region_t plat_arm_mmap[] = {
2529d870b79SZelalem Aweke 	V2M_MAP_IOFPGA,
2539d870b79SZelalem Aweke 	MAP_DEVICE0,
2549d870b79SZelalem Aweke 	MAP_DEVICE1,
2559d870b79SZelalem Aweke 	{0}
2569d870b79SZelalem Aweke };
2579d870b79SZelalem Aweke #endif
2589d870b79SZelalem Aweke 
2593e4b8fdcSSoby Mathew ARM_CASSERT_MMAP
2603e4b8fdcSSoby Mathew 
261955242d8SJeenu Viswambharan #if FVP_INTERCONNECT_DRIVER != FVP_CCN
262955242d8SJeenu Viswambharan static const int fvp_cci400_map[] = {
263955242d8SJeenu Viswambharan 	PLAT_FVP_CCI400_CLUS0_SL_PORT,
264955242d8SJeenu Viswambharan 	PLAT_FVP_CCI400_CLUS1_SL_PORT,
265955242d8SJeenu Viswambharan };
266955242d8SJeenu Viswambharan 
267955242d8SJeenu Viswambharan static const int fvp_cci5xx_map[] = {
268955242d8SJeenu Viswambharan 	PLAT_FVP_CCI5XX_CLUS0_SL_PORT,
269955242d8SJeenu Viswambharan 	PLAT_FVP_CCI5XX_CLUS1_SL_PORT,
270955242d8SJeenu Viswambharan };
271955242d8SJeenu Viswambharan 
272955242d8SJeenu Viswambharan static unsigned int get_interconnect_master(void)
273955242d8SJeenu Viswambharan {
274955242d8SJeenu Viswambharan 	unsigned int master;
275955242d8SJeenu Viswambharan 	u_register_t mpidr;
276955242d8SJeenu Viswambharan 
277955242d8SJeenu Viswambharan 	mpidr = read_mpidr_el1();
278583e0791SAntonio Nino Diaz 	master = ((arm_config.flags & ARM_CONFIG_FVP_SHIFTED_AFF) != 0U) ?
279955242d8SJeenu Viswambharan 		MPIDR_AFFLVL2_VAL(mpidr) : MPIDR_AFFLVL1_VAL(mpidr);
280955242d8SJeenu Viswambharan 
281955242d8SJeenu Viswambharan 	assert(master < FVP_CLUSTER_COUNT);
282955242d8SJeenu Viswambharan 	return master;
283955242d8SJeenu Viswambharan }
284955242d8SJeenu Viswambharan #endif
2853e4b8fdcSSoby Mathew 
2863f3c341aSPaul Beesley #if defined(IMAGE_BL31) && SPM_MM
287e29efeb1SAntonio Nino Diaz /*
288e29efeb1SAntonio Nino Diaz  * Boot information passed to a secure partition during initialisation. Linear
289e29efeb1SAntonio Nino Diaz  * indices in MP information will be filled at runtime.
290e29efeb1SAntonio Nino Diaz  */
291aeaa225cSPaul Beesley static spm_mm_mp_info_t sp_mp_info[] = {
292e29efeb1SAntonio Nino Diaz 	[0] = {0x80000000, 0},
293e29efeb1SAntonio Nino Diaz 	[1] = {0x80000001, 0},
294e29efeb1SAntonio Nino Diaz 	[2] = {0x80000002, 0},
295e29efeb1SAntonio Nino Diaz 	[3] = {0x80000003, 0},
296e29efeb1SAntonio Nino Diaz 	[4] = {0x80000100, 0},
297e29efeb1SAntonio Nino Diaz 	[5] = {0x80000101, 0},
298e29efeb1SAntonio Nino Diaz 	[6] = {0x80000102, 0},
299e29efeb1SAntonio Nino Diaz 	[7] = {0x80000103, 0},
300e29efeb1SAntonio Nino Diaz };
301e29efeb1SAntonio Nino Diaz 
302aeaa225cSPaul Beesley const spm_mm_boot_info_t plat_arm_secure_partition_boot_info = {
303e29efeb1SAntonio Nino Diaz 	.h.type              = PARAM_SP_IMAGE_BOOT_INFO,
304e29efeb1SAntonio Nino Diaz 	.h.version           = VERSION_1,
305aeaa225cSPaul Beesley 	.h.size              = sizeof(spm_mm_boot_info_t),
306e29efeb1SAntonio Nino Diaz 	.h.attr              = 0,
307e29efeb1SAntonio Nino Diaz 	.sp_mem_base         = ARM_SP_IMAGE_BASE,
308e29efeb1SAntonio Nino Diaz 	.sp_mem_limit        = ARM_SP_IMAGE_LIMIT,
309e29efeb1SAntonio Nino Diaz 	.sp_image_base       = ARM_SP_IMAGE_BASE,
310e29efeb1SAntonio Nino Diaz 	.sp_stack_base       = PLAT_SP_IMAGE_STACK_BASE,
311e29efeb1SAntonio Nino Diaz 	.sp_heap_base        = ARM_SP_IMAGE_HEAP_BASE,
3120560efb9SArd Biesheuvel 	.sp_ns_comm_buf_base = PLAT_SP_IMAGE_NS_BUF_BASE,
313e29efeb1SAntonio Nino Diaz 	.sp_shared_buf_base  = PLAT_SPM_BUF_BASE,
314e29efeb1SAntonio Nino Diaz 	.sp_image_size       = ARM_SP_IMAGE_SIZE,
315e29efeb1SAntonio Nino Diaz 	.sp_pcpu_stack_size  = PLAT_SP_IMAGE_STACK_PCPU_SIZE,
316e29efeb1SAntonio Nino Diaz 	.sp_heap_size        = ARM_SP_IMAGE_HEAP_SIZE,
3170560efb9SArd Biesheuvel 	.sp_ns_comm_buf_size = PLAT_SP_IMAGE_NS_BUF_SIZE,
318e29efeb1SAntonio Nino Diaz 	.sp_shared_buf_size  = PLAT_SPM_BUF_SIZE,
319e29efeb1SAntonio Nino Diaz 	.num_sp_mem_regions  = ARM_SP_IMAGE_NUM_MEM_REGIONS,
320e29efeb1SAntonio Nino Diaz 	.num_cpus            = PLATFORM_CORE_COUNT,
321e29efeb1SAntonio Nino Diaz 	.mp_info             = &sp_mp_info[0],
322e29efeb1SAntonio Nino Diaz };
323e29efeb1SAntonio Nino Diaz 
324e29efeb1SAntonio Nino Diaz const struct mmap_region *plat_get_secure_partition_mmap(void *cookie)
325e29efeb1SAntonio Nino Diaz {
326e29efeb1SAntonio Nino Diaz 	return plat_arm_secure_partition_mmap;
327e29efeb1SAntonio Nino Diaz }
328e29efeb1SAntonio Nino Diaz 
329aeaa225cSPaul Beesley const struct spm_mm_boot_info *plat_get_secure_partition_boot_info(
330e29efeb1SAntonio Nino Diaz 		void *cookie)
331e29efeb1SAntonio Nino Diaz {
332e29efeb1SAntonio Nino Diaz 	return &plat_arm_secure_partition_boot_info;
333e29efeb1SAntonio Nino Diaz }
334e29efeb1SAntonio Nino Diaz #endif
335e29efeb1SAntonio Nino Diaz 
3363e4b8fdcSSoby Mathew /*******************************************************************************
3373e4b8fdcSSoby Mathew  * A single boot loader stack is expected to work on both the Foundation FVP
3383e4b8fdcSSoby Mathew  * models and the two flavours of the Base FVP models (AEMv8 & Cortex). The
3393e4b8fdcSSoby Mathew  * SYS_ID register provides a mechanism for detecting the differences between
3403e4b8fdcSSoby Mathew  * these platforms. This information is stored in a per-BL array to allow the
3413e4b8fdcSSoby Mathew  * code to take the correct path.Per BL platform configuration.
3423e4b8fdcSSoby Mathew  ******************************************************************************/
3434d010d0dSDaniel Boulby void __init fvp_config_setup(void)
3443e4b8fdcSSoby Mathew {
3453e4b8fdcSSoby Mathew 	unsigned int rev, hbi, bld, arch, sys_id;
3463e4b8fdcSSoby Mathew 
3473e4b8fdcSSoby Mathew 	sys_id = mmio_read_32(V2M_SYSREGS_BASE + V2M_SYS_ID);
3483e4b8fdcSSoby Mathew 	rev = (sys_id >> V2M_SYS_ID_REV_SHIFT) & V2M_SYS_ID_REV_MASK;
3493e4b8fdcSSoby Mathew 	hbi = (sys_id >> V2M_SYS_ID_HBI_SHIFT) & V2M_SYS_ID_HBI_MASK;
3503e4b8fdcSSoby Mathew 	bld = (sys_id >> V2M_SYS_ID_BLD_SHIFT) & V2M_SYS_ID_BLD_MASK;
3513e4b8fdcSSoby Mathew 	arch = (sys_id >> V2M_SYS_ID_ARCH_SHIFT) & V2M_SYS_ID_ARCH_MASK;
3523e4b8fdcSSoby Mathew 
3533e4b8fdcSSoby Mathew 	if (arch != ARCH_MODEL) {
3543e4b8fdcSSoby Mathew 		ERROR("This firmware is for FVP models\n");
3553e4b8fdcSSoby Mathew 		panic();
3563e4b8fdcSSoby Mathew 	}
3573e4b8fdcSSoby Mathew 
3583e4b8fdcSSoby Mathew 	/*
3593e4b8fdcSSoby Mathew 	 * The build field in the SYS_ID tells which variant of the GIC
3603e4b8fdcSSoby Mathew 	 * memory is implemented by the model.
3613e4b8fdcSSoby Mathew 	 */
3623e4b8fdcSSoby Mathew 	switch (bld) {
3633e4b8fdcSSoby Mathew 	case BLD_GIC_VE_MMAP:
36421a3973dSSoby Mathew 		ERROR("Legacy Versatile Express memory map for GIC peripheral"
36521a3973dSSoby Mathew 				" is not supported\n");
3663e4b8fdcSSoby Mathew 		panic();
3673e4b8fdcSSoby Mathew 		break;
3683e4b8fdcSSoby Mathew 	case BLD_GIC_A53A57_MMAP:
3693e4b8fdcSSoby Mathew 		break;
3703e4b8fdcSSoby Mathew 	default:
3713e4b8fdcSSoby Mathew 		ERROR("Unsupported board build %x\n", bld);
3723e4b8fdcSSoby Mathew 		panic();
3733e4b8fdcSSoby Mathew 	}
3743e4b8fdcSSoby Mathew 
3753e4b8fdcSSoby Mathew 	/*
3763e4b8fdcSSoby Mathew 	 * The hbi field in the SYS_ID is 0x020 for the Base FVP & 0x010
3773e4b8fdcSSoby Mathew 	 * for the Foundation FVP.
3783e4b8fdcSSoby Mathew 	 */
3793e4b8fdcSSoby Mathew 	switch (hbi) {
3803e4b8fdcSSoby Mathew 	case HBI_FOUNDATION_FVP:
3813e4b8fdcSSoby Mathew 		arm_config.flags = 0;
3823e4b8fdcSSoby Mathew 
3833e4b8fdcSSoby Mathew 		/*
3843e4b8fdcSSoby Mathew 		 * Check for supported revisions of Foundation FVP
3853e4b8fdcSSoby Mathew 		 * Allow future revisions to run but emit warning diagnostic
3863e4b8fdcSSoby Mathew 		 */
3873e4b8fdcSSoby Mathew 		switch (rev) {
3883e4b8fdcSSoby Mathew 		case REV_FOUNDATION_FVP_V2_0:
3893e4b8fdcSSoby Mathew 		case REV_FOUNDATION_FVP_V2_1:
3903e4b8fdcSSoby Mathew 		case REV_FOUNDATION_FVP_v9_1:
3914faa4a1dSSandrine Bailleux 		case REV_FOUNDATION_FVP_v9_6:
3923e4b8fdcSSoby Mathew 			break;
3933e4b8fdcSSoby Mathew 		default:
3943e4b8fdcSSoby Mathew 			WARN("Unrecognized Foundation FVP revision %x\n", rev);
3953e4b8fdcSSoby Mathew 			break;
3963e4b8fdcSSoby Mathew 		}
3973e4b8fdcSSoby Mathew 		break;
3983e4b8fdcSSoby Mathew 	case HBI_BASE_FVP:
399955242d8SJeenu Viswambharan 		arm_config.flags |= (ARM_CONFIG_BASE_MMAP | ARM_CONFIG_HAS_TZC);
4003e4b8fdcSSoby Mathew 
4013e4b8fdcSSoby Mathew 		/*
4023e4b8fdcSSoby Mathew 		 * Check for supported revisions
4033e4b8fdcSSoby Mathew 		 * Allow future revisions to run but emit warning diagnostic
4043e4b8fdcSSoby Mathew 		 */
4053e4b8fdcSSoby Mathew 		switch (rev) {
4063e4b8fdcSSoby Mathew 		case REV_BASE_FVP_V0:
407955242d8SJeenu Viswambharan 			arm_config.flags |= ARM_CONFIG_FVP_HAS_CCI400;
408955242d8SJeenu Viswambharan 			break;
409955242d8SJeenu Viswambharan 		case REV_BASE_FVP_REVC:
4108431635bSIsla Mitchell 			arm_config.flags |= (ARM_CONFIG_FVP_HAS_SMMUV3 |
411955242d8SJeenu Viswambharan 					ARM_CONFIG_FVP_HAS_CCI5XX);
4123e4b8fdcSSoby Mathew 			break;
4133e4b8fdcSSoby Mathew 		default:
4143e4b8fdcSSoby Mathew 			WARN("Unrecognized Base FVP revision %x\n", rev);
4153e4b8fdcSSoby Mathew 			break;
4163e4b8fdcSSoby Mathew 		}
4173e4b8fdcSSoby Mathew 		break;
4183e4b8fdcSSoby Mathew 	default:
4193e4b8fdcSSoby Mathew 		ERROR("Unsupported board HBI number 0x%x\n", hbi);
4203e4b8fdcSSoby Mathew 		panic();
4213e4b8fdcSSoby Mathew 	}
4228431635bSIsla Mitchell 
4238431635bSIsla Mitchell 	/*
4248431635bSIsla Mitchell 	 * We assume that the presence of MT bit, and therefore shifted
4258431635bSIsla Mitchell 	 * affinities, is uniform across the platform: either all CPUs, or no
4268431635bSIsla Mitchell 	 * CPUs implement it.
4278431635bSIsla Mitchell 	 */
428583e0791SAntonio Nino Diaz 	if ((read_mpidr_el1() & MPIDR_MT_MASK) != 0U)
4298431635bSIsla Mitchell 		arm_config.flags |= ARM_CONFIG_FVP_SHIFTED_AFF;
4303e4b8fdcSSoby Mathew }
4313e4b8fdcSSoby Mathew 
4323e4b8fdcSSoby Mathew 
4334d010d0dSDaniel Boulby void __init fvp_interconnect_init(void)
4343e4b8fdcSSoby Mathew {
43571237876SSoby Mathew #if FVP_INTERCONNECT_DRIVER == FVP_CCN
43671237876SSoby Mathew 	if (ccn_get_part0_id(PLAT_ARM_CCN_BASE) != CCN_502_PART0_ID) {
437583e0791SAntonio Nino Diaz 		ERROR("Unrecognized CCN variant detected. Only CCN-502 is supported");
43871237876SSoby Mathew 		panic();
43971237876SSoby Mathew 	}
440955242d8SJeenu Viswambharan 
4413e4b8fdcSSoby Mathew 	plat_arm_interconnect_init();
442955242d8SJeenu Viswambharan #else
443583e0791SAntonio Nino Diaz 	uintptr_t cci_base = 0U;
444583e0791SAntonio Nino Diaz 	const int *cci_map = NULL;
445583e0791SAntonio Nino Diaz 	unsigned int map_size = 0U;
446955242d8SJeenu Viswambharan 
447955242d8SJeenu Viswambharan 	/* Initialize the right interconnect */
448583e0791SAntonio Nino Diaz 	if ((arm_config.flags & ARM_CONFIG_FVP_HAS_CCI5XX) != 0U) {
449955242d8SJeenu Viswambharan 		cci_base = PLAT_FVP_CCI5XX_BASE;
450955242d8SJeenu Viswambharan 		cci_map = fvp_cci5xx_map;
451955242d8SJeenu Viswambharan 		map_size = ARRAY_SIZE(fvp_cci5xx_map);
452583e0791SAntonio Nino Diaz 	} else if ((arm_config.flags & ARM_CONFIG_FVP_HAS_CCI400) != 0U) {
453955242d8SJeenu Viswambharan 		cci_base = PLAT_FVP_CCI400_BASE;
454955242d8SJeenu Viswambharan 		cci_map = fvp_cci400_map;
455955242d8SJeenu Viswambharan 		map_size = ARRAY_SIZE(fvp_cci400_map);
456583e0791SAntonio Nino Diaz 	} else {
457583e0791SAntonio Nino Diaz 		return;
458955242d8SJeenu Viswambharan 	}
459955242d8SJeenu Viswambharan 
460583e0791SAntonio Nino Diaz 	assert(cci_base != 0U);
461583e0791SAntonio Nino Diaz 	assert(cci_map != NULL);
462955242d8SJeenu Viswambharan 	cci_init(cci_base, cci_map, map_size);
463955242d8SJeenu Viswambharan #endif
46471237876SSoby Mathew }
4653e4b8fdcSSoby Mathew 
4663e4b8fdcSSoby Mathew void fvp_interconnect_enable(void)
4673e4b8fdcSSoby Mathew {
468955242d8SJeenu Viswambharan #if FVP_INTERCONNECT_DRIVER == FVP_CCN
4693e4b8fdcSSoby Mathew 	plat_arm_interconnect_enter_coherency();
470955242d8SJeenu Viswambharan #else
471955242d8SJeenu Viswambharan 	unsigned int master;
472955242d8SJeenu Viswambharan 
473583e0791SAntonio Nino Diaz 	if ((arm_config.flags & (ARM_CONFIG_FVP_HAS_CCI400 |
474583e0791SAntonio Nino Diaz 				 ARM_CONFIG_FVP_HAS_CCI5XX)) != 0U) {
475955242d8SJeenu Viswambharan 		master = get_interconnect_master();
476955242d8SJeenu Viswambharan 		cci_enable_snoop_dvm_reqs(master);
477955242d8SJeenu Viswambharan 	}
478955242d8SJeenu Viswambharan #endif
4793e4b8fdcSSoby Mathew }
4803e4b8fdcSSoby Mathew 
4813e4b8fdcSSoby Mathew void fvp_interconnect_disable(void)
4823e4b8fdcSSoby Mathew {
483955242d8SJeenu Viswambharan #if FVP_INTERCONNECT_DRIVER == FVP_CCN
4843e4b8fdcSSoby Mathew 	plat_arm_interconnect_exit_coherency();
485955242d8SJeenu Viswambharan #else
486955242d8SJeenu Viswambharan 	unsigned int master;
487955242d8SJeenu Viswambharan 
488583e0791SAntonio Nino Diaz 	if ((arm_config.flags & (ARM_CONFIG_FVP_HAS_CCI400 |
489583e0791SAntonio Nino Diaz 				 ARM_CONFIG_FVP_HAS_CCI5XX)) != 0U) {
490955242d8SJeenu Viswambharan 		master = get_interconnect_master();
491955242d8SJeenu Viswambharan 		cci_disable_snoop_dvm_reqs(master);
492955242d8SJeenu Viswambharan 	}
493955242d8SJeenu Viswambharan #endif
4943e4b8fdcSSoby Mathew }
495ba597da7SJohn Tsichritzis 
49688c51c3fSManish V Badarkhe #if CRYPTO_SUPPORT
497ba597da7SJohn Tsichritzis int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
498ba597da7SJohn Tsichritzis {
499ba597da7SJohn Tsichritzis 	assert(heap_addr != NULL);
500ba597da7SJohn Tsichritzis 	assert(heap_size != NULL);
501ba597da7SJohn Tsichritzis 
502ba597da7SJohn Tsichritzis 	return arm_get_mbedtls_heap(heap_addr, heap_size);
503ba597da7SJohn Tsichritzis }
50488c51c3fSManish V Badarkhe #endif /* CRYPTO_SUPPORT */
5051b597c22SAlexei Fedorov 
5061b597c22SAlexei Fedorov void fvp_timer_init(void)
5071b597c22SAlexei Fedorov {
508fddfb3baSMadhukar Pappireddy #if USE_SP804_TIMER
5091b597c22SAlexei Fedorov 	/* Enable the clock override for SP804 timer 0, which means that no
5101b597c22SAlexei Fedorov 	 * clock dividers are applied and the raw (35MHz) clock will be used.
5111b597c22SAlexei Fedorov 	 */
5121b597c22SAlexei Fedorov 	mmio_write_32(V2M_SP810_BASE, FVP_SP810_CTRL_TIM0_OV);
5131b597c22SAlexei Fedorov 
5141b597c22SAlexei Fedorov 	/* Initialize delay timer driver using SP804 dual timer 0 */
5151b597c22SAlexei Fedorov 	sp804_timer_init(V2M_SP804_TIMER0_BASE,
5161b597c22SAlexei Fedorov 			SP804_TIMER_CLKMULT, SP804_TIMER_CLKDIV);
5171b597c22SAlexei Fedorov #else
5181b597c22SAlexei Fedorov 	generic_delay_timer_init();
5191b597c22SAlexei Fedorov 
5201b597c22SAlexei Fedorov 	/* Enable System level generic timer */
5211b597c22SAlexei Fedorov 	mmio_write_32(ARM_SYS_CNTCTL_BASE + CNTCR_OFF,
5221b597c22SAlexei Fedorov 			CNTCR_FCREQ(0U) | CNTCR_EN);
523fddfb3baSMadhukar Pappireddy #endif /* USE_SP804_TIMER */
5241b597c22SAlexei Fedorov }
525ed9653ffSManish V Badarkhe 
526ed9653ffSManish V Badarkhe /*****************************************************************************
527ed9653ffSManish V Badarkhe  * plat_is_smccc_feature_available() - This function checks whether SMCCC
528ed9653ffSManish V Badarkhe  *                                     feature is availabile for platform.
529ed9653ffSManish V Badarkhe  * @fid: SMCCC function id
530ed9653ffSManish V Badarkhe  *
531ed9653ffSManish V Badarkhe  * Return SMC_ARCH_CALL_SUCCESS if SMCCC feature is available and
532ed9653ffSManish V Badarkhe  * SMC_ARCH_CALL_NOT_SUPPORTED otherwise.
533ed9653ffSManish V Badarkhe  *****************************************************************************/
534ed9653ffSManish V Badarkhe int32_t plat_is_smccc_feature_available(u_register_t fid)
535ed9653ffSManish V Badarkhe {
536ed9653ffSManish V Badarkhe 	switch (fid) {
537ed9653ffSManish V Badarkhe 	case SMCCC_ARCH_SOC_ID:
538ed9653ffSManish V Badarkhe 		return SMC_ARCH_CALL_SUCCESS;
539ed9653ffSManish V Badarkhe 	default:
540ed9653ffSManish V Badarkhe 		return SMC_ARCH_CALL_NOT_SUPPORTED;
541ed9653ffSManish V Badarkhe 	}
542ed9653ffSManish V Badarkhe }
543ed9653ffSManish V Badarkhe 
544ed9653ffSManish V Badarkhe /* Get SOC version */
545ed9653ffSManish V Badarkhe int32_t plat_get_soc_version(void)
546ed9653ffSManish V Badarkhe {
547ed9653ffSManish V Badarkhe 	return (int32_t)
548dfff4686SYann Gautier 		(SOC_ID_SET_JEP_106(ARM_SOC_CONTINUATION_CODE,
549dfff4686SYann Gautier 				    ARM_SOC_IDENTIFICATION_CODE) |
550dfff4686SYann Gautier 		 (FVP_SOC_ID & SOC_ID_IMPL_DEF_MASK));
551ed9653ffSManish V Badarkhe }
552ed9653ffSManish V Badarkhe 
553ed9653ffSManish V Badarkhe /* Get SOC revision */
554ed9653ffSManish V Badarkhe int32_t plat_get_soc_revision(void)
555ed9653ffSManish V Badarkhe {
556ed9653ffSManish V Badarkhe 	unsigned int sys_id;
557ed9653ffSManish V Badarkhe 
558ed9653ffSManish V Badarkhe 	sys_id = mmio_read_32(V2M_SYSREGS_BASE + V2M_SYS_ID);
559dfff4686SYann Gautier 	return (int32_t)(((sys_id >> V2M_SYS_ID_REV_SHIFT) &
560dfff4686SYann Gautier 			  V2M_SYS_ID_REV_MASK) & SOC_ID_REV_MASK);
561ed9653ffSManish V Badarkhe }
5628c980a4aSJavier Almansa Sobrino 
5638c980a4aSJavier Almansa Sobrino #if ENABLE_RME
5648c980a4aSJavier Almansa Sobrino /*
5658c980a4aSJavier Almansa Sobrino  * Get a pointer to the RMM-EL3 Shared buffer and return it
5668c980a4aSJavier Almansa Sobrino  * through the pointer passed as parameter.
5678c980a4aSJavier Almansa Sobrino  *
5688c980a4aSJavier Almansa Sobrino  * This function returns the size of the shared buffer.
5698c980a4aSJavier Almansa Sobrino  */
5708c980a4aSJavier Almansa Sobrino size_t plat_rmmd_get_el3_rmm_shared_mem(uintptr_t *shared)
5718c980a4aSJavier Almansa Sobrino {
5728c980a4aSJavier Almansa Sobrino 	*shared = (uintptr_t)RMM_SHARED_BASE;
5738c980a4aSJavier Almansa Sobrino 
5748c980a4aSJavier Almansa Sobrino 	return (size_t)RMM_SHARED_SIZE;
5758c980a4aSJavier Almansa Sobrino }
5761d0ca40eSJavier Almansa Sobrino 
577aa99881dSAlexeiFedorov /*
578aa99881dSAlexeiFedorov  * Calculate checksum of 64-bit words @buffer with @size length
579aa99881dSAlexeiFedorov  */
580aa99881dSAlexeiFedorov static uint64_t checksum_calc(uint64_t *buffer, size_t size)
581aa99881dSAlexeiFedorov {
582aa99881dSAlexeiFedorov 	uint64_t sum = 0UL;
583aa99881dSAlexeiFedorov 
584aa99881dSAlexeiFedorov 	assert(((uintptr_t)buffer & (sizeof(uint64_t) - 1UL)) == 0UL);
585aa99881dSAlexeiFedorov 	assert((size & (sizeof(uint64_t) - 1UL)) == 0UL);
586aa99881dSAlexeiFedorov 
587aa99881dSAlexeiFedorov 	for (unsigned long i = 0UL; i < (size / sizeof(uint64_t)); i++) {
588aa99881dSAlexeiFedorov 		sum += buffer[i];
589aa99881dSAlexeiFedorov 	}
590aa99881dSAlexeiFedorov 
591aa99881dSAlexeiFedorov 	return sum;
592aa99881dSAlexeiFedorov }
593bef44f60SAlexeiFedorov /*
594bef44f60SAlexeiFedorov  * Boot Manifest structure illustration, with two DRAM banks,
595bef44f60SAlexeiFedorov  * a single console and one device memory with two PCIe device
596bef44f60SAlexeiFedorov  * non-coherent address ranges.
597bef44f60SAlexeiFedorov  *
598bef44f60SAlexeiFedorov  * +--------------------------------------------------+
599bef44f60SAlexeiFedorov  * | offset |        field       |      comment       |
600bef44f60SAlexeiFedorov  * +--------+--------------------+--------------------+
601bef44f60SAlexeiFedorov  * |   0    |       version      |     0x00000004     |
602bef44f60SAlexeiFedorov  * +--------+--------------------+--------------------+
603bef44f60SAlexeiFedorov  * |   4    |       padding      |     0x00000000     |
604bef44f60SAlexeiFedorov  * +--------+--------------------+--------------------+
605bef44f60SAlexeiFedorov  * |   8    |      plat_data     |       NULL         |
606bef44f60SAlexeiFedorov  * +--------+--------------------+--------------------+
607bef44f60SAlexeiFedorov  * |   16   |      num_banks     |                    |
608bef44f60SAlexeiFedorov  * +--------+--------------------+                    |
609bef44f60SAlexeiFedorov  * |   24   |       banks        |     plat_dram      +--+
610bef44f60SAlexeiFedorov  * +--------+--------------------+                    |  |
611bef44f60SAlexeiFedorov  * |   32   |      checksum      |                    |  |
612bef44f60SAlexeiFedorov  * +--------+--------------------+--------------------+  |
613bef44f60SAlexeiFedorov  * |   40   |    num_consoles    |                    |  |
614bef44f60SAlexeiFedorov  * +--------+--------------------+                    |  |
615bef44f60SAlexeiFedorov  * |   48   |      consoles      |    plat_console    +--|--+
616bef44f60SAlexeiFedorov  * +--------+--------------------+                    |  |  |
617bef44f60SAlexeiFedorov  * |   56   |      checksum      |                    |  |  |
618bef44f60SAlexeiFedorov  * +--------+--------------------+--------------------+  |  |
619bef44f60SAlexeiFedorov  * |   64   |      num_banks     |                    |  |  |
620bef44f60SAlexeiFedorov  * +--------+--------------------+                    |  |  |
621bef44f60SAlexeiFedorov  * |   72   |        banks       |  plat_ncoh_region  +--|--|--+
622bef44f60SAlexeiFedorov  * +--------+--------------------+                    |  |  |  |
623bef44f60SAlexeiFedorov  * |   80   |      checksum      |                    |  |  |  |
624bef44f60SAlexeiFedorov  * +--------+--------------------+--------------------+  |  |  |
625bef44f60SAlexeiFedorov  * |   88   |      num_banks     |                    |  |  |  |
626bef44f60SAlexeiFedorov  * +--------+--------------------+                    |  |  |  |
627bef44f60SAlexeiFedorov  * |   96   |       banks        |   plat_coh_region  |  |  |  |
628bef44f60SAlexeiFedorov  * +--------+--------------------+                    |  |  |  |
629bef44f60SAlexeiFedorov  * |   104  |      checksum      |                    |  |  |  |
630bef44f60SAlexeiFedorov  * +--------+--------------------+--------------------+<-+  |  |
631bef44f60SAlexeiFedorov  * |   112  |       base 0       |                    |     |  |
632bef44f60SAlexeiFedorov  * +--------+--------------------+     mem_bank[0]    |     |  |
633bef44f60SAlexeiFedorov  * |   120  |       size 0       |                    |     |  |
634bef44f60SAlexeiFedorov  * +--------+--------------------+--------------------+     |  |
635bef44f60SAlexeiFedorov  * |   128  |       base 1       |                    |     |  |
636bef44f60SAlexeiFedorov  * +--------+--------------------+     mem_bank[1]    |     |  |
637bef44f60SAlexeiFedorov  * |   136  |       size 1       |                    |     |  |
638bef44f60SAlexeiFedorov  * +--------+--------------------+--------------------+<----+  |
639bef44f60SAlexeiFedorov  * |   144  |       base         |                    |        |
640bef44f60SAlexeiFedorov  * +--------+--------------------+                    |        |
641bef44f60SAlexeiFedorov  * |   152  |      map_pages     |                    |        |
642bef44f60SAlexeiFedorov  * +--------+--------------------+                    |        |
643bef44f60SAlexeiFedorov  * |   160  |       name         |                    |        |
644bef44f60SAlexeiFedorov  * +--------+--------------------+     consoles[0]    |        |
645bef44f60SAlexeiFedorov  * |   168  |     clk_in_hz      |                    |        |
646bef44f60SAlexeiFedorov  * +--------+--------------------+                    |        |
647bef44f60SAlexeiFedorov  * |   176  |     baud_rate      |                    |        |
648bef44f60SAlexeiFedorov  * +--------+--------------------+                    |        |
649bef44f60SAlexeiFedorov  * |   184  |       flags        |                    |        |
650bef44f60SAlexeiFedorov  * +--------+--------------------+--------------------+<-------+
651bef44f60SAlexeiFedorov  * |   192  |       base 0       |                    |
652bef44f60SAlexeiFedorov  * +--------+--------------------+   ncoh_region[0]   |
653bef44f60SAlexeiFedorov  * |   200  |       size 0       |                    |
654bef44f60SAlexeiFedorov  * +--------+--------------------+--------------------+
655bef44f60SAlexeiFedorov  * |   208  |       base 1       |                    |
656bef44f60SAlexeiFedorov  * +--------+--------------------+   ncoh_region[1]   |
657bef44f60SAlexeiFedorov  * |   216  |       size 1       |                    |
658bef44f60SAlexeiFedorov  * +--------+--------------------+--------------------+
659bef44f60SAlexeiFedorov  */
660a97bfa5fSAlexeiFedorov int plat_rmmd_load_manifest(struct rmm_manifest *manifest)
6611d0ca40eSJavier Almansa Sobrino {
66232904472SSoby Mathew 	uint64_t checksum, num_banks, num_consoles;
663bef44f60SAlexeiFedorov 	uint64_t num_ncoh_regions, num_coh_regions;
664bef44f60SAlexeiFedorov 	struct memory_bank *bank_ptr, *ncoh_region_ptr;
66532904472SSoby Mathew 	struct console_info *console_ptr;
666a97bfa5fSAlexeiFedorov 
6671d0ca40eSJavier Almansa Sobrino 	assert(manifest != NULL);
6681d0ca40eSJavier Almansa Sobrino 
66982685904SAlexeiFedorov 	/* Get number of DRAM banks */
67082685904SAlexeiFedorov 	num_banks = FCONF_GET_PROPERTY(hw_config, dram_layout, num_banks);
67182685904SAlexeiFedorov 	assert(num_banks <= ARM_DRAM_NUM_BANKS);
67282685904SAlexeiFedorov 
67332904472SSoby Mathew 	/* Set number of consoles */
67432904472SSoby Mathew 	num_consoles = FVP_RMM_CONSOLE_COUNT;
67532904472SSoby Mathew 
676bef44f60SAlexeiFedorov 	/* Set number of device non-coherent address ranges based on DT */
677bef44f60SAlexeiFedorov 	num_ncoh_regions = FCONF_GET_PROPERTY(hw_config, pci_props, num_ncoh_regions);
678bef44f60SAlexeiFedorov 
6791d0ca40eSJavier Almansa Sobrino 	manifest->version = RMMD_MANIFEST_VERSION;
680dc0ca64eSJavier Almansa Sobrino 	manifest->padding = 0U; /* RES0 */
681bef44f60SAlexeiFedorov 	manifest->plat_data = 0UL;
68282685904SAlexeiFedorov 	manifest->plat_dram.num_banks = num_banks;
68332904472SSoby Mathew 	manifest->plat_console.num_consoles = num_consoles;
684bef44f60SAlexeiFedorov 	manifest->plat_ncoh_region.num_banks = num_ncoh_regions;
685a97bfa5fSAlexeiFedorov 
686bef44f60SAlexeiFedorov 	/* FVP does not support device coherent address ranges */
687bef44f60SAlexeiFedorov 	num_coh_regions = 0UL;
688bef44f60SAlexeiFedorov 	manifest->plat_coh_region.num_banks = num_coh_regions;
689bef44f60SAlexeiFedorov 	manifest->plat_coh_region.banks = NULL;
690bef44f60SAlexeiFedorov 	manifest->plat_coh_region.checksum = 0UL;
69132904472SSoby Mathew 
692bef44f60SAlexeiFedorov 	bank_ptr = (struct memory_bank *)
693bef44f60SAlexeiFedorov 			(((uintptr_t)manifest) + sizeof(struct rmm_manifest));
69432904472SSoby Mathew 	console_ptr = (struct console_info *)
695bef44f60SAlexeiFedorov 			((uintptr_t)bank_ptr + (num_banks *
696bef44f60SAlexeiFedorov 						sizeof(struct memory_bank)));
697bef44f60SAlexeiFedorov 	ncoh_region_ptr = (struct memory_bank *)
698bef44f60SAlexeiFedorov 			((uintptr_t)console_ptr + (num_consoles *
699bef44f60SAlexeiFedorov 						sizeof(struct console_info)));
70082685904SAlexeiFedorov 	manifest->plat_dram.banks = bank_ptr;
70132904472SSoby Mathew 	manifest->plat_console.consoles = console_ptr;
702bef44f60SAlexeiFedorov 	manifest->plat_ncoh_region.banks = ncoh_region_ptr;
70332904472SSoby Mathew 
70432904472SSoby Mathew 	/* Ensure the manifest is not larger than the shared buffer */
70532904472SSoby Mathew 	assert((sizeof(struct rmm_manifest) +
706bef44f60SAlexeiFedorov 		(sizeof(struct memory_bank) *
707bef44f60SAlexeiFedorov 			manifest->plat_dram.num_banks) +
708bef44f60SAlexeiFedorov 		(sizeof(struct console_info) *
709bef44f60SAlexeiFedorov 			manifest->plat_console.num_consoles) +
710bef44f60SAlexeiFedorov 		(sizeof(struct memory_bank) *
711bef44f60SAlexeiFedorov 			manifest->plat_ncoh_region.num_banks) +
712bef44f60SAlexeiFedorov 		(sizeof(struct memory_bank) *
713bef44f60SAlexeiFedorov 			manifest->plat_coh_region.num_banks))
714bef44f60SAlexeiFedorov 		<= ARM_EL3_RMM_SHARED_SIZE);
715a97bfa5fSAlexeiFedorov 
716a97bfa5fSAlexeiFedorov 	/* Calculate checksum of plat_dram structure */
71782685904SAlexeiFedorov 	checksum = num_banks + (uint64_t)bank_ptr;
718a97bfa5fSAlexeiFedorov 
71982685904SAlexeiFedorov 	/* Store FVP DRAM banks data in Boot Manifest */
72082685904SAlexeiFedorov 	for (unsigned long i = 0UL; i < num_banks; i++) {
721aa99881dSAlexeiFedorov 		bank_ptr[i].base = FCONF_GET_PROPERTY(hw_config, dram_layout, dram_bank[i].base);
722aa99881dSAlexeiFedorov 		bank_ptr[i].size = FCONF_GET_PROPERTY(hw_config, dram_layout, dram_bank[i].size);
723aa99881dSAlexeiFedorov 	}
72482685904SAlexeiFedorov 
72582685904SAlexeiFedorov 	/* Update checksum */
726bef44f60SAlexeiFedorov 	checksum += checksum_calc((uint64_t *)bank_ptr, sizeof(struct memory_bank) * num_banks);
727a97bfa5fSAlexeiFedorov 
728a97bfa5fSAlexeiFedorov 	/* Checksum must be 0 */
72982685904SAlexeiFedorov 	manifest->plat_dram.checksum = ~checksum + 1UL;
7301d0ca40eSJavier Almansa Sobrino 
731bef44f60SAlexeiFedorov 	/* Calculate the checksum of plat_consoles structure */
73232904472SSoby Mathew 	checksum = num_consoles + (uint64_t)console_ptr;
73332904472SSoby Mathew 
73432904472SSoby Mathew 	/* Zero out the console info struct */
735bef44f60SAlexeiFedorov 	(void)memset((void *)console_ptr, '\0',
736bef44f60SAlexeiFedorov 			sizeof(struct console_info) * num_consoles);
73732904472SSoby Mathew 
73832904472SSoby Mathew 	console_ptr[0].base = FVP_RMM_CONSOLE_BASE;
739aa99881dSAlexeiFedorov 	console_ptr[0].map_pages = 1UL;
74032904472SSoby Mathew 	console_ptr[0].clk_in_hz = FVP_RMM_CONSOLE_CLK_IN_HZ;
74132904472SSoby Mathew 	console_ptr[0].baud_rate = FVP_RMM_CONSOLE_BAUD;
74232904472SSoby Mathew 
743bef44f60SAlexeiFedorov 	(void)strlcpy(console_ptr[0].name, FVP_RMM_CONSOLE_NAME,
744bef44f60SAlexeiFedorov 						RMM_CONSOLE_MAX_NAME_LEN - 1UL);
74532904472SSoby Mathew 
74632904472SSoby Mathew 	/* Update checksum */
747aa99881dSAlexeiFedorov 	checksum += checksum_calc((uint64_t *)console_ptr,
748aa99881dSAlexeiFedorov 					sizeof(struct console_info) * num_consoles);
74932904472SSoby Mathew 	/* Checksum must be 0 */
75032904472SSoby Mathew 	manifest->plat_console.checksum = ~checksum + 1UL;
75132904472SSoby Mathew 
752bef44f60SAlexeiFedorov 	/*
753bef44f60SAlexeiFedorov 	 * Calculate the checksum of device non-coherent address ranges
754bef44f60SAlexeiFedorov 	 * info structure
755bef44f60SAlexeiFedorov 	 */
756bef44f60SAlexeiFedorov 	checksum = num_ncoh_regions + (uint64_t)ncoh_region_ptr;
757bef44f60SAlexeiFedorov 
758bef44f60SAlexeiFedorov 	/* Zero out the PCIe region info struct */
759bef44f60SAlexeiFedorov 	(void)memset((void *)ncoh_region_ptr, 0,
760bef44f60SAlexeiFedorov 			sizeof(struct memory_bank) * num_ncoh_regions);
761bef44f60SAlexeiFedorov 
762bef44f60SAlexeiFedorov 	for (unsigned long i = 0UL; i < num_ncoh_regions; i++) {
763bef44f60SAlexeiFedorov 		ncoh_region_ptr[i].base =
764bef44f60SAlexeiFedorov 			FCONF_GET_PROPERTY(hw_config, pci_props, ncoh_regions[i].base);
765bef44f60SAlexeiFedorov 		ncoh_region_ptr[i].size =
766bef44f60SAlexeiFedorov 			FCONF_GET_PROPERTY(hw_config, pci_props, ncoh_regions[i].size);
767bef44f60SAlexeiFedorov 	}
768bef44f60SAlexeiFedorov 
769bef44f60SAlexeiFedorov 	/* Update checksum */
770bef44f60SAlexeiFedorov 	checksum += checksum_calc((uint64_t *)ncoh_region_ptr,
771bef44f60SAlexeiFedorov 			sizeof(struct memory_bank) * num_ncoh_regions);
772bef44f60SAlexeiFedorov 
773bef44f60SAlexeiFedorov 	/* Checksum must be 0 */
774bef44f60SAlexeiFedorov 	manifest->plat_ncoh_region.checksum = ~checksum + 1UL;
775bef44f60SAlexeiFedorov 
7761d0ca40eSJavier Almansa Sobrino 	return 0;
7771d0ca40eSJavier Almansa Sobrino }
778a97bfa5fSAlexeiFedorov #endif	/* ENABLE_RME */
779