X-Git-Url: https://git.kernelconcepts.de/?a=blobdiff_plain;ds=sidebyside;f=arch%2Farm%2Fcpu%2Farmv7%2Fstart.S;h=0eebe226905785e8e4c990050e7720d35186d873;hb=1e362dc3e799fd86722a60f5639e52a67dfc0658;hp=eee648bdc405f8ac8db7c0e4414f0c79c81d319f;hpb=22193540c174bd7140bc1af0021efedd8ab9da4a;p=karo-tx-uboot.git diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S index eee648bdc4..0eebe22690 100644 --- a/arch/arm/cpu/armv7/start.S +++ b/arch/arm/cpu/armv7/start.S @@ -32,6 +32,8 @@ #include #include #include +#include +#include .globl _start _start: b reset @@ -42,7 +44,16 @@ _start: b reset ldr pc, _not_used ldr pc, _irq ldr pc, _fiq - +#ifdef CONFIG_SPL_BUILD +_undefined_instruction: .word _undefined_instruction +_software_interrupt: .word _software_interrupt +_prefetch_abort: .word _prefetch_abort +_data_abort: .word _data_abort +_not_used: .word _not_used +_irq: .word _irq +_fiq: .word _fiq +_pad: .word 0x12345678 /* now 16*4=64 */ +#else _undefined_instruction: .word undefined_instruction _software_interrupt: .word software_interrupt _prefetch_abort: .word prefetch_abort @@ -51,6 +62,8 @@ _not_used: .word not_used _irq: .word irq _fiq: .word fiq _pad: .word 0x12345678 /* now 16*4=64 */ +#endif /* CONFIG_SPL_BUILD */ + .global _end_vect _end_vect: @@ -68,19 +81,7 @@ _end_vect: .globl _TEXT_BASE _TEXT_BASE: - .word CONFIG_SYS_TEXT_BASE - -#ifdef CONFIG_TEGRA2 -/* - * Tegra2 uses 2 separate CPUs - the AVP (ARM7TDMI) and the CPU (dual A9s). - * U-Boot runs on the AVP first, setting things up for the CPU (PLLs, - * muxes, clocks, clamps, etc.). Then the AVP halts, and expects the CPU - * to pick up its reset vector, which points here. - */ -.globl _armboot_start -_armboot_start: - .word _start -#endif + .word _start /* * These are defined in the board-specific linker script. @@ -89,6 +90,10 @@ _armboot_start: _bss_start_ofs: .word __bss_start - _start +.global _image_copy_end_ofs +_image_copy_end_ofs: + .word __image_copy_end - _start + .globl _bss_end_ofs _bss_end_ofs: .word __bss_end__ - _start @@ -119,6 +124,7 @@ IRQ_STACK_START_IN: */ reset: + bl save_boot_params /* * set the cpu to SVC32 mode */ @@ -127,43 +133,33 @@ reset: orr r0, r0, #0xd3 msr cpsr,r0 -#if defined(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 */ +/* + * Setup vector: + * (OMAP4 spl TEXT_BASE is not 32 byte aligned. + * Continue to use ROM code vector only in OMAP4 spl) + */ +#if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD)) + /* Set V=0 in CP15 SCTRL register - for VBAR to point to vector */ + mrc p15, 0, r0, c1, c0, 0 @ Read CP15 SCTRL Register + bic r0, #CR_V @ V = 0 + mcr p15, 0, r0, c1, c0, 0 @ Write CP15 SCTRL Register + + /* Set vector address in CP15 VBAR register */ + ldr r0, =_start + mcr p15, 0, r0, c12, c0, 0 @Set VBAR #endif + /* the mask ROM code should have PLL and others stable */ #ifndef CONFIG_SKIP_LOWLEVEL_INIT + bl cpu_init_cp15 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) - bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ - ldr r0,=0x00000000 - bl board_init_f + bl _main /*------------------------------------------------------------------------------*/ +#ifndef CONFIG_SPL_BUILD /* * void relocate_code (addr_sp, gd, addr_moni) * @@ -171,23 +167,16 @@ call_board_init_f: * after relocating the monitor code. * */ - .globl relocate_code -relocate_code: +ENTRY(relocate_code) mov r4, r0 /* save addr_sp */ mov r5, r1 /* save addr of gd */ mov r6, r2 /* save addr of destination */ - /* Set up the stack */ -stack_setup: - mov sp, r4 - adr r0, _start -#ifndef CONFIG_PRELOADER - cmp r0, r6 - beq clear_bss /* skip relocation */ -#endif + subs r9, r6, r0 + beq relocate_done /* skip relocation */ mov r1, r6 /* r1 <- scratch for copy_loop */ - ldr r3, _bss_start_ofs + ldr r3, _image_copy_end_ofs add r2, r0, r3 /* r2 <- source end address */ copy_loop: @@ -196,11 +185,10 @@ copy_loop: cmp r0, r2 /* until source end address [r2] */ blo copy_loop -#ifndef CONFIG_PRELOADER /* * fix .rel.dyn relocations */ - ldr r0, _TEXT_BASE /* r0 <- Text base */ + adr r0, _start /* r0 <- beginning of code */ sub r9, r6, r0 /* r9 <- relocation offset */ ldr r10, _dynsym_start_ofs /* r10 <- sym table ofs */ add r10, r10, r0 /* r10 <- sym table in FLASH */ @@ -208,8 +196,11 @@ copy_loop: add r2, r2, r0 /* r2 <- rel dyn start in FLASH */ ldr r3, _rel_dyn_end_ofs /* r3 <- rel dyn end ofs */ add r3, r3, r0 /* r3 <- rel dyn end in FLASH */ + mov r4, r0 fixloop: ldr r0, [r2] /* r0 <- location to fix up, IN FLASH! */ + cmp r0, r4 + blo skipfix add r0, r0, r9 /* r0 <- location to fix up in RAM */ ldr r1, [r2, #4] and r7, r1, #0xff @@ -232,29 +223,26 @@ fixrel: add r1, r1, r9 fixnext: str r1, [r0] +skipfix: add r2, r2, #8 /* each rel.dyn entry is 8 bytes */ cmp r2, r3 blo fixloop -clear_bss: - ldr r0, _bss_start_ofs - ldr r1, _bss_end_ofs - mov r4, r6 /* reloc addr */ - add r0, r0, r4 - add r1, r1, r4 - mov r2, #0x00000000 /* clear */ +relocate_done: -clbss_l:str r2, [r0] /* clear loop... */ - add r0, r0, #4 - cmp r0, r1 - bne clbss_l -#endif /* #ifndef CONFIG_PRELOADER */ + bx lr -/* - * We are done. Do not return, instead branch to second part of board - * initialization, now running from RAM. - */ -jump_2_ram: +_rel_dyn_start_ofs: + .word __rel_dyn_start - _start +_rel_dyn_end_ofs: + .word __rel_dyn_end - _start +_dynsym_start_ofs: + .word __dynsym_start - _start +ENDPROC(relocate_code) + +#endif + +ENTRY(c_runtime_cpu_setup) /* * If I-cache is enabled invalidate it */ @@ -263,36 +251,43 @@ jump_2_ram: mcr p15, 0, r0, c7, c10, 4 @ DSB mcr p15, 0, r0, c7, c5, 4 @ ISB #endif - ldr r0, _board_init_r_ofs - adr r1, _start - add lr, r0, r1 - add lr, lr, r9 - /* setup parameters for board_init_r */ - mov r0, r5 /* gd_t */ - mov r1, r6 /* dest_addr */ - /* jump to it ... */ - mov pc, lr - -_board_init_r_ofs: - .word board_init_r - _start +/* + * Move vector table + */ +#if !defined(CONFIG_TEGRA20) + /* Set vector address in CP15 VBAR register */ + ldr r0, =_start + add r0, r0, r9 + mcr p15, 0, r0, c12, c0, 0 @Set VBAR +#endif /* !Tegra20 */ -_rel_dyn_start_ofs: - .word __rel_dyn_start - _start -_rel_dyn_end_ofs: - .word __rel_dyn_end - _start -_dynsym_start_ofs: - .word __dynsym_start - _start + bx lr + +ENDPROC(c_runtime_cpu_setup) -#ifndef CONFIG_SKIP_LOWLEVEL_INIT /************************************************************************* * - * CPU_init_critical registers + * void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3) + * __attribute__((weak)); * - * setup important registers - * setup memory timing + * Stack pointer is not yet initialized at this moment + * Don't save anything to stack even if compiled with -O0 * *************************************************************************/ -cpu_init_crit: +ENTRY(save_boot_params) + bx lr @ back to my caller +ENDPROC(save_boot_params) + .weak save_boot_params + +/************************************************************************* + * + * cpu_init_cp15 + * + * Setup CP15 registers (cache, MMU, TLBs). The I-cache is turned on unless + * CONFIG_SYS_ICACHE_OFF is defined. + * + *************************************************************************/ +ENTRY(cpu_init_cp15) /* * Invalidate L1 I/D */ @@ -317,18 +312,30 @@ cpu_init_crit: orr r0, r0, #0x00001000 @ set bit 12 (I) I-cache #endif mcr p15, 0, r0, c1, c0, 0 + mov pc, lr @ back to my caller +ENDPROC(cpu_init_cp15) +#ifndef CONFIG_SKIP_LOWLEVEL_INIT +/************************************************************************* + * + * CPU_init_critical registers + * + * setup important registers + * setup memory timing + * + *************************************************************************/ +ENTRY(cpu_init_crit) /* * Jump to board specific initialization... * The Mask ROM will have already initialized * basic memory. Go here to bump up clock rate and handle * wake up conditions. */ - mov ip, lr @ persevere link reg across call - bl lowlevel_init @ go setup pll,mux,memory - mov lr, ip @ restore link - mov pc, lr @ back to my caller + b lowlevel_init @ go setup pll,mux,memory +ENDPROC(cpu_init_crit) #endif + +#ifndef CONFIG_SPL_BUILD /* ************************************************************************* * @@ -516,4 +523,5 @@ fiq: bad_save_user_regs bl do_fiq -#endif +#endif /* CONFIG_USE_IRQ */ +#endif /* CONFIG_SPL_BUILD */