Rename TEXT_BASE into CONFIG_SYS_TEXT_BASE
[platform/kernel/u-boot.git] / arch / arm / cpu / arm1176 / start.S
index a540edb..24e5bf4 100644 (file)
@@ -95,8 +95,9 @@ _end_vect:
  *************************************************************************
  */
 
+.globl _TEXT_BASE
 _TEXT_BASE:
-       .word   TEXT_BASE
+       .word   CONFIG_SYS_TEXT_BASE
 
 /*
  * Below variable is very important because we use MMU in U-Boot.
@@ -106,9 +107,11 @@ _TEXT_BASE:
 _TEXT_PHY_BASE:
        .word   CONFIG_SYS_PHY_UBOOT_BASE
 
+#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
 .globl _armboot_start
 _armboot_start:
        .word _start
+#endif
 
 /*
  * These are defined in the board-specific linker script.
@@ -121,6 +124,275 @@ _bss_start:
 _bss_end:
        .word _end
 
+#if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
+/* IRQ stack memory (calculated at run-time) + 8 bytes */
+.globl IRQ_STACK_START_IN
+IRQ_STACK_START_IN:
+       .word   0x0badc0de
+
+.globl _datarel_start
+_datarel_start:
+       .word __datarel_start
+
+.globl _datarelrolocal_start
+_datarelrolocal_start:
+       .word __datarelrolocal_start
+
+.globl _datarellocal_start
+_datarellocal_start:
+       .word __datarellocal_start
+
+.globl _datarelro_start
+_datarelro_start:
+       .word __datarelro_start
+
+.globl _got_start
+_got_start:
+       .word __got_start
+
+.globl _got_end
+_got_end:
+       .word __got_end
+
+/*
+ * the actual reset code
+ */
+
+reset:
+       /*
+        * set the cpu to SVC32 mode
+        */
+       mrs     r0, cpsr
+       bic     r0, r0, #0x3f
+       orr     r0, r0, #0xd3
+       msr     cpsr, r0
+
+/*
+ *************************************************************************
+ *
+ * CPU_init_critical registers
+ *
+ * setup important registers
+ * setup memory timing
+ *
+ *************************************************************************
+ */
+       /*
+        * we do sys-critical inits only at reboot,
+        * not when booting from ram!
+        */
+cpu_init_crit:
+       /*
+        * When booting from NAND - it has definitely been a reset, so, no need
+        * to flush caches and disable the MMU
+        */
+#ifndef CONFIG_NAND_SPL
+       /*
+        * flush v4 I/D caches
+        */
+       mov     r0, #0
+       mcr     p15, 0, r0, c7, c7, 0   /* flush v3/v4 cache */
+       mcr     p15, 0, r0, c8, c7, 0   /* flush v4 TLB */
+
+       /*
+        * disable MMU stuff and caches
+        */
+       mrc     p15, 0, r0, c1, c0, 0
+       bic     r0, r0, #0x00002300     @ clear bits 13, 9:8 (--V- --RS)
+       bic     r0, r0, #0x00000087     @ clear bits 7, 2:0 (B--- -CAM)
+       orr     r0, r0, #0x00000002     @ set bit 2 (A) Align
+       orr     r0, r0, #0x00001000     @ set bit 12 (I) I-Cache
+
+       /* Prepare to disable the MMU */
+       adr     r2, mmu_disable_phys
+       sub     r2, r2, #(CONFIG_SYS_PHY_UBOOT_BASE - CONFIG_SYS_TEXT_BASE)
+       b       mmu_disable
+
+       .align 5
+       /* Run in a single cache-line */
+mmu_disable:
+       mcr     p15, 0, r0, c1, c0, 0
+       nop
+       nop
+       mov     pc, r2
+mmu_disable_phys:
+
+#ifdef CONFIG_DISABLE_TCM
+       /*
+        * Disable the TCMs
+        */
+       mrc     p15, 0, r0, c0, c0, 2   /* Return TCM details */
+       cmp     r0, #0
+       beq     skip_tcmdisable
+       mov     r1, #0
+       mov     r2, #1
+       tst     r0, r2
+       mcrne   p15, 0, r1, c9, c1, 1   /* Disable Instruction TCM if present*/
+       tst     r0, r2, LSL #16
+       mcrne   p15, 0, r1, c9, c1, 0   /* Disable Data TCM if present*/
+skip_tcmdisable:
+#endif
+#endif
+
+#ifdef CONFIG_PERIPORT_REMAP
+       /* Peri port setup */
+       ldr     r0, =CONFIG_PERIPORT_BASE
+       orr     r0, r0, #CONFIG_PERIPORT_SIZE
+       mcr     p15,0,r0,c15,c2,4
+#endif
+
+       /*
+        * Go setup Memory and board specific bits prior to relocation.
+        */
+       bl      lowlevel_init           /* go setup pll,mux,memory */
+
+/* Set stackpointer in internal RAM to call board_init_f */
+call_board_init_f:
+       ldr     sp, =(CONFIG_SYS_INIT_SP_ADDR)
+       ldr     r0,=0x00000000
+       bl      board_init_f
+
+/*------------------------------------------------------------------------------*/
+
+/*
+ * void relocate_code (addr_sp, gd, addr_moni)
+ *
+ * This "function" does not return, instead it continues in RAM
+ * after relocating the monitor code.
+ *
+ */
+       .globl  relocate_code
+relocate_code:
+       mov     r4, r0  /* save addr_sp */
+       mov     r5, r1  /* save addr of gd */
+       mov     r6, r2  /* save addr of destination */
+       mov     r7, r2  /* save addr of destination */
+
+       /* Set up the stack                                                 */
+stack_setup:
+       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!, {r9-r10}           /* copy from source address [r0]    */
+       stmia   r6!, {r9-r10}           /* copy to   target address [r1]    */
+       cmp     r0, r2                  /* until source end address [r2]    */
+       blo     copy_loop
+
+#ifndef CONFIG_PRELOADER
+       /* fix got entries */
+       ldr     r1, _TEXT_BASE          /* 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
+#endif /* #ifndef CONFIG_SKIP_RELOCATE_UBOOT */
+
+#ifdef CONFIG_ENABLE_MMU
+enable_mmu:
+       /* enable domain access */
+       ldr     r5, =0x0000ffff
+       mcr     p15, 0, r5, c3, c0, 0   /* load domain access register */
+
+       /* Set the TTB register */
+       ldr     r0, _mmu_table_base
+       ldr     r1, =CONFIG_SYS_PHY_UBOOT_BASE
+       ldr     r2, =0xfff00000
+       bic     r0, r0, r2
+       orr     r1, r0, r1
+       mcr     p15, 0, r1, c2, c0, 0
+
+       /* Enable the MMU */
+       mrc     p15, 0, r0, c1, c0, 0
+       orr     r0, r0, #1              /* Set CR_M to enable MMU */
+
+       /* Prepare to enable the MMU */
+       adr     r1, skip_hw_init
+       and     r1, r1, #0x3fc
+       ldr     r2, _TEXT_BASE
+       ldr     r3, =0xfff00000
+       and     r2, r2, r3
+       orr     r2, r2, r1
+       b       mmu_enable
+
+       .align 5
+       /* Run in a single cache-line */
+mmu_enable:
+
+       mcr     p15, 0, r0, c1, c0, 0
+       nop
+       nop
+       mov     pc, r2
+skip_hw_init:
+#endif
+
+clear_bss:
+#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                            */
+
+clbss_l:str    r2, [r0]                /* clear loop...                    */
+       add     r0, r0, #4
+       cmp     r0, r1
+       bne     clbss_l
+
+       bl coloured_LED_init
+       bl red_LED_on
+#endif
+
+/*
+ * We are done. Do not return, instead branch to second part of board
+ * initialization, now running from RAM.
+ */
+#ifdef CONFIG_NAND_SPL
+       ldr     pc, _nand_boot
+
+_nand_boot: .word nand_boot
+#else
+       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
+
+#else /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */
+
 /*
  * the actual reset code
  */
@@ -172,7 +444,7 @@ cpu_init_crit:
 
        /* Prepare to disable the MMU */
        adr     r2, mmu_disable_phys
-       sub     r2, r2, #(CONFIG_SYS_PHY_UBOOT_BASE - TEXT_BASE)
+       sub     r2, r2, #(CONFIG_SYS_PHY_UBOOT_BASE - CONFIG_SYS_TEXT_BASE)
        b       mmu_disable
 
        .align 5
@@ -228,8 +500,8 @@ relocate:                           /* relocate U-Boot to RAM           */
 copy_loop:
        ldmia   r0!, {r3-r10}           /* copy from source address [r0]    */
        stmia   r1!, {r3-r10}           /* copy to   target address [r1]    */
-       cmp     r0, r2                  /* until source end addreee [r2]    */
-       ble     copy_loop
+       cmp     r0, r2                  /* until source end address [r2]    */
+       blo     copy_loop
 #endif /* CONFIG_SKIP_RELOCATE_UBOOT */
 
 #ifdef CONFIG_ENABLE_MMU
@@ -276,6 +548,7 @@ stack_setup:
        sub     r0, r0, #CONFIG_SYS_MALLOC_LEN  /* malloc area                      */
        sub     r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo                        */
        sub     sp, r0, #12             /* leave 3 words for abort-stack    */
+       bic     sp, sp, #7              /* 8-byte alignment for ABI compliance */
 
 clear_bss:
        ldr     r0, _bss_start          /* find start of bss segment        */
@@ -286,7 +559,7 @@ clbss_l:
        str     r2, [r0]                /* clear loop...                    */
        add     r0, r0, #4
        cmp     r0, r1
-       ble     clbss_l
+       blo     clbss_l
 
 #ifndef CONFIG_NAND_SPL
        ldr     pc, _start_armboot
@@ -298,6 +571,8 @@ _start_armboot:
 /*     .word nand_boot*/
 #endif
 
+#endif /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */
+
 #ifdef CONFIG_ENABLE_MMU
 _mmu_table_base:
        .word mmu_table
@@ -384,10 +659,14 @@ phy_last_jump:
        /* Save user registers (now in svc mode) r0-r12 */
        stmia   sp, {r0 - r12}
 
+#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
        ldr     r2, _armboot_start
        sub     r2, r2, #(CONFIG_SYS_MALLOC_LEN)
        /* set base 2 words into abort stack */
        sub     r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8)
+#else
+       ldr     r2, IRQ_STACK_START_IN
+#endif
        /* get values for "aborted" pc and cpsr (into parm regs) */
        ldmia   r2, {r2 - r3}
        /* grab pointer to old stack */
@@ -402,12 +681,16 @@ phy_last_jump:
        .endm
 
        .macro get_bad_stack
+#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
        /* setup our mode stack (enter in banked mode) */
        ldr     r13, _armboot_start
        /* move past malloc pool */
        sub     r13, r13, #(CONFIG_SYS_MALLOC_LEN)
        /* move to reserved a couple spots for abort stack */
        sub     r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE + 8)
+#else
+       ldr     r13, IRQ_STACK_START_IN         @ setup our mode stack
+#endif
 
        /* save caller lr in position 0 of saved stack */
        str     lr, [r13]
@@ -432,12 +715,16 @@ phy_last_jump:
        sub     r13, r13, #4
        /* save R0's value. */
        str     r0, [r13]
+#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
        /* get data regions start */
        ldr     r0, _armboot_start
        /* move past malloc pool */
        sub     r0, r0, #(CONFIG_SYS_MALLOC_LEN)
        /* move past gbl and a couple spots for abort stack */
        sub     r0, r0, #(CONFIG_SYS_GBL_DATA_SIZE + 8)
+#else
+       ldr     r13, IRQ_STACK_START_IN         @ setup our mode stack
+#endif
        /* save caller lr in position 0 of saved stack */
        str     lr, [r0]
        /* get the spsr */