x86: Defer setup of final stack
diff --git a/arch/i386/cpu/start.S b/arch/i386/cpu/start.S
index 95be5a2..77f0332 100644
--- a/arch/i386/cpu/start.S
+++ b/arch/i386/cpu/start.S
@@ -96,21 +96,6 @@
/* size memory */
call dram_init_f
- /* Setup stack in SDRAM */
- movl (GD_RAM_SIZE * 4)(%ebp), %esp
-
- /* Test the stack */
- pushl $0
- popl %ecx
- cmpl $0, %ecx
- jne die
- push $0x55aa55aa
- popl %ecx
- cmpl $0x55aa55aa, %ecx
- jne die
-
- wbinvd
-
/* Set parameter to board_init_f() to boot flags */
movl (GD_FLAGS * 4)(%ebp), %eax
@@ -118,6 +103,35 @@
/* indicate (lack of) progress */
movw $0x85, %ax
+ jmp die
+
+.globl relocate_code
+.type relocate_code, @function
+relocate_code:
+ /*
+ * 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
+ *
+ * %eax = Address of top of stack
+ * %edx = Address of Global Data
+ * %ecx = Base address of in-RAM copy of U-Boot
+ */
+
+ /* Setup stack in RAM */
+ movl %eax, %esp
+
+ /* Setup call address of in-RAM copy of board_init_r() */
+ movl $board_init_r, %ebp
+ subl (GD_RELOC_OFF * 4)(%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
+
die: hlt
jmp die
hlt
diff --git a/arch/i386/lib/board.c b/arch/i386/lib/board.c
index d716232..60fa982 100644
--- a/arch/i386/lib/board.c
+++ b/arch/i386/lib/board.c
@@ -189,6 +189,7 @@
ulong *src_addr;
ulong *end_addr;
+ void *addr_sp;
void *dest_addr;
ulong rel_offset;
Elf32_Rel *re_src;
@@ -198,6 +199,7 @@
/* Calculate destination RAM Address and relocation offset */
dest_addr = (void *)gd->ram_size;
+ addr_sp = dest_addr;
dest_addr -= CONFIG_SYS_STACK_SIZE;
dest_addr -= (bss_end - text_start);
rel_offset = text_start - dest_addr;
@@ -242,9 +244,9 @@
gd->flags |= GD_FLG_RELOC;
/* Enter the relocated U-Boot! */
- (board_init_r - rel_offset)(gd, (ulong)dest_addr);
+ relocate_code((ulong)addr_sp, gd, (ulong)dest_addr);
- /* NOTREACHED - board_init_f() does not return */
+ /* NOTREACHED - relocate_code() does not return */
while(1);
}