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 */ 609d40e0eSAntonio Nino Diaz 7b4315306SDan Handley #include <assert.h> 8b4315306SDan Handley #include <string.h> 909d40e0eSAntonio Nino Diaz 1009d40e0eSAntonio Nino Diaz #include <platform_def.h> 1109d40e0eSAntonio Nino Diaz 1209d40e0eSAntonio Nino Diaz #include <common/debug.h> 1309d40e0eSAntonio Nino Diaz #include <drivers/io/io_driver.h> 1409d40e0eSAntonio Nino Diaz #include <drivers/io/io_fip.h> 1509d40e0eSAntonio Nino Diaz #include <drivers/io/io_memmap.h> 1609d40e0eSAntonio Nino Diaz #include <drivers/io/io_storage.h> 1709d40e0eSAntonio Nino Diaz #include <lib/utils.h> 18*bd9344f6SAntonio Nino Diaz #include <plat/arm/common/plat_arm.h> 1909d40e0eSAntonio Nino Diaz #include <plat/common/platform.h> 2009d40e0eSAntonio Nino Diaz #include <tools_share/firmware_image_package.h> 2109d40e0eSAntonio Nino Diaz 22b4315306SDan Handley /* IO devices */ 23b4315306SDan Handley static const io_dev_connector_t *fip_dev_con; 24b4315306SDan Handley static uintptr_t fip_dev_handle; 25b4315306SDan Handley static const io_dev_connector_t *memmap_dev_con; 26b4315306SDan Handley static uintptr_t memmap_dev_handle; 27b4315306SDan Handley 28b4315306SDan Handley static const io_block_spec_t fip_block_spec = { 29b4315306SDan Handley .offset = PLAT_ARM_FIP_BASE, 30b4315306SDan Handley .length = PLAT_ARM_FIP_MAX_SIZE 31b4315306SDan Handley }; 32b4315306SDan Handley 3316948ae1SJuan Castillo static const io_uuid_spec_t bl2_uuid_spec = { 3416948ae1SJuan Castillo .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2, 35b4315306SDan Handley }; 36b4315306SDan Handley 37f59821d5SJuan Castillo static const io_uuid_spec_t scp_bl2_uuid_spec = { 38f59821d5SJuan Castillo .uuid = UUID_SCP_FIRMWARE_SCP_BL2, 39b4315306SDan Handley }; 40b4315306SDan Handley 4116948ae1SJuan Castillo static const io_uuid_spec_t bl31_uuid_spec = { 4216948ae1SJuan Castillo .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31, 43b4315306SDan Handley }; 44b4315306SDan Handley 4516948ae1SJuan Castillo static const io_uuid_spec_t bl32_uuid_spec = { 4616948ae1SJuan Castillo .uuid = UUID_SECURE_PAYLOAD_BL32, 47b4315306SDan Handley }; 48b4315306SDan Handley 4971fb3964SSummer Qin static const io_uuid_spec_t bl32_extra1_uuid_spec = { 5071fb3964SSummer Qin .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1, 5171fb3964SSummer Qin }; 5271fb3964SSummer Qin 5371fb3964SSummer Qin static const io_uuid_spec_t bl32_extra2_uuid_spec = { 5471fb3964SSummer Qin .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2, 5571fb3964SSummer Qin }; 5671fb3964SSummer Qin 5716948ae1SJuan Castillo static const io_uuid_spec_t bl33_uuid_spec = { 5816948ae1SJuan Castillo .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33, 59b4315306SDan Handley }; 60b4315306SDan Handley 61c228956aSSoby Mathew static const io_uuid_spec_t tb_fw_config_uuid_spec = { 62c228956aSSoby Mathew .uuid = UUID_TB_FW_CONFIG, 63c228956aSSoby Mathew }; 64c228956aSSoby Mathew 65cab0b5b0SSoby Mathew static const io_uuid_spec_t hw_config_uuid_spec = { 66cab0b5b0SSoby Mathew .uuid = UUID_HW_CONFIG, 67cab0b5b0SSoby Mathew }; 68cab0b5b0SSoby Mathew 691d71ba14SSoby Mathew static const io_uuid_spec_t soc_fw_config_uuid_spec = { 701d71ba14SSoby Mathew .uuid = UUID_SOC_FW_CONFIG, 711d71ba14SSoby Mathew }; 721d71ba14SSoby Mathew 731d71ba14SSoby Mathew static const io_uuid_spec_t tos_fw_config_uuid_spec = { 741d71ba14SSoby Mathew .uuid = UUID_TOS_FW_CONFIG, 751d71ba14SSoby Mathew }; 761d71ba14SSoby Mathew 771d71ba14SSoby Mathew static const io_uuid_spec_t nt_fw_config_uuid_spec = { 781d71ba14SSoby Mathew .uuid = UUID_NT_FW_CONFIG, 791d71ba14SSoby Mathew }; 801d71ba14SSoby Mathew 81b4315306SDan Handley #if TRUSTED_BOARD_BOOT 82516beb58SJuan Castillo static const io_uuid_spec_t tb_fw_cert_uuid_spec = { 83516beb58SJuan Castillo .uuid = UUID_TRUSTED_BOOT_FW_CERT, 84b4315306SDan Handley }; 85b4315306SDan Handley 8616948ae1SJuan Castillo static const io_uuid_spec_t trusted_key_cert_uuid_spec = { 8716948ae1SJuan Castillo .uuid = UUID_TRUSTED_KEY_CERT, 88b4315306SDan Handley }; 89b4315306SDan Handley 90516beb58SJuan Castillo static const io_uuid_spec_t scp_fw_key_cert_uuid_spec = { 91516beb58SJuan Castillo .uuid = UUID_SCP_FW_KEY_CERT, 92b4315306SDan Handley }; 93b4315306SDan Handley 94516beb58SJuan Castillo static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = { 95516beb58SJuan Castillo .uuid = UUID_SOC_FW_KEY_CERT, 96b4315306SDan Handley }; 97b4315306SDan Handley 98516beb58SJuan Castillo static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = { 99516beb58SJuan Castillo .uuid = UUID_TRUSTED_OS_FW_KEY_CERT, 100b4315306SDan Handley }; 101b4315306SDan Handley 102516beb58SJuan Castillo static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = { 103516beb58SJuan Castillo .uuid = UUID_NON_TRUSTED_FW_KEY_CERT, 104b4315306SDan Handley }; 105b4315306SDan Handley 106516beb58SJuan Castillo static const io_uuid_spec_t scp_fw_cert_uuid_spec = { 107516beb58SJuan Castillo .uuid = UUID_SCP_FW_CONTENT_CERT, 108b4315306SDan Handley }; 109b4315306SDan Handley 110516beb58SJuan Castillo static const io_uuid_spec_t soc_fw_cert_uuid_spec = { 111516beb58SJuan Castillo .uuid = UUID_SOC_FW_CONTENT_CERT, 112b4315306SDan Handley }; 113b4315306SDan Handley 114516beb58SJuan Castillo static const io_uuid_spec_t tos_fw_cert_uuid_spec = { 115516beb58SJuan Castillo .uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT, 116b4315306SDan Handley }; 117b4315306SDan Handley 118516beb58SJuan Castillo static const io_uuid_spec_t nt_fw_cert_uuid_spec = { 119516beb58SJuan Castillo .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT, 120b4315306SDan Handley }; 121b4315306SDan Handley #endif /* TRUSTED_BOARD_BOOT */ 122b4315306SDan Handley 12316948ae1SJuan Castillo 124b4315306SDan Handley static int open_fip(const uintptr_t spec); 125b4315306SDan Handley static int open_memmap(const uintptr_t spec); 126b4315306SDan Handley 127b4315306SDan Handley struct plat_io_policy { 128b4315306SDan Handley uintptr_t *dev_handle; 129b4315306SDan Handley uintptr_t image_spec; 130b4315306SDan Handley int (*check)(const uintptr_t spec); 131b4315306SDan Handley }; 132b4315306SDan Handley 13316948ae1SJuan Castillo /* By default, ARM platforms load images from the FIP */ 134b4315306SDan Handley static const struct plat_io_policy policies[] = { 13516948ae1SJuan Castillo [FIP_IMAGE_ID] = { 136b4315306SDan Handley &memmap_dev_handle, 137b4315306SDan Handley (uintptr_t)&fip_block_spec, 138b4315306SDan Handley open_memmap 13916948ae1SJuan Castillo }, 14016948ae1SJuan Castillo [BL2_IMAGE_ID] = { 141b4315306SDan Handley &fip_dev_handle, 14216948ae1SJuan Castillo (uintptr_t)&bl2_uuid_spec, 143b4315306SDan Handley open_fip 14416948ae1SJuan Castillo }, 145f59821d5SJuan Castillo [SCP_BL2_IMAGE_ID] = { 146b4315306SDan Handley &fip_dev_handle, 147f59821d5SJuan Castillo (uintptr_t)&scp_bl2_uuid_spec, 148b4315306SDan Handley open_fip 14916948ae1SJuan Castillo }, 15016948ae1SJuan Castillo [BL31_IMAGE_ID] = { 151b4315306SDan Handley &fip_dev_handle, 15216948ae1SJuan Castillo (uintptr_t)&bl31_uuid_spec, 153b4315306SDan Handley open_fip 15416948ae1SJuan Castillo }, 15516948ae1SJuan Castillo [BL32_IMAGE_ID] = { 156b4315306SDan Handley &fip_dev_handle, 15716948ae1SJuan Castillo (uintptr_t)&bl32_uuid_spec, 158b4315306SDan Handley open_fip 15916948ae1SJuan Castillo }, 16071fb3964SSummer Qin [BL32_EXTRA1_IMAGE_ID] = { 16171fb3964SSummer Qin &fip_dev_handle, 16271fb3964SSummer Qin (uintptr_t)&bl32_extra1_uuid_spec, 16371fb3964SSummer Qin open_fip 16471fb3964SSummer Qin }, 16571fb3964SSummer Qin [BL32_EXTRA2_IMAGE_ID] = { 16671fb3964SSummer Qin &fip_dev_handle, 16771fb3964SSummer Qin (uintptr_t)&bl32_extra2_uuid_spec, 16871fb3964SSummer Qin open_fip 16971fb3964SSummer Qin }, 17016948ae1SJuan Castillo [BL33_IMAGE_ID] = { 171b4315306SDan Handley &fip_dev_handle, 17216948ae1SJuan Castillo (uintptr_t)&bl33_uuid_spec, 173b4315306SDan Handley open_fip 17416948ae1SJuan Castillo }, 175c228956aSSoby Mathew [TB_FW_CONFIG_ID] = { 176c228956aSSoby Mathew &fip_dev_handle, 177c228956aSSoby Mathew (uintptr_t)&tb_fw_config_uuid_spec, 178c228956aSSoby Mathew open_fip 179c228956aSSoby Mathew }, 180cab0b5b0SSoby Mathew [HW_CONFIG_ID] = { 181cab0b5b0SSoby Mathew &fip_dev_handle, 182cab0b5b0SSoby Mathew (uintptr_t)&hw_config_uuid_spec, 183cab0b5b0SSoby Mathew open_fip 184cab0b5b0SSoby Mathew }, 1851d71ba14SSoby Mathew [SOC_FW_CONFIG_ID] = { 1861d71ba14SSoby Mathew &fip_dev_handle, 1871d71ba14SSoby Mathew (uintptr_t)&soc_fw_config_uuid_spec, 1881d71ba14SSoby Mathew open_fip 1891d71ba14SSoby Mathew }, 1901d71ba14SSoby Mathew [TOS_FW_CONFIG_ID] = { 1911d71ba14SSoby Mathew &fip_dev_handle, 1921d71ba14SSoby Mathew (uintptr_t)&tos_fw_config_uuid_spec, 1931d71ba14SSoby Mathew open_fip 1941d71ba14SSoby Mathew }, 1951d71ba14SSoby Mathew [NT_FW_CONFIG_ID] = { 1961d71ba14SSoby Mathew &fip_dev_handle, 1971d71ba14SSoby Mathew (uintptr_t)&nt_fw_config_uuid_spec, 1981d71ba14SSoby Mathew open_fip 1991d71ba14SSoby Mathew }, 200b4315306SDan Handley #if TRUSTED_BOARD_BOOT 201516beb58SJuan Castillo [TRUSTED_BOOT_FW_CERT_ID] = { 202b4315306SDan Handley &fip_dev_handle, 203516beb58SJuan Castillo (uintptr_t)&tb_fw_cert_uuid_spec, 204b4315306SDan Handley open_fip 20516948ae1SJuan Castillo }, 20616948ae1SJuan Castillo [TRUSTED_KEY_CERT_ID] = { 207b4315306SDan Handley &fip_dev_handle, 20816948ae1SJuan Castillo (uintptr_t)&trusted_key_cert_uuid_spec, 209b4315306SDan Handley open_fip 21016948ae1SJuan Castillo }, 211516beb58SJuan Castillo [SCP_FW_KEY_CERT_ID] = { 212b4315306SDan Handley &fip_dev_handle, 213516beb58SJuan Castillo (uintptr_t)&scp_fw_key_cert_uuid_spec, 214b4315306SDan Handley open_fip 21516948ae1SJuan Castillo }, 216516beb58SJuan Castillo [SOC_FW_KEY_CERT_ID] = { 217b4315306SDan Handley &fip_dev_handle, 218516beb58SJuan Castillo (uintptr_t)&soc_fw_key_cert_uuid_spec, 219b4315306SDan Handley open_fip 22016948ae1SJuan Castillo }, 221516beb58SJuan Castillo [TRUSTED_OS_FW_KEY_CERT_ID] = { 222b4315306SDan Handley &fip_dev_handle, 223516beb58SJuan Castillo (uintptr_t)&tos_fw_key_cert_uuid_spec, 224b4315306SDan Handley open_fip 22516948ae1SJuan Castillo }, 226516beb58SJuan Castillo [NON_TRUSTED_FW_KEY_CERT_ID] = { 227b4315306SDan Handley &fip_dev_handle, 228516beb58SJuan Castillo (uintptr_t)&nt_fw_key_cert_uuid_spec, 229b4315306SDan Handley open_fip 23016948ae1SJuan Castillo }, 231516beb58SJuan Castillo [SCP_FW_CONTENT_CERT_ID] = { 232b4315306SDan Handley &fip_dev_handle, 233516beb58SJuan Castillo (uintptr_t)&scp_fw_cert_uuid_spec, 234b4315306SDan Handley open_fip 23516948ae1SJuan Castillo }, 236516beb58SJuan Castillo [SOC_FW_CONTENT_CERT_ID] = { 237b4315306SDan Handley &fip_dev_handle, 238516beb58SJuan Castillo (uintptr_t)&soc_fw_cert_uuid_spec, 239b4315306SDan Handley open_fip 24016948ae1SJuan Castillo }, 241516beb58SJuan Castillo [TRUSTED_OS_FW_CONTENT_CERT_ID] = { 242b4315306SDan Handley &fip_dev_handle, 243516beb58SJuan Castillo (uintptr_t)&tos_fw_cert_uuid_spec, 244b4315306SDan Handley open_fip 24516948ae1SJuan Castillo }, 246516beb58SJuan Castillo [NON_TRUSTED_FW_CONTENT_CERT_ID] = { 247b4315306SDan Handley &fip_dev_handle, 248516beb58SJuan Castillo (uintptr_t)&nt_fw_cert_uuid_spec, 249b4315306SDan Handley open_fip 25016948ae1SJuan Castillo }, 251b4315306SDan Handley #endif /* TRUSTED_BOARD_BOOT */ 252b4315306SDan Handley }; 253b4315306SDan Handley 254b4315306SDan Handley 255b4315306SDan Handley /* Weak definitions may be overridden in specific ARM standard platform */ 256b4315306SDan Handley #pragma weak plat_arm_io_setup 257b4315306SDan Handley #pragma weak plat_arm_get_alt_image_source 258b4315306SDan Handley 259b4315306SDan Handley 260b4315306SDan Handley static int open_fip(const uintptr_t spec) 261b4315306SDan Handley { 262b4315306SDan Handley int result; 263b4315306SDan Handley uintptr_t local_image_handle; 264b4315306SDan Handley 265b4315306SDan Handley /* See if a Firmware Image Package is available */ 26616948ae1SJuan Castillo result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); 267e098e244SJuan Castillo if (result == 0) { 268b4315306SDan Handley result = io_open(fip_dev_handle, spec, &local_image_handle); 269e098e244SJuan Castillo if (result == 0) { 270b4315306SDan Handley VERBOSE("Using FIP\n"); 271b4315306SDan Handley io_close(local_image_handle); 272b4315306SDan Handley } 273b4315306SDan Handley } 274b4315306SDan Handley return result; 275b4315306SDan Handley } 276b4315306SDan Handley 277b4315306SDan Handley 278b4315306SDan Handley static int open_memmap(const uintptr_t spec) 279b4315306SDan Handley { 280b4315306SDan Handley int result; 281b4315306SDan Handley uintptr_t local_image_handle; 282b4315306SDan Handley 283b4315306SDan Handley result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL); 284e098e244SJuan Castillo if (result == 0) { 285b4315306SDan Handley result = io_open(memmap_dev_handle, spec, &local_image_handle); 286e098e244SJuan Castillo if (result == 0) { 287b4315306SDan Handley VERBOSE("Using Memmap\n"); 288b4315306SDan Handley io_close(local_image_handle); 289b4315306SDan Handley } 290b4315306SDan Handley } 291b4315306SDan Handley return result; 292b4315306SDan Handley } 293b4315306SDan Handley 294b4315306SDan Handley 295b4315306SDan Handley void arm_io_setup(void) 296b4315306SDan Handley { 297b4315306SDan Handley int io_result; 298b4315306SDan Handley 299b4315306SDan Handley io_result = register_io_dev_fip(&fip_dev_con); 300e098e244SJuan Castillo assert(io_result == 0); 301b4315306SDan Handley 302b4315306SDan Handley io_result = register_io_dev_memmap(&memmap_dev_con); 303e098e244SJuan Castillo assert(io_result == 0); 304b4315306SDan Handley 305b4315306SDan Handley /* Open connections to devices and cache the handles */ 306b4315306SDan Handley io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL, 307b4315306SDan Handley &fip_dev_handle); 308e098e244SJuan Castillo assert(io_result == 0); 309b4315306SDan Handley 310b4315306SDan Handley io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL, 311b4315306SDan Handley &memmap_dev_handle); 312e098e244SJuan Castillo assert(io_result == 0); 313b4315306SDan Handley 314b4315306SDan Handley /* Ignore improbable errors in release builds */ 315b4315306SDan Handley (void)io_result; 316b4315306SDan Handley } 317b4315306SDan Handley 318b4315306SDan Handley void plat_arm_io_setup(void) 319b4315306SDan Handley { 320b4315306SDan Handley arm_io_setup(); 321b4315306SDan Handley } 322b4315306SDan Handley 323b4315306SDan Handley int plat_arm_get_alt_image_source( 32465cd299fSSoren Brinkmann unsigned int image_id __unused, 32565cd299fSSoren Brinkmann uintptr_t *dev_handle __unused, 32665cd299fSSoren Brinkmann uintptr_t *image_spec __unused) 327b4315306SDan Handley { 328b4315306SDan Handley /* By default do not try an alternative */ 329e098e244SJuan Castillo return -ENOENT; 330b4315306SDan Handley } 331b4315306SDan Handley 332b4315306SDan Handley /* Return an IO device handle and specification which can be used to access 333b4315306SDan Handley * an image. Use this to enforce platform load policy */ 33416948ae1SJuan Castillo int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, 335b4315306SDan Handley uintptr_t *image_spec) 336b4315306SDan Handley { 337e098e244SJuan Castillo int result; 338b4315306SDan Handley const struct plat_io_policy *policy; 339b4315306SDan Handley 34016948ae1SJuan Castillo assert(image_id < ARRAY_SIZE(policies)); 34116948ae1SJuan Castillo 34216948ae1SJuan Castillo policy = &policies[image_id]; 343b4315306SDan Handley result = policy->check(policy->image_spec); 344e098e244SJuan Castillo if (result == 0) { 345b4315306SDan Handley *image_spec = policy->image_spec; 346b4315306SDan Handley *dev_handle = *(policy->dev_handle); 347b4315306SDan Handley } else { 34816948ae1SJuan Castillo VERBOSE("Trying alternative IO\n"); 34916948ae1SJuan Castillo result = plat_arm_get_alt_image_source(image_id, dev_handle, 35016948ae1SJuan Castillo image_spec); 351b4315306SDan Handley } 35216948ae1SJuan Castillo 353b4315306SDan Handley return result; 354b4315306SDan Handley } 355436223deSYatharth Kochar 356436223deSYatharth Kochar /* 357436223deSYatharth Kochar * See if a Firmware Image Package is available, 358436223deSYatharth Kochar * by checking if TOC is valid or not. 359436223deSYatharth Kochar */ 360436223deSYatharth Kochar int arm_io_is_toc_valid(void) 361436223deSYatharth Kochar { 362436223deSYatharth Kochar int result; 363436223deSYatharth Kochar 364436223deSYatharth Kochar result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); 365436223deSYatharth Kochar 366436223deSYatharth Kochar return (result == 0); 367436223deSYatharth Kochar } 368436223deSYatharth Kochar 369