fvp_common.c 10.3 KB
Newer Older
1
/*
Roberto Vargas's avatar
Roberto Vargas committed
2
 * Copyright (c) 2013-2018, 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
#include <arm_config.h>
#include <arm_def.h>
9
#include <arm_spm_def.h>
10
#include <arm_xlat_tables.h>
11
12
#include <assert.h>
#include <cci.h>
13
#include <ccn.h>
14
#include <debug.h>
15
#include <gicv2.h>
16
#include <mmio.h>
17
#include <plat_arm.h>
18
#include <platform.h>
19
#include <secure_partition.h>
20
#include <v2m_def.h>
21
#include "../fvp_def.h"
Roberto Vargas's avatar
Roberto Vargas committed
22
#include "fvp_private.h"
23

24
25
26
27
28
/* Defines for GIC Driver build time selection */
#define FVP_GICV2		1
#define FVP_GICV3		2
#define FVP_GICV3_LEGACY	3

29
/*******************************************************************************
30
31
 * arm_config holds the characteristics of the differences between the three FVP
 * platforms (Base, A53_A57 & Foundation). It will be populated during cold boot
32
33
34
 * 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.
35
 ******************************************************************************/
36
arm_config_t arm_config;
37
38
39
40
41
42
43
44
45

#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)

46
47
48
49
/*
 * Need to be mapped with write permissions in order to set a new non-volatile
 * counter value.
 */
50
51
#define MAP_DEVICE2	MAP_REGION_FLAT(DEVICE2_BASE,			\
					DEVICE2_SIZE,			\
52
					MT_DEVICE | MT_RW | MT_SECURE)
53

54
/*
55
56
57
 * Table of memory regions for various BL stages to map using the MMU.
 * This doesn't include Trusted SRAM as arm_setup_page_tables() already
 * takes care of mapping it.
58
59
60
 *
 * 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()).
61
 */
62
#ifdef IMAGE_BL1
63
64
const mmap_region_t plat_arm_mmap[] = {
	ARM_MAP_SHARED_RAM,
65
	V2M_MAP_FLASH0_RW,
66
	V2M_MAP_IOFPGA,
67
68
	MAP_DEVICE0,
	MAP_DEVICE1,
69
#if TRUSTED_BOARD_BOOT
70
71
72
	/* To access the Root of Trust Public Key registers. */
	MAP_DEVICE2,
	/* Map DRAM to authenticate NS_BL2U image. */
73
74
	ARM_MAP_NS_DRAM1,
#endif
75
76
77
	{0}
};
#endif
78
#ifdef IMAGE_BL2
79
80
const mmap_region_t plat_arm_mmap[] = {
	ARM_MAP_SHARED_RAM,
81
	V2M_MAP_FLASH0_RW,
82
	V2M_MAP_IOFPGA,
83
84
	MAP_DEVICE0,
	MAP_DEVICE1,
85
	ARM_MAP_NS_DRAM1,
86
87
88
#ifdef AARCH64
	ARM_MAP_DRAM2,
#endif
89
#ifdef SPD_tspd
90
	ARM_MAP_TSP_SEC_MEM,
91
#endif
92
93
94
#if TRUSTED_BOARD_BOOT
	/* To access the Root of Trust Public Key registers. */
	MAP_DEVICE2,
95
96
97
98
#if LOAD_IMAGE_V2 && !BL2_AT_EL3
	ARM_MAP_BL1_RW,
#endif /* LOAD_IMAGE_V2 && !BL2_AT_EL3 */
#endif /* TRUSTED_BOARD_BOOT */
99
100
101
#if ENABLE_SPM
	ARM_SP_IMAGE_MMAP,
#endif
David Wang's avatar
David Wang committed
102
103
#if ARM_BL31_IN_DRAM
	ARM_MAP_BL31_SEC_DRAM,
104
105
#endif
#ifdef SPD_opteed
106
	ARM_MAP_OPTEE_CORE_MEM,
107
	ARM_OPTEE_PAGEABLE_LOAD_MEM,
David Wang's avatar
David Wang committed
108
#endif
109
110
111
	{0}
};
#endif
112
#ifdef IMAGE_BL2U
113
114
115
116
117
118
const mmap_region_t plat_arm_mmap[] = {
	MAP_DEVICE0,
	V2M_MAP_IOFPGA,
	{0}
};
#endif
119
#ifdef IMAGE_BL31
120
121
const mmap_region_t plat_arm_mmap[] = {
	ARM_MAP_SHARED_RAM,
122
	ARM_MAP_EL3_TZC_DRAM,
123
	V2M_MAP_IOFPGA,
124
125
	MAP_DEVICE0,
	MAP_DEVICE1,
126
	ARM_V2M_MAP_MEM_PROTECT,
127
128
129
130
131
132
133
134
135
#if ENABLE_SPM
	ARM_SPM_BUF_EL3_MMAP,
#endif
	{0}
};

#if ENABLE_SPM && defined(IMAGE_BL31)
const mmap_region_t plat_arm_secure_partition_mmap[] = {
	V2M_MAP_IOFPGA_EL0, /* for the UART */
136
137
138
	MAP_REGION_FLAT(DEVICE0_BASE,				\
			DEVICE0_SIZE,				\
			MT_DEVICE | MT_RO | MT_SECURE | MT_USER),
139
140
141
142
	ARM_SP_IMAGE_MMAP,
	ARM_SP_IMAGE_NS_BUF_MMAP,
	ARM_SP_IMAGE_RW_MMAP,
	ARM_SPM_BUF_EL0_MMAP,
143
144
145
	{0}
};
#endif
146
#endif
147
#ifdef IMAGE_BL32
148
const mmap_region_t plat_arm_mmap[] = {
149
150
#ifdef AARCH32
	ARM_MAP_SHARED_RAM,
151
	ARM_V2M_MAP_MEM_PROTECT,
152
#endif
153
	V2M_MAP_IOFPGA,
154
155
	MAP_DEVICE0,
	MAP_DEVICE1,
156
157
	{0}
};
158
#endif
159

160
ARM_CASSERT_MMAP
161

162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
#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();
	master = (arm_config.flags & ARM_CONFIG_FVP_SHIFTED_AFF) ?
		MPIDR_AFFLVL2_VAL(mpidr) : MPIDR_AFFLVL1_VAL(mpidr);

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

187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
#if ENABLE_SPM && defined(IMAGE_BL31)
/*
 * Boot information passed to a secure partition during initialisation. Linear
 * indices in MP information will be filled at runtime.
 */
static secure_partition_mp_info_t sp_mp_info[] = {
	[0] = {0x80000000, 0},
	[1] = {0x80000001, 0},
	[2] = {0x80000002, 0},
	[3] = {0x80000003, 0},
	[4] = {0x80000100, 0},
	[5] = {0x80000101, 0},
	[6] = {0x80000102, 0},
	[7] = {0x80000103, 0},
};

const secure_partition_boot_info_t plat_arm_secure_partition_boot_info = {
	.h.type              = PARAM_SP_IMAGE_BOOT_INFO,
	.h.version           = VERSION_1,
	.h.size              = sizeof(secure_partition_boot_info_t),
	.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,
	.sp_ns_comm_buf_base = ARM_SP_IMAGE_NS_BUF_BASE,
	.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,
	.sp_ns_comm_buf_size = ARM_SP_IMAGE_NS_BUF_SIZE,
	.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;
}

const struct secure_partition_boot_info *plat_get_secure_partition_boot_info(
		void *cookie)
{
	return &plat_arm_secure_partition_boot_info;
}

#endif

238
239
240
241
242
243
244
/*******************************************************************************
 * 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.
 ******************************************************************************/
245
void fvp_config_setup(void)
246
{
247
	unsigned int rev, hbi, bld, arch, sys_id;
248

249
250
251
252
253
	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;
254

255
256
	if (arch != ARCH_MODEL) {
		ERROR("This firmware is for FVP models\n");
257
		panic();
258
	}
259
260
261
262
263
264
265

	/*
	 * 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:
266
267
		ERROR("Legacy Versatile Express memory map for GIC peripheral"
				" is not supported\n");
268
		panic();
269
270
271
272
		break;
	case BLD_GIC_A53A57_MMAP:
		break;
	default:
273
274
		ERROR("Unsupported board build %x\n", bld);
		panic();
275
276
277
278
279
280
281
	}

	/*
	 * The hbi field in the SYS_ID is 0x020 for the Base FVP & 0x010
	 * for the Foundation FVP.
	 */
	switch (hbi) {
282
283
	case HBI_FOUNDATION_FVP:
		arm_config.flags = 0;
284
285
286
287
288
289

		/*
		 * Check for supported revisions of Foundation FVP
		 * Allow future revisions to run but emit warning diagnostic
		 */
		switch (rev) {
290
291
292
		case REV_FOUNDATION_FVP_V2_0:
		case REV_FOUNDATION_FVP_V2_1:
		case REV_FOUNDATION_FVP_v9_1:
293
		case REV_FOUNDATION_FVP_v9_6:
294
295
296
297
298
			break;
		default:
			WARN("Unrecognized Foundation FVP revision %x\n", rev);
			break;
		}
299
		break;
300
	case HBI_BASE_FVP:
301
		arm_config.flags |= (ARM_CONFIG_BASE_MMAP | ARM_CONFIG_HAS_TZC);
302
303
304
305
306
307

		/*
		 * Check for supported revisions
		 * Allow future revisions to run but emit warning diagnostic
		 */
		switch (rev) {
308
		case REV_BASE_FVP_V0:
309
310
311
			arm_config.flags |= ARM_CONFIG_FVP_HAS_CCI400;
			break;
		case REV_BASE_FVP_REVC:
312
			arm_config.flags |= (ARM_CONFIG_FVP_HAS_SMMUV3 |
313
					ARM_CONFIG_FVP_HAS_CCI5XX);
314
315
316
317
318
			break;
		default:
			WARN("Unrecognized Base FVP revision %x\n", rev);
			break;
		}
319
320
		break;
	default:
321
322
		ERROR("Unsupported board HBI number 0x%x\n", hbi);
		panic();
323
	}
324
325
326
327
328
329
330
331

	/*
	 * 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.
	 */
	if (read_mpidr_el1() & MPIDR_MT_MASK)
		arm_config.flags |= ARM_CONFIG_FVP_SHIFTED_AFF;
332
}
333

334

335
void fvp_interconnect_init(void)
336
{
337
#if FVP_INTERCONNECT_DRIVER == FVP_CCN
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
	if (ccn_get_part0_id(PLAT_ARM_CCN_BASE) != CCN_502_PART0_ID) {
		ERROR("Unrecognized CCN variant detected. Only CCN-502"
				" is supported");
		panic();
	}

	plat_arm_interconnect_init();
#else
	uintptr_t cci_base = 0;
	const int *cci_map = 0;
	unsigned int map_size = 0;

	if (!(arm_config.flags & (ARM_CONFIG_FVP_HAS_CCI400 |
				ARM_CONFIG_FVP_HAS_CCI5XX))) {
		return;
	}

	/* Initialize the right interconnect */
	if (arm_config.flags & ARM_CONFIG_FVP_HAS_CCI5XX) {
		cci_base = PLAT_FVP_CCI5XX_BASE;
		cci_map = fvp_cci5xx_map;
		map_size = ARRAY_SIZE(fvp_cci5xx_map);
	} else if (arm_config.flags & ARM_CONFIG_FVP_HAS_CCI400) {
		cci_base = PLAT_FVP_CCI400_BASE;
		cci_map = fvp_cci400_map;
		map_size = ARRAY_SIZE(fvp_cci400_map);
364
	}
365
366
367
368
369

	assert(cci_base);
	assert(cci_map);
	cci_init(cci_base, cci_map, map_size);
#endif
370
371
}

372
void fvp_interconnect_enable(void)
373
{
374
375
376
377
378
379
380
381
382
383
384
#if FVP_INTERCONNECT_DRIVER == FVP_CCN
	plat_arm_interconnect_enter_coherency();
#else
	unsigned int master;

	if (arm_config.flags & (ARM_CONFIG_FVP_HAS_CCI400 |
				ARM_CONFIG_FVP_HAS_CCI5XX)) {
		master = get_interconnect_master();
		cci_enable_snoop_dvm_reqs(master);
	}
#endif
385
386
}

387
void fvp_interconnect_disable(void)
388
{
389
390
391
392
393
394
395
396
397
398
399
#if FVP_INTERCONNECT_DRIVER == FVP_CCN
	plat_arm_interconnect_exit_coherency();
#else
	unsigned int master;

	if (arm_config.flags & (ARM_CONFIG_FVP_HAS_CCI400 |
				ARM_CONFIG_FVP_HAS_CCI5XX)) {
		master = get_interconnect_master();
		cci_disable_snoop_dvm_reqs(master);
	}
#endif
400
}
401
402
403
404
405
406
407
408
409
410

#if TRUSTED_BOARD_BOOT && LOAD_IMAGE_V2
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