1*e3db7579SRicardo Koller/* SPDX-License-Identifier: GPL-2.0 */
2*e3db7579SRicardo Koller.macro save_registers
3*e3db7579SRicardo Koller	add	sp, sp, #-16 * 17
4*e3db7579SRicardo Koller
5*e3db7579SRicardo Koller	stp	x0, x1, [sp, #16 * 0]
6*e3db7579SRicardo Koller	stp	x2, x3, [sp, #16 * 1]
7*e3db7579SRicardo Koller	stp	x4, x5, [sp, #16 * 2]
8*e3db7579SRicardo Koller	stp	x6, x7, [sp, #16 * 3]
9*e3db7579SRicardo Koller	stp	x8, x9, [sp, #16 * 4]
10*e3db7579SRicardo Koller	stp	x10, x11, [sp, #16 * 5]
11*e3db7579SRicardo Koller	stp	x12, x13, [sp, #16 * 6]
12*e3db7579SRicardo Koller	stp	x14, x15, [sp, #16 * 7]
13*e3db7579SRicardo Koller	stp	x16, x17, [sp, #16 * 8]
14*e3db7579SRicardo Koller	stp	x18, x19, [sp, #16 * 9]
15*e3db7579SRicardo Koller	stp	x20, x21, [sp, #16 * 10]
16*e3db7579SRicardo Koller	stp	x22, x23, [sp, #16 * 11]
17*e3db7579SRicardo Koller	stp	x24, x25, [sp, #16 * 12]
18*e3db7579SRicardo Koller	stp	x26, x27, [sp, #16 * 13]
19*e3db7579SRicardo Koller	stp	x28, x29, [sp, #16 * 14]
20*e3db7579SRicardo Koller
21*e3db7579SRicardo Koller	/*
22*e3db7579SRicardo Koller	 * This stores sp_el1 into ex_regs.sp so exception handlers can "look"
23*e3db7579SRicardo Koller	 * at it. It will _not_ be used to restore the sp on return from the
24*e3db7579SRicardo Koller	 * exception so handlers can not update it.
25*e3db7579SRicardo Koller	 */
26*e3db7579SRicardo Koller	add	x1, sp, #16 * 17
27*e3db7579SRicardo Koller	stp	x30, x1, [sp, #16 * 15] /* x30, SP */
28*e3db7579SRicardo Koller
29*e3db7579SRicardo Koller	mrs	x1, elr_el1
30*e3db7579SRicardo Koller	mrs	x2, spsr_el1
31*e3db7579SRicardo Koller	stp	x1, x2, [sp, #16 * 16] /* PC, PSTATE */
32*e3db7579SRicardo Koller.endm
33*e3db7579SRicardo Koller
34*e3db7579SRicardo Koller.macro restore_registers
35*e3db7579SRicardo Koller	ldp	x1, x2, [sp, #16 * 16] /* PC, PSTATE */
36*e3db7579SRicardo Koller	msr	elr_el1, x1
37*e3db7579SRicardo Koller	msr	spsr_el1, x2
38*e3db7579SRicardo Koller
39*e3db7579SRicardo Koller	/* sp is not restored */
40*e3db7579SRicardo Koller	ldp	x30, xzr, [sp, #16 * 15] /* x30, SP */
41*e3db7579SRicardo Koller
42*e3db7579SRicardo Koller	ldp	x28, x29, [sp, #16 * 14]
43*e3db7579SRicardo Koller	ldp	x26, x27, [sp, #16 * 13]
44*e3db7579SRicardo Koller	ldp	x24, x25, [sp, #16 * 12]
45*e3db7579SRicardo Koller	ldp	x22, x23, [sp, #16 * 11]
46*e3db7579SRicardo Koller	ldp	x20, x21, [sp, #16 * 10]
47*e3db7579SRicardo Koller	ldp	x18, x19, [sp, #16 * 9]
48*e3db7579SRicardo Koller	ldp	x16, x17, [sp, #16 * 8]
49*e3db7579SRicardo Koller	ldp	x14, x15, [sp, #16 * 7]
50*e3db7579SRicardo Koller	ldp	x12, x13, [sp, #16 * 6]
51*e3db7579SRicardo Koller	ldp	x10, x11, [sp, #16 * 5]
52*e3db7579SRicardo Koller	ldp	x8, x9, [sp, #16 * 4]
53*e3db7579SRicardo Koller	ldp	x6, x7, [sp, #16 * 3]
54*e3db7579SRicardo Koller	ldp	x4, x5, [sp, #16 * 2]
55*e3db7579SRicardo Koller	ldp	x2, x3, [sp, #16 * 1]
56*e3db7579SRicardo Koller	ldp	x0, x1, [sp, #16 * 0]
57*e3db7579SRicardo Koller
58*e3db7579SRicardo Koller	add	sp, sp, #16 * 17
59*e3db7579SRicardo Koller
60*e3db7579SRicardo Koller	eret
61*e3db7579SRicardo Koller.endm
62*e3db7579SRicardo Koller
63*e3db7579SRicardo Koller.pushsection ".entry.text", "ax"
64*e3db7579SRicardo Koller.balign 0x800
65*e3db7579SRicardo Koller.global vectors
66*e3db7579SRicardo Kollervectors:
67*e3db7579SRicardo Koller.popsection
68*e3db7579SRicardo Koller
69*e3db7579SRicardo Koller.set	vector, 0
70*e3db7579SRicardo Koller
71*e3db7579SRicardo Koller/*
72*e3db7579SRicardo Koller * Build an exception handler for vector and append a jump to it into
73*e3db7579SRicardo Koller * vectors (while making sure that it's 0x80 aligned).
74*e3db7579SRicardo Koller */
75*e3db7579SRicardo Koller.macro HANDLER, label
76*e3db7579SRicardo Kollerhandler_\label:
77*e3db7579SRicardo Koller	save_registers
78*e3db7579SRicardo Koller	mov	x0, sp
79*e3db7579SRicardo Koller	mov	x1, #vector
80*e3db7579SRicardo Koller	bl	route_exception
81*e3db7579SRicardo Koller	restore_registers
82*e3db7579SRicardo Koller
83*e3db7579SRicardo Koller.pushsection ".entry.text", "ax"
84*e3db7579SRicardo Koller.balign 0x80
85*e3db7579SRicardo Koller	b	handler_\label
86*e3db7579SRicardo Koller.popsection
87*e3db7579SRicardo Koller
88*e3db7579SRicardo Koller.set	vector, vector + 1
89*e3db7579SRicardo Koller.endm
90*e3db7579SRicardo Koller
91*e3db7579SRicardo Koller.macro HANDLER_INVALID
92*e3db7579SRicardo Koller.pushsection ".entry.text", "ax"
93*e3db7579SRicardo Koller.balign 0x80
94*e3db7579SRicardo Koller/* This will abort so no need to save and restore registers. */
95*e3db7579SRicardo Koller	mov	x0, #vector
96*e3db7579SRicardo Koller	mov	x1, #0 /* ec */
97*e3db7579SRicardo Koller	mov	x2, #0 /* valid_ec */
98*e3db7579SRicardo Koller	b	kvm_exit_unexpected_exception
99*e3db7579SRicardo Koller.popsection
100*e3db7579SRicardo Koller
101*e3db7579SRicardo Koller.set	vector, vector + 1
102*e3db7579SRicardo Koller.endm
103*e3db7579SRicardo Koller
104*e3db7579SRicardo Koller/*
105*e3db7579SRicardo Koller * Caution: be sure to not add anything between the declaration of vectors
106*e3db7579SRicardo Koller * above and these macro calls that will build the vectors table below it.
107*e3db7579SRicardo Koller */
108*e3db7579SRicardo Koller	HANDLER_INVALID                         // Synchronous EL1t
109*e3db7579SRicardo Koller	HANDLER_INVALID                         // IRQ EL1t
110*e3db7579SRicardo Koller	HANDLER_INVALID                         // FIQ EL1t
111*e3db7579SRicardo Koller	HANDLER_INVALID                         // Error EL1t
112*e3db7579SRicardo Koller
113*e3db7579SRicardo Koller	HANDLER	el1h_sync                       // Synchronous EL1h
114*e3db7579SRicardo Koller	HANDLER	el1h_irq                        // IRQ EL1h
115*e3db7579SRicardo Koller	HANDLER el1h_fiq                        // FIQ EL1h
116*e3db7579SRicardo Koller	HANDLER	el1h_error                      // Error EL1h
117*e3db7579SRicardo Koller
118*e3db7579SRicardo Koller	HANDLER	el0_sync_64                     // Synchronous 64-bit EL0
119*e3db7579SRicardo Koller	HANDLER	el0_irq_64                      // IRQ 64-bit EL0
120*e3db7579SRicardo Koller	HANDLER	el0_fiq_64                      // FIQ 64-bit EL0
121*e3db7579SRicardo Koller	HANDLER	el0_error_64                    // Error 64-bit EL0
122*e3db7579SRicardo Koller
123*e3db7579SRicardo Koller	HANDLER	el0_sync_32                     // Synchronous 32-bit EL0
124*e3db7579SRicardo Koller	HANDLER	el0_irq_32                      // IRQ 32-bit EL0
125*e3db7579SRicardo Koller	HANDLER	el0_fiq_32                      // FIQ 32-bit EL0
126*e3db7579SRicardo Koller	HANDLER	el0_error_32                    // Error 32-bit EL0
127