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