diff options
Diffstat (limited to 'arch/arm/cpu/armv7/start.S')
| -rw-r--r-- | arch/arm/cpu/armv7/start.S | 191 | 
1 files changed, 187 insertions, 4 deletions
| diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S index 1e0a1504b..f411c0f4f 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 |