All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [RFC][PATCH 04/19] arm, arm1136, qong: add relocation support
@ 2010-07-29 10:44 Heiko Schocher
  0 siblings, 0 replies; only message in thread
From: Heiko Schocher @ 2010-07-29 10:44 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Heiko Schocher <hs@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@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@%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

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2010-07-29 10:44 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-07-29 10:44 [U-Boot] [RFC][PATCH 04/19] arm, arm1136, qong: add relocation support Heiko Schocher

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.