
--- arch/x86/cpu/start.S | 37 +++++++----------- arch/x86/include/asm/u-boot-x86.h | 1 + arch/x86/lib/board.c | 76 +++++++++++++++++++++++------------- 3 files changed, 64 insertions(+), 50 deletions(-)
diff --git a/arch/x86/cpu/start.S b/arch/x86/cpu/start.S index f87633b..be21d97 100644 --- a/arch/x86/cpu/start.S +++ b/arch/x86/cpu/start.S @@ -95,32 +95,25 @@ car_init_ret: movw $0x85, %ax jmp die
-.globl relocate_code -.type relocate_code, @function -relocate_code: +.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 + andl $~15, %eax + + /* Create a new stack */ + movl %eax, %esp + /* - * SDRAM has been initialised, U-Boot code has been copied into - * RAM, BSS has been cleared and relocation adjustments have been - * made. It is now time to jump into the in-RAM copy of U-Boot - * + * 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 + * %ecx = Base address of in-RAM copy of U-Boot (ignored) */ - - /* Setup stack in RAM */ - movl %eax, %esp - - /* Setup call address of in-RAM copy of board_init_r() */ - movl $board_init_r, %ebp - addl (GENERATED_GD_RELOC_OFF)(%edx), %ebp - - /* Setup parameters to board_init_r() */ - movl %edx, %eax - movl %ecx, %edx - - /* Jump to in-RAM copy of board_init_r() */ - call *%ebp + movl %eax, %edx + xorl %ecx, %ecx + call relocate_code
die: hlt diff --git a/arch/x86/include/asm/u-boot-x86.h b/arch/x86/include/asm/u-boot-x86.h index 755f88a..757a8ee 100644 --- a/arch/x86/include/asm/u-boot-x86.h +++ b/arch/x86/include/asm/u-boot-x86.h @@ -61,5 +61,6 @@ 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 ba6b59f..4736477 100644 --- a/arch/x86/lib/board.c +++ b/arch/x86/lib/board.c @@ -124,10 +124,10 @@ static void display_flash_config(ulong size) */ typedef int (init_fnc_t) (void);
-static int calculate_relocation_address(void); -static int copy_uboot_to_ram(void); -static int clear_bss(void); -static int do_elf_reloc_fixups(void); +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 *);
init_fnc_t *init_sequence_f[] = { cpu_init_f, @@ -137,10 +137,6 @@ init_fnc_t *init_sequence_f[] = { serial_init, console_init_f, dram_init_f, - calculate_relocation_address, - copy_uboot_to_ram, - clear_bss, - do_elf_reloc_fixups,
NULL, }; @@ -159,7 +155,7 @@ init_fnc_t *init_sequence_r[] = {
gd_t *gd;
-static int calculate_relocation_address(void) +static int calculate_relocation_address(gd_t *id) { ulong text_start = (ulong)&__text_start; ulong bss_end = (ulong)&__bss_end; @@ -167,7 +163,7 @@ static int calculate_relocation_address(void) ulong rel_offset;
/* Calculate destination RAM Address and relocation offset */ - dest_addr = gd->ram_size; + dest_addr = id->start_addr_sp; dest_addr -= CONFIG_SYS_STACK_SIZE; dest_addr -= (bss_end - text_start);
@@ -179,33 +175,32 @@ static int calculate_relocation_address(void)
rel_offset = dest_addr - text_start;
- gd->start_addr_sp = gd->ram_size; - gd->relocaddr = dest_addr; - gd->reloc_off = rel_offset; + id->relocaddr = dest_addr; + id->reloc_off = rel_offset;
return 0; }
-static int copy_uboot_to_ram(void) +static int copy_uboot_to_ram(gd_t *id) { - size_t len = (size_t)(&__data_end) - (size_t)(&__text_start); + size_t len = (size_t)&__data_end - (size_t)&__text_start;
- memcpy((void *)gd->relocaddr, (void *)&__text_start, len); + memcpy((void *)id->relocaddr, (void *)&__text_start, len);
return 0; }
-static int clear_bss(void) +static int clear_bss(gd_t *id) { - ulong dst_addr = (ulong)(&__bss_start) + gd->reloc_off; - size_t len = (size_t)(&__bss_end) - (size_t)(&__bss_start); + ulong dst_addr = (ulong)&__bss_start + id->reloc_off; + size_t len = (size_t)&__bss_end - (size_t)&__bss_start;
memset((void *)dst_addr, 0x00, len);
return 0; }
-static int do_elf_reloc_fixups(void) +static 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); @@ -225,13 +220,13 @@ static int do_elf_reloc_fixups(void)
/* Switch to the in-RAM version */ offset_ptr_ram = (Elf32_Addr *)((ulong)offset_ptr_rom + - gd->reloc_off); + id->reloc_off);
/* Check that the target points into .text */ if (*offset_ptr_ram >= CONFIG_SYS_TEXT_BASE && *offset_ptr_ram < (CONFIG_SYS_TEXT_BASE + size)) { - *offset_ptr_ram += gd->reloc_off; + *offset_ptr_ram += id->reloc_off; } } } while (re_src++ < re_end); @@ -251,10 +246,35 @@ void board_init_f(ulong boot_flags) hang(); }
- gd->flags |= GD_FLG_RELOC; + /* SDRAM is now initialised setup a new stack in SDRAM */ + setup_sdram_environment(gd->ram_size, GENERATED_GBL_DATA_SIZE); + + /* NOTREACHED - relocate_code() does not return */ + while (1) + ; +}
- /* Enter the relocated U-Boot! */ - relocate_code(gd->start_addr_sp, gd, gd->relocaddr); +typedef void (board_init_r_t) (gd_t *, ulong); + +void relocate_code(ulong stack_ptr, gd_t *id, ulong reloc_addr) +{ + 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)); + + id->start_addr_sp = stack_ptr; + + 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) @@ -270,14 +290,14 @@ void board_init_r(gd_t *id, ulong dest_addr) ulong size; #endif static bd_t bd_data; - static gd_t gd_data; init_fnc_t **init_fnc_ptr;
show_boot_progress(0x21);
/* Global data pointer is now writable */ - gd = &gd_data; - memcpy(gd, id, sizeof(gd_t)); + gd = id; + + gd->flags |= GD_FLG_RELOC;
/* compiler optimization barrier needed for GCC >= 3.4 */ __asm__ __volatile__("" : : : "memory");