1b4315306SDan Handley /* 2c228956aSSoby Mathew * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. 3b4315306SDan Handley * 482cb2c1aSdp-arm * SPDX-License-Identifier: BSD-3-Clause 5b4315306SDan Handley */ 6b4315306SDan Handley #include <assert.h> 7b4315306SDan Handley #include <debug.h> 816948ae1SJuan Castillo #include <firmware_image_package.h> 9b4315306SDan Handley #include <io_driver.h> 10b4315306SDan Handley #include <io_fip.h> 11b4315306SDan Handley #include <io_memmap.h> 12b4315306SDan Handley #include <io_storage.h> 131af540efSRoberto Vargas #include <plat_arm.h> 141af540efSRoberto Vargas #include <platform.h> 15b4315306SDan Handley #include <platform_def.h> 16b4315306SDan Handley #include <string.h> 17ed81f3ebSSandrine Bailleux #include <utils.h> 18b4315306SDan Handley 19b4315306SDan Handley /* IO devices */ 20b4315306SDan Handley static const io_dev_connector_t *fip_dev_con; 21b4315306SDan Handley static uintptr_t fip_dev_handle; 22b4315306SDan Handley static const io_dev_connector_t *memmap_dev_con; 23b4315306SDan Handley static uintptr_t memmap_dev_handle; 24b4315306SDan Handley 25b4315306SDan Handley static const io_block_spec_t fip_block_spec = { 26b4315306SDan Handley .offset = PLAT_ARM_FIP_BASE, 27b4315306SDan Handley .length = PLAT_ARM_FIP_MAX_SIZE 28b4315306SDan Handley }; 29b4315306SDan Handley 3016948ae1SJuan Castillo static const io_uuid_spec_t bl2_uuid_spec = { 3116948ae1SJuan Castillo .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2, 32b4315306SDan Handley }; 33b4315306SDan Handley 34f59821d5SJuan Castillo static const io_uuid_spec_t scp_bl2_uuid_spec = { 35f59821d5SJuan Castillo .uuid = UUID_SCP_FIRMWARE_SCP_BL2, 36b4315306SDan Handley }; 37b4315306SDan Handley 3816948ae1SJuan Castillo static const io_uuid_spec_t bl31_uuid_spec = { 3916948ae1SJuan Castillo .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31, 40b4315306SDan Handley }; 41b4315306SDan Handley 4216948ae1SJuan Castillo static const io_uuid_spec_t bl32_uuid_spec = { 4316948ae1SJuan Castillo .uuid = UUID_SECURE_PAYLOAD_BL32, 44b4315306SDan Handley }; 45b4315306SDan Handley 4671fb3964SSummer Qin static const io_uuid_spec_t bl32_extra1_uuid_spec = { 4771fb3964SSummer Qin .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1, 4871fb3964SSummer Qin }; 4971fb3964SSummer Qin 5071fb3964SSummer Qin static const io_uuid_spec_t bl32_extra2_uuid_spec = { 5171fb3964SSummer Qin .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2, 5271fb3964SSummer Qin }; 5371fb3964SSummer Qin 5416948ae1SJuan Castillo static const io_uuid_spec_t bl33_uuid_spec = { 5516948ae1SJuan Castillo .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33, 56b4315306SDan Handley }; 57b4315306SDan Handley 58c228956aSSoby Mathew static const io_uuid_spec_t tb_fw_config_uuid_spec = { 59c228956aSSoby Mathew .uuid = UUID_TB_FW_CONFIG, 60c228956aSSoby Mathew }; 61c228956aSSoby Mathew 62cab0b5b0SSoby Mathew static const io_uuid_spec_t hw_config_uuid_spec = { 63cab0b5b0SSoby Mathew .uuid = UUID_HW_CONFIG, 64cab0b5b0SSoby Mathew }; 65cab0b5b0SSoby Mathew 66*1d71ba14SSoby Mathew static const io_uuid_spec_t soc_fw_config_uuid_spec = { 67*1d71ba14SSoby Mathew .uuid = UUID_SOC_FW_CONFIG, 68*1d71ba14SSoby Mathew }; 69*1d71ba14SSoby Mathew 70*1d71ba14SSoby Mathew static const io_uuid_spec_t tos_fw_config_uuid_spec = { 71*1d71ba14SSoby Mathew .uuid = UUID_TOS_FW_CONFIG, 72*1d71ba14SSoby Mathew }; 73*1d71ba14SSoby Mathew 74*1d71ba14SSoby Mathew static const io_uuid_spec_t nt_fw_config_uuid_spec = { 75*1d71ba14SSoby Mathew .uuid = UUID_NT_FW_CONFIG, 76*1d71ba14SSoby Mathew }; 77*1d71ba14SSoby Mathew 78b4315306SDan Handley #if TRUSTED_BOARD_BOOT 79516beb58SJuan Castillo static const io_uuid_spec_t tb_fw_cert_uuid_spec = { 80516beb58SJuan Castillo .uuid = UUID_TRUSTED_BOOT_FW_CERT, 81b4315306SDan Handley }; 82b4315306SDan Handley 8316948ae1SJuan Castillo static const io_uuid_spec_t trusted_key_cert_uuid_spec = { 8416948ae1SJuan Castillo .uuid = UUID_TRUSTED_KEY_CERT, 85b4315306SDan Handley }; 86b4315306SDan Handley 87516beb58SJuan Castillo static const io_uuid_spec_t scp_fw_key_cert_uuid_spec = { 88516beb58SJuan Castillo .uuid = UUID_SCP_FW_KEY_CERT, 89b4315306SDan Handley }; 90b4315306SDan Handley 91516beb58SJuan Castillo static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = { 92516beb58SJuan Castillo .uuid = UUID_SOC_FW_KEY_CERT, 93b4315306SDan Handley }; 94b4315306SDan Handley 95516beb58SJuan Castillo static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = { 96516beb58SJuan Castillo .uuid = UUID_TRUSTED_OS_FW_KEY_CERT, 97b4315306SDan Handley }; 98b4315306SDan Handley 99516beb58SJuan Castillo static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = { 100516beb58SJuan Castillo .uuid = UUID_NON_TRUSTED_FW_KEY_CERT, 101b4315306SDan Handley }; 102b4315306SDan Handley 103516beb58SJuan Castillo static const io_uuid_spec_t scp_fw_cert_uuid_spec = { 104516beb58SJuan Castillo .uuid = UUID_SCP_FW_CONTENT_CERT, 105b4315306SDan Handley }; 106b4315306SDan Handley 107516beb58SJuan Castillo static const io_uuid_spec_t soc_fw_cert_uuid_spec = { 108516beb58SJuan Castillo .uuid = UUID_SOC_FW_CONTENT_CERT, 109b4315306SDan Handley }; 110b4315306SDan Handley 111516beb58SJuan Castillo static const io_uuid_spec_t tos_fw_cert_uuid_spec = { 112516beb58SJuan Castillo .uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT, 113b4315306SDan Handley }; 114b4315306SDan Handley 115516beb58SJuan Castillo static const io_uuid_spec_t nt_fw_cert_uuid_spec = { 116516beb58SJuan Castillo .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT, 117b4315306SDan Handley }; 118b4315306SDan Handley #endif /* TRUSTED_BOARD_BOOT */ 119b4315306SDan Handley 12016948ae1SJuan Castillo 121b4315306SDan Handley static int open_fip(const uintptr_t spec); 122b4315306SDan Handley static int open_memmap(const uintptr_t spec); 123b4315306SDan Handley 124b4315306SDan Handley struct plat_io_policy { 125b4315306SDan Handley uintptr_t *dev_handle; 126b4315306SDan Handley uintptr_t image_spec; 127b4315306SDan Handley int (*check)(const uintptr_t spec); 128b4315306SDan Handley }; 129b4315306SDan Handley 13016948ae1SJuan Castillo /* By default, ARM platforms load images from the FIP */ 131b4315306SDan Handley static const struct plat_io_policy policies[] = { 13216948ae1SJuan Castillo [FIP_IMAGE_ID] = { 133b4315306SDan Handley &memmap_dev_handle, 134b4315306SDan Handley (uintptr_t)&fip_block_spec, 135b4315306SDan Handley open_memmap 13616948ae1SJuan Castillo }, 13716948ae1SJuan Castillo [BL2_IMAGE_ID] = { 138b4315306SDan Handley &fip_dev_handle, 13916948ae1SJuan Castillo (uintptr_t)&bl2_uuid_spec, 140b4315306SDan Handley open_fip 14116948ae1SJuan Castillo }, 142f59821d5SJuan Castillo [SCP_BL2_IMAGE_ID] = { 143b4315306SDan Handley &fip_dev_handle, 144f59821d5SJuan Castillo (uintptr_t)&scp_bl2_uuid_spec, 145b4315306SDan Handley open_fip 14616948ae1SJuan Castillo }, 14716948ae1SJuan Castillo [BL31_IMAGE_ID] = { 148b4315306SDan Handley &fip_dev_handle, 14916948ae1SJuan Castillo (uintptr_t)&bl31_uuid_spec, 150b4315306SDan Handley open_fip 15116948ae1SJuan Castillo }, 15216948ae1SJuan Castillo [BL32_IMAGE_ID] = { 153b4315306SDan Handley &fip_dev_handle, 15416948ae1SJuan Castillo (uintptr_t)&bl32_uuid_spec, 155b4315306SDan Handley open_fip 15616948ae1SJuan Castillo }, 15771fb3964SSummer Qin [BL32_EXTRA1_IMAGE_ID] = { 15871fb3964SSummer Qin &fip_dev_handle, 15971fb3964SSummer Qin (uintptr_t)&bl32_extra1_uuid_spec, 16071fb3964SSummer Qin open_fip 16171fb3964SSummer Qin }, 16271fb3964SSummer Qin [BL32_EXTRA2_IMAGE_ID] = { 16371fb3964SSummer Qin &fip_dev_handle, 16471fb3964SSummer Qin (uintptr_t)&bl32_extra2_uuid_spec, 16571fb3964SSummer Qin open_fip 16671fb3964SSummer Qin }, 16716948ae1SJuan Castillo [BL33_IMAGE_ID] = { 168b4315306SDan Handley &fip_dev_handle, 16916948ae1SJuan Castillo (uintptr_t)&bl33_uuid_spec, 170b4315306SDan Handley open_fip 17116948ae1SJuan Castillo }, 172c228956aSSoby Mathew [TB_FW_CONFIG_ID] = { 173c228956aSSoby Mathew &fip_dev_handle, 174c228956aSSoby Mathew (uintptr_t)&tb_fw_config_uuid_spec, 175c228956aSSoby Mathew open_fip 176c228956aSSoby Mathew }, 177cab0b5b0SSoby Mathew [HW_CONFIG_ID] = { 178cab0b5b0SSoby Mathew &fip_dev_handle, 179cab0b5b0SSoby Mathew (uintptr_t)&hw_config_uuid_spec, 180cab0b5b0SSoby Mathew open_fip 181cab0b5b0SSoby Mathew }, 182*1d71ba14SSoby Mathew [SOC_FW_CONFIG_ID] = { 183*1d71ba14SSoby Mathew &fip_dev_handle, 184*1d71ba14SSoby Mathew (uintptr_t)&soc_fw_config_uuid_spec, 185*1d71ba14SSoby Mathew open_fip 186*1d71ba14SSoby Mathew }, 187*1d71ba14SSoby Mathew [TOS_FW_CONFIG_ID] = { 188*1d71ba14SSoby Mathew &fip_dev_handle, 189*1d71ba14SSoby Mathew (uintptr_t)&tos_fw_config_uuid_spec, 190*1d71ba14SSoby Mathew open_fip 191*1d71ba14SSoby Mathew }, 192*1d71ba14SSoby Mathew [NT_FW_CONFIG_ID] = { 193*1d71ba14SSoby Mathew &fip_dev_handle, 194*1d71ba14SSoby Mathew (uintptr_t)&nt_fw_config_uuid_spec, 195*1d71ba14SSoby Mathew open_fip 196*1d71ba14SSoby Mathew }, 197b4315306SDan Handley #if TRUSTED_BOARD_BOOT 198516beb58SJuan Castillo [TRUSTED_BOOT_FW_CERT_ID] = { 199b4315306SDan Handley &fip_dev_handle, 200516beb58SJuan Castillo (uintptr_t)&tb_fw_cert_uuid_spec, 201b4315306SDan Handley open_fip 20216948ae1SJuan Castillo }, 20316948ae1SJuan Castillo [TRUSTED_KEY_CERT_ID] = { 204b4315306SDan Handley &fip_dev_handle, 20516948ae1SJuan Castillo (uintptr_t)&trusted_key_cert_uuid_spec, 206b4315306SDan Handley open_fip 20716948ae1SJuan Castillo }, 208516beb58SJuan Castillo [SCP_FW_KEY_CERT_ID] = { 209b4315306SDan Handley &fip_dev_handle, 210516beb58SJuan Castillo (uintptr_t)&scp_fw_key_cert_uuid_spec, 211b4315306SDan Handley open_fip 21216948ae1SJuan Castillo }, 213516beb58SJuan Castillo [SOC_FW_KEY_CERT_ID] = { 214b4315306SDan Handley &fip_dev_handle, 215516beb58SJuan Castillo (uintptr_t)&soc_fw_key_cert_uuid_spec, 216b4315306SDan Handley open_fip 21716948ae1SJuan Castillo }, 218516beb58SJuan Castillo [TRUSTED_OS_FW_KEY_CERT_ID] = { 219b4315306SDan Handley &fip_dev_handle, 220516beb58SJuan Castillo (uintptr_t)&tos_fw_key_cert_uuid_spec, 221b4315306SDan Handley open_fip 22216948ae1SJuan Castillo }, 223516beb58SJuan Castillo [NON_TRUSTED_FW_KEY_CERT_ID] = { 224b4315306SDan Handley &fip_dev_handle, 225516beb58SJuan Castillo (uintptr_t)&nt_fw_key_cert_uuid_spec, 226b4315306SDan Handley open_fip 22716948ae1SJuan Castillo }, 228516beb58SJuan Castillo [SCP_FW_CONTENT_CERT_ID] = { 229b4315306SDan Handley &fip_dev_handle, 230516beb58SJuan Castillo (uintptr_t)&scp_fw_cert_uuid_spec, 231b4315306SDan Handley open_fip 23216948ae1SJuan Castillo }, 233516beb58SJuan Castillo [SOC_FW_CONTENT_CERT_ID] = { 234b4315306SDan Handley &fip_dev_handle, 235516beb58SJuan Castillo (uintptr_t)&soc_fw_cert_uuid_spec, 236b4315306SDan Handley open_fip 23716948ae1SJuan Castillo }, 238516beb58SJuan Castillo [TRUSTED_OS_FW_CONTENT_CERT_ID] = { 239b4315306SDan Handley &fip_dev_handle, 240516beb58SJuan Castillo (uintptr_t)&tos_fw_cert_uuid_spec, 241b4315306SDan Handley open_fip 24216948ae1SJuan Castillo }, 243516beb58SJuan Castillo [NON_TRUSTED_FW_CONTENT_CERT_ID] = { 244b4315306SDan Handley &fip_dev_handle, 245516beb58SJuan Castillo (uintptr_t)&nt_fw_cert_uuid_spec, 246b4315306SDan Handley open_fip 24716948ae1SJuan Castillo }, 248b4315306SDan Handley #endif /* TRUSTED_BOARD_BOOT */ 249b4315306SDan Handley }; 250b4315306SDan Handley 251b4315306SDan Handley 252b4315306SDan Handley /* Weak definitions may be overridden in specific ARM standard platform */ 253b4315306SDan Handley #pragma weak plat_arm_io_setup 254b4315306SDan Handley #pragma weak plat_arm_get_alt_image_source 255b4315306SDan Handley 256b4315306SDan Handley 257b4315306SDan Handley static int open_fip(const uintptr_t spec) 258b4315306SDan Handley { 259b4315306SDan Handley int result; 260b4315306SDan Handley uintptr_t local_image_handle; 261b4315306SDan Handley 262b4315306SDan Handley /* See if a Firmware Image Package is available */ 26316948ae1SJuan Castillo result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); 264e098e244SJuan Castillo if (result == 0) { 265b4315306SDan Handley result = io_open(fip_dev_handle, spec, &local_image_handle); 266e098e244SJuan Castillo if (result == 0) { 267b4315306SDan Handley VERBOSE("Using FIP\n"); 268b4315306SDan Handley io_close(local_image_handle); 269b4315306SDan Handley } 270b4315306SDan Handley } 271b4315306SDan Handley return result; 272b4315306SDan Handley } 273b4315306SDan Handley 274b4315306SDan Handley 275b4315306SDan Handley static int open_memmap(const uintptr_t spec) 276b4315306SDan Handley { 277b4315306SDan Handley int result; 278b4315306SDan Handley uintptr_t local_image_handle; 279b4315306SDan Handley 280b4315306SDan Handley result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL); 281e098e244SJuan Castillo if (result == 0) { 282b4315306SDan Handley result = io_open(memmap_dev_handle, spec, &local_image_handle); 283e098e244SJuan Castillo if (result == 0) { 284b4315306SDan Handley VERBOSE("Using Memmap\n"); 285b4315306SDan Handley io_close(local_image_handle); 286b4315306SDan Handley } 287b4315306SDan Handley } 288b4315306SDan Handley return result; 289b4315306SDan Handley } 290b4315306SDan Handley 291b4315306SDan Handley 292b4315306SDan Handley void arm_io_setup(void) 293b4315306SDan Handley { 294b4315306SDan Handley int io_result; 295b4315306SDan Handley 296b4315306SDan Handley io_result = register_io_dev_fip(&fip_dev_con); 297e098e244SJuan Castillo assert(io_result == 0); 298b4315306SDan Handley 299b4315306SDan Handley io_result = register_io_dev_memmap(&memmap_dev_con); 300e098e244SJuan Castillo assert(io_result == 0); 301b4315306SDan Handley 302b4315306SDan Handley /* Open connections to devices and cache the handles */ 303b4315306SDan Handley io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL, 304b4315306SDan Handley &fip_dev_handle); 305e098e244SJuan Castillo assert(io_result == 0); 306b4315306SDan Handley 307b4315306SDan Handley io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL, 308b4315306SDan Handley &memmap_dev_handle); 309e098e244SJuan Castillo assert(io_result == 0); 310b4315306SDan Handley 311b4315306SDan Handley /* Ignore improbable errors in release builds */ 312b4315306SDan Handley (void)io_result; 313b4315306SDan Handley } 314b4315306SDan Handley 315b4315306SDan Handley void plat_arm_io_setup(void) 316b4315306SDan Handley { 317b4315306SDan Handley arm_io_setup(); 318b4315306SDan Handley } 319b4315306SDan Handley 320b4315306SDan Handley int plat_arm_get_alt_image_source( 32165cd299fSSoren Brinkmann unsigned int image_id __unused, 32265cd299fSSoren Brinkmann uintptr_t *dev_handle __unused, 32365cd299fSSoren Brinkmann uintptr_t *image_spec __unused) 324b4315306SDan Handley { 325b4315306SDan Handley /* By default do not try an alternative */ 326e098e244SJuan Castillo return -ENOENT; 327b4315306SDan Handley } 328b4315306SDan Handley 329b4315306SDan Handley /* Return an IO device handle and specification which can be used to access 330b4315306SDan Handley * an image. Use this to enforce platform load policy */ 33116948ae1SJuan Castillo int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, 332b4315306SDan Handley uintptr_t *image_spec) 333b4315306SDan Handley { 334e098e244SJuan Castillo int result; 335b4315306SDan Handley const struct plat_io_policy *policy; 336b4315306SDan Handley 33716948ae1SJuan Castillo assert(image_id < ARRAY_SIZE(policies)); 33816948ae1SJuan Castillo 33916948ae1SJuan Castillo policy = &policies[image_id]; 340b4315306SDan Handley result = policy->check(policy->image_spec); 341e098e244SJuan Castillo if (result == 0) { 342b4315306SDan Handley *image_spec = policy->image_spec; 343b4315306SDan Handley *dev_handle = *(policy->dev_handle); 344b4315306SDan Handley } else { 34516948ae1SJuan Castillo VERBOSE("Trying alternative IO\n"); 34616948ae1SJuan Castillo result = plat_arm_get_alt_image_source(image_id, dev_handle, 34716948ae1SJuan Castillo image_spec); 348b4315306SDan Handley } 34916948ae1SJuan Castillo 350b4315306SDan Handley return result; 351b4315306SDan Handley } 352436223deSYatharth Kochar 353436223deSYatharth Kochar /* 354436223deSYatharth Kochar * See if a Firmware Image Package is available, 355436223deSYatharth Kochar * by checking if TOC is valid or not. 356436223deSYatharth Kochar */ 357436223deSYatharth Kochar int arm_io_is_toc_valid(void) 358436223deSYatharth Kochar { 359436223deSYatharth Kochar int result; 360436223deSYatharth Kochar 361436223deSYatharth Kochar result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); 362436223deSYatharth Kochar 363436223deSYatharth Kochar return (result == 0); 364436223deSYatharth Kochar } 365436223deSYatharth Kochar 366