1 /* 2 * Copyright (c) 2019-2020, 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 <common/debug.h> 11 #include <drivers/io/io_driver.h> 12 #include <drivers/io/io_fip.h> 13 #include <drivers/io/io_memmap.h> 14 #include <drivers/io/io_storage.h> 15 #include <tools_share/firmware_image_package.h> 16 17 #include <cmn_plat_def.h> 18 #include <cmn_plat_util.h> 19 #include <plat_brcm.h> 20 #include <platform_def.h> 21 22 /* IO devices */ 23 static const io_dev_connector_t *fip_dev_con; 24 static uintptr_t fip_dev_handle; 25 static const io_dev_connector_t *memmap_dev_con; 26 static uintptr_t memmap_dev_handle; 27 28 static const io_block_spec_t fip_block_spec = { 29 .offset = PLAT_BRCM_FIP_BASE, 30 .length = PLAT_BRCM_FIP_MAX_SIZE 31 }; 32 33 static const io_block_spec_t qspi_fip_block_spec = { 34 .offset = PLAT_BRCM_FIP_QSPI_BASE, 35 .length = PLAT_BRCM_FIP_MAX_SIZE 36 }; 37 38 static const io_block_spec_t nand_fip_block_spec = { 39 .offset = PLAT_BRCM_FIP_NAND_BASE, 40 .length = PLAT_BRCM_FIP_MAX_SIZE 41 }; 42 43 static const io_uuid_spec_t bl2_uuid_spec = { 44 .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2, 45 }; 46 47 static const io_uuid_spec_t scp_bl2_uuid_spec = { 48 .uuid = UUID_SCP_FIRMWARE_SCP_BL2, 49 }; 50 51 static const io_uuid_spec_t bl31_uuid_spec = { 52 .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31, 53 }; 54 55 static const io_uuid_spec_t bl32_uuid_spec = { 56 .uuid = UUID_SECURE_PAYLOAD_BL32, 57 }; 58 59 static const io_uuid_spec_t bl32_extra1_uuid_spec = { 60 .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1, 61 }; 62 63 static const io_uuid_spec_t bl32_extra2_uuid_spec = { 64 .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2, 65 }; 66 67 static const io_uuid_spec_t bl33_uuid_spec = { 68 .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33, 69 }; 70 71 static const io_uuid_spec_t tb_fw_config_uuid_spec = { 72 .uuid = UUID_TB_FW_CONFIG, 73 }; 74 75 static const io_uuid_spec_t hw_config_uuid_spec = { 76 .uuid = UUID_HW_CONFIG, 77 }; 78 79 static const io_uuid_spec_t soc_fw_config_uuid_spec = { 80 .uuid = UUID_SOC_FW_CONFIG, 81 }; 82 83 static const io_uuid_spec_t tos_fw_config_uuid_spec = { 84 .uuid = UUID_TOS_FW_CONFIG, 85 }; 86 87 static const io_uuid_spec_t nt_fw_config_uuid_spec = { 88 .uuid = UUID_NT_FW_CONFIG, 89 }; 90 91 #if TRUSTED_BOARD_BOOT 92 static const io_uuid_spec_t tb_fw_cert_uuid_spec = { 93 .uuid = UUID_TRUSTED_BOOT_FW_CERT, 94 }; 95 96 static const io_uuid_spec_t trusted_key_cert_uuid_spec = { 97 .uuid = UUID_TRUSTED_KEY_CERT, 98 }; 99 100 static const io_uuid_spec_t scp_fw_key_cert_uuid_spec = { 101 .uuid = UUID_SCP_FW_KEY_CERT, 102 }; 103 104 static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = { 105 .uuid = UUID_SOC_FW_KEY_CERT, 106 }; 107 108 static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = { 109 .uuid = UUID_TRUSTED_OS_FW_KEY_CERT, 110 }; 111 112 static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = { 113 .uuid = UUID_NON_TRUSTED_FW_KEY_CERT, 114 }; 115 116 static const io_uuid_spec_t scp_fw_cert_uuid_spec = { 117 .uuid = UUID_SCP_FW_CONTENT_CERT, 118 }; 119 120 static const io_uuid_spec_t soc_fw_cert_uuid_spec = { 121 .uuid = UUID_SOC_FW_CONTENT_CERT, 122 }; 123 124 static const io_uuid_spec_t tos_fw_cert_uuid_spec = { 125 .uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT, 126 }; 127 128 static const io_uuid_spec_t nt_fw_cert_uuid_spec = { 129 .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT, 130 }; 131 #endif /* TRUSTED_BOARD_BOOT */ 132 133 static int open_fip(const uintptr_t spec); 134 static int open_memmap(const uintptr_t spec); 135 static int open_qspi(const uintptr_t spec); 136 static int open_nand(const uintptr_t spec); 137 138 struct plat_io_policy { 139 uintptr_t *dev_handle; 140 uintptr_t image_spec; 141 int (*check)(const uintptr_t spec); 142 }; 143 144 /* By default, BRCM platforms load images from the FIP */ 145 static const struct plat_io_policy policies[] = { 146 [FIP_IMAGE_ID] = { 147 &memmap_dev_handle, 148 (uintptr_t)&fip_block_spec, 149 open_memmap 150 }, 151 [BL2_IMAGE_ID] = { 152 &fip_dev_handle, 153 (uintptr_t)&bl2_uuid_spec, 154 open_fip 155 }, 156 [SCP_BL2_IMAGE_ID] = { 157 &fip_dev_handle, 158 (uintptr_t)&scp_bl2_uuid_spec, 159 open_fip 160 }, 161 [BL31_IMAGE_ID] = { 162 &fip_dev_handle, 163 (uintptr_t)&bl31_uuid_spec, 164 open_fip 165 }, 166 [BL32_IMAGE_ID] = { 167 &fip_dev_handle, 168 (uintptr_t)&bl32_uuid_spec, 169 open_fip 170 }, 171 [BL32_EXTRA1_IMAGE_ID] = { 172 &fip_dev_handle, 173 (uintptr_t)&bl32_extra1_uuid_spec, 174 open_fip 175 }, 176 [BL32_EXTRA2_IMAGE_ID] = { 177 &fip_dev_handle, 178 (uintptr_t)&bl32_extra2_uuid_spec, 179 open_fip 180 }, 181 [BL33_IMAGE_ID] = { 182 &fip_dev_handle, 183 (uintptr_t)&bl33_uuid_spec, 184 open_fip 185 }, 186 [TB_FW_CONFIG_ID] = { 187 &fip_dev_handle, 188 (uintptr_t)&tb_fw_config_uuid_spec, 189 open_fip 190 }, 191 [HW_CONFIG_ID] = { 192 &fip_dev_handle, 193 (uintptr_t)&hw_config_uuid_spec, 194 open_fip 195 }, 196 [SOC_FW_CONFIG_ID] = { 197 &fip_dev_handle, 198 (uintptr_t)&soc_fw_config_uuid_spec, 199 open_fip 200 }, 201 [TOS_FW_CONFIG_ID] = { 202 &fip_dev_handle, 203 (uintptr_t)&tos_fw_config_uuid_spec, 204 open_fip 205 }, 206 [NT_FW_CONFIG_ID] = { 207 &fip_dev_handle, 208 (uintptr_t)&nt_fw_config_uuid_spec, 209 open_fip 210 }, 211 #if TRUSTED_BOARD_BOOT 212 [TRUSTED_BOOT_FW_CERT_ID] = { 213 &fip_dev_handle, 214 (uintptr_t)&tb_fw_cert_uuid_spec, 215 open_fip 216 }, 217 [TRUSTED_KEY_CERT_ID] = { 218 &fip_dev_handle, 219 (uintptr_t)&trusted_key_cert_uuid_spec, 220 open_fip 221 }, 222 [SCP_FW_KEY_CERT_ID] = { 223 &fip_dev_handle, 224 (uintptr_t)&scp_fw_key_cert_uuid_spec, 225 open_fip 226 }, 227 [SOC_FW_KEY_CERT_ID] = { 228 &fip_dev_handle, 229 (uintptr_t)&soc_fw_key_cert_uuid_spec, 230 open_fip 231 }, 232 [TRUSTED_OS_FW_KEY_CERT_ID] = { 233 &fip_dev_handle, 234 (uintptr_t)&tos_fw_key_cert_uuid_spec, 235 open_fip 236 }, 237 [NON_TRUSTED_FW_KEY_CERT_ID] = { 238 &fip_dev_handle, 239 (uintptr_t)&nt_fw_key_cert_uuid_spec, 240 open_fip 241 }, 242 [SCP_FW_CONTENT_CERT_ID] = { 243 &fip_dev_handle, 244 (uintptr_t)&scp_fw_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 /* By default, BRCM platforms load images from the FIP */ 266 static const struct plat_io_policy boot_source_policies[] = { 267 [BOOT_SOURCE_QSPI] = { 268 &memmap_dev_handle, 269 (uintptr_t)&qspi_fip_block_spec, 270 open_qspi 271 }, 272 [BOOT_SOURCE_NAND] = { 273 &memmap_dev_handle, 274 (uintptr_t)&nand_fip_block_spec, 275 open_nand 276 }, 277 }; 278 279 /* Weak definitions may be overridden in specific brcm platform */ 280 #pragma weak plat_brcm_io_setup 281 #pragma weak plat_brcm_process_flags 282 283 static int open_fip(const uintptr_t spec) 284 { 285 int result; 286 uintptr_t local_image_handle; 287 288 /* See if a Firmware Image Package is available */ 289 result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); 290 if (result == 0) { 291 result = io_open(fip_dev_handle, spec, &local_image_handle); 292 if (result == 0) { 293 VERBOSE("Using FIP\n"); 294 io_close(local_image_handle); 295 } 296 } 297 return result; 298 } 299 300 301 static int open_memmap(const uintptr_t spec) 302 { 303 int result; 304 uintptr_t local_image_handle; 305 306 result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL); 307 if (result == 0) { 308 result = io_open(memmap_dev_handle, spec, &local_image_handle); 309 if (result == 0) { 310 VERBOSE("Using Memmap\n"); 311 io_close(local_image_handle); 312 } 313 } 314 return result; 315 } 316 317 static int open_qspi(const uintptr_t spec) 318 { 319 return open_memmap(spec); 320 } 321 322 static int open_nand(const uintptr_t spec) 323 { 324 return open_memmap(spec); 325 } 326 327 328 void brcm_io_setup(void) 329 { 330 int io_result; 331 uint32_t boot_source; 332 333 io_result = register_io_dev_fip(&fip_dev_con); 334 assert(io_result == 0); 335 336 io_result = register_io_dev_memmap(&memmap_dev_con); 337 assert(io_result == 0); 338 339 /* Open connections to devices and cache the handles */ 340 io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL, 341 &fip_dev_handle); 342 assert(io_result == 0); 343 344 boot_source = boot_source_get(); 345 switch (boot_source) { 346 case BOOT_SOURCE_QSPI: 347 case BOOT_SOURCE_NAND: 348 default: 349 io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL, 350 &memmap_dev_handle); 351 break; 352 } 353 assert(io_result == 0); 354 355 /* Ignore improbable errors in release builds */ 356 (void)io_result; 357 } 358 359 void plat_brcm_io_setup(void) 360 { 361 brcm_io_setup(); 362 } 363 364 void plat_brcm_process_flags(uint16_t plat_toc_flags __unused) 365 { 366 WARN("%s not implemented\n", __func__); 367 } 368 369 /* 370 * Return an IO device handle and specification which can be used to access 371 * an image. Use this to enforce platform load policy 372 */ 373 int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, 374 uintptr_t *image_spec) 375 { 376 int result; 377 const struct plat_io_policy *policy; 378 uint32_t boot_source; 379 uint16_t lcl_plat_toc_flg; 380 381 assert(image_id < ARRAY_SIZE(policies)); 382 383 boot_source = boot_source_get(); 384 if (image_id == FIP_IMAGE_ID) 385 policy = &boot_source_policies[boot_source]; 386 else 387 policy = &policies[image_id]; 388 389 result = policy->check(policy->image_spec); 390 if (result == 0) { 391 *image_spec = policy->image_spec; 392 *dev_handle = *(policy->dev_handle); 393 394 if (image_id == TRUSTED_BOOT_FW_CERT_ID) { 395 /* 396 * Process the header flags to perform 397 * such custom actions as speeding up PLL. 398 * CERT seems to be the first image accessed 399 * by BL1 so this is where we process the flags. 400 */ 401 fip_dev_get_plat_toc_flag((io_dev_info_t *)fip_dev_handle, 402 &lcl_plat_toc_flg); 403 plat_brcm_process_flags(lcl_plat_toc_flg); 404 } 405 } 406 407 return result; 408 } 409