1 /* 2 * Copyright (c) 2015-2018, 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 <plat_arm.h> 14 #include <platform.h> 15 #include <platform_def.h> 16 #include <string.h> 17 #include <utils.h> 18 19 /* IO devices */ 20 static const io_dev_connector_t *fip_dev_con; 21 static uintptr_t fip_dev_handle; 22 static const io_dev_connector_t *memmap_dev_con; 23 static uintptr_t memmap_dev_handle; 24 25 static const io_block_spec_t fip_block_spec = { 26 .offset = PLAT_ARM_FIP_BASE, 27 .length = PLAT_ARM_FIP_MAX_SIZE 28 }; 29 30 static const io_uuid_spec_t bl2_uuid_spec = { 31 .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2, 32 }; 33 34 static const io_uuid_spec_t scp_bl2_uuid_spec = { 35 .uuid = UUID_SCP_FIRMWARE_SCP_BL2, 36 }; 37 38 static const io_uuid_spec_t bl31_uuid_spec = { 39 .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31, 40 }; 41 42 static const io_uuid_spec_t bl32_uuid_spec = { 43 .uuid = UUID_SECURE_PAYLOAD_BL32, 44 }; 45 46 static const io_uuid_spec_t bl32_extra1_uuid_spec = { 47 .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1, 48 }; 49 50 static const io_uuid_spec_t bl32_extra2_uuid_spec = { 51 .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2, 52 }; 53 54 static const io_uuid_spec_t bl33_uuid_spec = { 55 .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33, 56 }; 57 58 static const io_uuid_spec_t tb_fw_config_uuid_spec = { 59 .uuid = UUID_TB_FW_CONFIG, 60 }; 61 62 static const io_uuid_spec_t hw_config_uuid_spec = { 63 .uuid = UUID_HW_CONFIG, 64 }; 65 66 static const io_uuid_spec_t soc_fw_config_uuid_spec = { 67 .uuid = UUID_SOC_FW_CONFIG, 68 }; 69 70 static const io_uuid_spec_t tos_fw_config_uuid_spec = { 71 .uuid = UUID_TOS_FW_CONFIG, 72 }; 73 74 static const io_uuid_spec_t nt_fw_config_uuid_spec = { 75 .uuid = UUID_NT_FW_CONFIG, 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 scp_fw_key_cert_uuid_spec = { 88 .uuid = UUID_SCP_FW_KEY_CERT, 89 }; 90 91 static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = { 92 .uuid = UUID_SOC_FW_KEY_CERT, 93 }; 94 95 static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = { 96 .uuid = UUID_TRUSTED_OS_FW_KEY_CERT, 97 }; 98 99 static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = { 100 .uuid = UUID_NON_TRUSTED_FW_KEY_CERT, 101 }; 102 103 static const io_uuid_spec_t scp_fw_cert_uuid_spec = { 104 .uuid = UUID_SCP_FW_CONTENT_CERT, 105 }; 106 107 static const io_uuid_spec_t soc_fw_cert_uuid_spec = { 108 .uuid = UUID_SOC_FW_CONTENT_CERT, 109 }; 110 111 static const io_uuid_spec_t tos_fw_cert_uuid_spec = { 112 .uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT, 113 }; 114 115 static const io_uuid_spec_t nt_fw_cert_uuid_spec = { 116 .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT, 117 }; 118 #endif /* TRUSTED_BOARD_BOOT */ 119 120 121 static int open_fip(const uintptr_t spec); 122 static int open_memmap(const uintptr_t spec); 123 124 struct plat_io_policy { 125 uintptr_t *dev_handle; 126 uintptr_t image_spec; 127 int (*check)(const uintptr_t spec); 128 }; 129 130 /* By default, ARM platforms load images from the FIP */ 131 static const struct plat_io_policy policies[] = { 132 [FIP_IMAGE_ID] = { 133 &memmap_dev_handle, 134 (uintptr_t)&fip_block_spec, 135 open_memmap 136 }, 137 [BL2_IMAGE_ID] = { 138 &fip_dev_handle, 139 (uintptr_t)&bl2_uuid_spec, 140 open_fip 141 }, 142 [SCP_BL2_IMAGE_ID] = { 143 &fip_dev_handle, 144 (uintptr_t)&scp_bl2_uuid_spec, 145 open_fip 146 }, 147 [BL31_IMAGE_ID] = { 148 &fip_dev_handle, 149 (uintptr_t)&bl31_uuid_spec, 150 open_fip 151 }, 152 [BL32_IMAGE_ID] = { 153 &fip_dev_handle, 154 (uintptr_t)&bl32_uuid_spec, 155 open_fip 156 }, 157 [BL32_EXTRA1_IMAGE_ID] = { 158 &fip_dev_handle, 159 (uintptr_t)&bl32_extra1_uuid_spec, 160 open_fip 161 }, 162 [BL32_EXTRA2_IMAGE_ID] = { 163 &fip_dev_handle, 164 (uintptr_t)&bl32_extra2_uuid_spec, 165 open_fip 166 }, 167 [BL33_IMAGE_ID] = { 168 &fip_dev_handle, 169 (uintptr_t)&bl33_uuid_spec, 170 open_fip 171 }, 172 [TB_FW_CONFIG_ID] = { 173 &fip_dev_handle, 174 (uintptr_t)&tb_fw_config_uuid_spec, 175 open_fip 176 }, 177 [HW_CONFIG_ID] = { 178 &fip_dev_handle, 179 (uintptr_t)&hw_config_uuid_spec, 180 open_fip 181 }, 182 [SOC_FW_CONFIG_ID] = { 183 &fip_dev_handle, 184 (uintptr_t)&soc_fw_config_uuid_spec, 185 open_fip 186 }, 187 [TOS_FW_CONFIG_ID] = { 188 &fip_dev_handle, 189 (uintptr_t)&tos_fw_config_uuid_spec, 190 open_fip 191 }, 192 [NT_FW_CONFIG_ID] = { 193 &fip_dev_handle, 194 (uintptr_t)&nt_fw_config_uuid_spec, 195 open_fip 196 }, 197 #if TRUSTED_BOARD_BOOT 198 [TRUSTED_BOOT_FW_CERT_ID] = { 199 &fip_dev_handle, 200 (uintptr_t)&tb_fw_cert_uuid_spec, 201 open_fip 202 }, 203 [TRUSTED_KEY_CERT_ID] = { 204 &fip_dev_handle, 205 (uintptr_t)&trusted_key_cert_uuid_spec, 206 open_fip 207 }, 208 [SCP_FW_KEY_CERT_ID] = { 209 &fip_dev_handle, 210 (uintptr_t)&scp_fw_key_cert_uuid_spec, 211 open_fip 212 }, 213 [SOC_FW_KEY_CERT_ID] = { 214 &fip_dev_handle, 215 (uintptr_t)&soc_fw_key_cert_uuid_spec, 216 open_fip 217 }, 218 [TRUSTED_OS_FW_KEY_CERT_ID] = { 219 &fip_dev_handle, 220 (uintptr_t)&tos_fw_key_cert_uuid_spec, 221 open_fip 222 }, 223 [NON_TRUSTED_FW_KEY_CERT_ID] = { 224 &fip_dev_handle, 225 (uintptr_t)&nt_fw_key_cert_uuid_spec, 226 open_fip 227 }, 228 [SCP_FW_CONTENT_CERT_ID] = { 229 &fip_dev_handle, 230 (uintptr_t)&scp_fw_cert_uuid_spec, 231 open_fip 232 }, 233 [SOC_FW_CONTENT_CERT_ID] = { 234 &fip_dev_handle, 235 (uintptr_t)&soc_fw_cert_uuid_spec, 236 open_fip 237 }, 238 [TRUSTED_OS_FW_CONTENT_CERT_ID] = { 239 &fip_dev_handle, 240 (uintptr_t)&tos_fw_cert_uuid_spec, 241 open_fip 242 }, 243 [NON_TRUSTED_FW_CONTENT_CERT_ID] = { 244 &fip_dev_handle, 245 (uintptr_t)&nt_fw_cert_uuid_spec, 246 open_fip 247 }, 248 #endif /* TRUSTED_BOARD_BOOT */ 249 }; 250 251 252 /* Weak definitions may be overridden in specific ARM standard platform */ 253 #pragma weak plat_arm_io_setup 254 #pragma weak plat_arm_get_alt_image_source 255 256 257 static int open_fip(const uintptr_t spec) 258 { 259 int result; 260 uintptr_t local_image_handle; 261 262 /* See if a Firmware Image Package is available */ 263 result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); 264 if (result == 0) { 265 result = io_open(fip_dev_handle, spec, &local_image_handle); 266 if (result == 0) { 267 VERBOSE("Using FIP\n"); 268 io_close(local_image_handle); 269 } 270 } 271 return result; 272 } 273 274 275 static int open_memmap(const uintptr_t spec) 276 { 277 int result; 278 uintptr_t local_image_handle; 279 280 result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL); 281 if (result == 0) { 282 result = io_open(memmap_dev_handle, spec, &local_image_handle); 283 if (result == 0) { 284 VERBOSE("Using Memmap\n"); 285 io_close(local_image_handle); 286 } 287 } 288 return result; 289 } 290 291 292 void arm_io_setup(void) 293 { 294 int io_result; 295 296 io_result = register_io_dev_fip(&fip_dev_con); 297 assert(io_result == 0); 298 299 io_result = register_io_dev_memmap(&memmap_dev_con); 300 assert(io_result == 0); 301 302 /* Open connections to devices and cache the handles */ 303 io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL, 304 &fip_dev_handle); 305 assert(io_result == 0); 306 307 io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL, 308 &memmap_dev_handle); 309 assert(io_result == 0); 310 311 /* Ignore improbable errors in release builds */ 312 (void)io_result; 313 } 314 315 void plat_arm_io_setup(void) 316 { 317 arm_io_setup(); 318 } 319 320 int plat_arm_get_alt_image_source( 321 unsigned int image_id __unused, 322 uintptr_t *dev_handle __unused, 323 uintptr_t *image_spec __unused) 324 { 325 /* By default do not try an alternative */ 326 return -ENOENT; 327 } 328 329 /* Return an IO device handle and specification which can be used to access 330 * an image. Use this to enforce platform load policy */ 331 int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, 332 uintptr_t *image_spec) 333 { 334 int result; 335 const struct plat_io_policy *policy; 336 337 assert(image_id < ARRAY_SIZE(policies)); 338 339 policy = &policies[image_id]; 340 result = policy->check(policy->image_spec); 341 if (result == 0) { 342 *image_spec = policy->image_spec; 343 *dev_handle = *(policy->dev_handle); 344 } else { 345 VERBOSE("Trying alternative IO\n"); 346 result = plat_arm_get_alt_image_source(image_id, dev_handle, 347 image_spec); 348 } 349 350 return result; 351 } 352 353 /* 354 * See if a Firmware Image Package is available, 355 * by checking if TOC is valid or not. 356 */ 357 int arm_io_is_toc_valid(void) 358 { 359 int result; 360 361 result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); 362 363 return (result == 0); 364 } 365 366