X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=common%2Fspl%2Fspl.c;h=1566acdbc30672eb4a8efe476d21bd6e0ae7ea85;hb=af2f44267fdc006e47166187632f63d396822bed;hp=d3a4ff62e58090630b199b02d13b4368ffff074d;hpb=22802f4e3a0a8ead928a0af06b7719b604a98afb;p=u-boot diff --git a/common/spl/spl.c b/common/spl/spl.c index d3a4ff62e5..1566acdbc3 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -6,7 +6,9 @@ * * SPDX-License-Identifier: GPL-2.0+ */ + #include +#include #include #include #include @@ -17,6 +19,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -30,6 +33,9 @@ DECLARE_GLOBAL_DATA_PTR; u32 *boot_params_ptr = NULL; +/* See spl.h for information about this */ +binman_sym_declare(ulong, u_boot_any, pos); + /* Define board data structure */ static bd_t bdata __attribute__ ((section(".data"))); @@ -56,6 +62,14 @@ __weak int spl_start_uboot(void) return 1; } +/* weak default platform specific function to initialize + * dram banks + */ +__weak int dram_init_banksize(void) +{ + return 0; +} + /* * Weak default function for arch specific zImage check. Return zero * and fill start and end address if image is recognized. @@ -66,6 +80,33 @@ int __weak bootz_setup(ulong image, ulong *start, ulong *end) } #endif +void spl_fixup_fdt(void) +{ +#if defined(CONFIG_SPL_OF_LIBFDT) && defined(CONFIG_SYS_SPL_ARGS_ADDR) + void *fdt_blob = (void *)CONFIG_SYS_SPL_ARGS_ADDR; + int err; + + err = fdt_check_header(fdt_blob); + if (err < 0) { + printf("fdt_root: %s\n", fdt_strerror(err)); + return; + } + + /* fixup the memory dt node */ + err = fdt_shrink_to_minimum(fdt_blob, 0); + if (err == 0) { + printf("spl: fdt_shrink_to_minimum err - %d\n", err); + return; + } + + err = arch_fixup_fdt(fdt_blob); + if (err) { + printf("spl: arch_fixup_fdt err - %d\n", err); + return; + } +#endif +} + /* * Weak default function for board specific cleanup/preparation before * Linux boot. Some boards/platforms might not need it, so just provide @@ -83,9 +124,17 @@ __weak void spl_board_prepare_for_boot(void) void spl_set_header_raw_uboot(struct spl_image_info *spl_image) { + ulong u_boot_pos = binman_sym(ulong, u_boot_any, pos); + spl_image->size = CONFIG_SYS_MONITOR_LEN; - spl_image->entry_point = CONFIG_SYS_UBOOT_START; - spl_image->load_addr = CONFIG_SYS_TEXT_BASE; + if (u_boot_pos != BINMAN_SYM_MISSING) { + /* biman does not support separate entry addresses at present */ + spl_image->entry_point = u_boot_pos; + spl_image->load_addr = u_boot_pos; + } else { + spl_image->entry_point = CONFIG_SYS_UBOOT_START; + spl_image->load_addr = CONFIG_SYS_TEXT_BASE; + } spl_image->os = IH_OS_U_BOOT; spl_image->name = "U-Boot"; } @@ -93,9 +142,10 @@ void spl_set_header_raw_uboot(struct spl_image_info *spl_image) int spl_parse_image_header(struct spl_image_info *spl_image, const struct image_header *header) { - u32 header_size = sizeof(struct image_header); - if (image_get_magic(header) == IH_MAGIC) { +#ifdef CONFIG_SPL_LEGACY_IMAGE_SUPPORT + u32 header_size = sizeof(struct image_header); + if (spl_image->flags & SPL_COPY_PAYLOAD_ONLY) { /* * On some system (e.g. powerpc), the load-address and @@ -116,8 +166,13 @@ int spl_parse_image_header(struct spl_image_info *spl_image, spl_image->os = image_get_os(header); spl_image->name = image_get_name(header); debug("spl: payload image: %.*s load addr: 0x%lx size: %d\n", - (int)sizeof(spl_image->name), spl_image->name, + IH_NMLEN, spl_image->name, spl_image->load_addr, spl_image->size); +#else + /* LEGACY image not supported */ + debug("Legacy boot image support not enabled, proceeding to other boot methods\n"); + return -EINVAL; +#endif } else { #ifdef CONFIG_SPL_PANIC_ON_RAW_IMAGE /* @@ -146,16 +201,18 @@ int spl_parse_image_header(struct spl_image_info *spl_image, } #endif -#ifdef CONFIG_SPL_ABORT_ON_RAW_IMAGE - /* Signature not found, proceed to other boot methods. */ - return -EINVAL; -#else +#ifdef CONFIG_SPL_RAW_IMAGE_SUPPORT /* Signature not found - assume u-boot.bin */ debug("mkimage signature not found - ih_magic = %x\n", header->ih_magic); spl_set_header_raw_uboot(spl_image); +#else + /* RAW image not supported, proceed to other boot methods. */ + debug("Raw boot image support not enabled, proceeding to other boot methods\n"); + return -EINVAL; #endif } + return 0; } @@ -170,18 +227,28 @@ __weak void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) image_entry(); } -int spl_init(void) +static int spl_common_init(bool setup_malloc) { int ret; - debug("spl_init()\n"); -#if defined(CONFIG_SYS_MALLOC_F_LEN) + debug("spl_early_init()\n"); + +#if CONFIG_VAL(SYS_MALLOC_F_LEN) + if (setup_malloc) { #ifdef CONFIG_MALLOC_F_ADDR - gd->malloc_base = CONFIG_MALLOC_F_ADDR; + gd->malloc_base = CONFIG_MALLOC_F_ADDR; #endif - gd->malloc_limit = CONFIG_SYS_MALLOC_F_LEN; - gd->malloc_ptr = 0; + gd->malloc_limit = CONFIG_VAL(SYS_MALLOC_F_LEN); + gd->malloc_ptr = 0; + } #endif + ret = bootstage_init(true); + if (ret) { + debug("%s: Failed to set up bootstage: ret=%d\n", __func__, + ret); + return ret; + } + bootstage_mark_name(BOOTSTAGE_ID_START_SPL, "spl"); if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) { ret = fdtdec_setup(); if (ret) { @@ -189,14 +256,49 @@ int spl_init(void) return ret; } } - if (IS_ENABLED(CONFIG_SPL_DM)) { + if (CONFIG_IS_ENABLED(DM)) { + bootstage_start(BOOTSTATE_ID_ACCUM_DM_SPL, "dm_spl"); /* With CONFIG_SPL_OF_PLATDATA, bring in all devices */ ret = dm_init_and_scan(!CONFIG_IS_ENABLED(OF_PLATDATA)); + bootstage_accum(BOOTSTATE_ID_ACCUM_DM_SPL); if (ret) { debug("dm_init_and_scan() returned error %d\n", ret); return ret; } } + + return 0; +} + +void spl_set_bd(void) +{ + if (!gd->bd) + gd->bd = &bdata; +} + +int spl_early_init(void) +{ + int ret; + + ret = spl_common_init(true); + if (ret) + return ret; + gd->flags |= GD_FLG_SPL_EARLY_INIT; + + return 0; +} + +int spl_init(void) +{ + int ret; + bool setup_malloc = !(IS_ENABLED(CONFIG_SPL_STACK_R) && + IS_ENABLED(CONFIG_SPL_SYS_MALLOC_SIMPLE)); + + if (!(gd->flags & GD_FLG_SPL_EARLY_INIT)) { + ret = spl_common_init(setup_malloc); + if (ret) + return ret; + } gd->flags |= GD_FLG_SPL_INIT; return 0; @@ -258,7 +360,7 @@ static int boot_from_devices(struct spl_image_info *spl_image, loader = spl_ll_find_loader(spl_boot_list[i]); #if defined(CONFIG_SPL_SERIAL_SUPPORT) && defined(CONFIG_SPL_LIBCOMMON_SUPPORT) if (loader) - printf("Trying to boot from %s", loader->name); + printf("Trying to boot from %s\n", loader->name); else puts("SPL: Unsupported Boot Device!\n"); #endif @@ -282,6 +384,12 @@ void board_init_r(gd_t *dummy1, ulong dummy2) debug(">>spl:board_init_r()\n"); + spl_set_bd(); + +#ifdef CONFIG_SPL_OS_BOOT + dram_init_banksize(); +#endif + #if defined(CONFIG_SYS_SPL_MALLOC_START) mem_malloc_init(CONFIG_SYS_SPL_MALLOC_START, CONFIG_SYS_SPL_MALLOC_SIZE); @@ -291,7 +399,7 @@ void board_init_r(gd_t *dummy1, ulong dummy2) if (spl_init()) hang(); } -#ifndef CONFIG_PPC +#if !defined(CONFIG_PPC) && !defined(CONFIG_ARCH_MX6) /* * timer_init() does not exist on PPC systems. The timer is initialized * and enabled (decrementer) in interrupt_init() here. @@ -299,11 +407,14 @@ void board_init_r(gd_t *dummy1, ulong dummy2) timer_init(); #endif -#ifdef CONFIG_SPL_BOARD_INIT +#if CONFIG_IS_ENABLED(BOARD_INIT) spl_board_init(); #endif memset(&spl_image, '\0', sizeof(spl_image)); +#ifdef CONFIG_SYS_SPL_ARGS_ADDR + spl_image.arg = (void *)CONFIG_SYS_SPL_ARGS_ADDR; +#endif board_boot_order(spl_boot_list); if (boot_from_devices(&spl_image, spl_boot_list, @@ -312,26 +423,44 @@ void board_init_r(gd_t *dummy1, ulong dummy2) hang(); } +#ifdef CONFIG_CPU_V7M + spl_image.entry_point |= 0x1; +#endif switch (spl_image.os) { case IH_OS_U_BOOT: debug("Jumping to U-Boot\n"); break; +#if CONFIG_IS_ENABLED(ATF) + case IH_OS_ARM_TRUSTED_FIRMWARE: + debug("Jumping to U-Boot via ARM Trusted Firmware\n"); + spl_invoke_atf(&spl_image); + break; +#endif #ifdef CONFIG_SPL_OS_BOOT case IH_OS_LINUX: debug("Jumping to Linux\n"); + spl_fixup_fdt(); spl_board_prepare_for_linux(); - jump_to_image_linux(&spl_image, - (void *)CONFIG_SYS_SPL_ARGS_ADDR); + jump_to_image_linux(&spl_image); #endif default: debug("Unsupported OS image.. Jumping nevertheless..\n"); } -#if defined(CONFIG_SYS_MALLOC_F_LEN) && !defined(CONFIG_SYS_SPL_MALLOC_SIZE) +#if CONFIG_VAL(SYS_MALLOC_F_LEN) && !defined(CONFIG_SYS_SPL_MALLOC_SIZE) debug("SPL malloc() used %#lx bytes (%ld KB)\n", gd->malloc_ptr, gd->malloc_ptr / 1024); #endif +#ifdef CONFIG_BOOTSTAGE_STASH + int ret; + + bootstage_mark_name(BOOTSTAGE_ID_END_SPL, "end_spl"); + ret = bootstage_stash((void *)CONFIG_BOOTSTAGE_STASH_ADDR, + CONFIG_BOOTSTAGE_STASH_SIZE); + if (ret) + debug("Failed to stash bootstage: err=%d\n", ret); +#endif - debug("loaded - jumping to U-Boot..."); + debug("loaded - jumping to U-Boot...\n"); spl_board_prepare_for_boot(); jump_to_image_no_args(&spl_image); } @@ -342,7 +471,6 @@ void board_init_r(gd_t *dummy1, ulong dummy2) */ void preloader_console_init(void) { - gd->bd = &bdata; gd->baudrate = CONFIG_BAUDRATE; serial_init(); /* serial communications setup */ @@ -380,7 +508,7 @@ ulong spl_relocate_stack_gd(void) gd_t *new_gd; ulong ptr = CONFIG_SPL_STACK_R_ADDR; -#ifdef CONFIG_SPL_SYS_MALLOC_SIMPLE +#if defined(CONFIG_SPL_SYS_MALLOC_SIMPLE) && CONFIG_VAL(SYS_MALLOC_F_LEN) if (CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN) { ptr -= CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN; gd->malloc_base = ptr;