xref: /rk3399_ARM-atf/plat/arm/common/arm_io_storage.c (revision f59821d51255f14e0ac00eef7bc98ef75c686876)
1b4315306SDan Handley /*
2b4315306SDan Handley  * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
3b4315306SDan Handley  *
4b4315306SDan Handley  * Redistribution and use in source and binary forms, with or without
5b4315306SDan Handley  * modification, are permitted provided that the following conditions are met:
6b4315306SDan Handley  *
7b4315306SDan Handley  * Redistributions of source code must retain the above copyright notice, this
8b4315306SDan Handley  * list of conditions and the following disclaimer.
9b4315306SDan Handley  *
10b4315306SDan Handley  * Redistributions in binary form must reproduce the above copyright notice,
11b4315306SDan Handley  * this list of conditions and the following disclaimer in the documentation
12b4315306SDan Handley  * and/or other materials provided with the distribution.
13b4315306SDan Handley  *
14b4315306SDan Handley  * Neither the name of ARM nor the names of its contributors may be used
15b4315306SDan Handley  * to endorse or promote products derived from this software without specific
16b4315306SDan Handley  * prior written permission.
17b4315306SDan Handley  *
18b4315306SDan Handley  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19b4315306SDan Handley  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20b4315306SDan Handley  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21b4315306SDan Handley  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22b4315306SDan Handley  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23b4315306SDan Handley  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24b4315306SDan Handley  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25b4315306SDan Handley  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26b4315306SDan Handley  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27b4315306SDan Handley  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28b4315306SDan Handley  * POSSIBILITY OF SUCH DAMAGE.
29b4315306SDan Handley  */
30b4315306SDan Handley #include <assert.h>
3116948ae1SJuan Castillo #include <bl_common.h>		/* For ARRAY_SIZE */
32b4315306SDan Handley #include <debug.h>
3316948ae1SJuan Castillo #include <firmware_image_package.h>
34b4315306SDan Handley #include <io_driver.h>
35b4315306SDan Handley #include <io_fip.h>
36b4315306SDan Handley #include <io_memmap.h>
37b4315306SDan Handley #include <io_storage.h>
38b4315306SDan Handley #include <platform_def.h>
39b4315306SDan Handley #include <string.h>
40b4315306SDan Handley 
41b4315306SDan Handley /* IO devices */
42b4315306SDan Handley static const io_dev_connector_t *fip_dev_con;
43b4315306SDan Handley static uintptr_t fip_dev_handle;
44b4315306SDan Handley static const io_dev_connector_t *memmap_dev_con;
45b4315306SDan Handley static uintptr_t memmap_dev_handle;
46b4315306SDan Handley 
47b4315306SDan Handley static const io_block_spec_t fip_block_spec = {
48b4315306SDan Handley 	.offset = PLAT_ARM_FIP_BASE,
49b4315306SDan Handley 	.length = PLAT_ARM_FIP_MAX_SIZE
50b4315306SDan Handley };
51b4315306SDan Handley 
5216948ae1SJuan Castillo static const io_uuid_spec_t bl2_uuid_spec = {
5316948ae1SJuan Castillo 	.uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
54b4315306SDan Handley };
55b4315306SDan Handley 
56*f59821d5SJuan Castillo static const io_uuid_spec_t scp_bl2_uuid_spec = {
57*f59821d5SJuan Castillo 	.uuid = UUID_SCP_FIRMWARE_SCP_BL2,
58b4315306SDan Handley };
59b4315306SDan Handley 
6016948ae1SJuan Castillo static const io_uuid_spec_t bl31_uuid_spec = {
6116948ae1SJuan Castillo 	.uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
62b4315306SDan Handley };
63b4315306SDan Handley 
6416948ae1SJuan Castillo static const io_uuid_spec_t bl32_uuid_spec = {
6516948ae1SJuan Castillo 	.uuid = UUID_SECURE_PAYLOAD_BL32,
66b4315306SDan Handley };
67b4315306SDan Handley 
6816948ae1SJuan Castillo static const io_uuid_spec_t bl33_uuid_spec = {
6916948ae1SJuan Castillo 	.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
70b4315306SDan Handley };
71b4315306SDan Handley 
72b4315306SDan Handley #if TRUSTED_BOARD_BOOT
73516beb58SJuan Castillo static const io_uuid_spec_t tb_fw_cert_uuid_spec = {
74516beb58SJuan Castillo 	.uuid = UUID_TRUSTED_BOOT_FW_CERT,
75b4315306SDan Handley };
76b4315306SDan Handley 
7716948ae1SJuan Castillo static const io_uuid_spec_t trusted_key_cert_uuid_spec = {
7816948ae1SJuan Castillo 	.uuid = UUID_TRUSTED_KEY_CERT,
79b4315306SDan Handley };
80b4315306SDan Handley 
81516beb58SJuan Castillo static const io_uuid_spec_t scp_fw_key_cert_uuid_spec = {
82516beb58SJuan Castillo 	.uuid = UUID_SCP_FW_KEY_CERT,
83b4315306SDan Handley };
84b4315306SDan Handley 
85516beb58SJuan Castillo static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = {
86516beb58SJuan Castillo 	.uuid = UUID_SOC_FW_KEY_CERT,
87b4315306SDan Handley };
88b4315306SDan Handley 
89516beb58SJuan Castillo static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = {
90516beb58SJuan Castillo 	.uuid = UUID_TRUSTED_OS_FW_KEY_CERT,
91b4315306SDan Handley };
92b4315306SDan Handley 
93516beb58SJuan Castillo static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = {
94516beb58SJuan Castillo 	.uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
95b4315306SDan Handley };
96b4315306SDan Handley 
97516beb58SJuan Castillo static const io_uuid_spec_t scp_fw_cert_uuid_spec = {
98516beb58SJuan Castillo 	.uuid = UUID_SCP_FW_CONTENT_CERT,
99b4315306SDan Handley };
100b4315306SDan Handley 
101516beb58SJuan Castillo static const io_uuid_spec_t soc_fw_cert_uuid_spec = {
102516beb58SJuan Castillo 	.uuid = UUID_SOC_FW_CONTENT_CERT,
103b4315306SDan Handley };
104b4315306SDan Handley 
105516beb58SJuan Castillo static const io_uuid_spec_t tos_fw_cert_uuid_spec = {
106516beb58SJuan Castillo 	.uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT,
107b4315306SDan Handley };
108b4315306SDan Handley 
109516beb58SJuan Castillo static const io_uuid_spec_t nt_fw_cert_uuid_spec = {
110516beb58SJuan Castillo 	.uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT,
111b4315306SDan Handley };
112b4315306SDan Handley #endif /* TRUSTED_BOARD_BOOT */
113b4315306SDan Handley 
11416948ae1SJuan Castillo 
115b4315306SDan Handley static int open_fip(const uintptr_t spec);
116b4315306SDan Handley static int open_memmap(const uintptr_t spec);
117b4315306SDan Handley 
118b4315306SDan Handley struct plat_io_policy {
119b4315306SDan Handley 	uintptr_t *dev_handle;
120b4315306SDan Handley 	uintptr_t image_spec;
121b4315306SDan Handley 	int (*check)(const uintptr_t spec);
122b4315306SDan Handley };
123b4315306SDan Handley 
12416948ae1SJuan Castillo /* By default, ARM platforms load images from the FIP */
125b4315306SDan Handley static const struct plat_io_policy policies[] = {
12616948ae1SJuan Castillo 	[FIP_IMAGE_ID] = {
127b4315306SDan Handley 		&memmap_dev_handle,
128b4315306SDan Handley 		(uintptr_t)&fip_block_spec,
129b4315306SDan Handley 		open_memmap
13016948ae1SJuan Castillo 	},
13116948ae1SJuan Castillo 	[BL2_IMAGE_ID] = {
132b4315306SDan Handley 		&fip_dev_handle,
13316948ae1SJuan Castillo 		(uintptr_t)&bl2_uuid_spec,
134b4315306SDan Handley 		open_fip
13516948ae1SJuan Castillo 	},
136*f59821d5SJuan Castillo 	[SCP_BL2_IMAGE_ID] = {
137b4315306SDan Handley 		&fip_dev_handle,
138*f59821d5SJuan Castillo 		(uintptr_t)&scp_bl2_uuid_spec,
139b4315306SDan Handley 		open_fip
14016948ae1SJuan Castillo 	},
14116948ae1SJuan Castillo 	[BL31_IMAGE_ID] = {
142b4315306SDan Handley 		&fip_dev_handle,
14316948ae1SJuan Castillo 		(uintptr_t)&bl31_uuid_spec,
144b4315306SDan Handley 		open_fip
14516948ae1SJuan Castillo 	},
14616948ae1SJuan Castillo 	[BL32_IMAGE_ID] = {
147b4315306SDan Handley 		&fip_dev_handle,
14816948ae1SJuan Castillo 		(uintptr_t)&bl32_uuid_spec,
149b4315306SDan Handley 		open_fip
15016948ae1SJuan Castillo 	},
15116948ae1SJuan Castillo 	[BL33_IMAGE_ID] = {
152b4315306SDan Handley 		&fip_dev_handle,
15316948ae1SJuan Castillo 		(uintptr_t)&bl33_uuid_spec,
154b4315306SDan Handley 		open_fip
15516948ae1SJuan Castillo 	},
156b4315306SDan Handley #if TRUSTED_BOARD_BOOT
157516beb58SJuan Castillo 	[TRUSTED_BOOT_FW_CERT_ID] = {
158b4315306SDan Handley 		&fip_dev_handle,
159516beb58SJuan Castillo 		(uintptr_t)&tb_fw_cert_uuid_spec,
160b4315306SDan Handley 		open_fip
16116948ae1SJuan Castillo 	},
16216948ae1SJuan Castillo 	[TRUSTED_KEY_CERT_ID] = {
163b4315306SDan Handley 		&fip_dev_handle,
16416948ae1SJuan Castillo 		(uintptr_t)&trusted_key_cert_uuid_spec,
165b4315306SDan Handley 		open_fip
16616948ae1SJuan Castillo 	},
167516beb58SJuan Castillo 	[SCP_FW_KEY_CERT_ID] = {
168b4315306SDan Handley 		&fip_dev_handle,
169516beb58SJuan Castillo 		(uintptr_t)&scp_fw_key_cert_uuid_spec,
170b4315306SDan Handley 		open_fip
17116948ae1SJuan Castillo 	},
172516beb58SJuan Castillo 	[SOC_FW_KEY_CERT_ID] = {
173b4315306SDan Handley 		&fip_dev_handle,
174516beb58SJuan Castillo 		(uintptr_t)&soc_fw_key_cert_uuid_spec,
175b4315306SDan Handley 		open_fip
17616948ae1SJuan Castillo 	},
177516beb58SJuan Castillo 	[TRUSTED_OS_FW_KEY_CERT_ID] = {
178b4315306SDan Handley 		&fip_dev_handle,
179516beb58SJuan Castillo 		(uintptr_t)&tos_fw_key_cert_uuid_spec,
180b4315306SDan Handley 		open_fip
18116948ae1SJuan Castillo 	},
182516beb58SJuan Castillo 	[NON_TRUSTED_FW_KEY_CERT_ID] = {
183b4315306SDan Handley 		&fip_dev_handle,
184516beb58SJuan Castillo 		(uintptr_t)&nt_fw_key_cert_uuid_spec,
185b4315306SDan Handley 		open_fip
18616948ae1SJuan Castillo 	},
187516beb58SJuan Castillo 	[SCP_FW_CONTENT_CERT_ID] = {
188b4315306SDan Handley 		&fip_dev_handle,
189516beb58SJuan Castillo 		(uintptr_t)&scp_fw_cert_uuid_spec,
190b4315306SDan Handley 		open_fip
19116948ae1SJuan Castillo 	},
192516beb58SJuan Castillo 	[SOC_FW_CONTENT_CERT_ID] = {
193b4315306SDan Handley 		&fip_dev_handle,
194516beb58SJuan Castillo 		(uintptr_t)&soc_fw_cert_uuid_spec,
195b4315306SDan Handley 		open_fip
19616948ae1SJuan Castillo 	},
197516beb58SJuan Castillo 	[TRUSTED_OS_FW_CONTENT_CERT_ID] = {
198b4315306SDan Handley 		&fip_dev_handle,
199516beb58SJuan Castillo 		(uintptr_t)&tos_fw_cert_uuid_spec,
200b4315306SDan Handley 		open_fip
20116948ae1SJuan Castillo 	},
202516beb58SJuan Castillo 	[NON_TRUSTED_FW_CONTENT_CERT_ID] = {
203b4315306SDan Handley 		&fip_dev_handle,
204516beb58SJuan Castillo 		(uintptr_t)&nt_fw_cert_uuid_spec,
205b4315306SDan Handley 		open_fip
20616948ae1SJuan Castillo 	},
207b4315306SDan Handley #endif /* TRUSTED_BOARD_BOOT */
208b4315306SDan Handley };
209b4315306SDan Handley 
210b4315306SDan Handley 
211b4315306SDan Handley /* Weak definitions may be overridden in specific ARM standard platform */
212b4315306SDan Handley #pragma weak plat_arm_io_setup
213b4315306SDan Handley #pragma weak plat_arm_get_alt_image_source
214b4315306SDan Handley 
215b4315306SDan Handley 
216b4315306SDan Handley static int open_fip(const uintptr_t spec)
217b4315306SDan Handley {
218b4315306SDan Handley 	int result;
219b4315306SDan Handley 	uintptr_t local_image_handle;
220b4315306SDan Handley 
221b4315306SDan Handley 	/* See if a Firmware Image Package is available */
22216948ae1SJuan Castillo 	result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
223e098e244SJuan Castillo 	if (result == 0) {
224b4315306SDan Handley 		result = io_open(fip_dev_handle, spec, &local_image_handle);
225e098e244SJuan Castillo 		if (result == 0) {
226b4315306SDan Handley 			VERBOSE("Using FIP\n");
227b4315306SDan Handley 			io_close(local_image_handle);
228b4315306SDan Handley 		}
229b4315306SDan Handley 	}
230b4315306SDan Handley 	return result;
231b4315306SDan Handley }
232b4315306SDan Handley 
233b4315306SDan Handley 
234b4315306SDan Handley static int open_memmap(const uintptr_t spec)
235b4315306SDan Handley {
236b4315306SDan Handley 	int result;
237b4315306SDan Handley 	uintptr_t local_image_handle;
238b4315306SDan Handley 
239b4315306SDan Handley 	result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL);
240e098e244SJuan Castillo 	if (result == 0) {
241b4315306SDan Handley 		result = io_open(memmap_dev_handle, spec, &local_image_handle);
242e098e244SJuan Castillo 		if (result == 0) {
243b4315306SDan Handley 			VERBOSE("Using Memmap\n");
244b4315306SDan Handley 			io_close(local_image_handle);
245b4315306SDan Handley 		}
246b4315306SDan Handley 	}
247b4315306SDan Handley 	return result;
248b4315306SDan Handley }
249b4315306SDan Handley 
250b4315306SDan Handley 
251b4315306SDan Handley void arm_io_setup(void)
252b4315306SDan Handley {
253b4315306SDan Handley 	int io_result;
254b4315306SDan Handley 
255b4315306SDan Handley 	io_result = register_io_dev_fip(&fip_dev_con);
256e098e244SJuan Castillo 	assert(io_result == 0);
257b4315306SDan Handley 
258b4315306SDan Handley 	io_result = register_io_dev_memmap(&memmap_dev_con);
259e098e244SJuan Castillo 	assert(io_result == 0);
260b4315306SDan Handley 
261b4315306SDan Handley 	/* Open connections to devices and cache the handles */
262b4315306SDan Handley 	io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL,
263b4315306SDan Handley 				&fip_dev_handle);
264e098e244SJuan Castillo 	assert(io_result == 0);
265b4315306SDan Handley 
266b4315306SDan Handley 	io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL,
267b4315306SDan Handley 				&memmap_dev_handle);
268e098e244SJuan Castillo 	assert(io_result == 0);
269b4315306SDan Handley 
270b4315306SDan Handley 	/* Ignore improbable errors in release builds */
271b4315306SDan Handley 	(void)io_result;
272b4315306SDan Handley }
273b4315306SDan Handley 
274b4315306SDan Handley void plat_arm_io_setup(void)
275b4315306SDan Handley {
276b4315306SDan Handley 	arm_io_setup();
277b4315306SDan Handley }
278b4315306SDan Handley 
279b4315306SDan Handley int plat_arm_get_alt_image_source(
28016948ae1SJuan Castillo 	unsigned int image_id __attribute__((unused)),
28116948ae1SJuan Castillo 	uintptr_t *dev_handle __attribute__((unused)),
28216948ae1SJuan Castillo 	uintptr_t *image_spec __attribute__((unused)))
283b4315306SDan Handley {
284b4315306SDan Handley 	/* By default do not try an alternative */
285e098e244SJuan Castillo 	return -ENOENT;
286b4315306SDan Handley }
287b4315306SDan Handley 
288b4315306SDan Handley /* Return an IO device handle and specification which can be used to access
289b4315306SDan Handley  * an image. Use this to enforce platform load policy */
29016948ae1SJuan Castillo int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
291b4315306SDan Handley 			  uintptr_t *image_spec)
292b4315306SDan Handley {
293e098e244SJuan Castillo 	int result;
294b4315306SDan Handley 	const struct plat_io_policy *policy;
295b4315306SDan Handley 
29616948ae1SJuan Castillo 	assert(image_id < ARRAY_SIZE(policies));
29716948ae1SJuan Castillo 
29816948ae1SJuan Castillo 	policy = &policies[image_id];
299b4315306SDan Handley 	result = policy->check(policy->image_spec);
300e098e244SJuan Castillo 	if (result == 0) {
301b4315306SDan Handley 		*image_spec = policy->image_spec;
302b4315306SDan Handley 		*dev_handle = *(policy->dev_handle);
303b4315306SDan Handley 	} else {
30416948ae1SJuan Castillo 		VERBOSE("Trying alternative IO\n");
30516948ae1SJuan Castillo 		result = plat_arm_get_alt_image_source(image_id, dev_handle,
30616948ae1SJuan Castillo 						       image_spec);
307b4315306SDan Handley 	}
30816948ae1SJuan Castillo 
309b4315306SDan Handley 	return result;
310b4315306SDan Handley }
311436223deSYatharth Kochar 
312436223deSYatharth Kochar /*
313436223deSYatharth Kochar  * See if a Firmware Image Package is available,
314436223deSYatharth Kochar  * by checking if TOC is valid or not.
315436223deSYatharth Kochar  */
316436223deSYatharth Kochar int arm_io_is_toc_valid(void)
317436223deSYatharth Kochar {
318436223deSYatharth Kochar 	int result;
319436223deSYatharth Kochar 
320436223deSYatharth Kochar 	result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
321436223deSYatharth Kochar 
322436223deSYatharth Kochar 	return (result == 0);
323436223deSYatharth Kochar }
324436223deSYatharth Kochar 
325