1301d27d9SRadoslaw Biernacki /* 2*8ffe0b2eSJean-Philippe Brucker * Copyright (c) 2015-2024, 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> 1436802e2cSJens Wiklander #include <common/desc_image_load.h> 1536802e2cSJens Wiklander #include <common/uuid.h> 16301d27d9SRadoslaw Biernacki #include <drivers/io/io_driver.h> 1751857762SSumit Garg #include <drivers/io/io_encrypted.h> 18301d27d9SRadoslaw Biernacki #include <drivers/io/io_fip.h> 19301d27d9SRadoslaw Biernacki #include <drivers/io/io_memmap.h> 20301d27d9SRadoslaw Biernacki #include <drivers/io/io_semihosting.h> 21301d27d9SRadoslaw Biernacki #include <drivers/io/io_storage.h> 22301d27d9SRadoslaw Biernacki #include <lib/semihosting.h> 23301d27d9SRadoslaw Biernacki #include <tools_share/firmware_image_package.h> 24301d27d9SRadoslaw Biernacki 2536802e2cSJens Wiklander #include "qemu_private.h" 2636802e2cSJens Wiklander 27301d27d9SRadoslaw Biernacki /* Semihosting filenames */ 28301d27d9SRadoslaw Biernacki #define BL2_IMAGE_NAME "bl2.bin" 29301d27d9SRadoslaw Biernacki #define BL31_IMAGE_NAME "bl31.bin" 30301d27d9SRadoslaw Biernacki #define BL32_IMAGE_NAME "bl32.bin" 3136802e2cSJens Wiklander #define TB_FW_CONFIG_NAME "tb_fw_config.dtb" 3225ae7ad1SJens Wiklander #define TOS_FW_CONFIG_NAME "tos_fw_config.dtb" 33301d27d9SRadoslaw Biernacki #define BL32_EXTRA1_IMAGE_NAME "bl32_extra1.bin" 34301d27d9SRadoslaw Biernacki #define BL32_EXTRA2_IMAGE_NAME "bl32_extra2.bin" 35301d27d9SRadoslaw Biernacki #define BL33_IMAGE_NAME "bl33.bin" 36*8ffe0b2eSJean-Philippe Brucker #define RMM_IMAGE_NAME "rmm.bin" 37301d27d9SRadoslaw Biernacki 38301d27d9SRadoslaw Biernacki #if TRUSTED_BOARD_BOOT 39301d27d9SRadoslaw Biernacki #define TRUSTED_BOOT_FW_CERT_NAME "tb_fw.crt" 40301d27d9SRadoslaw Biernacki #define TRUSTED_KEY_CERT_NAME "trusted_key.crt" 41301d27d9SRadoslaw Biernacki #define SOC_FW_KEY_CERT_NAME "soc_fw_key.crt" 42301d27d9SRadoslaw Biernacki #define TOS_FW_KEY_CERT_NAME "tos_fw_key.crt" 43301d27d9SRadoslaw Biernacki #define NT_FW_KEY_CERT_NAME "nt_fw_key.crt" 44301d27d9SRadoslaw Biernacki #define SOC_FW_CONTENT_CERT_NAME "soc_fw_content.crt" 45301d27d9SRadoslaw Biernacki #define TOS_FW_CONTENT_CERT_NAME "tos_fw_content.crt" 46301d27d9SRadoslaw Biernacki #define NT_FW_CONTENT_CERT_NAME "nt_fw_content.crt" 47301d27d9SRadoslaw Biernacki #endif /* TRUSTED_BOARD_BOOT */ 48301d27d9SRadoslaw Biernacki 49301d27d9SRadoslaw Biernacki 50301d27d9SRadoslaw Biernacki 51301d27d9SRadoslaw Biernacki /* IO devices */ 52301d27d9SRadoslaw Biernacki static const io_dev_connector_t *fip_dev_con; 53301d27d9SRadoslaw Biernacki static uintptr_t fip_dev_handle; 54301d27d9SRadoslaw Biernacki static const io_dev_connector_t *memmap_dev_con; 55301d27d9SRadoslaw Biernacki static uintptr_t memmap_dev_handle; 56301d27d9SRadoslaw Biernacki static const io_dev_connector_t *sh_dev_con; 57301d27d9SRadoslaw Biernacki static uintptr_t sh_dev_handle; 5851857762SSumit Garg #ifndef DECRYPTION_SUPPORT_none 5951857762SSumit Garg static const io_dev_connector_t *enc_dev_con; 6051857762SSumit Garg static uintptr_t enc_dev_handle; 6151857762SSumit Garg #endif 62301d27d9SRadoslaw Biernacki 63301d27d9SRadoslaw Biernacki static const io_block_spec_t fip_block_spec = { 64301d27d9SRadoslaw Biernacki .offset = PLAT_QEMU_FIP_BASE, 65301d27d9SRadoslaw Biernacki .length = PLAT_QEMU_FIP_MAX_SIZE 66301d27d9SRadoslaw Biernacki }; 67301d27d9SRadoslaw Biernacki 68301d27d9SRadoslaw Biernacki static const io_uuid_spec_t bl2_uuid_spec = { 69301d27d9SRadoslaw Biernacki .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2, 70301d27d9SRadoslaw Biernacki }; 71301d27d9SRadoslaw Biernacki 72301d27d9SRadoslaw Biernacki static const io_uuid_spec_t bl31_uuid_spec = { 73301d27d9SRadoslaw Biernacki .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31, 74301d27d9SRadoslaw Biernacki }; 75301d27d9SRadoslaw Biernacki 76301d27d9SRadoslaw Biernacki static const io_uuid_spec_t bl32_uuid_spec = { 77301d27d9SRadoslaw Biernacki .uuid = UUID_SECURE_PAYLOAD_BL32, 78301d27d9SRadoslaw Biernacki }; 79301d27d9SRadoslaw Biernacki 80301d27d9SRadoslaw Biernacki static const io_uuid_spec_t bl32_extra1_uuid_spec = { 81301d27d9SRadoslaw Biernacki .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1, 82301d27d9SRadoslaw Biernacki }; 83301d27d9SRadoslaw Biernacki 84301d27d9SRadoslaw Biernacki static const io_uuid_spec_t bl32_extra2_uuid_spec = { 85301d27d9SRadoslaw Biernacki .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2, 86301d27d9SRadoslaw Biernacki }; 87301d27d9SRadoslaw Biernacki 8836802e2cSJens Wiklander static const io_uuid_spec_t tb_fw_config_uuid_spec = { 8936802e2cSJens Wiklander .uuid = UUID_TB_FW_CONFIG, 9036802e2cSJens Wiklander }; 9136802e2cSJens Wiklander 9225ae7ad1SJens Wiklander static const io_uuid_spec_t tos_fw_config_uuid_spec = { 9325ae7ad1SJens Wiklander .uuid = UUID_TOS_FW_CONFIG, 9425ae7ad1SJens Wiklander }; 9525ae7ad1SJens Wiklander 96301d27d9SRadoslaw Biernacki static const io_uuid_spec_t bl33_uuid_spec = { 97301d27d9SRadoslaw Biernacki .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33, 98301d27d9SRadoslaw Biernacki }; 99301d27d9SRadoslaw Biernacki 100*8ffe0b2eSJean-Philippe Brucker static const io_uuid_spec_t rmm_uuid_spec = { 101*8ffe0b2eSJean-Philippe Brucker .uuid = UUID_REALM_MONITOR_MGMT_FIRMWARE, 102*8ffe0b2eSJean-Philippe Brucker }; 103*8ffe0b2eSJean-Philippe Brucker 104301d27d9SRadoslaw Biernacki #if TRUSTED_BOARD_BOOT 105301d27d9SRadoslaw Biernacki static const io_uuid_spec_t tb_fw_cert_uuid_spec = { 106301d27d9SRadoslaw Biernacki .uuid = UUID_TRUSTED_BOOT_FW_CERT, 107301d27d9SRadoslaw Biernacki }; 108301d27d9SRadoslaw Biernacki 109301d27d9SRadoslaw Biernacki static const io_uuid_spec_t trusted_key_cert_uuid_spec = { 110301d27d9SRadoslaw Biernacki .uuid = UUID_TRUSTED_KEY_CERT, 111301d27d9SRadoslaw Biernacki }; 112301d27d9SRadoslaw Biernacki 113301d27d9SRadoslaw Biernacki static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = { 114301d27d9SRadoslaw Biernacki .uuid = UUID_SOC_FW_KEY_CERT, 115301d27d9SRadoslaw Biernacki }; 116301d27d9SRadoslaw Biernacki 117301d27d9SRadoslaw Biernacki static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = { 118301d27d9SRadoslaw Biernacki .uuid = UUID_TRUSTED_OS_FW_KEY_CERT, 119301d27d9SRadoslaw Biernacki }; 120301d27d9SRadoslaw Biernacki 121301d27d9SRadoslaw Biernacki static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = { 122301d27d9SRadoslaw Biernacki .uuid = UUID_NON_TRUSTED_FW_KEY_CERT, 123301d27d9SRadoslaw Biernacki }; 124301d27d9SRadoslaw Biernacki 125301d27d9SRadoslaw Biernacki static const io_uuid_spec_t soc_fw_cert_uuid_spec = { 126301d27d9SRadoslaw Biernacki .uuid = UUID_SOC_FW_CONTENT_CERT, 127301d27d9SRadoslaw Biernacki }; 128301d27d9SRadoslaw Biernacki 129301d27d9SRadoslaw Biernacki static const io_uuid_spec_t tos_fw_cert_uuid_spec = { 130301d27d9SRadoslaw Biernacki .uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT, 131301d27d9SRadoslaw Biernacki }; 132301d27d9SRadoslaw Biernacki 133301d27d9SRadoslaw Biernacki static const io_uuid_spec_t nt_fw_cert_uuid_spec = { 134301d27d9SRadoslaw Biernacki .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT, 135301d27d9SRadoslaw Biernacki }; 136301d27d9SRadoslaw Biernacki #endif /* TRUSTED_BOARD_BOOT */ 137301d27d9SRadoslaw Biernacki 138301d27d9SRadoslaw Biernacki static const io_file_spec_t sh_file_spec[] = { 139301d27d9SRadoslaw Biernacki [BL2_IMAGE_ID] = { 140301d27d9SRadoslaw Biernacki .path = BL2_IMAGE_NAME, 141301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 142301d27d9SRadoslaw Biernacki }, 143301d27d9SRadoslaw Biernacki [BL31_IMAGE_ID] = { 144301d27d9SRadoslaw Biernacki .path = BL31_IMAGE_NAME, 145301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 146301d27d9SRadoslaw Biernacki }, 147301d27d9SRadoslaw Biernacki [BL32_IMAGE_ID] = { 148301d27d9SRadoslaw Biernacki .path = BL32_IMAGE_NAME, 149301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 150301d27d9SRadoslaw Biernacki }, 151301d27d9SRadoslaw Biernacki [BL32_EXTRA1_IMAGE_ID] = { 152301d27d9SRadoslaw Biernacki .path = BL32_EXTRA1_IMAGE_NAME, 153301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 154301d27d9SRadoslaw Biernacki }, 155301d27d9SRadoslaw Biernacki [BL32_EXTRA2_IMAGE_ID] = { 156301d27d9SRadoslaw Biernacki .path = BL32_EXTRA2_IMAGE_NAME, 157301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 158301d27d9SRadoslaw Biernacki }, 15936802e2cSJens Wiklander [TB_FW_CONFIG_ID] = { 16036802e2cSJens Wiklander .path = TB_FW_CONFIG_NAME, 16136802e2cSJens Wiklander .mode = FOPEN_MODE_RB 16236802e2cSJens Wiklander }, 16325ae7ad1SJens Wiklander [TOS_FW_CONFIG_ID] = { 16425ae7ad1SJens Wiklander .path = TOS_FW_CONFIG_NAME, 16525ae7ad1SJens Wiklander .mode = FOPEN_MODE_RB 16625ae7ad1SJens Wiklander }, 167301d27d9SRadoslaw Biernacki [BL33_IMAGE_ID] = { 168301d27d9SRadoslaw Biernacki .path = BL33_IMAGE_NAME, 169301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 170301d27d9SRadoslaw Biernacki }, 171*8ffe0b2eSJean-Philippe Brucker [RMM_IMAGE_ID] = { 172*8ffe0b2eSJean-Philippe Brucker .path = RMM_IMAGE_NAME, 173*8ffe0b2eSJean-Philippe Brucker .mode = FOPEN_MODE_RB 174*8ffe0b2eSJean-Philippe Brucker }, 175301d27d9SRadoslaw Biernacki #if TRUSTED_BOARD_BOOT 176301d27d9SRadoslaw Biernacki [TRUSTED_BOOT_FW_CERT_ID] = { 177301d27d9SRadoslaw Biernacki .path = TRUSTED_BOOT_FW_CERT_NAME, 178301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 179301d27d9SRadoslaw Biernacki }, 180301d27d9SRadoslaw Biernacki [TRUSTED_KEY_CERT_ID] = { 181301d27d9SRadoslaw Biernacki .path = TRUSTED_KEY_CERT_NAME, 182301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 183301d27d9SRadoslaw Biernacki }, 184301d27d9SRadoslaw Biernacki [SOC_FW_KEY_CERT_ID] = { 185301d27d9SRadoslaw Biernacki .path = SOC_FW_KEY_CERT_NAME, 186301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 187301d27d9SRadoslaw Biernacki }, 188301d27d9SRadoslaw Biernacki [TRUSTED_OS_FW_KEY_CERT_ID] = { 189301d27d9SRadoslaw Biernacki .path = TOS_FW_KEY_CERT_NAME, 190301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 191301d27d9SRadoslaw Biernacki }, 192301d27d9SRadoslaw Biernacki [NON_TRUSTED_FW_KEY_CERT_ID] = { 193301d27d9SRadoslaw Biernacki .path = NT_FW_KEY_CERT_NAME, 194301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 195301d27d9SRadoslaw Biernacki }, 196301d27d9SRadoslaw Biernacki [SOC_FW_CONTENT_CERT_ID] = { 197301d27d9SRadoslaw Biernacki .path = SOC_FW_CONTENT_CERT_NAME, 198301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 199301d27d9SRadoslaw Biernacki }, 200301d27d9SRadoslaw Biernacki [TRUSTED_OS_FW_CONTENT_CERT_ID] = { 201301d27d9SRadoslaw Biernacki .path = TOS_FW_CONTENT_CERT_NAME, 202301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 203301d27d9SRadoslaw Biernacki }, 204301d27d9SRadoslaw Biernacki [NON_TRUSTED_FW_CONTENT_CERT_ID] = { 205301d27d9SRadoslaw Biernacki .path = NT_FW_CONTENT_CERT_NAME, 206301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 207301d27d9SRadoslaw Biernacki }, 208301d27d9SRadoslaw Biernacki #endif /* TRUSTED_BOARD_BOOT */ 209301d27d9SRadoslaw Biernacki }; 210301d27d9SRadoslaw Biernacki 211301d27d9SRadoslaw Biernacki static int open_fip(const uintptr_t spec); 212301d27d9SRadoslaw Biernacki static int open_memmap(const uintptr_t spec); 21351857762SSumit Garg #ifndef DECRYPTION_SUPPORT_none 21451857762SSumit Garg static int open_enc_fip(const uintptr_t spec); 21551857762SSumit Garg #endif 216301d27d9SRadoslaw Biernacki 217301d27d9SRadoslaw Biernacki struct plat_io_policy { 218301d27d9SRadoslaw Biernacki uintptr_t *dev_handle; 219301d27d9SRadoslaw Biernacki uintptr_t image_spec; 220301d27d9SRadoslaw Biernacki int (*check)(const uintptr_t spec); 221301d27d9SRadoslaw Biernacki }; 222301d27d9SRadoslaw Biernacki 223301d27d9SRadoslaw Biernacki /* By default, ARM platforms load images from the FIP */ 224301d27d9SRadoslaw Biernacki static const struct plat_io_policy policies[] = { 225301d27d9SRadoslaw Biernacki [FIP_IMAGE_ID] = { 226301d27d9SRadoslaw Biernacki &memmap_dev_handle, 227301d27d9SRadoslaw Biernacki (uintptr_t)&fip_block_spec, 228301d27d9SRadoslaw Biernacki open_memmap 229301d27d9SRadoslaw Biernacki }, 23051857762SSumit Garg [ENC_IMAGE_ID] = { 23151857762SSumit Garg &fip_dev_handle, 23251857762SSumit Garg (uintptr_t)NULL, 23351857762SSumit Garg open_fip 23451857762SSumit Garg }, 235301d27d9SRadoslaw Biernacki [BL2_IMAGE_ID] = { 236301d27d9SRadoslaw Biernacki &fip_dev_handle, 237301d27d9SRadoslaw Biernacki (uintptr_t)&bl2_uuid_spec, 238301d27d9SRadoslaw Biernacki open_fip 239301d27d9SRadoslaw Biernacki }, 24051857762SSumit Garg #if ENCRYPT_BL31 && !defined(DECRYPTION_SUPPORT_none) 24151857762SSumit Garg [BL31_IMAGE_ID] = { 24251857762SSumit Garg &enc_dev_handle, 24351857762SSumit Garg (uintptr_t)&bl31_uuid_spec, 24451857762SSumit Garg open_enc_fip 24551857762SSumit Garg }, 24651857762SSumit Garg #else 247301d27d9SRadoslaw Biernacki [BL31_IMAGE_ID] = { 248301d27d9SRadoslaw Biernacki &fip_dev_handle, 249301d27d9SRadoslaw Biernacki (uintptr_t)&bl31_uuid_spec, 250301d27d9SRadoslaw Biernacki open_fip 251301d27d9SRadoslaw Biernacki }, 25251857762SSumit Garg #endif 25351857762SSumit Garg #if ENCRYPT_BL32 && !defined(DECRYPTION_SUPPORT_none) 25451857762SSumit Garg [BL32_IMAGE_ID] = { 25551857762SSumit Garg &enc_dev_handle, 25651857762SSumit Garg (uintptr_t)&bl32_uuid_spec, 25751857762SSumit Garg open_enc_fip 25851857762SSumit Garg }, 25951857762SSumit Garg [BL32_EXTRA1_IMAGE_ID] = { 26051857762SSumit Garg &enc_dev_handle, 26151857762SSumit Garg (uintptr_t)&bl32_extra1_uuid_spec, 26251857762SSumit Garg open_enc_fip 26351857762SSumit Garg }, 26451857762SSumit Garg [BL32_EXTRA2_IMAGE_ID] = { 26551857762SSumit Garg &enc_dev_handle, 26651857762SSumit Garg (uintptr_t)&bl32_extra2_uuid_spec, 26751857762SSumit Garg open_enc_fip 26851857762SSumit Garg }, 26951857762SSumit Garg #else 270301d27d9SRadoslaw Biernacki [BL32_IMAGE_ID] = { 271301d27d9SRadoslaw Biernacki &fip_dev_handle, 272301d27d9SRadoslaw Biernacki (uintptr_t)&bl32_uuid_spec, 273301d27d9SRadoslaw Biernacki open_fip 274301d27d9SRadoslaw Biernacki }, 275301d27d9SRadoslaw Biernacki [BL32_EXTRA1_IMAGE_ID] = { 276301d27d9SRadoslaw Biernacki &fip_dev_handle, 277301d27d9SRadoslaw Biernacki (uintptr_t)&bl32_extra1_uuid_spec, 278301d27d9SRadoslaw Biernacki open_fip 279301d27d9SRadoslaw Biernacki }, 280301d27d9SRadoslaw Biernacki [BL32_EXTRA2_IMAGE_ID] = { 281301d27d9SRadoslaw Biernacki &fip_dev_handle, 282301d27d9SRadoslaw Biernacki (uintptr_t)&bl32_extra2_uuid_spec, 283301d27d9SRadoslaw Biernacki open_fip 284301d27d9SRadoslaw Biernacki }, 28551857762SSumit Garg #endif 28636802e2cSJens Wiklander [TB_FW_CONFIG_ID] = { 28736802e2cSJens Wiklander &fip_dev_handle, 28836802e2cSJens Wiklander (uintptr_t)&tb_fw_config_uuid_spec, 28936802e2cSJens Wiklander open_fip 29036802e2cSJens Wiklander }, 29125ae7ad1SJens Wiklander [TOS_FW_CONFIG_ID] = { 29225ae7ad1SJens Wiklander &fip_dev_handle, 29325ae7ad1SJens Wiklander (uintptr_t)&tos_fw_config_uuid_spec, 29425ae7ad1SJens Wiklander open_fip 29525ae7ad1SJens Wiklander }, 296301d27d9SRadoslaw Biernacki [BL33_IMAGE_ID] = { 297301d27d9SRadoslaw Biernacki &fip_dev_handle, 298301d27d9SRadoslaw Biernacki (uintptr_t)&bl33_uuid_spec, 299301d27d9SRadoslaw Biernacki open_fip 300301d27d9SRadoslaw Biernacki }, 301*8ffe0b2eSJean-Philippe Brucker [RMM_IMAGE_ID] = { 302*8ffe0b2eSJean-Philippe Brucker &fip_dev_handle, 303*8ffe0b2eSJean-Philippe Brucker (uintptr_t)&rmm_uuid_spec, 304*8ffe0b2eSJean-Philippe Brucker open_fip 305*8ffe0b2eSJean-Philippe Brucker }, 306*8ffe0b2eSJean-Philippe Brucker 307301d27d9SRadoslaw Biernacki #if TRUSTED_BOARD_BOOT 308301d27d9SRadoslaw Biernacki [TRUSTED_BOOT_FW_CERT_ID] = { 309301d27d9SRadoslaw Biernacki &fip_dev_handle, 310301d27d9SRadoslaw Biernacki (uintptr_t)&tb_fw_cert_uuid_spec, 311301d27d9SRadoslaw Biernacki open_fip 312301d27d9SRadoslaw Biernacki }, 313301d27d9SRadoslaw Biernacki [TRUSTED_KEY_CERT_ID] = { 314301d27d9SRadoslaw Biernacki &fip_dev_handle, 315301d27d9SRadoslaw Biernacki (uintptr_t)&trusted_key_cert_uuid_spec, 316301d27d9SRadoslaw Biernacki open_fip 317301d27d9SRadoslaw Biernacki }, 318301d27d9SRadoslaw Biernacki [SOC_FW_KEY_CERT_ID] = { 319301d27d9SRadoslaw Biernacki &fip_dev_handle, 320301d27d9SRadoslaw Biernacki (uintptr_t)&soc_fw_key_cert_uuid_spec, 321301d27d9SRadoslaw Biernacki open_fip 322301d27d9SRadoslaw Biernacki }, 323301d27d9SRadoslaw Biernacki [TRUSTED_OS_FW_KEY_CERT_ID] = { 324301d27d9SRadoslaw Biernacki &fip_dev_handle, 325301d27d9SRadoslaw Biernacki (uintptr_t)&tos_fw_key_cert_uuid_spec, 326301d27d9SRadoslaw Biernacki open_fip 327301d27d9SRadoslaw Biernacki }, 328301d27d9SRadoslaw Biernacki [NON_TRUSTED_FW_KEY_CERT_ID] = { 329301d27d9SRadoslaw Biernacki &fip_dev_handle, 330301d27d9SRadoslaw Biernacki (uintptr_t)&nt_fw_key_cert_uuid_spec, 331301d27d9SRadoslaw Biernacki open_fip 332301d27d9SRadoslaw Biernacki }, 333301d27d9SRadoslaw Biernacki [SOC_FW_CONTENT_CERT_ID] = { 334301d27d9SRadoslaw Biernacki &fip_dev_handle, 335301d27d9SRadoslaw Biernacki (uintptr_t)&soc_fw_cert_uuid_spec, 336301d27d9SRadoslaw Biernacki open_fip 337301d27d9SRadoslaw Biernacki }, 338301d27d9SRadoslaw Biernacki [TRUSTED_OS_FW_CONTENT_CERT_ID] = { 339301d27d9SRadoslaw Biernacki &fip_dev_handle, 340301d27d9SRadoslaw Biernacki (uintptr_t)&tos_fw_cert_uuid_spec, 341301d27d9SRadoslaw Biernacki open_fip 342301d27d9SRadoslaw Biernacki }, 343301d27d9SRadoslaw Biernacki [NON_TRUSTED_FW_CONTENT_CERT_ID] = { 344301d27d9SRadoslaw Biernacki &fip_dev_handle, 345301d27d9SRadoslaw Biernacki (uintptr_t)&nt_fw_cert_uuid_spec, 346301d27d9SRadoslaw Biernacki open_fip 347301d27d9SRadoslaw Biernacki }, 348301d27d9SRadoslaw Biernacki #endif /* TRUSTED_BOARD_BOOT */ 349301d27d9SRadoslaw Biernacki }; 350301d27d9SRadoslaw Biernacki 35136802e2cSJens Wiklander #if defined(SPD_spmd) 35236802e2cSJens Wiklander static struct sp_pkg { 35336802e2cSJens Wiklander struct plat_io_policy policy; 35436802e2cSJens Wiklander io_file_spec_t sh_file_spec; 35536802e2cSJens Wiklander uint8_t uuid[UUID_BYTES_LENGTH]; 35636802e2cSJens Wiklander char path[80]; 35736802e2cSJens Wiklander } sp_pkgs[MAX_SP_IDS]; 35836802e2cSJens Wiklander static unsigned int sp_pkg_count; 35936802e2cSJens Wiklander 36036802e2cSJens Wiklander int qemu_io_register_sp_pkg(const char *name, const char *uuid, 36136802e2cSJens Wiklander uintptr_t load_addr) 36236802e2cSJens Wiklander { 36336802e2cSJens Wiklander struct sp_pkg *pkg; 36436802e2cSJens Wiklander bl_mem_params_node_t *mem_params; 36536802e2cSJens Wiklander 36636802e2cSJens Wiklander if (sp_pkg_count == MAX_SP_IDS) { 36736802e2cSJens Wiklander INFO("Reached Max number of SPs\n"); 36836802e2cSJens Wiklander return -1; 36936802e2cSJens Wiklander } 37036802e2cSJens Wiklander mem_params = get_bl_mem_params_node(SP_PKG1_ID + sp_pkg_count); 37136802e2cSJens Wiklander if (mem_params == NULL) { 37236802e2cSJens Wiklander ERROR("Can't find SP_PKG ID %u (SP_PKG%u_ID)\n", 37336802e2cSJens Wiklander SP_PKG1_ID + sp_pkg_count, sp_pkg_count); 37436802e2cSJens Wiklander return -1; 37536802e2cSJens Wiklander } 37636802e2cSJens Wiklander pkg = sp_pkgs + sp_pkg_count; 37736802e2cSJens Wiklander 37836802e2cSJens Wiklander if (read_uuid(pkg->uuid, (char *)uuid)) { 37936802e2cSJens Wiklander return -1; 38036802e2cSJens Wiklander } 38136802e2cSJens Wiklander 38236802e2cSJens Wiklander strlcpy(pkg->path, name, sizeof(pkg->path)); 38336802e2cSJens Wiklander strlcat(pkg->path, ".pkg", sizeof(pkg->path)); 38436802e2cSJens Wiklander 38536802e2cSJens Wiklander pkg->policy.dev_handle = &fip_dev_handle; 38636802e2cSJens Wiklander pkg->policy.image_spec = (uintptr_t)&pkg->uuid; 38736802e2cSJens Wiklander pkg->policy.check = open_fip; 38836802e2cSJens Wiklander pkg->sh_file_spec.path = pkg->path; 38936802e2cSJens Wiklander pkg->sh_file_spec.mode = FOPEN_MODE_RB; 39036802e2cSJens Wiklander 39136802e2cSJens Wiklander mem_params->image_info.image_base = load_addr; 39236802e2cSJens Wiklander mem_params->image_info.image_max_size = SZ_4M; 39336802e2cSJens Wiklander mem_params->image_info.h.attr &= ~IMAGE_ATTRIB_SKIP_LOADING; 39436802e2cSJens Wiklander 39536802e2cSJens Wiklander sp_pkg_count++; 39636802e2cSJens Wiklander 39736802e2cSJens Wiklander return 0; 39836802e2cSJens Wiklander } 39936802e2cSJens Wiklander #endif /*SPD_spmd*/ 40036802e2cSJens Wiklander 40136802e2cSJens Wiklander static const io_file_spec_t *get_io_file_spec(unsigned int image_id) 40236802e2cSJens Wiklander { 40336802e2cSJens Wiklander #if defined(SPD_spmd) 40436802e2cSJens Wiklander if (image_id >= SP_PKG1_ID && image_id <= SP_PKG8_ID) { 40536802e2cSJens Wiklander return &sp_pkgs[image_id - SP_PKG1_ID].sh_file_spec; 40636802e2cSJens Wiklander } 40736802e2cSJens Wiklander #endif 40836802e2cSJens Wiklander 40936802e2cSJens Wiklander assert(image_id < ARRAY_SIZE(sh_file_spec)); 41036802e2cSJens Wiklander return &sh_file_spec[image_id]; 41136802e2cSJens Wiklander } 41236802e2cSJens Wiklander 41336802e2cSJens Wiklander static const struct plat_io_policy *get_io_policy(unsigned int image_id) 41436802e2cSJens Wiklander { 41536802e2cSJens Wiklander #if defined(SPD_spmd) 41636802e2cSJens Wiklander if (image_id >= SP_PKG1_ID && image_id <= SP_PKG8_ID) { 41736802e2cSJens Wiklander return &sp_pkgs[image_id - SP_PKG1_ID].policy; 41836802e2cSJens Wiklander } 41936802e2cSJens Wiklander #endif 42036802e2cSJens Wiklander 42136802e2cSJens Wiklander assert(image_id < ARRAY_SIZE(policies)); 42236802e2cSJens Wiklander return &policies[image_id]; 42336802e2cSJens Wiklander } 42436802e2cSJens Wiklander 425301d27d9SRadoslaw Biernacki static int open_fip(const uintptr_t spec) 426301d27d9SRadoslaw Biernacki { 427301d27d9SRadoslaw Biernacki int result; 428301d27d9SRadoslaw Biernacki uintptr_t local_image_handle; 429301d27d9SRadoslaw Biernacki 430301d27d9SRadoslaw Biernacki /* See if a Firmware Image Package is available */ 431301d27d9SRadoslaw Biernacki result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); 43251857762SSumit Garg if (result == 0 && spec != (uintptr_t)NULL) { 433301d27d9SRadoslaw Biernacki result = io_open(fip_dev_handle, spec, &local_image_handle); 434301d27d9SRadoslaw Biernacki if (result == 0) { 435301d27d9SRadoslaw Biernacki VERBOSE("Using FIP\n"); 436301d27d9SRadoslaw Biernacki io_close(local_image_handle); 437301d27d9SRadoslaw Biernacki } 438301d27d9SRadoslaw Biernacki } 439301d27d9SRadoslaw Biernacki return result; 440301d27d9SRadoslaw Biernacki } 441301d27d9SRadoslaw Biernacki 44251857762SSumit Garg #ifndef DECRYPTION_SUPPORT_none 44351857762SSumit Garg static int open_enc_fip(const uintptr_t spec) 44451857762SSumit Garg { 44551857762SSumit Garg int result; 44651857762SSumit Garg uintptr_t local_image_handle; 44751857762SSumit Garg 44851857762SSumit Garg /* See if an encrypted FIP is available */ 44951857762SSumit Garg result = io_dev_init(enc_dev_handle, (uintptr_t)ENC_IMAGE_ID); 45051857762SSumit Garg if (result == 0) { 45151857762SSumit Garg result = io_open(enc_dev_handle, spec, &local_image_handle); 45251857762SSumit Garg if (result == 0) { 45351857762SSumit Garg VERBOSE("Using encrypted FIP\n"); 45451857762SSumit Garg io_close(local_image_handle); 45551857762SSumit Garg } 45651857762SSumit Garg } 45751857762SSumit Garg return result; 45851857762SSumit Garg } 45951857762SSumit Garg #endif 46051857762SSumit Garg 461301d27d9SRadoslaw Biernacki static int open_memmap(const uintptr_t spec) 462301d27d9SRadoslaw Biernacki { 463301d27d9SRadoslaw Biernacki int result; 464301d27d9SRadoslaw Biernacki uintptr_t local_image_handle; 465301d27d9SRadoslaw Biernacki 466301d27d9SRadoslaw Biernacki result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL); 467301d27d9SRadoslaw Biernacki if (result == 0) { 468301d27d9SRadoslaw Biernacki result = io_open(memmap_dev_handle, spec, &local_image_handle); 469301d27d9SRadoslaw Biernacki if (result == 0) { 470301d27d9SRadoslaw Biernacki VERBOSE("Using Memmap\n"); 471301d27d9SRadoslaw Biernacki io_close(local_image_handle); 472301d27d9SRadoslaw Biernacki } 473301d27d9SRadoslaw Biernacki } 474301d27d9SRadoslaw Biernacki return result; 475301d27d9SRadoslaw Biernacki } 476301d27d9SRadoslaw Biernacki 477301d27d9SRadoslaw Biernacki static int open_semihosting(const uintptr_t spec) 478301d27d9SRadoslaw Biernacki { 479301d27d9SRadoslaw Biernacki int result; 480301d27d9SRadoslaw Biernacki uintptr_t local_image_handle; 481301d27d9SRadoslaw Biernacki 482301d27d9SRadoslaw Biernacki /* See if the file exists on semi-hosting.*/ 483301d27d9SRadoslaw Biernacki result = io_dev_init(sh_dev_handle, (uintptr_t)NULL); 484301d27d9SRadoslaw Biernacki if (result == 0) { 485301d27d9SRadoslaw Biernacki result = io_open(sh_dev_handle, spec, &local_image_handle); 486301d27d9SRadoslaw Biernacki if (result == 0) { 487301d27d9SRadoslaw Biernacki VERBOSE("Using Semi-hosting IO\n"); 488301d27d9SRadoslaw Biernacki io_close(local_image_handle); 489301d27d9SRadoslaw Biernacki } 490301d27d9SRadoslaw Biernacki } 491301d27d9SRadoslaw Biernacki return result; 492301d27d9SRadoslaw Biernacki } 493301d27d9SRadoslaw Biernacki 494301d27d9SRadoslaw Biernacki void plat_qemu_io_setup(void) 495301d27d9SRadoslaw Biernacki { 496301d27d9SRadoslaw Biernacki int io_result; 497301d27d9SRadoslaw Biernacki 498301d27d9SRadoslaw Biernacki io_result = register_io_dev_fip(&fip_dev_con); 499301d27d9SRadoslaw Biernacki assert(io_result == 0); 500301d27d9SRadoslaw Biernacki 501301d27d9SRadoslaw Biernacki io_result = register_io_dev_memmap(&memmap_dev_con); 502301d27d9SRadoslaw Biernacki assert(io_result == 0); 503301d27d9SRadoslaw Biernacki 504301d27d9SRadoslaw Biernacki /* Open connections to devices and cache the handles */ 505301d27d9SRadoslaw Biernacki io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL, 506301d27d9SRadoslaw Biernacki &fip_dev_handle); 507301d27d9SRadoslaw Biernacki assert(io_result == 0); 508301d27d9SRadoslaw Biernacki 509301d27d9SRadoslaw Biernacki io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL, 510301d27d9SRadoslaw Biernacki &memmap_dev_handle); 511301d27d9SRadoslaw Biernacki assert(io_result == 0); 512301d27d9SRadoslaw Biernacki 51351857762SSumit Garg #ifndef DECRYPTION_SUPPORT_none 51451857762SSumit Garg io_result = register_io_dev_enc(&enc_dev_con); 51551857762SSumit Garg assert(io_result == 0); 51651857762SSumit Garg 51751857762SSumit Garg io_result = io_dev_open(enc_dev_con, (uintptr_t)NULL, 51851857762SSumit Garg &enc_dev_handle); 51951857762SSumit Garg assert(io_result == 0); 52051857762SSumit Garg #endif 52151857762SSumit Garg 522301d27d9SRadoslaw Biernacki /* Register the additional IO devices on this platform */ 523301d27d9SRadoslaw Biernacki io_result = register_io_dev_sh(&sh_dev_con); 524301d27d9SRadoslaw Biernacki assert(io_result == 0); 525301d27d9SRadoslaw Biernacki 526301d27d9SRadoslaw Biernacki /* Open connections to devices and cache the handles */ 527301d27d9SRadoslaw Biernacki io_result = io_dev_open(sh_dev_con, (uintptr_t)NULL, &sh_dev_handle); 528301d27d9SRadoslaw Biernacki assert(io_result == 0); 529301d27d9SRadoslaw Biernacki 530301d27d9SRadoslaw Biernacki /* Ignore improbable errors in release builds */ 531301d27d9SRadoslaw Biernacki (void)io_result; 532301d27d9SRadoslaw Biernacki } 533301d27d9SRadoslaw Biernacki 534301d27d9SRadoslaw Biernacki static int get_alt_image_source(unsigned int image_id, uintptr_t *dev_handle, 535301d27d9SRadoslaw Biernacki uintptr_t *image_spec) 536301d27d9SRadoslaw Biernacki { 53736802e2cSJens Wiklander const io_file_spec_t *spec = get_io_file_spec(image_id); 53836802e2cSJens Wiklander int result; 539301d27d9SRadoslaw Biernacki 54036802e2cSJens Wiklander result = open_semihosting((const uintptr_t)spec); 541301d27d9SRadoslaw Biernacki if (result == 0) { 542301d27d9SRadoslaw Biernacki *dev_handle = sh_dev_handle; 54336802e2cSJens Wiklander *image_spec = (uintptr_t)spec; 544301d27d9SRadoslaw Biernacki } 545301d27d9SRadoslaw Biernacki 546301d27d9SRadoslaw Biernacki return result; 547301d27d9SRadoslaw Biernacki } 548301d27d9SRadoslaw Biernacki 549301d27d9SRadoslaw Biernacki /* 550301d27d9SRadoslaw Biernacki * Return an IO device handle and specification which can be used to access 551301d27d9SRadoslaw Biernacki * an image. Use this to enforce platform load policy 552301d27d9SRadoslaw Biernacki */ 553301d27d9SRadoslaw Biernacki int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, 554301d27d9SRadoslaw Biernacki uintptr_t *image_spec) 555301d27d9SRadoslaw Biernacki { 55636802e2cSJens Wiklander const struct plat_io_policy *policy = get_io_policy(image_id); 557301d27d9SRadoslaw Biernacki int result; 558301d27d9SRadoslaw Biernacki 559301d27d9SRadoslaw Biernacki result = policy->check(policy->image_spec); 560301d27d9SRadoslaw Biernacki if (result == 0) { 561301d27d9SRadoslaw Biernacki *image_spec = policy->image_spec; 562301d27d9SRadoslaw Biernacki *dev_handle = *(policy->dev_handle); 563301d27d9SRadoslaw Biernacki } else { 564301d27d9SRadoslaw Biernacki VERBOSE("Trying alternative IO\n"); 565301d27d9SRadoslaw Biernacki result = get_alt_image_source(image_id, dev_handle, image_spec); 566301d27d9SRadoslaw Biernacki } 567301d27d9SRadoslaw Biernacki 568301d27d9SRadoslaw Biernacki return result; 569301d27d9SRadoslaw Biernacki } 570