1/*
2 * Copyright (c) 2014 Travis Geiselbrecht
3 *
4 * Use of this source code is governed by a MIT-style
5 * license that can be found in the LICENSE file or at
6 * https://opensource.org/licenses/MIT
7 */
8#include <lk/asm.h>
9#include <arch/asm_macros.h>
10
11.section .text.boot.vectab
12.p2align 11
13
14#define lr x30
15#define regsave_long_offset 0xf0
16#define regsave_short_offset 0x90
17
18.macro regsave_long
19sub  sp, sp, #32
20push x28, x29
21push x26, x27
22push x24, x25
23push x22, x23
24push x20, x21
25push x18, x19
26push x16, x17
27push x14, x15
28push x12, x13
29push x10, x11
30push x8, x9
31push x6, x7
32push x4, x5
33push x2, x3
34push x0, x1
35mrs  x0, sp_el0
36mrs  x1, elr_el1
37mrs  x2, spsr_el1
38stp  lr, x0, [sp, #regsave_long_offset]
39stp  x1, x2, [sp, #regsave_long_offset + 16]
40.endm
41
42.macro regsave_short
43sub  sp, sp, #32
44push x16, x17
45push x14, x15
46push x12, x13
47push x10, x11
48push x8, x9
49push x6, x7
50push x4, x5
51push x2, x3
52push x0, x1
53mrs  x0, sp_el0
54mrs  x1, elr_el1
55mrs  x2, spsr_el1
56stp  lr, x0, [sp, #regsave_short_offset]
57stp  x1, x2, [sp, #regsave_short_offset + 16]
58.endm
59
60.macro regrestore_long
61ldp  lr, x0, [sp, #regsave_long_offset]
62ldp  x1, x2, [sp, #regsave_long_offset + 16]
63msr  sp_el0, x0
64msr  elr_el1, x1
65msr  spsr_el1, x2
66pop x0, x1
67pop x2, x3
68pop x4, x5
69pop x6, x7
70pop x8, x9
71pop x10, x11
72pop x12, x13
73pop x14, x15
74pop x16, x17
75pop x18, x19
76pop x20, x21
77pop x22, x23
78pop x24, x25
79pop x26, x27
80pop x28, x29
81add sp, sp, #32
82.endm
83
84.macro regrestore_short
85ldp  lr, x0, [sp, #regsave_short_offset]
86ldp  x1, x2, [sp, #regsave_short_offset + 16]
87msr  sp_el0, x0
88msr  elr_el1, x1
89msr  spsr_el1, x2
90pop x0, x1
91pop x2, x3
92pop x4, x5
93pop x6, x7
94pop x8, x9
95pop x10, x11
96pop x12, x13
97pop x14, x15
98pop x16, x17
99add sp, sp, #32
100.endm
101
102.macro invalid_exception, which
103    regsave_long
104    mov x1, #\which
105    mov x0, sp
106    bl  arm64_invalid_exception
107    b   .
108.endm
109
110.macro irq_exception
111    regsave_short
112    msr daifclr, #1 /* reenable fiqs once elr and spsr have been saved */
113    mov x0, sp
114    bl  platform_irq
115    cbz x0, .Lirq_exception_no_preempt\@
116    bl  thread_preempt
117.Lirq_exception_no_preempt\@:
118    msr daifset, #1 /* disable fiqs to protect elr and spsr restore */
119    b   arm64_exc_shared_restore_short
120.endm
121
122FUNCTION(arm64_exception_base)
123
124/* exceptions from current EL, using SP0 */
125LOCAL_FUNCTION(arm64_sync_exc_current_el_SP0)
126    invalid_exception 0
127
128.org 0x080
129LOCAL_FUNCTION(arm64_irq_current_el_SP0)
130    invalid_exception 1
131
132.org 0x100
133LOCAL_FUNCTION(arm64_fiq_current_el_SP0)
134    invalid_exception 2
135
136.org 0x180
137LOCAL_FUNCTION(arm64_err_exc_current_el_SP0)
138    invalid_exception 3
139
140/* exceptions from current EL, using SPx */
141.org 0x200
142LOCAL_FUNCTION(arm64_sync_exc_current_el_SPx)
143    regsave_long
144    mov x0, sp
145    bl  arm64_sync_exception
146    b  arm64_exc_shared_restore_long
147
148.org 0x280
149LOCAL_FUNCTION(arm64_irq_current_el_SPx)
150    irq_exception
151
152.org 0x300
153LOCAL_FUNCTION(arm64_fiq_current_el_SPx)
154    regsave_short
155    mov x0, sp
156    bl  platform_fiq
157    b  arm64_exc_shared_restore_short
158
159.org 0x380
160LOCAL_FUNCTION(arm64_err_exc_current_el_SPx)
161    invalid_exception 0x13
162
163/* exceptions from lower EL, running arm64 */
164.org 0x400
165LOCAL_FUNCTION(arm64_sync_exc_lower_el_64)
166    regsave_long
167    mov x0, sp
168    bl  arm64_sync_exception
169    b  arm64_exc_shared_restore_long
170
171.org 0x480
172LOCAL_FUNCTION(arm64_irq_lower_el_64)
173    irq_exception
174
175.org 0x500
176LOCAL_FUNCTION(arm64_fiq_lower_el_64)
177    regsave_short
178    mov x0, sp
179    bl  platform_fiq
180    b  arm64_exc_shared_restore_short
181
182.org 0x580
183LOCAL_FUNCTION(arm64_err_exc_lower_el_64)
184    invalid_exception 0x23
185
186/* exceptions from lower EL, running arm32 */
187.org 0x600
188LOCAL_FUNCTION(arm64_sync_exc_lower_el_32)
189    regsave_long
190    mov x0, sp
191    bl  arm64_sync_exception
192    b  arm64_exc_shared_restore_long
193
194.org 0x680
195LOCAL_FUNCTION(arm64_irq_lower_el_32)
196    irq_exception
197
198.org 0x700
199LOCAL_FUNCTION(arm64_fiq_lower_el_32)
200    regsave_short
201    mov x0, sp
202    bl  platform_fiq
203    b  arm64_exc_shared_restore_short
204
205.org 0x780
206LOCAL_FUNCTION(arm64_err_exc_lower_el_32)
207    invalid_exception 0x33
208
209.text
210LOCAL_FUNCTION(arm64_exc_shared_restore_long)
211    regrestore_long
212    eret
213
214LOCAL_FUNCTION(arm64_exc_shared_restore_short)
215    regrestore_short
216    eret
217