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
40 SectorSize: .word 0 # Sector Size - 16 bits
41 SectorsPerCluster: .byte 0 # Sector Per Cluster - 8 bits
42 ReservedSectors: .word 0 # Reserved Sectors - 16 bits
43 NoFats: .byte 0 # Number of FATs - 8 bits
44 RootEntries: .word 0 # Root Entries - 16 bits
45 Sectors: .word 0 # Number of Sectors - 16 bits
46 Media: .byte 0 # Media - 8 bits - ignored
47 SectorsPerFat: .word 0 # Sectors Per FAT - 16 bits
48 SectorsPerTrack: .word 0 # Sectors Per Track - 16 bits - ignored
49 Heads: .word 0 # Heads - 16 bits - ignored
50 HiddenSectors: .long 0 # Hidden Sectors - 32 bits - ignored
51 LargeSectors: .long 0 # Large Sectors - 32 bits
52 PhysicalDrive: .byte 0 # PhysicalDriveNumber - 8 bits - ignored
53 CurrentHead: .byte 0 # Current Head - 8 bits
54 Signature: .byte 0 # Signature - 8 bits - ignored
55 VolId: .ascii " " # Volume Serial Number- 4 bytes
56 FatLabel: .ascii " " # Label - 11 bytes
57 SystemId: .ascii "FAT16 " # SystemId - 8 bytes
62 # ds = 1000, es = 2000 + x (size of first cluster >> 4)
63 # cx = Start Cluster of EfiLdr
64 # dx = Start Cluster of Efivar.bin
66 # Re use the BPB data stored in Boot Sector
71 # 1000:dx = DirectoryEntry of Efivar.bin -> BS.com has filled already
80 # Set the 5th byte start @ 0:19000 to non-zero indicating we should init var store header in DxeIpl
86 cmpl $0x4000, %ds:2(%di)
103 movw %ax, %es:(0) # Save Volume Id to 0:19000. we will find the correct volume according to this VolumeId
104 movw VolId+2(%bp), %ax
109 # cx = Start Cluster of Efildr -> BS.com has filled already
110 # ES:DI = 2000:0, first cluster will be read again
111 xorw %di,%di # di = 0
116 movw %ax, %cs:JumpSegment
119 movl $0x80000001,%eax
128 jmp PrintStringAndHalt
139 # ****************************************************************************
143 # CX = Start Cluster of File
144 # ES:DI = Buffer to store file content read from disk
147 # (ES << 4 + DI) = end of file content Buffer
149 # ****************************************************************************
151 # si = NumberOfClusters
153 # dx = CachedFatSectorNumber
154 # ds:0000 = CacheFatSectorBuffer
155 # es:di = Buffer to load file
156 # bx = NextClusterNumber
158 movw $1,%si # NumberOfClusters = 1
159 pushw %cx # Push Start Cluster onto stack
160 movw $0xfff,%dx # CachedFatSectorNumber = 0xfff
162 movw %cx,%ax # ax = ClusterNumber
163 andw $0xfff8,%ax # ax = ax & 0xfff8
164 cmpw $0xfff8,%ax # See if this is the last cluster
165 je FoundLastCluster # Jump if last cluster found
166 movw %cx,%ax # ax = ClusterNumber
167 shlw %ax # FatOffset = ClusterNumber * 2
169 movw %ax,%si # si = FatOffset
170 shrw $BLOCK_SHIFT, %ax # ax = FatOffset >> BLOCK_SHIFT
171 addw ReservedSectors(%bp), %ax # ax = FatSectorNumber = ReservedSectors + (FatOffset >> BLOCK_OFFSET)
172 andw $BLOCK_MASK, %si # si = FatOffset & BLOCK_MASK
173 cmpw %dx,%ax # Compare FatSectorNumber to CachedFatSectorNumber
179 call ReadBlocks # Read 2 blocks starting at AX storing at ES:DI
181 movw %ax,%dx # CachedFatSectorNumber = FatSectorNumber
183 movw (%si), %bx # bx = NextClusterNumber
184 movw %cx,%ax # ax = ClusterNumber
185 popw %si # Restore si
186 decw %bx # bx = NextClusterNumber - 1
187 cmpw %cx,%bx # See if (NextClusterNumber-1)==ClusterNumber
189 incw %bx # bx = NextClusterNumber
190 incw %si # NumberOfClusters++
191 movw %bx,%cx # ClusterNumber = NextClusterNumber
195 popw %ax # ax = StartCluster
196 pushw %bx # StartCluster = NextClusterNumber
197 movw %bx,%cx # ClusterNumber = NextClusterNumber
198 subw $2,%ax # ax = StartCluster - 2
200 movb SectorsPerCluster(%bp), %bl # bx = SectorsPerCluster
201 mulw %bx # ax = (StartCluster - 2) * SectorsPerCluster
202 addw (%bp), %ax # ax = FirstClusterLBA + (StartCluster-2)*SectorsPerCluster
203 pushw %ax # save start sector
204 movw %si,%ax # ax = NumberOfClusters
205 mulw %bx # ax = NumberOfClusters * SectorsPerCluster
206 movw %ax,%bx # bx = Number of Sectors
207 popw %ax # ax = Start Sector
209 movw $1,%si # NumberOfClusters = 1
217 # ****************************************************************************
218 # ReadBlocks - Reads a set of blocks from a block device
221 # BX = Number of Blocks to Read
222 # ES:DI = Buffer to store sectors read from disk
223 # ****************************************************************************
226 # bx = NumberOfBlocks
231 addl LBAOffsetForBootSector(%bp), %eax # Add LBAOffsetForBootSector to Start LBA
232 addl HiddenSectors(%bp), %eax # Add HiddenSectors to Start LBA
233 movl %eax,%esi # esi = Start LBA
234 movw %bx,%cx # cx = Number of blocks to read
236 movw $0x7bfc,%bp # bp = 0x7bfc
237 movl %esi,%eax # eax = Start LBA
238 xorl %edx,%edx # edx = 0
239 movzwl (%bp), %ebx # bx = MaxSector
240 divl %ebx # ax = StartLBA / MaxSector
241 incw %dx # dx = (StartLBA % MaxSector) + 1
243 movw (%bp), %bx # bx = MaxSector
244 subw %dx,%bx # bx = MaxSector - Sector
245 incw %bx # bx = MaxSector - Sector + 1
246 cmpw %bx,%cx # Compare (Blocks) to (MaxSector - Sector + 1)
248 movw %cx,%bx # bx = Blocks
251 movw %es,%ax # ax = es
252 shrw $(BLOCK_SHIFT-4), %ax # ax = Number of blocks into mem system
253 andw $0x7f,%ax # ax = Number of blocks into current seg
254 addw %bx,%ax # ax = End Block number of transfer
255 cmpw $0x80,%ax # See if it crosses a 64K boundry
256 jle NotCrossing64KBoundry # Branch if not crossing 64K boundry
257 subw $0x80,%ax # ax = Number of blocks past 64K boundry
258 subw %ax,%bx # Decrease transfer size by block overage
259 NotCrossing64KBoundry:
260 popw %ax # restore ax
263 movb %dl,%cl # cl = (StartLBA % MaxSector) + 1 = Sector
264 xorw %dx,%dx # dx = 0
265 divw 2(%bp) # ax = ax / (MaxHead + 1) = Cylinder
266 # dx = ax % (MaxHead + 1) = Head
268 pushw %bx # Save number of blocks to transfer
269 movb %dl,%dh # dh = Head
270 movw $0x7c00,%bp # bp = 0x7c00
271 movb PhysicalDrive(%bp), %dl # dl = Drive Number
272 movb %al,%ch # ch = Cylinder
273 movb %bl,%al # al = Blocks
274 movb $2,%ah # ah = Function 2
275 movw %di,%bx # es:bx = Buffer address
281 addl %ebx,%esi # StartLBA = StartLBA + NumberOfBlocks
282 subw %bx,%cx # Blocks = Blocks - NumberOfBlocks
284 shlw $(BLOCK_SHIFT-4), %bx
286 movw %ax,%es # es:di = es:di + NumberOfBlocks*BLOCK_SIZE
297 jmp PrintStringAndHalt
309 .byte 'S', 0x0c, 'E', 0x0c, 'r', 0x0c, 'r', 0x0c, 'o', 0x0c, 'r', 0x0c, '!',0x0c
312 LBAOffsetForBootSector:
318 #******************************************************************************
319 #******************************************************************************
320 #******************************************************************************
322 .equ DELAY_PORT, 0x0ed # Port to use for 1uS delay
323 .equ KBD_CONTROL_PORT, 0x060 # 8042 control port
324 .equ KBD_STATUS_PORT, 0x064 # 8042 status port
325 .equ WRITE_DATA_PORT_CMD, 0x0d1 # 8042 command to write the data port
326 .equ ENABLE_A20_CMD, 0x0df # 8042 command to enable A20
331 .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
342 # mov byte ptr es:[160],'a'
351 movl $0x534d4150, %edx # SMAP
360 subl %eax,%edi # Get the address of the memory map
361 movl %edi, MemoryMapSize # Save the size of the memory map
364 movw %cs,%bx # BX=segment
365 shll $4,%ebx # BX="linear" address of segment base
366 leal GDT_BASE(%ebx), %eax # EAX=PHYSICAL address of gdt
367 movl %eax, (gdtr + 2) # Put address of gdt into the gdtr
368 leal IDT_BASE(%ebx), %eax # EAX=PHYSICAL address of idt
369 movl %eax, (idtr + 2) # Put address of idt into the idtr
370 leal MemoryMapSize(%ebx), %edx # Physical base address of the memory map
374 # mov byte ptr es:[162],'b'
382 movw $0x2401,%ax # Enable A20 Gate
384 jnc A20GateEnabled # Jump if it suceeded
387 # If INT 15 Function 2401 is not supported, then attempt to Enable A20 manually.
390 call Empty8042InputBuffer # Empty the Input Buffer on the 8042 controller
391 jnz Timeout8042 # Jump if the 8042 timed out
392 outw %ax, $DELAY_PORT # Delay 1 uS
393 movb $WRITE_DATA_PORT_CMD, %al # 8042 cmd to write output port
394 outb %al, $KBD_STATUS_PORT # Send command to the 8042
395 call Empty8042InputBuffer # Empty the Input Buffer on the 8042 controller
396 jnz Timeout8042 # Jump if the 8042 timed out
397 movb $ENABLE_A20_CMD, %al # gate address bit 20 on
398 outb %al, $KBD_CONTROL_PORT # Send command to thre 8042
399 call Empty8042InputBuffer # Empty the Input Buffer on the 8042 controller
400 movw $25,%cx # Delay 25 uS for the command to complete on the 8042
402 outw %ax, $DELAY_PORT # Delay 1 uS
410 # DISABLE INTERRUPTS - Entering Protected Mode
417 # mov byte ptr es:[164],'c'
421 leal OffsetIn32BitProtectedMode, %eax
422 addl $0x20000+0x6,%eax
423 movl %eax, OffsetIn32BitProtectedMode
425 leal OffsetInLongMode, %eax
426 addl $0x20000+0x6,%eax
427 movl %eax, OffsetInLongMode
436 # Enable Protect Mode (set CR0.PE=1)
438 movl %cr0, %eax # Read CR0.
439 orl $0x1,%eax # Set PE=1
440 movl %eax, %cr0 # Write CR0.
442 .byte 0xea # jmp far 16:32
443 OffsetIn32BitProtectedMode:
444 .long 0x0000000 # offset $+8 (In32BitProtectedMode)
445 .word 0x10 # selector (flat CS)
446 In32BitProtectedMode:
458 # Enable the 64-bit page-translation-table entries by
459 # setting CR4.PAE=1 (this is _required_ before activating
460 # long mode). Paging is not enabled until after long mode
474 # This is the Trapolean Page Tables that are guarenteed
478 # 10000 ~ 12000 - efildr (loaded)
479 # 20000 ~ 21000 - start64.com
480 # 21000 ~ 22000 - efi64.com
481 # 22000 ~ 90000 - efildr
482 # 90000 ~ 96000 - 4G pagetable (will be reload later)
490 # Enable long mode (set EFER.LME=1).
494 # mov ecx, 0c0000080h ; EFER MSR number.
502 # bts eax, 8 ; Set LME=1.
505 # wrmsr ; Write EFER.
508 # Enable paging to activate long mode (set CR0.PG=1)
510 movl %cr0, %eax # Read CR0.
515 # bts eax, 31 ; Set PG=1.
516 movl %eax, %cr0 # Write CR0.
521 .byte 0xea # Far Jump $+9:Selector to reload CS
523 .long 00000000 # $+9 Offset is ensuing instruction boundary
524 .word 0x38 # Selector is our code selector, 38h
539 # mov ebp,000400000h ; Destination of EFILDR32
542 # mov ebx,000070000h ; Length of copy
561 # lidt fword ptr [rax]
574 Empty8042InputBuffer:
577 outw %ax, $DELAY_PORT # Delay 1us
578 inb $KBD_STATUS_PORT, %al # Read the 8042 Status Port
579 andb $0x2,%al # Check the Input Buffer Full Flag
580 loopnz Empty8042Loop # Loop until the input buffer is empty or a timout of 65536 uS
583 ##############################################################################
585 ##############################################################################
589 gdtr: .long GDT_END - GDT_BASE - 1 # GDT limit
590 .long 0 # (GDT base gets set above)
591 ##############################################################################
592 # global descriptor table (GDT)
593 ##############################################################################
599 .equ NULL_SEL, .-GDT_BASE # Selector [0x0]
604 .byte 0 # limit 19:16, flags
607 # linear data segment descriptor
608 .equ LINEAR_SEL, .-GDT_BASE # Selector [0x8]
609 .word 0xFFFF # limit 0xFFFFF
612 .byte 0x92 # present, ring 0, data, expand-up, writable
613 .byte 0xCF # page-granular, 32-bit
616 # linear code segment descriptor
617 .equ LINEAR_CODE_SEL, .-GDT_BASE # Selector [0x10]
618 .word 0xFFFF # limit 0xFFFFF
621 .byte 0x9A # present, ring 0, data, expand-up, writable
622 .byte 0xCF # page-granular, 32-bit
625 # system data segment descriptor
626 .equ SYS_DATA_SEL, .-GDT_BASE # Selector [0x18]
627 .word 0xFFFF # limit 0xFFFFF
630 .byte 0x92 # present, ring 0, data, expand-up, writable
631 .byte 0xCF # page-granular, 32-bit
634 # system code segment descriptor
635 .equ SYS_CODE_SEL, .-GDT_BASE # Selector [0x20]
636 .word 0xFFFF # limit 0xFFFFF
639 .byte 0x9A # present, ring 0, data, expand-up, writable
640 .byte 0xCF # page-granular, 32-bit
643 # spare segment descriptor
644 .equ SPARE3_SEL, .-GDT_BASE # Selector [0x28]
645 .word 0 # limit 0xFFFFF
648 .byte 0 # present, ring 0, data, expand-up, writable
649 .byte 0 # page-granular, 32-bit
653 # system data segment descriptor
655 .equ SYS_DATA64_SEL, .-GDT_BASE # Selector [0x30]
656 .word 0xFFFF # limit 0xFFFFF
659 .byte 0x92 # P | DPL [1..2] | 1 | 1 | C | R | A
660 .byte 0xCF # G | D | L | AVL | Segment [19..16]
664 # system code segment descriptor
666 .equ SYS_CODE64_SEL, .-GDT_BASE # Selector [0x38]
667 .word 0xFFFF # limit 0xFFFFF
670 .byte 0x9A # P | DPL [1..2] | 1 | 1 | C | R | A
671 .byte 0xAF # G | D | L | AVL | Segment [19..16]
674 # spare segment descriptor
675 .equ SPARE4_SEL, .-GDT_BASE # Selector [0x40]
676 .word 0 # limit 0xFFFFF
679 .byte 0 # present, ring 0, data, expand-up, writable
680 .byte 0 # page-granular, 32-bit
689 idtr: .long IDT_END - IDT_BASE - 1 # IDT limit
690 .quad 0 # (IDT base gets set above)
692 ##############################################################################
693 # interrupt descriptor table (IDT)
695 # Note: The hardware IRQ's specified in this table are the normal PC/AT IRQ
696 # mappings. This implementation only uses the system timer and all other
697 # IRQs will remain masked. The descriptors for vectors 33+ are provided
699 ##############################################################################
706 # divide by zero (INT 0)
707 .equ DIV_ZERO_SEL, .-IDT_BASE
708 .word 0 # offset 15:0
709 .long SYS_CODE64_SEL # selector 15:0
710 .byte 0 # 0 for interrupt gate
711 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
712 .word 0 # offset 31:16
713 .long 0 # offset 63:32
714 .long 0 # 0 for reserved
716 # debug exception (INT 1)
717 .equ DEBUG_EXCEPT_SEL, .-IDT_BASE
718 .word 0 # offset 15:0
719 .long SYS_CODE64_SEL # selector 15:0
720 .byte 0 # 0 for interrupt gate
721 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
722 .word 0 # offset 31:16
723 .long 0 # offset 63:32
724 .long 0 # 0 for reserved
727 .equ NMI_SEL, .-IDT_BASE
728 .word 0 # offset 15:0
729 .long SYS_CODE64_SEL # selector 15:0
730 .byte 0 # 0 for interrupt gate
731 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
732 .word 0 # offset 31:16
733 .long 0 # offset 63:32
734 .long 0 # 0 for reserved
736 # soft breakpoint (INT 3)
737 .equ BREAKPOINT_SEL, .-IDT_BASE
738 .word 0 # offset 15:0
739 .long SYS_CODE64_SEL # selector 15:0
740 .byte 0 # 0 for interrupt gate
741 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
742 .word 0 # offset 31:16
743 .long 0 # offset 63:32
744 .long 0 # 0 for reserved
747 .equ OVERFLOW_SEL, .-IDT_BASE
748 .word 0 # offset 15:0
749 .long SYS_CODE64_SEL # selector 15:0
750 .byte 0 # 0 for interrupt gate
751 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
752 .word 0 # offset 31:16
753 .long 0 # offset 63:32
754 .long 0 # 0 for reserved
756 # bounds check (INT 5)
757 .equ BOUNDS_CHECK_SEL, .-IDT_BASE
758 .word 0 # offset 15:0
759 .long SYS_CODE64_SEL # selector 15:0
760 .byte 0 # 0 for interrupt gate
761 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
762 .word 0 # offset 31:16
763 .long 0 # offset 63:32
764 .long 0 # 0 for reserved
766 # invalid opcode (INT 6)
767 .equ INVALID_OPCODE_SEL, .-IDT_BASE
768 .word 0 # offset 15:0
769 .long SYS_CODE64_SEL # selector 15:0
770 .byte 0 # 0 for interrupt gate
771 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
772 .word 0 # offset 31:16
773 .long 0 # offset 63:32
774 .long 0 # 0 for reserved
776 # device not available (INT 7)
777 .equ DEV_NOT_AVAIL_SEL, .-IDT_BASE
778 .word 0 # offset 15:0
779 .long SYS_CODE64_SEL # selector 15:0
780 .byte 0 # 0 for interrupt gate
781 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
782 .word 0 # offset 31:16
783 .long 0 # offset 63:32
784 .long 0 # 0 for reserved
786 # double fault (INT 8)
787 .equ DOUBLE_FAULT_SEL, .-IDT_BASE
788 .word 0 # offset 15:0
789 .long SYS_CODE64_SEL # selector 15:0
790 .byte 0 # 0 for interrupt gate
791 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
792 .word 0 # offset 31:16
793 .long 0 # offset 63:32
794 .long 0 # 0 for reserved
796 # Coprocessor segment overrun - reserved (INT 9)
797 .equ RSVD_INTR_SEL1, .-IDT_BASE
798 .word 0 # offset 15:0
799 .long SYS_CODE64_SEL # selector 15:0
800 .byte 0 # 0 for interrupt gate
801 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
802 .word 0 # offset 31:16
803 .long 0 # offset 63:32
804 .long 0 # 0 for reserved
806 # invalid TSS (INT 0ah)
807 .equ INVALID_TSS_SEL, .-IDT_BASE
808 .word 0 # offset 15:0
809 .long SYS_CODE64_SEL # selector 15:0
810 .byte 0 # 0 for interrupt gate
811 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
812 .word 0 # offset 31:16
813 .long 0 # offset 63:32
814 .long 0 # 0 for reserved
816 # segment not present (INT 0bh)
817 .equ SEG_NOT_PRESENT_SEL, .-IDT_BASE
818 .word 0 # offset 15:0
819 .long SYS_CODE64_SEL # selector 15:0
820 .byte 0 # 0 for interrupt gate
821 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
822 .word 0 # offset 31:16
823 .long 0 # offset 63:32
824 .long 0 # 0 for reserved
826 # stack fault (INT 0ch)
827 .equ STACK_FAULT_SEL, .-IDT_BASE
828 .word 0 # offset 15:0
829 .long SYS_CODE64_SEL # selector 15:0
830 .byte 0 # 0 for interrupt gate
831 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
832 .word 0 # offset 31:16
833 .long 0 # offset 63:32
834 .long 0 # 0 for reserved
836 # general protection (INT 0dh)
837 .equ GP_FAULT_SEL, .-IDT_BASE
838 .word 0 # offset 15:0
839 .long SYS_CODE64_SEL # selector 15:0
840 .byte 0 # 0 for interrupt gate
841 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
842 .word 0 # offset 31:16
843 .long 0 # offset 63:32
844 .long 0 # 0 for reserved
846 # page fault (INT 0eh)
847 .equ PAGE_FAULT_SEL, .-IDT_BASE
848 .word 0 # offset 15:0
849 .long SYS_CODE64_SEL # selector 15:0
850 .byte 0 # 0 for interrupt gate
851 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
852 .word 0 # offset 31:16
853 .long 0 # offset 63:32
854 .long 0 # 0 for reserved
856 # Intel reserved - do not use (INT 0fh)
857 .equ RSVD_INTR_SEL2, .-IDT_BASE
858 .word 0 # offset 15:0
859 .long SYS_CODE64_SEL # selector 15:0
860 .byte 0 # 0 for interrupt gate
861 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
862 .word 0 # offset 31:16
863 .long 0 # offset 63:32
864 .long 0 # 0 for reserved
866 # floating point error (INT 10h)
867 .equ FLT_POINT_ERR_SEL, .-IDT_BASE
868 .word 0 # offset 15:0
869 .long SYS_CODE64_SEL # selector 15:0
870 .byte 0 # 0 for interrupt gate
871 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
872 .word 0 # offset 31:16
873 .long 0 # offset 63:32
874 .long 0 # 0 for reserved
876 # alignment check (INT 11h)
877 .equ ALIGNMENT_CHECK_SEL, .-IDT_BASE
878 .word 0 # offset 15:0
879 .long SYS_CODE64_SEL # selector 15:0
880 .byte 0 # 0 for interrupt gate
881 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
882 .word 0 # offset 31:16
883 .long 0 # offset 63:32
884 .long 0 # 0 for reserved
886 # machine check (INT 12h)
887 .equ MACHINE_CHECK_SEL, .-IDT_BASE
888 .word 0 # offset 15:0
889 .long SYS_CODE64_SEL # selector 15:0
890 .byte 0 # 0 for interrupt gate
891 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
892 .word 0 # offset 31:16
893 .long 0 # offset 63:32
894 .long 0 # 0 for reserved
896 # SIMD floating-point exception (INT 13h)
897 .equ SIMD_EXCEPTION_SEL, .-IDT_BASE
898 .word 0 # offset 15:0
899 .long SYS_CODE64_SEL # selector 15:0
900 .byte 0 # 0 for interrupt gate
901 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
902 .word 0 # offset 31:16
903 .long 0 # offset 63:32
904 .long 0 # 0 for reserved
906 # 85 unspecified descriptors, First 12 of them are reserved, the rest are avail
907 .fill 85 * 16, 1, 0 # db (85 * 16) dup(0)
909 # IRQ 0 (System timer) - (INT 68h)
910 .equ IRQ0_SEL, .-IDT_BASE
911 .word 0 # offset 15:0
912 .long SYS_CODE64_SEL # selector 15:0
913 .byte 0 # 0 for interrupt gate
914 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
915 .word 0 # offset 31:16
916 .long 0 # offset 63:32
917 .long 0 # 0 for reserved
919 # IRQ 1 (8042 Keyboard controller) - (INT 69h)
920 .equ IRQ1_SEL, .-IDT_BASE
921 .word 0 # offset 15:0
922 .long SYS_CODE64_SEL # selector 15:0
923 .byte 0 # 0 for interrupt gate
924 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
925 .word 0 # offset 31:16
926 .long 0 # offset 63:32
927 .long 0 # 0 for reserved
929 # Reserved - IRQ 2 redirect (IRQ 2) - DO NOT USE!!! - (INT 6ah)
930 .equ IRQ2_SEL, .-IDT_BASE
931 .word 0 # offset 15:0
932 .long SYS_CODE64_SEL # selector 15:0
933 .byte 0 # 0 for interrupt gate
934 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
935 .word 0 # offset 31:16
936 .long 0 # offset 63:32
937 .long 0 # 0 for reserved
939 # IRQ 3 (COM 2) - (INT 6bh)
940 .equ IRQ3_SEL, .-IDT_BASE
941 .word 0 # offset 15:0
942 .long SYS_CODE64_SEL # selector 15:0
943 .byte 0 # 0 for interrupt gate
944 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
945 .word 0 # offset 31:16
946 .long 0 # offset 63:32
947 .long 0 # 0 for reserved
949 # IRQ 4 (COM 1) - (INT 6ch)
950 .equ IRQ4_SEL, .-IDT_BASE
951 .word 0 # offset 15:0
952 .long SYS_CODE64_SEL # selector 15:0
953 .byte 0 # 0 for interrupt gate
954 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
955 .word 0 # offset 31:16
956 .long 0 # offset 63:32
957 .long 0 # 0 for reserved
959 # IRQ 5 (LPT 2) - (INT 6dh)
960 .equ IRQ5_SEL, .-IDT_BASE
961 .word 0 # offset 15:0
962 .long SYS_CODE64_SEL # selector 15:0
963 .byte 0 # 0 for interrupt gate
964 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
965 .word 0 # offset 31:16
966 .long 0 # offset 63:32
967 .long 0 # 0 for reserved
969 # IRQ 6 (Floppy controller) - (INT 6eh)
970 .equ IRQ6_SEL, .-IDT_BASE
971 .word 0 # offset 15:0
972 .long SYS_CODE64_SEL # selector 15:0
973 .byte 0 # 0 for interrupt gate
974 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
975 .word 0 # offset 31:16
976 .long 0 # offset 63:32
977 .long 0 # 0 for reserved
979 # IRQ 7 (LPT 1) - (INT 6fh)
980 .equ IRQ7_SEL, .-IDT_BASE
981 .word 0 # offset 15:0
982 .long SYS_CODE64_SEL # selector 15:0
983 .byte 0 # 0 for interrupt gate
984 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
985 .word 0 # offset 31:16
986 .long 0 # offset 63:32
987 .long 0 # 0 for reserved
989 # IRQ 8 (RTC Alarm) - (INT 70h)
990 .equ IRQ8_SEL, .-IDT_BASE
991 .word 0 # offset 15:0
992 .long SYS_CODE64_SEL # selector 15:0
993 .byte 0 # 0 for interrupt gate
994 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
995 .word 0 # offset 31:16
996 .long 0 # offset 63:32
997 .long 0 # 0 for reserved
1000 .equ IRQ9_SEL, .-IDT_BASE
1001 .word 0 # offset 15:0
1002 .long SYS_CODE64_SEL # selector 15:0
1003 .byte 0 # 0 for interrupt gate
1004 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
1005 .word 0 # offset 31:16
1006 .long 0 # offset 63:32
1007 .long 0 # 0 for reserved
1009 # IRQ 10 - (INT 72h)
1010 .equ IRQ10_SEL, .-IDT_BASE
1011 .word 0 # offset 15:0
1012 .long SYS_CODE64_SEL # selector 15:0
1013 .byte 0 # 0 for interrupt gate
1014 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
1015 .word 0 # offset 31:16
1016 .long 0 # offset 63:32
1017 .long 0 # 0 for reserved
1019 # IRQ 11 - (INT 73h)
1020 .equ IRQ11_SEL, .-IDT_BASE
1021 .word 0 # offset 15:0
1022 .long SYS_CODE64_SEL # selector 15:0
1023 .byte 0 # 0 for interrupt gate
1024 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
1025 .word 0 # offset 31:16
1026 .long 0 # offset 63:32
1027 .long 0 # 0 for reserved
1029 # IRQ 12 (PS/2 mouse) - (INT 74h)
1030 .equ IRQ12_SEL, .-IDT_BASE
1031 .word 0 # offset 15:0
1032 .long SYS_CODE64_SEL # selector 15:0
1033 .byte 0 # 0 for interrupt gate
1034 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
1035 .word 0 # offset 31:16
1036 .long 0 # offset 63:32
1037 .long 0 # 0 for reserved
1039 # IRQ 13 (Floating point error) - (INT 75h)
1040 .equ IRQ13_SEL, .-IDT_BASE
1041 .word 0 # offset 15:0
1042 .long SYS_CODE64_SEL # selector 15:0
1043 .byte 0 # 0 for interrupt gate
1044 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
1045 .word 0 # offset 31:16
1046 .long 0 # offset 63:32
1047 .long 0 # 0 for reserved
1049 # IRQ 14 (Secondary IDE) - (INT 76h)
1050 .equ IRQ14_SEL, .-IDT_BASE
1051 .word 0 # offset 15:0
1052 .long SYS_CODE64_SEL # selector 15:0
1053 .byte 0 # 0 for interrupt gate
1054 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
1055 .word 0 # offset 31:16
1056 .long 0 # offset 63:32
1057 .long 0 # 0 for reserved
1059 # IRQ 15 (Primary IDE) - (INT 77h)
1060 .equ IRQ15_SEL, .-IDT_BASE
1061 .word 0 # offset 15:0
1062 .long SYS_CODE64_SEL # selector 15:0
1063 .byte 0 # 0 for interrupt gate
1064 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
1065 .word 0 # offset 31:16
1066 .long 0 # offset 63:32
1067 .long 0 # 0 for reserved
1073 MemoryMapSize: .long 0
1074 MemoryMap: .long 0,0,0,0,0,0,0,0
1075 .long 0,0,0,0,0,0,0,0
1076 .long 0,0,0,0,0,0,0,0
1077 .long 0,0,0,0,0,0,0,0
1078 .long 0,0,0,0,0,0,0,0
1079 .long 0,0,0,0,0,0,0,0
1080 .long 0,0,0,0,0,0,0,0
1081 .long 0,0,0,0,0,0,0,0
1082 .long 0,0,0,0,0,0,0,0
1083 .long 0,0,0,0,0,0,0,0
1084 .long 0,0,0,0,0,0,0,0
1085 .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
1105 .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
1109 # below is the pieces of the IVT that is used to redirect INT 68h - 6fh
1110 # back to INT 08h - 0fh when in real mode... It is 'org'ed to a
1111 # known low address (20f00) so it can be set up by PlMapIrqToVect in