[U-Boot] [RFC][PATCH 11/19] cortexa8, beagle: add relocation support

Heiko Schocher hs at denx.de
Thu Jul 29 12:44:54 CEST 2010


Signed-off-by: Heiko Schocher <hs at denx.de>
---
 arch/arm/cpu/armv7/omap3/sdrc.c |   14 +++-
 arch/arm/cpu/armv7/start.S      |  174 +++++++++++++++++++++++++++-----------
 arch/arm/cpu/armv7/u-boot.lds   |   14 +++-
 board/ti/beagle/config.mk       |    2 +-
 include/configs/omap3_beagle.h  |    4 +
 5 files changed, 153 insertions(+), 55 deletions(-)

diff --git a/arch/arm/cpu/armv7/omap3/sdrc.c b/arch/arm/cpu/armv7/omap3/sdrc.c
index 96fd990..bfe4e1f 100644
--- a/arch/arm/cpu/armv7/omap3/sdrc.c
+++ b/arch/arm/cpu/armv7/omap3/sdrc.c
@@ -181,13 +181,23 @@ int dram_init(void)

 		size1 = get_sdr_cs_size(CS1);
 	}
+	gd->ram_size = size0 + size1;
+
+	return 0;
+}
+
+void dram_init_banksize (void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+	unsigned int size0 = 0, size1 = 0;
+
+	size0 = get_sdr_cs_size(CS0);
+	size1 = get_sdr_cs_size(CS1);

 	gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
 	gd->bd->bi_dram[0].size = size0;
 	gd->bd->bi_dram[1].start = PHYS_SDRAM_1 + get_sdr_cs_offset(CS1);
 	gd->bd->bi_dram[1].size = size1;
-
-	return 0;
 }

 /*
diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S
index 1e0a150..20c999f 100644
--- a/arch/arm/cpu/armv7/start.S
+++ b/arch/arm/cpu/armv7/start.S
@@ -65,13 +65,10 @@ _end_vect:
  *
  *************************************************************************/

+.globl _TEXT_BASE
 _TEXT_BASE:
 	.word	TEXT_BASE

-.globl _armboot_start
-_armboot_start:
-	.word _start
-
 /*
  * These are defined in the board-specific linker script.
  */
@@ -95,6 +92,35 @@ FIQ_STACK_START:
 	.word 0x0badc0de
 #endif

+/* IRQ stack memory (calculated at run-time) + 8 bytes */
+.globl IRQ_STACK_START_IN
+IRQ_STACK_START_IN:
+	.word	0x0badc0de
+
+.globl _datarel_start
+_datarel_start:
+	.word __datarel_start
+
+.globl _datarelrolocal_start
+_datarelrolocal_start:
+	.word __datarelrolocal_start
+
+.globl _datarellocal_start
+_datarellocal_start:
+	.word __datarellocal_start
+
+.globl _datarelro_start
+_datarelro_start:
+	.word __datarelro_start
+
+.globl _got_start
+_got_start:
+	.word __got_start
+
+.globl _got_end
+_got_end:
+	.word __got_end
+
 /*
  * the actual reset code
  */
@@ -136,51 +162,104 @@ next:
 	bl	cpu_init_crit
 #endif

-#ifndef CONFIG_SKIP_RELOCATE_UBOOT
-relocate:				@ relocate U-Boot to RAM
-	adr	r0, _start		@ r0 <- current position of code
-	ldr	r1, _TEXT_BASE		@ test if we run from flash or RAM
-	cmp	r0, r1			@ don't reloc during debug
-	beq	stack_setup
+/* Set stackpointer in internal RAM to call board_init_f */
+call_board_init_f:
+	ldr	sp, =(CONFIG_SYS_INIT_SP_ADDR)
+	ldr	r0,=0x00000000
+	bl	board_init_f

-	ldr	r2, _armboot_start
-	ldr	r3, _bss_start
-	sub	r2, r3, r2		@ r2 <- size of armboot
-	add	r2, r0, r2		@ r2 <- source end address
+/*------------------------------------------------------------------------------*/

-copy_loop:				@ copy 32 bytes at a time
-	ldmia	r0!, {r3 - r10}		@ copy from source address [r0]
-	stmia	r1!, {r3 - r10}		@ copy to   target address [r1]
-	cmp	r0, r2			@ until source end addreee [r2]
-	ble	copy_loop
-#endif	/* CONFIG_SKIP_RELOCATE_UBOOT */
-
-	/* Set up the stack */
+/*
+ * void relocate_code (addr_sp, gd, addr_moni)
+ *
+ * This "function" does not return, instead it continues in RAM
+ * after relocating the monitor code.
+ *
+ */
+	.globl	relocate_code
+relocate_code:
+	mov	r4, r0	/* save addr_sp */
+	mov	r5, r1	/* save addr of gd */
+	mov	r6, r2	/* save addr of destination */
+	mov	r7, r2	/* save addr of destination */
+
+	/* Set up the stack						    */
 stack_setup:
-	ldr	r0, _TEXT_BASE		@ upper 128 KiB: relocated uboot
-	sub	r0, r0, #CONFIG_SYS_MALLOC_LEN @ malloc area
-	sub	r0, r0, #CONFIG_SYS_GBL_DATA_SIZE @ bdinfo
-#ifdef CONFIG_USE_IRQ
-	sub	r0, r0, #(CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ)
+	mov	sp, r4
+
+#ifndef CONFIG_SKIP_RELOCATE_UBOOT
+	adr	r0, _start
+	ldr	r2, _TEXT_BASE
+	ldr	r3, _bss_start
+	sub	r2, r3, r2		/* r2 <- size of armboot	    */
+	add	r2, r0, r2		/* r2 <- source end address	    */
+	cmp	r0, r6
+#ifndef CONFIG_PRELOADER
+	beq	jump_2_ram
 #endif
-	sub	sp, r0, #12		@ leave 3 words for abort-stack
-	bic	sp, sp, #7		@ 8-byte alignment for ABI compliance

-	/* Clear BSS (if any). Is below tx (watch load addr - need space) */
-clear_bss:
-	ldr	r0, _bss_start		@ find start of bss segment
-	ldr	r1, _bss_end		@ stop here
-	mov	r2, #0x00000000		@ clear value
-clbss_l:
-	str	r2, [r0]		@ clear BSS location
-	cmp	r0, r1			@ are we at the end yet
-	add	r0, r0, #4		@ increment clear index pointer
-	bne	clbss_l			@ keep clearing till at end
+copy_loop:
+	ldmia	r0!, {r9-r10}		/* copy from source address [r0]    */
+	stmia	r6!, {r9-r10}		/* copy to   target address [r1]    */
+	cmp	r0, r2			/* until source end addreee [r2]    */
+	ble	copy_loop

-	ldr	pc, _start_armboot	@ jump to C code
+#ifndef CONFIG_PRELOADER
+	/* fix got entries */
+	ldr	r1, _TEXT_BASE
+	mov	r0, r7			/* reloc addr */
+	ldr	r2, _got_start		/* addr in Flash */
+	ldr	r3, _got_end		/* addr in Flash */
+	sub	r3, r3, r1
+	add	r3, r3, r0
+	sub	r2, r2, r1
+	add	r2, r2, r0
+
+fixloop:
+	ldr	r4, [r2]
+	sub	r4, r4, r1
+	add	r4, r4, r0
+	str	r4, [r2]
+	add	r2, r2, #4
+	cmp	r2, r3
+	bne	fixloop

-_start_armboot: .word start_armboot
+clear_bss:
+	ldr	r0, _bss_start
+	ldr	r1, _bss_end
+	ldr	r3, _TEXT_BASE		/* Text base */
+	mov	r4, r7			/* reloc addr */
+	sub	r0, r0, r3
+	add	r0, r0, r4
+	sub	r1, r1, r3
+	add	r1, r1, r4
+	mov	r2, #0x00000000		/* clear			    */
+
+clbss_l:str	r2, [r0]		/* clear loop...		    */
+	add	r0, r0, #4
+	cmp	r0, r1
+	bne	clbss_l
+#endif	/* #ifndef CONFIG_PRELOADER */
+#endif	/* #ifndef CONFIG_SKIP_RELOCATE_UBOOT */

+/*
+ * We are done. Do not return, instead branch to second part of board
+ * initialization, now running from RAM.
+ */
+jump_2_ram:
+	ldr	r0, _TEXT_BASE
+	ldr	r2, _board_init_r
+	sub	r2, r2, r0
+	add	r2, r2, r7	/* position from board_init_r in RAM */
+	/* setup parameters for board_init_r */
+	mov	r0, r5		/* gd_t */
+	mov	r1, r7		/* dest_addr */
+	/* jump to it ... */
+	mov	lr, r2
+	mov	pc, lr
+
+_board_init_r: .word board_init_r

 /*************************************************************************
  *
@@ -264,9 +343,7 @@ cpu_init_crit:
 	stmia	sp, {r0 - r12}			@ Save user registers (now in
 						@ svc mode) r0-r12

-	ldr	r2, _armboot_start
-	sub	r2, r2, #(CONFIG_SYS_MALLOC_LEN)
-	sub	r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE + 8)	@ set base 2 words into abort
+	ldr	r2, IRQ_STACK_START_IN		@ set base 2 words into abort
 						@ stack
 	ldmia	r2, {r2 - r3}			@ get values for "aborted" pc
 						@ and cpsr (into parm regs)
@@ -303,11 +380,8 @@ cpu_init_crit:
 	.endm

 	.macro get_bad_stack
-	ldr	r13, _armboot_start		@ setup our mode stack (enter
+	ldr	r13, IRQ_STACK_START_IN		@ setup our mode stack (enter
 						@ in banked mode)
-	sub	r13, r13, #(CONFIG_SYS_MALLOC_LEN)	@ move past malloc pool
-	sub	r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE + 8) @ move to reserved a couple
-						@ spots for abort stack

 	str	lr, [r13]			@ save caller lr in position 0
 						@ of saved stack
@@ -328,9 +402,7 @@ cpu_init_crit:
 	sub	r13, r13, #4			@ space on current stack for
 						@ scratch reg.
 	str	r0, [r13]			@ save R0's value.
-	ldr	r0, _armboot_start		@ get data regions start
-	sub	r0, r0, #(CONFIG_SYS_MALLOC_LEN)	@ move past malloc pool
-	sub	r0, r0, #(CONFIG_SYS_GBL_DATA_SIZE + 8)	@ move past gbl and a couple
+	ldr	r0, IRQ_STACK_START_IN		@ get data regions start
 						@ spots for abort stack
 	str	lr, [r0]			@ save caller lr in position 0
 						@ of saved stack
diff --git a/arch/arm/cpu/armv7/u-boot.lds b/arch/arm/cpu/armv7/u-boot.lds
index 9e5b5a9..d4fd3fc 100644
--- a/arch/arm/cpu/armv7/u-boot.lds
+++ b/arch/arm/cpu/armv7/u-boot.lds
@@ -42,10 +42,22 @@ SECTIONS
 	.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }

 	. = ALIGN(4);
-	.data : { *(.data) }
+	.data : {
+		*(.data)
+	__datarel_start = .;
+		*(.data.rel)
+	__datarelrolocal_start = .;
+		*(.data.rel.ro.local)
+	__datarellocal_start = .;
+		*(.data.rel.local)
+	__datarelro_start = .;
+		*(.data.rel.ro)
+	}

+	__got_start = .;
 	. = ALIGN(4);
 	.got : { *(.got) }
+	__got_end = .;

 	__u_boot_cmd_start = .;
 	.u_boot_cmd : { *(.u_boot_cmd) }
diff --git a/board/ti/beagle/config.mk b/board/ti/beagle/config.mk
index 879b2e2..6fb10e3 100644
--- a/board/ti/beagle/config.mk
+++ b/board/ti/beagle/config.mk
@@ -30,4 +30,4 @@
 # (mem base + reserved)

 # For use with external or internal boots.
-TEXT_BASE = 0x80e80000
+TEXT_BASE = 0x80008000
diff --git a/include/configs/omap3_beagle.h b/include/configs/omap3_beagle.h
index ae5a791..e10fb89 100644
--- a/include/configs/omap3_beagle.h
+++ b/include/configs/omap3_beagle.h
@@ -335,4 +335,8 @@ extern unsigned int boot_flash_sec;
 extern unsigned int boot_flash_type;
 #endif

+/* additions for new relocation code, must added to all boards */
+#define CONFIG_SYS_SDRAM_BASE		PHYS_SDRAM_1
+#define CONFIG_SYS_INIT_SP_ADDR		(LOW_LEVEL_SRAM_STACK - CONFIG_SYS_GBL_DATA_SIZE)
+
 #endif /* __CONFIG_H */
-- 
1.6.2.5

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany


More information about the U-Boot mailing list