Signed-off-by: Heiko Schocher <[email protected]>
---
 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
_______________________________________________
U-Boot mailing list
[email protected]
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to