1 /*
2  * Copyright (c) 2015-2017, 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 #if TRUSTED_BOARD_BOOT
57 static const io_uuid_spec_t tb_fw_cert_uuid_spec = {
58 	.uuid = UUID_TRUSTED_BOOT_FW_CERT,
59 };
60 
61 static const io_uuid_spec_t trusted_key_cert_uuid_spec = {
62 	.uuid = UUID_TRUSTED_KEY_CERT,
63 };
64 
65 static const io_uuid_spec_t scp_fw_key_cert_uuid_spec = {
66 	.uuid = UUID_SCP_FW_KEY_CERT,
67 };
68 
69 static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = {
70 	.uuid = UUID_SOC_FW_KEY_CERT,
71 };
72 
73 static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = {
74 	.uuid = UUID_TRUSTED_OS_FW_KEY_CERT,
75 };
76 
77 static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = {
78 	.uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
79 };
80 
81 static const io_uuid_spec_t scp_fw_cert_uuid_spec = {
82 	.uuid = UUID_SCP_FW_CONTENT_CERT,
83 };
84 
85 static const io_uuid_spec_t soc_fw_cert_uuid_spec = {
86 	.uuid = UUID_SOC_FW_CONTENT_CERT,
87 };
88 
89 static const io_uuid_spec_t tos_fw_cert_uuid_spec = {
90 	.uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT,
91 };
92 
93 static const io_uuid_spec_t nt_fw_cert_uuid_spec = {
94 	.uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT,
95 };
96 #endif /* TRUSTED_BOARD_BOOT */
97 
98 
99 static int open_fip(const uintptr_t spec);
100 static int open_memmap(const uintptr_t spec);
101 
102 struct plat_io_policy {
103 	uintptr_t *dev_handle;
104 	uintptr_t image_spec;
105 	int (*check)(const uintptr_t spec);
106 };
107 
108 /* By default, ARM platforms load images from the FIP */
109 static const struct plat_io_policy policies[] = {
110 	[FIP_IMAGE_ID] = {
111 		&memmap_dev_handle,
112 		(uintptr_t)&fip_block_spec,
113 		open_memmap
114 	},
115 	[BL2_IMAGE_ID] = {
116 		&fip_dev_handle,
117 		(uintptr_t)&bl2_uuid_spec,
118 		open_fip
119 	},
120 	[SCP_BL2_IMAGE_ID] = {
121 		&fip_dev_handle,
122 		(uintptr_t)&scp_bl2_uuid_spec,
123 		open_fip
124 	},
125 	[BL31_IMAGE_ID] = {
126 		&fip_dev_handle,
127 		(uintptr_t)&bl31_uuid_spec,
128 		open_fip
129 	},
130 	[BL32_IMAGE_ID] = {
131 		&fip_dev_handle,
132 		(uintptr_t)&bl32_uuid_spec,
133 		open_fip
134 	},
135 	[BL32_EXTRA1_IMAGE_ID] = {
136 		&fip_dev_handle,
137 		(uintptr_t)&bl32_extra1_uuid_spec,
138 		open_fip
139 	},
140 	[BL32_EXTRA2_IMAGE_ID] = {
141 		&fip_dev_handle,
142 		(uintptr_t)&bl32_extra2_uuid_spec,
143 		open_fip
144 	},
145 	[BL33_IMAGE_ID] = {
146 		&fip_dev_handle,
147 		(uintptr_t)&bl33_uuid_spec,
148 		open_fip
149 	},
150 #if TRUSTED_BOARD_BOOT
151 	[TRUSTED_BOOT_FW_CERT_ID] = {
152 		&fip_dev_handle,
153 		(uintptr_t)&tb_fw_cert_uuid_spec,
154 		open_fip
155 	},
156 	[TRUSTED_KEY_CERT_ID] = {
157 		&fip_dev_handle,
158 		(uintptr_t)&trusted_key_cert_uuid_spec,
159 		open_fip
160 	},
161 	[SCP_FW_KEY_CERT_ID] = {
162 		&fip_dev_handle,
163 		(uintptr_t)&scp_fw_key_cert_uuid_spec,
164 		open_fip
165 	},
166 	[SOC_FW_KEY_CERT_ID] = {
167 		&fip_dev_handle,
168 		(uintptr_t)&soc_fw_key_cert_uuid_spec,
169 		open_fip
170 	},
171 	[TRUSTED_OS_FW_KEY_CERT_ID] = {
172 		&fip_dev_handle,
173 		(uintptr_t)&tos_fw_key_cert_uuid_spec,
174 		open_fip
175 	},
176 	[NON_TRUSTED_FW_KEY_CERT_ID] = {
177 		&fip_dev_handle,
178 		(uintptr_t)&nt_fw_key_cert_uuid_spec,
179 		open_fip
180 	},
181 	[SCP_FW_CONTENT_CERT_ID] = {
182 		&fip_dev_handle,
183 		(uintptr_t)&scp_fw_cert_uuid_spec,
184 		open_fip
185 	},
186 	[SOC_FW_CONTENT_CERT_ID] = {
187 		&fip_dev_handle,
188 		(uintptr_t)&soc_fw_cert_uuid_spec,
189 		open_fip
190 	},
191 	[TRUSTED_OS_FW_CONTENT_CERT_ID] = {
192 		&fip_dev_handle,
193 		(uintptr_t)&tos_fw_cert_uuid_spec,
194 		open_fip
195 	},
196 	[NON_TRUSTED_FW_CONTENT_CERT_ID] = {
197 		&fip_dev_handle,
198 		(uintptr_t)&nt_fw_cert_uuid_spec,
199 		open_fip
200 	},
201 #endif /* TRUSTED_BOARD_BOOT */
202 };
203 
204 
205 /* Weak definitions may be overridden in specific ARM standard platform */
206 #pragma weak plat_arm_io_setup
207 #pragma weak plat_arm_get_alt_image_source
208 
209 
open_fip(const uintptr_t spec)210 static int open_fip(const uintptr_t spec)
211 {
212 	int result;
213 	uintptr_t local_image_handle;
214 
215 	/* See if a Firmware Image Package is available */
216 	result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
217 	if (result == 0) {
218 		result = io_open(fip_dev_handle, spec, &local_image_handle);
219 		if (result == 0) {
220 			VERBOSE("Using FIP\n");
221 			io_close(local_image_handle);
222 		}
223 	}
224 	return result;
225 }
226 
227 
open_memmap(const uintptr_t spec)228 static int open_memmap(const uintptr_t spec)
229 {
230 	int result;
231 	uintptr_t local_image_handle;
232 
233 	result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL);
234 	if (result == 0) {
235 		result = io_open(memmap_dev_handle, spec, &local_image_handle);
236 		if (result == 0) {
237 			VERBOSE("Using Memmap\n");
238 			io_close(local_image_handle);
239 		}
240 	}
241 	return result;
242 }
243 
244 
arm_io_setup(void)245 void arm_io_setup(void)
246 {
247 	int io_result;
248 
249 	io_result = register_io_dev_fip(&fip_dev_con);
250 	assert(io_result == 0);
251 
252 	io_result = register_io_dev_memmap(&memmap_dev_con);
253 	assert(io_result == 0);
254 
255 	/* Open connections to devices and cache the handles */
256 	io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL,
257 				&fip_dev_handle);
258 	assert(io_result == 0);
259 
260 	io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL,
261 				&memmap_dev_handle);
262 	assert(io_result == 0);
263 
264 	/* Ignore improbable errors in release builds */
265 	(void)io_result;
266 }
267 
plat_arm_io_setup(void)268 void plat_arm_io_setup(void)
269 {
270 	arm_io_setup();
271 }
272 
plat_arm_get_alt_image_source(unsigned int image_id __unused,uintptr_t * dev_handle __unused,uintptr_t * image_spec __unused)273 int plat_arm_get_alt_image_source(
274 	unsigned int image_id __unused,
275 	uintptr_t *dev_handle __unused,
276 	uintptr_t *image_spec __unused)
277 {
278 	/* By default do not try an alternative */
279 	return -ENOENT;
280 }
281 
282 /* Return an IO device handle and specification which can be used to access
283  * an image. Use this to enforce platform load policy */
plat_get_image_source(unsigned int image_id,uintptr_t * dev_handle,uintptr_t * image_spec)284 int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
285 			  uintptr_t *image_spec)
286 {
287 	int result;
288 	const struct plat_io_policy *policy;
289 
290 	assert(image_id < ARRAY_SIZE(policies));
291 
292 	policy = &policies[image_id];
293 	result = policy->check(policy->image_spec);
294 	if (result == 0) {
295 		*image_spec = policy->image_spec;
296 		*dev_handle = *(policy->dev_handle);
297 	} else {
298 		VERBOSE("Trying alternative IO\n");
299 		result = plat_arm_get_alt_image_source(image_id, dev_handle,
300 						       image_spec);
301 	}
302 
303 	return result;
304 }
305 
306 /*
307  * See if a Firmware Image Package is available,
308  * by checking if TOC is valid or not.
309  */
arm_io_is_toc_valid(void)310 int arm_io_is_toc_valid(void)
311 {
312 	int result;
313 
314 	result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
315 
316 	return (result == 0);
317 }
318 
319