1 #------------------------------------------------------------------------------
3 #* Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
4 #* 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 .equ FAT_DIRECTORY_ENTRY_SIZE, 0x020
24 .equ FAT_DIRECTORY_ENTRY_SHIFT, 5
25 .equ BLOCK_SIZE, 0x0200
26 .equ BLOCK_MASK, 0x01ff
35 jmp BootSectorEntryPoint # JMP inst - 3 bytes
38 OemId: .ascii "INTEL " # OemId - 8 bytes
39 SectorSize: .word 0 # Sector Size - 2 bytes
40 SectorsPerCluster: .byte 0 # Sector Per Cluster - 1 byte
41 ReservedSectors: .word 0 # Reserved Sectors - 2 bytes
42 NoFats: .byte 0 # Number of FATs - 1 byte
43 RootEntries: .word 0 # Root Entries - 2 bytes
44 Sectors: .word 0 # Number of Sectors - 2 bytes
45 Media: .byte 0 # Media - 1 byte
46 SectorsPerFat16: .word 0 # Sectors Per FAT for FAT12/FAT16 - 2 byte
47 SectorsPerTrack: .word 0 # Sectors Per Track - 2 bytes
48 Heads: .word 0 # Heads - 2 bytes
49 HiddenSectors: .long 0 # Hidden Sectors - 4 bytes
50 LargeSectors: .long 0 # Large Sectors - 4 bytes
52 #******************************************************************************
54 #The structure for FAT32 starting at offset 36 of the boot sector. (At this point,
55 #the BPB/boot sector for FAT12 and FAT16 differs from the BPB/boot sector for FAT32.)
57 #******************************************************************************
59 SectorsPerFat32: .long 0 # Sectors Per FAT for FAT32 - 4 bytes
60 ExtFlags: .word 0 # Mirror Flag - 2 bytes
61 FSVersion: .word 0 # File System Version - 2 bytes
62 RootCluster: .long 0 # 1st Cluster Number of Root Dir - 4 bytes
63 FSInfo: .word 0 # Sector Number of FSINFO - 2 bytes
64 BkBootSector: .word 0 # Sector Number of Bk BootSector - 2 bytes
65 Reserved: .fill 12,1,0 # Reserved Field - 12 bytes
66 PhysicalDrive: .byte 0 # Physical Drive Number - 1 byte
67 Reserved1: .byte 0 # Reserved Field - 1 byte
68 Signature: .byte 0 # Extended Boot Signature - 1 byte
69 VolId: .ascii " " # Volume Serial Number - 4 bytes
70 FatLabel: .ascii " " # Volume Label - 11 bytes
71 FileSystemType: .ascii "FAT32 " # File System Type - 8 bytes
77 # ds = 1000, es = 2000 + x (size of first cluster >> 4)
78 # cx = Start Cluster of EfiLdr
79 # dx = Start Cluster of Efivar.bin
81 # Re use the BPB data stored in Boot Sector
86 # 1000:dx = DirectoryEntry of Efivar.bin -> BS.com has filled already
95 # Set the 5th byte start @ 0:19000 to non-zero indicating we should init var store header in DxeIpl
101 cmpl $0x4000, %ds:2(%di)
118 movw %ax, %es:(0) # Save Volume Id to 0:19000. we will find the correct volume according to this VolumeId
119 movw VolId+2(%bp), %ax
124 # cx = Start Cluster of Efildr -> BS.com has filled already
125 # ES:DI = 2000:0, first cluster will be read again
126 xorw %di,%di # di = 0
131 movw %ax, %cs:JumpSegment
134 movl $0x80000001,%eax
143 jmp PrintStringAndHalt
154 # ****************************************************************************
158 # CX = Start Cluster of File
159 # ES:DI = Buffer to store file content read from disk
162 # (ES << 4 + DI) = end of file content Buffer
164 # ****************************************************************************
166 # si = NumberOfClusters
168 # dx = CachedFatSectorNumber
169 # ds:0000 = CacheFatSectorBuffer
170 # es:di = Buffer to load file
171 # bx = NextClusterNumber
173 movw $1,%si # NumberOfClusters = 1
174 pushw %cx # Push Start Cluster onto stack
175 movw $0xfff,%dx # CachedFatSectorNumber = 0xfff
177 movw %cx,%ax # ax = ClusterNumber
178 andw $0xfff8,%ax # ax = ax & 0xfff8
179 cmpw $0xfff8,%ax # See if this is the last cluster
180 je FoundLastCluster # Jump if last cluster found
181 movw %cx,%ax # ax = ClusterNumber
182 shlw $2, %ax # FatOffset = ClusterNumber * 2
184 movw %ax,%si # si = FatOffset
185 shrw $BLOCK_SHIFT, %ax # ax = FatOffset >> BLOCK_SHIFT
186 addw ReservedSectors(%bp), %ax # ax = FatSectorNumber = ReservedSectors + (FatOffset >> BLOCK_OFFSET)
187 andw $BLOCK_MASK, %si # si = FatOffset & BLOCK_MASK
188 cmpw %dx,%ax # Compare FatSectorNumber to CachedFatSectorNumber
194 call ReadBlocks # Read 2 blocks starting at AX storing at ES:DI
196 movw %ax,%dx # CachedFatSectorNumber = FatSectorNumber
198 movw (%si), %bx # bx = NextClusterNumber
199 movw %cx,%ax # ax = ClusterNumber
200 popw %si # Restore si
201 decw %bx # bx = NextClusterNumber - 1
202 cmpw %cx,%bx # See if (NextClusterNumber-1)==ClusterNumber
204 incw %bx # bx = NextClusterNumber
205 incw %si # NumberOfClusters++
206 movw %bx,%cx # ClusterNumber = NextClusterNumber
210 popw %ax # ax = StartCluster
211 pushw %bx # StartCluster = NextClusterNumber
212 movw %bx,%cx # ClusterNumber = NextClusterNumber
213 subw $2,%ax # ax = StartCluster - 2
215 movb SectorsPerCluster(%bp), %bl # bx = SectorsPerCluster
216 mulw %bx # ax = (StartCluster - 2) * SectorsPerCluster
217 addw (%bp), %ax # ax = FirstClusterLBA + (StartCluster-2)*SectorsPerCluster
218 pushw %ax # save start sector
219 movw %si,%ax # ax = NumberOfClusters
220 mulw %bx # ax = NumberOfClusters * SectorsPerCluster
221 movw %ax,%bx # bx = Number of Sectors
222 popw %ax # ax = Start Sector
224 movw $1,%si # NumberOfClusters = 1
232 # ****************************************************************************
233 # ReadBlocks - Reads a set of blocks from a block device
236 # BX = Number of Blocks to Read
237 # ES:DI = Buffer to store sectors read from disk
238 # ****************************************************************************
241 # bx = NumberOfBlocks
246 addl LBAOffsetForBootSector(%bp), %eax # Add LBAOffsetForBootSector to Start LBA
247 addl HiddenSectors(%bp), %eax # Add HiddenSectors to Start LBA
248 movl %eax,%esi # esi = Start LBA
249 movw %bx,%cx # cx = Number of blocks to read
251 movw $0x7bfc,%bp # bp = 0x7bfc
252 movl %esi,%eax # eax = Start LBA
253 xorl %edx,%edx # edx = 0
254 movzwl (%bp), %ebx # bx = MaxSector
255 divl %ebx # ax = StartLBA / MaxSector
256 incw %dx # dx = (StartLBA % MaxSector) + 1
258 movw (%bp), %bx # bx = MaxSector
259 subw %dx,%bx # bx = MaxSector - Sector
260 incw %bx # bx = MaxSector - Sector + 1
261 cmpw %bx,%cx # Compare (Blocks) to (MaxSector - Sector + 1)
263 movw %cx,%bx # bx = Blocks
266 movw %es,%ax # ax = es
267 shrw $(BLOCK_SHIFT-4), %ax # ax = Number of blocks into mem system
268 andw $0x7f,%ax # ax = Number of blocks into current seg
269 addw %bx,%ax # ax = End Block number of transfer
270 cmpw $0x80,%ax # See if it crosses a 64K boundry
271 jle NotCrossing64KBoundry # Branch if not crossing 64K boundry
272 subw $0x80,%ax # ax = Number of blocks past 64K boundry
273 subw %ax,%bx # Decrease transfer size by block overage
274 NotCrossing64KBoundry:
275 popw %ax # restore ax
278 movb %dl,%cl # cl = (StartLBA % MaxSector) + 1 = Sector
279 xorw %dx,%dx # dx = 0
280 divw 2(%bp) # ax = ax / (MaxHead + 1) = Cylinder
281 # dx = ax % (MaxHead + 1) = Head
283 pushw %bx # Save number of blocks to transfer
284 movb %dl,%dh # dh = Head
285 movw $0x7c00,%bp # bp = 0x7c00
286 movb PhysicalDrive(%bp), %dl # dl = Drive Number
287 movb %al,%ch # ch = Cylinder
288 movb %bl,%al # al = Blocks
289 movb $2,%ah # ah = Function 2
290 movw %di,%bx # es:bx = Buffer address
296 addl %ebx,%esi # StartLBA = StartLBA + NumberOfBlocks
297 subw %bx,%cx # Blocks = Blocks - NumberOfBlocks
299 shlw $(BLOCK_SHIFT-4), %bx
301 movw %ax,%es # es:di = es:di + NumberOfBlocks*BLOCK_SIZE
312 jmp PrintStringAndHalt
324 .byte 'S', 0x0c, 'E', 0x0c, 'r', 0x0c, 'r', 0x0c, 'o', 0x0c, 'r', 0x0c, '!',0x0c
327 LBAOffsetForBootSector:
333 #******************************************************************************
334 #******************************************************************************
335 #******************************************************************************
337 .equ DELAY_PORT, 0x0ed # Port to use for 1uS delay
338 .equ KBD_CONTROL_PORT, 0x060 # 8042 control port
339 .equ KBD_STATUS_PORT, 0x064 # 8042 status port
340 .equ WRITE_DATA_PORT_CMD, 0x0d1 # 8042 command to write the data port
341 .equ ENABLE_A20_CMD, 0x0df # 8042 command to enable A20
346 .byte 'E', 0x0c, 'm', 0x0c, '6', 0x0c, '4', 0x0c, 'T', 0x0c, ' ', 0x0c, 'U', 0x0c, 'n', 0x0c, 's', 0x0c, 'u', 0x0c, 'p', 0x0c, 'p', 0x0c, 'o', 0x0c, 'r', 0x0c, 't', 0x0c, 'e', 0x0c, 'd', 0x0c, '!', 0x0c
357 # mov byte ptr es:[160],'a'
366 movl $0x534d4150, %edx # SMAP
375 subl %eax,%edi # Get the address of the memory map
376 movl %edi, MemoryMapSize # Save the size of the memory map
379 movw %cs,%bx # BX=segment
380 shll $4,%ebx # BX="linear" address of segment base
381 leal GDT_BASE(%ebx), %eax # EAX=PHYSICAL address of gdt
382 movl %eax, (gdtr + 2) # Put address of gdt into the gdtr
383 leal IDT_BASE(%ebx), %eax # EAX=PHYSICAL address of idt
384 movl %eax, (idtr + 2) # Put address of idt into the idtr
385 leal MemoryMapSize(%ebx), %edx # Physical base address of the memory map
389 # mov byte ptr es:[162],'b'
397 movw $0x2401,%ax # Enable A20 Gate
399 jnc A20GateEnabled # Jump if it suceeded
402 # If INT 15 Function 2401 is not supported, then attempt to Enable A20 manually.
405 call Empty8042InputBuffer # Empty the Input Buffer on the 8042 controller
406 jnz Timeout8042 # Jump if the 8042 timed out
407 outw %ax, $DELAY_PORT # Delay 1 uS
408 movb $WRITE_DATA_PORT_CMD, %al # 8042 cmd to write output port
409 outb %al, $KBD_STATUS_PORT # Send command to the 8042
410 call Empty8042InputBuffer # Empty the Input Buffer on the 8042 controller
411 jnz Timeout8042 # Jump if the 8042 timed out
412 movb $ENABLE_A20_CMD, %al # gate address bit 20 on
413 outb %al, $KBD_CONTROL_PORT # Send command to thre 8042
414 call Empty8042InputBuffer # Empty the Input Buffer on the 8042 controller
415 movw $25,%cx # Delay 25 uS for the command to complete on the 8042
417 outw %ax, $DELAY_PORT # Delay 1 uS
425 # DISABLE INTERRUPTS - Entering Protected Mode
432 # mov byte ptr es:[164],'c'
436 leal OffsetIn32BitProtectedMode, %eax
437 addl $0x20000+0x6,%eax
438 movl %eax, OffsetIn32BitProtectedMode
440 leal OffsetInLongMode, %eax
441 addl $0x20000+0x6,%eax
442 movl %eax, OffsetInLongMode
451 # Enable Protect Mode (set CR0.PE=1)
453 movl %cr0, %eax # Read CR0.
454 orl $0x1,%eax # Set PE=1
455 movl %eax, %cr0 # Write CR0.
457 .byte 0xea # jmp far 16:32
458 OffsetIn32BitProtectedMode:
459 .long 0x0000000 # offset $+8 (In32BitProtectedMode)
460 .word 0x10 # selector (flat CS)
461 In32BitProtectedMode:
473 # Enable the 64-bit page-translation-table entries by
474 # setting CR4.PAE=1 (this is _required_ before activating
475 # long mode). Paging is not enabled until after long mode
489 # This is the Trapolean Page Tables that are guarenteed
493 # 10000 ~ 12000 - efildr (loaded)
494 # 20000 ~ 21000 - start64.com
495 # 21000 ~ 22000 - efi64.com
496 # 22000 ~ 90000 - efildr
497 # 90000 ~ 96000 - 4G pagetable (will be reload later)
505 # Enable long mode (set EFER.LME=1).
509 # mov ecx, 0c0000080h ; EFER MSR number.
517 # bts eax, 8 ; Set LME=1.
520 # wrmsr ; Write EFER.
523 # Enable paging to activate long mode (set CR0.PG=1)
525 movl %cr0, %eax # Read CR0.
530 # bts eax, 31 ; Set PG=1.
531 movl %eax, %cr0 # Write CR0.
536 .byte 0xea # Far Jump $+9:Selector to reload CS
538 .long 00000000 # $+9 Offset is ensuing instruction boundary
539 .word 0x38 # Selector is our code selector, 38h
554 # mov ebp,000400000h ; Destination of EFILDR32
557 # mov ebx,000070000h ; Length of copy
576 # lidt fword ptr [rax]
589 Empty8042InputBuffer:
592 outw %ax, $DELAY_PORT # Delay 1us
593 inb $KBD_STATUS_PORT, %al # Read the 8042 Status Port
594 andb $0x2,%al # Check the Input Buffer Full Flag
595 loopnz Empty8042Loop # Loop until the input buffer is empty or a timout of 65536 uS
598 ##############################################################################
600 ##############################################################################
604 gdtr: .word GDT_END - GDT_BASE - 1 # GDT limit
605 .long 0 # (GDT base gets set above)
606 ##############################################################################
607 # global descriptor table (GDT)
608 ##############################################################################
614 .equ NULL_SEL, .-GDT_BASE # Selector [0x0]
619 .byte 0 # limit 19:16, flags
622 # linear data segment descriptor
623 .equ LINEAR_SEL, .-GDT_BASE # Selector [0x8]
624 .word 0xFFFF # limit 0xFFFFF
627 .byte 0x92 # present, ring 0, data, expand-up, writable
628 .byte 0xCF # page-granular, 32-bit
631 # linear code segment descriptor
632 .equ LINEAR_CODE_SEL, .-GDT_BASE # Selector [0x10]
633 .word 0xFFFF # limit 0xFFFFF
636 .byte 0x9A # present, ring 0, data, expand-up, writable
637 .byte 0xCF # page-granular, 32-bit
640 # system data segment descriptor
641 .equ SYS_DATA_SEL, .-GDT_BASE # Selector [0x18]
642 .word 0xFFFF # limit 0xFFFFF
645 .byte 0x92 # present, ring 0, data, expand-up, writable
646 .byte 0xCF # page-granular, 32-bit
649 # system code segment descriptor
650 .equ SYS_CODE_SEL, .-GDT_BASE # Selector [0x20]
651 .word 0xFFFF # limit 0xFFFFF
654 .byte 0x9A # present, ring 0, data, expand-up, writable
655 .byte 0xCF # page-granular, 32-bit
658 # spare segment descriptor
659 .equ SPARE3_SEL, .-GDT_BASE # Selector [0x28]
660 .word 0 # limit 0xFFFFF
663 .byte 0 # present, ring 0, data, expand-up, writable
664 .byte 0 # page-granular, 32-bit
668 # system data segment descriptor
670 .equ SYS_DATA64_SEL, .-GDT_BASE # Selector [0x30]
671 .word 0xFFFF # limit 0xFFFFF
674 .byte 0x92 # P | DPL [1..2] | 1 | 1 | C | R | A
675 .byte 0xCF # G | D | L | AVL | Segment [19..16]
679 # system code segment descriptor
681 .equ SYS_CODE64_SEL, .-GDT_BASE # Selector [0x38]
682 .word 0xFFFF # limit 0xFFFFF
685 .byte 0x9A # P | DPL [1..2] | 1 | 1 | C | R | A
686 .byte 0xAF # G | D | L | AVL | Segment [19..16]
689 # spare segment descriptor
690 .equ SPARE4_SEL, .-GDT_BASE # Selector [0x40]
691 .word 0 # limit 0xFFFFF
694 .byte 0 # present, ring 0, data, expand-up, writable
695 .byte 0 # page-granular, 32-bit
704 idtr: .long IDT_END - IDT_BASE - 1 # IDT limit
705 .quad 0 # (IDT base gets set above)
707 ##############################################################################
708 # interrupt descriptor table (IDT)
710 # Note: The hardware IRQ's specified in this table are the normal PC/AT IRQ
711 # mappings. This implementation only uses the system timer and all other
712 # IRQs will remain masked. The descriptors for vectors 33+ are provided
714 ##############################################################################
721 # divide by zero (INT 0)
722 .equ DIV_ZERO_SEL, .-IDT_BASE
723 .word 0 # offset 15:0
724 .long SYS_CODE64_SEL # selector 15:0
725 .byte 0 # 0 for interrupt gate
726 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
727 .word 0 # offset 31:16
728 .long 0 # offset 63:32
729 .long 0 # 0 for reserved
731 # debug exception (INT 1)
732 .equ DEBUG_EXCEPT_SEL, .-IDT_BASE
733 .word 0 # offset 15:0
734 .long SYS_CODE64_SEL # selector 15:0
735 .byte 0 # 0 for interrupt gate
736 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
737 .word 0 # offset 31:16
738 .long 0 # offset 63:32
739 .long 0 # 0 for reserved
742 .equ NMI_SEL, .-IDT_BASE
743 .word 0 # offset 15:0
744 .long SYS_CODE64_SEL # selector 15:0
745 .byte 0 # 0 for interrupt gate
746 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
747 .word 0 # offset 31:16
748 .long 0 # offset 63:32
749 .long 0 # 0 for reserved
751 # soft breakpoint (INT 3)
752 .equ BREAKPOINT_SEL, .-IDT_BASE
753 .word 0 # offset 15:0
754 .long SYS_CODE64_SEL # selector 15:0
755 .byte 0 # 0 for interrupt gate
756 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
757 .word 0 # offset 31:16
758 .long 0 # offset 63:32
759 .long 0 # 0 for reserved
762 .equ OVERFLOW_SEL, .-IDT_BASE
763 .word 0 # offset 15:0
764 .long SYS_CODE64_SEL # selector 15:0
765 .byte 0 # 0 for interrupt gate
766 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
767 .word 0 # offset 31:16
768 .long 0 # offset 63:32
769 .long 0 # 0 for reserved
771 # bounds check (INT 5)
772 .equ BOUNDS_CHECK_SEL, .-IDT_BASE
773 .word 0 # offset 15:0
774 .long SYS_CODE64_SEL # selector 15:0
775 .byte 0 # 0 for interrupt gate
776 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
777 .word 0 # offset 31:16
778 .long 0 # offset 63:32
779 .long 0 # 0 for reserved
781 # invalid opcode (INT 6)
782 .equ INVALID_OPCODE_SEL, .-IDT_BASE
783 .word 0 # offset 15:0
784 .long SYS_CODE64_SEL # selector 15:0
785 .byte 0 # 0 for interrupt gate
786 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
787 .word 0 # offset 31:16
788 .long 0 # offset 63:32
789 .long 0 # 0 for reserved
791 # device not available (INT 7)
792 .equ DEV_NOT_AVAIL_SEL, .-IDT_BASE
793 .word 0 # offset 15:0
794 .long SYS_CODE64_SEL # selector 15:0
795 .byte 0 # 0 for interrupt gate
796 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
797 .word 0 # offset 31:16
798 .long 0 # offset 63:32
799 .long 0 # 0 for reserved
801 # double fault (INT 8)
802 .equ DOUBLE_FAULT_SEL, .-IDT_BASE
803 .word 0 # offset 15:0
804 .long SYS_CODE64_SEL # selector 15:0
805 .byte 0 # 0 for interrupt gate
806 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
807 .word 0 # offset 31:16
808 .long 0 # offset 63:32
809 .long 0 # 0 for reserved
811 # Coprocessor segment overrun - reserved (INT 9)
812 .equ RSVD_INTR_SEL1, .-IDT_BASE
813 .word 0 # offset 15:0
814 .long SYS_CODE64_SEL # selector 15:0
815 .byte 0 # 0 for interrupt gate
816 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
817 .word 0 # offset 31:16
818 .long 0 # offset 63:32
819 .long 0 # 0 for reserved
821 # invalid TSS (INT 0ah)
822 .equ INVALID_TSS_SEL, .-IDT_BASE
823 .word 0 # offset 15:0
824 .long SYS_CODE64_SEL # selector 15:0
825 .byte 0 # 0 for interrupt gate
826 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
827 .word 0 # offset 31:16
828 .long 0 # offset 63:32
829 .long 0 # 0 for reserved
831 # segment not present (INT 0bh)
832 .equ SEG_NOT_PRESENT_SEL, .-IDT_BASE
833 .word 0 # offset 15:0
834 .long SYS_CODE64_SEL # selector 15:0
835 .byte 0 # 0 for interrupt gate
836 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
837 .word 0 # offset 31:16
838 .long 0 # offset 63:32
839 .long 0 # 0 for reserved
841 # stack fault (INT 0ch)
842 .equ STACK_FAULT_SEL, .-IDT_BASE
843 .word 0 # offset 15:0
844 .long SYS_CODE64_SEL # selector 15:0
845 .byte 0 # 0 for interrupt gate
846 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
847 .word 0 # offset 31:16
848 .long 0 # offset 63:32
849 .long 0 # 0 for reserved
851 # general protection (INT 0dh)
852 .equ GP_FAULT_SEL, .-IDT_BASE
853 .word 0 # offset 15:0
854 .long SYS_CODE64_SEL # selector 15:0
855 .byte 0 # 0 for interrupt gate
856 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
857 .word 0 # offset 31:16
858 .long 0 # offset 63:32
859 .long 0 # 0 for reserved
861 # page fault (INT 0eh)
862 .equ PAGE_FAULT_SEL, .-IDT_BASE
863 .word 0 # offset 15:0
864 .long SYS_CODE64_SEL # selector 15:0
865 .byte 0 # 0 for interrupt gate
866 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
867 .word 0 # offset 31:16
868 .long 0 # offset 63:32
869 .long 0 # 0 for reserved
871 # Intel reserved - do not use (INT 0fh)
872 .equ RSVD_INTR_SEL2, .-IDT_BASE
873 .word 0 # offset 15:0
874 .long SYS_CODE64_SEL # selector 15:0
875 .byte 0 # 0 for interrupt gate
876 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
877 .word 0 # offset 31:16
878 .long 0 # offset 63:32
879 .long 0 # 0 for reserved
881 # floating point error (INT 10h)
882 .equ FLT_POINT_ERR_SEL, .-IDT_BASE
883 .word 0 # offset 15:0
884 .long SYS_CODE64_SEL # selector 15:0
885 .byte 0 # 0 for interrupt gate
886 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
887 .word 0 # offset 31:16
888 .long 0 # offset 63:32
889 .long 0 # 0 for reserved
891 # alignment check (INT 11h)
892 .equ ALIGNMENT_CHECK_SEL, .-IDT_BASE
893 .word 0 # offset 15:0
894 .long SYS_CODE64_SEL # selector 15:0
895 .byte 0 # 0 for interrupt gate
896 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
897 .word 0 # offset 31:16
898 .long 0 # offset 63:32
899 .long 0 # 0 for reserved
901 # machine check (INT 12h)
902 .equ MACHINE_CHECK_SEL, .-IDT_BASE
903 .word 0 # offset 15:0
904 .long SYS_CODE64_SEL # selector 15:0
905 .byte 0 # 0 for interrupt gate
906 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
907 .word 0 # offset 31:16
908 .long 0 # offset 63:32
909 .long 0 # 0 for reserved
911 # SIMD floating-point exception (INT 13h)
912 .equ SIMD_EXCEPTION_SEL, .-IDT_BASE
913 .word 0 # offset 15:0
914 .long SYS_CODE64_SEL # selector 15:0
915 .byte 0 # 0 for interrupt gate
916 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
917 .word 0 # offset 31:16
918 .long 0 # offset 63:32
919 .long 0 # 0 for reserved
921 # 85 unspecified descriptors, First 12 of them are reserved, the rest are avail
922 .fill 85 * 16, 1, 0 # db (85 * 16) dup(0)
924 # IRQ 0 (System timer) - (INT 68h)
925 .equ IRQ0_SEL, .-IDT_BASE
926 .word 0 # offset 15:0
927 .long SYS_CODE64_SEL # selector 15:0
928 .byte 0 # 0 for interrupt gate
929 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
930 .word 0 # offset 31:16
931 .long 0 # offset 63:32
932 .long 0 # 0 for reserved
934 # IRQ 1 (8042 Keyboard controller) - (INT 69h)
935 .equ IRQ1_SEL, .-IDT_BASE
936 .word 0 # offset 15:0
937 .long SYS_CODE64_SEL # selector 15:0
938 .byte 0 # 0 for interrupt gate
939 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
940 .word 0 # offset 31:16
941 .long 0 # offset 63:32
942 .long 0 # 0 for reserved
944 # Reserved - IRQ 2 redirect (IRQ 2) - DO NOT USE!!! - (INT 6ah)
945 .equ IRQ2_SEL, .-IDT_BASE
946 .word 0 # offset 15:0
947 .long SYS_CODE64_SEL # selector 15:0
948 .byte 0 # 0 for interrupt gate
949 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
950 .word 0 # offset 31:16
951 .long 0 # offset 63:32
952 .long 0 # 0 for reserved
954 # IRQ 3 (COM 2) - (INT 6bh)
955 .equ IRQ3_SEL, .-IDT_BASE
956 .word 0 # offset 15:0
957 .long SYS_CODE64_SEL # selector 15:0
958 .byte 0 # 0 for interrupt gate
959 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
960 .word 0 # offset 31:16
961 .long 0 # offset 63:32
962 .long 0 # 0 for reserved
964 # IRQ 4 (COM 1) - (INT 6ch)
965 .equ IRQ4_SEL, .-IDT_BASE
966 .word 0 # offset 15:0
967 .long SYS_CODE64_SEL # selector 15:0
968 .byte 0 # 0 for interrupt gate
969 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
970 .word 0 # offset 31:16
971 .long 0 # offset 63:32
972 .long 0 # 0 for reserved
974 # IRQ 5 (LPT 2) - (INT 6dh)
975 .equ IRQ5_SEL, .-IDT_BASE
976 .word 0 # offset 15:0
977 .long SYS_CODE64_SEL # selector 15:0
978 .byte 0 # 0 for interrupt gate
979 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
980 .word 0 # offset 31:16
981 .long 0 # offset 63:32
982 .long 0 # 0 for reserved
984 # IRQ 6 (Floppy controller) - (INT 6eh)
985 .equ IRQ6_SEL, .-IDT_BASE
986 .word 0 # offset 15:0
987 .long SYS_CODE64_SEL # selector 15:0
988 .byte 0 # 0 for interrupt gate
989 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
990 .word 0 # offset 31:16
991 .long 0 # offset 63:32
992 .long 0 # 0 for reserved
994 # IRQ 7 (LPT 1) - (INT 6fh)
995 .equ IRQ7_SEL, .-IDT_BASE
996 .word 0 # offset 15:0
997 .long SYS_CODE64_SEL # selector 15:0
998 .byte 0 # 0 for interrupt gate
999 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
1000 .word 0 # offset 31:16
1001 .long 0 # offset 63:32
1002 .long 0 # 0 for reserved
1004 # IRQ 8 (RTC Alarm) - (INT 70h)
1005 .equ IRQ8_SEL, .-IDT_BASE
1006 .word 0 # offset 15:0
1007 .long SYS_CODE64_SEL # selector 15:0
1008 .byte 0 # 0 for interrupt gate
1009 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
1010 .word 0 # offset 31:16
1011 .long 0 # offset 63:32
1012 .long 0 # 0 for reserved
1015 .equ IRQ9_SEL, .-IDT_BASE
1016 .word 0 # offset 15:0
1017 .long SYS_CODE64_SEL # selector 15:0
1018 .byte 0 # 0 for interrupt gate
1019 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
1020 .word 0 # offset 31:16
1021 .long 0 # offset 63:32
1022 .long 0 # 0 for reserved
1024 # IRQ 10 - (INT 72h)
1025 .equ IRQ10_SEL, .-IDT_BASE
1026 .word 0 # offset 15:0
1027 .long SYS_CODE64_SEL # selector 15:0
1028 .byte 0 # 0 for interrupt gate
1029 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
1030 .word 0 # offset 31:16
1031 .long 0 # offset 63:32
1032 .long 0 # 0 for reserved
1034 # IRQ 11 - (INT 73h)
1035 .equ IRQ11_SEL, .-IDT_BASE
1036 .word 0 # offset 15:0
1037 .long SYS_CODE64_SEL # selector 15:0
1038 .byte 0 # 0 for interrupt gate
1039 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
1040 .word 0 # offset 31:16
1041 .long 0 # offset 63:32
1042 .long 0 # 0 for reserved
1044 # IRQ 12 (PS/2 mouse) - (INT 74h)
1045 .equ IRQ12_SEL, .-IDT_BASE
1046 .word 0 # offset 15:0
1047 .long SYS_CODE64_SEL # selector 15:0
1048 .byte 0 # 0 for interrupt gate
1049 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
1050 .word 0 # offset 31:16
1051 .long 0 # offset 63:32
1052 .long 0 # 0 for reserved
1054 # IRQ 13 (Floating point error) - (INT 75h)
1055 .equ IRQ13_SEL, .-IDT_BASE
1056 .word 0 # offset 15:0
1057 .long SYS_CODE64_SEL # selector 15:0
1058 .byte 0 # 0 for interrupt gate
1059 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
1060 .word 0 # offset 31:16
1061 .long 0 # offset 63:32
1062 .long 0 # 0 for reserved
1064 # IRQ 14 (Secondary IDE) - (INT 76h)
1065 .equ IRQ14_SEL, .-IDT_BASE
1066 .word 0 # offset 15:0
1067 .long SYS_CODE64_SEL # selector 15:0
1068 .byte 0 # 0 for interrupt gate
1069 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
1070 .word 0 # offset 31:16
1071 .long 0 # offset 63:32
1072 .long 0 # 0 for reserved
1074 # IRQ 15 (Primary IDE) - (INT 77h)
1075 .equ IRQ15_SEL, .-IDT_BASE
1076 .word 0 # offset 15:0
1077 .long SYS_CODE64_SEL # selector 15:0
1078 .byte 0 # 0 for interrupt gate
1079 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
1080 .word 0 # offset 31:16
1081 .long 0 # offset 63:32
1082 .long 0 # 0 for reserved
1088 MemoryMapSize: .long 0
1089 MemoryMap: .long 0,0,0,0,0,0,0,0
1090 .long 0,0,0,0,0,0,0,0
1091 .long 0,0,0,0,0,0,0,0
1092 .long 0,0,0,0,0,0,0,0
1093 .long 0,0,0,0,0,0,0,0
1094 .long 0,0,0,0,0,0,0,0
1095 .long 0,0,0,0,0,0,0,0
1096 .long 0,0,0,0,0,0,0,0
1097 .long 0,0,0,0,0,0,0,0
1098 .long 0,0,0,0,0,0,0,0
1099 .long 0,0,0,0,0,0,0,0
1100 .long 0,0,0,0,0,0,0,0
1101 .long 0,0,0,0,0,0,0,0
1102 .long 0,0,0,0,0,0,0,0
1103 .long 0,0,0,0,0,0,0,0
1104 .long 0,0,0,0,0,0,0,0
1105 .long 0,0,0,0,0,0,0,0
1106 .long 0,0,0,0,0,0,0,0
1107 .long 0,0,0,0,0,0,0,0
1108 .long 0,0,0,0,0,0,0,0
1109 .long 0,0,0,0,0,0,0,0
1110 .long 0,0,0,0,0,0,0,0
1111 .long 0,0,0,0,0,0,0,0
1112 .long 0,0,0,0,0,0,0,0
1113 .long 0,0,0,0,0,0,0,0
1114 .long 0,0,0,0,0,0,0,0
1115 .long 0,0,0,0,0,0,0,0
1116 .long 0,0,0,0,0,0,0,0
1117 .long 0,0,0,0,0,0,0,0
1118 .long 0,0,0,0,0,0,0,0
1120 .long 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
1124 # below is the pieces of the IVT that is used to redirect INT 68h - 6fh
1125 # back to INT 08h - 0fh when in real mode... It is 'org'ed to a
1126 # known low address (20f00) so it can be set up by PlMapIrqToVect in