uboot/common/spl/spl.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * (C) Copyright 2010
   4 * Texas Instruments, <www.ti.com>
   5 *
   6 * Aneesh V <aneesh@ti.com>
   7 */
   8
   9#include <common.h>
  10#include <bloblist.h>
  11#include <binman_sym.h>
  12#include <bootstage.h>
  13#include <dm.h>
  14#include <handoff.h>
  15#include <hang.h>
  16#include <init.h>
  17#include <irq_func.h>
  18#include <log.h>
  19#include <mapmem.h>
  20#include <serial.h>
  21#include <spl.h>
  22#include <asm/global_data.h>
  23#include <asm/u-boot.h>
  24#include <nand.h>
  25#include <fat.h>
  26#include <u-boot/crc.h>
  27#if CONFIG_IS_ENABLED(BANNER_PRINT)
  28#include <timestamp.h>
  29#endif
  30#include <version.h>
  31#include <image.h>
  32#include <malloc.h>
  33#include <mapmem.h>
  34#include <dm/root.h>
  35#include <linux/compiler.h>
  36#include <fdt_support.h>
  37#include <bootcount.h>
  38#include <wdt.h>
  39
  40DECLARE_GLOBAL_DATA_PTR;
  41
  42#ifndef CONFIG_SYS_UBOOT_START
  43#define CONFIG_SYS_UBOOT_START  CONFIG_SYS_TEXT_BASE
  44#endif
  45#ifndef CONFIG_SYS_MONITOR_LEN
  46/* Unknown U-Boot size, let's assume it will not be more than 200 KB */
  47#define CONFIG_SYS_MONITOR_LEN  (200 * 1024)
  48#endif
  49
  50u32 *boot_params_ptr = NULL;
  51
  52/* See spl.h for information about this */
  53binman_sym_declare(ulong, u_boot_any, image_pos);
  54binman_sym_declare(ulong, u_boot_any, size);
  55
  56#ifdef CONFIG_TPL
  57binman_sym_declare(ulong, spl, image_pos);
  58binman_sym_declare(ulong, spl, size);
  59#endif
  60
  61/* Define board data structure */
  62static struct bd_info bdata __attribute__ ((section(".data")));
  63
  64#if CONFIG_IS_ENABLED(SHOW_BOOT_PROGRESS)
  65/*
  66 * Board-specific Platform code can reimplement show_boot_progress () if needed
  67 */
  68__weak void show_boot_progress(int val) {}
  69#endif
  70
  71#if defined(CONFIG_SPL_OS_BOOT) || CONFIG_IS_ENABLED(HANDOFF) || \
  72        defined(CONFIG_SPL_ATF)
  73/* weak, default platform-specific function to initialize dram banks */
  74__weak int dram_init_banksize(void)
  75{
  76        return 0;
  77}
  78#endif
  79
  80/*
  81 * Default function to determine if u-boot or the OS should
  82 * be started. This implementation always returns 1.
  83 *
  84 * Please implement your own board specific funcion to do this.
  85 *
  86 * RETURN
  87 * 0 to not start u-boot
  88 * positive if u-boot should start
  89 */
  90#if CONFIG_IS_ENABLED(OS_BOOT)
  91__weak int spl_start_uboot(void)
  92{
  93        puts(SPL_TPL_PROMPT
  94             "Please implement spl_start_uboot() for your board\n");
  95        puts(SPL_TPL_PROMPT "Direct Linux boot not active!\n");
  96        return 1;
  97}
  98
  99/*
 100 * Weak default function for arch specific zImage check. Return zero
 101 * and fill start and end address if image is recognized.
 102 */
 103int __weak bootz_setup(ulong image, ulong *start, ulong *end)
 104{
 105         return 1;
 106}
 107#endif
 108
 109/* Weak default function for arch/board-specific fixups to the spl_image_info */
 110void __weak spl_perform_fixups(struct spl_image_info *spl_image)
 111{
 112}
 113
 114void spl_fixup_fdt(void *fdt_blob)
 115{
 116#if defined(CONFIG_SPL_OF_LIBFDT)
 117        int err;
 118
 119        if (!fdt_blob)
 120                return;
 121
 122        err = fdt_check_header(fdt_blob);
 123        if (err < 0) {
 124                printf("fdt_root: %s\n", fdt_strerror(err));
 125                return;
 126        }
 127
 128        /* fixup the memory dt node */
 129        err = fdt_shrink_to_minimum(fdt_blob, 0);
 130        if (err == 0) {
 131                printf(SPL_TPL_PROMPT "fdt_shrink_to_minimum err - %d\n", err);
 132                return;
 133        }
 134
 135        err = arch_fixup_fdt(fdt_blob);
 136        if (err) {
 137                printf(SPL_TPL_PROMPT "arch_fixup_fdt err - %d\n", err);
 138                return;
 139        }
 140#endif
 141}
 142
 143ulong spl_get_image_pos(void)
 144{
 145        return spl_phase() == PHASE_TPL ?
 146                binman_sym(ulong, spl, image_pos) :
 147                binman_sym(ulong, u_boot_any, image_pos);
 148}
 149
 150ulong spl_get_image_size(void)
 151{
 152        return spl_phase() == PHASE_TPL ?
 153                binman_sym(ulong, spl, size) :
 154                binman_sym(ulong, u_boot_any, size);
 155}
 156
 157ulong spl_get_image_text_base(void)
 158{
 159        return spl_phase() == PHASE_TPL ? CONFIG_SPL_TEXT_BASE :
 160                CONFIG_SYS_TEXT_BASE;
 161}
 162
 163/*
 164 * Weak default function for board specific cleanup/preparation before
 165 * Linux boot. Some boards/platforms might not need it, so just provide
 166 * an empty stub here.
 167 */
 168__weak void spl_board_prepare_for_linux(void)
 169{
 170        /* Nothing to do! */
 171}
 172
 173__weak void spl_board_prepare_for_optee(void *fdt)
 174{
 175}
 176
 177#if CONFIG_IS_ENABLED(OPTEE_IMAGE)
 178__weak void __noreturn jump_to_image_optee(struct spl_image_info *spl_image)
 179{
 180        spl_optee_entry(NULL, NULL, spl_image->fdt_addr,
 181                        (void *)spl_image->entry_point);
 182}
 183#endif
 184
 185__weak void spl_board_prepare_for_boot(void)
 186{
 187        /* Nothing to do! */
 188}
 189
 190__weak struct image_header *spl_get_load_buffer(ssize_t offset, size_t size)
 191{
 192        return map_sysmem(CONFIG_SYS_TEXT_BASE + offset, 0);
 193}
 194
 195void spl_set_header_raw_uboot(struct spl_image_info *spl_image)
 196{
 197        ulong u_boot_pos = binman_sym(ulong, u_boot_any, image_pos);
 198
 199        spl_image->size = CONFIG_SYS_MONITOR_LEN;
 200
 201        /*
 202         * Binman error cases: address of the end of the previous region or the
 203         * start of the image's entry area (usually 0) if there is no previous
 204         * region.
 205         */
 206        if (u_boot_pos && u_boot_pos != BINMAN_SYM_MISSING) {
 207                /* Binman does not support separated entry addresses */
 208                spl_image->entry_point = u_boot_pos;
 209                spl_image->load_addr = u_boot_pos;
 210        } else {
 211                spl_image->entry_point = CONFIG_SYS_UBOOT_START;
 212                spl_image->load_addr = CONFIG_SYS_TEXT_BASE;
 213        }
 214        spl_image->os = IH_OS_U_BOOT;
 215        spl_image->name = "U-Boot";
 216}
 217
 218#if CONFIG_IS_ENABLED(LOAD_FIT_FULL)
 219/* Parse and load full fitImage in SPL */
 220static int spl_load_fit_image(struct spl_image_info *spl_image,
 221                              const struct image_header *header)
 222{
 223        bootm_headers_t images;
 224        const char *fit_uname_config = NULL;
 225        uintptr_t fdt_hack;
 226        const char *uname;
 227        ulong fw_data = 0, dt_data = 0, img_data = 0;
 228        ulong fw_len = 0, dt_len = 0, img_len = 0;
 229        int idx, conf_noffset;
 230        int ret;
 231
 232#ifdef CONFIG_SPL_FIT_SIGNATURE
 233        images.verify = 1;
 234#endif
 235        ret = fit_image_load(&images, (ulong)header,
 236                             NULL, &fit_uname_config,
 237                             IH_ARCH_DEFAULT, IH_TYPE_STANDALONE, -1,
 238                             FIT_LOAD_OPTIONAL, &fw_data, &fw_len);
 239        if (ret >= 0) {
 240                printf("DEPRECATED: 'standalone = ' property.");
 241                printf("Please use either 'firmware =' or 'kernel ='\n");
 242        } else {
 243                ret = fit_image_load(&images, (ulong)header, NULL,
 244                                     &fit_uname_config, IH_ARCH_DEFAULT,
 245                                     IH_TYPE_FIRMWARE, -1, FIT_LOAD_OPTIONAL,
 246                                     &fw_data, &fw_len);
 247        }
 248
 249        if (ret < 0) {
 250                ret = fit_image_load(&images, (ulong)header, NULL,
 251                                     &fit_uname_config, IH_ARCH_DEFAULT,
 252                                     IH_TYPE_KERNEL, -1, FIT_LOAD_OPTIONAL,
 253                                     &fw_data, &fw_len);
 254        }
 255
 256        if (ret < 0)
 257                return ret;
 258
 259        spl_image->size = fw_len;
 260        spl_image->entry_point = fw_data;
 261        spl_image->load_addr = fw_data;
 262        if (fit_image_get_os(header, ret, &spl_image->os))
 263                spl_image->os = IH_OS_INVALID;
 264        spl_image->name = genimg_get_os_name(spl_image->os);
 265
 266        debug(SPL_TPL_PROMPT "payload image: %32s load addr: 0x%lx size: %d\n",
 267              spl_image->name, spl_image->load_addr, spl_image->size);
 268
 269#ifdef CONFIG_SPL_FIT_SIGNATURE
 270        images.verify = 1;
 271#endif
 272        ret = fit_image_load(&images, (ulong)header, NULL, &fit_uname_config,
 273                       IH_ARCH_DEFAULT, IH_TYPE_FLATDT, -1,
 274                       FIT_LOAD_OPTIONAL, &dt_data, &dt_len);
 275        if (ret >= 0) {
 276                spl_image->fdt_addr = (void *)dt_data;
 277
 278                if (spl_image->os == IH_OS_U_BOOT) {
 279                        /* HACK: U-boot expects FDT at a specific address */
 280                        fdt_hack = spl_image->load_addr + spl_image->size;
 281                        fdt_hack = (fdt_hack + 3) & ~3;
 282                        debug("Relocating FDT to %p\n", spl_image->fdt_addr);
 283                        memcpy((void *)fdt_hack, spl_image->fdt_addr, dt_len);
 284                }
 285        }
 286
 287        conf_noffset = fit_conf_get_node((const void *)header,
 288                                         fit_uname_config);
 289        if (conf_noffset <= 0)
 290                return 0;
 291
 292        for (idx = 0;
 293             uname = fdt_stringlist_get((const void *)header, conf_noffset,
 294                                        FIT_LOADABLE_PROP, idx,
 295                                NULL), uname;
 296             idx++)
 297        {
 298#ifdef CONFIG_SPL_FIT_SIGNATURE
 299                images.verify = 1;
 300#endif
 301                ret = fit_image_load(&images, (ulong)header,
 302                                     &uname, &fit_uname_config,
 303                                     IH_ARCH_DEFAULT, IH_TYPE_LOADABLE, -1,
 304                                     FIT_LOAD_OPTIONAL_NON_ZERO,
 305                                     &img_data, &img_len);
 306                if (ret < 0)
 307                        return ret;
 308        }
 309
 310        return 0;
 311}
 312#endif
 313
 314__weak int spl_parse_board_header(struct spl_image_info *spl_image,
 315                                  const void *image_header, size_t size)
 316{
 317        return -EINVAL;
 318}
 319
 320__weak int spl_parse_legacy_header(struct spl_image_info *spl_image,
 321                                   const struct image_header *header)
 322{
 323        /* LEGACY image not supported */
 324        debug("Legacy boot image support not enabled, proceeding to other boot methods\n");
 325        return -EINVAL;
 326}
 327
 328int spl_parse_image_header(struct spl_image_info *spl_image,
 329                           const struct image_header *header)
 330{
 331#if CONFIG_IS_ENABLED(LOAD_FIT_FULL)
 332        int ret = spl_load_fit_image(spl_image, header);
 333
 334        if (!ret)
 335                return ret;
 336#endif
 337        if (image_get_magic(header) == IH_MAGIC) {
 338                int ret;
 339
 340                ret = spl_parse_legacy_header(spl_image, header);
 341                if (ret)
 342                        return ret;
 343        } else {
 344#ifdef CONFIG_SPL_PANIC_ON_RAW_IMAGE
 345                /*
 346                 * CONFIG_SPL_PANIC_ON_RAW_IMAGE is defined when the
 347                 * code which loads images in SPL cannot guarantee that
 348                 * absolutely all read errors will be reported.
 349                 * An example is the LPC32XX MLC NAND driver, which
 350                 * will consider that a completely unreadable NAND block
 351                 * is bad, and thus should be skipped silently.
 352                 */
 353                panic("** no mkimage signature but raw image not supported");
 354#endif
 355
 356#if CONFIG_IS_ENABLED(OS_BOOT)
 357                ulong start, end;
 358
 359                if (!bootz_setup((ulong)header, &start, &end)) {
 360                        spl_image->name = "Linux";
 361                        spl_image->os = IH_OS_LINUX;
 362                        spl_image->load_addr = CONFIG_SYS_LOAD_ADDR;
 363                        spl_image->entry_point = CONFIG_SYS_LOAD_ADDR;
 364                        spl_image->size = end - start;
 365                        debug(SPL_TPL_PROMPT
 366                              "payload zImage, load addr: 0x%lx size: %d\n",
 367                              spl_image->load_addr, spl_image->size);
 368                        return 0;
 369                }
 370#endif
 371
 372                if (!spl_parse_board_header(spl_image, (const void *)header, sizeof(*header)))
 373                        return 0;
 374
 375#ifdef CONFIG_SPL_RAW_IMAGE_SUPPORT
 376                /* Signature not found - assume u-boot.bin */
 377                debug("mkimage signature not found - ih_magic = %x\n",
 378                        header->ih_magic);
 379                spl_set_header_raw_uboot(spl_image);
 380#else
 381                /* RAW image not supported, proceed to other boot methods. */
 382                debug("Raw boot image support not enabled, proceeding to other boot methods\n");
 383                return -EINVAL;
 384#endif
 385        }
 386
 387        return 0;
 388}
 389
 390__weak void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
 391{
 392        typedef void __noreturn (*image_entry_noargs_t)(void);
 393
 394        image_entry_noargs_t image_entry =
 395                (image_entry_noargs_t)spl_image->entry_point;
 396
 397        debug("image entry point: 0x%lx\n", spl_image->entry_point);
 398        image_entry();
 399}
 400
 401#if CONFIG_IS_ENABLED(HANDOFF)
 402/**
 403 * Set up the SPL hand-off information
 404 *
 405 * This is initially empty (zero) but can be written by
 406 */
 407static int setup_spl_handoff(void)
 408{
 409        struct spl_handoff *ho;
 410
 411        ho = bloblist_ensure(BLOBLISTT_SPL_HANDOFF, sizeof(struct spl_handoff));
 412        if (!ho)
 413                return -ENOENT;
 414
 415        return 0;
 416}
 417
 418__weak int handoff_arch_save(struct spl_handoff *ho)
 419{
 420        return 0;
 421}
 422
 423static int write_spl_handoff(void)
 424{
 425        struct spl_handoff *ho;
 426        int ret;
 427
 428        ho = bloblist_find(BLOBLISTT_SPL_HANDOFF, sizeof(struct spl_handoff));
 429        if (!ho)
 430                return -ENOENT;
 431        handoff_save_dram(ho);
 432        ret = handoff_arch_save(ho);
 433        if (ret)
 434                return ret;
 435        debug(SPL_TPL_PROMPT "Wrote SPL handoff\n");
 436
 437        return 0;
 438}
 439#else
 440static inline int setup_spl_handoff(void) { return 0; }
 441static inline int write_spl_handoff(void) { return 0; }
 442
 443#endif /* HANDOFF */
 444
 445/**
 446 * get_bootstage_id() - Get the bootstage ID to emit
 447 *
 448 * @start: true if this is for starting SPL, false for ending it
 449 * @return bootstage ID to use
 450 */
 451static enum bootstage_id get_bootstage_id(bool start)
 452{
 453        enum u_boot_phase phase = spl_phase();
 454
 455        if (IS_ENABLED(CONFIG_TPL_BUILD) && phase == PHASE_TPL)
 456                return start ? BOOTSTAGE_ID_START_TPL : BOOTSTAGE_ID_END_TPL;
 457        else
 458                return start ? BOOTSTAGE_ID_START_SPL : BOOTSTAGE_ID_END_SPL;
 459}
 460
 461static int spl_common_init(bool setup_malloc)
 462{
 463        int ret;
 464
 465#if CONFIG_VAL(SYS_MALLOC_F_LEN)
 466        if (setup_malloc) {
 467#ifdef CONFIG_MALLOC_F_ADDR
 468                gd->malloc_base = CONFIG_MALLOC_F_ADDR;
 469#endif
 470                gd->malloc_limit = CONFIG_VAL(SYS_MALLOC_F_LEN);
 471                gd->malloc_ptr = 0;
 472        }
 473#endif
 474        ret = bootstage_init(u_boot_first_phase());
 475        if (ret) {
 476                debug("%s: Failed to set up bootstage: ret=%d\n", __func__,
 477                      ret);
 478                return ret;
 479        }
 480#ifdef CONFIG_BOOTSTAGE_STASH
 481        if (!u_boot_first_phase()) {
 482                const void *stash = map_sysmem(CONFIG_BOOTSTAGE_STASH_ADDR,
 483                                               CONFIG_BOOTSTAGE_STASH_SIZE);
 484
 485                ret = bootstage_unstash(stash, CONFIG_BOOTSTAGE_STASH_SIZE);
 486                if (ret)
 487                        debug("%s: Failed to unstash bootstage: ret=%d\n",
 488                              __func__, ret);
 489        }
 490#endif /* CONFIG_BOOTSTAGE_STASH */
 491        bootstage_mark_name(get_bootstage_id(true),
 492                            spl_phase_name(spl_phase()));
 493#if CONFIG_IS_ENABLED(LOG)
 494        ret = log_init();
 495        if (ret) {
 496                debug("%s: Failed to set up logging\n", __func__);
 497                return ret;
 498        }
 499#endif
 500        if (CONFIG_IS_ENABLED(OF_REAL)) {
 501                ret = fdtdec_setup();
 502                if (ret) {
 503                        debug("fdtdec_setup() returned error %d\n", ret);
 504                        return ret;
 505                }
 506        }
 507        if (CONFIG_IS_ENABLED(DM)) {
 508                bootstage_start(BOOTSTAGE_ID_ACCUM_DM_SPL,
 509                                spl_phase() == PHASE_TPL ? "dm tpl" : "dm_spl");
 510                /* With CONFIG_SPL_OF_PLATDATA, bring in all devices */
 511                ret = dm_init_and_scan(!CONFIG_IS_ENABLED(OF_PLATDATA));
 512                bootstage_accum(BOOTSTAGE_ID_ACCUM_DM_SPL);
 513                if (ret) {
 514                        debug("dm_init_and_scan() returned error %d\n", ret);
 515                        return ret;
 516                }
 517        }
 518
 519        return 0;
 520}
 521
 522void spl_set_bd(void)
 523{
 524        /*
 525         * NOTE: On some platforms (e.g. x86) bdata may be in flash and not
 526         * writeable.
 527         */
 528        if (!gd->bd)
 529                gd->bd = &bdata;
 530}
 531
 532int spl_early_init(void)
 533{
 534        int ret;
 535
 536        debug("%s\n", __func__);
 537
 538        ret = spl_common_init(true);
 539        if (ret)
 540                return ret;
 541        gd->flags |= GD_FLG_SPL_EARLY_INIT;
 542
 543        return 0;
 544}
 545
 546int spl_init(void)
 547{
 548        int ret;
 549        bool setup_malloc = !(IS_ENABLED(CONFIG_SPL_STACK_R) &&
 550                        IS_ENABLED(CONFIG_SPL_SYS_MALLOC_SIMPLE));
 551
 552        debug("%s\n", __func__);
 553
 554        if (!(gd->flags & GD_FLG_SPL_EARLY_INIT)) {
 555                ret = spl_common_init(setup_malloc);
 556                if (ret)
 557                        return ret;
 558        }
 559        gd->flags |= GD_FLG_SPL_INIT;
 560
 561        return 0;
 562}
 563
 564#ifndef BOOT_DEVICE_NONE
 565#define BOOT_DEVICE_NONE 0xdeadbeef
 566#endif
 567
 568__weak void board_boot_order(u32 *spl_boot_list)
 569{
 570        spl_boot_list[0] = spl_boot_device();
 571}
 572
 573static struct spl_image_loader *spl_ll_find_loader(uint boot_device)
 574{
 575        struct spl_image_loader *drv =
 576                ll_entry_start(struct spl_image_loader, spl_image_loader);
 577        const int n_ents =
 578                ll_entry_count(struct spl_image_loader, spl_image_loader);
 579        struct spl_image_loader *entry;
 580
 581        for (entry = drv; entry != drv + n_ents; entry++) {
 582                if (boot_device == entry->boot_device)
 583                        return entry;
 584        }
 585
 586        /* Not found */
 587        return NULL;
 588}
 589
 590static int spl_load_image(struct spl_image_info *spl_image,
 591                          struct spl_image_loader *loader)
 592{
 593        int ret;
 594        struct spl_boot_device bootdev;
 595
 596        bootdev.boot_device = loader->boot_device;
 597        bootdev.boot_device_name = NULL;
 598
 599        ret = loader->load_image(spl_image, &bootdev);
 600#ifdef CONFIG_SPL_LEGACY_IMAGE_CRC_CHECK
 601        if (!ret && spl_image->dcrc_length) {
 602                /* check data crc */
 603                ulong dcrc = crc32_wd(0, (unsigned char *)spl_image->dcrc_data,
 604                                      spl_image->dcrc_length, CHUNKSZ_CRC32);
 605                if (dcrc != spl_image->dcrc) {
 606                        puts("SPL: Image data CRC check failed!\n");
 607                        ret = -EINVAL;
 608                }
 609        }
 610#endif
 611        return ret;
 612}
 613
 614/**
 615 * boot_from_devices() - Try loading a booting U-Boot from a list of devices
 616 *
 617 * @spl_image: Place to put the image details if successful
 618 * @spl_boot_list: List of boot devices to try
 619 * @count: Number of elements in spl_boot_list
 620 * @return 0 if OK, -ENODEV if there were no boot devices
 621 *      if CONFIG_SHOW_ERRORS is enabled, returns -ENXIO if there were
 622 *      devices but none worked
 623 */
 624static int boot_from_devices(struct spl_image_info *spl_image,
 625                             u32 spl_boot_list[], int count)
 626{
 627        int ret = -ENODEV;
 628        int i;
 629
 630        for (i = 0; i < count && spl_boot_list[i] != BOOT_DEVICE_NONE; i++) {
 631                struct spl_image_loader *loader;
 632                int bootdev = spl_boot_list[i];
 633
 634                if (CONFIG_IS_ENABLED(SHOW_ERRORS))
 635                        ret = -ENXIO;
 636                loader = spl_ll_find_loader(bootdev);
 637                if (CONFIG_IS_ENABLED(SERIAL) &&
 638                    CONFIG_IS_ENABLED(LIBCOMMON_SUPPORT) &&
 639                    !IS_ENABLED(CONFIG_SILENT_CONSOLE)) {
 640                        if (loader)
 641                                printf("Trying to boot from %s\n",
 642                                       spl_loader_name(loader));
 643                        else if (CONFIG_IS_ENABLED(SHOW_ERRORS))
 644                                printf(SPL_TPL_PROMPT
 645                                       "Unsupported Boot Device %d\n", bootdev);
 646                        else
 647                                puts(SPL_TPL_PROMPT "Unsupported Boot Device!\n");
 648                }
 649                if (loader && !spl_load_image(spl_image, loader)) {
 650                        spl_image->boot_device = bootdev;
 651                        return 0;
 652                }
 653        }
 654
 655        return ret;
 656}
 657
 658#if defined(CONFIG_SPL_FRAMEWORK_BOARD_INIT_F)
 659void board_init_f(ulong dummy)
 660{
 661        if (CONFIG_IS_ENABLED(OF_CONTROL)) {
 662                int ret;
 663
 664                ret = spl_early_init();
 665                if (ret) {
 666                        debug("spl_early_init() failed: %d\n", ret);
 667                        hang();
 668                }
 669        }
 670
 671        preloader_console_init();
 672}
 673#endif
 674
 675void board_init_r(gd_t *dummy1, ulong dummy2)
 676{
 677        u32 spl_boot_list[] = {
 678                BOOT_DEVICE_NONE,
 679                BOOT_DEVICE_NONE,
 680                BOOT_DEVICE_NONE,
 681                BOOT_DEVICE_NONE,
 682                BOOT_DEVICE_NONE,
 683        };
 684        struct spl_image_info spl_image;
 685        int ret;
 686
 687        debug(">>" SPL_TPL_PROMPT "board_init_r()\n");
 688
 689        spl_set_bd();
 690
 691#if defined(CONFIG_SYS_SPL_MALLOC_START)
 692        mem_malloc_init(CONFIG_SYS_SPL_MALLOC_START,
 693                        CONFIG_SYS_SPL_MALLOC_SIZE);
 694        gd->flags |= GD_FLG_FULL_MALLOC_INIT;
 695#endif
 696        if (!(gd->flags & GD_FLG_SPL_INIT)) {
 697                if (spl_init())
 698                        hang();
 699        }
 700#if !defined(CONFIG_PPC) && !defined(CONFIG_ARCH_MX6)
 701        /*
 702         * timer_init() does not exist on PPC systems. The timer is initialized
 703         * and enabled (decrementer) in interrupt_init() here.
 704         */
 705        timer_init();
 706#endif
 707        if (CONFIG_IS_ENABLED(BLOBLIST)) {
 708                ret = bloblist_init();
 709                if (ret) {
 710                        debug("%s: Failed to set up bloblist: ret=%d\n",
 711                              __func__, ret);
 712                        puts(SPL_TPL_PROMPT "Cannot set up bloblist\n");
 713                        hang();
 714                }
 715        }
 716        if (CONFIG_IS_ENABLED(HANDOFF)) {
 717                int ret;
 718
 719                ret = setup_spl_handoff();
 720                if (ret) {
 721                        puts(SPL_TPL_PROMPT "Cannot set up SPL handoff\n");
 722                        hang();
 723                }
 724        }
 725
 726#if CONFIG_IS_ENABLED(BOARD_INIT)
 727        spl_board_init();
 728#endif
 729
 730#if defined(CONFIG_SPL_WATCHDOG) && CONFIG_IS_ENABLED(WDT)
 731        initr_watchdog();
 732#endif
 733
 734        if (IS_ENABLED(CONFIG_SPL_OS_BOOT) || CONFIG_IS_ENABLED(HANDOFF) ||
 735            IS_ENABLED(CONFIG_SPL_ATF))
 736                dram_init_banksize();
 737
 738        bootcount_inc();
 739
 740        memset(&spl_image, '\0', sizeof(spl_image));
 741#ifdef CONFIG_SYS_SPL_ARGS_ADDR
 742        spl_image.arg = (void *)CONFIG_SYS_SPL_ARGS_ADDR;
 743#endif
 744        spl_image.boot_device = BOOT_DEVICE_NONE;
 745        board_boot_order(spl_boot_list);
 746
 747        ret = boot_from_devices(&spl_image, spl_boot_list,
 748                                ARRAY_SIZE(spl_boot_list));
 749        if (ret) {
 750                if (CONFIG_IS_ENABLED(SHOW_ERRORS) &&
 751                    CONFIG_IS_ENABLED(LIBCOMMON_SUPPORT))
 752                        printf(SPL_TPL_PROMPT "failed to boot from all boot devices (err=%d)\n",
 753                               ret);
 754                else
 755                        puts(SPL_TPL_PROMPT "failed to boot from all boot devices\n");
 756                hang();
 757        }
 758
 759        spl_perform_fixups(&spl_image);
 760        if (CONFIG_IS_ENABLED(HANDOFF)) {
 761                ret = write_spl_handoff();
 762                if (ret)
 763                        printf(SPL_TPL_PROMPT
 764                               "SPL hand-off write failed (err=%d)\n", ret);
 765        }
 766        if (CONFIG_IS_ENABLED(BLOBLIST)) {
 767                ret = bloblist_finish();
 768                if (ret)
 769                        printf("Warning: Failed to finish bloblist (ret=%d)\n",
 770                               ret);
 771        }
 772
 773#ifdef CONFIG_CPU_V7M
 774        spl_image.entry_point |= 0x1;
 775#endif
 776        switch (spl_image.os) {
 777        case IH_OS_U_BOOT:
 778                debug("Jumping to %s...\n", spl_phase_name(spl_next_phase()));
 779                break;
 780#if CONFIG_IS_ENABLED(ATF)
 781        case IH_OS_ARM_TRUSTED_FIRMWARE:
 782                debug("Jumping to U-Boot via ARM Trusted Firmware\n");
 783                spl_fixup_fdt(spl_image.fdt_addr);
 784                spl_invoke_atf(&spl_image);
 785                break;
 786#endif
 787#if CONFIG_IS_ENABLED(OPTEE_IMAGE)
 788        case IH_OS_TEE:
 789                debug("Jumping to U-Boot via OP-TEE\n");
 790                spl_board_prepare_for_optee(spl_image.fdt_addr);
 791                jump_to_image_optee(&spl_image);
 792                break;
 793#endif
 794#if CONFIG_IS_ENABLED(OPENSBI)
 795        case IH_OS_OPENSBI:
 796                debug("Jumping to U-Boot via RISC-V OpenSBI\n");
 797                spl_invoke_opensbi(&spl_image);
 798                break;
 799#endif
 800#if CONFIG_IS_ENABLED(OS_BOOT)
 801        case IH_OS_LINUX:
 802                debug("Jumping to Linux\n");
 803#if defined(CONFIG_SYS_SPL_ARGS_ADDR)
 804                spl_fixup_fdt((void *)CONFIG_SYS_SPL_ARGS_ADDR);
 805#endif
 806                spl_board_prepare_for_linux();
 807                jump_to_image_linux(&spl_image);
 808#endif
 809        default:
 810                debug("Unsupported OS image.. Jumping nevertheless..\n");
 811        }
 812#if CONFIG_VAL(SYS_MALLOC_F_LEN) && !defined(CONFIG_SYS_SPL_MALLOC_SIZE)
 813        debug("SPL malloc() used 0x%lx bytes (%ld KB)\n", gd->malloc_ptr,
 814              gd->malloc_ptr / 1024);
 815#endif
 816        bootstage_mark_name(get_bootstage_id(false), "end phase");
 817#ifdef CONFIG_BOOTSTAGE_STASH
 818        ret = bootstage_stash((void *)CONFIG_BOOTSTAGE_STASH_ADDR,
 819                              CONFIG_BOOTSTAGE_STASH_SIZE);
 820        if (ret)
 821                debug("Failed to stash bootstage: err=%d\n", ret);
 822#endif
 823
 824        spl_board_prepare_for_boot();
 825        jump_to_image_no_args(&spl_image);
 826}
 827
 828/*
 829 * This requires UART clocks to be enabled.  In order for this to work the
 830 * caller must ensure that the gd pointer is valid.
 831 */
 832void preloader_console_init(void)
 833{
 834#ifdef CONFIG_SPL_SERIAL
 835        gd->baudrate = CONFIG_BAUDRATE;
 836
 837        serial_init();          /* serial communications setup */
 838
 839        gd->have_console = 1;
 840
 841#if CONFIG_IS_ENABLED(BANNER_PRINT)
 842        puts("\nU-Boot " SPL_TPL_NAME " " PLAIN_VERSION " (" U_BOOT_DATE " - "
 843             U_BOOT_TIME " " U_BOOT_TZ ")\n");
 844#endif
 845#ifdef CONFIG_SPL_DISPLAY_PRINT
 846        spl_display_print();
 847#endif
 848#endif
 849}
 850
 851/**
 852 * This function is called before the stack is changed from initial stack to
 853 * relocated stack. It tries to dump the stack size used
 854 */
 855__weak void spl_relocate_stack_check(void)
 856{
 857#if CONFIG_IS_ENABLED(SYS_REPORT_STACK_F_USAGE)
 858        ulong init_sp = gd->start_addr_sp;
 859        ulong stack_bottom = init_sp - CONFIG_VAL(SIZE_LIMIT_PROVIDE_STACK);
 860        u8 *ptr = (u8 *)stack_bottom;
 861        ulong i;
 862
 863        for (i = 0; i < CONFIG_VAL(SIZE_LIMIT_PROVIDE_STACK); i++) {
 864                if (*ptr != CONFIG_VAL(SYS_STACK_F_CHECK_BYTE))
 865                        break;
 866                ptr++;
 867        }
 868        printf("SPL initial stack usage: %lu bytes\n",
 869               CONFIG_VAL(SIZE_LIMIT_PROVIDE_STACK) - i);
 870#endif
 871}
 872
 873/**
 874 * spl_relocate_stack_gd() - Relocate stack ready for board_init_r() execution
 875 *
 876 * Sometimes board_init_f() runs with a stack in SRAM but we want to use SDRAM
 877 * for the main board_init_r() execution. This is typically because we need
 878 * more stack space for things like the MMC sub-system.
 879 *
 880 * This function calculates the stack position, copies the global_data into
 881 * place, sets the new gd (except for ARM, for which setting GD within a C
 882 * function may not always work) and returns the new stack position. The
 883 * caller is responsible for setting up the sp register and, in the case
 884 * of ARM, setting up gd.
 885 *
 886 * All of this is done using the same layout and alignments as done in
 887 * board_init_f_init_reserve() / board_init_f_alloc_reserve().
 888 *
 889 * @return new stack location, or 0 to use the same stack
 890 */
 891ulong spl_relocate_stack_gd(void)
 892{
 893#ifdef CONFIG_SPL_STACK_R
 894        gd_t *new_gd;
 895        ulong ptr = CONFIG_SPL_STACK_R_ADDR;
 896
 897        if (CONFIG_IS_ENABLED(SYS_REPORT_STACK_F_USAGE))
 898                spl_relocate_stack_check();
 899
 900#if defined(CONFIG_SPL_SYS_MALLOC_SIMPLE) && CONFIG_VAL(SYS_MALLOC_F_LEN)
 901        if (CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN) {
 902                debug("SPL malloc() before relocation used 0x%lx bytes (%ld KB)\n",
 903                      gd->malloc_ptr, gd->malloc_ptr / 1024);
 904                ptr -= CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN;
 905                gd->malloc_base = ptr;
 906                gd->malloc_limit = CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN;
 907                gd->malloc_ptr = 0;
 908        }
 909#endif
 910        /* Get stack position: use 8-byte alignment for ABI compliance */
 911        ptr = CONFIG_SPL_STACK_R_ADDR - roundup(sizeof(gd_t),16);
 912        new_gd = (gd_t *)ptr;
 913        memcpy(new_gd, (void *)gd, sizeof(gd_t));
 914#if CONFIG_IS_ENABLED(DM)
 915        dm_fixup_for_gd_move(new_gd);
 916#endif
 917#if !defined(CONFIG_ARM) && !defined(CONFIG_RISCV)
 918        gd = new_gd;
 919#endif
 920        return ptr;
 921#else
 922        return 0;
 923#endif
 924}
 925
 926#if defined(CONFIG_BOOTCOUNT_LIMIT) && \
 927        ((!defined(CONFIG_TPL_BUILD) && !defined(CONFIG_SPL_BOOTCOUNT_LIMIT)) || \
 928         (defined(CONFIG_TPL_BUILD) && !defined(CONFIG_TPL_BOOTCOUNT_LIMIT)))
 929void bootcount_store(ulong a)
 930{
 931}
 932
 933ulong bootcount_load(void)
 934{
 935        return 0;
 936}
 937#endif
 938