]> git.ipfire.org Git - thirdparty/u-boot.git/blame - common/spl/spl.c
Revert "Merge patch series "arm: dts: am62-beagleplay: Fix Beagleplay Ethernet""
[thirdparty/u-boot.git] / common / spl / spl.c
CommitLineData
83d290c5 1// SPDX-License-Identifier: GPL-2.0+
bcae7211
A
2/*
3 * (C) Copyright 2010
4 * Texas Instruments, <www.ti.com>
5 *
6 * Aneesh V <aneesh@ti.com>
bcae7211 7 */
f1c6e192 8
d678a59d 9#include <common.h>
e945a726 10#include <bloblist.h>
8bee2d25 11#include <binman_sym.h>
52f24238 12#include <bootstage.h>
11516518 13#include <dm.h>
b0edea3c 14#include <handoff.h>
db41d65a 15#include <hang.h>
691d719d 16#include <init.h>
c30b7adb 17#include <irq_func.h>
f7ae49fc 18#include <log.h>
891d9e84 19#include <mapmem.h>
b03e0510 20#include <serial.h>
47f7bcae 21#include <spl.h>
77507416 22#include <spl_load.h>
10f6e4dc 23#include <system-constants.h>
401d1c4f 24#include <asm/global_data.h>
1d99e673 25#include <asm-generic/gpio.h>
d678a59d 26#include <asm/u-boot.h>
bb085b87 27#include <nand.h>
8cf686e1 28#include <fat.h>
3db71108 29#include <u-boot/crc.h>
121a165c
T
30#if CONFIG_IS_ENABLED(BANNER_PRINT)
31#include <timestamp.h>
32#endif
efb2172e 33#include <version.h>
8cf686e1 34#include <image.h>
2d01dd95 35#include <malloc.h>
31f9f0ea 36#include <mapmem.h>
11516518 37#include <dm/root.h>
4f6500aa 38#include <dm/util.h>
7a17e4c6
NJ
39#include <dm/device-internal.h>
40#include <dm/uclass-internal.h>
761ca31e 41#include <linux/compiler.h>
6e7585bb 42#include <fdt_support.h>
a8be2494 43#include <bootcount.h>
06985289 44#include <wdt.h>
1d3c2667 45#include <video.h>
bcae7211
A
46
47DECLARE_GLOBAL_DATA_PTR;
367ecbf2 48DECLARE_BINMAN_MAGIC_SYM;
bcae7211 49
47f7bcae 50u32 *boot_params_ptr = NULL;
9ea5c6ef 51
d8830cf8 52#if CONFIG_IS_ENABLED(BINMAN_UBOOT_SYMBOLS)
8bee2d25 53/* See spl.h for information about this */
dbf6be9f 54binman_sym_declare(ulong, u_boot_any, image_pos);
e82c624d
SG
55binman_sym_declare(ulong, u_boot_any, size);
56
57#ifdef CONFIG_TPL
2b8d2ccd
SG
58binman_sym_declare(ulong, u_boot_spl_any, image_pos);
59binman_sym_declare(ulong, u_boot_spl_any, size);
e82c624d 60#endif
8bee2d25 61
f86ca5ad 62#ifdef CONFIG_VPL
2b8d2ccd
SG
63binman_sym_declare(ulong, u_boot_vpl_any, image_pos);
64binman_sym_declare(ulong, u_boot_vpl_any, size);
f86ca5ad
SG
65#endif
66
d8830cf8
ANY
67#endif /* BINMAN_UBOOT_SYMBOLS */
68
58b504e5
AG
69/* Define board data structure */
70static struct bd_info bdata __attribute__ ((section(".data")));
71
b55881dd 72#if CONFIG_IS_ENABLED(SHOW_BOOT_PROGRESS)
496c5483
HS
73/*
74 * Board-specific Platform code can reimplement show_boot_progress () if needed
75 */
76__weak void show_boot_progress(int val) {}
cb80ff20 77#endif
496c5483 78
a343b4fe
HS
79#if defined(CONFIG_SPL_OS_BOOT) || CONFIG_IS_ENABLED(HANDOFF) || \
80 defined(CONFIG_SPL_ATF)
b0edea3c
SG
81/* weak, default platform-specific function to initialize dram banks */
82__weak int dram_init_banksize(void)
83{
84 return 0;
85}
86#endif
87
379c19ab
SS
88/*
89 * Default function to determine if u-boot or the OS should
90 * be started. This implementation always returns 1.
91 *
92 * Please implement your own board specific funcion to do this.
93 *
94 * RETURN
95 * 0 to not start u-boot
96 * positive if u-boot should start
97 */
7115007c 98#if CONFIG_IS_ENABLED(OS_BOOT)
379c19ab
SS
99__weak int spl_start_uboot(void)
100{
d6330064
SG
101 puts(SPL_TPL_PROMPT
102 "Please implement spl_start_uboot() for your board\n");
103 puts(SPL_TPL_PROMPT "Direct Linux boot not active!\n");
379c19ab
SS
104 return 1;
105}
431889d6
LM
106
107/*
108 * Weak default function for arch specific zImage check. Return zero
109 * and fill start and end address if image is recognized.
110 */
111int __weak bootz_setup(ulong image, ulong *start, ulong *end)
112{
113 return 1;
114}
7a0d8807
NBM
115
116int __weak booti_setup(ulong image, ulong *relocated_addr, ulong *size, bool force_reloc)
117{
118 return 1;
119}
379c19ab
SS
120#endif
121
de5dd4c4
PT
122/* Weak default function for arch/board-specific fixups to the spl_image_info */
123void __weak spl_perform_fixups(struct spl_image_info *spl_image)
124{
125}
126
a343b4fe 127void spl_fixup_fdt(void *fdt_blob)
6e7585bb 128{
a343b4fe 129#if defined(CONFIG_SPL_OF_LIBFDT)
6e7585bb
R
130 int err;
131
a343b4fe
HS
132 if (!fdt_blob)
133 return;
134
6e7585bb
R
135 err = fdt_check_header(fdt_blob);
136 if (err < 0) {
137 printf("fdt_root: %s\n", fdt_strerror(err));
138 return;
139 }
140
141 /* fixup the memory dt node */
142 err = fdt_shrink_to_minimum(fdt_blob, 0);
143 if (err == 0) {
d6330064 144 printf(SPL_TPL_PROMPT "fdt_shrink_to_minimum err - %d\n", err);
6e7585bb
R
145 return;
146 }
147
148 err = arch_fixup_fdt(fdt_blob);
149 if (err) {
d6330064 150 printf(SPL_TPL_PROMPT "arch_fixup_fdt err - %d\n", err);
6e7585bb
R
151 return;
152 }
153#endif
154}
155
1d3c2667
DT
156int spl_reserve_video_from_ram_top(void)
157{
158 if (CONFIG_IS_ENABLED(VIDEO)) {
159 ulong addr;
160 int ret;
161
162 addr = gd->ram_top;
163 ret = video_reserve(&addr);
164 if (ret)
165 return ret;
166 debug("Reserving %luk for video at: %08lx\n",
167 ((unsigned long)gd->relocaddr - addr) >> 10, addr);
168 gd->relocaddr = addr;
169 }
170
171 return 0;
172}
173
e82c624d
SG
174ulong spl_get_image_pos(void)
175{
d8830cf8 176 if (!CONFIG_IS_ENABLED(BINMAN_UBOOT_SYMBOLS))
d7f07172
ANY
177 return BINMAN_SYM_MISSING;
178
f86ca5ad
SG
179#ifdef CONFIG_VPL
180 if (spl_next_phase() == PHASE_VPL)
2b8d2ccd 181 return binman_sym(ulong, u_boot_vpl_any, image_pos);
f86ca5ad
SG
182#endif
183 return spl_next_phase() == PHASE_SPL ?
2b8d2ccd 184 binman_sym(ulong, u_boot_spl_any, image_pos) :
e82c624d
SG
185 binman_sym(ulong, u_boot_any, image_pos);
186}
187
188ulong spl_get_image_size(void)
189{
d8830cf8 190 if (!CONFIG_IS_ENABLED(BINMAN_UBOOT_SYMBOLS))
d7f07172
ANY
191 return BINMAN_SYM_MISSING;
192
f86ca5ad
SG
193#ifdef CONFIG_VPL
194 if (spl_next_phase() == PHASE_VPL)
2b8d2ccd 195 return binman_sym(ulong, u_boot_vpl_any, size);
f86ca5ad
SG
196#endif
197 return spl_next_phase() == PHASE_SPL ?
2b8d2ccd 198 binman_sym(ulong, u_boot_spl_any, size) :
e82c624d
SG
199 binman_sym(ulong, u_boot_any, size);
200}
201
86c372af
SG
202ulong spl_get_image_text_base(void)
203{
f86ca5ad
SG
204#ifdef CONFIG_VPL
205 if (spl_next_phase() == PHASE_VPL)
206 return CONFIG_VPL_TEXT_BASE;
207#endif
208 return spl_next_phase() == PHASE_SPL ? CONFIG_SPL_TEXT_BASE :
98463903 209 CONFIG_TEXT_BASE;
86c372af
SG
210}
211
ea8256f0
SR
212/*
213 * Weak default function for board specific cleanup/preparation before
214 * Linux boot. Some boards/platforms might not need it, so just provide
215 * an empty stub here.
216 */
217__weak void spl_board_prepare_for_linux(void)
218{
219 /* Nothing to do! */
220}
221
a25d6b65
AG
222__weak void spl_board_prepare_for_optee(void *fdt)
223{
224}
225
c5922923
HT
226__weak const char *spl_board_loader_name(u32 boot_device)
227{
228 return NULL;
229}
230
949eb228
RS
231#if CONFIG_IS_ENABLED(OPTEE_IMAGE)
232__weak void __noreturn jump_to_image_optee(struct spl_image_info *spl_image)
233{
234 spl_optee_entry(NULL, NULL, spl_image->fdt_addr,
235 (void *)spl_image->entry_point);
236}
237#endif
238
3a3b9147
MS
239__weak void spl_board_prepare_for_boot(void)
240{
241 /* Nothing to do! */
242}
243
f3543e69 244__weak struct legacy_img_hdr *spl_get_load_buffer(ssize_t offset, size_t size)
04ce5427 245{
98463903 246 return map_sysmem(CONFIG_TEXT_BASE + offset, 0);
04ce5427
MV
247}
248
08574ed3 249#ifdef CONFIG_SPL_RAW_IMAGE_SUPPORT
d95ceb97 250void spl_set_header_raw_uboot(struct spl_image_info *spl_image)
0c3117b1 251{
d7f07172 252 ulong u_boot_pos = spl_get_image_pos();
8bee2d25 253
08574ed3 254#if CONFIG_SYS_MONITOR_LEN != 0
d95ceb97 255 spl_image->size = CONFIG_SYS_MONITOR_LEN;
08574ed3
TR
256#else
257 /* Unknown U-Boot size, let's assume it will not be more than 200 KB */
258 spl_image->size = 200 * 1024;
259#endif
55fe0e2b
MR
260
261 /*
262 * Binman error cases: address of the end of the previous region or the
263 * start of the image's entry area (usually 0) if there is no previous
264 * region.
265 */
266 if (u_boot_pos && u_boot_pos != BINMAN_SYM_MISSING) {
267 /* Binman does not support separated entry addresses */
8bee2d25
SG
268 spl_image->entry_point = u_boot_pos;
269 spl_image->load_addr = u_boot_pos;
270 } else {
6ab77bb1 271 spl_image->entry_point = CONFIG_SYS_UBOOT_START;
98463903 272 spl_image->load_addr = CONFIG_TEXT_BASE;
8bee2d25 273 }
d95ceb97
SG
274 spl_image->os = IH_OS_U_BOOT;
275 spl_image->name = "U-Boot";
0c3117b1 276}
08574ed3 277#endif
0c3117b1 278
9baab60b 279__weak int spl_parse_board_header(struct spl_image_info *spl_image,
2e0429bc 280 const struct spl_boot_device *bootdev,
9baab60b
T
281 const void *image_header, size_t size)
282{
283 return -EINVAL;
284}
285
c1108172 286__weak int spl_parse_legacy_header(struct spl_image_info *spl_image,
f3543e69 287 const struct legacy_img_hdr *header)
c1108172
SR
288{
289 /* LEGACY image not supported */
290 debug("Legacy boot image support not enabled, proceeding to other boot methods\n");
291 return -EINVAL;
292}
293
71316c1d 294int spl_parse_image_header(struct spl_image_info *spl_image,
2e0429bc 295 const struct spl_boot_device *bootdev,
f3543e69 296 const struct legacy_img_hdr *header)
8cf686e1 297{
035ab46e 298 int ret;
8a9dc16e 299
035ab46e
SG
300 if (CONFIG_IS_ENABLED(LOAD_FIT_FULL)) {
301 ret = spl_load_fit_image(spl_image, header);
302
303 if (!ret)
304 return ret;
305 }
77552b06 306 if (image_get_magic(header) == IH_MAGIC) {
c1108172 307 int ret;
dae5c2dc 308
c1108172
SR
309 ret = spl_parse_legacy_header(spl_image, header);
310 if (ret)
311 return ret;
8cf686e1 312 } else {
8c80eb3b
AA
313#ifdef CONFIG_SPL_PANIC_ON_RAW_IMAGE
314 /*
315 * CONFIG_SPL_PANIC_ON_RAW_IMAGE is defined when the
316 * code which loads images in SPL cannot guarantee that
317 * absolutely all read errors will be reported.
318 * An example is the LPC32XX MLC NAND driver, which
319 * will consider that a completely unreadable NAND block
320 * is bad, and thus should be skipped silently.
321 */
322 panic("** no mkimage signature but raw image not supported");
85a37729
PK
323#endif
324
7115007c 325#if CONFIG_IS_ENABLED(OS_BOOT)
7a0d8807
NBM
326#if defined(CMD_BOOTI)
327 ulong start, size;
328
329 if (!booti_setup((ulong)header, &start, &size, 0)) {
330 spl_image->name = "Linux";
331 spl_image->os = IH_OS_LINUX;
332 spl_image->load_addr = start;
333 spl_image->entry_point = start;
334 spl_image->size = size;
335 debug(SPL_TPL_PROMPT
336 "payload Image, load addr: 0x%lx size: %d\n",
337 spl_image->load_addr, spl_image->size);
338 return 0;
339 }
340#elif defined(CMD_BOOTZ)
431889d6
LM
341 ulong start, end;
342
343 if (!bootz_setup((ulong)header, &start, &end)) {
71316c1d
SG
344 spl_image->name = "Linux";
345 spl_image->os = IH_OS_LINUX;
346 spl_image->load_addr = CONFIG_SYS_LOAD_ADDR;
347 spl_image->entry_point = CONFIG_SYS_LOAD_ADDR;
348 spl_image->size = end - start;
d6330064
SG
349 debug(SPL_TPL_PROMPT
350 "payload zImage, load addr: 0x%lx size: %d\n",
71316c1d 351 spl_image->load_addr, spl_image->size);
431889d6
LM
352 return 0;
353 }
7a0d8807 354#endif
431889d6 355#endif
85a37729 356
2e0429bc 357 if (!spl_parse_board_header(spl_image, bootdev, (const void *)header, sizeof(*header)))
9baab60b
T
358 return 0;
359
24eb39b5 360#ifdef CONFIG_SPL_RAW_IMAGE_SUPPORT
8cf686e1 361 /* Signature not found - assume u-boot.bin */
026b2fe3 362 debug("mkimage signature not found - ih_magic = %x\n",
8cf686e1 363 header->ih_magic);
71316c1d 364 spl_set_header_raw_uboot(spl_image);
24eb39b5
AD
365#else
366 /* RAW image not supported, proceed to other boot methods. */
2d2531be 367 debug("Raw boot image support not enabled, proceeding to other boot methods\n");
24eb39b5 368 return -EINVAL;
8c80eb3b 369#endif
8cf686e1 370 }
24eb39b5 371
7e0f2267 372 return 0;
8cf686e1
A
373}
374
77507416
SA
375#if SPL_LOAD_USERS > 1
376int spl_load(struct spl_image_info *spl_image,
377 const struct spl_boot_device *bootdev, struct spl_load_info *info,
378 size_t size, size_t offset)
379{
380 return _spl_load(spl_image, bootdev, info, size, offset);
381}
382#endif
383
a759f1e0 384__weak void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
8cf686e1 385{
4a0eb757
S
386 typedef void __noreturn (*image_entry_noargs_t)(void);
387
8cf686e1 388 image_entry_noargs_t image_entry =
11e1479b 389 (image_entry_noargs_t)spl_image->entry_point;
8cf686e1 390
30c0740e 391 debug("image entry point: 0x%lx\n", spl_image->entry_point);
4a0eb757 392 image_entry();
8cf686e1
A
393}
394
b0edea3c
SG
395#if CONFIG_IS_ENABLED(HANDOFF)
396/**
397 * Set up the SPL hand-off information
398 *
399 * This is initially empty (zero) but can be written by
400 */
401static int setup_spl_handoff(void)
402{
403 struct spl_handoff *ho;
404
7f3b79af 405 ho = bloblist_ensure(BLOBLISTT_U_BOOT_SPL_HANDOFF, sizeof(struct spl_handoff));
b0edea3c
SG
406 if (!ho)
407 return -ENOENT;
408
409 return 0;
410}
411
366291af
SG
412__weak int handoff_arch_save(struct spl_handoff *ho)
413{
414 return 0;
415}
416
b0edea3c
SG
417static int write_spl_handoff(void)
418{
419 struct spl_handoff *ho;
366291af 420 int ret;
b0edea3c 421
7f3b79af 422 ho = bloblist_find(BLOBLISTT_U_BOOT_SPL_HANDOFF, sizeof(struct spl_handoff));
b0edea3c
SG
423 if (!ho)
424 return -ENOENT;
425 handoff_save_dram(ho);
366291af
SG
426 ret = handoff_arch_save(ho);
427 if (ret)
428 return ret;
b0edea3c
SG
429 debug(SPL_TPL_PROMPT "Wrote SPL handoff\n");
430
431 return 0;
432}
433#else
434static inline int setup_spl_handoff(void) { return 0; }
435static inline int write_spl_handoff(void) { return 0; }
436
437#endif /* HANDOFF */
438
05e3a0d6
SG
439/**
440 * get_bootstage_id() - Get the bootstage ID to emit
441 *
442 * @start: true if this is for starting SPL, false for ending it
185f812c 443 * Return: bootstage ID to use
05e3a0d6
SG
444 */
445static enum bootstage_id get_bootstage_id(bool start)
446{
447 enum u_boot_phase phase = spl_phase();
448
449 if (IS_ENABLED(CONFIG_TPL_BUILD) && phase == PHASE_TPL)
450 return start ? BOOTSTAGE_ID_START_TPL : BOOTSTAGE_ID_END_TPL;
f86ca5ad
SG
451 else if (IS_ENABLED(CONFIG_VPL_BUILD) && phase == PHASE_VPL)
452 return start ? BOOTSTAGE_ID_START_VPL : BOOTSTAGE_ID_END_VPL;
05e3a0d6
SG
453 else
454 return start ? BOOTSTAGE_ID_START_SPL : BOOTSTAGE_ID_END_SPL;
455}
456
340f418a 457static int spl_common_init(bool setup_malloc)
bcae7211 458{
f3d46bd6
SG
459 int ret;
460
3d6d5075 461#if CONFIG_IS_ENABLED(SYS_MALLOC_F)
340f418a 462 if (setup_malloc) {
dd5b58c4
TR
463#ifdef CFG_MALLOC_F_ADDR
464 gd->malloc_base = CFG_MALLOC_F_ADDR;
94b9e22e 465#endif
f1896c45 466 gd->malloc_limit = CONFIG_VAL(SYS_MALLOC_F_LEN);
340f418a
EC
467 gd->malloc_ptr = 0;
468 }
24dafad5 469#endif
31f9f0ea 470 ret = bootstage_init(u_boot_first_phase());
824bb1b4
SG
471 if (ret) {
472 debug("%s: Failed to set up bootstage: ret=%d\n", __func__,
473 ret);
474 return ret;
475 }
31f9f0ea 476 if (!u_boot_first_phase()) {
17ba5010 477 ret = bootstage_unstash_default();
31f9f0ea 478 if (ret)
17ba5010 479 log_debug("Failed to unstash bootstage: ret=%d\n", ret);
31f9f0ea 480 }
05e3a0d6
SG
481 bootstage_mark_name(get_bootstage_id(true),
482 spl_phase_name(spl_phase()));
4d8d3056
SG
483#if CONFIG_IS_ENABLED(LOG)
484 ret = log_init();
485 if (ret) {
486 debug("%s: Failed to set up logging\n", __func__);
487 return ret;
488 }
489#endif
414cc151 490 if (CONFIG_IS_ENABLED(OF_REAL)) {
f3d46bd6
SG
491 ret = fdtdec_setup();
492 if (ret) {
493 debug("fdtdec_setup() returned error %d\n", ret);
070d00b8 494 return ret;
f3d46bd6
SG
495 }
496 }
f1c6e192 497 if (CONFIG_IS_ENABLED(DM)) {
b67eefdb 498 bootstage_start(BOOTSTAGE_ID_ACCUM_DM_SPL,
5256beec 499 spl_phase() == PHASE_TPL ? "dm tpl" : "dm_spl");
7f73ca48 500 /* With CONFIG_SPL_OF_PLATDATA, bring in all devices */
7d23b9cf 501 ret = dm_init_and_scan(!CONFIG_IS_ENABLED(OF_PLATDATA));
b67eefdb 502 bootstage_accum(BOOTSTAGE_ID_ACCUM_DM_SPL);
f3d46bd6
SG
503 if (ret) {
504 debug("dm_init_and_scan() returned error %d\n", ret);
070d00b8 505 return ret;
f3d46bd6
SG
506 }
507 }
340f418a
EC
508
509 return 0;
510}
511
58b504e5 512void spl_set_bd(void)
d1fc0a31 513{
c21f407b
SG
514 /*
515 * NOTE: On some platforms (e.g. x86) bdata may be in flash and not
516 * writeable.
517 */
58b504e5
AG
518 if (!gd->bd)
519 gd->bd = &bdata;
d1fc0a31
YS
520}
521
340f418a
EC
522int spl_early_init(void)
523{
524 int ret;
525
94cb986e
SG
526 debug("%s\n", __func__);
527
340f418a
EC
528 ret = spl_common_init(true);
529 if (ret)
530 return ret;
531 gd->flags |= GD_FLG_SPL_EARLY_INIT;
532
533 return 0;
534}
535
536int spl_init(void)
537{
538 int ret;
cf334edf
TR
539 bool setup_malloc = !(IS_ENABLED(CONFIG_SPL_STACK_R) &&
540 IS_ENABLED(CONFIG_SPL_SYS_MALLOC_SIMPLE));
340f418a 541
94cb986e
SG
542 debug("%s\n", __func__);
543
340f418a 544 if (!(gd->flags & GD_FLG_SPL_EARLY_INIT)) {
cf334edf 545 ret = spl_common_init(setup_malloc);
340f418a
EC
546 if (ret)
547 return ret;
548 }
070d00b8 549 gd->flags |= GD_FLG_SPL_INIT;
2d01dd95 550
070d00b8
SG
551 return 0;
552}
553
f101e4bd
NK
554#ifndef BOOT_DEVICE_NONE
555#define BOOT_DEVICE_NONE 0xdeadbeef
556#endif
557
f101e4bd
NK
558__weak void board_boot_order(u32 *spl_boot_list)
559{
560 spl_boot_list[0] = spl_boot_device();
561}
562
c10939d8
T
563__weak int spl_check_board_image(struct spl_image_info *spl_image,
564 const struct spl_boot_device *bootdev)
565{
566 return 0;
567}
568
29d357d7
SG
569static int spl_load_image(struct spl_image_info *spl_image,
570 struct spl_image_loader *loader)
070d00b8 571{
dae5c2dc 572 int ret;
ecdfd69a
SG
573 struct spl_boot_device bootdev;
574
29d357d7 575 bootdev.boot_device = loader->boot_device;
ecdfd69a
SG
576 bootdev.boot_device_name = NULL;
577
dae5c2dc
SG
578 ret = loader->load_image(spl_image, &bootdev);
579#ifdef CONFIG_SPL_LEGACY_IMAGE_CRC_CHECK
580 if (!ret && spl_image->dcrc_length) {
581 /* check data crc */
582 ulong dcrc = crc32_wd(0, (unsigned char *)spl_image->dcrc_data,
583 spl_image->dcrc_length, CHUNKSZ_CRC32);
584 if (dcrc != spl_image->dcrc) {
585 puts("SPL: Image data CRC check failed!\n");
586 ret = -EINVAL;
587 }
588 }
589#endif
c10939d8
T
590 if (!ret)
591 ret = spl_check_board_image(spl_image, &bootdev);
592
dae5c2dc 593 return ret;
540bfe7d
SG
594}
595
596/**
fd4ee98d 597 * boot_from_devices() - Try loading a booting U-Boot from a list of devices
540bfe7d
SG
598 *
599 * @spl_image: Place to put the image details if successful
600 * @spl_boot_list: List of boot devices to try
601 * @count: Number of elements in spl_boot_list
185f812c 602 * Return: 0 if OK, -ENODEV if there were no boot devices
7d84fbb5
SG
603 * if CONFIG_SHOW_ERRORS is enabled, returns -ENXIO if there were
604 * devices but none worked
540bfe7d
SG
605 */
606static int boot_from_devices(struct spl_image_info *spl_image,
607 u32 spl_boot_list[], int count)
608{
5a61bf17
SG
609 struct spl_image_loader *drv =
610 ll_entry_start(struct spl_image_loader, spl_image_loader);
611 const int n_ents =
612 ll_entry_count(struct spl_image_loader, spl_image_loader);
7d84fbb5 613 int ret = -ENODEV;
540bfe7d
SG
614 int i;
615
616 for (i = 0; i < count && spl_boot_list[i] != BOOT_DEVICE_NONE; i++) {
617 struct spl_image_loader *loader;
7d84fbb5
SG
618 int bootdev = spl_boot_list[i];
619
620 if (CONFIG_IS_ENABLED(SHOW_ERRORS))
621 ret = -ENXIO;
5a61bf17
SG
622 for (loader = drv; loader != drv + n_ents; loader++) {
623 if (bootdev != loader->boot_device)
624 continue;
625 if (!CONFIG_IS_ENABLED(SILENT_CONSOLE)) {
626 if (loader)
627 printf("Trying to boot from %s\n",
628 spl_loader_name(loader));
629 else if (CONFIG_IS_ENABLED(SHOW_ERRORS)) {
630 printf(SPL_TPL_PROMPT
631 "Unsupported Boot Device %d\n",
632 bootdev);
633 } else {
634 puts(SPL_TPL_PROMPT
635 "Unsupported Boot Device!\n");
636 }
637 }
638 if (loader &&
639 !spl_load_image(spl_image, loader)) {
640 spl_image->boot_device = bootdev;
641 return 0;
642 }
de5dd4c4 643 }
540bfe7d
SG
644 }
645
7d84fbb5 646 return ret;
5211b87e
NK
647}
648
a9a3aada
PR
649#if defined(CONFIG_SPL_FRAMEWORK_BOARD_INIT_F)
650void board_init_f(ulong dummy)
651{
652 if (CONFIG_IS_ENABLED(OF_CONTROL)) {
653 int ret;
654
655 ret = spl_early_init();
656 if (ret) {
657 debug("spl_early_init() failed: %d\n", ret);
658 hang();
659 }
660 }
661
3988be5f 662 preloader_console_init();
a9a3aada
PR
663}
664#endif
665
5211b87e
NK
666void board_init_r(gd_t *dummy1, ulong dummy2)
667{
d32b2d1c
SG
668 u32 spl_boot_list[] = {
669 BOOT_DEVICE_NONE,
670 BOOT_DEVICE_NONE,
671 BOOT_DEVICE_NONE,
672 BOOT_DEVICE_NONE,
673 BOOT_DEVICE_NONE,
674 };
6826c432
JK
675 typedef void __noreturn (*jump_to_image_t)(struct spl_image_info *);
676 jump_to_image_t jump_to_image = &jump_to_image_no_args;
d32b2d1c 677 struct spl_image_info spl_image;
f817e08f 678 int ret, os;
5211b87e 679
d6330064 680 debug(">>" SPL_TPL_PROMPT "board_init_r()\n");
d1fc0a31 681
58b504e5
AG
682 spl_set_bd();
683
52779874 684 if (IS_ENABLED(CONFIG_SPL_SYS_MALLOC)) {
b02c4e94
SA
685 mem_malloc_init((ulong)map_sysmem(SPL_SYS_MALLOC_START,
686 SPL_SYS_MALLOC_SIZE),
687 SPL_SYS_MALLOC_SIZE);
52779874
SG
688 gd->flags |= GD_FLG_FULL_MALLOC_INIT;
689 }
5211b87e
NK
690 if (!(gd->flags & GD_FLG_SPL_INIT)) {
691 if (spl_init())
692 hang();
693 }
5211b87e 694 timer_init();
3cd71981
SG
695 if (CONFIG_IS_ENABLED(BLOBLIST)) {
696 ret = bloblist_init();
697 if (ret) {
698 debug("%s: Failed to set up bloblist: ret=%d\n",
699 __func__, ret);
700 puts(SPL_TPL_PROMPT "Cannot set up bloblist\n");
701 hang();
702 }
703 }
704 if (CONFIG_IS_ENABLED(HANDOFF)) {
705 int ret;
706
707 ret = setup_spl_handoff();
708 if (ret) {
709 puts(SPL_TPL_PROMPT "Cannot set up SPL handoff\n");
710 hang();
711 }
712 }
5211b87e 713
6371c479
SG
714 if (CONFIG_IS_ENABLED(BOARD_INIT))
715 spl_board_init();
5211b87e 716
6371c479
SG
717 if (IS_ENABLED(CONFIG_SPL_WATCHDOG) && CONFIG_IS_ENABLED(WDT))
718 initr_watchdog();
06985289 719
a343b4fe
HS
720 if (IS_ENABLED(CONFIG_SPL_OS_BOOT) || CONFIG_IS_ENABLED(HANDOFF) ||
721 IS_ENABLED(CONFIG_SPL_ATF))
b0edea3c
SG
722 dram_init_banksize();
723
15a23b6f 724 if (CONFIG_IS_ENABLED(PCI) && !(gd->flags & GD_FLG_DM_DEAD)) {
7d4c8cfe
HS
725 ret = pci_init();
726 if (ret)
727 puts(SPL_TPL_PROMPT "Cannot initialize PCI\n");
728 /* Don't fail. We still can try other boot methods. */
729 }
730
a8be2494
LM
731 bootcount_inc();
732
4f6500aa
SG
733 /* Dump driver model states to aid analysis */
734 if (CONFIG_IS_ENABLED(DM_STATS)) {
735 struct dm_stats mem;
736
737 dm_get_mem(&mem);
738 dm_dump_mem(&mem);
739 }
740
d32b2d1c 741 memset(&spl_image, '\0', sizeof(spl_image));
e0be6eaf
SG
742 if (IS_ENABLED(CONFIG_SPL_OS_BOOT))
743 spl_image.arg = (void *)SPL_PAYLOAD_ARGS_ADDR;
de5dd4c4 744 spl_image.boot_device = BOOT_DEVICE_NONE;
f101e4bd 745 board_boot_order(spl_boot_list);
f101e4bd 746
7d84fbb5
SG
747 ret = boot_from_devices(&spl_image, spl_boot_list,
748 ARRAY_SIZE(spl_boot_list));
749 if (ret) {
06b1bca6 750 if (CONFIG_IS_ENABLED(SHOW_ERRORS))
7d84fbb5
SG
751 printf(SPL_TPL_PROMPT "failed to boot from all boot devices (err=%d)\n",
752 ret);
753 else
754 puts(SPL_TPL_PROMPT "failed to boot from all boot devices\n");
5211b87e 755 hang();
f101e4bd 756 }
5211b87e 757
de5dd4c4
PT
758 spl_perform_fixups(&spl_image);
759
f817e08f
SG
760 os = spl_image.os;
761 if (os == IH_OS_U_BOOT) {
1a9e75bd 762 debug("Jumping to %s...\n", spl_phase_name(spl_next_phase()));
f817e08f 763 } else if (CONFIG_IS_ENABLED(ATF) && os == IH_OS_ARM_TRUSTED_FIRMWARE) {
1d379090 764 debug("Jumping to U-Boot via ARM Trusted Firmware\n");
f817e08f 765 spl_fixup_fdt(spl_image_fdt_addr(&spl_image));
6826c432 766 jump_to_image = &spl_invoke_atf;
f817e08f 767 } else if (CONFIG_IS_ENABLED(OPTEE_IMAGE) && os == IH_OS_TEE) {
70fe2876 768 debug("Jumping to U-Boot via OP-TEE\n");
f817e08f 769 spl_board_prepare_for_optee(spl_image_fdt_addr(&spl_image));
6826c432 770 jump_to_image = &jump_to_image_optee;
f817e08f 771 } else if (CONFIG_IS_ENABLED(OPENSBI) && os == IH_OS_OPENSBI) {
5e30e45c 772 debug("Jumping to U-Boot via RISC-V OpenSBI\n");
6826c432 773 jump_to_image = &spl_invoke_opensbi;
f817e08f 774 } else if (CONFIG_IS_ENABLED(OS_BOOT) && os == IH_OS_LINUX) {
379c19ab 775 debug("Jumping to Linux\n");
e0be6eaf
SG
776 if (IS_ENABLED(CONFIG_SPL_OS_BOOT))
777 spl_fixup_fdt((void *)SPL_PAYLOAD_ARGS_ADDR);
379c19ab 778 spl_board_prepare_for_linux();
6826c432 779 jump_to_image = &jump_to_image_linux;
f817e08f 780 } else {
42120981 781 debug("Unsupported OS image.. Jumping nevertheless..\n");
8cf686e1 782 }
2003a83c
SG
783 if (CONFIG_IS_ENABLED(SYS_MALLOC_F) &&
784 !IS_ENABLED(CONFIG_SPL_SYS_MALLOC_SIZE))
785 debug("SPL malloc() used 0x%lx bytes (%ld KB)\n",
786 gd_malloc_ptr(), gd_malloc_ptr() / 1024);
787
05e3a0d6 788 bootstage_mark_name(get_bootstage_id(false), "end phase");
17ba5010 789 ret = bootstage_stash_default();
824bb1b4
SG
790 if (ret)
791 debug("Failed to stash bootstage: err=%d\n", ret);
a8c5112a 792
954b0ad4
NJ
793 if (IS_ENABLED(CONFIG_SPL_VIDEO_REMOVE)) {
794 struct udevice *dev;
795 int rc;
796
797 rc = uclass_find_device(UCLASS_VIDEO, 0, &dev);
798 if (!rc && dev) {
799 rc = device_remove(dev, DM_REMOVE_NORMAL);
800 if (rc)
801 printf("Cannot remove video device '%s' (err=%d)\n",
802 dev->name, rc);
803 }
7a17e4c6 804 }
a17e1e76
SG
805 if (CONFIG_IS_ENABLED(HANDOFF)) {
806 ret = write_spl_handoff();
807 if (ret)
808 printf(SPL_TPL_PROMPT
809 "SPL hand-off write failed (err=%d)\n", ret);
810 }
811 if (CONFIG_IS_ENABLED(BLOBLIST)) {
812 ret = bloblist_finish();
813 if (ret)
814 printf("Warning: Failed to finish bloblist (ret=%d)\n",
815 ret);
816 }
7a17e4c6 817
3a3b9147 818 spl_board_prepare_for_boot();
6826c432 819 jump_to_image(&spl_image);
bcae7211
A
820}
821
6507f133
TR
822/*
823 * This requires UART clocks to be enabled. In order for this to work the
824 * caller must ensure that the gd pointer is valid.
825 */
bcae7211
A
826void preloader_console_init(void)
827{
2a736066 828#ifdef CONFIG_SPL_SERIAL
bcae7211
A
829 gd->baudrate = CONFIG_BAUDRATE;
830
bcae7211
A
831 serial_init(); /* serial communications setup */
832
b88befa5
IY
833 gd->have_console = 1;
834
aedc08b2 835#if CONFIG_IS_ENABLED(BANNER_PRINT)
d6330064
SG
836 puts("\nU-Boot " SPL_TPL_NAME " " PLAIN_VERSION " (" U_BOOT_DATE " - "
837 U_BOOT_TIME " " U_BOOT_TZ ")\n");
0292bc0d 838#endif
861a86f4
TR
839#ifdef CONFIG_SPL_DISPLAY_PRINT
840 spl_display_print();
841#endif
117a0e02 842#endif
3988be5f 843}
db910353 844
d8c03320
SG
845/**
846 * This function is called before the stack is changed from initial stack to
847 * relocated stack. It tries to dump the stack size used
848 */
849__weak void spl_relocate_stack_check(void)
850{
851#if CONFIG_IS_ENABLED(SYS_REPORT_STACK_F_USAGE)
852 ulong init_sp = gd->start_addr_sp;
853 ulong stack_bottom = init_sp - CONFIG_VAL(SIZE_LIMIT_PROVIDE_STACK);
854 u8 *ptr = (u8 *)stack_bottom;
855 ulong i;
856
857 for (i = 0; i < CONFIG_VAL(SIZE_LIMIT_PROVIDE_STACK); i++) {
858 if (*ptr != CONFIG_VAL(SYS_STACK_F_CHECK_BYTE))
859 break;
860 ptr++;
861 }
862 printf("SPL initial stack usage: %lu bytes\n",
863 CONFIG_VAL(SIZE_LIMIT_PROVIDE_STACK) - i);
864#endif
865}
866
db910353
SG
867/**
868 * spl_relocate_stack_gd() - Relocate stack ready for board_init_r() execution
869 *
870 * Sometimes board_init_f() runs with a stack in SRAM but we want to use SDRAM
871 * for the main board_init_r() execution. This is typically because we need
872 * more stack space for things like the MMC sub-system.
873 *
874 * This function calculates the stack position, copies the global_data into
adc421e4
AA
875 * place, sets the new gd (except for ARM, for which setting GD within a C
876 * function may not always work) and returns the new stack position. The
877 * caller is responsible for setting up the sp register and, in the case
878 * of ARM, setting up gd.
879 *
880 * All of this is done using the same layout and alignments as done in
881 * board_init_f_init_reserve() / board_init_f_alloc_reserve().
db910353 882 *
185f812c 883 * Return: new stack location, or 0 to use the same stack
db910353
SG
884 */
885ulong spl_relocate_stack_gd(void)
886{
887#ifdef CONFIG_SPL_STACK_R
888 gd_t *new_gd;
adc421e4 889 ulong ptr = CONFIG_SPL_STACK_R_ADDR;
db910353 890
d8c03320
SG
891 if (CONFIG_IS_ENABLED(SYS_REPORT_STACK_F_USAGE))
892 spl_relocate_stack_check();
893
3d6d5075 894#if defined(CONFIG_SPL_SYS_MALLOC_SIMPLE) && CONFIG_IS_ENABLED(SYS_MALLOC_F)
dcfcb8d4 895 if (CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN) {
438dcabb
SG
896 debug("SPL malloc() before relocation used 0x%lx bytes (%ld KB)\n",
897 gd->malloc_ptr, gd->malloc_ptr / 1024);
dcfcb8d4
HG
898 ptr -= CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN;
899 gd->malloc_base = ptr;
900 gd->malloc_limit = CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN;
901 gd->malloc_ptr = 0;
902 }
903#endif
adc421e4
AA
904 /* Get stack position: use 8-byte alignment for ABI compliance */
905 ptr = CONFIG_SPL_STACK_R_ADDR - roundup(sizeof(gd_t),16);
149fb05b 906 gd->start_addr_sp = ptr;
adc421e4
AA
907 new_gd = (gd_t *)ptr;
908 memcpy(new_gd, (void *)gd, sizeof(gd_t));
2f11cd91
SG
909#if CONFIG_IS_ENABLED(DM)
910 dm_fixup_for_gd_move(new_gd);
911#endif
39162d93
TW
912#if CONFIG_IS_ENABLED(LOG)
913 log_fixup_for_gd_move(new_gd);
914#endif
c7e1effb 915#if !defined(CONFIG_ARM) && !defined(CONFIG_RISCV)
adc421e4
AA
916 gd = new_gd;
917#endif
db910353
SG
918 return ptr;
919#else
920 return 0;
921#endif
922}
c6604441 923
4d145f26
PR
924#if defined(CONFIG_BOOTCOUNT_LIMIT) && \
925 ((!defined(CONFIG_TPL_BUILD) && !defined(CONFIG_SPL_BOOTCOUNT_LIMIT)) || \
926 (defined(CONFIG_TPL_BUILD) && !defined(CONFIG_TPL_BOOTCOUNT_LIMIT)))
c6604441
SG
927void bootcount_store(ulong a)
928{
929}
930
931ulong bootcount_load(void)
932{
933 return 0;
934}
935#endif