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 <asm-offsets.h> | ||||||
| #include <config.h> | #include <config.h> | ||||||
| #include <version.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 | 	.globl	reset
 | ||||||
| /* 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: | reset: | ||||||
| 	/* | 	/* | ||||||
|  | @ -150,185 +92,3 @@ cpu_init_crit: | ||||||
| 	mov	lr, ip		/* restore link */ | 	mov	lr, ip		/* restore link */ | ||||||
| 	mov	pc, lr		/* back to my caller */ | 	mov	pc, lr		/* back to my caller */ | ||||||
| #endif /* CONFIG_SKIP_LOWLEVEL_INIT */ | #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 | #define CONFIG_SYS_PHY_UBOOT_BASE	CONFIG_SYS_UBOOT_BASE | ||||||
| #endif | #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 reset
 | ||||||
| .globl IRQ_STACK_START_IN
 |  | ||||||
| IRQ_STACK_START_IN: |  | ||||||
| 	.word	0x0badc0de
 |  | ||||||
| 
 |  | ||||||
| /* |  | ||||||
|  * the actual reset code |  | ||||||
|  */ |  | ||||||
| 
 | 
 | ||||||
| reset: | reset: | ||||||
| 	/* | 	/* | ||||||
|  | @ -180,150 +133,3 @@ skip_tcmdisable: | ||||||
| c_runtime_cpu_setup: | c_runtime_cpu_setup: | ||||||
| 
 | 
 | ||||||
| 	mov	pc, lr | 	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 <version.h> | ||||||
| #include <asm/hardware.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 | 	.globl	reset
 | ||||||
| /* 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: | reset: | ||||||
| 	/* | 	/* | ||||||
|  | @ -139,169 +78,3 @@ cpu_init_crit: | ||||||
| 
 | 
 | ||||||
| 	mov	pc, lr | 	mov	pc, lr | ||||||
| #endif /* CONFIG_SKIP_LOWLEVEL_INIT */ | #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,6 +16,7 @@ SECTIONS | ||||||
| 	.text      : | 	.text      : | ||||||
| 	{ | 	{ | ||||||
| 		*(.__image_copy_start) | 		*(.__image_copy_start) | ||||||
|  | 		*(.vectors) | ||||||
| 		arch/arm/cpu/arm920t/start.o	(.text*) | 		arch/arm/cpu/arm920t/start.o	(.text*) | ||||||
| 		/* the EP93xx expects to find the pattern 'CRUS' at 0x1000 */ | 		/* the EP93xx expects to find the pattern 'CRUS' at 0x1000 */ | ||||||
| 	  . = 0x1000; | 	  . = 0x1000; | ||||||
|  |  | ||||||
|  | @ -12,36 +12,6 @@ | ||||||
| #include <common.h> | #include <common.h> | ||||||
| #include <config.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 | 	.globl	reset
 | ||||||
| /* IRQ stack memory (calculated at run-time) */ |  | ||||||
| .globl IRQ_STACK_START
 |  | ||||||
| IRQ_STACK_START: |  | ||||||
| 	.word	0x0badc0de
 |  | ||||||
| 
 | 
 | ||||||
| /* IRQ stack memory (calculated at run-time) */ | reset: | ||||||
| .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: |  | ||||||
| 	/* | 	/* | ||||||
| 	 * set the cpu to SVC32 mode | 	 * set the cpu to SVC32 mode | ||||||
| 	 */ | 	 */ | ||||||
|  | @ -196,166 +147,3 @@ cpu_init_crit: | ||||||
| 	mov	lr, ip | 	mov	lr, ip | ||||||
| 	mov	pc, lr | 	mov	pc, lr | ||||||
| #endif /* CONFIG_SKIP_LOWLEVEL_INIT */ | #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 <common.h> | ||||||
| #include <version.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 | 	.globl	reset
 | ||||||
| /* IRQ stack memory (calculated at run-time) */ | reset: | ||||||
| .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: |  | ||||||
| 	/* | 	/* | ||||||
| 	 * If the CPU is configured in "Wait JTAG connection mode", the stack | 	 * If the CPU is configured in "Wait JTAG connection mode", the stack | ||||||
| 	 * pointer is not configured and is zero. This will cause crash when | 	 * pointer is not configured and is zero. This will cause crash when | ||||||
|  | @ -179,7 +95,3 @@ _reset: | ||||||
| 	mov r0, #0 | 	mov r0, #0 | ||||||
| 
 | 
 | ||||||
| 	bx	lr | 	bx	lr | ||||||
| 
 |  | ||||||
| _hang: |  | ||||||
| 1: |  | ||||||
| 	bl	1b				/* hang and never return */ |  | ||||||
|  |  | ||||||
|  | @ -17,29 +17,6 @@ | ||||||
| 
 | 
 | ||||||
| #include <config.h> | #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: | ||||||
|  ************************************************************************* |  ************************************************************************* | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| /* | 	.globl	reset
 | ||||||
|  * the actual reset code |  | ||||||
|  */ |  | ||||||
| 
 | 
 | ||||||
| reset: | reset: | ||||||
| /* | /* | ||||||
|  |  | ||||||
|  | @ -21,6 +21,7 @@ SECTIONS | ||||||
| 	. = ALIGN(4); | 	. = ALIGN(4); | ||||||
| 	.text	: | 	.text	: | ||||||
| 	{ | 	{ | ||||||
|  | 		*(.vectors) | ||||||
| 		arch/arm/cpu/arm926ejs/spear/start.o	(.text*) | 		arch/arm/cpu/arm926ejs/spear/start.o	(.text*) | ||||||
| 		*(.text*) | 		*(.text*) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -20,75 +20,6 @@ | ||||||
| #include <common.h> | #include <common.h> | ||||||
| #include <version.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 | 	.globl	reset
 | ||||||
| /* 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: | reset: | ||||||
| 	/* | 	/* | ||||||
|  | @ -198,175 +110,3 @@ flush_dcache: | ||||||
| 	mov	lr, ip		/* restore link */ | 	mov	lr, ip		/* restore link */ | ||||||
| 	mov	pc, lr		/* back to my caller */ | 	mov	pc, lr		/* back to my caller */ | ||||||
| #endif /* CONFIG_SKIP_LOWLEVEL_INIT */ | #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 <config.h> | ||||||
| #include <version.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 | 	.globl	reset
 | ||||||
| /* 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: | reset: | ||||||
| 	/* | 	/* | ||||||
|  | @ -155,166 +99,3 @@ cpu_init_crit: | ||||||
| 	mov	lr, ip		/* restore link */ | 	mov	lr, ip		/* restore link */ | ||||||
| 	mov	pc, lr		/* back to my caller */ | 	mov	pc, lr		/* back to my caller */ | ||||||
| #endif | #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 <config.h> | ||||||
| #include <version.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 | 	.globl	reset
 | ||||||
| /* 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: | reset: | ||||||
| 	/* | 	/* | ||||||
|  | @ -132,174 +77,3 @@ cpu_init_crit: | ||||||
| 	 */ | 	 */ | ||||||
| 	mov	pc, lr		/* back to my caller */ | 	mov	pc, lr		/* back to my caller */ | ||||||
| #endif | #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 */ | /* Save the parameter pass in by previous boot loader */ | ||||||
| .global save_boot_params
 | .global save_boot_params
 | ||||||
| save_boot_params: | save_boot_params: | ||||||
| 	/* save the parameter here */ | 	/* no parameter to save */ | ||||||
| 
 |  | ||||||
| 	/* |  | ||||||
| 	 * 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] |  | ||||||
| 
 |  | ||||||
| 	bx	lr | 	bx	lr | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -19,43 +19,6 @@ | ||||||
| #include <asm/system.h> | #include <asm/system.h> | ||||||
| #include <linux/linkage.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) |  * Startup Code (reset vector) | ||||||
|  | @ -67,26 +30,7 @@ _pad:			.word 0x12345678 /* now 16*4=64 */ | ||||||
|  * |  * | ||||||
|  *************************************************************************/ |  *************************************************************************/ | ||||||
| 
 | 
 | ||||||
| #ifdef CONFIG_USE_IRQ | 	.globl	reset
 | ||||||
| /* 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: | reset: | ||||||
| 	bl	save_boot_params | 	bl	save_boot_params | ||||||
|  | @ -247,195 +191,3 @@ ENTRY(cpu_init_crit) | ||||||
| 	b	lowlevel_init		@ go setup pll,mux,memory
 | 	b	lowlevel_init		@ go setup pll,mux,memory
 | ||||||
| ENDPROC(cpu_init_crit) | ENDPROC(cpu_init_crit) | ||||||
| #endif | #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 | 	 * is expected to pass this image on to tools for boot.bin | ||||||
| 	 * generation that require them to be dropped. | 	 * generation that require them to be dropped. | ||||||
| 	 */ | 	 */ | ||||||
|  |  | ||||||
|  | @ -23,46 +23,6 @@ | ||||||
| #include <config.h> | #include <config.h> | ||||||
| #include <version.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 | 	.globl	reset
 | ||||||
| /* 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: | reset: | ||||||
| 	/* | 	/* | ||||||
|  | @ -166,190 +107,6 @@ cpu_init_crit: | ||||||
| 	mov	pc, lr		/* back to my caller */ | 	mov	pc, lr		/* back to my caller */ | ||||||
| #endif /* !CONFIG_SKIP_LOWLEVEL_INIT || CONFIG_CPU_PXA25X */ | #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. |  * Enable MMU to use DCache as DRAM. | ||||||
|  * |  * | ||||||
|  |  | ||||||
|  | @ -13,36 +13,6 @@ | ||||||
| #include <config.h> | #include <config.h> | ||||||
| #include <version.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 | 	.globl	reset
 | ||||||
| /* 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: | reset: | ||||||
| 	/* | 	/* | ||||||
|  | @ -173,167 +124,3 @@ cpu_init_crit: | ||||||
| 	mcr	p15, 0, r0, c8, c7, 0	/* flush v4 TLB */ | 	mcr	p15, 0, r0, c8, c7, 0	/* flush v4 TLB */ | ||||||
| 
 | 
 | ||||||
| 	mov	pc, lr | 	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 : | 	.text : | ||||||
| 	{ | 	{ | ||||||
| 		__image_copy_start = .; | 		__image_copy_start = .; | ||||||
|  | 		*(.vectors) | ||||||
| 		CPUDIR/start.o (.text*) | 		CPUDIR/start.o (.text*) | ||||||
| 		*(.text*) | 		*(.text*) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -18,6 +18,7 @@ SECTIONS | ||||||
| 	.text : | 	.text : | ||||||
| 	{ | 	{ | ||||||
| 		*(.__image_copy_start) | 		*(.__image_copy_start) | ||||||
|  | 		*(.vectors) | ||||||
| 		CPUDIR/start.o (.text*) | 		CPUDIR/start.o (.text*) | ||||||
| 		*(.text*) | 		*(.text*) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -11,7 +11,7 @@ lib-$(CONFIG_USE_PRIVATE_LIBGCC) += _ashldi3.o _ashrdi3.o _divsi3.o \ | ||||||
| ifdef CONFIG_ARM64 | ifdef CONFIG_ARM64 | ||||||
| obj-y	+= crt0_64.o | obj-y	+= crt0_64.o | ||||||
| else | else | ||||||
| obj-y	+= crt0.o | obj-y	+= vectors.o crt0.o | ||||||
| endif | endif | ||||||
| 
 | 
 | ||||||
| ifndef CONFIG_SPL_BUILD | 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 : | 	.text : | ||||||
| 	{ | 	{ | ||||||
| 		*(.__image_copy_start) | 		*(.__image_copy_start) | ||||||
|  | 		*(.vectors) | ||||||
| 		CPUDIR/start.o (.text*) | 		CPUDIR/start.o (.text*) | ||||||
| 		board/compulab/cm_t335/built-in.o (.text*) | 		board/compulab/cm_t335/built-in.o (.text*) | ||||||
| 		*(.text*) | 		*(.text*) | ||||||
|  |  | ||||||
|  | @ -22,6 +22,7 @@ SECTIONS | ||||||
| 	  /* WARNING - the following is hand-optimized to fit within	*/ | 	  /* WARNING - the following is hand-optimized to fit within	*/ | ||||||
| 	  /* the sector layout of our flash chips!	XXX FIXME XXX	*/ | 	  /* the sector layout of our flash chips!	XXX FIXME XXX	*/ | ||||||
| 
 | 
 | ||||||
|  | 	  *					(.vectors) | ||||||
| 	  arch/arm/cpu/arm1136/start.o		(.text*) | 	  arch/arm/cpu/arm1136/start.o		(.text*) | ||||||
| 	  board/freescale/mx31ads/built-in.o	(.text*) | 	  board/freescale/mx31ads/built-in.o	(.text*) | ||||||
| 	  arch/arm/lib/built-in.o		(.text*) | 	  arch/arm/lib/built-in.o		(.text*) | ||||||
|  |  | ||||||
|  | @ -34,6 +34,7 @@ SECTIONS | ||||||
| 	.text : | 	.text : | ||||||
| 	{ | 	{ | ||||||
| 		*(.__image_copy_start) | 		*(.__image_copy_start) | ||||||
|  | 		*(.vectors) | ||||||
| 		CPUDIR/start.o (.text*) | 		CPUDIR/start.o (.text*) | ||||||
| 		board/ti/am335x/built-in.o (.text*) | 		board/ti/am335x/built-in.o (.text*) | ||||||
| 		*(.text*) | 		*(.text*) | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue