1b4315306SDan Handley /* 2*c228956aSSoby 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> 13b4315306SDan Handley #include <platform_def.h> 14b4315306SDan Handley #include <string.h> 15ed81f3ebSSandrine Bailleux #include <utils.h> 16b4315306SDan Handley 17b4315306SDan Handley /* IO devices */ 18b4315306SDan Handley static const io_dev_connector_t *fip_dev_con; 19b4315306SDan Handley static uintptr_t fip_dev_handle; 20b4315306SDan Handley static const io_dev_connector_t *memmap_dev_con; 21b4315306SDan Handley static uintptr_t memmap_dev_handle; 22b4315306SDan Handley 23b4315306SDan Handley static const io_block_spec_t fip_block_spec = { 24b4315306SDan Handley .offset = PLAT_ARM_FIP_BASE, 25b4315306SDan Handley .length = PLAT_ARM_FIP_MAX_SIZE 26b4315306SDan Handley }; 27b4315306SDan Handley 2816948ae1SJuan Castillo static const io_uuid_spec_t bl2_uuid_spec = { 2916948ae1SJuan Castillo .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2, 30b4315306SDan Handley }; 31b4315306SDan Handley 32f59821d5SJuan Castillo static const io_uuid_spec_t scp_bl2_uuid_spec = { 33f59821d5SJuan Castillo .uuid = UUID_SCP_FIRMWARE_SCP_BL2, 34b4315306SDan Handley }; 35b4315306SDan Handley 3616948ae1SJuan Castillo static const io_uuid_spec_t bl31_uuid_spec = { 3716948ae1SJuan Castillo .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31, 38b4315306SDan Handley }; 39b4315306SDan Handley 4016948ae1SJuan Castillo static const io_uuid_spec_t bl32_uuid_spec = { 4116948ae1SJuan Castillo .uuid = UUID_SECURE_PAYLOAD_BL32, 42b4315306SDan Handley }; 43b4315306SDan Handley 4471fb3964SSummer Qin static const io_uuid_spec_t bl32_extra1_uuid_spec = { 4571fb3964SSummer Qin .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1, 4671fb3964SSummer Qin }; 4771fb3964SSummer Qin 4871fb3964SSummer Qin static const io_uuid_spec_t bl32_extra2_uuid_spec = { 4971fb3964SSummer Qin .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2, 5071fb3964SSummer Qin }; 5171fb3964SSummer Qin 5216948ae1SJuan Castillo static const io_uuid_spec_t bl33_uuid_spec = { 5316948ae1SJuan Castillo .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33, 54b4315306SDan Handley }; 55b4315306SDan Handley 56*c228956aSSoby Mathew static const io_uuid_spec_t tb_fw_config_uuid_spec = { 57*c228956aSSoby Mathew .uuid = UUID_TB_FW_CONFIG, 58*c228956aSSoby Mathew }; 59*c228956aSSoby Mathew 60b4315306SDan Handley #if TRUSTED_BOARD_BOOT 61516beb58SJuan Castillo static const io_uuid_spec_t tb_fw_cert_uuid_spec = { 62516beb58SJuan Castillo .uuid = UUID_TRUSTED_BOOT_FW_CERT, 63b4315306SDan Handley }; 64b4315306SDan Handley 6516948ae1SJuan Castillo static const io_uuid_spec_t trusted_key_cert_uuid_spec = { 6616948ae1SJuan Castillo .uuid = UUID_TRUSTED_KEY_CERT, 67b4315306SDan Handley }; 68b4315306SDan Handley 69516beb58SJuan Castillo static const io_uuid_spec_t scp_fw_key_cert_uuid_spec = { 70516beb58SJuan Castillo .uuid = UUID_SCP_FW_KEY_CERT, 71b4315306SDan Handley }; 72b4315306SDan Handley 73516beb58SJuan Castillo static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = { 74516beb58SJuan Castillo .uuid = UUID_SOC_FW_KEY_CERT, 75b4315306SDan Handley }; 76b4315306SDan Handley 77516beb58SJuan Castillo static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = { 78516beb58SJuan Castillo .uuid = UUID_TRUSTED_OS_FW_KEY_CERT, 79b4315306SDan Handley }; 80b4315306SDan Handley 81516beb58SJuan Castillo static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = { 82516beb58SJuan Castillo .uuid = UUID_NON_TRUSTED_FW_KEY_CERT, 83b4315306SDan Handley }; 84b4315306SDan Handley 85516beb58SJuan Castillo static const io_uuid_spec_t scp_fw_cert_uuid_spec = { 86516beb58SJuan Castillo .uuid = UUID_SCP_FW_CONTENT_CERT, 87b4315306SDan Handley }; 88b4315306SDan Handley 89516beb58SJuan Castillo static const io_uuid_spec_t soc_fw_cert_uuid_spec = { 90516beb58SJuan Castillo .uuid = UUID_SOC_FW_CONTENT_CERT, 91b4315306SDan Handley }; 92b4315306SDan Handley 93516beb58SJuan Castillo static const io_uuid_spec_t tos_fw_cert_uuid_spec = { 94516beb58SJuan Castillo .uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT, 95b4315306SDan Handley }; 96b4315306SDan Handley 97516beb58SJuan Castillo static const io_uuid_spec_t nt_fw_cert_uuid_spec = { 98516beb58SJuan Castillo .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT, 99b4315306SDan Handley }; 100b4315306SDan Handley #endif /* TRUSTED_BOARD_BOOT */ 101b4315306SDan Handley 10216948ae1SJuan Castillo 103b4315306SDan Handley static int open_fip(const uintptr_t spec); 104b4315306SDan Handley static int open_memmap(const uintptr_t spec); 105b4315306SDan Handley 106b4315306SDan Handley struct plat_io_policy { 107b4315306SDan Handley uintptr_t *dev_handle; 108b4315306SDan Handley uintptr_t image_spec; 109b4315306SDan Handley int (*check)(const uintptr_t spec); 110b4315306SDan Handley }; 111b4315306SDan Handley 11216948ae1SJuan Castillo /* By default, ARM platforms load images from the FIP */ 113b4315306SDan Handley static const struct plat_io_policy policies[] = { 11416948ae1SJuan Castillo [FIP_IMAGE_ID] = { 115b4315306SDan Handley &memmap_dev_handle, 116b4315306SDan Handley (uintptr_t)&fip_block_spec, 117b4315306SDan Handley open_memmap 11816948ae1SJuan Castillo }, 11916948ae1SJuan Castillo [BL2_IMAGE_ID] = { 120b4315306SDan Handley &fip_dev_handle, 12116948ae1SJuan Castillo (uintptr_t)&bl2_uuid_spec, 122b4315306SDan Handley open_fip 12316948ae1SJuan Castillo }, 124f59821d5SJuan Castillo [SCP_BL2_IMAGE_ID] = { 125b4315306SDan Handley &fip_dev_handle, 126f59821d5SJuan Castillo (uintptr_t)&scp_bl2_uuid_spec, 127b4315306SDan Handley open_fip 12816948ae1SJuan Castillo }, 12916948ae1SJuan Castillo [BL31_IMAGE_ID] = { 130b4315306SDan Handley &fip_dev_handle, 13116948ae1SJuan Castillo (uintptr_t)&bl31_uuid_spec, 132b4315306SDan Handley open_fip 13316948ae1SJuan Castillo }, 13416948ae1SJuan Castillo [BL32_IMAGE_ID] = { 135b4315306SDan Handley &fip_dev_handle, 13616948ae1SJuan Castillo (uintptr_t)&bl32_uuid_spec, 137b4315306SDan Handley open_fip 13816948ae1SJuan Castillo }, 13971fb3964SSummer Qin [BL32_EXTRA1_IMAGE_ID] = { 14071fb3964SSummer Qin &fip_dev_handle, 14171fb3964SSummer Qin (uintptr_t)&bl32_extra1_uuid_spec, 14271fb3964SSummer Qin open_fip 14371fb3964SSummer Qin }, 14471fb3964SSummer Qin [BL32_EXTRA2_IMAGE_ID] = { 14571fb3964SSummer Qin &fip_dev_handle, 14671fb3964SSummer Qin (uintptr_t)&bl32_extra2_uuid_spec, 14771fb3964SSummer Qin open_fip 14871fb3964SSummer Qin }, 14916948ae1SJuan Castillo [BL33_IMAGE_ID] = { 150b4315306SDan Handley &fip_dev_handle, 15116948ae1SJuan Castillo (uintptr_t)&bl33_uuid_spec, 152b4315306SDan Handley open_fip 15316948ae1SJuan Castillo }, 154*c228956aSSoby Mathew [TB_FW_CONFIG_ID] = { 155*c228956aSSoby Mathew &fip_dev_handle, 156*c228956aSSoby Mathew (uintptr_t)&tb_fw_config_uuid_spec, 157*c228956aSSoby Mathew open_fip 158*c228956aSSoby Mathew }, 159b4315306SDan Handley #if TRUSTED_BOARD_BOOT 160516beb58SJuan Castillo [TRUSTED_BOOT_FW_CERT_ID] = { 161b4315306SDan Handley &fip_dev_handle, 162516beb58SJuan Castillo (uintptr_t)&tb_fw_cert_uuid_spec, 163b4315306SDan Handley open_fip 16416948ae1SJuan Castillo }, 16516948ae1SJuan Castillo [TRUSTED_KEY_CERT_ID] = { 166b4315306SDan Handley &fip_dev_handle, 16716948ae1SJuan Castillo (uintptr_t)&trusted_key_cert_uuid_spec, 168b4315306SDan Handley open_fip 16916948ae1SJuan Castillo }, 170516beb58SJuan Castillo [SCP_FW_KEY_CERT_ID] = { 171b4315306SDan Handley &fip_dev_handle, 172516beb58SJuan Castillo (uintptr_t)&scp_fw_key_cert_uuid_spec, 173b4315306SDan Handley open_fip 17416948ae1SJuan Castillo }, 175516beb58SJuan Castillo [SOC_FW_KEY_CERT_ID] = { 176b4315306SDan Handley &fip_dev_handle, 177516beb58SJuan Castillo (uintptr_t)&soc_fw_key_cert_uuid_spec, 178b4315306SDan Handley open_fip 17916948ae1SJuan Castillo }, 180516beb58SJuan Castillo [TRUSTED_OS_FW_KEY_CERT_ID] = { 181b4315306SDan Handley &fip_dev_handle, 182516beb58SJuan Castillo (uintptr_t)&tos_fw_key_cert_uuid_spec, 183b4315306SDan Handley open_fip 18416948ae1SJuan Castillo }, 185516beb58SJuan Castillo [NON_TRUSTED_FW_KEY_CERT_ID] = { 186b4315306SDan Handley &fip_dev_handle, 187516beb58SJuan Castillo (uintptr_t)&nt_fw_key_cert_uuid_spec, 188b4315306SDan Handley open_fip 18916948ae1SJuan Castillo }, 190516beb58SJuan Castillo [SCP_FW_CONTENT_CERT_ID] = { 191b4315306SDan Handley &fip_dev_handle, 192516beb58SJuan Castillo (uintptr_t)&scp_fw_cert_uuid_spec, 193b4315306SDan Handley open_fip 19416948ae1SJuan Castillo }, 195516beb58SJuan Castillo [SOC_FW_CONTENT_CERT_ID] = { 196b4315306SDan Handley &fip_dev_handle, 197516beb58SJuan Castillo (uintptr_t)&soc_fw_cert_uuid_spec, 198b4315306SDan Handley open_fip 19916948ae1SJuan Castillo }, 200516beb58SJuan Castillo [TRUSTED_OS_FW_CONTENT_CERT_ID] = { 201b4315306SDan Handley &fip_dev_handle, 202516beb58SJuan Castillo (uintptr_t)&tos_fw_cert_uuid_spec, 203b4315306SDan Handley open_fip 20416948ae1SJuan Castillo }, 205516beb58SJuan Castillo [NON_TRUSTED_FW_CONTENT_CERT_ID] = { 206b4315306SDan Handley &fip_dev_handle, 207516beb58SJuan Castillo (uintptr_t)&nt_fw_cert_uuid_spec, 208b4315306SDan Handley open_fip 20916948ae1SJuan Castillo }, 210b4315306SDan Handley #endif /* TRUSTED_BOARD_BOOT */ 211b4315306SDan Handley }; 212b4315306SDan Handley 213b4315306SDan Handley 214b4315306SDan Handley /* Weak definitions may be overridden in specific ARM standard platform */ 215b4315306SDan Handley #pragma weak plat_arm_io_setup 216b4315306SDan Handley #pragma weak plat_arm_get_alt_image_source 217b4315306SDan Handley 218b4315306SDan Handley 219b4315306SDan Handley static int open_fip(const uintptr_t spec) 220b4315306SDan Handley { 221b4315306SDan Handley int result; 222b4315306SDan Handley uintptr_t local_image_handle; 223b4315306SDan Handley 224b4315306SDan Handley /* See if a Firmware Image Package is available */ 22516948ae1SJuan Castillo result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); 226e098e244SJuan Castillo if (result == 0) { 227b4315306SDan Handley result = io_open(fip_dev_handle, spec, &local_image_handle); 228e098e244SJuan Castillo if (result == 0) { 229b4315306SDan Handley VERBOSE("Using FIP\n"); 230b4315306SDan Handley io_close(local_image_handle); 231b4315306SDan Handley } 232b4315306SDan Handley } 233b4315306SDan Handley return result; 234b4315306SDan Handley } 235b4315306SDan Handley 236b4315306SDan Handley 237b4315306SDan Handley static int open_memmap(const uintptr_t spec) 238b4315306SDan Handley { 239b4315306SDan Handley int result; 240b4315306SDan Handley uintptr_t local_image_handle; 241b4315306SDan Handley 242b4315306SDan Handley result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL); 243e098e244SJuan Castillo if (result == 0) { 244b4315306SDan Handley result = io_open(memmap_dev_handle, spec, &local_image_handle); 245e098e244SJuan Castillo if (result == 0) { 246b4315306SDan Handley VERBOSE("Using Memmap\n"); 247b4315306SDan Handley io_close(local_image_handle); 248b4315306SDan Handley } 249b4315306SDan Handley } 250b4315306SDan Handley return result; 251b4315306SDan Handley } 252b4315306SDan Handley 253b4315306SDan Handley 254b4315306SDan Handley void arm_io_setup(void) 255b4315306SDan Handley { 256b4315306SDan Handley int io_result; 257b4315306SDan Handley 258b4315306SDan Handley io_result = register_io_dev_fip(&fip_dev_con); 259e098e244SJuan Castillo assert(io_result == 0); 260b4315306SDan Handley 261b4315306SDan Handley io_result = register_io_dev_memmap(&memmap_dev_con); 262e098e244SJuan Castillo assert(io_result == 0); 263b4315306SDan Handley 264b4315306SDan Handley /* Open connections to devices and cache the handles */ 265b4315306SDan Handley io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL, 266b4315306SDan Handley &fip_dev_handle); 267e098e244SJuan Castillo assert(io_result == 0); 268b4315306SDan Handley 269b4315306SDan Handley io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL, 270b4315306SDan Handley &memmap_dev_handle); 271e098e244SJuan Castillo assert(io_result == 0); 272b4315306SDan Handley 273b4315306SDan Handley /* Ignore improbable errors in release builds */ 274b4315306SDan Handley (void)io_result; 275b4315306SDan Handley } 276b4315306SDan Handley 277b4315306SDan Handley void plat_arm_io_setup(void) 278b4315306SDan Handley { 279b4315306SDan Handley arm_io_setup(); 280b4315306SDan Handley } 281b4315306SDan Handley 282b4315306SDan Handley int plat_arm_get_alt_image_source( 28365cd299fSSoren Brinkmann unsigned int image_id __unused, 28465cd299fSSoren Brinkmann uintptr_t *dev_handle __unused, 28565cd299fSSoren Brinkmann uintptr_t *image_spec __unused) 286b4315306SDan Handley { 287b4315306SDan Handley /* By default do not try an alternative */ 288e098e244SJuan Castillo return -ENOENT; 289b4315306SDan Handley } 290b4315306SDan Handley 291b4315306SDan Handley /* Return an IO device handle and specification which can be used to access 292b4315306SDan Handley * an image. Use this to enforce platform load policy */ 29316948ae1SJuan Castillo int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, 294b4315306SDan Handley uintptr_t *image_spec) 295b4315306SDan Handley { 296e098e244SJuan Castillo int result; 297b4315306SDan Handley const struct plat_io_policy *policy; 298b4315306SDan Handley 29916948ae1SJuan Castillo assert(image_id < ARRAY_SIZE(policies)); 30016948ae1SJuan Castillo 30116948ae1SJuan Castillo policy = &policies[image_id]; 302b4315306SDan Handley result = policy->check(policy->image_spec); 303e098e244SJuan Castillo if (result == 0) { 304b4315306SDan Handley *image_spec = policy->image_spec; 305b4315306SDan Handley *dev_handle = *(policy->dev_handle); 306b4315306SDan Handley } else { 30716948ae1SJuan Castillo VERBOSE("Trying alternative IO\n"); 30816948ae1SJuan Castillo result = plat_arm_get_alt_image_source(image_id, dev_handle, 30916948ae1SJuan Castillo image_spec); 310b4315306SDan Handley } 31116948ae1SJuan Castillo 312b4315306SDan Handley return result; 313b4315306SDan Handley } 314436223deSYatharth Kochar 315436223deSYatharth Kochar /* 316436223deSYatharth Kochar * See if a Firmware Image Package is available, 317436223deSYatharth Kochar * by checking if TOC is valid or not. 318436223deSYatharth Kochar */ 319436223deSYatharth Kochar int arm_io_is_toc_valid(void) 320436223deSYatharth Kochar { 321436223deSYatharth Kochar int result; 322436223deSYatharth Kochar 323436223deSYatharth Kochar result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); 324436223deSYatharth Kochar 325436223deSYatharth Kochar return (result == 0); 326436223deSYatharth Kochar } 327436223deSYatharth Kochar 328