xref: /rk3399_ARM-atf/plat/arm/common/arm_io_storage.c (revision bd9344f670a46125cdd8949ded75be124f34d587)
1b4315306SDan Handley /*
2c228956aSSoby Mathew  * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
3b4315306SDan Handley  *
482cb2c1aSdp-arm  * SPDX-License-Identifier: BSD-3-Clause
5b4315306SDan Handley  */
609d40e0eSAntonio Nino Diaz 
7b4315306SDan Handley #include <assert.h>
8b4315306SDan Handley #include <string.h>
909d40e0eSAntonio Nino Diaz 
1009d40e0eSAntonio Nino Diaz #include <platform_def.h>
1109d40e0eSAntonio Nino Diaz 
1209d40e0eSAntonio Nino Diaz #include <common/debug.h>
1309d40e0eSAntonio Nino Diaz #include <drivers/io/io_driver.h>
1409d40e0eSAntonio Nino Diaz #include <drivers/io/io_fip.h>
1509d40e0eSAntonio Nino Diaz #include <drivers/io/io_memmap.h>
1609d40e0eSAntonio Nino Diaz #include <drivers/io/io_storage.h>
1709d40e0eSAntonio Nino Diaz #include <lib/utils.h>
18*bd9344f6SAntonio Nino Diaz #include <plat/arm/common/plat_arm.h>
1909d40e0eSAntonio Nino Diaz #include <plat/common/platform.h>
2009d40e0eSAntonio Nino Diaz #include <tools_share/firmware_image_package.h>
2109d40e0eSAntonio Nino Diaz 
22b4315306SDan Handley /* IO devices */
23b4315306SDan Handley static const io_dev_connector_t *fip_dev_con;
24b4315306SDan Handley static uintptr_t fip_dev_handle;
25b4315306SDan Handley static const io_dev_connector_t *memmap_dev_con;
26b4315306SDan Handley static uintptr_t memmap_dev_handle;
27b4315306SDan Handley 
28b4315306SDan Handley static const io_block_spec_t fip_block_spec = {
29b4315306SDan Handley 	.offset = PLAT_ARM_FIP_BASE,
30b4315306SDan Handley 	.length = PLAT_ARM_FIP_MAX_SIZE
31b4315306SDan Handley };
32b4315306SDan Handley 
3316948ae1SJuan Castillo static const io_uuid_spec_t bl2_uuid_spec = {
3416948ae1SJuan Castillo 	.uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
35b4315306SDan Handley };
36b4315306SDan Handley 
37f59821d5SJuan Castillo static const io_uuid_spec_t scp_bl2_uuid_spec = {
38f59821d5SJuan Castillo 	.uuid = UUID_SCP_FIRMWARE_SCP_BL2,
39b4315306SDan Handley };
40b4315306SDan Handley 
4116948ae1SJuan Castillo static const io_uuid_spec_t bl31_uuid_spec = {
4216948ae1SJuan Castillo 	.uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
43b4315306SDan Handley };
44b4315306SDan Handley 
4516948ae1SJuan Castillo static const io_uuid_spec_t bl32_uuid_spec = {
4616948ae1SJuan Castillo 	.uuid = UUID_SECURE_PAYLOAD_BL32,
47b4315306SDan Handley };
48b4315306SDan Handley 
4971fb3964SSummer Qin static const io_uuid_spec_t bl32_extra1_uuid_spec = {
5071fb3964SSummer Qin 	.uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1,
5171fb3964SSummer Qin };
5271fb3964SSummer Qin 
5371fb3964SSummer Qin static const io_uuid_spec_t bl32_extra2_uuid_spec = {
5471fb3964SSummer Qin 	.uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2,
5571fb3964SSummer Qin };
5671fb3964SSummer Qin 
5716948ae1SJuan Castillo static const io_uuid_spec_t bl33_uuid_spec = {
5816948ae1SJuan Castillo 	.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
59b4315306SDan Handley };
60b4315306SDan Handley 
61c228956aSSoby Mathew static const io_uuid_spec_t tb_fw_config_uuid_spec = {
62c228956aSSoby Mathew 	.uuid = UUID_TB_FW_CONFIG,
63c228956aSSoby Mathew };
64c228956aSSoby Mathew 
65cab0b5b0SSoby Mathew static const io_uuid_spec_t hw_config_uuid_spec = {
66cab0b5b0SSoby Mathew 	.uuid = UUID_HW_CONFIG,
67cab0b5b0SSoby Mathew };
68cab0b5b0SSoby Mathew 
691d71ba14SSoby Mathew static const io_uuid_spec_t soc_fw_config_uuid_spec = {
701d71ba14SSoby Mathew 	.uuid = UUID_SOC_FW_CONFIG,
711d71ba14SSoby Mathew };
721d71ba14SSoby Mathew 
731d71ba14SSoby Mathew static const io_uuid_spec_t tos_fw_config_uuid_spec = {
741d71ba14SSoby Mathew 	.uuid = UUID_TOS_FW_CONFIG,
751d71ba14SSoby Mathew };
761d71ba14SSoby Mathew 
771d71ba14SSoby Mathew static const io_uuid_spec_t nt_fw_config_uuid_spec = {
781d71ba14SSoby Mathew 	.uuid = UUID_NT_FW_CONFIG,
791d71ba14SSoby Mathew };
801d71ba14SSoby Mathew 
81b4315306SDan Handley #if TRUSTED_BOARD_BOOT
82516beb58SJuan Castillo static const io_uuid_spec_t tb_fw_cert_uuid_spec = {
83516beb58SJuan Castillo 	.uuid = UUID_TRUSTED_BOOT_FW_CERT,
84b4315306SDan Handley };
85b4315306SDan Handley 
8616948ae1SJuan Castillo static const io_uuid_spec_t trusted_key_cert_uuid_spec = {
8716948ae1SJuan Castillo 	.uuid = UUID_TRUSTED_KEY_CERT,
88b4315306SDan Handley };
89b4315306SDan Handley 
90516beb58SJuan Castillo static const io_uuid_spec_t scp_fw_key_cert_uuid_spec = {
91516beb58SJuan Castillo 	.uuid = UUID_SCP_FW_KEY_CERT,
92b4315306SDan Handley };
93b4315306SDan Handley 
94516beb58SJuan Castillo static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = {
95516beb58SJuan Castillo 	.uuid = UUID_SOC_FW_KEY_CERT,
96b4315306SDan Handley };
97b4315306SDan Handley 
98516beb58SJuan Castillo static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = {
99516beb58SJuan Castillo 	.uuid = UUID_TRUSTED_OS_FW_KEY_CERT,
100b4315306SDan Handley };
101b4315306SDan Handley 
102516beb58SJuan Castillo static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = {
103516beb58SJuan Castillo 	.uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
104b4315306SDan Handley };
105b4315306SDan Handley 
106516beb58SJuan Castillo static const io_uuid_spec_t scp_fw_cert_uuid_spec = {
107516beb58SJuan Castillo 	.uuid = UUID_SCP_FW_CONTENT_CERT,
108b4315306SDan Handley };
109b4315306SDan Handley 
110516beb58SJuan Castillo static const io_uuid_spec_t soc_fw_cert_uuid_spec = {
111516beb58SJuan Castillo 	.uuid = UUID_SOC_FW_CONTENT_CERT,
112b4315306SDan Handley };
113b4315306SDan Handley 
114516beb58SJuan Castillo static const io_uuid_spec_t tos_fw_cert_uuid_spec = {
115516beb58SJuan Castillo 	.uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT,
116b4315306SDan Handley };
117b4315306SDan Handley 
118516beb58SJuan Castillo static const io_uuid_spec_t nt_fw_cert_uuid_spec = {
119516beb58SJuan Castillo 	.uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT,
120b4315306SDan Handley };
121b4315306SDan Handley #endif /* TRUSTED_BOARD_BOOT */
122b4315306SDan Handley 
12316948ae1SJuan Castillo 
124b4315306SDan Handley static int open_fip(const uintptr_t spec);
125b4315306SDan Handley static int open_memmap(const uintptr_t spec);
126b4315306SDan Handley 
127b4315306SDan Handley struct plat_io_policy {
128b4315306SDan Handley 	uintptr_t *dev_handle;
129b4315306SDan Handley 	uintptr_t image_spec;
130b4315306SDan Handley 	int (*check)(const uintptr_t spec);
131b4315306SDan Handley };
132b4315306SDan Handley 
13316948ae1SJuan Castillo /* By default, ARM platforms load images from the FIP */
134b4315306SDan Handley static const struct plat_io_policy policies[] = {
13516948ae1SJuan Castillo 	[FIP_IMAGE_ID] = {
136b4315306SDan Handley 		&memmap_dev_handle,
137b4315306SDan Handley 		(uintptr_t)&fip_block_spec,
138b4315306SDan Handley 		open_memmap
13916948ae1SJuan Castillo 	},
14016948ae1SJuan Castillo 	[BL2_IMAGE_ID] = {
141b4315306SDan Handley 		&fip_dev_handle,
14216948ae1SJuan Castillo 		(uintptr_t)&bl2_uuid_spec,
143b4315306SDan Handley 		open_fip
14416948ae1SJuan Castillo 	},
145f59821d5SJuan Castillo 	[SCP_BL2_IMAGE_ID] = {
146b4315306SDan Handley 		&fip_dev_handle,
147f59821d5SJuan Castillo 		(uintptr_t)&scp_bl2_uuid_spec,
148b4315306SDan Handley 		open_fip
14916948ae1SJuan Castillo 	},
15016948ae1SJuan Castillo 	[BL31_IMAGE_ID] = {
151b4315306SDan Handley 		&fip_dev_handle,
15216948ae1SJuan Castillo 		(uintptr_t)&bl31_uuid_spec,
153b4315306SDan Handley 		open_fip
15416948ae1SJuan Castillo 	},
15516948ae1SJuan Castillo 	[BL32_IMAGE_ID] = {
156b4315306SDan Handley 		&fip_dev_handle,
15716948ae1SJuan Castillo 		(uintptr_t)&bl32_uuid_spec,
158b4315306SDan Handley 		open_fip
15916948ae1SJuan Castillo 	},
16071fb3964SSummer Qin 	[BL32_EXTRA1_IMAGE_ID] = {
16171fb3964SSummer Qin 		&fip_dev_handle,
16271fb3964SSummer Qin 		(uintptr_t)&bl32_extra1_uuid_spec,
16371fb3964SSummer Qin 		open_fip
16471fb3964SSummer Qin 	},
16571fb3964SSummer Qin 	[BL32_EXTRA2_IMAGE_ID] = {
16671fb3964SSummer Qin 		&fip_dev_handle,
16771fb3964SSummer Qin 		(uintptr_t)&bl32_extra2_uuid_spec,
16871fb3964SSummer Qin 		open_fip
16971fb3964SSummer Qin 	},
17016948ae1SJuan Castillo 	[BL33_IMAGE_ID] = {
171b4315306SDan Handley 		&fip_dev_handle,
17216948ae1SJuan Castillo 		(uintptr_t)&bl33_uuid_spec,
173b4315306SDan Handley 		open_fip
17416948ae1SJuan Castillo 	},
175c228956aSSoby Mathew 	[TB_FW_CONFIG_ID] = {
176c228956aSSoby Mathew 		&fip_dev_handle,
177c228956aSSoby Mathew 		(uintptr_t)&tb_fw_config_uuid_spec,
178c228956aSSoby Mathew 		open_fip
179c228956aSSoby Mathew 	},
180cab0b5b0SSoby Mathew 	[HW_CONFIG_ID] = {
181cab0b5b0SSoby Mathew 		&fip_dev_handle,
182cab0b5b0SSoby Mathew 		(uintptr_t)&hw_config_uuid_spec,
183cab0b5b0SSoby Mathew 		open_fip
184cab0b5b0SSoby Mathew 	},
1851d71ba14SSoby Mathew 	[SOC_FW_CONFIG_ID] = {
1861d71ba14SSoby Mathew 			&fip_dev_handle,
1871d71ba14SSoby Mathew 			(uintptr_t)&soc_fw_config_uuid_spec,
1881d71ba14SSoby Mathew 			open_fip
1891d71ba14SSoby Mathew 	},
1901d71ba14SSoby Mathew 	[TOS_FW_CONFIG_ID] = {
1911d71ba14SSoby Mathew 		&fip_dev_handle,
1921d71ba14SSoby Mathew 		(uintptr_t)&tos_fw_config_uuid_spec,
1931d71ba14SSoby Mathew 		open_fip
1941d71ba14SSoby Mathew 	},
1951d71ba14SSoby Mathew 	[NT_FW_CONFIG_ID] = {
1961d71ba14SSoby Mathew 		&fip_dev_handle,
1971d71ba14SSoby Mathew 		(uintptr_t)&nt_fw_config_uuid_spec,
1981d71ba14SSoby Mathew 		open_fip
1991d71ba14SSoby Mathew 	},
200b4315306SDan Handley #if TRUSTED_BOARD_BOOT
201516beb58SJuan Castillo 	[TRUSTED_BOOT_FW_CERT_ID] = {
202b4315306SDan Handley 		&fip_dev_handle,
203516beb58SJuan Castillo 		(uintptr_t)&tb_fw_cert_uuid_spec,
204b4315306SDan Handley 		open_fip
20516948ae1SJuan Castillo 	},
20616948ae1SJuan Castillo 	[TRUSTED_KEY_CERT_ID] = {
207b4315306SDan Handley 		&fip_dev_handle,
20816948ae1SJuan Castillo 		(uintptr_t)&trusted_key_cert_uuid_spec,
209b4315306SDan Handley 		open_fip
21016948ae1SJuan Castillo 	},
211516beb58SJuan Castillo 	[SCP_FW_KEY_CERT_ID] = {
212b4315306SDan Handley 		&fip_dev_handle,
213516beb58SJuan Castillo 		(uintptr_t)&scp_fw_key_cert_uuid_spec,
214b4315306SDan Handley 		open_fip
21516948ae1SJuan Castillo 	},
216516beb58SJuan Castillo 	[SOC_FW_KEY_CERT_ID] = {
217b4315306SDan Handley 		&fip_dev_handle,
218516beb58SJuan Castillo 		(uintptr_t)&soc_fw_key_cert_uuid_spec,
219b4315306SDan Handley 		open_fip
22016948ae1SJuan Castillo 	},
221516beb58SJuan Castillo 	[TRUSTED_OS_FW_KEY_CERT_ID] = {
222b4315306SDan Handley 		&fip_dev_handle,
223516beb58SJuan Castillo 		(uintptr_t)&tos_fw_key_cert_uuid_spec,
224b4315306SDan Handley 		open_fip
22516948ae1SJuan Castillo 	},
226516beb58SJuan Castillo 	[NON_TRUSTED_FW_KEY_CERT_ID] = {
227b4315306SDan Handley 		&fip_dev_handle,
228516beb58SJuan Castillo 		(uintptr_t)&nt_fw_key_cert_uuid_spec,
229b4315306SDan Handley 		open_fip
23016948ae1SJuan Castillo 	},
231516beb58SJuan Castillo 	[SCP_FW_CONTENT_CERT_ID] = {
232b4315306SDan Handley 		&fip_dev_handle,
233516beb58SJuan Castillo 		(uintptr_t)&scp_fw_cert_uuid_spec,
234b4315306SDan Handley 		open_fip
23516948ae1SJuan Castillo 	},
236516beb58SJuan Castillo 	[SOC_FW_CONTENT_CERT_ID] = {
237b4315306SDan Handley 		&fip_dev_handle,
238516beb58SJuan Castillo 		(uintptr_t)&soc_fw_cert_uuid_spec,
239b4315306SDan Handley 		open_fip
24016948ae1SJuan Castillo 	},
241516beb58SJuan Castillo 	[TRUSTED_OS_FW_CONTENT_CERT_ID] = {
242b4315306SDan Handley 		&fip_dev_handle,
243516beb58SJuan Castillo 		(uintptr_t)&tos_fw_cert_uuid_spec,
244b4315306SDan Handley 		open_fip
24516948ae1SJuan Castillo 	},
246516beb58SJuan Castillo 	[NON_TRUSTED_FW_CONTENT_CERT_ID] = {
247b4315306SDan Handley 		&fip_dev_handle,
248516beb58SJuan Castillo 		(uintptr_t)&nt_fw_cert_uuid_spec,
249b4315306SDan Handley 		open_fip
25016948ae1SJuan Castillo 	},
251b4315306SDan Handley #endif /* TRUSTED_BOARD_BOOT */
252b4315306SDan Handley };
253b4315306SDan Handley 
254b4315306SDan Handley 
255b4315306SDan Handley /* Weak definitions may be overridden in specific ARM standard platform */
256b4315306SDan Handley #pragma weak plat_arm_io_setup
257b4315306SDan Handley #pragma weak plat_arm_get_alt_image_source
258b4315306SDan Handley 
259b4315306SDan Handley 
260b4315306SDan Handley static int open_fip(const uintptr_t spec)
261b4315306SDan Handley {
262b4315306SDan Handley 	int result;
263b4315306SDan Handley 	uintptr_t local_image_handle;
264b4315306SDan Handley 
265b4315306SDan Handley 	/* See if a Firmware Image Package is available */
26616948ae1SJuan Castillo 	result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
267e098e244SJuan Castillo 	if (result == 0) {
268b4315306SDan Handley 		result = io_open(fip_dev_handle, spec, &local_image_handle);
269e098e244SJuan Castillo 		if (result == 0) {
270b4315306SDan Handley 			VERBOSE("Using FIP\n");
271b4315306SDan Handley 			io_close(local_image_handle);
272b4315306SDan Handley 		}
273b4315306SDan Handley 	}
274b4315306SDan Handley 	return result;
275b4315306SDan Handley }
276b4315306SDan Handley 
277b4315306SDan Handley 
278b4315306SDan Handley static int open_memmap(const uintptr_t spec)
279b4315306SDan Handley {
280b4315306SDan Handley 	int result;
281b4315306SDan Handley 	uintptr_t local_image_handle;
282b4315306SDan Handley 
283b4315306SDan Handley 	result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL);
284e098e244SJuan Castillo 	if (result == 0) {
285b4315306SDan Handley 		result = io_open(memmap_dev_handle, spec, &local_image_handle);
286e098e244SJuan Castillo 		if (result == 0) {
287b4315306SDan Handley 			VERBOSE("Using Memmap\n");
288b4315306SDan Handley 			io_close(local_image_handle);
289b4315306SDan Handley 		}
290b4315306SDan Handley 	}
291b4315306SDan Handley 	return result;
292b4315306SDan Handley }
293b4315306SDan Handley 
294b4315306SDan Handley 
295b4315306SDan Handley void arm_io_setup(void)
296b4315306SDan Handley {
297b4315306SDan Handley 	int io_result;
298b4315306SDan Handley 
299b4315306SDan Handley 	io_result = register_io_dev_fip(&fip_dev_con);
300e098e244SJuan Castillo 	assert(io_result == 0);
301b4315306SDan Handley 
302b4315306SDan Handley 	io_result = register_io_dev_memmap(&memmap_dev_con);
303e098e244SJuan Castillo 	assert(io_result == 0);
304b4315306SDan Handley 
305b4315306SDan Handley 	/* Open connections to devices and cache the handles */
306b4315306SDan Handley 	io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL,
307b4315306SDan Handley 				&fip_dev_handle);
308e098e244SJuan Castillo 	assert(io_result == 0);
309b4315306SDan Handley 
310b4315306SDan Handley 	io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL,
311b4315306SDan Handley 				&memmap_dev_handle);
312e098e244SJuan Castillo 	assert(io_result == 0);
313b4315306SDan Handley 
314b4315306SDan Handley 	/* Ignore improbable errors in release builds */
315b4315306SDan Handley 	(void)io_result;
316b4315306SDan Handley }
317b4315306SDan Handley 
318b4315306SDan Handley void plat_arm_io_setup(void)
319b4315306SDan Handley {
320b4315306SDan Handley 	arm_io_setup();
321b4315306SDan Handley }
322b4315306SDan Handley 
323b4315306SDan Handley int plat_arm_get_alt_image_source(
32465cd299fSSoren Brinkmann 	unsigned int image_id __unused,
32565cd299fSSoren Brinkmann 	uintptr_t *dev_handle __unused,
32665cd299fSSoren Brinkmann 	uintptr_t *image_spec __unused)
327b4315306SDan Handley {
328b4315306SDan Handley 	/* By default do not try an alternative */
329e098e244SJuan Castillo 	return -ENOENT;
330b4315306SDan Handley }
331b4315306SDan Handley 
332b4315306SDan Handley /* Return an IO device handle and specification which can be used to access
333b4315306SDan Handley  * an image. Use this to enforce platform load policy */
33416948ae1SJuan Castillo int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
335b4315306SDan Handley 			  uintptr_t *image_spec)
336b4315306SDan Handley {
337e098e244SJuan Castillo 	int result;
338b4315306SDan Handley 	const struct plat_io_policy *policy;
339b4315306SDan Handley 
34016948ae1SJuan Castillo 	assert(image_id < ARRAY_SIZE(policies));
34116948ae1SJuan Castillo 
34216948ae1SJuan Castillo 	policy = &policies[image_id];
343b4315306SDan Handley 	result = policy->check(policy->image_spec);
344e098e244SJuan Castillo 	if (result == 0) {
345b4315306SDan Handley 		*image_spec = policy->image_spec;
346b4315306SDan Handley 		*dev_handle = *(policy->dev_handle);
347b4315306SDan Handley 	} else {
34816948ae1SJuan Castillo 		VERBOSE("Trying alternative IO\n");
34916948ae1SJuan Castillo 		result = plat_arm_get_alt_image_source(image_id, dev_handle,
35016948ae1SJuan Castillo 						       image_spec);
351b4315306SDan Handley 	}
35216948ae1SJuan Castillo 
353b4315306SDan Handley 	return result;
354b4315306SDan Handley }
355436223deSYatharth Kochar 
356436223deSYatharth Kochar /*
357436223deSYatharth Kochar  * See if a Firmware Image Package is available,
358436223deSYatharth Kochar  * by checking if TOC is valid or not.
359436223deSYatharth Kochar  */
360436223deSYatharth Kochar int arm_io_is_toc_valid(void)
361436223deSYatharth Kochar {
362436223deSYatharth Kochar 	int result;
363436223deSYatharth Kochar 
364436223deSYatharth Kochar 	result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
365436223deSYatharth Kochar 
366436223deSYatharth Kochar 	return (result == 0);
367436223deSYatharth Kochar }
368436223deSYatharth Kochar 
369