1 ;------------------------------------------------------------------------------
3 ;* Copyright 2006 - 2007, Intel Corporation
4 ;* All rights reserved. This program and the accompanying materials
5 ;* are licensed and made available under the terms and conditions of the BSD License
6 ;* which accompanies this distribution. The full text of the license may be found at
7 ;* http://opensource.org/licenses/bsd-license.php
9 ;* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 ;* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 ;------------------------------------------------------------------------------
23 FAT_DIRECTORY_ENTRY_SIZE EQU 020h
24 FAT_DIRECTORY_ENTRY_SHIFT EQU 5
31 jmp BootSectorEntryPoint ; JMP inst - 3 bytes
34 OemId db "INTEL " ; OemId - 8 bytes
35 SectorSize dw 0 ; Sector Size - 2 bytes
36 SectorsPerCluster db 0 ; Sector Per Cluster - 1 byte
37 ReservedSectors dw 0 ; Reserved Sectors - 2 bytes
38 NoFats db 0 ; Number of FATs - 1 byte
39 RootEntries dw 0 ; Root Entries - 2 bytes
40 Sectors dw 0 ; Number of Sectors - 2 bytes
41 Media db 0 ; Media - 1 byte
42 SectorsPerFat16 dw 0 ; Sectors Per FAT for FAT12/FAT16 - 2 byte
43 SectorsPerTrack dw 0 ; Sectors Per Track - 2 bytes
44 Heads dw 0 ; Heads - 2 bytes
45 HiddenSectors dd 0 ; Hidden Sectors - 4 bytes
46 LargeSectors dd 0 ; Large Sectors - 4 bytes
48 ;******************************************************************************
50 ;The structure for FAT32 starting at offset 36 of the boot sector. (At this point,
51 ;the BPB/boot sector for FAT12 and FAT16 differs from the BPB/boot sector for FAT32.)
53 ;******************************************************************************
55 SectorsPerFat32 dd 0 ; Sectors Per FAT for FAT32 - 4 bytes
56 ExtFlags dw 0 ; Mirror Flag - 2 bytes
57 FSVersion dw 0 ; File System Version - 2 bytes
58 RootCluster dd 0 ; 1st Cluster Number of Root Dir - 4 bytes
59 FSInfo dw 0 ; Sector Number of FSINFO - 2 bytes
60 BkBootSector dw 0 ; Sector Number of Bk BootSector - 2 bytes
61 Reserved db 12 dup(0) ; Reserved Field - 12 bytes
62 PhysicalDrive db 0 ; Physical Drive Number - 1 byte
63 Reserved1 db 0 ; Reserved Field - 1 byte
64 Signature db 0 ; Extended Boot Signature - 1 byte
65 VolId db " " ; Volume Serial Number - 4 bytes
66 FatLabel db " " ; Volume Label - 11 bytes
67 FileSystemType db "FAT32 " ; File System Type - 8 bytes
72 ; ds = 1000, es = 2000 + x (size of first cluster >> 4)
73 ; cx = Start Cluster of EfiLdr
74 ; dx = Start Cluster of Efivar.bin
76 ; Re use the BPB data stored in Boot Sector
82 ; 1000:dx = DirectoryEntry of Efivar.bin -> BS.com has filled already
91 ; Set the 5th byte start @ 0:19000 to non-zero indicating we should init var store header in DxeIpl
92 mov byte ptr es:[4],al
97 cmp dword ptr ds:[di+2], 04000h
103 mov byte ptr es:[4],al
113 mov ax,word ptr [bp+VolId]
114 mov word ptr es:[0],ax ; Save Volume Id to 0:19000. we will find the correct volume according to this VolumeId
115 mov ax,word ptr [bp+VolId+2]
116 mov word ptr es:[2],ax
120 ; cx = Start Cluster of Efildr -> BS.com has filled already
121 ; ES:DI = 2000:0, first cluster will be read again
127 mov word ptr cs:[JumpSegment],ax
139 jmp PrintStringAndHalt
151 ; ****************************************************************************
155 ; CX = Start Cluster of File
156 ; ES:DI = Buffer to store file content read from disk
159 ; (ES << 4 + DI) = end of file content Buffer
161 ; ****************************************************************************
163 ; si = NumberOfClusters
165 ; dx = CachedFatSectorNumber
166 ; ds:0000 = CacheFatSectorBuffer
167 ; es:di = Buffer to load file
168 ; bx = NextClusterNumber
170 mov si,1 ; NumberOfClusters = 1
171 push cx ; Push Start Cluster onto stack
172 mov dx,0fffh ; CachedFatSectorNumber = 0xfff
174 mov ax,cx ; ax = ClusterNumber
175 and ax,0fff8h ; ax = ax & 0xfff8
176 cmp ax,0fff8h ; See if this is the last cluster
177 je FoundLastCluster ; Jump if last cluster found
178 mov ax,cx ; ax = ClusterNumber
179 shl ax,2 ; FatOffset = ClusterNumber * 4
181 mov si,ax ; si = FatOffset
182 shr ax,BLOCK_SHIFT ; ax = FatOffset >> BLOCK_SHIFT
183 add ax,word ptr [bp+ReservedSectors] ; ax = FatSectorNumber = ReservedSectors + (FatOffset >> BLOCK_OFFSET)
184 and si,BLOCK_MASK ; si = FatOffset & BLOCK_MASK
185 cmp ax,dx ; Compare FatSectorNumber to CachedFatSectorNumber
191 call ReadBlocks ; Read 2 blocks starting at AX storing at ES:DI
193 mov dx,ax ; CachedFatSectorNumber = FatSectorNumber
195 mov bx,word ptr [si] ; bx = NextClusterNumber
196 mov ax,cx ; ax = ClusterNumber
198 dec bx ; bx = NextClusterNumber - 1
199 cmp bx,cx ; See if (NextClusterNumber-1)==ClusterNumber
201 inc bx ; bx = NextClusterNumber
202 inc si ; NumberOfClusters++
203 mov cx,bx ; ClusterNumber = NextClusterNumber
207 pop ax ; ax = StartCluster
208 push bx ; StartCluster = NextClusterNumber
209 mov cx,bx ; ClusterNumber = NextClusterNumber
210 sub ax,2 ; ax = StartCluster - 2
212 mov bl,byte ptr [bp+SectorsPerCluster] ; bx = SectorsPerCluster
213 mul bx ; ax = (StartCluster - 2) * SectorsPerCluster
214 add ax, word ptr [bp] ; ax = FirstClusterLBA + (StartCluster-2)*SectorsPerCluster
215 push ax ; save start sector
216 mov ax,si ; ax = NumberOfClusters
217 mul bx ; ax = NumberOfClusters * SectorsPerCluster
218 mov bx,ax ; bx = Number of Sectors
219 pop ax ; ax = Start Sector
221 mov si,1 ; NumberOfClusters = 1
229 ; ****************************************************************************
230 ; ReadBlocks - Reads a set of blocks from a block device
233 ; BX = Number of Blocks to Read
234 ; ES:DI = Buffer to store sectors read from disk
235 ; ****************************************************************************
238 ; bx = NumberOfBlocks
243 add eax,dword ptr [bp+LBAOffsetForBootSector] ; Add LBAOffsetForBootSector to Start LBA
244 add eax,dword ptr [bp+HiddenSectors] ; Add HiddenSectors to Start LBA
245 mov esi,eax ; esi = Start LBA
246 mov cx,bx ; cx = Number of blocks to read
248 mov bp,07bfch ; bp = 0x7bfc
249 mov eax,esi ; eax = Start LBA
250 xor edx,edx ; edx = 0
251 movzx ebx,word ptr [bp] ; bx = MaxSector
252 div ebx ; ax = StartLBA / MaxSector
253 inc dx ; dx = (StartLBA % MaxSector) + 1
255 mov bx,word ptr [bp] ; bx = MaxSector
256 sub bx,dx ; bx = MaxSector - Sector
257 inc bx ; bx = MaxSector - Sector + 1
258 cmp cx,bx ; Compare (Blocks) to (MaxSector - Sector + 1)
260 mov bx,cx ; bx = Blocks
264 shr ax,(BLOCK_SHIFT-4) ; ax = Number of blocks into mem system
265 and ax,07fh ; ax = Number of blocks into current seg
266 add ax,bx ; ax = End Block number of transfer
267 cmp ax,080h ; See if it crosses a 64K boundry
268 jle NotCrossing64KBoundry ; Branch if not crossing 64K boundry
269 sub ax,080h ; ax = Number of blocks past 64K boundry
270 sub bx,ax ; Decrease transfer size by block overage
271 NotCrossing64KBoundry:
275 mov cl,dl ; cl = (StartLBA % MaxSector) + 1 = Sector
277 div word ptr [bp+2] ; ax = ax / (MaxHead + 1) = Cylinder
278 ; dx = ax % (MaxHead + 1) = Head
280 push bx ; Save number of blocks to transfer
281 mov dh,dl ; dh = Head
282 mov bp,07c00h ; bp = 0x7c00
283 mov dl,byte ptr [bp+PhysicalDrive] ; dl = Drive Number
284 mov ch,al ; ch = Cylinder
285 mov al,bl ; al = Blocks
286 mov ah,2 ; ah = Function 2
287 mov bx,di ; es:bx = Buffer address
293 add esi,ebx ; StartLBA = StartLBA + NumberOfBlocks
294 sub cx,bx ; Blocks = Blocks - NumberOfBlocks
296 shl bx,(BLOCK_SHIFT-4)
298 mov es,ax ; es:di = es:di + NumberOfBlocks*BLOCK_SIZE
307 lea si, [ErrorString]
309 jmp PrintStringAndHalt
320 db 'S', 0ch, 'E', 0ch, 'r', 0ch, 'r', 0ch, 'o', 0ch, 'r', 0ch, '!', 0ch
323 LBAOffsetForBootSector:
329 ;******************************************************************************
330 ;******************************************************************************
331 ;******************************************************************************
333 DELAY_PORT equ 0edh ; Port to use for 1uS delay
334 KBD_CONTROL_PORT equ 060h ; 8042 control port
335 KBD_STATUS_PORT equ 064h ; 8042 status port
336 WRITE_DATA_PORT_CMD equ 0d1h ; 8042 command to write the data port
337 ENABLE_A20_CMD equ 0dfh ; 8042 command to enable A20
342 db 'E', 0ch, 'm', 0ch, '6', 0ch, '4', 0ch, 'T', 0ch, ' ', 0ch, 'U', 0ch, 'n', 0ch, 's', 0ch, 'u', 0ch, 'p', 0ch, 'p', 0ch, 'o', 0ch, 'r', 0ch, 't', 0ch, 'e', 0ch, 'd', 0ch, '!', 0ch
353 ; mov byte ptr es:[160],'a'
371 sub edi,eax ; Get the address of the memory map
372 mov dword ptr [MemoryMapSize],edi ; Save the size of the memory map
375 mov bx,cs ; BX=segment
376 shl ebx,4 ; BX="linear" address of segment base
377 lea eax,[GDT_BASE + ebx] ; EAX=PHYSICAL address of gdt
378 mov dword ptr [gdtr + 2],eax ; Put address of gdt into the gdtr
379 lea eax,[IDT_BASE + ebx] ; EAX=PHYSICAL address of idt
380 mov dword ptr [idtr + 2],eax ; Put address of idt into the idtr
381 lea edx,[MemoryMapSize + ebx] ; Physical base address of the memory map
385 ; mov byte ptr es:[162],'b'
393 mov ax,2401h ; Enable A20 Gate
395 jnc A20GateEnabled ; Jump if it suceeded
398 ; If INT 15 Function 2401 is not supported, then attempt to Enable A20 manually.
401 call Empty8042InputBuffer ; Empty the Input Buffer on the 8042 controller
402 jnz Timeout8042 ; Jump if the 8042 timed out
403 out DELAY_PORT,ax ; Delay 1 uS
404 mov al,WRITE_DATA_PORT_CMD ; 8042 cmd to write output port
405 out KBD_STATUS_PORT,al ; Send command to the 8042
406 call Empty8042InputBuffer ; Empty the Input Buffer on the 8042 controller
407 jnz Timeout8042 ; Jump if the 8042 timed out
408 mov al,ENABLE_A20_CMD ; gate address bit 20 on
409 out KBD_CONTROL_PORT,al ; Send command to thre 8042
410 call Empty8042InputBuffer ; Empty the Input Buffer on the 8042 controller
411 mov cx,25 ; Delay 25 uS for the command to complete on the 8042
413 out DELAY_PORT,ax ; Delay 1 uS
421 ; DISABLE INTERRUPTS - Entering Protected Mode
428 ; mov byte ptr es:[164],'c'
432 lea eax, OffsetIn32BitProtectedMode
434 mov dword ptr[OffsetIn32BitProtectedMode], eax
436 lea eax, OffsetInLongMode
438 mov dword ptr[OffsetInLongMode], eax
444 lgdt fword ptr [gdtr]
447 ; Enable Protect Mode (set CR0.PE=1)
449 mov eax, cr0 ; Read CR0.
450 or eax, 1h ; Set PE=1
451 mov cr0, eax ; Write CR0.
453 db 0eah ; jmp far 16:32
454 OffsetIn32BitProtectedMode:
455 dd 00000000h ; offset $+8 (In32BitProtectedMode)
456 dw 10h ; selector (flat CS)
457 In32BitProtectedMode:
469 ; Enable the 64-bit page-translation-table entries by
470 ; setting CR4.PAE=1 (this is _required_ before activating
471 ; long mode). Paging is not enabled until after long mode
485 ; This is the Trapolean Page Tables that are guarenteed
489 ; 10000 ~ 12000 - efildr (loaded)
490 ; 20000 ~ 21000 - start64.com
491 ; 21000 ~ 22000 - efi64.com
492 ; 22000 ~ 90000 - efildr
493 ; 90000 ~ 96000 - 4G pagetable (will be reload later)
501 ; Enable long mode (set EFER.LME=1).
505 ; mov ecx, 0c0000080h ; EFER MSR number.
513 ; bts eax, 8 ; Set LME=1.
516 ; wrmsr ; Write EFER.
519 ; Enable paging to activate long mode (set CR0.PG=1)
521 mov eax, cr0 ; Read CR0.
526 ; bts eax, 31 ; Set PG=1.
527 mov cr0, eax ; Write CR0.
532 db 0eah ; Far Jump $+9:Selector to reload CS
534 dd 00000000 ; $+9 Offset is ensuing instruction boundary
535 dw 038h ; Selector is our code selector, 38h
550 ; mov ebp,000400000h ; Destination of EFILDR32
553 ; mov ebx,000070000h ; Length of copy
572 ; lidt fword ptr [rax]
585 Empty8042InputBuffer:
588 out DELAY_PORT,ax ; Delay 1us
589 in al,KBD_STATUS_PORT ; Read the 8042 Status Port
590 and al,02h ; Check the Input Buffer Full Flag
591 loopnz Empty8042Loop ; Loop until the input buffer is empty or a timout of 65536 uS
594 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
596 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
600 gdtr dw GDT_END - GDT_BASE - 1 ; GDT limit
601 dd 0 ; (GDT base gets set above)
602 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
603 ; global descriptor table (GDT)
604 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
611 NULL_SEL equ $-GDT_BASE ; Selector [0x0]
616 db 0 ; limit 19:16, flags
619 ; linear data segment descriptor
620 LINEAR_SEL equ $-GDT_BASE ; Selector [0x8]
621 dw 0FFFFh ; limit 0xFFFFF
624 db 092h ; present, ring 0, data, expand-up, writable
625 db 0CFh ; page-granular, 32-bit
628 ; linear code segment descriptor
629 LINEAR_CODE_SEL equ $-GDT_BASE ; Selector [0x10]
630 dw 0FFFFh ; limit 0xFFFFF
633 db 09Ah ; present, ring 0, data, expand-up, writable
634 db 0CFh ; page-granular, 32-bit
637 ; system data segment descriptor
638 SYS_DATA_SEL equ $-GDT_BASE ; Selector [0x18]
639 dw 0FFFFh ; limit 0xFFFFF
642 db 092h ; present, ring 0, data, expand-up, writable
643 db 0CFh ; page-granular, 32-bit
646 ; system code segment descriptor
647 SYS_CODE_SEL equ $-GDT_BASE ; Selector [0x20]
648 dw 0FFFFh ; limit 0xFFFFF
651 db 09Ah ; present, ring 0, data, expand-up, writable
652 db 0CFh ; page-granular, 32-bit
655 ; spare segment descriptor
656 SPARE3_SEL equ $-GDT_BASE ; Selector [0x28]
660 db 0 ; present, ring 0, data, expand-up, writable
661 db 0 ; page-granular, 32-bit
665 ; system data segment descriptor
667 SYS_DATA64_SEL equ $-GDT_BASE ; Selector [0x30]
668 dw 0FFFFh ; limit 0xFFFFF
671 db 092h ; P | DPL [1..2] | 1 | 1 | C | R | A
672 db 0CFh ; G | D | L | AVL | Segment [19..16]
676 ; system code segment descriptor
678 SYS_CODE64_SEL equ $-GDT_BASE ; Selector [0x38]
679 dw 0FFFFh ; limit 0xFFFFF
682 db 09Ah ; P | DPL [1..2] | 1 | 1 | C | R | A
683 db 0AFh ; G | D | L | AVL | Segment [19..16]
686 ; spare segment descriptor
687 SPARE4_SEL equ $-GDT_BASE ; Selector [0x40]
691 db 0 ; present, ring 0, data, expand-up, writable
692 db 0 ; page-granular, 32-bit
701 idtr dw IDT_END - IDT_BASE - 1 ; IDT limit
702 dq 0 ; (IDT base gets set above)
704 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
705 ; interrupt descriptor table (IDT)
707 ; Note: The hardware IRQ's specified in this table are the normal PC/AT IRQ
708 ; mappings. This implementation only uses the system timer and all other
709 ; IRQs will remain masked. The descriptors for vectors 33+ are provided
711 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
718 ; divide by zero (INT 0)
719 DIV_ZERO_SEL equ $-IDT_BASE
721 dw SYS_CODE64_SEL ; selector 15:0
722 db 0 ; 0 for interrupt gate
723 db 0eh OR 80h ; type = 386 interrupt gate, present
726 dd 0 ; 0 for reserved
728 ; debug exception (INT 1)
729 DEBUG_EXCEPT_SEL equ $-IDT_BASE
731 dw SYS_CODE64_SEL ; selector 15:0
732 db 0 ; 0 for interrupt gate
733 db 0eh OR 80h ; type = 386 interrupt gate, present
736 dd 0 ; 0 for reserved
739 NMI_SEL equ $-IDT_BASE
741 dw SYS_CODE64_SEL ; selector 15:0
742 db 0 ; 0 for interrupt gate
743 db 0eh OR 80h ; type = 386 interrupt gate, present
746 dd 0 ; 0 for reserved
748 ; soft breakpoint (INT 3)
749 BREAKPOINT_SEL equ $-IDT_BASE
751 dw SYS_CODE64_SEL ; selector 15:0
752 db 0 ; 0 for interrupt gate
753 db 0eh OR 80h ; type = 386 interrupt gate, present
756 dd 0 ; 0 for reserved
759 OVERFLOW_SEL equ $-IDT_BASE
761 dw SYS_CODE64_SEL ; selector 15:0
762 db 0 ; 0 for interrupt gate
763 db 0eh OR 80h ; type = 386 interrupt gate, present
766 dd 0 ; 0 for reserved
768 ; bounds check (INT 5)
769 BOUNDS_CHECK_SEL equ $-IDT_BASE
771 dw SYS_CODE64_SEL ; selector 15:0
772 db 0 ; 0 for interrupt gate
773 db 0eh OR 80h ; type = 386 interrupt gate, present
776 dd 0 ; 0 for reserved
778 ; invalid opcode (INT 6)
779 INVALID_OPCODE_SEL equ $-IDT_BASE
781 dw SYS_CODE64_SEL ; selector 15:0
782 db 0 ; 0 for interrupt gate
783 db 0eh OR 80h ; type = 386 interrupt gate, present
786 dd 0 ; 0 for reserved
788 ; device not available (INT 7)
789 DEV_NOT_AVAIL_SEL equ $-IDT_BASE
791 dw SYS_CODE64_SEL ; selector 15:0
792 db 0 ; 0 for interrupt gate
793 db 0eh OR 80h ; type = 386 interrupt gate, present
796 dd 0 ; 0 for reserved
798 ; double fault (INT 8)
799 DOUBLE_FAULT_SEL equ $-IDT_BASE
801 dw SYS_CODE64_SEL ; selector 15:0
802 db 0 ; 0 for interrupt gate
803 db 0eh OR 80h ; type = 386 interrupt gate, present
806 dd 0 ; 0 for reserved
808 ; Coprocessor segment overrun - reserved (INT 9)
809 RSVD_INTR_SEL1 equ $-IDT_BASE
811 dw SYS_CODE64_SEL ; selector 15:0
812 db 0 ; 0 for interrupt gate
813 db 0eh OR 80h ; type = 386 interrupt gate, present
816 dd 0 ; 0 for reserved
818 ; invalid TSS (INT 0ah)
819 INVALID_TSS_SEL equ $-IDT_BASE
821 dw SYS_CODE64_SEL ; selector 15:0
822 db 0 ; 0 for interrupt gate
823 db 0eh OR 80h ; type = 386 interrupt gate, present
826 dd 0 ; 0 for reserved
828 ; segment not present (INT 0bh)
829 SEG_NOT_PRESENT_SEL equ $-IDT_BASE
831 dw SYS_CODE64_SEL ; selector 15:0
832 db 0 ; 0 for interrupt gate
833 db 0eh OR 80h ; type = 386 interrupt gate, present
836 dd 0 ; 0 for reserved
838 ; stack fault (INT 0ch)
839 STACK_FAULT_SEL equ $-IDT_BASE
841 dw SYS_CODE64_SEL ; selector 15:0
842 db 0 ; 0 for interrupt gate
843 db 0eh OR 80h ; type = 386 interrupt gate, present
846 dd 0 ; 0 for reserved
848 ; general protection (INT 0dh)
849 GP_FAULT_SEL equ $-IDT_BASE
851 dw SYS_CODE64_SEL ; selector 15:0
852 db 0 ; 0 for interrupt gate
853 db 0eh OR 80h ; type = 386 interrupt gate, present
856 dd 0 ; 0 for reserved
858 ; page fault (INT 0eh)
859 PAGE_FAULT_SEL equ $-IDT_BASE
861 dw SYS_CODE64_SEL ; selector 15:0
862 db 0 ; 0 for interrupt gate
863 db 0eh OR 80h ; type = 386 interrupt gate, present
866 dd 0 ; 0 for reserved
868 ; Intel reserved - do not use (INT 0fh)
869 RSVD_INTR_SEL2 equ $-IDT_BASE
871 dw SYS_CODE64_SEL ; selector 15:0
872 db 0 ; 0 for interrupt gate
873 db 0eh OR 80h ; type = 386 interrupt gate, present
876 dd 0 ; 0 for reserved
878 ; floating point error (INT 10h)
879 FLT_POINT_ERR_SEL equ $-IDT_BASE
881 dw SYS_CODE64_SEL ; selector 15:0
882 db 0 ; 0 for interrupt gate
883 db 0eh OR 80h ; type = 386 interrupt gate, present
886 dd 0 ; 0 for reserved
888 ; alignment check (INT 11h)
889 ALIGNMENT_CHECK_SEL equ $-IDT_BASE
891 dw SYS_CODE64_SEL ; selector 15:0
892 db 0 ; 0 for interrupt gate
893 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
896 dd 0 ; 0 for reserved
898 ; machine check (INT 12h)
899 MACHINE_CHECK_SEL equ $-IDT_BASE
901 dw SYS_CODE64_SEL ; selector 15:0
902 db 0 ; 0 for interrupt gate
903 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
906 dd 0 ; 0 for reserved
908 ; SIMD floating-point exception (INT 13h)
909 SIMD_EXCEPTION_SEL equ $-IDT_BASE
911 dw SYS_CODE64_SEL ; selector 15:0
912 db 0 ; 0 for interrupt gate
913 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
916 dd 0 ; 0 for reserved
918 ; 85 unspecified descriptors, First 12 of them are reserved, the rest are avail
921 ; IRQ 0 (System timer) - (INT 68h)
922 IRQ0_SEL equ $-IDT_BASE
924 dw SYS_CODE64_SEL ; selector 15:0
925 db 0 ; 0 for interrupt gate
926 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
929 dd 0 ; 0 for reserved
931 ; IRQ 1 (8042 Keyboard controller) - (INT 69h)
932 IRQ1_SEL equ $-IDT_BASE
934 dw SYS_CODE64_SEL ; selector 15:0
935 db 0 ; 0 for interrupt gate
936 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
939 dd 0 ; 0 for reserved
941 ; Reserved - IRQ 2 redirect (IRQ 2) - DO NOT USE!!! - (INT 6ah)
942 IRQ2_SEL equ $-IDT_BASE
944 dw SYS_CODE64_SEL ; selector 15:0
945 db 0 ; 0 for interrupt gate
946 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
949 dd 0 ; 0 for reserved
951 ; IRQ 3 (COM 2) - (INT 6bh)
952 IRQ3_SEL equ $-IDT_BASE
954 dw SYS_CODE64_SEL ; selector 15:0
955 db 0 ; 0 for interrupt gate
956 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
959 dd 0 ; 0 for reserved
961 ; IRQ 4 (COM 1) - (INT 6ch)
962 IRQ4_SEL equ $-IDT_BASE
964 dw SYS_CODE64_SEL ; selector 15:0
965 db 0 ; 0 for interrupt gate
966 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
969 dd 0 ; 0 for reserved
971 ; IRQ 5 (LPT 2) - (INT 6dh)
972 IRQ5_SEL equ $-IDT_BASE
974 dw SYS_CODE64_SEL ; selector 15:0
975 db 0 ; 0 for interrupt gate
976 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
979 dd 0 ; 0 for reserved
981 ; IRQ 6 (Floppy controller) - (INT 6eh)
982 IRQ6_SEL equ $-IDT_BASE
984 dw SYS_CODE64_SEL ; selector 15:0
985 db 0 ; 0 for interrupt gate
986 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
989 dd 0 ; 0 for reserved
991 ; IRQ 7 (LPT 1) - (INT 6fh)
992 IRQ7_SEL equ $-IDT_BASE
994 dw SYS_CODE64_SEL ; selector 15:0
995 db 0 ; 0 for interrupt gate
996 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
999 dd 0 ; 0 for reserved
1001 ; IRQ 8 (RTC Alarm) - (INT 70h)
1002 IRQ8_SEL equ $-IDT_BASE
1004 dw SYS_CODE64_SEL ; selector 15:0
1005 db 0 ; 0 for interrupt gate
1006 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
1009 dd 0 ; 0 for reserved
1012 IRQ9_SEL equ $-IDT_BASE
1014 dw SYS_CODE64_SEL ; selector 15:0
1015 db 0 ; 0 for interrupt gate
1016 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
1019 dd 0 ; 0 for reserved
1021 ; IRQ 10 - (INT 72h)
1022 IRQ10_SEL equ $-IDT_BASE
1024 dw SYS_CODE64_SEL ; selector 15:0
1025 db 0 ; 0 for interrupt gate
1026 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
1029 dd 0 ; 0 for reserved
1031 ; IRQ 11 - (INT 73h)
1032 IRQ11_SEL equ $-IDT_BASE
1034 dw SYS_CODE64_SEL ; selector 15:0
1035 db 0 ; 0 for interrupt gate
1036 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
1039 dd 0 ; 0 for reserved
1041 ; IRQ 12 (PS/2 mouse) - (INT 74h)
1042 IRQ12_SEL equ $-IDT_BASE
1044 dw SYS_CODE64_SEL ; selector 15:0
1045 db 0 ; 0 for interrupt gate
1046 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
1049 dd 0 ; 0 for reserved
1051 ; IRQ 13 (Floating point error) - (INT 75h)
1052 IRQ13_SEL equ $-IDT_BASE
1054 dw SYS_CODE64_SEL ; selector 15:0
1055 db 0 ; 0 for interrupt gate
1056 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
1059 dd 0 ; 0 for reserved
1061 ; IRQ 14 (Secondary IDE) - (INT 76h)
1062 IRQ14_SEL equ $-IDT_BASE
1064 dw SYS_CODE64_SEL ; selector 15:0
1065 db 0 ; 0 for interrupt gate
1066 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
1069 dd 0 ; 0 for reserved
1071 ; IRQ 15 (Primary IDE) - (INT 77h)
1072 IRQ15_SEL equ $-IDT_BASE
1074 dw SYS_CODE64_SEL ; selector 15:0
1075 db 0 ; 0 for interrupt gate
1076 db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
1079 dd 0 ; 0 for reserved
1086 MemoryMap dd 0,0,0,0,0,0,0,0
1117 dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1118 dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1122 ; below is the pieces of the IVT that is used to redirect INT 68h - 6fh
1123 ; back to INT 08h - 0fh when in real mode... It is 'org'ed to a
1124 ; known low address (20f00) so it can be set up by PlMapIrqToVect in