blob: 1918f21d5d9011377438288a91dc421a0c73ea30 [file] [log] [blame]
Jens Wiklander52c798e2015-12-07 14:37:10 +01001/*
2 * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
3 *
dp-armfa3cf0b2017-05-03 09:38:09 +01004 * SPDX-License-Identifier: BSD-3-Clause
Jens Wiklander52c798e2015-12-07 14:37:10 +01005 */
6
7#include <assert.h>
8#include <bl_common.h> /* For ARRAY_SIZE */
9#include <debug.h>
10#include <firmware_image_package.h>
11#include <io_driver.h>
12#include <io_fip.h>
13#include <io_memmap.h>
14#include <io_semihosting.h>
15#include <io_storage.h>
16#include <platform_def.h>
17#include <semihosting.h>
18#include <string.h>
19
20/* Semihosting filenames */
21#define BL2_IMAGE_NAME "bl2.bin"
22#define BL31_IMAGE_NAME "bl31.bin"
23#define BL32_IMAGE_NAME "bl32.bin"
Jens Wiklander0acbaaa2017-08-24 13:16:26 +020024#define BL32_EXTRA1_IMAGE_NAME "bl32_extra1.bin"
25#define BL32_EXTRA2_IMAGE_NAME "bl32_extra2.bin"
Jens Wiklander52c798e2015-12-07 14:37:10 +010026#define BL33_IMAGE_NAME "bl33.bin"
27
28#if TRUSTED_BOARD_BOOT
Michalis Pappas3469cd02017-10-18 09:43:37 +080029#define TRUSTED_BOOT_FW_CERT_NAME "tb_fw.crt"
Jens Wiklander52c798e2015-12-07 14:37:10 +010030#define TRUSTED_KEY_CERT_NAME "trusted_key.crt"
Michalis Pappas3469cd02017-10-18 09:43:37 +080031#define SOC_FW_KEY_CERT_NAME "soc_fw_key.crt"
32#define TOS_FW_KEY_CERT_NAME "tos_fw_key.crt"
33#define NT_FW_KEY_CERT_NAME "nt_fw_key.crt"
34#define SOC_FW_CONTENT_CERT_NAME "soc_fw_content.crt"
35#define TOS_FW_CONTENT_CERT_NAME "tos_fw_content.crt"
36#define NT_FW_CONTENT_CERT_NAME "nt_fw_content.crt"
Jens Wiklander52c798e2015-12-07 14:37:10 +010037#endif /* TRUSTED_BOARD_BOOT */
38
39
40
41/* IO devices */
42static const io_dev_connector_t *fip_dev_con;
43static uintptr_t fip_dev_handle;
44static const io_dev_connector_t *memmap_dev_con;
45static uintptr_t memmap_dev_handle;
46static const io_dev_connector_t *sh_dev_con;
47static uintptr_t sh_dev_handle;
48
49static const io_block_spec_t fip_block_spec = {
50 .offset = PLAT_QEMU_FIP_BASE,
51 .length = PLAT_QEMU_FIP_MAX_SIZE
52};
53
54static const io_uuid_spec_t bl2_uuid_spec = {
55 .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
56};
57
58static const io_uuid_spec_t bl31_uuid_spec = {
59 .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
60};
61
62static const io_uuid_spec_t bl32_uuid_spec = {
63 .uuid = UUID_SECURE_PAYLOAD_BL32,
64};
65
Jens Wiklander0acbaaa2017-08-24 13:16:26 +020066static const io_uuid_spec_t bl32_extra1_uuid_spec = {
67 .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1,
68};
69
70static const io_uuid_spec_t bl32_extra2_uuid_spec = {
71 .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2,
72};
73
Jens Wiklander52c798e2015-12-07 14:37:10 +010074static const io_uuid_spec_t bl33_uuid_spec = {
75 .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
76};
77
78#if TRUSTED_BOARD_BOOT
Michalis Pappas3469cd02017-10-18 09:43:37 +080079static const io_uuid_spec_t tb_fw_cert_uuid_spec = {
80 .uuid = UUID_TRUSTED_BOOT_FW_CERT,
Jens Wiklander52c798e2015-12-07 14:37:10 +010081};
82
83static const io_uuid_spec_t trusted_key_cert_uuid_spec = {
84 .uuid = UUID_TRUSTED_KEY_CERT,
85};
86
Michalis Pappas3469cd02017-10-18 09:43:37 +080087static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = {
88 .uuid = UUID_SOC_FW_KEY_CERT,
Jens Wiklander52c798e2015-12-07 14:37:10 +010089};
90
Michalis Pappas3469cd02017-10-18 09:43:37 +080091static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = {
92 .uuid = UUID_TRUSTED_OS_FW_KEY_CERT,
Jens Wiklander52c798e2015-12-07 14:37:10 +010093};
94
Michalis Pappas3469cd02017-10-18 09:43:37 +080095static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = {
96 .uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
Jens Wiklander52c798e2015-12-07 14:37:10 +010097};
98
Michalis Pappas3469cd02017-10-18 09:43:37 +080099static const io_uuid_spec_t soc_fw_cert_uuid_spec = {
100 .uuid = UUID_SOC_FW_CONTENT_CERT,
Jens Wiklander52c798e2015-12-07 14:37:10 +0100101};
102
Michalis Pappas3469cd02017-10-18 09:43:37 +0800103static const io_uuid_spec_t tos_fw_cert_uuid_spec = {
104 .uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT,
Jens Wiklander52c798e2015-12-07 14:37:10 +0100105};
106
Michalis Pappas3469cd02017-10-18 09:43:37 +0800107static const io_uuid_spec_t nt_fw_cert_uuid_spec = {
108 .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT,
Jens Wiklander52c798e2015-12-07 14:37:10 +0100109};
110#endif /* TRUSTED_BOARD_BOOT */
111
112static const io_file_spec_t sh_file_spec[] = {
113 [BL2_IMAGE_ID] = {
114 .path = BL2_IMAGE_NAME,
115 .mode = FOPEN_MODE_RB
116 },
117 [BL31_IMAGE_ID] = {
118 .path = BL31_IMAGE_NAME,
119 .mode = FOPEN_MODE_RB
120 },
121 [BL32_IMAGE_ID] = {
122 .path = BL32_IMAGE_NAME,
123 .mode = FOPEN_MODE_RB
124 },
Jens Wiklander0acbaaa2017-08-24 13:16:26 +0200125 [BL32_EXTRA1_IMAGE_ID] = {
126 .path = BL32_EXTRA1_IMAGE_NAME,
127 .mode = FOPEN_MODE_RB
128 },
129 [BL32_EXTRA2_IMAGE_ID] = {
130 .path = BL32_EXTRA2_IMAGE_NAME,
131 .mode = FOPEN_MODE_RB
132 },
Jens Wiklander52c798e2015-12-07 14:37:10 +0100133 [BL33_IMAGE_ID] = {
134 .path = BL33_IMAGE_NAME,
135 .mode = FOPEN_MODE_RB
136 },
137#if TRUSTED_BOARD_BOOT
Michalis Pappas3469cd02017-10-18 09:43:37 +0800138 [TRUSTED_BOOT_FW_CERT_ID] = {
139 .path = TRUSTED_BOOT_FW_CERT_NAME,
Jens Wiklander52c798e2015-12-07 14:37:10 +0100140 .mode = FOPEN_MODE_RB
141 },
142 [TRUSTED_KEY_CERT_ID] = {
143 .path = TRUSTED_KEY_CERT_NAME,
144 .mode = FOPEN_MODE_RB
145 },
Michalis Pappas3469cd02017-10-18 09:43:37 +0800146 [SOC_FW_KEY_CERT_ID] = {
147 .path = SOC_FW_KEY_CERT_NAME,
Jens Wiklander52c798e2015-12-07 14:37:10 +0100148 .mode = FOPEN_MODE_RB
149 },
Michalis Pappas3469cd02017-10-18 09:43:37 +0800150 [TRUSTED_OS_FW_KEY_CERT_ID] = {
151 .path = TOS_FW_KEY_CERT_NAME,
Jens Wiklander52c798e2015-12-07 14:37:10 +0100152 .mode = FOPEN_MODE_RB
153 },
Michalis Pappas3469cd02017-10-18 09:43:37 +0800154 [NON_TRUSTED_FW_KEY_CERT_ID] = {
155 .path = NT_FW_KEY_CERT_NAME,
Jens Wiklander52c798e2015-12-07 14:37:10 +0100156 .mode = FOPEN_MODE_RB
157 },
Michalis Pappas3469cd02017-10-18 09:43:37 +0800158 [SOC_FW_CONTENT_CERT_ID] = {
159 .path = SOC_FW_CONTENT_CERT_NAME,
Jens Wiklander52c798e2015-12-07 14:37:10 +0100160 .mode = FOPEN_MODE_RB
161 },
Michalis Pappas3469cd02017-10-18 09:43:37 +0800162 [TRUSTED_OS_FW_CONTENT_CERT_ID] = {
163 .path = TOS_FW_CONTENT_CERT_NAME,
Jens Wiklander52c798e2015-12-07 14:37:10 +0100164 .mode = FOPEN_MODE_RB
165 },
Michalis Pappas3469cd02017-10-18 09:43:37 +0800166 [NON_TRUSTED_FW_CONTENT_CERT_ID] = {
167 .path = NT_FW_CONTENT_CERT_NAME,
Jens Wiklander52c798e2015-12-07 14:37:10 +0100168 .mode = FOPEN_MODE_RB
169 },
170#endif /* TRUSTED_BOARD_BOOT */
171};
172
173
174
175static int open_fip(const uintptr_t spec);
176static int open_memmap(const uintptr_t spec);
177
178struct plat_io_policy {
179 uintptr_t *dev_handle;
180 uintptr_t image_spec;
181 int (*check)(const uintptr_t spec);
182};
183
184/* By default, ARM platforms load images from the FIP */
185static const struct plat_io_policy policies[] = {
186 [FIP_IMAGE_ID] = {
187 &memmap_dev_handle,
188 (uintptr_t)&fip_block_spec,
189 open_memmap
190 },
191 [BL2_IMAGE_ID] = {
192 &fip_dev_handle,
193 (uintptr_t)&bl2_uuid_spec,
194 open_fip
195 },
196 [BL31_IMAGE_ID] = {
197 &fip_dev_handle,
198 (uintptr_t)&bl31_uuid_spec,
199 open_fip
200 },
201 [BL32_IMAGE_ID] = {
202 &fip_dev_handle,
203 (uintptr_t)&bl32_uuid_spec,
204 open_fip
205 },
Jens Wiklander0acbaaa2017-08-24 13:16:26 +0200206 [BL32_EXTRA1_IMAGE_ID] = {
207 &fip_dev_handle,
208 (uintptr_t)&bl32_extra1_uuid_spec,
209 open_fip
210 },
211 [BL32_EXTRA2_IMAGE_ID] = {
212 &fip_dev_handle,
213 (uintptr_t)&bl32_extra2_uuid_spec,
214 open_fip
215 },
Jens Wiklander52c798e2015-12-07 14:37:10 +0100216 [BL33_IMAGE_ID] = {
217 &fip_dev_handle,
218 (uintptr_t)&bl33_uuid_spec,
219 open_fip
220 },
221#if TRUSTED_BOARD_BOOT
Michalis Pappas3469cd02017-10-18 09:43:37 +0800222 [TRUSTED_BOOT_FW_CERT_ID] = {
Jens Wiklander52c798e2015-12-07 14:37:10 +0100223 &fip_dev_handle,
Michalis Pappas3469cd02017-10-18 09:43:37 +0800224 (uintptr_t)&tb_fw_cert_uuid_spec,
Jens Wiklander52c798e2015-12-07 14:37:10 +0100225 open_fip
226 },
227 [TRUSTED_KEY_CERT_ID] = {
228 &fip_dev_handle,
229 (uintptr_t)&trusted_key_cert_uuid_spec,
230 open_fip
231 },
Michalis Pappas3469cd02017-10-18 09:43:37 +0800232 [SOC_FW_KEY_CERT_ID] = {
Jens Wiklander52c798e2015-12-07 14:37:10 +0100233 &fip_dev_handle,
Michalis Pappas3469cd02017-10-18 09:43:37 +0800234 (uintptr_t)&soc_fw_key_cert_uuid_spec,
Jens Wiklander52c798e2015-12-07 14:37:10 +0100235 open_fip
236 },
Michalis Pappas3469cd02017-10-18 09:43:37 +0800237 [TRUSTED_OS_FW_KEY_CERT_ID] = {
Jens Wiklander52c798e2015-12-07 14:37:10 +0100238 &fip_dev_handle,
Michalis Pappas3469cd02017-10-18 09:43:37 +0800239 (uintptr_t)&tos_fw_key_cert_uuid_spec,
Jens Wiklander52c798e2015-12-07 14:37:10 +0100240 open_fip
241 },
Michalis Pappas3469cd02017-10-18 09:43:37 +0800242 [NON_TRUSTED_FW_KEY_CERT_ID] = {
Jens Wiklander52c798e2015-12-07 14:37:10 +0100243 &fip_dev_handle,
Michalis Pappas3469cd02017-10-18 09:43:37 +0800244 (uintptr_t)&nt_fw_key_cert_uuid_spec,
Jens Wiklander52c798e2015-12-07 14:37:10 +0100245 open_fip
246 },
Michalis Pappas3469cd02017-10-18 09:43:37 +0800247 [SOC_FW_CONTENT_CERT_ID] = {
Jens Wiklander52c798e2015-12-07 14:37:10 +0100248 &fip_dev_handle,
Michalis Pappas3469cd02017-10-18 09:43:37 +0800249 (uintptr_t)&soc_fw_cert_uuid_spec,
Jens Wiklander52c798e2015-12-07 14:37:10 +0100250 open_fip
251 },
Michalis Pappas3469cd02017-10-18 09:43:37 +0800252 [TRUSTED_OS_FW_CONTENT_CERT_ID] = {
Jens Wiklander52c798e2015-12-07 14:37:10 +0100253 &fip_dev_handle,
Michalis Pappas3469cd02017-10-18 09:43:37 +0800254 (uintptr_t)&tos_fw_cert_uuid_spec,
Jens Wiklander52c798e2015-12-07 14:37:10 +0100255 open_fip
256 },
Michalis Pappas3469cd02017-10-18 09:43:37 +0800257 [NON_TRUSTED_FW_CONTENT_CERT_ID] = {
Jens Wiklander52c798e2015-12-07 14:37:10 +0100258 &fip_dev_handle,
Michalis Pappas3469cd02017-10-18 09:43:37 +0800259 (uintptr_t)&nt_fw_cert_uuid_spec,
Jens Wiklander52c798e2015-12-07 14:37:10 +0100260 open_fip
261 },
262#endif /* TRUSTED_BOARD_BOOT */
263};
264
265static int open_fip(const uintptr_t spec)
266{
267 int result;
268 uintptr_t local_image_handle;
269
270 /* See if a Firmware Image Package is available */
271 result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
272 if (result == 0) {
273 result = io_open(fip_dev_handle, spec, &local_image_handle);
274 if (result == 0) {
275 VERBOSE("Using FIP\n");
276 io_close(local_image_handle);
277 }
278 }
279 return result;
280}
281
282static int open_memmap(const uintptr_t spec)
283{
284 int result;
285 uintptr_t local_image_handle;
286
287 result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL);
288 if (result == 0) {
289 result = io_open(memmap_dev_handle, spec, &local_image_handle);
290 if (result == 0) {
291 VERBOSE("Using Memmap\n");
292 io_close(local_image_handle);
293 }
294 }
295 return result;
296}
297
298static int open_semihosting(const uintptr_t spec)
299{
300 int result;
301 uintptr_t local_image_handle;
302
303 /* See if the file exists on semi-hosting.*/
304 result = io_dev_init(sh_dev_handle, (uintptr_t)NULL);
305 if (result == 0) {
306 result = io_open(sh_dev_handle, spec, &local_image_handle);
307 if (result == 0) {
308 VERBOSE("Using Semi-hosting IO\n");
309 io_close(local_image_handle);
310 }
311 }
312 return result;
313}
314
315void plat_qemu_io_setup(void)
316{
317 int io_result;
318
319 io_result = register_io_dev_fip(&fip_dev_con);
320 assert(io_result == 0);
321
322 io_result = register_io_dev_memmap(&memmap_dev_con);
323 assert(io_result == 0);
324
325 /* Open connections to devices and cache the handles */
326 io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL,
327 &fip_dev_handle);
328 assert(io_result == 0);
329
330 io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL,
331 &memmap_dev_handle);
332 assert(io_result == 0);
333
334 /* Register the additional IO devices on this platform */
335 io_result = register_io_dev_sh(&sh_dev_con);
336 assert(io_result == 0);
337
338 /* Open connections to devices and cache the handles */
339 io_result = io_dev_open(sh_dev_con, (uintptr_t)NULL, &sh_dev_handle);
340 assert(io_result == 0);
341
342 /* Ignore improbable errors in release builds */
343 (void)io_result;
344}
345
346static int get_alt_image_source(unsigned int image_id, uintptr_t *dev_handle,
347 uintptr_t *image_spec)
348{
349 int result = open_semihosting((const uintptr_t)&sh_file_spec[image_id]);
350
351 if (result == 0) {
352 *dev_handle = sh_dev_handle;
353 *image_spec = (uintptr_t)&sh_file_spec[image_id];
354 }
355
356 return result;
357}
358
359/*
360 * Return an IO device handle and specification which can be used to access
361 * an image. Use this to enforce platform load policy
362 */
363int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
364 uintptr_t *image_spec)
365{
366 int result;
367 const struct plat_io_policy *policy;
368
369 assert(image_id < ARRAY_SIZE(policies));
370
371 policy = &policies[image_id];
372 result = policy->check(policy->image_spec);
373 if (result == 0) {
374 *image_spec = policy->image_spec;
375 *dev_handle = *(policy->dev_handle);
376 } else {
377 VERBOSE("Trying alternative IO\n");
378 result = get_alt_image_source(image_id, dev_handle, image_spec);
379 }
380
381 return result;
382}