fvp_common.c 9.88 KB
Newer Older
1
/*
2
 * Copyright (c) 2013-2017, 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 <secure_partition.h>
19
#include <v2m_def.h>
20
#include "../fvp_def.h"
21

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

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

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

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


53
/*
54
55
56
 * 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.
57
58
59
 *
 * 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()).
60
 */
61
#ifdef IMAGE_BL1
62
63
const mmap_region_t plat_arm_mmap[] = {
	ARM_MAP_SHARED_RAM,
64
	V2M_MAP_FLASH0_RW,
65
	V2M_MAP_IOFPGA,
66
67
	MAP_DEVICE0,
	MAP_DEVICE1,
68
#if TRUSTED_BOARD_BOOT
69
70
71
	/* To access the Root of Trust Public Key registers. */
	MAP_DEVICE2,
	/* Map DRAM to authenticate NS_BL2U image. */
72
73
	ARM_MAP_NS_DRAM1,
#endif
74
75
76
	{0}
};
#endif
77
#ifdef IMAGE_BL2
78
79
const mmap_region_t plat_arm_mmap[] = {
	ARM_MAP_SHARED_RAM,
80
	V2M_MAP_FLASH0_RW,
81
	V2M_MAP_IOFPGA,
82
83
	MAP_DEVICE0,
	MAP_DEVICE1,
84
	ARM_MAP_NS_DRAM1,
85
86
87
#ifdef AARCH64
	ARM_MAP_DRAM2,
#endif
88
#ifdef SPD_tspd
89
	ARM_MAP_TSP_SEC_MEM,
90
#endif
91
92
93
94
#if TRUSTED_BOARD_BOOT
	/* To access the Root of Trust Public Key registers. */
	MAP_DEVICE2,
#endif
95
96
97
#if ENABLE_SPM
	ARM_SP_IMAGE_MMAP,
#endif
David Wang's avatar
David Wang committed
98
99
#if ARM_BL31_IN_DRAM
	ARM_MAP_BL31_SEC_DRAM,
100
101
#endif
#ifdef SPD_opteed
102
	ARM_MAP_OPTEE_CORE_MEM,
103
	ARM_OPTEE_PAGEABLE_LOAD_MEM,
David Wang's avatar
David Wang committed
104
#endif
105
106
107
	{0}
};
#endif
108
#ifdef IMAGE_BL2U
109
110
111
112
113
114
const mmap_region_t plat_arm_mmap[] = {
	MAP_DEVICE0,
	V2M_MAP_IOFPGA,
	{0}
};
#endif
115
#ifdef IMAGE_BL31
116
117
const mmap_region_t plat_arm_mmap[] = {
	ARM_MAP_SHARED_RAM,
118
	ARM_MAP_EL3_TZC_DRAM,
119
	V2M_MAP_IOFPGA,
120
121
	MAP_DEVICE0,
	MAP_DEVICE1,
122
	ARM_V2M_MAP_MEM_PROTECT,
123
124
125
126
127
128
129
130
131
#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 */
132
133
134
	MAP_REGION_FLAT(DEVICE0_BASE,				\
			DEVICE0_SIZE,				\
			MT_DEVICE | MT_RO | MT_SECURE | MT_USER),
135
136
137
138
	ARM_SP_IMAGE_MMAP,
	ARM_SP_IMAGE_NS_BUF_MMAP,
	ARM_SP_IMAGE_RW_MMAP,
	ARM_SPM_BUF_EL0_MMAP,
139
140
141
	{0}
};
#endif
142
#endif
143
#ifdef IMAGE_BL32
144
const mmap_region_t plat_arm_mmap[] = {
145
146
147
#ifdef AARCH32
	ARM_MAP_SHARED_RAM,
#endif
148
	V2M_MAP_IOFPGA,
149
150
	MAP_DEVICE0,
	MAP_DEVICE1,
151
152
	{0}
};
153
#endif
154

155
ARM_CASSERT_MMAP
156

157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
#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
181

182
183
184
185
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
#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

233
234
235
236
237
238
239
/*******************************************************************************
 * 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.
 ******************************************************************************/
240
void fvp_config_setup(void)
241
{
242
	unsigned int rev, hbi, bld, arch, sys_id;
243

244
245
246
247
248
	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;
249

250
251
	if (arch != ARCH_MODEL) {
		ERROR("This firmware is for FVP models\n");
252
		panic();
253
	}
254
255
256
257
258
259
260

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

	/*
	 * The hbi field in the SYS_ID is 0x020 for the Base FVP & 0x010
	 * for the Foundation FVP.
	 */
	switch (hbi) {
277
278
	case HBI_FOUNDATION_FVP:
		arm_config.flags = 0;
279
280
281
282
283
284

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

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

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

329

330
void fvp_interconnect_init(void)
331
{
332
#if FVP_INTERCONNECT_DRIVER == FVP_CCN
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
	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);
359
	}
360
361
362
363
364

	assert(cci_base);
	assert(cci_map);
	cci_init(cci_base, cci_map, map_size);
#endif
365
366
}

367
void fvp_interconnect_enable(void)
368
{
369
370
371
372
373
374
375
376
377
378
379
#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
380
381
}

382
void fvp_interconnect_disable(void)
383
{
384
385
386
387
388
389
390
391
392
393
394
#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
395
}