From: Tom Rini Date: Wed, 22 Aug 2012 22:31:05 +0000 (-0700) Subject: SPL: Create arch/arm/lib/spl.c for board_init_f and jump_to_image_linux X-Git-Tag: v2012.10-rc2~26 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=6507f133f3201ed5fb22e4a3d73c33b47497539d;p=oweals%2Fu-boot.git SPL: Create arch/arm/lib/spl.c for board_init_f and jump_to_image_linux In SPL (CONFIG_SPL_FRAMEWORK) board_init_f must setup the stack pointer, clear the BSS and call board_init_r. We mark this as weak as some platforms may need to perform additional initalization at this point. We provide a gd that we know will be in a usable location, once the BSS has been cleared to help with this as well. Finally, we no longer call relocate_code so remove that from the armv7 version. Next, both board_init_f and jump_to_image_linux are going to be inherently arch-specific, so move these versions to arch/arm/lib/spl.c Signed-off-by: Tom Rini --- diff --git a/arch/arm/cpu/armv7/am33xx/board.c b/arch/arm/cpu/armv7/am33xx/board.c index c45b19b913..978b184fb2 100644 --- a/arch/arm/cpu/armv7/am33xx/board.c +++ b/arch/arm/cpu/armv7/am33xx/board.c @@ -166,6 +166,8 @@ void s_init(void) regVal |= UART_SMART_IDLE_EN; writel(regVal, &uart_base->uartsyscfg); + gd = &gdata; + preloader_console_init(); /* Initalize the board header */ diff --git a/arch/arm/cpu/armv7/omap-common/hwinit-common.c b/arch/arm/cpu/armv7/omap-common/hwinit-common.c index ad8b5acce1..9ef10bdf2d 100644 --- a/arch/arm/cpu/armv7/omap-common/hwinit-common.c +++ b/arch/arm/cpu/armv7/omap-common/hwinit-common.c @@ -124,6 +124,9 @@ void s_init(void) set_mux_conf_regs(); #ifdef CONFIG_SPL_BUILD setup_clocks_for_console(); + + gd = &gdata; + preloader_console_init(); do_io_settings(); #endif diff --git a/arch/arm/cpu/armv7/omap3/board.c b/arch/arm/cpu/armv7/omap3/board.c index 42e2fd9198..9cee1d9b49 100644 --- a/arch/arm/cpu/armv7/omap3/board.c +++ b/arch/arm/cpu/armv7/omap3/board.c @@ -45,6 +45,8 @@ #include #include +DECLARE_GLOBAL_DATA_PTR; + /* Declarations */ extern omap3_sysinfo sysinfo; static void omap3_setup_aux_cr(void); @@ -252,6 +254,8 @@ void s_init(void) #endif #ifdef CONFIG_SPL_BUILD + gd = &gdata; + preloader_console_init(); timer_init(); diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S index 32658eb7a5..f26308df16 100644 --- a/arch/arm/cpu/armv7/start.S +++ b/arch/arm/cpu/armv7/start.S @@ -164,6 +164,7 @@ call_board_init_f: /*------------------------------------------------------------------------------*/ +#ifndef CONFIG_SPL_BUILD /* * void relocate_code (addr_sp, gd, addr_moni) * @@ -194,7 +195,6 @@ copy_loop: cmp r0, r2 /* until source end address [r2] */ blo copy_loop -#ifndef CONFIG_SPL_BUILD /* * fix .rel.dyn relocations */ @@ -241,20 +241,12 @@ _rel_dyn_end_ofs: _dynsym_start_ofs: .word __dynsym_start - _start -#endif /* #ifndef CONFIG_SPL_BUILD */ - clear_bss: -#ifdef CONFIG_SPL_BUILD - /* No relocation for SPL */ - ldr r0, =__bss_start - ldr r1, =__bss_end__ -#else ldr r0, _bss_start_ofs ldr r1, _bss_end_ofs mov r4, r6 /* reloc addr */ add r0, r0, r4 add r1, r1, r4 -#endif mov r2, #0x00000000 /* clear */ clbss_l:cmp r0, r1 /* clear loop... */ @@ -281,12 +273,10 @@ jump_2_ram: * Move vector table */ #if !defined(CONFIG_TEGRA20) -#if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD)) /* Set vector address in CP15 VBAR register */ ldr r0, =_start add r0, r0, r9 mcr p15, 0, r0, c12, c0, 0 @Set VBAR -#endif #endif /* !Tegra20 */ ldr r0, _board_init_r_ofs @@ -302,6 +292,7 @@ jump_2_ram: _board_init_r_ofs: .word board_init_r - _start ENDPROC(relocate_code) +#endif /************************************************************************* * diff --git a/arch/arm/include/asm/spl.h b/arch/arm/include/asm/spl.h index ad619905ac..62011aaada 100644 --- a/arch/arm/include/asm/spl.h +++ b/arch/arm/include/asm/spl.h @@ -26,4 +26,9 @@ /* Platform-specific defines */ #include +/* Linker symbols. */ +extern char __bss_start[], __bss_end__[]; + +extern gd_t gdata; + #endif diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index bd3b77f2e6..3422ac1c5f 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -44,6 +44,8 @@ COBJS-y += interrupts.o COBJS-y += reset.o SOBJS-$(CONFIG_USE_ARCH_MEMSET) += memset.o SOBJS-$(CONFIG_USE_ARCH_MEMCPY) += memcpy.o +else +COBJS-$(CONFIG_SPL_FRAMEWORK) += spl.o endif COBJS-y += cache.o diff --git a/arch/arm/lib/spl.c b/arch/arm/lib/spl.c new file mode 100644 index 0000000000..f568f619cb --- /dev/null +++ b/arch/arm/lib/spl.c @@ -0,0 +1,72 @@ +/* + * (C) Copyright 2010-2012 + * Texas Instruments, + * + * Aneesh V + * Tom Rini + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#include +#include +#include +#include +#include + +/* Pointer to as well as the global data structure for SPL */ +DECLARE_GLOBAL_DATA_PTR; +gd_t gdata __attribute__ ((section(".data"))); + +/* + * In the context of SPL, board_init_f must ensure that any clocks/etc for + * DDR are enabled, ensure that the stack pointer is valid, clear the BSS + * and call board_init_f. We provide this version by default but mark it + * as __weak to allow for platforms to do this in their own way if needed. + */ +void __weak board_init_f(ulong dummy) +{ + /* Set the stack pointer. */ + asm volatile("mov sp, %0\n" : : "r"(CONFIG_SPL_STACK)); + + /* Clear the BSS. */ + memset(__bss_start, 0, __bss_end__ - __bss_start); + + /* Set global data pointer. */ + gd = &gdata; + + board_init_r(NULL, 0); +} + +/* + * This function jumps to an image with argument. Normally an FDT or ATAGS + * image. + * arg: Pointer to paramter image in RAM + */ +#ifdef CONFIG_SPL_OS_BOOT +void __noreturn jump_to_image_linux(void *arg) +{ + debug("Entering kernel arg pointer: 0x%p\n", arg); + typedef void (*image_entry_arg_t)(int, int, void *) + __attribute__ ((noreturn)); + image_entry_arg_t image_entry = + (image_entry_arg_t) spl_image.entry_point; + cleanup_before_linux(); + image_entry(0, CONFIG_MACH_TYPE, arg); +} +#endif diff --git a/common/spl/spl.c b/common/spl/spl.c index 1562f2a162..3f41014023 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -38,8 +38,7 @@ DECLARE_GLOBAL_DATA_PTR; u32 *boot_params_ptr = NULL; struct spl_image_info spl_image; -/* Define global data structure pointer to it*/ -static gd_t gdata __attribute__ ((section(".data"))); +/* Define board data structure */ static bd_t bdata __attribute__ ((section(".data"))); inline void hang(void) @@ -49,18 +48,6 @@ inline void hang(void) ; } -void board_init_f(ulong dummy) -{ - /* - * We call relocate_code() with relocation target same as the - * CONFIG_SYS_SPL_TEXT_BASE. This will result in relocation getting - * skipped. Instead, only .bss initialization will happen. That's - * all we need - */ - debug(">>board_init_f()\n"); - relocate_code(CONFIG_SPL_STACK, &gdata, CONFIG_SPL_TEXT_BASE); -} - /* * Default function to determine if u-boot or the OS should * be started. This implementation always returns 1. @@ -107,24 +94,6 @@ void spl_parse_image_header(const struct image_header *header) } } -/* - * This function jumps to an image with argument. Normally an FDT or ATAGS - * image. - * arg: Pointer to paramter image in RAM - */ -#ifdef CONFIG_SPL_OS_BOOT -static void __noreturn jump_to_image_linux(void *arg) -{ - debug("Entering kernel arg pointer: 0x%p\n", arg); - typedef void (*image_entry_arg_t)(int, int, void *) - __attribute__ ((noreturn)); - image_entry_arg_t image_entry = - (image_entry_arg_t) spl_image.entry_point; - cleanup_before_linux(); - image_entry(0, CONFIG_MACH_TYPE, arg); -} -#endif - static void __noreturn jump_to_image_no_args(void) { typedef void __noreturn (*image_entry_noargs_t)(u32 *); @@ -140,7 +109,7 @@ static void __noreturn jump_to_image_no_args(void) image_entry((u32 *)boot_params_ptr_addr); } -void board_init_r(gd_t *id, ulong dummy) +void board_init_r(gd_t *dummy1, ulong dummy2) { u32 boot_device; debug(">>spl:board_init_r()\n"); @@ -204,10 +173,12 @@ void board_init_r(gd_t *id, ulong dummy) } } -/* This requires UART clocks to be enabled */ +/* + * This requires UART clocks to be enabled. In order for this to work the + * caller must ensure that the gd pointer is valid. + */ void preloader_console_init(void) { - gd = &gdata; gd->bd = &bdata; gd->flags |= GD_FLG_RELOC; gd->baudrate = CONFIG_BAUDRATE; diff --git a/include/spl.h b/include/spl.h index af9ef71b01..2923cd2a8d 100644 --- a/include/spl.h +++ b/include/spl.h @@ -24,6 +24,7 @@ #define _SPL_H_ /* Platform-specific defines */ +#include #include /* Boot type */ @@ -48,6 +49,7 @@ u32 spl_boot_device(void); u32 spl_boot_mode(void); void spl_parse_image_header(const struct image_header *header); void spl_board_prepare_for_linux(void); +void __noreturn jump_to_image_linux(void *arg); int spl_start_uboot(void); void spl_display_print(void);