fvp_common.c 13.1 KB
Newer Older
1
/*
2
 * Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved.
3
 *
dp-arm's avatar
dp-arm committed
4
 * SPDX-License-Identifier: BSD-3-Clause
5
6
 */

7
8
9
10
11
12
#include <assert.h>

#include <common/debug.h>
#include <drivers/arm/cci.h>
#include <drivers/arm/ccn.h>
#include <drivers/arm/gicv2.h>
13
14
#include <drivers/arm/sp804_delay_timer.h>
#include <drivers/generic_delay_timer.h>
15
#include <lib/mmio.h>
16
#include <lib/smccc.h>
17
#include <lib/xlat_tables/xlat_tables_compat.h>
18
#include <platform_def.h>
19
#include <services/arm_arch_svc.h>
20
#if SPM_MM
21
#include <services/spm_mm_partition.h>
22
#endif
23

24
25
26
27
#include <plat/arm/common/arm_config.h>
#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>

Roberto Vargas's avatar
Roberto Vargas committed
28
#include "fvp_private.h"
29

30
31
32
33
/* Defines for GIC Driver build time selection */
#define FVP_GICV2		1
#define FVP_GICV3		2

34
/*******************************************************************************
35
36
 * arm_config holds the characteristics of the differences between the three FVP
 * platforms (Base, A53_A57 & Foundation). It will be populated during cold boot
37
38
39
 * at each boot stage by the primary before enabling the MMU (to allow
 * interconnect configuration) & used thereafter. Each BL will have its own copy
 * to allow independent operation.
40
 ******************************************************************************/
41
arm_config_t arm_config;
42
43
44
45
46
47
48
49
50

#define MAP_DEVICE0	MAP_REGION_FLAT(DEVICE0_BASE,			\
					DEVICE0_SIZE,			\
					MT_DEVICE | MT_RW | MT_SECURE)

#define MAP_DEVICE1	MAP_REGION_FLAT(DEVICE1_BASE,			\
					DEVICE1_SIZE,			\
					MT_DEVICE | MT_RW | MT_SECURE)

51
52
53
54
55
56
57
58
59
60
61
62
#if FVP_GICR_REGION_PROTECTION
#define MAP_GICD_MEM	MAP_REGION_FLAT(BASE_GICD_BASE,			\
					BASE_GICD_SIZE,			\
					MT_DEVICE | MT_RW | MT_SECURE)

/* Map all core's redistributor memory as read-only. After boots up,
 * per-core map its redistributor memory as read-write */
#define MAP_GICR_MEM	MAP_REGION_FLAT(BASE_GICR_BASE,			\
					(BASE_GICR_SIZE * PLATFORM_CORE_COUNT),\
					MT_DEVICE | MT_RO | MT_SECURE)
#endif /* FVP_GICR_REGION_PROTECTION */

63
64
65
66
/*
 * Need to be mapped with write permissions in order to set a new non-volatile
 * counter value.
 */
67
68
#define MAP_DEVICE2	MAP_REGION_FLAT(DEVICE2_BASE,			\
					DEVICE2_SIZE,			\
69
					MT_DEVICE | MT_RW | MT_SECURE)
70

71
/*
72
 * Table of memory regions for various BL stages to map using the MMU.
73
74
 * This doesn't include Trusted SRAM as setup_page_tables() already takes care
 * of mapping it.
75
76
77
 *
 * The flash needs to be mapped as writable in order to erase the FIP's Table of
 * Contents in case of unrecoverable error (see plat_error_handler()).
78
 */
79
#ifdef IMAGE_BL1
80
81
const mmap_region_t plat_arm_mmap[] = {
	ARM_MAP_SHARED_RAM,
82
	V2M_MAP_FLASH0_RW,
83
	V2M_MAP_IOFPGA,
84
	MAP_DEVICE0,
85
#if FVP_INTERCONNECT_DRIVER == FVP_CCN
86
	MAP_DEVICE1,
87
#endif
88
#if TRUSTED_BOARD_BOOT
89
90
91
	/* To access the Root of Trust Public Key registers. */
	MAP_DEVICE2,
	/* Map DRAM to authenticate NS_BL2U image. */
92
93
	ARM_MAP_NS_DRAM1,
#endif
94
95
96
	{0}
};
#endif
97
#ifdef IMAGE_BL2
98
99
const mmap_region_t plat_arm_mmap[] = {
	ARM_MAP_SHARED_RAM,
100
	V2M_MAP_FLASH0_RW,
101
	V2M_MAP_IOFPGA,
102
	MAP_DEVICE0,
103
#if FVP_INTERCONNECT_DRIVER == FVP_CCN
104
	MAP_DEVICE1,
105
#endif
106
	ARM_MAP_NS_DRAM1,
107
#ifdef __aarch64__
108
109
	ARM_MAP_DRAM2,
#endif
110
111
112
#if defined(SPD_spmd)
	ARM_MAP_TRUSTED_DRAM,
#endif
johpow01's avatar
johpow01 committed
113
114
115
116
#if ENABLE_RME
	ARM_MAP_RMM_DRAM,
	ARM_MAP_GPT_L1_DRAM,
#endif /* ENABLE_RME */
117
#ifdef SPD_tspd
118
	ARM_MAP_TSP_SEC_MEM,
119
#endif
120
121
122
#if TRUSTED_BOARD_BOOT
	/* To access the Root of Trust Public Key registers. */
	MAP_DEVICE2,
123
#if !BL2_AT_EL3
124
	ARM_MAP_BL1_RW,
125
#endif
126
#endif /* TRUSTED_BOARD_BOOT */
127
#if SPM_MM
128
129
	ARM_SP_IMAGE_MMAP,
#endif
David Wang's avatar
David Wang committed
130
131
#if ARM_BL31_IN_DRAM
	ARM_MAP_BL31_SEC_DRAM,
132
133
#endif
#ifdef SPD_opteed
134
	ARM_MAP_OPTEE_CORE_MEM,
135
	ARM_OPTEE_PAGEABLE_LOAD_MEM,
David Wang's avatar
David Wang committed
136
#endif
137
138
139
	{0}
};
#endif
140
#ifdef IMAGE_BL2U
141
142
143
144
145
146
const mmap_region_t plat_arm_mmap[] = {
	MAP_DEVICE0,
	V2M_MAP_IOFPGA,
	{0}
};
#endif
147
#ifdef IMAGE_BL31
148
149
const mmap_region_t plat_arm_mmap[] = {
	ARM_MAP_SHARED_RAM,
Ambroise Vincent's avatar
Ambroise Vincent committed
150
151
152
153
#if USE_DEBUGFS
	/* Required by devfip, can be removed if devfip is not used */
	V2M_MAP_FLASH0_RW,
#endif /* USE_DEBUGFS */
154
	ARM_MAP_EL3_TZC_DRAM,
155
	V2M_MAP_IOFPGA,
156
	MAP_DEVICE0,
157
158
159
160
#if FVP_GICR_REGION_PROTECTION
	MAP_GICD_MEM,
	MAP_GICR_MEM,
#else
161
	MAP_DEVICE1,
162
#endif /* FVP_GICR_REGION_PROTECTION */
163
	ARM_V2M_MAP_MEM_PROTECT,
164
#if SPM_MM
165
166
	ARM_SPM_BUF_EL3_MMAP,
#endif
167
	/* Required by fconf APIs to read HW_CONFIG dtb loaded into DRAM */
168
	ARM_DTB_DRAM_NS,
johpow01's avatar
johpow01 committed
169
170
171
#if ENABLE_RME
	ARM_MAP_GPT_L1_DRAM,
#endif
172
173
174
	{0}
};

175
#if defined(IMAGE_BL31) && SPM_MM
176
177
const mmap_region_t plat_arm_secure_partition_mmap[] = {
	V2M_MAP_IOFPGA_EL0, /* for the UART */
178
179
180
	MAP_REGION_FLAT(DEVICE0_BASE,				\
			DEVICE0_SIZE,				\
			MT_DEVICE | MT_RO | MT_SECURE | MT_USER),
181
182
183
184
	ARM_SP_IMAGE_MMAP,
	ARM_SP_IMAGE_NS_BUF_MMAP,
	ARM_SP_IMAGE_RW_MMAP,
	ARM_SPM_BUF_EL0_MMAP,
185
186
187
	{0}
};
#endif
188
#endif
189
#ifdef IMAGE_BL32
190
const mmap_region_t plat_arm_mmap[] = {
191
#ifndef __aarch64__
192
	ARM_MAP_SHARED_RAM,
193
	ARM_V2M_MAP_MEM_PROTECT,
194
#endif
195
	V2M_MAP_IOFPGA,
196
197
	MAP_DEVICE0,
	MAP_DEVICE1,
198
	/* Required by fconf APIs to read HW_CONFIG dtb loaded into DRAM */
199
	ARM_DTB_DRAM_NS,
200
201
	{0}
};
202
#endif
203

204
ARM_CASSERT_MMAP
205

206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
#if FVP_INTERCONNECT_DRIVER != FVP_CCN
static const int fvp_cci400_map[] = {
	PLAT_FVP_CCI400_CLUS0_SL_PORT,
	PLAT_FVP_CCI400_CLUS1_SL_PORT,
};

static const int fvp_cci5xx_map[] = {
	PLAT_FVP_CCI5XX_CLUS0_SL_PORT,
	PLAT_FVP_CCI5XX_CLUS1_SL_PORT,
};

static unsigned int get_interconnect_master(void)
{
	unsigned int master;
	u_register_t mpidr;

	mpidr = read_mpidr_el1();
223
	master = ((arm_config.flags & ARM_CONFIG_FVP_SHIFTED_AFF) != 0U) ?
224
225
226
227
228
229
		MPIDR_AFFLVL2_VAL(mpidr) : MPIDR_AFFLVL1_VAL(mpidr);

	assert(master < FVP_CLUSTER_COUNT);
	return master;
}
#endif
230

231
#if defined(IMAGE_BL31) && SPM_MM
232
233
234
235
/*
 * Boot information passed to a secure partition during initialisation. Linear
 * indices in MP information will be filled at runtime.
 */
236
static spm_mm_mp_info_t sp_mp_info[] = {
237
238
239
240
241
242
243
244
245
246
	[0] = {0x80000000, 0},
	[1] = {0x80000001, 0},
	[2] = {0x80000002, 0},
	[3] = {0x80000003, 0},
	[4] = {0x80000100, 0},
	[5] = {0x80000101, 0},
	[6] = {0x80000102, 0},
	[7] = {0x80000103, 0},
};

247
const spm_mm_boot_info_t plat_arm_secure_partition_boot_info = {
248
249
	.h.type              = PARAM_SP_IMAGE_BOOT_INFO,
	.h.version           = VERSION_1,
250
	.h.size              = sizeof(spm_mm_boot_info_t),
251
252
253
254
255
256
	.h.attr              = 0,
	.sp_mem_base         = ARM_SP_IMAGE_BASE,
	.sp_mem_limit        = ARM_SP_IMAGE_LIMIT,
	.sp_image_base       = ARM_SP_IMAGE_BASE,
	.sp_stack_base       = PLAT_SP_IMAGE_STACK_BASE,
	.sp_heap_base        = ARM_SP_IMAGE_HEAP_BASE,
257
	.sp_ns_comm_buf_base = PLAT_SP_IMAGE_NS_BUF_BASE,
258
259
260
261
	.sp_shared_buf_base  = PLAT_SPM_BUF_BASE,
	.sp_image_size       = ARM_SP_IMAGE_SIZE,
	.sp_pcpu_stack_size  = PLAT_SP_IMAGE_STACK_PCPU_SIZE,
	.sp_heap_size        = ARM_SP_IMAGE_HEAP_SIZE,
262
	.sp_ns_comm_buf_size = PLAT_SP_IMAGE_NS_BUF_SIZE,
263
264
265
266
267
268
269
270
271
272
273
	.sp_shared_buf_size  = PLAT_SPM_BUF_SIZE,
	.num_sp_mem_regions  = ARM_SP_IMAGE_NUM_MEM_REGIONS,
	.num_cpus            = PLATFORM_CORE_COUNT,
	.mp_info             = &sp_mp_info[0],
};

const struct mmap_region *plat_get_secure_partition_mmap(void *cookie)
{
	return plat_arm_secure_partition_mmap;
}

274
const struct spm_mm_boot_info *plat_get_secure_partition_boot_info(
275
276
277
278
279
280
		void *cookie)
{
	return &plat_arm_secure_partition_boot_info;
}
#endif

281
282
283
284
285
286
287
/*******************************************************************************
 * A single boot loader stack is expected to work on both the Foundation FVP
 * models and the two flavours of the Base FVP models (AEMv8 & Cortex). The
 * SYS_ID register provides a mechanism for detecting the differences between
 * these platforms. This information is stored in a per-BL array to allow the
 * code to take the correct path.Per BL platform configuration.
 ******************************************************************************/
288
void __init fvp_config_setup(void)
289
{
290
	unsigned int rev, hbi, bld, arch, sys_id;
291

292
293
294
295
296
	sys_id = mmio_read_32(V2M_SYSREGS_BASE + V2M_SYS_ID);
	rev = (sys_id >> V2M_SYS_ID_REV_SHIFT) & V2M_SYS_ID_REV_MASK;
	hbi = (sys_id >> V2M_SYS_ID_HBI_SHIFT) & V2M_SYS_ID_HBI_MASK;
	bld = (sys_id >> V2M_SYS_ID_BLD_SHIFT) & V2M_SYS_ID_BLD_MASK;
	arch = (sys_id >> V2M_SYS_ID_ARCH_SHIFT) & V2M_SYS_ID_ARCH_MASK;
297

298
299
	if (arch != ARCH_MODEL) {
		ERROR("This firmware is for FVP models\n");
300
		panic();
301
	}
302
303
304
305
306
307
308

	/*
	 * The build field in the SYS_ID tells which variant of the GIC
	 * memory is implemented by the model.
	 */
	switch (bld) {
	case BLD_GIC_VE_MMAP:
309
310
		ERROR("Legacy Versatile Express memory map for GIC peripheral"
				" is not supported\n");
311
		panic();
312
313
314
315
		break;
	case BLD_GIC_A53A57_MMAP:
		break;
	default:
316
317
		ERROR("Unsupported board build %x\n", bld);
		panic();
318
319
320
321
322
323
324
	}

	/*
	 * The hbi field in the SYS_ID is 0x020 for the Base FVP & 0x010
	 * for the Foundation FVP.
	 */
	switch (hbi) {
325
326
	case HBI_FOUNDATION_FVP:
		arm_config.flags = 0;
327
328
329
330
331
332

		/*
		 * Check for supported revisions of Foundation FVP
		 * Allow future revisions to run but emit warning diagnostic
		 */
		switch (rev) {
333
334
335
		case REV_FOUNDATION_FVP_V2_0:
		case REV_FOUNDATION_FVP_V2_1:
		case REV_FOUNDATION_FVP_v9_1:
336
		case REV_FOUNDATION_FVP_v9_6:
337
338
339
340
341
			break;
		default:
			WARN("Unrecognized Foundation FVP revision %x\n", rev);
			break;
		}
342
		break;
343
	case HBI_BASE_FVP:
344
		arm_config.flags |= (ARM_CONFIG_BASE_MMAP | ARM_CONFIG_HAS_TZC);
345
346
347
348
349
350

		/*
		 * Check for supported revisions
		 * Allow future revisions to run but emit warning diagnostic
		 */
		switch (rev) {
351
		case REV_BASE_FVP_V0:
352
353
354
			arm_config.flags |= ARM_CONFIG_FVP_HAS_CCI400;
			break;
		case REV_BASE_FVP_REVC:
355
			arm_config.flags |= (ARM_CONFIG_FVP_HAS_SMMUV3 |
356
					ARM_CONFIG_FVP_HAS_CCI5XX);
357
358
359
360
361
			break;
		default:
			WARN("Unrecognized Base FVP revision %x\n", rev);
			break;
		}
362
363
		break;
	default:
364
365
		ERROR("Unsupported board HBI number 0x%x\n", hbi);
		panic();
366
	}
367
368
369
370
371
372

	/*
	 * We assume that the presence of MT bit, and therefore shifted
	 * affinities, is uniform across the platform: either all CPUs, or no
	 * CPUs implement it.
	 */
373
	if ((read_mpidr_el1() & MPIDR_MT_MASK) != 0U)
374
		arm_config.flags |= ARM_CONFIG_FVP_SHIFTED_AFF;
375
}
376

377

378
void __init fvp_interconnect_init(void)
379
{
380
#if FVP_INTERCONNECT_DRIVER == FVP_CCN
381
	if (ccn_get_part0_id(PLAT_ARM_CCN_BASE) != CCN_502_PART0_ID) {
382
		ERROR("Unrecognized CCN variant detected. Only CCN-502 is supported");
383
384
385
386
387
		panic();
	}

	plat_arm_interconnect_init();
#else
388
389
390
	uintptr_t cci_base = 0U;
	const int *cci_map = NULL;
	unsigned int map_size = 0U;
391
392

	/* Initialize the right interconnect */
393
	if ((arm_config.flags & ARM_CONFIG_FVP_HAS_CCI5XX) != 0U) {
394
395
396
		cci_base = PLAT_FVP_CCI5XX_BASE;
		cci_map = fvp_cci5xx_map;
		map_size = ARRAY_SIZE(fvp_cci5xx_map);
397
	} else if ((arm_config.flags & ARM_CONFIG_FVP_HAS_CCI400) != 0U) {
398
399
400
		cci_base = PLAT_FVP_CCI400_BASE;
		cci_map = fvp_cci400_map;
		map_size = ARRAY_SIZE(fvp_cci400_map);
401
402
	} else {
		return;
403
	}
404

405
406
	assert(cci_base != 0U);
	assert(cci_map != NULL);
407
408
	cci_init(cci_base, cci_map, map_size);
#endif
409
410
}

411
void fvp_interconnect_enable(void)
412
{
413
414
415
416
417
#if FVP_INTERCONNECT_DRIVER == FVP_CCN
	plat_arm_interconnect_enter_coherency();
#else
	unsigned int master;

418
419
	if ((arm_config.flags & (ARM_CONFIG_FVP_HAS_CCI400 |
				 ARM_CONFIG_FVP_HAS_CCI5XX)) != 0U) {
420
421
422
423
		master = get_interconnect_master();
		cci_enable_snoop_dvm_reqs(master);
	}
#endif
424
425
}

426
void fvp_interconnect_disable(void)
427
{
428
429
430
431
432
#if FVP_INTERCONNECT_DRIVER == FVP_CCN
	plat_arm_interconnect_exit_coherency();
#else
	unsigned int master;

433
434
	if ((arm_config.flags & (ARM_CONFIG_FVP_HAS_CCI400 |
				 ARM_CONFIG_FVP_HAS_CCI5XX)) != 0U) {
435
436
437
438
		master = get_interconnect_master();
		cci_disable_snoop_dvm_reqs(master);
	}
#endif
439
}
440

441
#if TRUSTED_BOARD_BOOT
442
443
444
445
446
447
448
449
int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
{
	assert(heap_addr != NULL);
	assert(heap_size != NULL);

	return arm_get_mbedtls_heap(heap_addr, heap_size);
}
#endif
450
451
452

void fvp_timer_init(void)
{
453
#if USE_SP804_TIMER
454
455
456
457
458
459
460
461
462
463
464
465
466
467
	/* Enable the clock override for SP804 timer 0, which means that no
	 * clock dividers are applied and the raw (35MHz) clock will be used.
	 */
	mmio_write_32(V2M_SP810_BASE, FVP_SP810_CTRL_TIM0_OV);

	/* Initialize delay timer driver using SP804 dual timer 0 */
	sp804_timer_init(V2M_SP804_TIMER0_BASE,
			SP804_TIMER_CLKMULT, SP804_TIMER_CLKDIV);
#else
	generic_delay_timer_init();

	/* Enable System level generic timer */
	mmio_write_32(ARM_SYS_CNTCTL_BASE + CNTCR_OFF,
			CNTCR_FCREQ(0U) | CNTCR_EN);
468
#endif /* USE_SP804_TIMER */
469
}
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506

/*****************************************************************************
 * plat_is_smccc_feature_available() - This function checks whether SMCCC
 *                                     feature is availabile for platform.
 * @fid: SMCCC function id
 *
 * Return SMC_ARCH_CALL_SUCCESS if SMCCC feature is available and
 * SMC_ARCH_CALL_NOT_SUPPORTED otherwise.
 *****************************************************************************/
int32_t plat_is_smccc_feature_available(u_register_t fid)
{
	switch (fid) {
	case SMCCC_ARCH_SOC_ID:
		return SMC_ARCH_CALL_SUCCESS;
	default:
		return SMC_ARCH_CALL_NOT_SUPPORTED;
	}
}

/* Get SOC version */
int32_t plat_get_soc_version(void)
{
	return (int32_t)
		((ARM_SOC_IDENTIFICATION_CODE << ARM_SOC_IDENTIFICATION_SHIFT)
		 | (ARM_SOC_CONTINUATION_CODE << ARM_SOC_CONTINUATION_SHIFT)
		 | FVP_SOC_ID);
}

/* Get SOC revision */
int32_t plat_get_soc_revision(void)
{
	unsigned int sys_id;

	sys_id = mmio_read_32(V2M_SYSREGS_BASE + V2M_SYS_ID);
	return (int32_t)((sys_id >> V2M_SYS_ID_REV_SHIFT) &
			V2M_SYS_ID_REV_MASK);
}