xref: /rk3399_ARM-atf/plat/qemu/common/qemu_io_storage.c (revision 36802e2c792f79ab630b53298dfd4f1e5a95d173)
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