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