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