arm: move exception handling out of start.S files
Exception handling is basically identical for all ARM targets. Factorize it out of the various start.S files and into a single vectors.S file, and adjust linker scripts accordingly. Signed-off-by: Albert ARIBAUD <albert.u.boot@aribaud.net>
This commit is contained in:
		
							parent
							
								
									60a4f39fcd
								
							
						
					
					
						commit
						41623c91b0
					
				|  | @ -15,46 +15,7 @@ | |||
| #include <asm-offsets.h> | ||||
| #include <config.h> | ||||
| #include <version.h> | ||||
| .globl _start
 | ||||
| _start: b	reset | ||||
| #ifdef CONFIG_SPL_BUILD | ||||
| 	ldr	pc, _hang | ||||
| 	ldr	pc, _hang | ||||
| 	ldr	pc, _hang | ||||
| 	ldr	pc, _hang | ||||
| 	ldr	pc, _hang | ||||
| 	ldr	pc, _hang | ||||
| 	ldr	pc, _hang | ||||
| 
 | ||||
| _hang: | ||||
| 	.word	do_hang
 | ||||
| 	.word	0x12345678
 | ||||
| 	.word	0x12345678
 | ||||
| 	.word	0x12345678
 | ||||
| 	.word	0x12345678
 | ||||
| 	.word	0x12345678
 | ||||
| 	.word	0x12345678
 | ||||
| 	.word	0x12345678	/* now 16*4=64 */ | ||||
| #else | ||||
| 	ldr	pc, _undefined_instruction | ||||
| 	ldr	pc, _software_interrupt | ||||
| 	ldr	pc, _prefetch_abort | ||||
| 	ldr	pc, _data_abort | ||||
| 	ldr	pc, _not_used | ||||
| 	ldr	pc, _irq | ||||
| 	ldr	pc, _fiq | ||||
| 
 | ||||
| _undefined_instruction: .word undefined_instruction | ||||
| _software_interrupt:	.word software_interrupt | ||||
| _prefetch_abort:	.word prefetch_abort | ||||
| _data_abort:		.word data_abort | ||||
| _not_used:		.word not_used | ||||
| _irq:			.word irq | ||||
| _fiq:			.word fiq | ||||
| _pad:			.word 0x12345678 /* now 16*4=64 */ | ||||
| #endif	/* CONFIG_SPL_BUILD */ | ||||
| 
 | ||||
| 	.balignl 16,0xdeadbeef | ||||
| /* | ||||
|  ************************************************************************* | ||||
|  * | ||||
|  | @ -68,26 +29,7 @@ _pad:			.word 0x12345678 /* now 16*4=64 */ | |||
|  ************************************************************************* | ||||
|  */ | ||||
| 
 | ||||
| #ifdef CONFIG_USE_IRQ | ||||
| /* IRQ stack memory (calculated at run-time) */ | ||||
| .globl IRQ_STACK_START
 | ||||
| IRQ_STACK_START: | ||||
| 	.word	0x0badc0de
 | ||||
| 
 | ||||
| /* IRQ stack memory (calculated at run-time) */ | ||||
| .globl FIQ_STACK_START
 | ||||
| FIQ_STACK_START: | ||||
| 	.word 0x0badc0de
 | ||||
| #endif | ||||
| 
 | ||||
| /* IRQ stack memory (calculated at run-time) + 8 bytes */ | ||||
| .globl IRQ_STACK_START_IN
 | ||||
| IRQ_STACK_START_IN: | ||||
| 	.word	0x0badc0de
 | ||||
| 
 | ||||
| /* | ||||
|  * the actual reset code | ||||
|  */ | ||||
| 	.globl	reset
 | ||||
| 
 | ||||
| reset: | ||||
| 	/* | ||||
|  | @ -150,185 +92,3 @@ cpu_init_crit: | |||
| 	mov	lr, ip		/* restore link */ | ||||
| 	mov	pc, lr		/* back to my caller */ | ||||
| #endif /* CONFIG_SKIP_LOWLEVEL_INIT */ | ||||
| 
 | ||||
| #ifndef CONFIG_SPL_BUILD | ||||
| /* | ||||
|  ************************************************************************* | ||||
|  * | ||||
|  * Interrupt handling | ||||
|  * | ||||
|  ************************************************************************* | ||||
|  */ | ||||
| @
 | ||||
| @ IRQ stack frame.
 | ||||
| @
 | ||||
| #define S_FRAME_SIZE	72 | ||||
| 
 | ||||
| #define S_OLD_R0	68 | ||||
| #define S_PSR		64 | ||||
| #define S_PC		60 | ||||
| #define S_LR		56 | ||||
| #define S_SP		52 | ||||
| 
 | ||||
| #define S_IP		48 | ||||
| #define S_FP		44 | ||||
| #define S_R10		40 | ||||
| #define S_R9		36 | ||||
| #define S_R8		32 | ||||
| #define S_R7		28 | ||||
| #define S_R6		24 | ||||
| #define S_R5		20 | ||||
| #define S_R4		16 | ||||
| #define S_R3		12 | ||||
| #define S_R2		8 | ||||
| #define S_R1		4 | ||||
| #define S_R0		0 | ||||
| 
 | ||||
| #define MODE_SVC 0x13 | ||||
| #define I_BIT	 0x80 | ||||
| 
 | ||||
| /* | ||||
|  * use bad_save_user_regs for abort/prefetch/undef/swi ... | ||||
|  * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling | ||||
|  */ | ||||
| 
 | ||||
| 	.macro	bad_save_user_regs
 | ||||
| 	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
 | ||||
| 
 | ||||
| 	ldr	r2, IRQ_STACK_START_IN		@ set base 2 words into abort stack
 | ||||
| 	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 | ||||
| 
 | ||||
| 	add	r5, sp, #S_SP | ||||
| 	mov	r1, lr | ||||
| 	stmia	r5, {r0 - r3}			@ save sp_SVC, lr_SVC, pc, cpsr
 | ||||
| 	mov	r0, sp				@ save current stack into r0 (param register)
 | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro	irq_save_user_regs
 | ||||
| 	sub	sp, sp, #S_FRAME_SIZE | ||||
| 	stmia	sp, {r0 - r12}			@ Calling r0-r12
 | ||||
| 	add	r8, sp, #S_PC			@ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good. | ||||
| 	stmdb	r8, {sp, lr}^			@ Calling SP, LR
 | ||||
| 	str	lr, [r8, #0]			@ Save calling PC
 | ||||
| 	mrs	r6, spsr | ||||
| 	str	r6, [r8, #4]			@ Save CPSR
 | ||||
| 	str	r0, [r8, #8]			@ Save OLD_R0
 | ||||
| 	mov	r0, sp | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro	irq_restore_user_regs
 | ||||
| 	ldmia	sp, {r0 - lr}^			@ Calling r0 - lr
 | ||||
| 	mov	r0, r0 | ||||
| 	ldr	lr, [sp, #S_PC]			@ Get PC | ||||
| 	add	sp, sp, #S_FRAME_SIZE | ||||
| 	subs	pc, lr, #4			@ return & move spsr_svc into cpsr
 | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro get_bad_stack
 | ||||
| 	ldr	r13, IRQ_STACK_START_IN		@ setup our mode stack (enter in banked mode)
 | ||||
| 
 | ||||
| 	str	lr, [r13]			@ save caller lr in position 0 of saved stack
 | ||||
| 	mrs	lr, spsr			@ get the spsr
 | ||||
| 	str	lr, [r13, #4]			@ save spsr in position 1 of saved stack
 | ||||
| 
 | ||||
| 	mov	r13, #MODE_SVC			@ prepare SVC-Mode | ||||
| 	@ msr	spsr_c, r13
 | ||||
| 	msr	spsr, r13			@ switch modes, make sure moves will execute
 | ||||
| 	mov	lr, pc				@ capture return pc
 | ||||
| 	movs	pc, lr				@ jump to next instruction & switch modes.
 | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro get_bad_stack_swi
 | ||||
| 	sub	r13, r13, #4			@ space on current stack for scratch reg.
 | ||||
| 	str	r0, [r13]			@ save R0's value.
 | ||||
| 	ldr	r0, IRQ_STACK_START_IN		@ get data regions start
 | ||||
| 	str	lr, [r0]			@ save caller lr in position 0 of saved stack
 | ||||
| 	mrs	lr, spsr			@ get the spsr
 | ||||
| 	str	lr, [r0, #4]			@ save spsr in position 1 of saved stack
 | ||||
| 	ldr	lr, [r0]			@ restore lr
 | ||||
| 	ldr	r0, [r13]			@ restore r0
 | ||||
| 	add	r13, r13, #4			@ pop stack entry
 | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro get_irq_stack			@ setup IRQ stack
 | ||||
| 	ldr	sp, IRQ_STACK_START | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro get_fiq_stack			@ setup FIQ stack
 | ||||
| 	ldr	sp, FIQ_STACK_START | ||||
| 	.endm | ||||
| #endif	/* CONFIG_SPL_BUILD */ | ||||
| 
 | ||||
| /* | ||||
|  * exception handlers | ||||
|  */ | ||||
| #ifdef CONFIG_SPL_BUILD | ||||
| 	.align	5
 | ||||
| do_hang: | ||||
| 	bl	hang				/* hang and never return */ | ||||
| #else	/* !CONFIG_SPL_BUILD */ | ||||
| 	.align	5
 | ||||
| undefined_instruction: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_undefined_instruction | ||||
| 
 | ||||
| 	.align	5
 | ||||
| software_interrupt: | ||||
| 	get_bad_stack_swi | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_software_interrupt | ||||
| 
 | ||||
| 	.align	5
 | ||||
| prefetch_abort: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_prefetch_abort | ||||
| 
 | ||||
| 	.align	5
 | ||||
| data_abort: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_data_abort | ||||
| 
 | ||||
| 	.align	5
 | ||||
| not_used: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_not_used | ||||
| 
 | ||||
| #ifdef CONFIG_USE_IRQ | ||||
| 
 | ||||
| 	.align	5
 | ||||
| irq: | ||||
| 	get_irq_stack | ||||
| 	irq_save_user_regs | ||||
| 	bl	do_irq | ||||
| 	irq_restore_user_regs | ||||
| 
 | ||||
| 	.align	5
 | ||||
| fiq: | ||||
| 	get_fiq_stack | ||||
| 	/* someone ought to write a more effiction fiq_save_user_regs */ | ||||
| 	irq_save_user_regs | ||||
| 	bl	do_fiq | ||||
| 	irq_restore_user_regs | ||||
| 
 | ||||
| #else | ||||
| 
 | ||||
| 	.align	5
 | ||||
| irq: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_irq | ||||
| 
 | ||||
| 	.align	5
 | ||||
| fiq: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_fiq | ||||
| 
 | ||||
| #endif | ||||
| #endif	/* CONFIG_SPL_BUILD */ | ||||
|  |  | |||
|  | @ -22,46 +22,6 @@ | |||
| #define CONFIG_SYS_PHY_UBOOT_BASE	CONFIG_SYS_UBOOT_BASE | ||||
| #endif | ||||
| 
 | ||||
| /* | ||||
|  ************************************************************************* | ||||
|  * | ||||
|  * Jump vector table as in table 3.1 in [1] | ||||
|  * | ||||
|  ************************************************************************* | ||||
|  */ | ||||
| 
 | ||||
| .globl _start
 | ||||
| _start: b	reset | ||||
| #ifndef CONFIG_SPL_BUILD | ||||
| 	ldr	pc, _undefined_instruction | ||||
| 	ldr	pc, _software_interrupt | ||||
| 	ldr	pc, _prefetch_abort | ||||
| 	ldr	pc, _data_abort | ||||
| 	ldr	pc, _not_used | ||||
| 	ldr	pc, _irq | ||||
| 	ldr	pc, _fiq | ||||
| 
 | ||||
| _undefined_instruction: | ||||
| 	.word undefined_instruction
 | ||||
| _software_interrupt: | ||||
| 	.word software_interrupt
 | ||||
| _prefetch_abort: | ||||
| 	.word prefetch_abort
 | ||||
| _data_abort: | ||||
| 	.word data_abort
 | ||||
| _not_used: | ||||
| 	.word not_used
 | ||||
| _irq: | ||||
| 	.word irq
 | ||||
| _fiq: | ||||
| 	.word fiq
 | ||||
| _pad: | ||||
| 	.word 0x12345678 /* now 16*4=64 */ | ||||
| #else | ||||
| 	. = _start + 64 | ||||
| #endif | ||||
| 
 | ||||
| 	.balignl 16,0xdeadbeef | ||||
| /* | ||||
|  ************************************************************************* | ||||
|  * | ||||
|  | @ -75,14 +35,7 @@ _pad: | |||
|  ************************************************************************* | ||||
|  */ | ||||
| 
 | ||||
| /* IRQ stack memory (calculated at run-time) + 8 bytes */ | ||||
| .globl IRQ_STACK_START_IN
 | ||||
| IRQ_STACK_START_IN: | ||||
| 	.word	0x0badc0de
 | ||||
| 
 | ||||
| /* | ||||
|  * the actual reset code | ||||
|  */ | ||||
| 	.globl reset
 | ||||
| 
 | ||||
| reset: | ||||
| 	/* | ||||
|  | @ -180,150 +133,3 @@ skip_tcmdisable: | |||
| c_runtime_cpu_setup: | ||||
| 
 | ||||
| 	mov	pc, lr | ||||
| 
 | ||||
| #ifndef CONFIG_SPL_BUILD | ||||
| /* | ||||
|  ************************************************************************* | ||||
|  * | ||||
|  * Interrupt handling | ||||
|  * | ||||
|  ************************************************************************* | ||||
|  */ | ||||
| @
 | ||||
| @ IRQ stack frame.
 | ||||
| @
 | ||||
| #define S_FRAME_SIZE	72 | ||||
| 
 | ||||
| #define S_OLD_R0	68 | ||||
| #define S_PSR		64 | ||||
| #define S_PC		60 | ||||
| #define S_LR		56 | ||||
| #define S_SP		52 | ||||
| 
 | ||||
| #define S_IP		48 | ||||
| #define S_FP		44 | ||||
| #define S_R10		40 | ||||
| #define S_R9		36 | ||||
| #define S_R8		32 | ||||
| #define S_R7		28 | ||||
| #define S_R6		24 | ||||
| #define S_R5		20 | ||||
| #define S_R4		16 | ||||
| #define S_R3		12 | ||||
| #define S_R2		8 | ||||
| #define S_R1		4 | ||||
| #define S_R0		0 | ||||
| 
 | ||||
| #define MODE_SVC 0x13 | ||||
| #define I_BIT	 0x80 | ||||
| 
 | ||||
| /* | ||||
|  * use bad_save_user_regs for abort/prefetch/undef/swi ... | ||||
|  */ | ||||
| 
 | ||||
| 	.macro	bad_save_user_regs
 | ||||
| 	/* carve out a frame on current user stack */ | ||||
| 	sub	sp, sp, #S_FRAME_SIZE | ||||
| 	/* Save user registers (now in svc mode) r0-r12 */ | ||||
| 	stmia	sp, {r0 - r12} | ||||
| 
 | ||||
| 	ldr	r2, IRQ_STACK_START_IN | ||||
| 	/* get values for "aborted" pc and cpsr (into parm regs) */ | ||||
| 	ldmia	r2, {r2 - r3} | ||||
| 	/* grab pointer to old stack */ | ||||
| 	add	r0, sp, #S_FRAME_SIZE | ||||
| 
 | ||||
| 	add	r5, sp, #S_SP | ||||
| 	mov	r1, lr | ||||
| 	/* save sp_SVC, lr_SVC, pc, cpsr */ | ||||
| 	stmia	r5, {r0 - r3} | ||||
| 	/* save current stack into r0 (param register) */ | ||||
| 	mov	r0, sp | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro get_bad_stack
 | ||||
| 	ldr	r13, IRQ_STACK_START_IN		@ setup our mode stack
 | ||||
| 
 | ||||
| 	/* save caller lr in position 0 of saved stack */ | ||||
| 	str	lr, [r13] | ||||
| 	/* get the spsr */ | ||||
| 	mrs	lr, spsr | ||||
| 	/* save spsr in position 1 of saved stack */ | ||||
| 	str	lr, [r13, #4] | ||||
| 
 | ||||
| 	/* prepare SVC-Mode */ | ||||
| 	mov	r13, #MODE_SVC | ||||
| 	@ msr	spsr_c, r13
 | ||||
| 	/* switch modes, make sure moves will execute */ | ||||
| 	msr	spsr, r13 | ||||
| 	/* capture return pc */ | ||||
| 	mov	lr, pc | ||||
| 	/* jump to next instruction & switch modes. */ | ||||
| 	movs	pc, lr | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro get_bad_stack_swi
 | ||||
| 	/* space on current stack for scratch reg. */ | ||||
| 	sub	r13, r13, #4 | ||||
| 	/* save R0's value. */ | ||||
| 	str	r0, [r13] | ||||
| 	ldr	r13, IRQ_STACK_START_IN		@ setup our mode stack
 | ||||
| 	/* save caller lr in position 0 of saved stack */ | ||||
| 	str	lr, [r0] | ||||
| 	/* get the spsr */ | ||||
| 	mrs	lr, spsr | ||||
| 	/* save spsr in position 1 of saved stack */ | ||||
| 	str	lr, [r0, #4] | ||||
| 	/* restore lr */ | ||||
| 	ldr	lr, [r0] | ||||
| 	/* restore r0 */ | ||||
| 	ldr	r0, [r13] | ||||
| 	/* pop stack entry */ | ||||
| 	add	r13, r13, #4 | ||||
| 	.endm | ||||
| 
 | ||||
| /* | ||||
|  * exception handlers | ||||
|  */ | ||||
| 	.align	5
 | ||||
| undefined_instruction: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_undefined_instruction | ||||
| 
 | ||||
| 	.align	5
 | ||||
| software_interrupt: | ||||
| 	get_bad_stack_swi | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_software_interrupt | ||||
| 
 | ||||
| 	.align	5
 | ||||
| prefetch_abort: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_prefetch_abort | ||||
| 
 | ||||
| 	.align	5
 | ||||
| data_abort: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_data_abort | ||||
| 
 | ||||
| 	.align	5
 | ||||
| not_used: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_not_used | ||||
| 
 | ||||
| 	.align	5
 | ||||
| irq: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_irq | ||||
| 
 | ||||
| 	.align	5
 | ||||
| fiq: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_fiq | ||||
| #endif /* CONFIG_SPL_BUILD */ | ||||
|  |  | |||
|  | @ -12,48 +12,6 @@ | |||
| #include <version.h> | ||||
| #include <asm/hardware.h> | ||||
| 
 | ||||
| /* | ||||
|  ************************************************************************* | ||||
|  * | ||||
|  * Jump vector table as in table 3.1 in [1] | ||||
|  * | ||||
|  ************************************************************************* | ||||
|  */ | ||||
| 
 | ||||
| 
 | ||||
| .globl _start
 | ||||
| _start: b	reset | ||||
| 	ldr	pc, _undefined_instruction | ||||
| 	ldr	pc, _software_interrupt | ||||
| 	ldr	pc, _prefetch_abort | ||||
| 	ldr	pc, _data_abort | ||||
| 	ldr	pc, _not_used | ||||
| 	ldr	pc, _irq | ||||
| 	ldr	pc, _fiq | ||||
| 
 | ||||
| #ifdef CONFIG_SPL_BUILD | ||||
| _undefined_instruction: .word _undefined_instruction | ||||
| _software_interrupt:	.word _software_interrupt | ||||
| _prefetch_abort:	.word _prefetch_abort | ||||
| _data_abort:		.word _data_abort | ||||
| _not_used:		.word _not_used | ||||
| _irq:			.word _irq | ||||
| _fiq:			.word _fiq | ||||
| _pad:			.word 0x12345678 /* now 16*4=64 */ | ||||
| #else | ||||
| _undefined_instruction: .word undefined_instruction | ||||
| _software_interrupt:	.word software_interrupt | ||||
| _prefetch_abort:	.word prefetch_abort | ||||
| _data_abort:		.word data_abort | ||||
| _not_used:		.word not_used | ||||
| _irq:			.word irq | ||||
| _fiq:			.word fiq | ||||
| _pad:			.word 0x12345678 /* now 16*4=64 */ | ||||
| #endif	/* CONFIG_SPL_BUILD */ | ||||
| 
 | ||||
| 	.balignl 16,0xdeadbeef | ||||
| 
 | ||||
| 
 | ||||
| /* | ||||
|  ************************************************************************* | ||||
|  * | ||||
|  | @ -67,26 +25,7 @@ _pad:			.word 0x12345678 /* now 16*4=64 */ | |||
|  ************************************************************************* | ||||
|  */ | ||||
| 
 | ||||
| #ifdef CONFIG_USE_IRQ | ||||
| /* IRQ stack memory (calculated at run-time) */ | ||||
| .globl IRQ_STACK_START
 | ||||
| IRQ_STACK_START: | ||||
| 	.word	0x0badc0de
 | ||||
| 
 | ||||
| /* IRQ stack memory (calculated at run-time) */ | ||||
| .globl FIQ_STACK_START
 | ||||
| FIQ_STACK_START: | ||||
| 	.word 0x0badc0de
 | ||||
| #endif | ||||
| 
 | ||||
| /* IRQ stack memory (calculated at run-time) + 8 bytes */ | ||||
| .globl IRQ_STACK_START_IN
 | ||||
| IRQ_STACK_START_IN: | ||||
| 	.word	0x0badc0de
 | ||||
| 
 | ||||
| /* | ||||
|  * the actual reset code | ||||
|  */ | ||||
| 	.globl	reset
 | ||||
| 
 | ||||
| reset: | ||||
| 	/* | ||||
|  | @ -139,169 +78,3 @@ cpu_init_crit: | |||
| 
 | ||||
| 	mov	pc, lr | ||||
| #endif /* CONFIG_SKIP_LOWLEVEL_INIT */ | ||||
| 
 | ||||
| 
 | ||||
| #ifndef CONFIG_SPL_BUILD | ||||
| /* | ||||
|  ************************************************************************* | ||||
|  * | ||||
|  * Interrupt handling | ||||
|  * | ||||
|  ************************************************************************* | ||||
|  */ | ||||
| 
 | ||||
| @
 | ||||
| @ IRQ stack frame.
 | ||||
| @
 | ||||
| #define S_FRAME_SIZE	72 | ||||
| 
 | ||||
| #define S_OLD_R0	68 | ||||
| #define S_PSR		64 | ||||
| #define S_PC		60 | ||||
| #define S_LR		56 | ||||
| #define S_SP		52 | ||||
| 
 | ||||
| #define S_IP		48 | ||||
| #define S_FP		44 | ||||
| #define S_R10		40 | ||||
| #define S_R9		36 | ||||
| #define S_R8		32 | ||||
| #define S_R7		28 | ||||
| #define S_R6		24 | ||||
| #define S_R5		20 | ||||
| #define S_R4		16 | ||||
| #define S_R3		12 | ||||
| #define S_R2		8 | ||||
| #define S_R1		4 | ||||
| #define S_R0		0 | ||||
| 
 | ||||
| #define MODE_SVC 0x13 | ||||
| #define I_BIT	 0x80 | ||||
| 
 | ||||
| /* | ||||
|  * use bad_save_user_regs for abort/prefetch/undef/swi ... | ||||
|  * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling | ||||
|  */ | ||||
| 
 | ||||
| 	.macro	bad_save_user_regs
 | ||||
| 	sub	sp, sp, #S_FRAME_SIZE | ||||
| 	stmia	sp, {r0 - r12}			@ Calling r0-r12
 | ||||
| 	add	r8, sp, #S_PC | ||||
| 
 | ||||
| 	ldr	r2, IRQ_STACK_START_IN | ||||
| 	ldmia	r2, {r2 - r4}			@ get pc, cpsr, old_r0
 | ||||
| 	add	r0, sp, #S_FRAME_SIZE		@ restore sp_SVC | ||||
| 
 | ||||
| 	add	r5, sp, #S_SP | ||||
| 	mov	r1, lr | ||||
| 	stmia	r5, {r0 - r4}			@ save sp_SVC, lr_SVC, pc, cpsr, old_r
 | ||||
| 	mov	r0, sp | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro	irq_save_user_regs
 | ||||
| 	sub	sp, sp, #S_FRAME_SIZE | ||||
| 	stmia	sp, {r0 - r12}			@ Calling r0-r12
 | ||||
| 	add	r8, sp, #S_PC | ||||
| 	stmdb	r8, {sp, lr}^			@ Calling SP, LR
 | ||||
| 	str	lr, [r8, #0]			@ Save calling PC
 | ||||
| 	mrs	r6, spsr | ||||
| 	str	r6, [r8, #4]			@ Save CPSR
 | ||||
| 	str	r0, [r8, #8]			@ Save OLD_R0
 | ||||
| 	mov	r0, sp | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro	irq_restore_user_regs
 | ||||
| 	ldmia	sp, {r0 - lr}^			@ Calling r0 - lr
 | ||||
| 	mov	r0, r0 | ||||
| 	ldr	lr, [sp, #S_PC]			@ Get PC | ||||
| 	add	sp, sp, #S_FRAME_SIZE | ||||
| 	subs	pc, lr, #4			@ return & move spsr_svc into cpsr
 | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro get_bad_stack
 | ||||
| 	ldr	r13, IRQ_STACK_START_IN		@ setup our mode stack
 | ||||
| 
 | ||||
| 	str	lr, [r13]			@ save caller lr / spsr
 | ||||
| 	mrs	lr, spsr | ||||
| 	str	lr, [r13, #4] | ||||
| 
 | ||||
| 	mov	r13, #MODE_SVC			@ prepare SVC-Mode | ||||
| 	msr	spsr_c, r13 | ||||
| 	mov	lr, pc | ||||
| 	movs	pc, lr | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro get_irq_stack			@ setup IRQ stack
 | ||||
| 	ldr	sp, IRQ_STACK_START | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro get_fiq_stack			@ setup FIQ stack
 | ||||
| 	ldr	sp, FIQ_STACK_START | ||||
| 	.endm | ||||
| 
 | ||||
| /* | ||||
|  * exception handlers | ||||
|  */ | ||||
| 	.align	5
 | ||||
| undefined_instruction: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_undefined_instruction | ||||
| 
 | ||||
| 	.align	5
 | ||||
| software_interrupt: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_software_interrupt | ||||
| 
 | ||||
| 	.align	5
 | ||||
| prefetch_abort: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_prefetch_abort | ||||
| 
 | ||||
| 	.align	5
 | ||||
| data_abort: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_data_abort | ||||
| 
 | ||||
| 	.align	5
 | ||||
| not_used: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_not_used | ||||
| 
 | ||||
| #ifdef CONFIG_USE_IRQ | ||||
| 
 | ||||
| 	.align	5
 | ||||
| irq: | ||||
| 	get_irq_stack | ||||
| 	irq_save_user_regs | ||||
| 	bl	do_irq | ||||
| 	irq_restore_user_regs | ||||
| 
 | ||||
| 	.align	5
 | ||||
| fiq: | ||||
| 	get_fiq_stack | ||||
| 	/* someone ought to write a more effiction fiq_save_user_regs */ | ||||
| 	irq_save_user_regs | ||||
| 	bl	do_fiq | ||||
| 	irq_restore_user_regs | ||||
| 
 | ||||
| #else | ||||
| 
 | ||||
| 	.align	5
 | ||||
| irq: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_irq | ||||
| 
 | ||||
| 	.align	5
 | ||||
| fiq: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_fiq | ||||
| 
 | ||||
| #endif | ||||
| #endif /* CONFIG_SPL_BUILD */ | ||||
|  |  | |||
|  | @ -16,7 +16,8 @@ SECTIONS | |||
| 	.text      : | ||||
| 	{ | ||||
| 		*(.__image_copy_start) | ||||
| 	  arch/arm/cpu/arm920t/start.o	(.text*) | ||||
| 		*(.vectors) | ||||
| 		arch/arm/cpu/arm920t/start.o	(.text*) | ||||
| 		/* the EP93xx expects to find the pattern 'CRUS' at 0x1000 */ | ||||
| 	  . = 0x1000; | ||||
| 	  LONG(0x53555243) | ||||
|  |  | |||
|  | @ -12,36 +12,6 @@ | |||
| #include <common.h> | ||||
| #include <config.h> | ||||
| 
 | ||||
| /* | ||||
|  ************************************************************************* | ||||
|  * | ||||
|  * Jump vector table as in table 3.1 in [1] | ||||
|  * | ||||
|  ************************************************************************* | ||||
|  */ | ||||
| 
 | ||||
| 
 | ||||
| .globl _start
 | ||||
| _start:	b	start_code | ||||
| 	ldr	pc, _undefined_instruction | ||||
| 	ldr	pc, _software_interrupt | ||||
| 	ldr	pc, _prefetch_abort | ||||
| 	ldr	pc, _data_abort | ||||
| 	ldr	pc, _not_used | ||||
| 	ldr	pc, _irq | ||||
| 	ldr	pc, _fiq | ||||
| 
 | ||||
| _undefined_instruction:	.word undefined_instruction | ||||
| _software_interrupt:	.word software_interrupt | ||||
| _prefetch_abort:	.word prefetch_abort | ||||
| _data_abort:		.word data_abort | ||||
| _not_used:		.word not_used | ||||
| _irq:			.word irq | ||||
| _fiq:			.word fiq | ||||
| 
 | ||||
| 	.balignl 16,0xdeadbeef | ||||
| 
 | ||||
| 
 | ||||
| /* | ||||
|  ************************************************************************* | ||||
|  * | ||||
|  | @ -55,28 +25,9 @@ _fiq:			.word fiq | |||
|  ************************************************************************* | ||||
|  */ | ||||
| 
 | ||||
| #ifdef CONFIG_USE_IRQ | ||||
| /* IRQ stack memory (calculated at run-time) */ | ||||
| .globl IRQ_STACK_START
 | ||||
| IRQ_STACK_START: | ||||
| 	.word	0x0badc0de
 | ||||
| 	.globl	reset
 | ||||
| 
 | ||||
| /* IRQ stack memory (calculated at run-time) */ | ||||
| .globl FIQ_STACK_START
 | ||||
| FIQ_STACK_START: | ||||
| 	.word 0x0badc0de
 | ||||
| #endif | ||||
| 
 | ||||
| /* IRQ stack memory (calculated at run-time) + 8 bytes */ | ||||
| .globl IRQ_STACK_START_IN
 | ||||
| IRQ_STACK_START_IN: | ||||
| 	.word	0x0badc0de
 | ||||
| 
 | ||||
| /* | ||||
|  * the actual start code | ||||
|  */ | ||||
| 
 | ||||
| start_code: | ||||
| reset: | ||||
| 	/* | ||||
| 	 * set the cpu to SVC32 mode | ||||
| 	 */ | ||||
|  | @ -196,166 +147,3 @@ cpu_init_crit: | |||
| 	mov	lr, ip | ||||
| 	mov	pc, lr | ||||
| #endif /* CONFIG_SKIP_LOWLEVEL_INIT */ | ||||
| 
 | ||||
| /* | ||||
|  ************************************************************************* | ||||
|  * | ||||
|  * Interrupt handling | ||||
|  * | ||||
|  ************************************************************************* | ||||
|  */ | ||||
| 
 | ||||
| @
 | ||||
| @ IRQ stack frame.
 | ||||
| @
 | ||||
| #define S_FRAME_SIZE	72 | ||||
| 
 | ||||
| #define S_OLD_R0	68 | ||||
| #define S_PSR		64 | ||||
| #define S_PC		60 | ||||
| #define S_LR		56 | ||||
| #define S_SP		52 | ||||
| 
 | ||||
| #define S_IP		48 | ||||
| #define S_FP		44 | ||||
| #define S_R10		40 | ||||
| #define S_R9		36 | ||||
| #define S_R8		32 | ||||
| #define S_R7		28 | ||||
| #define S_R6		24 | ||||
| #define S_R5		20 | ||||
| #define S_R4		16 | ||||
| #define S_R3		12 | ||||
| #define S_R2		8 | ||||
| #define S_R1		4 | ||||
| #define S_R0		0 | ||||
| 
 | ||||
| #define MODE_SVC	0x13 | ||||
| #define I_BIT		0x80 | ||||
| 
 | ||||
| /* | ||||
|  * use bad_save_user_regs for abort/prefetch/undef/swi ... | ||||
|  * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling | ||||
|  */ | ||||
| 
 | ||||
| 	.macro	bad_save_user_regs
 | ||||
| 	sub	sp, sp, #S_FRAME_SIZE | ||||
| 	stmia	sp, {r0 - r12}			@ Calling r0-r12
 | ||||
| 	ldr	r2, IRQ_STACK_START_IN | ||||
| 	ldmia	r2, {r2 - r3}			@ get pc, cpsr
 | ||||
| 	add	r0, sp, #S_FRAME_SIZE		@ restore sp_SVC | ||||
| 
 | ||||
| 	add	r5, sp, #S_SP | ||||
| 	mov	r1, lr | ||||
| 	stmia	r5, {r0 - r3}			@ save sp_SVC, lr_SVC, pc, cpsr
 | ||||
| 	mov	r0, sp | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro	irq_save_user_regs
 | ||||
| 	sub	sp, sp, #S_FRAME_SIZE | ||||
| 	stmia	sp, {r0 - r12}			@ Calling r0-r12
 | ||||
| 	add	r7, sp, #S_PC | ||||
| 	stmdb	r7, {sp, lr}^			@ Calling SP, LR
 | ||||
| 	str	lr, [r7, #0]			@ Save calling PC
 | ||||
| 	mrs	r6, spsr | ||||
| 	str	r6, [r7, #4]			@ Save CPSR
 | ||||
| 	str	r0, [r7, #8]			@ Save OLD_R0
 | ||||
| 	mov	r0, sp | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro	irq_restore_user_regs
 | ||||
| 	ldmia	sp, {r0 - lr}^			@ Calling r0 - lr
 | ||||
| 	mov	r0, r0 | ||||
| 	ldr	lr, [sp, #S_PC]			@ Get PC | ||||
| 	add	sp, sp, #S_FRAME_SIZE | ||||
| 	/* return & move spsr_svc into cpsr */ | ||||
| 	subs	pc, lr, #4 | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro get_bad_stack
 | ||||
| 	ldr	r13, IRQ_STACK_START_IN		@ setup our mode stack
 | ||||
| 
 | ||||
| 	str	lr, [r13]			@ save caller lr / spsr
 | ||||
| 	mrs	lr, spsr | ||||
| 	str	lr, [r13, #4] | ||||
| 
 | ||||
| 	mov	r13, #MODE_SVC			@ prepare SVC-Mode | ||||
| 	@ msr	spsr_c, r13
 | ||||
| 	msr	spsr, r13 | ||||
| 	mov	lr, pc | ||||
| 	movs	pc, lr | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro get_irq_stack			@ setup IRQ stack
 | ||||
| 	ldr	sp, IRQ_STACK_START | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro get_fiq_stack			@ setup FIQ stack
 | ||||
| 	ldr	sp, FIQ_STACK_START | ||||
| 	.endm | ||||
| 
 | ||||
| /* | ||||
|  * exception handlers | ||||
|  */ | ||||
| 	.align  5
 | ||||
| undefined_instruction: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_undefined_instruction | ||||
| 
 | ||||
| 	.align	5
 | ||||
| software_interrupt: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_software_interrupt | ||||
| 
 | ||||
| 	.align	5
 | ||||
| prefetch_abort: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_prefetch_abort | ||||
| 
 | ||||
| 	.align	5
 | ||||
| data_abort: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_data_abort | ||||
| 
 | ||||
| 	.align	5
 | ||||
| not_used: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_not_used | ||||
| 
 | ||||
| #ifdef CONFIG_USE_IRQ | ||||
| 
 | ||||
| 	.align	5
 | ||||
| irq: | ||||
| 	get_irq_stack | ||||
| 	irq_save_user_regs | ||||
| 	bl	do_irq | ||||
| 	irq_restore_user_regs | ||||
| 
 | ||||
| 	.align	5
 | ||||
| fiq: | ||||
| 	get_fiq_stack | ||||
| 	/* someone ought to write a more effiction fiq_save_user_regs */ | ||||
| 	irq_save_user_regs | ||||
| 	bl	do_fiq | ||||
| 	irq_restore_user_regs | ||||
| 
 | ||||
| #else | ||||
| 
 | ||||
| 	.align	5
 | ||||
| irq: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_irq | ||||
| 
 | ||||
| 	.align	5
 | ||||
| fiq: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_fiq | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -24,70 +24,6 @@ | |||
| #include <common.h> | ||||
| #include <version.h> | ||||
| 
 | ||||
| /* | ||||
|  ************************************************************************* | ||||
|  * | ||||
|  * Jump vector table as in table 3.1 in [1] | ||||
|  * | ||||
|  ************************************************************************* | ||||
|  */ | ||||
| 
 | ||||
| 
 | ||||
| .globl _start
 | ||||
| _start: | ||||
| 	b	reset | ||||
| 	b	undefined_instruction | ||||
| 	b	software_interrupt | ||||
| 	b	prefetch_abort | ||||
| 	b	data_abort | ||||
| 	b	not_used | ||||
| 	b	irq | ||||
| 	b	fiq | ||||
| 
 | ||||
| /* | ||||
|  * Vector table, located at address 0x20. | ||||
|  * This table allows the code running AFTER SPL, the U-Boot, to install it's | ||||
|  * interrupt handlers here. The problem is that the U-Boot is loaded into RAM, | ||||
|  * including it's interrupt vectoring table and the table at 0x0 is still the | ||||
|  * SPLs. So if interrupt happens in U-Boot, the SPLs interrupt vectoring table | ||||
|  * is still used. | ||||
|  */ | ||||
| _vt_reset: | ||||
| 	.word	_reset
 | ||||
| _vt_undefined_instruction: | ||||
| 	.word	_hang
 | ||||
| _vt_software_interrupt: | ||||
| 	.word	_hang
 | ||||
| _vt_prefetch_abort: | ||||
| 	.word	_hang
 | ||||
| _vt_data_abort: | ||||
| 	.word	_hang
 | ||||
| _vt_not_used: | ||||
| 	.word	_reset
 | ||||
| _vt_irq: | ||||
| 	.word	_hang
 | ||||
| _vt_fiq: | ||||
| 	.word	_hang
 | ||||
| 
 | ||||
| reset: | ||||
| 	ldr	pc, _vt_reset | ||||
| undefined_instruction: | ||||
| 	ldr	pc, _vt_undefined_instruction | ||||
| software_interrupt: | ||||
| 	ldr	pc, _vt_software_interrupt | ||||
| prefetch_abort: | ||||
| 	ldr	pc, _vt_prefetch_abort | ||||
| data_abort: | ||||
| 	ldr	pc, _vt_data_abort | ||||
| not_used: | ||||
| 	ldr	pc, _vt_not_used | ||||
| irq: | ||||
| 	ldr	pc, _vt_irq | ||||
| fiq: | ||||
| 	ldr	pc, _vt_fiq | ||||
| 
 | ||||
| 	.balignl 16,0xdeadbeef | ||||
| 
 | ||||
| /* | ||||
|  ************************************************************************* | ||||
|  * | ||||
|  | @ -101,28 +37,8 @@ fiq: | |||
|  ************************************************************************* | ||||
|  */ | ||||
| 
 | ||||
| #ifdef CONFIG_USE_IRQ | ||||
| /* IRQ stack memory (calculated at run-time) */ | ||||
| .globl IRQ_STACK_START
 | ||||
| IRQ_STACK_START: | ||||
| 	.word	0x0badc0de
 | ||||
| 
 | ||||
| /* IRQ stack memory (calculated at run-time) */ | ||||
| .globl FIQ_STACK_START
 | ||||
| FIQ_STACK_START: | ||||
| 	.word 0x0badc0de
 | ||||
| #endif | ||||
| 
 | ||||
| /* IRQ stack memory (calculated at run-time) + 8 bytes */ | ||||
| .globl IRQ_STACK_START_IN
 | ||||
| IRQ_STACK_START_IN: | ||||
| 	.word	0x0badc0de
 | ||||
| 
 | ||||
| /* | ||||
|  * the actual reset code | ||||
|  */ | ||||
| 
 | ||||
| _reset: | ||||
| 	.globl	reset
 | ||||
| reset: | ||||
| 	/* | ||||
| 	 * If the CPU is configured in "Wait JTAG connection mode", the stack | ||||
| 	 * pointer is not configured and is zero. This will cause crash when | ||||
|  | @ -179,7 +95,3 @@ _reset: | |||
| 	mov r0, #0 | ||||
| 
 | ||||
| 	bx	lr | ||||
| 
 | ||||
| _hang: | ||||
| 1: | ||||
| 	bl	1b				/* hang and never return */ | ||||
|  |  | |||
|  | @ -17,29 +17,6 @@ | |||
| 
 | ||||
| #include <config.h> | ||||
| 
 | ||||
| .globl _start
 | ||||
| _start: | ||||
| 	b	reset | ||||
| 	ldr	pc, _undefined_instruction | ||||
| 	ldr	pc, _software_interrupt | ||||
| 	ldr	pc, _prefetch_abort | ||||
| 	ldr	pc, _data_abort | ||||
| 	ldr	pc, _not_used | ||||
| 	ldr	pc, _irq | ||||
| 	ldr	pc, _fiq | ||||
| 
 | ||||
| _undefined_instruction: | ||||
| _software_interrupt: | ||||
| _prefetch_abort: | ||||
| _data_abort: | ||||
| _not_used: | ||||
| _irq: | ||||
| _fiq: | ||||
| 	.word infinite_loop
 | ||||
| 
 | ||||
| infinite_loop: | ||||
| 	b	infinite_loop | ||||
| 
 | ||||
| /* | ||||
|  ************************************************************************* | ||||
|  * | ||||
|  | @ -53,9 +30,7 @@ infinite_loop: | |||
|  ************************************************************************* | ||||
|  */ | ||||
| 
 | ||||
| /* | ||||
|  * the actual reset code | ||||
|  */ | ||||
| 	.globl	reset
 | ||||
| 
 | ||||
| reset: | ||||
| /* | ||||
|  |  | |||
|  | @ -21,6 +21,7 @@ SECTIONS | |||
| 	. = ALIGN(4); | ||||
| 	.text	: | ||||
| 	{ | ||||
| 		*(.vectors) | ||||
| 		arch/arm/cpu/arm926ejs/spear/start.o	(.text*) | ||||
| 		*(.text*) | ||||
| 	} | ||||
|  |  | |||
|  | @ -20,75 +20,6 @@ | |||
| #include <common.h> | ||||
| #include <version.h> | ||||
| 
 | ||||
| /* | ||||
|  ************************************************************************* | ||||
|  * | ||||
|  * Jump vector table as in table 3.1 in [1] | ||||
|  * | ||||
|  ************************************************************************* | ||||
|  */ | ||||
| 
 | ||||
| 
 | ||||
| #ifdef CONFIG_SYS_DV_NOR_BOOT_CFG | ||||
| .globl _start
 | ||||
| _start: | ||||
| .globl _NOR_BOOT_CFG
 | ||||
| _NOR_BOOT_CFG: | ||||
| 	.word	CONFIG_SYS_DV_NOR_BOOT_CFG
 | ||||
| 	b	reset | ||||
| #else | ||||
| .globl _start
 | ||||
| _start: | ||||
| 	b	reset | ||||
| #endif | ||||
| #ifdef CONFIG_SPL_BUILD | ||||
| /* No exception handlers in preloader */ | ||||
| 	ldr	pc, _hang | ||||
| 	ldr	pc, _hang | ||||
| 	ldr	pc, _hang | ||||
| 	ldr	pc, _hang | ||||
| 	ldr	pc, _hang | ||||
| 	ldr	pc, _hang | ||||
| 	ldr	pc, _hang | ||||
| 
 | ||||
| _hang: | ||||
| 	.word	do_hang
 | ||||
| /* pad to 64 byte boundary */ | ||||
| 	.word	0x12345678
 | ||||
| 	.word	0x12345678
 | ||||
| 	.word	0x12345678
 | ||||
| 	.word	0x12345678
 | ||||
| 	.word	0x12345678
 | ||||
| 	.word	0x12345678
 | ||||
| 	.word	0x12345678
 | ||||
| #else | ||||
| 	ldr	pc, _undefined_instruction | ||||
| 	ldr	pc, _software_interrupt | ||||
| 	ldr	pc, _prefetch_abort | ||||
| 	ldr	pc, _data_abort | ||||
| 	ldr	pc, _not_used | ||||
| 	ldr	pc, _irq | ||||
| 	ldr	pc, _fiq | ||||
| 
 | ||||
| _undefined_instruction: | ||||
| 	.word undefined_instruction
 | ||||
| _software_interrupt: | ||||
| 	.word software_interrupt
 | ||||
| _prefetch_abort: | ||||
| 	.word prefetch_abort
 | ||||
| _data_abort: | ||||
| 	.word data_abort
 | ||||
| _not_used: | ||||
| 	.word not_used
 | ||||
| _irq: | ||||
| 	.word irq
 | ||||
| _fiq: | ||||
| 	.word fiq
 | ||||
| 
 | ||||
| #endif	/* CONFIG_SPL_BUILD */ | ||||
| 	.balignl 16,0xdeadbeef | ||||
| 
 | ||||
| 
 | ||||
| /* | ||||
|  ************************************************************************* | ||||
|  * | ||||
|  | @ -102,26 +33,7 @@ _fiq: | |||
|  ************************************************************************* | ||||
|  */ | ||||
| 
 | ||||
| #ifdef CONFIG_USE_IRQ | ||||
| /* IRQ stack memory (calculated at run-time) */ | ||||
| .globl IRQ_STACK_START
 | ||||
| IRQ_STACK_START: | ||||
| 	.word	0x0badc0de
 | ||||
| 
 | ||||
| /* IRQ stack memory (calculated at run-time) */ | ||||
| .globl FIQ_STACK_START
 | ||||
| FIQ_STACK_START: | ||||
| 	.word 0x0badc0de
 | ||||
| #endif | ||||
| 
 | ||||
| /* IRQ stack memory (calculated at run-time) + 8 bytes */ | ||||
| .globl IRQ_STACK_START_IN
 | ||||
| IRQ_STACK_START_IN: | ||||
| 	.word	0x0badc0de
 | ||||
| 
 | ||||
| /* | ||||
|  * the actual reset code | ||||
|  */ | ||||
| 	.globl	reset
 | ||||
| 
 | ||||
| reset: | ||||
| 	/* | ||||
|  | @ -198,175 +110,3 @@ flush_dcache: | |||
| 	mov	lr, ip		/* restore link */ | ||||
| 	mov	pc, lr		/* back to my caller */ | ||||
| #endif /* CONFIG_SKIP_LOWLEVEL_INIT */ | ||||
| 
 | ||||
| #ifndef CONFIG_SPL_BUILD | ||||
| /* | ||||
|  ************************************************************************* | ||||
|  * | ||||
|  * Interrupt handling | ||||
|  * | ||||
|  ************************************************************************* | ||||
|  */ | ||||
| 
 | ||||
| @
 | ||||
| @ IRQ stack frame.
 | ||||
| @
 | ||||
| #define S_FRAME_SIZE	72 | ||||
| 
 | ||||
| #define S_OLD_R0	68 | ||||
| #define S_PSR		64 | ||||
| #define S_PC		60 | ||||
| #define S_LR		56 | ||||
| #define S_SP		52 | ||||
| 
 | ||||
| #define S_IP		48 | ||||
| #define S_FP		44 | ||||
| #define S_R10		40 | ||||
| #define S_R9		36 | ||||
| #define S_R8		32 | ||||
| #define S_R7		28 | ||||
| #define S_R6		24 | ||||
| #define S_R5		20 | ||||
| #define S_R4		16 | ||||
| #define S_R3		12 | ||||
| #define S_R2		8 | ||||
| #define S_R1		4 | ||||
| #define S_R0		0 | ||||
| 
 | ||||
| #define MODE_SVC 0x13 | ||||
| #define I_BIT	 0x80 | ||||
| 
 | ||||
| /* | ||||
|  * use bad_save_user_regs for abort/prefetch/undef/swi ... | ||||
|  * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling | ||||
|  */ | ||||
| 
 | ||||
| 	.macro	bad_save_user_regs
 | ||||
| 	@ 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
 | ||||
| 	ldr	r2, IRQ_STACK_START_IN | ||||
| 	@ 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 | ||||
| 	add	r5, sp, #S_SP | ||||
| 	mov	r1, lr | ||||
| 	stmia	r5, {r0 - r3}	@ save sp_SVC, lr_SVC, pc, cpsr
 | ||||
| 	mov	r0, sp		@ save current stack into r0 (param register)
 | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro	irq_save_user_regs
 | ||||
| 	sub	sp, sp, #S_FRAME_SIZE | ||||
| 	stmia	sp, {r0 - r12}			@ Calling r0-r12
 | ||||
| 	@ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good.
 | ||||
| 	add	r8, sp, #S_PC | ||||
| 	stmdb	r8, {sp, lr}^		@ Calling SP, LR
 | ||||
| 	str	lr, [r8, #0]		@ Save calling PC
 | ||||
| 	mrs	r6, spsr | ||||
| 	str	r6, [r8, #4]		@ Save CPSR
 | ||||
| 	str	r0, [r8, #8]		@ Save OLD_R0
 | ||||
| 	mov	r0, sp | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro	irq_restore_user_regs
 | ||||
| 	ldmia	sp, {r0 - lr}^			@ Calling r0 - lr
 | ||||
| 	mov	r0, r0 | ||||
| 	ldr	lr, [sp, #S_PC]			@ Get PC | ||||
| 	add	sp, sp, #S_FRAME_SIZE | ||||
| 	subs	pc, lr, #4		@ return & move spsr_svc into cpsr
 | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro get_bad_stack
 | ||||
| 	ldr	r13, IRQ_STACK_START_IN		@ setup our mode stack
 | ||||
| 
 | ||||
| 	str	lr, [r13]	@ save caller lr in position 0 of saved stack
 | ||||
| 	mrs	lr, spsr	@ get the spsr
 | ||||
| 	str	lr, [r13, #4]	@ save spsr in position 1 of saved stack
 | ||||
| 	mov	r13, #MODE_SVC	@ prepare SVC-Mode | ||||
| 	@ msr	spsr_c, r13
 | ||||
| 	msr	spsr, r13	@ switch modes, make sure moves will execute
 | ||||
| 	mov	lr, pc		@ capture return pc
 | ||||
| 	movs	pc, lr		@ jump to next instruction & switch modes.
 | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro get_irq_stack			@ setup IRQ stack
 | ||||
| 	ldr	sp, IRQ_STACK_START | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro get_fiq_stack			@ setup FIQ stack
 | ||||
| 	ldr	sp, FIQ_STACK_START | ||||
| 	.endm | ||||
| #endif	/* CONFIG_SPL_BUILD */ | ||||
| 
 | ||||
| /* | ||||
|  * exception handlers | ||||
|  */ | ||||
| #ifdef CONFIG_SPL_BUILD | ||||
| 	.align	5
 | ||||
| do_hang: | ||||
| 1: | ||||
| 	bl	1b				/* hang and never return */ | ||||
| #else	/* !CONFIG_SPL_BUILD */ | ||||
| 	.align  5
 | ||||
| undefined_instruction: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_undefined_instruction | ||||
| 
 | ||||
| 	.align	5
 | ||||
| software_interrupt: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_software_interrupt | ||||
| 
 | ||||
| 	.align	5
 | ||||
| prefetch_abort: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_prefetch_abort | ||||
| 
 | ||||
| 	.align	5
 | ||||
| data_abort: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_data_abort | ||||
| 
 | ||||
| 	.align	5
 | ||||
| not_used: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_not_used | ||||
| 
 | ||||
| #ifdef CONFIG_USE_IRQ | ||||
| 
 | ||||
| 	.align	5
 | ||||
| irq: | ||||
| 	get_irq_stack | ||||
| 	irq_save_user_regs | ||||
| 	bl	do_irq | ||||
| 	irq_restore_user_regs | ||||
| 
 | ||||
| 	.align	5
 | ||||
| fiq: | ||||
| 	get_fiq_stack | ||||
| 	/* someone ought to write a more effiction fiq_save_user_regs */ | ||||
| 	irq_save_user_regs | ||||
| 	bl	do_fiq | ||||
| 	irq_restore_user_regs | ||||
| 
 | ||||
| #else | ||||
| 
 | ||||
| 	.align	5
 | ||||
| irq: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_irq | ||||
| 
 | ||||
| 	.align	5
 | ||||
| fiq: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_fiq | ||||
| 
 | ||||
| #endif | ||||
| #endif	/* CONFIG_SPL_BUILD */ | ||||
|  |  | |||
|  | @ -19,43 +19,6 @@ | |||
| #include <config.h> | ||||
| #include <version.h> | ||||
| 
 | ||||
| /* | ||||
|  ************************************************************************* | ||||
|  * | ||||
|  * Jump vector table as in table 3.1 in [1] | ||||
|  * | ||||
|  ************************************************************************* | ||||
|  */ | ||||
| 
 | ||||
| 
 | ||||
| .globl _start
 | ||||
| _start: | ||||
| 	b	reset | ||||
| 	ldr	pc, _undefined_instruction | ||||
| 	ldr	pc, _software_interrupt | ||||
| 	ldr	pc, _prefetch_abort | ||||
| 	ldr	pc, _data_abort | ||||
| 	ldr	pc, _not_used | ||||
| 	ldr	pc, _irq | ||||
| 	ldr	pc, _fiq | ||||
| 
 | ||||
| _undefined_instruction: | ||||
| 	.word undefined_instruction
 | ||||
| _software_interrupt: | ||||
| 	.word software_interrupt
 | ||||
| _prefetch_abort: | ||||
| 	.word prefetch_abort
 | ||||
| _data_abort: | ||||
| 	.word data_abort
 | ||||
| _not_used: | ||||
| 	.word not_used
 | ||||
| _irq: | ||||
| 	.word irq
 | ||||
| _fiq: | ||||
| 	.word fiq
 | ||||
| 
 | ||||
| 	.balignl 16,0xdeadbeef | ||||
| 
 | ||||
| /* | ||||
|  ************************************************************************* | ||||
|  * | ||||
|  | @ -69,26 +32,7 @@ _fiq: | |||
|  ************************************************************************* | ||||
|  */ | ||||
| 
 | ||||
| #ifdef CONFIG_USE_IRQ | ||||
| /* IRQ stack memory (calculated at run-time) */ | ||||
| .globl IRQ_STACK_START
 | ||||
| IRQ_STACK_START: | ||||
| 	.word	0x0badc0de
 | ||||
| 
 | ||||
| /* IRQ stack memory (calculated at run-time) */ | ||||
| .globl FIQ_STACK_START
 | ||||
| FIQ_STACK_START: | ||||
| 	.word 0x0badc0de
 | ||||
| #endif | ||||
| 
 | ||||
| /* IRQ stack memory (calculated at run-time) + 8 bytes */ | ||||
| .globl IRQ_STACK_START_IN
 | ||||
| IRQ_STACK_START_IN: | ||||
| 	.word	0x0badc0de
 | ||||
| 
 | ||||
| /* | ||||
|  * the actual reset code | ||||
|  */ | ||||
| 	.globl	reset
 | ||||
| 
 | ||||
| reset: | ||||
| 	/* | ||||
|  | @ -155,166 +99,3 @@ cpu_init_crit: | |||
| 	mov	lr, ip		/* restore link */ | ||||
| 	mov	pc, lr		/* back to my caller */ | ||||
| #endif | ||||
| /* | ||||
|  ************************************************************************* | ||||
|  * | ||||
|  * Interrupt handling | ||||
|  * | ||||
|  ************************************************************************* | ||||
|  */ | ||||
| 
 | ||||
| @
 | ||||
| @ IRQ stack frame.
 | ||||
| @
 | ||||
| #define S_FRAME_SIZE	72 | ||||
| 
 | ||||
| #define S_OLD_R0	68 | ||||
| #define S_PSR		64 | ||||
| #define S_PC		60 | ||||
| #define S_LR		56 | ||||
| #define S_SP		52 | ||||
| 
 | ||||
| #define S_IP		48 | ||||
| #define S_FP		44 | ||||
| #define S_R10		40 | ||||
| #define S_R9		36 | ||||
| #define S_R8		32 | ||||
| #define S_R7		28 | ||||
| #define S_R6		24 | ||||
| #define S_R5		20 | ||||
| #define S_R4		16 | ||||
| #define S_R3		12 | ||||
| #define S_R2		8 | ||||
| #define S_R1		4 | ||||
| #define S_R0		0 | ||||
| 
 | ||||
| #define MODE_SVC 0x13 | ||||
| #define I_BIT	 0x80 | ||||
| 
 | ||||
| /* | ||||
|  * use bad_save_user_regs for abort/prefetch/undef/swi ... | ||||
|  * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling | ||||
|  */ | ||||
| 
 | ||||
| 	.macro	bad_save_user_regs
 | ||||
| 	@ 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
 | ||||
| 
 | ||||
| 	ldr	r2, IRQ_STACK_START_IN | ||||
| 	@ 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 | ||||
| 	add	r5, sp, #S_SP | ||||
| 	mov	r1, lr | ||||
| 	stmia	r5, {r0 - r3}	@ save sp_SVC, lr_SVC, pc, cpsr
 | ||||
| 	mov	r0, sp		@ save current stack into r0 (param register)
 | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro	irq_save_user_regs
 | ||||
| 	sub	sp, sp, #S_FRAME_SIZE | ||||
| 	stmia	sp, {r0 - r12}			@ Calling r0-r12
 | ||||
| 	@ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good.
 | ||||
| 	add	r8, sp, #S_PC | ||||
| 	stmdb	r8, {sp, lr}^		@ Calling SP, LR
 | ||||
| 	str	lr, [r8, #0]		@ Save calling PC
 | ||||
| 	mrs	r6, spsr | ||||
| 	str	r6, [r8, #4]		@ Save CPSR
 | ||||
| 	str	r0, [r8, #8]		@ Save OLD_R0
 | ||||
| 	mov	r0, sp | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro	irq_restore_user_regs
 | ||||
| 	ldmia	sp, {r0 - lr}^			@ Calling r0 - lr
 | ||||
| 	mov	r0, r0 | ||||
| 	ldr	lr, [sp, #S_PC]			@ Get PC | ||||
| 	add	sp, sp, #S_FRAME_SIZE | ||||
| 	subs	pc, lr, #4		@ return & move spsr_svc into cpsr
 | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro get_bad_stack
 | ||||
| 	ldr	r13, IRQ_STACK_START_IN		@ setup our mode stack
 | ||||
| 
 | ||||
| 	str	lr, [r13]	@ save caller lr in position 0 of saved stack
 | ||||
| 	mrs	lr, spsr	@ get the spsr
 | ||||
| 	str	lr, [r13, #4]	@ save spsr in position 1 of saved stack
 | ||||
| 	mov	r13, #MODE_SVC	@ prepare SVC-Mode | ||||
| 	@ msr	spsr_c, r13
 | ||||
| 	msr	spsr, r13	@ switch modes, make sure moves will execute
 | ||||
| 	mov	lr, pc		@ capture return pc
 | ||||
| 	movs	pc, lr		@ jump to next instruction & switch modes.
 | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro get_irq_stack			@ setup IRQ stack
 | ||||
| 	ldr	sp, IRQ_STACK_START | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro get_fiq_stack			@ setup FIQ stack
 | ||||
| 	ldr	sp, FIQ_STACK_START | ||||
| 	.endm | ||||
| 
 | ||||
| /* | ||||
|  * exception handlers | ||||
|  */ | ||||
| 	.align  5
 | ||||
| undefined_instruction: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_undefined_instruction | ||||
| 
 | ||||
| 	.align	5
 | ||||
| software_interrupt: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_software_interrupt | ||||
| 
 | ||||
| 	.align	5
 | ||||
| prefetch_abort: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_prefetch_abort | ||||
| 
 | ||||
| 	.align	5
 | ||||
| data_abort: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_data_abort | ||||
| 
 | ||||
| 	.align	5
 | ||||
| not_used: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_not_used | ||||
| 
 | ||||
| #ifdef CONFIG_USE_IRQ | ||||
| 
 | ||||
| 	.align	5
 | ||||
| irq: | ||||
| 	get_irq_stack | ||||
| 	irq_save_user_regs | ||||
| 	bl	do_irq | ||||
| 	irq_restore_user_regs | ||||
| 
 | ||||
| 	.align	5
 | ||||
| fiq: | ||||
| 	get_fiq_stack | ||||
| 	/* someone ought to write a more effiction fiq_save_user_regs */ | ||||
| 	irq_save_user_regs | ||||
| 	bl	do_fiq | ||||
| 	irq_restore_user_regs | ||||
| 
 | ||||
| #else | ||||
| 
 | ||||
| 	.align	5
 | ||||
| irq: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_irq | ||||
| 
 | ||||
| 	.align	5
 | ||||
| fiq: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_fiq | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -18,42 +18,6 @@ | |||
| #include <config.h> | ||||
| #include <version.h> | ||||
| 
 | ||||
| /* | ||||
|  ************************************************************************* | ||||
|  * | ||||
|  * Jump vector table | ||||
|  * | ||||
|  ************************************************************************* | ||||
|  */ | ||||
| 
 | ||||
| .globl _start
 | ||||
| _start: | ||||
| 	b	reset | ||||
| 	ldr	pc, _undefined_instruction | ||||
| 	ldr	pc, _software_interrupt | ||||
| 	ldr	pc, _prefetch_abort | ||||
| 	ldr	pc, _data_abort | ||||
| 	ldr	pc, _not_used | ||||
| 	ldr	pc, _irq | ||||
| 	ldr	pc, _fiq | ||||
| 
 | ||||
| _undefined_instruction: | ||||
| 	.word undefined_instruction
 | ||||
| _software_interrupt: | ||||
| 	.word software_interrupt
 | ||||
| _prefetch_abort: | ||||
| 	.word prefetch_abort
 | ||||
| _data_abort: | ||||
| 	.word data_abort
 | ||||
| _not_used: | ||||
| 	.word not_used
 | ||||
| _irq: | ||||
| 	.word irq
 | ||||
| _fiq: | ||||
| 	.word fiq
 | ||||
| 
 | ||||
| 	.balignl 16,0xdeadbeef | ||||
| 
 | ||||
| /* | ||||
|  ************************************************************************* | ||||
|  * | ||||
|  | @ -67,26 +31,7 @@ _fiq: | |||
|  ************************************************************************* | ||||
|  */ | ||||
| 
 | ||||
| #ifdef CONFIG_USE_IRQ | ||||
| /* IRQ stack memory (calculated at run-time) */ | ||||
| .globl IRQ_STACK_START
 | ||||
| IRQ_STACK_START: | ||||
| 	.word	0x0badc0de
 | ||||
| 
 | ||||
| /* IRQ stack memory (calculated at run-time) */ | ||||
| .globl FIQ_STACK_START
 | ||||
| FIQ_STACK_START: | ||||
| 	.word 0x0badc0de
 | ||||
| #endif | ||||
| 
 | ||||
| /* IRQ stack memory (calculated at run-time) + 8 bytes */ | ||||
| .globl IRQ_STACK_START_IN
 | ||||
| IRQ_STACK_START_IN: | ||||
| 	.word	0x0badc0de
 | ||||
| 
 | ||||
| /* | ||||
|  * the actual reset code | ||||
|  */ | ||||
| 	.globl	reset
 | ||||
| 
 | ||||
| reset: | ||||
| 	/* | ||||
|  | @ -132,174 +77,3 @@ cpu_init_crit: | |||
| 	 */ | ||||
| 	mov	pc, lr		/* back to my caller */ | ||||
| #endif | ||||
| /* | ||||
|  ************************************************************************* | ||||
|  * | ||||
|  * Interrupt handling | ||||
|  * | ||||
|  ************************************************************************* | ||||
|  */ | ||||
| 
 | ||||
| @
 | ||||
| @ IRQ stack frame.
 | ||||
| @
 | ||||
| #define S_FRAME_SIZE	72 | ||||
| 
 | ||||
| #define S_OLD_R0	68 | ||||
| #define S_PSR		64 | ||||
| #define S_PC		60 | ||||
| #define S_LR		56 | ||||
| #define S_SP		52 | ||||
| 
 | ||||
| #define S_IP		48 | ||||
| #define S_FP		44 | ||||
| #define S_R10		40 | ||||
| #define S_R9		36 | ||||
| #define S_R8		32 | ||||
| #define S_R7		28 | ||||
| #define S_R6		24 | ||||
| #define S_R5		20 | ||||
| #define S_R4		16 | ||||
| #define S_R3		12 | ||||
| #define S_R2		8 | ||||
| #define S_R1		4 | ||||
| #define S_R0		0 | ||||
| 
 | ||||
| #define MODE_SVC 0x13 | ||||
| #define I_BIT	 0x80 | ||||
| 
 | ||||
| /* | ||||
|  * use bad_save_user_regs for abort/prefetch/undef/swi ... | ||||
|  * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling | ||||
|  */ | ||||
| 
 | ||||
| 	.macro	bad_save_user_regs
 | ||||
| 	@ 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
 | ||||
| 
 | ||||
| 	ldr	r2, IRQ_STACK_START_IN | ||||
| 	@ 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 | ||||
| 	add	r5, sp, #S_SP | ||||
| 	mov	r1, lr | ||||
| 	stmia	r5, {r0 - r3}	@ save sp_SVC, lr_SVC, pc, cpsr
 | ||||
| 	mov	r0, sp		@ save current stack into r0 (param register)
 | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro	irq_save_user_regs
 | ||||
| 	sub	sp, sp, #S_FRAME_SIZE | ||||
| 	stmia	sp, {r0 - r12}			@ Calling r0-r12
 | ||||
| 	@ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good.
 | ||||
| 	add	r8, sp, #S_PC | ||||
| 	stmdb	r8, {sp, lr}^		@ Calling SP, LR
 | ||||
| 	str	lr, [r8, #0]		@ Save calling PC
 | ||||
| 	mrs	r6, spsr | ||||
| 	str	r6, [r8, #4]		@ Save CPSR
 | ||||
| 	str	r0, [r8, #8]		@ Save OLD_R0
 | ||||
| 	mov	r0, sp | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro	irq_restore_user_regs
 | ||||
| 	ldmia	sp, {r0 - lr}^			@ Calling r0 - lr
 | ||||
| 	mov	r0, r0 | ||||
| 	ldr	lr, [sp, #S_PC]			@ Get PC | ||||
| 	add	sp, sp, #S_FRAME_SIZE | ||||
| 	subs	pc, lr, #4		@ return & move spsr_svc into cpsr
 | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro get_bad_stack
 | ||||
| 	ldr	r13, IRQ_STACK_START_IN		@ setup our mode stack
 | ||||
| 
 | ||||
| 	str	lr, [r13]	@ save caller lr in position 0 of saved stack
 | ||||
| 	mrs	lr, spsr	@ get the spsr
 | ||||
| 	str	lr, [r13, #4]	@ save spsr in position 1 of saved stack
 | ||||
| 	mov	r13, #MODE_SVC	@ prepare SVC-Mode | ||||
| 	@ msr	spsr_c, r13
 | ||||
| 	msr	spsr, r13	@ switch modes, make sure moves will execute
 | ||||
| 	mov	lr, pc		@ capture return pc
 | ||||
| 	movs	pc, lr		@ jump to next instruction & switch modes.
 | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro get_irq_stack			@ setup IRQ stack
 | ||||
| 	ldr	sp, IRQ_STACK_START | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro get_fiq_stack			@ setup FIQ stack
 | ||||
| 	ldr	sp, FIQ_STACK_START | ||||
| 	.endm | ||||
| 
 | ||||
| /* | ||||
|  * exception handlers | ||||
|  */ | ||||
| 	.align  5
 | ||||
| .globl undefined_instruction
 | ||||
| undefined_instruction: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_undefined_instruction | ||||
| 
 | ||||
| 	.align	5
 | ||||
| .globl software_interrupt
 | ||||
| software_interrupt: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_software_interrupt | ||||
| 
 | ||||
| 	.align	5
 | ||||
| .globl prefetch_abort
 | ||||
| prefetch_abort: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_prefetch_abort | ||||
| 
 | ||||
| 	.align	5
 | ||||
| .globl data_abort
 | ||||
| data_abort: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_data_abort | ||||
| 
 | ||||
| 	.align	5
 | ||||
| .globl not_used
 | ||||
| not_used: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_not_used | ||||
| 
 | ||||
| #ifdef CONFIG_USE_IRQ | ||||
| 	.align	5
 | ||||
| .globl irq
 | ||||
| irq: | ||||
| 	get_irq_stack | ||||
| 	irq_save_user_regs | ||||
| 	bl	do_irq | ||||
| 	irq_restore_user_regs | ||||
| 
 | ||||
| 	.align	5
 | ||||
| .globl fiq
 | ||||
| fiq: | ||||
| 	get_fiq_stack | ||||
| 	/* someone ought to write a more effiction fiq_save_user_regs */ | ||||
| 	irq_save_user_regs | ||||
| 	bl	do_fiq | ||||
| 	irq_restore_user_regs | ||||
| 
 | ||||
| #else | ||||
| 
 | ||||
| 	.align	5
 | ||||
| .globl irq
 | ||||
| irq: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_irq | ||||
| 
 | ||||
| 	.align	5
 | ||||
| .globl fiq
 | ||||
| fiq: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_fiq | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -10,20 +10,7 @@ | |||
| /* Save the parameter pass in by previous boot loader */ | ||||
| .global save_boot_params
 | ||||
| save_boot_params: | ||||
| 	/* save the parameter here */ | ||||
| 
 | ||||
| 	/* | ||||
| 	 * Setup stack for exception, which is located | ||||
| 	 * at the end of on-chip RAM. We don't expect exception prior to | ||||
| 	 * relocation and if that happens, we won't worry -- it will overide | ||||
| 	 * global data region as the code will goto reset. After relocation, | ||||
| 	 * this region won't be used by other part of program. | ||||
| 	 * Hence it is safe. | ||||
| 	 */ | ||||
| 	ldr	r0, =(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_SIZE) | ||||
| 	ldr	r1, =IRQ_STACK_START_IN | ||||
| 	str	r0, [r1] | ||||
| 
 | ||||
| 	/* no parameter to save */ | ||||
| 	bx	lr | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -19,43 +19,6 @@ | |||
| #include <asm/system.h> | ||||
| #include <linux/linkage.h> | ||||
| 
 | ||||
| .globl _start
 | ||||
| _start: b	reset | ||||
| 	ldr	pc, _undefined_instruction | ||||
| 	ldr	pc, _software_interrupt | ||||
| 	ldr	pc, _prefetch_abort | ||||
| 	ldr	pc, _data_abort | ||||
| 	ldr	pc, _not_used | ||||
| 	ldr	pc, _irq | ||||
| 	ldr	pc, _fiq | ||||
| #ifdef CONFIG_SPL_BUILD | ||||
| _undefined_instruction: .word _undefined_instruction | ||||
| _software_interrupt:	.word _software_interrupt | ||||
| _prefetch_abort:	.word _prefetch_abort | ||||
| _data_abort:		.word _data_abort | ||||
| _not_used:		.word _not_used | ||||
| _irq:			.word _irq | ||||
| _fiq:			.word _fiq | ||||
| _pad:			.word 0x12345678 /* now 16*4=64 */ | ||||
| #else | ||||
| .globl _undefined_instruction
 | ||||
| _undefined_instruction: .word undefined_instruction | ||||
| .globl _software_interrupt
 | ||||
| _software_interrupt:	.word software_interrupt | ||||
| .globl _prefetch_abort
 | ||||
| _prefetch_abort:	.word prefetch_abort | ||||
| .globl _data_abort
 | ||||
| _data_abort:		.word data_abort | ||||
| .globl _not_used
 | ||||
| _not_used:		.word not_used | ||||
| .globl _irq
 | ||||
| _irq:			.word irq | ||||
| .globl _fiq
 | ||||
| _fiq:			.word fiq | ||||
| _pad:			.word 0x12345678 /* now 16*4=64 */ | ||||
| #endif	/* CONFIG_SPL_BUILD */ | ||||
| 
 | ||||
| 	.balignl 16,0xdeadbeef | ||||
| /************************************************************************* | ||||
|  * | ||||
|  * Startup Code (reset vector) | ||||
|  | @ -67,26 +30,7 @@ _pad:			.word 0x12345678 /* now 16*4=64 */ | |||
|  * | ||||
|  *************************************************************************/ | ||||
| 
 | ||||
| #ifdef CONFIG_USE_IRQ | ||||
| /* IRQ stack memory (calculated at run-time) */ | ||||
| .globl IRQ_STACK_START
 | ||||
| IRQ_STACK_START: | ||||
| 	.word	0x0badc0de
 | ||||
| 
 | ||||
| /* IRQ stack memory (calculated at run-time) */ | ||||
| .globl FIQ_STACK_START
 | ||||
| FIQ_STACK_START: | ||||
| 	.word 0x0badc0de
 | ||||
| #endif | ||||
| 
 | ||||
| /* IRQ stack memory (calculated at run-time) + 8 bytes */ | ||||
| .globl IRQ_STACK_START_IN
 | ||||
| IRQ_STACK_START_IN: | ||||
| 	.word	0x0badc0de
 | ||||
| 
 | ||||
| /* | ||||
|  * the actual reset code | ||||
|  */ | ||||
| 	.globl	reset
 | ||||
| 
 | ||||
| reset: | ||||
| 	bl	save_boot_params | ||||
|  | @ -247,195 +191,3 @@ ENTRY(cpu_init_crit) | |||
| 	b	lowlevel_init		@ go setup pll,mux,memory
 | ||||
| ENDPROC(cpu_init_crit) | ||||
| #endif | ||||
| 
 | ||||
| #ifndef CONFIG_SPL_BUILD | ||||
| /* | ||||
|  ************************************************************************* | ||||
|  * | ||||
|  * Interrupt handling | ||||
|  * | ||||
|  ************************************************************************* | ||||
|  */ | ||||
| @
 | ||||
| @ IRQ stack frame.
 | ||||
| @
 | ||||
| #define S_FRAME_SIZE	72 | ||||
| 
 | ||||
| #define S_OLD_R0	68 | ||||
| #define S_PSR		64 | ||||
| #define S_PC		60 | ||||
| #define S_LR		56 | ||||
| #define S_SP		52 | ||||
| 
 | ||||
| #define S_IP		48 | ||||
| #define S_FP		44 | ||||
| #define S_R10		40 | ||||
| #define S_R9		36 | ||||
| #define S_R8		32 | ||||
| #define S_R7		28 | ||||
| #define S_R6		24 | ||||
| #define S_R5		20 | ||||
| #define S_R4		16 | ||||
| #define S_R3		12 | ||||
| #define S_R2		8 | ||||
| #define S_R1		4 | ||||
| #define S_R0		0 | ||||
| 
 | ||||
| #define MODE_SVC 0x13 | ||||
| #define I_BIT	 0x80 | ||||
| 
 | ||||
| /* | ||||
|  * use bad_save_user_regs for abort/prefetch/undef/swi ... | ||||
|  * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling | ||||
|  */ | ||||
| 
 | ||||
| 	.macro	bad_save_user_regs
 | ||||
| 	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
 | ||||
| 	ldr	r2, IRQ_STACK_START_IN		@ set base 2 words into abort
 | ||||
| 						@ stack
 | ||||
| 	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 | ||||
| 
 | ||||
| 	add	r5, sp, #S_SP | ||||
| 	mov	r1, lr | ||||
| 	stmia	r5, {r0 - r3}			@ save sp_SVC, lr_SVC, pc, cpsr
 | ||||
| 	mov	r0, sp				@ save current stack into r0
 | ||||
| 						@ (param register)
 | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro	irq_save_user_regs
 | ||||
| 	sub	sp, sp, #S_FRAME_SIZE | ||||
| 	stmia	sp, {r0 - r12}			@ Calling r0-r12
 | ||||
| 	add	r8, sp, #S_PC			@ !! R8 NEEDS to be saved !! | ||||
| 						@ a reserved stack spot would
 | ||||
| 						@ be good.
 | ||||
| 	stmdb	r8, {sp, lr}^			@ Calling SP, LR
 | ||||
| 	str	lr, [r8, #0]			@ Save calling PC
 | ||||
| 	mrs	r6, spsr | ||||
| 	str	r6, [r8, #4]			@ Save CPSR
 | ||||
| 	str	r0, [r8, #8]			@ Save OLD_R0
 | ||||
| 	mov	r0, sp | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro	irq_restore_user_regs
 | ||||
| 	ldmia	sp, {r0 - lr}^			@ Calling r0 - lr
 | ||||
| 	mov	r0, r0 | ||||
| 	ldr	lr, [sp, #S_PC]			@ Get PC | ||||
| 	add	sp, sp, #S_FRAME_SIZE | ||||
| 	subs	pc, lr, #4			@ return & move spsr_svc into
 | ||||
| 						@ cpsr
 | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro get_bad_stack
 | ||||
| 	ldr	r13, IRQ_STACK_START_IN		@ setup our mode stack (enter
 | ||||
| 						@ in banked mode)
 | ||||
| 
 | ||||
| 	str	lr, [r13]			@ save caller lr in position 0
 | ||||
| 						@ of saved stack
 | ||||
| 	mrs	lr, spsr			@ get the spsr
 | ||||
| 	str	lr, [r13, #4]			@ save spsr in position 1 of
 | ||||
| 						@ saved stack
 | ||||
| 
 | ||||
| 	mov	r13, #MODE_SVC			@ prepare SVC-Mode | ||||
| 	@ msr	spsr_c, r13
 | ||||
| 	msr	spsr, r13			@ switch modes, make sure
 | ||||
| 						@ moves will execute
 | ||||
| 	mov	lr, pc				@ capture return pc
 | ||||
| 	movs	pc, lr				@ jump to next instruction &
 | ||||
| 						@ switch modes.
 | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro get_bad_stack_swi
 | ||||
| 	sub	r13, r13, #4			@ space on current stack for
 | ||||
| 						@ scratch reg.
 | ||||
| 	str	r0, [r13]			@ save R0's value.
 | ||||
| 	ldr	r0, IRQ_STACK_START_IN		@ get data regions start
 | ||||
| 						@ spots for abort stack
 | ||||
| 	str	lr, [r0]			@ save caller lr in position 0
 | ||||
| 						@ of saved stack
 | ||||
| 	mrs	lr, spsr			@ get the spsr
 | ||||
| 	str	lr, [r0, #4]			@ save spsr in position 1 of
 | ||||
| 						@ saved stack
 | ||||
| 	ldr	lr, [r0]			@ restore lr
 | ||||
| 	ldr	r0, [r13]			@ restore r0
 | ||||
| 	add	r13, r13, #4			@ pop stack entry
 | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro get_irq_stack			@ setup IRQ stack
 | ||||
| 	ldr	sp, IRQ_STACK_START | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro get_fiq_stack			@ setup FIQ stack
 | ||||
| 	ldr	sp, FIQ_STACK_START | ||||
| 	.endm | ||||
| 
 | ||||
| /* | ||||
|  * exception handlers | ||||
|  */ | ||||
| 	.align	5
 | ||||
| undefined_instruction: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_undefined_instruction | ||||
| 
 | ||||
| 	.align	5
 | ||||
| software_interrupt: | ||||
| 	get_bad_stack_swi | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_software_interrupt | ||||
| 
 | ||||
| 	.align	5
 | ||||
| prefetch_abort: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_prefetch_abort | ||||
| 
 | ||||
| 	.align	5
 | ||||
| data_abort: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_data_abort | ||||
| 
 | ||||
| 	.align	5
 | ||||
| not_used: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_not_used | ||||
| 
 | ||||
| #ifdef CONFIG_USE_IRQ | ||||
| 
 | ||||
| 	.align	5
 | ||||
| irq: | ||||
| 	get_irq_stack | ||||
| 	irq_save_user_regs | ||||
| 	bl	do_irq | ||||
| 	irq_restore_user_regs | ||||
| 
 | ||||
| 	.align	5
 | ||||
| fiq: | ||||
| 	get_fiq_stack | ||||
| 	/* someone ought to write a more effective fiq_save_user_regs */ | ||||
| 	irq_save_user_regs | ||||
| 	bl	do_fiq | ||||
| 	irq_restore_user_regs | ||||
| 
 | ||||
| #else | ||||
| 
 | ||||
| 	.align	5
 | ||||
| irq: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_irq | ||||
| 
 | ||||
| 	.align	5
 | ||||
| fiq: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_fiq | ||||
| 
 | ||||
| #endif /* CONFIG_USE_IRQ */ | ||||
| #endif /* CONFIG_SPL_BUILD */ | ||||
|  |  | |||
|  | @ -88,7 +88,7 @@ SECTIONS | |||
| 	} | ||||
| 
 | ||||
| 	/* | ||||
| 	 * Zynq needs to discard more sections because the user | ||||
| 	 * Zynq needs to discard these sections because the user | ||||
| 	 * is expected to pass this image on to tools for boot.bin | ||||
| 	 * generation that require them to be dropped. | ||||
| 	 */ | ||||
|  |  | |||
|  | @ -23,46 +23,6 @@ | |||
| #include <config.h> | ||||
| #include <version.h> | ||||
| 
 | ||||
| .globl _start
 | ||||
| _start: b	reset | ||||
| #ifdef CONFIG_SPL_BUILD | ||||
| 	ldr	pc, _hang | ||||
| 	ldr	pc, _hang | ||||
| 	ldr	pc, _hang | ||||
| 	ldr	pc, _hang | ||||
| 	ldr	pc, _hang | ||||
| 	ldr	pc, _hang | ||||
| 	ldr	pc, _hang | ||||
| 
 | ||||
| _hang: | ||||
| 	.word	do_hang
 | ||||
| 	.word	0x12345678
 | ||||
| 	.word	0x12345678
 | ||||
| 	.word	0x12345678
 | ||||
| 	.word	0x12345678
 | ||||
| 	.word	0x12345678
 | ||||
| 	.word	0x12345678
 | ||||
| 	.word	0x12345678	/* now 16*4=64 */ | ||||
| #else | ||||
| 	ldr	pc, _undefined_instruction | ||||
| 	ldr	pc, _software_interrupt | ||||
| 	ldr	pc, _prefetch_abort | ||||
| 	ldr	pc, _data_abort | ||||
| 	ldr	pc, _not_used | ||||
| 	ldr	pc, _irq | ||||
| 	ldr	pc, _fiq | ||||
| 
 | ||||
| _undefined_instruction: .word undefined_instruction | ||||
| _software_interrupt:	.word software_interrupt | ||||
| _prefetch_abort:	.word prefetch_abort | ||||
| _data_abort:		.word data_abort | ||||
| _not_used:		.word not_used | ||||
| _irq:			.word irq | ||||
| _fiq:			.word fiq | ||||
| _pad:			.word 0x12345678 /* now 16*4=64 */ | ||||
| #endif	/* CONFIG_SPL_BUILD */ | ||||
| 
 | ||||
| 	.balignl 16,0xdeadbeef | ||||
| /* | ||||
|  ************************************************************************* | ||||
|  * | ||||
|  | @ -76,26 +36,7 @@ _pad:			.word 0x12345678 /* now 16*4=64 */ | |||
|  ************************************************************************* | ||||
|  */ | ||||
| 
 | ||||
| #ifdef CONFIG_USE_IRQ | ||||
| /* IRQ stack memory (calculated at run-time) */ | ||||
| .globl IRQ_STACK_START
 | ||||
| IRQ_STACK_START: | ||||
| 	.word	0x0badc0de
 | ||||
| 
 | ||||
| /* IRQ stack memory (calculated at run-time) */ | ||||
| .globl FIQ_STACK_START
 | ||||
| FIQ_STACK_START: | ||||
| 	.word 0x0badc0de
 | ||||
| #endif | ||||
| 
 | ||||
| /* IRQ stack memory (calculated at run-time) + 8 bytes */ | ||||
| .globl IRQ_STACK_START_IN
 | ||||
| IRQ_STACK_START_IN: | ||||
| 	.word	0x0badc0de
 | ||||
| 
 | ||||
| /* | ||||
|  * the actual reset code | ||||
|  */ | ||||
| 	.globl	reset
 | ||||
| 
 | ||||
| reset: | ||||
| 	/* | ||||
|  | @ -166,190 +107,6 @@ cpu_init_crit: | |||
| 	mov	pc, lr		/* back to my caller */ | ||||
| #endif /* !CONFIG_SKIP_LOWLEVEL_INIT || CONFIG_CPU_PXA25X */ | ||||
| 
 | ||||
| #ifndef CONFIG_SPL_BUILD | ||||
| /* | ||||
|  ************************************************************************* | ||||
|  * | ||||
|  * Interrupt handling | ||||
|  * | ||||
|  ************************************************************************* | ||||
|  */ | ||||
| @
 | ||||
| @ IRQ stack frame.
 | ||||
| @
 | ||||
| #define S_FRAME_SIZE	72 | ||||
| 
 | ||||
| #define S_OLD_R0	68 | ||||
| #define S_PSR		64 | ||||
| #define S_PC		60 | ||||
| #define S_LR		56 | ||||
| #define S_SP		52 | ||||
| 
 | ||||
| #define S_IP		48 | ||||
| #define S_FP		44 | ||||
| #define S_R10		40 | ||||
| #define S_R9		36 | ||||
| #define S_R8		32 | ||||
| #define S_R7		28 | ||||
| #define S_R6		24 | ||||
| #define S_R5		20 | ||||
| #define S_R4		16 | ||||
| #define S_R3		12 | ||||
| #define S_R2		8 | ||||
| #define S_R1		4 | ||||
| #define S_R0		0 | ||||
| 
 | ||||
| #define MODE_SVC 0x13 | ||||
| #define I_BIT	 0x80 | ||||
| 
 | ||||
| /* | ||||
|  * use bad_save_user_regs for abort/prefetch/undef/swi ... | ||||
|  * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling | ||||
|  */ | ||||
| 
 | ||||
| 	.macro	bad_save_user_regs
 | ||||
| 	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
 | ||||
| 
 | ||||
| 	ldr	r2, IRQ_STACK_START_IN		@ set base 2 words into abort stack
 | ||||
| 	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 | ||||
| 
 | ||||
| 	add	r5, sp, #S_SP | ||||
| 	mov	r1, lr | ||||
| 	stmia	r5, {r0 - r3}			@ save sp_SVC, lr_SVC, pc, cpsr
 | ||||
| 	mov	r0, sp				@ save current stack into r0 (param register)
 | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro	irq_save_user_regs
 | ||||
| 	sub	sp, sp, #S_FRAME_SIZE | ||||
| 	stmia	sp, {r0 - r12}			@ Calling r0-r12
 | ||||
| 	add	r8, sp, #S_PC			@ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good. | ||||
| 	stmdb	r8, {sp, lr}^			@ Calling SP, LR
 | ||||
| 	str	lr, [r8, #0]			@ Save calling PC
 | ||||
| 	mrs	r6, spsr | ||||
| 	str	r6, [r8, #4]			@ Save CPSR
 | ||||
| 	str	r0, [r8, #8]			@ Save OLD_R0
 | ||||
| 	mov	r0, sp | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro	irq_restore_user_regs
 | ||||
| 	ldmia	sp, {r0 - lr}^			@ Calling r0 - lr
 | ||||
| 	mov	r0, r0 | ||||
| 	ldr	lr, [sp, #S_PC]			@ Get PC | ||||
| 	add	sp, sp, #S_FRAME_SIZE | ||||
| 	subs	pc, lr, #4			@ return & move spsr_svc into cpsr
 | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro get_bad_stack
 | ||||
| 	ldr	r13, IRQ_STACK_START_IN		@ setup our mode stack (enter in banked mode)
 | ||||
| 
 | ||||
| 	str	lr, [r13]			@ save caller lr in position 0 of saved stack
 | ||||
| 	mrs	lr, spsr			@ get the spsr
 | ||||
| 	str	lr, [r13, #4]			@ save spsr in position 1 of saved stack
 | ||||
| 
 | ||||
| 	mov	r13, #MODE_SVC			@ prepare SVC-Mode | ||||
| 	@ msr	spsr_c, r13
 | ||||
| 	msr	spsr, r13			@ switch modes, make sure moves will execute
 | ||||
| 	mov	lr, pc				@ capture return pc
 | ||||
| 	movs	pc, lr				@ jump to next instruction & switch modes.
 | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro get_bad_stack_swi
 | ||||
| 	sub	r13, r13, #4			@ space on current stack for scratch reg.
 | ||||
| 	str	r0, [r13]			@ save R0's value.
 | ||||
| 	ldr	r0, IRQ_STACK_START_IN		@ get data regions start
 | ||||
| 	str	lr, [r0]			@ save caller lr in position 0 of saved stack
 | ||||
| 	mrs	lr, spsr			@ get the spsr
 | ||||
| 	str	lr, [r0, #4]			@ save spsr in position 1 of saved stack
 | ||||
| 	ldr	lr, [r0]			@ restore lr
 | ||||
| 	ldr	r0, [r13]			@ restore r0
 | ||||
| 	add	r13, r13, #4			@ pop stack entry
 | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro get_irq_stack			@ setup IRQ stack
 | ||||
| 	ldr	sp, IRQ_STACK_START | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro get_fiq_stack			@ setup FIQ stack
 | ||||
| 	ldr	sp, FIQ_STACK_START | ||||
| 	.endm | ||||
| #endif	/* CONFIG_SPL_BUILD */ | ||||
| 
 | ||||
| /* | ||||
|  * exception handlers | ||||
|  */ | ||||
| #ifdef CONFIG_SPL_BUILD | ||||
| 	.align	5
 | ||||
| do_hang: | ||||
| 	bl	hang				/* hang and never return */ | ||||
| #else	/* !CONFIG_SPL_BUILD */ | ||||
| 	.align	5
 | ||||
| undefined_instruction: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_undefined_instruction | ||||
| 
 | ||||
| 	.align	5
 | ||||
| software_interrupt: | ||||
| 	get_bad_stack_swi | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_software_interrupt | ||||
| 
 | ||||
| 	.align	5
 | ||||
| prefetch_abort: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_prefetch_abort | ||||
| 
 | ||||
| 	.align	5
 | ||||
| data_abort: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_data_abort | ||||
| 
 | ||||
| 	.align	5
 | ||||
| not_used: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_not_used | ||||
| 
 | ||||
| #ifdef CONFIG_USE_IRQ | ||||
| 
 | ||||
| 	.align	5
 | ||||
| irq: | ||||
| 	get_irq_stack | ||||
| 	irq_save_user_regs | ||||
| 	bl	do_irq | ||||
| 	irq_restore_user_regs | ||||
| 
 | ||||
| 	.align	5
 | ||||
| fiq: | ||||
| 	get_fiq_stack | ||||
| 	/* someone ought to write a more effiction fiq_save_user_regs */ | ||||
| 	irq_save_user_regs | ||||
| 	bl	do_fiq | ||||
| 	irq_restore_user_regs | ||||
| 
 | ||||
| #else | ||||
| 
 | ||||
| 	.align	5
 | ||||
| irq: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_irq | ||||
| 
 | ||||
| 	.align	5
 | ||||
| fiq: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_fiq | ||||
| 
 | ||||
| #endif | ||||
| 	.align 5
 | ||||
| #endif	/* CONFIG_SPL_BUILD */ | ||||
| 
 | ||||
| 
 | ||||
| /* | ||||
|  * Enable MMU to use DCache as DRAM. | ||||
|  * | ||||
|  |  | |||
|  | @ -13,36 +13,6 @@ | |||
| #include <config.h> | ||||
| #include <version.h> | ||||
| 
 | ||||
| /* | ||||
|  ************************************************************************* | ||||
|  * | ||||
|  * Jump vector table as in table 3.1 in [1] | ||||
|  * | ||||
|  ************************************************************************* | ||||
|  */ | ||||
| 
 | ||||
| 
 | ||||
| .globl _start
 | ||||
| _start:	b       reset | ||||
| 	ldr	pc, _undefined_instruction | ||||
| 	ldr	pc, _software_interrupt | ||||
| 	ldr	pc, _prefetch_abort | ||||
| 	ldr	pc, _data_abort | ||||
| 	ldr	pc, _not_used | ||||
| 	ldr	pc, _irq | ||||
| 	ldr	pc, _fiq | ||||
| 
 | ||||
| _undefined_instruction:	.word undefined_instruction | ||||
| _software_interrupt:	.word software_interrupt | ||||
| _prefetch_abort:	.word prefetch_abort | ||||
| _data_abort:		.word data_abort | ||||
| _not_used:		.word not_used | ||||
| _irq:			.word irq | ||||
| _fiq:			.word fiq | ||||
| 
 | ||||
| 	.balignl 16,0xdeadbeef | ||||
| 
 | ||||
| 
 | ||||
| /* | ||||
|  ************************************************************************* | ||||
|  * | ||||
|  | @ -56,26 +26,7 @@ _fiq:			.word fiq | |||
|  ************************************************************************* | ||||
|  */ | ||||
| 
 | ||||
| #ifdef CONFIG_USE_IRQ | ||||
| /* IRQ stack memory (calculated at run-time) */ | ||||
| .globl IRQ_STACK_START
 | ||||
| IRQ_STACK_START: | ||||
| 	.word	0x0badc0de
 | ||||
| 
 | ||||
| /* IRQ stack memory (calculated at run-time) */ | ||||
| .globl FIQ_STACK_START
 | ||||
| FIQ_STACK_START: | ||||
| 	.word 0x0badc0de
 | ||||
| #endif | ||||
| 
 | ||||
| /* IRQ stack memory (calculated at run-time) + 8 bytes */ | ||||
| .globl IRQ_STACK_START_IN
 | ||||
| IRQ_STACK_START_IN: | ||||
| 	.word	0x0badc0de
 | ||||
| 
 | ||||
| /* | ||||
|  * the actual reset code | ||||
|  */ | ||||
| 	.globl	reset
 | ||||
| 
 | ||||
| reset: | ||||
| 	/* | ||||
|  | @ -173,167 +124,3 @@ cpu_init_crit: | |||
| 	mcr	p15, 0, r0, c8, c7, 0	/* flush v4 TLB */ | ||||
| 
 | ||||
| 	mov	pc, lr | ||||
| 
 | ||||
| 
 | ||||
| /* | ||||
|  ************************************************************************* | ||||
|  * | ||||
|  * Interrupt handling | ||||
|  * | ||||
|  ************************************************************************* | ||||
|  */ | ||||
| 
 | ||||
| @
 | ||||
| @ IRQ stack frame.
 | ||||
| @
 | ||||
| #define S_FRAME_SIZE	72 | ||||
| 
 | ||||
| #define S_OLD_R0	68 | ||||
| #define S_PSR		64 | ||||
| #define S_PC		60 | ||||
| #define S_LR		56 | ||||
| #define S_SP		52 | ||||
| 
 | ||||
| #define S_IP		48 | ||||
| #define S_FP		44 | ||||
| #define S_R10		40 | ||||
| #define S_R9		36 | ||||
| #define S_R8		32 | ||||
| #define S_R7		28 | ||||
| #define S_R6		24 | ||||
| #define S_R5		20 | ||||
| #define S_R4		16 | ||||
| #define S_R3		12 | ||||
| #define S_R2		8 | ||||
| #define S_R1		4 | ||||
| #define S_R0		0 | ||||
| 
 | ||||
| #define MODE_SVC 0x13 | ||||
| #define I_BIT	 0x80 | ||||
| 
 | ||||
| /* | ||||
|  * use bad_save_user_regs for abort/prefetch/undef/swi ... | ||||
|  * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling | ||||
|  */ | ||||
| 
 | ||||
| 	.macro	bad_save_user_regs
 | ||||
| 	sub	sp, sp, #S_FRAME_SIZE | ||||
| 	stmia	sp, {r0 - r12}			@ Calling r0-r12
 | ||||
| 	add     r8, sp, #S_PC | ||||
| 
 | ||||
| 	ldr	r2, IRQ_STACK_START_IN | ||||
| 	ldmia	r2, {r2 - r4}                   @ get pc, cpsr, old_r0
 | ||||
| 	add	r0, sp, #S_FRAME_SIZE		@ restore sp_SVC | ||||
| 
 | ||||
| 	add	r5, sp, #S_SP | ||||
| 	mov	r1, lr | ||||
| 	stmia	r5, {r0 - r4}                   @ save sp_SVC, lr_SVC, pc, cpsr, old_r
 | ||||
| 	mov	r0, sp | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro	irq_save_user_regs
 | ||||
| 	sub	sp, sp, #S_FRAME_SIZE | ||||
| 	stmia	sp, {r0 - r12}			@ Calling r0-r12
 | ||||
| 	add     r8, sp, #S_PC | ||||
| 	stmdb   r8, {sp, lr}^                   @ Calling SP, LR
 | ||||
| 	str     lr, [r8, #0]                    @ Save calling PC
 | ||||
| 	mrs     r6, spsr | ||||
| 	str     r6, [r8, #4]                    @ Save CPSR
 | ||||
| 	str     r0, [r8, #8]                    @ Save OLD_R0
 | ||||
| 	mov	r0, sp | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro	irq_restore_user_regs
 | ||||
| 	ldmia	sp, {r0 - lr}^			@ Calling r0 - lr
 | ||||
| 	mov	r0, r0 | ||||
| 	ldr	lr, [sp, #S_PC]			@ Get PC | ||||
| 	add	sp, sp, #S_FRAME_SIZE | ||||
| 	subs	pc, lr, #4			@ return & move spsr_svc into cpsr
 | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro get_bad_stack
 | ||||
| 	ldr	r13, IRQ_STACK_START_IN		@ setup our mode stack
 | ||||
| 
 | ||||
| 	str	lr, [r13]			@ save caller lr / spsr
 | ||||
| 	mrs	lr, spsr | ||||
| 	str     lr, [r13, #4] | ||||
| 
 | ||||
| 	mov	r13, #MODE_SVC			@ prepare SVC-Mode | ||||
| 	msr	spsr_c, r13 | ||||
| 	mov	lr, pc | ||||
| 	movs	pc, lr | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro get_irq_stack			@ setup IRQ stack
 | ||||
| 	ldr	sp, IRQ_STACK_START | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro get_fiq_stack			@ setup FIQ stack
 | ||||
| 	ldr	sp, FIQ_STACK_START | ||||
| 	.endm | ||||
| 
 | ||||
| /* | ||||
|  * exception handlers | ||||
|  */ | ||||
| 	.align  5
 | ||||
| undefined_instruction: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_undefined_instruction | ||||
| 
 | ||||
| 	.align	5
 | ||||
| software_interrupt: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_software_interrupt | ||||
| 
 | ||||
| 	.align	5
 | ||||
| prefetch_abort: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_prefetch_abort | ||||
| 
 | ||||
| 	.align	5
 | ||||
| data_abort: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_data_abort | ||||
| 
 | ||||
| 	.align	5
 | ||||
| not_used: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_not_used | ||||
| 
 | ||||
| #ifdef CONFIG_USE_IRQ | ||||
| 
 | ||||
| 	.align	5
 | ||||
| irq: | ||||
| 	get_irq_stack | ||||
| 	irq_save_user_regs | ||||
| 	bl	do_irq | ||||
| 	irq_restore_user_regs | ||||
| 
 | ||||
| 	.align	5
 | ||||
| fiq: | ||||
| 	get_fiq_stack | ||||
| 	/* someone ought to write a more effiction fiq_save_user_regs */ | ||||
| 	irq_save_user_regs | ||||
| 	bl	do_fiq | ||||
| 	irq_restore_user_regs | ||||
| 
 | ||||
| #else | ||||
| 
 | ||||
| 	.align	5
 | ||||
| irq: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_irq | ||||
| 
 | ||||
| 	.align	5
 | ||||
| fiq: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_fiq | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -18,6 +18,7 @@ SECTIONS | |||
| 	.text : | ||||
| 	{ | ||||
| 		__image_copy_start = .; | ||||
| 		*(.vectors) | ||||
| 		CPUDIR/start.o (.text*) | ||||
| 		*(.text*) | ||||
| 	} | ||||
|  |  | |||
|  | @ -18,6 +18,7 @@ SECTIONS | |||
| 	.text : | ||||
| 	{ | ||||
| 		*(.__image_copy_start) | ||||
| 		*(.vectors) | ||||
| 		CPUDIR/start.o (.text*) | ||||
| 		*(.text*) | ||||
| 	} | ||||
|  |  | |||
|  | @ -11,7 +11,7 @@ lib-$(CONFIG_USE_PRIVATE_LIBGCC) += _ashldi3.o _ashrdi3.o _divsi3.o \ | |||
| ifdef CONFIG_ARM64 | ||||
| obj-y	+= crt0_64.o | ||||
| else | ||||
| obj-y	+= crt0.o | ||||
| obj-y	+= vectors.o crt0.o | ||||
| endif | ||||
| 
 | ||||
| ifndef CONFIG_SPL_BUILD | ||||
|  |  | |||
|  | @ -0,0 +1,291 @@ | |||
| /* | ||||
|  *  vectors - Generic ARM exception table code | ||||
|  * | ||||
|  *  Copyright (c) 1998	Dan Malek <dmalek@jlc.net>
 | ||||
|  *  Copyright (c) 1999	Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se> | ||||
|  *  Copyright (c) 2000	Wolfgang Denk <wd@denx.de>
 | ||||
|  *  Copyright (c) 2001	Alex Züpke <azu@sysgo.de>
 | ||||
|  *  Copyright (c) 2001	Marius Gröger <mag@sysgo.de>
 | ||||
|  *  Copyright (c) 2002	Alex Züpke <azu@sysgo.de>
 | ||||
|  *  Copyright (c) 2002	Gary Jennejohn <garyj@denx.de>
 | ||||
|  *  Copyright (c) 2002	Kyle Harris <kharris@nexus-tech.net>
 | ||||
|  * | ||||
|  * SPDX-License-Identifier:	GPL-2.0+ | ||||
|  */ | ||||
| 
 | ||||
| /* | ||||
|  ************************************************************************* | ||||
|  * | ||||
|  * Symbol _start is referenced elsewhere, so make it global | ||||
|  * | ||||
|  ************************************************************************* | ||||
|  */ | ||||
| 
 | ||||
| .globl _start
 | ||||
| 
 | ||||
| /* | ||||
|  ************************************************************************* | ||||
|  * | ||||
|  * Vectors have their own section so linker script can map them easily | ||||
|  * | ||||
|  ************************************************************************* | ||||
|  */ | ||||
| 
 | ||||
| 	.section ".vectors", "x" | ||||
| 
 | ||||
| /* | ||||
|  ************************************************************************* | ||||
|  * | ||||
|  * Exception vectors as described in ARM reference manuals | ||||
|  * | ||||
|  * Uses indirect branch to allow reaching handlers anywhere in memory. | ||||
|  * | ||||
|  ************************************************************************* | ||||
|  */ | ||||
| 
 | ||||
| _start: | ||||
| 
 | ||||
| #ifdef CONFIG_SYS_DV_NOR_BOOT_CFG | ||||
| 	.word	CONFIG_SYS_DV_NOR_BOOT_CFG
 | ||||
| #endif | ||||
| 
 | ||||
| _start: | ||||
| 	ldr	pc, _reset | ||||
| 	ldr	pc, _undefined_instruction | ||||
| 	ldr	pc, _software_interrupt | ||||
| 	ldr	pc, _prefetch_abort | ||||
| 	ldr	pc, _data_abort | ||||
| 	ldr	pc, _not_used | ||||
| 	ldr	pc, _irq | ||||
| 	ldr	pc, _fiq | ||||
| 
 | ||||
| /* | ||||
|  ************************************************************************* | ||||
|  * | ||||
|  * Indirect vectors table | ||||
|  * | ||||
|  * Symbols referenced here must be defined somewhere else | ||||
|  * | ||||
|  ************************************************************************* | ||||
|  */ | ||||
| 
 | ||||
| 	.globl	_undefined_instruction
 | ||||
| 	.globl	_software_interrupt
 | ||||
| 	.globl	_prefetch_abort
 | ||||
| 	.globl	_data_abort
 | ||||
| 	.globl	_not_used
 | ||||
| 	.globl	_irq
 | ||||
| 	.globl	_fiq
 | ||||
| 
 | ||||
| _reset:			.word reset | ||||
| _undefined_instruction:	.word undefined_instruction | ||||
| _software_interrupt:	.word software_interrupt | ||||
| _prefetch_abort:	.word prefetch_abort | ||||
| _data_abort:		.word data_abort | ||||
| _not_used:		.word not_used | ||||
| _irq:			.word irq | ||||
| _fiq:			.word fiq | ||||
| 
 | ||||
| 	.balignl 16,0xdeadbeef | ||||
| 
 | ||||
| /* | ||||
|  ************************************************************************* | ||||
|  * | ||||
|  * Interrupt handling | ||||
|  * | ||||
|  ************************************************************************* | ||||
|  */ | ||||
| 
 | ||||
| /* SPL interrupt handling: just hang */ | ||||
| 
 | ||||
| #ifdef CONFIG_SPL_BUILD | ||||
| 
 | ||||
| 	.align	5
 | ||||
| undefined_instruction: | ||||
| software_interrupt: | ||||
| prefetch_abort: | ||||
| data_abort: | ||||
| not_used: | ||||
| irq: | ||||
| fiq: | ||||
| 
 | ||||
| 1: | ||||
| 	bl	1b			/* hang and never return */ | ||||
| 
 | ||||
| #else	/* !CONFIG_SPL_BUILD */ | ||||
| 
 | ||||
| /* IRQ stack memory (calculated at run-time) + 8 bytes */ | ||||
| .globl IRQ_STACK_START_IN
 | ||||
| IRQ_STACK_START_IN: | ||||
| 	.word	0x0badc0de
 | ||||
| 
 | ||||
| #ifdef CONFIG_USE_IRQ | ||||
| /* IRQ stack memory (calculated at run-time) */ | ||||
| .globl IRQ_STACK_START
 | ||||
| IRQ_STACK_START: | ||||
| 	.word	0x0badc0de
 | ||||
| 
 | ||||
| /* IRQ stack memory (calculated at run-time) */ | ||||
| .globl FIQ_STACK_START
 | ||||
| FIQ_STACK_START: | ||||
| 	.word 0x0badc0de
 | ||||
| 
 | ||||
| #endif /* CONFIG_USE_IRQ */ | ||||
| 
 | ||||
| @
 | ||||
| @ IRQ stack frame.
 | ||||
| @
 | ||||
| #define S_FRAME_SIZE	72 | ||||
| 
 | ||||
| #define S_OLD_R0	68 | ||||
| #define S_PSR		64 | ||||
| #define S_PC		60 | ||||
| #define S_LR		56 | ||||
| #define S_SP		52 | ||||
| 
 | ||||
| #define S_IP		48 | ||||
| #define S_FP		44 | ||||
| #define S_R10		40 | ||||
| #define S_R9		36 | ||||
| #define S_R8		32 | ||||
| #define S_R7		28 | ||||
| #define S_R6		24 | ||||
| #define S_R5		20 | ||||
| #define S_R4		16 | ||||
| #define S_R3		12 | ||||
| #define S_R2		8 | ||||
| #define S_R1		4 | ||||
| #define S_R0		0 | ||||
| 
 | ||||
| #define MODE_SVC 0x13 | ||||
| #define I_BIT	 0x80 | ||||
| 
 | ||||
| /* | ||||
|  * use bad_save_user_regs for abort/prefetch/undef/swi ... | ||||
|  * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling | ||||
|  */ | ||||
| 
 | ||||
| 	.macro	bad_save_user_regs
 | ||||
| 	@ 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
 | ||||
| 	ldr	r2, IRQ_STACK_START_IN | ||||
| 	@ 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 | ||||
| 	add	r5, sp, #S_SP | ||||
| 	mov	r1, lr | ||||
| 	stmia	r5, {r0 - r3}	@ save sp_SVC, lr_SVC, pc, cpsr
 | ||||
| 	mov	r0, sp		@ save current stack into r0 (param register)
 | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro	irq_save_user_regs
 | ||||
| 	sub	sp, sp, #S_FRAME_SIZE | ||||
| 	stmia	sp, {r0 - r12}			@ Calling r0-r12
 | ||||
| 	@ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good.
 | ||||
| 	add	r8, sp, #S_PC | ||||
| 	stmdb	r8, {sp, lr}^		@ Calling SP, LR
 | ||||
| 	str	lr, [r8, #0]		@ Save calling PC
 | ||||
| 	mrs	r6, spsr | ||||
| 	str	r6, [r8, #4]		@ Save CPSR
 | ||||
| 	str	r0, [r8, #8]		@ Save OLD_R0
 | ||||
| 	mov	r0, sp | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro	irq_restore_user_regs
 | ||||
| 	ldmia	sp, {r0 - lr}^			@ Calling r0 - lr
 | ||||
| 	mov	r0, r0 | ||||
| 	ldr	lr, [sp, #S_PC]			@ Get PC | ||||
| 	add	sp, sp, #S_FRAME_SIZE | ||||
| 	subs	pc, lr, #4		@ return & move spsr_svc into cpsr
 | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro get_bad_stack
 | ||||
| 	ldr	r13, IRQ_STACK_START_IN		@ setup our mode stack
 | ||||
| 
 | ||||
| 	str	lr, [r13]	@ save caller lr in position 0 of saved stack
 | ||||
| 	mrs	lr, spsr	@ get the spsr
 | ||||
| 	str	lr, [r13, #4]	@ save spsr in position 1 of saved stack
 | ||||
| 	mov	r13, #MODE_SVC	@ prepare SVC-Mode | ||||
| 	@ msr	spsr_c, r13
 | ||||
| 	msr	spsr, r13	@ switch modes, make sure moves will execute
 | ||||
| 	mov	lr, pc		@ capture return pc
 | ||||
| 	movs	pc, lr		@ jump to next instruction & switch modes.
 | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro get_irq_stack			@ setup IRQ stack
 | ||||
| 	ldr	sp, IRQ_STACK_START | ||||
| 	.endm | ||||
| 
 | ||||
| 	.macro get_fiq_stack			@ setup FIQ stack
 | ||||
| 	ldr	sp, FIQ_STACK_START | ||||
| 	.endm | ||||
| 
 | ||||
| /* | ||||
|  * exception handlers | ||||
|  */ | ||||
| 
 | ||||
| 	.align  5
 | ||||
| undefined_instruction: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_undefined_instruction | ||||
| 
 | ||||
| 	.align	5
 | ||||
| software_interrupt: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_software_interrupt | ||||
| 
 | ||||
| 	.align	5
 | ||||
| prefetch_abort: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_prefetch_abort | ||||
| 
 | ||||
| 	.align	5
 | ||||
| data_abort: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_data_abort | ||||
| 
 | ||||
| 	.align	5
 | ||||
| not_used: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_not_used | ||||
| 
 | ||||
| #ifdef CONFIG_USE_IRQ | ||||
| 
 | ||||
| 	.align	5
 | ||||
| irq: | ||||
| 	get_irq_stack | ||||
| 	irq_save_user_regs | ||||
| 	bl	do_irq | ||||
| 	irq_restore_user_regs | ||||
| 
 | ||||
| 	.align	5
 | ||||
| fiq: | ||||
| 	get_fiq_stack | ||||
| 	/* someone ought to write a more effiction fiq_save_user_regs */ | ||||
| 	irq_save_user_regs | ||||
| 	bl	do_fiq | ||||
| 	irq_restore_user_regs | ||||
| 
 | ||||
| #else | ||||
| 
 | ||||
| 	.align	5
 | ||||
| irq: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_irq | ||||
| 
 | ||||
| 	.align	5
 | ||||
| fiq: | ||||
| 	get_bad_stack | ||||
| 	bad_save_user_regs | ||||
| 	bl	do_fiq | ||||
| 
 | ||||
| #endif /* CONFIG_USE_IRQ */ | ||||
| 
 | ||||
| #endif	/* CONFIG_SPL_BUILD */ | ||||
|  | @ -18,6 +18,7 @@ SECTIONS | |||
| 	.text : | ||||
| 	{ | ||||
| 		*(.__image_copy_start) | ||||
| 		*(.vectors) | ||||
| 		CPUDIR/start.o (.text*) | ||||
| 		board/compulab/cm_t335/built-in.o (.text*) | ||||
| 		*(.text*) | ||||
|  |  | |||
|  | @ -22,6 +22,7 @@ SECTIONS | |||
| 	  /* WARNING - the following is hand-optimized to fit within	*/ | ||||
| 	  /* the sector layout of our flash chips!	XXX FIXME XXX	*/ | ||||
| 
 | ||||
| 	  *					(.vectors) | ||||
| 	  arch/arm/cpu/arm1136/start.o		(.text*) | ||||
| 	  board/freescale/mx31ads/built-in.o	(.text*) | ||||
| 	  arch/arm/lib/built-in.o		(.text*) | ||||
|  |  | |||
|  | @ -34,6 +34,7 @@ SECTIONS | |||
| 	.text : | ||||
| 	{ | ||||
| 		*(.__image_copy_start) | ||||
| 		*(.vectors) | ||||
| 		CPUDIR/start.o (.text*) | ||||
| 		board/ti/am335x/built-in.o (.text*) | ||||
| 		*(.text*) | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue