198675Sdes// SPDX-License-Identifier: GPL-2.0+
298675Sdes/*
398675Sdes * (C) Copyright 2010
498675Sdes * Texas Instruments, <www.ti.com>
598675Sdes *
698675Sdes * Aneesh V <aneesh@ti.com>
798675Sdes */
898675Sdes
998675Sdes#include <common.h>
1098675Sdes#include <bloblist.h>
1198675Sdes#include <binman_sym.h>
1298675Sdes#include <bootstage.h>
1398675Sdes#include <dm.h>
1498675Sdes#include <handoff.h>
1598675Sdes#include <hang.h>
1698675Sdes#include <init.h>
1798675Sdes#include <irq_func.h>
1898675Sdes#include <log.h>
1998675Sdes#include <mapmem.h>
2098675Sdes#include <serial.h>
2198675Sdes#include <spl.h>
2298675Sdes#include <spl_load.h>
2398675Sdes#include <system-constants.h>
2498675Sdes#include <asm/global_data.h>
2598675Sdes#include <asm-generic/gpio.h>
2698675Sdes#include <asm/u-boot.h>
2798675Sdes#include <nand.h>
2898675Sdes#include <fat.h>
2998675Sdes#include <u-boot/crc.h>
3098675Sdes#if CONFIG_IS_ENABLED(BANNER_PRINT)
3198675Sdes#include <timestamp.h>
3298675Sdes#endif
3398675Sdes#include <version.h>
3498675Sdes#include <image.h>
3598675Sdes#include <malloc.h>
3698675Sdes#include <mapmem.h>
3798675Sdes#include <dm/root.h>
3898675Sdes#include <dm/util.h>
3998675Sdes#include <dm/device-internal.h>
4098675Sdes#include <dm/uclass-internal.h>
4198675Sdes#include <linux/compiler.h>
4298675Sdes#include <fdt_support.h>
4398675Sdes#include <bootcount.h>
4498675Sdes#include <wdt.h>
4598675Sdes#include <video.h>
4698675Sdes
4798675SdesDECLARE_GLOBAL_DATA_PTR;
4898675SdesDECLARE_BINMAN_MAGIC_SYM;
4998675Sdes
5098675Sdesu32 *boot_params_ptr = NULL;
5198675Sdes
5298675Sdes#if CONFIG_IS_ENABLED(BINMAN_UBOOT_SYMBOLS)
5398675Sdes/* See spl.h for information about this */
5498675Sdesbinman_sym_declare(ulong, u_boot_any, image_pos);
5598675Sdesbinman_sym_declare(ulong, u_boot_any, size);
5698675Sdes
5798675Sdes#ifdef CONFIG_TPL
5898675Sdesbinman_sym_declare(ulong, u_boot_spl_any, image_pos);
5998675Sdesbinman_sym_declare(ulong, u_boot_spl_any, size);
6098675Sdes#endif
6198675Sdes
6298675Sdes#ifdef CONFIG_VPL
6398675Sdesbinman_sym_declare(ulong, u_boot_vpl_any, image_pos);
6498675Sdesbinman_sym_declare(ulong, u_boot_vpl_any, size);
6598675Sdes#endif
6698675Sdes
6798675Sdes#endif /* BINMAN_UBOOT_SYMBOLS */
6898675Sdes
6998675Sdes/* Define board data structure */
7098675Sdesstatic struct bd_info bdata __attribute__ ((section(".data")));
7198675Sdes
7298675Sdes#if CONFIG_IS_ENABLED(SHOW_BOOT_PROGRESS)
7398675Sdes/*
7498675Sdes * Board-specific Platform code can reimplement show_boot_progress () if needed
7598675Sdes */
7698675Sdes__weak void show_boot_progress(int val) {}
7798675Sdes#endif
7898675Sdes
7998675Sdes#if defined(CONFIG_SPL_OS_BOOT) || CONFIG_IS_ENABLED(HANDOFF) || \
8098675Sdes	defined(CONFIG_SPL_ATF)
8198675Sdes/* weak, default platform-specific function to initialize dram banks */
8298675Sdes__weak int dram_init_banksize(void)
8398675Sdes{
8498675Sdes	return 0;
8598675Sdes}
8698675Sdes#endif
8798675Sdes
8898675Sdes/*
8998675Sdes * Default function to determine if u-boot or the OS should
9098675Sdes * be started. This implementation always returns 1.
9198675Sdes *
9298675Sdes * Please implement your own board specific funcion to do this.
9398675Sdes *
9498675Sdes * RETURN
9598675Sdes * 0 to not start u-boot
9698675Sdes * positive if u-boot should start
9798675Sdes */
9898675Sdes#if CONFIG_IS_ENABLED(OS_BOOT)
9998675Sdes__weak int spl_start_uboot(void)
10098675Sdes{
10198675Sdes	puts(SPL_TPL_PROMPT
10298675Sdes	     "Please implement spl_start_uboot() for your board\n");
10398675Sdes	puts(SPL_TPL_PROMPT "Direct Linux boot not active!\n");
10498675Sdes	return 1;
10598675Sdes}
10698675Sdes
10798675Sdes/*
10898675Sdes * Weak default function for arch specific zImage check. Return zero
10998675Sdes * and fill start and end address if image is recognized.
11098675Sdes */
11198675Sdesint __weak bootz_setup(ulong image, ulong *start, ulong *end)
11298675Sdes{
11398675Sdes	 return 1;
11498675Sdes}
11598675Sdes
11698675Sdesint __weak booti_setup(ulong image, ulong *relocated_addr, ulong *size, bool force_reloc)
11798675Sdes{
11898675Sdes	 return 1;
11998675Sdes}
12098675Sdes#endif
12198675Sdes
12298675Sdes/* Weak default function for arch/board-specific fixups to the spl_image_info */
12398675Sdesvoid __weak spl_perform_fixups(struct spl_image_info *spl_image)
12498675Sdes{
12598675Sdes}
12698675Sdes
12798675Sdesvoid spl_fixup_fdt(void *fdt_blob)
12898675Sdes{
12998675Sdes#if defined(CONFIG_SPL_OF_LIBFDT)
13098675Sdes	int err;
13198675Sdes
13298675Sdes	if (!fdt_blob)
13398675Sdes		return;
13498675Sdes
13598675Sdes	err = fdt_check_header(fdt_blob);
13698675Sdes	if (err < 0) {
13798675Sdes		printf("fdt_root: %s\n", fdt_strerror(err));
13898675Sdes		return;
13998675Sdes	}
14098675Sdes
14198675Sdes	/* fixup the memory dt node */
14298675Sdes	err = fdt_shrink_to_minimum(fdt_blob, 0);
14398675Sdes	if (err == 0) {
14498675Sdes		printf(SPL_TPL_PROMPT "fdt_shrink_to_minimum err - %d\n", err);
14598675Sdes		return;
14698675Sdes	}
14798675Sdes
14898675Sdes	err = arch_fixup_fdt(fdt_blob);
14998675Sdes	if (err) {
15098675Sdes		printf(SPL_TPL_PROMPT "arch_fixup_fdt err - %d\n", err);
15198675Sdes		return;
15298675Sdes	}
15398675Sdes#endif
15498675Sdes}
15598675Sdes
15698675Sdesint spl_reserve_video_from_ram_top(void)
15798675Sdes{
15898675Sdes	if (CONFIG_IS_ENABLED(VIDEO)) {
15998675Sdes		ulong addr;
16098675Sdes		int ret;
16198675Sdes
16298675Sdes		addr = gd->ram_top;
16398675Sdes		ret = video_reserve(&addr);
16498675Sdes		if (ret)
16598675Sdes			return ret;
16698675Sdes		debug("Reserving %luk for video at: %08lx\n",
16798675Sdes		      ((unsigned long)gd->relocaddr - addr) >> 10, addr);
16898675Sdes		gd->relocaddr = addr;
16998675Sdes	}
17098675Sdes
17198675Sdes	return 0;
17298675Sdes}
17398675Sdes
17498675Sdesulong spl_get_image_pos(void)
17598675Sdes{
17698675Sdes	if (!CONFIG_IS_ENABLED(BINMAN_UBOOT_SYMBOLS))
17798675Sdes		return BINMAN_SYM_MISSING;
17898675Sdes
17998675Sdes#ifdef CONFIG_VPL
18098675Sdes	if (spl_next_phase() == PHASE_VPL)
18198675Sdes		return binman_sym(ulong, u_boot_vpl_any, image_pos);
18298675Sdes#endif
18398675Sdes	return spl_next_phase() == PHASE_SPL ?
18498675Sdes		binman_sym(ulong, u_boot_spl_any, image_pos) :
18598675Sdes		binman_sym(ulong, u_boot_any, image_pos);
18698675Sdes}
18798675Sdes
18898675Sdesulong spl_get_image_size(void)
18998675Sdes{
19098675Sdes	if (!CONFIG_IS_ENABLED(BINMAN_UBOOT_SYMBOLS))
19198675Sdes		return BINMAN_SYM_MISSING;
19298675Sdes
19398675Sdes#ifdef CONFIG_VPL
19498675Sdes	if (spl_next_phase() == PHASE_VPL)
19598675Sdes		return binman_sym(ulong, u_boot_vpl_any, size);
19698675Sdes#endif
19798675Sdes	return spl_next_phase() == PHASE_SPL ?
19898675Sdes		binman_sym(ulong, u_boot_spl_any, size) :
19998675Sdes		binman_sym(ulong, u_boot_any, size);
20098937Sdes}
20198675Sdes
20298937Sdesulong spl_get_image_text_base(void)
20398675Sdes{
20498675Sdes#ifdef CONFIG_VPL
20598675Sdes	if (spl_next_phase() == PHASE_VPL)
20698675Sdes		return CONFIG_VPL_TEXT_BASE;
20798675Sdes#endif
20898675Sdes	return spl_next_phase() == PHASE_SPL ? CONFIG_SPL_TEXT_BASE :
20998675Sdes		CONFIG_TEXT_BASE;
21098675Sdes}
21198675Sdes
21298675Sdes/*
21398675Sdes * Weak default function for board specific cleanup/preparation before
21498675Sdes * Linux boot. Some boards/platforms might not need it, so just provide
21598675Sdes * an empty stub here.
21698675Sdes */
21798675Sdes__weak void spl_board_prepare_for_linux(void)
21898675Sdes{
21998675Sdes	/* Nothing to do! */
22098675Sdes}
22198675Sdes
22298675Sdes__weak void spl_board_prepare_for_optee(void *fdt)
22398675Sdes{
22498675Sdes}
22598675Sdes
22698675Sdes__weak const char *spl_board_loader_name(u32 boot_device)
22798675Sdes{
22898675Sdes	return NULL;
22998675Sdes}
23098675Sdes
23198675Sdes#if CONFIG_IS_ENABLED(OPTEE_IMAGE)
23298675Sdes__weak void __noreturn jump_to_image_optee(struct spl_image_info *spl_image)
23398675Sdes{
23498675Sdes	spl_optee_entry(NULL, NULL, spl_image->fdt_addr,
23598675Sdes			(void *)spl_image->entry_point);
23698675Sdes}
23798675Sdes#endif
23898675Sdes
23998675Sdes__weak void spl_board_prepare_for_boot(void)
24098675Sdes{
24198675Sdes	/* Nothing to do! */
24298675Sdes}
24398675Sdes
24498675Sdes__weak struct legacy_img_hdr *spl_get_load_buffer(ssize_t offset, size_t size)
24598675Sdes{
24698675Sdes	return map_sysmem(CONFIG_TEXT_BASE + offset, 0);
24798675Sdes}
24898675Sdes
24998675Sdes#ifdef CONFIG_SPL_RAW_IMAGE_SUPPORT
25098675Sdesvoid spl_set_header_raw_uboot(struct spl_image_info *spl_image)
25198675Sdes{
25298675Sdes	ulong u_boot_pos = spl_get_image_pos();
25398675Sdes
25498675Sdes#if CONFIG_SYS_MONITOR_LEN != 0
25598675Sdes	spl_image->size = CONFIG_SYS_MONITOR_LEN;
25698675Sdes#else
25798675Sdes	/* Unknown U-Boot size, let's assume it will not be more than 200 KB */
25898675Sdes	spl_image->size = 200 * 1024;
25998675Sdes#endif
26098675Sdes
26198675Sdes	/*
26298675Sdes	 * Binman error cases: address of the end of the previous region or the
26398675Sdes	 * start of the image's entry area (usually 0) if there is no previous
26498675Sdes	 * region.
26598675Sdes	 */
26698675Sdes	if (u_boot_pos && u_boot_pos != BINMAN_SYM_MISSING) {
26798675Sdes		/* Binman does not support separated entry addresses */
26898675Sdes		spl_image->entry_point = u_boot_pos;
26998675Sdes		spl_image->load_addr = u_boot_pos;
27098675Sdes	} else {
27198675Sdes		spl_image->entry_point = CONFIG_SYS_UBOOT_START;
27298675Sdes		spl_image->load_addr = CONFIG_TEXT_BASE;
27398675Sdes	}
27498675Sdes	spl_image->os = IH_OS_U_BOOT;
27598675Sdes	spl_image->name = "U-Boot";
27698675Sdes}
27798675Sdes#endif
27898675Sdes
27998675Sdes__weak int spl_parse_board_header(struct spl_image_info *spl_image,
28098675Sdes				  const struct spl_boot_device *bootdev,
28198675Sdes				  const void *image_header, size_t size)
28298675Sdes{
28398675Sdes	return -EINVAL;
28498675Sdes}
28598675Sdes
28698675Sdes__weak int spl_parse_legacy_header(struct spl_image_info *spl_image,
28798675Sdes				   const struct legacy_img_hdr *header)
28898675Sdes{
28998675Sdes	/* LEGACY image not supported */
29098675Sdes	debug("Legacy boot image support not enabled, proceeding to other boot methods\n");
29198675Sdes	return -EINVAL;
29298675Sdes}
29398675Sdes
29498675Sdesint spl_parse_image_header(struct spl_image_info *spl_image,
29598675Sdes			   const struct spl_boot_device *bootdev,
29698675Sdes			   const struct legacy_img_hdr *header)
29798675Sdes{
29898675Sdes	int ret;
29998675Sdes
30098675Sdes	if (CONFIG_IS_ENABLED(LOAD_FIT_FULL)) {
30198675Sdes		ret = spl_load_fit_image(spl_image, header);
30298675Sdes
30398675Sdes		if (!ret)
30498675Sdes			return ret;
30598675Sdes	}
30698675Sdes	if (image_get_magic(header) == IH_MAGIC) {
30798675Sdes		int ret;
30898675Sdes
30998675Sdes		ret = spl_parse_legacy_header(spl_image, header);
31098675Sdes		if (ret)
31198675Sdes			return ret;
31298675Sdes	} else {
31398675Sdes#ifdef CONFIG_SPL_PANIC_ON_RAW_IMAGE
31498675Sdes		/*
31598675Sdes		 * CONFIG_SPL_PANIC_ON_RAW_IMAGE is defined when the
31698675Sdes		 * code which loads images in SPL cannot guarantee that
31798675Sdes		 * absolutely all read errors will be reported.
31898675Sdes		 * An example is the LPC32XX MLC NAND driver, which
31998675Sdes		 * will consider that a completely unreadable NAND block
32098675Sdes		 * is bad, and thus should be skipped silently.
32198675Sdes		 */
32298675Sdes		panic("** no mkimage signature but raw image not supported");
32398675Sdes#endif
32498675Sdes
32598675Sdes#if CONFIG_IS_ENABLED(OS_BOOT)
32698675Sdes#if defined(CMD_BOOTI)
32798675Sdes		ulong start, size;
32898675Sdes
32998675Sdes		if (!booti_setup((ulong)header, &start, &size, 0)) {
33098675Sdes			spl_image->name = "Linux";
33198675Sdes			spl_image->os = IH_OS_LINUX;
33298675Sdes			spl_image->load_addr = start;
33398675Sdes			spl_image->entry_point = start;
33498675Sdes			spl_image->size = size;
33598675Sdes			debug(SPL_TPL_PROMPT
33698675Sdes			      "payload Image, load addr: 0x%lx size: %d\n",
33798675Sdes			      spl_image->load_addr, spl_image->size);
33898675Sdes			return 0;
33998675Sdes		}
34098675Sdes#elif defined(CMD_BOOTZ)
34198675Sdes		ulong start, end;
34298675Sdes
34398675Sdes		if (!bootz_setup((ulong)header, &start, &end)) {
34498675Sdes			spl_image->name = "Linux";
34598675Sdes			spl_image->os = IH_OS_LINUX;
34698675Sdes			spl_image->load_addr = CONFIG_SYS_LOAD_ADDR;
34798675Sdes			spl_image->entry_point = CONFIG_SYS_LOAD_ADDR;
34898675Sdes			spl_image->size = end - start;
34998675Sdes			debug(SPL_TPL_PROMPT
35098675Sdes			      "payload zImage, load addr: 0x%lx size: %d\n",
35198675Sdes			      spl_image->load_addr, spl_image->size);
35298675Sdes			return 0;
35398675Sdes		}
35498675Sdes#endif
35598675Sdes#endif
35698675Sdes
35798675Sdes		if (!spl_parse_board_header(spl_image, bootdev, (const void *)header, sizeof(*header)))
35898675Sdes			return 0;
35998675Sdes
36098675Sdes#ifdef CONFIG_SPL_RAW_IMAGE_SUPPORT
36198675Sdes		/* Signature not found - assume u-boot.bin */
36298675Sdes		debug("mkimage signature not found - ih_magic = %x\n",
36398675Sdes			header->ih_magic);
36498675Sdes		spl_set_header_raw_uboot(spl_image);
36598675Sdes#else
36698675Sdes		/* RAW image not supported, proceed to other boot methods. */
36798675Sdes		debug("Raw boot image support not enabled, proceeding to other boot methods\n");
36898675Sdes		return -EINVAL;
36998675Sdes#endif
37098675Sdes	}
37198675Sdes
37298675Sdes	return 0;
37398675Sdes}
37498675Sdes
37598675Sdes#if SPL_LOAD_USERS > 1
37698675Sdesint spl_load(struct spl_image_info *spl_image,
37798675Sdes	     const struct spl_boot_device *bootdev, struct spl_load_info *info,
37898675Sdes	     size_t size, size_t offset)
37998675Sdes{
38098675Sdes	return _spl_load(spl_image, bootdev, info, size, offset);
38198675Sdes}
38298675Sdes#endif
38398675Sdes
38498675Sdes__weak void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
38598675Sdes{
38698675Sdes	typedef void __noreturn (*image_entry_noargs_t)(void);
38798675Sdes
38898675Sdes	image_entry_noargs_t image_entry =
38998675Sdes		(image_entry_noargs_t)spl_image->entry_point;
39098675Sdes
39198675Sdes	debug("image entry point: 0x%lx\n", spl_image->entry_point);
39298675Sdes	image_entry();
39398675Sdes}
39498675Sdes
39598675Sdes#if CONFIG_IS_ENABLED(HANDOFF)
39698675Sdes/**
39798675Sdes * Set up the SPL hand-off information
39898675Sdes *
39998675Sdes * This is initially empty (zero) but can be written by
40098675Sdes */
40198675Sdesstatic int setup_spl_handoff(void)
40298675Sdes{
40398675Sdes	struct spl_handoff *ho;
40498675Sdes
40598675Sdes	ho = bloblist_ensure(BLOBLISTT_U_BOOT_SPL_HANDOFF, sizeof(struct spl_handoff));
40698675Sdes	if (!ho)
40798675Sdes		return -ENOENT;
40898675Sdes
40998675Sdes	return 0;
41098675Sdes}
41198675Sdes
41298675Sdes__weak int handoff_arch_save(struct spl_handoff *ho)
41398675Sdes{
41498675Sdes	return 0;
41598675Sdes}
41698675Sdes
41798675Sdesstatic int write_spl_handoff(void)
41898675Sdes{
41998675Sdes	struct spl_handoff *ho;
42098675Sdes	int ret;
42198675Sdes
42298675Sdes	ho = bloblist_find(BLOBLISTT_U_BOOT_SPL_HANDOFF, sizeof(struct spl_handoff));
42398675Sdes	if (!ho)
42498675Sdes		return -ENOENT;
42598675Sdes	handoff_save_dram(ho);
42698675Sdes	ret = handoff_arch_save(ho);
42798675Sdes	if (ret)
42898675Sdes		return ret;
42998675Sdes	debug(SPL_TPL_PROMPT "Wrote SPL handoff\n");
43098675Sdes
43198675Sdes	return 0;
43298675Sdes}
43398675Sdes#else
43498675Sdesstatic inline int setup_spl_handoff(void) { return 0; }
43598675Sdesstatic inline int write_spl_handoff(void) { return 0; }
43698675Sdes
43798675Sdes#endif /* HANDOFF */
43898675Sdes
43998675Sdes/**
44098675Sdes * get_bootstage_id() - Get the bootstage ID to emit
44198675Sdes *
44298675Sdes * @start: true if this is for starting SPL, false for ending it
44398675Sdes * Return: bootstage ID to use
44498675Sdes */
44598675Sdesstatic enum bootstage_id get_bootstage_id(bool start)
44698675Sdes{
44798675Sdes	enum u_boot_phase phase = spl_phase();
44898675Sdes
44998675Sdes	if (IS_ENABLED(CONFIG_TPL_BUILD) && phase == PHASE_TPL)
45098675Sdes		return start ? BOOTSTAGE_ID_START_TPL : BOOTSTAGE_ID_END_TPL;
45198675Sdes	else if (IS_ENABLED(CONFIG_VPL_BUILD) && phase == PHASE_VPL)
45298675Sdes		return start ? BOOTSTAGE_ID_START_VPL : BOOTSTAGE_ID_END_VPL;
45398675Sdes	else
45498675Sdes		return start ? BOOTSTAGE_ID_START_SPL : BOOTSTAGE_ID_END_SPL;
45598675Sdes}
45698675Sdes
45798675Sdesstatic int spl_common_init(bool setup_malloc)
45898675Sdes{
45998675Sdes	int ret;
46098675Sdes
46198675Sdes#if CONFIG_IS_ENABLED(SYS_MALLOC_F)
46298675Sdes	if (setup_malloc) {
46398675Sdes#ifdef CFG_MALLOC_F_ADDR
46498675Sdes		gd->malloc_base = CFG_MALLOC_F_ADDR;
46598675Sdes#endif
46698675Sdes		gd->malloc_limit = CONFIG_VAL(SYS_MALLOC_F_LEN);
46798675Sdes		gd->malloc_ptr = 0;
46898675Sdes	}
46998675Sdes#endif
47098675Sdes	ret = bootstage_init(u_boot_first_phase());
47198675Sdes	if (ret) {
47298675Sdes		debug("%s: Failed to set up bootstage: ret=%d\n", __func__,
47398675Sdes		      ret);
47498675Sdes		return ret;
47598675Sdes	}
47698675Sdes	if (!u_boot_first_phase()) {
47798675Sdes		ret = bootstage_unstash_default();
47898675Sdes		if (ret)
47998675Sdes			log_debug("Failed to unstash bootstage: ret=%d\n", ret);
48098675Sdes	}
48198675Sdes	bootstage_mark_name(get_bootstage_id(true),
48298675Sdes			    spl_phase_name(spl_phase()));
48398675Sdes#if CONFIG_IS_ENABLED(LOG)
48498675Sdes	ret = log_init();
48598675Sdes	if (ret) {
48698675Sdes		debug("%s: Failed to set up logging\n", __func__);
48798675Sdes		return ret;
48898675Sdes	}
48998675Sdes#endif
49098675Sdes	if (CONFIG_IS_ENABLED(OF_REAL)) {
49198675Sdes		ret = fdtdec_setup();
49298675Sdes		if (ret) {
49398675Sdes			debug("fdtdec_setup() returned error %d\n", ret);
49498675Sdes			return ret;
49598675Sdes		}
49698675Sdes	}
49798675Sdes	if (CONFIG_IS_ENABLED(DM)) {
49898675Sdes		bootstage_start(BOOTSTAGE_ID_ACCUM_DM_SPL,
49998675Sdes				spl_phase() == PHASE_TPL ? "dm tpl" : "dm_spl");
50098675Sdes		/* With CONFIG_SPL_OF_PLATDATA, bring in all devices */
50198675Sdes		ret = dm_init_and_scan(!CONFIG_IS_ENABLED(OF_PLATDATA));
50298675Sdes		bootstage_accum(BOOTSTAGE_ID_ACCUM_DM_SPL);
50398675Sdes		if (ret) {
50498675Sdes			debug("dm_init_and_scan() returned error %d\n", ret);
50598675Sdes			return ret;
50698675Sdes		}
50798675Sdes	}
50898675Sdes
50998675Sdes	return 0;
51098675Sdes}
51198675Sdes
51298675Sdesvoid spl_set_bd(void)
51398675Sdes{
51498675Sdes	/*
51598675Sdes	 * NOTE: On some platforms (e.g. x86) bdata may be in flash and not
51698675Sdes	 * writeable.
51798675Sdes	 */
51898675Sdes	if (!gd->bd)
51998675Sdes		gd->bd = &bdata;
52098675Sdes}
52198675Sdes
52298675Sdesint spl_early_init(void)
52398675Sdes{
52498675Sdes	int ret;
52598675Sdes
52698675Sdes	debug("%s\n", __func__);
52798675Sdes
52898675Sdes	ret = spl_common_init(true);
52998675Sdes	if (ret)
53098675Sdes		return ret;
53198675Sdes	gd->flags |= GD_FLG_SPL_EARLY_INIT;
53298675Sdes
53398675Sdes	return 0;
53498675Sdes}
53598675Sdes
53698675Sdesint spl_init(void)
53798675Sdes{
53898675Sdes	int ret;
53998675Sdes	bool setup_malloc = !(IS_ENABLED(CONFIG_SPL_STACK_R) &&
54098675Sdes			IS_ENABLED(CONFIG_SPL_SYS_MALLOC_SIMPLE));
54198675Sdes
54298675Sdes	debug("%s\n", __func__);
54398675Sdes
54498675Sdes	if (!(gd->flags & GD_FLG_SPL_EARLY_INIT)) {
54598675Sdes		ret = spl_common_init(setup_malloc);
54698675Sdes		if (ret)
54798675Sdes			return ret;
54898675Sdes	}
54998675Sdes	gd->flags |= GD_FLG_SPL_INIT;
55098675Sdes
55198675Sdes	return 0;
55298675Sdes}
55398675Sdes
55498675Sdes#ifndef BOOT_DEVICE_NONE
55598675Sdes#define BOOT_DEVICE_NONE 0xdeadbeef
55698675Sdes#endif
55798675Sdes
55898675Sdes__weak void board_boot_order(u32 *spl_boot_list)
55998675Sdes{
56098675Sdes	spl_boot_list[0] = spl_boot_device();
56198675Sdes}
56298675Sdes
56398675Sdes__weak int spl_check_board_image(struct spl_image_info *spl_image,
56498675Sdes				 const struct spl_boot_device *bootdev)
56598675Sdes{
56698675Sdes	return 0;
56798675Sdes}
56898675Sdes
56998675Sdesstatic int spl_load_image(struct spl_image_info *spl_image,
57098675Sdes			  struct spl_image_loader *loader)
57198675Sdes{
57298675Sdes	int ret;
57398675Sdes	struct spl_boot_device bootdev;
57498675Sdes
57598675Sdes	bootdev.boot_device = loader->boot_device;
57698675Sdes	bootdev.boot_device_name = NULL;
57798675Sdes
57898675Sdes	ret = loader->load_image(spl_image, &bootdev);
57998675Sdes#ifdef CONFIG_SPL_LEGACY_IMAGE_CRC_CHECK
58098675Sdes	if (!ret && spl_image->dcrc_length) {
58198675Sdes		/* check data crc */
58298675Sdes		ulong dcrc = crc32_wd(0, (unsigned char *)spl_image->dcrc_data,
58398675Sdes				      spl_image->dcrc_length, CHUNKSZ_CRC32);
58498675Sdes		if (dcrc != spl_image->dcrc) {
58598675Sdes			puts("SPL: Image data CRC check failed!\n");
58698675Sdes			ret = -EINVAL;
58798675Sdes		}
58898675Sdes	}
58998675Sdes#endif
59098675Sdes	if (!ret)
59198675Sdes		ret = spl_check_board_image(spl_image, &bootdev);
59298675Sdes
59398675Sdes	return ret;
59498675Sdes}
59598675Sdes
59698675Sdes/**
59798675Sdes * boot_from_devices() - Try loading a booting U-Boot from a list of devices
59898675Sdes *
59998675Sdes * @spl_image: Place to put the image details if successful
60098675Sdes * @spl_boot_list: List of boot devices to try
60198675Sdes * @count: Number of elements in spl_boot_list
60298675Sdes * Return: 0 if OK, -ENODEV if there were no boot devices
60398675Sdes *	if CONFIG_SHOW_ERRORS is enabled, returns -ENXIO if there were
60498675Sdes *	devices but none worked
60598675Sdes */
60698675Sdesstatic int boot_from_devices(struct spl_image_info *spl_image,
60798675Sdes			     u32 spl_boot_list[], int count)
60898675Sdes{
60998675Sdes	struct spl_image_loader *drv =
61098675Sdes		ll_entry_start(struct spl_image_loader, spl_image_loader);
61198675Sdes	const int n_ents =
61298675Sdes		ll_entry_count(struct spl_image_loader, spl_image_loader);
61398675Sdes	int ret = -ENODEV;
61498675Sdes	int i;
61598675Sdes
61698675Sdes	for (i = 0; i < count && spl_boot_list[i] != BOOT_DEVICE_NONE; i++) {
61798675Sdes		struct spl_image_loader *loader;
61898675Sdes		int bootdev = spl_boot_list[i];
61998675Sdes
62098675Sdes		if (CONFIG_IS_ENABLED(SHOW_ERRORS))
62198675Sdes			ret = -ENXIO;
62298675Sdes		for (loader = drv; loader != drv + n_ents; loader++) {
62398675Sdes			if (bootdev != loader->boot_device)
62498675Sdes				continue;
62598675Sdes			if (!CONFIG_IS_ENABLED(SILENT_CONSOLE)) {
62698675Sdes				if (loader)
62798675Sdes					printf("Trying to boot from %s\n",
62898675Sdes					       spl_loader_name(loader));
62998675Sdes				else if (CONFIG_IS_ENABLED(SHOW_ERRORS)) {
63098675Sdes					printf(SPL_TPL_PROMPT
63198675Sdes					       "Unsupported Boot Device %d\n",
63298675Sdes					       bootdev);
63398675Sdes				} else {
63498675Sdes					puts(SPL_TPL_PROMPT
63598675Sdes					     "Unsupported Boot Device!\n");
63698675Sdes				}
63798675Sdes			}
63898675Sdes			if (loader &&
63998675Sdes				!spl_load_image(spl_image, loader)) {
64098675Sdes				spl_image->boot_device = bootdev;
64198675Sdes				return 0;
64298675Sdes			}
64398675Sdes		}
64498675Sdes	}
64598675Sdes
64698675Sdes	return ret;
64798675Sdes}
64898675Sdes
64998675Sdes#if defined(CONFIG_SPL_FRAMEWORK_BOARD_INIT_F)
65098675Sdesvoid board_init_f(ulong dummy)
65198675Sdes{
65298937Sdes	if (CONFIG_IS_ENABLED(OF_CONTROL)) {
65398937Sdes		int ret;
65498937Sdes
65598937Sdes		ret = spl_early_init();
65698937Sdes		if (ret) {
65798937Sdes			debug("spl_early_init() failed: %d\n", ret);
65898937Sdes			hang();
65998937Sdes		}
66098937Sdes	}
66198937Sdes
66298937Sdes	preloader_console_init();
66398937Sdes}
66498937Sdes#endif
66598937Sdes
66698937Sdesvoid board_init_r(gd_t *dummy1, ulong dummy2)
66798937Sdes{
66898937Sdes	u32 spl_boot_list[] = {
66998675Sdes		BOOT_DEVICE_NONE,
67098675Sdes		BOOT_DEVICE_NONE,
67198675Sdes		BOOT_DEVICE_NONE,
67298675Sdes		BOOT_DEVICE_NONE,
67398675Sdes		BOOT_DEVICE_NONE,
67498675Sdes	};
67598675Sdes	typedef void __noreturn (*jump_to_image_t)(struct spl_image_info *);
67698675Sdes	jump_to_image_t jump_to_image = &jump_to_image_no_args;
67798675Sdes	struct spl_image_info spl_image;
67898675Sdes	int ret, os;
67998675Sdes
68098675Sdes	debug(">>" SPL_TPL_PROMPT "board_init_r()\n");
68198675Sdes
68298675Sdes	spl_set_bd();
68398675Sdes
68498675Sdes	if (IS_ENABLED(CONFIG_SPL_SYS_MALLOC)) {
68598675Sdes		mem_malloc_init((ulong)map_sysmem(SPL_SYS_MALLOC_START,
68698675Sdes						  SPL_SYS_MALLOC_SIZE),
68798675Sdes				SPL_SYS_MALLOC_SIZE);
68898675Sdes		gd->flags |= GD_FLG_FULL_MALLOC_INIT;
68998675Sdes	}
69098675Sdes	if (!(gd->flags & GD_FLG_SPL_INIT)) {
69198675Sdes		if (spl_init())
69298675Sdes			hang();
69398675Sdes	}
69498675Sdes	timer_init();
69598675Sdes	if (CONFIG_IS_ENABLED(BLOBLIST)) {
69698675Sdes		ret = bloblist_init();
69798675Sdes		if (ret) {
69898675Sdes			debug("%s: Failed to set up bloblist: ret=%d\n",
69998675Sdes			      __func__, ret);
70098675Sdes			puts(SPL_TPL_PROMPT "Cannot set up bloblist\n");
70198675Sdes			hang();
70298675Sdes		}
70398675Sdes	}
70498675Sdes	if (CONFIG_IS_ENABLED(HANDOFF)) {
70598675Sdes		int ret;
70698675Sdes
70798675Sdes		ret = setup_spl_handoff();
70898675Sdes		if (ret) {
70998675Sdes			puts(SPL_TPL_PROMPT "Cannot set up SPL handoff\n");
71098675Sdes			hang();
71198675Sdes		}
71298675Sdes	}
71398675Sdes
71498675Sdes	if (CONFIG_IS_ENABLED(BOARD_INIT))
71598675Sdes		spl_board_init();
71698675Sdes
71798675Sdes	if (IS_ENABLED(CONFIG_SPL_WATCHDOG) && CONFIG_IS_ENABLED(WDT))
71898675Sdes		initr_watchdog();
71998675Sdes
72098675Sdes	if (IS_ENABLED(CONFIG_SPL_OS_BOOT) || CONFIG_IS_ENABLED(HANDOFF) ||
72198675Sdes	    IS_ENABLED(CONFIG_SPL_ATF))
72298675Sdes		dram_init_banksize();
72398675Sdes
72498675Sdes	if (CONFIG_IS_ENABLED(PCI) && !(gd->flags & GD_FLG_DM_DEAD)) {
72598675Sdes		ret = pci_init();
72698675Sdes		if (ret)
72798675Sdes			puts(SPL_TPL_PROMPT "Cannot initialize PCI\n");
72898675Sdes		/* Don't fail. We still can try other boot methods. */
72998675Sdes	}
73098675Sdes
73198675Sdes	bootcount_inc();
73298675Sdes
73398675Sdes	/* Dump driver model states to aid analysis */
73498675Sdes	if (CONFIG_IS_ENABLED(DM_STATS)) {
73598675Sdes		struct dm_stats mem;
73698675Sdes
73798675Sdes		dm_get_mem(&mem);
73898675Sdes		dm_dump_mem(&mem);
73998675Sdes	}
74098675Sdes
74198675Sdes	memset(&spl_image, '\0', sizeof(spl_image));
74298675Sdes	if (IS_ENABLED(CONFIG_SPL_OS_BOOT))
74398675Sdes		spl_image.arg = (void *)SPL_PAYLOAD_ARGS_ADDR;
74498675Sdes	spl_image.boot_device = BOOT_DEVICE_NONE;
74598675Sdes	board_boot_order(spl_boot_list);
74698675Sdes
74798675Sdes	ret = boot_from_devices(&spl_image, spl_boot_list,
74898675Sdes				ARRAY_SIZE(spl_boot_list));
74998675Sdes	if (ret) {
75098675Sdes		if (CONFIG_IS_ENABLED(SHOW_ERRORS))
75198675Sdes			printf(SPL_TPL_PROMPT "failed to boot from all boot devices (err=%d)\n",
75298675Sdes			       ret);
75398675Sdes		else
75498675Sdes			puts(SPL_TPL_PROMPT "failed to boot from all boot devices\n");
75598675Sdes		hang();
75698675Sdes	}
75798675Sdes
75898675Sdes	spl_perform_fixups(&spl_image);
75998675Sdes
76098675Sdes	os = spl_image.os;
76198675Sdes	if (os == IH_OS_U_BOOT) {
76298675Sdes		debug("Jumping to %s...\n", spl_phase_name(spl_next_phase()));
76398675Sdes	} else if (CONFIG_IS_ENABLED(ATF) && os == IH_OS_ARM_TRUSTED_FIRMWARE) {
76498675Sdes		debug("Jumping to U-Boot via ARM Trusted Firmware\n");
76598675Sdes		spl_fixup_fdt(spl_image_fdt_addr(&spl_image));
76698675Sdes		jump_to_image = &spl_invoke_atf;
76798675Sdes	} else if (CONFIG_IS_ENABLED(OPTEE_IMAGE) && os == IH_OS_TEE) {
76898675Sdes		debug("Jumping to U-Boot via OP-TEE\n");
76998675Sdes		spl_board_prepare_for_optee(spl_image_fdt_addr(&spl_image));
77099046Sdes		jump_to_image = &jump_to_image_optee;
77198675Sdes	} else if (CONFIG_IS_ENABLED(OPENSBI) && os == IH_OS_OPENSBI) {
77298675Sdes		debug("Jumping to U-Boot via RISC-V OpenSBI\n");
77398675Sdes		jump_to_image = &spl_invoke_opensbi;
77498675Sdes	} else if (CONFIG_IS_ENABLED(OS_BOOT) && os == IH_OS_LINUX) {
77598675Sdes		debug("Jumping to Linux\n");
77698675Sdes		if (IS_ENABLED(CONFIG_SPL_OS_BOOT))
77798675Sdes			spl_fixup_fdt((void *)SPL_PAYLOAD_ARGS_ADDR);
77898675Sdes		spl_board_prepare_for_linux();
77998675Sdes		jump_to_image = &jump_to_image_linux;
78098675Sdes	} else {
78198675Sdes		debug("Unsupported OS image.. Jumping nevertheless..\n");
78298675Sdes	}
78398675Sdes	if (CONFIG_IS_ENABLED(SYS_MALLOC_F) &&
78498675Sdes	    !IS_ENABLED(CONFIG_SPL_SYS_MALLOC_SIZE))
78598675Sdes		debug("SPL malloc() used 0x%lx bytes (%ld KB)\n",
78698675Sdes		      gd_malloc_ptr(), gd_malloc_ptr() / 1024);
78798675Sdes
78898675Sdes	bootstage_mark_name(get_bootstage_id(false), "end phase");
78998675Sdes	ret = bootstage_stash_default();
79098675Sdes	if (ret)
79198675Sdes		debug("Failed to stash bootstage: err=%d\n", ret);
79298675Sdes
79398675Sdes	if (IS_ENABLED(CONFIG_SPL_VIDEO_REMOVE)) {
79498675Sdes		struct udevice *dev;
79598675Sdes		int rc;
79698675Sdes
79798675Sdes		rc = uclass_find_device(UCLASS_VIDEO, 0, &dev);
79898675Sdes		if (!rc && dev) {
79998675Sdes			rc = device_remove(dev, DM_REMOVE_NORMAL);
80098675Sdes			if (rc)
80198675Sdes				printf("Cannot remove video device '%s' (err=%d)\n",
80298675Sdes				       dev->name, rc);
80398675Sdes		}
80498675Sdes	}
80598675Sdes	if (CONFIG_IS_ENABLED(HANDOFF)) {
80698675Sdes		ret = write_spl_handoff();
80798675Sdes		if (ret)
80898675Sdes			printf(SPL_TPL_PROMPT
80998675Sdes			       "SPL hand-off write failed (err=%d)\n", ret);
81098675Sdes	}
81198675Sdes	if (CONFIG_IS_ENABLED(BLOBLIST)) {
81298675Sdes		ret = bloblist_finish();
81398675Sdes		if (ret)
81498675Sdes			printf("Warning: Failed to finish bloblist (ret=%d)\n",
81598675Sdes			       ret);
81698675Sdes	}
81798675Sdes
81898675Sdes	spl_board_prepare_for_boot();
81998675Sdes	jump_to_image(&spl_image);
82098675Sdes}
82198675Sdes
82298675Sdes/*
82398675Sdes * This requires UART clocks to be enabled.  In order for this to work the
82498675Sdes * caller must ensure that the gd pointer is valid.
82598675Sdes */
82698675Sdesvoid preloader_console_init(void)
82798675Sdes{
82898675Sdes#ifdef CONFIG_SPL_SERIAL
82998675Sdes	gd->baudrate = CONFIG_BAUDRATE;
83098675Sdes
83198675Sdes	serial_init();		/* serial communications setup */
83298675Sdes
83399046Sdes	gd->have_console = 1;
83498675Sdes
83598675Sdes#if CONFIG_IS_ENABLED(BANNER_PRINT)
83698675Sdes	puts("\nU-Boot " SPL_TPL_NAME " " PLAIN_VERSION " (" U_BOOT_DATE " - "
83798675Sdes	     U_BOOT_TIME " " U_BOOT_TZ ")\n");
83898675Sdes#endif
83998675Sdes#ifdef CONFIG_SPL_DISPLAY_PRINT
84098675Sdes	spl_display_print();
84198675Sdes#endif
84298675Sdes#endif
84398675Sdes}
84498675Sdes
84598675Sdes/**
84698675Sdes * This function is called before the stack is changed from initial stack to
84798675Sdes * relocated stack. It tries to dump the stack size used
84898675Sdes */
84998675Sdes__weak void spl_relocate_stack_check(void)
85098675Sdes{
85198675Sdes#if CONFIG_IS_ENABLED(SYS_REPORT_STACK_F_USAGE)
85298675Sdes	ulong init_sp = gd->start_addr_sp;
85398675Sdes	ulong stack_bottom = init_sp - CONFIG_VAL(SIZE_LIMIT_PROVIDE_STACK);
85498675Sdes	u8 *ptr = (u8 *)stack_bottom;
85598675Sdes	ulong i;
85698675Sdes
85798675Sdes	for (i = 0; i < CONFIG_VAL(SIZE_LIMIT_PROVIDE_STACK); i++) {
85898675Sdes		if (*ptr != CONFIG_VAL(SYS_STACK_F_CHECK_BYTE))
85998675Sdes			break;
86098675Sdes		ptr++;
86198675Sdes	}
86298675Sdes	printf("SPL initial stack usage: %lu bytes\n",
86398675Sdes	       CONFIG_VAL(SIZE_LIMIT_PROVIDE_STACK) - i);
86498675Sdes#endif
86598675Sdes}
86698675Sdes
86798675Sdes/**
86898675Sdes * spl_relocate_stack_gd() - Relocate stack ready for board_init_r() execution
86998675Sdes *
87098675Sdes * Sometimes board_init_f() runs with a stack in SRAM but we want to use SDRAM
87198675Sdes * for the main board_init_r() execution. This is typically because we need
87298675Sdes * more stack space for things like the MMC sub-system.
87398675Sdes *
87498675Sdes * This function calculates the stack position, copies the global_data into
87598675Sdes * place, sets the new gd (except for ARM, for which setting GD within a C
87698675Sdes * function may not always work) and returns the new stack position. The
87798675Sdes * caller is responsible for setting up the sp register and, in the case
87898675Sdes * of ARM, setting up gd.
87998675Sdes *
88098675Sdes * All of this is done using the same layout and alignments as done in
88198675Sdes * board_init_f_init_reserve() / board_init_f_alloc_reserve().
88298675Sdes *
88398675Sdes * Return: new stack location, or 0 to use the same stack
88498675Sdes */
88598675Sdesulong spl_relocate_stack_gd(void)
88698675Sdes{
88798675Sdes#ifdef CONFIG_SPL_STACK_R
88898675Sdes	gd_t *new_gd;
88998675Sdes	ulong ptr = CONFIG_SPL_STACK_R_ADDR;
89098675Sdes
89198675Sdes	if (CONFIG_IS_ENABLED(SYS_REPORT_STACK_F_USAGE))
89298675Sdes		spl_relocate_stack_check();
89398675Sdes
89498675Sdes#if defined(CONFIG_SPL_SYS_MALLOC_SIMPLE) && CONFIG_IS_ENABLED(SYS_MALLOC_F)
89598675Sdes	if (CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN) {
89698675Sdes		debug("SPL malloc() before relocation used 0x%lx bytes (%ld KB)\n",
89798675Sdes		      gd->malloc_ptr, gd->malloc_ptr / 1024);
89898675Sdes		ptr -= CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN;
89998675Sdes		gd->malloc_base = ptr;
90098675Sdes		gd->malloc_limit = CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN;
90198675Sdes		gd->malloc_ptr = 0;
90298675Sdes	}
90398675Sdes#endif
90498675Sdes	/* Get stack position: use 8-byte alignment for ABI compliance */
90598675Sdes	ptr = CONFIG_SPL_STACK_R_ADDR - roundup(sizeof(gd_t),16);
90698675Sdes	gd->start_addr_sp = ptr;
90798675Sdes	new_gd = (gd_t *)ptr;
90898675Sdes	memcpy(new_gd, (void *)gd, sizeof(gd_t));
90998675Sdes#if CONFIG_IS_ENABLED(DM)
91098675Sdes	dm_fixup_for_gd_move(new_gd);
91198675Sdes#endif
91298675Sdes#if CONFIG_IS_ENABLED(LOG)
91398675Sdes	log_fixup_for_gd_move(new_gd);
91498675Sdes#endif
91598675Sdes#if !defined(CONFIG_ARM) && !defined(CONFIG_RISCV)
91698675Sdes	gd = new_gd;
91798675Sdes#endif
91898675Sdes	return ptr;
91998675Sdes#else
92098675Sdes	return 0;
92198675Sdes#endif
92298675Sdes}
92398675Sdes
92498675Sdes#if defined(CONFIG_BOOTCOUNT_LIMIT) && \
92598675Sdes	((!defined(CONFIG_TPL_BUILD) && !defined(CONFIG_SPL_BOOTCOUNT_LIMIT)) || \
92698675Sdes	 (defined(CONFIG_TPL_BUILD) && !defined(CONFIG_TPL_BOOTCOUNT_LIMIT)))
92798675Sdesvoid bootcount_store(ulong a)
92898675Sdes{
92998675Sdes}
93098675Sdes
93198675Sdesulong bootcount_load(void)
93298675Sdes{
93398675Sdes	return 0;
93498675Sdes}
93598675Sdes#endif
93698675Sdes