diff options
author | Wolfgang Denk <wd@denx.de> | 2010-09-28 23:30:47 +0200 |
---|---|---|
committer | Wolfgang Denk <wd@denx.de> | 2010-09-28 23:30:47 +0200 |
commit | 2e6e1772c0e34871769be4aef79748fe3e47d953 (patch) | |
tree | 00e4e19d7bccd2a1cd5753854ff4c2b8a26bebb0 /arch/arm | |
parent | 1e4e5ef0469050f014aee1204dae8a9ab6053e49 (diff) | |
parent | 3df61957938586c512c17e72d83551d190400981 (diff) |
Merge branch 'next' of /home/wd/git/u-boot/next
Conflicts:
include/ppc4xx.h
Signed-off-by: Wolfgang Denk <wd@denx.de>
Diffstat (limited to 'arch/arm')
42 files changed, 3740 insertions, 47 deletions
diff --git a/arch/arm/config.mk b/arch/arm/config.mk index e10dafca58..6923f6dafa 100644 --- a/arch/arm/config.mk +++ b/arch/arm/config.mk @@ -33,6 +33,14 @@ STANDALONE_LOAD_ADDR = 0xc100000 endif endif +ifndef CONFIG_SYS_ARM_WITHOUT_RELOC +# needed for relocation +PLATFORM_RELFLAGS += -fPIC +endif + +ifdef CONFIG_SYS_ARM_WITHOUT_RELOC +PLATFORM_CPPFLAGS += -DCONFIG_SYS_ARM_WITHOUT_RELOC +endif PLATFORM_CPPFLAGS += -DCONFIG_ARM -D__ARM__ # Explicitly specifiy 32-bit ARM ISA since toolchain default can be -mthumb: diff --git a/arch/arm/cpu/arm1136/start.S b/arch/arm/cpu/arm1136/start.S index 41eb82dae2..8b631920c9 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 e7eefc972c..1db4b49cc7 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 f98a7aa355..e5e7913d94 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 8969587e8c..fa640eec20 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 d6f2c165c7..0f5f6c4611 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 c975fc3d5e..4a0bc70c77 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 e532f55bfc..a079bb2727 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 a7decfcd7d..6985434795 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 346615e4b4..c0a856dfe1 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 e21d6dc5a7..1c4e9bcfb5 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 c719798a66..c5c8ab7e4d 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 cf40ce1292..16ee972f2b 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 ecbc58c7c2..02eb8ca607 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 8844d4438b..18ed0b2da4 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 fef21c7587..6535963093 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 328bae0274..b39fdc64c4 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 4ed7d8906d..242c7ece02 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 d66434c95d..55d6599b41 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 fdc1666fe9..cda87ba1af 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 fae5b1161b..da2cd90013 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 8905224439..2719bb53a7 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 1e0a1504bf..f411c0f4f0 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 9e5b5a97d7..d4fd3fccee 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 6efe333f1a..b2c8255141 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 b8ff2eed5c..f3d9dc5148 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 14a1fbe121..002116a401 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 5a8ccf5888..cb55b0a274 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 8010b0ee17..064ddbcf3f 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 d4e85ef550..74a4c6e90c 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 0063063f45..e1ab5ccb36 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 267d94c083..bbc8c3aa55 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 deb4745e21..4730e5a9ab 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 f6197acd81..2e29291909 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) } diff --git a/arch/arm/include/asm/config.h b/arch/arm/include/asm/config.h index b76fd8eb48..4e8dfd7bc5 100644 --- a/arch/arm/include/asm/config.h +++ b/arch/arm/include/asm/config.h @@ -21,7 +21,8 @@ #ifndef _ASM_CONFIG_H_ #define _ASM_CONFIG_H_ +#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC) /* Relocation to SDRAM works on all ARM boards */ #define CONFIG_RELOC_FIXUP_WORKS - +#endif #endif diff --git a/arch/arm/include/asm/global_data.h b/arch/arm/include/asm/global_data.h index 02cfe4584a..6152f348f3 100644 --- a/arch/arm/include/asm/global_data.h +++ b/arch/arm/include/asm/global_data.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 2002 + * (C) Copyright 2002-2010 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * * See file CREDITS for list of people who contributed to this @@ -47,25 +47,32 @@ typedef struct global_data { #ifdef CONFIG_FSL_ESDHC unsigned long sdhc_clk; #endif -#if 0 - unsigned long cpu_clk; /* CPU clock in Hz! */ - unsigned long bus_clk; +#if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) + unsigned long relocaddr; /* Start address of U-Boot in RAM */ phys_size_t ram_size; /* RAM size */ - unsigned long reset_status; /* reset status register at boot */ + unsigned long mon_len; /* monitor len */ + unsigned long irq_sp; /* irq stack pointer */ + unsigned long start_addr_sp; /* start_addr_stackpointer */ + unsigned long reloc_off; +#if !(defined(CONFIG_SYS_NO_ICACHE) && defined(CONFIG_SYS_NO_DCACHE)) + unsigned long tlb_addr; +#endif #endif void **jt; /* jump table */ + char env_buf[32]; /* buffer for getenv() before reloc. */ } gd_t; /* * Global Data Flags */ -#define GD_FLG_RELOC 0x00001 /* Code was relocated to RAM */ -#define GD_FLG_DEVINIT 0x00002 /* Devices have been initialized */ -#define GD_FLG_SILENT 0x00004 /* Silent mode */ -#define GD_FLG_POSTFAIL 0x00008 /* Critical POST test failed */ -#define GD_FLG_POSTSTOP 0x00010 /* POST seqeunce aborted */ -#define GD_FLG_LOGINIT 0x00020 /* Log Buffer has been initialized */ -#define GD_FLG_DISABLE_CONSOLE 0x00040 /* Disable console (in & out) */ +#define GD_FLG_RELOC 0x00001 /* Code was relocated to RAM */ +#define GD_FLG_DEVINIT 0x00002 /* Devices have been initialized */ +#define GD_FLG_SILENT 0x00004 /* Silent mode */ +#define GD_FLG_POSTFAIL 0x00008 /* Critical POST test failed */ +#define GD_FLG_POSTSTOP 0x00010 /* POST seqeunce aborted */ +#define GD_FLG_LOGINIT 0x00020 /* Log Buffer has been initialized */ +#define GD_FLG_DISABLE_CONSOLE 0x00040 /* Disable console (in & out) */ +#define GD_FLG_ENV_READY 0x00080 /* Environment imported into hash table */ #define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("r8") diff --git a/arch/arm/include/asm/u-boot-arm.h b/arch/arm/include/asm/u-boot-arm.h index 6d2f8bccb5..faf800a17b 100644 --- a/arch/arm/include/asm/u-boot-arm.h +++ b/arch/arm/include/asm/u-boot-arm.h @@ -30,11 +30,20 @@ #define _U_BOOT_ARM_H_ 1 /* for the following variables, see start.S */ -extern ulong _armboot_start; /* code start */ extern ulong _bss_start; /* code + data end == BSS start */ extern ulong _bss_end; /* BSS end */ extern ulong IRQ_STACK_START; /* top of IRQ stack */ extern ulong FIQ_STACK_START; /* top of FIQ stack */ +#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC) +extern ulong _armboot_start; /* code start */ +#else +extern ulong _TEXT_BASE; /* code start */ +extern ulong _datarel_start; +extern ulong _datarelrolocal_start; +extern ulong _datarellocal_start; +extern ulong _datarelro_start; +extern ulong IRQ_STACK_START_IN; /* 8 bytes in IRQ stack */ +#endif /* cpu/.../cpu.c */ int cpu_init(void); @@ -47,6 +56,9 @@ int arch_misc_init(void); /* board/.../... */ int board_init(void); int dram_init (void); +#if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) +void dram_init_banksize (void); +#endif void setup_serial_tag (struct tag **params); void setup_revision_tag (struct tag **params); diff --git a/arch/arm/include/asm/u-boot.h b/arch/arm/include/asm/u-boot.h index cfd5a9ba45..ed33327094 100644 --- a/arch/arm/include/asm/u-boot.h +++ b/arch/arm/include/asm/u-boot.h @@ -39,7 +39,6 @@ typedef struct bd_info { int bi_baudrate; /* serial console baudrate */ unsigned long bi_ip_addr; /* IP Address */ - struct environment_s *bi_env; ulong bi_arch_number; /* unique id for this board */ ulong bi_boot_params; /* where this board expects params */ struct /* RAM configuration */ @@ -49,7 +48,4 @@ typedef struct bd_info { } bi_dram[CONFIG_NR_DRAM_BANKS]; } bd_t; -#define bi_env_data bi_env->data -#define bi_env_crc bi_env->crc - #endif /* _U_BOOT_H_ */ diff --git a/arch/arm/lib/board.c b/arch/arm/lib/board.c index e17f182e18..5f2dfd08ac 100644 --- a/arch/arm/lib/board.c +++ b/arch/arm/lib/board.c @@ -126,7 +126,12 @@ static int init_baudrate (void) { char tmp[64]; /* long enough for environment variables */ int i = getenv_f("baudrate", tmp, sizeof (tmp)); + +#if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) + gd->baudrate = (i > 0) +#else gd->bd->bi_baudrate = gd->baudrate = (i > 0) +#endif ? (int) simple_strtoul (tmp, NULL, 10) : CONFIG_BAUDRATE; @@ -137,7 +142,12 @@ static int display_banner (void) { printf ("\n\n%s\n\n", version_string); debug ("U-Boot code: %08lX -> %08lX BSS: -> %08lX\n", - _armboot_start, _bss_start, _bss_end); +#if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) + _TEXT_BASE, +#else + _armboot_start, +#endif + _bss_start, _bss_end); #ifdef CONFIG_MODEM_SUPPORT debug ("Modem Support enabled\n"); #endif @@ -180,6 +190,7 @@ static int display_dram_config (void) return (0); } +#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC) #ifndef CONFIG_SYS_NO_FLASH static void display_flash_config (ulong size) { @@ -187,6 +198,7 @@ static void display_flash_config (ulong size) print_size (size, "\n"); } #endif /* CONFIG_SYS_NO_FLASH */ +#endif #if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C) static int init_func_i2c (void) @@ -234,6 +246,7 @@ typedef int (init_fnc_t) (void); int print_cpuinfo (void); +#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC) init_fnc_t *init_sequence[] = { #if defined(CONFIG_ARCH_CPU_INIT) arch_cpu_init, /* basic arch cpu dependent setup */ @@ -449,6 +462,459 @@ extern void davinci_eth_set_mac_addr (const u_int8_t *addr); /* NOTREACHED - no way out of command loop except booting */ } +#else +void __dram_init_banksize(void) +{ + gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE; + gd->bd->bi_dram[0].size = gd->ram_size; +} +void dram_init_banksize(void) + __attribute__((weak, alias("__dram_init_banksize"))); + +init_fnc_t *init_sequence[] = { +#if defined(CONFIG_ARCH_CPU_INIT) + arch_cpu_init, /* basic arch cpu dependent setup */ +#endif +#if defined(CONFIG_BOARD_EARLY_INIT_F) + board_early_init_f, +#endif + timer_init, /* initialize timer */ +#ifdef CONFIG_FSL_ESDHC + get_clocks, +#endif + env_init, /* initialize environment */ + init_baudrate, /* initialze baudrate settings */ + serial_init, /* serial communications setup */ + console_init_f, /* stage 1 init of console */ + display_banner, /* say that we are here */ +#if defined(CONFIG_DISPLAY_CPUINFO) + print_cpuinfo, /* display cpu info (and speed) */ +#endif +#if defined(CONFIG_DISPLAY_BOARDINFO) + checkboard, /* display board info */ +#endif +#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C) + init_func_i2c, +#endif + dram_init, /* configure available RAM banks */ +#if defined(CONFIG_CMD_PCI) || defined (CONFIG_PCI) + arm_pci_init, +#endif + NULL, +}; + +void board_init_f (ulong bootflag) +{ + bd_t *bd; + init_fnc_t **init_fnc_ptr; + gd_t *id; + ulong addr, addr_sp; + + /* Pointer is writable since we allocated a register for it */ + gd = (gd_t *) (CONFIG_SYS_INIT_SP_ADDR); + /* compiler optimization barrier needed for GCC >= 3.4 */ + __asm__ __volatile__("": : :"memory"); + + memset ((void*)gd, 0, sizeof (gd_t)); + + gd->mon_len = _bss_end - _TEXT_BASE; + + for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) { + if ((*init_fnc_ptr)() != 0) { + hang (); + } + } + + debug ("monitor len: %08lX\n", gd->mon_len); + /* + * Ram is setup, size stored in gd !! + */ + debug ("ramsize: %08lX\n", gd->ram_size); +#if defined(CONFIG_SYS_MEM_TOP_HIDE) + /* + * Subtract specified amount of memory to hide so that it won't + * get "touched" at all by U-Boot. By fixing up gd->ram_size + * the Linux kernel should now get passed the now "corrected" + * memory size and won't touch it either. This should work + * for arch/ppc and arch/powerpc. Only Linux board ports in + * arch/powerpc with bootwrapper support, that recalculate the + * memory size from the SDRAM controller setup will have to + * get fixed. + */ + gd->ram_size -= CONFIG_SYS_MEM_TOP_HIDE; +#endif + + addr = CONFIG_SYS_SDRAM_BASE + gd->ram_size; + +#ifdef CONFIG_LOGBUFFER +#ifndef CONFIG_ALT_LB_ADDR + /* reserve kernel log buffer */ + addr -= (LOGBUFF_RESERVE); + debug ("Reserving %dk for kernel logbuffer at %08lx\n", LOGBUFF_LEN, addr); +#endif +#endif + +#ifdef CONFIG_PRAM + /* + * reserve protected RAM + */ + i = getenv_r ("pram", (char *)tmp, sizeof (tmp)); + reg = (i > 0) ? simple_strtoul ((const char *)tmp, NULL, 10) : CONFIG_PRAM; + addr -= (reg << 10); /* size is in kB */ + debug ("Reserving %ldk for protected RAM at %08lx\n", reg, addr); +#endif /* CONFIG_PRAM */ + +#if !(defined(CONFIG_SYS_NO_ICACHE) && defined(CONFIG_SYS_NO_DCACHE)) + /* reserve TLB table */ + addr -= (4096 * 4); + + /* round down to next 64 kB limit */ + addr &= ~(0x10000 - 1); + + gd->tlb_addr = addr; + debug ("TLB table at: %08lx\n", addr); +#endif + + /* round down to next 4 kB limit */ + addr &= ~(4096 - 1); + debug ("Top of RAM usable for U-Boot at: %08lx\n", addr); + +#ifdef CONFIG_VFD +# ifndef PAGE_SIZE +# define PAGE_SIZE 4096 +# endif + /* + * reserve memory for VFD display (always full pages) + */ + addr -= vfd_setmem (addr); + gd->fb_base = addr; +#endif /* CONFIG_VFD */ + +#ifdef CONFIG_LCD + /* reserve memory for LCD display (always full pages) */ + addr = lcd_setmem (addr); + gd->fb_base = addr; +#endif /* CONFIG_LCD */ + + /* + * reserve memory for U-Boot code, data & bss + * round down to next 4 kB limit + */ + addr -= gd->mon_len; + addr &= ~(4096 - 1); + + debug ("Reserving %ldk for U-Boot at: %08lx\n", gd->mon_len >> 10, addr); + +#ifndef CONFIG_PRELOADER + /* + * reserve memory for malloc() arena + */ + addr_sp = addr - TOTAL_MALLOC_LEN; + debug ("Reserving %dk for malloc() at: %08lx\n", + TOTAL_MALLOC_LEN >> 10, addr_sp); + /* + * (permanently) allocate a Board Info struct + * and a permanent copy of the "global" data + */ + addr_sp -= sizeof (bd_t); + bd = (bd_t *) addr_sp; + gd->bd = bd; + debug ("Reserving %zu Bytes for Board Info at: %08lx\n", + sizeof (bd_t), addr_sp); + addr_sp -= sizeof (gd_t); + id = (gd_t *) addr_sp; + debug ("Reserving %zu Bytes for Global Data at: %08lx\n", + sizeof (gd_t), addr_sp); + + /* setup stackpointer for exeptions */ + gd->irq_sp = addr_sp; +#ifdef CONFIG_USE_IRQ + addr_sp -= (CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ); + debug ("Reserving %zu Bytes for IRQ stack at: %08lx\n", + CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ, addr_sp); +#endif + /* leave 3 words for abort-stack */ + addr_sp -= 3; + + /* 8-byte alignment for ABI compliance */ + addr_sp &= ~0x07; +#else + addr_sp += 128; /* leave 32 words for abort-stack */ + gd->irq_sp = addr_sp; +#endif + + debug ("New Stack Pointer is: %08lx\n", addr_sp); + +#ifdef CONFIG_POST + post_bootmode_init(); + post_run (NULL, POST_ROM | post_bootmode_get(0)); +#endif + + gd->bd->bi_baudrate = gd->baudrate; + /* Ram ist board specific, so move it to board code ... */ + dram_init_banksize(); + display_dram_config(); /* and display it */ + + gd->relocaddr = addr; + gd->start_addr_sp = addr_sp; + gd->reloc_off = addr - _TEXT_BASE; + debug ("relocation Offset is: %08lx\n", gd->reloc_off); + memcpy (id, (void *)gd, sizeof (gd_t)); + + relocate_code (addr_sp, id, addr); + + /* NOTREACHED - relocate_code() does not return */ +} + +#if !defined(CONFIG_SYS_NO_FLASH) +static char *failed = "*** failed ***\n"; +#endif + +/************************************************************************ + * + * This is the next part if the initialization sequence: we are now + * running from RAM and have a "normal" C environment, i. e. global + * data can be written, BSS has been cleared, the stack size in not + * that critical any more, etc. + * + ************************************************************************ + */ +void board_init_r (gd_t *id, ulong dest_addr) +{ + char *s; + bd_t *bd; + ulong malloc_start; +#if !defined(CONFIG_SYS_NO_FLASH) + ulong flash_size; +#endif +#if !defined(CONFIG_RELOC_FIXUP_WORKS) + extern void malloc_bin_reloc (void); +#if defined(CONFIG_CMD_BMP) + extern void bmp_reloc(void); +#endif +#if defined(CONFIG_CMD_I2C) + extern void i2c_reloc(void); +#endif +#endif + + gd = id; + bd = gd->bd; + + gd->flags |= GD_FLG_RELOC; /* tell others: relocation done */ + + monitor_flash_len = _bss_start - _TEXT_BASE; + debug ("monitor flash len: %08lX\n", monitor_flash_len); + board_init(); /* Setup chipselects */ + +#ifdef CONFIG_SERIAL_MULTI + serial_initialize(); +#endif + + debug ("Now running in RAM - U-Boot at: %08lx\n", dest_addr); + +#if !defined(CONFIG_RELOC_FIXUP_WORKS) + /* + * We have to relocate the command table manually + */ + fixup_cmdtable(&__u_boot_cmd_start, + (ulong)(&__u_boot_cmd_end - &__u_boot_cmd_start)); +#if defined(CONFIG_CMD_BMP) + bmp_reloc(); +#endif +#if defined(CONFIG_CMD_I2C) + i2c_reloc(); +#endif +#endif /* !defined(CONFIG_RELOC_FIXUP_WORKS) */ + +#ifdef CONFIG_LOGBUFFER + logbuff_init_ptrs (); +#endif +#ifdef CONFIG_POST + post_output_backlog (); +#ifndef CONFIG_RELOC_FIXUP_WORKS + post_reloc (); +#endif +#endif + + /* The Malloc area is immediately below the monitor copy in DRAM */ + malloc_start = dest_addr - TOTAL_MALLOC_LEN; + mem_malloc_init (malloc_start, TOTAL_MALLOC_LEN); +#if !defined(CONFIG_RELOC_FIXUP_WORKS) + malloc_bin_reloc (); +#endif + +#if !defined(CONFIG_SYS_NO_FLASH) + puts ("FLASH: "); + + if ((flash_size = flash_init ()) > 0) { +# ifdef CONFIG_SYS_FLASH_CHECKSUM + print_size (flash_size, ""); + /* + * Compute and print flash CRC if flashchecksum is set to 'y' + * + * NOTE: Maybe we should add some WATCHDOG_RESET()? XXX + */ + s = getenv ("flashchecksum"); + if (s && (*s == 'y')) { + printf (" CRC: %08X", + crc32 (0, (const unsigned char *) CONFIG_SYS_FLASH_BASE, flash_size) + ); + } + putc ('\n'); +# else /* !CONFIG_SYS_FLASH_CHECKSUM */ + print_size (flash_size, "\n"); +# endif /* CONFIG_SYS_FLASH_CHECKSUM */ + } else { + puts (failed); + hang (); + } +#endif + +#if defined(CONFIG_CMD_NAND) + puts ("NAND: "); + nand_init(); /* go init the NAND */ +#endif + +#if defined(CONFIG_CMD_ONENAND) + onenand_init(); +#endif + +#ifdef CONFIG_HAS_DATAFLASH + AT91F_DataflashInit(); + dataflash_print_info(); +#endif + + /* initialize environment */ + env_relocate (); + +#ifdef CONFIG_VFD + /* must do this after the framebuffer is allocated */ + drv_vfd_init(); +#endif /* CONFIG_VFD */ + + /* IP Address */ + gd->bd->bi_ip_addr = getenv_IPaddr ("ipaddr"); + + stdio_init (); /* get the devices list going. */ + + jumptable_init (); + +#if defined(CONFIG_API) + /* Initialize API */ + api_init (); +#endif + + console_init_r (); /* fully init console as a device */ + +#if defined(CONFIG_ARCH_MISC_INIT) + /* miscellaneous arch dependent initialisations */ + arch_misc_init (); +#endif +#if defined(CONFIG_MISC_INIT_R) + /* miscellaneous platform dependent initialisations */ + misc_init_r (); +#endif + + /* set up exceptions */ + interrupt_init (); + /* enable exceptions */ + enable_interrupts (); + + /* Perform network card initialisation if necessary */ +#ifdef CONFIG_DRIVER_TI_EMAC + /* XXX: this needs to be moved to board init */ +extern void davinci_eth_set_mac_addr (const u_int8_t *addr); + if (getenv ("ethaddr")) { + uchar enetaddr[6]; + eth_getenv_enetaddr("ethaddr", enetaddr); + davinci_eth_set_mac_addr(enetaddr); + } +#endif + +#if defined(CONFIG_DRIVER_SMC91111) || defined (CONFIG_DRIVER_LAN91C96) + /* XXX: this needs to be moved to board init */ + if (getenv ("ethaddr")) { + uchar enetaddr[6]; + eth_getenv_enetaddr("ethaddr", enetaddr); + smc_set_mac_addr(enetaddr); + } +#endif /* CONFIG_DRIVER_SMC91111 || CONFIG_DRIVER_LAN91C96 */ + + /* Initialize from environment */ + if ((s = getenv ("loadaddr")) != NULL) { + load_addr = simple_strtoul (s, NULL, 16); + } +#if defined(CONFIG_CMD_NET) + if ((s = getenv ("bootfile")) != NULL) { + copy_filename (BootFile, s, sizeof (BootFile)); + } +#endif + +#ifdef BOARD_LATE_INIT + board_late_init (); +#endif + +#ifdef CONFIG_GENERIC_MMC + puts ("MMC: "); + mmc_initialize (gd->bd); +#endif + +#ifdef CONFIG_BITBANGMII + bb_miiphy_init(); +#endif +#if defined(CONFIG_CMD_NET) +#if defined(CONFIG_NET_MULTI) + puts ("Net: "); +#endif + eth_initialize(gd->bd); +#if defined(CONFIG_RESET_PHY_R) + debug ("Reset Ethernet PHY\n"); + reset_phy(); +#endif +#endif + +#ifdef CONFIG_POST + post_run (NULL, POST_RAM | post_bootmode_get(0)); +#endif + +#if defined(CONFIG_PRAM) || defined(CONFIG_LOGBUFFER) + /* + * Export available size of memory for Linux, + * taking into account the protected RAM at top of memory + */ + { + ulong pram; + uchar memsz[32]; +#ifdef CONFIG_PRAM + char *s; + + if ((s = getenv ("pram")) != NULL) { + pram = simple_strtoul (s, NULL, 10); + } else { + pram = CONFIG_PRAM; + } +#else + pram=0; +#endif +#ifdef CONFIG_LOGBUFFER +#ifndef CONFIG_ALT_LB_ADDR + /* Also take the logbuffer into account (pram is in kB) */ + pram += (LOGBUFF_LEN+LOGBUFF_OVERHEAD)/1024; +#endif +#endif + sprintf ((char *)memsz, "%ldk", (bd->bi_memsize / 1024) - pram); + setenv ("mem", (char *)memsz); + } +#endif + + /* main_loop() can return to retry autoboot, if so just run it again. */ + for (;;) { + main_loop (); + } + + /* NOTREACHED - no way out of command loop except booting */ +} +#endif /* defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */ void hang (void) { diff --git a/arch/arm/lib/cache-cp15.c b/arch/arm/lib/cache-cp15.c index 62ed54fb4d..fe6d45987b 100644 --- a/arch/arm/lib/cache-cp15.c +++ b/arch/arm/lib/cache-cp15.c @@ -25,6 +25,15 @@ #include <asm/system.h> #if !(defined(CONFIG_SYS_NO_ICACHE) && defined(CONFIG_SYS_NO_DCACHE)) + +#if defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH) +#define CACHE_SETUP 0x1a +#else +#define CACHE_SETUP 0x1e +#endif + +DECLARE_GLOBAL_DATA_PTR; + static void cp_delay (void) { volatile int i; @@ -32,6 +41,67 @@ static void cp_delay (void) /* copro seems to need some delay between reading and writing */ for (i = 0; i < 100; i++) nop(); + asm volatile("" : : : "memory"); +} + +#if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) +static inline void dram_bank_mmu_setup(int bank) +{ + u32 *page_table = (u32 *)gd->tlb_addr; + bd_t *bd = gd->bd; + int i; + + debug("%s: bank: %d\n", __func__, bank); + for (i = bd->bi_dram[bank].start >> 20; + i < (bd->bi_dram[bank].start + bd->bi_dram[bank].size) >> 20; + i++) { + page_table[i] = i << 20 | (3 << 10) | CACHE_SETUP; + } +} +#endif + +/* to activate the MMU we need to set up virtual memory: use 1M areas */ +static inline void mmu_setup(void) +{ +#if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) + u32 *page_table = (u32 *)gd->tlb_addr; +#else + static u32 __attribute__((aligned(16384))) page_table[4096]; + bd_t *bd = gd->bd; + int j; +#endif + int i; + u32 reg; + + /* Set up an identity-mapping for all 4GB, rw for everyone */ + for (i = 0; i < 4096; i++) + page_table[i] = i << 20 | (3 << 10) | 0x12; + +#if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) + for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { + dram_bank_mmu_setup(i); + } +#else + /* Then, enable cacheable and bufferable for RAM only */ + for (j = 0; j < CONFIG_NR_DRAM_BANKS; j++) { + for (i = bd->bi_dram[j].start >> 20; + i < (bd->bi_dram[j].start + bd->bi_dram[j].size) >> 20; + i++) { + page_table[i] = i << 20 | (3 << 10) | CACHE_SETUP; + } + } +#endif + + /* Copy the page table address to cp15 */ + asm volatile("mcr p15, 0, %0, c2, c0, 0" + : : "r" (page_table) : "memory"); + /* Set the access control to all-supervisor */ + asm volatile("mcr p15, 0, %0, c3, c0, 0" + : : "r" (~0)); + /* and enable the mmu */ + reg = get_cr(); /* get control reg. */ + cp_delay(); + set_cr(reg | CR_M); } /* cache_bit must be either CR_I or CR_C */ @@ -39,6 +109,9 @@ static void cache_enable(uint32_t cache_bit) { uint32_t reg; + /* The data cache is not active unless the mmu is enabled too */ + if (cache_bit == CR_C) + mmu_setup(); reg = get_cr(); /* get control reg. */ cp_delay(); set_cr(reg | cache_bit); @@ -49,6 +122,15 @@ static void cache_disable(uint32_t cache_bit) { uint32_t reg; + if (cache_bit == CR_C) { + /* if cache isn;t enabled no need to disable */ + reg = get_cr(); + if ((reg & CR_C) != CR_C) + return; + /* if disabling data cache, disable mmu too */ + cache_bit |= CR_M; + flush_cache(0, ~0); + } reg = get_cr(); cp_delay(); set_cr(reg & ~cache_bit); diff --git a/arch/arm/lib/cache.c b/arch/arm/lib/cache.c index 61ee9d3b13..55b633ee00 100644 --- a/arch/arm/lib/cache.c +++ b/arch/arm/lib/cache.c @@ -27,10 +27,21 @@ void flush_cache (unsigned long dummy1, unsigned long dummy2) { -#ifdef CONFIG_OMAP2420 +#if defined(CONFIG_OMAP2420) || defined(CONFIG_ARM1136) void arm1136_cache_flush(void); arm1136_cache_flush(); #endif +#ifdef CONFIG_ARM926EJS + /* test and clean, page 2-23 of arm926ejs manual */ + asm("0: mrc p15, 0, r15, c7, c10, 3\n\t" "bne 0b\n" : : : "memory"); + /* disable write buffer as well (page 2-22) */ + asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (0)); +#endif +#ifdef CONFIG_ARMCORTEXA8 + void v7_flush_cache_all(void); + + v7_flush_cache_all(); +#endif return; } diff --git a/arch/arm/lib/interrupts.c b/arch/arm/lib/interrupts.c index 1f2b815611..9a21e7b40a 100644 --- a/arch/arm/lib/interrupts.c +++ b/arch/arm/lib/interrupts.c @@ -38,15 +38,20 @@ #include <common.h> #include <asm/proc-armv/ptrace.h> -#ifdef CONFIG_USE_IRQ DECLARE_GLOBAL_DATA_PTR; +#ifdef CONFIG_USE_IRQ int interrupt_init (void) { /* * setup up stacks if necessary */ +#if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) + IRQ_STACK_START = gd->irq_sp - 4; + IRQ_STACK_START_IN = gd->irq_sp + 8; +#else IRQ_STACK_START = _armboot_start - CONFIG_SYS_MALLOC_LEN - CONFIG_SYS_GBL_DATA_SIZE - 4; +#endif FIQ_STACK_START = IRQ_STACK_START - CONFIG_STACKSIZE_IRQ; return arch_interrupt_init(); @@ -81,6 +86,18 @@ int disable_interrupts (void) return (old & 0x80) == 0; } #else +#if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) +int interrupt_init (void) +{ + /* + * setup up stacks if necessary + */ + IRQ_STACK_START_IN = gd->irq_sp + 8; + + return 0; +} +#endif + void enable_interrupts (void) { return; |