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