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