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