1b4315306SDan Handley /* 2b4315306SDan Handley * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. 3b4315306SDan Handley * 4b4315306SDan Handley * Redistribution and use in source and binary forms, with or without 5b4315306SDan Handley * modification, are permitted provided that the following conditions are met: 6b4315306SDan Handley * 7b4315306SDan Handley * Redistributions of source code must retain the above copyright notice, this 8b4315306SDan Handley * list of conditions and the following disclaimer. 9b4315306SDan Handley * 10b4315306SDan Handley * Redistributions in binary form must reproduce the above copyright notice, 11b4315306SDan Handley * this list of conditions and the following disclaimer in the documentation 12b4315306SDan Handley * and/or other materials provided with the distribution. 13b4315306SDan Handley * 14b4315306SDan Handley * Neither the name of ARM nor the names of its contributors may be used 15b4315306SDan Handley * to endorse or promote products derived from this software without specific 16b4315306SDan Handley * prior written permission. 17b4315306SDan Handley * 18b4315306SDan Handley * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19b4315306SDan Handley * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20b4315306SDan Handley * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21b4315306SDan Handley * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22b4315306SDan Handley * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23b4315306SDan Handley * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24b4315306SDan Handley * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25b4315306SDan Handley * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26b4315306SDan Handley * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27b4315306SDan Handley * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28b4315306SDan Handley * POSSIBILITY OF SUCH DAMAGE. 29b4315306SDan Handley */ 30b4315306SDan Handley #include <assert.h> 3116948ae1SJuan Castillo #include <bl_common.h> /* For ARRAY_SIZE */ 32b4315306SDan Handley #include <debug.h> 3316948ae1SJuan Castillo #include <firmware_image_package.h> 34b4315306SDan Handley #include <io_driver.h> 35b4315306SDan Handley #include <io_fip.h> 36b4315306SDan Handley #include <io_memmap.h> 37b4315306SDan Handley #include <io_storage.h> 38b4315306SDan Handley #include <platform_def.h> 39b4315306SDan Handley #include <string.h> 40b4315306SDan Handley 41b4315306SDan Handley /* IO devices */ 42b4315306SDan Handley static const io_dev_connector_t *fip_dev_con; 43b4315306SDan Handley static uintptr_t fip_dev_handle; 44b4315306SDan Handley static const io_dev_connector_t *memmap_dev_con; 45b4315306SDan Handley static uintptr_t memmap_dev_handle; 46b4315306SDan Handley 47b4315306SDan Handley static const io_block_spec_t fip_block_spec = { 48b4315306SDan Handley .offset = PLAT_ARM_FIP_BASE, 49b4315306SDan Handley .length = PLAT_ARM_FIP_MAX_SIZE 50b4315306SDan Handley }; 51b4315306SDan Handley 5216948ae1SJuan Castillo static const io_uuid_spec_t bl2_uuid_spec = { 5316948ae1SJuan Castillo .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2, 54b4315306SDan Handley }; 55b4315306SDan Handley 56*f59821d5SJuan Castillo static const io_uuid_spec_t scp_bl2_uuid_spec = { 57*f59821d5SJuan Castillo .uuid = UUID_SCP_FIRMWARE_SCP_BL2, 58b4315306SDan Handley }; 59b4315306SDan Handley 6016948ae1SJuan Castillo static const io_uuid_spec_t bl31_uuid_spec = { 6116948ae1SJuan Castillo .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31, 62b4315306SDan Handley }; 63b4315306SDan Handley 6416948ae1SJuan Castillo static const io_uuid_spec_t bl32_uuid_spec = { 6516948ae1SJuan Castillo .uuid = UUID_SECURE_PAYLOAD_BL32, 66b4315306SDan Handley }; 67b4315306SDan Handley 6816948ae1SJuan Castillo static const io_uuid_spec_t bl33_uuid_spec = { 6916948ae1SJuan Castillo .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33, 70b4315306SDan Handley }; 71b4315306SDan Handley 72b4315306SDan Handley #if TRUSTED_BOARD_BOOT 73516beb58SJuan Castillo static const io_uuid_spec_t tb_fw_cert_uuid_spec = { 74516beb58SJuan Castillo .uuid = UUID_TRUSTED_BOOT_FW_CERT, 75b4315306SDan Handley }; 76b4315306SDan Handley 7716948ae1SJuan Castillo static const io_uuid_spec_t trusted_key_cert_uuid_spec = { 7816948ae1SJuan Castillo .uuid = UUID_TRUSTED_KEY_CERT, 79b4315306SDan Handley }; 80b4315306SDan Handley 81516beb58SJuan Castillo static const io_uuid_spec_t scp_fw_key_cert_uuid_spec = { 82516beb58SJuan Castillo .uuid = UUID_SCP_FW_KEY_CERT, 83b4315306SDan Handley }; 84b4315306SDan Handley 85516beb58SJuan Castillo static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = { 86516beb58SJuan Castillo .uuid = UUID_SOC_FW_KEY_CERT, 87b4315306SDan Handley }; 88b4315306SDan Handley 89516beb58SJuan Castillo static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = { 90516beb58SJuan Castillo .uuid = UUID_TRUSTED_OS_FW_KEY_CERT, 91b4315306SDan Handley }; 92b4315306SDan Handley 93516beb58SJuan Castillo static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = { 94516beb58SJuan Castillo .uuid = UUID_NON_TRUSTED_FW_KEY_CERT, 95b4315306SDan Handley }; 96b4315306SDan Handley 97516beb58SJuan Castillo static const io_uuid_spec_t scp_fw_cert_uuid_spec = { 98516beb58SJuan Castillo .uuid = UUID_SCP_FW_CONTENT_CERT, 99b4315306SDan Handley }; 100b4315306SDan Handley 101516beb58SJuan Castillo static const io_uuid_spec_t soc_fw_cert_uuid_spec = { 102516beb58SJuan Castillo .uuid = UUID_SOC_FW_CONTENT_CERT, 103b4315306SDan Handley }; 104b4315306SDan Handley 105516beb58SJuan Castillo static const io_uuid_spec_t tos_fw_cert_uuid_spec = { 106516beb58SJuan Castillo .uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT, 107b4315306SDan Handley }; 108b4315306SDan Handley 109516beb58SJuan Castillo static const io_uuid_spec_t nt_fw_cert_uuid_spec = { 110516beb58SJuan Castillo .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT, 111b4315306SDan Handley }; 112b4315306SDan Handley #endif /* TRUSTED_BOARD_BOOT */ 113b4315306SDan Handley 11416948ae1SJuan Castillo 115b4315306SDan Handley static int open_fip(const uintptr_t spec); 116b4315306SDan Handley static int open_memmap(const uintptr_t spec); 117b4315306SDan Handley 118b4315306SDan Handley struct plat_io_policy { 119b4315306SDan Handley uintptr_t *dev_handle; 120b4315306SDan Handley uintptr_t image_spec; 121b4315306SDan Handley int (*check)(const uintptr_t spec); 122b4315306SDan Handley }; 123b4315306SDan Handley 12416948ae1SJuan Castillo /* By default, ARM platforms load images from the FIP */ 125b4315306SDan Handley static const struct plat_io_policy policies[] = { 12616948ae1SJuan Castillo [FIP_IMAGE_ID] = { 127b4315306SDan Handley &memmap_dev_handle, 128b4315306SDan Handley (uintptr_t)&fip_block_spec, 129b4315306SDan Handley open_memmap 13016948ae1SJuan Castillo }, 13116948ae1SJuan Castillo [BL2_IMAGE_ID] = { 132b4315306SDan Handley &fip_dev_handle, 13316948ae1SJuan Castillo (uintptr_t)&bl2_uuid_spec, 134b4315306SDan Handley open_fip 13516948ae1SJuan Castillo }, 136*f59821d5SJuan Castillo [SCP_BL2_IMAGE_ID] = { 137b4315306SDan Handley &fip_dev_handle, 138*f59821d5SJuan Castillo (uintptr_t)&scp_bl2_uuid_spec, 139b4315306SDan Handley open_fip 14016948ae1SJuan Castillo }, 14116948ae1SJuan Castillo [BL31_IMAGE_ID] = { 142b4315306SDan Handley &fip_dev_handle, 14316948ae1SJuan Castillo (uintptr_t)&bl31_uuid_spec, 144b4315306SDan Handley open_fip 14516948ae1SJuan Castillo }, 14616948ae1SJuan Castillo [BL32_IMAGE_ID] = { 147b4315306SDan Handley &fip_dev_handle, 14816948ae1SJuan Castillo (uintptr_t)&bl32_uuid_spec, 149b4315306SDan Handley open_fip 15016948ae1SJuan Castillo }, 15116948ae1SJuan Castillo [BL33_IMAGE_ID] = { 152b4315306SDan Handley &fip_dev_handle, 15316948ae1SJuan Castillo (uintptr_t)&bl33_uuid_spec, 154b4315306SDan Handley open_fip 15516948ae1SJuan Castillo }, 156b4315306SDan Handley #if TRUSTED_BOARD_BOOT 157516beb58SJuan Castillo [TRUSTED_BOOT_FW_CERT_ID] = { 158b4315306SDan Handley &fip_dev_handle, 159516beb58SJuan Castillo (uintptr_t)&tb_fw_cert_uuid_spec, 160b4315306SDan Handley open_fip 16116948ae1SJuan Castillo }, 16216948ae1SJuan Castillo [TRUSTED_KEY_CERT_ID] = { 163b4315306SDan Handley &fip_dev_handle, 16416948ae1SJuan Castillo (uintptr_t)&trusted_key_cert_uuid_spec, 165b4315306SDan Handley open_fip 16616948ae1SJuan Castillo }, 167516beb58SJuan Castillo [SCP_FW_KEY_CERT_ID] = { 168b4315306SDan Handley &fip_dev_handle, 169516beb58SJuan Castillo (uintptr_t)&scp_fw_key_cert_uuid_spec, 170b4315306SDan Handley open_fip 17116948ae1SJuan Castillo }, 172516beb58SJuan Castillo [SOC_FW_KEY_CERT_ID] = { 173b4315306SDan Handley &fip_dev_handle, 174516beb58SJuan Castillo (uintptr_t)&soc_fw_key_cert_uuid_spec, 175b4315306SDan Handley open_fip 17616948ae1SJuan Castillo }, 177516beb58SJuan Castillo [TRUSTED_OS_FW_KEY_CERT_ID] = { 178b4315306SDan Handley &fip_dev_handle, 179516beb58SJuan Castillo (uintptr_t)&tos_fw_key_cert_uuid_spec, 180b4315306SDan Handley open_fip 18116948ae1SJuan Castillo }, 182516beb58SJuan Castillo [NON_TRUSTED_FW_KEY_CERT_ID] = { 183b4315306SDan Handley &fip_dev_handle, 184516beb58SJuan Castillo (uintptr_t)&nt_fw_key_cert_uuid_spec, 185b4315306SDan Handley open_fip 18616948ae1SJuan Castillo }, 187516beb58SJuan Castillo [SCP_FW_CONTENT_CERT_ID] = { 188b4315306SDan Handley &fip_dev_handle, 189516beb58SJuan Castillo (uintptr_t)&scp_fw_cert_uuid_spec, 190b4315306SDan Handley open_fip 19116948ae1SJuan Castillo }, 192516beb58SJuan Castillo [SOC_FW_CONTENT_CERT_ID] = { 193b4315306SDan Handley &fip_dev_handle, 194516beb58SJuan Castillo (uintptr_t)&soc_fw_cert_uuid_spec, 195b4315306SDan Handley open_fip 19616948ae1SJuan Castillo }, 197516beb58SJuan Castillo [TRUSTED_OS_FW_CONTENT_CERT_ID] = { 198b4315306SDan Handley &fip_dev_handle, 199516beb58SJuan Castillo (uintptr_t)&tos_fw_cert_uuid_spec, 200b4315306SDan Handley open_fip 20116948ae1SJuan Castillo }, 202516beb58SJuan Castillo [NON_TRUSTED_FW_CONTENT_CERT_ID] = { 203b4315306SDan Handley &fip_dev_handle, 204516beb58SJuan Castillo (uintptr_t)&nt_fw_cert_uuid_spec, 205b4315306SDan Handley open_fip 20616948ae1SJuan Castillo }, 207b4315306SDan Handley #endif /* TRUSTED_BOARD_BOOT */ 208b4315306SDan Handley }; 209b4315306SDan Handley 210b4315306SDan Handley 211b4315306SDan Handley /* Weak definitions may be overridden in specific ARM standard platform */ 212b4315306SDan Handley #pragma weak plat_arm_io_setup 213b4315306SDan Handley #pragma weak plat_arm_get_alt_image_source 214b4315306SDan Handley 215b4315306SDan Handley 216b4315306SDan Handley static int open_fip(const uintptr_t spec) 217b4315306SDan Handley { 218b4315306SDan Handley int result; 219b4315306SDan Handley uintptr_t local_image_handle; 220b4315306SDan Handley 221b4315306SDan Handley /* See if a Firmware Image Package is available */ 22216948ae1SJuan Castillo result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); 223e098e244SJuan Castillo if (result == 0) { 224b4315306SDan Handley result = io_open(fip_dev_handle, spec, &local_image_handle); 225e098e244SJuan Castillo if (result == 0) { 226b4315306SDan Handley VERBOSE("Using FIP\n"); 227b4315306SDan Handley io_close(local_image_handle); 228b4315306SDan Handley } 229b4315306SDan Handley } 230b4315306SDan Handley return result; 231b4315306SDan Handley } 232b4315306SDan Handley 233b4315306SDan Handley 234b4315306SDan Handley static int open_memmap(const uintptr_t spec) 235b4315306SDan Handley { 236b4315306SDan Handley int result; 237b4315306SDan Handley uintptr_t local_image_handle; 238b4315306SDan Handley 239b4315306SDan Handley result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL); 240e098e244SJuan Castillo if (result == 0) { 241b4315306SDan Handley result = io_open(memmap_dev_handle, spec, &local_image_handle); 242e098e244SJuan Castillo if (result == 0) { 243b4315306SDan Handley VERBOSE("Using Memmap\n"); 244b4315306SDan Handley io_close(local_image_handle); 245b4315306SDan Handley } 246b4315306SDan Handley } 247b4315306SDan Handley return result; 248b4315306SDan Handley } 249b4315306SDan Handley 250b4315306SDan Handley 251b4315306SDan Handley void arm_io_setup(void) 252b4315306SDan Handley { 253b4315306SDan Handley int io_result; 254b4315306SDan Handley 255b4315306SDan Handley io_result = register_io_dev_fip(&fip_dev_con); 256e098e244SJuan Castillo assert(io_result == 0); 257b4315306SDan Handley 258b4315306SDan Handley io_result = register_io_dev_memmap(&memmap_dev_con); 259e098e244SJuan Castillo assert(io_result == 0); 260b4315306SDan Handley 261b4315306SDan Handley /* Open connections to devices and cache the handles */ 262b4315306SDan Handley io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL, 263b4315306SDan Handley &fip_dev_handle); 264e098e244SJuan Castillo assert(io_result == 0); 265b4315306SDan Handley 266b4315306SDan Handley io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL, 267b4315306SDan Handley &memmap_dev_handle); 268e098e244SJuan Castillo assert(io_result == 0); 269b4315306SDan Handley 270b4315306SDan Handley /* Ignore improbable errors in release builds */ 271b4315306SDan Handley (void)io_result; 272b4315306SDan Handley } 273b4315306SDan Handley 274b4315306SDan Handley void plat_arm_io_setup(void) 275b4315306SDan Handley { 276b4315306SDan Handley arm_io_setup(); 277b4315306SDan Handley } 278b4315306SDan Handley 279b4315306SDan Handley int plat_arm_get_alt_image_source( 28016948ae1SJuan Castillo unsigned int image_id __attribute__((unused)), 28116948ae1SJuan Castillo uintptr_t *dev_handle __attribute__((unused)), 28216948ae1SJuan Castillo uintptr_t *image_spec __attribute__((unused))) 283b4315306SDan Handley { 284b4315306SDan Handley /* By default do not try an alternative */ 285e098e244SJuan Castillo return -ENOENT; 286b4315306SDan Handley } 287b4315306SDan Handley 288b4315306SDan Handley /* Return an IO device handle and specification which can be used to access 289b4315306SDan Handley * an image. Use this to enforce platform load policy */ 29016948ae1SJuan Castillo int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, 291b4315306SDan Handley uintptr_t *image_spec) 292b4315306SDan Handley { 293e098e244SJuan Castillo int result; 294b4315306SDan Handley const struct plat_io_policy *policy; 295b4315306SDan Handley 29616948ae1SJuan Castillo assert(image_id < ARRAY_SIZE(policies)); 29716948ae1SJuan Castillo 29816948ae1SJuan Castillo policy = &policies[image_id]; 299b4315306SDan Handley result = policy->check(policy->image_spec); 300e098e244SJuan Castillo if (result == 0) { 301b4315306SDan Handley *image_spec = policy->image_spec; 302b4315306SDan Handley *dev_handle = *(policy->dev_handle); 303b4315306SDan Handley } else { 30416948ae1SJuan Castillo VERBOSE("Trying alternative IO\n"); 30516948ae1SJuan Castillo result = plat_arm_get_alt_image_source(image_id, dev_handle, 30616948ae1SJuan Castillo image_spec); 307b4315306SDan Handley } 30816948ae1SJuan Castillo 309b4315306SDan Handley return result; 310b4315306SDan Handley } 311436223deSYatharth Kochar 312436223deSYatharth Kochar /* 313436223deSYatharth Kochar * See if a Firmware Image Package is available, 314436223deSYatharth Kochar * by checking if TOC is valid or not. 315436223deSYatharth Kochar */ 316436223deSYatharth Kochar int arm_io_is_toc_valid(void) 317436223deSYatharth Kochar { 318436223deSYatharth Kochar int result; 319436223deSYatharth Kochar 320436223deSYatharth Kochar result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); 321436223deSYatharth Kochar 322436223deSYatharth Kochar return (result == 0); 323436223deSYatharth Kochar } 324436223deSYatharth Kochar 325