fvp_common.c 9.76 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
11
#include <assert.h>
#include <cci.h>
12
#include <ccn.h>
13
#include <debug.h>
14
#include <gicv2.h>
15
#include <mmio.h>
16
#include <plat_arm.h>
17
#include <secure_partition.h>
18
#include <v2m_def.h>
19
#include "../fvp_def.h"
20

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

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

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

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


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

151
ARM_CASSERT_MMAP
152

153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
#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
177

178
179
180
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
#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

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

240
241
242
243
244
	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;
245

246
247
	if (arch != ARCH_MODEL) {
		ERROR("This firmware is for FVP models\n");
248
		panic();
249
	}
250
251
252
253
254
255
256

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

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

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

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

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

325

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

	assert(cci_base);
	assert(cci_map);
	cci_init(cci_base, cci_map, map_size);
#endif
361
362
}

363
void fvp_interconnect_enable(void)
364
{
365
366
367
368
369
370
371
372
373
374
375
#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
376
377
}

378
void fvp_interconnect_disable(void)
379
{
380
381
382
383
384
385
386
387
388
389
390
#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
391
}