X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=common%2Fspl%2Fspl.c;h=163e960a1e865041cbef21b66755ef37321eb42d;hb=b67eefdb6ec9467c41b1c0081f0823bbfff36b00;hp=0a6a47c202019c1885c25173d6520a95f467886a;hpb=b4ee6daad7a2604ca9466b2ba48de86cc27d381f;p=oweals%2Fu-boot.git diff --git a/common/spl/spl.c b/common/spl/spl.c index 0a6a47c202..163e960a1e 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -11,13 +11,18 @@ #include #include #include +#include +#include +#include #include #include #include #include +#include #include #include #include +#include #include #include #include @@ -38,6 +43,12 @@ u32 *boot_params_ptr = NULL; /* See spl.h for information about this */ binman_sym_declare(ulong, u_boot_any, image_pos); +binman_sym_declare(ulong, u_boot_any, size); + +#ifdef CONFIG_TPL +binman_sym_declare(ulong, spl, image_pos); +binman_sym_declare(ulong, spl, size); +#endif /* Define board data structure */ static bd_t bdata __attribute__ ((section(".data"))); @@ -116,6 +127,20 @@ void spl_fixup_fdt(void) #endif } +ulong spl_get_image_pos(void) +{ + return spl_phase() == PHASE_TPL ? + binman_sym(ulong, spl, image_pos) : + binman_sym(ulong, u_boot_any, image_pos); +} + +ulong spl_get_image_size(void) +{ + return spl_phase() == PHASE_TPL ? + binman_sym(ulong, spl, size) : + binman_sym(ulong, u_boot_any, size); +} + /* * Weak default function for board specific cleanup/preparation before * Linux boot. Some boards/platforms might not need it, so just provide @@ -195,10 +220,12 @@ static int spl_load_fit_image(struct spl_image_info *spl_image, #ifdef CONFIG_SPL_FIT_SIGNATURE images.verify = 1; #endif - fit_image_load(&images, (ulong)header, + ret = fit_image_load(&images, (ulong)header, &fit_uname_fdt, &fit_uname_config, IH_ARCH_DEFAULT, IH_TYPE_FLATDT, -1, FIT_LOAD_OPTIONAL, &dt_data, &dt_len); + if (ret >= 0) + spl_image->fdt_addr = (void *)dt_data; conf_noffset = fit_conf_get_node((const void *)header, fit_uname_config); @@ -227,6 +254,14 @@ static int spl_load_fit_image(struct spl_image_info *spl_image, } #endif +__weak int spl_parse_legacy_header(struct spl_image_info *spl_image, + const struct image_header *header) +{ + /* LEGACY image not supported */ + debug("Legacy boot image support not enabled, proceeding to other boot methods\n"); + return -EINVAL; +} + int spl_parse_image_header(struct spl_image_info *spl_image, const struct image_header *header) { @@ -237,51 +272,11 @@ int spl_parse_image_header(struct spl_image_info *spl_image, return ret; #endif if (image_get_magic(header) == IH_MAGIC) { -#ifdef CONFIG_SPL_LEGACY_IMAGE_SUPPORT - u32 header_size = sizeof(struct image_header); - -#ifdef CONFIG_SPL_LEGACY_IMAGE_CRC_CHECK - /* check uImage header CRC */ - if (!image_check_hcrc(header)) { - puts("SPL: Image header CRC check failed!\n"); - return -EINVAL; - } -#endif - - if (spl_image->flags & SPL_COPY_PAYLOAD_ONLY) { - /* - * On some system (e.g. powerpc), the load-address and - * entry-point is located at address 0. We can't load - * to 0-0x40. So skip header in this case. - */ - spl_image->load_addr = image_get_load(header); - spl_image->entry_point = image_get_ep(header); - spl_image->size = image_get_data_size(header); - } else { - spl_image->entry_point = image_get_load(header); - /* Load including the header */ - spl_image->load_addr = spl_image->entry_point - - header_size; - spl_image->size = image_get_data_size(header) + - header_size; - } -#ifdef CONFIG_SPL_LEGACY_IMAGE_CRC_CHECK - /* store uImage data length and CRC to check later */ - spl_image->dcrc_data = image_get_load(header); - spl_image->dcrc_length = image_get_data_size(header); - spl_image->dcrc = image_get_dcrc(header); -#endif + int ret; - spl_image->os = image_get_os(header); - spl_image->name = image_get_name(header); - debug(SPL_TPL_PROMPT - "payload image: %32s load addr: 0x%lx size: %d\n", - 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 + ret = spl_parse_legacy_header(spl_image, header); + if (ret) + return ret; } else { #ifdef CONFIG_SPL_PANIC_ON_RAW_IMAGE /* @@ -354,17 +349,23 @@ static int setup_spl_handoff(void) return 0; } +__weak int handoff_arch_save(struct spl_handoff *ho) +{ + return 0; +} + static int write_spl_handoff(void) { struct spl_handoff *ho; + int ret; ho = bloblist_find(BLOBLISTT_SPL_HANDOFF, sizeof(struct spl_handoff)); if (!ho) return -ENOENT; handoff_save_dram(ho); -#ifdef CONFIG_SANDBOX - ho->arch.magic = TEST_HANDOFF_MAGIC; -#endif + ret = handoff_arch_save(ho); + if (ret) + return ret; debug(SPL_TPL_PROMPT "Wrote SPL handoff\n"); return 0; @@ -388,13 +389,25 @@ static int spl_common_init(bool setup_malloc) gd->malloc_ptr = 0; } #endif - ret = bootstage_init(true); + ret = bootstage_init(u_boot_first_phase()); if (ret) { debug("%s: Failed to set up bootstage: ret=%d\n", __func__, ret); return ret; } - bootstage_mark_name(BOOTSTAGE_ID_START_SPL, "spl"); +#ifdef CONFIG_BOOTSTAGE_STASH + if (!u_boot_first_phase()) { + const void *stash = map_sysmem(CONFIG_BOOTSTAGE_STASH_ADDR, + CONFIG_BOOTSTAGE_STASH_SIZE); + + ret = bootstage_unstash(stash, CONFIG_BOOTSTAGE_STASH_SIZE); + if (ret) + debug("%s: Failed to unstash bootstage: ret=%d\n", + __func__, ret); + } +#endif /* CONFIG_BOOTSTAGE_STASH */ + bootstage_mark_name(spl_phase() == PHASE_TPL ? BOOTSTAGE_ID_START_TPL : + BOOTSTAGE_ID_START_SPL, SPL_TPL_NAME); #if CONFIG_IS_ENABLED(LOG) ret = log_init(); if (ret) { @@ -402,23 +415,6 @@ static int spl_common_init(bool setup_malloc) return ret; } #endif - if (CONFIG_IS_ENABLED(BLOBLIST)) { - ret = bloblist_init(); - if (ret) { - debug("%s: Failed to set up bloblist: ret=%d\n", - __func__, ret); - return ret; - } - } - if (CONFIG_IS_ENABLED(HANDOFF)) { - int ret; - - ret = setup_spl_handoff(); - if (ret) { - puts(SPL_TPL_PROMPT "Cannot set up SPL handoff\n"); - hang(); - } - } if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) { ret = fdtdec_setup(); if (ret) { @@ -427,10 +423,11 @@ static int spl_common_init(bool setup_malloc) } } if (CONFIG_IS_ENABLED(DM)) { - bootstage_start(BOOTSTATE_ID_ACCUM_DM_SPL, "dm_spl"); + bootstage_start(BOOTSTAGE_ID_ACCUM_DM_SPL, + spl_phase() == PHASE_TPL ? "dm tpl" : "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); + bootstage_accum(BOOTSTAGE_ID_ACCUM_DM_SPL); if (ret) { debug("dm_init_and_scan() returned error %d\n", ret); return ret; @@ -533,7 +530,7 @@ static int spl_load_image(struct spl_image_info *spl_image, } /** - * boot_from_devices() - Try loading an booting U-Boot from a list of devices + * boot_from_devices() - Try loading a booting U-Boot from a list of devices * * @spl_image: Place to put the image details if successful * @spl_boot_list: List of boot devices to try @@ -564,6 +561,23 @@ static int boot_from_devices(struct spl_image_info *spl_image, return -ENODEV; } +#if defined(CONFIG_SPL_FRAMEWORK_BOARD_INIT_F) +void board_init_f(ulong dummy) +{ + if (CONFIG_IS_ENABLED(OF_CONTROL)) { + int ret; + + ret = spl_early_init(); + if (ret) { + debug("spl_early_init() failed: %d\n", ret); + hang(); + } + } + + preloader_console_init(); +} +#endif + void board_init_r(gd_t *dummy1, ulong dummy2) { u32 spl_boot_list[] = { @@ -596,12 +610,30 @@ void board_init_r(gd_t *dummy1, ulong dummy2) */ timer_init(); #endif + if (CONFIG_IS_ENABLED(BLOBLIST)) { + ret = bloblist_init(); + if (ret) { + debug("%s: Failed to set up bloblist: ret=%d\n", + __func__, ret); + puts(SPL_TPL_PROMPT "Cannot set up bloblist\n"); + hang(); + } + } + if (CONFIG_IS_ENABLED(HANDOFF)) { + int ret; + + ret = setup_spl_handoff(); + if (ret) { + puts(SPL_TPL_PROMPT "Cannot set up SPL handoff\n"); + hang(); + } + } #if CONFIG_IS_ENABLED(BOARD_INIT) spl_board_init(); #endif -#if defined(CONFIG_SPL_WATCHDOG_SUPPORT) && defined(CONFIG_WDT) +#if defined(CONFIG_SPL_WATCHDOG_SUPPORT) && CONFIG_IS_ENABLED(WDT) initr_watchdog(); #endif @@ -657,6 +689,12 @@ void board_init_r(gd_t *dummy1, ulong dummy2) (void *)spl_image.entry_point); break; #endif +#if CONFIG_IS_ENABLED(OPENSBI) + case IH_OS_OPENSBI: + debug("Jumping to U-Boot via RISC-V OpenSBI\n"); + spl_invoke_opensbi(&spl_image); + break; +#endif #ifdef CONFIG_SPL_OS_BOOT case IH_OS_LINUX: debug("Jumping to Linux\n"); @@ -671,8 +709,9 @@ void board_init_r(gd_t *dummy1, ulong dummy2) debug("SPL malloc() used 0x%lx bytes (%ld KB)\n", gd->malloc_ptr, gd->malloc_ptr / 1024); #endif + bootstage_mark_name(spl_phase() == PHASE_TPL ? BOOTSTAGE_ID_END_TPL : + BOOTSTAGE_ID_END_SPL, "end " SPL_TPL_NAME); #ifdef CONFIG_BOOTSTAGE_STASH - bootstage_mark_name(BOOTSTAGE_ID_END_SPL, "end_spl"); ret = bootstage_stash((void *)CONFIG_BOOTSTAGE_STASH_ADDR, CONFIG_BOOTSTAGE_STASH_SIZE); if (ret) @@ -684,13 +723,13 @@ void board_init_r(gd_t *dummy1, ulong dummy2) jump_to_image_no_args(&spl_image); } -#ifdef CONFIG_SPL_SERIAL_SUPPORT /* * This requires UART clocks to be enabled. In order for this to work the * caller must ensure that the gd pointer is valid. */ void preloader_console_init(void) { +#ifdef CONFIG_SPL_SERIAL_SUPPORT gd->baudrate = CONFIG_BAUDRATE; serial_init(); /* serial communications setup */ @@ -704,8 +743,30 @@ void preloader_console_init(void) #ifdef CONFIG_SPL_DISPLAY_PRINT spl_display_print(); #endif +#endif } + +/** + * This function is called before the stack is changed from initial stack to + * relocated stack. It tries to dump the stack size used + */ +__weak void spl_relocate_stack_check(void) +{ +#if CONFIG_IS_ENABLED(SYS_REPORT_STACK_F_USAGE) + ulong init_sp = gd->start_addr_sp; + ulong stack_bottom = init_sp - CONFIG_VAL(SIZE_LIMIT_PROVIDE_STACK); + u8 *ptr = (u8 *)stack_bottom; + ulong i; + + for (i = 0; i < CONFIG_VAL(SIZE_LIMIT_PROVIDE_STACK); i++) { + if (*ptr != CONFIG_VAL(SYS_STACK_F_CHECK_BYTE)) + break; + ptr++; + } + printf("SPL initial stack usage: %lu bytes\n", + CONFIG_VAL(SIZE_LIMIT_PROVIDE_STACK) - i); #endif +} /** * spl_relocate_stack_gd() - Relocate stack ready for board_init_r() execution @@ -731,6 +792,9 @@ ulong spl_relocate_stack_gd(void) gd_t *new_gd; ulong ptr = CONFIG_SPL_STACK_R_ADDR; + if (CONFIG_IS_ENABLED(SYS_REPORT_STACK_F_USAGE)) + spl_relocate_stack_check(); + #if defined(CONFIG_SPL_SYS_MALLOC_SIMPLE) && CONFIG_VAL(SYS_MALLOC_F_LEN) if (CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN) { debug("SPL malloc() before relocation used 0x%lx bytes (%ld KB)\n", @@ -748,7 +812,7 @@ ulong spl_relocate_stack_gd(void) #if CONFIG_IS_ENABLED(DM) dm_fixup_for_gd_move(new_gd); #endif -#if !defined(CONFIG_ARM) +#if !defined(CONFIG_ARM) && !defined(CONFIG_RISCV) gd = new_gd; #endif return ptr; @@ -756,3 +820,14 @@ ulong spl_relocate_stack_gd(void) return 0; #endif } + +#if defined(CONFIG_BOOTCOUNT_LIMIT) && !defined(CONFIG_SPL_BOOTCOUNT_LIMIT) +void bootcount_store(ulong a) +{ +} + +ulong bootcount_load(void) +{ + return 0; +} +#endif