blob: 0e81cd1997b3739a153cf12d87a02c53d45f33a7 [file] [log] [blame]
Jens Wiklander419e0d22015-12-07 14:37:10 +01001/*
2 * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
3 *
dp-arm82cb2c12017-05-03 09:38:09 +01004 * SPDX-License-Identifier: BSD-3-Clause
Jens Wiklander419e0d22015-12-07 14:37:10 +01005 */
6
7#include <assert.h>
Jens Wiklander419e0d22015-12-07 14:37:10 +01008#include <string.h>
9
Antonio Nino Diaz09d40e02018-12-14 00:18:21 +000010#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
Jens Wiklander419e0d22015-12-07 14:37:10 +010022/* Semihosting filenames */
23#define BL2_IMAGE_NAME "bl2.bin"
24#define BL31_IMAGE_NAME "bl31.bin"
25#define BL32_IMAGE_NAME "bl32.bin"
Jens Wiklandere2af1ca2017-08-24 13:16:26 +020026#define BL32_EXTRA1_IMAGE_NAME "bl32_extra1.bin"
27#define BL32_EXTRA2_IMAGE_NAME "bl32_extra2.bin"
Jens Wiklander419e0d22015-12-07 14:37:10 +010028#define BL33_IMAGE_NAME "bl33.bin"
29
30#if TRUSTED_BOARD_BOOT
Michalis Pappas5cc34b12017-10-18 09:43:37 +080031#define TRUSTED_BOOT_FW_CERT_NAME "tb_fw.crt"
Jens Wiklander419e0d22015-12-07 14:37:10 +010032#define TRUSTED_KEY_CERT_NAME "trusted_key.crt"
Michalis Pappas5cc34b12017-10-18 09:43:37 +080033#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"
Jens Wiklander419e0d22015-12-07 14:37:10 +010039#endif /* TRUSTED_BOARD_BOOT */
40
41
42
43/* IO devices */
44static const io_dev_connector_t *fip_dev_con;
45static uintptr_t fip_dev_handle;
46static const io_dev_connector_t *memmap_dev_con;
47static uintptr_t memmap_dev_handle;
48static const io_dev_connector_t *sh_dev_con;
49static uintptr_t sh_dev_handle;
50
51static const io_block_spec_t fip_block_spec = {
52 .offset = PLAT_QEMU_FIP_BASE,
53 .length = PLAT_QEMU_FIP_MAX_SIZE
54};
55
56static const io_uuid_spec_t bl2_uuid_spec = {
57 .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
58};
59
60static const io_uuid_spec_t bl31_uuid_spec = {
61 .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
62};
63
64static const io_uuid_spec_t bl32_uuid_spec = {
65 .uuid = UUID_SECURE_PAYLOAD_BL32,
66};
67
Jens Wiklandere2af1ca2017-08-24 13:16:26 +020068static const io_uuid_spec_t bl32_extra1_uuid_spec = {
69 .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1,
70};
71
72static const io_uuid_spec_t bl32_extra2_uuid_spec = {
73 .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2,
74};
75
Jens Wiklander419e0d22015-12-07 14:37:10 +010076static const io_uuid_spec_t bl33_uuid_spec = {
77 .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
78};
79
80#if TRUSTED_BOARD_BOOT
Michalis Pappas5cc34b12017-10-18 09:43:37 +080081static const io_uuid_spec_t tb_fw_cert_uuid_spec = {
82 .uuid = UUID_TRUSTED_BOOT_FW_CERT,
Jens Wiklander419e0d22015-12-07 14:37:10 +010083};
84
85static const io_uuid_spec_t trusted_key_cert_uuid_spec = {
86 .uuid = UUID_TRUSTED_KEY_CERT,
87};
88
Michalis Pappas5cc34b12017-10-18 09:43:37 +080089static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = {
90 .uuid = UUID_SOC_FW_KEY_CERT,
Jens Wiklander419e0d22015-12-07 14:37:10 +010091};
92
Michalis Pappas5cc34b12017-10-18 09:43:37 +080093static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = {
94 .uuid = UUID_TRUSTED_OS_FW_KEY_CERT,
Jens Wiklander419e0d22015-12-07 14:37:10 +010095};
96
Michalis Pappas5cc34b12017-10-18 09:43:37 +080097static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = {
98 .uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
Jens Wiklander419e0d22015-12-07 14:37:10 +010099};
100
Michalis Pappas5cc34b12017-10-18 09:43:37 +0800101static const io_uuid_spec_t soc_fw_cert_uuid_spec = {
102 .uuid = UUID_SOC_FW_CONTENT_CERT,
Jens Wiklander419e0d22015-12-07 14:37:10 +0100103};
104
Michalis Pappas5cc34b12017-10-18 09:43:37 +0800105static const io_uuid_spec_t tos_fw_cert_uuid_spec = {
106 .uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT,
Jens Wiklander419e0d22015-12-07 14:37:10 +0100107};
108
Michalis Pappas5cc34b12017-10-18 09:43:37 +0800109static const io_uuid_spec_t nt_fw_cert_uuid_spec = {
110 .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT,
Jens Wiklander419e0d22015-12-07 14:37:10 +0100111};
112#endif /* TRUSTED_BOARD_BOOT */
113
114static 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 },
Jens Wiklandere2af1ca2017-08-24 13:16:26 +0200127 [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 },
Jens Wiklander419e0d22015-12-07 14:37:10 +0100135 [BL33_IMAGE_ID] = {
136 .path = BL33_IMAGE_NAME,
137 .mode = FOPEN_MODE_RB
138 },
139#if TRUSTED_BOARD_BOOT
Michalis Pappas5cc34b12017-10-18 09:43:37 +0800140 [TRUSTED_BOOT_FW_CERT_ID] = {
141 .path = TRUSTED_BOOT_FW_CERT_NAME,
Jens Wiklander419e0d22015-12-07 14:37:10 +0100142 .mode = FOPEN_MODE_RB
143 },
144 [TRUSTED_KEY_CERT_ID] = {
145 .path = TRUSTED_KEY_CERT_NAME,
146 .mode = FOPEN_MODE_RB
147 },
Michalis Pappas5cc34b12017-10-18 09:43:37 +0800148 [SOC_FW_KEY_CERT_ID] = {
149 .path = SOC_FW_KEY_CERT_NAME,
Jens Wiklander419e0d22015-12-07 14:37:10 +0100150 .mode = FOPEN_MODE_RB
151 },
Michalis Pappas5cc34b12017-10-18 09:43:37 +0800152 [TRUSTED_OS_FW_KEY_CERT_ID] = {
153 .path = TOS_FW_KEY_CERT_NAME,
Jens Wiklander419e0d22015-12-07 14:37:10 +0100154 .mode = FOPEN_MODE_RB
155 },
Michalis Pappas5cc34b12017-10-18 09:43:37 +0800156 [NON_TRUSTED_FW_KEY_CERT_ID] = {
157 .path = NT_FW_KEY_CERT_NAME,
Jens Wiklander419e0d22015-12-07 14:37:10 +0100158 .mode = FOPEN_MODE_RB
159 },
Michalis Pappas5cc34b12017-10-18 09:43:37 +0800160 [SOC_FW_CONTENT_CERT_ID] = {
161 .path = SOC_FW_CONTENT_CERT_NAME,
Jens Wiklander419e0d22015-12-07 14:37:10 +0100162 .mode = FOPEN_MODE_RB
163 },
Michalis Pappas5cc34b12017-10-18 09:43:37 +0800164 [TRUSTED_OS_FW_CONTENT_CERT_ID] = {
165 .path = TOS_FW_CONTENT_CERT_NAME,
Jens Wiklander419e0d22015-12-07 14:37:10 +0100166 .mode = FOPEN_MODE_RB
167 },
Michalis Pappas5cc34b12017-10-18 09:43:37 +0800168 [NON_TRUSTED_FW_CONTENT_CERT_ID] = {
169 .path = NT_FW_CONTENT_CERT_NAME,
Jens Wiklander419e0d22015-12-07 14:37:10 +0100170 .mode = FOPEN_MODE_RB
171 },
172#endif /* TRUSTED_BOARD_BOOT */
173};
174
175
176
177static int open_fip(const uintptr_t spec);
178static int open_memmap(const uintptr_t spec);
179
180struct 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 */
187static 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 },
Jens Wiklandere2af1ca2017-08-24 13:16:26 +0200208 [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 },
Jens Wiklander419e0d22015-12-07 14:37:10 +0100218 [BL33_IMAGE_ID] = {
219 &fip_dev_handle,
220 (uintptr_t)&bl33_uuid_spec,
221 open_fip
222 },
223#if TRUSTED_BOARD_BOOT
Michalis Pappas5cc34b12017-10-18 09:43:37 +0800224 [TRUSTED_BOOT_FW_CERT_ID] = {
Jens Wiklander419e0d22015-12-07 14:37:10 +0100225 &fip_dev_handle,
Michalis Pappas5cc34b12017-10-18 09:43:37 +0800226 (uintptr_t)&tb_fw_cert_uuid_spec,
Jens Wiklander419e0d22015-12-07 14:37:10 +0100227 open_fip
228 },
229 [TRUSTED_KEY_CERT_ID] = {
230 &fip_dev_handle,
231 (uintptr_t)&trusted_key_cert_uuid_spec,
232 open_fip
233 },
Michalis Pappas5cc34b12017-10-18 09:43:37 +0800234 [SOC_FW_KEY_CERT_ID] = {
Jens Wiklander419e0d22015-12-07 14:37:10 +0100235 &fip_dev_handle,
Michalis Pappas5cc34b12017-10-18 09:43:37 +0800236 (uintptr_t)&soc_fw_key_cert_uuid_spec,
Jens Wiklander419e0d22015-12-07 14:37:10 +0100237 open_fip
238 },
Michalis Pappas5cc34b12017-10-18 09:43:37 +0800239 [TRUSTED_OS_FW_KEY_CERT_ID] = {
Jens Wiklander419e0d22015-12-07 14:37:10 +0100240 &fip_dev_handle,
Michalis Pappas5cc34b12017-10-18 09:43:37 +0800241 (uintptr_t)&tos_fw_key_cert_uuid_spec,
Jens Wiklander419e0d22015-12-07 14:37:10 +0100242 open_fip
243 },
Michalis Pappas5cc34b12017-10-18 09:43:37 +0800244 [NON_TRUSTED_FW_KEY_CERT_ID] = {
Jens Wiklander419e0d22015-12-07 14:37:10 +0100245 &fip_dev_handle,
Michalis Pappas5cc34b12017-10-18 09:43:37 +0800246 (uintptr_t)&nt_fw_key_cert_uuid_spec,
Jens Wiklander419e0d22015-12-07 14:37:10 +0100247 open_fip
248 },
Michalis Pappas5cc34b12017-10-18 09:43:37 +0800249 [SOC_FW_CONTENT_CERT_ID] = {
Jens Wiklander419e0d22015-12-07 14:37:10 +0100250 &fip_dev_handle,
Michalis Pappas5cc34b12017-10-18 09:43:37 +0800251 (uintptr_t)&soc_fw_cert_uuid_spec,
Jens Wiklander419e0d22015-12-07 14:37:10 +0100252 open_fip
253 },
Michalis Pappas5cc34b12017-10-18 09:43:37 +0800254 [TRUSTED_OS_FW_CONTENT_CERT_ID] = {
Jens Wiklander419e0d22015-12-07 14:37:10 +0100255 &fip_dev_handle,
Michalis Pappas5cc34b12017-10-18 09:43:37 +0800256 (uintptr_t)&tos_fw_cert_uuid_spec,
Jens Wiklander419e0d22015-12-07 14:37:10 +0100257 open_fip
258 },
Michalis Pappas5cc34b12017-10-18 09:43:37 +0800259 [NON_TRUSTED_FW_CONTENT_CERT_ID] = {
Jens Wiklander419e0d22015-12-07 14:37:10 +0100260 &fip_dev_handle,
Michalis Pappas5cc34b12017-10-18 09:43:37 +0800261 (uintptr_t)&nt_fw_cert_uuid_spec,
Jens Wiklander419e0d22015-12-07 14:37:10 +0100262 open_fip
263 },
264#endif /* TRUSTED_BOARD_BOOT */
265};
266
267static 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
284static 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
300static 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
317void 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
348static 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 */
365int 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}