diff options
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 e10dafca5..6923f6daf 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 41eb82dae..8b631920c 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 e7eefc972..1db4b49cc 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 f98a7aa35..e5e7913d9 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 8969587e8..fa640eec2 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 d6f2c165c..0f5f6c461 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 c975fc3d5..4a0bc70c7 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 e532f55bf..a079bb272 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 a7decfcd7..698543479 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 346615e4b..c0a856dfe 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,6 +114,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 @@ -168,6 +200,168 @@ poll1:  	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 + */ + +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 +  #ifndef CONFIG_SKIP_RELOCATE_UBOOT  relocate:				/* relocate U-Boot to RAM	    */  	adr	r0, _start		/* r0 <- current position of 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 e21d6dc5a..1c4e9bcfb 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 c719798a6..c5c8ab7e4 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 cf40ce129..16ee972f2 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,7 +147,165 @@ 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. + */ +#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   */ @@ -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 ecbc58c7c..02eb8ca60 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 8844d4438..18ed0b2da 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,6 +118,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 @@ -137,6 +169,132 @@ 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 +#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 +  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 */ @@ -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 fef21c758..653596309 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 328bae027..b39fdc64c 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 4ed7d8906..242c7ece0 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 d66434c95..55d6599b4 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 fdc1666fe..cda87ba1a 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 fae5b1161..da2cd9001 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 890522443..2719bb53a 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 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 diff --git a/arch/arm/cpu/armv7/u-boot.lds b/arch/arm/cpu/armv7/u-boot.lds index 9e5b5a97d..d4fd3fcce 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 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 diff --git a/arch/arm/cpu/ixp/u-boot.lds b/arch/arm/cpu/ixp/u-boot.lds index b8ff2eed5..f3d9dc514 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 14a1fbe12..002116a40 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,6 +105,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 @@ -149,6 +181,151 @@ 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 +#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 + */ + +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 +  #ifndef CONFIG_SKIP_RELOCATE_UBOOT  relocate:				/* relocate U-Boot to RAM	    */  	adr	r0, _start		/* r0 <- current position of 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 5a8ccf588..cb55b0a27 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 8010b0ee1..064ddbcf3 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 d4e85ef55..74a4c6e90 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 0063063f4..e1ab5ccb3 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 267d94c08..bbc8c3aa5 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 deb4745e2..4730e5a9a 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 f6197acd8..2e2929190 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 b76fd8eb4..4e8dfd7bc 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 02cfe4584..6152f348f 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 6d2f8bccb..faf800a17 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 cfd5a9ba4..ed3332709 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 e17f182e1..5f2dfd08a 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 62ed54fb4..fe6d45987 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 61ee9d3b1..55b633ee0 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 1f2b81561..9a21e7b40 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; |