xref: /rk3399_rockchip-uboot/arch/arm/lib/vectors.S (revision cdaa633fcf9c2bd54aa3c130ee727708a4e2406a)
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
63*cdaa633fSAndre Przywara#ifdef CONFIG_ENABLE_ARM_SOC_BOOT0_HOOK
64*cdaa633fSAndre Przywara/*
65*cdaa633fSAndre Przywara * Various SoCs need something special and SoC-specific up front in
66*cdaa633fSAndre Przywara * order to boot, allow them to set that in their boot0.h file and then
67*cdaa633fSAndre Przywara * use it here.
68*cdaa633fSAndre Przywara */
69*cdaa633fSAndre Przywara#include <asm/arch/boot0.h>
70*cdaa633fSAndre PrzywaraARM_SOC_BOOT0_HOOK
71*cdaa633fSAndre Przywara#endif
72*cdaa633fSAndre Przywara
7341623c91SAlbert ARIBAUD/*
7441623c91SAlbert ARIBAUD *************************************************************************
7541623c91SAlbert ARIBAUD *
7641623c91SAlbert ARIBAUD * Indirect vectors table
7741623c91SAlbert ARIBAUD *
7841623c91SAlbert ARIBAUD * Symbols referenced here must be defined somewhere else
7941623c91SAlbert ARIBAUD *
8041623c91SAlbert ARIBAUD *************************************************************************
8141623c91SAlbert ARIBAUD */
8241623c91SAlbert ARIBAUD
8341623c91SAlbert ARIBAUD	.globl	_undefined_instruction
8441623c91SAlbert ARIBAUD	.globl	_software_interrupt
8541623c91SAlbert ARIBAUD	.globl	_prefetch_abort
8641623c91SAlbert ARIBAUD	.globl	_data_abort
8741623c91SAlbert ARIBAUD	.globl	_not_used
8841623c91SAlbert ARIBAUD	.globl	_irq
8941623c91SAlbert ARIBAUD	.globl	_fiq
9041623c91SAlbert ARIBAUD
9141623c91SAlbert ARIBAUD_undefined_instruction:	.word undefined_instruction
9241623c91SAlbert ARIBAUD_software_interrupt:	.word software_interrupt
9341623c91SAlbert ARIBAUD_prefetch_abort:	.word prefetch_abort
9441623c91SAlbert ARIBAUD_data_abort:		.word data_abort
9541623c91SAlbert ARIBAUD_not_used:		.word not_used
9641623c91SAlbert ARIBAUD_irq:			.word irq
9741623c91SAlbert ARIBAUD_fiq:			.word fiq
9841623c91SAlbert ARIBAUD
9941623c91SAlbert ARIBAUD	.balignl 16,0xdeadbeef
10041623c91SAlbert ARIBAUD
10141623c91SAlbert ARIBAUD/*
10241623c91SAlbert ARIBAUD *************************************************************************
10341623c91SAlbert ARIBAUD *
10441623c91SAlbert ARIBAUD * Interrupt handling
10541623c91SAlbert ARIBAUD *
10641623c91SAlbert ARIBAUD *************************************************************************
10741623c91SAlbert ARIBAUD */
10841623c91SAlbert ARIBAUD
10941623c91SAlbert ARIBAUD/* SPL interrupt handling: just hang */
11041623c91SAlbert ARIBAUD
11141623c91SAlbert ARIBAUD#ifdef CONFIG_SPL_BUILD
11241623c91SAlbert ARIBAUD
11341623c91SAlbert ARIBAUD	.align	5
11441623c91SAlbert ARIBAUDundefined_instruction:
11541623c91SAlbert ARIBAUDsoftware_interrupt:
11641623c91SAlbert ARIBAUDprefetch_abort:
11741623c91SAlbert ARIBAUDdata_abort:
11841623c91SAlbert ARIBAUDnot_used:
11941623c91SAlbert ARIBAUDirq:
12041623c91SAlbert ARIBAUDfiq:
12141623c91SAlbert ARIBAUD
12241623c91SAlbert ARIBAUD1:
12341623c91SAlbert ARIBAUD	bl	1b			/* hang and never return */
12441623c91SAlbert ARIBAUD
12541623c91SAlbert ARIBAUD#else	/* !CONFIG_SPL_BUILD */
12641623c91SAlbert ARIBAUD
12741623c91SAlbert ARIBAUD/* IRQ stack memory (calculated at run-time) + 8 bytes */
12841623c91SAlbert ARIBAUD.globl IRQ_STACK_START_IN
12941623c91SAlbert ARIBAUDIRQ_STACK_START_IN:
13041623c91SAlbert ARIBAUD	.word	0x0badc0de
13141623c91SAlbert ARIBAUD
13241623c91SAlbert ARIBAUD#ifdef CONFIG_USE_IRQ
13341623c91SAlbert ARIBAUD/* IRQ stack memory (calculated at run-time) */
13441623c91SAlbert ARIBAUD.globl IRQ_STACK_START
13541623c91SAlbert ARIBAUDIRQ_STACK_START:
13641623c91SAlbert ARIBAUD	.word	0x0badc0de
13741623c91SAlbert ARIBAUD
13841623c91SAlbert ARIBAUD/* IRQ stack memory (calculated at run-time) */
13941623c91SAlbert ARIBAUD.globl FIQ_STACK_START
14041623c91SAlbert ARIBAUDFIQ_STACK_START:
14141623c91SAlbert ARIBAUD	.word 0x0badc0de
14241623c91SAlbert ARIBAUD
14341623c91SAlbert ARIBAUD#endif /* CONFIG_USE_IRQ */
14441623c91SAlbert ARIBAUD
14541623c91SAlbert ARIBAUD@
14641623c91SAlbert ARIBAUD@ IRQ stack frame.
14741623c91SAlbert ARIBAUD@
14841623c91SAlbert ARIBAUD#define S_FRAME_SIZE	72
14941623c91SAlbert ARIBAUD
15041623c91SAlbert ARIBAUD#define S_OLD_R0	68
15141623c91SAlbert ARIBAUD#define S_PSR		64
15241623c91SAlbert ARIBAUD#define S_PC		60
15341623c91SAlbert ARIBAUD#define S_LR		56
15441623c91SAlbert ARIBAUD#define S_SP		52
15541623c91SAlbert ARIBAUD
15641623c91SAlbert ARIBAUD#define S_IP		48
15741623c91SAlbert ARIBAUD#define S_FP		44
15841623c91SAlbert ARIBAUD#define S_R10		40
15941623c91SAlbert ARIBAUD#define S_R9		36
16041623c91SAlbert ARIBAUD#define S_R8		32
16141623c91SAlbert ARIBAUD#define S_R7		28
16241623c91SAlbert ARIBAUD#define S_R6		24
16341623c91SAlbert ARIBAUD#define S_R5		20
16441623c91SAlbert ARIBAUD#define S_R4		16
16541623c91SAlbert ARIBAUD#define S_R3		12
16641623c91SAlbert ARIBAUD#define S_R2		8
16741623c91SAlbert ARIBAUD#define S_R1		4
16841623c91SAlbert ARIBAUD#define S_R0		0
16941623c91SAlbert ARIBAUD
17041623c91SAlbert ARIBAUD#define MODE_SVC 0x13
17141623c91SAlbert ARIBAUD#define I_BIT	 0x80
17241623c91SAlbert ARIBAUD
17341623c91SAlbert ARIBAUD/*
17441623c91SAlbert ARIBAUD * use bad_save_user_regs for abort/prefetch/undef/swi ...
17541623c91SAlbert ARIBAUD * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
17641623c91SAlbert ARIBAUD */
17741623c91SAlbert ARIBAUD
17841623c91SAlbert ARIBAUD	.macro	bad_save_user_regs
17941623c91SAlbert ARIBAUD	@ carve out a frame on current user stack
18041623c91SAlbert ARIBAUD	sub	sp, sp, #S_FRAME_SIZE
18141623c91SAlbert ARIBAUD	stmia	sp, {r0 - r12}	@ Save user registers (now in svc mode) r0-r12
18241623c91SAlbert ARIBAUD	ldr	r2, IRQ_STACK_START_IN
18341623c91SAlbert ARIBAUD	@ get values for "aborted" pc and cpsr (into parm regs)
18441623c91SAlbert ARIBAUD	ldmia	r2, {r2 - r3}
18541623c91SAlbert ARIBAUD	add	r0, sp, #S_FRAME_SIZE		@ grab pointer to old stack
18641623c91SAlbert ARIBAUD	add	r5, sp, #S_SP
18741623c91SAlbert ARIBAUD	mov	r1, lr
18841623c91SAlbert ARIBAUD	stmia	r5, {r0 - r3}	@ save sp_SVC, lr_SVC, pc, cpsr
18941623c91SAlbert ARIBAUD	mov	r0, sp		@ save current stack into r0 (param register)
19041623c91SAlbert ARIBAUD	.endm
19141623c91SAlbert ARIBAUD
19241623c91SAlbert ARIBAUD	.macro	irq_save_user_regs
19341623c91SAlbert ARIBAUD	sub	sp, sp, #S_FRAME_SIZE
19441623c91SAlbert ARIBAUD	stmia	sp, {r0 - r12}			@ Calling r0-r12
19541623c91SAlbert ARIBAUD	@ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good.
19641623c91SAlbert ARIBAUD	add	r8, sp, #S_PC
19741623c91SAlbert ARIBAUD	stmdb	r8, {sp, lr}^		@ Calling SP, LR
19841623c91SAlbert ARIBAUD	str	lr, [r8, #0]		@ Save calling PC
19941623c91SAlbert ARIBAUD	mrs	r6, spsr
20041623c91SAlbert ARIBAUD	str	r6, [r8, #4]		@ Save CPSR
20141623c91SAlbert ARIBAUD	str	r0, [r8, #8]		@ Save OLD_R0
20241623c91SAlbert ARIBAUD	mov	r0, sp
20341623c91SAlbert ARIBAUD	.endm
20441623c91SAlbert ARIBAUD
20541623c91SAlbert ARIBAUD	.macro	irq_restore_user_regs
20641623c91SAlbert ARIBAUD	ldmia	sp, {r0 - lr}^			@ Calling r0 - lr
20741623c91SAlbert ARIBAUD	mov	r0, r0
20841623c91SAlbert ARIBAUD	ldr	lr, [sp, #S_PC]			@ Get PC
20941623c91SAlbert ARIBAUD	add	sp, sp, #S_FRAME_SIZE
21041623c91SAlbert ARIBAUD	subs	pc, lr, #4		@ return & move spsr_svc into cpsr
21141623c91SAlbert ARIBAUD	.endm
21241623c91SAlbert ARIBAUD
21341623c91SAlbert ARIBAUD	.macro get_bad_stack
21441623c91SAlbert ARIBAUD	ldr	r13, IRQ_STACK_START_IN		@ setup our mode stack
21541623c91SAlbert ARIBAUD
21641623c91SAlbert ARIBAUD	str	lr, [r13]	@ save caller lr in position 0 of saved stack
21741623c91SAlbert ARIBAUD	mrs	lr, spsr	@ get the spsr
21841623c91SAlbert ARIBAUD	str	lr, [r13, #4]	@ save spsr in position 1 of saved stack
21941623c91SAlbert ARIBAUD	mov	r13, #MODE_SVC	@ prepare SVC-Mode
22041623c91SAlbert ARIBAUD	@ msr	spsr_c, r13
22141623c91SAlbert ARIBAUD	msr	spsr, r13	@ switch modes, make sure moves will execute
22241623c91SAlbert ARIBAUD	mov	lr, pc		@ capture return pc
22341623c91SAlbert ARIBAUD	movs	pc, lr		@ jump to next instruction & switch modes.
22441623c91SAlbert ARIBAUD	.endm
22541623c91SAlbert ARIBAUD
22641623c91SAlbert ARIBAUD	.macro get_irq_stack			@ setup IRQ stack
22741623c91SAlbert ARIBAUD	ldr	sp, IRQ_STACK_START
22841623c91SAlbert ARIBAUD	.endm
22941623c91SAlbert ARIBAUD
23041623c91SAlbert ARIBAUD	.macro get_fiq_stack			@ setup FIQ stack
23141623c91SAlbert ARIBAUD	ldr	sp, FIQ_STACK_START
23241623c91SAlbert ARIBAUD	.endm
23341623c91SAlbert ARIBAUD
23441623c91SAlbert ARIBAUD/*
23541623c91SAlbert ARIBAUD * exception handlers
23641623c91SAlbert ARIBAUD */
23741623c91SAlbert ARIBAUD
23841623c91SAlbert ARIBAUD	.align  5
23941623c91SAlbert ARIBAUDundefined_instruction:
24041623c91SAlbert ARIBAUD	get_bad_stack
24141623c91SAlbert ARIBAUD	bad_save_user_regs
24241623c91SAlbert ARIBAUD	bl	do_undefined_instruction
24341623c91SAlbert ARIBAUD
24441623c91SAlbert ARIBAUD	.align	5
24541623c91SAlbert ARIBAUDsoftware_interrupt:
24641623c91SAlbert ARIBAUD	get_bad_stack
24741623c91SAlbert ARIBAUD	bad_save_user_regs
24841623c91SAlbert ARIBAUD	bl	do_software_interrupt
24941623c91SAlbert ARIBAUD
25041623c91SAlbert ARIBAUD	.align	5
25141623c91SAlbert ARIBAUDprefetch_abort:
25241623c91SAlbert ARIBAUD	get_bad_stack
25341623c91SAlbert ARIBAUD	bad_save_user_regs
25441623c91SAlbert ARIBAUD	bl	do_prefetch_abort
25541623c91SAlbert ARIBAUD
25641623c91SAlbert ARIBAUD	.align	5
25741623c91SAlbert ARIBAUDdata_abort:
25841623c91SAlbert ARIBAUD	get_bad_stack
25941623c91SAlbert ARIBAUD	bad_save_user_regs
26041623c91SAlbert ARIBAUD	bl	do_data_abort
26141623c91SAlbert ARIBAUD
26241623c91SAlbert ARIBAUD	.align	5
26341623c91SAlbert ARIBAUDnot_used:
26441623c91SAlbert ARIBAUD	get_bad_stack
26541623c91SAlbert ARIBAUD	bad_save_user_regs
26641623c91SAlbert ARIBAUD	bl	do_not_used
26741623c91SAlbert ARIBAUD
26841623c91SAlbert ARIBAUD#ifdef CONFIG_USE_IRQ
26941623c91SAlbert ARIBAUD
27041623c91SAlbert ARIBAUD	.align	5
27141623c91SAlbert ARIBAUDirq:
27241623c91SAlbert ARIBAUD	get_irq_stack
27341623c91SAlbert ARIBAUD	irq_save_user_regs
27441623c91SAlbert ARIBAUD	bl	do_irq
27541623c91SAlbert ARIBAUD	irq_restore_user_regs
27641623c91SAlbert ARIBAUD
27741623c91SAlbert ARIBAUD	.align	5
27841623c91SAlbert ARIBAUDfiq:
27941623c91SAlbert ARIBAUD	get_fiq_stack
28041623c91SAlbert ARIBAUD	/* someone ought to write a more effiction fiq_save_user_regs */
28141623c91SAlbert ARIBAUD	irq_save_user_regs
28241623c91SAlbert ARIBAUD	bl	do_fiq
28341623c91SAlbert ARIBAUD	irq_restore_user_regs
28441623c91SAlbert ARIBAUD
28541623c91SAlbert ARIBAUD#else
28641623c91SAlbert ARIBAUD
28741623c91SAlbert ARIBAUD	.align	5
28841623c91SAlbert ARIBAUDirq:
28941623c91SAlbert ARIBAUD	get_bad_stack
29041623c91SAlbert ARIBAUD	bad_save_user_regs
29141623c91SAlbert ARIBAUD	bl	do_irq
29241623c91SAlbert ARIBAUD
29341623c91SAlbert ARIBAUD	.align	5
29441623c91SAlbert ARIBAUDfiq:
29541623c91SAlbert ARIBAUD	get_bad_stack
29641623c91SAlbert ARIBAUD	bad_save_user_regs
29741623c91SAlbert ARIBAUD	bl	do_fiq
29841623c91SAlbert ARIBAUD
29941623c91SAlbert ARIBAUD#endif /* CONFIG_USE_IRQ */
30041623c91SAlbert ARIBAUD
30141623c91SAlbert ARIBAUD#endif	/* CONFIG_SPL_BUILD */
302