acrn-hypervisor/hypervisor/arch/x86/idt.S

418 lines
7.5 KiB
ArmAsm

/*
* Copyright (C) 2018 Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <gdt.h>
#include <idt.h>
.altmacro
.global HOST_IDT
.global HOST_IDTR
.section .data
.align 8
.long 0
.short 0
HOST_IDTR:
.short HOST_IDT_SIZE - 1
.quad HOST_IDT
/*
* We'll rearrange and fix up the descriptors at runtime
*/
.macro interrupt_descriptor entry, dpl=0 ist=0
.long HOST_GDT_RING0_CODE_SEL << 16
.long 0x00008e00 + (dpl << 13) + ist
.quad entry
.endm
.macro trap_descriptor entry, dpl=0, ist=0
.long HOST_GDT_RING0_CODE_SEL << 16
.long 0x00008f00 + (dpl <<13) + ist
.quad entry
.endm
.macro _external_interrupt_descriptor vector
__external_interrupt_descriptor %vector
.endm
.macro __external_interrupt_descriptor vector
interrupt_descriptor external_interrupt_\vector
.endm
#define MACHINE_CHECK_IST (0x1)
#define DOUBLE_FAULT_IST (0x2)
#define STACK_FAULT_IST (0x3)
/*
* We'll use interrupt gates. Change to trap or task only as needed.
*/
.section .rodata
.align 16
HOST_IDT:
interrupt_descriptor excp_divide_error
interrupt_descriptor excp_debug, 3
interrupt_descriptor excp_nmi
interrupt_descriptor excp_breakpoint, 3
interrupt_descriptor excp_overflow, 3
interrupt_descriptor excp_bounds_check
interrupt_descriptor excp_illegal_opcode
interrupt_descriptor excp_device_not_available
interrupt_descriptor excp_double_fault, 0, DOUBLE_FAULT_IST
interrupt_descriptor excp_rsvd_09
interrupt_descriptor excp_invalid_tss
interrupt_descriptor excp_segment_not_present
interrupt_descriptor excp_stack_fault, 0, STACK_FAULT_IST
interrupt_descriptor excp_general_protection
interrupt_descriptor excp_page_fault
interrupt_descriptor excp_rsvd_0f
interrupt_descriptor excp_float_error
interrupt_descriptor excp_alignment_check
interrupt_descriptor expt_machine_check, 0, MACHINE_CHECK_IST
interrupt_descriptor excp_simd_fp_error
interrupt_descriptor excp_virtualization
interrupt_descriptor excp_rsvd_21
interrupt_descriptor excp_rsvd_22
interrupt_descriptor excp_rsvd_23
interrupt_descriptor excp_rsvd_24
interrupt_descriptor excp_rsvd_25
interrupt_descriptor excp_rsvd_26
interrupt_descriptor excp_rsvd_27
interrupt_descriptor excp_rsvd_28
interrupt_descriptor excp_rsvd_29
interrupt_descriptor excp_rsvd_30
interrupt_descriptor excp_rsvd_31
vector = 0x20
.rept (0x100 - 0x20)
_external_interrupt_descriptor vector
vector = vector + 1
.endr
.section .text
.align 16
excp_divide_error:
pushq $0x0 /* pseudo error code */
pushq $0x00
jmp excp_save_frame
.align 8
excp_debug:
pushq $0x0 /* pseudo error code */
pushq $0x01
jmp excp_save_frame
.align 8
excp_nmi:
.align 8
excp_breakpoint:
pushq $0x0 /* pseudo error code */
pushq $0x03
jmp excp_save_frame
.align 8
excp_overflow:
pushq $0x0 /* pseudo error code */
pushq $0x04
jmp excp_save_frame
.align 8
excp_bounds_check:
pushq $0x0 /* pseudo error code */
pushq $0x05
jmp excp_save_frame
.align 8
excp_illegal_opcode:
pushq $0x0 /* pseudo error code */
pushq $0x06
jmp excp_save_frame
.align 8
excp_device_not_available:
pushq $0x0 /* pseudo error code */
pushq $0x07
jmp excp_save_frame
.align 8
excp_double_fault:
pushq $0x08
jmp excp_save_frame
.align 8
excp_invalid_tss:
pushq $0x0A
jmp excp_save_frame
.align 8
excp_segment_not_present:
pushq $0x0B
jmp excp_save_frame
.align 8
excp_stack_fault:
pushq $0x0C
jmp excp_save_frame
.align 8
excp_general_protection:
pushq $0x0D
jmp excp_save_frame
.align 8
excp_page_fault:
pushq $0x0E
jmp excp_save_frame
.align 8
excp_float_error:
pushq $0x0 /* pseudo error code */
pushq $0x10
jmp excp_save_frame
.align 8
excp_alignment_check:
pushq $0x11
jmp excp_save_frame
.align 8
expt_machine_check:
pushq $0x0 /* pseudo error code */
pushq $0x12
jmp excp_save_frame
.align 8
excp_simd_fp_error:
pushq $0x0 /* pseudo error code */
pushq $0x13
jmp excp_save_frame
.align 8
excp_virtualization:
pushq $0x0 /* pseudo error code */
pushq $0x14
jmp excp_save_frame
/*
* Macros for rsvd vectors. Vectors 0x09, 0x0F, 0x15 through 0x1F
*/
.macro _rsvd_vector vector
__rsvd_vector %vector
.endm
.macro __rsvd_vector vector
.align 8
excp_rsvd_\vector\():
pushq $0x0 /* pseudo error code */
pushq $\vector
jmp excp_rsvd
.endm
.align 8
excp_rsvd_09:
_rsvd_vector 0x09
.align 8
excp_rsvd_0f:
_rsvd_vector 0x0f
vector = 0x15
.rept (0x20 - 0x15)
_rsvd_vector vector
vector = vector + 1
.endr
/*
* Macros for external interrupts. Vectors$0x20 through$0xFF
*/
.macro _external_interrupt vector
__external_interrupt %vector
.endm
.macro __external_interrupt vector
.align 8
external_interrupt_\vector\():
pushq $0x0 /* pseudo error code */
pushq $\vector
jmp external_interrupt_save_frame
.endm
vector =0x20
.rept (0x100 - 0x20)
_external_interrupt vector
vector = vector + 1
.endr
/*
* Common entry point for defined exceptions
*/
.align 8
excp_save_frame:
pushq %r11
pushq %r10
pushq %r9
pushq %r8
pushq %rdi
pushq %rsi
pushq %rdx
pushq %rcx
pushq %rax
pushq %rbp
pushq %rbx
pushq %r15
pushq %r14
pushq %r13
pushq %r12
/* Put current stack pointer into 1st param register (rdi) */
movq %rsp, %rdi
call dispatch_exception
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbx
popq %rbp
popq %rax
popq %rcx
popq %rdx
popq %rsi
popq %rdi
popq %r8
popq %r9
popq %r10
popq %r11
/* Skip vector and error code*/
add $16, %rsp
iretq
/*
* Common entry point for reserved exceptions.
* These should never execute.
* We put a handler on them anyway to highlight the unexpected.
*/
.align 8
excp_rsvd:
pushq %r11
pushq %r10
pushq %r9
pushq %r8
pushq %rdi
pushq %rsi
pushq %rdx
pushq %rcx
pushq %rax
pushq %rbp
pushq %rbx
pushq %r15
pushq %r14
pushq %r13
pushq %r12
/* Put current stack pointer into 1st param register (rdi) */
movq %rsp, %rdi
call dispatch_exception
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbx
popq %rbp
popq %rax
popq %rcx
popq %rdx
popq %rsi
popq %rdi
popq %r8
popq %r9
popq %r10
popq %r11
/* Skip vector and error code*/
add $16, %rsp
iretq
/*
* Common entry point for defined interrupts.
* Vectors 0x20 through 0xFF
*/
.align 8
external_interrupt_save_frame:
pushq %r11
pushq %r10
pushq %r9
pushq %r8
pushq %rdi
pushq %rsi
pushq %rdx
pushq %rcx
pushq %rax
pushq %rbp
pushq %rbx
pushq %r15
pushq %r14
pushq %r13
pushq %r12
/* Put current stack pointer into 1st param register (rdi) */
movq %rsp, %rdi
call dispatch_interrupt
/*
* We disable softirq path from interrupt IRET, since right now all IRQ
* are for Guest, and we can execute softirq in hv_main() loop
*/
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbx
popq %rbp
popq %rax
popq %rcx
popq %rdx
popq %rsi
popq %rdi
popq %r8
popq %r9
popq %r10
popq %r11
/* Skip vector and error code*/
add $16, %rsp
iretq