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 .equ FAT_DIRECTORY_ENTRY_SIZE, 0x020
24 .equ FAT_DIRECTORY_ENTRY_SHIFT, 5
25 .equ BLOCK_SIZE, 0x0200
26 .equ BLOCK_MASK, 0x01ff
31 jmp BootSectorEntryPoint # JMP inst - 3 bytes
34 OemId: .ascii "INTEL " # OemId - 8 bytes
35 SectorSize: .word 0 # Sector Size - 2 bytes
36 SectorsPerCluster: .byte 0 # Sector Per Cluster - 1 byte
37 ReservedSectors: .word 0 # Reserved Sectors - 2 bytes
38 NoFats: .byte 0 # Number of FATs - 1 byte
39 RootEntries: .word 0 # Root Entries - 2 bytes
40 Sectors: .word 0 # Number of Sectors - 2 bytes
41 Media: .byte 0 # Media - 1 byte
42 SectorsPerFat16: .word 0 # Sectors Per FAT for FAT12/FAT16 - 2 byte
43 SectorsPerTrack: .word 0 # Sectors Per Track - 2 bytes
44 Heads: .word 0 # Heads - 2 bytes
45 HiddenSectors: .long 0 # Hidden Sectors - 4 bytes
46 LargeSectors: .long 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: .long 0 # Sectors Per FAT for FAT32 - 4 bytes
56 ExtFlags: .word 0 # Mirror Flag - 2 bytes
57 FSVersion: .word 0 # File System Version - 2 bytes
58 RootCluster: .long 0 # 1st Cluster Number of Root Dir - 4 bytes
59 FSInfo: .word 0 # Sector Number of FSINFO - 2 bytes
60 BkBootSector: .word 0 # Sector Number of Bk BootSector - 2 bytes
61 Reserved: .fill 12,1,0 # Reserved Field - 12 bytes
62 PhysicalDrive: .byte 0 # Physical Drive Number - 1 byte
63 Reserved1: .byte 0 # Reserved Field - 1 byte
64 Signature: .byte 0 # Extended Boot Signature - 1 byte
65 VolId: .ascii " " # Volume Serial Number - 4 bytes
66 FatLabel: .ascii " " # Volume Label - 11 bytes
67 FileSystemType: .ascii "FAT32 " # File System Type - 8 bytes
73 # ds = 1000, es = 2000 + x (size of first cluster >> 4)
74 # cx = Start Cluster of EfiLdr
75 # dx = Start Cluster of Efivar.bin
77 # 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
97 cmpl $0x4000, %ds:2(%di)
114 movw %ax, %es:(0) # Save Volume Id to 0:19000. we will find the correct volume according to this VolumeId
115 movw VolId+2(%bp), %ax
120 # cx = Start Cluster of Efildr -> BS.com has filled already
121 # ES:DI = 2000:0, first cluster will be read again
122 xorw %di,%di # di = 0
127 movw %ax, %cs:JumpSegment
130 movl $0x80000001,%eax
139 jmp PrintStringAndHalt
150 # ****************************************************************************
154 # CX = Start Cluster of File
155 # ES:DI = Buffer to store file content read from disk
158 # (ES << 4 + DI) = end of file content Buffer
160 # ****************************************************************************
162 # si = NumberOfClusters
164 # dx = CachedFatSectorNumber
165 # ds:0000 = CacheFatSectorBuffer
166 # es:di = Buffer to load file
167 # bx = NextClusterNumber
169 movw $1,%si # NumberOfClusters = 1
170 pushw %cx # Push Start Cluster onto stack
171 movw $0xfff,%dx # CachedFatSectorNumber = 0xfff
173 movw %cx,%ax # ax = ClusterNumber
174 andw $0xfff8,%ax # ax = ax & 0xfff8
175 cmpw $0xfff8,%ax # See if this is the last cluster
176 je FoundLastCluster # Jump if last cluster found
177 movw %cx,%ax # ax = ClusterNumber
178 shlw $2, %ax # FatOffset = ClusterNumber * 2
180 movw %ax,%si # si = FatOffset
181 shrw $BLOCK_SHIFT, %ax # ax = FatOffset >> BLOCK_SHIFT
182 addw ReservedSectors(%bp), %ax # ax = FatSectorNumber = ReservedSectors + (FatOffset >> BLOCK_OFFSET)
183 andw $BLOCK_MASK, %si # si = FatOffset & BLOCK_MASK
184 cmpw %dx,%ax # Compare FatSectorNumber to CachedFatSectorNumber
190 call ReadBlocks # Read 2 blocks starting at AX storing at ES:DI
192 movw %ax,%dx # CachedFatSectorNumber = FatSectorNumber
194 movw (%si), %bx # bx = NextClusterNumber
195 movw %cx,%ax # ax = ClusterNumber
196 popw %si # Restore si
197 decw %bx # bx = NextClusterNumber - 1
198 cmpw %cx,%bx # See if (NextClusterNumber-1)==ClusterNumber
200 incw %bx # bx = NextClusterNumber
201 incw %si # NumberOfClusters++
202 movw %bx,%cx # ClusterNumber = NextClusterNumber
206 popw %ax # ax = StartCluster
207 pushw %bx # StartCluster = NextClusterNumber
208 movw %bx,%cx # ClusterNumber = NextClusterNumber
209 subw $2,%ax # ax = StartCluster - 2
211 movb SectorsPerCluster(%bp), %bl # bx = SectorsPerCluster
212 mulw %bx # ax = (StartCluster - 2) * SectorsPerCluster
213 addw (%bp), %ax # ax = FirstClusterLBA + (StartCluster-2)*SectorsPerCluster
214 pushw %ax # save start sector
215 movw %si,%ax # ax = NumberOfClusters
216 mulw %bx # ax = NumberOfClusters * SectorsPerCluster
217 movw %ax,%bx # bx = Number of Sectors
218 popw %ax # ax = Start Sector
220 movw $1,%si # NumberOfClusters = 1
228 # ****************************************************************************
229 # ReadBlocks - Reads a set of blocks from a block device
232 # BX = Number of Blocks to Read
233 # ES:DI = Buffer to store sectors read from disk
234 # ****************************************************************************
237 # bx = NumberOfBlocks
242 addl LBAOffsetForBootSector(%bp), %eax # Add LBAOffsetForBootSector to Start LBA
243 addl HiddenSectors(%bp), %eax # Add HiddenSectors to Start LBA
244 movl %eax,%esi # esi = Start LBA
245 movw %bx,%cx # cx = Number of blocks to read
247 movw $0x7bfc,%bp # bp = 0x7bfc
248 movl %esi,%eax # eax = Start LBA
249 xorl %edx,%edx # edx = 0
250 movzwl (%bp), %ebx # bx = MaxSector
251 divl %ebx # ax = StartLBA / MaxSector
252 incw %dx # dx = (StartLBA % MaxSector) + 1
254 movw (%bp), %bx # bx = MaxSector
255 subw %dx,%bx # bx = MaxSector - Sector
256 incw %bx # bx = MaxSector - Sector + 1
257 cmpw %bx,%cx # Compare (Blocks) to (MaxSector - Sector + 1)
259 movw %cx,%bx # bx = Blocks
262 movw %es,%ax # ax = es
263 shrw $(BLOCK_SHIFT-4), %ax # ax = Number of blocks into mem system
264 andw $0x7f,%ax # ax = Number of blocks into current seg
265 addw %bx,%ax # ax = End Block number of transfer
266 cmpw $0x80,%ax # See if it crosses a 64K boundry
267 jle NotCrossing64KBoundry # Branch if not crossing 64K boundry
268 subw $0x80,%ax # ax = Number of blocks past 64K boundry
269 subw %ax,%bx # Decrease transfer size by block overage
270 NotCrossing64KBoundry:
271 popw %ax # restore ax
274 movb %dl,%cl # cl = (StartLBA % MaxSector) + 1 = Sector
275 xorw %dx,%dx # dx = 0
276 divw 2(%bp) # ax = ax / (MaxHead + 1) = Cylinder
277 # dx = ax % (MaxHead + 1) = Head
279 pushw %bx # Save number of blocks to transfer
280 movb %dl,%dh # dh = Head
281 movw $0x7c00,%bp # bp = 0x7c00
282 movb PhysicalDrive(%bp), %dl # dl = Drive Number
283 movb %al,%ch # ch = Cylinder
284 movb %bl,%al # al = Blocks
285 movb $2,%ah # ah = Function 2
286 movw %di,%bx # es:bx = Buffer address
292 addl %ebx,%esi # StartLBA = StartLBA + NumberOfBlocks
293 subw %bx,%cx # Blocks = Blocks - NumberOfBlocks
295 shlw $(BLOCK_SHIFT-4), %bx
297 movw %ax,%es # es:di = es:di + NumberOfBlocks*BLOCK_SIZE
308 jmp PrintStringAndHalt
320 .byte 'S', 0x0c, 'E', 0x0c, 'r', 0x0c, 'r', 0x0c, 'o', 0x0c, 'r', 0x0c, '!',0x0c
323 LBAOffsetForBootSector:
329 #******************************************************************************
330 #******************************************************************************
331 #******************************************************************************
333 .equ DELAY_PORT, 0x0ed # Port to use for 1uS delay
334 .equ KBD_CONTROL_PORT, 0x060 # 8042 control port
335 .equ KBD_STATUS_PORT, 0x064 # 8042 status port
336 .equ WRITE_DATA_PORT_CMD, 0x0d1 # 8042 command to write the data port
337 .equ ENABLE_A20_CMD, 0x0df # 8042 command to enable A20
342 .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
353 # mov byte ptr es:[160],'a'
362 movl $0x534d4150, %edx # SMAP
371 subl %eax,%edi # Get the address of the memory map
372 movl %edi, MemoryMapSize # Save the size of the memory map
375 movw %cs,%bx # BX=segment
376 shll $4,%ebx # BX="linear" address of segment base
377 leal GDT_BASE(%ebx), %eax # EAX=PHYSICAL address of gdt
378 movl %eax, (gdtr + 2) # Put address of gdt into the gdtr
379 leal IDT_BASE(%ebx), %eax # EAX=PHYSICAL address of idt
380 movl %eax, (idtr + 2) # Put address of idt into the idtr
381 leal MemoryMapSize(%ebx), %edx # Physical base address of the memory map
385 # mov byte ptr es:[162],'b'
393 movw $0x2401,%ax # 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 outw %ax, $DELAY_PORT # Delay 1 uS
404 movb $WRITE_DATA_PORT_CMD, %al # 8042 cmd to write output port
405 outb %al, $KBD_STATUS_PORT # 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 movb $ENABLE_A20_CMD, %al # gate address bit 20 on
409 outb %al, $KBD_CONTROL_PORT # Send command to thre 8042
410 call Empty8042InputBuffer # Empty the Input Buffer on the 8042 controller
411 movw $25,%cx # Delay 25 uS for the command to complete on the 8042
413 outw %ax, $DELAY_PORT # Delay 1 uS
421 # DISABLE INTERRUPTS - Entering Protected Mode
428 # mov byte ptr es:[164],'c'
432 leal OffsetIn32BitProtectedMode, %eax
433 addl $0x20000+0x6,%eax
434 movl %eax, OffsetIn32BitProtectedMode
436 leal OffsetInLongMode, %eax
437 addl $0x20000+0x6,%eax
438 movl %eax, OffsetInLongMode
447 # Enable Protect Mode (set CR0.PE=1)
449 movl $cr0, %eax # Read CR0.
450 orl $0x1,%eax # Set PE=1
451 movl %eax, %cr0 # Write CR0.
453 .byte 0xea # jmp far 16:32
454 OffsetIn32BitProtectedMode:
455 .long 0x0000000 # offset $+8 (In32BitProtectedMode)
456 .word 0x10 # 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 movl $cr0, %eax # Read CR0.
526 # bts eax, 31 ; Set PG=1.
527 movl %eax, %cr0 # Write CR0.
532 .byte 0xea # Far Jump $+9:Selector to reload CS
534 .long 00000000 # $+9 Offset is ensuing instruction boundary
535 .word 0x38 # 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 outw %ax, $DELAY_PORT # Delay 1us
589 inb $KBD_STATUS_PORT, %al # Read the 8042 Status Port
590 andb $0x2,%al # 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: .long GDT_END - GDT_BASE - 1 # GDT limit
601 .long 0 # (GDT base gets set above)
602 ##############################################################################
603 # global descriptor table (GDT)
604 ##############################################################################
610 .equ NULL_SEL, .-GDT_BASE # Selector [0x0]
615 .byte 0 # limit 19:16, flags
618 # linear data segment descriptor
619 .equ LINEAR_SEL, .-GDT_BASE # Selector [0x8]
620 .word 0xFFFF # limit 0xFFFFF
623 .byte 0x92 # present, ring 0, data, expand-up, writable
624 .byte 0xCF # page-granular, 32-bit
627 # linear code segment descriptor
628 .equ LINEAR_CODE_SEL, .-GDT_BASE # Selector [0x10]
629 .word 0xFFFF # limit 0xFFFFF
632 .byte 0x9A # present, ring 0, data, expand-up, writable
633 .byte 0xCF # page-granular, 32-bit
636 # system data segment descriptor
637 .equ SYS_DATA_SEL, .-GDT_BASE # Selector [0x18]
638 .word 0xFFFF # limit 0xFFFFF
641 .byte 0x92 # present, ring 0, data, expand-up, writable
642 .byte 0xCF # page-granular, 32-bit
645 # system code segment descriptor
646 .equ SYS_CODE_SEL, .-GDT_BASE # Selector [0x20]
647 .word 0xFFFF # limit 0xFFFFF
650 .byte 0x9A # present, ring 0, data, expand-up, writable
651 .byte 0xCF # page-granular, 32-bit
654 # spare segment descriptor
655 .equ SPARE3_SEL, .-GDT_BASE # Selector [0x28]
656 .word 0 # limit 0xFFFFF
659 .byte 0 # present, ring 0, data, expand-up, writable
660 .byte 0 # page-granular, 32-bit
664 # system data segment descriptor
666 .equ SYS_DATA64_SEL, .-GDT_BASE # Selector [0x30]
667 .word 0xFFFF # limit 0xFFFFF
670 .byte 0x92 # P | DPL [1..2] | 1 | 1 | C | R | A
671 .byte 0xCF # G | D | L | AVL | Segment [19..16]
675 # system code segment descriptor
677 .equ SYS_CODE64_SEL, .-GDT_BASE # Selector [0x38]
678 .word 0xFFFF # limit 0xFFFFF
681 .byte 0x9A # P | DPL [1..2] | 1 | 1 | C | R | A
682 .byte 0xAF # G | D | L | AVL | Segment [19..16]
685 # spare segment descriptor
686 .equ SPARE4_SEL, .-GDT_BASE # Selector [0x40]
687 .word 0 # limit 0xFFFFF
690 .byte 0 # present, ring 0, data, expand-up, writable
691 .byte 0 # page-granular, 32-bit
700 idtr: .long IDT_END - IDT_BASE - 1 # IDT limit
701 .quad 0 # (IDT base gets set above)
703 ##############################################################################
704 # interrupt descriptor table (IDT)
706 # Note: The hardware IRQ's specified in this table are the normal PC/AT IRQ
707 # mappings. This implementation only uses the system timer and all other
708 # IRQs will remain masked. The descriptors for vectors 33+ are provided
710 ##############################################################################
717 # divide by zero (INT 0)
718 .equ DIV_ZERO_SEL, .-IDT_BASE
719 .word 0 # offset 15:0
720 .long SYS_CODE64_SEL # selector 15:0
721 .byte 0 # 0 for interrupt gate
722 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
723 .word 0 # offset 31:16
724 .long 0 # offset 63:32
725 .long 0 # 0 for reserved
727 # debug exception (INT 1)
728 .equ DEBUG_EXCEPT_SEL, .-IDT_BASE
729 .word 0 # offset 15:0
730 .long SYS_CODE64_SEL # selector 15:0
731 .byte 0 # 0 for interrupt gate
732 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
733 .word 0 # offset 31:16
734 .long 0 # offset 63:32
735 .long 0 # 0 for reserved
738 .equ NMI_SEL, .-IDT_BASE
739 .word 0 # offset 15:0
740 .long SYS_CODE64_SEL # selector 15:0
741 .byte 0 # 0 for interrupt gate
742 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
743 .word 0 # offset 31:16
744 .long 0 # offset 63:32
745 .long 0 # 0 for reserved
747 # soft breakpoint (INT 3)
748 .equ BREAKPOINT_SEL, .-IDT_BASE
749 .word 0 # offset 15:0
750 .long SYS_CODE64_SEL # selector 15:0
751 .byte 0 # 0 for interrupt gate
752 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
753 .word 0 # offset 31:16
754 .long 0 # offset 63:32
755 .long 0 # 0 for reserved
758 .equ OVERFLOW_SEL, .-IDT_BASE
759 .word 0 # offset 15:0
760 .long SYS_CODE64_SEL # selector 15:0
761 .byte 0 # 0 for interrupt gate
762 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
763 .word 0 # offset 31:16
764 .long 0 # offset 63:32
765 .long 0 # 0 for reserved
767 # bounds check (INT 5)
768 .equ BOUNDS_CHECK_SEL, .-IDT_BASE
769 .word 0 # offset 15:0
770 .long SYS_CODE64_SEL # selector 15:0
771 .byte 0 # 0 for interrupt gate
772 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
773 .word 0 # offset 31:16
774 .long 0 # offset 63:32
775 .long 0 # 0 for reserved
777 # invalid opcode (INT 6)
778 .equ INVALID_OPCODE_SEL, .-IDT_BASE
779 .word 0 # offset 15:0
780 .long SYS_CODE64_SEL # selector 15:0
781 .byte 0 # 0 for interrupt gate
782 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
783 .word 0 # offset 31:16
784 .long 0 # offset 63:32
785 .long 0 # 0 for reserved
787 # device not available (INT 7)
788 .equ DEV_NOT_AVAIL_SEL, .-IDT_BASE
789 .word 0 # offset 15:0
790 .long SYS_CODE64_SEL # selector 15:0
791 .byte 0 # 0 for interrupt gate
792 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
793 .word 0 # offset 31:16
794 .long 0 # offset 63:32
795 .long 0 # 0 for reserved
797 # double fault (INT 8)
798 .equ DOUBLE_FAULT_SEL, .-IDT_BASE
799 .word 0 # offset 15:0
800 .long SYS_CODE64_SEL # selector 15:0
801 .byte 0 # 0 for interrupt gate
802 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
803 .word 0 # offset 31:16
804 .long 0 # offset 63:32
805 .long 0 # 0 for reserved
807 # Coprocessor segment overrun - reserved (INT 9)
808 .equ RSVD_INTR_SEL1, .-IDT_BASE
809 .word 0 # offset 15:0
810 .long SYS_CODE64_SEL # selector 15:0
811 .byte 0 # 0 for interrupt gate
812 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
813 .word 0 # offset 31:16
814 .long 0 # offset 63:32
815 .long 0 # 0 for reserved
817 # invalid TSS (INT 0ah)
818 .equ INVALID_TSS_SEL, .-IDT_BASE
819 .word 0 # offset 15:0
820 .long SYS_CODE64_SEL # selector 15:0
821 .byte 0 # 0 for interrupt gate
822 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
823 .word 0 # offset 31:16
824 .long 0 # offset 63:32
825 .long 0 # 0 for reserved
827 # segment not present (INT 0bh)
828 .equ SEG_NOT_PRESENT_SEL, .-IDT_BASE
829 .word 0 # offset 15:0
830 .long SYS_CODE64_SEL # selector 15:0
831 .byte 0 # 0 for interrupt gate
832 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
833 .word 0 # offset 31:16
834 .long 0 # offset 63:32
835 .long 0 # 0 for reserved
837 # stack fault (INT 0ch)
838 .equ STACK_FAULT_SEL, .-IDT_BASE
839 .word 0 # offset 15:0
840 .long SYS_CODE64_SEL # selector 15:0
841 .byte 0 # 0 for interrupt gate
842 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
843 .word 0 # offset 31:16
844 .long 0 # offset 63:32
845 .long 0 # 0 for reserved
847 # general protection (INT 0dh)
848 .equ GP_FAULT_SEL, .-IDT_BASE
849 .word 0 # offset 15:0
850 .long SYS_CODE64_SEL # selector 15:0
851 .byte 0 # 0 for interrupt gate
852 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
853 .word 0 # offset 31:16
854 .long 0 # offset 63:32
855 .long 0 # 0 for reserved
857 # page fault (INT 0eh)
858 .equ PAGE_FAULT_SEL, .-IDT_BASE
859 .word 0 # offset 15:0
860 .long SYS_CODE64_SEL # selector 15:0
861 .byte 0 # 0 for interrupt gate
862 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
863 .word 0 # offset 31:16
864 .long 0 # offset 63:32
865 .long 0 # 0 for reserved
867 # Intel reserved - do not use (INT 0fh)
868 .equ RSVD_INTR_SEL2, .-IDT_BASE
869 .word 0 # offset 15:0
870 .long SYS_CODE64_SEL # selector 15:0
871 .byte 0 # 0 for interrupt gate
872 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
873 .word 0 # offset 31:16
874 .long 0 # offset 63:32
875 .long 0 # 0 for reserved
877 # floating point error (INT 10h)
878 .equ FLT_POINT_ERR_SEL, .-IDT_BASE
879 .word 0 # offset 15:0
880 .long SYS_CODE64_SEL # selector 15:0
881 .byte 0 # 0 for interrupt gate
882 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
883 .word 0 # offset 31:16
884 .long 0 # offset 63:32
885 .long 0 # 0 for reserved
887 # alignment check (INT 11h)
888 .equ ALIGNMENT_CHECK_SEL, .-IDT_BASE
889 .word 0 # offset 15:0
890 .long SYS_CODE64_SEL # selector 15:0
891 .byte 0 # 0 for interrupt gate
892 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
893 .word 0 # offset 31:16
894 .long 0 # offset 63:32
895 .long 0 # 0 for reserved
897 # machine check (INT 12h)
898 .equ MACHINE_CHECK_SEL, .-IDT_BASE
899 .word 0 # offset 15:0
900 .long SYS_CODE64_SEL # selector 15:0
901 .byte 0 # 0 for interrupt gate
902 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
903 .word 0 # offset 31:16
904 .long 0 # offset 63:32
905 .long 0 # 0 for reserved
907 # SIMD floating-point exception (INT 13h)
908 .equ SIMD_EXCEPTION_SEL, .-IDT_BASE
909 .word 0 # offset 15:0
910 .long SYS_CODE64_SEL # selector 15:0
911 .byte 0 # 0 for interrupt gate
912 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
913 .word 0 # offset 31:16
914 .long 0 # offset 63:32
915 .long 0 # 0 for reserved
917 # 85 unspecified descriptors, First 12 of them are reserved, the rest are avail
918 .fill 85 * 16, 1, 0 # db (85 * 16) dup(0)
920 # IRQ 0 (System timer) - (INT 68h)
921 .equ IRQ0_SEL, .-IDT_BASE
922 .word 0 # offset 15:0
923 .long SYS_CODE64_SEL # selector 15:0
924 .byte 0 # 0 for interrupt gate
925 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
926 .word 0 # offset 31:16
927 .long 0 # offset 63:32
928 .long 0 # 0 for reserved
930 # IRQ 1 (8042 Keyboard controller) - (INT 69h)
931 .equ IRQ1_SEL, .-IDT_BASE
932 .word 0 # offset 15:0
933 .long SYS_CODE64_SEL # selector 15:0
934 .byte 0 # 0 for interrupt gate
935 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
936 .word 0 # offset 31:16
937 .long 0 # offset 63:32
938 .long 0 # 0 for reserved
940 # Reserved - IRQ 2 redirect (IRQ 2) - DO NOT USE!!! - (INT 6ah)
941 .equ IRQ2_SEL, .-IDT_BASE
942 .word 0 # offset 15:0
943 .long SYS_CODE64_SEL # selector 15:0
944 .byte 0 # 0 for interrupt gate
945 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
946 .word 0 # offset 31:16
947 .long 0 # offset 63:32
948 .long 0 # 0 for reserved
950 # IRQ 3 (COM 2) - (INT 6bh)
951 .equ IRQ3_SEL, .-IDT_BASE
952 .word 0 # offset 15:0
953 .long SYS_CODE64_SEL # selector 15:0
954 .byte 0 # 0 for interrupt gate
955 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
956 .word 0 # offset 31:16
957 .long 0 # offset 63:32
958 .long 0 # 0 for reserved
960 # IRQ 4 (COM 1) - (INT 6ch)
961 .equ IRQ4_SEL, .-IDT_BASE
962 .word 0 # offset 15:0
963 .long SYS_CODE64_SEL # selector 15:0
964 .byte 0 # 0 for interrupt gate
965 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
966 .word 0 # offset 31:16
967 .long 0 # offset 63:32
968 .long 0 # 0 for reserved
970 # IRQ 5 (LPT 2) - (INT 6dh)
971 .equ IRQ5_SEL, .-IDT_BASE
972 .word 0 # offset 15:0
973 .long SYS_CODE64_SEL # selector 15:0
974 .byte 0 # 0 for interrupt gate
975 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
976 .word 0 # offset 31:16
977 .long 0 # offset 63:32
978 .long 0 # 0 for reserved
980 # IRQ 6 (Floppy controller) - (INT 6eh)
981 .equ IRQ6_SEL, .-IDT_BASE
982 .word 0 # offset 15:0
983 .long SYS_CODE64_SEL # selector 15:0
984 .byte 0 # 0 for interrupt gate
985 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
986 .word 0 # offset 31:16
987 .long 0 # offset 63:32
988 .long 0 # 0 for reserved
990 # IRQ 7 (LPT 1) - (INT 6fh)
991 .equ IRQ7_SEL, .-IDT_BASE
992 .word 0 # offset 15:0
993 .long SYS_CODE64_SEL # selector 15:0
994 .byte 0 # 0 for interrupt gate
995 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
996 .word 0 # offset 31:16
997 .long 0 # offset 63:32
998 .long 0 # 0 for reserved
1000 # IRQ 8 (RTC Alarm) - (INT 70h)
1001 .equ IRQ8_SEL, .-IDT_BASE
1002 .word 0 # offset 15:0
1003 .long SYS_CODE64_SEL # selector 15:0
1004 .byte 0 # 0 for interrupt gate
1005 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
1006 .word 0 # offset 31:16
1007 .long 0 # offset 63:32
1008 .long 0 # 0 for reserved
1011 .equ IRQ9_SEL, .-IDT_BASE
1012 .word 0 # offset 15:0
1013 .long SYS_CODE64_SEL # selector 15:0
1014 .byte 0 # 0 for interrupt gate
1015 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
1016 .word 0 # offset 31:16
1017 .long 0 # offset 63:32
1018 .long 0 # 0 for reserved
1020 # IRQ 10 - (INT 72h)
1021 .equ IRQ10_SEL, .-IDT_BASE
1022 .word 0 # offset 15:0
1023 .long SYS_CODE64_SEL # selector 15:0
1024 .byte 0 # 0 for interrupt gate
1025 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
1026 .word 0 # offset 31:16
1027 .long 0 # offset 63:32
1028 .long 0 # 0 for reserved
1030 # IRQ 11 - (INT 73h)
1031 .equ IRQ11_SEL, .-IDT_BASE
1032 .word 0 # offset 15:0
1033 .long SYS_CODE64_SEL # selector 15:0
1034 .byte 0 # 0 for interrupt gate
1035 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
1036 .word 0 # offset 31:16
1037 .long 0 # offset 63:32
1038 .long 0 # 0 for reserved
1040 # IRQ 12 (PS/2 mouse) - (INT 74h)
1041 .equ IRQ12_SEL, .-IDT_BASE
1042 .word 0 # offset 15:0
1043 .long SYS_CODE64_SEL # selector 15:0
1044 .byte 0 # 0 for interrupt gate
1045 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
1046 .word 0 # offset 31:16
1047 .long 0 # offset 63:32
1048 .long 0 # 0 for reserved
1050 # IRQ 13 (Floating point error) - (INT 75h)
1051 .equ IRQ13_SEL, .-IDT_BASE
1052 .word 0 # offset 15:0
1053 .long SYS_CODE64_SEL # selector 15:0
1054 .byte 0 # 0 for interrupt gate
1055 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
1056 .word 0 # offset 31:16
1057 .long 0 # offset 63:32
1058 .long 0 # 0 for reserved
1060 # IRQ 14 (Secondary IDE) - (INT 76h)
1061 .equ IRQ14_SEL, .-IDT_BASE
1062 .word 0 # offset 15:0
1063 .long SYS_CODE64_SEL # selector 15:0
1064 .byte 0 # 0 for interrupt gate
1065 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
1066 .word 0 # offset 31:16
1067 .long 0 # offset 63:32
1068 .long 0 # 0 for reserved
1070 # IRQ 15 (Primary IDE) - (INT 77h)
1071 .equ IRQ15_SEL, .-IDT_BASE
1072 .word 0 # offset 15:0
1073 .long SYS_CODE64_SEL # selector 15:0
1074 .byte 0 # 0 for interrupt gate
1075 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
1076 .word 0 # offset 31:16
1077 .long 0 # offset 63:32
1078 .long 0 # 0 for reserved
1084 MemoryMapSize: .long 0
1085 MemoryMap: .long 0,0,0,0,0,0,0,0
1086 .long 0,0,0,0,0,0,0,0
1087 .long 0,0,0,0,0,0,0,0
1088 .long 0,0,0,0,0,0,0,0
1089 .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
1116 .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
1117 .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
1119 #.org 0x0fe0 #Just for pass build
1121 # below is the pieces of the IVT that is used to redirect INT 68h - 6fh
1122 # back to INT 08h - 0fh when in real mode... It is 'org'ed to a
1123 # known low address (20f00) so it can be set up by PlMapIrqToVect in
1151 #.org 0x0ffe #Just for pass build