[U-Boot] [RFC][PATCH 04/19] arm, arm1136, qong: add relocation support

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


Signed-off-by: Heiko Schocher <hs at denx.de>
---
 arch/arm/config.mk                 |    3 +
 arch/arm/cpu/arm1136/start.S       |  176 ++++++++++++++------
 arch/arm/cpu/arm1136/u-boot.lds    |   14 ++-
 arch/arm/include/asm/config.h      |    3 -
 arch/arm/include/asm/global_data.h |    6 +
 arch/arm/include/asm/u-boot-arm.h  |    8 +-
 arch/arm/lib/board.c               |  315 ++++++++++++++++++++++++++++++------
 arch/arm/lib/interrupts.c          |   15 ++-
 board/davedenx/qong/config.mk      |    4 +-
 board/davedenx/qong/qong.c         |   92 ++++++-----
 common/cmd_bdinfo.c                |    1 +
 common/cmd_bmp.c                   |    6 +
 common/cmd_i2c.c                   |    6 +
 include/configs/qong.h             |    9 +
 nand_spl/nand_boot.c               |    5 +
 nand_spl/nand_boot_fsl_nfc.c       |    5 +
 16 files changed, 519 insertions(+), 149 deletions(-)

diff --git a/arch/arm/config.mk b/arch/arm/config.mk
index e10dafc..be79f50 100644
--- a/arch/arm/config.mk
+++ b/arch/arm/config.mk
@@ -33,6 +33,9 @@ STANDALONE_LOAD_ADDR = 0xc100000
 endif
 endif

+# needed for relocation
+PLATFORM_RELFLAGS += -fPIC
+
 PLATFORM_CPPFLAGS += -DCONFIG_ARM -D__ARM__

 # Explicitly specifiy 32-bit ARM ISA since toolchain default can be -mthumb:
diff --git a/arch/arm/cpu/arm1136/start.S b/arch/arm/cpu/arm1136/start.S
index 41eb82d..68ee309 100644
--- a/arch/arm/cpu/arm1136/start.S
+++ b/arch/arm/cpu/arm1136/start.S
@@ -85,13 +85,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.
  */
@@ -103,6 +100,30 @@ _bss_start:
 _bss_end:
 	.word _end

+.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
+
 #ifdef CONFIG_USE_IRQ
 /* IRQ stack memory (calculated at run-time) */
 .globl IRQ_STACK_START
@@ -115,6 +136,11 @@ 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
+
 /*
  * the actual reset code
  */
@@ -151,65 +177,119 @@ 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	    */
-#ifndef CONFIG_PRELOADER
-	beq	stack_setup
-#endif	/* CONFIG_PRELOADER */
+/* Set stackpointer in internal RAM to call board_init_f */
+call_board_init_f:
+	ldr	sp, =(CONFIG_SYS_INIT_SP_ADDR)
+	ldr	r0,=0x00000000
+
+#ifdef CONFIG_NAND_SPL
+	bl	nand_boot
+#else
+#ifdef CONFIG_ONENAND_IPL
+	bl	start_oneboot
+#else
+	bl	board_init_f
+#endif /* CONFIG_ONENAND_IPL */
+#endif /* CONFIG_NAND_SPL */
+
+/*------------------------------------------------------------------------------*/
+
+/*
+ * 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 */

-	ldr	r2, _armboot_start
+	/* Set up the stack						    */
+stack_setup:
+	mov	sp, r4
+
+	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
+	beq	clear_bss

+#ifndef CONFIG_SKIP_RELOCATE_UBOOT
 copy_loop:
-	ldmia	r0!, {r3-r10}		/* copy from source address [r0]    */
-	stmia	r1!, {r3-r10}		/* copy to   target address [r1]    */
+	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
-#endif	/* CONFIG_SKIP_RELOCATE_UBOOT */

-	/* Set up the stack						    */
-stack_setup:
-	ldr	r0, _TEXT_BASE		/* upper 128 KiB: relocated uboot   */
-#ifdef CONFIG_PRELOADER
-	sub	sp, r0, #128		/* leave 32 words for abort-stack   */
-#else
-	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)
+#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
 #endif
-	sub	sp, r0, #12		/* leave 3 words for abort-stack    */
-#endif	/* CONFIG_PRELOADER */
-	bic	sp, sp, #7		/* 8-byte alignment for ABI compliance */
+#endif	/* #ifndef CONFIG_SKIP_RELOCATE_UBOOT */

 clear_bss:
-	ldr	r0, _bss_start		/* find start of bss segment	    */
-	ldr	r1, _bss_end		/* stop here			    */
+#ifndef CONFIG_PRELOADER
+	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			    */

-#ifndef CONFIG_PRELOADER
 clbss_l:str	r2, [r0]		/* clear loop...		    */
 	add	r0, r0, #4
 	cmp	r0, r1
 	bne	clbss_l
-#endif
-
-	ldr	pc, _start_armboot
+#endif	/* #ifndef CONFIG_PRELOADER */

+/*
+ * We are done. Do not return, instead branch to second part of board
+ * initialization, now running from RAM.
+ */
 #ifdef CONFIG_NAND_SPL
-_start_armboot: .word nand_boot
-#else
-#ifdef CONFIG_ONENAND_IPL
-_start_armboot: .word start_oneboot
+	ldr     pc, _nand_boot
+
+_nand_boot: .word nand_boot
 #else
-_start_armboot: .word start_armboot
-#endif /* CONFIG_ONENAND_IPL */
-#endif /* CONFIG_NAND_SPL */
+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
+#endif

 /*
  *************************************************************************
@@ -295,9 +375,7 @@ cpu_init_crit:
 	sub	sp, sp, #S_FRAME_SIZE		@ carve out a frame on current user stack
 	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 stack
+	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)
 	add	r0, sp, #S_FRAME_SIZE		@ grab pointer to old stack

@@ -328,9 +406,7 @@ cpu_init_crit:
 	.endm

 	.macro get_bad_stack
-	ldr	r13, _armboot_start		@ 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
+	ldr	r13, IRQ_STACK_START_IN		@ setup our mode stack (enter in banked mode)

 	str	lr, [r13]			@ save caller lr in position 0 of saved stack
 	mrs	lr, spsr			@ get the spsr
@@ -346,9 +422,7 @@ cpu_init_crit:
 	.macro get_bad_stack_swi
 	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 spots for abort stack
+	ldr	r0, IRQ_STACK_START_IN		@ get data regions start
 	str	lr, [r0]			@ save caller lr in position 0 of saved stack
 	mrs	r0, spsr			@ get the spsr
 	str	lr, [r0, #4]			@ save spsr in position 1 of saved stack
diff --git a/arch/arm/cpu/arm1136/u-boot.lds b/arch/arm/cpu/arm1136/u-boot.lds
index e7eefc9..1db4b49 100644
--- a/arch/arm/cpu/arm1136/u-boot.lds
+++ b/arch/arm/cpu/arm1136/u-boot.lds
@@ -47,11 +47,23 @@ 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/arch/arm/include/asm/config.h b/arch/arm/include/asm/config.h
index b76fd8e..049c44e 100644
--- a/arch/arm/include/asm/config.h
+++ b/arch/arm/include/asm/config.h
@@ -21,7 +21,4 @@
 #ifndef _ASM_CONFIG_H_
 #define _ASM_CONFIG_H_

-/* Relocation to SDRAM works on all ARM boards */
-#define CONFIG_RELOC_FIXUP_WORKS
-
 #endif
diff --git a/arch/arm/include/asm/global_data.h b/arch/arm/include/asm/global_data.h
index 02cfe45..192db7e 100644
--- a/arch/arm/include/asm/global_data.h
+++ b/arch/arm/include/asm/global_data.h
@@ -53,6 +53,12 @@ typedef	struct	global_data {
 	phys_size_t	ram_size;	/* RAM size */
 	unsigned long	reset_status;	/* reset status register at boot */
 #endif
+	unsigned long	relocaddr;	/* Start address of U-Boot in RAM */
+	phys_size_t	ram_size;	/* RAM size */
+	unsigned long	mon_len;	/* monitor len */
+	unsigned long	irq_sp;		/* irq stack pointer */
+	unsigned long	start_addr_sp;	/* start_addr_stackpointer */
+	unsigned long	reloc_off;
 	void		**jt;		/* jump table */
 } gd_t;

diff --git a/arch/arm/include/asm/u-boot-arm.h b/arch/arm/include/asm/u-boot-arm.h
index 6d2f8bc..76f01a7 100644
--- a/arch/arm/include/asm/u-boot-arm.h
+++ b/arch/arm/include/asm/u-boot-arm.h
@@ -30,10 +30,15 @@
 #define _U_BOOT_ARM_H_	1

 /* for the following variables, see start.S */
-extern ulong _armboot_start;	/* code start */
+extern ulong _TEXT_BASE;	/* code start */
 extern ulong _bss_start;	/* code + data end == BSS start */
 extern ulong _bss_end;		/* BSS end */
+extern ulong _datarel_start;
+extern ulong _datarelrolocal_start;
+extern ulong _datarellocal_start;
+extern ulong _datarelro_start;
 extern ulong IRQ_STACK_START;	/* top of IRQ stack */
+extern ulong IRQ_STACK_START_IN;	/* 8 bytes in IRQ stack */
 extern ulong FIQ_STACK_START;	/* top of FIQ stack */

 /* cpu/.../cpu.c */
@@ -47,6 +52,7 @@ int	arch_misc_init(void);
 /* board/.../... */
 int	board_init(void);
 int	dram_init (void);
+void	dram_init_banksize (void);
 void	setup_serial_tag (struct tag **params);
 void	setup_revision_tag (struct tag **params);

diff --git a/arch/arm/lib/board.c b/arch/arm/lib/board.c
index f5660a9..18ac183 100644
--- a/arch/arm/lib/board.c
+++ b/arch/arm/lib/board.c
@@ -126,7 +126,8 @@ static int init_baudrate (void)
 {
 	char tmp[64];	/* long enough for environment variables */
 	int i = getenv_r ("baudrate", tmp, sizeof (tmp));
-	gd->bd->bi_baudrate = gd->baudrate = (i > 0)
+
+	gd->baudrate = (i > 0)
 			? (int) simple_strtoul (tmp, NULL, 10)
 			: CONFIG_BAUDRATE;

@@ -137,7 +138,7 @@ static int display_banner (void)
 {
 	printf ("\n\n%s\n\n", version_string);
 	debug ("U-Boot code: %08lX -> %08lX  BSS: -> %08lX\n",
-	       _armboot_start, _bss_start, _bss_end);
+	       _TEXT_BASE, _bss_start, _bss_end);
 #ifdef CONFIG_MODEM_SUPPORT
 	debug ("Modem Support enabled\n");
 #endif
@@ -180,14 +181,6 @@ static int display_dram_config (void)
 	return (0);
 }

-#ifndef CONFIG_SYS_NO_FLASH
-static void display_flash_config (ulong size)
-{
-	puts ("Flash: ");
-	print_size (size, "\n");
-}
-#endif /* CONFIG_SYS_NO_FLASH */
-
 #if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
 static int init_func_i2c (void)
 {
@@ -238,9 +231,8 @@ init_fnc_t *init_sequence[] = {
 #if defined(CONFIG_ARCH_CPU_INIT)
 	arch_cpu_init,		/* basic arch cpu dependent setup */
 #endif
-	board_init,		/* basic board dependent setup */
-#if defined(CONFIG_USE_IRQ)
-	interrupt_init,		/* set up exceptions */
+#if defined(CONFIG_BOARD_EARLY_INIT_F)
+	board_early_init_f,
 #endif
 	timer_init,		/* initialize timer */
 #ifdef CONFIG_FSL_ESDHC
@@ -264,30 +256,24 @@ init_fnc_t *init_sequence[] = {
 #if defined(CONFIG_CMD_PCI) || defined (CONFIG_PCI)
 	arm_pci_init,
 #endif
-	display_dram_config,
 	NULL,
 };

-void start_armboot (void)
+void board_init_f (ulong bootflag)
 {
+	bd_t *bd;
 	init_fnc_t **init_fnc_ptr;
-	char *s;
-#if defined(CONFIG_VFD) || defined(CONFIG_LCD)
-	unsigned long addr;
-#endif
+	gd_t *id;
+	ulong addr, addr_sp;

 	/* Pointer is writable since we allocated a register for it */
-	gd = (gd_t*)(_armboot_start - CONFIG_SYS_MALLOC_LEN - sizeof(gd_t));
+	gd = (gd_t *) (CONFIG_SYS_INIT_SP_ADDR);
 	/* compiler optimization barrier needed for GCC >= 3.4 */
 	__asm__ __volatile__("": : :"memory");

 	memset ((void*)gd, 0, sizeof (gd_t));
-	gd->bd = (bd_t*)((char*)gd - sizeof(bd_t));
-	memset (gd->bd, 0, sizeof (bd_t));
-
-	gd->flags |= GD_FLG_RELOC;

-	monitor_flash_len = _bss_start - _armboot_start;
+	gd->mon_len = _bss_end - _TEXT_BASE;

 	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
 		if ((*init_fnc_ptr)() != 0) {
@@ -295,14 +281,48 @@ void start_armboot (void)
 		}
 	}

-	/* armboot_start is defined in the board-specific linker script */
-	mem_malloc_init (_armboot_start - CONFIG_SYS_MALLOC_LEN,
-			CONFIG_SYS_MALLOC_LEN);
+	debug ("monitor len: %08lX\n", gd->mon_len);
+	/*
+	 * Ram is setup, size stored in gd !!
+	 */
+	debug ("ramsize: %08lX\n", gd->ram_size);
+#if defined(CONFIG_SYS_MEM_TOP_HIDE)
+	/*
+	 * Subtract specified amount of memory to hide so that it won't
+	 * get "touched" at all by U-Boot. By fixing up gd->ram_size
+	 * the Linux kernel should now get passed the now "corrected"
+	 * memory size and won't touch it either. This should work
+	 * for arch/ppc and arch/powerpc. Only Linux board ports in
+	 * arch/powerpc with bootwrapper support, that recalculate the
+	 * memory size from the SDRAM controller setup will have to
+	 * get fixed.
+	 */
+	gd->ram_size -= CONFIG_SYS_MEM_TOP_HIDE;
+#endif

-#ifndef CONFIG_SYS_NO_FLASH
-	/* configure available FLASH banks */
-	display_flash_config (flash_init ());
-#endif /* CONFIG_SYS_NO_FLASH */
+	addr = CONFIG_SYS_SDRAM_BASE + gd->ram_size;
+
+#ifdef CONFIG_LOGBUFFER
+#ifndef CONFIG_ALT_LB_ADDR
+	/* reserve kernel log buffer */
+	addr -= (LOGBUFF_RESERVE);
+	debug ("Reserving %dk for kernel logbuffer at %08lx\n", LOGBUFF_LEN, addr);
+#endif
+#endif
+
+#ifdef CONFIG_PRAM
+	/*
+	 * reserve protected RAM
+	 */
+	i = getenv_r ("pram", (char *)tmp, sizeof (tmp));
+	reg = (i > 0) ? simple_strtoul ((const char *)tmp, NULL, 10) : CONFIG_PRAM;
+	addr -= (reg << 10);		/* size is in kB */
+	debug ("Reserving %ldk for protected RAM at %08lx\n", reg, addr);
+#endif /* CONFIG_PRAM */
+
+	/* round down to next 4 kB limit */
+	addr &= ~(4096 - 1);
+	debug ("Top of RAM usable for U-Boot at: %08lx\n", addr);

 #ifdef CONFIG_VFD
 #	ifndef PAGE_SIZE
@@ -311,27 +331,189 @@ void start_armboot (void)
 	/*
 	 * reserve memory for VFD display (always full pages)
 	 */
-	/* bss_end is defined in the board-specific linker script */
-	addr = (_bss_end + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
-	vfd_setmem (addr);
+	addr -= vfd_setmem (addr);
 	gd->fb_base = addr;
 #endif /* CONFIG_VFD */

 #ifdef CONFIG_LCD
-	/* board init may have inited fb_base */
-	if (!gd->fb_base) {
-#		ifndef PAGE_SIZE
-#		  define PAGE_SIZE 4096
-#		endif
+	/* reserve memory for LCD display (always full pages) */
+	addr = lcd_setmem (addr);
+	gd->fb_base = addr;
+#endif /* CONFIG_LCD */
+
+	/*
+	 * reserve memory for U-Boot code, data & bss
+	 * round down to next 4 kB limit
+	 */
+	addr -= gd->mon_len;
+	addr &= ~(4096 - 1);
+
+	debug ("Reserving %ldk for U-Boot at: %08lx\n", gd->mon_len >> 10, addr);
+
+#ifndef CONFIG_PRELOADER
+	/*
+	 * reserve memory for malloc() arena
+	 */
+	addr_sp = addr - TOTAL_MALLOC_LEN;
+	debug ("Reserving %dk for malloc() at: %08lx\n",
+			TOTAL_MALLOC_LEN >> 10, addr_sp);
+	/*
+	 * (permanently) allocate a Board Info struct
+	 * and a permanent copy of the "global" data
+	 */
+	addr_sp -= sizeof (bd_t);
+	bd = (bd_t *) addr_sp;
+	gd->bd = bd;
+	debug ("Reserving %zu Bytes for Board Info at: %08lx\n",
+			sizeof (bd_t), addr_sp);
+	addr_sp -= sizeof (gd_t);
+	id = (gd_t *) addr_sp;
+	debug ("Reserving %zu Bytes for Global Data at: %08lx\n",
+			sizeof (gd_t), addr_sp);
+
+	/* setup stackpointer for exeptions */
+	gd->irq_sp = addr_sp;
+#ifdef CONFIG_USE_IRQ
+	addr_sp -= (CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ);
+	debug ("Reserving %zu Bytes for IRQ stack at: %08lx\n",
+		CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ, addr_sp);
+#endif
+	/* leave 3 words for abort-stack    */
+	addr_sp -= 3;
+
+	/* 8-byte alignment for ABI compliance */
+	addr_sp &= ~0x07;
+#else
+	addr_sp += 128;	/* leave 32 words for abort-stack   */
+	gd->irq_sp = addr_sp;
+#endif
+
+	debug ("New Stack Pointer is: %08lx\n", addr_sp);
+
+#ifdef CONFIG_POST
+	post_bootmode_init();
+	post_run (NULL, POST_ROM | post_bootmode_get(0));
+#endif
+
+	gd->bd->bi_baudrate = gd->baudrate;
+	/* Ram ist board specific, so move it to board code ... */
+	dram_init_banksize();
+	display_dram_config();	/* and display it */
+
+	gd->relocaddr = addr;
+	gd->start_addr_sp = addr_sp;
+	gd->reloc_off = addr - _TEXT_BASE;
+	debug ("relocation Offset is: %08lx\n", gd->reloc_off);
+	memcpy (id, (void *)gd, sizeof (gd_t));
+
+	relocate_code (addr_sp, id, addr);
+
+	/* NOTREACHED - relocate_code() does not return */
+}
+
+#if !defined(CONFIG_SYS_NO_FLASH)
+static char *failed = "*** failed ***\n";
+#endif
+
+/************************************************************************
+ *
+ * This is the next part if the initialization sequence: we are now
+ * running from RAM and have a "normal" C environment, i. e. global
+ * data can be written, BSS has been cleared, the stack size in not
+ * that critical any more, etc.
+ *
+ ************************************************************************
+ */
+void board_init_r (gd_t *id, ulong dest_addr)
+{
+	char *s;
+	bd_t *bd;
+	ulong malloc_start;
+#if !defined(CONFIG_SYS_NO_FLASH)
+	ulong flash_size;
+#endif
+#if !defined(CONFIG_RELOC_FIXUP_WORKS)
+	extern void malloc_bin_reloc (void);
+#if defined(CONFIG_CMD_BMP)
+	extern void bmp_reloc(void);
+#endif
+#if defined(CONFIG_CMD_I2C)
+	extern void i2c_reloc(void);
+#endif
+#endif
+
+	gd = id;
+	bd = gd->bd;
+
+	gd->flags |= GD_FLG_RELOC;	/* tell others: relocation done */
+
+	monitor_flash_len = _bss_start - _TEXT_BASE;
+	debug ("monitor flash len: %08lX\n", monitor_flash_len);
+	board_init();	/* Setup chipselects */
+
+#ifdef CONFIG_SERIAL_MULTI
+	serial_initialize();
+#endif
+
+	debug ("Now running in RAM - U-Boot at: %08lx\n", dest_addr);
+
+#if !defined(CONFIG_RELOC_FIXUP_WORKS)
+	/*
+	 * We have to relocate the command table manually
+	 */
+	fixup_cmdtable(&__u_boot_cmd_start,
+		(ulong)(&__u_boot_cmd_end - &__u_boot_cmd_start));
+#if defined(CONFIG_CMD_BMP)
+	bmp_reloc();
+#endif
+#if defined(CONFIG_CMD_I2C)
+	i2c_reloc();
+#endif
+#endif /* !defined(CONFIG_RELOC_FIXUP_WORKS) */
+
+#ifdef CONFIG_LOGBUFFER
+	logbuff_init_ptrs ();
+#endif
+#ifdef CONFIG_POST
+	post_output_backlog ();
+#ifndef CONFIG_RELOC_FIXUP_WORKS
+	post_reloc ();
+#endif
+#endif
+
+	/* The Malloc area is immediately below the monitor copy in DRAM */
+	malloc_start = dest_addr - TOTAL_MALLOC_LEN;
+	mem_malloc_init (malloc_start, TOTAL_MALLOC_LEN);
+#if !defined(CONFIG_RELOC_FIXUP_WORKS)
+	malloc_bin_reloc ();
+#endif
+
+#if !defined(CONFIG_SYS_NO_FLASH)
+	puts ("FLASH: ");
+
+	if ((flash_size = flash_init ()) > 0) {
+# ifdef CONFIG_SYS_FLASH_CHECKSUM
+		print_size (flash_size, "");
 		/*
-		 * reserve memory for LCD display (always full pages)
+		 * Compute and print flash CRC if flashchecksum is set to 'y'
+		 *
+		 * NOTE: Maybe we should add some WATCHDOG_RESET()? XXX
 		 */
-		/* bss_end is defined in the board-specific linker script */
-		addr = (_bss_end + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
-		lcd_setmem (addr);
-		gd->fb_base = addr;
+		s = getenv ("flashchecksum");
+		if (s && (*s == 'y')) {
+			printf ("  CRC: %08X",
+				crc32 (0, (const unsigned char *) CONFIG_SYS_FLASH_BASE, flash_size)
+			);
+		}
+		putc ('\n');
+# else	/* !CONFIG_SYS_FLASH_CHECKSUM */
+		print_size (flash_size, "\n");
+# endif /* CONFIG_SYS_FLASH_CHECKSUM */
+	} else {
+		puts (failed);
+		hang ();
 	}
-#endif /* CONFIG_LCD */
+#endif

 #if defined(CONFIG_CMD_NAND)
 	puts ("NAND:  ");
@@ -355,10 +537,6 @@ void start_armboot (void)
 	drv_vfd_init();
 #endif /* CONFIG_VFD */

-#ifdef CONFIG_SERIAL_MULTI
-	serial_initialize();
-#endif
-
 	/* IP Address */
 	gd->bd->bi_ip_addr = getenv_IPaddr ("ipaddr");

@@ -382,6 +560,8 @@ void start_armboot (void)
 	misc_init_r ();
 #endif

+	 /* set up exceptions */
+	interrupt_init ();
 	/* enable exceptions */
 	enable_interrupts ();

@@ -437,6 +617,41 @@ extern void davinci_eth_set_mac_addr (const u_int8_t *addr);
 	reset_phy();
 #endif
 #endif
+
+#ifdef CONFIG_POST
+	post_run (NULL, POST_RAM | post_bootmode_get(0));
+#endif
+
+#if defined(CONFIG_PRAM) || defined(CONFIG_LOGBUFFER)
+	/*
+	 * Export available size of memory for Linux,
+	 * taking into account the protected RAM at top of memory
+	 */
+	{
+		ulong pram;
+		uchar memsz[32];
+#ifdef CONFIG_PRAM
+		char *s;
+
+		if ((s = getenv ("pram")) != NULL) {
+			pram = simple_strtoul (s, NULL, 10);
+		} else {
+			pram = CONFIG_PRAM;
+		}
+#else
+		pram=0;
+#endif
+#ifdef CONFIG_LOGBUFFER
+#ifndef CONFIG_ALT_LB_ADDR
+		/* Also take the logbuffer into account (pram is in kB) */
+		pram += (LOGBUFF_LEN+LOGBUFF_OVERHEAD)/1024;
+#endif
+#endif
+		sprintf ((char *)memsz, "%ldk", (bd->bi_memsize / 1024) - pram);
+		setenv ("mem", (char *)memsz);
+	}
+#endif
+
 	/* main_loop() can return to retry autoboot, if so just run it again. */
 	for (;;) {
 		main_loop ();
diff --git a/arch/arm/lib/interrupts.c b/arch/arm/lib/interrupts.c
index 1f2b815..74ff5ce 100644
--- a/arch/arm/lib/interrupts.c
+++ b/arch/arm/lib/interrupts.c
@@ -38,15 +38,16 @@
 #include <common.h>
 #include <asm/proc-armv/ptrace.h>

-#ifdef CONFIG_USE_IRQ
 DECLARE_GLOBAL_DATA_PTR;

+#ifdef CONFIG_USE_IRQ
 int interrupt_init (void)
 {
 	/*
 	 * setup up stacks if necessary
 	 */
-	IRQ_STACK_START = _armboot_start - CONFIG_SYS_MALLOC_LEN - CONFIG_SYS_GBL_DATA_SIZE - 4;
+	IRQ_STACK_START = gd->irq_sp - 4;
+	IRQ_STACK_START_IN = gd->irq_sp + 8;
 	FIQ_STACK_START = IRQ_STACK_START - CONFIG_STACKSIZE_IRQ;

 	return arch_interrupt_init();
@@ -81,6 +82,16 @@ int disable_interrupts (void)
 	return (old & 0x80) == 0;
 }
 #else
+int interrupt_init (void)
+{
+	/*
+	 * setup up stacks if necessary
+	 */
+	IRQ_STACK_START_IN = gd->irq_sp + 8;
+
+	return 0;
+}
+
 void enable_interrupts (void)
 {
 	return;
diff --git a/board/davedenx/qong/config.mk b/board/davedenx/qong/config.mk
index d8d0a57..39c1203 100644
--- a/board/davedenx/qong/config.mk
+++ b/board/davedenx/qong/config.mk
@@ -1 +1,3 @@
-TEXT_BASE = 0x8ff00000
+TEXT_BASE = 0xa0000000
+
+# PLATFORM_CPPFLAGS += -DDEBUG
diff --git a/board/davedenx/qong/qong.c b/board/davedenx/qong/qong.c
index 781333b..88d1231 100644
--- a/board/davedenx/qong/qong.c
+++ b/board/davedenx/qong/qong.c
@@ -33,11 +33,17 @@ DECLARE_GLOBAL_DATA_PTR;

 int dram_init (void)
 {
+	/* dram_init must store complete ramsize in gd->ram_size */
+	gd->ram_size = get_ram_size((volatile void *)PHYS_SDRAM_1,
+				PHYS_SDRAM_1_SIZE);
+	return 0;
+}
+
+void dram_init_banksize (void)
+{
 	gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
-	gd->bd->bi_dram[0].size = get_ram_size((volatile void *)PHYS_SDRAM_1,
-			PHYS_SDRAM_1_SIZE);
+	gd->bd->bi_dram[0].size = gd->ram_size;

-	return 0;
 }

 static void qong_fpga_reset(void)
@@ -49,6 +55,49 @@ static void qong_fpga_reset(void)
 	udelay(300);
 }

+int board_early_init_f (void)
+{
+#ifdef CONFIG_QONG_FPGA
+	/* CS1: FPGA/Network Controller/GPIO */
+	/* 16-bit, no DTACK */
+	__REG(CSCR_U(1)) = 0x00000A01;
+	__REG(CSCR_L(1)) = 0x20040501;
+	__REG(CSCR_A(1)) = 0x04020C00;
+
+	/* setup pins for FPGA */
+	mx31_gpio_mux(IOMUX_MODE(0x76, MUX_CTL_GPIO));
+	mx31_gpio_mux(IOMUX_MODE(0x7e, MUX_CTL_GPIO));
+	mx31_gpio_mux(IOMUX_MODE(0x91, MUX_CTL_OUT_FUNC | MUX_CTL_IN_GPIO));
+	mx31_gpio_mux(IOMUX_MODE(0x92, MUX_CTL_GPIO));
+	mx31_gpio_mux(IOMUX_MODE(0x93, MUX_CTL_GPIO));
+
+	/* FPGA reset  Pin */
+	/* rstn = 0 */
+	mx31_gpio_set(QONG_FPGA_RST_PIN, 0);
+	mx31_gpio_direction(QONG_FPGA_RST_PIN, MX31_GPIO_DIRECTION_OUT);
+
+	/* set interrupt pin as input */
+	mx31_gpio_direction(QONG_FPGA_IRQ_PIN, MX31_GPIO_DIRECTION_IN);
+
+#endif
+
+	/* setup pins for UART1 */
+	mx31_gpio_mux(MUX_RXD1__UART1_RXD_MUX);
+	mx31_gpio_mux(MUX_TXD1__UART1_TXD_MUX);
+	mx31_gpio_mux(MUX_RTS1__UART1_RTS_B);
+	mx31_gpio_mux(MUX_CTS1__UART1_CTS_B);
+
+	/* setup pins for SPI (pmic) */
+	mx31_gpio_mux(MUX_CSPI2_SS0__CSPI2_SS0_B);
+	mx31_gpio_mux(MUX_CSPI2_MOSI__CSPI2_MOSI);
+	mx31_gpio_mux(MUX_CSPI2_MISO__CSPI2_MISO);
+	mx31_gpio_mux(MUX_CSPI2_SCLK__CSPI2_CLK);
+	mx31_gpio_mux(MUX_CSPI2_SPI_RDY__CSPI2_DATAREADY_B);
+
+	return 0;
+
+}
+
 int board_init (void)
 {
 	/* Chip selects */
@@ -99,43 +148,6 @@ int board_init (void)
 						(0 << 0)	  /* FCE */
 					   );

-#ifdef CONFIG_QONG_FPGA
-	/* CS1: FPGA/Network Controller/GPIO */
-	/* 16-bit, no DTACK */
-	__REG(CSCR_U(1)) = 0x00000A01;
-	__REG(CSCR_L(1)) = 0x20040501;
-	__REG(CSCR_A(1)) = 0x04020C00;
-
-	/* setup pins for FPGA */
-	mx31_gpio_mux(IOMUX_MODE(0x76, MUX_CTL_GPIO));
-	mx31_gpio_mux(IOMUX_MODE(0x7e, MUX_CTL_GPIO));
-	mx31_gpio_mux(IOMUX_MODE(0x91, MUX_CTL_OUT_FUNC | MUX_CTL_IN_GPIO));
-	mx31_gpio_mux(IOMUX_MODE(0x92, MUX_CTL_GPIO));
-	mx31_gpio_mux(IOMUX_MODE(0x93, MUX_CTL_GPIO));
-
-	/* FPGA reset  Pin */
-	/* rstn = 0 */
-	mx31_gpio_set(QONG_FPGA_RST_PIN, 0);
-	mx31_gpio_direction(QONG_FPGA_RST_PIN, MX31_GPIO_DIRECTION_OUT);
-
-	/* set interrupt pin as input */
-	mx31_gpio_direction(QONG_FPGA_IRQ_PIN, MX31_GPIO_DIRECTION_IN);
-
-#endif
-
-	/* setup pins for UART1 */
-	mx31_gpio_mux(MUX_RXD1__UART1_RXD_MUX);
-	mx31_gpio_mux(MUX_TXD1__UART1_TXD_MUX);
-	mx31_gpio_mux(MUX_RTS1__UART1_RTS_B);
-	mx31_gpio_mux(MUX_CTS1__UART1_CTS_B);
-
-	/* setup pins for SPI (pmic) */
-	mx31_gpio_mux(MUX_CSPI2_SS0__CSPI2_SS0_B);
-	mx31_gpio_mux(MUX_CSPI2_MOSI__CSPI2_MOSI);
-	mx31_gpio_mux(MUX_CSPI2_MISO__CSPI2_MISO);
-	mx31_gpio_mux(MUX_CSPI2_SCLK__CSPI2_CLK);
-	mx31_gpio_mux(MUX_CSPI2_SPI_RDY__CSPI2_DATAREADY_B);
-
 	/* board id for linux */
 	gd->bd->bi_arch_number = MACH_TYPE_QONG;
 	gd->bd->bi_boot_params = (0x80000100);	/* adress of boot parameters */
diff --git a/common/cmd_bdinfo.c b/common/cmd_bdinfo.c
index cc81543..57a2243 100644
--- a/common/cmd_bdinfo.c
+++ b/common/cmd_bdinfo.c
@@ -343,6 +343,7 @@ int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 	printf ("ip_addr     = %pI4\n", &bd->bi_ip_addr);
 #endif
 	printf ("baudrate    = %d bps\n", bd->bi_baudrate);
+	print_num ("irq_sp", gd->irq_sp);	/* irq stack pointer */

 	return 0;
 }
diff --git a/common/cmd_bmp.c b/common/cmd_bmp.c
index d51cc55..6fa8a15 100644
--- a/common/cmd_bmp.c
+++ b/common/cmd_bmp.c
@@ -137,6 +137,12 @@ static cmd_tbl_t cmd_bmp_sub[] = {
 	U_BOOT_CMD_MKENT(display, 5, 0, do_bmp_display, "", ""),
 };

+#ifndef CONFIG_RELOC_FIXUP_WORKS
+void bmp_reloc(void) {
+	fixup_cmdtable(cmd_bmp_sub, ARRAY_SIZE(cmd_bmp_sub));
+}
+#endif
+
 /*
  * Subroutine:  do_bmp
  *
diff --git a/common/cmd_i2c.c b/common/cmd_i2c.c
index 371e022..a1a84a1 100644
--- a/common/cmd_i2c.c
+++ b/common/cmd_i2c.c
@@ -1287,6 +1287,12 @@ static cmd_tbl_t cmd_i2c_sub[] = {
 	U_BOOT_CMD_MKENT(speed, 1, 1, do_i2c_bus_speed, "", ""),
 };

+#ifndef CONFIG_RELOC_FIXUP_WORKS
+void i2c_reloc(void) {
+	fixup_cmdtable(cmd_i2c_sub, ARRAY_SIZE(cmd_i2c_sub));
+}
+#endif
+
 static int do_i2c(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 {
 	cmd_tbl_t *c;
diff --git a/include/configs/qong.h b/include/configs/qong.h
index 100fa3f..0d6718c 100644
--- a/include/configs/qong.h
+++ b/include/configs/qong.h
@@ -281,4 +281,13 @@ extern int qong_nand_rdy(void *chip);
 	"mtdparts=physmap-flash.0:384k(U-Boot),128k(env1),"	\
 	"128k(env2),2432k(kernel),13m(ramdisk),-(user)"

+/* additions for new relocation code, must added to all boards */
+#define CONFIG_SYS_SDRAM_BASE	0x80000000
+#define CONFIG_SYS_INIT_RAM_ADDR	IRAM_BASE_ADDR
+#define CONFIG_SYS_INIT_RAM_END		IRAM_SIZE
+#define CONFIG_SYS_GBL_DATA_OFFSET	(CONFIG_SYS_INIT_RAM_END - CONFIG_SYS_GBL_DATA_SIZE)
+#define CONFIG_SYS_INIT_SP_ADDR		(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET)
+
+#define CONFIG_BOARD_EARLY_INIT_F	1
+
 #endif /* __CONFIG_H */
diff --git a/nand_spl/nand_boot.c b/nand_spl/nand_boot.c
index b9fd6f5..ded0c0e 100644
--- a/nand_spl/nand_boot.c
+++ b/nand_spl/nand_boot.c
@@ -221,6 +221,11 @@ static int nand_load(struct mtd_info *mtd, unsigned int offs,
 	return 0;
 }

+void board_init_f (ulong bootflag)
+{
+	relocate_code (TEXT_BASE - TOTAL_MALLOC_LEN, NULL, TEXT_BASE);
+}
+
 /*
  * The main entry for NAND booting. It's necessary that SDRAM is already
  * configured and available since this code loads the main U-Boot image
diff --git a/nand_spl/nand_boot_fsl_nfc.c b/nand_spl/nand_boot_fsl_nfc.c
index bfae30e..9720f6a 100644
--- a/nand_spl/nand_boot_fsl_nfc.c
+++ b/nand_spl/nand_boot_fsl_nfc.c
@@ -265,6 +265,11 @@ static int nand_load(unsigned int from, unsigned int size, unsigned char *buf)
 	return 0;
 }

+void board_init_f (ulong bootflag)
+{
+	relocate_code (TEXT_BASE - TOTAL_MALLOC_LEN, NULL, TEXT_BASE);
+}
+
 /*
  * The main entry for NAND booting. It's necessary that SDRAM is already
  * configured and available since this code loads the main U-Boot image
-- 
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