1/*
2 * Copyright (C) 2018-2022 Intel Corporation.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <asm/idt.h>
8
9.altmacro
10
11.global HOST_IDT
12.global HOST_IDTR
13
14.section    .data
15.align 8
16    .long   0
17    .short  0
18HOST_IDTR:
19    .short  HOST_IDT_SIZE - 1
20    .quad   HOST_IDT
21
22/*
23 * We'll rearrange and fix up the descriptors at runtime
24 */
25.macro interrupt_descriptor entry, dpl=0 ist=0
26	/* 0x0008 = HOST_GDT_RING0_CODE_SEL */
27	.long	0x0008 << 16
28	.long	0x00008e00 + (dpl << 13) + ist
29	.quad	entry
30.endm
31
32.macro	trap_descriptor entry, dpl=0, ist=0
33        /* 0x0008 = HOST_GDT_RING0_CODE_SEL */
34	.long	0x0008 << 16
35	.long	0x00008f00 + (dpl <<13) + ist
36	.quad	entry
37.endm
38
39
40.macro _external_interrupt_descriptor vector
41    __external_interrupt_descriptor %vector
42.endm
43
44
45.macro	__external_interrupt_descriptor vector
46	interrupt_descriptor external_interrupt_\vector
47.endm
48
49#define MACHINE_CHECK_IST   (0x1)
50#define DOUBLE_FAULT_IST    (0x2)
51#define STACK_FAULT_IST     (0x3)
52
53/*
54 * We'll use interrupt gates.  Change to trap or task only as needed.
55 */
56.section    .rodata
57.align 16
58HOST_IDT:
59interrupt_descriptor	excp_divide_error
60interrupt_descriptor	excp_debug, 3
61interrupt_descriptor	excp_nmi
62interrupt_descriptor	excp_breakpoint, 3
63interrupt_descriptor	excp_overflow, 3
64interrupt_descriptor	excp_bounds_check
65interrupt_descriptor	excp_illegal_opcode
66interrupt_descriptor	excp_device_not_available
67interrupt_descriptor	excp_double_fault, 0, DOUBLE_FAULT_IST
68interrupt_descriptor	excp_rsvd_09
69interrupt_descriptor	excp_invalid_tss
70interrupt_descriptor	excp_segment_not_present
71interrupt_descriptor	excp_stack_fault, 0, STACK_FAULT_IST
72interrupt_descriptor	excp_general_protection
73interrupt_descriptor	excp_page_fault
74interrupt_descriptor	excp_rsvd_0f
75interrupt_descriptor	excp_float_error
76interrupt_descriptor	excp_alignment_check
77interrupt_descriptor	expt_machine_check, 0, MACHINE_CHECK_IST
78interrupt_descriptor	excp_simd_fp_error
79interrupt_descriptor	excp_virtualization
80interrupt_descriptor	excp_rsvd_21
81interrupt_descriptor	excp_rsvd_22
82interrupt_descriptor	excp_rsvd_23
83interrupt_descriptor	excp_rsvd_24
84interrupt_descriptor	excp_rsvd_25
85interrupt_descriptor	excp_rsvd_26
86interrupt_descriptor	excp_rsvd_27
87interrupt_descriptor	excp_rsvd_28
88interrupt_descriptor	excp_rsvd_29
89interrupt_descriptor	excp_rsvd_30
90interrupt_descriptor	excp_rsvd_31
91
92vector = 0x20
93.rept	(0x100 - 0x20)
94	_external_interrupt_descriptor vector
95	vector = vector + 1
96.endr
97
98.section .text
99.align 16
100excp_divide_error:
101	pushq  $0x0			/* pseudo error code */
102	pushq  $0x00
103	jmp    excp_save_frame
104
105.align 8
106excp_debug:
107	pushq  $0x0			/* pseudo error code */
108	pushq  $0x01
109	jmp    excp_save_frame
110
111.align 8
112excp_nmi:
113	pushq  $0x0			/* pseudo error code */
114	pushq  $0x2
115	jmp    nmi_save_frame
116
117.align 8
118excp_breakpoint:
119	pushq  $0x0			/* pseudo error code */
120	pushq  $0x03
121	jmp    excp_save_frame
122
123.align 8
124excp_overflow:
125	pushq  $0x0			/* pseudo error code */
126	pushq  $0x04
127	jmp    excp_save_frame
128
129.align 8
130excp_bounds_check:
131	pushq  $0x0			/* pseudo error code */
132	pushq  $0x05
133	jmp    excp_save_frame
134
135.align 8
136excp_illegal_opcode:
137	pushq  $0x0			/* pseudo error code */
138	pushq  $0x06
139	jmp    excp_save_frame
140
141.align 8
142excp_device_not_available:
143	pushq  $0x0			/* pseudo error code */
144	pushq  $0x07
145	jmp    excp_save_frame
146
147.align 8
148excp_double_fault:
149	pushq  $0x08
150	jmp    excp_save_frame
151
152.align 8
153excp_invalid_tss:
154	pushq  $0x0A
155	jmp    excp_save_frame
156
157.align 8
158excp_segment_not_present:
159	pushq  $0x0B
160	jmp    excp_save_frame
161
162.align 8
163excp_stack_fault:
164	pushq  $0x0C
165	jmp    excp_save_frame
166
167.align 8
168excp_general_protection:
169	pushq  $0x0D
170	jmp    excp_save_frame
171
172.align 8
173excp_page_fault:
174	pushq  $0x0E
175	jmp    excp_save_frame
176
177.align 8
178excp_float_error:
179	pushq  $0x0			/* pseudo error code */
180	pushq  $0x10
181	jmp    excp_save_frame
182
183.align 8
184excp_alignment_check:
185	pushq  $0x11
186	jmp    excp_save_frame
187
188.align 8
189expt_machine_check:
190	pushq  $0x0			/* pseudo error code */
191	pushq  $0x12
192	jmp    excp_save_frame
193
194.align 8
195excp_simd_fp_error:
196	pushq  $0x0			/* pseudo error code */
197	pushq  $0x13
198	jmp    excp_save_frame
199
200.align 8
201excp_virtualization:
202	pushq  $0x0			/* pseudo error code */
203	pushq  $0x14
204	jmp    excp_save_frame
205
206
207
208/*
209 * Macros for rsvd vectors.  Vectors 0x09, 0x0F, 0x15 through 0x1F
210 */
211.macro _rsvd_vector vector
212    __rsvd_vector %vector
213.endm
214
215.macro __rsvd_vector vector
216.align 8
217excp_rsvd_\vector\():
218	pushq  $0x0			/* pseudo error code */
219	pushq  $\vector
220	jmp    excp_rsvd
221.endm
222
223.align 8
224excp_rsvd_09:
225    _rsvd_vector 0x09
226
227.align 8
228excp_rsvd_0f:
229    _rsvd_vector 0x0f
230
231vector = 0x15
232.rept	(0x20 - 0x15)
233    _rsvd_vector vector
234    vector = vector + 1
235.endr
236
237
238
239/*
240 * Macros for external interrupts.  Vectors$0x20 through$0xFF
241 */
242.macro _external_interrupt vector
243    __external_interrupt %vector
244.endm
245
246.macro __external_interrupt vector
247.align 8
248external_interrupt_\vector\():
249	pushq  $0x0			/* pseudo error code */
250	pushq  $\vector
251	jmp    external_interrupt_save_frame
252.endm
253
254vector =0x20
255.rept	(0x100 - 0x20)
256    _external_interrupt vector
257    vector = vector + 1
258.endr
259
260.macro save_frame
261    pushq %r15
262    pushq %r14
263    pushq %r13
264    pushq %r12
265    pushq %r11
266    pushq %r10
267    pushq %r9
268    pushq %r8
269    pushq %rdi
270    pushq %rsi
271    pushq %rbp
272    pushq %rsp
273    pushq %rbx
274    pushq %rdx
275    pushq %rcx
276    pushq %rax
277
278    /* Put current stack pointer into 1st param register (rdi) */
279    movq    %rsp, %rdi
280.endm
281
282.macro restore_frame
283    popq    %rax
284    popq    %rcx
285    popq    %rdx
286    popq    %rbx
287    popq    %rsp
288    popq    %rbp
289    popq    %rsi
290    popq    %rdi
291    popq    %r8
292    popq    %r9
293    popq    %r10
294    popq    %r11
295    popq    %r12
296    popq    %r13
297    popq    %r14
298    popq    %r15
299
300    /* Skip vector and error code*/
301    add     $16, %rsp
302.endm
303
304/*
305 * Common entry point for defined exceptions
306 */
307.align 8
308excp_save_frame:
309    save_frame
310
311    call   dispatch_exception
312
313    restore_frame
314
315    iretq
316
317
318/*
319 * Common entry point for reserved exceptions.
320 * These should never execute.
321 * We put a handler on them anyway to highlight the unexpected.
322 */
323.align 8
324excp_rsvd:
325    save_frame
326
327    call   dispatch_exception
328
329    restore_frame
330
331    iretq
332
333/*
334 * Common entry point for NMI interrupts
335 */
336.align 8
337nmi_save_frame:
338    save_frame
339
340    call   handle_nmi
341
342    restore_frame
343
344    iretq
345
346
347/*
348 * Common entry point for defined interrupts.
349 * Vectors 0x20 through 0xFF
350 */
351.align 8
352external_interrupt_save_frame:
353    save_frame
354
355    call   dispatch_interrupt
356
357    /*
358     * We disable softirq path from interrupt IRET, since right now all IRQ
359     * are for Guest.
360     */
361
362    restore_frame
363
364    iretq
365
366