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