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 <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"
24 #define BL32_EXTRA1_IMAGE_NAME "bl32_extra1.bin"
25 #define BL32_EXTRA2_IMAGE_NAME "bl32_extra2.bin"
26 #define BL33_IMAGE_NAME "bl33.bin"
27
28 #if TRUSTED_BOARD_BOOT
29 #define TRUSTED_BOOT_FW_CERT_NAME "tb_fw.crt"
30 #define TRUSTED_KEY_CERT_NAME "trusted_key.crt"
31 #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"
37 #endif /* TRUSTED_BOARD_BOOT */
38
39
40
41 /* IO devices */
42 static const io_dev_connector_t *fip_dev_con;
43 static uintptr_t fip_dev_handle;
44 static const io_dev_connector_t *memmap_dev_con;
45 static uintptr_t memmap_dev_handle;
46 static const io_dev_connector_t *sh_dev_con;
47 static uintptr_t sh_dev_handle;
48
49 static const io_block_spec_t fip_block_spec = {
50 .offset = PLAT_QEMU_FIP_BASE,
51 .length = PLAT_QEMU_FIP_MAX_SIZE
52 };
53
54 static const io_uuid_spec_t bl2_uuid_spec = {
55 .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
56 };
57
58 static const io_uuid_spec_t bl31_uuid_spec = {
59 .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
60 };
61
62 static const io_uuid_spec_t bl32_uuid_spec = {
63 .uuid = UUID_SECURE_PAYLOAD_BL32,
64 };
65
66 static const io_uuid_spec_t bl32_extra1_uuid_spec = {
67 .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1,
68 };
69
70 static const io_uuid_spec_t bl32_extra2_uuid_spec = {
71 .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2,
72 };
73
74 static const io_uuid_spec_t bl33_uuid_spec = {
75 .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
76 };
77
78 #if TRUSTED_BOARD_BOOT
79 static const io_uuid_spec_t tb_fw_cert_uuid_spec = {
80 .uuid = UUID_TRUSTED_BOOT_FW_CERT,
81 };
82
83 static const io_uuid_spec_t trusted_key_cert_uuid_spec = {
84 .uuid = UUID_TRUSTED_KEY_CERT,
85 };
86
87 static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = {
88 .uuid = UUID_SOC_FW_KEY_CERT,
89 };
90
91 static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = {
92 .uuid = UUID_TRUSTED_OS_FW_KEY_CERT,
93 };
94
95 static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = {
96 .uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
97 };
98
99 static const io_uuid_spec_t soc_fw_cert_uuid_spec = {
100 .uuid = UUID_SOC_FW_CONTENT_CERT,
101 };
102
103 static const io_uuid_spec_t tos_fw_cert_uuid_spec = {
104 .uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT,
105 };
106
107 static const io_uuid_spec_t nt_fw_cert_uuid_spec = {
108 .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT,
109 };
110 #endif /* TRUSTED_BOARD_BOOT */
111
112 static 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 },
125 [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 },
133 [BL33_IMAGE_ID] = {
134 .path = BL33_IMAGE_NAME,
135 .mode = FOPEN_MODE_RB
136 },
137 #if TRUSTED_BOARD_BOOT
138 [TRUSTED_BOOT_FW_CERT_ID] = {
139 .path = TRUSTED_BOOT_FW_CERT_NAME,
140 .mode = FOPEN_MODE_RB
141 },
142 [TRUSTED_KEY_CERT_ID] = {
143 .path = TRUSTED_KEY_CERT_NAME,
144 .mode = FOPEN_MODE_RB
145 },
146 [SOC_FW_KEY_CERT_ID] = {
147 .path = SOC_FW_KEY_CERT_NAME,
148 .mode = FOPEN_MODE_RB
149 },
150 [TRUSTED_OS_FW_KEY_CERT_ID] = {
151 .path = TOS_FW_KEY_CERT_NAME,
152 .mode = FOPEN_MODE_RB
153 },
154 [NON_TRUSTED_FW_KEY_CERT_ID] = {
155 .path = NT_FW_KEY_CERT_NAME,
156 .mode = FOPEN_MODE_RB
157 },
158 [SOC_FW_CONTENT_CERT_ID] = {
159 .path = SOC_FW_CONTENT_CERT_NAME,
160 .mode = FOPEN_MODE_RB
161 },
162 [TRUSTED_OS_FW_CONTENT_CERT_ID] = {
163 .path = TOS_FW_CONTENT_CERT_NAME,
164 .mode = FOPEN_MODE_RB
165 },
166 [NON_TRUSTED_FW_CONTENT_CERT_ID] = {
167 .path = NT_FW_CONTENT_CERT_NAME,
168 .mode = FOPEN_MODE_RB
169 },
170 #endif /* TRUSTED_BOARD_BOOT */
171 };
172
173
174
175 static int open_fip(const uintptr_t spec);
176 static int open_memmap(const uintptr_t spec);
177
178 struct 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 */
185 static 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 },
206 [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 },
216 [BL33_IMAGE_ID] = {
217 &fip_dev_handle,
218 (uintptr_t)&bl33_uuid_spec,
219 open_fip
220 },
221 #if TRUSTED_BOARD_BOOT
222 [TRUSTED_BOOT_FW_CERT_ID] = {
223 &fip_dev_handle,
224 (uintptr_t)&tb_fw_cert_uuid_spec,
225 open_fip
226 },
227 [TRUSTED_KEY_CERT_ID] = {
228 &fip_dev_handle,
229 (uintptr_t)&trusted_key_cert_uuid_spec,
230 open_fip
231 },
232 [SOC_FW_KEY_CERT_ID] = {
233 &fip_dev_handle,
234 (uintptr_t)&soc_fw_key_cert_uuid_spec,
235 open_fip
236 },
237 [TRUSTED_OS_FW_KEY_CERT_ID] = {
238 &fip_dev_handle,
239 (uintptr_t)&tos_fw_key_cert_uuid_spec,
240 open_fip
241 },
242 [NON_TRUSTED_FW_KEY_CERT_ID] = {
243 &fip_dev_handle,
244 (uintptr_t)&nt_fw_key_cert_uuid_spec,
245 open_fip
246 },
247 [SOC_FW_CONTENT_CERT_ID] = {
248 &fip_dev_handle,
249 (uintptr_t)&soc_fw_cert_uuid_spec,
250 open_fip
251 },
252 [TRUSTED_OS_FW_CONTENT_CERT_ID] = {
253 &fip_dev_handle,
254 (uintptr_t)&tos_fw_cert_uuid_spec,
255 open_fip
256 },
257 [NON_TRUSTED_FW_CONTENT_CERT_ID] = {
258 &fip_dev_handle,
259 (uintptr_t)&nt_fw_cert_uuid_spec,
260 open_fip
261 },
262 #endif /* TRUSTED_BOARD_BOOT */
263 };
264
open_fip(const uintptr_t spec)265 static 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
open_memmap(const uintptr_t spec)282 static 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
open_semihosting(const uintptr_t spec)298 static 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
plat_qemu_io_setup(void)315 void 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
get_alt_image_source(unsigned int image_id,uintptr_t * dev_handle,uintptr_t * image_spec)346 static 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 */
plat_get_image_source(unsigned int image_id,uintptr_t * dev_handle,uintptr_t * image_spec)363 int 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 }
383