diff options
Diffstat (limited to 'arch/arm/cpu/arm1176/start.S')
-rw-r--r-- | arch/arm/cpu/arm1176/start.S | 356 |
1 files changed, 83 insertions, 273 deletions
diff --git a/arch/arm/cpu/arm1176/start.S b/arch/arm/cpu/arm1176/start.S index 24e5bf4..f04d268 100644 --- a/arch/arm/cpu/arm1176/start.S +++ b/arch/arm/cpu/arm1176/start.S @@ -30,6 +30,7 @@ * Base codes by scsuh (sc.suh) */ +#include <asm-offsets.h> #include <config.h> #include <version.h> #ifdef CONFIG_ENABLE_MMU @@ -107,52 +108,53 @@ _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. + * Subtracting _start from them lets the linker put their + * relative position in the executable instead of leaving + * them null. */ -.globl _bss_start -_bss_start: - .word __bss_start -.globl _bss_end -_bss_end: - .word _end +.globl _bss_start_ofs +_bss_start_ofs: + .word __bss_start - _start -#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 _bss_end_ofs +_bss_end_ofs: + .word _end - _start -.globl _datarel_start -_datarel_start: - .word __datarel_start +.globl _datarel_start_ofs +_datarel_start_ofs: + .word __datarel_start - _start -.globl _datarelrolocal_start -_datarelrolocal_start: - .word __datarelrolocal_start +.globl _datarelrolocal_start_ofs +_datarelrolocal_start_ofs: + .word __datarelrolocal_start - _start -.globl _datarellocal_start -_datarellocal_start: - .word __datarellocal_start +.globl _datarellocal_start_ofs +_datarellocal_start_ofs: + .word __datarellocal_start - _start -.globl _datarelro_start -_datarelro_start: - .word __datarelro_start +.globl _datarelro_start_ofs +_datarelro_start_ofs: + .word __datarelro_start - _start -.globl _got_start -_got_start: - .word __got_start +.globl _rel_dyn_start_ofs +_rel_dyn_start_ofs: + .word __rel_dyn_start - _start -.globl _got_end -_got_end: - .word __got_end +.globl _rel_dyn_end_ofs +_rel_dyn_end_ofs: + .word __rel_dyn_end - _start + +.globl _dynsym_start_ofs +_dynsym_start_ofs: + .word __dynsym_start - _start + +/* IRQ stack memory (calculated at run-time) + 8 bytes */ +.globl IRQ_STACK_START_IN +IRQ_STACK_START_IN: + .word 0x0badc0de /* * the actual reset code @@ -274,13 +276,11 @@ stack_setup: 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 */ + ldr r3, _bss_start_ofs + add r2, r0, r3 /* 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] */ @@ -288,26 +288,45 @@ copy_loop: 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 - + /* + * fix .rel.dyn relocations + */ + ldr r0, _TEXT_BASE /* r0 <- Text base */ + sub r9, r7, r0 /* r9 <- relocation offset */ + ldr r10, _dynsym_start_ofs /* r10 <- sym table ofs */ + add r10, r10, r0 /* r10 <- sym table in FLASH */ + ldr r2, _rel_dyn_start_ofs /* r2 <- rel dyn start ofs */ + add r2, r2, r0 /* r2 <- rel dyn start in FLASH */ + ldr r3, _rel_dyn_end_ofs /* r3 <- rel dyn end ofs */ + add r3, r3, r0 /* r3 <- rel dyn end in FLASH */ fixloop: - ldr r4, [r2] - sub r4, r4, r1 - add r4, r4, r0 - str r4, [r2] - add r2, r2, #4 + ldr r0, [r2] /* r0 <- location to fix up, IN FLASH! */ + add r0, r0, r9 /* r0 <- location to fix up in RAM */ + ldr r1, [r2, #4] + and r8, r1, #0xff + cmp r8, #23 /* relative fixup? */ + beq fixrel + cmp r8, #2 /* absolute fixup? */ + beq fixabs + /* ignore unknown type of fixup */ + b fixnext +fixabs: + /* absolute fix: set location to (offset) symbol value */ + mov r1, r1, LSR #4 /* r1 <- symbol index in .dynsym */ + add r1, r10, r1 /* r1 <- address of symbol in table */ + ldr r1, [r1, #4] /* r1 <- symbol value */ + add r1, r1, r9 /* r1 <- relocated sym addr */ + b fixnext +fixrel: + /* relative fix: increase location by offset */ + ldr r1, [r0] + add r1, r1, r9 +fixnext: + str r1, [r0] + add r2, r2, #8 /* each rel.dyn entry is 8 bytes */ cmp r2, r3 - bne fixloop + blo fixloop #endif -#endif /* #ifndef CONFIG_SKIP_RELOCATE_UBOOT */ #ifdef CONFIG_ENABLE_MMU enable_mmu: @@ -349,13 +368,11 @@ skip_hw_init: clear_bss: #ifndef CONFIG_PRELOADER - ldr r0, _bss_start - ldr r1, _bss_end + ldr r0, _bss_start_ofs + ldr r1, _bss_end_ofs 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 */ @@ -377,202 +394,20 @@ clbss_l:str r2, [r0] /* clear loop... */ _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 */ + ldr r0, _board_init_r_ofs + adr r1, _start + add lr, r0, r1 + add lr, lr, r9 /* 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 - */ - -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 */ - -#ifndef CONFIG_SKIP_RELOCATE_UBOOT -relocate: /* relocate U-Boot to RAM */ - adr r0, _start /* r0 <- current position of code */ - ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ - cmp r0, r1 /* don't reloc during debug */ - beq stack_setup - - ldr r2, _armboot_start - ldr r3, _bss_start - sub r2, r3, r2 /* r2 <- size of armboot */ - add r2, r0, r2 /* r2 <- source end address */ - -copy_loop: - ldmia r0!, {r3-r10} /* copy from source address [r0] */ - stmia r1!, {r3-r10} /* copy to target address [r1] */ - cmp r0, r2 /* until source end address [r2] */ - blo copy_loop -#endif /* 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: +_board_init_r_ofs: + .word board_init_r - _start #endif - /* Set up the stack */ -stack_setup: - ldr r0, =CONFIG_SYS_UBOOT_BASE /* base of copy in DRAM */ - 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 */ - ldr r1, _bss_end /* stop here */ - mov r2, #0 /* clear */ - -clbss_l: - str r2, [r0] /* clear loop... */ - add r0, r0, #4 - cmp r0, r1 - blo clbss_l - -#ifndef CONFIG_NAND_SPL - ldr pc, _start_armboot - -_start_armboot: - .word start_armboot -#else - b nand_boot -/* .word nand_boot*/ -#endif - -#endif /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */ - #ifdef CONFIG_ENABLE_MMU _mmu_table_base: .word mmu_table @@ -659,14 +494,7 @@ 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 */ @@ -681,16 +509,7 @@ 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] @@ -715,16 +534,7 @@ 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 */ |