arm_io_storage.c 6.47 KB
Newer Older
1
/*
2
 * Copyright (c) 2015-2016, 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
 */
#include <assert.h>
#include <debug.h>
8
#include <firmware_image_package.h>
9
10
11
12
13
14
#include <io_driver.h>
#include <io_fip.h>
#include <io_memmap.h>
#include <io_storage.h>
#include <platform_def.h>
#include <string.h>
15
#include <utils.h>
16
17
18
19
20
21
22
23
24
25
26
27

/* IO devices */
static const io_dev_connector_t *fip_dev_con;
static uintptr_t fip_dev_handle;
static const io_dev_connector_t *memmap_dev_con;
static uintptr_t memmap_dev_handle;

static const io_block_spec_t fip_block_spec = {
	.offset = PLAT_ARM_FIP_BASE,
	.length = PLAT_ARM_FIP_MAX_SIZE
};

28
29
static const io_uuid_spec_t bl2_uuid_spec = {
	.uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
30
31
};

32
33
static const io_uuid_spec_t scp_bl2_uuid_spec = {
	.uuid = UUID_SCP_FIRMWARE_SCP_BL2,
34
35
};

36
37
static const io_uuid_spec_t bl31_uuid_spec = {
	.uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
38
39
};

40
41
static const io_uuid_spec_t bl32_uuid_spec = {
	.uuid = UUID_SECURE_PAYLOAD_BL32,
42
43
};

44
45
static const io_uuid_spec_t bl33_uuid_spec = {
	.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
46
47
48
};

#if TRUSTED_BOARD_BOOT
49
50
static const io_uuid_spec_t tb_fw_cert_uuid_spec = {
	.uuid = UUID_TRUSTED_BOOT_FW_CERT,
51
52
};

53
54
static const io_uuid_spec_t trusted_key_cert_uuid_spec = {
	.uuid = UUID_TRUSTED_KEY_CERT,
55
56
};

57
58
static const io_uuid_spec_t scp_fw_key_cert_uuid_spec = {
	.uuid = UUID_SCP_FW_KEY_CERT,
59
60
};

61
62
static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = {
	.uuid = UUID_SOC_FW_KEY_CERT,
63
64
};

65
66
static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = {
	.uuid = UUID_TRUSTED_OS_FW_KEY_CERT,
67
68
};

69
70
static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = {
	.uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
71
72
};

73
74
static const io_uuid_spec_t scp_fw_cert_uuid_spec = {
	.uuid = UUID_SCP_FW_CONTENT_CERT,
75
76
};

77
78
static const io_uuid_spec_t soc_fw_cert_uuid_spec = {
	.uuid = UUID_SOC_FW_CONTENT_CERT,
79
80
};

81
82
static const io_uuid_spec_t tos_fw_cert_uuid_spec = {
	.uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT,
83
84
};

85
86
static const io_uuid_spec_t nt_fw_cert_uuid_spec = {
	.uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT,
87
88
89
};
#endif /* TRUSTED_BOARD_BOOT */

90

91
92
93
94
95
96
97
98
99
static int open_fip(const uintptr_t spec);
static int open_memmap(const uintptr_t spec);

struct plat_io_policy {
	uintptr_t *dev_handle;
	uintptr_t image_spec;
	int (*check)(const uintptr_t spec);
};

100
/* By default, ARM platforms load images from the FIP */
101
static const struct plat_io_policy policies[] = {
102
	[FIP_IMAGE_ID] = {
103
104
105
		&memmap_dev_handle,
		(uintptr_t)&fip_block_spec,
		open_memmap
106
107
	},
	[BL2_IMAGE_ID] = {
108
		&fip_dev_handle,
109
		(uintptr_t)&bl2_uuid_spec,
110
		open_fip
111
	},
112
	[SCP_BL2_IMAGE_ID] = {
113
		&fip_dev_handle,
114
		(uintptr_t)&scp_bl2_uuid_spec,
115
		open_fip
116
117
	},
	[BL31_IMAGE_ID] = {
118
		&fip_dev_handle,
119
		(uintptr_t)&bl31_uuid_spec,
120
		open_fip
121
122
	},
	[BL32_IMAGE_ID] = {
123
		&fip_dev_handle,
124
		(uintptr_t)&bl32_uuid_spec,
125
		open_fip
126
127
	},
	[BL33_IMAGE_ID] = {
128
		&fip_dev_handle,
129
		(uintptr_t)&bl33_uuid_spec,
130
		open_fip
131
	},
132
#if TRUSTED_BOARD_BOOT
133
	[TRUSTED_BOOT_FW_CERT_ID] = {
134
		&fip_dev_handle,
135
		(uintptr_t)&tb_fw_cert_uuid_spec,
136
		open_fip
137
138
	},
	[TRUSTED_KEY_CERT_ID] = {
139
		&fip_dev_handle,
140
		(uintptr_t)&trusted_key_cert_uuid_spec,
141
		open_fip
142
	},
143
	[SCP_FW_KEY_CERT_ID] = {
144
		&fip_dev_handle,
145
		(uintptr_t)&scp_fw_key_cert_uuid_spec,
146
		open_fip
147
	},
148
	[SOC_FW_KEY_CERT_ID] = {
149
		&fip_dev_handle,
150
		(uintptr_t)&soc_fw_key_cert_uuid_spec,
151
		open_fip
152
	},
153
	[TRUSTED_OS_FW_KEY_CERT_ID] = {
154
		&fip_dev_handle,
155
		(uintptr_t)&tos_fw_key_cert_uuid_spec,
156
		open_fip
157
	},
158
	[NON_TRUSTED_FW_KEY_CERT_ID] = {
159
		&fip_dev_handle,
160
		(uintptr_t)&nt_fw_key_cert_uuid_spec,
161
		open_fip
162
	},
163
	[SCP_FW_CONTENT_CERT_ID] = {
164
		&fip_dev_handle,
165
		(uintptr_t)&scp_fw_cert_uuid_spec,
166
		open_fip
167
	},
168
	[SOC_FW_CONTENT_CERT_ID] = {
169
		&fip_dev_handle,
170
		(uintptr_t)&soc_fw_cert_uuid_spec,
171
		open_fip
172
	},
173
	[TRUSTED_OS_FW_CONTENT_CERT_ID] = {
174
		&fip_dev_handle,
175
		(uintptr_t)&tos_fw_cert_uuid_spec,
176
		open_fip
177
	},
178
	[NON_TRUSTED_FW_CONTENT_CERT_ID] = {
179
		&fip_dev_handle,
180
		(uintptr_t)&nt_fw_cert_uuid_spec,
181
		open_fip
182
	},
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
#endif /* TRUSTED_BOARD_BOOT */
};


/* Weak definitions may be overridden in specific ARM standard platform */
#pragma weak plat_arm_io_setup
#pragma weak plat_arm_get_alt_image_source


static int open_fip(const uintptr_t spec)
{
	int result;
	uintptr_t local_image_handle;

	/* See if a Firmware Image Package is available */
198
	result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
199
	if (result == 0) {
200
		result = io_open(fip_dev_handle, spec, &local_image_handle);
201
		if (result == 0) {
202
203
204
205
206
207
208
209
210
211
212
213
214
215
			VERBOSE("Using FIP\n");
			io_close(local_image_handle);
		}
	}
	return result;
}


static int open_memmap(const uintptr_t spec)
{
	int result;
	uintptr_t local_image_handle;

	result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL);
216
	if (result == 0) {
217
		result = io_open(memmap_dev_handle, spec, &local_image_handle);
218
		if (result == 0) {
219
220
221
222
223
224
225
226
227
228
229
230
231
			VERBOSE("Using Memmap\n");
			io_close(local_image_handle);
		}
	}
	return result;
}


void arm_io_setup(void)
{
	int io_result;

	io_result = register_io_dev_fip(&fip_dev_con);
232
	assert(io_result == 0);
233
234

	io_result = register_io_dev_memmap(&memmap_dev_con);
235
	assert(io_result == 0);
236
237
238
239

	/* Open connections to devices and cache the handles */
	io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL,
				&fip_dev_handle);
240
	assert(io_result == 0);
241
242
243

	io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL,
				&memmap_dev_handle);
244
	assert(io_result == 0);
245
246
247
248
249
250
251
252
253
254
255

	/* Ignore improbable errors in release builds */
	(void)io_result;
}

void plat_arm_io_setup(void)
{
	arm_io_setup();
}

int plat_arm_get_alt_image_source(
256
257
258
	unsigned int image_id __unused,
	uintptr_t *dev_handle __unused,
	uintptr_t *image_spec __unused)
259
260
{
	/* By default do not try an alternative */
261
	return -ENOENT;
262
263
264
265
}

/* Return an IO device handle and specification which can be used to access
 * an image. Use this to enforce platform load policy */
266
int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
267
268
			  uintptr_t *image_spec)
{
269
	int result;
270
271
	const struct plat_io_policy *policy;

272
273
274
275
	assert(image_id < ARRAY_SIZE(policies));

	policy = &policies[image_id];
	result = policy->check(policy->image_spec);
276
	if (result == 0) {
277
278
		*image_spec = policy->image_spec;
		*dev_handle = *(policy->dev_handle);
279
	} else {
280
281
282
		VERBOSE("Trying alternative IO\n");
		result = plat_arm_get_alt_image_source(image_id, dev_handle,
						       image_spec);
283
	}
284

285
286
	return result;
}
287
288
289
290
291
292
293
294
295
296
297
298
299
300

/*
 * See if a Firmware Image Package is available,
 * by checking if TOC is valid or not.
 */
int arm_io_is_toc_valid(void)
{
	int result;

	result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);

	return (result == 0);
}