blob: 153fdfe8d88a8aaf556c90f3e154313be5b4e556 [file] [log] [blame]
Dan Handley9df48042015-03-19 18:58:55 +00001/*
2 * Copyright (c) 2015, 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#include <assert.h>
Juan Castillo3a66aca2015-04-13 17:36:19 +010031#include <bl_common.h> /* For ARRAY_SIZE */
Dan Handley9df48042015-03-19 18:58:55 +000032#include <debug.h>
Juan Castillo3a66aca2015-04-13 17:36:19 +010033#include <firmware_image_package.h>
Dan Handley9df48042015-03-19 18:58:55 +000034#include <io_driver.h>
35#include <io_fip.h>
36#include <io_memmap.h>
37#include <io_storage.h>
38#include <platform_def.h>
Dan Handley9df48042015-03-19 18:58:55 +000039#include <string.h>
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;
46
47static const io_block_spec_t fip_block_spec = {
48 .offset = PLAT_ARM_FIP_BASE,
49 .length = PLAT_ARM_FIP_MAX_SIZE
50};
51
Juan Castillo3a66aca2015-04-13 17:36:19 +010052static const io_uuid_spec_t bl2_uuid_spec = {
53 .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
Dan Handley9df48042015-03-19 18:58:55 +000054};
55
Juan Castilloa72b6472015-12-10 15:49:17 +000056static const io_uuid_spec_t scp_bl2_uuid_spec = {
57 .uuid = UUID_SCP_FIRMWARE_SCP_BL2,
Dan Handley9df48042015-03-19 18:58:55 +000058};
59
Juan Castillo3a66aca2015-04-13 17:36:19 +010060static const io_uuid_spec_t bl31_uuid_spec = {
61 .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
Dan Handley9df48042015-03-19 18:58:55 +000062};
63
Juan Castillo3a66aca2015-04-13 17:36:19 +010064static const io_uuid_spec_t bl32_uuid_spec = {
65 .uuid = UUID_SECURE_PAYLOAD_BL32,
Dan Handley9df48042015-03-19 18:58:55 +000066};
67
Juan Castillo3a66aca2015-04-13 17:36:19 +010068static const io_uuid_spec_t bl33_uuid_spec = {
69 .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
Dan Handley9df48042015-03-19 18:58:55 +000070};
71
72#if TRUSTED_BOARD_BOOT
Juan Castillobe801202015-12-03 10:19:21 +000073static const io_uuid_spec_t tb_fw_cert_uuid_spec = {
74 .uuid = UUID_TRUSTED_BOOT_FW_CERT,
Dan Handley9df48042015-03-19 18:58:55 +000075};
76
Juan Castillo3a66aca2015-04-13 17:36:19 +010077static const io_uuid_spec_t trusted_key_cert_uuid_spec = {
78 .uuid = UUID_TRUSTED_KEY_CERT,
Dan Handley9df48042015-03-19 18:58:55 +000079};
80
Juan Castillobe801202015-12-03 10:19:21 +000081static const io_uuid_spec_t scp_fw_key_cert_uuid_spec = {
82 .uuid = UUID_SCP_FW_KEY_CERT,
Dan Handley9df48042015-03-19 18:58:55 +000083};
84
Juan Castillobe801202015-12-03 10:19:21 +000085static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = {
86 .uuid = UUID_SOC_FW_KEY_CERT,
Dan Handley9df48042015-03-19 18:58:55 +000087};
88
Juan Castillobe801202015-12-03 10:19:21 +000089static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = {
90 .uuid = UUID_TRUSTED_OS_FW_KEY_CERT,
Dan Handley9df48042015-03-19 18:58:55 +000091};
92
Juan Castillobe801202015-12-03 10:19:21 +000093static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = {
94 .uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
Dan Handley9df48042015-03-19 18:58:55 +000095};
96
Juan Castillobe801202015-12-03 10:19:21 +000097static const io_uuid_spec_t scp_fw_cert_uuid_spec = {
98 .uuid = UUID_SCP_FW_CONTENT_CERT,
Dan Handley9df48042015-03-19 18:58:55 +000099};
100
Juan Castillobe801202015-12-03 10:19:21 +0000101static const io_uuid_spec_t soc_fw_cert_uuid_spec = {
102 .uuid = UUID_SOC_FW_CONTENT_CERT,
Dan Handley9df48042015-03-19 18:58:55 +0000103};
104
Juan Castillobe801202015-12-03 10:19:21 +0000105static const io_uuid_spec_t tos_fw_cert_uuid_spec = {
106 .uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT,
Dan Handley9df48042015-03-19 18:58:55 +0000107};
108
Juan Castillobe801202015-12-03 10:19:21 +0000109static const io_uuid_spec_t nt_fw_cert_uuid_spec = {
110 .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT,
Dan Handley9df48042015-03-19 18:58:55 +0000111};
112#endif /* TRUSTED_BOARD_BOOT */
113
Juan Castillo3a66aca2015-04-13 17:36:19 +0100114
Dan Handley9df48042015-03-19 18:58:55 +0000115static int open_fip(const uintptr_t spec);
116static int open_memmap(const uintptr_t spec);
117
118struct plat_io_policy {
Dan Handley9df48042015-03-19 18:58:55 +0000119 uintptr_t *dev_handle;
120 uintptr_t image_spec;
121 int (*check)(const uintptr_t spec);
122};
123
Juan Castillo3a66aca2015-04-13 17:36:19 +0100124/* By default, ARM platforms load images from the FIP */
Dan Handley9df48042015-03-19 18:58:55 +0000125static const struct plat_io_policy policies[] = {
Juan Castillo3a66aca2015-04-13 17:36:19 +0100126 [FIP_IMAGE_ID] = {
Dan Handley9df48042015-03-19 18:58:55 +0000127 &memmap_dev_handle,
128 (uintptr_t)&fip_block_spec,
129 open_memmap
Juan Castillo3a66aca2015-04-13 17:36:19 +0100130 },
131 [BL2_IMAGE_ID] = {
Dan Handley9df48042015-03-19 18:58:55 +0000132 &fip_dev_handle,
Juan Castillo3a66aca2015-04-13 17:36:19 +0100133 (uintptr_t)&bl2_uuid_spec,
Dan Handley9df48042015-03-19 18:58:55 +0000134 open_fip
Juan Castillo3a66aca2015-04-13 17:36:19 +0100135 },
Juan Castilloa72b6472015-12-10 15:49:17 +0000136 [SCP_BL2_IMAGE_ID] = {
Dan Handley9df48042015-03-19 18:58:55 +0000137 &fip_dev_handle,
Juan Castilloa72b6472015-12-10 15:49:17 +0000138 (uintptr_t)&scp_bl2_uuid_spec,
Dan Handley9df48042015-03-19 18:58:55 +0000139 open_fip
Juan Castillo3a66aca2015-04-13 17:36:19 +0100140 },
141 [BL31_IMAGE_ID] = {
Dan Handley9df48042015-03-19 18:58:55 +0000142 &fip_dev_handle,
Juan Castillo3a66aca2015-04-13 17:36:19 +0100143 (uintptr_t)&bl31_uuid_spec,
Dan Handley9df48042015-03-19 18:58:55 +0000144 open_fip
Juan Castillo3a66aca2015-04-13 17:36:19 +0100145 },
146 [BL32_IMAGE_ID] = {
Dan Handley9df48042015-03-19 18:58:55 +0000147 &fip_dev_handle,
Juan Castillo3a66aca2015-04-13 17:36:19 +0100148 (uintptr_t)&bl32_uuid_spec,
Dan Handley9df48042015-03-19 18:58:55 +0000149 open_fip
Juan Castillo3a66aca2015-04-13 17:36:19 +0100150 },
151 [BL33_IMAGE_ID] = {
Dan Handley9df48042015-03-19 18:58:55 +0000152 &fip_dev_handle,
Juan Castillo3a66aca2015-04-13 17:36:19 +0100153 (uintptr_t)&bl33_uuid_spec,
Dan Handley9df48042015-03-19 18:58:55 +0000154 open_fip
Juan Castillo3a66aca2015-04-13 17:36:19 +0100155 },
Dan Handley9df48042015-03-19 18:58:55 +0000156#if TRUSTED_BOARD_BOOT
Juan Castillobe801202015-12-03 10:19:21 +0000157 [TRUSTED_BOOT_FW_CERT_ID] = {
Dan Handley9df48042015-03-19 18:58:55 +0000158 &fip_dev_handle,
Juan Castillobe801202015-12-03 10:19:21 +0000159 (uintptr_t)&tb_fw_cert_uuid_spec,
Dan Handley9df48042015-03-19 18:58:55 +0000160 open_fip
Juan Castillo3a66aca2015-04-13 17:36:19 +0100161 },
162 [TRUSTED_KEY_CERT_ID] = {
Dan Handley9df48042015-03-19 18:58:55 +0000163 &fip_dev_handle,
Juan Castillo3a66aca2015-04-13 17:36:19 +0100164 (uintptr_t)&trusted_key_cert_uuid_spec,
Dan Handley9df48042015-03-19 18:58:55 +0000165 open_fip
Juan Castillo3a66aca2015-04-13 17:36:19 +0100166 },
Juan Castillobe801202015-12-03 10:19:21 +0000167 [SCP_FW_KEY_CERT_ID] = {
Dan Handley9df48042015-03-19 18:58:55 +0000168 &fip_dev_handle,
Juan Castillobe801202015-12-03 10:19:21 +0000169 (uintptr_t)&scp_fw_key_cert_uuid_spec,
Dan Handley9df48042015-03-19 18:58:55 +0000170 open_fip
Juan Castillo3a66aca2015-04-13 17:36:19 +0100171 },
Juan Castillobe801202015-12-03 10:19:21 +0000172 [SOC_FW_KEY_CERT_ID] = {
Dan Handley9df48042015-03-19 18:58:55 +0000173 &fip_dev_handle,
Juan Castillobe801202015-12-03 10:19:21 +0000174 (uintptr_t)&soc_fw_key_cert_uuid_spec,
Dan Handley9df48042015-03-19 18:58:55 +0000175 open_fip
Juan Castillo3a66aca2015-04-13 17:36:19 +0100176 },
Juan Castillobe801202015-12-03 10:19:21 +0000177 [TRUSTED_OS_FW_KEY_CERT_ID] = {
Dan Handley9df48042015-03-19 18:58:55 +0000178 &fip_dev_handle,
Juan Castillobe801202015-12-03 10:19:21 +0000179 (uintptr_t)&tos_fw_key_cert_uuid_spec,
Dan Handley9df48042015-03-19 18:58:55 +0000180 open_fip
Juan Castillo3a66aca2015-04-13 17:36:19 +0100181 },
Juan Castillobe801202015-12-03 10:19:21 +0000182 [NON_TRUSTED_FW_KEY_CERT_ID] = {
Dan Handley9df48042015-03-19 18:58:55 +0000183 &fip_dev_handle,
Juan Castillobe801202015-12-03 10:19:21 +0000184 (uintptr_t)&nt_fw_key_cert_uuid_spec,
Dan Handley9df48042015-03-19 18:58:55 +0000185 open_fip
Juan Castillo3a66aca2015-04-13 17:36:19 +0100186 },
Juan Castillobe801202015-12-03 10:19:21 +0000187 [SCP_FW_CONTENT_CERT_ID] = {
Dan Handley9df48042015-03-19 18:58:55 +0000188 &fip_dev_handle,
Juan Castillobe801202015-12-03 10:19:21 +0000189 (uintptr_t)&scp_fw_cert_uuid_spec,
Dan Handley9df48042015-03-19 18:58:55 +0000190 open_fip
Juan Castillo3a66aca2015-04-13 17:36:19 +0100191 },
Juan Castillobe801202015-12-03 10:19:21 +0000192 [SOC_FW_CONTENT_CERT_ID] = {
Dan Handley9df48042015-03-19 18:58:55 +0000193 &fip_dev_handle,
Juan Castillobe801202015-12-03 10:19:21 +0000194 (uintptr_t)&soc_fw_cert_uuid_spec,
Dan Handley9df48042015-03-19 18:58:55 +0000195 open_fip
Juan Castillo3a66aca2015-04-13 17:36:19 +0100196 },
Juan Castillobe801202015-12-03 10:19:21 +0000197 [TRUSTED_OS_FW_CONTENT_CERT_ID] = {
Dan Handley9df48042015-03-19 18:58:55 +0000198 &fip_dev_handle,
Juan Castillobe801202015-12-03 10:19:21 +0000199 (uintptr_t)&tos_fw_cert_uuid_spec,
Dan Handley9df48042015-03-19 18:58:55 +0000200 open_fip
Juan Castillo3a66aca2015-04-13 17:36:19 +0100201 },
Juan Castillobe801202015-12-03 10:19:21 +0000202 [NON_TRUSTED_FW_CONTENT_CERT_ID] = {
Dan Handley9df48042015-03-19 18:58:55 +0000203 &fip_dev_handle,
Juan Castillobe801202015-12-03 10:19:21 +0000204 (uintptr_t)&nt_fw_cert_uuid_spec,
Dan Handley9df48042015-03-19 18:58:55 +0000205 open_fip
Juan Castillo3a66aca2015-04-13 17:36:19 +0100206 },
Dan Handley9df48042015-03-19 18:58:55 +0000207#endif /* TRUSTED_BOARD_BOOT */
Dan Handley9df48042015-03-19 18:58:55 +0000208};
209
210
211/* Weak definitions may be overridden in specific ARM standard platform */
212#pragma weak plat_arm_io_setup
213#pragma weak plat_arm_get_alt_image_source
214
215
216static int open_fip(const uintptr_t spec)
217{
218 int result;
219 uintptr_t local_image_handle;
220
221 /* See if a Firmware Image Package is available */
Juan Castillo3a66aca2015-04-13 17:36:19 +0100222 result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
Juan Castillo6e762062015-11-02 10:47:01 +0000223 if (result == 0) {
Dan Handley9df48042015-03-19 18:58:55 +0000224 result = io_open(fip_dev_handle, spec, &local_image_handle);
Juan Castillo6e762062015-11-02 10:47:01 +0000225 if (result == 0) {
Dan Handley9df48042015-03-19 18:58:55 +0000226 VERBOSE("Using FIP\n");
227 io_close(local_image_handle);
228 }
229 }
230 return result;
231}
232
233
234static int open_memmap(const uintptr_t spec)
235{
236 int result;
237 uintptr_t local_image_handle;
238
239 result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL);
Juan Castillo6e762062015-11-02 10:47:01 +0000240 if (result == 0) {
Dan Handley9df48042015-03-19 18:58:55 +0000241 result = io_open(memmap_dev_handle, spec, &local_image_handle);
Juan Castillo6e762062015-11-02 10:47:01 +0000242 if (result == 0) {
Dan Handley9df48042015-03-19 18:58:55 +0000243 VERBOSE("Using Memmap\n");
244 io_close(local_image_handle);
245 }
246 }
247 return result;
248}
249
250
251void arm_io_setup(void)
252{
253 int io_result;
254
255 io_result = register_io_dev_fip(&fip_dev_con);
Juan Castillo6e762062015-11-02 10:47:01 +0000256 assert(io_result == 0);
Dan Handley9df48042015-03-19 18:58:55 +0000257
258 io_result = register_io_dev_memmap(&memmap_dev_con);
Juan Castillo6e762062015-11-02 10:47:01 +0000259 assert(io_result == 0);
Dan Handley9df48042015-03-19 18:58:55 +0000260
261 /* Open connections to devices and cache the handles */
262 io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL,
263 &fip_dev_handle);
Juan Castillo6e762062015-11-02 10:47:01 +0000264 assert(io_result == 0);
Dan Handley9df48042015-03-19 18:58:55 +0000265
266 io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL,
267 &memmap_dev_handle);
Juan Castillo6e762062015-11-02 10:47:01 +0000268 assert(io_result == 0);
Dan Handley9df48042015-03-19 18:58:55 +0000269
270 /* Ignore improbable errors in release builds */
271 (void)io_result;
272}
273
274void plat_arm_io_setup(void)
275{
276 arm_io_setup();
277}
278
279int plat_arm_get_alt_image_source(
Soren Brinkmann46dd1702016-01-14 10:11:05 -0800280 unsigned int image_id __unused,
281 uintptr_t *dev_handle __unused,
282 uintptr_t *image_spec __unused)
Dan Handley9df48042015-03-19 18:58:55 +0000283{
284 /* By default do not try an alternative */
Juan Castillo6e762062015-11-02 10:47:01 +0000285 return -ENOENT;
Dan Handley9df48042015-03-19 18:58:55 +0000286}
287
288/* Return an IO device handle and specification which can be used to access
289 * an image. Use this to enforce platform load policy */
Juan Castillo3a66aca2015-04-13 17:36:19 +0100290int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
Dan Handley9df48042015-03-19 18:58:55 +0000291 uintptr_t *image_spec)
292{
Juan Castillo6e762062015-11-02 10:47:01 +0000293 int result;
Dan Handley9df48042015-03-19 18:58:55 +0000294 const struct plat_io_policy *policy;
295
Juan Castillo3a66aca2015-04-13 17:36:19 +0100296 assert(image_id < ARRAY_SIZE(policies));
297
298 policy = &policies[image_id];
299 result = policy->check(policy->image_spec);
Juan Castillo6e762062015-11-02 10:47:01 +0000300 if (result == 0) {
Juan Castillo3a66aca2015-04-13 17:36:19 +0100301 *image_spec = policy->image_spec;
302 *dev_handle = *(policy->dev_handle);
Dan Handley9df48042015-03-19 18:58:55 +0000303 } else {
Juan Castillo3a66aca2015-04-13 17:36:19 +0100304 VERBOSE("Trying alternative IO\n");
305 result = plat_arm_get_alt_image_source(image_id, dev_handle,
306 image_spec);
Dan Handley9df48042015-03-19 18:58:55 +0000307 }
Juan Castillo3a66aca2015-04-13 17:36:19 +0100308
Dan Handley9df48042015-03-19 18:58:55 +0000309 return result;
310}
Yatharth Kochar736a3bf2015-10-11 14:14:55 +0100311
312/*
313 * See if a Firmware Image Package is available,
314 * by checking if TOC is valid or not.
315 */
316int arm_io_is_toc_valid(void)
317{
318 int result;
319
320 result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
321
322 return (result == 0);
323}
324