diff options
-rw-r--r-- | common/init/board_init.c | 20 | ||||
-rw-r--r-- | common/spl/Kconfig | 19 | ||||
-rw-r--r-- | common/spl/spl.c | 25 |
3 files changed, 64 insertions, 0 deletions
diff --git a/common/init/board_init.c b/common/init/board_init.c index 526fee35ff..e52106966d 100644 --- a/common/init/board_init.c +++ b/common/init/board_init.c @@ -18,6 +18,23 @@ __weak void arch_setup_gd(struct global_data *gd_ptr) } #endif /* !CONFIG_X86 && !CONFIG_ARM */ +/** + * This function is called after the position of the initial stack is + * determined in gd->start_addr_sp. Boards can override it to set up + * stack-checking markers. + */ +__weak void board_init_f_init_stack_protection(void) +{ +#if CONFIG_IS_ENABLED(SYS_REPORT_STACK_F_USAGE) + ulong stack_bottom = gd->start_addr_sp - + CONFIG_VAL(SIZE_LIMIT_PROVIDE_STACK); + + /* substact some safety margin (0x20) since stack is in use here */ + memset((void *)stack_bottom, CONFIG_VAL(SYS_STACK_F_CHECK_BYTE), + CONFIG_VAL(SIZE_LIMIT_PROVIDE_STACK) - 0x20); +#endif +} + /* * Allocate reserved space for use as 'globals' from 'top' address and * return 'bottom' address of allocated space @@ -126,6 +143,9 @@ void board_init_f_init_reserve(ulong base) /* next alloc will be higher by one 'early malloc arena' size */ base += CONFIG_VAL(SYS_MALLOC_F_LEN); #endif + + if (CONFIG_IS_ENABLED(SYS_REPORT_STACK_F_USAGE)) + board_init_f_init_stack_protection(); } /* diff --git a/common/spl/Kconfig b/common/spl/Kconfig index 54154b93c9..630491699c 100644 --- a/common/spl/Kconfig +++ b/common/spl/Kconfig @@ -62,6 +62,25 @@ config SPL_SIZE_LIMIT_PROVIDE_STACK of SRAM available for SPL when the stack required before reolcation uses this SRAM, too. +config SPL_SYS_STACK_F_CHECK_BYTE + hex + default 0xaa + help + Constant used to check the stack + +config SPL_SYS_REPORT_STACK_F_USAGE + depends on SPL_SIZE_LIMIT_PROVIDE_STACK != 0 + bool "Check and report stack usage in SPL before relocation" + help + If this option is enabled, the initial SPL stack is filled with 0xaa + very early, up to the size configured with + SPL_SIZE_LIMIT_PROVIDE_STACK. + Later when SPL is done using this initial stack and switches to a + stack in DRAM, the actually used size of this initial stack is + reported by examining the memory and searching for the lowest + occurrence of non 0xaa bytes. + This default implementation works for stacks growing down only. + menu "PowerPC SPL Boot options" depends on PPC && (SUPPORT_SPL && !SPL_FRAMEWORK) diff --git a/common/spl/spl.c b/common/spl/spl.c index c182705b3f..2c696f2a79 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -710,6 +710,28 @@ void preloader_console_init(void) #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 * * Sometimes board_init_f() runs with a stack in SRAM but we want to use SDRAM @@ -733,6 +755,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", |