X-Git-Url: https://git.kernelconcepts.de/?p=karo-tx-uboot.git;a=blobdiff_plain;f=arch%2Farm%2Fcpu%2Farmv7%2Fstart.S;h=d23dc9d719b926cc7f2e3b978fbc728d1df8a2e8;hp=f411c0f4f058f9bd44f5412e2137fe868d8f2782;hb=1086c5d6f8541460f0f10e4a302d8aac27e0e6e0;hpb=561142af20f1fd7b425d9425730014e656defb91 diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S index f411c0f4f0..d23dc9d719 100644 --- a/arch/arm/cpu/armv7/start.S +++ b/arch/arm/cpu/armv7/start.S @@ -29,8 +29,10 @@ * MA 02111-1307 USA */ +#include #include #include +#include .globl _start _start: b reset @@ -41,7 +43,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 @@ -50,6 +61,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: @@ -67,9 +80,15 @@ _end_vect: .globl _TEXT_BASE _TEXT_BASE: - .word TEXT_BASE + .word CONFIG_SYS_TEXT_BASE -#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC) +#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 @@ -78,13 +97,21 @@ _armboot_start: /* * These are defined in the board-specific linker script. */ -.globl _bss_start -_bss_start: - .word __bss_start +.globl _bss_start_ofs +_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 -.globl _bss_end -_bss_end: - .word _end +.globl _end_ofs +_end_ofs: + .word _end - _start #ifdef CONFIG_USE_IRQ /* IRQ stack memory (calculated at run-time) */ @@ -98,41 +125,17 @@ 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: + bl save_boot_params /* * set the cpu to SVC32 mode */ @@ -141,29 +144,22 @@ reset: 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 */ +/* + * 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_crit @@ -172,6 +168,7 @@ next: /* 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 @@ -189,172 +186,121 @@ 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 + moveq r9, #0 /* no relocation. relocation offset(r9) = 0 */ + beq clear_bss /* skip relocation */ + mov r1, r6 /* r1 <- scratch for copy_loop */ + ldr r3, _image_copy_end_ofs + add r2, r0, r3 /* r2 <- source end address */ 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 + stmia r1!, {r9-r10} /* copy to target address [r1] */ + cmp r0, r2 /* until source end address [r2] */ + blo copy_loop +#ifndef CONFIG_SPL_BUILD + /* + * fix .rel.dyn relocations + */ + ldr r0, _TEXT_BASE /* r0 <- Text base */ + 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 */ + ldr r2, _rel_dyn_start_ofs /* r2 <- rel dyn start ofs */ + add r2, r2, r0 /* r2 <- rel dyn start in FLASH */ + ldr r3, _rel_dyn_end_ofs /* r3 <- rel dyn end ofs */ + add r3, r3, r0 /* r3 <- rel dyn end in FLASH */ fixloop: - ldr r4, [r2] - sub r4, r4, r1 - add r4, r4, r0 - str r4, [r2] - add r2, r2, #4 + ldr r0, [r2] /* r0 <- location to fix up, IN FLASH! */ + add r0, r0, r9 /* r0 <- location to fix up in RAM */ + ldr r1, [r2, #4] + and r7, r1, #0xff + cmp r7, #23 /* relative fixup? */ + beq fixrel + cmp r7, #2 /* absolute fixup? */ + beq fixabs + /* ignore unknown type of fixup */ + b fixnext +fixabs: + /* absolute fix: set location to (offset) symbol value */ + mov r1, r1, LSR #4 /* r1 <- symbol index in .dynsym */ + add r1, r10, r1 /* r1 <- address of symbol in table */ + ldr r1, [r1, #4] /* r1 <- symbol value */ + add r1, r1, r9 /* r1 <- relocated sym addr */ + b fixnext +fixrel: + /* relative fix: increase location by offset */ + ldr r1, [r0] + add r1, r1, r9 +fixnext: + str r1, [r0] + add r2, r2, #8 /* each rel.dyn entry is 8 bytes */ cmp r2, r3 - bne fixloop + blo fixloop + b clear_bss +_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 + +#endif /* #ifndef CONFIG_SPL_BUILD */ 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 +#ifdef CONFIG_SPL_BUILD + /* No relocation for SPL */ + ldr r0, =__bss_start + ldr r1, =__bss_end__ +#else + ldr r0, _bss_start_ofs + ldr r1, _bss_end_ofs + mov r4, r6 /* reloc addr */ add r0, r0, r4 - sub r1, r1, r3 add r1, r1, r4 +#endif 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 */ +/* + * If I-cache is enabled invalidate it + */ +#ifndef CONFIG_SYS_ICACHE_OFF + mcr p15, 0, r0, c7, c5, 0 @ invalidate icache + 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, r7 /* dest_addr */ + mov r1, r6 /* 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 - */ +_board_init_r_ofs: + .word board_init_r - _start -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 - -#ifndef CONFIG_SKIP_RELOCATE_UBOOT -relocate: @ relocate U-Boot to RAM - adr r0, _start @ r0 <- current position of code - ldr r1, _TEXT_BASE @ test if we run from flash or RAM - cmp r0, r1 @ don't reloc during debug - beq stack_setup - - ldr r2, _armboot_start - ldr r3, _bss_start - sub r2, r3, r2 @ r2 <- size of armboot - add r2, r0, r2 @ r2 <- source end address - -copy_loop: @ copy 32 bytes at a time - ldmia r0!, {r3 - r10} @ copy from source address [r0] - stmia r1!, {r3 - r10} @ copy to target address [r1] - cmp r0, r2 @ until source end addreee [r2] - ble copy_loop -#endif /* CONFIG_SKIP_RELOCATE_UBOOT */ - - /* Set up the stack */ -stack_setup: - ldr r0, _TEXT_BASE @ upper 128 KiB: relocated uboot - sub r0, r0, #CONFIG_SYS_MALLOC_LEN @ malloc area - sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE @ bdinfo -#ifdef CONFIG_USE_IRQ - sub r0, r0, #(CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ) -#endif - sub sp, r0, #12 @ leave 3 words for abort-stack - bic sp, sp, #7 @ 8-byte alignment for ABI compliance - - /* Clear BSS (if any). Is below tx (watch load addr - need space) */ -clear_bss: - ldr r0, _bss_start @ find start of bss segment - ldr r1, _bss_end @ stop here - mov r2, #0x00000000 @ clear value -clbss_l: - str r2, [r0] @ clear BSS location - cmp r0, r1 @ are we at the end yet - add r0, r0, #4 @ increment clear index pointer - bne clbss_l @ keep clearing till at end - - ldr pc, _start_armboot @ jump to C code - -_start_armboot: .word start_armboot -#endif /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */ - /************************************************************************* * * CPU_init_critical registers @@ -370,6 +316,9 @@ cpu_init_crit: mov r0, #0 @ set up for MCR mcr p15, 0, r0, c8, c7, 0 @ invalidate TLBs mcr p15, 0, r0, c7, c5, 0 @ invalidate icache + mcr p15, 0, r0, c7, c5, 6 @ invalidate BP array + mcr p15, 0, r0, c7, c10, 4 @ DSB + mcr p15, 0, r0, c7, c5, 4 @ ISB /* * disable MMU stuff and caches @@ -378,7 +327,12 @@ cpu_init_crit: bic r0, r0, #0x00002000 @ clear bits 13 (--V-) bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM) orr r0, r0, #0x00000002 @ set bit 1 (--A-) Align - orr r0, r0, #0x00000800 @ set bit 12 (Z---) BTB + orr r0, r0, #0x00000800 @ set bit 11 (Z---) BTB +#ifdef CONFIG_SYS_ICACHE_OFF + bic r0, r0, #0x00001000 @ clear bit 12 (I) I-cache +#else + orr r0, r0, #0x00001000 @ set bit 12 (I) I-cache +#endif mcr p15, 0, r0, c1, c0, 0 /* @@ -391,6 +345,9 @@ cpu_init_crit: bl lowlevel_init @ go setup pll,mux,memory mov lr, ip @ restore link mov pc, lr @ back to my caller +#endif + +#ifndef CONFIG_SPL_BUILD /* ************************************************************************* * @@ -436,14 +393,8 @@ 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 @@ -479,14 +430,8 @@ cpu_init_crit: .endm .macro get_bad_stack -#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC) - ldr r13, _armboot_start @ setup our mode stack (enter - 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 -#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 @@ -507,14 +452,8 @@ 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 @@ -596,4 +535,5 @@ fiq: bad_save_user_regs bl do_fiq -#endif +#endif /* CONFIG_USE_IRQ */ +#endif /* CONFIG_SPL_BUILD */