xref: /rk3399_ARM-atf/plat/arm/common/arm_io_storage.c (revision e098e244a25017d8298d63a8bf04e9151b52ac3a)
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 
5616948ae1SJuan Castillo static const io_uuid_spec_t bl30_uuid_spec = {
5716948ae1SJuan Castillo 	.uuid = UUID_SCP_FIRMWARE_BL30,
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
7316948ae1SJuan Castillo static const io_uuid_spec_t bl2_cert_uuid_spec = {
7416948ae1SJuan Castillo 	.uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2_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 
8116948ae1SJuan Castillo static const io_uuid_spec_t bl30_key_cert_uuid_spec = {
8216948ae1SJuan Castillo 	.uuid = UUID_SCP_FIRMWARE_BL30_KEY_CERT,
83b4315306SDan Handley };
84b4315306SDan Handley 
8516948ae1SJuan Castillo static const io_uuid_spec_t bl31_key_cert_uuid_spec = {
8616948ae1SJuan Castillo 	.uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31_KEY_CERT,
87b4315306SDan Handley };
88b4315306SDan Handley 
8916948ae1SJuan Castillo static const io_uuid_spec_t bl32_key_cert_uuid_spec = {
9016948ae1SJuan Castillo 	.uuid = UUID_SECURE_PAYLOAD_BL32_KEY_CERT,
91b4315306SDan Handley };
92b4315306SDan Handley 
9316948ae1SJuan Castillo static const io_uuid_spec_t bl33_key_cert_uuid_spec = {
9416948ae1SJuan Castillo 	.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33_KEY_CERT,
95b4315306SDan Handley };
96b4315306SDan Handley 
9716948ae1SJuan Castillo static const io_uuid_spec_t bl30_cert_uuid_spec = {
9816948ae1SJuan Castillo 	.uuid = UUID_SCP_FIRMWARE_BL30_CERT,
99b4315306SDan Handley };
100b4315306SDan Handley 
10116948ae1SJuan Castillo static const io_uuid_spec_t bl31_cert_uuid_spec = {
10216948ae1SJuan Castillo 	.uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31_CERT,
103b4315306SDan Handley };
104b4315306SDan Handley 
10516948ae1SJuan Castillo static const io_uuid_spec_t bl32_cert_uuid_spec = {
10616948ae1SJuan Castillo 	.uuid = UUID_SECURE_PAYLOAD_BL32_CERT,
107b4315306SDan Handley };
108b4315306SDan Handley 
10916948ae1SJuan Castillo static const io_uuid_spec_t bl33_cert_uuid_spec = {
11016948ae1SJuan Castillo 	.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33_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 	},
13616948ae1SJuan Castillo 	[BL30_IMAGE_ID] = {
137b4315306SDan Handley 		&fip_dev_handle,
13816948ae1SJuan Castillo 		(uintptr_t)&bl30_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
15716948ae1SJuan Castillo 	[BL2_CERT_ID] = {
158b4315306SDan Handley 		&fip_dev_handle,
15916948ae1SJuan Castillo 		(uintptr_t)&bl2_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 	},
16716948ae1SJuan Castillo 	[BL30_KEY_CERT_ID] = {
168b4315306SDan Handley 		&fip_dev_handle,
16916948ae1SJuan Castillo 		(uintptr_t)&bl30_key_cert_uuid_spec,
170b4315306SDan Handley 		open_fip
17116948ae1SJuan Castillo 	},
17216948ae1SJuan Castillo 	[BL31_KEY_CERT_ID] = {
173b4315306SDan Handley 		&fip_dev_handle,
17416948ae1SJuan Castillo 		(uintptr_t)&bl31_key_cert_uuid_spec,
175b4315306SDan Handley 		open_fip
17616948ae1SJuan Castillo 	},
17716948ae1SJuan Castillo 	[BL32_KEY_CERT_ID] = {
178b4315306SDan Handley 		&fip_dev_handle,
17916948ae1SJuan Castillo 		(uintptr_t)&bl32_key_cert_uuid_spec,
180b4315306SDan Handley 		open_fip
18116948ae1SJuan Castillo 	},
18216948ae1SJuan Castillo 	[BL33_KEY_CERT_ID] = {
183b4315306SDan Handley 		&fip_dev_handle,
18416948ae1SJuan Castillo 		(uintptr_t)&bl33_key_cert_uuid_spec,
185b4315306SDan Handley 		open_fip
18616948ae1SJuan Castillo 	},
18716948ae1SJuan Castillo 	[BL30_CERT_ID] = {
188b4315306SDan Handley 		&fip_dev_handle,
18916948ae1SJuan Castillo 		(uintptr_t)&bl30_cert_uuid_spec,
190b4315306SDan Handley 		open_fip
19116948ae1SJuan Castillo 	},
19216948ae1SJuan Castillo 	[BL31_CERT_ID] = {
193b4315306SDan Handley 		&fip_dev_handle,
19416948ae1SJuan Castillo 		(uintptr_t)&bl31_cert_uuid_spec,
195b4315306SDan Handley 		open_fip
19616948ae1SJuan Castillo 	},
19716948ae1SJuan Castillo 	[BL32_CERT_ID] = {
198b4315306SDan Handley 		&fip_dev_handle,
19916948ae1SJuan Castillo 		(uintptr_t)&bl32_cert_uuid_spec,
200b4315306SDan Handley 		open_fip
20116948ae1SJuan Castillo 	},
20216948ae1SJuan Castillo 	[BL33_CERT_ID] = {
203b4315306SDan Handley 		&fip_dev_handle,
20416948ae1SJuan Castillo 		(uintptr_t)&bl33_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);
223*e098e244SJuan Castillo 	if (result == 0) {
224b4315306SDan Handley 		result = io_open(fip_dev_handle, spec, &local_image_handle);
225*e098e244SJuan 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);
240*e098e244SJuan Castillo 	if (result == 0) {
241b4315306SDan Handley 		result = io_open(memmap_dev_handle, spec, &local_image_handle);
242*e098e244SJuan 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);
256*e098e244SJuan Castillo 	assert(io_result == 0);
257b4315306SDan Handley 
258b4315306SDan Handley 	io_result = register_io_dev_memmap(&memmap_dev_con);
259*e098e244SJuan 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);
264*e098e244SJuan 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);
268*e098e244SJuan 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 */
285*e098e244SJuan 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 {
293*e098e244SJuan 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);
300*e098e244SJuan 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 }
311