xref: /rk3399_rockchip-uboot/arch/arm/lib/vectors.S (revision fa40f8a0c4e1a304a22cb297b4faf59a4627a774)
141623c91SAlbert ARIBAUD/*
241623c91SAlbert ARIBAUD *  vectors - Generic ARM exception table code
341623c91SAlbert ARIBAUD *
441623c91SAlbert ARIBAUD *  Copyright (c) 1998	Dan Malek <dmalek@jlc.net>
541623c91SAlbert ARIBAUD *  Copyright (c) 1999	Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se>
641623c91SAlbert ARIBAUD *  Copyright (c) 2000	Wolfgang Denk <wd@denx.de>
741623c91SAlbert ARIBAUD *  Copyright (c) 2001	Alex Züpke <azu@sysgo.de>
841623c91SAlbert ARIBAUD *  Copyright (c) 2001	Marius Gröger <mag@sysgo.de>
941623c91SAlbert ARIBAUD *  Copyright (c) 2002	Alex Züpke <azu@sysgo.de>
1041623c91SAlbert ARIBAUD *  Copyright (c) 2002	Gary Jennejohn <garyj@denx.de>
1141623c91SAlbert ARIBAUD *  Copyright (c) 2002	Kyle Harris <kharris@nexus-tech.net>
1241623c91SAlbert ARIBAUD *
1341623c91SAlbert ARIBAUD * SPDX-License-Identifier:	GPL-2.0+
1441623c91SAlbert ARIBAUD */
1541623c91SAlbert ARIBAUD
16db993fc8SChristian Riesch#include <config.h>
17db993fc8SChristian Riesch
1841623c91SAlbert ARIBAUD/*
1941623c91SAlbert ARIBAUD *************************************************************************
2041623c91SAlbert ARIBAUD *
2141623c91SAlbert ARIBAUD * Symbol _start is referenced elsewhere, so make it global
2241623c91SAlbert ARIBAUD *
2341623c91SAlbert ARIBAUD *************************************************************************
2441623c91SAlbert ARIBAUD */
2541623c91SAlbert ARIBAUD
2641623c91SAlbert ARIBAUD.globl _start
2741623c91SAlbert ARIBAUD
2841623c91SAlbert ARIBAUD/*
2941623c91SAlbert ARIBAUD *************************************************************************
3041623c91SAlbert ARIBAUD *
3141623c91SAlbert ARIBAUD * Vectors have their own section so linker script can map them easily
3241623c91SAlbert ARIBAUD *
3341623c91SAlbert ARIBAUD *************************************************************************
3441623c91SAlbert ARIBAUD */
3541623c91SAlbert ARIBAUD
36c57a6423SGeorges Savoundararadj	.section ".vectors", "ax"
3741623c91SAlbert ARIBAUD
3841623c91SAlbert ARIBAUD/*
3941623c91SAlbert ARIBAUD *************************************************************************
4041623c91SAlbert ARIBAUD *
4141623c91SAlbert ARIBAUD * Exception vectors as described in ARM reference manuals
4241623c91SAlbert ARIBAUD *
4341623c91SAlbert ARIBAUD * Uses indirect branch to allow reaching handlers anywhere in memory.
4441623c91SAlbert ARIBAUD *
4541623c91SAlbert ARIBAUD *************************************************************************
4641623c91SAlbert ARIBAUD */
4741623c91SAlbert ARIBAUD
48a7f99bf1SBenoît Thébaudeau_start:
49a7f99bf1SBenoît Thébaudeau
5041623c91SAlbert ARIBAUD#ifdef CONFIG_SYS_DV_NOR_BOOT_CFG
5141623c91SAlbert ARIBAUD	.word	CONFIG_SYS_DV_NOR_BOOT_CFG
5241623c91SAlbert ARIBAUD#endif
5341623c91SAlbert ARIBAUD
5458f9e1aeSBenoît Thébaudeau	b	reset
5541623c91SAlbert ARIBAUD	ldr	pc, _undefined_instruction
5641623c91SAlbert ARIBAUD	ldr	pc, _software_interrupt
5741623c91SAlbert ARIBAUD	ldr	pc, _prefetch_abort
5841623c91SAlbert ARIBAUD	ldr	pc, _data_abort
5941623c91SAlbert ARIBAUD	ldr	pc, _not_used
6041623c91SAlbert ARIBAUD	ldr	pc, _irq
6141623c91SAlbert ARIBAUD	ldr	pc, _fiq
6241623c91SAlbert ARIBAUD
63cdaa633fSAndre Przywara#ifdef CONFIG_ENABLE_ARM_SOC_BOOT0_HOOK
64cdaa633fSAndre Przywara/*
65cdaa633fSAndre Przywara * Various SoCs need something special and SoC-specific up front in
66cdaa633fSAndre Przywara * order to boot, allow them to set that in their boot0.h file and then
67cdaa633fSAndre Przywara * use it here.
68cdaa633fSAndre Przywara */
69cdaa633fSAndre Przywara#include <asm/arch/boot0.h>
70cdaa633fSAndre Przywara#endif
71cdaa633fSAndre Przywara
7241623c91SAlbert ARIBAUD/*
7341623c91SAlbert ARIBAUD *************************************************************************
7441623c91SAlbert ARIBAUD *
7541623c91SAlbert ARIBAUD * Indirect vectors table
7641623c91SAlbert ARIBAUD *
7741623c91SAlbert ARIBAUD * Symbols referenced here must be defined somewhere else
7841623c91SAlbert ARIBAUD *
7941623c91SAlbert ARIBAUD *************************************************************************
8041623c91SAlbert ARIBAUD */
8141623c91SAlbert ARIBAUD
8241623c91SAlbert ARIBAUD	.globl	_undefined_instruction
8341623c91SAlbert ARIBAUD	.globl	_software_interrupt
8441623c91SAlbert ARIBAUD	.globl	_prefetch_abort
8541623c91SAlbert ARIBAUD	.globl	_data_abort
8641623c91SAlbert ARIBAUD	.globl	_not_used
8741623c91SAlbert ARIBAUD	.globl	_irq
8841623c91SAlbert ARIBAUD	.globl	_fiq
8941623c91SAlbert ARIBAUD
9041623c91SAlbert ARIBAUD_undefined_instruction:	.word undefined_instruction
9141623c91SAlbert ARIBAUD_software_interrupt:	.word software_interrupt
9241623c91SAlbert ARIBAUD_prefetch_abort:	.word prefetch_abort
9341623c91SAlbert ARIBAUD_data_abort:		.word data_abort
9441623c91SAlbert ARIBAUD_not_used:		.word not_used
9541623c91SAlbert ARIBAUD_irq:			.word irq
9641623c91SAlbert ARIBAUD_fiq:			.word fiq
9741623c91SAlbert ARIBAUD
9841623c91SAlbert ARIBAUD	.balignl 16,0xdeadbeef
9941623c91SAlbert ARIBAUD
10041623c91SAlbert ARIBAUD/*
10141623c91SAlbert ARIBAUD *************************************************************************
10241623c91SAlbert ARIBAUD *
10341623c91SAlbert ARIBAUD * Interrupt handling
10441623c91SAlbert ARIBAUD *
10541623c91SAlbert ARIBAUD *************************************************************************
10641623c91SAlbert ARIBAUD */
10741623c91SAlbert ARIBAUD
10841623c91SAlbert ARIBAUD/* SPL interrupt handling: just hang */
10941623c91SAlbert ARIBAUD
11041623c91SAlbert ARIBAUD#ifdef CONFIG_SPL_BUILD
11141623c91SAlbert ARIBAUD
11241623c91SAlbert ARIBAUD	.align	5
11341623c91SAlbert ARIBAUDundefined_instruction:
11441623c91SAlbert ARIBAUDsoftware_interrupt:
11541623c91SAlbert ARIBAUDprefetch_abort:
11641623c91SAlbert ARIBAUDdata_abort:
11741623c91SAlbert ARIBAUDnot_used:
11841623c91SAlbert ARIBAUDirq:
11941623c91SAlbert ARIBAUDfiq:
12041623c91SAlbert ARIBAUD1:
12141623c91SAlbert ARIBAUD	bl	1b			/* hang and never return */
12241623c91SAlbert ARIBAUD
12341623c91SAlbert ARIBAUD#else	/* !CONFIG_SPL_BUILD */
12441623c91SAlbert ARIBAUD
12541623c91SAlbert ARIBAUD/* IRQ stack memory (calculated at run-time) + 8 bytes */
12641623c91SAlbert ARIBAUD.globl IRQ_STACK_START_IN
12741623c91SAlbert ARIBAUDIRQ_STACK_START_IN:
12869c5d76fSLothar Waßmann#ifdef IRAM_BASE_ADDR
12969c5d76fSLothar Waßmann	.word   IRAM_BASE_ADDR + 0x20
13069c5d76fSLothar Waßmann#else
13141623c91SAlbert ARIBAUD	.word	0x0badc0de
13269c5d76fSLothar Waßmann#endif
13341623c91SAlbert ARIBAUD
134*fa40f8a0SJoseph Chen#ifdef CONFIG_IRQ
135*fa40f8a0SJoseph Chen/* IRQ stack memory (calculated at run-time) */
136*fa40f8a0SJoseph Chen.globl IRQ_STACK_START
137*fa40f8a0SJoseph ChenIRQ_STACK_START:
138*fa40f8a0SJoseph Chen	.word	0x0badc0de
139*fa40f8a0SJoseph Chen#endif
140*fa40f8a0SJoseph Chen
14141623c91SAlbert ARIBAUD@
14241623c91SAlbert ARIBAUD@ IRQ stack frame.
14341623c91SAlbert ARIBAUD@
14441623c91SAlbert ARIBAUD#define S_FRAME_SIZE	72
14541623c91SAlbert ARIBAUD
14641623c91SAlbert ARIBAUD#define S_OLD_R0	68
14741623c91SAlbert ARIBAUD#define S_PSR		64
14841623c91SAlbert ARIBAUD#define S_PC		60
14941623c91SAlbert ARIBAUD#define S_LR		56
15041623c91SAlbert ARIBAUD#define S_SP		52
15141623c91SAlbert ARIBAUD
15241623c91SAlbert ARIBAUD#define S_IP		48
15341623c91SAlbert ARIBAUD#define S_FP		44
15441623c91SAlbert ARIBAUD#define S_R10		40
15541623c91SAlbert ARIBAUD#define S_R9		36
15641623c91SAlbert ARIBAUD#define S_R8		32
15741623c91SAlbert ARIBAUD#define S_R7		28
15841623c91SAlbert ARIBAUD#define S_R6		24
15941623c91SAlbert ARIBAUD#define S_R5		20
16041623c91SAlbert ARIBAUD#define S_R4		16
16141623c91SAlbert ARIBAUD#define S_R3		12
16241623c91SAlbert ARIBAUD#define S_R2		8
16341623c91SAlbert ARIBAUD#define S_R1		4
16441623c91SAlbert ARIBAUD#define S_R0		0
16541623c91SAlbert ARIBAUD
16641623c91SAlbert ARIBAUD#define MODE_SVC 0x13
16741623c91SAlbert ARIBAUD#define I_BIT	 0x80
16841623c91SAlbert ARIBAUD
16941623c91SAlbert ARIBAUD/*
17041623c91SAlbert ARIBAUD * use bad_save_user_regs for abort/prefetch/undef/swi ...
17141623c91SAlbert ARIBAUD * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
17241623c91SAlbert ARIBAUD */
17341623c91SAlbert ARIBAUD
17441623c91SAlbert ARIBAUD	.macro	bad_save_user_regs
17541623c91SAlbert ARIBAUD	@ carve out a frame on current user stack
17641623c91SAlbert ARIBAUD	sub	sp, sp, #S_FRAME_SIZE
17741623c91SAlbert ARIBAUD	stmia	sp, {r0 - r12}	@ Save user registers (now in svc mode) r0-r12
17841623c91SAlbert ARIBAUD	ldr	r2, IRQ_STACK_START_IN
17941623c91SAlbert ARIBAUD	@ get values for "aborted" pc and cpsr (into parm regs)
18041623c91SAlbert ARIBAUD	ldmia	r2, {r2 - r3}
18141623c91SAlbert ARIBAUD	add	r0, sp, #S_FRAME_SIZE		@ grab pointer to old stack
18241623c91SAlbert ARIBAUD	add	r5, sp, #S_SP
18341623c91SAlbert ARIBAUD	mov	r1, lr
18441623c91SAlbert ARIBAUD	stmia	r5, {r0 - r3}	@ save sp_SVC, lr_SVC, pc, cpsr
18541623c91SAlbert ARIBAUD	mov	r0, sp		@ save current stack into r0 (param register)
18641623c91SAlbert ARIBAUD	.endm
18741623c91SAlbert ARIBAUD
18841623c91SAlbert ARIBAUD	.macro	irq_save_user_regs
18941623c91SAlbert ARIBAUD	sub	sp, sp, #S_FRAME_SIZE
19041623c91SAlbert ARIBAUD	stmia	sp, {r0 - r12}			@ Calling r0-r12
19141623c91SAlbert ARIBAUD	@ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good.
19241623c91SAlbert ARIBAUD	add	r8, sp, #S_PC
19341623c91SAlbert ARIBAUD	stmdb	r8, {sp, lr}^		@ Calling SP, LR
19441623c91SAlbert ARIBAUD	str	lr, [r8, #0]		@ Save calling PC
19541623c91SAlbert ARIBAUD	mrs	r6, spsr
19641623c91SAlbert ARIBAUD	str	r6, [r8, #4]		@ Save CPSR
19741623c91SAlbert ARIBAUD	str	r0, [r8, #8]		@ Save OLD_R0
19841623c91SAlbert ARIBAUD	mov	r0, sp
19941623c91SAlbert ARIBAUD	.endm
20041623c91SAlbert ARIBAUD
20141623c91SAlbert ARIBAUD	.macro	irq_restore_user_regs
20241623c91SAlbert ARIBAUD	ldmia	sp, {r0 - lr}^			@ Calling r0 - lr
20341623c91SAlbert ARIBAUD	mov	r0, r0
20441623c91SAlbert ARIBAUD	ldr	lr, [sp, #S_PC]			@ Get PC
20541623c91SAlbert ARIBAUD	add	sp, sp, #S_FRAME_SIZE
20641623c91SAlbert ARIBAUD	subs	pc, lr, #4		@ return & move spsr_svc into cpsr
20741623c91SAlbert ARIBAUD	.endm
20841623c91SAlbert ARIBAUD
20941623c91SAlbert ARIBAUD	.macro get_bad_stack
21041623c91SAlbert ARIBAUD	ldr	r13, IRQ_STACK_START_IN		@ setup our mode stack
21141623c91SAlbert ARIBAUD
21241623c91SAlbert ARIBAUD	str	lr, [r13]	@ save caller lr in position 0 of saved stack
21341623c91SAlbert ARIBAUD	mrs	lr, spsr	@ get the spsr
21441623c91SAlbert ARIBAUD	str	lr, [r13, #4]	@ save spsr in position 1 of saved stack
21541623c91SAlbert ARIBAUD	mov	r13, #MODE_SVC	@ prepare SVC-Mode
21641623c91SAlbert ARIBAUD	@ msr	spsr_c, r13
21741623c91SAlbert ARIBAUD	msr	spsr, r13	@ switch modes, make sure moves will execute
21841623c91SAlbert ARIBAUD	mov	lr, pc		@ capture return pc
21941623c91SAlbert ARIBAUD	movs	pc, lr		@ jump to next instruction & switch modes.
22041623c91SAlbert ARIBAUD	.endm
22141623c91SAlbert ARIBAUD
22241623c91SAlbert ARIBAUD	.macro get_irq_stack			@ setup IRQ stack
22341623c91SAlbert ARIBAUD	ldr	sp, IRQ_STACK_START
22441623c91SAlbert ARIBAUD	.endm
22541623c91SAlbert ARIBAUD
22641623c91SAlbert ARIBAUD	.macro get_fiq_stack			@ setup FIQ stack
22741623c91SAlbert ARIBAUD	ldr	sp, FIQ_STACK_START
22841623c91SAlbert ARIBAUD	.endm
22941623c91SAlbert ARIBAUD
23041623c91SAlbert ARIBAUD/*
23141623c91SAlbert ARIBAUD * exception handlers
23241623c91SAlbert ARIBAUD */
23341623c91SAlbert ARIBAUD
23441623c91SAlbert ARIBAUD	.align  5
23541623c91SAlbert ARIBAUDundefined_instruction:
23641623c91SAlbert ARIBAUD	get_bad_stack
23741623c91SAlbert ARIBAUD	bad_save_user_regs
23841623c91SAlbert ARIBAUD	bl	do_undefined_instruction
23941623c91SAlbert ARIBAUD
24041623c91SAlbert ARIBAUD	.align	5
24141623c91SAlbert ARIBAUDsoftware_interrupt:
24241623c91SAlbert ARIBAUD	get_bad_stack
24341623c91SAlbert ARIBAUD	bad_save_user_regs
24441623c91SAlbert ARIBAUD	bl	do_software_interrupt
24541623c91SAlbert ARIBAUD
24641623c91SAlbert ARIBAUD	.align	5
24741623c91SAlbert ARIBAUDprefetch_abort:
24841623c91SAlbert ARIBAUD	get_bad_stack
24941623c91SAlbert ARIBAUD	bad_save_user_regs
25041623c91SAlbert ARIBAUD	bl	do_prefetch_abort
25141623c91SAlbert ARIBAUD
25241623c91SAlbert ARIBAUD	.align	5
25341623c91SAlbert ARIBAUDdata_abort:
25441623c91SAlbert ARIBAUD	get_bad_stack
25541623c91SAlbert ARIBAUD	bad_save_user_regs
25641623c91SAlbert ARIBAUD	bl	do_data_abort
25741623c91SAlbert ARIBAUD
25841623c91SAlbert ARIBAUD	.align	5
25941623c91SAlbert ARIBAUDnot_used:
26041623c91SAlbert ARIBAUD	get_bad_stack
26141623c91SAlbert ARIBAUD	bad_save_user_regs
26241623c91SAlbert ARIBAUD	bl	do_not_used
26341623c91SAlbert ARIBAUD
26441623c91SAlbert ARIBAUD
26541623c91SAlbert ARIBAUD	.align	5
26641623c91SAlbert ARIBAUDirq:
267*fa40f8a0SJoseph Chen#ifdef CONFIG_IRQ
268*fa40f8a0SJoseph Chen	get_irq_stack
269*fa40f8a0SJoseph Chen	irq_save_user_regs
270*fa40f8a0SJoseph Chen	bl	do_irq
271*fa40f8a0SJoseph Chen	irq_restore_user_regs
272*fa40f8a0SJoseph Chen#else
27341623c91SAlbert ARIBAUD	get_bad_stack
27441623c91SAlbert ARIBAUD	bad_save_user_regs
27541623c91SAlbert ARIBAUD	bl	do_irq
276*fa40f8a0SJoseph Chen#endif
27741623c91SAlbert ARIBAUD
27841623c91SAlbert ARIBAUD	.align	5
27941623c91SAlbert ARIBAUDfiq:
28041623c91SAlbert ARIBAUD	get_bad_stack
28141623c91SAlbert ARIBAUD	bad_save_user_regs
28241623c91SAlbert ARIBAUD	bl	do_fiq
28341623c91SAlbert ARIBAUD
28441623c91SAlbert ARIBAUD#endif	/* CONFIG_SPL_BUILD */
285