diff --git a/arch/arm/cpu/armv8/fsl-layerscape/spl.c b/arch/arm/cpu/armv8/fsl-layerscape/spl.c index 77724336d6..215ed9759e 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/spl.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/spl.c @@ -38,6 +38,9 @@ u32 spl_boot_device(void) #ifdef CONFIG_SPL_BUILD +/* Define board data structure */ +static struct bd_info bdata __attribute__ ((section(".data"))); + void spl_board_init(void) { #if defined(CONFIG_NXP_ESBC) && defined(CONFIG_FSL_LSCH2) @@ -74,7 +77,7 @@ void board_init_f(ulong dummy) get_clocks(); preloader_console_init(); - spl_set_bd(); + gd->bd = &bdata; #ifdef CONFIG_SYS_I2C #ifdef CONFIG_SPL_I2C_SUPPORT diff --git a/common/spl/Kconfig b/common/spl/Kconfig index 6d980be0b7..6b0186763b 100644 --- a/common/spl/Kconfig +++ b/common/spl/Kconfig @@ -113,6 +113,15 @@ config SPL_FSL_PBL Create boot binary having SPL binary in PBI format concatenated with u-boot binary. +config SPL_ALLOC_BD + bool "Allocate memory for bd_info" + default y if X86 || SANDBOX + help + Some boards don't allocate space for this in their board_init_f() + code. In this case U-Boot can allocate space for gd->bd in the + standard SPL flow (board_init_r()). Enable this option to support + this feature. + endmenu config HANDOFF diff --git a/common/spl/spl.c b/common/spl/spl.c index 63c48fbf33..835c53deaa 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -53,9 +53,6 @@ binman_sym_declare(ulong, spl, image_pos); binman_sym_declare(ulong, spl, size); #endif -/* Define board data structure */ -static struct bd_info bdata __attribute__ ((section(".data"))); - /* * Board-specific Platform code can reimplement show_boot_progress () if needed */ @@ -443,14 +440,19 @@ static int spl_common_init(bool setup_malloc) return 0; } -void spl_set_bd(void) +int spl_alloc_bd(void) { /* * NOTE: On some platforms (e.g. x86) bdata may be in flash and not * writeable. */ - if (!gd->bd) - gd->bd = &bdata; + if (!gd->bd) { + gd->bd = malloc(sizeof(*gd->bd)); + if (!gd->bd) + return -ENOMEM; + } + + return 0; } int spl_early_init(void) @@ -600,8 +602,6 @@ void board_init_r(gd_t *dummy1, ulong dummy2) debug(">>" SPL_TPL_PROMPT "board_init_r()\n"); - spl_set_bd(); - #if defined(CONFIG_SYS_SPL_MALLOC_START) mem_malloc_init(CONFIG_SYS_SPL_MALLOC_START, CONFIG_SYS_SPL_MALLOC_SIZE); @@ -611,6 +611,10 @@ void board_init_r(gd_t *dummy1, ulong dummy2) if (spl_init()) hang(); } + if (IS_ENABLED(CONFIG_SPL_ALLOC_BD) && spl_alloc_bd()) { + puts("Cannot alloc bd\n"); + hang(); + } #if !defined(CONFIG_PPC) && !defined(CONFIG_ARCH_MX6) /* * timer_init() does not exist on PPC systems. The timer is initialized diff --git a/include/spl.h b/include/spl.h index 374a295fa3..a7648787b7 100644 --- a/include/spl.h +++ b/include/spl.h @@ -285,7 +285,15 @@ u32 spl_mmc_boot_mode(const u32 boot_device); * If not overridden, it is weakly defined in common/spl/spl_mmc.c. */ int spl_mmc_boot_partition(const u32 boot_device); -void spl_set_bd(void); + +/** + * spl_alloc_bd() - Allocate space for bd_info + * + * This sets up the gd->bd pointer by allocating memory for it + * + * @return 0 if OK, -ENOMEM if out of memory + */ +int spl_alloc_bd(void); /** * spl_set_header_raw_uboot() - Set up a standard SPL image structure