board_init_f_mem() alters the C runtime environment's stack it ls actually already using. This is not a valid C runtime environment.
Split board_init_f_mem into C functions which do not alter their own stack and therefore run in a valid C runtime environment. Signed-off-by: Albert ARIBAUD <albert.u.b...@aribaud.net> --- For NIOS2, this patch hopefully contains all manual fixes by Thomas. Changes in v2: - Fix all checkpatch issues - Fix board_init_f_malloc prototype mismatch - Fix board_init_[f_]xxx typo in NIOS2 - Fix aarch64 asm 'sub' syntax error arch/arc/lib/start.S | 20 +++++++++++++--- arch/arm/lib/crt0.S | 10 ++++++-- arch/arm/lib/crt0_64.S | 10 ++++++-- arch/microblaze/cpu/start.S | 4 ++-- arch/nios2/cpu/start.S | 17 ++++++++++++-- arch/powerpc/cpu/ppc4xx/start.S | 18 ++++++++++---- arch/x86/cpu/start.S | 10 ++++++-- arch/x86/lib/fsp/fsp_common.c | 4 ++-- common/init/board_init.c | 31 ++++++++++++++---------- include/common.h | 52 +++++++++++++++++++++++++---------------- 10 files changed, 125 insertions(+), 51 deletions(-) diff --git a/arch/arc/lib/start.S b/arch/arc/lib/start.S index 26a5934..d24d60b 100644 --- a/arch/arc/lib/start.S +++ b/arch/arc/lib/start.S @@ -54,14 +54,28 @@ ENTRY(_start) mov %sp, CONFIG_SYS_INIT_SP_ADDR mov %fp, %sp - /* Allocate and zero GD, update SP */ + /* Allocate GD, update SP */ mov %r0, %sp - bl board_init_f_mem + bl board_init_f_gd_size + /* Update stack- and frame-pointers */ + sub %sp, %sp, %r0 + mov %fp, %sp + + /* Zero GD */ + mov %r0, %sp + bl board_init_f_gd + /* Allocate malloc, update SP */ + mov %r0, %sp + bl board_init_f_malloc_size /* Update stack- and frame-pointers */ - mov %sp, %r0 + sub %sp, %sp, %r0 mov %fp, %sp + /* update GD with malloc base */ + mov %r0, %sp + bl board_init_f_malloc + /* Zero the one and only argument of "board_init_f" */ mov_s %r0, 0 j board_init_f diff --git a/arch/arm/lib/crt0.S b/arch/arm/lib/crt0.S index 80548eb..26abab7 100644 --- a/arch/arm/lib/crt0.S +++ b/arch/arm/lib/crt0.S @@ -82,9 +82,15 @@ ENTRY(_main) #else bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ #endif + bl board_init_f_gd_size + sub sp, r0 mov r0, sp - bl board_init_f_mem - mov sp, r0 + mov r9, r0 + bl board_init_f_gd + bl board_init_f_malloc_size + sub sp, r0 + mov r0, sp + bl board_init_f_malloc mov r0, #0 bl board_init_f diff --git a/arch/arm/lib/crt0_64.S b/arch/arm/lib/crt0_64.S index cef1c71..00cef36 100644 --- a/arch/arm/lib/crt0_64.S +++ b/arch/arm/lib/crt0_64.S @@ -75,8 +75,14 @@ ENTRY(_main) ldr x0, =(CONFIG_SYS_INIT_SP_ADDR) #endif bic sp, x0, #0xf /* 16-byte alignment for ABI compliance */ - bl board_init_f_mem - mov sp, x0 + bl board_init_f_gd_size + sub sp, sp, x0 + mov x0, sp + bl board_init_f_gd + bl board_init_f_malloc_size + sub sp, sp, x0 + mov x0, sp + bl board_init_f_malloc mov x0, #0 bl board_init_f diff --git a/arch/microblaze/cpu/start.S b/arch/microblaze/cpu/start.S index 14f46a8..206be3e 100644 --- a/arch/microblaze/cpu/start.S +++ b/arch/microblaze/cpu/start.S @@ -25,7 +25,7 @@ _start: addi r8, r0, __end mts rslr, r8 - /* TODO: Redo this code to call board_init_f_mem() */ + /* TODO: Redo this code to call board_init_f_*() */ #if defined(CONFIG_SPL_BUILD) addi r1, r0, CONFIG_SPL_STACK_ADDR mts rshr, r1 @@ -142,7 +142,7 @@ _start: ori r12, r12, 0x1a0 mts rmsr, r12 - /* TODO: Redo this code to call board_init_f_mem() */ + /* TODO: Redo this code to call board_init_f_*() */ clear_bss: /* clear BSS segments */ addi r5, r0, __bss_start diff --git a/arch/nios2/cpu/start.S b/arch/nios2/cpu/start.S index 54787c5..c163ce1 100644 --- a/arch/nios2/cpu/start.S +++ b/arch/nios2/cpu/start.S @@ -107,9 +107,22 @@ _reloc: mov fp, sp /* Allocate and zero GD, update SP */ + movhi r2, %hi(board_init_f_gd_size@h) + ori r2, r2, %lo(board_init_f_gd_size@h) + callr r2 + sub sp, sp, r4 + mov r4, sp + movhi r2, %hi(board_init_f_gd@h) + ori r2, r2, %lo(board_init_f_gd@h) + callr r2 + /* Allocate malloc arena, update SP */ + movhi r2, %hi(board_init_f_malloc_size@h) + ori r2, r2, %lo(board_init_f_malloc_size@h) + callr r2 + sub sp, sp, r4 mov r4, sp - movhi r2, %hi(board_init_f_mem@h) - ori r2, r2, %lo(board_init_f_mem@h) + movhi r2, %hi(board_init_f_malloc@h) + ori r2, r2, %lo(board_init_f_malloc@h) callr r2 /* Update stack- and frame-pointers */ diff --git a/arch/powerpc/cpu/ppc4xx/start.S b/arch/powerpc/cpu/ppc4xx/start.S index 77d4040..c827c95 100644 --- a/arch/powerpc/cpu/ppc4xx/start.S +++ b/arch/powerpc/cpu/ppc4xx/start.S @@ -761,9 +761,14 @@ _start: bl cpu_init_f /* run low-level CPU init code (from Flash) */ #ifdef CONFIG_SYS_GENERIC_BOARD + bl board_init_f_gd_size + sub r1, r1, r3 mr r3, r1 - bl board_init_f_mem - mr r1, r3 + bl board_init_f_gd + bl board_init_f_malloc_size + sub r1, r1, r3 + mr r3, r1 + bl board_init_f_malloc li r0,0 stwu r0, -4(r1) stwu r0, -4(r1) @@ -1037,9 +1042,14 @@ _start: bl cpu_init_f /* run low-level CPU init code (from Flash) */ #ifdef CONFIG_SYS_GENERIC_BOARD + bl board_init_f_gd_size + sub r1, r1, r3 + mr r3, r1 + bl board_init_f_gd + bl board_init_f_malloc_size + sub r1, r1, r3 mr r3, r1 - bl board_init_f_mem - mr r1, r3 + bl board_init_f_malloc stwu r0, -4(r1) stwu r0, -4(r1) #endif diff --git a/arch/x86/cpu/start.S b/arch/x86/cpu/start.S index 5b4ee79..25ac286 100644 --- a/arch/x86/cpu/start.S +++ b/arch/x86/cpu/start.S @@ -122,9 +122,15 @@ car_init_ret: */ #endif /* Set up global data */ + call board_init_f_gd_size + subl %esp, %eax mov %esp, %eax - call board_init_f_mem - mov %eax, %esp + call board_init_f_gd + /* Set up malloc arena */ + call board_init_f_malloc_size + subl %esp, %eax + mov %esp, %eax + call board_init_f_malloc #ifdef CONFIG_DEBUG_UART call debug_uart_init diff --git a/arch/x86/lib/fsp/fsp_common.c b/arch/x86/lib/fsp/fsp_common.c index c78df94..5249455 100644 --- a/arch/x86/lib/fsp/fsp_common.c +++ b/arch/x86/lib/fsp/fsp_common.c @@ -95,8 +95,8 @@ int x86_fsp_init(void) /* * The second time we enter here, adjust the size of malloc() * pool before relocation. Given gd->malloc_base was adjusted - * after the call to board_init_f_mem() in arch/x86/cpu/start.S, - * we should fix up gd->malloc_limit here. + * after the call to board_init_f_malloc() in arch/x86/cpu/ + * start.S, we should fix up gd->malloc_limit here. */ gd->malloc_limit += CONFIG_FSP_SYS_MALLOC_F_LEN; } diff --git a/common/init/board_init.c b/common/init/board_init.c index e74b63b..8839a4a 100644 --- a/common/init/board_init.c +++ b/common/init/board_init.c @@ -29,32 +29,39 @@ __weak void arch_setup_gd(struct global_data *gd_ptr) } #endif /* !CONFIG_X86 */ -ulong board_init_f_mem(ulong top) +ulong board_init_f_gd_size(void) +{ + return roundup(sizeof(struct global_data), 16); +} + +void board_init_f_gd(struct global_data *gd_ptr) { - struct global_data *gd_ptr; #ifndef _USE_MEMCPY int *ptr; #endif - /* Leave space for the stack we are running with now */ - top -= 0x40; - - top -= sizeof(struct global_data); - top = ALIGN(top, 16); - gd_ptr = (struct global_data *)top; #ifdef _USE_MEMCPY memset(gd_ptr, '\0', sizeof(*gd)); #else for (ptr = (int *)gd_ptr; ptr < (int *)(gd_ptr + 1); ) *ptr++ = 0; #endif - arch_setup_gd(gd_ptr); +} +ulong board_init_f_malloc_size(void) +{ #if defined(CONFIG_SYS_MALLOC_F) && \ (!defined(CONFIG_SPL_BUILD) || !defined(CONFIG_SYS_SPL_MALLOC_START)) - top -= CONFIG_SYS_MALLOC_F_LEN; - gd->malloc_base = top; + return CONFIG_SYS_MALLOC_F_LEN; +#else + return 0; #endif +} - return top; +void board_init_f_malloc(ulong malloc_base) +{ +#if defined(CONFIG_SYS_MALLOC_F) && \ + (!defined(CONFIG_SPL_BUILD) || !defined(CONFIG_SYS_SPL_MALLOC_START)) + gd->malloc_base = malloc_base; +#endif } diff --git a/include/common.h b/include/common.h index 09a131d..a2d81d9 100644 --- a/include/common.h +++ b/include/common.h @@ -225,32 +225,44 @@ void board_init_f(ulong); void board_init_r(gd_t *, ulong) __attribute__ ((noreturn)); /** - * board_init_f_mem() - Allocate global data and set stack position + * board_init_f_gd_size() - Return the size of the global data * * This function is called by each architecture very early in the start-up - * code to set up the environment for board_init_f(). It allocates space for - * global_data (see include/asm-generic/global_data.h) and places the stack - * below this. + * code to allow the C runtime to reserve space for the GD on the stack. * - * This function requires a stack[1] Normally this is at @top. The function - * starts allocating space from 64 bytes below @top. First it creates space - * for global_data. Then it calls arch_setup_gd() which sets gd to point to - * the global_data space and can reserve additional bytes of space if - * required). Finally it allocates early malloc() memory - * (CONFIG_SYS_MALLOC_F_LEN). The new top of the stack is just below this, - * and it returned by this function. + * @return: GD size + */ +ulong board_init_f_gd_size(void); + +/** + * board_init_f_gd() - Initialize (zero) the global data + * + * This function is called once the C runtime has allocated the GD on + * the stack. It must initialize the GD. + * + * @gd_ptr: the pointer to the GD to initialize + */ +void board_init_f_gd(struct global_data *gd_ptr); + +/** + * board_init_f_malloc_size() - Return the size of the malloc arena + * + * This function is called once the GD is initialized, to allow the C + * runtime to allocate the malloc arena on the stack. + * + * @return: Malloc arena size + */ +ulong board_init_f_malloc_size(void); + +/** + * board_init_f_malloc() - Mark the malloc arena base in the global data * - * [1] Strictly speaking it would be possible to implement this function - * in C on many archs such that it does not require a stack. However this - * does not seem hugely important as only 64 byte are wasted. The 64 bytes - * are used to handle the calling standard which generally requires pushing - * addresses or registers onto the stack. We should be able to get away with - * less if this becomes important. + * This function is called once the malloc arena is allocated on the + * stack. It marks the malloc arena base in the global data. * - * @top: Top of available memory, also normally the top of the stack - * @return: New stack location + * @malloc_base: the base of the malloc arena */ -ulong board_init_f_mem(ulong top); +void board_init_f_malloc(ulong malloc_base); /** * arch_setup_gd() - Set up the global_data pointer -- 2.5.0 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot