xref: /rk3399_ARM-atf/plat/arm/common/arm_io_storage.c (revision c228956afa415685d7555578f252dfe4d0d1695e)
1 /*
2  * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 #include <assert.h>
7 #include <debug.h>
8 #include <firmware_image_package.h>
9 #include <io_driver.h>
10 #include <io_fip.h>
11 #include <io_memmap.h>
12 #include <io_storage.h>
13 #include <platform_def.h>
14 #include <string.h>
15 #include <utils.h>
16 
17 /* IO devices */
18 static const io_dev_connector_t *fip_dev_con;
19 static uintptr_t fip_dev_handle;
20 static const io_dev_connector_t *memmap_dev_con;
21 static uintptr_t memmap_dev_handle;
22 
23 static const io_block_spec_t fip_block_spec = {
24 	.offset = PLAT_ARM_FIP_BASE,
25 	.length = PLAT_ARM_FIP_MAX_SIZE
26 };
27 
28 static const io_uuid_spec_t bl2_uuid_spec = {
29 	.uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
30 };
31 
32 static const io_uuid_spec_t scp_bl2_uuid_spec = {
33 	.uuid = UUID_SCP_FIRMWARE_SCP_BL2,
34 };
35 
36 static const io_uuid_spec_t bl31_uuid_spec = {
37 	.uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
38 };
39 
40 static const io_uuid_spec_t bl32_uuid_spec = {
41 	.uuid = UUID_SECURE_PAYLOAD_BL32,
42 };
43 
44 static const io_uuid_spec_t bl32_extra1_uuid_spec = {
45 	.uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1,
46 };
47 
48 static const io_uuid_spec_t bl32_extra2_uuid_spec = {
49 	.uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2,
50 };
51 
52 static const io_uuid_spec_t bl33_uuid_spec = {
53 	.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
54 };
55 
56 static const io_uuid_spec_t tb_fw_config_uuid_spec = {
57 	.uuid = UUID_TB_FW_CONFIG,
58 };
59 
60 #if TRUSTED_BOARD_BOOT
61 static const io_uuid_spec_t tb_fw_cert_uuid_spec = {
62 	.uuid = UUID_TRUSTED_BOOT_FW_CERT,
63 };
64 
65 static const io_uuid_spec_t trusted_key_cert_uuid_spec = {
66 	.uuid = UUID_TRUSTED_KEY_CERT,
67 };
68 
69 static const io_uuid_spec_t scp_fw_key_cert_uuid_spec = {
70 	.uuid = UUID_SCP_FW_KEY_CERT,
71 };
72 
73 static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = {
74 	.uuid = UUID_SOC_FW_KEY_CERT,
75 };
76 
77 static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = {
78 	.uuid = UUID_TRUSTED_OS_FW_KEY_CERT,
79 };
80 
81 static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = {
82 	.uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
83 };
84 
85 static const io_uuid_spec_t scp_fw_cert_uuid_spec = {
86 	.uuid = UUID_SCP_FW_CONTENT_CERT,
87 };
88 
89 static const io_uuid_spec_t soc_fw_cert_uuid_spec = {
90 	.uuid = UUID_SOC_FW_CONTENT_CERT,
91 };
92 
93 static const io_uuid_spec_t tos_fw_cert_uuid_spec = {
94 	.uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT,
95 };
96 
97 static const io_uuid_spec_t nt_fw_cert_uuid_spec = {
98 	.uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT,
99 };
100 #endif /* TRUSTED_BOARD_BOOT */
101 
102 
103 static int open_fip(const uintptr_t spec);
104 static int open_memmap(const uintptr_t spec);
105 
106 struct plat_io_policy {
107 	uintptr_t *dev_handle;
108 	uintptr_t image_spec;
109 	int (*check)(const uintptr_t spec);
110 };
111 
112 /* By default, ARM platforms load images from the FIP */
113 static const struct plat_io_policy policies[] = {
114 	[FIP_IMAGE_ID] = {
115 		&memmap_dev_handle,
116 		(uintptr_t)&fip_block_spec,
117 		open_memmap
118 	},
119 	[BL2_IMAGE_ID] = {
120 		&fip_dev_handle,
121 		(uintptr_t)&bl2_uuid_spec,
122 		open_fip
123 	},
124 	[SCP_BL2_IMAGE_ID] = {
125 		&fip_dev_handle,
126 		(uintptr_t)&scp_bl2_uuid_spec,
127 		open_fip
128 	},
129 	[BL31_IMAGE_ID] = {
130 		&fip_dev_handle,
131 		(uintptr_t)&bl31_uuid_spec,
132 		open_fip
133 	},
134 	[BL32_IMAGE_ID] = {
135 		&fip_dev_handle,
136 		(uintptr_t)&bl32_uuid_spec,
137 		open_fip
138 	},
139 	[BL32_EXTRA1_IMAGE_ID] = {
140 		&fip_dev_handle,
141 		(uintptr_t)&bl32_extra1_uuid_spec,
142 		open_fip
143 	},
144 	[BL32_EXTRA2_IMAGE_ID] = {
145 		&fip_dev_handle,
146 		(uintptr_t)&bl32_extra2_uuid_spec,
147 		open_fip
148 	},
149 	[BL33_IMAGE_ID] = {
150 		&fip_dev_handle,
151 		(uintptr_t)&bl33_uuid_spec,
152 		open_fip
153 	},
154 	[TB_FW_CONFIG_ID] = {
155 		&fip_dev_handle,
156 		(uintptr_t)&tb_fw_config_uuid_spec,
157 		open_fip
158 	},
159 #if TRUSTED_BOARD_BOOT
160 	[TRUSTED_BOOT_FW_CERT_ID] = {
161 		&fip_dev_handle,
162 		(uintptr_t)&tb_fw_cert_uuid_spec,
163 		open_fip
164 	},
165 	[TRUSTED_KEY_CERT_ID] = {
166 		&fip_dev_handle,
167 		(uintptr_t)&trusted_key_cert_uuid_spec,
168 		open_fip
169 	},
170 	[SCP_FW_KEY_CERT_ID] = {
171 		&fip_dev_handle,
172 		(uintptr_t)&scp_fw_key_cert_uuid_spec,
173 		open_fip
174 	},
175 	[SOC_FW_KEY_CERT_ID] = {
176 		&fip_dev_handle,
177 		(uintptr_t)&soc_fw_key_cert_uuid_spec,
178 		open_fip
179 	},
180 	[TRUSTED_OS_FW_KEY_CERT_ID] = {
181 		&fip_dev_handle,
182 		(uintptr_t)&tos_fw_key_cert_uuid_spec,
183 		open_fip
184 	},
185 	[NON_TRUSTED_FW_KEY_CERT_ID] = {
186 		&fip_dev_handle,
187 		(uintptr_t)&nt_fw_key_cert_uuid_spec,
188 		open_fip
189 	},
190 	[SCP_FW_CONTENT_CERT_ID] = {
191 		&fip_dev_handle,
192 		(uintptr_t)&scp_fw_cert_uuid_spec,
193 		open_fip
194 	},
195 	[SOC_FW_CONTENT_CERT_ID] = {
196 		&fip_dev_handle,
197 		(uintptr_t)&soc_fw_cert_uuid_spec,
198 		open_fip
199 	},
200 	[TRUSTED_OS_FW_CONTENT_CERT_ID] = {
201 		&fip_dev_handle,
202 		(uintptr_t)&tos_fw_cert_uuid_spec,
203 		open_fip
204 	},
205 	[NON_TRUSTED_FW_CONTENT_CERT_ID] = {
206 		&fip_dev_handle,
207 		(uintptr_t)&nt_fw_cert_uuid_spec,
208 		open_fip
209 	},
210 #endif /* TRUSTED_BOARD_BOOT */
211 };
212 
213 
214 /* Weak definitions may be overridden in specific ARM standard platform */
215 #pragma weak plat_arm_io_setup
216 #pragma weak plat_arm_get_alt_image_source
217 
218 
219 static int open_fip(const uintptr_t spec)
220 {
221 	int result;
222 	uintptr_t local_image_handle;
223 
224 	/* See if a Firmware Image Package is available */
225 	result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
226 	if (result == 0) {
227 		result = io_open(fip_dev_handle, spec, &local_image_handle);
228 		if (result == 0) {
229 			VERBOSE("Using FIP\n");
230 			io_close(local_image_handle);
231 		}
232 	}
233 	return result;
234 }
235 
236 
237 static int open_memmap(const uintptr_t spec)
238 {
239 	int result;
240 	uintptr_t local_image_handle;
241 
242 	result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL);
243 	if (result == 0) {
244 		result = io_open(memmap_dev_handle, spec, &local_image_handle);
245 		if (result == 0) {
246 			VERBOSE("Using Memmap\n");
247 			io_close(local_image_handle);
248 		}
249 	}
250 	return result;
251 }
252 
253 
254 void arm_io_setup(void)
255 {
256 	int io_result;
257 
258 	io_result = register_io_dev_fip(&fip_dev_con);
259 	assert(io_result == 0);
260 
261 	io_result = register_io_dev_memmap(&memmap_dev_con);
262 	assert(io_result == 0);
263 
264 	/* Open connections to devices and cache the handles */
265 	io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL,
266 				&fip_dev_handle);
267 	assert(io_result == 0);
268 
269 	io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL,
270 				&memmap_dev_handle);
271 	assert(io_result == 0);
272 
273 	/* Ignore improbable errors in release builds */
274 	(void)io_result;
275 }
276 
277 void plat_arm_io_setup(void)
278 {
279 	arm_io_setup();
280 }
281 
282 int plat_arm_get_alt_image_source(
283 	unsigned int image_id __unused,
284 	uintptr_t *dev_handle __unused,
285 	uintptr_t *image_spec __unused)
286 {
287 	/* By default do not try an alternative */
288 	return -ENOENT;
289 }
290 
291 /* Return an IO device handle and specification which can be used to access
292  * an image. Use this to enforce platform load policy */
293 int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
294 			  uintptr_t *image_spec)
295 {
296 	int result;
297 	const struct plat_io_policy *policy;
298 
299 	assert(image_id < ARRAY_SIZE(policies));
300 
301 	policy = &policies[image_id];
302 	result = policy->check(policy->image_spec);
303 	if (result == 0) {
304 		*image_spec = policy->image_spec;
305 		*dev_handle = *(policy->dev_handle);
306 	} else {
307 		VERBOSE("Trying alternative IO\n");
308 		result = plat_arm_get_alt_image_source(image_id, dev_handle,
309 						       image_spec);
310 	}
311 
312 	return result;
313 }
314 
315 /*
316  * See if a Firmware Image Package is available,
317  * by checking if TOC is valid or not.
318  */
319 int arm_io_is_toc_valid(void)
320 {
321 	int result;
322 
323 	result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
324 
325 	return (result == 0);
326 }
327 
328