diff options
Diffstat (limited to 'arch/arm/cpu/ixp/start.S')
| -rw-r--r-- | arch/arm/cpu/ixp/start.S | 280 | 
1 files changed, 280 insertions, 0 deletions
| diff --git a/arch/arm/cpu/ixp/start.S b/arch/arm/cpu/ixp/start.S index 6efe333f1..b2c825514 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 |