1301d27d9SRadoslaw Biernacki /* 225ae7ad1SJens 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> 14*36802e2cSJens Wiklander #include <common/desc_image_load.h> 15*36802e2cSJens 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 25*36802e2cSJens Wiklander #include "qemu_private.h" 26*36802e2cSJens 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" 31*36802e2cSJens 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" 36301d27d9SRadoslaw Biernacki 37301d27d9SRadoslaw Biernacki #if TRUSTED_BOARD_BOOT 38301d27d9SRadoslaw Biernacki #define TRUSTED_BOOT_FW_CERT_NAME "tb_fw.crt" 39301d27d9SRadoslaw Biernacki #define TRUSTED_KEY_CERT_NAME "trusted_key.crt" 40301d27d9SRadoslaw Biernacki #define SOC_FW_KEY_CERT_NAME "soc_fw_key.crt" 41301d27d9SRadoslaw Biernacki #define TOS_FW_KEY_CERT_NAME "tos_fw_key.crt" 42301d27d9SRadoslaw Biernacki #define NT_FW_KEY_CERT_NAME "nt_fw_key.crt" 43301d27d9SRadoslaw Biernacki #define SOC_FW_CONTENT_CERT_NAME "soc_fw_content.crt" 44301d27d9SRadoslaw Biernacki #define TOS_FW_CONTENT_CERT_NAME "tos_fw_content.crt" 45301d27d9SRadoslaw Biernacki #define NT_FW_CONTENT_CERT_NAME "nt_fw_content.crt" 46301d27d9SRadoslaw Biernacki #endif /* TRUSTED_BOARD_BOOT */ 47301d27d9SRadoslaw Biernacki 48301d27d9SRadoslaw Biernacki 49301d27d9SRadoslaw Biernacki 50301d27d9SRadoslaw Biernacki /* IO devices */ 51301d27d9SRadoslaw Biernacki static const io_dev_connector_t *fip_dev_con; 52301d27d9SRadoslaw Biernacki static uintptr_t fip_dev_handle; 53301d27d9SRadoslaw Biernacki static const io_dev_connector_t *memmap_dev_con; 54301d27d9SRadoslaw Biernacki static uintptr_t memmap_dev_handle; 55301d27d9SRadoslaw Biernacki static const io_dev_connector_t *sh_dev_con; 56301d27d9SRadoslaw Biernacki static uintptr_t sh_dev_handle; 5751857762SSumit Garg #ifndef DECRYPTION_SUPPORT_none 5851857762SSumit Garg static const io_dev_connector_t *enc_dev_con; 5951857762SSumit Garg static uintptr_t enc_dev_handle; 6051857762SSumit Garg #endif 61301d27d9SRadoslaw Biernacki 62301d27d9SRadoslaw Biernacki static const io_block_spec_t fip_block_spec = { 63301d27d9SRadoslaw Biernacki .offset = PLAT_QEMU_FIP_BASE, 64301d27d9SRadoslaw Biernacki .length = PLAT_QEMU_FIP_MAX_SIZE 65301d27d9SRadoslaw Biernacki }; 66301d27d9SRadoslaw Biernacki 67301d27d9SRadoslaw Biernacki static const io_uuid_spec_t bl2_uuid_spec = { 68301d27d9SRadoslaw Biernacki .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2, 69301d27d9SRadoslaw Biernacki }; 70301d27d9SRadoslaw Biernacki 71301d27d9SRadoslaw Biernacki static const io_uuid_spec_t bl31_uuid_spec = { 72301d27d9SRadoslaw Biernacki .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31, 73301d27d9SRadoslaw Biernacki }; 74301d27d9SRadoslaw Biernacki 75301d27d9SRadoslaw Biernacki static const io_uuid_spec_t bl32_uuid_spec = { 76301d27d9SRadoslaw Biernacki .uuid = UUID_SECURE_PAYLOAD_BL32, 77301d27d9SRadoslaw Biernacki }; 78301d27d9SRadoslaw Biernacki 79301d27d9SRadoslaw Biernacki static const io_uuid_spec_t bl32_extra1_uuid_spec = { 80301d27d9SRadoslaw Biernacki .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1, 81301d27d9SRadoslaw Biernacki }; 82301d27d9SRadoslaw Biernacki 83301d27d9SRadoslaw Biernacki static const io_uuid_spec_t bl32_extra2_uuid_spec = { 84301d27d9SRadoslaw Biernacki .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2, 85301d27d9SRadoslaw Biernacki }; 86301d27d9SRadoslaw Biernacki 87*36802e2cSJens Wiklander static const io_uuid_spec_t tb_fw_config_uuid_spec = { 88*36802e2cSJens Wiklander .uuid = UUID_TB_FW_CONFIG, 89*36802e2cSJens Wiklander }; 90*36802e2cSJens Wiklander 9125ae7ad1SJens Wiklander static const io_uuid_spec_t tos_fw_config_uuid_spec = { 9225ae7ad1SJens Wiklander .uuid = UUID_TOS_FW_CONFIG, 9325ae7ad1SJens Wiklander }; 9425ae7ad1SJens Wiklander 95301d27d9SRadoslaw Biernacki static const io_uuid_spec_t bl33_uuid_spec = { 96301d27d9SRadoslaw Biernacki .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33, 97301d27d9SRadoslaw Biernacki }; 98301d27d9SRadoslaw Biernacki 99301d27d9SRadoslaw Biernacki #if TRUSTED_BOARD_BOOT 100301d27d9SRadoslaw Biernacki static const io_uuid_spec_t tb_fw_cert_uuid_spec = { 101301d27d9SRadoslaw Biernacki .uuid = UUID_TRUSTED_BOOT_FW_CERT, 102301d27d9SRadoslaw Biernacki }; 103301d27d9SRadoslaw Biernacki 104301d27d9SRadoslaw Biernacki static const io_uuid_spec_t trusted_key_cert_uuid_spec = { 105301d27d9SRadoslaw Biernacki .uuid = UUID_TRUSTED_KEY_CERT, 106301d27d9SRadoslaw Biernacki }; 107301d27d9SRadoslaw Biernacki 108301d27d9SRadoslaw Biernacki static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = { 109301d27d9SRadoslaw Biernacki .uuid = UUID_SOC_FW_KEY_CERT, 110301d27d9SRadoslaw Biernacki }; 111301d27d9SRadoslaw Biernacki 112301d27d9SRadoslaw Biernacki static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = { 113301d27d9SRadoslaw Biernacki .uuid = UUID_TRUSTED_OS_FW_KEY_CERT, 114301d27d9SRadoslaw Biernacki }; 115301d27d9SRadoslaw Biernacki 116301d27d9SRadoslaw Biernacki static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = { 117301d27d9SRadoslaw Biernacki .uuid = UUID_NON_TRUSTED_FW_KEY_CERT, 118301d27d9SRadoslaw Biernacki }; 119301d27d9SRadoslaw Biernacki 120301d27d9SRadoslaw Biernacki static const io_uuid_spec_t soc_fw_cert_uuid_spec = { 121301d27d9SRadoslaw Biernacki .uuid = UUID_SOC_FW_CONTENT_CERT, 122301d27d9SRadoslaw Biernacki }; 123301d27d9SRadoslaw Biernacki 124301d27d9SRadoslaw Biernacki static const io_uuid_spec_t tos_fw_cert_uuid_spec = { 125301d27d9SRadoslaw Biernacki .uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT, 126301d27d9SRadoslaw Biernacki }; 127301d27d9SRadoslaw Biernacki 128301d27d9SRadoslaw Biernacki static const io_uuid_spec_t nt_fw_cert_uuid_spec = { 129301d27d9SRadoslaw Biernacki .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT, 130301d27d9SRadoslaw Biernacki }; 131301d27d9SRadoslaw Biernacki #endif /* TRUSTED_BOARD_BOOT */ 132301d27d9SRadoslaw Biernacki 133301d27d9SRadoslaw Biernacki static const io_file_spec_t sh_file_spec[] = { 134301d27d9SRadoslaw Biernacki [BL2_IMAGE_ID] = { 135301d27d9SRadoslaw Biernacki .path = BL2_IMAGE_NAME, 136301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 137301d27d9SRadoslaw Biernacki }, 138301d27d9SRadoslaw Biernacki [BL31_IMAGE_ID] = { 139301d27d9SRadoslaw Biernacki .path = BL31_IMAGE_NAME, 140301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 141301d27d9SRadoslaw Biernacki }, 142301d27d9SRadoslaw Biernacki [BL32_IMAGE_ID] = { 143301d27d9SRadoslaw Biernacki .path = BL32_IMAGE_NAME, 144301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 145301d27d9SRadoslaw Biernacki }, 146301d27d9SRadoslaw Biernacki [BL32_EXTRA1_IMAGE_ID] = { 147301d27d9SRadoslaw Biernacki .path = BL32_EXTRA1_IMAGE_NAME, 148301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 149301d27d9SRadoslaw Biernacki }, 150301d27d9SRadoslaw Biernacki [BL32_EXTRA2_IMAGE_ID] = { 151301d27d9SRadoslaw Biernacki .path = BL32_EXTRA2_IMAGE_NAME, 152301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 153301d27d9SRadoslaw Biernacki }, 154*36802e2cSJens Wiklander [TB_FW_CONFIG_ID] = { 155*36802e2cSJens Wiklander .path = TB_FW_CONFIG_NAME, 156*36802e2cSJens Wiklander .mode = FOPEN_MODE_RB 157*36802e2cSJens Wiklander }, 15825ae7ad1SJens Wiklander [TOS_FW_CONFIG_ID] = { 15925ae7ad1SJens Wiklander .path = TOS_FW_CONFIG_NAME, 16025ae7ad1SJens Wiklander .mode = FOPEN_MODE_RB 16125ae7ad1SJens Wiklander }, 162301d27d9SRadoslaw Biernacki [BL33_IMAGE_ID] = { 163301d27d9SRadoslaw Biernacki .path = BL33_IMAGE_NAME, 164301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 165301d27d9SRadoslaw Biernacki }, 166301d27d9SRadoslaw Biernacki #if TRUSTED_BOARD_BOOT 167301d27d9SRadoslaw Biernacki [TRUSTED_BOOT_FW_CERT_ID] = { 168301d27d9SRadoslaw Biernacki .path = TRUSTED_BOOT_FW_CERT_NAME, 169301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 170301d27d9SRadoslaw Biernacki }, 171301d27d9SRadoslaw Biernacki [TRUSTED_KEY_CERT_ID] = { 172301d27d9SRadoslaw Biernacki .path = TRUSTED_KEY_CERT_NAME, 173301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 174301d27d9SRadoslaw Biernacki }, 175301d27d9SRadoslaw Biernacki [SOC_FW_KEY_CERT_ID] = { 176301d27d9SRadoslaw Biernacki .path = SOC_FW_KEY_CERT_NAME, 177301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 178301d27d9SRadoslaw Biernacki }, 179301d27d9SRadoslaw Biernacki [TRUSTED_OS_FW_KEY_CERT_ID] = { 180301d27d9SRadoslaw Biernacki .path = TOS_FW_KEY_CERT_NAME, 181301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 182301d27d9SRadoslaw Biernacki }, 183301d27d9SRadoslaw Biernacki [NON_TRUSTED_FW_KEY_CERT_ID] = { 184301d27d9SRadoslaw Biernacki .path = NT_FW_KEY_CERT_NAME, 185301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 186301d27d9SRadoslaw Biernacki }, 187301d27d9SRadoslaw Biernacki [SOC_FW_CONTENT_CERT_ID] = { 188301d27d9SRadoslaw Biernacki .path = SOC_FW_CONTENT_CERT_NAME, 189301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 190301d27d9SRadoslaw Biernacki }, 191301d27d9SRadoslaw Biernacki [TRUSTED_OS_FW_CONTENT_CERT_ID] = { 192301d27d9SRadoslaw Biernacki .path = TOS_FW_CONTENT_CERT_NAME, 193301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 194301d27d9SRadoslaw Biernacki }, 195301d27d9SRadoslaw Biernacki [NON_TRUSTED_FW_CONTENT_CERT_ID] = { 196301d27d9SRadoslaw Biernacki .path = NT_FW_CONTENT_CERT_NAME, 197301d27d9SRadoslaw Biernacki .mode = FOPEN_MODE_RB 198301d27d9SRadoslaw Biernacki }, 199301d27d9SRadoslaw Biernacki #endif /* TRUSTED_BOARD_BOOT */ 200301d27d9SRadoslaw Biernacki }; 201301d27d9SRadoslaw Biernacki 202301d27d9SRadoslaw Biernacki static int open_fip(const uintptr_t spec); 203301d27d9SRadoslaw Biernacki static int open_memmap(const uintptr_t spec); 20451857762SSumit Garg #ifndef DECRYPTION_SUPPORT_none 20551857762SSumit Garg static int open_enc_fip(const uintptr_t spec); 20651857762SSumit Garg #endif 207301d27d9SRadoslaw Biernacki 208301d27d9SRadoslaw Biernacki struct plat_io_policy { 209301d27d9SRadoslaw Biernacki uintptr_t *dev_handle; 210301d27d9SRadoslaw Biernacki uintptr_t image_spec; 211301d27d9SRadoslaw Biernacki int (*check)(const uintptr_t spec); 212301d27d9SRadoslaw Biernacki }; 213301d27d9SRadoslaw Biernacki 214301d27d9SRadoslaw Biernacki /* By default, ARM platforms load images from the FIP */ 215301d27d9SRadoslaw Biernacki static const struct plat_io_policy policies[] = { 216301d27d9SRadoslaw Biernacki [FIP_IMAGE_ID] = { 217301d27d9SRadoslaw Biernacki &memmap_dev_handle, 218301d27d9SRadoslaw Biernacki (uintptr_t)&fip_block_spec, 219301d27d9SRadoslaw Biernacki open_memmap 220301d27d9SRadoslaw Biernacki }, 22151857762SSumit Garg [ENC_IMAGE_ID] = { 22251857762SSumit Garg &fip_dev_handle, 22351857762SSumit Garg (uintptr_t)NULL, 22451857762SSumit Garg open_fip 22551857762SSumit Garg }, 226301d27d9SRadoslaw Biernacki [BL2_IMAGE_ID] = { 227301d27d9SRadoslaw Biernacki &fip_dev_handle, 228301d27d9SRadoslaw Biernacki (uintptr_t)&bl2_uuid_spec, 229301d27d9SRadoslaw Biernacki open_fip 230301d27d9SRadoslaw Biernacki }, 23151857762SSumit Garg #if ENCRYPT_BL31 && !defined(DECRYPTION_SUPPORT_none) 23251857762SSumit Garg [BL31_IMAGE_ID] = { 23351857762SSumit Garg &enc_dev_handle, 23451857762SSumit Garg (uintptr_t)&bl31_uuid_spec, 23551857762SSumit Garg open_enc_fip 23651857762SSumit Garg }, 23751857762SSumit Garg #else 238301d27d9SRadoslaw Biernacki [BL31_IMAGE_ID] = { 239301d27d9SRadoslaw Biernacki &fip_dev_handle, 240301d27d9SRadoslaw Biernacki (uintptr_t)&bl31_uuid_spec, 241301d27d9SRadoslaw Biernacki open_fip 242301d27d9SRadoslaw Biernacki }, 24351857762SSumit Garg #endif 24451857762SSumit Garg #if ENCRYPT_BL32 && !defined(DECRYPTION_SUPPORT_none) 24551857762SSumit Garg [BL32_IMAGE_ID] = { 24651857762SSumit Garg &enc_dev_handle, 24751857762SSumit Garg (uintptr_t)&bl32_uuid_spec, 24851857762SSumit Garg open_enc_fip 24951857762SSumit Garg }, 25051857762SSumit Garg [BL32_EXTRA1_IMAGE_ID] = { 25151857762SSumit Garg &enc_dev_handle, 25251857762SSumit Garg (uintptr_t)&bl32_extra1_uuid_spec, 25351857762SSumit Garg open_enc_fip 25451857762SSumit Garg }, 25551857762SSumit Garg [BL32_EXTRA2_IMAGE_ID] = { 25651857762SSumit Garg &enc_dev_handle, 25751857762SSumit Garg (uintptr_t)&bl32_extra2_uuid_spec, 25851857762SSumit Garg open_enc_fip 25951857762SSumit Garg }, 26051857762SSumit Garg #else 261301d27d9SRadoslaw Biernacki [BL32_IMAGE_ID] = { 262301d27d9SRadoslaw Biernacki &fip_dev_handle, 263301d27d9SRadoslaw Biernacki (uintptr_t)&bl32_uuid_spec, 264301d27d9SRadoslaw Biernacki open_fip 265301d27d9SRadoslaw Biernacki }, 266301d27d9SRadoslaw Biernacki [BL32_EXTRA1_IMAGE_ID] = { 267301d27d9SRadoslaw Biernacki &fip_dev_handle, 268301d27d9SRadoslaw Biernacki (uintptr_t)&bl32_extra1_uuid_spec, 269301d27d9SRadoslaw Biernacki open_fip 270301d27d9SRadoslaw Biernacki }, 271301d27d9SRadoslaw Biernacki [BL32_EXTRA2_IMAGE_ID] = { 272301d27d9SRadoslaw Biernacki &fip_dev_handle, 273301d27d9SRadoslaw Biernacki (uintptr_t)&bl32_extra2_uuid_spec, 274301d27d9SRadoslaw Biernacki open_fip 275301d27d9SRadoslaw Biernacki }, 27651857762SSumit Garg #endif 277*36802e2cSJens Wiklander [TB_FW_CONFIG_ID] = { 278*36802e2cSJens Wiklander &fip_dev_handle, 279*36802e2cSJens Wiklander (uintptr_t)&tb_fw_config_uuid_spec, 280*36802e2cSJens Wiklander open_fip 281*36802e2cSJens Wiklander }, 28225ae7ad1SJens Wiklander [TOS_FW_CONFIG_ID] = { 28325ae7ad1SJens Wiklander &fip_dev_handle, 28425ae7ad1SJens Wiklander (uintptr_t)&tos_fw_config_uuid_spec, 28525ae7ad1SJens Wiklander open_fip 28625ae7ad1SJens Wiklander }, 287301d27d9SRadoslaw Biernacki [BL33_IMAGE_ID] = { 288301d27d9SRadoslaw Biernacki &fip_dev_handle, 289301d27d9SRadoslaw Biernacki (uintptr_t)&bl33_uuid_spec, 290301d27d9SRadoslaw Biernacki open_fip 291301d27d9SRadoslaw Biernacki }, 292301d27d9SRadoslaw Biernacki #if TRUSTED_BOARD_BOOT 293301d27d9SRadoslaw Biernacki [TRUSTED_BOOT_FW_CERT_ID] = { 294301d27d9SRadoslaw Biernacki &fip_dev_handle, 295301d27d9SRadoslaw Biernacki (uintptr_t)&tb_fw_cert_uuid_spec, 296301d27d9SRadoslaw Biernacki open_fip 297301d27d9SRadoslaw Biernacki }, 298301d27d9SRadoslaw Biernacki [TRUSTED_KEY_CERT_ID] = { 299301d27d9SRadoslaw Biernacki &fip_dev_handle, 300301d27d9SRadoslaw Biernacki (uintptr_t)&trusted_key_cert_uuid_spec, 301301d27d9SRadoslaw Biernacki open_fip 302301d27d9SRadoslaw Biernacki }, 303301d27d9SRadoslaw Biernacki [SOC_FW_KEY_CERT_ID] = { 304301d27d9SRadoslaw Biernacki &fip_dev_handle, 305301d27d9SRadoslaw Biernacki (uintptr_t)&soc_fw_key_cert_uuid_spec, 306301d27d9SRadoslaw Biernacki open_fip 307301d27d9SRadoslaw Biernacki }, 308301d27d9SRadoslaw Biernacki [TRUSTED_OS_FW_KEY_CERT_ID] = { 309301d27d9SRadoslaw Biernacki &fip_dev_handle, 310301d27d9SRadoslaw Biernacki (uintptr_t)&tos_fw_key_cert_uuid_spec, 311301d27d9SRadoslaw Biernacki open_fip 312301d27d9SRadoslaw Biernacki }, 313301d27d9SRadoslaw Biernacki [NON_TRUSTED_FW_KEY_CERT_ID] = { 314301d27d9SRadoslaw Biernacki &fip_dev_handle, 315301d27d9SRadoslaw Biernacki (uintptr_t)&nt_fw_key_cert_uuid_spec, 316301d27d9SRadoslaw Biernacki open_fip 317301d27d9SRadoslaw Biernacki }, 318301d27d9SRadoslaw Biernacki [SOC_FW_CONTENT_CERT_ID] = { 319301d27d9SRadoslaw Biernacki &fip_dev_handle, 320301d27d9SRadoslaw Biernacki (uintptr_t)&soc_fw_cert_uuid_spec, 321301d27d9SRadoslaw Biernacki open_fip 322301d27d9SRadoslaw Biernacki }, 323301d27d9SRadoslaw Biernacki [TRUSTED_OS_FW_CONTENT_CERT_ID] = { 324301d27d9SRadoslaw Biernacki &fip_dev_handle, 325301d27d9SRadoslaw Biernacki (uintptr_t)&tos_fw_cert_uuid_spec, 326301d27d9SRadoslaw Biernacki open_fip 327301d27d9SRadoslaw Biernacki }, 328301d27d9SRadoslaw Biernacki [NON_TRUSTED_FW_CONTENT_CERT_ID] = { 329301d27d9SRadoslaw Biernacki &fip_dev_handle, 330301d27d9SRadoslaw Biernacki (uintptr_t)&nt_fw_cert_uuid_spec, 331301d27d9SRadoslaw Biernacki open_fip 332301d27d9SRadoslaw Biernacki }, 333301d27d9SRadoslaw Biernacki #endif /* TRUSTED_BOARD_BOOT */ 334301d27d9SRadoslaw Biernacki }; 335301d27d9SRadoslaw Biernacki 336*36802e2cSJens Wiklander #if defined(SPD_spmd) 337*36802e2cSJens Wiklander static struct sp_pkg { 338*36802e2cSJens Wiklander struct plat_io_policy policy; 339*36802e2cSJens Wiklander io_file_spec_t sh_file_spec; 340*36802e2cSJens Wiklander uint8_t uuid[UUID_BYTES_LENGTH]; 341*36802e2cSJens Wiklander char path[80]; 342*36802e2cSJens Wiklander } sp_pkgs[MAX_SP_IDS]; 343*36802e2cSJens Wiklander static unsigned int sp_pkg_count; 344*36802e2cSJens Wiklander 345*36802e2cSJens Wiklander int qemu_io_register_sp_pkg(const char *name, const char *uuid, 346*36802e2cSJens Wiklander uintptr_t load_addr) 347*36802e2cSJens Wiklander { 348*36802e2cSJens Wiklander struct sp_pkg *pkg; 349*36802e2cSJens Wiklander bl_mem_params_node_t *mem_params; 350*36802e2cSJens Wiklander 351*36802e2cSJens Wiklander if (sp_pkg_count == MAX_SP_IDS) { 352*36802e2cSJens Wiklander INFO("Reached Max number of SPs\n"); 353*36802e2cSJens Wiklander return -1; 354*36802e2cSJens Wiklander } 355*36802e2cSJens Wiklander mem_params = get_bl_mem_params_node(SP_PKG1_ID + sp_pkg_count); 356*36802e2cSJens Wiklander if (mem_params == NULL) { 357*36802e2cSJens Wiklander ERROR("Can't find SP_PKG ID %u (SP_PKG%u_ID)\n", 358*36802e2cSJens Wiklander SP_PKG1_ID + sp_pkg_count, sp_pkg_count); 359*36802e2cSJens Wiklander return -1; 360*36802e2cSJens Wiklander } 361*36802e2cSJens Wiklander pkg = sp_pkgs + sp_pkg_count; 362*36802e2cSJens Wiklander 363*36802e2cSJens Wiklander if (read_uuid(pkg->uuid, (char *)uuid)) { 364*36802e2cSJens Wiklander return -1; 365*36802e2cSJens Wiklander } 366*36802e2cSJens Wiklander 367*36802e2cSJens Wiklander strlcpy(pkg->path, name, sizeof(pkg->path)); 368*36802e2cSJens Wiklander strlcat(pkg->path, ".pkg", sizeof(pkg->path)); 369*36802e2cSJens Wiklander 370*36802e2cSJens Wiklander pkg->policy.dev_handle = &fip_dev_handle; 371*36802e2cSJens Wiklander pkg->policy.image_spec = (uintptr_t)&pkg->uuid; 372*36802e2cSJens Wiklander pkg->policy.check = open_fip; 373*36802e2cSJens Wiklander pkg->sh_file_spec.path = pkg->path; 374*36802e2cSJens Wiklander pkg->sh_file_spec.mode = FOPEN_MODE_RB; 375*36802e2cSJens Wiklander 376*36802e2cSJens Wiklander mem_params->image_info.image_base = load_addr; 377*36802e2cSJens Wiklander mem_params->image_info.image_max_size = SZ_4M; 378*36802e2cSJens Wiklander mem_params->image_info.h.attr &= ~IMAGE_ATTRIB_SKIP_LOADING; 379*36802e2cSJens Wiklander 380*36802e2cSJens Wiklander sp_pkg_count++; 381*36802e2cSJens Wiklander 382*36802e2cSJens Wiklander return 0; 383*36802e2cSJens Wiklander } 384*36802e2cSJens Wiklander #endif /*SPD_spmd*/ 385*36802e2cSJens Wiklander 386*36802e2cSJens Wiklander static const io_file_spec_t *get_io_file_spec(unsigned int image_id) 387*36802e2cSJens Wiklander { 388*36802e2cSJens Wiklander #if defined(SPD_spmd) 389*36802e2cSJens Wiklander if (image_id >= SP_PKG1_ID && image_id <= SP_PKG8_ID) { 390*36802e2cSJens Wiklander return &sp_pkgs[image_id - SP_PKG1_ID].sh_file_spec; 391*36802e2cSJens Wiklander } 392*36802e2cSJens Wiklander #endif 393*36802e2cSJens Wiklander 394*36802e2cSJens Wiklander assert(image_id < ARRAY_SIZE(sh_file_spec)); 395*36802e2cSJens Wiklander return &sh_file_spec[image_id]; 396*36802e2cSJens Wiklander } 397*36802e2cSJens Wiklander 398*36802e2cSJens Wiklander static const struct plat_io_policy *get_io_policy(unsigned int image_id) 399*36802e2cSJens Wiklander { 400*36802e2cSJens Wiklander #if defined(SPD_spmd) 401*36802e2cSJens Wiklander if (image_id >= SP_PKG1_ID && image_id <= SP_PKG8_ID) { 402*36802e2cSJens Wiklander return &sp_pkgs[image_id - SP_PKG1_ID].policy; 403*36802e2cSJens Wiklander } 404*36802e2cSJens Wiklander #endif 405*36802e2cSJens Wiklander 406*36802e2cSJens Wiklander assert(image_id < ARRAY_SIZE(policies)); 407*36802e2cSJens Wiklander return &policies[image_id]; 408*36802e2cSJens Wiklander } 409*36802e2cSJens Wiklander 410301d27d9SRadoslaw Biernacki static int open_fip(const uintptr_t spec) 411301d27d9SRadoslaw Biernacki { 412301d27d9SRadoslaw Biernacki int result; 413301d27d9SRadoslaw Biernacki uintptr_t local_image_handle; 414301d27d9SRadoslaw Biernacki 415301d27d9SRadoslaw Biernacki /* See if a Firmware Image Package is available */ 416301d27d9SRadoslaw Biernacki result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); 41751857762SSumit Garg if (result == 0 && spec != (uintptr_t)NULL) { 418301d27d9SRadoslaw Biernacki result = io_open(fip_dev_handle, spec, &local_image_handle); 419301d27d9SRadoslaw Biernacki if (result == 0) { 420301d27d9SRadoslaw Biernacki VERBOSE("Using FIP\n"); 421301d27d9SRadoslaw Biernacki io_close(local_image_handle); 422301d27d9SRadoslaw Biernacki } 423301d27d9SRadoslaw Biernacki } 424301d27d9SRadoslaw Biernacki return result; 425301d27d9SRadoslaw Biernacki } 426301d27d9SRadoslaw Biernacki 42751857762SSumit Garg #ifndef DECRYPTION_SUPPORT_none 42851857762SSumit Garg static int open_enc_fip(const uintptr_t spec) 42951857762SSumit Garg { 43051857762SSumit Garg int result; 43151857762SSumit Garg uintptr_t local_image_handle; 43251857762SSumit Garg 43351857762SSumit Garg /* See if an encrypted FIP is available */ 43451857762SSumit Garg result = io_dev_init(enc_dev_handle, (uintptr_t)ENC_IMAGE_ID); 43551857762SSumit Garg if (result == 0) { 43651857762SSumit Garg result = io_open(enc_dev_handle, spec, &local_image_handle); 43751857762SSumit Garg if (result == 0) { 43851857762SSumit Garg VERBOSE("Using encrypted FIP\n"); 43951857762SSumit Garg io_close(local_image_handle); 44051857762SSumit Garg } 44151857762SSumit Garg } 44251857762SSumit Garg return result; 44351857762SSumit Garg } 44451857762SSumit Garg #endif 44551857762SSumit Garg 446301d27d9SRadoslaw Biernacki static int open_memmap(const uintptr_t spec) 447301d27d9SRadoslaw Biernacki { 448301d27d9SRadoslaw Biernacki int result; 449301d27d9SRadoslaw Biernacki uintptr_t local_image_handle; 450301d27d9SRadoslaw Biernacki 451301d27d9SRadoslaw Biernacki result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL); 452301d27d9SRadoslaw Biernacki if (result == 0) { 453301d27d9SRadoslaw Biernacki result = io_open(memmap_dev_handle, spec, &local_image_handle); 454301d27d9SRadoslaw Biernacki if (result == 0) { 455301d27d9SRadoslaw Biernacki VERBOSE("Using Memmap\n"); 456301d27d9SRadoslaw Biernacki io_close(local_image_handle); 457301d27d9SRadoslaw Biernacki } 458301d27d9SRadoslaw Biernacki } 459301d27d9SRadoslaw Biernacki return result; 460301d27d9SRadoslaw Biernacki } 461301d27d9SRadoslaw Biernacki 462301d27d9SRadoslaw Biernacki static int open_semihosting(const uintptr_t spec) 463301d27d9SRadoslaw Biernacki { 464301d27d9SRadoslaw Biernacki int result; 465301d27d9SRadoslaw Biernacki uintptr_t local_image_handle; 466301d27d9SRadoslaw Biernacki 467301d27d9SRadoslaw Biernacki /* See if the file exists on semi-hosting.*/ 468301d27d9SRadoslaw Biernacki result = io_dev_init(sh_dev_handle, (uintptr_t)NULL); 469301d27d9SRadoslaw Biernacki if (result == 0) { 470301d27d9SRadoslaw Biernacki result = io_open(sh_dev_handle, spec, &local_image_handle); 471301d27d9SRadoslaw Biernacki if (result == 0) { 472301d27d9SRadoslaw Biernacki VERBOSE("Using Semi-hosting IO\n"); 473301d27d9SRadoslaw Biernacki io_close(local_image_handle); 474301d27d9SRadoslaw Biernacki } 475301d27d9SRadoslaw Biernacki } 476301d27d9SRadoslaw Biernacki return result; 477301d27d9SRadoslaw Biernacki } 478301d27d9SRadoslaw Biernacki 479301d27d9SRadoslaw Biernacki void plat_qemu_io_setup(void) 480301d27d9SRadoslaw Biernacki { 481301d27d9SRadoslaw Biernacki int io_result; 482301d27d9SRadoslaw Biernacki 483301d27d9SRadoslaw Biernacki io_result = register_io_dev_fip(&fip_dev_con); 484301d27d9SRadoslaw Biernacki assert(io_result == 0); 485301d27d9SRadoslaw Biernacki 486301d27d9SRadoslaw Biernacki io_result = register_io_dev_memmap(&memmap_dev_con); 487301d27d9SRadoslaw Biernacki assert(io_result == 0); 488301d27d9SRadoslaw Biernacki 489301d27d9SRadoslaw Biernacki /* Open connections to devices and cache the handles */ 490301d27d9SRadoslaw Biernacki io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL, 491301d27d9SRadoslaw Biernacki &fip_dev_handle); 492301d27d9SRadoslaw Biernacki assert(io_result == 0); 493301d27d9SRadoslaw Biernacki 494301d27d9SRadoslaw Biernacki io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL, 495301d27d9SRadoslaw Biernacki &memmap_dev_handle); 496301d27d9SRadoslaw Biernacki assert(io_result == 0); 497301d27d9SRadoslaw Biernacki 49851857762SSumit Garg #ifndef DECRYPTION_SUPPORT_none 49951857762SSumit Garg io_result = register_io_dev_enc(&enc_dev_con); 50051857762SSumit Garg assert(io_result == 0); 50151857762SSumit Garg 50251857762SSumit Garg io_result = io_dev_open(enc_dev_con, (uintptr_t)NULL, 50351857762SSumit Garg &enc_dev_handle); 50451857762SSumit Garg assert(io_result == 0); 50551857762SSumit Garg #endif 50651857762SSumit Garg 507301d27d9SRadoslaw Biernacki /* Register the additional IO devices on this platform */ 508301d27d9SRadoslaw Biernacki io_result = register_io_dev_sh(&sh_dev_con); 509301d27d9SRadoslaw Biernacki assert(io_result == 0); 510301d27d9SRadoslaw Biernacki 511301d27d9SRadoslaw Biernacki /* Open connections to devices and cache the handles */ 512301d27d9SRadoslaw Biernacki io_result = io_dev_open(sh_dev_con, (uintptr_t)NULL, &sh_dev_handle); 513301d27d9SRadoslaw Biernacki assert(io_result == 0); 514301d27d9SRadoslaw Biernacki 515301d27d9SRadoslaw Biernacki /* Ignore improbable errors in release builds */ 516301d27d9SRadoslaw Biernacki (void)io_result; 517301d27d9SRadoslaw Biernacki } 518301d27d9SRadoslaw Biernacki 519301d27d9SRadoslaw Biernacki static int get_alt_image_source(unsigned int image_id, uintptr_t *dev_handle, 520301d27d9SRadoslaw Biernacki uintptr_t *image_spec) 521301d27d9SRadoslaw Biernacki { 522*36802e2cSJens Wiklander const io_file_spec_t *spec = get_io_file_spec(image_id); 523*36802e2cSJens Wiklander int result; 524301d27d9SRadoslaw Biernacki 525*36802e2cSJens Wiklander result = open_semihosting((const uintptr_t)spec); 526301d27d9SRadoslaw Biernacki if (result == 0) { 527301d27d9SRadoslaw Biernacki *dev_handle = sh_dev_handle; 528*36802e2cSJens Wiklander *image_spec = (uintptr_t)spec; 529301d27d9SRadoslaw Biernacki } 530301d27d9SRadoslaw Biernacki 531301d27d9SRadoslaw Biernacki return result; 532301d27d9SRadoslaw Biernacki } 533301d27d9SRadoslaw Biernacki 534301d27d9SRadoslaw Biernacki /* 535301d27d9SRadoslaw Biernacki * Return an IO device handle and specification which can be used to access 536301d27d9SRadoslaw Biernacki * an image. Use this to enforce platform load policy 537301d27d9SRadoslaw Biernacki */ 538301d27d9SRadoslaw Biernacki int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, 539301d27d9SRadoslaw Biernacki uintptr_t *image_spec) 540301d27d9SRadoslaw Biernacki { 541*36802e2cSJens Wiklander const struct plat_io_policy *policy = get_io_policy(image_id); 542301d27d9SRadoslaw Biernacki int result; 543301d27d9SRadoslaw Biernacki 544301d27d9SRadoslaw Biernacki result = policy->check(policy->image_spec); 545301d27d9SRadoslaw Biernacki if (result == 0) { 546301d27d9SRadoslaw Biernacki *image_spec = policy->image_spec; 547301d27d9SRadoslaw Biernacki *dev_handle = *(policy->dev_handle); 548301d27d9SRadoslaw Biernacki } else { 549301d27d9SRadoslaw Biernacki VERBOSE("Trying alternative IO\n"); 550301d27d9SRadoslaw Biernacki result = get_alt_image_source(image_id, dev_handle, image_spec); 551301d27d9SRadoslaw Biernacki } 552301d27d9SRadoslaw Biernacki 553301d27d9SRadoslaw Biernacki return result; 554301d27d9SRadoslaw Biernacki } 555