| TITLE CpuInterrupt.asm: | |
| ;------------------------------------------------------------------------------ | |
| ;* | |
| ;* Copyright 2006, Intel Corporation | |
| ;* All rights reserved. This program and the accompanying materials | |
| ;* are licensed and made available under the terms and conditions of the BSD License | |
| ;* which accompanies this distribution. The full text of the license may be found at | |
| ;* http://opensource.org/licenses/bsd-license.php | |
| ;* | |
| ;* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, | |
| ;* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |
| ;* | |
| ;* CpuInterrupt.asm | |
| ;* | |
| ;* Abstract: | |
| ;* | |
| ;------------------------------------------------------------------------------ | |
| EXTERNDEF mExceptionCodeSize:DWORD | |
| .code | |
| EXTERN TimerHandler: FAR | |
| EXTERN ExceptionHandler: NEAR | |
| EXTERN mTimerVector: QWORD | |
| mExceptionCodeSize DD 9 | |
| InitDescriptor PROC | |
| lea rax, [GDT_BASE] ; RAX=PHYSICAL address of gdt | |
| mov qword ptr [gdtr + 2], rax ; Put address of gdt into the gdtr | |
| lgdt fword ptr [gdtr] | |
| mov rax, 18h | |
| mov gs, rax | |
| mov fs, rax | |
| lea rax, [IDT_BASE] ; RAX=PHYSICAL address of idt | |
| mov qword ptr [idtr + 2], rax ; Put address of idt into the idtr | |
| lidt fword ptr [idtr] | |
| ret | |
| InitDescriptor ENDP | |
| ; VOID | |
| ; InstallInterruptHandler ( | |
| ; UINTN Vector, // rcx | |
| ; void (*Handler)(void) // rdx | |
| ; ) | |
| InstallInterruptHandler PROC | |
| push rbx | |
| pushfq ; save eflags | |
| cli ; turn off interrupts | |
| sub rsp, 10h ; open some space on the stack | |
| mov rbx, rsp | |
| sidt [rbx] ; get fword address of IDT | |
| mov rbx, [rbx+2] ; move offset of IDT into RBX | |
| add rsp, 10h ; correct stack | |
| mov rax, rcx ; Get vector number | |
| shl rax, 4 ; multiply by 16 to get offset | |
| add rbx, rax ; add to IDT base to get entry | |
| mov rax, rdx ; load new address into IDT entry | |
| mov word ptr [rbx], ax ; write bits 15..0 of offset | |
| shr rax, 16 ; use ax to copy 31..16 to descriptors | |
| mov word ptr [rbx+6], ax ; write bits 31..16 of offset | |
| shr rax, 16 ; use eax to copy 63..32 to descriptors | |
| mov dword ptr [rbx+8], eax ; write bits 63..32 of offset | |
| popfq ; restore flags (possible enabling interrupts) | |
| pop rbx | |
| ret | |
| InstallInterruptHandler ENDP | |
| JmpCommonIdtEntry macro | |
| ; jmp commonIdtEntry - this must be hand coded to keep the assembler from | |
| ; using a 8 bit reletive jump when the entries are | |
| ; within 255 bytes of the common entry. This must | |
| ; be done to maintain the consistency of the size | |
| ; of entry points... | |
| db 0e9h ; jmp 16 bit reletive | |
| dd commonIdtEntry - $ - 4 ; offset to jump to | |
| endm | |
| align 02h | |
| SystemExceptionHandler PROC | |
| INT0: | |
| push 0h ; push error code place holder on the stack | |
| push 0h | |
| JmpCommonIdtEntry | |
| ; db 0e9h ; jmp 16 bit reletive | |
| ; dd commonIdtEntry - $ - 4 ; offset to jump to | |
| INT1: | |
| push 0h ; push error code place holder on the stack | |
| push 1h | |
| JmpCommonIdtEntry | |
| INT2: | |
| push 0h ; push error code place holder on the stack | |
| push 2h | |
| JmpCommonIdtEntry | |
| INT3: | |
| push 0h ; push error code place holder on the stack | |
| push 3h | |
| JmpCommonIdtEntry | |
| INT4: | |
| push 0h ; push error code place holder on the stack | |
| push 4h | |
| JmpCommonIdtEntry | |
| INT5: | |
| push 0h ; push error code place holder on the stack | |
| push 5h | |
| JmpCommonIdtEntry | |
| INT6: | |
| push 0h ; push error code place holder on the stack | |
| push 6h | |
| JmpCommonIdtEntry | |
| INT7: | |
| push 0h ; push error code place holder on the stack | |
| push 7h | |
| JmpCommonIdtEntry | |
| INT8: | |
| ; Double fault causes an error code to be pushed so no phony push necessary | |
| nop | |
| nop | |
| push 8h | |
| JmpCommonIdtEntry | |
| INT9: | |
| push 0h ; push error code place holder on the stack | |
| push 9h | |
| JmpCommonIdtEntry | |
| INT10: | |
| ; Invalid TSS causes an error code to be pushed so no phony push necessary | |
| nop | |
| nop | |
| push 10 | |
| JmpCommonIdtEntry | |
| INT11: | |
| ; Segment Not Present causes an error code to be pushed so no phony push necessary | |
| nop | |
| nop | |
| push 11 | |
| JmpCommonIdtEntry | |
| INT12: | |
| ; Stack fault causes an error code to be pushed so no phony push necessary | |
| nop | |
| nop | |
| push 12 | |
| JmpCommonIdtEntry | |
| INT13: | |
| ; GP fault causes an error code to be pushed so no phony push necessary | |
| nop | |
| nop | |
| push 13 | |
| JmpCommonIdtEntry | |
| INT14: | |
| ; Page fault causes an error code to be pushed so no phony push necessary | |
| nop | |
| nop | |
| push 14 | |
| JmpCommonIdtEntry | |
| INT15: | |
| push 0h ; push error code place holder on the stack | |
| push 15 | |
| JmpCommonIdtEntry | |
| INT16: | |
| push 0h ; push error code place holder on the stack | |
| push 16 | |
| JmpCommonIdtEntry | |
| INT17: | |
| ; Alignment check causes an error code to be pushed so no phony push necessary | |
| nop | |
| nop | |
| push 17 | |
| JmpCommonIdtEntry | |
| INT18: | |
| push 0h ; push error code place holder on the stack | |
| push 18 | |
| JmpCommonIdtEntry | |
| INT19: | |
| push 0h ; push error code place holder on the stack | |
| push 19 | |
| JmpCommonIdtEntry | |
| INTUnknown: | |
| REPEAT (32 - 20) | |
| push 0h ; push error code place holder on the stack | |
| ; push xxh ; push vector number | |
| db 06ah | |
| db ( $ - INTUnknown - 3 ) / 9 + 20 ; vector number | |
| JmpCommonIdtEntry | |
| ENDM | |
| SystemExceptionHandler ENDP | |
| SystemTimerHandler PROC | |
| push 0 | |
| push mTimerVector | |
| JmpCommonIdtEntry | |
| SystemTimerHandler ENDP | |
| commonIdtEntry: | |
| ; +---------------------+ <-- 16-byte aligned ensured by processor | |
| ; + Old SS + | |
| ; +---------------------+ | |
| ; + Old RSP + | |
| ; +---------------------+ | |
| ; + RFlags + | |
| ; +---------------------+ | |
| ; + CS + | |
| ; +---------------------+ | |
| ; + RIP + | |
| ; +---------------------+ | |
| ; + Error Code + | |
| ; +---------------------+ | |
| ; + Vector Number + | |
| ; +---------------------+ | |
| ; + RBP + | |
| ; +---------------------+ <-- RBP, 16-byte aligned | |
| cli | |
| push rbp | |
| mov rbp, rsp | |
| ; | |
| ; Since here the stack pointer is 16-byte aligned, so | |
| ; EFI_FX_SAVE_STATE_X64 of EFI_SYSTEM_CONTEXT_x64 | |
| ; is 16-byte aligned | |
| ; | |
| ;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax; | |
| ;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15; | |
| push r15 | |
| push r14 | |
| push r13 | |
| push r12 | |
| push r11 | |
| push r10 | |
| push r9 | |
| push r8 | |
| push rax | |
| push rcx | |
| push rdx | |
| push rbx | |
| push qword ptr [rbp + 6 * 8] ; RSP | |
| push qword ptr [rbp] ; RBP | |
| push rsi | |
| push rdi | |
| ;; UINT64 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero | |
| movzx rax, word ptr [rbp + 7 * 8] | |
| push rax ; for ss | |
| movzx rax, word ptr [rbp + 4 * 8] | |
| push rax ; for cs | |
| mov rax, ds | |
| push rax | |
| mov rax, es | |
| push rax | |
| mov rax, fs | |
| push rax | |
| mov rax, gs | |
| push rax | |
| ;; UINT64 Rip; | |
| push qword ptr [rbp + 3 * 8] | |
| ;; UINT64 Gdtr[2], Idtr[2]; | |
| sub rsp, 16 | |
| sidt fword ptr [rsp] | |
| sub rsp, 16 | |
| sgdt fword ptr [rsp] | |
| ;; UINT64 Ldtr, Tr; | |
| xor rax, rax | |
| str ax | |
| push rax | |
| sldt ax | |
| push rax | |
| ;; UINT64 RFlags; | |
| push qword ptr [rbp + 5 * 8] | |
| ;; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8; | |
| mov rax, cr8 | |
| push rax | |
| mov rax, cr4 | |
| or rax, 208h | |
| mov cr4, rax | |
| push rax | |
| mov rax, cr3 | |
| push rax | |
| mov rax, cr2 | |
| push rax | |
| xor rax, rax | |
| push rax | |
| mov rax, cr0 | |
| push rax | |
| ;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; | |
| mov rax, dr7 | |
| push rax | |
| ;; clear Dr7 while executing debugger itself | |
| xor rax, rax | |
| mov dr7, rax | |
| mov rax, dr6 | |
| push rax | |
| ;; insure all status bits in dr6 are clear... | |
| xor rax, rax | |
| mov dr6, rax | |
| mov rax, dr3 | |
| push rax | |
| mov rax, dr2 | |
| push rax | |
| mov rax, dr1 | |
| push rax | |
| mov rax, dr0 | |
| push rax | |
| ;; FX_SAVE_STATE_X64 FxSaveState; | |
| sub rsp, 512 | |
| mov rdi, rsp | |
| db 0fh, 0aeh, 00000111y ;fxsave [rdi] | |
| ;; UINT32 ExceptionData; | |
| push qword ptr [rbp + 2 * 8] | |
| ;; call into exception handler | |
| ;; Prepare parameter and call | |
| mov rcx, qword ptr [rbp + 1 * 8] | |
| mov rdx, rsp | |
| ; | |
| ; Per X64 calling convention, allocate maximum parameter stack space | |
| ; and make sure RSP is 16-byte aligned | |
| ; | |
| sub rsp, 4 * 8 + 8 | |
| cmp rcx, 32 | |
| jb CallException | |
| call TimerHandler | |
| jmp ExceptionDone | |
| CallException: | |
| call ExceptionHandler | |
| ExceptionDone: | |
| add rsp, 4 * 8 + 8 | |
| cli | |
| ;; UINT64 ExceptionData; | |
| add rsp, 8 | |
| ;; FX_SAVE_STATE_X64 FxSaveState; | |
| mov rsi, rsp | |
| db 0fh, 0aeh, 00001110y ; fxrstor [rsi] | |
| add rsp, 512 | |
| ;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; | |
| pop rax | |
| mov dr0, rax | |
| pop rax | |
| mov dr1, rax | |
| pop rax | |
| mov dr2, rax | |
| pop rax | |
| mov dr3, rax | |
| ;; skip restore of dr6. We cleared dr6 during the context save. | |
| add rsp, 8 | |
| pop rax | |
| mov dr7, rax | |
| ;; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8; | |
| pop rax | |
| mov cr0, rax | |
| add rsp, 8 ; not for Cr1 | |
| pop rax | |
| mov cr2, rax | |
| pop rax | |
| mov cr3, rax | |
| pop rax | |
| mov cr4, rax | |
| pop rax | |
| mov cr8, rax | |
| ;; UINT64 RFlags; | |
| pop qword ptr [rbp + 5 * 8] | |
| ;; UINT64 Ldtr, Tr; | |
| ;; UINT64 Gdtr[2], Idtr[2]; | |
| ;; Best not let anyone mess with these particular registers... | |
| add rsp, 48 | |
| ;; UINT64 Rip; | |
| pop qword ptr [rbp + 3 * 8] | |
| ;; UINT64 Gs, Fs, Es, Ds, Cs, Ss; | |
| pop rax | |
| ; mov gs, rax ; not for gs | |
| pop rax | |
| ; mov fs, rax ; not for fs | |
| ; (X64 will not use fs and gs, so we do not restore it) | |
| pop rax | |
| mov es, rax | |
| pop rax | |
| mov ds, rax | |
| pop qword ptr [rbp + 4 * 8] ; for cs | |
| pop qword ptr [rbp + 7 * 8] ; for ss | |
| ;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax; | |
| ;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15; | |
| pop rdi | |
| pop rsi | |
| add rsp, 8 ; not for rbp | |
| pop qword ptr [rbp + 6 * 8] ; for rsp | |
| pop rbx | |
| pop rdx | |
| pop rcx | |
| pop rax | |
| pop r8 | |
| pop r9 | |
| pop r10 | |
| pop r11 | |
| pop r12 | |
| pop r13 | |
| pop r14 | |
| pop r15 | |
| mov rsp, rbp | |
| pop rbp | |
| add rsp, 16 | |
| iretq | |
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
| ; data | |
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
| align 010h | |
| gdtr dw GDT_END - GDT_BASE - 1 ; GDT limit | |
| dq 0 ; (GDT base gets set above) | |
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
| ; global descriptor table (GDT) | |
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
| align 010h | |
| public GDT_BASE | |
| GDT_BASE: | |
| ; null descriptor | |
| NULL_SEL equ $-GDT_BASE ; Selector [0x0] | |
| dw 0 ; limit 15:0 | |
| dw 0 ; base 15:0 | |
| db 0 ; base 23:16 | |
| db 0 ; type | |
| db 0 ; limit 19:16, flags | |
| db 0 ; base 31:24 | |
| ; linear data segment descriptor | |
| LINEAR_SEL equ $-GDT_BASE ; Selector [0x8] | |
| dw 0FFFFh ; limit 0xFFFFF | |
| dw 0 ; base 0 | |
| db 0 | |
| db 092h ; present, ring 0, data, expand-up, writable | |
| db 0CFh ; page-granular, 32-bit | |
| db 0 | |
| ; linear code segment descriptor | |
| LINEAR_CODE_SEL equ $-GDT_BASE ; Selector [0x10] | |
| dw 0FFFFh ; limit 0xFFFFF | |
| dw 0 ; base 0 | |
| db 0 | |
| db 09Ah ; present, ring 0, data, expand-up, writable | |
| db 0CFh ; page-granular, 32-bit | |
| db 0 | |
| ; system data segment descriptor | |
| SYS_DATA_SEL equ $-GDT_BASE ; Selector [0x18] | |
| dw 0FFFFh ; limit 0xFFFFF | |
| dw 0 ; base 0 | |
| db 0 | |
| db 092h ; present, ring 0, data, expand-up, writable | |
| db 0CFh ; page-granular, 32-bit | |
| db 0 | |
| ; system code segment descriptor | |
| SYS_CODE_SEL equ $-GDT_BASE ; Selector [0x20] | |
| dw 0FFFFh ; limit 0xFFFFF | |
| dw 0 ; base 0 | |
| db 0 | |
| db 09Ah ; present, ring 0, data, expand-up, writable | |
| db 0CFh ; page-granular, 32-bit | |
| db 0 | |
| ; spare segment descriptor | |
| SPARE3_SEL equ $-GDT_BASE ; Selector [0x28] | |
| dw 0 ; limit 0xFFFFF | |
| dw 0 ; base 0 | |
| db 0 | |
| db 0 ; present, ring 0, data, expand-up, writable | |
| db 0 ; page-granular, 32-bit | |
| db 0 | |
| ; | |
| ; system data segment descriptor | |
| ; | |
| SYS_DATA64_SEL equ $-GDT_BASE ; Selector [0x30] | |
| dw 0FFFFh ; limit 0xFFFFF | |
| dw 0 ; base 0 | |
| db 0 | |
| db 092h ; P | DPL [1..2] | 1 | 1 | C | R | A | |
| db 0CFh ; G | D | L | AVL | Segment [19..16] | |
| db 0 | |
| ; | |
| ; system code segment descriptor | |
| ; | |
| SYS_CODE64_SEL equ $-GDT_BASE ; Selector [0x38] | |
| dw 0FFFFh ; limit 0xFFFFF | |
| dw 0 ; base 0 | |
| db 0 | |
| db 09Ah ; P | DPL [1..2] | 1 | 1 | C | R | A | |
| db 0AFh ; G | D | L | AVL | Segment [19..16] | |
| db 0 | |
| ; spare segment descriptor | |
| SPARE4_SEL equ $-GDT_BASE ; Selector [0x40] | |
| dw 0 ; limit 0xFFFFF | |
| dw 0 ; base 0 | |
| db 0 | |
| db 0 ; present, ring 0, data, expand-up, writable | |
| db 0 ; page-granular, 32-bit | |
| db 0 | |
| GDT_END: | |
| align 02h | |
| idtr dw IDT_END - IDT_BASE - 1 ; IDT limit | |
| dq 0 ; (IDT base gets set above) | |
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
| ; interrupt descriptor table (IDT) | |
| ; | |
| ; Note: The hardware IRQ's specified in this table are the normal PC/AT IRQ | |
| ; mappings. This implementation only uses the system timer and all other | |
| ; IRQs will remain masked. The descriptors for vectors 33+ are provided | |
| ; for convenience. | |
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
| ;idt_tag db "IDT",0 | |
| align 02h | |
| public IDT_BASE | |
| IDT_BASE: | |
| ; divide by zero (INT 0) | |
| DIV_ZERO_SEL equ $-IDT_BASE | |
| dw 0 ; offset 15:0 | |
| dw SYS_CODE64_SEL ; selector 15:0 | |
| db 0 ; 0 for interrupt gate | |
| db 0eh OR 80h ; type = 386 interrupt gate, present | |
| dw 0 ; offset 31:16 | |
| dd 0 ; offset 63:32 | |
| dd 0 ; 0 for reserved | |
| ; debug exception (INT 1) | |
| DEBUG_EXCEPT_SEL equ $-IDT_BASE | |
| dw 0 ; offset 15:0 | |
| dw SYS_CODE64_SEL ; selector 15:0 | |
| db 0 ; 0 for interrupt gate | |
| db 0eh OR 80h ; type = 386 interrupt gate, present | |
| dw 0 ; offset 31:16 | |
| dd 0 ; offset 63:32 | |
| dd 0 ; 0 for reserved | |
| ; NMI (INT 2) | |
| NMI_SEL equ $-IDT_BASE | |
| dw 0 ; offset 15:0 | |
| dw SYS_CODE64_SEL ; selector 15:0 | |
| db 0 ; 0 for interrupt gate | |
| db 0eh OR 80h ; type = 386 interrupt gate, present | |
| dw 0 ; offset 31:16 | |
| dd 0 ; offset 63:32 | |
| dd 0 ; 0 for reserved | |
| ; soft breakpoint (INT 3) | |
| BREAKPOINT_SEL equ $-IDT_BASE | |
| dw 0 ; offset 15:0 | |
| dw SYS_CODE64_SEL ; selector 15:0 | |
| db 0 ; 0 for interrupt gate | |
| db 0eh OR 80h ; type = 386 interrupt gate, present | |
| dw 0 ; offset 31:16 | |
| dd 0 ; offset 63:32 | |
| dd 0 ; 0 for reserved | |
| ; overflow (INT 4) | |
| OVERFLOW_SEL equ $-IDT_BASE | |
| dw 0 ; offset 15:0 | |
| dw SYS_CODE64_SEL ; selector 15:0 | |
| db 0 ; 0 for interrupt gate | |
| db 0eh OR 80h ; type = 386 interrupt gate, present | |
| dw 0 ; offset 31:16 | |
| dd 0 ; offset 63:32 | |
| dd 0 ; 0 for reserved | |
| ; bounds check (INT 5) | |
| BOUNDS_CHECK_SEL equ $-IDT_BASE | |
| dw 0 ; offset 15:0 | |
| dw SYS_CODE64_SEL ; selector 15:0 | |
| db 0 ; 0 for interrupt gate | |
| db 0eh OR 80h ; type = 386 interrupt gate, present | |
| dw 0 ; offset 31:16 | |
| dd 0 ; offset 63:32 | |
| dd 0 ; 0 for reserved | |
| ; invalid opcode (INT 6) | |
| INVALID_OPCODE_SEL equ $-IDT_BASE | |
| dw 0 ; offset 15:0 | |
| dw SYS_CODE64_SEL ; selector 15:0 | |
| db 0 ; 0 for interrupt gate | |
| db 0eh OR 80h ; type = 386 interrupt gate, present | |
| dw 0 ; offset 31:16 | |
| dd 0 ; offset 63:32 | |
| dd 0 ; 0 for reserved | |
| ; device not available (INT 7) | |
| DEV_NOT_AVAIL_SEL equ $-IDT_BASE | |
| dw 0 ; offset 15:0 | |
| dw SYS_CODE64_SEL ; selector 15:0 | |
| db 0 ; 0 for interrupt gate | |
| db 0eh OR 80h ; type = 386 interrupt gate, present | |
| dw 0 ; offset 31:16 | |
| dd 0 ; offset 63:32 | |
| dd 0 ; 0 for reserved | |
| ; double fault (INT 8) | |
| DOUBLE_FAULT_SEL equ $-IDT_BASE | |
| dw 0 ; offset 15:0 | |
| dw SYS_CODE64_SEL ; selector 15:0 | |
| db 0 ; 0 for interrupt gate | |
| db 0eh OR 80h ; type = 386 interrupt gate, present | |
| dw 0 ; offset 31:16 | |
| dd 0 ; offset 63:32 | |
| dd 0 ; 0 for reserved | |
| ; Coprocessor segment overrun - reserved (INT 9) | |
| RSVD_INTR_SEL1 equ $-IDT_BASE | |
| dw 0 ; offset 15:0 | |
| dw SYS_CODE64_SEL ; selector 15:0 | |
| db 0 ; 0 for interrupt gate | |
| db 0eh OR 80h ; type = 386 interrupt gate, present | |
| dw 0 ; offset 31:16 | |
| dd 0 ; offset 63:32 | |
| dd 0 ; 0 for reserved | |
| ; invalid TSS (INT 0ah) | |
| INVALID_TSS_SEL equ $-IDT_BASE | |
| dw 0 ; offset 15:0 | |
| dw SYS_CODE64_SEL ; selector 15:0 | |
| db 0 ; 0 for interrupt gate | |
| db 0eh OR 80h ; type = 386 interrupt gate, present | |
| dw 0 ; offset 31:16 | |
| dd 0 ; offset 63:32 | |
| dd 0 ; 0 for reserved | |
| ; segment not present (INT 0bh) | |
| SEG_NOT_PRESENT_SEL equ $-IDT_BASE | |
| dw 0 ; offset 15:0 | |
| dw SYS_CODE64_SEL ; selector 15:0 | |
| db 0 ; 0 for interrupt gate | |
| db 0eh OR 80h ; type = 386 interrupt gate, present | |
| dw 0 ; offset 31:16 | |
| dd 0 ; offset 63:32 | |
| dd 0 ; 0 for reserved | |
| ; stack fault (INT 0ch) | |
| STACK_FAULT_SEL equ $-IDT_BASE | |
| dw 0 ; offset 15:0 | |
| dw SYS_CODE64_SEL ; selector 15:0 | |
| db 0 ; 0 for interrupt gate | |
| db 0eh OR 80h ; type = 386 interrupt gate, present | |
| dw 0 ; offset 31:16 | |
| dd 0 ; offset 63:32 | |
| dd 0 ; 0 for reserved | |
| ; general protection (INT 0dh) | |
| GP_FAULT_SEL equ $-IDT_BASE | |
| dw 0 ; offset 15:0 | |
| dw SYS_CODE64_SEL ; selector 15:0 | |
| db 0 ; 0 for interrupt gate | |
| db 0eh OR 80h ; type = 386 interrupt gate, present | |
| dw 0 ; offset 31:16 | |
| dd 0 ; offset 63:32 | |
| dd 0 ; 0 for reserved | |
| ; page fault (INT 0eh) | |
| PAGE_FAULT_SEL equ $-IDT_BASE | |
| dw 0 ; offset 15:0 | |
| dw SYS_CODE64_SEL ; selector 15:0 | |
| db 0 ; 0 for interrupt gate | |
| db 0eh OR 80h ; type = 386 interrupt gate, present | |
| dw 0 ; offset 31:16 | |
| dd 0 ; offset 63:32 | |
| dd 0 ; 0 for reserved | |
| ; Intel reserved - do not use (INT 0fh) | |
| RSVD_INTR_SEL2 equ $-IDT_BASE | |
| dw 0 ; offset 15:0 | |
| dw SYS_CODE64_SEL ; selector 15:0 | |
| db 0 ; 0 for interrupt gate | |
| db 0eh OR 80h ; type = 386 interrupt gate, present | |
| dw 0 ; offset 31:16 | |
| dd 0 ; offset 63:32 | |
| dd 0 ; 0 for reserved | |
| ; floating point error (INT 10h) | |
| FLT_POINT_ERR_SEL equ $-IDT_BASE | |
| dw 0 ; offset 15:0 | |
| dw SYS_CODE64_SEL ; selector 15:0 | |
| db 0 ; 0 for interrupt gate | |
| db 0eh OR 80h ; type = 386 interrupt gate, present | |
| dw 0 ; offset 31:16 | |
| dd 0 ; offset 63:32 | |
| dd 0 ; 0 for reserved | |
| ; alignment check (INT 11h) | |
| ALIGNMENT_CHECK_SEL equ $-IDT_BASE | |
| dw 0 ; offset 15:0 | |
| dw SYS_CODE64_SEL ; selector 15:0 | |
| db 0 ; 0 for interrupt gate | |
| db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present | |
| dw 0 ; offset 31:16 | |
| dd 0 ; offset 63:32 | |
| dd 0 ; 0 for reserved | |
| ; machine check (INT 12h) | |
| MACHINE_CHECK_SEL equ $-IDT_BASE | |
| dw 0 ; offset 15:0 | |
| dw SYS_CODE64_SEL ; selector 15:0 | |
| db 0 ; 0 for interrupt gate | |
| db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present | |
| dw 0 ; offset 31:16 | |
| dd 0 ; offset 63:32 | |
| dd 0 ; 0 for reserved | |
| ; SIMD floating-point exception (INT 13h) | |
| SIMD_EXCEPTION_SEL equ $-IDT_BASE | |
| dw 0 ; offset 15:0 | |
| dw SYS_CODE64_SEL ; selector 15:0 | |
| db 0 ; 0 for interrupt gate | |
| db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present | |
| dw 0 ; offset 31:16 | |
| dd 0 ; offset 63:32 | |
| dd 0 ; 0 for reserved | |
| REPEAT (32 - 20) | |
| dw 0 ; offset 15:0 | |
| dw SYS_CODE64_SEL ; selector 15:0 | |
| db 0 ; 0 for interrupt gate | |
| db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present | |
| dw 0 ; offset 31:16 | |
| dd 0 ; offset 63:32 | |
| dd 0 ; 0 for reserved | |
| ENDM | |
| ; 72 unspecified descriptors | |
| db (72 * 16) dup(0) | |
| ; IRQ 0 (System timer) - (INT 68h) | |
| IRQ0_SEL equ $-IDT_BASE | |
| dw 0 ; offset 15:0 | |
| dw SYS_CODE64_SEL ; selector 15:0 | |
| db 0 ; 0 for interrupt gate | |
| db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present | |
| dw 0 ; offset 31:16 | |
| dd 0 ; offset 63:32 | |
| dd 0 ; 0 for reserved | |
| ; IRQ 1 (8042 Keyboard controller) - (INT 69h) | |
| IRQ1_SEL equ $-IDT_BASE | |
| dw 0 ; offset 15:0 | |
| dw SYS_CODE64_SEL ; selector 15:0 | |
| db 0 ; 0 for interrupt gate | |
| db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present | |
| dw 0 ; offset 31:16 | |
| dd 0 ; offset 63:32 | |
| dd 0 ; 0 for reserved | |
| ; Reserved - IRQ 2 redirect (IRQ 2) - DO NOT USE!!! - (INT 6ah) | |
| IRQ2_SEL equ $-IDT_BASE | |
| dw 0 ; offset 15:0 | |
| dw SYS_CODE64_SEL ; selector 15:0 | |
| db 0 ; 0 for interrupt gate | |
| db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present | |
| dw 0 ; offset 31:16 | |
| dd 0 ; offset 63:32 | |
| dd 0 ; 0 for reserved | |
| ; IRQ 3 (COM 2) - (INT 6bh) | |
| IRQ3_SEL equ $-IDT_BASE | |
| dw 0 ; offset 15:0 | |
| dw SYS_CODE64_SEL ; selector 15:0 | |
| db 0 ; 0 for interrupt gate | |
| db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present | |
| dw 0 ; offset 31:16 | |
| dd 0 ; offset 63:32 | |
| dd 0 ; 0 for reserved | |
| ; IRQ 4 (COM 1) - (INT 6ch) | |
| IRQ4_SEL equ $-IDT_BASE | |
| dw 0 ; offset 15:0 | |
| dw SYS_CODE64_SEL ; selector 15:0 | |
| db 0 ; 0 for interrupt gate | |
| db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present | |
| dw 0 ; offset 31:16 | |
| dd 0 ; offset 63:32 | |
| dd 0 ; 0 for reserved | |
| ; IRQ 5 (LPT 2) - (INT 6dh) | |
| IRQ5_SEL equ $-IDT_BASE | |
| dw 0 ; offset 15:0 | |
| dw SYS_CODE64_SEL ; selector 15:0 | |
| db 0 ; 0 for interrupt gate | |
| db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present | |
| dw 0 ; offset 31:16 | |
| dd 0 ; offset 63:32 | |
| dd 0 ; 0 for reserved | |
| ; IRQ 6 (Floppy controller) - (INT 6eh) | |
| IRQ6_SEL equ $-IDT_BASE | |
| dw 0 ; offset 15:0 | |
| dw SYS_CODE64_SEL ; selector 15:0 | |
| db 0 ; 0 for interrupt gate | |
| db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present | |
| dw 0 ; offset 31:16 | |
| dd 0 ; offset 63:32 | |
| dd 0 ; 0 for reserved | |
| ; IRQ 7 (LPT 1) - (INT 6fh) | |
| IRQ7_SEL equ $-IDT_BASE | |
| dw 0 ; offset 15:0 | |
| dw SYS_CODE64_SEL ; selector 15:0 | |
| db 0 ; 0 for interrupt gate | |
| db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present | |
| dw 0 ; offset 31:16 | |
| dd 0 ; offset 63:32 | |
| dd 0 ; 0 for reserved | |
| ; IRQ 8 (RTC Alarm) - (INT 70h) | |
| IRQ8_SEL equ $-IDT_BASE | |
| dw 0 ; offset 15:0 | |
| dw SYS_CODE64_SEL ; selector 15:0 | |
| db 0 ; 0 for interrupt gate | |
| db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present | |
| dw 0 ; offset 31:16 | |
| dd 0 ; offset 63:32 | |
| dd 0 ; 0 for reserved | |
| ; IRQ 9 - (INT 71h) | |
| IRQ9_SEL equ $-IDT_BASE | |
| dw 0 ; offset 15:0 | |
| dw SYS_CODE64_SEL ; selector 15:0 | |
| db 0 ; 0 for interrupt gate | |
| db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present | |
| dw 0 ; offset 31:16 | |
| dd 0 ; offset 63:32 | |
| dd 0 ; 0 for reserved | |
| ; IRQ 10 - (INT 72h) | |
| IRQ10_SEL equ $-IDT_BASE | |
| dw 0 ; offset 15:0 | |
| dw SYS_CODE64_SEL ; selector 15:0 | |
| db 0 ; 0 for interrupt gate | |
| db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present | |
| dw 0 ; offset 31:16 | |
| dd 0 ; offset 63:32 | |
| dd 0 ; 0 for reserved | |
| ; IRQ 11 - (INT 73h) | |
| IRQ11_SEL equ $-IDT_BASE | |
| dw 0 ; offset 15:0 | |
| dw SYS_CODE64_SEL ; selector 15:0 | |
| db 0 ; 0 for interrupt gate | |
| db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present | |
| dw 0 ; offset 31:16 | |
| dd 0 ; offset 63:32 | |
| dd 0 ; 0 for reserved | |
| ; IRQ 12 (PS/2 mouse) - (INT 74h) | |
| IRQ12_SEL equ $-IDT_BASE | |
| dw 0 ; offset 15:0 | |
| dw SYS_CODE64_SEL ; selector 15:0 | |
| db 0 ; 0 for interrupt gate | |
| db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present | |
| dw 0 ; offset 31:16 | |
| dd 0 ; offset 63:32 | |
| dd 0 ; 0 for reserved | |
| ; IRQ 13 (Floating point error) - (INT 75h) | |
| IRQ13_SEL equ $-IDT_BASE | |
| dw 0 ; offset 15:0 | |
| dw SYS_CODE64_SEL ; selector 15:0 | |
| db 0 ; 0 for interrupt gate | |
| db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present | |
| dw 0 ; offset 31:16 | |
| dd 0 ; offset 63:32 | |
| dd 0 ; 0 for reserved | |
| ; IRQ 14 (Secondary IDE) - (INT 76h) | |
| IRQ14_SEL equ $-IDT_BASE | |
| dw 0 ; offset 15:0 | |
| dw SYS_CODE64_SEL ; selector 15:0 | |
| db 0 ; 0 for interrupt gate | |
| db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present | |
| dw 0 ; offset 31:16 | |
| dd 0 ; offset 63:32 | |
| dd 0 ; 0 for reserved | |
| ; IRQ 15 (Primary IDE) - (INT 77h) | |
| IRQ15_SEL equ $-IDT_BASE | |
| dw 0 ; offset 15:0 | |
| dw SYS_CODE64_SEL ; selector 15:0 | |
| db 0 ; 0 for interrupt gate | |
| db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present | |
| dw 0 ; offset 31:16 | |
| dd 0 ; offset 63:32 | |
| dd 0 ; 0 for reserved | |
| db (1 * 16) dup(0) | |
| IDT_END: | |
| align 02h | |
| END |