blob: 7f01e72c3f3a173f22a23bc53767ef21ce0b511c [file] [log] [blame]
Pankaj Gupta988bbb22020-12-09 14:02:40 +05301/*
Jiafei Pand81dc462021-10-21 16:30:12 +08002 * Copyright 2018-2021 NXP
Pankaj Gupta988bbb22020-12-09 14:02:40 +05303 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8#include <assert.h>
9#include <endian.h>
10#include <string.h>
11
12#include <common/debug.h>
13#include <common/tbbr/tbbr_img_def.h>
14#include <drivers/io/io_block.h>
15#include <drivers/io/io_driver.h>
16#include <drivers/io/io_fip.h>
17#include <drivers/io/io_memmap.h>
18#include <drivers/io/io_storage.h>
19#ifdef FLEXSPI_NOR_BOOT
20#include <flexspi_nor.h>
21#endif
Jiafei Pand81dc462021-10-21 16:30:12 +080022#if defined(NAND_BOOT)
23#include <ifc_nand.h>
24#endif
25#if defined(NOR_BOOT)
26#include <ifc_nor.h>
27#endif
Pankaj Gupta988bbb22020-12-09 14:02:40 +053028#if defined(QSPI_BOOT)
29#include <qspi.h>
30#endif
31#if defined(SD_BOOT) || defined(EMMC_BOOT)
32#include <sd_mmc.h>
33#endif
34#include <tools_share/firmware_image_package.h>
35
36#ifdef CONFIG_DDR_FIP_IMAGE
37#include <ddr_io_storage.h>
38#endif
39#ifdef POLICY_FUSE_PROVISION
40#include <fuse_io.h>
41#endif
42#include "plat_common.h"
43#include "platform_def.h"
44
45uint32_t fip_device;
46/* IO devices */
47uintptr_t backend_dev_handle;
48
49static const io_dev_connector_t *fip_dev_con;
50static uintptr_t fip_dev_handle;
51static const io_dev_connector_t *backend_dev_con;
52
53static io_block_spec_t fip_block_spec = {
54 .offset = PLAT_FIP_OFFSET,
55 .length = PLAT_FIP_MAX_SIZE
56};
57
58static const io_uuid_spec_t bl2_uuid_spec = {
59 .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
60};
61
62static const io_uuid_spec_t fuse_bl2_uuid_spec = {
63 .uuid = UUID_SCP_FIRMWARE_SCP_BL2,
64};
65
66static const io_uuid_spec_t bl31_uuid_spec = {
67 .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
68};
69
70static const io_uuid_spec_t bl32_uuid_spec = {
71 .uuid = UUID_SECURE_PAYLOAD_BL32,
72};
73
74static const io_uuid_spec_t bl33_uuid_spec = {
75 .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
76};
77
78static const io_uuid_spec_t tb_fw_config_uuid_spec = {
79 .uuid = UUID_TB_FW_CONFIG,
80};
81
82static const io_uuid_spec_t hw_config_uuid_spec = {
83 .uuid = UUID_HW_CONFIG,
84};
85
86#if TRUSTED_BOARD_BOOT
87static const io_uuid_spec_t tb_fw_cert_uuid_spec = {
88 .uuid = UUID_TRUSTED_BOOT_FW_CERT,
89};
90
91static const io_uuid_spec_t trusted_key_cert_uuid_spec = {
92 .uuid = UUID_TRUSTED_KEY_CERT,
93};
94
95static const io_uuid_spec_t fuse_key_cert_uuid_spec = {
96 .uuid = UUID_SCP_FW_KEY_CERT,
97};
98
99static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = {
100 .uuid = UUID_SOC_FW_KEY_CERT,
101};
102
103static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = {
104 .uuid = UUID_TRUSTED_OS_FW_KEY_CERT,
105};
106
107static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = {
108 .uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
109};
110
111static const io_uuid_spec_t fuse_cert_uuid_spec = {
112 .uuid = UUID_SCP_FW_CONTENT_CERT,
113};
114
115static const io_uuid_spec_t soc_fw_cert_uuid_spec = {
116 .uuid = UUID_SOC_FW_CONTENT_CERT,
117};
118
119static const io_uuid_spec_t tos_fw_cert_uuid_spec = {
120 .uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT,
121};
122
123static const io_uuid_spec_t nt_fw_cert_uuid_spec = {
124 .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT,
125};
126#endif /* TRUSTED_BOARD_BOOT */
127
128static int open_fip(const uintptr_t spec);
129
130struct plat_io_policy {
131 uintptr_t *dev_handle;
132 uintptr_t image_spec;
133 int (*check)(const uintptr_t spec);
134};
135
136/* By default, ARM platforms load images from the FIP */
137static const struct plat_io_policy policies[] = {
138 [FIP_IMAGE_ID] = {
139 &backend_dev_handle,
140 (uintptr_t)&fip_block_spec,
141 open_backend
142 },
143 [BL2_IMAGE_ID] = {
144 &fip_dev_handle,
145 (uintptr_t)&bl2_uuid_spec,
146 open_fip
147 },
148 [SCP_BL2_IMAGE_ID] = {
149 &fip_dev_handle,
150 (uintptr_t)&fuse_bl2_uuid_spec,
151 open_fip
152 },
153 [BL31_IMAGE_ID] = {
154 &fip_dev_handle,
155 (uintptr_t)&bl31_uuid_spec,
156 open_fip
157 },
158 [BL32_IMAGE_ID] = {
159 &fip_dev_handle,
160 (uintptr_t)&bl32_uuid_spec,
161 open_fip
162 },
163 [BL33_IMAGE_ID] = {
164 &fip_dev_handle,
165 (uintptr_t)&bl33_uuid_spec,
166 open_fip
167 },
168 [TB_FW_CONFIG_ID] = {
169 &fip_dev_handle,
170 (uintptr_t)&tb_fw_config_uuid_spec,
171 open_fip
172 },
173 [HW_CONFIG_ID] = {
174 &fip_dev_handle,
175 (uintptr_t)&hw_config_uuid_spec,
176 open_fip
177 },
178#if TRUSTED_BOARD_BOOT
179 [TRUSTED_BOOT_FW_CERT_ID] = {
180 &fip_dev_handle,
181 (uintptr_t)&tb_fw_cert_uuid_spec,
182 open_fip
183 },
184 [TRUSTED_KEY_CERT_ID] = {
185 &fip_dev_handle,
186 (uintptr_t)&trusted_key_cert_uuid_spec,
187 open_fip
188 },
189 [SCP_FW_KEY_CERT_ID] = {
190 &fip_dev_handle,
191 (uintptr_t)&fuse_key_cert_uuid_spec,
192 open_fip
193 },
194 [SOC_FW_KEY_CERT_ID] = {
195 &fip_dev_handle,
196 (uintptr_t)&soc_fw_key_cert_uuid_spec,
197 open_fip
198 },
199 [TRUSTED_OS_FW_KEY_CERT_ID] = {
200 &fip_dev_handle,
201 (uintptr_t)&tos_fw_key_cert_uuid_spec,
202 open_fip
203 },
204 [NON_TRUSTED_FW_KEY_CERT_ID] = {
205 &fip_dev_handle,
206 (uintptr_t)&nt_fw_key_cert_uuid_spec,
207 open_fip
208 },
209 [SCP_FW_CONTENT_CERT_ID] = {
210 &fip_dev_handle,
211 (uintptr_t)&fuse_cert_uuid_spec,
212 open_fip
213 },
214 [SOC_FW_CONTENT_CERT_ID] = {
215 &fip_dev_handle,
216 (uintptr_t)&soc_fw_cert_uuid_spec,
217 open_fip
218 },
219 [TRUSTED_OS_FW_CONTENT_CERT_ID] = {
220 &fip_dev_handle,
221 (uintptr_t)&tos_fw_cert_uuid_spec,
222 open_fip
223 },
224 [NON_TRUSTED_FW_CONTENT_CERT_ID] = {
225 &fip_dev_handle,
226 (uintptr_t)&nt_fw_cert_uuid_spec,
227 open_fip
228 },
229#endif /* TRUSTED_BOARD_BOOT */
230};
231
232
233/* Weak definitions may be overridden in specific ARM standard platform */
234#pragma weak plat_io_setup
235
236/*
237 * Return an IO device handle and specification which can be used to access
238 */
239static int open_fip(const uintptr_t spec)
240{
241 int result;
242 uintptr_t local_image_handle;
243
244 /* See if a Firmware Image Package is available */
245 result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
246 if (result == 0) {
247 result = io_open(fip_dev_handle, spec, &local_image_handle);
248 if (result == 0) {
249 VERBOSE("Using FIP\n");
250 io_close(local_image_handle);
251 }
252 }
253 return result;
254}
255
256
257int open_backend(const uintptr_t spec)
258{
259 int result;
260 uintptr_t local_image_handle;
261
262 result = io_dev_init(backend_dev_handle, (uintptr_t)NULL);
263 if (result == 0) {
264 result = io_open(backend_dev_handle, spec, &local_image_handle);
265 if (result == 0) {
266 io_close(local_image_handle);
267 }
268 }
269 return result;
270}
271
Jiafei Pand81dc462021-10-21 16:30:12 +0800272#if defined(SD_BOOT) || defined(EMMC_BOOT) || defined(NAND_BOOT)
Pankaj Gupta988bbb22020-12-09 14:02:40 +0530273static int plat_io_block_setup(size_t fip_offset, uintptr_t block_dev_spec)
274{
275 int io_result;
276
277 fip_block_spec.offset = fip_offset;
278
279 io_result = register_io_dev_block(&backend_dev_con);
280 assert(io_result == 0);
281
282 /* Open connections to devices and cache the handles */
283 io_result = io_dev_open(backend_dev_con, block_dev_spec,
284 &backend_dev_handle);
285 assert(io_result == 0);
286
287 return io_result;
288}
289#endif
290
Jiafei Pand81dc462021-10-21 16:30:12 +0800291#if defined(FLEXSPI_NOR_BOOT) || defined(QSPI_BOOT) || defined(NOR_BOOT)
Pankaj Gupta988bbb22020-12-09 14:02:40 +0530292static int plat_io_memmap_setup(size_t fip_offset)
293{
294 int io_result;
295
296 fip_block_spec.offset = fip_offset;
297
298 io_result = register_io_dev_memmap(&backend_dev_con);
299 assert(io_result == 0);
300
301 /* Open connections to devices and cache the handles */
302 io_result = io_dev_open(backend_dev_con, (uintptr_t)NULL,
303 &backend_dev_handle);
304 assert(io_result == 0);
305
306 return io_result;
307}
308#endif
309
310static int ls_io_fip_setup(unsigned int boot_dev)
311{
312 int io_result;
313
314 io_result = register_io_dev_fip(&fip_dev_con);
315 assert(io_result == 0);
316
317 /* Open connections to devices and cache the handles */
318 io_result = io_dev_open(fip_dev_con, (uintptr_t)&fip_device,
319 &fip_dev_handle);
320 assert(io_result == 0);
321
322#ifdef CONFIG_DDR_FIP_IMAGE
323 /* Open connection to DDR FIP image if available */
324 io_result = ddr_fip_setup(fip_dev_con, boot_dev);
325
326 assert(io_result == 0);
327#endif
328
329#ifdef POLICY_FUSE_PROVISION
330 /* Open connection to FUSE FIP image if available */
331 io_result = fuse_fip_setup(fip_dev_con, boot_dev);
332
333 assert(io_result == 0);
334#endif
335
336 return io_result;
337}
338
339int ls_qspi_io_setup(void)
340{
341#ifdef QSPI_BOOT
342 qspi_io_setup(NXP_QSPI_FLASH_ADDR,
343 NXP_QSPI_FLASH_SIZE,
344 PLAT_FIP_OFFSET);
345 return plat_io_memmap_setup(NXP_QSPI_FLASH_ADDR + PLAT_FIP_OFFSET);
346#else
347 ERROR("QSPI driver not present. Check your BUILD\n");
348
349 /* Should never reach here */
350 assert(false);
351 return -1;
352#endif
353}
354
355int emmc_sdhc2_io_setup(void)
356{
357#if defined(EMMC_BOOT) && defined(NXP_ESDHC2_ADDR)
358 uintptr_t block_dev_spec;
359 int ret;
360
361 ret = sd_emmc_init(&block_dev_spec,
362 NXP_ESDHC2_ADDR,
363 NXP_SD_BLOCK_BUF_ADDR,
364 NXP_SD_BLOCK_BUF_SIZE,
365 false);
366 if (ret != 0) {
367 return ret;
368 }
369
370 return plat_io_block_setup(PLAT_FIP_OFFSET, block_dev_spec);
371#else
372 ERROR("EMMC driver not present. Check your BUILD\n");
373
374 /* Should never reach here */
375 assert(false);
376 return -1;
377#endif
378}
379
380int emmc_io_setup(void)
381{
382/* On the platforms which only has one ESDHC controller,
383 * eMMC-boot will use the first ESDHC controller.
384 */
385#if defined(SD_BOOT) || defined(EMMC_BOOT)
386 uintptr_t block_dev_spec;
387 int ret;
388
389 ret = sd_emmc_init(&block_dev_spec,
390 NXP_ESDHC_ADDR,
391 NXP_SD_BLOCK_BUF_ADDR,
392 NXP_SD_BLOCK_BUF_SIZE,
393 true);
394 if (ret != 0) {
395 return ret;
396 }
397
398 return plat_io_block_setup(PLAT_FIP_OFFSET, block_dev_spec);
399#else
400 ERROR("SD driver not present. Check your BUILD\n");
401
402 /* Should never reach here */
403 assert(false);
404 return -1;
405#endif
406}
407
408int ifc_nor_io_setup(void)
409{
Jiafei Pand81dc462021-10-21 16:30:12 +0800410#if defined(NOR_BOOT)
411 int ret;
412
413 ret = ifc_nor_init(NXP_NOR_FLASH_ADDR,
414 NXP_NOR_FLASH_SIZE);
415
416 if (ret != 0) {
417 return ret;
418 }
419
420 return plat_io_memmap_setup(NXP_NOR_FLASH_ADDR + PLAT_FIP_OFFSET);
421#else
Pankaj Gupta988bbb22020-12-09 14:02:40 +0530422 ERROR("NOR driver not present. Check your BUILD\n");
423
424 /* Should never reach here */
425 assert(false);
426 return -1;
Jiafei Pand81dc462021-10-21 16:30:12 +0800427#endif
Pankaj Gupta988bbb22020-12-09 14:02:40 +0530428}
429
430int ifc_nand_io_setup(void)
431{
Jiafei Pand81dc462021-10-21 16:30:12 +0800432#if defined(NAND_BOOT)
433 uintptr_t block_dev_spec;
434 int ret;
435
436 ret = ifc_nand_init(&block_dev_spec,
437 NXP_IFC_REGION_ADDR,
438 NXP_IFC_ADDR,
439 NXP_IFC_SRAM_BUFFER_SIZE,
440 NXP_SD_BLOCK_BUF_ADDR,
441 NXP_SD_BLOCK_BUF_SIZE);
442 if (ret != 0) {
443 return ret;
444 }
445
446 return plat_io_block_setup(PLAT_FIP_OFFSET, block_dev_spec);
447#else
448
Pankaj Gupta988bbb22020-12-09 14:02:40 +0530449 ERROR("NAND driver not present. Check your BUILD\n");
450
451 /* Should never reach here */
452 assert(false);
453 return -1;
Jiafei Pand81dc462021-10-21 16:30:12 +0800454#endif
Pankaj Gupta988bbb22020-12-09 14:02:40 +0530455}
456
457int ls_flexspi_nor_io_setup(void)
458{
459#ifdef FLEXSPI_NOR_BOOT
460 int ret = 0;
461
462 ret = flexspi_nor_io_setup(NXP_FLEXSPI_FLASH_ADDR,
463 NXP_FLEXSPI_FLASH_SIZE,
464 NXP_FLEXSPI_ADDR);
465
466 if (ret != 0) {
467 ERROR("FlexSPI NOR driver initialization error.\n");
468 /* Should never reach here */
469 assert(0);
470 panic();
471 return -1;
472 }
473
474 return plat_io_memmap_setup(NXP_FLEXSPI_FLASH_ADDR + PLAT_FIP_OFFSET);
475#else
476 ERROR("FlexSPI NOR driver not present. Check your BUILD\n");
477
478 /* Should never reach here */
479 assert(false);
480 return -1;
481#endif
482}
483
484static int (* const ls_io_setup_table[])(void) = {
485 [BOOT_DEVICE_IFC_NOR] = ifc_nor_io_setup,
486 [BOOT_DEVICE_IFC_NAND] = ifc_nand_io_setup,
487 [BOOT_DEVICE_QSPI] = ls_qspi_io_setup,
488 [BOOT_DEVICE_EMMC] = emmc_io_setup,
489 [BOOT_DEVICE_SDHC2_EMMC] = emmc_sdhc2_io_setup,
490 [BOOT_DEVICE_FLEXSPI_NOR] = ls_flexspi_nor_io_setup,
491 [BOOT_DEVICE_FLEXSPI_NAND] = ls_flexspi_nor_io_setup,
492};
493
494
495int plat_io_setup(void)
496{
497 int (*io_setup)(void);
498 unsigned int boot_dev = BOOT_DEVICE_NONE;
499 int ret;
500
501 boot_dev = get_boot_dev();
502 if (boot_dev == BOOT_DEVICE_NONE) {
503 ERROR("Boot Device detection failed, Check RCW_SRC\n");
504 return -EINVAL;
505 }
506
507 io_setup = ls_io_setup_table[boot_dev];
508 ret = io_setup();
509 if (ret != 0) {
510 return ret;
511 }
512
513 ret = ls_io_fip_setup(boot_dev);
514 if (ret != 0) {
515 return ret;
516 }
517
518 return 0;
519}
520
521
522/* Return an IO device handle and specification which can be used to access
523 * an image. Use this to enforce platform load policy
524 */
525int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
526 uintptr_t *image_spec)
527{
528 int result = -1;
529 const struct plat_io_policy *policy;
530
531 if (image_id < ARRAY_SIZE(policies)) {
532
533 policy = &policies[image_id];
534 result = policy->check(policy->image_spec);
535 if (result == 0) {
536 *image_spec = policy->image_spec;
537 *dev_handle = *(policy->dev_handle);
538 }
539 }
540#ifdef CONFIG_DDR_FIP_IMAGE
541 else {
542 VERBOSE("Trying alternative IO\n");
543 result = plat_get_ddr_fip_image_source(image_id, dev_handle,
544 image_spec, open_backend);
545 }
546#endif
547#ifdef POLICY_FUSE_PROVISION
548 if (result != 0) {
549 VERBOSE("Trying FUSE IO\n");
550 result = plat_get_fuse_image_source(image_id, dev_handle,
551 image_spec, open_backend);
552 }
553#endif
554
555 return result;
556}