diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index d74e4b8..da8ed72 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -35,6 +35,7 @@ endif obj-$(CONFIG_SEMIHOSTING) += semihosting.o obj-y += sections.o +obj-y += stack.o ifdef CONFIG_ARM64 obj-y += gic_64.o obj-y += interrupts_64.o diff --git a/arch/arm/lib/stack.c b/arch/arm/lib/stack.c new file mode 100644 index 0000000..cf10a53 --- /dev/null +++ b/arch/arm/lib/stack.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2015 Andreas Bießmann + * + * Copyright (c) 2011 The Chromium OS Authors. + * (C) Copyright 2002-2006 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include + +DECLARE_GLOBAL_DATA_PTR; + +int arch_reserve_stacks(void) +{ +#ifdef CONFIG_SPL_BUILD + gd->start_addr_sp -= 128; /* leave 32 words for abort-stack */ + gd->irq_sp = gd->start_addr_sp; +#else + /* setup stack pointer for exceptions */ + gd->irq_sp = gd->start_addr_sp; + +# if !defined(CONFIG_ARM64) +# ifdef CONFIG_USE_IRQ + gd->start_addr_sp -= (CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ); + debug("Reserving %zu Bytes for IRQ stack at: %08lx\n", + CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ, gd->start_addr_sp); + + /* 8-byte alignment for ARM ABI compliance */ + gd->start_addr_sp &= ~0x07; +# endif + /* leave 3 words for abort-stack, plus 1 for alignment */ + gd->start_addr_sp -= 16; +# endif +#endif + + return 0; +} diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile index 0f62982..05b22bb 100644 --- a/arch/powerpc/lib/Makefile +++ b/arch/powerpc/lib/Makefile @@ -40,6 +40,7 @@ obj-y += extable.o obj-y += interrupts.o obj-$(CONFIG_CMD_KGDB) += kgdb.o obj-$(CONFIG_CMD_IDE) += ide.o +obj-y += stack.o obj-y += time.o # Don't include the MPC5xxx special memcpy into the diff --git a/arch/powerpc/lib/stack.c b/arch/powerpc/lib/stack.c new file mode 100644 index 0000000..1985f03 --- /dev/null +++ b/arch/powerpc/lib/stack.c @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2015 Andreas Bießmann + * + * Copyright (c) 2011 The Chromium OS Authors. + * (C) Copyright 2002-2006 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include + +DECLARE_GLOBAL_DATA_PTR; + +int arch_reserve_stacks(void) +{ + ulong *s; + + /* setup stack pointer for exceptions */ + gd->irq_sp = gd->start_addr_sp; + + /* Clear initial stack frame */ + s = (ulong *)gd->start_addr_sp; + *s = 0; /* Terminate back chain */ + *++s = 0; /* NULL return address */ + + return 0; +} diff --git a/common/board_f.c b/common/board_f.c index 2c10215..ef3f036 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -573,48 +573,22 @@ static int reserve_fdt(void) return 0; } -static int reserve_stacks(void) +int arch_reserve_stacks(void) { -#ifdef CONFIG_SPL_BUILD -# ifdef CONFIG_ARM - gd->start_addr_sp -= 128; /* leave 32 words for abort-stack */ - gd->irq_sp = gd->start_addr_sp; -# endif -#else -# ifdef CONFIG_PPC - ulong *s; -# endif + return 0; +} - /* setup stack pointer for exceptions */ +static int reserve_stacks(void) +{ + /* make stack pointer 16-byte aligned */ gd->start_addr_sp -= 16; gd->start_addr_sp &= ~0xf; - gd->irq_sp = gd->start_addr_sp; /* - * Handle architecture-specific things here - * TODO(sjg@chromium.org): Perhaps create arch_reserve_stack() - * to handle this and put in arch/xxx/lib/stack.c + * let the architecture specific code tailor gd->start_addr_sp and + * gd->irq_sp */ -# if defined(CONFIG_ARM) && !defined(CONFIG_ARM64) -# ifdef CONFIG_USE_IRQ - gd->start_addr_sp -= (CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ); - debug("Reserving %zu Bytes for IRQ stack at: %08lx\n", - CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ, gd->start_addr_sp); - - /* 8-byte alignment for ARM ABI compliance */ - gd->start_addr_sp &= ~0x07; -# endif - /* leave 3 words for abort-stack, plus 1 for alignment */ - gd->start_addr_sp -= 16; -# elif defined(CONFIG_PPC) - /* Clear initial stack frame */ - s = (ulong *) gd->start_addr_sp; - *s = 0; /* Terminate back chain */ - *++s = 0; /* NULL return address */ -# endif /* Architecture specific code */ - - return 0; -#endif + return arch_reserve_stacks(); } static int display_new_sp(void) diff --git a/include/common.h b/include/common.h index 9129454..77c55c6 100644 --- a/include/common.h +++ b/include/common.h @@ -253,6 +253,24 @@ int update_flash_size(int flash_size); int arch_early_init_r(void); /** + * Reserve all necessary stacks + * + * This is used in generic board init sequence in common/board_f.c. Each + * architecture could provide this function to tailor the required stacks. + * + * On entry gd->start_addr_sp is pointing to the suggested top of the stack. + * The callee ensures gd->start_add_sp is 16-byte aligned, so architectures + * require only this can leave it untouched. + * + * On exit gd->start_addr_sp and gd->irq_sp should be set to the respective + * positions of the stack. The stack pointer(s) will be set to this later. + * gd->irq_sp is only required, if the architecture needs it. + * + * @return 0 if no error + */ +__weak int arch_reserve_stacks(void); + +/** * Show the DRAM size in a board-specific way * * This is used by boards to display DRAM information in their own way.