
--- arch/x86/cpu/start.S | 43 ++++++++++-------- arch/x86/include/asm/init_helpers.h | 3 + arch/x86/include/asm/u-boot-x86.h | 2 - arch/x86/lib/board.c | 87 ++++++++++++++++++++++++++++++---- arch/x86/lib/init_helpers.c | 14 ++++++ arch/x86/lib/relocate.c | 43 ++--------------- include/common.h | 11 ++++- 7 files changed, 131 insertions(+), 72 deletions(-)
diff --git a/arch/x86/cpu/start.S b/arch/x86/cpu/start.S index be21d97..9cfd54d 100644 --- a/arch/x86/cpu/start.S +++ b/arch/x86/cpu/start.S @@ -30,7 +30,7 @@ #include <version.h> #include <asm/global_data.h> #include <asm/processor-flags.h> -#include <generated/asm-offsets.h> +#include <generated/generic-asm-offsets.h>
.section .text .code32 @@ -84,36 +84,41 @@ car_init_ret: */ movl $CONFIG_SYS_INIT_SP_ADDR, %esp
- /* Set parameter to board_init_f() to boot flags */ - xorl %eax, %eax - movw %bx, %ax + /* + * Any setting of Global Data member need to be done here + * NOTE: car_init must clear CAR so that Global Data is initialised + * to zero! + */
- /* Enter, U-boot! */ + /* + * Enter U-boot by calling: + * board_init_f(location_of_gd_in_temporary_memory) + */ + movl $CONFIG_SYS_INIT_GD_ADDR, %eax call board_init_f
/* indicate (lack of) progress */ movw $0x85, %ax jmp die
-.globl setup_sdram_environment -.type setup_sdram_environment, @function -setup_sdram_environment: - /* Leave room for Global Data - Round down to 16 byte boundary */ - subl %edx, %eax +.globl board_init_f_r_trampoline +.type board_init_f_r_trampoline, @function +board_init_f_r_trampoline: + /* + * %eax contains the upper address of usable RAM. Create a fresh + * stack in RAM. x86 stack grows down, global data sits immediately + * above the stack, so we have to leave enough room between the top + * of the stack and top of RAM for global data + */ + subl $GENERATED_GBL_DATA_SIZE, %eax andl $~15, %eax - - /* Create a new stack */ movl %eax, %esp
/* - * relocate_code(ulong stack_ptr, gd_t *id, ulong reloc_addr) - * %eax = Address of top of stack - * %edx = Address of Global Data - * %ecx = Base address of in-RAM copy of U-Boot (ignored) + * Re-enter U-Boot by calling: + * board_init_f_r(location_of_gd_in_RAM) */ - movl %eax, %edx - xorl %ecx, %ecx - call relocate_code + call board_init_f_r
die: hlt diff --git a/arch/x86/include/asm/init_helpers.h b/arch/x86/include/asm/init_helpers.h index 14ef11a..2d08834 100644 --- a/arch/x86/include/asm/init_helpers.h +++ b/arch/x86/include/asm/init_helpers.h @@ -28,6 +28,9 @@ int display_banner(void); int display_dram_config(void); int init_baudrate_f(void);
+int copy_gd_to_ram_f_r(gd_t *id); +int init_cache_f_r(gd_t *id); + int mem_malloc_init_r(void); int init_bd_struct_r(void); int flash_init_r(void); diff --git a/arch/x86/include/asm/u-boot-x86.h b/arch/x86/include/asm/u-boot-x86.h index eaa50cc..093ad11 100644 --- a/arch/x86/include/asm/u-boot-x86.h +++ b/arch/x86/include/asm/u-boot-x86.h @@ -63,6 +63,4 @@ u32 isa_map_rom(u32 bus_addr, int size); int video_bios_init(void); int video_init(void);
-void setup_sdram_environment(phys_size_t ram_size, ulong gd_size); - #endif /* _U_BOOT_I386_H_ */ diff --git a/arch/x86/lib/board.c b/arch/x86/lib/board.c index b06063a..05d362d 100644 --- a/arch/x86/lib/board.c +++ b/arch/x86/lib/board.c @@ -35,6 +35,7 @@ #include <watchdog.h> #include <stdio_dev.h> #include <asm/u-boot-x86.h> +#include <asm/relocate.h>
#include <asm/init_helpers.h> #include <asm/init_wrappers.h> @@ -51,12 +52,35 @@ DECLARE_GLOBAL_DATA_PTR = (gd_t *) (CONFIG_SYS_INIT_GD_ADDR); /* * Breath some life into the board... * - * Initialize an SMC for serial comms, and carry out some hardware - * tests. + * Getting the board up and running is a three-stage process: + * 1) Execute from Flash, SDRAM Uninitialised + * At this point, there is a limited amount of non-SDRAM memory + * (typically the CPU cache, but can also be SRAM or even a buffer of + * of some peripheral). This limited memory is used to hold the initial + * copy of the Global Data Structure and a temporary stack. * - * The first part of initialization is running from Flash memory; - * its main purpose is to initialize the RAM so that we - * can relocate the monitor code to RAM. + * The following is performed during this phase of execution: + * - Core low-level CPU initialisation + * - Console initialisation + * - SDRAM initialisation + * + * 2) Execute from Flash, SDRAM Initialised + * At this point we copy Global Data from the initial non-SDRAM + * memory and set up the permanent stack in SDRAM. The CPU cache is no + * longer being used as temporary memory, so we can now fully enable + * it. + * + * The following is performed during this phase of execution: + * - Create final stack in SDRAM + * - Copy Global Data from temporary memory to SDRAM + * - Enabling of CPU cache(s), + * - Copying of U-Boot code and data from Flash to RAM + * - Clearing of the BSS + * - ELF relocation adjustments + * + * 3) Execute from SDRAM + * The following is performed during this phase of execution: + * - All remaining initialisation */
/* @@ -72,6 +96,7 @@ DECLARE_GLOBAL_DATA_PTR = (gd_t *) (CONFIG_SYS_INIT_GD_ADDR); * "continue" and != 0 means "fatal error, hang the system". */ typedef int (init_fnc_t) (void); +typedef int (init_fnc_gd_t) (gd_t *);
init_fnc_t *init_sequence_f[] = { cpu_init_f, @@ -85,6 +110,18 @@ init_fnc_t *init_sequence_f[] = { NULL, };
+init_fnc_gd_t *init_sequence_f_r[] = { + copy_gd_to_ram_f_r, + init_cache_f_r, + calculate_relocation_address, + copy_uboot_to_ram, + clear_bss, + do_elf_reloc_fixups, + + NULL, +}; + + init_fnc_t *init_sequence_r[] = { init_bd_struct_r, mem_malloc_init_r, @@ -161,15 +198,28 @@ static void do_init_loop(init_fnc_t **init_fnc_ptr) } }
+static void do_init_loop_gt(init_fnc_gd_t **init_fnc_ptr, gd_t *id) +{ + for (; *init_fnc_ptr; ++init_fnc_ptr) { + WATCHDOG_RESET(); + if ((*init_fnc_ptr)(id) != 0) + hang(); + } +} + /* Perform all steps necessary to get RAM initialised ready for relocation */ -void board_init_f(ulong boot_flags) +void board_init_f(gd_t *id) { - gd->flags = boot_flags; + /* + * NOTE: The gd_t pointer parameter is not used, but should be, in + * future, passed to the init_xxx_f functions which would + * allow the DECLARE_GLOBAL_DATA_PTR 'hack' to be removed + */
do_init_loop(init_sequence_f);
/* - * SDRAM is now initialised setup a new stack in SDRAM + * SDRAM is now initialised - setup the final stack in SDRAM * * Code execution will continue in Flash, but with the stack * in SDRAM. This allows us to copy global data out of the CPU @@ -177,14 +227,29 @@ void board_init_f(ulong boot_flags) * enable caching for the copy operation (which speeds it up * considerably) */ - setup_sdram_environment(gd->ram_size, GENERATED_GBL_DATA_SIZE); + board_init_f_r_trampoline(gd->ram_size); + + /* NOTREACHED - board_init_f_r_trampoline() does not return */ + while (1) + ; +} + +void board_init_f_r(gd_t *id) +{ + do_init_loop_gt(init_sequence_f_r, id); + + /* + * Transfer execution from Flash to RAM by calculating the address + * of the in-RAM copy of board_init_r() and calling it + */ + (board_init_r + id->reloc_off)(id);
- /* NOTREACHED - setup_sdram_environment() does not return */ + /* NOTREACHED - board_init_r() does not return */ while (1) ; }
-void board_init_r(gd_t *id, ulong dest_addr) +void board_init_r(gd_t *id) { /* Global data pointer is now writable */ gd = id; diff --git a/arch/x86/lib/init_helpers.c b/arch/x86/lib/init_helpers.c index a589fd3..c932812 100644 --- a/arch/x86/lib/init_helpers.c +++ b/arch/x86/lib/init_helpers.c @@ -70,6 +70,20 @@ int init_baudrate_f(void) return 0; }
+ +int copy_gd_to_ram_f_r(gd_t *id) +{ + memcpy(id, gd, sizeof(gd_t)); + + return 0; +} + +int init_cache_f_r(gd_t *id) +{ + /* Initialise the CPU cache(s) */ + return init_cache(); +} + int mem_malloc_init_r(void) { mem_malloc_init(((gd->relocaddr - CONFIG_SYS_MALLOC_LEN)+3)&~3, diff --git a/arch/x86/lib/relocate.c b/arch/x86/lib/relocate.c index f8c0b3f..cbce22b 100644 --- a/arch/x86/lib/relocate.c +++ b/arch/x86/lib/relocate.c @@ -34,14 +34,10 @@ #include <common.h> #include <malloc.h> #include <asm/u-boot-x86.h> +#include <asm/relocate.h> #include <elf.h>
-static int calculate_relocation_address(gd_t *); -static int copy_uboot_to_ram(gd_t *); -static int clear_bss(gd_t *); -static int do_elf_reloc_fixups(gd_t *); - -static int calculate_relocation_address(gd_t *id) +int calculate_relocation_address(gd_t *id) { ulong text_start = (ulong)&__text_start; ulong bss_end = (ulong)&__bss_end; @@ -67,7 +63,7 @@ static int calculate_relocation_address(gd_t *id) return 0; }
-static int copy_uboot_to_ram(gd_t *id) +int copy_uboot_to_ram(gd_t *id) { size_t len = (size_t)&__data_end - (size_t)&__text_start;
@@ -76,7 +72,7 @@ static int copy_uboot_to_ram(gd_t *id) return 0; }
-static int clear_bss(gd_t *id) +int clear_bss(gd_t *id) { ulong dst_addr = (ulong)&__bss_start + id->reloc_off; size_t len = (size_t)&__bss_end - (size_t)&__bss_start; @@ -86,7 +82,7 @@ static int clear_bss(gd_t *id) return 0; }
-static int do_elf_reloc_fixups(gd_t *id) +int do_elf_reloc_fixups(gd_t *id) { Elf32_Rel *re_src = (Elf32_Rel *)(&__rel_dyn_start); Elf32_Rel *re_end = (Elf32_Rel *)(&__rel_dyn_end); @@ -119,32 +115,3 @@ static int do_elf_reloc_fixups(gd_t *id)
return 0; } - -typedef void (board_init_r_t) (gd_t *, ulong); - -__attribute__ ((__noreturn__)) -void relocate_code(ulong dummy_1, gd_t *id, ulong dummy_2) -{ - board_init_r_t *board_init_r_func; - - /* We are running from flash, but the stack is now in SDRAM */ - - /* gd is still in CAR - Copy it into SDRAM */ - memcpy(id, gd, sizeof(gd_t)); - - if (init_cache() != 0) - hang(); - - calculate_relocation_address(id); - copy_uboot_to_ram(id); - clear_bss(id); - do_elf_reloc_fixups(id); - - board_init_r_func = board_init_r; - board_init_r_func += id->reloc_off; - board_init_r_func(id, id->relocaddr); - - /* NOTREACHED - relocate_code() does not return */ - while (1) - ; -} diff --git a/include/common.h b/include/common.h index 05a658c..4ef2a80 100644 --- a/include/common.h +++ b/include/common.h @@ -275,8 +275,15 @@ int abortboot(int bootdelay); extern char console_buffer[];
/* arch/$(ARCH)/lib/board.c */ -void board_init_f (ulong) __attribute__ ((noreturn)); -void board_init_r (gd_t *, ulong) __attribute__ ((noreturn)); +#ifndef CONFIG_X86 /* Horrible Hack */ +void board_init_f (ulong) __attribute__ ((noreturn)); +void board_init_r (gd_t *, ulong) __attribute__ ((noreturn)); +#else +void board_init_f(gd_t *) __attribute__ ((noreturn)); +void board_init_f_r_trampoline(ulong) __attribute__ ((noreturn)); +void board_init_f_r(gd_t *) __attribute__ ((noreturn)); +void board_init_r(gd_t *) __attribute__ ((noreturn)); +#endif int checkboard (void); int checkflash (void); int checkdram (void);