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