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