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