fvp_common.c 13 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
113
#ifdef SPD_tspd
114
	ARM_MAP_TSP_SEC_MEM,
115
#endif
116
117
118
#if TRUSTED_BOARD_BOOT
	/* To access the Root of Trust Public Key registers. */
	MAP_DEVICE2,
119
#if !BL2_AT_EL3
120
	ARM_MAP_BL1_RW,
121
#endif
122
#endif /* TRUSTED_BOARD_BOOT */
123
#if SPM_MM
124
125
	ARM_SP_IMAGE_MMAP,
#endif
David Wang's avatar
David Wang committed
126
127
#if ARM_BL31_IN_DRAM
	ARM_MAP_BL31_SEC_DRAM,
128
129
#endif
#ifdef SPD_opteed
130
	ARM_MAP_OPTEE_CORE_MEM,
131
	ARM_OPTEE_PAGEABLE_LOAD_MEM,
David Wang's avatar
David Wang committed
132
#endif
133
134
135
	{0}
};
#endif
136
#ifdef IMAGE_BL2U
137
138
139
140
141
142
const mmap_region_t plat_arm_mmap[] = {
	MAP_DEVICE0,
	V2M_MAP_IOFPGA,
	{0}
};
#endif
143
#ifdef IMAGE_BL31
144
145
const mmap_region_t plat_arm_mmap[] = {
	ARM_MAP_SHARED_RAM,
Ambroise Vincent's avatar
Ambroise Vincent committed
146
147
148
149
#if USE_DEBUGFS
	/* Required by devfip, can be removed if devfip is not used */
	V2M_MAP_FLASH0_RW,
#endif /* USE_DEBUGFS */
150
	ARM_MAP_EL3_TZC_DRAM,
151
	V2M_MAP_IOFPGA,
152
	MAP_DEVICE0,
153
154
155
156
#if FVP_GICR_REGION_PROTECTION
	MAP_GICD_MEM,
	MAP_GICR_MEM,
#else
157
	MAP_DEVICE1,
158
#endif /* FVP_GICR_REGION_PROTECTION */
159
	ARM_V2M_MAP_MEM_PROTECT,
160
#if SPM_MM
161
162
	ARM_SPM_BUF_EL3_MMAP,
#endif
163
	/* Required by fconf APIs to read HW_CONFIG dtb loaded into DRAM */
164
	ARM_DTB_DRAM_NS,
165
166
167
	{0}
};

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

197
ARM_CASSERT_MMAP
198

199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
#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();
216
	master = ((arm_config.flags & ARM_CONFIG_FVP_SHIFTED_AFF) != 0U) ?
217
218
219
220
221
222
		MPIDR_AFFLVL2_VAL(mpidr) : MPIDR_AFFLVL1_VAL(mpidr);

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

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

240
const spm_mm_boot_info_t plat_arm_secure_partition_boot_info = {
241
242
	.h.type              = PARAM_SP_IMAGE_BOOT_INFO,
	.h.version           = VERSION_1,
243
	.h.size              = sizeof(spm_mm_boot_info_t),
244
245
246
247
248
249
	.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,
250
	.sp_ns_comm_buf_base = PLAT_SP_IMAGE_NS_BUF_BASE,
251
252
253
254
	.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,
255
	.sp_ns_comm_buf_size = PLAT_SP_IMAGE_NS_BUF_SIZE,
256
257
258
259
260
261
262
263
264
265
266
	.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;
}

267
const struct spm_mm_boot_info *plat_get_secure_partition_boot_info(
268
269
270
271
272
273
		void *cookie)
{
	return &plat_arm_secure_partition_boot_info;
}
#endif

274
275
276
277
278
279
280
/*******************************************************************************
 * 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.
 ******************************************************************************/
281
void __init fvp_config_setup(void)
282
{
283
	unsigned int rev, hbi, bld, arch, sys_id;
284

285
286
287
288
289
	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;
290

291
292
	if (arch != ARCH_MODEL) {
		ERROR("This firmware is for FVP models\n");
293
		panic();
294
	}
295
296
297
298
299
300
301

	/*
	 * 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:
302
303
		ERROR("Legacy Versatile Express memory map for GIC peripheral"
				" is not supported\n");
304
		panic();
305
306
307
308
		break;
	case BLD_GIC_A53A57_MMAP:
		break;
	default:
309
310
		ERROR("Unsupported board build %x\n", bld);
		panic();
311
312
313
314
315
316
317
	}

	/*
	 * The hbi field in the SYS_ID is 0x020 for the Base FVP & 0x010
	 * for the Foundation FVP.
	 */
	switch (hbi) {
318
319
	case HBI_FOUNDATION_FVP:
		arm_config.flags = 0;
320
321
322
323
324
325

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

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

	/*
	 * 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.
	 */
366
	if ((read_mpidr_el1() & MPIDR_MT_MASK) != 0U)
367
		arm_config.flags |= ARM_CONFIG_FVP_SHIFTED_AFF;
368
}
369

370

371
void __init fvp_interconnect_init(void)
372
{
373
#if FVP_INTERCONNECT_DRIVER == FVP_CCN
374
	if (ccn_get_part0_id(PLAT_ARM_CCN_BASE) != CCN_502_PART0_ID) {
375
		ERROR("Unrecognized CCN variant detected. Only CCN-502 is supported");
376
377
378
379
380
		panic();
	}

	plat_arm_interconnect_init();
#else
381
382
383
	uintptr_t cci_base = 0U;
	const int *cci_map = NULL;
	unsigned int map_size = 0U;
384
385

	/* Initialize the right interconnect */
386
	if ((arm_config.flags & ARM_CONFIG_FVP_HAS_CCI5XX) != 0U) {
387
388
389
		cci_base = PLAT_FVP_CCI5XX_BASE;
		cci_map = fvp_cci5xx_map;
		map_size = ARRAY_SIZE(fvp_cci5xx_map);
390
	} else if ((arm_config.flags & ARM_CONFIG_FVP_HAS_CCI400) != 0U) {
391
392
393
		cci_base = PLAT_FVP_CCI400_BASE;
		cci_map = fvp_cci400_map;
		map_size = ARRAY_SIZE(fvp_cci400_map);
394
395
	} else {
		return;
396
	}
397

398
399
	assert(cci_base != 0U);
	assert(cci_map != NULL);
400
401
	cci_init(cci_base, cci_map, map_size);
#endif
402
403
}

404
void fvp_interconnect_enable(void)
405
{
406
407
408
409
410
#if FVP_INTERCONNECT_DRIVER == FVP_CCN
	plat_arm_interconnect_enter_coherency();
#else
	unsigned int master;

411
412
	if ((arm_config.flags & (ARM_CONFIG_FVP_HAS_CCI400 |
				 ARM_CONFIG_FVP_HAS_CCI5XX)) != 0U) {
413
414
415
416
		master = get_interconnect_master();
		cci_enable_snoop_dvm_reqs(master);
	}
#endif
417
418
}

419
void fvp_interconnect_disable(void)
420
{
421
422
423
424
425
#if FVP_INTERCONNECT_DRIVER == FVP_CCN
	plat_arm_interconnect_exit_coherency();
#else
	unsigned int master;

426
427
	if ((arm_config.flags & (ARM_CONFIG_FVP_HAS_CCI400 |
				 ARM_CONFIG_FVP_HAS_CCI5XX)) != 0U) {
428
429
430
431
		master = get_interconnect_master();
		cci_disable_snoop_dvm_reqs(master);
	}
#endif
432
}
433

434
#if TRUSTED_BOARD_BOOT
435
436
437
438
439
440
441
442
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
443
444
445

void fvp_timer_init(void)
{
446
#if USE_SP804_TIMER
447
448
449
450
451
452
453
454
455
456
457
458
459
460
	/* 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);
461
#endif /* USE_SP804_TIMER */
462
}
463
464
465
466
467
468
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

/*****************************************************************************
 * 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);
}