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