+/** @file\r
+ *\r
+ * Copyright 2006, Intel Corporation \r
+ * All rights reserved. This program and the accompanying materials \r
+ * are licensed and made available under the terms and conditions of the BSD License \r
+ * which accompanies this distribution. The full text of the license may be found at \r
+ * http://opensource.org/licenses/bsd-license.php \r
+ * \r
+ * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+ * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+ * \r
+ * CpuInterrupt.S\r
+ * \r
+ * Abstract:\r
+ *\r
+ **/\r
+\r
+.globl ASM_PFX(SystemTimerHandler)\r
+.globl ASM_PFX(SystemExceptionHandler)\r
+.globl ASM_PFX(mExceptionCodeSize)\r
+.globl ASM_PFX(InitDescriptor)\r
+.globl ASM_PFX(InstallInterruptHandler)\r
+\r
+ASM_PFX(mExceptionCodeSize): .long 9\r
+\r
+/**\r
+ * VOID\r
+ * InitDescriptor (\r
+ * VOID\r
+ * )\r
+ **/\r
+ASM_PFX(InitDescriptor):\r
+ lgdt gdtr\r
+ lidt idtr\r
+ ret\r
+\r
+/**\r
+ * VOID\r
+ * InstallInterruptHandler (\r
+ * UINTN Vector,\r
+ * VOID (*Handler)(VOID)\r
+ * )\r
+ **/\r
+ASM_PFX(InstallInterruptHandler):\r
+ movl %esp, %ebp\r
+ pushl %edi\r
+ pushfl # save eflags\r
+ cli # turn off interrupts\r
+ subl $6, %esp # open some space on the stack\r
+ movl %esp, %edi\r
+ sidt %es:(%edi) # get fword address of IDT\r
+ movl %es:2(%edi), %edi # move offset of IDT into EDI\r
+ addl $6, %esp # correct stack\r
+ mov 4(%ebp), %eax # Get vector number\r
+ shll $3, %eax # multiply by 8 to get offset\r
+ addl %eax, %edi # add to IDT base to get entry\r
+ movl 8(%ebp), %eax # load new address into IDT entry\r
+ movw %ax, %es:(%edi) # write bits 15..0 of offset\r
+ shrl $16, %eax # use ax to copy 31..16 to descriptors\r
+ movw %ax, %es:6(%edi) # write bits 31..16 of offset\r
+ popfl # restore flags (possible enabling interrupts)\r
+ pop %edi\r
+ ret\r
+\r
+.macro JmpCommonIdtEntry errno, vector\r
+ /* jmp commonIdtEntry - this must be hand coded to keep the assembler from\r
+ * using a 8 bit reletive jump when the entries are\r
+ * within 255 bytes of the common entry. This must\r
+ * be done to maintain the consistency of the size\r
+ * of entry points...\r
+ */\r
+ pushl \errno\r
+ pushl \vector\r
+ #.byte 0e9h # jmp 16 bit reletive \r
+ #.long commonIdtEntry - $ - $4 # offset to jump to\r
+ jmpl *commonIdtEntry\r
+.endm\r
+\r
+.align 0x02\r
+ASM_PFX(SystemExceptionHandler):\r
+INT0:\r
+ JmpCommonIdtEntry errno=0,vector=0\r
+INT1:\r
+ JmpCommonIdtEntry errno=0,vector=1\r
+INT2:\r
+ JmpCommonIdtEntry errno=0,vector=2\r
+INT3:\r
+ JmpCommonIdtEntry errno=0,vector=3\r
+INT4:\r
+ JmpCommonIdtEntry errno=0,vector=4\r
+INT5:\r
+ JmpCommonIdtEntry errno=0,vector=5\r
+INT6:\r
+ JmpCommonIdtEntry errno=0,vector=6\r
+INT7:\r
+ JmpCommonIdtEntry errno=0,vector=7\r
+INT8:\r
+# Double fault causes an error code to be pushed so no phony pushl necessary\r
+ nop\r
+ nop\r
+ pushl $8\r
+ jmpl *commonIdtEntry\r
+INT9:\r
+ JmpCommonIdtEntry errno=0,vector=9\r
+INT10:\r
+# Invalid TSS causes an error code to be pushed so no phony pushl necessary\r
+ nop\r
+ nop\r
+ pushl $10\r
+ jmpl *commonIdtEntry\r
+INT11:\r
+# Segment Not Present causes an error code to be pushed so no phony pushl necessary\r
+ nop\r
+ nop\r
+ pushl $11\r
+ jmpl *commonIdtEntry \r
+INT12:\r
+# Stack fault causes an error code to be pushed so no phony pushl necessary\r
+ nop\r
+ nop\r
+ pushl $12\r
+ jmpl *commonIdtEntry\r
+INT13:\r
+# GP fault causes an error code to be pushed so no phony pushl necessary\r
+ nop\r
+ nop\r
+ pushl $13\r
+ jmpl *commonIdtEntry\r
+INT14:\r
+# Page fault causes an error code to be pushed so no phony pushl necessary\r
+ nop\r
+ nop\r
+ pushl $14\r
+ jmpl *commonIdtEntry\r
+INT15:\r
+ JmpCommonIdtEntry errno=0,vector=15\r
+INT16:\r
+ JmpCommonIdtEntry errno=0,vector=16\r
+INT17:\r
+# Alignment check causes an error code to be pushed so no phony pushl necessary\r
+ nop\r
+ nop\r
+ pushl $17\r
+ jmpl *commonIdtEntry\r
+INT18:\r
+ JmpCommonIdtEntry errno=0,vector=18\r
+INT19:\r
+ JmpCommonIdtEntry errno=0,vector=19\r
+INTUnknown:\r
+ JmpCommonIdtEntry errno=0,vector=20\r
+ JmpCommonIdtEntry errno=0,vector=21\r
+ JmpCommonIdtEntry errno=0,vector=22\r
+ JmpCommonIdtEntry errno=0,vector=23\r
+ JmpCommonIdtEntry errno=0,vector=24\r
+ JmpCommonIdtEntry errno=0,vector=25\r
+ JmpCommonIdtEntry errno=0,vector=26\r
+ JmpCommonIdtEntry errno=0,vector=27\r
+ JmpCommonIdtEntry errno=0,vector=28\r
+ JmpCommonIdtEntry errno=0,vector=29\r
+ JmpCommonIdtEntry errno=0,vector=30\r
+ JmpCommonIdtEntry errno=0,vector=31\r
+\r
+ASM_PFX(SystemTimerHandler):\r
+ JmpCommonIdtEntry errno=0,vector=ASM_PFX(mTimerVector)\r
+\r
+commonIdtEntry:\r
+# +---------------------+\r
+# + EFlags +\r
+# +---------------------+\r
+# + CS +\r
+# +---------------------+\r
+# + EIP +\r
+# +---------------------+\r
+# + Error Code +\r
+# +---------------------+\r
+# + Vector Number +\r
+# +---------------------+\r
+# + EBP +\r
+# +---------------------+ <-- EBP\r
+\r
+ cli\r
+ pushl %ebp\r
+ movl %esp, %ebp\r
+\r
+ #\r
+ # Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32\r
+ # is 16-byte aligned\r
+ #\r
+ andl $0xfffffff0, %esp\r
+ subl $12, %esp\r
+\r
+## UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax#\r
+ pushl %eax\r
+ pushl %ecx\r
+ pushl %edx\r
+ pushl %ebx\r
+ leal 24(%ebp), %ecx\r
+ pushl %ecx # ESP\r
+ pushl (%ebp) # EBP\r
+ pushl %esi\r
+ pushl %edi\r
+\r
+## UINT32 Gs, Fs, Es, Ds, Cs, Ss#\r
+ movl %ss, %eax\r
+ pushl %eax\r
+ movzwl 16(%ebp), %eax\r
+ pushl %eax\r
+ movl %ds, %eax\r
+ pushl %eax\r
+ movl %es, %eax\r
+ pushl %eax\r
+ movl %fs, %eax\r
+ pushl %eax\r
+ movl %gs, %eax\r
+ pushl %eax\r
+\r
+## UINT32 Eip#\r
+ pushl 12(%ebp)\r
+\r
+## UINT32 Gdtr[2], Idtr[2]#\r
+ subl $8, %esp\r
+ sidt (%esp)\r
+ subl $8, %esp\r
+ sgdt (%esp)\r
+\r
+## UINT32 Ldtr, Tr#\r
+ xorl %eax, %eax\r
+ strw %ax\r
+ pushl %eax\r
+ sldt %ax\r
+ pushl %eax\r
+\r
+## UINT32 EFlags#\r
+ pushl 5*4(%ebp)\r
+\r
+## UINT32 Cr0, Cr1, Cr2, Cr3, Cr4#\r
+ movl %cr4, %eax\r
+ orl $0x208, %eax\r
+ movl %eax, %cr4\r
+ pushl %eax\r
+ movl %cr3, %eax\r
+ pushl %eax\r
+ movl %cr2, %eax\r
+ pushl %eax\r
+ xorl %eax, %eax\r
+ pushl %eax\r
+ movl %cr0, %eax\r
+ pushl %eax\r
+\r
+## UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7#\r
+ movl %dr7, %eax\r
+ pushl %eax\r
+## clear Dr7 while executing debugger itself\r
+ xorl %eax, %eax\r
+ movl %eax, %dr7\r
+\r
+ movl %dr6, %eax\r
+ pushl %eax\r
+## insure all status bits in dr6 are clear...\r
+ xorl %eax, %eax\r
+ movl %eax, %dr6\r
+\r
+ movl %dr3, %eax\r
+ pushl %eax\r
+ movl %dr2, %eax\r
+ pushl %eax\r
+ movl %dr1, %eax\r
+ pushl %eax\r
+ movl %dr0, %eax\r
+ pushl %eax\r
+\r
+## FX_SAVE_STATE_IA32 FxSaveState#\r
+ subl $512, %esp\r
+ movl %esp, %edi\r
+ #.byte 0f, 0ae, 00000111y #fxsave [edi]\r
+ fxsave (%edi)\r
+ \r
+## UINT32 ExceptionData#\r
+ pushl 2*4(%ebp)\r
+\r
+## Prepare parameter and call\r
+ movl %esp, %edx\r
+ pushl %edx\r
+ movl 1*4(%ebp), %eax\r
+ pushl %eax\r
+ cmpl $32, %eax\r
+ jb CallException\r
+ call ASM_PFX(TimerHandler)\r
+ jmp ExceptionDone\r
+CallException:\r
+ call ASM_PFX(ExceptionHandler)\r
+ExceptionDone:\r
+ addl $8, %esp\r
+\r
+ cli\r
+## UINT32 ExceptionData#\r
+ addl $4, %esp\r
+\r
+## FX_SAVE_STATE_IA32 FxSaveState#\r
+ movl %esp, %esi\r
+ #db 0fh, 0aeh, 00001110y # fxrstor [esi]\r
+ fxrstor (%esi)\r
+ addl $512, %esp\r
+\r
+## UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7#\r
+ popl %eax\r
+ movl %eax, %dr0\r
+ popl %eax\r
+ movl %eax, %dr1\r
+ popl %eax\r
+ movl %eax, %dr2\r
+ popl %eax\r
+ movl %eax, %dr3\r
+## skip restore of dr6. We cleared dr6 during the context save.\r
+ addl $4, %esp\r
+ popl %eax\r
+ movl %eax, %dr7\r
+\r
+## UINT32 Cr0, Cr1, Cr2, Cr3, Cr4#\r
+ popl %eax\r
+ movl %eax, %cr0\r
+ addl $4, %esp # not for Cr1\r
+ popl %eax\r
+ movl %eax, %cr2\r
+ popl %eax\r
+ movl %eax, %cr3\r
+ popl %eax\r
+ movl %eax, %cr4\r
+\r
+## UINT32 EFlags#\r
+ popl 5*4(%ebp)\r
+\r
+## UINT32 Ldtr, Tr#\r
+## UINT32 Gdtr[2], Idtr[2]#\r
+## Best not let anyone mess with these particular registers...\r
+ addl $24, %esp\r
+\r
+## UINT32 Eip#\r
+ popl 3*4(%ebp)\r
+\r
+## UINT32 Gs, Fs, Es, Ds, Cs, Ss#\r
+## NOTE - modified segment registers could hang the debugger... We\r
+## could attempt to insulate ourselves against this possibility,\r
+## but that poses risks as well.\r
+##\r
+ popl %gs\r
+ popl %fs\r
+ popl %es\r
+ popl %ds\r
+ popl 4*4(%ebp)\r
+ popl %ss\r
+\r
+## UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax#\r
+ popl %edi\r
+ popl %esi\r
+ addl $4, %esp # not for ebp\r
+ addl $4, %esp # not for esp\r
+ popl %ebx\r
+ popl %edx\r
+ popl %ecx\r
+ popl %eax\r
+\r
+ movl %ebp, %esp\r
+ popl %ebp\r
+ addl $8, %esp\r
+ iretl\r
+\r
+\r
+##############################################################################\r
+# data\r
+##############################################################################\r
+\r
+.align 2, 0x0\r
+gdtr:\r
+ .word 8*8 - 1\r
+ .long GDT_BASE\r
+ \r
+##############################################################################\r
+# global descriptor table (GDT)\r
+##############################################################################\r
+\r
+\r
+.align 2, 0x90\r
+GDT_BASE:\r
+ .quad 0x0 // null descriptor\r
+ .quad 0x00cf92000000ffff // linear data segment descriptor\r
+ .quad 0x00cf9a000000ffff // linear code segment descriptor\r
+ .quad 0x00cf92000000ffff // system data segment descriptor\r
+ .quad 0x00cf9a000000ffff // system code segment descriptor\r
+ .quad 0x0 // spare segment descriptor\r
+ .quad 0x0\r
+ .quad 0x0\r
+\r
+.align 0x02\r
+\r
+idtr:\r
+ .word IDT_END - IDT_BASE - 1 # IDT limit\r
+ .long IDT_BASE\r
+ \r
+##############################################################################\r
+# interrupt descriptor table (IDT)\r
+#\r
+# Note: The hardware IRQ's specified in this table are the normal PC/AT IRQ\r
+# mappings. This implementation only uses the system timer and all other\r
+# IRQs will remain masked. The descriptors for vectors 33+ are provided\r
+# for convenience.\r
+##############################################################################\r
+\r
+.align 0x02\r
+\r
+IDT_BASE:\r
+ .skip 256 * 16\r
+\r
+/**\r
+# divide by zero (INT 0)\r
+DIV_ZERO_SEL equ $-IDT_BASE\r
+ dw 0 # offset 15:0\r
+ dw SYS_CODE_SEL # selector 15:0\r
+ db 0 # 0 for interrupt gate\r
+ db 0eh OR 80h # type = 386 interrupt gate, present\r
+ dw 0 # offset 31:16\r
+\r
+# debug exception (INT 1)\r
+DEBUG_EXCEPT_SEL equ $-IDT_BASE\r
+ dw 0 # offset 15:0\r
+ dw SYS_CODE_SEL # selector 15:0\r
+ db 0 # 0 for interrupt gate\r
+ db 0eh OR 80h # type = 386 interrupt gate, present\r
+ dw 0 # offset 31:16\r
+\r
+# NMI (INT 2)\r
+NMI_SEL equ $-IDT_BASE\r
+ dw 0 # offset 15:0\r
+ dw SYS_CODE_SEL # selector 15:0\r
+ db 0 # 0 for interrupt gate\r
+ db 0eh OR 80h # type = 386 interrupt gate, present\r
+ dw 0 # offset 31:16\r
+\r
+# soft breakpoint (INT 3)\r
+BREAKPOINT_SEL equ $-IDT_BASE\r
+ dw 0 # offset 15:0\r
+ dw SYS_CODE_SEL # selector 15:0\r
+ db 0 # 0 for interrupt gate\r
+ db 0eh OR 80h # type = 386 interrupt gate, present\r
+ dw 0 # offset 31:16\r
+\r
+# overflow (INT 4)\r
+OVERFLOW_SEL equ $-IDT_BASE\r
+ dw 0 # offset 15:0\r
+ dw SYS_CODE_SEL # selector 15:0\r
+ db 0 # 0 for interrupt gate\r
+ db 0eh OR 80h # type = 386 interrupt gate, present\r
+ dw 0 # offset 31:16\r
+\r
+# bounds check (INT 5)\r
+BOUNDS_CHECK_SEL equ $-IDT_BASE\r
+ dw 0 # offset 15:0\r
+ dw SYS_CODE_SEL # selector 15:0\r
+ db 0 # 0 for interrupt gate\r
+ db 0eh OR 80h # type = 386 interrupt gate, present\r
+ dw 0 # offset 31:16\r
+\r
+# invalid opcode (INT 6)\r
+INVALID_OPCODE_SEL equ $-IDT_BASE\r
+ dw 0 # offset 15:0\r
+ dw SYS_CODE_SEL # selector 15:0\r
+ db 0 # 0 for interrupt gate\r
+ db 0eh OR 80h # type = 386 interrupt gate, present\r
+ dw 0 # offset 31:16\r
+\r
+# device not available (INT 7)\r
+DEV_NOT_AVAIL_SEL equ $-IDT_BASE\r
+ dw 0 # offset 15:0\r
+ dw SYS_CODE_SEL # selector 15:0\r
+ db 0 # 0 for interrupt gate\r
+ db 0eh OR 80h # type = 386 interrupt gate, present\r
+ dw 0 # offset 31:16\r
+\r
+# double fault (INT 8)\r
+DOUBLE_FAULT_SEL equ $-IDT_BASE\r
+ dw 0 # offset 15:0\r
+ dw SYS_CODE_SEL # selector 15:0\r
+ db 0 # 0 for interrupt gate\r
+ db 0eh OR 80h # type = 386 interrupt gate, present\r
+ dw 0 # offset 31:16\r
+\r
+# Coprocessor segment overrun - reserved (INT 9)\r
+RSVD_INTR_SEL1 equ $-IDT_BASE\r
+ dw 0 # offset 15:0\r
+ dw SYS_CODE_SEL # selector 15:0\r
+ db 0 # 0 for interrupt gate\r
+ db 0eh OR 80h # type = 386 interrupt gate, present\r
+ dw 0 # offset 31:16\r
+\r
+# invalid TSS (INT 0ah)\r
+INVALID_TSS_SEL equ $-IDT_BASE\r
+ dw 0 # offset 15:0\r
+ dw SYS_CODE_SEL # selector 15:0\r
+ db 0 # 0 for interrupt gate\r
+ db 0eh OR 80h # type = 386 interrupt gate, present\r
+ dw 0 # offset 31:16\r
+\r
+# segment not present (INT 0bh)\r
+SEG_NOT_PRESENT_SEL equ $-IDT_BASE\r
+ dw 0 # offset 15:0\r
+ dw SYS_CODE_SEL # selector 15:0\r
+ db 0 # 0 for interrupt gate\r
+ db 0eh OR 80h # type = 386 interrupt gate, present\r
+ dw 0 # offset 31:16\r
+\r
+# stack fault (INT 0ch)\r
+STACK_FAULT_SEL equ $-IDT_BASE\r
+ dw 0 # offset 15:0\r
+ dw SYS_CODE_SEL # selector 15:0\r
+ db 0 # 0 for interrupt gate\r
+ db 0eh OR 80h # type = 386 interrupt gate, present\r
+ dw 0 # offset 31:16\r
+\r
+# general protection (INT 0dh)\r
+GP_FAULT_SEL equ $-IDT_BASE\r
+ dw 0 # offset 15:0\r
+ dw SYS_CODE_SEL # selector 15:0\r
+ db 0 # 0 for interrupt gate\r
+ db 0eh OR 80h # type = 386 interrupt gate, present\r
+ dw 0 # offset 31:16\r
+\r
+# page fault (INT 0eh)\r
+PAGE_FAULT_SEL equ $-IDT_BASE\r
+ dw 0 # offset 15:0\r
+ dw SYS_CODE_SEL # selector 15:0\r
+ db 0 # 0 for interrupt gate\r
+ db 0eh OR 80h # type = 386 interrupt gate, present\r
+ dw 0 # offset 31:16\r
+\r
+# Intel reserved - do not use (INT 0fh)\r
+RSVD_INTR_SEL2 equ $-IDT_BASE\r
+ dw 0 # offset 15:0\r
+ dw SYS_CODE_SEL # selector 15:0\r
+ db 0 # 0 for interrupt gate\r
+ db 0eh OR 80h # type = 386 interrupt gate, present\r
+ dw 0 # offset 31:16\r
+\r
+# floating point error (INT 10h)\r
+FLT_POINT_ERR_SEL equ $-IDT_BASE\r
+ dw 0 # offset 15:0\r
+ dw SYS_CODE_SEL # selector 15:0\r
+ db 0 # 0 for interrupt gate\r
+ db 0eh OR 80h # type = 386 interrupt gate, present\r
+ dw 0 # offset 31:16\r
+\r
+# alignment check (INT 11h)\r
+ALIGNMENT_CHECK_SEL equ $-IDT_BASE\r
+ dw 0 # offset 15:0\r
+ dw SYS_CODE_SEL # selector 15:0\r
+ db 0 # 0 for interrupt gate\r
+ db 0eh OR 80h # (10001110)type = 386 interrupt gate, present\r
+ dw 0 # offset 31:16\r
+\r
+# machine check (INT 12h)\r
+MACHINE_CHECK_SEL equ $-IDT_BASE\r
+ dw 0 # offset 15:0\r
+ dw SYS_CODE_SEL # selector 15:0\r
+ db 0 # 0 for interrupt gate\r
+ db 0eh OR 80h # (10001110)type = 386 interrupt gate, present\r
+ dw 0 # offset 31:16\r
+\r
+# SIMD floating-point exception (INT 13h)\r
+SIMD_EXCEPTION_SEL equ $-IDT_BASE\r
+ dw 0 # offset 15:0\r
+ dw SYS_CODE_SEL # selector 15:0\r
+ db 0 # 0 for interrupt gate\r
+ db 0eh OR 80h # (10001110)type = 386 interrupt gate, present\r
+ dw 0 # offset 31:16\r
+\r
+REPEAT (32 - 20)\r
+ dw 0 # offset 15:0\r
+ dw SYS_CODE_SEL # selector 15:0\r
+ db 0 # 0 for interrupt gate\r
+ db 0eh OR 80h # (10001110)type = 386 interrupt gate, present\r
+ dw 0 # offset 31:16\r
+ENDM\r
+\r
+# 72 unspecified descriptors\r
+ db (72 * 8) dup(0)\r
+ \r
+# IRQ 0 (System timer) - (INT 68h)\r
+IRQ0_SEL equ $-IDT_BASE\r
+ dw 0 # offset 15:0\r
+ dw SYS_CODE_SEL # selector 15:0\r
+ db 0 # 0 for interrupt gate\r
+ db 0eh OR 80h # (10001110)type = 386 interrupt gate, present\r
+ dw 0 # offset 31:16\r
+\r
+# IRQ 1 (8042 Keyboard controller) - (INT 69h)\r
+IRQ1_SEL equ $-IDT_BASE\r
+ dw 0 # offset 15:0\r
+ dw SYS_CODE_SEL # selector 15:0\r
+ db 0 # 0 for interrupt gate\r
+ db 0eh OR 80h # (10001110)type = 386 interrupt gate, present\r
+ dw 0 # offset 31:16\r
+\r
+# Reserved - IRQ 2 redirect (IRQ 2) - DO NOT USE!!! - (INT 6ah)\r
+IRQ2_SEL equ $-IDT_BASE\r
+ dw 0 # offset 15:0\r
+ dw SYS_CODE_SEL # selector 15:0\r
+ db 0 # 0 for interrupt gate\r
+ db 0eh OR 80h # (10001110)type = 386 interrupt gate, present\r
+ dw 0 # offset 31:16\r
+\r
+# IRQ 3 (COM 2) - (INT 6bh)\r
+IRQ3_SEL equ $-IDT_BASE\r
+ dw 0 # offset 15:0\r
+ dw SYS_CODE_SEL # selector 15:0\r
+ db 0 # 0 for interrupt gate\r
+ db 0eh OR 80h # (10001110)type = 386 interrupt gate, present\r
+ dw 0 # offset 31:16\r
+\r
+# IRQ 4 (COM 1) - (INT 6ch)\r
+IRQ4_SEL equ $-IDT_BASE\r
+ dw 0 # offset 15:0\r
+ dw SYS_CODE_SEL # selector 15:0\r
+ db 0 # 0 for interrupt gate\r
+ db 0eh OR 80h # (10001110)type = 386 interrupt gate, present\r
+ dw 0 # offset 31:16\r
+\r
+# IRQ 5 (LPT 2) - (INT 6dh)\r
+IRQ5_SEL equ $-IDT_BASE\r
+ dw 0 # offset 15:0\r
+ dw SYS_CODE_SEL # selector 15:0\r
+ db 0 # 0 for interrupt gate\r
+ db 0eh OR 80h # (10001110)type = 386 interrupt gate, present\r
+ dw 0 # offset 31:16\r
+\r
+# IRQ 6 (Floppy controller) - (INT 6eh)\r
+IRQ6_SEL equ $-IDT_BASE\r
+ dw 0 # offset 15:0\r
+ dw SYS_CODE_SEL # selector 15:0\r
+ db 0 # 0 for interrupt gate\r
+ db 0eh OR 80h # (10001110)type = 386 interrupt gate, present\r
+ dw 0 # offset 31:16\r
+\r
+# IRQ 7 (LPT 1) - (INT 6fh)\r
+IRQ7_SEL equ $-IDT_BASE\r
+ dw 0 # offset 15:0\r
+ dw SYS_CODE_SEL # selector 15:0\r
+ db 0 # 0 for interrupt gate\r
+ db 0eh OR 80h # (10001110)type = 386 interrupt gate, present\r
+ dw 0 # offset 31:16\r
+\r
+# IRQ 8 (RTC Alarm) - (INT 70h)\r
+IRQ8_SEL equ $-IDT_BASE\r
+ dw 0 # offset 15:0\r
+ dw SYS_CODE_SEL # selector 15:0\r
+ db 0 # 0 for interrupt gate\r
+ db 0eh OR 80h # (10001110)type = 386 interrupt gate, present\r
+ dw 0 # offset 31:16\r
+\r
+# IRQ 9 - (INT 71h)\r
+IRQ9_SEL equ $-IDT_BASE\r
+ dw 0 # offset 15:0\r
+ dw SYS_CODE_SEL # selector 15:0\r
+ db 0 # 0 for interrupt gate\r
+ db 0eh OR 80h # (10001110)type = 386 interrupt gate, present\r
+ dw 0 # offset 31:16\r
+\r
+# IRQ 10 - (INT 72h)\r
+IRQ10_SEL equ $-IDT_BASE\r
+ dw 0 # offset 15:0\r
+ dw SYS_CODE_SEL # selector 15:0\r
+ db 0 # 0 for interrupt gate\r
+ db 0eh OR 80h # (10001110)type = 386 interrupt gate, present\r
+ dw 0 # offset 31:16\r
+\r
+# IRQ 11 - (INT 73h)\r
+IRQ11_SEL equ $-IDT_BASE\r
+ dw 0 # offset 15:0\r
+ dw SYS_CODE_SEL # selector 15:0\r
+ db 0 # 0 for interrupt gate\r
+ db 0eh OR 80h # (10001110)type = 386 interrupt gate, present\r
+ dw 0 # offset 31:16\r
+\r
+# IRQ 12 (PS/2 mouse) - (INT 74h)\r
+IRQ12_SEL equ $-IDT_BASE\r
+ dw 0 # offset 15:0\r
+ dw SYS_CODE_SEL # selector 15:0\r
+ db 0 # 0 for interrupt gate\r
+ db 0eh OR 80h # (10001110)type = 386 interrupt gate, present\r
+ dw 0 # offset 31:16\r
+\r
+# IRQ 13 (Floating point error) - (INT 75h)\r
+IRQ13_SEL equ $-IDT_BASE\r
+ dw 0 # offset 15:0\r
+ dw SYS_CODE_SEL # selector 15:0\r
+ db 0 # 0 for interrupt gate\r
+ db 0eh OR 80h # (10001110)type = 386 interrupt gate, present\r
+ dw 0 # offset 31:16\r
+\r
+# IRQ 14 (Secondary IDE) - (INT 76h)\r
+IRQ14_SEL equ $-IDT_BASE\r
+ dw 0 # offset 15:0\r
+ dw SYS_CODE_SEL # selector 15:0\r
+ db 0 # 0 for interrupt gate\r
+ db 0eh OR 80h # (10001110)type = 386 interrupt gate, present\r
+ dw 0 # offset 31:16\r
+\r
+# IRQ 15 (Primary IDE) - (INT 77h)\r
+IRQ15_SEL equ $-IDT_BASE\r
+ dw 0 # offset 15:0\r
+ dw SYS_CODE_SEL # selector 15:0\r
+ db 0 # 0 for interrupt gate\r
+ db 0eh OR 80h # (10001110)type = 386 interrupt gate, present\r
+ dw 0 # offset 31:16\r
+\r
+ db (1 * 8) dup(0)\r
+\r
+**/\r
+IDT_END:\r