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