1 /*
2 * Copyright (c) 2019-2020, 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 <common/debug.h>
11 #include <drivers/io/io_driver.h>
12 #include <drivers/io/io_fip.h>
13 #include <drivers/io/io_memmap.h>
14 #include <drivers/io/io_storage.h>
15 #include <tools_share/firmware_image_package.h>
16
17 #include <cmn_plat_def.h>
18 #include <cmn_plat_util.h>
19 #include <plat_brcm.h>
20 #include <platform_def.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_BRCM_FIP_BASE,
30 .length = PLAT_BRCM_FIP_MAX_SIZE
31 };
32
33 static const io_block_spec_t qspi_fip_block_spec = {
34 .offset = PLAT_BRCM_FIP_QSPI_BASE,
35 .length = PLAT_BRCM_FIP_MAX_SIZE
36 };
37
38 static const io_block_spec_t nand_fip_block_spec = {
39 .offset = PLAT_BRCM_FIP_NAND_BASE,
40 .length = PLAT_BRCM_FIP_MAX_SIZE
41 };
42
43 static const io_uuid_spec_t bl2_uuid_spec = {
44 .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
45 };
46
47 static const io_uuid_spec_t scp_bl2_uuid_spec = {
48 .uuid = UUID_SCP_FIRMWARE_SCP_BL2,
49 };
50
51 static const io_uuid_spec_t bl31_uuid_spec = {
52 .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
53 };
54
55 static const io_uuid_spec_t bl32_uuid_spec = {
56 .uuid = UUID_SECURE_PAYLOAD_BL32,
57 };
58
59 static const io_uuid_spec_t bl32_extra1_uuid_spec = {
60 .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1,
61 };
62
63 static const io_uuid_spec_t bl32_extra2_uuid_spec = {
64 .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2,
65 };
66
67 static const io_uuid_spec_t bl33_uuid_spec = {
68 .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
69 };
70
71 static const io_uuid_spec_t tb_fw_config_uuid_spec = {
72 .uuid = UUID_TB_FW_CONFIG,
73 };
74
75 static const io_uuid_spec_t hw_config_uuid_spec = {
76 .uuid = UUID_HW_CONFIG,
77 };
78
79 static const io_uuid_spec_t soc_fw_config_uuid_spec = {
80 .uuid = UUID_SOC_FW_CONFIG,
81 };
82
83 static const io_uuid_spec_t tos_fw_config_uuid_spec = {
84 .uuid = UUID_TOS_FW_CONFIG,
85 };
86
87 static const io_uuid_spec_t nt_fw_config_uuid_spec = {
88 .uuid = UUID_NT_FW_CONFIG,
89 };
90
91 #if TRUSTED_BOARD_BOOT
92 static const io_uuid_spec_t tb_fw_cert_uuid_spec = {
93 .uuid = UUID_TRUSTED_BOOT_FW_CERT,
94 };
95
96 static const io_uuid_spec_t trusted_key_cert_uuid_spec = {
97 .uuid = UUID_TRUSTED_KEY_CERT,
98 };
99
100 static const io_uuid_spec_t scp_fw_key_cert_uuid_spec = {
101 .uuid = UUID_SCP_FW_KEY_CERT,
102 };
103
104 static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = {
105 .uuid = UUID_SOC_FW_KEY_CERT,
106 };
107
108 static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = {
109 .uuid = UUID_TRUSTED_OS_FW_KEY_CERT,
110 };
111
112 static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = {
113 .uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
114 };
115
116 static const io_uuid_spec_t scp_fw_cert_uuid_spec = {
117 .uuid = UUID_SCP_FW_CONTENT_CERT,
118 };
119
120 static const io_uuid_spec_t soc_fw_cert_uuid_spec = {
121 .uuid = UUID_SOC_FW_CONTENT_CERT,
122 };
123
124 static const io_uuid_spec_t tos_fw_cert_uuid_spec = {
125 .uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT,
126 };
127
128 static const io_uuid_spec_t nt_fw_cert_uuid_spec = {
129 .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT,
130 };
131 #endif /* TRUSTED_BOARD_BOOT */
132
133 static int open_fip(const uintptr_t spec);
134 static int open_memmap(const uintptr_t spec);
135 static int open_qspi(const uintptr_t spec);
136 static int open_nand(const uintptr_t spec);
137
138 struct plat_io_policy {
139 uintptr_t *dev_handle;
140 uintptr_t image_spec;
141 int (*check)(const uintptr_t spec);
142 };
143
144 /* By default, BRCM platforms load images from the FIP */
145 static const struct plat_io_policy policies[] = {
146 [FIP_IMAGE_ID] = {
147 &memmap_dev_handle,
148 (uintptr_t)&fip_block_spec,
149 open_memmap
150 },
151 [BL2_IMAGE_ID] = {
152 &fip_dev_handle,
153 (uintptr_t)&bl2_uuid_spec,
154 open_fip
155 },
156 [SCP_BL2_IMAGE_ID] = {
157 &fip_dev_handle,
158 (uintptr_t)&scp_bl2_uuid_spec,
159 open_fip
160 },
161 [BL31_IMAGE_ID] = {
162 &fip_dev_handle,
163 (uintptr_t)&bl31_uuid_spec,
164 open_fip
165 },
166 [BL32_IMAGE_ID] = {
167 &fip_dev_handle,
168 (uintptr_t)&bl32_uuid_spec,
169 open_fip
170 },
171 [BL32_EXTRA1_IMAGE_ID] = {
172 &fip_dev_handle,
173 (uintptr_t)&bl32_extra1_uuid_spec,
174 open_fip
175 },
176 [BL32_EXTRA2_IMAGE_ID] = {
177 &fip_dev_handle,
178 (uintptr_t)&bl32_extra2_uuid_spec,
179 open_fip
180 },
181 [BL33_IMAGE_ID] = {
182 &fip_dev_handle,
183 (uintptr_t)&bl33_uuid_spec,
184 open_fip
185 },
186 [TB_FW_CONFIG_ID] = {
187 &fip_dev_handle,
188 (uintptr_t)&tb_fw_config_uuid_spec,
189 open_fip
190 },
191 [HW_CONFIG_ID] = {
192 &fip_dev_handle,
193 (uintptr_t)&hw_config_uuid_spec,
194 open_fip
195 },
196 [SOC_FW_CONFIG_ID] = {
197 &fip_dev_handle,
198 (uintptr_t)&soc_fw_config_uuid_spec,
199 open_fip
200 },
201 [TOS_FW_CONFIG_ID] = {
202 &fip_dev_handle,
203 (uintptr_t)&tos_fw_config_uuid_spec,
204 open_fip
205 },
206 [NT_FW_CONFIG_ID] = {
207 &fip_dev_handle,
208 (uintptr_t)&nt_fw_config_uuid_spec,
209 open_fip
210 },
211 #if TRUSTED_BOARD_BOOT
212 [TRUSTED_BOOT_FW_CERT_ID] = {
213 &fip_dev_handle,
214 (uintptr_t)&tb_fw_cert_uuid_spec,
215 open_fip
216 },
217 [TRUSTED_KEY_CERT_ID] = {
218 &fip_dev_handle,
219 (uintptr_t)&trusted_key_cert_uuid_spec,
220 open_fip
221 },
222 [SCP_FW_KEY_CERT_ID] = {
223 &fip_dev_handle,
224 (uintptr_t)&scp_fw_key_cert_uuid_spec,
225 open_fip
226 },
227 [SOC_FW_KEY_CERT_ID] = {
228 &fip_dev_handle,
229 (uintptr_t)&soc_fw_key_cert_uuid_spec,
230 open_fip
231 },
232 [TRUSTED_OS_FW_KEY_CERT_ID] = {
233 &fip_dev_handle,
234 (uintptr_t)&tos_fw_key_cert_uuid_spec,
235 open_fip
236 },
237 [NON_TRUSTED_FW_KEY_CERT_ID] = {
238 &fip_dev_handle,
239 (uintptr_t)&nt_fw_key_cert_uuid_spec,
240 open_fip
241 },
242 [SCP_FW_CONTENT_CERT_ID] = {
243 &fip_dev_handle,
244 (uintptr_t)&scp_fw_cert_uuid_spec,
245 open_fip
246 },
247 [SOC_FW_CONTENT_CERT_ID] = {
248 &fip_dev_handle,
249 (uintptr_t)&soc_fw_cert_uuid_spec,
250 open_fip
251 },
252 [TRUSTED_OS_FW_CONTENT_CERT_ID] = {
253 &fip_dev_handle,
254 (uintptr_t)&tos_fw_cert_uuid_spec,
255 open_fip
256 },
257 [NON_TRUSTED_FW_CONTENT_CERT_ID] = {
258 &fip_dev_handle,
259 (uintptr_t)&nt_fw_cert_uuid_spec,
260 open_fip
261 },
262 #endif /* TRUSTED_BOARD_BOOT */
263 };
264
265 /* By default, BRCM platforms load images from the FIP */
266 static const struct plat_io_policy boot_source_policies[] = {
267 [BOOT_SOURCE_QSPI] = {
268 &memmap_dev_handle,
269 (uintptr_t)&qspi_fip_block_spec,
270 open_qspi
271 },
272 [BOOT_SOURCE_NAND] = {
273 &memmap_dev_handle,
274 (uintptr_t)&nand_fip_block_spec,
275 open_nand
276 },
277 };
278
279 /* Weak definitions may be overridden in specific brcm platform */
280 #pragma weak plat_brcm_io_setup
281 #pragma weak plat_brcm_process_flags
282
open_fip(const uintptr_t spec)283 static int open_fip(const uintptr_t spec)
284 {
285 int result;
286 uintptr_t local_image_handle;
287
288 /* See if a Firmware Image Package is available */
289 result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
290 if (result == 0) {
291 result = io_open(fip_dev_handle, spec, &local_image_handle);
292 if (result == 0) {
293 VERBOSE("Using FIP\n");
294 io_close(local_image_handle);
295 }
296 }
297 return result;
298 }
299
300
open_memmap(const uintptr_t spec)301 static int open_memmap(const uintptr_t spec)
302 {
303 int result;
304 uintptr_t local_image_handle;
305
306 result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL);
307 if (result == 0) {
308 result = io_open(memmap_dev_handle, spec, &local_image_handle);
309 if (result == 0) {
310 VERBOSE("Using Memmap\n");
311 io_close(local_image_handle);
312 }
313 }
314 return result;
315 }
316
open_qspi(const uintptr_t spec)317 static int open_qspi(const uintptr_t spec)
318 {
319 return open_memmap(spec);
320 }
321
open_nand(const uintptr_t spec)322 static int open_nand(const uintptr_t spec)
323 {
324 return open_memmap(spec);
325 }
326
327
brcm_io_setup(void)328 void brcm_io_setup(void)
329 {
330 int io_result;
331 uint32_t boot_source;
332
333 io_result = register_io_dev_fip(&fip_dev_con);
334 assert(io_result == 0);
335
336 io_result = register_io_dev_memmap(&memmap_dev_con);
337 assert(io_result == 0);
338
339 /* Open connections to devices and cache the handles */
340 io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL,
341 &fip_dev_handle);
342 assert(io_result == 0);
343
344 boot_source = boot_source_get();
345 switch (boot_source) {
346 case BOOT_SOURCE_QSPI:
347 case BOOT_SOURCE_NAND:
348 default:
349 io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL,
350 &memmap_dev_handle);
351 break;
352 }
353 assert(io_result == 0);
354
355 /* Ignore improbable errors in release builds */
356 (void)io_result;
357 }
358
plat_brcm_io_setup(void)359 void plat_brcm_io_setup(void)
360 {
361 brcm_io_setup();
362 }
363
plat_brcm_process_flags(uint16_t plat_toc_flags __unused)364 void plat_brcm_process_flags(uint16_t plat_toc_flags __unused)
365 {
366 WARN("%s not implemented\n", __func__);
367 }
368
369 /*
370 * Return an IO device handle and specification which can be used to access
371 * an image. Use this to enforce platform load policy
372 */
plat_get_image_source(unsigned int image_id,uintptr_t * dev_handle,uintptr_t * image_spec)373 int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
374 uintptr_t *image_spec)
375 {
376 int result;
377 const struct plat_io_policy *policy;
378 uint32_t boot_source;
379 uint16_t lcl_plat_toc_flg;
380
381 assert(image_id < ARRAY_SIZE(policies));
382
383 boot_source = boot_source_get();
384 if (image_id == FIP_IMAGE_ID)
385 policy = &boot_source_policies[boot_source];
386 else
387 policy = &policies[image_id];
388
389 result = policy->check(policy->image_spec);
390 if (result == 0) {
391 *image_spec = policy->image_spec;
392 *dev_handle = *(policy->dev_handle);
393
394 if (image_id == TRUSTED_BOOT_FW_CERT_ID) {
395 /*
396 * Process the header flags to perform
397 * such custom actions as speeding up PLL.
398 * CERT seems to be the first image accessed
399 * by BL1 so this is where we process the flags.
400 */
401 fip_dev_get_plat_toc_flag((io_dev_info_t *)fip_dev_handle,
402 &lcl_plat_toc_flg);
403 plat_brcm_process_flags(lcl_plat_toc_flg);
404 }
405 }
406
407 return result;
408 }
409