diff mbox

[U-Boot,RFC,03/14] x86: Allow cache before copy to RAM

Message ID 1324643151-23642-4-git-send-email-graeme.russ@gmail.com
State Superseded
Delegated to: Graeme Russ
Headers show

Commit Message

Graeme Russ Dec. 23, 2011, 12:25 p.m. UTC
---
 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 mbox

Patch

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");