1 /* 2 * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 #include <assert.h> 7 #include <debug.h> 8 #include <firmware_image_package.h> 9 #include <io_driver.h> 10 #include <io_fip.h> 11 #include <io_memmap.h> 12 #include <io_storage.h> 13 #include <platform_def.h> 14 #include <string.h> 15 #include <utils.h> 16 17 /* IO devices */ 18 static const io_dev_connector_t *fip_dev_con; 19 static uintptr_t fip_dev_handle; 20 static const io_dev_connector_t *memmap_dev_con; 21 static uintptr_t memmap_dev_handle; 22 23 static const io_block_spec_t fip_block_spec = { 24 .offset = PLAT_ARM_FIP_BASE, 25 .length = PLAT_ARM_FIP_MAX_SIZE 26 }; 27 28 static const io_uuid_spec_t bl2_uuid_spec = { 29 .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2, 30 }; 31 32 static const io_uuid_spec_t scp_bl2_uuid_spec = { 33 .uuid = UUID_SCP_FIRMWARE_SCP_BL2, 34 }; 35 36 static const io_uuid_spec_t bl31_uuid_spec = { 37 .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31, 38 }; 39 40 static const io_uuid_spec_t bl32_uuid_spec = { 41 .uuid = UUID_SECURE_PAYLOAD_BL32, 42 }; 43 44 static const io_uuid_spec_t bl33_uuid_spec = { 45 .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33, 46 }; 47 48 #if TRUSTED_BOARD_BOOT 49 static const io_uuid_spec_t tb_fw_cert_uuid_spec = { 50 .uuid = UUID_TRUSTED_BOOT_FW_CERT, 51 }; 52 53 static const io_uuid_spec_t trusted_key_cert_uuid_spec = { 54 .uuid = UUID_TRUSTED_KEY_CERT, 55 }; 56 57 static const io_uuid_spec_t scp_fw_key_cert_uuid_spec = { 58 .uuid = UUID_SCP_FW_KEY_CERT, 59 }; 60 61 static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = { 62 .uuid = UUID_SOC_FW_KEY_CERT, 63 }; 64 65 static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = { 66 .uuid = UUID_TRUSTED_OS_FW_KEY_CERT, 67 }; 68 69 static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = { 70 .uuid = UUID_NON_TRUSTED_FW_KEY_CERT, 71 }; 72 73 static const io_uuid_spec_t scp_fw_cert_uuid_spec = { 74 .uuid = UUID_SCP_FW_CONTENT_CERT, 75 }; 76 77 static const io_uuid_spec_t soc_fw_cert_uuid_spec = { 78 .uuid = UUID_SOC_FW_CONTENT_CERT, 79 }; 80 81 static const io_uuid_spec_t tos_fw_cert_uuid_spec = { 82 .uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT, 83 }; 84 85 static const io_uuid_spec_t nt_fw_cert_uuid_spec = { 86 .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT, 87 }; 88 #endif /* TRUSTED_BOARD_BOOT */ 89 90 91 static int open_fip(const uintptr_t spec); 92 static int open_memmap(const uintptr_t spec); 93 94 struct plat_io_policy { 95 uintptr_t *dev_handle; 96 uintptr_t image_spec; 97 int (*check)(const uintptr_t spec); 98 }; 99 100 /* By default, ARM platforms load images from the FIP */ 101 static const struct plat_io_policy policies[] = { 102 [FIP_IMAGE_ID] = { 103 &memmap_dev_handle, 104 (uintptr_t)&fip_block_spec, 105 open_memmap 106 }, 107 [BL2_IMAGE_ID] = { 108 &fip_dev_handle, 109 (uintptr_t)&bl2_uuid_spec, 110 open_fip 111 }, 112 [SCP_BL2_IMAGE_ID] = { 113 &fip_dev_handle, 114 (uintptr_t)&scp_bl2_uuid_spec, 115 open_fip 116 }, 117 [BL31_IMAGE_ID] = { 118 &fip_dev_handle, 119 (uintptr_t)&bl31_uuid_spec, 120 open_fip 121 }, 122 [BL32_IMAGE_ID] = { 123 &fip_dev_handle, 124 (uintptr_t)&bl32_uuid_spec, 125 open_fip 126 }, 127 [BL33_IMAGE_ID] = { 128 &fip_dev_handle, 129 (uintptr_t)&bl33_uuid_spec, 130 open_fip 131 }, 132 #if TRUSTED_BOARD_BOOT 133 [TRUSTED_BOOT_FW_CERT_ID] = { 134 &fip_dev_handle, 135 (uintptr_t)&tb_fw_cert_uuid_spec, 136 open_fip 137 }, 138 [TRUSTED_KEY_CERT_ID] = { 139 &fip_dev_handle, 140 (uintptr_t)&trusted_key_cert_uuid_spec, 141 open_fip 142 }, 143 [SCP_FW_KEY_CERT_ID] = { 144 &fip_dev_handle, 145 (uintptr_t)&scp_fw_key_cert_uuid_spec, 146 open_fip 147 }, 148 [SOC_FW_KEY_CERT_ID] = { 149 &fip_dev_handle, 150 (uintptr_t)&soc_fw_key_cert_uuid_spec, 151 open_fip 152 }, 153 [TRUSTED_OS_FW_KEY_CERT_ID] = { 154 &fip_dev_handle, 155 (uintptr_t)&tos_fw_key_cert_uuid_spec, 156 open_fip 157 }, 158 [NON_TRUSTED_FW_KEY_CERT_ID] = { 159 &fip_dev_handle, 160 (uintptr_t)&nt_fw_key_cert_uuid_spec, 161 open_fip 162 }, 163 [SCP_FW_CONTENT_CERT_ID] = { 164 &fip_dev_handle, 165 (uintptr_t)&scp_fw_cert_uuid_spec, 166 open_fip 167 }, 168 [SOC_FW_CONTENT_CERT_ID] = { 169 &fip_dev_handle, 170 (uintptr_t)&soc_fw_cert_uuid_spec, 171 open_fip 172 }, 173 [TRUSTED_OS_FW_CONTENT_CERT_ID] = { 174 &fip_dev_handle, 175 (uintptr_t)&tos_fw_cert_uuid_spec, 176 open_fip 177 }, 178 [NON_TRUSTED_FW_CONTENT_CERT_ID] = { 179 &fip_dev_handle, 180 (uintptr_t)&nt_fw_cert_uuid_spec, 181 open_fip 182 }, 183 #endif /* TRUSTED_BOARD_BOOT */ 184 }; 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 192 static 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 */ 198 result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); 199 if (result == 0) { 200 result = io_open(fip_dev_handle, spec, &local_image_handle); 201 if (result == 0) { 202 VERBOSE("Using FIP\n"); 203 io_close(local_image_handle); 204 } 205 } 206 return result; 207 } 208 209 210 static 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); 216 if (result == 0) { 217 result = io_open(memmap_dev_handle, spec, &local_image_handle); 218 if (result == 0) { 219 VERBOSE("Using Memmap\n"); 220 io_close(local_image_handle); 221 } 222 } 223 return result; 224 } 225 226 227 void arm_io_setup(void) 228 { 229 int io_result; 230 231 io_result = register_io_dev_fip(&fip_dev_con); 232 assert(io_result == 0); 233 234 io_result = register_io_dev_memmap(&memmap_dev_con); 235 assert(io_result == 0); 236 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); 240 assert(io_result == 0); 241 242 io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL, 243 &memmap_dev_handle); 244 assert(io_result == 0); 245 246 /* Ignore improbable errors in release builds */ 247 (void)io_result; 248 } 249 250 void plat_arm_io_setup(void) 251 { 252 arm_io_setup(); 253 } 254 255 int plat_arm_get_alt_image_source( 256 unsigned int image_id __unused, 257 uintptr_t *dev_handle __unused, 258 uintptr_t *image_spec __unused) 259 { 260 /* By default do not try an alternative */ 261 return -ENOENT; 262 } 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 */ 266 int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, 267 uintptr_t *image_spec) 268 { 269 int result; 270 const struct plat_io_policy *policy; 271 272 assert(image_id < ARRAY_SIZE(policies)); 273 274 policy = &policies[image_id]; 275 result = policy->check(policy->image_spec); 276 if (result == 0) { 277 *image_spec = policy->image_spec; 278 *dev_handle = *(policy->dev_handle); 279 } else { 280 VERBOSE("Trying alternative IO\n"); 281 result = plat_arm_get_alt_image_source(image_id, dev_handle, 282 image_spec); 283 } 284 285 return result; 286 } 287 288 /* 289 * See if a Firmware Image Package is available, 290 * by checking if TOC is valid or not. 291 */ 292 int 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 301