xref: /rk3399_ARM-atf/plat/qemu/common/qemu_io_storage.c (revision 2b6f940a106dba87ebfcbc5befe707bc2c34ee58)
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 
qemu_io_register_sp_pkg(const char * name,const char * uuid,uintptr_t load_addr)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 
get_io_file_spec(unsigned int image_id)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 
get_io_policy(unsigned int image_id)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 
open_fip(const uintptr_t spec)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
open_enc_fip(const uintptr_t spec)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 
open_memmap(const uintptr_t spec)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 
open_semihosting(const uintptr_t spec)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 
plat_qemu_io_setup(void)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 
get_alt_image_source(unsigned int image_id,uintptr_t * dev_handle,uintptr_t * image_spec)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  */
plat_get_image_source(unsigned int image_id,uintptr_t * dev_handle,uintptr_t * image_spec)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