Hi Albert, On 9 November 2015 at 17:20, Albert ARIBAUD <albert.u.b...@aribaud.net> wrote: > board_init_f_mem() alters the C runtime environment's > stack it ls actually already using. This is not a valid > C runtime environment and may conflict with the C compiler's > expectations. > > Split board_init_f_mem into C functions which do not > alter their own stack and therefore function in a valid C > runtime environment. > > NOTE: this has not been tested with all architectures. > > Signed-off-by: Albert ARIBAUD <albert.u.b...@aribaud.net> > --- > arch/arc/lib/start.S | 20 +++++++++++++--- > arch/arm/lib/crt0.S | 10 ++++++-- > arch/arm/lib/crt0_64.S | 12 +++++++--- > 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 | 2 +- > common/init/board_init.c | 33 +++++++++++++++----------- > include/common.h | 52 > +++++++++++++++++++++++++---------------- > 10 files changed, 126 insertions(+), 52 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 > +
I'm hoping we don't have to bring back this assembler. Do we really need to put everything in separate functions? Perhaps you could add a bit more detail in the commit message as to what problem this solves? > /* 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..e716889 100644 > --- a/arch/arm/lib/crt0_64.S > +++ b/arch/arm/lib/crt0_64.S > @@ -75,9 +75,15 @@ 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, x0 > + mov x0, sp > + bl board_init_f_gd > + bl board_init_f_malloc_size > + sub 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..4d5f0b0 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_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_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..cd7fd86 100644 > --- a/arch/x86/lib/fsp/fsp_common.c > +++ b/arch/x86/lib/fsp/fsp_common.c > @@ -95,7 +95,7 @@ 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, > + * 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..1313138 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; > + (!defined(CONFIG_SPL_BUILD) || !defined(CONFIG_SYS_SPL_MALLOC_START)) > + 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..dbc2808 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. > + * > + * @return: GD size > + */ > +ulong board_init_f_gd_size(void); > + > +/** > + * board_init_f_gd() - Initialize (zero) the global data > * > - * 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. > + * 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 > * > - * [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 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 > * > - * @top: Top of available memory, also normally the top of the stack > - * @return: New stack location > + * This function is called once the malloc arena is allocated on the > + * stack. It marks the malloc arena base in the global data. > + * > + * @malloc_base: the base of the malloc arena > */ > -ulong board_init_f_mem(ulong top); > +ulong 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 Regards, Simon _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot