blob: b7951b7d358bb5010b8ca5897251fb0dcf1f71a7 [file] [log] [blame]
Jens Wiklander52c798e2015-12-07 14:37:10 +01001/*
2 * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * Redistributions of source code must retain the above copyright notice, this
8 * list of conditions and the following disclaimer.
9 *
10 * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 *
14 * Neither the name of ARM nor the names of its contributors may be used
15 * to endorse or promote products derived from this software without specific
16 * prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include <assert.h>
32#include <bl_common.h> /* For ARRAY_SIZE */
33#include <debug.h>
34#include <firmware_image_package.h>
35#include <io_driver.h>
36#include <io_fip.h>
37#include <io_memmap.h>
38#include <io_semihosting.h>
39#include <io_storage.h>
40#include <platform_def.h>
41#include <semihosting.h>
42#include <string.h>
43
44/* Semihosting filenames */
45#define BL2_IMAGE_NAME "bl2.bin"
46#define BL31_IMAGE_NAME "bl31.bin"
47#define BL32_IMAGE_NAME "bl32.bin"
48#define BL33_IMAGE_NAME "bl33.bin"
49
50#if TRUSTED_BOARD_BOOT
51#define BL2_CERT_NAME "bl2.crt"
52#define TRUSTED_KEY_CERT_NAME "trusted_key.crt"
53#define BL31_KEY_CERT_NAME "bl31_key.crt"
54#define BL32_KEY_CERT_NAME "bl32_key.crt"
55#define BL33_KEY_CERT_NAME "bl33_key.crt"
56#define BL31_CERT_NAME "bl31.crt"
57#define BL32_CERT_NAME "bl32.crt"
58#define BL33_CERT_NAME "bl33.crt"
59#endif /* TRUSTED_BOARD_BOOT */
60
61
62
63/* IO devices */
64static const io_dev_connector_t *fip_dev_con;
65static uintptr_t fip_dev_handle;
66static const io_dev_connector_t *memmap_dev_con;
67static uintptr_t memmap_dev_handle;
68static const io_dev_connector_t *sh_dev_con;
69static uintptr_t sh_dev_handle;
70
71static const io_block_spec_t fip_block_spec = {
72 .offset = PLAT_QEMU_FIP_BASE,
73 .length = PLAT_QEMU_FIP_MAX_SIZE
74};
75
76static const io_uuid_spec_t bl2_uuid_spec = {
77 .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
78};
79
80static const io_uuid_spec_t bl31_uuid_spec = {
81 .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
82};
83
84static const io_uuid_spec_t bl32_uuid_spec = {
85 .uuid = UUID_SECURE_PAYLOAD_BL32,
86};
87
88static const io_uuid_spec_t bl33_uuid_spec = {
89 .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
90};
91
92#if TRUSTED_BOARD_BOOT
93static const io_uuid_spec_t bl2_cert_uuid_spec = {
94 .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2_CERT,
95};
96
97static const io_uuid_spec_t trusted_key_cert_uuid_spec = {
98 .uuid = UUID_TRUSTED_KEY_CERT,
99};
100
101static const io_uuid_spec_t bl31_key_cert_uuid_spec = {
102 .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31_KEY_CERT,
103};
104
105static const io_uuid_spec_t bl32_key_cert_uuid_spec = {
106 .uuid = UUID_SECURE_PAYLOAD_BL32_KEY_CERT,
107};
108
109static const io_uuid_spec_t bl33_key_cert_uuid_spec = {
110 .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33_KEY_CERT,
111};
112
113static const io_uuid_spec_t bl31_cert_uuid_spec = {
114 .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31_CERT,
115};
116
117static const io_uuid_spec_t bl32_cert_uuid_spec = {
118 .uuid = UUID_SECURE_PAYLOAD_BL32_CERT,
119};
120
121static const io_uuid_spec_t bl33_cert_uuid_spec = {
122 .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33_CERT,
123};
124#endif /* TRUSTED_BOARD_BOOT */
125
126static const io_file_spec_t sh_file_spec[] = {
127 [BL2_IMAGE_ID] = {
128 .path = BL2_IMAGE_NAME,
129 .mode = FOPEN_MODE_RB
130 },
131 [BL31_IMAGE_ID] = {
132 .path = BL31_IMAGE_NAME,
133 .mode = FOPEN_MODE_RB
134 },
135 [BL32_IMAGE_ID] = {
136 .path = BL32_IMAGE_NAME,
137 .mode = FOPEN_MODE_RB
138 },
139 [BL33_IMAGE_ID] = {
140 .path = BL33_IMAGE_NAME,
141 .mode = FOPEN_MODE_RB
142 },
143#if TRUSTED_BOARD_BOOT
144 [BL2_CERT_ID] = {
145 .path = BL2_CERT_NAME,
146 .mode = FOPEN_MODE_RB
147 },
148 [TRUSTED_KEY_CERT_ID] = {
149 .path = TRUSTED_KEY_CERT_NAME,
150 .mode = FOPEN_MODE_RB
151 },
152 [BL31_KEY_CERT_ID] = {
153 .path = BL31_KEY_CERT_NAME,
154 .mode = FOPEN_MODE_RB
155 },
156 [BL32_KEY_CERT_ID] = {
157 .path = BL32_KEY_CERT_NAME,
158 .mode = FOPEN_MODE_RB
159 },
160 [BL33_KEY_CERT_ID] = {
161 .path = BL33_KEY_CERT_NAME,
162 .mode = FOPEN_MODE_RB
163 },
164 [BL31_CERT_ID] = {
165 .path = BL31_CERT_NAME,
166 .mode = FOPEN_MODE_RB
167 },
168 [BL32_CERT_ID] = {
169 .path = BL32_CERT_NAME,
170 .mode = FOPEN_MODE_RB
171 },
172 [BL33_CERT_ID] = {
173 .path = BL33_CERT_NAME,
174 .mode = FOPEN_MODE_RB
175 },
176#endif /* TRUSTED_BOARD_BOOT */
177};
178
179
180
181static int open_fip(const uintptr_t spec);
182static int open_memmap(const uintptr_t spec);
183
184struct plat_io_policy {
185 uintptr_t *dev_handle;
186 uintptr_t image_spec;
187 int (*check)(const uintptr_t spec);
188};
189
190/* By default, ARM platforms load images from the FIP */
191static const struct plat_io_policy policies[] = {
192 [FIP_IMAGE_ID] = {
193 &memmap_dev_handle,
194 (uintptr_t)&fip_block_spec,
195 open_memmap
196 },
197 [BL2_IMAGE_ID] = {
198 &fip_dev_handle,
199 (uintptr_t)&bl2_uuid_spec,
200 open_fip
201 },
202 [BL31_IMAGE_ID] = {
203 &fip_dev_handle,
204 (uintptr_t)&bl31_uuid_spec,
205 open_fip
206 },
207 [BL32_IMAGE_ID] = {
208 &fip_dev_handle,
209 (uintptr_t)&bl32_uuid_spec,
210 open_fip
211 },
212 [BL33_IMAGE_ID] = {
213 &fip_dev_handle,
214 (uintptr_t)&bl33_uuid_spec,
215 open_fip
216 },
217#if TRUSTED_BOARD_BOOT
218 [BL2_CERT_ID] = {
219 &fip_dev_handle,
220 (uintptr_t)&bl2_cert_uuid_spec,
221 open_fip
222 },
223 [TRUSTED_KEY_CERT_ID] = {
224 &fip_dev_handle,
225 (uintptr_t)&trusted_key_cert_uuid_spec,
226 open_fip
227 },
228 [BL31_KEY_CERT_ID] = {
229 &fip_dev_handle,
230 (uintptr_t)&bl31_key_cert_uuid_spec,
231 open_fip
232 },
233 [BL32_KEY_CERT_ID] = {
234 &fip_dev_handle,
235 (uintptr_t)&bl32_key_cert_uuid_spec,
236 open_fip
237 },
238 [BL33_KEY_CERT_ID] = {
239 &fip_dev_handle,
240 (uintptr_t)&bl33_key_cert_uuid_spec,
241 open_fip
242 },
243 [BL31_CERT_ID] = {
244 &fip_dev_handle,
245 (uintptr_t)&bl31_cert_uuid_spec,
246 open_fip
247 },
248 [BL32_CERT_ID] = {
249 &fip_dev_handle,
250 (uintptr_t)&bl32_cert_uuid_spec,
251 open_fip
252 },
253 [BL33_CERT_ID] = {
254 &fip_dev_handle,
255 (uintptr_t)&bl33_cert_uuid_spec,
256 open_fip
257 },
258#endif /* TRUSTED_BOARD_BOOT */
259};
260
261static int open_fip(const uintptr_t spec)
262{
263 int result;
264 uintptr_t local_image_handle;
265
266 /* See if a Firmware Image Package is available */
267 result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
268 if (result == 0) {
269 result = io_open(fip_dev_handle, spec, &local_image_handle);
270 if (result == 0) {
271 VERBOSE("Using FIP\n");
272 io_close(local_image_handle);
273 }
274 }
275 return result;
276}
277
278static int open_memmap(const uintptr_t spec)
279{
280 int result;
281 uintptr_t local_image_handle;
282
283 result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL);
284 if (result == 0) {
285 result = io_open(memmap_dev_handle, spec, &local_image_handle);
286 if (result == 0) {
287 VERBOSE("Using Memmap\n");
288 io_close(local_image_handle);
289 }
290 }
291 return result;
292}
293
294static int open_semihosting(const uintptr_t spec)
295{
296 int result;
297 uintptr_t local_image_handle;
298
299 /* See if the file exists on semi-hosting.*/
300 result = io_dev_init(sh_dev_handle, (uintptr_t)NULL);
301 if (result == 0) {
302 result = io_open(sh_dev_handle, spec, &local_image_handle);
303 if (result == 0) {
304 VERBOSE("Using Semi-hosting IO\n");
305 io_close(local_image_handle);
306 }
307 }
308 return result;
309}
310
311void plat_qemu_io_setup(void)
312{
313 int io_result;
314
315 io_result = register_io_dev_fip(&fip_dev_con);
316 assert(io_result == 0);
317
318 io_result = register_io_dev_memmap(&memmap_dev_con);
319 assert(io_result == 0);
320
321 /* Open connections to devices and cache the handles */
322 io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL,
323 &fip_dev_handle);
324 assert(io_result == 0);
325
326 io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL,
327 &memmap_dev_handle);
328 assert(io_result == 0);
329
330 /* Register the additional IO devices on this platform */
331 io_result = register_io_dev_sh(&sh_dev_con);
332 assert(io_result == 0);
333
334 /* Open connections to devices and cache the handles */
335 io_result = io_dev_open(sh_dev_con, (uintptr_t)NULL, &sh_dev_handle);
336 assert(io_result == 0);
337
338 /* Ignore improbable errors in release builds */
339 (void)io_result;
340}
341
342static int get_alt_image_source(unsigned int image_id, uintptr_t *dev_handle,
343 uintptr_t *image_spec)
344{
345 int result = open_semihosting((const uintptr_t)&sh_file_spec[image_id]);
346
347 if (result == 0) {
348 *dev_handle = sh_dev_handle;
349 *image_spec = (uintptr_t)&sh_file_spec[image_id];
350 }
351
352 return result;
353}
354
355/*
356 * Return an IO device handle and specification which can be used to access
357 * an image. Use this to enforce platform load policy
358 */
359int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
360 uintptr_t *image_spec)
361{
362 int result;
363 const struct plat_io_policy *policy;
364
365 assert(image_id < ARRAY_SIZE(policies));
366
367 policy = &policies[image_id];
368 result = policy->check(policy->image_spec);
369 if (result == 0) {
370 *image_spec = policy->image_spec;
371 *dev_handle = *(policy->dev_handle);
372 } else {
373 VERBOSE("Trying alternative IO\n");
374 result = get_alt_image_source(image_id, dev_handle, image_spec);
375 }
376
377 return result;
378}