xref: /rk3399_ARM-atf/plat/arm/common/arm_io_storage.c (revision c228956afa415685d7555578f252dfe4d0d1695e)
1b4315306SDan Handley /*
2*c228956aSSoby Mathew  * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
3b4315306SDan Handley  *
482cb2c1aSdp-arm  * SPDX-License-Identifier: BSD-3-Clause
5b4315306SDan Handley  */
6b4315306SDan Handley #include <assert.h>
7b4315306SDan Handley #include <debug.h>
816948ae1SJuan Castillo #include <firmware_image_package.h>
9b4315306SDan Handley #include <io_driver.h>
10b4315306SDan Handley #include <io_fip.h>
11b4315306SDan Handley #include <io_memmap.h>
12b4315306SDan Handley #include <io_storage.h>
13b4315306SDan Handley #include <platform_def.h>
14b4315306SDan Handley #include <string.h>
15ed81f3ebSSandrine Bailleux #include <utils.h>
16b4315306SDan Handley 
17b4315306SDan Handley /* IO devices */
18b4315306SDan Handley static const io_dev_connector_t *fip_dev_con;
19b4315306SDan Handley static uintptr_t fip_dev_handle;
20b4315306SDan Handley static const io_dev_connector_t *memmap_dev_con;
21b4315306SDan Handley static uintptr_t memmap_dev_handle;
22b4315306SDan Handley 
23b4315306SDan Handley static const io_block_spec_t fip_block_spec = {
24b4315306SDan Handley 	.offset = PLAT_ARM_FIP_BASE,
25b4315306SDan Handley 	.length = PLAT_ARM_FIP_MAX_SIZE
26b4315306SDan Handley };
27b4315306SDan Handley 
2816948ae1SJuan Castillo static const io_uuid_spec_t bl2_uuid_spec = {
2916948ae1SJuan Castillo 	.uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
30b4315306SDan Handley };
31b4315306SDan Handley 
32f59821d5SJuan Castillo static const io_uuid_spec_t scp_bl2_uuid_spec = {
33f59821d5SJuan Castillo 	.uuid = UUID_SCP_FIRMWARE_SCP_BL2,
34b4315306SDan Handley };
35b4315306SDan Handley 
3616948ae1SJuan Castillo static const io_uuid_spec_t bl31_uuid_spec = {
3716948ae1SJuan Castillo 	.uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
38b4315306SDan Handley };
39b4315306SDan Handley 
4016948ae1SJuan Castillo static const io_uuid_spec_t bl32_uuid_spec = {
4116948ae1SJuan Castillo 	.uuid = UUID_SECURE_PAYLOAD_BL32,
42b4315306SDan Handley };
43b4315306SDan Handley 
4471fb3964SSummer Qin static const io_uuid_spec_t bl32_extra1_uuid_spec = {
4571fb3964SSummer Qin 	.uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1,
4671fb3964SSummer Qin };
4771fb3964SSummer Qin 
4871fb3964SSummer Qin static const io_uuid_spec_t bl32_extra2_uuid_spec = {
4971fb3964SSummer Qin 	.uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2,
5071fb3964SSummer Qin };
5171fb3964SSummer Qin 
5216948ae1SJuan Castillo static const io_uuid_spec_t bl33_uuid_spec = {
5316948ae1SJuan Castillo 	.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
54b4315306SDan Handley };
55b4315306SDan Handley 
56*c228956aSSoby Mathew static const io_uuid_spec_t tb_fw_config_uuid_spec = {
57*c228956aSSoby Mathew 	.uuid = UUID_TB_FW_CONFIG,
58*c228956aSSoby Mathew };
59*c228956aSSoby Mathew 
60b4315306SDan Handley #if TRUSTED_BOARD_BOOT
61516beb58SJuan Castillo static const io_uuid_spec_t tb_fw_cert_uuid_spec = {
62516beb58SJuan Castillo 	.uuid = UUID_TRUSTED_BOOT_FW_CERT,
63b4315306SDan Handley };
64b4315306SDan Handley 
6516948ae1SJuan Castillo static const io_uuid_spec_t trusted_key_cert_uuid_spec = {
6616948ae1SJuan Castillo 	.uuid = UUID_TRUSTED_KEY_CERT,
67b4315306SDan Handley };
68b4315306SDan Handley 
69516beb58SJuan Castillo static const io_uuid_spec_t scp_fw_key_cert_uuid_spec = {
70516beb58SJuan Castillo 	.uuid = UUID_SCP_FW_KEY_CERT,
71b4315306SDan Handley };
72b4315306SDan Handley 
73516beb58SJuan Castillo static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = {
74516beb58SJuan Castillo 	.uuid = UUID_SOC_FW_KEY_CERT,
75b4315306SDan Handley };
76b4315306SDan Handley 
77516beb58SJuan Castillo static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = {
78516beb58SJuan Castillo 	.uuid = UUID_TRUSTED_OS_FW_KEY_CERT,
79b4315306SDan Handley };
80b4315306SDan Handley 
81516beb58SJuan Castillo static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = {
82516beb58SJuan Castillo 	.uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
83b4315306SDan Handley };
84b4315306SDan Handley 
85516beb58SJuan Castillo static const io_uuid_spec_t scp_fw_cert_uuid_spec = {
86516beb58SJuan Castillo 	.uuid = UUID_SCP_FW_CONTENT_CERT,
87b4315306SDan Handley };
88b4315306SDan Handley 
89516beb58SJuan Castillo static const io_uuid_spec_t soc_fw_cert_uuid_spec = {
90516beb58SJuan Castillo 	.uuid = UUID_SOC_FW_CONTENT_CERT,
91b4315306SDan Handley };
92b4315306SDan Handley 
93516beb58SJuan Castillo static const io_uuid_spec_t tos_fw_cert_uuid_spec = {
94516beb58SJuan Castillo 	.uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT,
95b4315306SDan Handley };
96b4315306SDan Handley 
97516beb58SJuan Castillo static const io_uuid_spec_t nt_fw_cert_uuid_spec = {
98516beb58SJuan Castillo 	.uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT,
99b4315306SDan Handley };
100b4315306SDan Handley #endif /* TRUSTED_BOARD_BOOT */
101b4315306SDan Handley 
10216948ae1SJuan Castillo 
103b4315306SDan Handley static int open_fip(const uintptr_t spec);
104b4315306SDan Handley static int open_memmap(const uintptr_t spec);
105b4315306SDan Handley 
106b4315306SDan Handley struct plat_io_policy {
107b4315306SDan Handley 	uintptr_t *dev_handle;
108b4315306SDan Handley 	uintptr_t image_spec;
109b4315306SDan Handley 	int (*check)(const uintptr_t spec);
110b4315306SDan Handley };
111b4315306SDan Handley 
11216948ae1SJuan Castillo /* By default, ARM platforms load images from the FIP */
113b4315306SDan Handley static const struct plat_io_policy policies[] = {
11416948ae1SJuan Castillo 	[FIP_IMAGE_ID] = {
115b4315306SDan Handley 		&memmap_dev_handle,
116b4315306SDan Handley 		(uintptr_t)&fip_block_spec,
117b4315306SDan Handley 		open_memmap
11816948ae1SJuan Castillo 	},
11916948ae1SJuan Castillo 	[BL2_IMAGE_ID] = {
120b4315306SDan Handley 		&fip_dev_handle,
12116948ae1SJuan Castillo 		(uintptr_t)&bl2_uuid_spec,
122b4315306SDan Handley 		open_fip
12316948ae1SJuan Castillo 	},
124f59821d5SJuan Castillo 	[SCP_BL2_IMAGE_ID] = {
125b4315306SDan Handley 		&fip_dev_handle,
126f59821d5SJuan Castillo 		(uintptr_t)&scp_bl2_uuid_spec,
127b4315306SDan Handley 		open_fip
12816948ae1SJuan Castillo 	},
12916948ae1SJuan Castillo 	[BL31_IMAGE_ID] = {
130b4315306SDan Handley 		&fip_dev_handle,
13116948ae1SJuan Castillo 		(uintptr_t)&bl31_uuid_spec,
132b4315306SDan Handley 		open_fip
13316948ae1SJuan Castillo 	},
13416948ae1SJuan Castillo 	[BL32_IMAGE_ID] = {
135b4315306SDan Handley 		&fip_dev_handle,
13616948ae1SJuan Castillo 		(uintptr_t)&bl32_uuid_spec,
137b4315306SDan Handley 		open_fip
13816948ae1SJuan Castillo 	},
13971fb3964SSummer Qin 	[BL32_EXTRA1_IMAGE_ID] = {
14071fb3964SSummer Qin 		&fip_dev_handle,
14171fb3964SSummer Qin 		(uintptr_t)&bl32_extra1_uuid_spec,
14271fb3964SSummer Qin 		open_fip
14371fb3964SSummer Qin 	},
14471fb3964SSummer Qin 	[BL32_EXTRA2_IMAGE_ID] = {
14571fb3964SSummer Qin 		&fip_dev_handle,
14671fb3964SSummer Qin 		(uintptr_t)&bl32_extra2_uuid_spec,
14771fb3964SSummer Qin 		open_fip
14871fb3964SSummer Qin 	},
14916948ae1SJuan Castillo 	[BL33_IMAGE_ID] = {
150b4315306SDan Handley 		&fip_dev_handle,
15116948ae1SJuan Castillo 		(uintptr_t)&bl33_uuid_spec,
152b4315306SDan Handley 		open_fip
15316948ae1SJuan Castillo 	},
154*c228956aSSoby Mathew 	[TB_FW_CONFIG_ID] = {
155*c228956aSSoby Mathew 		&fip_dev_handle,
156*c228956aSSoby Mathew 		(uintptr_t)&tb_fw_config_uuid_spec,
157*c228956aSSoby Mathew 		open_fip
158*c228956aSSoby Mathew 	},
159b4315306SDan Handley #if TRUSTED_BOARD_BOOT
160516beb58SJuan Castillo 	[TRUSTED_BOOT_FW_CERT_ID] = {
161b4315306SDan Handley 		&fip_dev_handle,
162516beb58SJuan Castillo 		(uintptr_t)&tb_fw_cert_uuid_spec,
163b4315306SDan Handley 		open_fip
16416948ae1SJuan Castillo 	},
16516948ae1SJuan Castillo 	[TRUSTED_KEY_CERT_ID] = {
166b4315306SDan Handley 		&fip_dev_handle,
16716948ae1SJuan Castillo 		(uintptr_t)&trusted_key_cert_uuid_spec,
168b4315306SDan Handley 		open_fip
16916948ae1SJuan Castillo 	},
170516beb58SJuan Castillo 	[SCP_FW_KEY_CERT_ID] = {
171b4315306SDan Handley 		&fip_dev_handle,
172516beb58SJuan Castillo 		(uintptr_t)&scp_fw_key_cert_uuid_spec,
173b4315306SDan Handley 		open_fip
17416948ae1SJuan Castillo 	},
175516beb58SJuan Castillo 	[SOC_FW_KEY_CERT_ID] = {
176b4315306SDan Handley 		&fip_dev_handle,
177516beb58SJuan Castillo 		(uintptr_t)&soc_fw_key_cert_uuid_spec,
178b4315306SDan Handley 		open_fip
17916948ae1SJuan Castillo 	},
180516beb58SJuan Castillo 	[TRUSTED_OS_FW_KEY_CERT_ID] = {
181b4315306SDan Handley 		&fip_dev_handle,
182516beb58SJuan Castillo 		(uintptr_t)&tos_fw_key_cert_uuid_spec,
183b4315306SDan Handley 		open_fip
18416948ae1SJuan Castillo 	},
185516beb58SJuan Castillo 	[NON_TRUSTED_FW_KEY_CERT_ID] = {
186b4315306SDan Handley 		&fip_dev_handle,
187516beb58SJuan Castillo 		(uintptr_t)&nt_fw_key_cert_uuid_spec,
188b4315306SDan Handley 		open_fip
18916948ae1SJuan Castillo 	},
190516beb58SJuan Castillo 	[SCP_FW_CONTENT_CERT_ID] = {
191b4315306SDan Handley 		&fip_dev_handle,
192516beb58SJuan Castillo 		(uintptr_t)&scp_fw_cert_uuid_spec,
193b4315306SDan Handley 		open_fip
19416948ae1SJuan Castillo 	},
195516beb58SJuan Castillo 	[SOC_FW_CONTENT_CERT_ID] = {
196b4315306SDan Handley 		&fip_dev_handle,
197516beb58SJuan Castillo 		(uintptr_t)&soc_fw_cert_uuid_spec,
198b4315306SDan Handley 		open_fip
19916948ae1SJuan Castillo 	},
200516beb58SJuan Castillo 	[TRUSTED_OS_FW_CONTENT_CERT_ID] = {
201b4315306SDan Handley 		&fip_dev_handle,
202516beb58SJuan Castillo 		(uintptr_t)&tos_fw_cert_uuid_spec,
203b4315306SDan Handley 		open_fip
20416948ae1SJuan Castillo 	},
205516beb58SJuan Castillo 	[NON_TRUSTED_FW_CONTENT_CERT_ID] = {
206b4315306SDan Handley 		&fip_dev_handle,
207516beb58SJuan Castillo 		(uintptr_t)&nt_fw_cert_uuid_spec,
208b4315306SDan Handley 		open_fip
20916948ae1SJuan Castillo 	},
210b4315306SDan Handley #endif /* TRUSTED_BOARD_BOOT */
211b4315306SDan Handley };
212b4315306SDan Handley 
213b4315306SDan Handley 
214b4315306SDan Handley /* Weak definitions may be overridden in specific ARM standard platform */
215b4315306SDan Handley #pragma weak plat_arm_io_setup
216b4315306SDan Handley #pragma weak plat_arm_get_alt_image_source
217b4315306SDan Handley 
218b4315306SDan Handley 
219b4315306SDan Handley static int open_fip(const uintptr_t spec)
220b4315306SDan Handley {
221b4315306SDan Handley 	int result;
222b4315306SDan Handley 	uintptr_t local_image_handle;
223b4315306SDan Handley 
224b4315306SDan Handley 	/* See if a Firmware Image Package is available */
22516948ae1SJuan Castillo 	result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
226e098e244SJuan Castillo 	if (result == 0) {
227b4315306SDan Handley 		result = io_open(fip_dev_handle, spec, &local_image_handle);
228e098e244SJuan Castillo 		if (result == 0) {
229b4315306SDan Handley 			VERBOSE("Using FIP\n");
230b4315306SDan Handley 			io_close(local_image_handle);
231b4315306SDan Handley 		}
232b4315306SDan Handley 	}
233b4315306SDan Handley 	return result;
234b4315306SDan Handley }
235b4315306SDan Handley 
236b4315306SDan Handley 
237b4315306SDan Handley static int open_memmap(const uintptr_t spec)
238b4315306SDan Handley {
239b4315306SDan Handley 	int result;
240b4315306SDan Handley 	uintptr_t local_image_handle;
241b4315306SDan Handley 
242b4315306SDan Handley 	result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL);
243e098e244SJuan Castillo 	if (result == 0) {
244b4315306SDan Handley 		result = io_open(memmap_dev_handle, spec, &local_image_handle);
245e098e244SJuan Castillo 		if (result == 0) {
246b4315306SDan Handley 			VERBOSE("Using Memmap\n");
247b4315306SDan Handley 			io_close(local_image_handle);
248b4315306SDan Handley 		}
249b4315306SDan Handley 	}
250b4315306SDan Handley 	return result;
251b4315306SDan Handley }
252b4315306SDan Handley 
253b4315306SDan Handley 
254b4315306SDan Handley void arm_io_setup(void)
255b4315306SDan Handley {
256b4315306SDan Handley 	int io_result;
257b4315306SDan Handley 
258b4315306SDan Handley 	io_result = register_io_dev_fip(&fip_dev_con);
259e098e244SJuan Castillo 	assert(io_result == 0);
260b4315306SDan Handley 
261b4315306SDan Handley 	io_result = register_io_dev_memmap(&memmap_dev_con);
262e098e244SJuan Castillo 	assert(io_result == 0);
263b4315306SDan Handley 
264b4315306SDan Handley 	/* Open connections to devices and cache the handles */
265b4315306SDan Handley 	io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL,
266b4315306SDan Handley 				&fip_dev_handle);
267e098e244SJuan Castillo 	assert(io_result == 0);
268b4315306SDan Handley 
269b4315306SDan Handley 	io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL,
270b4315306SDan Handley 				&memmap_dev_handle);
271e098e244SJuan Castillo 	assert(io_result == 0);
272b4315306SDan Handley 
273b4315306SDan Handley 	/* Ignore improbable errors in release builds */
274b4315306SDan Handley 	(void)io_result;
275b4315306SDan Handley }
276b4315306SDan Handley 
277b4315306SDan Handley void plat_arm_io_setup(void)
278b4315306SDan Handley {
279b4315306SDan Handley 	arm_io_setup();
280b4315306SDan Handley }
281b4315306SDan Handley 
282b4315306SDan Handley int plat_arm_get_alt_image_source(
28365cd299fSSoren Brinkmann 	unsigned int image_id __unused,
28465cd299fSSoren Brinkmann 	uintptr_t *dev_handle __unused,
28565cd299fSSoren Brinkmann 	uintptr_t *image_spec __unused)
286b4315306SDan Handley {
287b4315306SDan Handley 	/* By default do not try an alternative */
288e098e244SJuan Castillo 	return -ENOENT;
289b4315306SDan Handley }
290b4315306SDan Handley 
291b4315306SDan Handley /* Return an IO device handle and specification which can be used to access
292b4315306SDan Handley  * an image. Use this to enforce platform load policy */
29316948ae1SJuan Castillo int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
294b4315306SDan Handley 			  uintptr_t *image_spec)
295b4315306SDan Handley {
296e098e244SJuan Castillo 	int result;
297b4315306SDan Handley 	const struct plat_io_policy *policy;
298b4315306SDan Handley 
29916948ae1SJuan Castillo 	assert(image_id < ARRAY_SIZE(policies));
30016948ae1SJuan Castillo 
30116948ae1SJuan Castillo 	policy = &policies[image_id];
302b4315306SDan Handley 	result = policy->check(policy->image_spec);
303e098e244SJuan Castillo 	if (result == 0) {
304b4315306SDan Handley 		*image_spec = policy->image_spec;
305b4315306SDan Handley 		*dev_handle = *(policy->dev_handle);
306b4315306SDan Handley 	} else {
30716948ae1SJuan Castillo 		VERBOSE("Trying alternative IO\n");
30816948ae1SJuan Castillo 		result = plat_arm_get_alt_image_source(image_id, dev_handle,
30916948ae1SJuan Castillo 						       image_spec);
310b4315306SDan Handley 	}
31116948ae1SJuan Castillo 
312b4315306SDan Handley 	return result;
313b4315306SDan Handley }
314436223deSYatharth Kochar 
315436223deSYatharth Kochar /*
316436223deSYatharth Kochar  * See if a Firmware Image Package is available,
317436223deSYatharth Kochar  * by checking if TOC is valid or not.
318436223deSYatharth Kochar  */
319436223deSYatharth Kochar int arm_io_is_toc_valid(void)
320436223deSYatharth Kochar {
321436223deSYatharth Kochar 	int result;
322436223deSYatharth Kochar 
323436223deSYatharth Kochar 	result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
324436223deSYatharth Kochar 
325436223deSYatharth Kochar 	return (result == 0);
326436223deSYatharth Kochar }
327436223deSYatharth Kochar 
328