xref: /rk3399_ARM-atf/plat/arm/common/arm_io_storage.c (revision 1d71ba141d32c9e8974d4e3e973a90fd0c6bf458)
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  */
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>
131af540efSRoberto Vargas #include <plat_arm.h>
141af540efSRoberto Vargas #include <platform.h>
15b4315306SDan Handley #include <platform_def.h>
16b4315306SDan Handley #include <string.h>
17ed81f3ebSSandrine Bailleux #include <utils.h>
18b4315306SDan Handley 
19b4315306SDan Handley /* IO devices */
20b4315306SDan Handley static const io_dev_connector_t *fip_dev_con;
21b4315306SDan Handley static uintptr_t fip_dev_handle;
22b4315306SDan Handley static const io_dev_connector_t *memmap_dev_con;
23b4315306SDan Handley static uintptr_t memmap_dev_handle;
24b4315306SDan Handley 
25b4315306SDan Handley static const io_block_spec_t fip_block_spec = {
26b4315306SDan Handley 	.offset = PLAT_ARM_FIP_BASE,
27b4315306SDan Handley 	.length = PLAT_ARM_FIP_MAX_SIZE
28b4315306SDan Handley };
29b4315306SDan Handley 
3016948ae1SJuan Castillo static const io_uuid_spec_t bl2_uuid_spec = {
3116948ae1SJuan Castillo 	.uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
32b4315306SDan Handley };
33b4315306SDan Handley 
34f59821d5SJuan Castillo static const io_uuid_spec_t scp_bl2_uuid_spec = {
35f59821d5SJuan Castillo 	.uuid = UUID_SCP_FIRMWARE_SCP_BL2,
36b4315306SDan Handley };
37b4315306SDan Handley 
3816948ae1SJuan Castillo static const io_uuid_spec_t bl31_uuid_spec = {
3916948ae1SJuan Castillo 	.uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
40b4315306SDan Handley };
41b4315306SDan Handley 
4216948ae1SJuan Castillo static const io_uuid_spec_t bl32_uuid_spec = {
4316948ae1SJuan Castillo 	.uuid = UUID_SECURE_PAYLOAD_BL32,
44b4315306SDan Handley };
45b4315306SDan Handley 
4671fb3964SSummer Qin static const io_uuid_spec_t bl32_extra1_uuid_spec = {
4771fb3964SSummer Qin 	.uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1,
4871fb3964SSummer Qin };
4971fb3964SSummer Qin 
5071fb3964SSummer Qin static const io_uuid_spec_t bl32_extra2_uuid_spec = {
5171fb3964SSummer Qin 	.uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2,
5271fb3964SSummer Qin };
5371fb3964SSummer Qin 
5416948ae1SJuan Castillo static const io_uuid_spec_t bl33_uuid_spec = {
5516948ae1SJuan Castillo 	.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
56b4315306SDan Handley };
57b4315306SDan Handley 
58c228956aSSoby Mathew static const io_uuid_spec_t tb_fw_config_uuid_spec = {
59c228956aSSoby Mathew 	.uuid = UUID_TB_FW_CONFIG,
60c228956aSSoby Mathew };
61c228956aSSoby Mathew 
62cab0b5b0SSoby Mathew static const io_uuid_spec_t hw_config_uuid_spec = {
63cab0b5b0SSoby Mathew 	.uuid = UUID_HW_CONFIG,
64cab0b5b0SSoby Mathew };
65cab0b5b0SSoby Mathew 
66*1d71ba14SSoby Mathew static const io_uuid_spec_t soc_fw_config_uuid_spec = {
67*1d71ba14SSoby Mathew 	.uuid = UUID_SOC_FW_CONFIG,
68*1d71ba14SSoby Mathew };
69*1d71ba14SSoby Mathew 
70*1d71ba14SSoby Mathew static const io_uuid_spec_t tos_fw_config_uuid_spec = {
71*1d71ba14SSoby Mathew 	.uuid = UUID_TOS_FW_CONFIG,
72*1d71ba14SSoby Mathew };
73*1d71ba14SSoby Mathew 
74*1d71ba14SSoby Mathew static const io_uuid_spec_t nt_fw_config_uuid_spec = {
75*1d71ba14SSoby Mathew 	.uuid = UUID_NT_FW_CONFIG,
76*1d71ba14SSoby Mathew };
77*1d71ba14SSoby Mathew 
78b4315306SDan Handley #if TRUSTED_BOARD_BOOT
79516beb58SJuan Castillo static const io_uuid_spec_t tb_fw_cert_uuid_spec = {
80516beb58SJuan Castillo 	.uuid = UUID_TRUSTED_BOOT_FW_CERT,
81b4315306SDan Handley };
82b4315306SDan Handley 
8316948ae1SJuan Castillo static const io_uuid_spec_t trusted_key_cert_uuid_spec = {
8416948ae1SJuan Castillo 	.uuid = UUID_TRUSTED_KEY_CERT,
85b4315306SDan Handley };
86b4315306SDan Handley 
87516beb58SJuan Castillo static const io_uuid_spec_t scp_fw_key_cert_uuid_spec = {
88516beb58SJuan Castillo 	.uuid = UUID_SCP_FW_KEY_CERT,
89b4315306SDan Handley };
90b4315306SDan Handley 
91516beb58SJuan Castillo static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = {
92516beb58SJuan Castillo 	.uuid = UUID_SOC_FW_KEY_CERT,
93b4315306SDan Handley };
94b4315306SDan Handley 
95516beb58SJuan Castillo static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = {
96516beb58SJuan Castillo 	.uuid = UUID_TRUSTED_OS_FW_KEY_CERT,
97b4315306SDan Handley };
98b4315306SDan Handley 
99516beb58SJuan Castillo static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = {
100516beb58SJuan Castillo 	.uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
101b4315306SDan Handley };
102b4315306SDan Handley 
103516beb58SJuan Castillo static const io_uuid_spec_t scp_fw_cert_uuid_spec = {
104516beb58SJuan Castillo 	.uuid = UUID_SCP_FW_CONTENT_CERT,
105b4315306SDan Handley };
106b4315306SDan Handley 
107516beb58SJuan Castillo static const io_uuid_spec_t soc_fw_cert_uuid_spec = {
108516beb58SJuan Castillo 	.uuid = UUID_SOC_FW_CONTENT_CERT,
109b4315306SDan Handley };
110b4315306SDan Handley 
111516beb58SJuan Castillo static const io_uuid_spec_t tos_fw_cert_uuid_spec = {
112516beb58SJuan Castillo 	.uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT,
113b4315306SDan Handley };
114b4315306SDan Handley 
115516beb58SJuan Castillo static const io_uuid_spec_t nt_fw_cert_uuid_spec = {
116516beb58SJuan Castillo 	.uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT,
117b4315306SDan Handley };
118b4315306SDan Handley #endif /* TRUSTED_BOARD_BOOT */
119b4315306SDan Handley 
12016948ae1SJuan Castillo 
121b4315306SDan Handley static int open_fip(const uintptr_t spec);
122b4315306SDan Handley static int open_memmap(const uintptr_t spec);
123b4315306SDan Handley 
124b4315306SDan Handley struct plat_io_policy {
125b4315306SDan Handley 	uintptr_t *dev_handle;
126b4315306SDan Handley 	uintptr_t image_spec;
127b4315306SDan Handley 	int (*check)(const uintptr_t spec);
128b4315306SDan Handley };
129b4315306SDan Handley 
13016948ae1SJuan Castillo /* By default, ARM platforms load images from the FIP */
131b4315306SDan Handley static const struct plat_io_policy policies[] = {
13216948ae1SJuan Castillo 	[FIP_IMAGE_ID] = {
133b4315306SDan Handley 		&memmap_dev_handle,
134b4315306SDan Handley 		(uintptr_t)&fip_block_spec,
135b4315306SDan Handley 		open_memmap
13616948ae1SJuan Castillo 	},
13716948ae1SJuan Castillo 	[BL2_IMAGE_ID] = {
138b4315306SDan Handley 		&fip_dev_handle,
13916948ae1SJuan Castillo 		(uintptr_t)&bl2_uuid_spec,
140b4315306SDan Handley 		open_fip
14116948ae1SJuan Castillo 	},
142f59821d5SJuan Castillo 	[SCP_BL2_IMAGE_ID] = {
143b4315306SDan Handley 		&fip_dev_handle,
144f59821d5SJuan Castillo 		(uintptr_t)&scp_bl2_uuid_spec,
145b4315306SDan Handley 		open_fip
14616948ae1SJuan Castillo 	},
14716948ae1SJuan Castillo 	[BL31_IMAGE_ID] = {
148b4315306SDan Handley 		&fip_dev_handle,
14916948ae1SJuan Castillo 		(uintptr_t)&bl31_uuid_spec,
150b4315306SDan Handley 		open_fip
15116948ae1SJuan Castillo 	},
15216948ae1SJuan Castillo 	[BL32_IMAGE_ID] = {
153b4315306SDan Handley 		&fip_dev_handle,
15416948ae1SJuan Castillo 		(uintptr_t)&bl32_uuid_spec,
155b4315306SDan Handley 		open_fip
15616948ae1SJuan Castillo 	},
15771fb3964SSummer Qin 	[BL32_EXTRA1_IMAGE_ID] = {
15871fb3964SSummer Qin 		&fip_dev_handle,
15971fb3964SSummer Qin 		(uintptr_t)&bl32_extra1_uuid_spec,
16071fb3964SSummer Qin 		open_fip
16171fb3964SSummer Qin 	},
16271fb3964SSummer Qin 	[BL32_EXTRA2_IMAGE_ID] = {
16371fb3964SSummer Qin 		&fip_dev_handle,
16471fb3964SSummer Qin 		(uintptr_t)&bl32_extra2_uuid_spec,
16571fb3964SSummer Qin 		open_fip
16671fb3964SSummer Qin 	},
16716948ae1SJuan Castillo 	[BL33_IMAGE_ID] = {
168b4315306SDan Handley 		&fip_dev_handle,
16916948ae1SJuan Castillo 		(uintptr_t)&bl33_uuid_spec,
170b4315306SDan Handley 		open_fip
17116948ae1SJuan Castillo 	},
172c228956aSSoby Mathew 	[TB_FW_CONFIG_ID] = {
173c228956aSSoby Mathew 		&fip_dev_handle,
174c228956aSSoby Mathew 		(uintptr_t)&tb_fw_config_uuid_spec,
175c228956aSSoby Mathew 		open_fip
176c228956aSSoby Mathew 	},
177cab0b5b0SSoby Mathew 	[HW_CONFIG_ID] = {
178cab0b5b0SSoby Mathew 		&fip_dev_handle,
179cab0b5b0SSoby Mathew 		(uintptr_t)&hw_config_uuid_spec,
180cab0b5b0SSoby Mathew 		open_fip
181cab0b5b0SSoby Mathew 	},
182*1d71ba14SSoby Mathew 	[SOC_FW_CONFIG_ID] = {
183*1d71ba14SSoby Mathew 			&fip_dev_handle,
184*1d71ba14SSoby Mathew 			(uintptr_t)&soc_fw_config_uuid_spec,
185*1d71ba14SSoby Mathew 			open_fip
186*1d71ba14SSoby Mathew 	},
187*1d71ba14SSoby Mathew 	[TOS_FW_CONFIG_ID] = {
188*1d71ba14SSoby Mathew 		&fip_dev_handle,
189*1d71ba14SSoby Mathew 		(uintptr_t)&tos_fw_config_uuid_spec,
190*1d71ba14SSoby Mathew 		open_fip
191*1d71ba14SSoby Mathew 	},
192*1d71ba14SSoby Mathew 	[NT_FW_CONFIG_ID] = {
193*1d71ba14SSoby Mathew 		&fip_dev_handle,
194*1d71ba14SSoby Mathew 		(uintptr_t)&nt_fw_config_uuid_spec,
195*1d71ba14SSoby Mathew 		open_fip
196*1d71ba14SSoby Mathew 	},
197b4315306SDan Handley #if TRUSTED_BOARD_BOOT
198516beb58SJuan Castillo 	[TRUSTED_BOOT_FW_CERT_ID] = {
199b4315306SDan Handley 		&fip_dev_handle,
200516beb58SJuan Castillo 		(uintptr_t)&tb_fw_cert_uuid_spec,
201b4315306SDan Handley 		open_fip
20216948ae1SJuan Castillo 	},
20316948ae1SJuan Castillo 	[TRUSTED_KEY_CERT_ID] = {
204b4315306SDan Handley 		&fip_dev_handle,
20516948ae1SJuan Castillo 		(uintptr_t)&trusted_key_cert_uuid_spec,
206b4315306SDan Handley 		open_fip
20716948ae1SJuan Castillo 	},
208516beb58SJuan Castillo 	[SCP_FW_KEY_CERT_ID] = {
209b4315306SDan Handley 		&fip_dev_handle,
210516beb58SJuan Castillo 		(uintptr_t)&scp_fw_key_cert_uuid_spec,
211b4315306SDan Handley 		open_fip
21216948ae1SJuan Castillo 	},
213516beb58SJuan Castillo 	[SOC_FW_KEY_CERT_ID] = {
214b4315306SDan Handley 		&fip_dev_handle,
215516beb58SJuan Castillo 		(uintptr_t)&soc_fw_key_cert_uuid_spec,
216b4315306SDan Handley 		open_fip
21716948ae1SJuan Castillo 	},
218516beb58SJuan Castillo 	[TRUSTED_OS_FW_KEY_CERT_ID] = {
219b4315306SDan Handley 		&fip_dev_handle,
220516beb58SJuan Castillo 		(uintptr_t)&tos_fw_key_cert_uuid_spec,
221b4315306SDan Handley 		open_fip
22216948ae1SJuan Castillo 	},
223516beb58SJuan Castillo 	[NON_TRUSTED_FW_KEY_CERT_ID] = {
224b4315306SDan Handley 		&fip_dev_handle,
225516beb58SJuan Castillo 		(uintptr_t)&nt_fw_key_cert_uuid_spec,
226b4315306SDan Handley 		open_fip
22716948ae1SJuan Castillo 	},
228516beb58SJuan Castillo 	[SCP_FW_CONTENT_CERT_ID] = {
229b4315306SDan Handley 		&fip_dev_handle,
230516beb58SJuan Castillo 		(uintptr_t)&scp_fw_cert_uuid_spec,
231b4315306SDan Handley 		open_fip
23216948ae1SJuan Castillo 	},
233516beb58SJuan Castillo 	[SOC_FW_CONTENT_CERT_ID] = {
234b4315306SDan Handley 		&fip_dev_handle,
235516beb58SJuan Castillo 		(uintptr_t)&soc_fw_cert_uuid_spec,
236b4315306SDan Handley 		open_fip
23716948ae1SJuan Castillo 	},
238516beb58SJuan Castillo 	[TRUSTED_OS_FW_CONTENT_CERT_ID] = {
239b4315306SDan Handley 		&fip_dev_handle,
240516beb58SJuan Castillo 		(uintptr_t)&tos_fw_cert_uuid_spec,
241b4315306SDan Handley 		open_fip
24216948ae1SJuan Castillo 	},
243516beb58SJuan Castillo 	[NON_TRUSTED_FW_CONTENT_CERT_ID] = {
244b4315306SDan Handley 		&fip_dev_handle,
245516beb58SJuan Castillo 		(uintptr_t)&nt_fw_cert_uuid_spec,
246b4315306SDan Handley 		open_fip
24716948ae1SJuan Castillo 	},
248b4315306SDan Handley #endif /* TRUSTED_BOARD_BOOT */
249b4315306SDan Handley };
250b4315306SDan Handley 
251b4315306SDan Handley 
252b4315306SDan Handley /* Weak definitions may be overridden in specific ARM standard platform */
253b4315306SDan Handley #pragma weak plat_arm_io_setup
254b4315306SDan Handley #pragma weak plat_arm_get_alt_image_source
255b4315306SDan Handley 
256b4315306SDan Handley 
257b4315306SDan Handley static int open_fip(const uintptr_t spec)
258b4315306SDan Handley {
259b4315306SDan Handley 	int result;
260b4315306SDan Handley 	uintptr_t local_image_handle;
261b4315306SDan Handley 
262b4315306SDan Handley 	/* See if a Firmware Image Package is available */
26316948ae1SJuan Castillo 	result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
264e098e244SJuan Castillo 	if (result == 0) {
265b4315306SDan Handley 		result = io_open(fip_dev_handle, spec, &local_image_handle);
266e098e244SJuan Castillo 		if (result == 0) {
267b4315306SDan Handley 			VERBOSE("Using FIP\n");
268b4315306SDan Handley 			io_close(local_image_handle);
269b4315306SDan Handley 		}
270b4315306SDan Handley 	}
271b4315306SDan Handley 	return result;
272b4315306SDan Handley }
273b4315306SDan Handley 
274b4315306SDan Handley 
275b4315306SDan Handley static int open_memmap(const uintptr_t spec)
276b4315306SDan Handley {
277b4315306SDan Handley 	int result;
278b4315306SDan Handley 	uintptr_t local_image_handle;
279b4315306SDan Handley 
280b4315306SDan Handley 	result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL);
281e098e244SJuan Castillo 	if (result == 0) {
282b4315306SDan Handley 		result = io_open(memmap_dev_handle, spec, &local_image_handle);
283e098e244SJuan Castillo 		if (result == 0) {
284b4315306SDan Handley 			VERBOSE("Using Memmap\n");
285b4315306SDan Handley 			io_close(local_image_handle);
286b4315306SDan Handley 		}
287b4315306SDan Handley 	}
288b4315306SDan Handley 	return result;
289b4315306SDan Handley }
290b4315306SDan Handley 
291b4315306SDan Handley 
292b4315306SDan Handley void arm_io_setup(void)
293b4315306SDan Handley {
294b4315306SDan Handley 	int io_result;
295b4315306SDan Handley 
296b4315306SDan Handley 	io_result = register_io_dev_fip(&fip_dev_con);
297e098e244SJuan Castillo 	assert(io_result == 0);
298b4315306SDan Handley 
299b4315306SDan Handley 	io_result = register_io_dev_memmap(&memmap_dev_con);
300e098e244SJuan Castillo 	assert(io_result == 0);
301b4315306SDan Handley 
302b4315306SDan Handley 	/* Open connections to devices and cache the handles */
303b4315306SDan Handley 	io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL,
304b4315306SDan Handley 				&fip_dev_handle);
305e098e244SJuan Castillo 	assert(io_result == 0);
306b4315306SDan Handley 
307b4315306SDan Handley 	io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL,
308b4315306SDan Handley 				&memmap_dev_handle);
309e098e244SJuan Castillo 	assert(io_result == 0);
310b4315306SDan Handley 
311b4315306SDan Handley 	/* Ignore improbable errors in release builds */
312b4315306SDan Handley 	(void)io_result;
313b4315306SDan Handley }
314b4315306SDan Handley 
315b4315306SDan Handley void plat_arm_io_setup(void)
316b4315306SDan Handley {
317b4315306SDan Handley 	arm_io_setup();
318b4315306SDan Handley }
319b4315306SDan Handley 
320b4315306SDan Handley int plat_arm_get_alt_image_source(
32165cd299fSSoren Brinkmann 	unsigned int image_id __unused,
32265cd299fSSoren Brinkmann 	uintptr_t *dev_handle __unused,
32365cd299fSSoren Brinkmann 	uintptr_t *image_spec __unused)
324b4315306SDan Handley {
325b4315306SDan Handley 	/* By default do not try an alternative */
326e098e244SJuan Castillo 	return -ENOENT;
327b4315306SDan Handley }
328b4315306SDan Handley 
329b4315306SDan Handley /* Return an IO device handle and specification which can be used to access
330b4315306SDan Handley  * an image. Use this to enforce platform load policy */
33116948ae1SJuan Castillo int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
332b4315306SDan Handley 			  uintptr_t *image_spec)
333b4315306SDan Handley {
334e098e244SJuan Castillo 	int result;
335b4315306SDan Handley 	const struct plat_io_policy *policy;
336b4315306SDan Handley 
33716948ae1SJuan Castillo 	assert(image_id < ARRAY_SIZE(policies));
33816948ae1SJuan Castillo 
33916948ae1SJuan Castillo 	policy = &policies[image_id];
340b4315306SDan Handley 	result = policy->check(policy->image_spec);
341e098e244SJuan Castillo 	if (result == 0) {
342b4315306SDan Handley 		*image_spec = policy->image_spec;
343b4315306SDan Handley 		*dev_handle = *(policy->dev_handle);
344b4315306SDan Handley 	} else {
34516948ae1SJuan Castillo 		VERBOSE("Trying alternative IO\n");
34616948ae1SJuan Castillo 		result = plat_arm_get_alt_image_source(image_id, dev_handle,
34716948ae1SJuan Castillo 						       image_spec);
348b4315306SDan Handley 	}
34916948ae1SJuan Castillo 
350b4315306SDan Handley 	return result;
351b4315306SDan Handley }
352436223deSYatharth Kochar 
353436223deSYatharth Kochar /*
354436223deSYatharth Kochar  * See if a Firmware Image Package is available,
355436223deSYatharth Kochar  * by checking if TOC is valid or not.
356436223deSYatharth Kochar  */
357436223deSYatharth Kochar int arm_io_is_toc_valid(void)
358436223deSYatharth Kochar {
359436223deSYatharth Kochar 	int result;
360436223deSYatharth Kochar 
361436223deSYatharth Kochar 	result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
362436223deSYatharth Kochar 
363436223deSYatharth Kochar 	return (result == 0);
364436223deSYatharth Kochar }
365436223deSYatharth Kochar 
366