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