1301d27d9SRadoslaw Biernacki /* 2*25ae7ad1SJens Wiklander * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved. 3301d27d9SRadoslaw Biernacki * 4301d27d9SRadoslaw Biernacki * SPDX-License-Identifier: BSD-3-Clause 5301d27d9SRadoslaw Biernacki */ 6301d27d9SRadoslaw Biernacki 7301d27d9SRadoslaw Biernacki #include <assert.h> 8301d27d9SRadoslaw Biernacki #include <string.h> 9301d27d9SRadoslaw Biernacki 10301d27d9SRadoslaw Biernacki #include <platform_def.h> 11301d27d9SRadoslaw Biernacki 12301d27d9SRadoslaw Biernacki #include <common/bl_common.h> 13301d27d9SRadoslaw Biernacki #include <common/debug.h> 14301d27d9SRadoslaw Biernacki #include <drivers/io/io_driver.h> 1551857762SSumit Garg #include <drivers/io/io_encrypted.h> 16301d27d9SRadoslaw Biernacki #include <drivers/io/io_fip.h> 17301d27d9SRadoslaw Biernacki #include <drivers/io/io_memmap.h> 18301d27d9SRadoslaw Biernacki #include <drivers/io/io_semihosting.h> 19301d27d9SRadoslaw Biernacki #include <drivers/io/io_storage.h> 20301d27d9SRadoslaw Biernacki #include <lib/semihosting.h> 21301d27d9SRadoslaw Biernacki #include <tools_share/firmware_image_package.h> 22301d27d9SRadoslaw Biernacki 23301d27d9SRadoslaw Biernacki /* Semihosting filenames */ 24301d27d9SRadoslaw Biernacki #define BL2_IMAGE_NAME "bl2.bin" 25301d27d9SRadoslaw Biernacki #define BL31_IMAGE_NAME "bl31.bin" 26301d27d9SRadoslaw Biernacki #define BL32_IMAGE_NAME "bl32.bin" 27*25ae7ad1SJens Wiklander #define TOS_FW_CONFIG_NAME "tos_fw_config.dtb" 28301d27d9SRadoslaw Biernacki #define BL32_EXTRA1_IMAGE_NAME "bl32_extra1.bin" 29301d27d9SRadoslaw Biernacki #define BL32_EXTRA2_IMAGE_NAME "bl32_extra2.bin" 30301d27d9SRadoslaw Biernacki #define BL33_IMAGE_NAME "bl33.bin" 31301d27d9SRadoslaw Biernacki 32301d27d9SRadoslaw Biernacki #if TRUSTED_BOARD_BOOT 33301d27d9SRadoslaw Biernacki #define TRUSTED_BOOT_FW_CERT_NAME "tb_fw.crt" 34301d27d9SRadoslaw Biernacki #define TRUSTED_KEY_CERT_NAME "trusted_key.crt" 35301d27d9SRadoslaw Biernacki #define SOC_FW_KEY_CERT_NAME "soc_fw_key.crt" 36301d27d9SRadoslaw Biernacki #define TOS_FW_KEY_CERT_NAME "tos_fw_key.crt" 37301d27d9SRadoslaw Biernacki #define NT_FW_KEY_CERT_NAME "nt_fw_key.crt" 38301d27d9SRadoslaw Biernacki #define SOC_FW_CONTENT_CERT_NAME "soc_fw_content.crt" 39301d27d9SRadoslaw Biernacki #define TOS_FW_CONTENT_CERT_NAME "tos_fw_content.crt" 40301d27d9SRadoslaw Biernacki #define NT_FW_CONTENT_CERT_NAME "nt_fw_content.crt" 41301d27d9SRadoslaw Biernacki #endif /* TRUSTED_BOARD_BOOT */ 42301d27d9SRadoslaw Biernacki 43301d27d9SRadoslaw Biernacki 44301d27d9SRadoslaw Biernacki 45301d27d9SRadoslaw Biernacki /* IO devices */ 46301d27d9SRadoslaw Biernacki static const io_dev_connector_t *fip_dev_con; 47301d27d9SRadoslaw Biernacki static uintptr_t fip_dev_handle; 48301d27d9SRadoslaw Biernacki static const io_dev_connector_t *memmap_dev_con; 49301d27d9SRadoslaw Biernacki static uintptr_t memmap_dev_handle; 50301d27d9SRadoslaw Biernacki static const io_dev_connector_t *sh_dev_con; 51301d27d9SRadoslaw Biernacki static uintptr_t sh_dev_handle; 5251857762SSumit Garg #ifndef DECRYPTION_SUPPORT_none 5351857762SSumit Garg static const io_dev_connector_t *enc_dev_con; 5451857762SSumit Garg static uintptr_t enc_dev_handle; 5551857762SSumit Garg #endif 56301d27d9SRadoslaw Biernacki 57301d27d9SRadoslaw Biernacki static const io_block_spec_t fip_block_spec = { 58301d27d9SRadoslaw Biernacki .offset = PLAT_QEMU_FIP_BASE, 59301d27d9SRadoslaw Biernacki .length = PLAT_QEMU_FIP_MAX_SIZE 60301d27d9SRadoslaw Biernacki }; 61301d27d9SRadoslaw Biernacki 62301d27d9SRadoslaw Biernacki static const io_uuid_spec_t bl2_uuid_spec = { 63301d27d9SRadoslaw Biernacki .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2, 64301d27d9SRadoslaw Biernacki }; 65301d27d9SRadoslaw Biernacki 66301d27d9SRadoslaw Biernacki static const io_uuid_spec_t bl31_uuid_spec = { 67301d27d9SRadoslaw Biernacki .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31, 68301d27d9SRadoslaw Biernacki }; 69301d27d9SRadoslaw Biernacki 70301d27d9SRadoslaw Biernacki static const io_uuid_spec_t bl32_uuid_spec = { 71301d27d9SRadoslaw Biernacki .uuid = UUID_SECURE_PAYLOAD_BL32, 72301d27d9SRadoslaw Biernacki }; 73301d27d9SRadoslaw Biernacki 74301d27d9SRadoslaw Biernacki static const io_uuid_spec_t bl32_extra1_uuid_spec = { 75301d27d9SRadoslaw Biernacki .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1, 76301d27d9SRadoslaw Biernacki }; 77301d27d9SRadoslaw Biernacki 78301d27d9SRadoslaw Biernacki static const io_uuid_spec_t bl32_extra2_uuid_spec = { 79301d27d9SRadoslaw Biernacki .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2, 80301d27d9SRadoslaw Biernacki }; 81301d27d9SRadoslaw Biernacki 82*25ae7ad1SJens Wiklander static const io_uuid_spec_t tos_fw_config_uuid_spec = { 83*25ae7ad1SJens Wiklander .uuid = UUID_TOS_FW_CONFIG, 84*25ae7ad1SJens Wiklander }; 85*25ae7ad1SJens Wiklander 86301d27d9SRadoslaw Biernacki static const io_uuid_spec_t bl33_uuid_spec = { 87301d27d9SRadoslaw Biernacki .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33, 88301d27d9SRadoslaw Biernacki }; 89301d27d9SRadoslaw Biernacki 90301d27d9SRadoslaw Biernacki #if TRUSTED_BOARD_BOOT 91301d27d9SRadoslaw Biernacki static const io_uuid_spec_t tb_fw_cert_uuid_spec = { 92301d27d9SRadoslaw Biernacki .uuid = UUID_TRUSTED_BOOT_FW_CERT, 93301d27d9SRadoslaw Biernacki }; 94301d27d9SRadoslaw Biernacki 95301d27d9SRadoslaw Biernacki static const io_uuid_spec_t trusted_key_cert_uuid_spec = { 96301d27d9SRadoslaw Biernacki .uuid = UUID_TRUSTED_KEY_CERT, 97301d27d9SRadoslaw Biernacki }; 98301d27d9SRadoslaw Biernacki 99301d27d9SRadoslaw Biernacki static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = { 100301d27d9SRadoslaw Biernacki .uuid = UUID_SOC_FW_KEY_CERT, 101301d27d9SRadoslaw Biernacki }; 102301d27d9SRadoslaw Biernacki 103301d27d9SRadoslaw Biernacki static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = { 104301d27d9SRadoslaw Biernacki .uuid = UUID_TRUSTED_OS_FW_KEY_CERT, 105301d27d9SRadoslaw Biernacki }; 106301d27d9SRadoslaw Biernacki 107301d27d9SRadoslaw Biernacki static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = { 108301d27d9SRadoslaw Biernacki .uuid = UUID_NON_TRUSTED_FW_KEY_CERT, 109301d27d9SRadoslaw Biernacki }; 110301d27d9SRadoslaw Biernacki 111301d27d9SRadoslaw Biernacki static const io_uuid_spec_t soc_fw_cert_uuid_spec = { 112301d27d9SRadoslaw Biernacki .uuid = UUID_SOC_FW_CONTENT_CERT, 113301d27d9SRadoslaw Biernacki }; 114301d27d9SRadoslaw Biernacki 115301d27d9SRadoslaw Biernacki static const io_uuid_spec_t tos_fw_cert_uuid_spec = { 116301d27d9SRadoslaw Biernacki .uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT, 117301d27d9SRadoslaw Biernacki }; 118301d27d9SRadoslaw Biernacki 119301d27d9SRadoslaw Biernacki static const io_uuid_spec_t nt_fw_cert_uuid_spec = { 120301d27d9SRadoslaw Biernacki .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT, 121301d27d9SRadoslaw Biernacki }; 122301d27d9SRadoslaw Biernacki #endif /* TRUSTED_BOARD_BOOT */ 123301d27d9SRadoslaw Biernacki 124301d27d9SRadoslaw Biernacki static const io_file_spec_t sh_file_spec[] = { 125301d27d9SRadoslaw Biernacki [BL2_IMAGE_ID] = { 126301d27d9SRadoslaw Biernacki .path = BL2_IMAGE_NAME, 127301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 128301d27d9SRadoslaw Biernacki }, 129301d27d9SRadoslaw Biernacki [BL31_IMAGE_ID] = { 130301d27d9SRadoslaw Biernacki .path = BL31_IMAGE_NAME, 131301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 132301d27d9SRadoslaw Biernacki }, 133301d27d9SRadoslaw Biernacki [BL32_IMAGE_ID] = { 134301d27d9SRadoslaw Biernacki .path = BL32_IMAGE_NAME, 135301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 136301d27d9SRadoslaw Biernacki }, 137301d27d9SRadoslaw Biernacki [BL32_EXTRA1_IMAGE_ID] = { 138301d27d9SRadoslaw Biernacki .path = BL32_EXTRA1_IMAGE_NAME, 139301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 140301d27d9SRadoslaw Biernacki }, 141301d27d9SRadoslaw Biernacki [BL32_EXTRA2_IMAGE_ID] = { 142301d27d9SRadoslaw Biernacki .path = BL32_EXTRA2_IMAGE_NAME, 143301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 144301d27d9SRadoslaw Biernacki }, 145*25ae7ad1SJens Wiklander [TOS_FW_CONFIG_ID] = { 146*25ae7ad1SJens Wiklander .path = TOS_FW_CONFIG_NAME, 147*25ae7ad1SJens Wiklander .mode = FOPEN_MODE_RB 148*25ae7ad1SJens Wiklander }, 149301d27d9SRadoslaw Biernacki [BL33_IMAGE_ID] = { 150301d27d9SRadoslaw Biernacki .path = BL33_IMAGE_NAME, 151301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 152301d27d9SRadoslaw Biernacki }, 153301d27d9SRadoslaw Biernacki #if TRUSTED_BOARD_BOOT 154301d27d9SRadoslaw Biernacki [TRUSTED_BOOT_FW_CERT_ID] = { 155301d27d9SRadoslaw Biernacki .path = TRUSTED_BOOT_FW_CERT_NAME, 156301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 157301d27d9SRadoslaw Biernacki }, 158301d27d9SRadoslaw Biernacki [TRUSTED_KEY_CERT_ID] = { 159301d27d9SRadoslaw Biernacki .path = TRUSTED_KEY_CERT_NAME, 160301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 161301d27d9SRadoslaw Biernacki }, 162301d27d9SRadoslaw Biernacki [SOC_FW_KEY_CERT_ID] = { 163301d27d9SRadoslaw Biernacki .path = SOC_FW_KEY_CERT_NAME, 164301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 165301d27d9SRadoslaw Biernacki }, 166301d27d9SRadoslaw Biernacki [TRUSTED_OS_FW_KEY_CERT_ID] = { 167301d27d9SRadoslaw Biernacki .path = TOS_FW_KEY_CERT_NAME, 168301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 169301d27d9SRadoslaw Biernacki }, 170301d27d9SRadoslaw Biernacki [NON_TRUSTED_FW_KEY_CERT_ID] = { 171301d27d9SRadoslaw Biernacki .path = NT_FW_KEY_CERT_NAME, 172301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 173301d27d9SRadoslaw Biernacki }, 174301d27d9SRadoslaw Biernacki [SOC_FW_CONTENT_CERT_ID] = { 175301d27d9SRadoslaw Biernacki .path = SOC_FW_CONTENT_CERT_NAME, 176301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 177301d27d9SRadoslaw Biernacki }, 178301d27d9SRadoslaw Biernacki [TRUSTED_OS_FW_CONTENT_CERT_ID] = { 179301d27d9SRadoslaw Biernacki .path = TOS_FW_CONTENT_CERT_NAME, 180301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 181301d27d9SRadoslaw Biernacki }, 182301d27d9SRadoslaw Biernacki [NON_TRUSTED_FW_CONTENT_CERT_ID] = { 183301d27d9SRadoslaw Biernacki .path = NT_FW_CONTENT_CERT_NAME, 184301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 185301d27d9SRadoslaw Biernacki }, 186301d27d9SRadoslaw Biernacki #endif /* TRUSTED_BOARD_BOOT */ 187301d27d9SRadoslaw Biernacki }; 188301d27d9SRadoslaw Biernacki 189301d27d9SRadoslaw Biernacki static int open_fip(const uintptr_t spec); 190301d27d9SRadoslaw Biernacki static int open_memmap(const uintptr_t spec); 19151857762SSumit Garg #ifndef DECRYPTION_SUPPORT_none 19251857762SSumit Garg static int open_enc_fip(const uintptr_t spec); 19351857762SSumit Garg #endif 194301d27d9SRadoslaw Biernacki 195301d27d9SRadoslaw Biernacki struct plat_io_policy { 196301d27d9SRadoslaw Biernacki uintptr_t *dev_handle; 197301d27d9SRadoslaw Biernacki uintptr_t image_spec; 198301d27d9SRadoslaw Biernacki int (*check)(const uintptr_t spec); 199301d27d9SRadoslaw Biernacki }; 200301d27d9SRadoslaw Biernacki 201301d27d9SRadoslaw Biernacki /* By default, ARM platforms load images from the FIP */ 202301d27d9SRadoslaw Biernacki static const struct plat_io_policy policies[] = { 203301d27d9SRadoslaw Biernacki [FIP_IMAGE_ID] = { 204301d27d9SRadoslaw Biernacki &memmap_dev_handle, 205301d27d9SRadoslaw Biernacki (uintptr_t)&fip_block_spec, 206301d27d9SRadoslaw Biernacki open_memmap 207301d27d9SRadoslaw Biernacki }, 20851857762SSumit Garg [ENC_IMAGE_ID] = { 20951857762SSumit Garg &fip_dev_handle, 21051857762SSumit Garg (uintptr_t)NULL, 21151857762SSumit Garg open_fip 21251857762SSumit Garg }, 213301d27d9SRadoslaw Biernacki [BL2_IMAGE_ID] = { 214301d27d9SRadoslaw Biernacki &fip_dev_handle, 215301d27d9SRadoslaw Biernacki (uintptr_t)&bl2_uuid_spec, 216301d27d9SRadoslaw Biernacki open_fip 217301d27d9SRadoslaw Biernacki }, 21851857762SSumit Garg #if ENCRYPT_BL31 && !defined(DECRYPTION_SUPPORT_none) 21951857762SSumit Garg [BL31_IMAGE_ID] = { 22051857762SSumit Garg &enc_dev_handle, 22151857762SSumit Garg (uintptr_t)&bl31_uuid_spec, 22251857762SSumit Garg open_enc_fip 22351857762SSumit Garg }, 22451857762SSumit Garg #else 225301d27d9SRadoslaw Biernacki [BL31_IMAGE_ID] = { 226301d27d9SRadoslaw Biernacki &fip_dev_handle, 227301d27d9SRadoslaw Biernacki (uintptr_t)&bl31_uuid_spec, 228301d27d9SRadoslaw Biernacki open_fip 229301d27d9SRadoslaw Biernacki }, 23051857762SSumit Garg #endif 23151857762SSumit Garg #if ENCRYPT_BL32 && !defined(DECRYPTION_SUPPORT_none) 23251857762SSumit Garg [BL32_IMAGE_ID] = { 23351857762SSumit Garg &enc_dev_handle, 23451857762SSumit Garg (uintptr_t)&bl32_uuid_spec, 23551857762SSumit Garg open_enc_fip 23651857762SSumit Garg }, 23751857762SSumit Garg [BL32_EXTRA1_IMAGE_ID] = { 23851857762SSumit Garg &enc_dev_handle, 23951857762SSumit Garg (uintptr_t)&bl32_extra1_uuid_spec, 24051857762SSumit Garg open_enc_fip 24151857762SSumit Garg }, 24251857762SSumit Garg [BL32_EXTRA2_IMAGE_ID] = { 24351857762SSumit Garg &enc_dev_handle, 24451857762SSumit Garg (uintptr_t)&bl32_extra2_uuid_spec, 24551857762SSumit Garg open_enc_fip 24651857762SSumit Garg }, 24751857762SSumit Garg #else 248301d27d9SRadoslaw Biernacki [BL32_IMAGE_ID] = { 249301d27d9SRadoslaw Biernacki &fip_dev_handle, 250301d27d9SRadoslaw Biernacki (uintptr_t)&bl32_uuid_spec, 251301d27d9SRadoslaw Biernacki open_fip 252301d27d9SRadoslaw Biernacki }, 253301d27d9SRadoslaw Biernacki [BL32_EXTRA1_IMAGE_ID] = { 254301d27d9SRadoslaw Biernacki &fip_dev_handle, 255301d27d9SRadoslaw Biernacki (uintptr_t)&bl32_extra1_uuid_spec, 256301d27d9SRadoslaw Biernacki open_fip 257301d27d9SRadoslaw Biernacki }, 258301d27d9SRadoslaw Biernacki [BL32_EXTRA2_IMAGE_ID] = { 259301d27d9SRadoslaw Biernacki &fip_dev_handle, 260301d27d9SRadoslaw Biernacki (uintptr_t)&bl32_extra2_uuid_spec, 261301d27d9SRadoslaw Biernacki open_fip 262301d27d9SRadoslaw Biernacki }, 26351857762SSumit Garg #endif 264*25ae7ad1SJens Wiklander [TOS_FW_CONFIG_ID] = { 265*25ae7ad1SJens Wiklander &fip_dev_handle, 266*25ae7ad1SJens Wiklander (uintptr_t)&tos_fw_config_uuid_spec, 267*25ae7ad1SJens Wiklander open_fip 268*25ae7ad1SJens Wiklander }, 269301d27d9SRadoslaw Biernacki [BL33_IMAGE_ID] = { 270301d27d9SRadoslaw Biernacki &fip_dev_handle, 271301d27d9SRadoslaw Biernacki (uintptr_t)&bl33_uuid_spec, 272301d27d9SRadoslaw Biernacki open_fip 273301d27d9SRadoslaw Biernacki }, 274301d27d9SRadoslaw Biernacki #if TRUSTED_BOARD_BOOT 275301d27d9SRadoslaw Biernacki [TRUSTED_BOOT_FW_CERT_ID] = { 276301d27d9SRadoslaw Biernacki &fip_dev_handle, 277301d27d9SRadoslaw Biernacki (uintptr_t)&tb_fw_cert_uuid_spec, 278301d27d9SRadoslaw Biernacki open_fip 279301d27d9SRadoslaw Biernacki }, 280301d27d9SRadoslaw Biernacki [TRUSTED_KEY_CERT_ID] = { 281301d27d9SRadoslaw Biernacki &fip_dev_handle, 282301d27d9SRadoslaw Biernacki (uintptr_t)&trusted_key_cert_uuid_spec, 283301d27d9SRadoslaw Biernacki open_fip 284301d27d9SRadoslaw Biernacki }, 285301d27d9SRadoslaw Biernacki [SOC_FW_KEY_CERT_ID] = { 286301d27d9SRadoslaw Biernacki &fip_dev_handle, 287301d27d9SRadoslaw Biernacki (uintptr_t)&soc_fw_key_cert_uuid_spec, 288301d27d9SRadoslaw Biernacki open_fip 289301d27d9SRadoslaw Biernacki }, 290301d27d9SRadoslaw Biernacki [TRUSTED_OS_FW_KEY_CERT_ID] = { 291301d27d9SRadoslaw Biernacki &fip_dev_handle, 292301d27d9SRadoslaw Biernacki (uintptr_t)&tos_fw_key_cert_uuid_spec, 293301d27d9SRadoslaw Biernacki open_fip 294301d27d9SRadoslaw Biernacki }, 295301d27d9SRadoslaw Biernacki [NON_TRUSTED_FW_KEY_CERT_ID] = { 296301d27d9SRadoslaw Biernacki &fip_dev_handle, 297301d27d9SRadoslaw Biernacki (uintptr_t)&nt_fw_key_cert_uuid_spec, 298301d27d9SRadoslaw Biernacki open_fip 299301d27d9SRadoslaw Biernacki }, 300301d27d9SRadoslaw Biernacki [SOC_FW_CONTENT_CERT_ID] = { 301301d27d9SRadoslaw Biernacki &fip_dev_handle, 302301d27d9SRadoslaw Biernacki (uintptr_t)&soc_fw_cert_uuid_spec, 303301d27d9SRadoslaw Biernacki open_fip 304301d27d9SRadoslaw Biernacki }, 305301d27d9SRadoslaw Biernacki [TRUSTED_OS_FW_CONTENT_CERT_ID] = { 306301d27d9SRadoslaw Biernacki &fip_dev_handle, 307301d27d9SRadoslaw Biernacki (uintptr_t)&tos_fw_cert_uuid_spec, 308301d27d9SRadoslaw Biernacki open_fip 309301d27d9SRadoslaw Biernacki }, 310301d27d9SRadoslaw Biernacki [NON_TRUSTED_FW_CONTENT_CERT_ID] = { 311301d27d9SRadoslaw Biernacki &fip_dev_handle, 312301d27d9SRadoslaw Biernacki (uintptr_t)&nt_fw_cert_uuid_spec, 313301d27d9SRadoslaw Biernacki open_fip 314301d27d9SRadoslaw Biernacki }, 315301d27d9SRadoslaw Biernacki #endif /* TRUSTED_BOARD_BOOT */ 316301d27d9SRadoslaw Biernacki }; 317301d27d9SRadoslaw Biernacki 318301d27d9SRadoslaw Biernacki static int open_fip(const uintptr_t spec) 319301d27d9SRadoslaw Biernacki { 320301d27d9SRadoslaw Biernacki int result; 321301d27d9SRadoslaw Biernacki uintptr_t local_image_handle; 322301d27d9SRadoslaw Biernacki 323301d27d9SRadoslaw Biernacki /* See if a Firmware Image Package is available */ 324301d27d9SRadoslaw Biernacki result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); 32551857762SSumit Garg if (result == 0 && spec != (uintptr_t)NULL) { 326301d27d9SRadoslaw Biernacki result = io_open(fip_dev_handle, spec, &local_image_handle); 327301d27d9SRadoslaw Biernacki if (result == 0) { 328301d27d9SRadoslaw Biernacki VERBOSE("Using FIP\n"); 329301d27d9SRadoslaw Biernacki io_close(local_image_handle); 330301d27d9SRadoslaw Biernacki } 331301d27d9SRadoslaw Biernacki } 332301d27d9SRadoslaw Biernacki return result; 333301d27d9SRadoslaw Biernacki } 334301d27d9SRadoslaw Biernacki 33551857762SSumit Garg #ifndef DECRYPTION_SUPPORT_none 33651857762SSumit Garg static int open_enc_fip(const uintptr_t spec) 33751857762SSumit Garg { 33851857762SSumit Garg int result; 33951857762SSumit Garg uintptr_t local_image_handle; 34051857762SSumit Garg 34151857762SSumit Garg /* See if an encrypted FIP is available */ 34251857762SSumit Garg result = io_dev_init(enc_dev_handle, (uintptr_t)ENC_IMAGE_ID); 34351857762SSumit Garg if (result == 0) { 34451857762SSumit Garg result = io_open(enc_dev_handle, spec, &local_image_handle); 34551857762SSumit Garg if (result == 0) { 34651857762SSumit Garg VERBOSE("Using encrypted FIP\n"); 34751857762SSumit Garg io_close(local_image_handle); 34851857762SSumit Garg } 34951857762SSumit Garg } 35051857762SSumit Garg return result; 35151857762SSumit Garg } 35251857762SSumit Garg #endif 35351857762SSumit Garg 354301d27d9SRadoslaw Biernacki static int open_memmap(const uintptr_t spec) 355301d27d9SRadoslaw Biernacki { 356301d27d9SRadoslaw Biernacki int result; 357301d27d9SRadoslaw Biernacki uintptr_t local_image_handle; 358301d27d9SRadoslaw Biernacki 359301d27d9SRadoslaw Biernacki result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL); 360301d27d9SRadoslaw Biernacki if (result == 0) { 361301d27d9SRadoslaw Biernacki result = io_open(memmap_dev_handle, spec, &local_image_handle); 362301d27d9SRadoslaw Biernacki if (result == 0) { 363301d27d9SRadoslaw Biernacki VERBOSE("Using Memmap\n"); 364301d27d9SRadoslaw Biernacki io_close(local_image_handle); 365301d27d9SRadoslaw Biernacki } 366301d27d9SRadoslaw Biernacki } 367301d27d9SRadoslaw Biernacki return result; 368301d27d9SRadoslaw Biernacki } 369301d27d9SRadoslaw Biernacki 370301d27d9SRadoslaw Biernacki static int open_semihosting(const uintptr_t spec) 371301d27d9SRadoslaw Biernacki { 372301d27d9SRadoslaw Biernacki int result; 373301d27d9SRadoslaw Biernacki uintptr_t local_image_handle; 374301d27d9SRadoslaw Biernacki 375301d27d9SRadoslaw Biernacki /* See if the file exists on semi-hosting.*/ 376301d27d9SRadoslaw Biernacki result = io_dev_init(sh_dev_handle, (uintptr_t)NULL); 377301d27d9SRadoslaw Biernacki if (result == 0) { 378301d27d9SRadoslaw Biernacki result = io_open(sh_dev_handle, spec, &local_image_handle); 379301d27d9SRadoslaw Biernacki if (result == 0) { 380301d27d9SRadoslaw Biernacki VERBOSE("Using Semi-hosting IO\n"); 381301d27d9SRadoslaw Biernacki io_close(local_image_handle); 382301d27d9SRadoslaw Biernacki } 383301d27d9SRadoslaw Biernacki } 384301d27d9SRadoslaw Biernacki return result; 385301d27d9SRadoslaw Biernacki } 386301d27d9SRadoslaw Biernacki 387301d27d9SRadoslaw Biernacki void plat_qemu_io_setup(void) 388301d27d9SRadoslaw Biernacki { 389301d27d9SRadoslaw Biernacki int io_result; 390301d27d9SRadoslaw Biernacki 391301d27d9SRadoslaw Biernacki io_result = register_io_dev_fip(&fip_dev_con); 392301d27d9SRadoslaw Biernacki assert(io_result == 0); 393301d27d9SRadoslaw Biernacki 394301d27d9SRadoslaw Biernacki io_result = register_io_dev_memmap(&memmap_dev_con); 395301d27d9SRadoslaw Biernacki assert(io_result == 0); 396301d27d9SRadoslaw Biernacki 397301d27d9SRadoslaw Biernacki /* Open connections to devices and cache the handles */ 398301d27d9SRadoslaw Biernacki io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL, 399301d27d9SRadoslaw Biernacki &fip_dev_handle); 400301d27d9SRadoslaw Biernacki assert(io_result == 0); 401301d27d9SRadoslaw Biernacki 402301d27d9SRadoslaw Biernacki io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL, 403301d27d9SRadoslaw Biernacki &memmap_dev_handle); 404301d27d9SRadoslaw Biernacki assert(io_result == 0); 405301d27d9SRadoslaw Biernacki 40651857762SSumit Garg #ifndef DECRYPTION_SUPPORT_none 40751857762SSumit Garg io_result = register_io_dev_enc(&enc_dev_con); 40851857762SSumit Garg assert(io_result == 0); 40951857762SSumit Garg 41051857762SSumit Garg io_result = io_dev_open(enc_dev_con, (uintptr_t)NULL, 41151857762SSumit Garg &enc_dev_handle); 41251857762SSumit Garg assert(io_result == 0); 41351857762SSumit Garg #endif 41451857762SSumit Garg 415301d27d9SRadoslaw Biernacki /* Register the additional IO devices on this platform */ 416301d27d9SRadoslaw Biernacki io_result = register_io_dev_sh(&sh_dev_con); 417301d27d9SRadoslaw Biernacki assert(io_result == 0); 418301d27d9SRadoslaw Biernacki 419301d27d9SRadoslaw Biernacki /* Open connections to devices and cache the handles */ 420301d27d9SRadoslaw Biernacki io_result = io_dev_open(sh_dev_con, (uintptr_t)NULL, &sh_dev_handle); 421301d27d9SRadoslaw Biernacki assert(io_result == 0); 422301d27d9SRadoslaw Biernacki 423301d27d9SRadoslaw Biernacki /* Ignore improbable errors in release builds */ 424301d27d9SRadoslaw Biernacki (void)io_result; 425301d27d9SRadoslaw Biernacki } 426301d27d9SRadoslaw Biernacki 427301d27d9SRadoslaw Biernacki static int get_alt_image_source(unsigned int image_id, uintptr_t *dev_handle, 428301d27d9SRadoslaw Biernacki uintptr_t *image_spec) 429301d27d9SRadoslaw Biernacki { 430301d27d9SRadoslaw Biernacki int result = open_semihosting((const uintptr_t)&sh_file_spec[image_id]); 431301d27d9SRadoslaw Biernacki 432301d27d9SRadoslaw Biernacki if (result == 0) { 433301d27d9SRadoslaw Biernacki *dev_handle = sh_dev_handle; 434301d27d9SRadoslaw Biernacki *image_spec = (uintptr_t)&sh_file_spec[image_id]; 435301d27d9SRadoslaw Biernacki } 436301d27d9SRadoslaw Biernacki 437301d27d9SRadoslaw Biernacki return result; 438301d27d9SRadoslaw Biernacki } 439301d27d9SRadoslaw Biernacki 440301d27d9SRadoslaw Biernacki /* 441301d27d9SRadoslaw Biernacki * Return an IO device handle and specification which can be used to access 442301d27d9SRadoslaw Biernacki * an image. Use this to enforce platform load policy 443301d27d9SRadoslaw Biernacki */ 444301d27d9SRadoslaw Biernacki int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, 445301d27d9SRadoslaw Biernacki uintptr_t *image_spec) 446301d27d9SRadoslaw Biernacki { 447301d27d9SRadoslaw Biernacki int result; 448301d27d9SRadoslaw Biernacki const struct plat_io_policy *policy; 449301d27d9SRadoslaw Biernacki 450301d27d9SRadoslaw Biernacki assert(image_id < ARRAY_SIZE(policies)); 451301d27d9SRadoslaw Biernacki 452301d27d9SRadoslaw Biernacki policy = &policies[image_id]; 453301d27d9SRadoslaw Biernacki result = policy->check(policy->image_spec); 454301d27d9SRadoslaw Biernacki if (result == 0) { 455301d27d9SRadoslaw Biernacki *image_spec = policy->image_spec; 456301d27d9SRadoslaw Biernacki *dev_handle = *(policy->dev_handle); 457301d27d9SRadoslaw Biernacki } else { 458301d27d9SRadoslaw Biernacki VERBOSE("Trying alternative IO\n"); 459301d27d9SRadoslaw Biernacki result = get_alt_image_source(image_id, dev_handle, image_spec); 460301d27d9SRadoslaw Biernacki } 461301d27d9SRadoslaw Biernacki 462301d27d9SRadoslaw Biernacki return result; 463301d27d9SRadoslaw Biernacki } 464