blob: 74e68245240ab3050f38fdace41c62896b5a3fc3 [file] [log] [blame]
Dan Handley9df48042015-03-19 18:58:55 +00001/*
Sandrine Bailleux7659a262016-07-05 09:55:03 +01002 * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
Dan Handley9df48042015-03-19 18:58:55 +00003 *
dp-armfa3cf0b2017-05-03 09:38:09 +01004 * SPDX-License-Identifier: BSD-3-Clause
Dan Handley9df48042015-03-19 18:58:55 +00005 */
6#include <assert.h>
7#include <debug.h>
Juan Castillo3a66aca2015-04-13 17:36:19 +01008#include <firmware_image_package.h>
Dan Handley9df48042015-03-19 18:58:55 +00009#include <io_driver.h>
10#include <io_fip.h>
11#include <io_memmap.h>
12#include <io_storage.h>
13#include <platform_def.h>
Dan Handley9df48042015-03-19 18:58:55 +000014#include <string.h>
Sandrine Bailleux7659a262016-07-05 09:55:03 +010015#include <utils.h>
Dan Handley9df48042015-03-19 18:58:55 +000016
17/* IO devices */
18static const io_dev_connector_t *fip_dev_con;
19static uintptr_t fip_dev_handle;
20static const io_dev_connector_t *memmap_dev_con;
21static uintptr_t memmap_dev_handle;
22
23static const io_block_spec_t fip_block_spec = {
24 .offset = PLAT_ARM_FIP_BASE,
25 .length = PLAT_ARM_FIP_MAX_SIZE
26};
27
Juan Castillo3a66aca2015-04-13 17:36:19 +010028static const io_uuid_spec_t bl2_uuid_spec = {
29 .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
Dan Handley9df48042015-03-19 18:58:55 +000030};
31
Juan Castilloa72b6472015-12-10 15:49:17 +000032static const io_uuid_spec_t scp_bl2_uuid_spec = {
33 .uuid = UUID_SCP_FIRMWARE_SCP_BL2,
Dan Handley9df48042015-03-19 18:58:55 +000034};
35
Juan Castillo3a66aca2015-04-13 17:36:19 +010036static const io_uuid_spec_t bl31_uuid_spec = {
37 .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
Dan Handley9df48042015-03-19 18:58:55 +000038};
39
Juan Castillo3a66aca2015-04-13 17:36:19 +010040static const io_uuid_spec_t bl32_uuid_spec = {
41 .uuid = UUID_SECURE_PAYLOAD_BL32,
Dan Handley9df48042015-03-19 18:58:55 +000042};
43
Juan Castillo3a66aca2015-04-13 17:36:19 +010044static const io_uuid_spec_t bl33_uuid_spec = {
45 .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
Dan Handley9df48042015-03-19 18:58:55 +000046};
47
48#if TRUSTED_BOARD_BOOT
Juan Castillobe801202015-12-03 10:19:21 +000049static const io_uuid_spec_t tb_fw_cert_uuid_spec = {
50 .uuid = UUID_TRUSTED_BOOT_FW_CERT,
Dan Handley9df48042015-03-19 18:58:55 +000051};
52
Juan Castillo3a66aca2015-04-13 17:36:19 +010053static const io_uuid_spec_t trusted_key_cert_uuid_spec = {
54 .uuid = UUID_TRUSTED_KEY_CERT,
Dan Handley9df48042015-03-19 18:58:55 +000055};
56
Juan Castillobe801202015-12-03 10:19:21 +000057static const io_uuid_spec_t scp_fw_key_cert_uuid_spec = {
58 .uuid = UUID_SCP_FW_KEY_CERT,
Dan Handley9df48042015-03-19 18:58:55 +000059};
60
Juan Castillobe801202015-12-03 10:19:21 +000061static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = {
62 .uuid = UUID_SOC_FW_KEY_CERT,
Dan Handley9df48042015-03-19 18:58:55 +000063};
64
Juan Castillobe801202015-12-03 10:19:21 +000065static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = {
66 .uuid = UUID_TRUSTED_OS_FW_KEY_CERT,
Dan Handley9df48042015-03-19 18:58:55 +000067};
68
Juan Castillobe801202015-12-03 10:19:21 +000069static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = {
70 .uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
Dan Handley9df48042015-03-19 18:58:55 +000071};
72
Juan Castillobe801202015-12-03 10:19:21 +000073static const io_uuid_spec_t scp_fw_cert_uuid_spec = {
74 .uuid = UUID_SCP_FW_CONTENT_CERT,
Dan Handley9df48042015-03-19 18:58:55 +000075};
76
Juan Castillobe801202015-12-03 10:19:21 +000077static const io_uuid_spec_t soc_fw_cert_uuid_spec = {
78 .uuid = UUID_SOC_FW_CONTENT_CERT,
Dan Handley9df48042015-03-19 18:58:55 +000079};
80
Juan Castillobe801202015-12-03 10:19:21 +000081static const io_uuid_spec_t tos_fw_cert_uuid_spec = {
82 .uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT,
Dan Handley9df48042015-03-19 18:58:55 +000083};
84
Juan Castillobe801202015-12-03 10:19:21 +000085static const io_uuid_spec_t nt_fw_cert_uuid_spec = {
86 .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT,
Dan Handley9df48042015-03-19 18:58:55 +000087};
88#endif /* TRUSTED_BOARD_BOOT */
89
Juan Castillo3a66aca2015-04-13 17:36:19 +010090
Dan Handley9df48042015-03-19 18:58:55 +000091static int open_fip(const uintptr_t spec);
92static int open_memmap(const uintptr_t spec);
93
94struct plat_io_policy {
Dan Handley9df48042015-03-19 18:58:55 +000095 uintptr_t *dev_handle;
96 uintptr_t image_spec;
97 int (*check)(const uintptr_t spec);
98};
99
Juan Castillo3a66aca2015-04-13 17:36:19 +0100100/* By default, ARM platforms load images from the FIP */
Dan Handley9df48042015-03-19 18:58:55 +0000101static const struct plat_io_policy policies[] = {
Juan Castillo3a66aca2015-04-13 17:36:19 +0100102 [FIP_IMAGE_ID] = {
Dan Handley9df48042015-03-19 18:58:55 +0000103 &memmap_dev_handle,
104 (uintptr_t)&fip_block_spec,
105 open_memmap
Juan Castillo3a66aca2015-04-13 17:36:19 +0100106 },
107 [BL2_IMAGE_ID] = {
Dan Handley9df48042015-03-19 18:58:55 +0000108 &fip_dev_handle,
Juan Castillo3a66aca2015-04-13 17:36:19 +0100109 (uintptr_t)&bl2_uuid_spec,
Dan Handley9df48042015-03-19 18:58:55 +0000110 open_fip
Juan Castillo3a66aca2015-04-13 17:36:19 +0100111 },
Juan Castilloa72b6472015-12-10 15:49:17 +0000112 [SCP_BL2_IMAGE_ID] = {
Dan Handley9df48042015-03-19 18:58:55 +0000113 &fip_dev_handle,
Juan Castilloa72b6472015-12-10 15:49:17 +0000114 (uintptr_t)&scp_bl2_uuid_spec,
Dan Handley9df48042015-03-19 18:58:55 +0000115 open_fip
Juan Castillo3a66aca2015-04-13 17:36:19 +0100116 },
117 [BL31_IMAGE_ID] = {
Dan Handley9df48042015-03-19 18:58:55 +0000118 &fip_dev_handle,
Juan Castillo3a66aca2015-04-13 17:36:19 +0100119 (uintptr_t)&bl31_uuid_spec,
Dan Handley9df48042015-03-19 18:58:55 +0000120 open_fip
Juan Castillo3a66aca2015-04-13 17:36:19 +0100121 },
122 [BL32_IMAGE_ID] = {
Dan Handley9df48042015-03-19 18:58:55 +0000123 &fip_dev_handle,
Juan Castillo3a66aca2015-04-13 17:36:19 +0100124 (uintptr_t)&bl32_uuid_spec,
Dan Handley9df48042015-03-19 18:58:55 +0000125 open_fip
Juan Castillo3a66aca2015-04-13 17:36:19 +0100126 },
127 [BL33_IMAGE_ID] = {
Dan Handley9df48042015-03-19 18:58:55 +0000128 &fip_dev_handle,
Juan Castillo3a66aca2015-04-13 17:36:19 +0100129 (uintptr_t)&bl33_uuid_spec,
Dan Handley9df48042015-03-19 18:58:55 +0000130 open_fip
Juan Castillo3a66aca2015-04-13 17:36:19 +0100131 },
Dan Handley9df48042015-03-19 18:58:55 +0000132#if TRUSTED_BOARD_BOOT
Juan Castillobe801202015-12-03 10:19:21 +0000133 [TRUSTED_BOOT_FW_CERT_ID] = {
Dan Handley9df48042015-03-19 18:58:55 +0000134 &fip_dev_handle,
Juan Castillobe801202015-12-03 10:19:21 +0000135 (uintptr_t)&tb_fw_cert_uuid_spec,
Dan Handley9df48042015-03-19 18:58:55 +0000136 open_fip
Juan Castillo3a66aca2015-04-13 17:36:19 +0100137 },
138 [TRUSTED_KEY_CERT_ID] = {
Dan Handley9df48042015-03-19 18:58:55 +0000139 &fip_dev_handle,
Juan Castillo3a66aca2015-04-13 17:36:19 +0100140 (uintptr_t)&trusted_key_cert_uuid_spec,
Dan Handley9df48042015-03-19 18:58:55 +0000141 open_fip
Juan Castillo3a66aca2015-04-13 17:36:19 +0100142 },
Juan Castillobe801202015-12-03 10:19:21 +0000143 [SCP_FW_KEY_CERT_ID] = {
Dan Handley9df48042015-03-19 18:58:55 +0000144 &fip_dev_handle,
Juan Castillobe801202015-12-03 10:19:21 +0000145 (uintptr_t)&scp_fw_key_cert_uuid_spec,
Dan Handley9df48042015-03-19 18:58:55 +0000146 open_fip
Juan Castillo3a66aca2015-04-13 17:36:19 +0100147 },
Juan Castillobe801202015-12-03 10:19:21 +0000148 [SOC_FW_KEY_CERT_ID] = {
Dan Handley9df48042015-03-19 18:58:55 +0000149 &fip_dev_handle,
Juan Castillobe801202015-12-03 10:19:21 +0000150 (uintptr_t)&soc_fw_key_cert_uuid_spec,
Dan Handley9df48042015-03-19 18:58:55 +0000151 open_fip
Juan Castillo3a66aca2015-04-13 17:36:19 +0100152 },
Juan Castillobe801202015-12-03 10:19:21 +0000153 [TRUSTED_OS_FW_KEY_CERT_ID] = {
Dan Handley9df48042015-03-19 18:58:55 +0000154 &fip_dev_handle,
Juan Castillobe801202015-12-03 10:19:21 +0000155 (uintptr_t)&tos_fw_key_cert_uuid_spec,
Dan Handley9df48042015-03-19 18:58:55 +0000156 open_fip
Juan Castillo3a66aca2015-04-13 17:36:19 +0100157 },
Juan Castillobe801202015-12-03 10:19:21 +0000158 [NON_TRUSTED_FW_KEY_CERT_ID] = {
Dan Handley9df48042015-03-19 18:58:55 +0000159 &fip_dev_handle,
Juan Castillobe801202015-12-03 10:19:21 +0000160 (uintptr_t)&nt_fw_key_cert_uuid_spec,
Dan Handley9df48042015-03-19 18:58:55 +0000161 open_fip
Juan Castillo3a66aca2015-04-13 17:36:19 +0100162 },
Juan Castillobe801202015-12-03 10:19:21 +0000163 [SCP_FW_CONTENT_CERT_ID] = {
Dan Handley9df48042015-03-19 18:58:55 +0000164 &fip_dev_handle,
Juan Castillobe801202015-12-03 10:19:21 +0000165 (uintptr_t)&scp_fw_cert_uuid_spec,
Dan Handley9df48042015-03-19 18:58:55 +0000166 open_fip
Juan Castillo3a66aca2015-04-13 17:36:19 +0100167 },
Juan Castillobe801202015-12-03 10:19:21 +0000168 [SOC_FW_CONTENT_CERT_ID] = {
Dan Handley9df48042015-03-19 18:58:55 +0000169 &fip_dev_handle,
Juan Castillobe801202015-12-03 10:19:21 +0000170 (uintptr_t)&soc_fw_cert_uuid_spec,
Dan Handley9df48042015-03-19 18:58:55 +0000171 open_fip
Juan Castillo3a66aca2015-04-13 17:36:19 +0100172 },
Juan Castillobe801202015-12-03 10:19:21 +0000173 [TRUSTED_OS_FW_CONTENT_CERT_ID] = {
Dan Handley9df48042015-03-19 18:58:55 +0000174 &fip_dev_handle,
Juan Castillobe801202015-12-03 10:19:21 +0000175 (uintptr_t)&tos_fw_cert_uuid_spec,
Dan Handley9df48042015-03-19 18:58:55 +0000176 open_fip
Juan Castillo3a66aca2015-04-13 17:36:19 +0100177 },
Juan Castillobe801202015-12-03 10:19:21 +0000178 [NON_TRUSTED_FW_CONTENT_CERT_ID] = {
Dan Handley9df48042015-03-19 18:58:55 +0000179 &fip_dev_handle,
Juan Castillobe801202015-12-03 10:19:21 +0000180 (uintptr_t)&nt_fw_cert_uuid_spec,
Dan Handley9df48042015-03-19 18:58:55 +0000181 open_fip
Juan Castillo3a66aca2015-04-13 17:36:19 +0100182 },
Dan Handley9df48042015-03-19 18:58:55 +0000183#endif /* TRUSTED_BOARD_BOOT */
Dan Handley9df48042015-03-19 18:58:55 +0000184};
185
186
187/* Weak definitions may be overridden in specific ARM standard platform */
188#pragma weak plat_arm_io_setup
189#pragma weak plat_arm_get_alt_image_source
190
191
192static int open_fip(const uintptr_t spec)
193{
194 int result;
195 uintptr_t local_image_handle;
196
197 /* See if a Firmware Image Package is available */
Juan Castillo3a66aca2015-04-13 17:36:19 +0100198 result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
Juan Castillo6e762062015-11-02 10:47:01 +0000199 if (result == 0) {
Dan Handley9df48042015-03-19 18:58:55 +0000200 result = io_open(fip_dev_handle, spec, &local_image_handle);
Juan Castillo6e762062015-11-02 10:47:01 +0000201 if (result == 0) {
Dan Handley9df48042015-03-19 18:58:55 +0000202 VERBOSE("Using FIP\n");
203 io_close(local_image_handle);
204 }
205 }
206 return result;
207}
208
209
210static int open_memmap(const uintptr_t spec)
211{
212 int result;
213 uintptr_t local_image_handle;
214
215 result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL);
Juan Castillo6e762062015-11-02 10:47:01 +0000216 if (result == 0) {
Dan Handley9df48042015-03-19 18:58:55 +0000217 result = io_open(memmap_dev_handle, spec, &local_image_handle);
Juan Castillo6e762062015-11-02 10:47:01 +0000218 if (result == 0) {
Dan Handley9df48042015-03-19 18:58:55 +0000219 VERBOSE("Using Memmap\n");
220 io_close(local_image_handle);
221 }
222 }
223 return result;
224}
225
226
227void arm_io_setup(void)
228{
229 int io_result;
230
231 io_result = register_io_dev_fip(&fip_dev_con);
Juan Castillo6e762062015-11-02 10:47:01 +0000232 assert(io_result == 0);
Dan Handley9df48042015-03-19 18:58:55 +0000233
234 io_result = register_io_dev_memmap(&memmap_dev_con);
Juan Castillo6e762062015-11-02 10:47:01 +0000235 assert(io_result == 0);
Dan Handley9df48042015-03-19 18:58:55 +0000236
237 /* Open connections to devices and cache the handles */
238 io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL,
239 &fip_dev_handle);
Juan Castillo6e762062015-11-02 10:47:01 +0000240 assert(io_result == 0);
Dan Handley9df48042015-03-19 18:58:55 +0000241
242 io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL,
243 &memmap_dev_handle);
Juan Castillo6e762062015-11-02 10:47:01 +0000244 assert(io_result == 0);
Dan Handley9df48042015-03-19 18:58:55 +0000245
246 /* Ignore improbable errors in release builds */
247 (void)io_result;
248}
249
250void plat_arm_io_setup(void)
251{
252 arm_io_setup();
253}
254
255int plat_arm_get_alt_image_source(
Soren Brinkmann46dd1702016-01-14 10:11:05 -0800256 unsigned int image_id __unused,
257 uintptr_t *dev_handle __unused,
258 uintptr_t *image_spec __unused)
Dan Handley9df48042015-03-19 18:58:55 +0000259{
260 /* By default do not try an alternative */
Juan Castillo6e762062015-11-02 10:47:01 +0000261 return -ENOENT;
Dan Handley9df48042015-03-19 18:58:55 +0000262}
263
264/* Return an IO device handle and specification which can be used to access
265 * an image. Use this to enforce platform load policy */
Juan Castillo3a66aca2015-04-13 17:36:19 +0100266int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
Dan Handley9df48042015-03-19 18:58:55 +0000267 uintptr_t *image_spec)
268{
Juan Castillo6e762062015-11-02 10:47:01 +0000269 int result;
Dan Handley9df48042015-03-19 18:58:55 +0000270 const struct plat_io_policy *policy;
271
Juan Castillo3a66aca2015-04-13 17:36:19 +0100272 assert(image_id < ARRAY_SIZE(policies));
273
274 policy = &policies[image_id];
275 result = policy->check(policy->image_spec);
Juan Castillo6e762062015-11-02 10:47:01 +0000276 if (result == 0) {
Juan Castillo3a66aca2015-04-13 17:36:19 +0100277 *image_spec = policy->image_spec;
278 *dev_handle = *(policy->dev_handle);
Dan Handley9df48042015-03-19 18:58:55 +0000279 } else {
Juan Castillo3a66aca2015-04-13 17:36:19 +0100280 VERBOSE("Trying alternative IO\n");
281 result = plat_arm_get_alt_image_source(image_id, dev_handle,
282 image_spec);
Dan Handley9df48042015-03-19 18:58:55 +0000283 }
Juan Castillo3a66aca2015-04-13 17:36:19 +0100284
Dan Handley9df48042015-03-19 18:58:55 +0000285 return result;
286}
Yatharth Kochar736a3bf2015-10-11 14:14:55 +0100287
288/*
289 * See if a Firmware Image Package is available,
290 * by checking if TOC is valid or not.
291 */
292int arm_io_is_toc_valid(void)
293{
294 int result;
295
296 result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
297
298 return (result == 0);
299}
300