xref: /rk3399_ARM-atf/plat/qemu/common/qemu_io_storage.c (revision 518577627e5c7f009094eb0ef8fdc24a200d2ffb)
1301d27d9SRadoslaw Biernacki /*
2301d27d9SRadoslaw Biernacki  * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
3301d27d9SRadoslaw Biernacki  *
4301d27d9SRadoslaw Biernacki  * SPDX-License-Identifier: BSD-3-Clause
5301d27d9SRadoslaw Biernacki  */
6301d27d9SRadoslaw Biernacki 
7301d27d9SRadoslaw Biernacki #include <assert.h>
8301d27d9SRadoslaw Biernacki #include <string.h>
9301d27d9SRadoslaw Biernacki 
10301d27d9SRadoslaw Biernacki #include <platform_def.h>
11301d27d9SRadoslaw Biernacki 
12301d27d9SRadoslaw Biernacki #include <common/bl_common.h>
13301d27d9SRadoslaw Biernacki #include <common/debug.h>
14301d27d9SRadoslaw Biernacki #include <drivers/io/io_driver.h>
15*51857762SSumit Garg #include <drivers/io/io_encrypted.h>
16301d27d9SRadoslaw Biernacki #include <drivers/io/io_fip.h>
17301d27d9SRadoslaw Biernacki #include <drivers/io/io_memmap.h>
18301d27d9SRadoslaw Biernacki #include <drivers/io/io_semihosting.h>
19301d27d9SRadoslaw Biernacki #include <drivers/io/io_storage.h>
20301d27d9SRadoslaw Biernacki #include <lib/semihosting.h>
21301d27d9SRadoslaw Biernacki #include <tools_share/firmware_image_package.h>
22301d27d9SRadoslaw Biernacki 
23301d27d9SRadoslaw Biernacki /* Semihosting filenames */
24301d27d9SRadoslaw Biernacki #define BL2_IMAGE_NAME			"bl2.bin"
25301d27d9SRadoslaw Biernacki #define BL31_IMAGE_NAME			"bl31.bin"
26301d27d9SRadoslaw Biernacki #define BL32_IMAGE_NAME			"bl32.bin"
27301d27d9SRadoslaw Biernacki #define BL32_EXTRA1_IMAGE_NAME		"bl32_extra1.bin"
28301d27d9SRadoslaw Biernacki #define BL32_EXTRA2_IMAGE_NAME		"bl32_extra2.bin"
29301d27d9SRadoslaw Biernacki #define BL33_IMAGE_NAME			"bl33.bin"
30301d27d9SRadoslaw Biernacki 
31301d27d9SRadoslaw Biernacki #if TRUSTED_BOARD_BOOT
32301d27d9SRadoslaw Biernacki #define TRUSTED_BOOT_FW_CERT_NAME	"tb_fw.crt"
33301d27d9SRadoslaw Biernacki #define TRUSTED_KEY_CERT_NAME		"trusted_key.crt"
34301d27d9SRadoslaw Biernacki #define SOC_FW_KEY_CERT_NAME		"soc_fw_key.crt"
35301d27d9SRadoslaw Biernacki #define TOS_FW_KEY_CERT_NAME		"tos_fw_key.crt"
36301d27d9SRadoslaw Biernacki #define NT_FW_KEY_CERT_NAME		"nt_fw_key.crt"
37301d27d9SRadoslaw Biernacki #define SOC_FW_CONTENT_CERT_NAME	"soc_fw_content.crt"
38301d27d9SRadoslaw Biernacki #define TOS_FW_CONTENT_CERT_NAME	"tos_fw_content.crt"
39301d27d9SRadoslaw Biernacki #define NT_FW_CONTENT_CERT_NAME		"nt_fw_content.crt"
40301d27d9SRadoslaw Biernacki #endif /* TRUSTED_BOARD_BOOT */
41301d27d9SRadoslaw Biernacki 
42301d27d9SRadoslaw Biernacki 
43301d27d9SRadoslaw Biernacki 
44301d27d9SRadoslaw Biernacki /* IO devices */
45301d27d9SRadoslaw Biernacki static const io_dev_connector_t *fip_dev_con;
46301d27d9SRadoslaw Biernacki static uintptr_t fip_dev_handle;
47301d27d9SRadoslaw Biernacki static const io_dev_connector_t *memmap_dev_con;
48301d27d9SRadoslaw Biernacki static uintptr_t memmap_dev_handle;
49301d27d9SRadoslaw Biernacki static const io_dev_connector_t *sh_dev_con;
50301d27d9SRadoslaw Biernacki static uintptr_t sh_dev_handle;
51*51857762SSumit Garg #ifndef DECRYPTION_SUPPORT_none
52*51857762SSumit Garg static const io_dev_connector_t *enc_dev_con;
53*51857762SSumit Garg static uintptr_t enc_dev_handle;
54*51857762SSumit Garg #endif
55301d27d9SRadoslaw Biernacki 
56301d27d9SRadoslaw Biernacki static const io_block_spec_t fip_block_spec = {
57301d27d9SRadoslaw Biernacki 	.offset = PLAT_QEMU_FIP_BASE,
58301d27d9SRadoslaw Biernacki 	.length = PLAT_QEMU_FIP_MAX_SIZE
59301d27d9SRadoslaw Biernacki };
60301d27d9SRadoslaw Biernacki 
61301d27d9SRadoslaw Biernacki static const io_uuid_spec_t bl2_uuid_spec = {
62301d27d9SRadoslaw Biernacki 	.uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
63301d27d9SRadoslaw Biernacki };
64301d27d9SRadoslaw Biernacki 
65301d27d9SRadoslaw Biernacki static const io_uuid_spec_t bl31_uuid_spec = {
66301d27d9SRadoslaw Biernacki 	.uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
67301d27d9SRadoslaw Biernacki };
68301d27d9SRadoslaw Biernacki 
69301d27d9SRadoslaw Biernacki static const io_uuid_spec_t bl32_uuid_spec = {
70301d27d9SRadoslaw Biernacki 	.uuid = UUID_SECURE_PAYLOAD_BL32,
71301d27d9SRadoslaw Biernacki };
72301d27d9SRadoslaw Biernacki 
73301d27d9SRadoslaw Biernacki static const io_uuid_spec_t bl32_extra1_uuid_spec = {
74301d27d9SRadoslaw Biernacki 	.uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1,
75301d27d9SRadoslaw Biernacki };
76301d27d9SRadoslaw Biernacki 
77301d27d9SRadoslaw Biernacki static const io_uuid_spec_t bl32_extra2_uuid_spec = {
78301d27d9SRadoslaw Biernacki 	.uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2,
79301d27d9SRadoslaw Biernacki };
80301d27d9SRadoslaw Biernacki 
81301d27d9SRadoslaw Biernacki static const io_uuid_spec_t bl33_uuid_spec = {
82301d27d9SRadoslaw Biernacki 	.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
83301d27d9SRadoslaw Biernacki };
84301d27d9SRadoslaw Biernacki 
85301d27d9SRadoslaw Biernacki #if TRUSTED_BOARD_BOOT
86301d27d9SRadoslaw Biernacki static const io_uuid_spec_t tb_fw_cert_uuid_spec = {
87301d27d9SRadoslaw Biernacki 	.uuid = UUID_TRUSTED_BOOT_FW_CERT,
88301d27d9SRadoslaw Biernacki };
89301d27d9SRadoslaw Biernacki 
90301d27d9SRadoslaw Biernacki static const io_uuid_spec_t trusted_key_cert_uuid_spec = {
91301d27d9SRadoslaw Biernacki 	.uuid = UUID_TRUSTED_KEY_CERT,
92301d27d9SRadoslaw Biernacki };
93301d27d9SRadoslaw Biernacki 
94301d27d9SRadoslaw Biernacki static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = {
95301d27d9SRadoslaw Biernacki 	.uuid = UUID_SOC_FW_KEY_CERT,
96301d27d9SRadoslaw Biernacki };
97301d27d9SRadoslaw Biernacki 
98301d27d9SRadoslaw Biernacki static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = {
99301d27d9SRadoslaw Biernacki 	.uuid = UUID_TRUSTED_OS_FW_KEY_CERT,
100301d27d9SRadoslaw Biernacki };
101301d27d9SRadoslaw Biernacki 
102301d27d9SRadoslaw Biernacki static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = {
103301d27d9SRadoslaw Biernacki 	.uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
104301d27d9SRadoslaw Biernacki };
105301d27d9SRadoslaw Biernacki 
106301d27d9SRadoslaw Biernacki static const io_uuid_spec_t soc_fw_cert_uuid_spec = {
107301d27d9SRadoslaw Biernacki 	.uuid = UUID_SOC_FW_CONTENT_CERT,
108301d27d9SRadoslaw Biernacki };
109301d27d9SRadoslaw Biernacki 
110301d27d9SRadoslaw Biernacki static const io_uuid_spec_t tos_fw_cert_uuid_spec = {
111301d27d9SRadoslaw Biernacki 	.uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT,
112301d27d9SRadoslaw Biernacki };
113301d27d9SRadoslaw Biernacki 
114301d27d9SRadoslaw Biernacki static const io_uuid_spec_t nt_fw_cert_uuid_spec = {
115301d27d9SRadoslaw Biernacki 	.uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT,
116301d27d9SRadoslaw Biernacki };
117301d27d9SRadoslaw Biernacki #endif /* TRUSTED_BOARD_BOOT */
118301d27d9SRadoslaw Biernacki 
119301d27d9SRadoslaw Biernacki static const io_file_spec_t sh_file_spec[] = {
120301d27d9SRadoslaw Biernacki 	[BL2_IMAGE_ID] = {
121301d27d9SRadoslaw Biernacki 		.path = BL2_IMAGE_NAME,
122301d27d9SRadoslaw Biernacki 		.mode = FOPEN_MODE_RB
123301d27d9SRadoslaw Biernacki 	},
124301d27d9SRadoslaw Biernacki 	[BL31_IMAGE_ID] = {
125301d27d9SRadoslaw Biernacki 		.path = BL31_IMAGE_NAME,
126301d27d9SRadoslaw Biernacki 		.mode = FOPEN_MODE_RB
127301d27d9SRadoslaw Biernacki 	},
128301d27d9SRadoslaw Biernacki 	[BL32_IMAGE_ID] = {
129301d27d9SRadoslaw Biernacki 		.path = BL32_IMAGE_NAME,
130301d27d9SRadoslaw Biernacki 		.mode = FOPEN_MODE_RB
131301d27d9SRadoslaw Biernacki 	},
132301d27d9SRadoslaw Biernacki 	[BL32_EXTRA1_IMAGE_ID] = {
133301d27d9SRadoslaw Biernacki 		.path = BL32_EXTRA1_IMAGE_NAME,
134301d27d9SRadoslaw Biernacki 		.mode = FOPEN_MODE_RB
135301d27d9SRadoslaw Biernacki 	},
136301d27d9SRadoslaw Biernacki 	[BL32_EXTRA2_IMAGE_ID] = {
137301d27d9SRadoslaw Biernacki 		.path = BL32_EXTRA2_IMAGE_NAME,
138301d27d9SRadoslaw Biernacki 		.mode = FOPEN_MODE_RB
139301d27d9SRadoslaw Biernacki 	},
140301d27d9SRadoslaw Biernacki 	[BL33_IMAGE_ID] = {
141301d27d9SRadoslaw Biernacki 		.path = BL33_IMAGE_NAME,
142301d27d9SRadoslaw Biernacki 		.mode = FOPEN_MODE_RB
143301d27d9SRadoslaw Biernacki 	},
144301d27d9SRadoslaw Biernacki #if TRUSTED_BOARD_BOOT
145301d27d9SRadoslaw Biernacki 	[TRUSTED_BOOT_FW_CERT_ID] = {
146301d27d9SRadoslaw Biernacki 		.path = TRUSTED_BOOT_FW_CERT_NAME,
147301d27d9SRadoslaw Biernacki 		.mode = FOPEN_MODE_RB
148301d27d9SRadoslaw Biernacki 	},
149301d27d9SRadoslaw Biernacki 	[TRUSTED_KEY_CERT_ID] = {
150301d27d9SRadoslaw Biernacki 		.path = TRUSTED_KEY_CERT_NAME,
151301d27d9SRadoslaw Biernacki 		.mode = FOPEN_MODE_RB
152301d27d9SRadoslaw Biernacki 	},
153301d27d9SRadoslaw Biernacki 	[SOC_FW_KEY_CERT_ID] = {
154301d27d9SRadoslaw Biernacki 		.path = SOC_FW_KEY_CERT_NAME,
155301d27d9SRadoslaw Biernacki 		.mode = FOPEN_MODE_RB
156301d27d9SRadoslaw Biernacki 	},
157301d27d9SRadoslaw Biernacki 	[TRUSTED_OS_FW_KEY_CERT_ID] = {
158301d27d9SRadoslaw Biernacki 		.path = TOS_FW_KEY_CERT_NAME,
159301d27d9SRadoslaw Biernacki 		.mode = FOPEN_MODE_RB
160301d27d9SRadoslaw Biernacki 	},
161301d27d9SRadoslaw Biernacki 	[NON_TRUSTED_FW_KEY_CERT_ID] = {
162301d27d9SRadoslaw Biernacki 		.path = NT_FW_KEY_CERT_NAME,
163301d27d9SRadoslaw Biernacki 		.mode = FOPEN_MODE_RB
164301d27d9SRadoslaw Biernacki 	},
165301d27d9SRadoslaw Biernacki 	[SOC_FW_CONTENT_CERT_ID] = {
166301d27d9SRadoslaw Biernacki 		.path = SOC_FW_CONTENT_CERT_NAME,
167301d27d9SRadoslaw Biernacki 		.mode = FOPEN_MODE_RB
168301d27d9SRadoslaw Biernacki 	},
169301d27d9SRadoslaw Biernacki 	[TRUSTED_OS_FW_CONTENT_CERT_ID] = {
170301d27d9SRadoslaw Biernacki 		.path = TOS_FW_CONTENT_CERT_NAME,
171301d27d9SRadoslaw Biernacki 		.mode = FOPEN_MODE_RB
172301d27d9SRadoslaw Biernacki 	},
173301d27d9SRadoslaw Biernacki 	[NON_TRUSTED_FW_CONTENT_CERT_ID] = {
174301d27d9SRadoslaw Biernacki 		.path = NT_FW_CONTENT_CERT_NAME,
175301d27d9SRadoslaw Biernacki 		.mode = FOPEN_MODE_RB
176301d27d9SRadoslaw Biernacki 	},
177301d27d9SRadoslaw Biernacki #endif /* TRUSTED_BOARD_BOOT */
178301d27d9SRadoslaw Biernacki };
179301d27d9SRadoslaw Biernacki 
180301d27d9SRadoslaw Biernacki static int open_fip(const uintptr_t spec);
181301d27d9SRadoslaw Biernacki static int open_memmap(const uintptr_t spec);
182*51857762SSumit Garg #ifndef DECRYPTION_SUPPORT_none
183*51857762SSumit Garg static int open_enc_fip(const uintptr_t spec);
184*51857762SSumit Garg #endif
185301d27d9SRadoslaw Biernacki 
186301d27d9SRadoslaw Biernacki struct plat_io_policy {
187301d27d9SRadoslaw Biernacki 	uintptr_t *dev_handle;
188301d27d9SRadoslaw Biernacki 	uintptr_t image_spec;
189301d27d9SRadoslaw Biernacki 	int (*check)(const uintptr_t spec);
190301d27d9SRadoslaw Biernacki };
191301d27d9SRadoslaw Biernacki 
192301d27d9SRadoslaw Biernacki /* By default, ARM platforms load images from the FIP */
193301d27d9SRadoslaw Biernacki static const struct plat_io_policy policies[] = {
194301d27d9SRadoslaw Biernacki 	[FIP_IMAGE_ID] = {
195301d27d9SRadoslaw Biernacki 		&memmap_dev_handle,
196301d27d9SRadoslaw Biernacki 		(uintptr_t)&fip_block_spec,
197301d27d9SRadoslaw Biernacki 		open_memmap
198301d27d9SRadoslaw Biernacki 	},
199*51857762SSumit Garg 	[ENC_IMAGE_ID] = {
200*51857762SSumit Garg 		&fip_dev_handle,
201*51857762SSumit Garg 		(uintptr_t)NULL,
202*51857762SSumit Garg 		open_fip
203*51857762SSumit Garg 	},
204301d27d9SRadoslaw Biernacki 	[BL2_IMAGE_ID] = {
205301d27d9SRadoslaw Biernacki 		&fip_dev_handle,
206301d27d9SRadoslaw Biernacki 		(uintptr_t)&bl2_uuid_spec,
207301d27d9SRadoslaw Biernacki 		open_fip
208301d27d9SRadoslaw Biernacki 	},
209*51857762SSumit Garg #if ENCRYPT_BL31 && !defined(DECRYPTION_SUPPORT_none)
210*51857762SSumit Garg 	[BL31_IMAGE_ID] = {
211*51857762SSumit Garg 		&enc_dev_handle,
212*51857762SSumit Garg 		(uintptr_t)&bl31_uuid_spec,
213*51857762SSumit Garg 		open_enc_fip
214*51857762SSumit Garg 	},
215*51857762SSumit Garg #else
216301d27d9SRadoslaw Biernacki 	[BL31_IMAGE_ID] = {
217301d27d9SRadoslaw Biernacki 		&fip_dev_handle,
218301d27d9SRadoslaw Biernacki 		(uintptr_t)&bl31_uuid_spec,
219301d27d9SRadoslaw Biernacki 		open_fip
220301d27d9SRadoslaw Biernacki 	},
221*51857762SSumit Garg #endif
222*51857762SSumit Garg #if ENCRYPT_BL32 && !defined(DECRYPTION_SUPPORT_none)
223*51857762SSumit Garg 	[BL32_IMAGE_ID] = {
224*51857762SSumit Garg 		&enc_dev_handle,
225*51857762SSumit Garg 		(uintptr_t)&bl32_uuid_spec,
226*51857762SSumit Garg 		open_enc_fip
227*51857762SSumit Garg 	},
228*51857762SSumit Garg 	[BL32_EXTRA1_IMAGE_ID] = {
229*51857762SSumit Garg 		&enc_dev_handle,
230*51857762SSumit Garg 		(uintptr_t)&bl32_extra1_uuid_spec,
231*51857762SSumit Garg 		open_enc_fip
232*51857762SSumit Garg 	},
233*51857762SSumit Garg 	[BL32_EXTRA2_IMAGE_ID] = {
234*51857762SSumit Garg 		&enc_dev_handle,
235*51857762SSumit Garg 		(uintptr_t)&bl32_extra2_uuid_spec,
236*51857762SSumit Garg 		open_enc_fip
237*51857762SSumit Garg 	},
238*51857762SSumit Garg #else
239301d27d9SRadoslaw Biernacki 	[BL32_IMAGE_ID] = {
240301d27d9SRadoslaw Biernacki 		&fip_dev_handle,
241301d27d9SRadoslaw Biernacki 		(uintptr_t)&bl32_uuid_spec,
242301d27d9SRadoslaw Biernacki 		open_fip
243301d27d9SRadoslaw Biernacki 	},
244301d27d9SRadoslaw Biernacki 	[BL32_EXTRA1_IMAGE_ID] = {
245301d27d9SRadoslaw Biernacki 		&fip_dev_handle,
246301d27d9SRadoslaw Biernacki 		(uintptr_t)&bl32_extra1_uuid_spec,
247301d27d9SRadoslaw Biernacki 		open_fip
248301d27d9SRadoslaw Biernacki 	},
249301d27d9SRadoslaw Biernacki 	[BL32_EXTRA2_IMAGE_ID] = {
250301d27d9SRadoslaw Biernacki 		&fip_dev_handle,
251301d27d9SRadoslaw Biernacki 		(uintptr_t)&bl32_extra2_uuid_spec,
252301d27d9SRadoslaw Biernacki 		open_fip
253301d27d9SRadoslaw Biernacki 	},
254*51857762SSumit Garg #endif
255301d27d9SRadoslaw Biernacki 	[BL33_IMAGE_ID] = {
256301d27d9SRadoslaw Biernacki 		&fip_dev_handle,
257301d27d9SRadoslaw Biernacki 		(uintptr_t)&bl33_uuid_spec,
258301d27d9SRadoslaw Biernacki 		open_fip
259301d27d9SRadoslaw Biernacki 	},
260301d27d9SRadoslaw Biernacki #if TRUSTED_BOARD_BOOT
261301d27d9SRadoslaw Biernacki 	[TRUSTED_BOOT_FW_CERT_ID] = {
262301d27d9SRadoslaw Biernacki 		&fip_dev_handle,
263301d27d9SRadoslaw Biernacki 		(uintptr_t)&tb_fw_cert_uuid_spec,
264301d27d9SRadoslaw Biernacki 		open_fip
265301d27d9SRadoslaw Biernacki 	},
266301d27d9SRadoslaw Biernacki 	[TRUSTED_KEY_CERT_ID] = {
267301d27d9SRadoslaw Biernacki 		&fip_dev_handle,
268301d27d9SRadoslaw Biernacki 		(uintptr_t)&trusted_key_cert_uuid_spec,
269301d27d9SRadoslaw Biernacki 		open_fip
270301d27d9SRadoslaw Biernacki 	},
271301d27d9SRadoslaw Biernacki 	[SOC_FW_KEY_CERT_ID] = {
272301d27d9SRadoslaw Biernacki 		&fip_dev_handle,
273301d27d9SRadoslaw Biernacki 		(uintptr_t)&soc_fw_key_cert_uuid_spec,
274301d27d9SRadoslaw Biernacki 		open_fip
275301d27d9SRadoslaw Biernacki 	},
276301d27d9SRadoslaw Biernacki 	[TRUSTED_OS_FW_KEY_CERT_ID] = {
277301d27d9SRadoslaw Biernacki 		&fip_dev_handle,
278301d27d9SRadoslaw Biernacki 		(uintptr_t)&tos_fw_key_cert_uuid_spec,
279301d27d9SRadoslaw Biernacki 		open_fip
280301d27d9SRadoslaw Biernacki 	},
281301d27d9SRadoslaw Biernacki 	[NON_TRUSTED_FW_KEY_CERT_ID] = {
282301d27d9SRadoslaw Biernacki 		&fip_dev_handle,
283301d27d9SRadoslaw Biernacki 		(uintptr_t)&nt_fw_key_cert_uuid_spec,
284301d27d9SRadoslaw Biernacki 		open_fip
285301d27d9SRadoslaw Biernacki 	},
286301d27d9SRadoslaw Biernacki 	[SOC_FW_CONTENT_CERT_ID] = {
287301d27d9SRadoslaw Biernacki 		&fip_dev_handle,
288301d27d9SRadoslaw Biernacki 		(uintptr_t)&soc_fw_cert_uuid_spec,
289301d27d9SRadoslaw Biernacki 		open_fip
290301d27d9SRadoslaw Biernacki 	},
291301d27d9SRadoslaw Biernacki 	[TRUSTED_OS_FW_CONTENT_CERT_ID] = {
292301d27d9SRadoslaw Biernacki 		&fip_dev_handle,
293301d27d9SRadoslaw Biernacki 		(uintptr_t)&tos_fw_cert_uuid_spec,
294301d27d9SRadoslaw Biernacki 		open_fip
295301d27d9SRadoslaw Biernacki 	},
296301d27d9SRadoslaw Biernacki 	[NON_TRUSTED_FW_CONTENT_CERT_ID] = {
297301d27d9SRadoslaw Biernacki 		&fip_dev_handle,
298301d27d9SRadoslaw Biernacki 		(uintptr_t)&nt_fw_cert_uuid_spec,
299301d27d9SRadoslaw Biernacki 		open_fip
300301d27d9SRadoslaw Biernacki 	},
301301d27d9SRadoslaw Biernacki #endif /* TRUSTED_BOARD_BOOT */
302301d27d9SRadoslaw Biernacki };
303301d27d9SRadoslaw Biernacki 
304301d27d9SRadoslaw Biernacki static int open_fip(const uintptr_t spec)
305301d27d9SRadoslaw Biernacki {
306301d27d9SRadoslaw Biernacki 	int result;
307301d27d9SRadoslaw Biernacki 	uintptr_t local_image_handle;
308301d27d9SRadoslaw Biernacki 
309301d27d9SRadoslaw Biernacki 	/* See if a Firmware Image Package is available */
310301d27d9SRadoslaw Biernacki 	result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
311*51857762SSumit Garg 	if (result == 0 && spec != (uintptr_t)NULL) {
312301d27d9SRadoslaw Biernacki 		result = io_open(fip_dev_handle, spec, &local_image_handle);
313301d27d9SRadoslaw Biernacki 		if (result == 0) {
314301d27d9SRadoslaw Biernacki 			VERBOSE("Using FIP\n");
315301d27d9SRadoslaw Biernacki 			io_close(local_image_handle);
316301d27d9SRadoslaw Biernacki 		}
317301d27d9SRadoslaw Biernacki 	}
318301d27d9SRadoslaw Biernacki 	return result;
319301d27d9SRadoslaw Biernacki }
320301d27d9SRadoslaw Biernacki 
321*51857762SSumit Garg #ifndef DECRYPTION_SUPPORT_none
322*51857762SSumit Garg static int open_enc_fip(const uintptr_t spec)
323*51857762SSumit Garg {
324*51857762SSumit Garg 	int result;
325*51857762SSumit Garg 	uintptr_t local_image_handle;
326*51857762SSumit Garg 
327*51857762SSumit Garg 	/* See if an encrypted FIP is available */
328*51857762SSumit Garg 	result = io_dev_init(enc_dev_handle, (uintptr_t)ENC_IMAGE_ID);
329*51857762SSumit Garg 	if (result == 0) {
330*51857762SSumit Garg 		result = io_open(enc_dev_handle, spec, &local_image_handle);
331*51857762SSumit Garg 		if (result == 0) {
332*51857762SSumit Garg 			VERBOSE("Using encrypted FIP\n");
333*51857762SSumit Garg 			io_close(local_image_handle);
334*51857762SSumit Garg 		}
335*51857762SSumit Garg 	}
336*51857762SSumit Garg 	return result;
337*51857762SSumit Garg }
338*51857762SSumit Garg #endif
339*51857762SSumit Garg 
340301d27d9SRadoslaw Biernacki static int open_memmap(const uintptr_t spec)
341301d27d9SRadoslaw Biernacki {
342301d27d9SRadoslaw Biernacki 	int result;
343301d27d9SRadoslaw Biernacki 	uintptr_t local_image_handle;
344301d27d9SRadoslaw Biernacki 
345301d27d9SRadoslaw Biernacki 	result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL);
346301d27d9SRadoslaw Biernacki 	if (result == 0) {
347301d27d9SRadoslaw Biernacki 		result = io_open(memmap_dev_handle, spec, &local_image_handle);
348301d27d9SRadoslaw Biernacki 		if (result == 0) {
349301d27d9SRadoslaw Biernacki 			VERBOSE("Using Memmap\n");
350301d27d9SRadoslaw Biernacki 			io_close(local_image_handle);
351301d27d9SRadoslaw Biernacki 		}
352301d27d9SRadoslaw Biernacki 	}
353301d27d9SRadoslaw Biernacki 	return result;
354301d27d9SRadoslaw Biernacki }
355301d27d9SRadoslaw Biernacki 
356301d27d9SRadoslaw Biernacki static int open_semihosting(const uintptr_t spec)
357301d27d9SRadoslaw Biernacki {
358301d27d9SRadoslaw Biernacki 	int result;
359301d27d9SRadoslaw Biernacki 	uintptr_t local_image_handle;
360301d27d9SRadoslaw Biernacki 
361301d27d9SRadoslaw Biernacki 	/* See if the file exists on semi-hosting.*/
362301d27d9SRadoslaw Biernacki 	result = io_dev_init(sh_dev_handle, (uintptr_t)NULL);
363301d27d9SRadoslaw Biernacki 	if (result == 0) {
364301d27d9SRadoslaw Biernacki 		result = io_open(sh_dev_handle, spec, &local_image_handle);
365301d27d9SRadoslaw Biernacki 		if (result == 0) {
366301d27d9SRadoslaw Biernacki 			VERBOSE("Using Semi-hosting IO\n");
367301d27d9SRadoslaw Biernacki 			io_close(local_image_handle);
368301d27d9SRadoslaw Biernacki 		}
369301d27d9SRadoslaw Biernacki 	}
370301d27d9SRadoslaw Biernacki 	return result;
371301d27d9SRadoslaw Biernacki }
372301d27d9SRadoslaw Biernacki 
373301d27d9SRadoslaw Biernacki void plat_qemu_io_setup(void)
374301d27d9SRadoslaw Biernacki {
375301d27d9SRadoslaw Biernacki 	int io_result;
376301d27d9SRadoslaw Biernacki 
377301d27d9SRadoslaw Biernacki 	io_result = register_io_dev_fip(&fip_dev_con);
378301d27d9SRadoslaw Biernacki 	assert(io_result == 0);
379301d27d9SRadoslaw Biernacki 
380301d27d9SRadoslaw Biernacki 	io_result = register_io_dev_memmap(&memmap_dev_con);
381301d27d9SRadoslaw Biernacki 	assert(io_result == 0);
382301d27d9SRadoslaw Biernacki 
383301d27d9SRadoslaw Biernacki 	/* Open connections to devices and cache the handles */
384301d27d9SRadoslaw Biernacki 	io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL,
385301d27d9SRadoslaw Biernacki 				&fip_dev_handle);
386301d27d9SRadoslaw Biernacki 	assert(io_result == 0);
387301d27d9SRadoslaw Biernacki 
388301d27d9SRadoslaw Biernacki 	io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL,
389301d27d9SRadoslaw Biernacki 				&memmap_dev_handle);
390301d27d9SRadoslaw Biernacki 	assert(io_result == 0);
391301d27d9SRadoslaw Biernacki 
392*51857762SSumit Garg #ifndef DECRYPTION_SUPPORT_none
393*51857762SSumit Garg 	io_result = register_io_dev_enc(&enc_dev_con);
394*51857762SSumit Garg 	assert(io_result == 0);
395*51857762SSumit Garg 
396*51857762SSumit Garg 	io_result = io_dev_open(enc_dev_con, (uintptr_t)NULL,
397*51857762SSumit Garg 				&enc_dev_handle);
398*51857762SSumit Garg 	assert(io_result == 0);
399*51857762SSumit Garg #endif
400*51857762SSumit Garg 
401301d27d9SRadoslaw Biernacki 	/* Register the additional IO devices on this platform */
402301d27d9SRadoslaw Biernacki 	io_result = register_io_dev_sh(&sh_dev_con);
403301d27d9SRadoslaw Biernacki 	assert(io_result == 0);
404301d27d9SRadoslaw Biernacki 
405301d27d9SRadoslaw Biernacki 	/* Open connections to devices and cache the handles */
406301d27d9SRadoslaw Biernacki 	io_result = io_dev_open(sh_dev_con, (uintptr_t)NULL, &sh_dev_handle);
407301d27d9SRadoslaw Biernacki 	assert(io_result == 0);
408301d27d9SRadoslaw Biernacki 
409301d27d9SRadoslaw Biernacki 	/* Ignore improbable errors in release builds */
410301d27d9SRadoslaw Biernacki 	(void)io_result;
411301d27d9SRadoslaw Biernacki }
412301d27d9SRadoslaw Biernacki 
413301d27d9SRadoslaw Biernacki static int get_alt_image_source(unsigned int image_id, uintptr_t *dev_handle,
414301d27d9SRadoslaw Biernacki 				  uintptr_t *image_spec)
415301d27d9SRadoslaw Biernacki {
416301d27d9SRadoslaw Biernacki 	int result = open_semihosting((const uintptr_t)&sh_file_spec[image_id]);
417301d27d9SRadoslaw Biernacki 
418301d27d9SRadoslaw Biernacki 	if (result == 0) {
419301d27d9SRadoslaw Biernacki 		*dev_handle = sh_dev_handle;
420301d27d9SRadoslaw Biernacki 		*image_spec = (uintptr_t)&sh_file_spec[image_id];
421301d27d9SRadoslaw Biernacki 	}
422301d27d9SRadoslaw Biernacki 
423301d27d9SRadoslaw Biernacki 	return result;
424301d27d9SRadoslaw Biernacki }
425301d27d9SRadoslaw Biernacki 
426301d27d9SRadoslaw Biernacki /*
427301d27d9SRadoslaw Biernacki  * Return an IO device handle and specification which can be used to access
428301d27d9SRadoslaw Biernacki  * an image. Use this to enforce platform load policy
429301d27d9SRadoslaw Biernacki  */
430301d27d9SRadoslaw Biernacki int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
431301d27d9SRadoslaw Biernacki 			  uintptr_t *image_spec)
432301d27d9SRadoslaw Biernacki {
433301d27d9SRadoslaw Biernacki 	int result;
434301d27d9SRadoslaw Biernacki 	const struct plat_io_policy *policy;
435301d27d9SRadoslaw Biernacki 
436301d27d9SRadoslaw Biernacki 	assert(image_id < ARRAY_SIZE(policies));
437301d27d9SRadoslaw Biernacki 
438301d27d9SRadoslaw Biernacki 	policy = &policies[image_id];
439301d27d9SRadoslaw Biernacki 	result = policy->check(policy->image_spec);
440301d27d9SRadoslaw Biernacki 	if (result == 0) {
441301d27d9SRadoslaw Biernacki 		*image_spec = policy->image_spec;
442301d27d9SRadoslaw Biernacki 		*dev_handle = *(policy->dev_handle);
443301d27d9SRadoslaw Biernacki 	} else {
444301d27d9SRadoslaw Biernacki 		VERBOSE("Trying alternative IO\n");
445301d27d9SRadoslaw Biernacki 		result = get_alt_image_source(image_id, dev_handle, image_spec);
446301d27d9SRadoslaw Biernacki 	}
447301d27d9SRadoslaw Biernacki 
448301d27d9SRadoslaw Biernacki 	return result;
449301d27d9SRadoslaw Biernacki }
450