blob: ee4e9e5b761c86e6beb2c372bbb9bd93c05de47e [file] [log] [blame]
Subrata Banikafa39102024-05-18 12:26:40 +00001/*
2 *
3 * Copyright 2024 Google Inc.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29 .align 16
30 .global exception_stack_end
31exception_stack_end:
32 .quad 0
33 .global exception_state
34exception_state:
35 .quad 0
36
37/* Some temporary variables which are used while saving exception state. */
38vector:
39 .quad 0
40error_code:
41 .quad 0
42old_rsp:
43 .quad 0
44old_rax:
45 .quad 0
46
47 .align 16
48
49/*
50 * Each exception vector has a small stub associated with it which sets aside
51 * the error code, if any, records which vector we entered from, and calls
52 * the common exception entry point. Some exceptions have error codes and some
53 * don't, so we have a macro for each type.
54 */
55
56 .macro stub num
57exception_stub_\num:
58 movq $0, error_code
59 movq $\num, vector
60 jmp exception_common
61 .endm
62
63 .macro stub_err num
64exception_stub_\num:
65 pop error_code
66 movq $\num, vector
67 jmp exception_common
68 .endm
69
70 .altmacro
71 .macro user_defined_stubs from, to
72 stub \from
73 .if \to-\from
74 user_defined_stubs %(from+1),\to
75 .endif
76 .endm
77
78 stub 0
79 stub 1
80 stub 2
81 stub 3
82 stub 4
83 stub 5
84 stub 6
85 stub 7
86 stub_err 8
87 stub 9
88 stub_err 10
89 stub_err 11
90 stub_err 12
91 stub_err 13
92 stub_err 14
93 stub 15
94 stub 16
95 stub_err 17
96 stub 18
97 stub 19
98 stub 20
99 stub 21
100 stub 22
101 stub 23
102 stub 24
103 stub 25
104 stub 26
105 stub 27
106 stub 28
107 stub 29
108 stub_err 30
109 stub 31
110 /* Split the macro so we avoid a stack overflow. */
111 user_defined_stubs 32, 63
112 user_defined_stubs 64, 127
113 user_defined_stubs 128, 191
114 user_defined_stubs 192, 255
115
116exception_common:
117
118 /* Return from the exception. */
119 iretl
120
121/*
122 * We need segment selectors for the IDT, so we need to know where things are
123 * in the GDT. We set one up here which is pretty standard and largely copied
124 * from coreboot.
125 */
126 .align 16
127gdt:
128 /* selgdt 0, unused */
129 .word 0x0000, 0x0000
130 .byte 0x00, 0x00, 0x00, 0x00
131
132 /* selgdt 8, unused */
133 .word 0x0000, 0x0000
134 .byte 0x00, 0x00, 0x00, 0x00
135
136 /* selgdt 0x10, flat 4GB code segment */
137 .word 0xffff, 0x0000
138 .byte 0x00, 0x9b, 0xcf, 0x00
139
140 /* selgdt 0x18, flat 4GB data segment */
141 .word 0xffff, 0x0000
142 .byte 0x00, 0x92, 0xcf, 0x00
143
144 /* selgdt 0x20, flat x64 code segment */
145 .word 0xffff, 0x0000
146 .byte 0x00, 0x9b, 0xaf, 0x00
147gdt_end:
148
149/* GDT pointer for use with lgdt */
150.global gdt_ptr
151gdt_ptr:
152 .word gdt_end - gdt - 1
153 .quad gdt
154
155 /*
156 * Record the target and construct the actual entry at init time. This
157 * is necessary because the linker doesn't want to construct the entry
158 * for us.
159 */
160 .macro interrupt_gate target
161 .quad \target
162 .quad \target
163 .endm
164
165 .altmacro
166 .macro user_defined_gates from, to
167 interrupt_gate exception_stub_\from
168 .if \to-\from
169 user_defined_gates %(from+1),\to
170 .endif
171 .endm
172
173 .align 16
174 .global idt
175idt:
176 interrupt_gate exception_stub_0
177 interrupt_gate exception_stub_1
178 interrupt_gate exception_stub_2
179 interrupt_gate exception_stub_3
180 interrupt_gate exception_stub_4
181 interrupt_gate exception_stub_5
182 interrupt_gate exception_stub_6
183 interrupt_gate exception_stub_7
184 interrupt_gate exception_stub_8
185 interrupt_gate exception_stub_9
186 interrupt_gate exception_stub_10
187 interrupt_gate exception_stub_11
188 interrupt_gate exception_stub_12
189 interrupt_gate exception_stub_13
190 interrupt_gate exception_stub_14
191 interrupt_gate exception_stub_15
192 interrupt_gate exception_stub_16
193 interrupt_gate exception_stub_17
194 interrupt_gate exception_stub_18
195 interrupt_gate exception_stub_19
196 interrupt_gate exception_stub_20
197 interrupt_gate exception_stub_21
198 interrupt_gate exception_stub_22
199 interrupt_gate exception_stub_23
200 interrupt_gate exception_stub_24
201 interrupt_gate exception_stub_25
202 interrupt_gate exception_stub_26
203 interrupt_gate exception_stub_27
204 interrupt_gate exception_stub_28
205 interrupt_gate exception_stub_29
206 interrupt_gate exception_stub_30
207 interrupt_gate exception_stub_31
208 user_defined_gates 32, 63
209 user_defined_gates 64, 127
210 user_defined_gates 128, 191
211 user_defined_gates 192, 255
212idt_end:
213
214/* IDT pointer for use with lidt */
215idt_ptr:
216 .word idt_end - idt - 1
217 .quad idt
218
219 .global exception_init_asm
220exception_init_asm:
221 ret