1*301d27d9SRadoslaw Biernacki /* 2*301d27d9SRadoslaw Biernacki * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. 3*301d27d9SRadoslaw Biernacki * 4*301d27d9SRadoslaw Biernacki * SPDX-License-Identifier: BSD-3-Clause 5*301d27d9SRadoslaw Biernacki */ 6*301d27d9SRadoslaw Biernacki 7*301d27d9SRadoslaw Biernacki #include <assert.h> 8*301d27d9SRadoslaw Biernacki #include <string.h> 9*301d27d9SRadoslaw Biernacki 10*301d27d9SRadoslaw Biernacki #include <platform_def.h> 11*301d27d9SRadoslaw Biernacki 12*301d27d9SRadoslaw Biernacki #include <common/bl_common.h> 13*301d27d9SRadoslaw Biernacki #include <common/debug.h> 14*301d27d9SRadoslaw Biernacki #include <drivers/io/io_driver.h> 15*301d27d9SRadoslaw Biernacki #include <drivers/io/io_fip.h> 16*301d27d9SRadoslaw Biernacki #include <drivers/io/io_memmap.h> 17*301d27d9SRadoslaw Biernacki #include <drivers/io/io_semihosting.h> 18*301d27d9SRadoslaw Biernacki #include <drivers/io/io_storage.h> 19*301d27d9SRadoslaw Biernacki #include <lib/semihosting.h> 20*301d27d9SRadoslaw Biernacki #include <tools_share/firmware_image_package.h> 21*301d27d9SRadoslaw Biernacki 22*301d27d9SRadoslaw Biernacki /* Semihosting filenames */ 23*301d27d9SRadoslaw Biernacki #define BL2_IMAGE_NAME "bl2.bin" 24*301d27d9SRadoslaw Biernacki #define BL31_IMAGE_NAME "bl31.bin" 25*301d27d9SRadoslaw Biernacki #define BL32_IMAGE_NAME "bl32.bin" 26*301d27d9SRadoslaw Biernacki #define BL32_EXTRA1_IMAGE_NAME "bl32_extra1.bin" 27*301d27d9SRadoslaw Biernacki #define BL32_EXTRA2_IMAGE_NAME "bl32_extra2.bin" 28*301d27d9SRadoslaw Biernacki #define BL33_IMAGE_NAME "bl33.bin" 29*301d27d9SRadoslaw Biernacki 30*301d27d9SRadoslaw Biernacki #if TRUSTED_BOARD_BOOT 31*301d27d9SRadoslaw Biernacki #define TRUSTED_BOOT_FW_CERT_NAME "tb_fw.crt" 32*301d27d9SRadoslaw Biernacki #define TRUSTED_KEY_CERT_NAME "trusted_key.crt" 33*301d27d9SRadoslaw Biernacki #define SOC_FW_KEY_CERT_NAME "soc_fw_key.crt" 34*301d27d9SRadoslaw Biernacki #define TOS_FW_KEY_CERT_NAME "tos_fw_key.crt" 35*301d27d9SRadoslaw Biernacki #define NT_FW_KEY_CERT_NAME "nt_fw_key.crt" 36*301d27d9SRadoslaw Biernacki #define SOC_FW_CONTENT_CERT_NAME "soc_fw_content.crt" 37*301d27d9SRadoslaw Biernacki #define TOS_FW_CONTENT_CERT_NAME "tos_fw_content.crt" 38*301d27d9SRadoslaw Biernacki #define NT_FW_CONTENT_CERT_NAME "nt_fw_content.crt" 39*301d27d9SRadoslaw Biernacki #endif /* TRUSTED_BOARD_BOOT */ 40*301d27d9SRadoslaw Biernacki 41*301d27d9SRadoslaw Biernacki 42*301d27d9SRadoslaw Biernacki 43*301d27d9SRadoslaw Biernacki /* IO devices */ 44*301d27d9SRadoslaw Biernacki static const io_dev_connector_t *fip_dev_con; 45*301d27d9SRadoslaw Biernacki static uintptr_t fip_dev_handle; 46*301d27d9SRadoslaw Biernacki static const io_dev_connector_t *memmap_dev_con; 47*301d27d9SRadoslaw Biernacki static uintptr_t memmap_dev_handle; 48*301d27d9SRadoslaw Biernacki static const io_dev_connector_t *sh_dev_con; 49*301d27d9SRadoslaw Biernacki static uintptr_t sh_dev_handle; 50*301d27d9SRadoslaw Biernacki 51*301d27d9SRadoslaw Biernacki static const io_block_spec_t fip_block_spec = { 52*301d27d9SRadoslaw Biernacki .offset = PLAT_QEMU_FIP_BASE, 53*301d27d9SRadoslaw Biernacki .length = PLAT_QEMU_FIP_MAX_SIZE 54*301d27d9SRadoslaw Biernacki }; 55*301d27d9SRadoslaw Biernacki 56*301d27d9SRadoslaw Biernacki static const io_uuid_spec_t bl2_uuid_spec = { 57*301d27d9SRadoslaw Biernacki .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2, 58*301d27d9SRadoslaw Biernacki }; 59*301d27d9SRadoslaw Biernacki 60*301d27d9SRadoslaw Biernacki static const io_uuid_spec_t bl31_uuid_spec = { 61*301d27d9SRadoslaw Biernacki .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31, 62*301d27d9SRadoslaw Biernacki }; 63*301d27d9SRadoslaw Biernacki 64*301d27d9SRadoslaw Biernacki static const io_uuid_spec_t bl32_uuid_spec = { 65*301d27d9SRadoslaw Biernacki .uuid = UUID_SECURE_PAYLOAD_BL32, 66*301d27d9SRadoslaw Biernacki }; 67*301d27d9SRadoslaw Biernacki 68*301d27d9SRadoslaw Biernacki static const io_uuid_spec_t bl32_extra1_uuid_spec = { 69*301d27d9SRadoslaw Biernacki .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1, 70*301d27d9SRadoslaw Biernacki }; 71*301d27d9SRadoslaw Biernacki 72*301d27d9SRadoslaw Biernacki static const io_uuid_spec_t bl32_extra2_uuid_spec = { 73*301d27d9SRadoslaw Biernacki .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2, 74*301d27d9SRadoslaw Biernacki }; 75*301d27d9SRadoslaw Biernacki 76*301d27d9SRadoslaw Biernacki static const io_uuid_spec_t bl33_uuid_spec = { 77*301d27d9SRadoslaw Biernacki .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33, 78*301d27d9SRadoslaw Biernacki }; 79*301d27d9SRadoslaw Biernacki 80*301d27d9SRadoslaw Biernacki #if TRUSTED_BOARD_BOOT 81*301d27d9SRadoslaw Biernacki static const io_uuid_spec_t tb_fw_cert_uuid_spec = { 82*301d27d9SRadoslaw Biernacki .uuid = UUID_TRUSTED_BOOT_FW_CERT, 83*301d27d9SRadoslaw Biernacki }; 84*301d27d9SRadoslaw Biernacki 85*301d27d9SRadoslaw Biernacki static const io_uuid_spec_t trusted_key_cert_uuid_spec = { 86*301d27d9SRadoslaw Biernacki .uuid = UUID_TRUSTED_KEY_CERT, 87*301d27d9SRadoslaw Biernacki }; 88*301d27d9SRadoslaw Biernacki 89*301d27d9SRadoslaw Biernacki static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = { 90*301d27d9SRadoslaw Biernacki .uuid = UUID_SOC_FW_KEY_CERT, 91*301d27d9SRadoslaw Biernacki }; 92*301d27d9SRadoslaw Biernacki 93*301d27d9SRadoslaw Biernacki static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = { 94*301d27d9SRadoslaw Biernacki .uuid = UUID_TRUSTED_OS_FW_KEY_CERT, 95*301d27d9SRadoslaw Biernacki }; 96*301d27d9SRadoslaw Biernacki 97*301d27d9SRadoslaw Biernacki static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = { 98*301d27d9SRadoslaw Biernacki .uuid = UUID_NON_TRUSTED_FW_KEY_CERT, 99*301d27d9SRadoslaw Biernacki }; 100*301d27d9SRadoslaw Biernacki 101*301d27d9SRadoslaw Biernacki static const io_uuid_spec_t soc_fw_cert_uuid_spec = { 102*301d27d9SRadoslaw Biernacki .uuid = UUID_SOC_FW_CONTENT_CERT, 103*301d27d9SRadoslaw Biernacki }; 104*301d27d9SRadoslaw Biernacki 105*301d27d9SRadoslaw Biernacki static const io_uuid_spec_t tos_fw_cert_uuid_spec = { 106*301d27d9SRadoslaw Biernacki .uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT, 107*301d27d9SRadoslaw Biernacki }; 108*301d27d9SRadoslaw Biernacki 109*301d27d9SRadoslaw Biernacki static const io_uuid_spec_t nt_fw_cert_uuid_spec = { 110*301d27d9SRadoslaw Biernacki .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT, 111*301d27d9SRadoslaw Biernacki }; 112*301d27d9SRadoslaw Biernacki #endif /* TRUSTED_BOARD_BOOT */ 113*301d27d9SRadoslaw Biernacki 114*301d27d9SRadoslaw Biernacki static const io_file_spec_t sh_file_spec[] = { 115*301d27d9SRadoslaw Biernacki [BL2_IMAGE_ID] = { 116*301d27d9SRadoslaw Biernacki .path = BL2_IMAGE_NAME, 117*301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 118*301d27d9SRadoslaw Biernacki }, 119*301d27d9SRadoslaw Biernacki [BL31_IMAGE_ID] = { 120*301d27d9SRadoslaw Biernacki .path = BL31_IMAGE_NAME, 121*301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 122*301d27d9SRadoslaw Biernacki }, 123*301d27d9SRadoslaw Biernacki [BL32_IMAGE_ID] = { 124*301d27d9SRadoslaw Biernacki .path = BL32_IMAGE_NAME, 125*301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 126*301d27d9SRadoslaw Biernacki }, 127*301d27d9SRadoslaw Biernacki [BL32_EXTRA1_IMAGE_ID] = { 128*301d27d9SRadoslaw Biernacki .path = BL32_EXTRA1_IMAGE_NAME, 129*301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 130*301d27d9SRadoslaw Biernacki }, 131*301d27d9SRadoslaw Biernacki [BL32_EXTRA2_IMAGE_ID] = { 132*301d27d9SRadoslaw Biernacki .path = BL32_EXTRA2_IMAGE_NAME, 133*301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 134*301d27d9SRadoslaw Biernacki }, 135*301d27d9SRadoslaw Biernacki [BL33_IMAGE_ID] = { 136*301d27d9SRadoslaw Biernacki .path = BL33_IMAGE_NAME, 137*301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 138*301d27d9SRadoslaw Biernacki }, 139*301d27d9SRadoslaw Biernacki #if TRUSTED_BOARD_BOOT 140*301d27d9SRadoslaw Biernacki [TRUSTED_BOOT_FW_CERT_ID] = { 141*301d27d9SRadoslaw Biernacki .path = TRUSTED_BOOT_FW_CERT_NAME, 142*301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 143*301d27d9SRadoslaw Biernacki }, 144*301d27d9SRadoslaw Biernacki [TRUSTED_KEY_CERT_ID] = { 145*301d27d9SRadoslaw Biernacki .path = TRUSTED_KEY_CERT_NAME, 146*301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 147*301d27d9SRadoslaw Biernacki }, 148*301d27d9SRadoslaw Biernacki [SOC_FW_KEY_CERT_ID] = { 149*301d27d9SRadoslaw Biernacki .path = SOC_FW_KEY_CERT_NAME, 150*301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 151*301d27d9SRadoslaw Biernacki }, 152*301d27d9SRadoslaw Biernacki [TRUSTED_OS_FW_KEY_CERT_ID] = { 153*301d27d9SRadoslaw Biernacki .path = TOS_FW_KEY_CERT_NAME, 154*301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 155*301d27d9SRadoslaw Biernacki }, 156*301d27d9SRadoslaw Biernacki [NON_TRUSTED_FW_KEY_CERT_ID] = { 157*301d27d9SRadoslaw Biernacki .path = NT_FW_KEY_CERT_NAME, 158*301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 159*301d27d9SRadoslaw Biernacki }, 160*301d27d9SRadoslaw Biernacki [SOC_FW_CONTENT_CERT_ID] = { 161*301d27d9SRadoslaw Biernacki .path = SOC_FW_CONTENT_CERT_NAME, 162*301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 163*301d27d9SRadoslaw Biernacki }, 164*301d27d9SRadoslaw Biernacki [TRUSTED_OS_FW_CONTENT_CERT_ID] = { 165*301d27d9SRadoslaw Biernacki .path = TOS_FW_CONTENT_CERT_NAME, 166*301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 167*301d27d9SRadoslaw Biernacki }, 168*301d27d9SRadoslaw Biernacki [NON_TRUSTED_FW_CONTENT_CERT_ID] = { 169*301d27d9SRadoslaw Biernacki .path = NT_FW_CONTENT_CERT_NAME, 170*301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 171*301d27d9SRadoslaw Biernacki }, 172*301d27d9SRadoslaw Biernacki #endif /* TRUSTED_BOARD_BOOT */ 173*301d27d9SRadoslaw Biernacki }; 174*301d27d9SRadoslaw Biernacki 175*301d27d9SRadoslaw Biernacki 176*301d27d9SRadoslaw Biernacki 177*301d27d9SRadoslaw Biernacki static int open_fip(const uintptr_t spec); 178*301d27d9SRadoslaw Biernacki static int open_memmap(const uintptr_t spec); 179*301d27d9SRadoslaw Biernacki 180*301d27d9SRadoslaw Biernacki struct plat_io_policy { 181*301d27d9SRadoslaw Biernacki uintptr_t *dev_handle; 182*301d27d9SRadoslaw Biernacki uintptr_t image_spec; 183*301d27d9SRadoslaw Biernacki int (*check)(const uintptr_t spec); 184*301d27d9SRadoslaw Biernacki }; 185*301d27d9SRadoslaw Biernacki 186*301d27d9SRadoslaw Biernacki /* By default, ARM platforms load images from the FIP */ 187*301d27d9SRadoslaw Biernacki static const struct plat_io_policy policies[] = { 188*301d27d9SRadoslaw Biernacki [FIP_IMAGE_ID] = { 189*301d27d9SRadoslaw Biernacki &memmap_dev_handle, 190*301d27d9SRadoslaw Biernacki (uintptr_t)&fip_block_spec, 191*301d27d9SRadoslaw Biernacki open_memmap 192*301d27d9SRadoslaw Biernacki }, 193*301d27d9SRadoslaw Biernacki [BL2_IMAGE_ID] = { 194*301d27d9SRadoslaw Biernacki &fip_dev_handle, 195*301d27d9SRadoslaw Biernacki (uintptr_t)&bl2_uuid_spec, 196*301d27d9SRadoslaw Biernacki open_fip 197*301d27d9SRadoslaw Biernacki }, 198*301d27d9SRadoslaw Biernacki [BL31_IMAGE_ID] = { 199*301d27d9SRadoslaw Biernacki &fip_dev_handle, 200*301d27d9SRadoslaw Biernacki (uintptr_t)&bl31_uuid_spec, 201*301d27d9SRadoslaw Biernacki open_fip 202*301d27d9SRadoslaw Biernacki }, 203*301d27d9SRadoslaw Biernacki [BL32_IMAGE_ID] = { 204*301d27d9SRadoslaw Biernacki &fip_dev_handle, 205*301d27d9SRadoslaw Biernacki (uintptr_t)&bl32_uuid_spec, 206*301d27d9SRadoslaw Biernacki open_fip 207*301d27d9SRadoslaw Biernacki }, 208*301d27d9SRadoslaw Biernacki [BL32_EXTRA1_IMAGE_ID] = { 209*301d27d9SRadoslaw Biernacki &fip_dev_handle, 210*301d27d9SRadoslaw Biernacki (uintptr_t)&bl32_extra1_uuid_spec, 211*301d27d9SRadoslaw Biernacki open_fip 212*301d27d9SRadoslaw Biernacki }, 213*301d27d9SRadoslaw Biernacki [BL32_EXTRA2_IMAGE_ID] = { 214*301d27d9SRadoslaw Biernacki &fip_dev_handle, 215*301d27d9SRadoslaw Biernacki (uintptr_t)&bl32_extra2_uuid_spec, 216*301d27d9SRadoslaw Biernacki open_fip 217*301d27d9SRadoslaw Biernacki }, 218*301d27d9SRadoslaw Biernacki [BL33_IMAGE_ID] = { 219*301d27d9SRadoslaw Biernacki &fip_dev_handle, 220*301d27d9SRadoslaw Biernacki (uintptr_t)&bl33_uuid_spec, 221*301d27d9SRadoslaw Biernacki open_fip 222*301d27d9SRadoslaw Biernacki }, 223*301d27d9SRadoslaw Biernacki #if TRUSTED_BOARD_BOOT 224*301d27d9SRadoslaw Biernacki [TRUSTED_BOOT_FW_CERT_ID] = { 225*301d27d9SRadoslaw Biernacki &fip_dev_handle, 226*301d27d9SRadoslaw Biernacki (uintptr_t)&tb_fw_cert_uuid_spec, 227*301d27d9SRadoslaw Biernacki open_fip 228*301d27d9SRadoslaw Biernacki }, 229*301d27d9SRadoslaw Biernacki [TRUSTED_KEY_CERT_ID] = { 230*301d27d9SRadoslaw Biernacki &fip_dev_handle, 231*301d27d9SRadoslaw Biernacki (uintptr_t)&trusted_key_cert_uuid_spec, 232*301d27d9SRadoslaw Biernacki open_fip 233*301d27d9SRadoslaw Biernacki }, 234*301d27d9SRadoslaw Biernacki [SOC_FW_KEY_CERT_ID] = { 235*301d27d9SRadoslaw Biernacki &fip_dev_handle, 236*301d27d9SRadoslaw Biernacki (uintptr_t)&soc_fw_key_cert_uuid_spec, 237*301d27d9SRadoslaw Biernacki open_fip 238*301d27d9SRadoslaw Biernacki }, 239*301d27d9SRadoslaw Biernacki [TRUSTED_OS_FW_KEY_CERT_ID] = { 240*301d27d9SRadoslaw Biernacki &fip_dev_handle, 241*301d27d9SRadoslaw Biernacki (uintptr_t)&tos_fw_key_cert_uuid_spec, 242*301d27d9SRadoslaw Biernacki open_fip 243*301d27d9SRadoslaw Biernacki }, 244*301d27d9SRadoslaw Biernacki [NON_TRUSTED_FW_KEY_CERT_ID] = { 245*301d27d9SRadoslaw Biernacki &fip_dev_handle, 246*301d27d9SRadoslaw Biernacki (uintptr_t)&nt_fw_key_cert_uuid_spec, 247*301d27d9SRadoslaw Biernacki open_fip 248*301d27d9SRadoslaw Biernacki }, 249*301d27d9SRadoslaw Biernacki [SOC_FW_CONTENT_CERT_ID] = { 250*301d27d9SRadoslaw Biernacki &fip_dev_handle, 251*301d27d9SRadoslaw Biernacki (uintptr_t)&soc_fw_cert_uuid_spec, 252*301d27d9SRadoslaw Biernacki open_fip 253*301d27d9SRadoslaw Biernacki }, 254*301d27d9SRadoslaw Biernacki [TRUSTED_OS_FW_CONTENT_CERT_ID] = { 255*301d27d9SRadoslaw Biernacki &fip_dev_handle, 256*301d27d9SRadoslaw Biernacki (uintptr_t)&tos_fw_cert_uuid_spec, 257*301d27d9SRadoslaw Biernacki open_fip 258*301d27d9SRadoslaw Biernacki }, 259*301d27d9SRadoslaw Biernacki [NON_TRUSTED_FW_CONTENT_CERT_ID] = { 260*301d27d9SRadoslaw Biernacki &fip_dev_handle, 261*301d27d9SRadoslaw Biernacki (uintptr_t)&nt_fw_cert_uuid_spec, 262*301d27d9SRadoslaw Biernacki open_fip 263*301d27d9SRadoslaw Biernacki }, 264*301d27d9SRadoslaw Biernacki #endif /* TRUSTED_BOARD_BOOT */ 265*301d27d9SRadoslaw Biernacki }; 266*301d27d9SRadoslaw Biernacki 267*301d27d9SRadoslaw Biernacki static int open_fip(const uintptr_t spec) 268*301d27d9SRadoslaw Biernacki { 269*301d27d9SRadoslaw Biernacki int result; 270*301d27d9SRadoslaw Biernacki uintptr_t local_image_handle; 271*301d27d9SRadoslaw Biernacki 272*301d27d9SRadoslaw Biernacki /* See if a Firmware Image Package is available */ 273*301d27d9SRadoslaw Biernacki result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); 274*301d27d9SRadoslaw Biernacki if (result == 0) { 275*301d27d9SRadoslaw Biernacki result = io_open(fip_dev_handle, spec, &local_image_handle); 276*301d27d9SRadoslaw Biernacki if (result == 0) { 277*301d27d9SRadoslaw Biernacki VERBOSE("Using FIP\n"); 278*301d27d9SRadoslaw Biernacki io_close(local_image_handle); 279*301d27d9SRadoslaw Biernacki } 280*301d27d9SRadoslaw Biernacki } 281*301d27d9SRadoslaw Biernacki return result; 282*301d27d9SRadoslaw Biernacki } 283*301d27d9SRadoslaw Biernacki 284*301d27d9SRadoslaw Biernacki static int open_memmap(const uintptr_t spec) 285*301d27d9SRadoslaw Biernacki { 286*301d27d9SRadoslaw Biernacki int result; 287*301d27d9SRadoslaw Biernacki uintptr_t local_image_handle; 288*301d27d9SRadoslaw Biernacki 289*301d27d9SRadoslaw Biernacki result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL); 290*301d27d9SRadoslaw Biernacki if (result == 0) { 291*301d27d9SRadoslaw Biernacki result = io_open(memmap_dev_handle, spec, &local_image_handle); 292*301d27d9SRadoslaw Biernacki if (result == 0) { 293*301d27d9SRadoslaw Biernacki VERBOSE("Using Memmap\n"); 294*301d27d9SRadoslaw Biernacki io_close(local_image_handle); 295*301d27d9SRadoslaw Biernacki } 296*301d27d9SRadoslaw Biernacki } 297*301d27d9SRadoslaw Biernacki return result; 298*301d27d9SRadoslaw Biernacki } 299*301d27d9SRadoslaw Biernacki 300*301d27d9SRadoslaw Biernacki static int open_semihosting(const uintptr_t spec) 301*301d27d9SRadoslaw Biernacki { 302*301d27d9SRadoslaw Biernacki int result; 303*301d27d9SRadoslaw Biernacki uintptr_t local_image_handle; 304*301d27d9SRadoslaw Biernacki 305*301d27d9SRadoslaw Biernacki /* See if the file exists on semi-hosting.*/ 306*301d27d9SRadoslaw Biernacki result = io_dev_init(sh_dev_handle, (uintptr_t)NULL); 307*301d27d9SRadoslaw Biernacki if (result == 0) { 308*301d27d9SRadoslaw Biernacki result = io_open(sh_dev_handle, spec, &local_image_handle); 309*301d27d9SRadoslaw Biernacki if (result == 0) { 310*301d27d9SRadoslaw Biernacki VERBOSE("Using Semi-hosting IO\n"); 311*301d27d9SRadoslaw Biernacki io_close(local_image_handle); 312*301d27d9SRadoslaw Biernacki } 313*301d27d9SRadoslaw Biernacki } 314*301d27d9SRadoslaw Biernacki return result; 315*301d27d9SRadoslaw Biernacki } 316*301d27d9SRadoslaw Biernacki 317*301d27d9SRadoslaw Biernacki void plat_qemu_io_setup(void) 318*301d27d9SRadoslaw Biernacki { 319*301d27d9SRadoslaw Biernacki int io_result; 320*301d27d9SRadoslaw Biernacki 321*301d27d9SRadoslaw Biernacki io_result = register_io_dev_fip(&fip_dev_con); 322*301d27d9SRadoslaw Biernacki assert(io_result == 0); 323*301d27d9SRadoslaw Biernacki 324*301d27d9SRadoslaw Biernacki io_result = register_io_dev_memmap(&memmap_dev_con); 325*301d27d9SRadoslaw Biernacki assert(io_result == 0); 326*301d27d9SRadoslaw Biernacki 327*301d27d9SRadoslaw Biernacki /* Open connections to devices and cache the handles */ 328*301d27d9SRadoslaw Biernacki io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL, 329*301d27d9SRadoslaw Biernacki &fip_dev_handle); 330*301d27d9SRadoslaw Biernacki assert(io_result == 0); 331*301d27d9SRadoslaw Biernacki 332*301d27d9SRadoslaw Biernacki io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL, 333*301d27d9SRadoslaw Biernacki &memmap_dev_handle); 334*301d27d9SRadoslaw Biernacki assert(io_result == 0); 335*301d27d9SRadoslaw Biernacki 336*301d27d9SRadoslaw Biernacki /* Register the additional IO devices on this platform */ 337*301d27d9SRadoslaw Biernacki io_result = register_io_dev_sh(&sh_dev_con); 338*301d27d9SRadoslaw Biernacki assert(io_result == 0); 339*301d27d9SRadoslaw Biernacki 340*301d27d9SRadoslaw Biernacki /* Open connections to devices and cache the handles */ 341*301d27d9SRadoslaw Biernacki io_result = io_dev_open(sh_dev_con, (uintptr_t)NULL, &sh_dev_handle); 342*301d27d9SRadoslaw Biernacki assert(io_result == 0); 343*301d27d9SRadoslaw Biernacki 344*301d27d9SRadoslaw Biernacki /* Ignore improbable errors in release builds */ 345*301d27d9SRadoslaw Biernacki (void)io_result; 346*301d27d9SRadoslaw Biernacki } 347*301d27d9SRadoslaw Biernacki 348*301d27d9SRadoslaw Biernacki static int get_alt_image_source(unsigned int image_id, uintptr_t *dev_handle, 349*301d27d9SRadoslaw Biernacki uintptr_t *image_spec) 350*301d27d9SRadoslaw Biernacki { 351*301d27d9SRadoslaw Biernacki int result = open_semihosting((const uintptr_t)&sh_file_spec[image_id]); 352*301d27d9SRadoslaw Biernacki 353*301d27d9SRadoslaw Biernacki if (result == 0) { 354*301d27d9SRadoslaw Biernacki *dev_handle = sh_dev_handle; 355*301d27d9SRadoslaw Biernacki *image_spec = (uintptr_t)&sh_file_spec[image_id]; 356*301d27d9SRadoslaw Biernacki } 357*301d27d9SRadoslaw Biernacki 358*301d27d9SRadoslaw Biernacki return result; 359*301d27d9SRadoslaw Biernacki } 360*301d27d9SRadoslaw Biernacki 361*301d27d9SRadoslaw Biernacki /* 362*301d27d9SRadoslaw Biernacki * Return an IO device handle and specification which can be used to access 363*301d27d9SRadoslaw Biernacki * an image. Use this to enforce platform load policy 364*301d27d9SRadoslaw Biernacki */ 365*301d27d9SRadoslaw Biernacki int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, 366*301d27d9SRadoslaw Biernacki uintptr_t *image_spec) 367*301d27d9SRadoslaw Biernacki { 368*301d27d9SRadoslaw Biernacki int result; 369*301d27d9SRadoslaw Biernacki const struct plat_io_policy *policy; 370*301d27d9SRadoslaw Biernacki 371*301d27d9SRadoslaw Biernacki assert(image_id < ARRAY_SIZE(policies)); 372*301d27d9SRadoslaw Biernacki 373*301d27d9SRadoslaw Biernacki policy = &policies[image_id]; 374*301d27d9SRadoslaw Biernacki result = policy->check(policy->image_spec); 375*301d27d9SRadoslaw Biernacki if (result == 0) { 376*301d27d9SRadoslaw Biernacki *image_spec = policy->image_spec; 377*301d27d9SRadoslaw Biernacki *dev_handle = *(policy->dev_handle); 378*301d27d9SRadoslaw Biernacki } else { 379*301d27d9SRadoslaw Biernacki VERBOSE("Trying alternative IO\n"); 380*301d27d9SRadoslaw Biernacki result = get_alt_image_source(image_id, dev_handle, image_spec); 381*301d27d9SRadoslaw Biernacki } 382*301d27d9SRadoslaw Biernacki 383*301d27d9SRadoslaw Biernacki return result; 384*301d27d9SRadoslaw Biernacki } 385