1 /*
2  * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <assert.h>
8 #include <string.h>
9 
10 #include <platform_def.h>
11 
12 #include <common/bl_common.h>
13 #include <common/debug.h>
14 #include <drivers/io/io_driver.h>
15 #include <drivers/io/io_encrypted.h>
16 #include <drivers/io/io_fip.h>
17 #include <drivers/io/io_memmap.h>
18 #include <drivers/io/io_semihosting.h>
19 #include <drivers/io/io_storage.h>
20 #include <lib/semihosting.h>
21 #include <tools_share/firmware_image_package.h>
22 
23 /* Semihosting filenames */
24 #define BL2_IMAGE_NAME			"bl2.bin"
25 #define BL31_IMAGE_NAME			"bl31.bin"
26 #define BL32_IMAGE_NAME			"bl32.bin"
27 #define BL32_EXTRA1_IMAGE_NAME		"bl32_extra1.bin"
28 #define BL32_EXTRA2_IMAGE_NAME		"bl32_extra2.bin"
29 #define BL33_IMAGE_NAME			"bl33.bin"
30 
31 #if TRUSTED_BOARD_BOOT
32 #define TRUSTED_BOOT_FW_CERT_NAME	"tb_fw.crt"
33 #define TRUSTED_KEY_CERT_NAME		"trusted_key.crt"
34 #define SOC_FW_KEY_CERT_NAME		"soc_fw_key.crt"
35 #define TOS_FW_KEY_CERT_NAME		"tos_fw_key.crt"
36 #define NT_FW_KEY_CERT_NAME		"nt_fw_key.crt"
37 #define SOC_FW_CONTENT_CERT_NAME	"soc_fw_content.crt"
38 #define TOS_FW_CONTENT_CERT_NAME	"tos_fw_content.crt"
39 #define NT_FW_CONTENT_CERT_NAME		"nt_fw_content.crt"
40 #endif /* TRUSTED_BOARD_BOOT */
41 
42 
43 
44 /* IO devices */
45 static const io_dev_connector_t *fip_dev_con;
46 static uintptr_t fip_dev_handle;
47 static const io_dev_connector_t *memmap_dev_con;
48 static uintptr_t memmap_dev_handle;
49 static const io_dev_connector_t *sh_dev_con;
50 static uintptr_t sh_dev_handle;
51 #ifndef DECRYPTION_SUPPORT_none
52 static const io_dev_connector_t *enc_dev_con;
53 static uintptr_t enc_dev_handle;
54 #endif
55 
56 static const io_block_spec_t fip_block_spec = {
57 	.offset = PLAT_QEMU_FIP_BASE,
58 	.length = PLAT_QEMU_FIP_MAX_SIZE
59 };
60 
61 static const io_uuid_spec_t bl2_uuid_spec = {
62 	.uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
63 };
64 
65 static const io_uuid_spec_t bl31_uuid_spec = {
66 	.uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
67 };
68 
69 static const io_uuid_spec_t bl32_uuid_spec = {
70 	.uuid = UUID_SECURE_PAYLOAD_BL32,
71 };
72 
73 static const io_uuid_spec_t bl32_extra1_uuid_spec = {
74 	.uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1,
75 };
76 
77 static const io_uuid_spec_t bl32_extra2_uuid_spec = {
78 	.uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2,
79 };
80 
81 static const io_uuid_spec_t bl33_uuid_spec = {
82 	.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
83 };
84 
85 #if TRUSTED_BOARD_BOOT
86 static const io_uuid_spec_t tb_fw_cert_uuid_spec = {
87 	.uuid = UUID_TRUSTED_BOOT_FW_CERT,
88 };
89 
90 static const io_uuid_spec_t trusted_key_cert_uuid_spec = {
91 	.uuid = UUID_TRUSTED_KEY_CERT,
92 };
93 
94 static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = {
95 	.uuid = UUID_SOC_FW_KEY_CERT,
96 };
97 
98 static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = {
99 	.uuid = UUID_TRUSTED_OS_FW_KEY_CERT,
100 };
101 
102 static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = {
103 	.uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
104 };
105 
106 static const io_uuid_spec_t soc_fw_cert_uuid_spec = {
107 	.uuid = UUID_SOC_FW_CONTENT_CERT,
108 };
109 
110 static const io_uuid_spec_t tos_fw_cert_uuid_spec = {
111 	.uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT,
112 };
113 
114 static const io_uuid_spec_t nt_fw_cert_uuid_spec = {
115 	.uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT,
116 };
117 #endif /* TRUSTED_BOARD_BOOT */
118 
119 static const io_file_spec_t sh_file_spec[] = {
120 	[BL2_IMAGE_ID] = {
121 		.path = BL2_IMAGE_NAME,
122 		.mode = FOPEN_MODE_RB
123 	},
124 	[BL31_IMAGE_ID] = {
125 		.path = BL31_IMAGE_NAME,
126 		.mode = FOPEN_MODE_RB
127 	},
128 	[BL32_IMAGE_ID] = {
129 		.path = BL32_IMAGE_NAME,
130 		.mode = FOPEN_MODE_RB
131 	},
132 	[BL32_EXTRA1_IMAGE_ID] = {
133 		.path = BL32_EXTRA1_IMAGE_NAME,
134 		.mode = FOPEN_MODE_RB
135 	},
136 	[BL32_EXTRA2_IMAGE_ID] = {
137 		.path = BL32_EXTRA2_IMAGE_NAME,
138 		.mode = FOPEN_MODE_RB
139 	},
140 	[BL33_IMAGE_ID] = {
141 		.path = BL33_IMAGE_NAME,
142 		.mode = FOPEN_MODE_RB
143 	},
144 #if TRUSTED_BOARD_BOOT
145 	[TRUSTED_BOOT_FW_CERT_ID] = {
146 		.path = TRUSTED_BOOT_FW_CERT_NAME,
147 		.mode = FOPEN_MODE_RB
148 	},
149 	[TRUSTED_KEY_CERT_ID] = {
150 		.path = TRUSTED_KEY_CERT_NAME,
151 		.mode = FOPEN_MODE_RB
152 	},
153 	[SOC_FW_KEY_CERT_ID] = {
154 		.path = SOC_FW_KEY_CERT_NAME,
155 		.mode = FOPEN_MODE_RB
156 	},
157 	[TRUSTED_OS_FW_KEY_CERT_ID] = {
158 		.path = TOS_FW_KEY_CERT_NAME,
159 		.mode = FOPEN_MODE_RB
160 	},
161 	[NON_TRUSTED_FW_KEY_CERT_ID] = {
162 		.path = NT_FW_KEY_CERT_NAME,
163 		.mode = FOPEN_MODE_RB
164 	},
165 	[SOC_FW_CONTENT_CERT_ID] = {
166 		.path = SOC_FW_CONTENT_CERT_NAME,
167 		.mode = FOPEN_MODE_RB
168 	},
169 	[TRUSTED_OS_FW_CONTENT_CERT_ID] = {
170 		.path = TOS_FW_CONTENT_CERT_NAME,
171 		.mode = FOPEN_MODE_RB
172 	},
173 	[NON_TRUSTED_FW_CONTENT_CERT_ID] = {
174 		.path = NT_FW_CONTENT_CERT_NAME,
175 		.mode = FOPEN_MODE_RB
176 	},
177 #endif /* TRUSTED_BOARD_BOOT */
178 };
179 
180 static int open_fip(const uintptr_t spec);
181 static int open_memmap(const uintptr_t spec);
182 #ifndef DECRYPTION_SUPPORT_none
183 static int open_enc_fip(const uintptr_t spec);
184 #endif
185 
186 struct plat_io_policy {
187 	uintptr_t *dev_handle;
188 	uintptr_t image_spec;
189 	int (*check)(const uintptr_t spec);
190 };
191 
192 /* By default, ARM platforms load images from the FIP */
193 static const struct plat_io_policy policies[] = {
194 	[FIP_IMAGE_ID] = {
195 		&memmap_dev_handle,
196 		(uintptr_t)&fip_block_spec,
197 		open_memmap
198 	},
199 	[ENC_IMAGE_ID] = {
200 		&fip_dev_handle,
201 		(uintptr_t)NULL,
202 		open_fip
203 	},
204 	[BL2_IMAGE_ID] = {
205 		&fip_dev_handle,
206 		(uintptr_t)&bl2_uuid_spec,
207 		open_fip
208 	},
209 #if ENCRYPT_BL31 && !defined(DECRYPTION_SUPPORT_none)
210 	[BL31_IMAGE_ID] = {
211 		&enc_dev_handle,
212 		(uintptr_t)&bl31_uuid_spec,
213 		open_enc_fip
214 	},
215 #else
216 	[BL31_IMAGE_ID] = {
217 		&fip_dev_handle,
218 		(uintptr_t)&bl31_uuid_spec,
219 		open_fip
220 	},
221 #endif
222 #if ENCRYPT_BL32 && !defined(DECRYPTION_SUPPORT_none)
223 	[BL32_IMAGE_ID] = {
224 		&enc_dev_handle,
225 		(uintptr_t)&bl32_uuid_spec,
226 		open_enc_fip
227 	},
228 	[BL32_EXTRA1_IMAGE_ID] = {
229 		&enc_dev_handle,
230 		(uintptr_t)&bl32_extra1_uuid_spec,
231 		open_enc_fip
232 	},
233 	[BL32_EXTRA2_IMAGE_ID] = {
234 		&enc_dev_handle,
235 		(uintptr_t)&bl32_extra2_uuid_spec,
236 		open_enc_fip
237 	},
238 #else
239 	[BL32_IMAGE_ID] = {
240 		&fip_dev_handle,
241 		(uintptr_t)&bl32_uuid_spec,
242 		open_fip
243 	},
244 	[BL32_EXTRA1_IMAGE_ID] = {
245 		&fip_dev_handle,
246 		(uintptr_t)&bl32_extra1_uuid_spec,
247 		open_fip
248 	},
249 	[BL32_EXTRA2_IMAGE_ID] = {
250 		&fip_dev_handle,
251 		(uintptr_t)&bl32_extra2_uuid_spec,
252 		open_fip
253 	},
254 #endif
255 	[BL33_IMAGE_ID] = {
256 		&fip_dev_handle,
257 		(uintptr_t)&bl33_uuid_spec,
258 		open_fip
259 	},
260 #if TRUSTED_BOARD_BOOT
261 	[TRUSTED_BOOT_FW_CERT_ID] = {
262 		&fip_dev_handle,
263 		(uintptr_t)&tb_fw_cert_uuid_spec,
264 		open_fip
265 	},
266 	[TRUSTED_KEY_CERT_ID] = {
267 		&fip_dev_handle,
268 		(uintptr_t)&trusted_key_cert_uuid_spec,
269 		open_fip
270 	},
271 	[SOC_FW_KEY_CERT_ID] = {
272 		&fip_dev_handle,
273 		(uintptr_t)&soc_fw_key_cert_uuid_spec,
274 		open_fip
275 	},
276 	[TRUSTED_OS_FW_KEY_CERT_ID] = {
277 		&fip_dev_handle,
278 		(uintptr_t)&tos_fw_key_cert_uuid_spec,
279 		open_fip
280 	},
281 	[NON_TRUSTED_FW_KEY_CERT_ID] = {
282 		&fip_dev_handle,
283 		(uintptr_t)&nt_fw_key_cert_uuid_spec,
284 		open_fip
285 	},
286 	[SOC_FW_CONTENT_CERT_ID] = {
287 		&fip_dev_handle,
288 		(uintptr_t)&soc_fw_cert_uuid_spec,
289 		open_fip
290 	},
291 	[TRUSTED_OS_FW_CONTENT_CERT_ID] = {
292 		&fip_dev_handle,
293 		(uintptr_t)&tos_fw_cert_uuid_spec,
294 		open_fip
295 	},
296 	[NON_TRUSTED_FW_CONTENT_CERT_ID] = {
297 		&fip_dev_handle,
298 		(uintptr_t)&nt_fw_cert_uuid_spec,
299 		open_fip
300 	},
301 #endif /* TRUSTED_BOARD_BOOT */
302 };
303 
open_fip(const uintptr_t spec)304 static int open_fip(const uintptr_t spec)
305 {
306 	int result;
307 	uintptr_t local_image_handle;
308 
309 	/* See if a Firmware Image Package is available */
310 	result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
311 	if (result == 0 && spec != (uintptr_t)NULL) {
312 		result = io_open(fip_dev_handle, spec, &local_image_handle);
313 		if (result == 0) {
314 			VERBOSE("Using FIP\n");
315 			io_close(local_image_handle);
316 		}
317 	}
318 	return result;
319 }
320 
321 #ifndef DECRYPTION_SUPPORT_none
open_enc_fip(const uintptr_t spec)322 static int open_enc_fip(const uintptr_t spec)
323 {
324 	int result;
325 	uintptr_t local_image_handle;
326 
327 	/* See if an encrypted FIP is available */
328 	result = io_dev_init(enc_dev_handle, (uintptr_t)ENC_IMAGE_ID);
329 	if (result == 0) {
330 		result = io_open(enc_dev_handle, spec, &local_image_handle);
331 		if (result == 0) {
332 			VERBOSE("Using encrypted FIP\n");
333 			io_close(local_image_handle);
334 		}
335 	}
336 	return result;
337 }
338 #endif
339 
open_memmap(const uintptr_t spec)340 static int open_memmap(const uintptr_t spec)
341 {
342 	int result;
343 	uintptr_t local_image_handle;
344 
345 	result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL);
346 	if (result == 0) {
347 		result = io_open(memmap_dev_handle, spec, &local_image_handle);
348 		if (result == 0) {
349 			VERBOSE("Using Memmap\n");
350 			io_close(local_image_handle);
351 		}
352 	}
353 	return result;
354 }
355 
open_semihosting(const uintptr_t spec)356 static int open_semihosting(const uintptr_t spec)
357 {
358 	int result;
359 	uintptr_t local_image_handle;
360 
361 	/* See if the file exists on semi-hosting.*/
362 	result = io_dev_init(sh_dev_handle, (uintptr_t)NULL);
363 	if (result == 0) {
364 		result = io_open(sh_dev_handle, spec, &local_image_handle);
365 		if (result == 0) {
366 			VERBOSE("Using Semi-hosting IO\n");
367 			io_close(local_image_handle);
368 		}
369 	}
370 	return result;
371 }
372 
plat_qemu_io_setup(void)373 void plat_qemu_io_setup(void)
374 {
375 	int io_result;
376 
377 	io_result = register_io_dev_fip(&fip_dev_con);
378 	assert(io_result == 0);
379 
380 	io_result = register_io_dev_memmap(&memmap_dev_con);
381 	assert(io_result == 0);
382 
383 	/* Open connections to devices and cache the handles */
384 	io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL,
385 				&fip_dev_handle);
386 	assert(io_result == 0);
387 
388 	io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL,
389 				&memmap_dev_handle);
390 	assert(io_result == 0);
391 
392 #ifndef DECRYPTION_SUPPORT_none
393 	io_result = register_io_dev_enc(&enc_dev_con);
394 	assert(io_result == 0);
395 
396 	io_result = io_dev_open(enc_dev_con, (uintptr_t)NULL,
397 				&enc_dev_handle);
398 	assert(io_result == 0);
399 #endif
400 
401 	/* Register the additional IO devices on this platform */
402 	io_result = register_io_dev_sh(&sh_dev_con);
403 	assert(io_result == 0);
404 
405 	/* Open connections to devices and cache the handles */
406 	io_result = io_dev_open(sh_dev_con, (uintptr_t)NULL, &sh_dev_handle);
407 	assert(io_result == 0);
408 
409 	/* Ignore improbable errors in release builds */
410 	(void)io_result;
411 }
412 
get_alt_image_source(unsigned int image_id,uintptr_t * dev_handle,uintptr_t * image_spec)413 static int get_alt_image_source(unsigned int image_id, uintptr_t *dev_handle,
414 				  uintptr_t *image_spec)
415 {
416 	int result = open_semihosting((const uintptr_t)&sh_file_spec[image_id]);
417 
418 	if (result == 0) {
419 		*dev_handle = sh_dev_handle;
420 		*image_spec = (uintptr_t)&sh_file_spec[image_id];
421 	}
422 
423 	return result;
424 }
425 
426 /*
427  * Return an IO device handle and specification which can be used to access
428  * an image. Use this to enforce platform load policy
429  */
plat_get_image_source(unsigned int image_id,uintptr_t * dev_handle,uintptr_t * image_spec)430 int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
431 			  uintptr_t *image_spec)
432 {
433 	int result;
434 	const struct plat_io_policy *policy;
435 
436 	assert(image_id < ARRAY_SIZE(policies));
437 
438 	policy = &policies[image_id];
439 	result = policy->check(policy->image_spec);
440 	if (result == 0) {
441 		*image_spec = policy->image_spec;
442 		*dev_handle = *(policy->dev_handle);
443 	} else {
444 		VERBOSE("Trying alternative IO\n");
445 		result = get_alt_image_source(image_id, dev_handle, image_spec);
446 	}
447 
448 	return result;
449 }
450