diff options
Diffstat (limited to 'arch/arm/cpu')
33 files changed, 3119 insertions, 26 deletions
diff --git a/arch/arm/cpu/arm1136/start.S b/arch/arm/cpu/arm1136/start.S index 41eb82dae24..8b631920c94 100644 --- a/arch/arm/cpu/arm1136/start.S +++ b/arch/arm/cpu/arm1136/start.S @@ -85,12 +85,15 @@ _end_vect: ************************************************************************* */ +.globl _TEXT_BASE _TEXT_BASE: .word TEXT_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. @@ -103,6 +106,32 @@ _bss_start: _bss_end: .word _end +#if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) +.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 +#endif + #ifdef CONFIG_USE_IRQ /* IRQ stack memory (calculated at run-time) */ .globl IRQ_STACK_START @@ -115,6 +144,164 @@ FIQ_STACK_START: .word 0x0badc0de #endif +#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 +#endif + +#if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) +/* + * the actual reset code + */ + +reset: + /* + * set the cpu to SVC32 mode + */ + mrs r0,cpsr + bic r0,r0,#0x1f + orr r0,r0,#0xd3 + msr cpsr,r0 + +#ifdef CONFIG_OMAP2420H4 + /* Copy vectors to mask ROM indirect addr */ + adr r0, _start /* r0 <- current position of code */ + add r0, r0, #4 /* skip reset vector */ + mov r2, #64 /* r2 <- size to copy */ + add r2, r0, r2 /* r2 <- source end address */ + mov r1, #SRAM_OFFSET0 /* build vect addr */ + mov r3, #SRAM_OFFSET1 + add r1, r1, r3 + mov r3, #SRAM_OFFSET2 + add r1, r1, r3 +next: + 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] */ + bne next /* loop until equal */ + bl cpy_clk_code /* put dpll adjust code behind vectors */ +#endif + /* the mask ROM code should have PLL and others stable */ +#ifndef CONFIG_SKIP_LOWLEVEL_INIT + bl cpu_init_crit +#endif + +/* 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 */ + + /* 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 addreee [r2] */ + ble copy_loop + +#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 +#endif /* #ifndef CONFIG_SKIP_RELOCATE_UBOOT */ + +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 +#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 + ldr pc, _nand_boot + +_nand_boot: .word nand_boot +#else +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 +#else /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */ /* * the actual reset code */ @@ -211,6 +398,8 @@ _start_armboot: .word start_armboot #endif /* CONFIG_ONENAND_IPL */ #endif /* CONFIG_NAND_SPL */ +#endif /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */ + /* ************************************************************************* * @@ -295,9 +484,13 @@ 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 +#if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) + ldr r2, IRQ_STACK_START_IN @ set base 2 words into abort stack +#else 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 +#endif 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 +521,13 @@ cpu_init_crit: .endm .macro get_bad_stack +#if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) + ldr r13, IRQ_STACK_START_IN @ setup our mode stack (enter in banked mode) +#else 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 +#endif str lr, [r13] @ save caller lr in position 0 of saved stack mrs lr, spsr @ get the spsr @@ -346,9 +543,13 @@ 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. +#if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) + ldr r0, IRQ_STACK_START_IN @ get data regions start +#else 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 +#endif 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 @@ -439,6 +640,11 @@ fiq: .align 5 .global arm1136_cache_flush arm1136_cache_flush: +#if !defined(CONFIG_SYS_NO_ICACHE) mcr p15, 0, r1, c7, c5, 0 @ invalidate I cache +#endif +#if !defined(CONFIG_SYS_NO_DCACHE) + mcr p15, 0, r1, c7, c14, 0 @ invalidate D cache +#endif mov pc, lr @ back to caller #endif /* CONFIG_PRELOADER */ diff --git a/arch/arm/cpu/arm1136/u-boot.lds b/arch/arm/cpu/arm1136/u-boot.lds index e7eefc972c4..1db4b49cc75 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/cpu/arm1176/start.S b/arch/arm/cpu/arm1176/start.S index f98a7aa3552..e5e7913d948 100644 --- a/arch/arm/cpu/arm1176/start.S +++ b/arch/arm/cpu/arm1176/start.S @@ -95,6 +95,7 @@ _end_vect: ************************************************************************* */ +.globl _TEXT_BASE _TEXT_BASE: .word TEXT_BASE @@ -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 - 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 addreee [r2] */ + ble 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 */ @@ -299,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 @@ -385,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 */ @@ -403,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] @@ -433,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 */ diff --git a/arch/arm/cpu/arm1176/u-boot.lds b/arch/arm/cpu/arm1176/u-boot.lds index 8969587e8c6..fa640eec200 100644 --- a/arch/arm/cpu/arm1176/u-boot.lds +++ b/arch/arm/cpu/arm1176/u-boot.lds @@ -39,11 +39,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/cpu/arm720t/start.S b/arch/arm/cpu/arm720t/start.S index d6f2c165c72..0f5f6c46111 100644 --- a/arch/arm/cpu/arm720t/start.S +++ b/arch/arm/cpu/arm720t/start.S @@ -75,12 +75,15 @@ _fiq: .word fiq ************************************************************************* */ +.globl _TEXT_BASE _TEXT_BASE: .word TEXT_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. @@ -105,6 +108,163 @@ FIQ_STACK_START: .word 0x0badc0de #endif +#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,#0x1f + orr r0,r0,#0xd3 + msr cpsr,r0 + + /* + * we do sys-critical inits only at reboot, + * not when booting from ram! + */ +#ifndef CONFIG_SKIP_LOWLEVEL_INIT + bl cpu_init_crit +#endif + +#ifdef CONFIG_LPC2292 + bl lowlevel_init +#endif + +/* 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 addreee [r2] */ + ble 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 */ + +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. + */ + 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 + +#else /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */ /* * the actual reset code @@ -188,6 +348,8 @@ clbss_l:str r2, [r0] /* clear loop... */ _start_armboot: .word start_armboot +#endif /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */ + /* ************************************************************************* * @@ -444,9 +606,13 @@ lock_loop: stmia sp, {r0 - r12} @ Calling r0-r12 add r8, sp, #S_PC +#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC) ldr r2, _armboot_start sub r2, r2, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ set base 2 words into abort stack +#else + ldr r2, IRQ_STACK_START_IN +#endif ldmia r2, {r2 - r4} @ get pc, cpsr, old_r0 add r0, sp, #S_FRAME_SIZE @ restore sp_SVC @@ -477,9 +643,13 @@ lock_loop: .endm .macro get_bad_stack +#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC) ldr r13, _armboot_start @ setup our mode stack sub r13, r13, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack +#else + ldr r13, IRQ_STACK_START_IN @ setup our mode stack +#endif str lr, [r13] @ save caller lr / spsr mrs lr, spsr diff --git a/arch/arm/cpu/arm720t/u-boot.lds b/arch/arm/cpu/arm720t/u-boot.lds index c975fc3d5e4..4a0bc70c770 100644 --- a/arch/arm/cpu/arm720t/u-boot.lds +++ b/arch/arm/cpu/arm720t/u-boot.lds @@ -39,11 +39,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/cpu/arm920t/start.S b/arch/arm/cpu/arm920t/start.S index e532f55bfcb..a079bb27271 100644 --- a/arch/arm/cpu/arm920t/start.S +++ b/arch/arm/cpu/arm920t/start.S @@ -70,12 +70,15 @@ _fiq: .word fiq ************************************************************************* */ +.globl _TEXT_BASE _TEXT_BASE: .word TEXT_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. @@ -100,6 +103,35 @@ FIQ_STACK_START: .word 0x0badc0de #endif +#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 start code @@ -176,6 +208,189 @@ copyex: bl cpu_init_crit #endif +/* 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 addreee [r2] */ + ble 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 */ + +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 start code + */ + +start_code: + /* + * set the cpu to SVC32 mode + */ + mrs r0, cpsr + bic r0, r0, #0x1f + orr r0, r0, #0xd3 + msr cpsr, r0 + + bl coloured_LED_init + bl red_LED_on + +#if defined(CONFIG_AT91RM9200DK) || defined(CONFIG_AT91RM9200EK) + /* + * relocate exception table + */ + ldr r0, =_start + ldr r1, =0x0 + mov r2, #16 +copyex: + subs r2, r2, #1 + ldr r3, [r0], #4 + str r3, [r1], #4 + bne copyex +#endif + +#ifdef CONFIG_S3C24X0 + /* turn off the watchdog */ + +# if defined(CONFIG_S3C2400) +# define pWTCON 0x15300000 +# define INTMSK 0x14400008 /* Interupt-Controller base addresses */ +# define CLKDIVN 0x14800014 /* clock divisor register */ +#else +# define pWTCON 0x53000000 +# define INTMSK 0x4A000008 /* Interupt-Controller base addresses */ +# define INTSUBMSK 0x4A00001C +# define CLKDIVN 0x4C000014 /* clock divisor register */ +# endif + + ldr r0, =pWTCON + mov r1, #0x0 + str r1, [r0] + + /* + * mask all IRQs by setting all bits in the INTMR - default + */ + mov r1, #0xffffffff + ldr r0, =INTMSK + str r1, [r0] +# if defined(CONFIG_S3C2410) + ldr r1, =0x3ff + ldr r0, =INTSUBMSK + str r1, [r0] +# endif + + /* FCLK:HCLK:PCLK = 1:2:4 */ + /* default FCLK is 120 MHz ! */ + ldr r0, =CLKDIVN + mov r1, #3 + str r1, [r0] +#endif /* CONFIG_S3C24X0 */ + + /* + * we do sys-critical inits only at reboot, + * not when booting from ram! + */ +#ifndef CONFIG_SKIP_LOWLEVEL_INIT + bl cpu_init_crit +#endif + #ifndef CONFIG_SKIP_RELOCATE_UBOOT relocate: /* relocate U-Boot to RAM */ adr r0, _start /* r0 <- current position of code */ @@ -219,7 +434,7 @@ clbss_l:str r2, [r0] /* clear loop... */ ldr pc, _start_armboot _start_armboot: .word start_armboot - +#endif /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */ /* ************************************************************************* @@ -309,11 +524,15 @@ cpu_init_crit: .macro bad_save_user_regs sub sp, sp, #S_FRAME_SIZE stmia sp, {r0 - r12} @ Calling r0-r12 +#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC) ldr r2, _armboot_start sub r2, r2, #(CONFIG_STACKSIZE) 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 ldmia r2, {r2 - r3} @ get pc, cpsr add r0, sp, #S_FRAME_SIZE @ restore sp_SVC @@ -345,11 +564,15 @@ cpu_init_crit: .endm .macro get_bad_stack +#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC) ldr r13, _armboot_start @ setup our mode stack sub r13, r13, #(CONFIG_STACKSIZE) sub r13, r13, #(CONFIG_SYS_MALLOC_LEN) /* reserve a couple spots in abort stack */ sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) +#else + ldr r13, IRQ_STACK_START_IN @ setup our mode stack +#endif str lr, [r13] @ save caller lr / spsr mrs lr, spsr diff --git a/arch/arm/cpu/arm920t/u-boot.lds b/arch/arm/cpu/arm920t/u-boot.lds index a7decfcd7db..69854347952 100644 --- a/arch/arm/cpu/arm920t/u-boot.lds +++ b/arch/arm/cpu/arm920t/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/cpu/arm925t/start.S b/arch/arm/cpu/arm925t/start.S index 346615e4b4d..c0a856dfe1d 100644 --- a/arch/arm/cpu/arm925t/start.S +++ b/arch/arm/cpu/arm925t/start.S @@ -81,12 +81,15 @@ _fiq: .word fiq ************************************************************************* */ +.globl _TEXT_BASE _TEXT_BASE: .word TEXT_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. @@ -111,7 +114,198 @@ FIQ_STACK_START: .word 0x0badc0de #endif +#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,#0x1f + orr r0,r0,#0xd3 + msr cpsr,r0 + + /* + * Set up 925T mode + */ + mov r1, #0x81 /* Set ARM925T configuration. */ + mcr p15, 0, r1, c15, c1, 0 /* Write ARM925T configuration register. */ + + /* + * turn off the watchdog, unlock/diable sequence + */ + mov r1, #0xF5 + ldr r0, =WDTIM_MODE + strh r1, [r0] + mov r1, #0xA0 + strh r1, [r0] + + /* + * mask all IRQs by setting all bits in the INTMR - default + */ + mov r1, #0xffffffff + ldr r0, =REG_IHL1_MIR + str r1, [r0] + ldr r0, =REG_IHL2_MIR + str r1, [r0] + + /* + * wait for dpll to lock + */ + ldr r0, =CK_DPLL1 + mov r1, #0x10 + strh r1, [r0] +poll1: + ldrh r1, [r0] + ands r1, r1, #0x01 + beq poll1 + + /* + * we do sys-critical inits only at reboot, + * not when booting from ram! + */ +#ifndef CONFIG_SKIP_LOWLEVEL_INIT + bl cpu_init_crit +#endif + +/* 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 addreee [r2] */ + ble 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 */ + +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 +#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 */ @@ -211,7 +405,7 @@ clbss_l:str r2, [r0] /* clear loop... */ ldr pc, _start_armboot _start_armboot: .word start_armboot - +#endif /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */ /* ************************************************************************* @@ -295,9 +489,13 @@ 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 +#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC) ldr r2, _armboot_start sub r2, r2, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ set base 2 words into abort stack +#else + ldr r2, IRQ_STACK_START_IN +#endif 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 +526,13 @@ cpu_init_crit: .endm .macro get_bad_stack +#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC) ldr r13, _armboot_start @ setup our mode stack sub r13, r13, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack +#else + ldr r13, IRQ_STACK_START_IN +#endif str lr, [r13] @ save caller lr in position 0 of saved stack mrs lr, spsr @ get the spsr diff --git a/arch/arm/cpu/arm925t/u-boot.lds b/arch/arm/cpu/arm925t/u-boot.lds index e21d6dc5a7d..1c4e9bcfb50 100644 --- a/arch/arm/cpu/arm925t/u-boot.lds +++ b/arch/arm/cpu/arm925t/u-boot.lds @@ -42,11 +42,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/cpu/arm926ejs/orion5x/dram.c b/arch/arm/cpu/arm926ejs/orion5x/dram.c index c719798a660..c5c8ab7e4d8 100644 --- a/arch/arm/cpu/arm926ejs/orion5x/dram.c +++ b/arch/arm/cpu/arm926ejs/orion5x/dram.c @@ -49,7 +49,7 @@ u32 orion5x_sdram_bar(enum memory_bank bank) result = winregs[bank].base; return result; } - +#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC) int dram_init(void) { int i; @@ -62,3 +62,25 @@ int dram_init(void) } return 0; } +#else +int dram_init (void) +{ + /* dram_init must store complete ramsize in gd->ram_size */ + gd->ram_size = get_ram_size( + (volatile long *) orion5x_sdram_bar(0), + CONFIG_MAX_RAM_BANK_SIZE); + return 0; +} + +void dram_init_banksize (void) +{ + int i; + + for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { + gd->bd->bi_dram[i].start = orion5x_sdram_bar(i); + gd->bd->bi_dram[i].size = get_ram_size( + (volatile long *) (gd->bd->bi_dram[i].start), + CONFIG_MAX_RAM_BANK_SIZE); + } +} +#endif diff --git a/arch/arm/cpu/arm926ejs/start.S b/arch/arm/cpu/arm926ejs/start.S index cf40ce12928..16ee972f2b9 100644 --- a/arch/arm/cpu/arm926ejs/start.S +++ b/arch/arm/cpu/arm926ejs/start.S @@ -114,12 +114,15 @@ _fiq: ************************************************************************* */ +.globl _TEXT_BASE _TEXT_BASE: .word TEXT_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. @@ -144,6 +147,35 @@ FIQ_STACK_START: .word 0x0badc0de #endif +#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 @@ -166,6 +198,135 @@ reset: bl cpu_init_crit #endif +/* 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 addreee [r2] */ + ble 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 */ + +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 + */ + +reset: + /* + * set the cpu to SVC32 mode + */ + mrs r0,cpsr + bic r0,r0,#0x1f + orr r0,r0,#0xd3 + msr cpsr,r0 + + /* + * we do sys-critical inits only at reboot, + * not when booting from ram! + */ +#ifndef CONFIG_SKIP_LOWLEVEL_INIT + bl cpu_init_crit +#endif + #ifndef CONFIG_SKIP_RELOCATE_UBOOT relocate: /* relocate U-Boot to RAM */ adr r0, _start /* r0 <- current position of code */ @@ -221,7 +382,7 @@ _start_armboot: #else .word start_armboot #endif /* CONFIG_NAND_SPL */ - +#endif /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */ /* ************************************************************************* @@ -307,10 +468,13 @@ cpu_init_crit: @ carve out a frame on current user stack sub sp, sp, #S_FRAME_SIZE stmia sp, {r0 - r12} @ Save user registers (now in svc mode) r0-r12 - +#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC) ldr r2, _armboot_start sub r2, r2, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ set base 2 words into abort stack +#else + ldr r2, IRQ_STACK_START_IN +#endif @ get values for "aborted" pc and cpsr (into parm regs) ldmia r2, {r2 - r3} add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack @@ -342,9 +506,13 @@ cpu_init_crit: .endm .macro get_bad_stack +#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC) ldr r13, _armboot_start @ setup our mode stack sub r13, r13, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack +#else + ldr r13, IRQ_STACK_START_IN @ setup our mode stack +#endif str lr, [r13] @ save caller lr in position 0 of saved stack mrs lr, spsr @ get the spsr diff --git a/arch/arm/cpu/arm926ejs/u-boot.lds b/arch/arm/cpu/arm926ejs/u-boot.lds index ecbc58c7c24..02eb8ca6072 100644 --- a/arch/arm/cpu/arm926ejs/u-boot.lds +++ b/arch/arm/cpu/arm926ejs/u-boot.lds @@ -39,11 +39,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/cpu/arm946es/start.S b/arch/arm/cpu/arm946es/start.S index 8844d4438b5..18ed0b2da41 100644 --- a/arch/arm/cpu/arm946es/start.S +++ b/arch/arm/cpu/arm946es/start.S @@ -85,12 +85,15 @@ _fiq: ************************************************************************* */ +.globl _TEXT_BASE _TEXT_BASE: .word TEXT_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. @@ -115,7 +118,162 @@ FIQ_STACK_START: .word 0x0badc0de #endif +#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,#0x1f + orr r0,r0,#0xd3 + msr cpsr,r0 + + /* + * we do sys-critical inits only at reboot, + * not when booting from ram! + */ +#ifndef CONFIG_SKIP_LOWLEVEL_INIT + bl cpu_init_crit +#endif + +/* 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 addreee [r2] */ + ble 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 */ + +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 +#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 */ @@ -179,7 +337,7 @@ clbss_l:str r2, [r0] /* clear loop... */ _start_armboot: .word start_armboot - +#endif /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */ /* ************************************************************************* @@ -266,9 +424,13 @@ cpu_init_crit: sub sp, sp, #S_FRAME_SIZE stmia sp, {r0 - r12} @ Save user registers (now in svc mode) r0-r12 +#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC) ldr r2, _armboot_start sub r2, r2, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ set base 2 words into abort stack +#else + ldr r2, IRQ_STACK_START_IN +#endif @ get values for "aborted" pc and cpsr (into parm regs) ldmia r2, {r2 - r3} add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack @@ -300,9 +462,13 @@ cpu_init_crit: .endm .macro get_bad_stack +#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC) ldr r13, _armboot_start @ setup our mode stack sub r13, r13, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack +#else + ldr r13, IRQ_STACK_START_IN @ setup our mode stack +#endif str lr, [r13] @ save caller lr in position 0 of saved stack mrs lr, spsr @ get the spsr diff --git a/arch/arm/cpu/arm946es/u-boot.lds b/arch/arm/cpu/arm946es/u-boot.lds index fef21c7587f..65359630933 100644 --- a/arch/arm/cpu/arm946es/u-boot.lds +++ b/arch/arm/cpu/arm946es/u-boot.lds @@ -39,11 +39,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/cpu/arm_intcm/start.S b/arch/arm/cpu/arm_intcm/start.S index 328bae02741..b39fdc64c41 100644 --- a/arch/arm/cpu/arm_intcm/start.S +++ b/arch/arm/cpu/arm_intcm/start.S @@ -83,12 +83,15 @@ _fiq: ************************************************************************* */ +.globl _TEXT_BASE _TEXT_BASE: .word TEXT_BASE /* address of _start in the linked image */ +#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC) .globl _armboot_start _armboot_start: .word _start +#endif /* * These are defined in the board-specific linker script. @@ -113,6 +116,159 @@ FIQ_STACK_START: .word 0x0badc0de #endif +#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,#0x1f + orr r0,r0,#0xd3 + msr cpsr,r0 + + /* + * we do sys-critical inits only at reboot, + * not when booting from ram! + */ +#ifndef CONFIG_SKIP_LOWLEVEL_INIT + bl cpu_init_crit +#endif + +/* 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 addreee [r2] */ + ble 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 */ + +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. + */ + 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 + +#else /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */ /* * the actual reset code @@ -178,6 +334,8 @@ clbss_l:str r2, [r0] /* clear loop... */ _start_armboot: .word start_armboot +#endif /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */ + /* ************************************************************************* * @@ -242,9 +400,13 @@ cpu_init_crit: sub sp, sp, #S_FRAME_SIZE stmia sp, {r0 - r12} @ Save user registers (now in svc mode) r0-r12 +#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC) ldr r2, _armboot_start sub r2, r2, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ set base 2 words into abort stack +#else + ldr r2, IRQ_STACK_START_IN +#endif @ get values for "aborted" pc and cpsr (into parm regs) ldmia r2, {r2 - r3} add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack @@ -276,9 +438,13 @@ cpu_init_crit: .endm .macro get_bad_stack +#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC) ldr r13, _armboot_start @ setup our mode stack sub r13, r13, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack +#else + ldr r13, IRQ_STACK_START_IN @ setup our mode stack +#endif str lr, [r13] @ save caller lr in position 0 of saved stack mrs lr, spsr @ get the spsr diff --git a/arch/arm/cpu/arm_intcm/u-boot.lds b/arch/arm/cpu/arm_intcm/u-boot.lds index 4ed7d8906d3..242c7ece020 100644 --- a/arch/arm/cpu/arm_intcm/u-boot.lds +++ b/arch/arm/cpu/arm_intcm/u-boot.lds @@ -39,11 +39,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/cpu/armv7/mx51/u-boot.lds b/arch/arm/cpu/armv7/mx51/u-boot.lds index d66434c95d6..55d6599b41c 100644 --- a/arch/arm/cpu/armv7/mx51/u-boot.lds +++ b/arch/arm/cpu/armv7/mx51/u-boot.lds @@ -44,10 +44,22 @@ SECTIONS .rodata : { *(.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 = .; diff --git a/arch/arm/cpu/armv7/omap3/cache.S b/arch/arm/cpu/armv7/omap3/cache.S index fdc1666fe9a..cda87ba1af3 100644 --- a/arch/arm/cpu/armv7/omap3/cache.S +++ b/arch/arm/cpu/armv7/omap3/cache.S @@ -181,3 +181,83 @@ setup_auxcr: orrlt r0, r0, #1 << 27 .word 0xE1600070 @ SMC bx lr + +.align 5 +.global v7_flush_dcache_all +.global v7_flush_cache_all + +/* + * v7_flush_dcache_all() + * + * Flush the whole D-cache. + * + * Corrupted registers: r0-r7, r9-r11 (r6 only in Thumb mode) + * + * - mm - mm_struct describing address space + */ +v7_flush_dcache_all: +# dmb @ ensure ordering with previous memory accesses + mrc p15, 1, r0, c0, c0, 1 @ read clidr + ands r3, r0, #0x7000000 @ extract loc from clidr + mov r3, r3, lsr #23 @ left align loc bit field + beq finished @ if loc is 0, then no need to clean + mov r10, #0 @ start clean at cache level 0 +loop1: + add r2, r10, r10, lsr #1 @ work out 3x current cache level + mov r1, r0, lsr r2 @ extract cache type bits from clidr + and r1, r1, #7 @ mask of the bits for current cache only + cmp r1, #2 @ see what cache we have at this level + blt skip @ skip if no cache, or just i-cache + mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr + mcr p15, 0, r10, c7, c5, 4 @ flush prefetch buffer, + @ with armv7 this is 'isb', + @ but we compile with armv5 + mrc p15, 1, r1, c0, c0, 0 @ read the new csidr + and r2, r1, #7 @ extract the length of the cache lines + add r2, r2, #4 @ add 4 (line length offset) + ldr r4, =0x3ff + ands r4, r4, r1, lsr #3 @ find maximum number on the way size + clz r5, r4 @ find bit position of way size increment + ldr r7, =0x7fff + ands r7, r7, r1, lsr #13 @ extract max number of the index size +loop2: + mov r9, r4 @ create working copy of max way size +loop3: + orr r11, r10, r9, lsl r5 @ factor way and cache number into r11 + orr r11, r11, r7, lsl r2 @ factor index number into r11 + mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way + subs r9, r9, #1 @ decrement the way + bge loop3 + subs r7, r7, #1 @ decrement the index + bge loop2 +skip: + add r10, r10, #2 @ increment cache number + cmp r3, r10 + bgt loop1 +finished: + mov r10, #0 @ swith back to cache level 0 + mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr +# dsb + mcr p15, 0, r10, c7, c5, 4 @ flush prefetch buffer, + @ with armv7 this is 'isb', + @ but we compile with armv5 + mov pc, lr + +/* + * v7_flush_cache_all() + * + * Flush the entire cache system. + * The data cache flush is now achieved using atomic clean / invalidates + * working outwards from L1 cache. This is done using Set/Way based cache + * maintainance instructions. + * The instruction cache can still be invalidated back to the point of + * unification in a single instruction. + * + */ +v7_flush_cache_all: + stmfd sp!, {r0-r7, r9-r11, lr} + bl v7_flush_dcache_all + mov r0, #0 + mcr p15, 0, r0, c7, c5, 0 @ I+BTB cache invalidate + ldmfd sp!, {r0-r7, r9-r11, lr} + mov pc, lr diff --git a/arch/arm/cpu/armv7/omap3/emif4.c b/arch/arm/cpu/armv7/omap3/emif4.c index fae5b1161b0..da2cd900130 100644 --- a/arch/arm/cpu/armv7/omap3/emif4.c +++ b/arch/arm/cpu/armv7/omap3/emif4.c @@ -136,6 +136,7 @@ void do_emif4_init(void) * dram_init - * - Sets uboots idea of sdram size */ +#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC) int dram_init(void) { DECLARE_GLOBAL_DATA_PTR; @@ -157,6 +158,39 @@ int dram_init(void) return 0; } +#else +int dram_init(void) +{ + DECLARE_GLOBAL_DATA_PTR; + unsigned int size0 = 0, size1 = 0; + + size0 = get_sdr_cs_size(CS0); + /* + * If a second bank of DDR is attached to CS1 this is + * where it can be started. Early init code will init + * memory on CS0. + */ + if ((sysinfo.mtype == DDR_COMBO) || (sysinfo.mtype == DDR_STACKED)) + size1 = get_sdr_cs_size(CS1); + + gd->ram_size = size0 + size1; + return 0; +} + +void dram_init_banksize (void) +{ + DECLARE_GLOBAL_DATA_PTR; + unsigned int size0 = 0, size1 = 0; + + size0 = get_sdr_cs_size(CS0); + size1 = get_sdr_cs_size(CS1); + + gd->bd->bi_dram[0].start = PHYS_SDRAM_1; + gd->bd->bi_dram[0].size = size0; + gd->bd->bi_dram[1].start = PHYS_SDRAM_1 + get_sdr_cs_offset(CS1); + gd->bd->bi_dram[1].size = size1; +} +#endif /* * mem_init() - diff --git a/arch/arm/cpu/armv7/omap3/sdrc.c b/arch/arm/cpu/armv7/omap3/sdrc.c index 8905224439b..2719bb53a7c 100644 --- a/arch/arm/cpu/armv7/omap3/sdrc.c +++ b/arch/arm/cpu/armv7/omap3/sdrc.c @@ -163,6 +163,7 @@ void do_sdrc_init(u32 cs, u32 early) * dram_init - * - Sets uboots idea of sdram size */ +#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC) int dram_init(void) { DECLARE_GLOBAL_DATA_PTR; @@ -188,6 +189,43 @@ int dram_init(void) return 0; } +#else +int dram_init(void) +{ + DECLARE_GLOBAL_DATA_PTR; + unsigned int size0 = 0, size1 = 0; + + size0 = get_sdr_cs_size(CS0); + /* + * If a second bank of DDR is attached to CS1 this is + * where it can be started. Early init code will init + * memory on CS0. + */ + if ((sysinfo.mtype == DDR_COMBO) || (sysinfo.mtype == DDR_STACKED)) { + do_sdrc_init(CS1, NOT_EARLY); + make_cs1_contiguous(); + + size1 = get_sdr_cs_size(CS1); + } + gd->ram_size = size0 + size1; + + return 0; +} + +void dram_init_banksize (void) +{ + DECLARE_GLOBAL_DATA_PTR; + unsigned int size0 = 0, size1 = 0; + + size0 = get_sdr_cs_size(CS0); + size1 = get_sdr_cs_size(CS1); + + gd->bd->bi_dram[0].start = PHYS_SDRAM_1; + gd->bd->bi_dram[0].size = size0; + gd->bd->bi_dram[1].start = PHYS_SDRAM_1 + get_sdr_cs_offset(CS1); + gd->bd->bi_dram[1].size = size1; +} +#endif /* * mem_init - diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S index 1e0a1504bfc..f411c0f4f05 100644 --- a/arch/arm/cpu/armv7/start.S +++ b/arch/arm/cpu/armv7/start.S @@ -65,12 +65,15 @@ _end_vect: * *************************************************************************/ +.globl _TEXT_BASE _TEXT_BASE: .word TEXT_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. @@ -95,6 +98,176 @@ FIQ_STACK_START: .word 0x0badc0de #endif +#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, #0x1f + orr r0, r0, #0xd3 + msr cpsr,r0 + +#if (CONFIG_OMAP34XX) + /* Copy vectors to mask ROM indirect addr */ + adr r0, _start @ r0 <- current position of code + add r0, r0, #4 @ skip reset vector + mov r2, #64 @ r2 <- size to copy + add r2, r0, r2 @ r2 <- source end address + mov r1, #SRAM_OFFSET0 @ build vect addr + mov r3, #SRAM_OFFSET1 + add r1, r1, r3 + mov r3, #SRAM_OFFSET2 + add r1, r1, r3 +next: + 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] + bne next @ loop until equal */ +#if !defined(CONFIG_SYS_NAND_BOOT) && !defined(CONFIG_SYS_ONENAND_BOOT) + /* No need to copy/exec the clock code - DPLL adjust already done + * in NAND/oneNAND Boot. + */ + bl cpy_clk_code @ put dpll adjust code behind vectors +#endif /* NAND Boot */ +#endif + /* the mask ROM code should have PLL and others stable */ +#ifndef CONFIG_SKIP_LOWLEVEL_INIT + bl cpu_init_crit +#endif + +/* 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 + +#ifndef CONFIG_SKIP_RELOCATE_UBOOT + 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 +#ifndef CONFIG_PRELOADER + beq jump_2_ram +#endif + +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 addreee [r2] */ + ble copy_loop + +#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 + +clear_bss: + 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 +#endif /* #ifndef CONFIG_PRELOADER */ +#endif /* #ifndef CONFIG_SKIP_RELOCATE_UBOOT */ + +/* + * We are done. Do not return, instead branch to second part of board + * initialization, now running from RAM. + */ +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 +#else /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */ /* * the actual reset code */ @@ -180,7 +353,7 @@ clbss_l: ldr pc, _start_armboot @ jump to C code _start_armboot: .word start_armboot - +#endif /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */ /************************************************************************* * @@ -263,11 +436,14 @@ cpu_init_crit: @ user stack stmia sp, {r0 - r12} @ Save user registers (now in @ svc mode) r0-r12 - +#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC) 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 +#else + ldr r2, IRQ_STACK_START_IN @ set base 2 words into abort @ stack +#endif 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 @@ -303,11 +479,14 @@ cpu_init_crit: .endm .macro get_bad_stack +#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC) 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 +#else + ldr r13, IRQ_STACK_START_IN @ setup our mode stack (enter + @ in banked mode) +#endif str lr, [r13] @ save caller lr in position 0 @ of saved stack @@ -328,10 +507,14 @@ cpu_init_crit: sub r13, r13, #4 @ space on current stack for @ scratch reg. str r0, [r13] @ save R0's value. +#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC) 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 +#else + ldr r0, IRQ_STACK_START_IN @ get data regions start @ spots for abort stack +#endif str lr, [r0] @ save caller lr in position 0 @ of saved stack mrs r0, spsr @ get the spsr diff --git a/arch/arm/cpu/armv7/u-boot.lds b/arch/arm/cpu/armv7/u-boot.lds index 9e5b5a97d74..d4fd3fccee6 100644 --- a/arch/arm/cpu/armv7/u-boot.lds +++ b/arch/arm/cpu/armv7/u-boot.lds @@ -42,10 +42,22 @@ 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/cpu/ixp/start.S b/arch/arm/cpu/ixp/start.S index 6efe333f1a1..b2c8255141e 100644 --- a/arch/arm/cpu/ixp/start.S +++ b/arch/arm/cpu/ixp/start.S @@ -93,12 +93,15 @@ _fiq: .word fiq * - jump to second stage */ +.globl _TEXT_BASE _TEXT_BASE: .word TEXT_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. @@ -123,6 +126,274 @@ FIQ_STACK_START: .word 0x0badc0de #endif +#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: + /* disable mmu, set big-endian */ + mov r0, #0xf8 + mcr p15, 0, r0, c1, c0, 0 + CPWAIT r0 + + /* invalidate I & D caches & BTB */ + mcr p15, 0, r0, c7, c7, 0 + CPWAIT r0 + + /* invalidate I & Data TLB */ + mcr p15, 0, r0, c8, c7, 0 + CPWAIT r0 + + /* drain write and fill buffers */ + mcr p15, 0, r0, c7, c10, 4 + CPWAIT r0 + + /* disable write buffer coalescing */ + mrc p15, 0, r0, c1, c0, 1 + orr r0, r0, #1 + mcr p15, 0, r0, c1, c0, 1 + CPWAIT r0 + + /* set EXP CS0 to the optimum timing */ + ldr r1, =CONFIG_SYS_EXP_CS0 + ldr r2, =IXP425_EXP_CS0 + str r1, [r2] + + /* make sure flash is visible at 0 */ +#if 0 + ldr r2, =IXP425_EXP_CFG0 + ldr r1, [r2] + orr r1, r1, #0x80000000 + str r1, [r2] +#endif + mov r1, #CONFIG_SYS_SDR_CONFIG + ldr r2, =IXP425_SDR_CONFIG + str r1, [r2] + + /* disable refresh cycles */ + mov r1, #0 + ldr r3, =IXP425_SDR_REFRESH + str r1, [r3] + + /* send nop command */ + mov r1, #3 + ldr r4, =IXP425_SDR_IR + str r1, [r4] + DELAY_FOR 0x4000, r0 + + /* set SDRAM internal refresh val */ + ldr r1, =CONFIG_SYS_SDRAM_REFRESH_CNT + str r1, [r3] + DELAY_FOR 0x4000, r0 + + /* send precharge-all command to close all open banks */ + mov r1, #2 + str r1, [r4] + DELAY_FOR 0x4000, r0 + + /* provide 8 auto-refresh cycles */ + mov r1, #4 + mov r5, #8 +111: str r1, [r4] + DELAY_FOR 0x100, r0 + subs r5, r5, #1 + bne 111b + + /* set mode register in sdram */ + mov r1, #CONFIG_SYS_SDR_MODE_CONFIG + str r1, [r4] + DELAY_FOR 0x4000, r0 + + /* send normal operation command */ + mov r1, #6 + str r1, [r4] + DELAY_FOR 0x4000, r0 + + /* copy */ + mov r0, #0 + mov r4, r0 + add r2, r0, #CONFIG_SYS_MONITOR_LEN + mov r1, #0x10000000 + mov r5, r1 + + 30: + ldr r3, [r0], #4 + str r3, [r1], #4 + cmp r0, r2 + bne 30b + + /* invalidate I & D caches & BTB */ + mcr p15, 0, r0, c7, c7, 0 + CPWAIT r0 + + /* invalidate I & Data TLB */ + mcr p15, 0, r0, c8, c7, 0 + CPWAIT r0 + + /* drain write and fill buffers */ + mcr p15, 0, r0, c7, c10, 4 + CPWAIT r0 + + /* move flash to 0x50000000 */ + ldr r2, =IXP425_EXP_CFG0 + ldr r1, [r2] + bic r1, r1, #0x80000000 + str r1, [r2] + + nop + nop + nop + nop + nop + nop + + /* invalidate I & Data TLB */ + mcr p15, 0, r0, c8, c7, 0 + CPWAIT r0 + + /* enable I cache */ + mrc p15, 0, r0, c1, c0, 0 + orr r0, r0, #MMU_Control_I + mcr p15, 0, r0, c1, c0, 0 + CPWAIT r0 + + mrs r0,cpsr /* set the cpu to SVC32 mode */ + bic r0,r0,#0x1f /* (superviser mode, M=10011) */ + orr r0,r0,#0x13 + msr cpsr,r0 + +/* 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 addreee [r2] */ + ble 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 */ + +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. + */ + 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 + +#else /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */ /****************************************************************************/ /* */ /* the actual reset code */ @@ -304,6 +575,7 @@ clbss_l:str r2, [r0] /* clear loop... */ ldr pc, _start_armboot _start_armboot: .word start_armboot +#endif /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */ /****************************************************************************/ @@ -345,9 +617,13 @@ _start_armboot: .word start_armboot stmia sp, {r0 - r12} /* Calling r0-r12 */ add r8, sp, #S_PC +#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC) ldr r2, _armboot_start sub r2, r2, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ set base 2 words into abort stack +#else + ldr r2, IRQ_STACK_START_IN +#endif ldmia r2, {r2 - r4} /* get pc, cpsr, old_r0 */ add r0, sp, #S_FRAME_SIZE /* restore sp_SVC */ @@ -382,9 +658,13 @@ _start_armboot: .word start_armboot .endm .macro get_bad_stack +#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC) ldr r13, _armboot_start @ setup our mode stack sub r13, r13, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack +#else + ldr r13, IRQ_STACK_START_IN @ setup our mode stack +#endif str lr, [r13] @ save caller lr / spsr mrs lr, spsr diff --git a/arch/arm/cpu/ixp/u-boot.lds b/arch/arm/cpu/ixp/u-boot.lds index b8ff2eed5c9..f3d9dc51487 100644 --- a/arch/arm/cpu/ixp/u-boot.lds +++ b/arch/arm/cpu/ixp/u-boot.lds @@ -39,11 +39,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/cpu/lh7a40x/start.S b/arch/arm/cpu/lh7a40x/start.S index 14a1fbe121f..002116a4010 100644 --- a/arch/arm/cpu/lh7a40x/start.S +++ b/arch/arm/cpu/lh7a40x/start.S @@ -72,12 +72,15 @@ _fiq: .word fiq ************************************************************************* */ +.globl _TEXT_BASE _TEXT_BASE: .word TEXT_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. @@ -102,8 +105,182 @@ FIQ_STACK_START: .word 0x0badc0de #endif +#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,#0x1f + orr r0,r0,#0xd3 + msr cpsr,r0 + +#define pWDTCTL 0x80001400 /* Watchdog Timer control register */ +#define pINTENC 0x8000050C /* Interupt-Controller enable clear register */ +#define pCLKSET 0x80000420 /* clock divisor register */ + + /* disable watchdog, set watchdog control register to + * all zeros (default reset) + */ + ldr r0, =pWDTCTL + mov r1, #0x0 + str r1, [r0] + + /* + * mask all IRQs by setting all bits in the INTENC register (default) + */ + mov r1, #0xffffffff + ldr r0, =pINTENC + str r1, [r0] + + /* FCLK:HCLK:PCLK = 1:2:2 */ + /* default FCLK is 200 MHz, using 14.7456 MHz fin */ + ldr r0, =pCLKSET + ldr r1, =0x0004ee39 +@ ldr r1, =0x0005ee39 @ 1: 2: 4 + str r1, [r0] + + /* + * we do sys-critical inits only at reboot, + * not when booting from ram! + */ +#ifndef CONFIG_SKIP_LOWLEVEL_INIT + bl cpu_init_crit +#endif + +/* 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 addreee [r2] */ + ble 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 */ + +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 +#endif + +/* + * We are done. Do not return, instead branch to second part of board + * initialization, now running from 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 + +#else /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */ +/* * the actual reset code */ @@ -195,7 +372,7 @@ clbss_l:str r2, [r0] /* clear loop... */ ldr pc, _start_armboot _start_armboot: .word start_armboot - +#endif /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */ /* ************************************************************************* @@ -285,9 +462,13 @@ cpu_init_crit: .macro bad_save_user_regs sub sp, sp, #S_FRAME_SIZE stmia sp, {r0 - r12} @ Calling r0-r12 +#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC) ldr r2, _armboot_start sub r2, r2, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ set base 2 words into abort stack +#else + ldr r2, IRQ_STACK_START_IN +#endif ldmia r2, {r2 - r3} @ get pc, cpsr add r0, sp, #S_FRAME_SIZE @ restore sp_SVC @@ -318,9 +499,13 @@ cpu_init_crit: .endm .macro get_bad_stack +#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC) ldr r13, _armboot_start @ setup our mode stack sub r13, r13, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack +#else + ldr r13, IRQ_STACK_START_IN @ setup our mode stack +#endif str lr, [r13] @ save caller lr / spsr mrs lr, spsr diff --git a/arch/arm/cpu/lh7a40x/u-boot.lds b/arch/arm/cpu/lh7a40x/u-boot.lds index 5a8ccf58884..cb55b0a2748 100644 --- a/arch/arm/cpu/lh7a40x/u-boot.lds +++ b/arch/arm/cpu/lh7a40x/u-boot.lds @@ -39,11 +39,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/cpu/pxa/start.S b/arch/arm/cpu/pxa/start.S index 8010b0ee17a..064ddbcf3fb 100644 --- a/arch/arm/cpu/pxa/start.S +++ b/arch/arm/cpu/pxa/start.S @@ -82,12 +82,15 @@ _fiq: .word fiq * - jump to second stage */ +.globl _TEXT_BASE _TEXT_BASE: .word TEXT_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. @@ -112,6 +115,162 @@ FIQ_STACK_START: .word 0x0badc0de #endif /* CONFIG_USE_IRQ */ +#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,#0x1f + orr r0,r0,#0xd3 + msr cpsr,r0 + + /* + * we do sys-critical inits only at reboot, + * not when booting from ram! + */ +#ifndef CONFIG_SKIP_LOWLEVEL_INIT + bl cpu_init_crit +#endif + +/* 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 addreee [r2] */ + ble 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 */ + +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 +#endif + +/* + * We are done. Do not return, instead branch to second part of board + * initialization, now running from RAM. + */ +#ifdef CONFIG_ONENAND_IPL + ldr pc, _start_oneboot + +_start_oneboot: .word start_oneboot +#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) */ /****************************************************************************/ /* */ @@ -188,6 +347,7 @@ _start_armboot: .word start_oneboot #else _start_armboot: .word start_armboot #endif +#endif /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */ /****************************************************************************/ /* */ @@ -367,9 +527,13 @@ setspeed_done: stmia sp, {r0 - r12} /* Calling r0-r12 */ add r8, sp, #S_PC +#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC) ldr r2, _armboot_start sub r2, r2, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ set base 2 words into abort stack +#else + ldr r2, IRQ_STACK_START_IN +#endif ldmia r2, {r2 - r4} /* get pc, cpsr, old_r0 */ add r0, sp, #S_FRAME_SIZE /* restore sp_SVC */ @@ -404,9 +568,13 @@ setspeed_done: .endm .macro get_bad_stack +#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC) ldr r13, _armboot_start @ setup our mode stack sub r13, r13, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack +#else + ldr r13, IRQ_STACK_START_IN @ setup our mode stack +#endif str lr, [r13] @ save caller lr / spsr mrs lr, spsr diff --git a/arch/arm/cpu/pxa/u-boot.lds b/arch/arm/cpu/pxa/u-boot.lds index d4e85ef5500..74a4c6e90c9 100644 --- a/arch/arm/cpu/pxa/u-boot.lds +++ b/arch/arm/cpu/pxa/u-boot.lds @@ -39,11 +39,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/cpu/s3c44b0/start.S b/arch/arm/cpu/s3c44b0/start.S index 0063063f45d..e1ab5ccb362 100644 --- a/arch/arm/cpu/s3c44b0/start.S +++ b/arch/arm/cpu/s3c44b0/start.S @@ -63,12 +63,15 @@ _start: b reset ************************************************************************* */ +.globl _TEXT_BASE _TEXT_BASE: .word TEXT_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. @@ -93,7 +96,177 @@ FIQ_STACK_START: .word 0x0badc0de #endif +#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,#0x1f + orr r0,r0,#0xd3 + msr cpsr,r0 + + /* + * we do sys-critical inits only at reboot, + * not when booting from ram! + */ +#ifndef CONFIG_SKIP_LOWLEVEL_INIT + bl cpu_init_crit + /* + * before relocating, we have to setup RAM timing + * because memory timing is board-dependend, you will + * find a lowlevel_init.S in your board directory. + */ + bl lowlevel_init +#endif + +/* 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 addreee [r2] */ + ble 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 +/* + now copy to sram the interrupt vector +*/ + adr r0, real_vectors + add r2, r0, #1024 + ldr r1, =0x0c000000 + add r1, r1, #0x08 +vector_copy_loop: + ldmia r0!, {r3-r10} + stmia r1!, {r3-r10} + cmp r0, r2 + ble vector_copy_loop +#endif /* #ifndef CONFIG_SKIP_RELOCATE_UBOOT */ + +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. + */ + 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 +#else /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */ /* * the actual reset code */ @@ -169,6 +342,7 @@ stack_setup: _start_armboot: .word start_armboot +#endif /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */ /* ************************************************************************* diff --git a/arch/arm/cpu/s3c44b0/u-boot.lds b/arch/arm/cpu/s3c44b0/u-boot.lds index 267d94c083d..bbc8c3aa552 100644 --- a/arch/arm/cpu/s3c44b0/u-boot.lds +++ b/arch/arm/cpu/s3c44b0/u-boot.lds @@ -39,11 +39,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/cpu/sa1100/start.S b/arch/arm/cpu/sa1100/start.S index deb4745e216..4730e5a9ab0 100644 --- a/arch/arm/cpu/sa1100/start.S +++ b/arch/arm/cpu/sa1100/start.S @@ -73,12 +73,15 @@ _fiq: .word fiq ************************************************************************* */ +.globl _TEXT_BASE _TEXT_BASE: .word TEXT_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. @@ -103,6 +106,156 @@ FIQ_STACK_START: .word 0x0badc0de #endif +#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,#0x1f + orr r0,r0,#0xd3 + msr cpsr,r0 + + /* + * we do sys-critical inits only at reboot, + * not when booting from ram! + */ +#ifndef CONFIG_SKIP_LOWLEVEL_INIT + bl cpu_init_crit +#endif + +/* 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 addreee [r2] */ + ble 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 */ + +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 +#endif + +/* + * We are done. Do not return, instead branch to second part of board + * initialization, now running from 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 + +#else /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */ /* * the actual reset code @@ -169,6 +322,7 @@ clbss_l:str r2, [r0] /* clear loop... */ _start_armboot: .word start_armboot +#endif /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */ /* ************************************************************************* @@ -288,9 +442,13 @@ cpu_init_crit: stmia sp, {r0 - r12} @ Calling r0-r12 add r8, sp, #S_PC +#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC) ldr r2, _armboot_start sub r2, r2, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ set base 2 words into abort stack +#else + ldr r2, IRQ_STACK_START_IN +#endif ldmia r2, {r2 - r4} @ get pc, cpsr, old_r0 add r0, sp, #S_FRAME_SIZE @ restore sp_SVC @@ -321,9 +479,13 @@ cpu_init_crit: .endm .macro get_bad_stack +#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC) ldr r13, _armboot_start @ setup our mode stack sub r13, r13, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack +#else + ldr r13, IRQ_STACK_START_IN @ setup our mode stack +#endif str lr, [r13] @ save caller lr / spsr mrs lr, spsr diff --git a/arch/arm/cpu/sa1100/u-boot.lds b/arch/arm/cpu/sa1100/u-boot.lds index f6197acd819..2e292919091 100644 --- a/arch/arm/cpu/sa1100/u-boot.lds +++ b/arch/arm/cpu/sa1100/u-boot.lds @@ -42,11 +42,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) } |