1 /* 2 * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 #include <string.h> 9 10 #include <platform_def.h> 11 12 #include <common/bl_common.h> 13 #include <common/debug.h> 14 #include <drivers/io/io_driver.h> 15 #include <drivers/io/io_encrypted.h> 16 #include <drivers/io/io_fip.h> 17 #include <drivers/io/io_memmap.h> 18 #include <drivers/io/io_semihosting.h> 19 #include <drivers/io/io_storage.h> 20 #include <lib/semihosting.h> 21 #include <tools_share/firmware_image_package.h> 22 23 /* Semihosting filenames */ 24 #define BL2_IMAGE_NAME "bl2.bin" 25 #define BL31_IMAGE_NAME "bl31.bin" 26 #define BL32_IMAGE_NAME "bl32.bin" 27 #define BL32_EXTRA1_IMAGE_NAME "bl32_extra1.bin" 28 #define BL32_EXTRA2_IMAGE_NAME "bl32_extra2.bin" 29 #define BL33_IMAGE_NAME "bl33.bin" 30 31 #if TRUSTED_BOARD_BOOT 32 #define TRUSTED_BOOT_FW_CERT_NAME "tb_fw.crt" 33 #define TRUSTED_KEY_CERT_NAME "trusted_key.crt" 34 #define SOC_FW_KEY_CERT_NAME "soc_fw_key.crt" 35 #define TOS_FW_KEY_CERT_NAME "tos_fw_key.crt" 36 #define NT_FW_KEY_CERT_NAME "nt_fw_key.crt" 37 #define SOC_FW_CONTENT_CERT_NAME "soc_fw_content.crt" 38 #define TOS_FW_CONTENT_CERT_NAME "tos_fw_content.crt" 39 #define NT_FW_CONTENT_CERT_NAME "nt_fw_content.crt" 40 #endif /* TRUSTED_BOARD_BOOT */ 41 42 43 44 /* IO devices */ 45 static const io_dev_connector_t *fip_dev_con; 46 static uintptr_t fip_dev_handle; 47 static const io_dev_connector_t *memmap_dev_con; 48 static uintptr_t memmap_dev_handle; 49 static const io_dev_connector_t *sh_dev_con; 50 static uintptr_t sh_dev_handle; 51 #ifndef DECRYPTION_SUPPORT_none 52 static const io_dev_connector_t *enc_dev_con; 53 static uintptr_t enc_dev_handle; 54 #endif 55 56 static const io_block_spec_t fip_block_spec = { 57 .offset = PLAT_QEMU_FIP_BASE, 58 .length = PLAT_QEMU_FIP_MAX_SIZE 59 }; 60 61 static const io_uuid_spec_t bl2_uuid_spec = { 62 .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2, 63 }; 64 65 static const io_uuid_spec_t bl31_uuid_spec = { 66 .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31, 67 }; 68 69 static const io_uuid_spec_t bl32_uuid_spec = { 70 .uuid = UUID_SECURE_PAYLOAD_BL32, 71 }; 72 73 static const io_uuid_spec_t bl32_extra1_uuid_spec = { 74 .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1, 75 }; 76 77 static const io_uuid_spec_t bl32_extra2_uuid_spec = { 78 .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2, 79 }; 80 81 static const io_uuid_spec_t bl33_uuid_spec = { 82 .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33, 83 }; 84 85 #if TRUSTED_BOARD_BOOT 86 static const io_uuid_spec_t tb_fw_cert_uuid_spec = { 87 .uuid = UUID_TRUSTED_BOOT_FW_CERT, 88 }; 89 90 static const io_uuid_spec_t trusted_key_cert_uuid_spec = { 91 .uuid = UUID_TRUSTED_KEY_CERT, 92 }; 93 94 static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = { 95 .uuid = UUID_SOC_FW_KEY_CERT, 96 }; 97 98 static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = { 99 .uuid = UUID_TRUSTED_OS_FW_KEY_CERT, 100 }; 101 102 static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = { 103 .uuid = UUID_NON_TRUSTED_FW_KEY_CERT, 104 }; 105 106 static const io_uuid_spec_t soc_fw_cert_uuid_spec = { 107 .uuid = UUID_SOC_FW_CONTENT_CERT, 108 }; 109 110 static const io_uuid_spec_t tos_fw_cert_uuid_spec = { 111 .uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT, 112 }; 113 114 static const io_uuid_spec_t nt_fw_cert_uuid_spec = { 115 .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT, 116 }; 117 #endif /* TRUSTED_BOARD_BOOT */ 118 119 static const io_file_spec_t sh_file_spec[] = { 120 [BL2_IMAGE_ID] = { 121 .path = BL2_IMAGE_NAME, 122 .mode = FOPEN_MODE_RB 123 }, 124 [BL31_IMAGE_ID] = { 125 .path = BL31_IMAGE_NAME, 126 .mode = FOPEN_MODE_RB 127 }, 128 [BL32_IMAGE_ID] = { 129 .path = BL32_IMAGE_NAME, 130 .mode = FOPEN_MODE_RB 131 }, 132 [BL32_EXTRA1_IMAGE_ID] = { 133 .path = BL32_EXTRA1_IMAGE_NAME, 134 .mode = FOPEN_MODE_RB 135 }, 136 [BL32_EXTRA2_IMAGE_ID] = { 137 .path = BL32_EXTRA2_IMAGE_NAME, 138 .mode = FOPEN_MODE_RB 139 }, 140 [BL33_IMAGE_ID] = { 141 .path = BL33_IMAGE_NAME, 142 .mode = FOPEN_MODE_RB 143 }, 144 #if TRUSTED_BOARD_BOOT 145 [TRUSTED_BOOT_FW_CERT_ID] = { 146 .path = TRUSTED_BOOT_FW_CERT_NAME, 147 .mode = FOPEN_MODE_RB 148 }, 149 [TRUSTED_KEY_CERT_ID] = { 150 .path = TRUSTED_KEY_CERT_NAME, 151 .mode = FOPEN_MODE_RB 152 }, 153 [SOC_FW_KEY_CERT_ID] = { 154 .path = SOC_FW_KEY_CERT_NAME, 155 .mode = FOPEN_MODE_RB 156 }, 157 [TRUSTED_OS_FW_KEY_CERT_ID] = { 158 .path = TOS_FW_KEY_CERT_NAME, 159 .mode = FOPEN_MODE_RB 160 }, 161 [NON_TRUSTED_FW_KEY_CERT_ID] = { 162 .path = NT_FW_KEY_CERT_NAME, 163 .mode = FOPEN_MODE_RB 164 }, 165 [SOC_FW_CONTENT_CERT_ID] = { 166 .path = SOC_FW_CONTENT_CERT_NAME, 167 .mode = FOPEN_MODE_RB 168 }, 169 [TRUSTED_OS_FW_CONTENT_CERT_ID] = { 170 .path = TOS_FW_CONTENT_CERT_NAME, 171 .mode = FOPEN_MODE_RB 172 }, 173 [NON_TRUSTED_FW_CONTENT_CERT_ID] = { 174 .path = NT_FW_CONTENT_CERT_NAME, 175 .mode = FOPEN_MODE_RB 176 }, 177 #endif /* TRUSTED_BOARD_BOOT */ 178 }; 179 180 static int open_fip(const uintptr_t spec); 181 static int open_memmap(const uintptr_t spec); 182 #ifndef DECRYPTION_SUPPORT_none 183 static int open_enc_fip(const uintptr_t spec); 184 #endif 185 186 struct plat_io_policy { 187 uintptr_t *dev_handle; 188 uintptr_t image_spec; 189 int (*check)(const uintptr_t spec); 190 }; 191 192 /* By default, ARM platforms load images from the FIP */ 193 static const struct plat_io_policy policies[] = { 194 [FIP_IMAGE_ID] = { 195 &memmap_dev_handle, 196 (uintptr_t)&fip_block_spec, 197 open_memmap 198 }, 199 [ENC_IMAGE_ID] = { 200 &fip_dev_handle, 201 (uintptr_t)NULL, 202 open_fip 203 }, 204 [BL2_IMAGE_ID] = { 205 &fip_dev_handle, 206 (uintptr_t)&bl2_uuid_spec, 207 open_fip 208 }, 209 #if ENCRYPT_BL31 && !defined(DECRYPTION_SUPPORT_none) 210 [BL31_IMAGE_ID] = { 211 &enc_dev_handle, 212 (uintptr_t)&bl31_uuid_spec, 213 open_enc_fip 214 }, 215 #else 216 [BL31_IMAGE_ID] = { 217 &fip_dev_handle, 218 (uintptr_t)&bl31_uuid_spec, 219 open_fip 220 }, 221 #endif 222 #if ENCRYPT_BL32 && !defined(DECRYPTION_SUPPORT_none) 223 [BL32_IMAGE_ID] = { 224 &enc_dev_handle, 225 (uintptr_t)&bl32_uuid_spec, 226 open_enc_fip 227 }, 228 [BL32_EXTRA1_IMAGE_ID] = { 229 &enc_dev_handle, 230 (uintptr_t)&bl32_extra1_uuid_spec, 231 open_enc_fip 232 }, 233 [BL32_EXTRA2_IMAGE_ID] = { 234 &enc_dev_handle, 235 (uintptr_t)&bl32_extra2_uuid_spec, 236 open_enc_fip 237 }, 238 #else 239 [BL32_IMAGE_ID] = { 240 &fip_dev_handle, 241 (uintptr_t)&bl32_uuid_spec, 242 open_fip 243 }, 244 [BL32_EXTRA1_IMAGE_ID] = { 245 &fip_dev_handle, 246 (uintptr_t)&bl32_extra1_uuid_spec, 247 open_fip 248 }, 249 [BL32_EXTRA2_IMAGE_ID] = { 250 &fip_dev_handle, 251 (uintptr_t)&bl32_extra2_uuid_spec, 252 open_fip 253 }, 254 #endif 255 [BL33_IMAGE_ID] = { 256 &fip_dev_handle, 257 (uintptr_t)&bl33_uuid_spec, 258 open_fip 259 }, 260 #if TRUSTED_BOARD_BOOT 261 [TRUSTED_BOOT_FW_CERT_ID] = { 262 &fip_dev_handle, 263 (uintptr_t)&tb_fw_cert_uuid_spec, 264 open_fip 265 }, 266 [TRUSTED_KEY_CERT_ID] = { 267 &fip_dev_handle, 268 (uintptr_t)&trusted_key_cert_uuid_spec, 269 open_fip 270 }, 271 [SOC_FW_KEY_CERT_ID] = { 272 &fip_dev_handle, 273 (uintptr_t)&soc_fw_key_cert_uuid_spec, 274 open_fip 275 }, 276 [TRUSTED_OS_FW_KEY_CERT_ID] = { 277 &fip_dev_handle, 278 (uintptr_t)&tos_fw_key_cert_uuid_spec, 279 open_fip 280 }, 281 [NON_TRUSTED_FW_KEY_CERT_ID] = { 282 &fip_dev_handle, 283 (uintptr_t)&nt_fw_key_cert_uuid_spec, 284 open_fip 285 }, 286 [SOC_FW_CONTENT_CERT_ID] = { 287 &fip_dev_handle, 288 (uintptr_t)&soc_fw_cert_uuid_spec, 289 open_fip 290 }, 291 [TRUSTED_OS_FW_CONTENT_CERT_ID] = { 292 &fip_dev_handle, 293 (uintptr_t)&tos_fw_cert_uuid_spec, 294 open_fip 295 }, 296 [NON_TRUSTED_FW_CONTENT_CERT_ID] = { 297 &fip_dev_handle, 298 (uintptr_t)&nt_fw_cert_uuid_spec, 299 open_fip 300 }, 301 #endif /* TRUSTED_BOARD_BOOT */ 302 }; 303 304 static int open_fip(const uintptr_t spec) 305 { 306 int result; 307 uintptr_t local_image_handle; 308 309 /* See if a Firmware Image Package is available */ 310 result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); 311 if (result == 0 && spec != (uintptr_t)NULL) { 312 result = io_open(fip_dev_handle, spec, &local_image_handle); 313 if (result == 0) { 314 VERBOSE("Using FIP\n"); 315 io_close(local_image_handle); 316 } 317 } 318 return result; 319 } 320 321 #ifndef DECRYPTION_SUPPORT_none 322 static int open_enc_fip(const uintptr_t spec) 323 { 324 int result; 325 uintptr_t local_image_handle; 326 327 /* See if an encrypted FIP is available */ 328 result = io_dev_init(enc_dev_handle, (uintptr_t)ENC_IMAGE_ID); 329 if (result == 0) { 330 result = io_open(enc_dev_handle, spec, &local_image_handle); 331 if (result == 0) { 332 VERBOSE("Using encrypted FIP\n"); 333 io_close(local_image_handle); 334 } 335 } 336 return result; 337 } 338 #endif 339 340 static int open_memmap(const uintptr_t spec) 341 { 342 int result; 343 uintptr_t local_image_handle; 344 345 result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL); 346 if (result == 0) { 347 result = io_open(memmap_dev_handle, spec, &local_image_handle); 348 if (result == 0) { 349 VERBOSE("Using Memmap\n"); 350 io_close(local_image_handle); 351 } 352 } 353 return result; 354 } 355 356 static int open_semihosting(const uintptr_t spec) 357 { 358 int result; 359 uintptr_t local_image_handle; 360 361 /* See if the file exists on semi-hosting.*/ 362 result = io_dev_init(sh_dev_handle, (uintptr_t)NULL); 363 if (result == 0) { 364 result = io_open(sh_dev_handle, spec, &local_image_handle); 365 if (result == 0) { 366 VERBOSE("Using Semi-hosting IO\n"); 367 io_close(local_image_handle); 368 } 369 } 370 return result; 371 } 372 373 void plat_qemu_io_setup(void) 374 { 375 int io_result; 376 377 io_result = register_io_dev_fip(&fip_dev_con); 378 assert(io_result == 0); 379 380 io_result = register_io_dev_memmap(&memmap_dev_con); 381 assert(io_result == 0); 382 383 /* Open connections to devices and cache the handles */ 384 io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL, 385 &fip_dev_handle); 386 assert(io_result == 0); 387 388 io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL, 389 &memmap_dev_handle); 390 assert(io_result == 0); 391 392 #ifndef DECRYPTION_SUPPORT_none 393 io_result = register_io_dev_enc(&enc_dev_con); 394 assert(io_result == 0); 395 396 io_result = io_dev_open(enc_dev_con, (uintptr_t)NULL, 397 &enc_dev_handle); 398 assert(io_result == 0); 399 #endif 400 401 /* Register the additional IO devices on this platform */ 402 io_result = register_io_dev_sh(&sh_dev_con); 403 assert(io_result == 0); 404 405 /* Open connections to devices and cache the handles */ 406 io_result = io_dev_open(sh_dev_con, (uintptr_t)NULL, &sh_dev_handle); 407 assert(io_result == 0); 408 409 /* Ignore improbable errors in release builds */ 410 (void)io_result; 411 } 412 413 static int get_alt_image_source(unsigned int image_id, uintptr_t *dev_handle, 414 uintptr_t *image_spec) 415 { 416 int result = open_semihosting((const uintptr_t)&sh_file_spec[image_id]); 417 418 if (result == 0) { 419 *dev_handle = sh_dev_handle; 420 *image_spec = (uintptr_t)&sh_file_spec[image_id]; 421 } 422 423 return result; 424 } 425 426 /* 427 * Return an IO device handle and specification which can be used to access 428 * an image. Use this to enforce platform load policy 429 */ 430 int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, 431 uintptr_t *image_spec) 432 { 433 int result; 434 const struct plat_io_policy *policy; 435 436 assert(image_id < ARRAY_SIZE(policies)); 437 438 policy = &policies[image_id]; 439 result = policy->check(policy->image_spec); 440 if (result == 0) { 441 *image_spec = policy->image_spec; 442 *dev_handle = *(policy->dev_handle); 443 } else { 444 VERBOSE("Trying alternative IO\n"); 445 result = get_alt_image_source(image_id, dev_handle, image_spec); 446 } 447 448 return result; 449 } 450