arm: spl: Allow board_init_r() to run with a larger stack
At present SPL uses a single stack, either CONFIG_SPL_STACK or CONFIG_SYS_INIT_SP_ADDR. Since some SPL features (such as MMC and environment) require a lot of stack, some boards set CONFIG_SPL_STACK to point into SDRAM. They then set up SDRAM very early, before board_init_f(), so that the larger stack can be used. This is an abuse of lowlevel_init(). That function should only be used for essential start-up code which cannot be delayed. An example of a valid use is when only part of the SPL code is visible/executable, and the SoC must be set up so that board_init_f() can be reached. It should not be used for SDRAM init, console init, etc. Add a CONFIG_SPL_STACK_R option, which allows the stack to be moved to a new address before board_init_r() is called in SPL. The expected SPL flow (for CONFIG_SPL_FRAMEWORK) is documented in the README. Signed-off-by: Simon Glass <sjg@chromium.org> For version 1: Acked-by: Albert ARIBAUD <albert.u.boot@aribaud.net> Reviewed-by: Stefan Roese <sr@denx.de> Tested-by: Bo Shen <voice.shen@atmel.com> Acked-by: Bo Shen <voice.shen@atmel.com> Acked-by: Heiko Schocher <hs@denx.de> Tested-by: Heiko Schocher <hs@denx.de> Signed-off-by: Tom Rini <trini@konsulko.com>
This commit is contained in:
@@ -281,3 +281,38 @@ void preloader_console_init(void)
|
||||
spl_display_print();
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* spl_relocate_stack_gd() - Relocate stack ready for board_init_r() execution
|
||||
*
|
||||
* Sometimes board_init_f() runs with a stack in SRAM but we want to use SDRAM
|
||||
* for the main board_init_r() execution. This is typically because we need
|
||||
* more stack space for things like the MMC sub-system.
|
||||
*
|
||||
* This function calculates the stack position, copies the global_data into
|
||||
* place and returns the new stack position. The caller is responsible for
|
||||
* setting up the sp register.
|
||||
*
|
||||
* @return new stack location, or 0 to use the same stack
|
||||
*/
|
||||
ulong spl_relocate_stack_gd(void)
|
||||
{
|
||||
#ifdef CONFIG_SPL_STACK_R
|
||||
gd_t *new_gd;
|
||||
ulong ptr;
|
||||
|
||||
/* Get stack position: use 8-byte alignment for ABI compliance */
|
||||
ptr = CONFIG_SPL_STACK_R - sizeof(gd_t);
|
||||
ptr &= ~7;
|
||||
new_gd = (gd_t *)ptr;
|
||||
memcpy(new_gd, (void *)gd, sizeof(gd_t));
|
||||
gd = new_gd;
|
||||
|
||||
/* Clear the BSS. */
|
||||
memset(__bss_start, 0, __bss_end - __bss_start);
|
||||
|
||||
return ptr;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user