fvp_common.c 10.5 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
9
10
11
12
13
14
15
16
17
#include <assert.h>

#include <common/debug.h>
#include <drivers/arm/cci.h>
#include <drivers/arm/ccn.h>
#include <drivers/arm/gicv2.h>
#include <lib/mmio.h>
#include <lib/xlat_tables/xlat_tables_compat.h>
#include <plat/common/platform.h>
#include <services/secure_partition.h>

18
19
#include <arm_config.h>
#include <arm_def.h>
20
#include <arm_spm_def.h>
21
22
#include <plat_arm.h>
#include <v2m_def.h>
23

24
#include "../fvp_def.h"
Roberto Vargas's avatar
Roberto Vargas committed
25
#include "fvp_private.h"
26

27
28
29
30
/* Defines for GIC Driver build time selection */
#define FVP_GICV2		1
#define FVP_GICV3		2

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

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

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

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

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

168
ARM_CASSERT_MMAP
169

170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
#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();
187
	master = ((arm_config.flags & ARM_CONFIG_FVP_SHIFTED_AFF) != 0U) ?
188
189
190
191
192
193
		MPIDR_AFFLVL2_VAL(mpidr) : MPIDR_AFFLVL1_VAL(mpidr);

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

195
#if ENABLE_SPM && defined(IMAGE_BL31) && SPM_DEPRECATED
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
238
239
240
241
242
243
244
/*
 * 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

245
246
247
248
249
250
251
/*******************************************************************************
 * 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.
 ******************************************************************************/
252
void __init fvp_config_setup(void)
253
{
254
	unsigned int rev, hbi, bld, arch, sys_id;
255

256
257
258
259
260
	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;
261

262
263
	if (arch != ARCH_MODEL) {
		ERROR("This firmware is for FVP models\n");
264
		panic();
265
	}
266
267
268
269
270
271
272

	/*
	 * 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:
273
274
		ERROR("Legacy Versatile Express memory map for GIC peripheral"
				" is not supported\n");
275
		panic();
276
277
278
279
		break;
	case BLD_GIC_A53A57_MMAP:
		break;
	default:
280
281
		ERROR("Unsupported board build %x\n", bld);
		panic();
282
283
284
285
286
287
288
	}

	/*
	 * The hbi field in the SYS_ID is 0x020 for the Base FVP & 0x010
	 * for the Foundation FVP.
	 */
	switch (hbi) {
289
290
	case HBI_FOUNDATION_FVP:
		arm_config.flags = 0;
291
292
293
294
295
296

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

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

	/*
	 * 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.
	 */
337
	if ((read_mpidr_el1() & MPIDR_MT_MASK) != 0U)
338
		arm_config.flags |= ARM_CONFIG_FVP_SHIFTED_AFF;
339
}
340

341

342
void __init fvp_interconnect_init(void)
343
{
344
#if FVP_INTERCONNECT_DRIVER == FVP_CCN
345
	if (ccn_get_part0_id(PLAT_ARM_CCN_BASE) != CCN_502_PART0_ID) {
346
		ERROR("Unrecognized CCN variant detected. Only CCN-502 is supported");
347
348
349
350
351
		panic();
	}

	plat_arm_interconnect_init();
#else
352
353
354
	uintptr_t cci_base = 0U;
	const int *cci_map = NULL;
	unsigned int map_size = 0U;
355
356

	/* Initialize the right interconnect */
357
	if ((arm_config.flags & ARM_CONFIG_FVP_HAS_CCI5XX) != 0U) {
358
359
360
		cci_base = PLAT_FVP_CCI5XX_BASE;
		cci_map = fvp_cci5xx_map;
		map_size = ARRAY_SIZE(fvp_cci5xx_map);
361
	} else if ((arm_config.flags & ARM_CONFIG_FVP_HAS_CCI400) != 0U) {
362
363
364
		cci_base = PLAT_FVP_CCI400_BASE;
		cci_map = fvp_cci400_map;
		map_size = ARRAY_SIZE(fvp_cci400_map);
365
366
	} else {
		return;
367
	}
368

369
370
	assert(cci_base != 0U);
	assert(cci_map != NULL);
371
372
	cci_init(cci_base, cci_map, map_size);
#endif
373
374
}

375
void fvp_interconnect_enable(void)
376
{
377
378
379
380
381
#if FVP_INTERCONNECT_DRIVER == FVP_CCN
	plat_arm_interconnect_enter_coherency();
#else
	unsigned int master;

382
383
	if ((arm_config.flags & (ARM_CONFIG_FVP_HAS_CCI400 |
				 ARM_CONFIG_FVP_HAS_CCI5XX)) != 0U) {
384
385
386
387
		master = get_interconnect_master();
		cci_enable_snoop_dvm_reqs(master);
	}
#endif
388
389
}

390
void fvp_interconnect_disable(void)
391
{
392
393
394
395
396
#if FVP_INTERCONNECT_DRIVER == FVP_CCN
	plat_arm_interconnect_exit_coherency();
#else
	unsigned int master;

397
398
	if ((arm_config.flags & (ARM_CONFIG_FVP_HAS_CCI400 |
				 ARM_CONFIG_FVP_HAS_CCI5XX)) != 0U) {
399
400
401
402
		master = get_interconnect_master();
		cci_disable_snoop_dvm_reqs(master);
	}
#endif
403
}
404

405
#if TRUSTED_BOARD_BOOT
406
407
408
409
410
411
412
413
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