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 "FAT12 " # 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)
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 $0xff8,%ax # ax = ax & 0xff8
164 cmpw $0xff8,%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 # ax = ClusterNumber * 2
168 addw %cx,%ax # ax = ClusterNumber * 2 + ClusterNumber = ClusterNumber * 3
169 shrw %ax # FatOffset = ClusterNumber*3 / 2
171 movw %ax,%si # si = FatOffset
172 shrw $BLOCK_SHIFT, %ax # ax = FatOffset >> BLOCK_SHIFT
173 addw ReservedSectors(%bp), %ax # ax = FatSectorNumber = ReservedSectors + (FatOffset >> BLOCK_OFFSET)
174 andw $BLOCK_MASK, %si # si = FatOffset & BLOCK_MASK
175 cmpw %dx,%ax # Compare FatSectorNumber to CachedFatSectorNumber
181 call ReadBlocks # Read 2 blocks starting at AX storing at ES:DI
183 movw %ax,%dx # CachedFatSectorNumber = FatSectorNumber
185 movw (%si), %bx # bx = NextClusterNumber
186 movw %cx,%ax # ax = ClusterNumber
187 andw $1,%ax # See if this is an odd cluster number
189 shrw $4,%bx # NextClusterNumber = NextClusterNumber >> 4
191 andw $0xfff,%bx # Strip upper 4 bits of NextClusterNumber
192 popw %si # Restore si
193 decw %bx # bx = NextClusterNumber - 1
194 cmpw %cx,%bx # See if (NextClusterNumber-1)==ClusterNumber
196 incw %bx # bx = NextClusterNumber
197 incw %si # NumberOfClusters++
198 movw %bx,%cx # ClusterNumber = NextClusterNumber
202 popw %ax # ax = StartCluster
203 pushw %bx # StartCluster = NextClusterNumber
204 movw %bx,%cx # ClusterNumber = NextClusterNumber
205 subw $2,%ax # ax = StartCluster - 2
207 movb SectorsPerCluster(%bp), %bl # bx = SectorsPerCluster
208 mulw %bx # ax = (StartCluster - 2) * SectorsPerCluster
209 addw (%bp), %ax # ax = FirstClusterLBA + (StartCluster-2)*SectorsPerCluster
210 pushw %ax # save start sector
211 movw %si,%ax # ax = NumberOfClusters
212 mulw %bx # ax = NumberOfClusters * SectorsPerCluster
213 movw %ax,%bx # bx = Number of Sectors
214 popw %ax # ax = Start Sector
216 movw $1,%si # NumberOfClusters = 1
224 # ****************************************************************************
225 # ReadBlocks - Reads a set of blocks from a block device
228 # BX = Number of Blocks to Read
229 # ES:DI = Buffer to store sectors read from disk
230 # ****************************************************************************
233 # bx = NumberOfBlocks
238 addl LBAOffsetForBootSector(%bp), %eax # Add LBAOffsetForBootSector to Start LBA
239 addl HiddenSectors(%bp), %eax # Add HiddenSectors to Start LBA
240 movl %eax,%esi # esi = Start LBA
241 movw %bx,%cx # cx = Number of blocks to read
243 movw $0x7bfc,%bp # bp = 0x7bfc
244 movl %esi,%eax # eax = Start LBA
245 xorl %edx,%edx # edx = 0
246 movzwl (%bp), %ebx # bx = MaxSector
247 divl %ebx # ax = StartLBA / MaxSector
248 incw %dx # dx = (StartLBA % MaxSector) + 1
250 movw (%bp), %bx # bx = MaxSector
251 subw %dx,%bx # bx = MaxSector - Sector
252 incw %bx # bx = MaxSector - Sector + 1
253 cmpw %bx,%cx # Compare (Blocks) to (MaxSector - Sector + 1)
255 movw %cx,%bx # bx = Blocks
258 movw %es,%ax # ax = es
259 shrw $(BLOCK_SHIFT-4), %ax # ax = Number of blocks into mem system
260 andw $0x7f,%ax # ax = Number of blocks into current seg
261 addw %bx,%ax # ax = End Block number of transfer
262 cmpw $0x80,%ax # See if it crosses a 64K boundry
263 jle NotCrossing64KBoundry # Branch if not crossing 64K boundry
264 subw $0x80,%ax # ax = Number of blocks past 64K boundry
265 subw %ax,%bx # Decrease transfer size by block overage
266 NotCrossing64KBoundry:
267 popw %ax # restore ax
270 movb %dl,%cl # cl = (StartLBA % MaxSector) + 1 = Sector
271 xorw %dx,%dx # dx = 0
272 divw 2(%bp) # ax = ax / (MaxHead + 1) = Cylinder
273 # dx = ax % (MaxHead + 1) = Head
275 pushw %bx # Save number of blocks to transfer
276 movb %dl,%dh # dh = Head
277 movw $0x7c00,%bp # bp = 0x7c00
278 movb PhysicalDrive(%bp), %dl # dl = Drive Number
279 movb %al,%ch # ch = Cylinder
280 movb %bl,%al # al = Blocks
281 movb $2,%ah # ah = Function 2
282 movw %di,%bx # es:bx = Buffer address
288 addl %ebx,%esi # StartLBA = StartLBA + NumberOfBlocks
289 subw %bx,%cx # Blocks = Blocks - NumberOfBlocks
291 shlw $(BLOCK_SHIFT-4), %bx
293 movw %ax,%es # es:di = es:di + NumberOfBlocks*BLOCK_SIZE
304 jmp PrintStringAndHalt
316 .byte 'S', 0x0c, 'E', 0x0c, 'r', 0x0c, 'r', 0x0c, 'o', 0x0c, 'r', 0x0c, '!',0x0c
319 LBAOffsetForBootSector:
325 #******************************************************************************
326 #******************************************************************************
327 #******************************************************************************
329 .equ DELAY_PORT, 0x0ed # Port to use for 1uS delay
330 .equ KBD_CONTROL_PORT, 0x060 # 8042 control port
331 .equ KBD_STATUS_PORT, 0x064 # 8042 status port
332 .equ WRITE_DATA_PORT_CMD, 0x0d1 # 8042 command to write the data port
333 .equ ENABLE_A20_CMD, 0x0df # 8042 command to enable A20
338 .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
349 # mov byte ptr es:[160],'a'
358 movl $0x534d4150, %edx # SMAP
367 subl %eax,%edi # Get the address of the memory map
368 movl %edi, MemoryMapSize # Save the size of the memory map
371 movw %cs,%bx # BX=segment
372 shll $4,%ebx # BX="linear" address of segment base
373 leal GDT_BASE(%ebx), %eax # EAX=PHYSICAL address of gdt
374 movl %eax, (gdtr + 2) # Put address of gdt into the gdtr
375 leal IDT_BASE(%ebx), %eax # EAX=PHYSICAL address of idt
376 movl %eax, (idtr + 2) # Put address of idt into the idtr
377 leal MemoryMapSize(%ebx), %edx # Physical base address of the memory map
381 # mov byte ptr es:[162],'b'
389 movw $0x2401,%ax # Enable A20 Gate
391 jnc A20GateEnabled # Jump if it suceeded
394 # If INT 15 Function 2401 is not supported, then attempt to Enable A20 manually.
397 call Empty8042InputBuffer # Empty the Input Buffer on the 8042 controller
398 jnz Timeout8042 # Jump if the 8042 timed out
399 outw %ax, $DELAY_PORT # Delay 1 uS
400 movb $WRITE_DATA_PORT_CMD, %al # 8042 cmd to write output port
401 outb %al, $KBD_STATUS_PORT # Send command to the 8042
402 call Empty8042InputBuffer # Empty the Input Buffer on the 8042 controller
403 jnz Timeout8042 # Jump if the 8042 timed out
404 movb $ENABLE_A20_CMD, %al # gate address bit 20 on
405 outb %al, $KBD_CONTROL_PORT # Send command to thre 8042
406 call Empty8042InputBuffer # Empty the Input Buffer on the 8042 controller
407 movw $25,%cx # Delay 25 uS for the command to complete on the 8042
409 outw %ax, $DELAY_PORT # Delay 1 uS
417 # DISABLE INTERRUPTS - Entering Protected Mode
424 # mov byte ptr es:[164],'c'
428 leal OffsetIn32BitProtectedMode, %eax
429 addl $0x20000+0x6,%eax
430 movl %eax, OffsetIn32BitProtectedMode
432 leal OffsetInLongMode, %eax
433 addl $0x20000+0x6,%eax
434 movl %eax, OffsetInLongMode
443 # Enable Protect Mode (set CR0.PE=1)
445 movl %cr0, %eax # Read CR0.
446 orl $0x1,%eax # Set PE=1
447 movl %eax, %cr0 # Write CR0.
449 .byte 0xea # jmp far 16:32
450 OffsetIn32BitProtectedMode:
451 .long 0x0000000 # offset $+8 (In32BitProtectedMode)
452 .word 0x10 # selector (flat CS)
453 In32BitProtectedMode:
465 # Enable the 64-bit page-translation-table entries by
466 # setting CR4.PAE=1 (this is _required_ before activating
467 # long mode). Paging is not enabled until after long mode
481 # This is the Trapolean Page Tables that are guarenteed
485 # 10000 ~ 12000 - efildr (loaded)
486 # 20000 ~ 21000 - start64.com
487 # 21000 ~ 22000 - efi64.com
488 # 22000 ~ 90000 - efildr
489 # 90000 ~ 96000 - 4G pagetable (will be reload later)
497 # Enable long mode (set EFER.LME=1).
501 # mov ecx, 0c0000080h ; EFER MSR number.
509 # bts eax, 8 ; Set LME=1.
512 # wrmsr ; Write EFER.
515 # Enable paging to activate long mode (set CR0.PG=1)
517 movl %cr0, %eax # Read CR0.
522 # bts eax, 31 ; Set PG=1.
523 movl %eax, %cr0 # Write CR0.
528 .byte 0xea # Far Jump $+9:Selector to reload CS
530 .long 00000000 # $+9 Offset is ensuing instruction boundary
531 .word 0x38 # Selector is our code selector, 38h
546 # mov ebp,000400000h ; Destination of EFILDR32
549 # mov ebx,000070000h ; Length of copy
568 # lidt fword ptr [rax]
581 Empty8042InputBuffer:
584 outw %ax, $DELAY_PORT # Delay 1us
585 inb $KBD_STATUS_PORT, %al # Read the 8042 Status Port
586 andb $0x2,%al # Check the Input Buffer Full Flag
587 loopnz Empty8042Loop # Loop until the input buffer is empty or a timout of 65536 uS
590 ##############################################################################
592 ##############################################################################
596 gdtr: .long GDT_END - GDT_BASE - 1 # GDT limit
597 .long 0 # (GDT base gets set above)
598 ##############################################################################
599 # global descriptor table (GDT)
600 ##############################################################################
606 .equ NULL_SEL, .-GDT_BASE # Selector [0x0]
611 .byte 0 # limit 19:16, flags
614 # linear data segment descriptor
615 .equ LINEAR_SEL, .-GDT_BASE # Selector [0x8]
616 .word 0xFFFF # limit 0xFFFFF
619 .byte 0x92 # present, ring 0, data, expand-up, writable
620 .byte 0xCF # page-granular, 32-bit
623 # linear code segment descriptor
624 .equ LINEAR_CODE_SEL, .-GDT_BASE # Selector [0x10]
625 .word 0xFFFF # limit 0xFFFFF
628 .byte 0x9A # present, ring 0, data, expand-up, writable
629 .byte 0xCF # page-granular, 32-bit
632 # system data segment descriptor
633 .equ SYS_DATA_SEL, .-GDT_BASE # Selector [0x18]
634 .word 0xFFFF # limit 0xFFFFF
637 .byte 0x92 # present, ring 0, data, expand-up, writable
638 .byte 0xCF # page-granular, 32-bit
641 # system code segment descriptor
642 .equ SYS_CODE_SEL, .-GDT_BASE # Selector [0x20]
643 .word 0xFFFF # limit 0xFFFFF
646 .byte 0x9A # present, ring 0, data, expand-up, writable
647 .byte 0xCF # page-granular, 32-bit
650 # spare segment descriptor
651 .equ SPARE3_SEL, .-GDT_BASE # Selector [0x28]
652 .word 0 # limit 0xFFFFF
655 .byte 0 # present, ring 0, data, expand-up, writable
656 .byte 0 # page-granular, 32-bit
660 # system data segment descriptor
662 .equ SYS_DATA64_SEL, .-GDT_BASE # Selector [0x30]
663 .word 0xFFFF # limit 0xFFFFF
666 .byte 0x92 # P | DPL [1..2] | 1 | 1 | C | R | A
667 .byte 0xCF # G | D | L | AVL | Segment [19..16]
671 # system code segment descriptor
673 .equ SYS_CODE64_SEL, .-GDT_BASE # Selector [0x38]
674 .word 0xFFFF # limit 0xFFFFF
677 .byte 0x9A # P | DPL [1..2] | 1 | 1 | C | R | A
678 .byte 0xAF # G | D | L | AVL | Segment [19..16]
681 # spare segment descriptor
682 .equ SPARE4_SEL, .-GDT_BASE # Selector [0x40]
683 .word 0 # limit 0xFFFFF
686 .byte 0 # present, ring 0, data, expand-up, writable
687 .byte 0 # page-granular, 32-bit
696 idtr: .long IDT_END - IDT_BASE - 1 # IDT limit
697 .quad 0 # (IDT base gets set above)
699 ##############################################################################
700 # interrupt descriptor table (IDT)
702 # Note: The hardware IRQ's specified in this table are the normal PC/AT IRQ
703 # mappings. This implementation only uses the system timer and all other
704 # IRQs will remain masked. The descriptors for vectors 33+ are provided
706 ##############################################################################
713 # divide by zero (INT 0)
714 .equ DIV_ZERO_SEL, .-IDT_BASE
715 .word 0 # offset 15:0
716 .long SYS_CODE64_SEL # selector 15:0
717 .byte 0 # 0 for interrupt gate
718 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
719 .word 0 # offset 31:16
720 .long 0 # offset 63:32
721 .long 0 # 0 for reserved
723 # debug exception (INT 1)
724 .equ DEBUG_EXCEPT_SEL, .-IDT_BASE
725 .word 0 # offset 15:0
726 .long SYS_CODE64_SEL # selector 15:0
727 .byte 0 # 0 for interrupt gate
728 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
729 .word 0 # offset 31:16
730 .long 0 # offset 63:32
731 .long 0 # 0 for reserved
734 .equ NMI_SEL, .-IDT_BASE
735 .word 0 # offset 15:0
736 .long SYS_CODE64_SEL # selector 15:0
737 .byte 0 # 0 for interrupt gate
738 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
739 .word 0 # offset 31:16
740 .long 0 # offset 63:32
741 .long 0 # 0 for reserved
743 # soft breakpoint (INT 3)
744 .equ BREAKPOINT_SEL, .-IDT_BASE
745 .word 0 # offset 15:0
746 .long SYS_CODE64_SEL # selector 15:0
747 .byte 0 # 0 for interrupt gate
748 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
749 .word 0 # offset 31:16
750 .long 0 # offset 63:32
751 .long 0 # 0 for reserved
754 .equ OVERFLOW_SEL, .-IDT_BASE
755 .word 0 # offset 15:0
756 .long SYS_CODE64_SEL # selector 15:0
757 .byte 0 # 0 for interrupt gate
758 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
759 .word 0 # offset 31:16
760 .long 0 # offset 63:32
761 .long 0 # 0 for reserved
763 # bounds check (INT 5)
764 .equ BOUNDS_CHECK_SEL, .-IDT_BASE
765 .word 0 # offset 15:0
766 .long SYS_CODE64_SEL # selector 15:0
767 .byte 0 # 0 for interrupt gate
768 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
769 .word 0 # offset 31:16
770 .long 0 # offset 63:32
771 .long 0 # 0 for reserved
773 # invalid opcode (INT 6)
774 .equ INVALID_OPCODE_SEL, .-IDT_BASE
775 .word 0 # offset 15:0
776 .long SYS_CODE64_SEL # selector 15:0
777 .byte 0 # 0 for interrupt gate
778 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
779 .word 0 # offset 31:16
780 .long 0 # offset 63:32
781 .long 0 # 0 for reserved
783 # device not available (INT 7)
784 .equ DEV_NOT_AVAIL_SEL, .-IDT_BASE
785 .word 0 # offset 15:0
786 .long SYS_CODE64_SEL # selector 15:0
787 .byte 0 # 0 for interrupt gate
788 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
789 .word 0 # offset 31:16
790 .long 0 # offset 63:32
791 .long 0 # 0 for reserved
793 # double fault (INT 8)
794 .equ DOUBLE_FAULT_SEL, .-IDT_BASE
795 .word 0 # offset 15:0
796 .long SYS_CODE64_SEL # selector 15:0
797 .byte 0 # 0 for interrupt gate
798 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
799 .word 0 # offset 31:16
800 .long 0 # offset 63:32
801 .long 0 # 0 for reserved
803 # Coprocessor segment overrun - reserved (INT 9)
804 .equ RSVD_INTR_SEL1, .-IDT_BASE
805 .word 0 # offset 15:0
806 .long SYS_CODE64_SEL # selector 15:0
807 .byte 0 # 0 for interrupt gate
808 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
809 .word 0 # offset 31:16
810 .long 0 # offset 63:32
811 .long 0 # 0 for reserved
813 # invalid TSS (INT 0ah)
814 .equ INVALID_TSS_SEL, .-IDT_BASE
815 .word 0 # offset 15:0
816 .long SYS_CODE64_SEL # selector 15:0
817 .byte 0 # 0 for interrupt gate
818 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
819 .word 0 # offset 31:16
820 .long 0 # offset 63:32
821 .long 0 # 0 for reserved
823 # segment not present (INT 0bh)
824 .equ SEG_NOT_PRESENT_SEL, .-IDT_BASE
825 .word 0 # offset 15:0
826 .long SYS_CODE64_SEL # selector 15:0
827 .byte 0 # 0 for interrupt gate
828 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
829 .word 0 # offset 31:16
830 .long 0 # offset 63:32
831 .long 0 # 0 for reserved
833 # stack fault (INT 0ch)
834 .equ STACK_FAULT_SEL, .-IDT_BASE
835 .word 0 # offset 15:0
836 .long SYS_CODE64_SEL # selector 15:0
837 .byte 0 # 0 for interrupt gate
838 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
839 .word 0 # offset 31:16
840 .long 0 # offset 63:32
841 .long 0 # 0 for reserved
843 # general protection (INT 0dh)
844 .equ GP_FAULT_SEL, .-IDT_BASE
845 .word 0 # offset 15:0
846 .long SYS_CODE64_SEL # selector 15:0
847 .byte 0 # 0 for interrupt gate
848 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
849 .word 0 # offset 31:16
850 .long 0 # offset 63:32
851 .long 0 # 0 for reserved
853 # page fault (INT 0eh)
854 .equ PAGE_FAULT_SEL, .-IDT_BASE
855 .word 0 # offset 15:0
856 .long SYS_CODE64_SEL # selector 15:0
857 .byte 0 # 0 for interrupt gate
858 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
859 .word 0 # offset 31:16
860 .long 0 # offset 63:32
861 .long 0 # 0 for reserved
863 # Intel reserved - do not use (INT 0fh)
864 .equ RSVD_INTR_SEL2, .-IDT_BASE
865 .word 0 # offset 15:0
866 .long SYS_CODE64_SEL # selector 15:0
867 .byte 0 # 0 for interrupt gate
868 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
869 .word 0 # offset 31:16
870 .long 0 # offset 63:32
871 .long 0 # 0 for reserved
873 # floating point error (INT 10h)
874 .equ FLT_POINT_ERR_SEL, .-IDT_BASE
875 .word 0 # offset 15:0
876 .long SYS_CODE64_SEL # selector 15:0
877 .byte 0 # 0 for interrupt gate
878 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
879 .word 0 # offset 31:16
880 .long 0 # offset 63:32
881 .long 0 # 0 for reserved
883 # alignment check (INT 11h)
884 .equ ALIGNMENT_CHECK_SEL, .-IDT_BASE
885 .word 0 # offset 15:0
886 .long SYS_CODE64_SEL # selector 15:0
887 .byte 0 # 0 for interrupt gate
888 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
889 .word 0 # offset 31:16
890 .long 0 # offset 63:32
891 .long 0 # 0 for reserved
893 # machine check (INT 12h)
894 .equ MACHINE_CHECK_SEL, .-IDT_BASE
895 .word 0 # offset 15:0
896 .long SYS_CODE64_SEL # selector 15:0
897 .byte 0 # 0 for interrupt gate
898 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
899 .word 0 # offset 31:16
900 .long 0 # offset 63:32
901 .long 0 # 0 for reserved
903 # SIMD floating-point exception (INT 13h)
904 .equ SIMD_EXCEPTION_SEL, .-IDT_BASE
905 .word 0 # offset 15:0
906 .long SYS_CODE64_SEL # selector 15:0
907 .byte 0 # 0 for interrupt gate
908 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
909 .word 0 # offset 31:16
910 .long 0 # offset 63:32
911 .long 0 # 0 for reserved
913 # 85 unspecified descriptors, First 12 of them are reserved, the rest are avail
914 .fill 85 * 16, 1, 0 # db (85 * 16) dup(0)
916 # IRQ 0 (System timer) - (INT 68h)
917 .equ IRQ0_SEL, .-IDT_BASE
918 .word 0 # offset 15:0
919 .long SYS_CODE64_SEL # selector 15:0
920 .byte 0 # 0 for interrupt gate
921 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
922 .word 0 # offset 31:16
923 .long 0 # offset 63:32
924 .long 0 # 0 for reserved
926 # IRQ 1 (8042 Keyboard controller) - (INT 69h)
927 .equ IRQ1_SEL, .-IDT_BASE
928 .word 0 # offset 15:0
929 .long SYS_CODE64_SEL # selector 15:0
930 .byte 0 # 0 for interrupt gate
931 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
932 .word 0 # offset 31:16
933 .long 0 # offset 63:32
934 .long 0 # 0 for reserved
936 # Reserved - IRQ 2 redirect (IRQ 2) - DO NOT USE!!! - (INT 6ah)
937 .equ IRQ2_SEL, .-IDT_BASE
938 .word 0 # offset 15:0
939 .long SYS_CODE64_SEL # selector 15:0
940 .byte 0 # 0 for interrupt gate
941 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
942 .word 0 # offset 31:16
943 .long 0 # offset 63:32
944 .long 0 # 0 for reserved
946 # IRQ 3 (COM 2) - (INT 6bh)
947 .equ IRQ3_SEL, .-IDT_BASE
948 .word 0 # offset 15:0
949 .long SYS_CODE64_SEL # selector 15:0
950 .byte 0 # 0 for interrupt gate
951 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
952 .word 0 # offset 31:16
953 .long 0 # offset 63:32
954 .long 0 # 0 for reserved
956 # IRQ 4 (COM 1) - (INT 6ch)
957 .equ IRQ4_SEL, .-IDT_BASE
958 .word 0 # offset 15:0
959 .long SYS_CODE64_SEL # selector 15:0
960 .byte 0 # 0 for interrupt gate
961 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
962 .word 0 # offset 31:16
963 .long 0 # offset 63:32
964 .long 0 # 0 for reserved
966 # IRQ 5 (LPT 2) - (INT 6dh)
967 .equ IRQ5_SEL, .-IDT_BASE
968 .word 0 # offset 15:0
969 .long SYS_CODE64_SEL # selector 15:0
970 .byte 0 # 0 for interrupt gate
971 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
972 .word 0 # offset 31:16
973 .long 0 # offset 63:32
974 .long 0 # 0 for reserved
976 # IRQ 6 (Floppy controller) - (INT 6eh)
977 .equ IRQ6_SEL, .-IDT_BASE
978 .word 0 # offset 15:0
979 .long SYS_CODE64_SEL # selector 15:0
980 .byte 0 # 0 for interrupt gate
981 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
982 .word 0 # offset 31:16
983 .long 0 # offset 63:32
984 .long 0 # 0 for reserved
986 # IRQ 7 (LPT 1) - (INT 6fh)
987 .equ IRQ7_SEL, .-IDT_BASE
988 .word 0 # offset 15:0
989 .long SYS_CODE64_SEL # selector 15:0
990 .byte 0 # 0 for interrupt gate
991 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
992 .word 0 # offset 31:16
993 .long 0 # offset 63:32
994 .long 0 # 0 for reserved
996 # IRQ 8 (RTC Alarm) - (INT 70h)
997 .equ IRQ8_SEL, .-IDT_BASE
998 .word 0 # offset 15:0
999 .long SYS_CODE64_SEL # selector 15:0
1000 .byte 0 # 0 for interrupt gate
1001 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
1002 .word 0 # offset 31:16
1003 .long 0 # offset 63:32
1004 .long 0 # 0 for reserved
1007 .equ IRQ9_SEL, .-IDT_BASE
1008 .word 0 # offset 15:0
1009 .long SYS_CODE64_SEL # selector 15:0
1010 .byte 0 # 0 for interrupt gate
1011 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
1012 .word 0 # offset 31:16
1013 .long 0 # offset 63:32
1014 .long 0 # 0 for reserved
1016 # IRQ 10 - (INT 72h)
1017 .equ IRQ10_SEL, .-IDT_BASE
1018 .word 0 # offset 15:0
1019 .long SYS_CODE64_SEL # selector 15:0
1020 .byte 0 # 0 for interrupt gate
1021 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
1022 .word 0 # offset 31:16
1023 .long 0 # offset 63:32
1024 .long 0 # 0 for reserved
1026 # IRQ 11 - (INT 73h)
1027 .equ IRQ11_SEL, .-IDT_BASE
1028 .word 0 # offset 15:0
1029 .long SYS_CODE64_SEL # selector 15:0
1030 .byte 0 # 0 for interrupt gate
1031 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
1032 .word 0 # offset 31:16
1033 .long 0 # offset 63:32
1034 .long 0 # 0 for reserved
1036 # IRQ 12 (PS/2 mouse) - (INT 74h)
1037 .equ IRQ12_SEL, .-IDT_BASE
1038 .word 0 # offset 15:0
1039 .long SYS_CODE64_SEL # selector 15:0
1040 .byte 0 # 0 for interrupt gate
1041 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
1042 .word 0 # offset 31:16
1043 .long 0 # offset 63:32
1044 .long 0 # 0 for reserved
1046 # IRQ 13 (Floating point error) - (INT 75h)
1047 .equ IRQ13_SEL, .-IDT_BASE
1048 .word 0 # offset 15:0
1049 .long SYS_CODE64_SEL # selector 15:0
1050 .byte 0 # 0 for interrupt gate
1051 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
1052 .word 0 # offset 31:16
1053 .long 0 # offset 63:32
1054 .long 0 # 0 for reserved
1056 # IRQ 14 (Secondary IDE) - (INT 76h)
1057 .equ IRQ14_SEL, .-IDT_BASE
1058 .word 0 # offset 15:0
1059 .long SYS_CODE64_SEL # selector 15:0
1060 .byte 0 # 0 for interrupt gate
1061 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
1062 .word 0 # offset 31:16
1063 .long 0 # offset 63:32
1064 .long 0 # 0 for reserved
1066 # IRQ 15 (Primary IDE) - (INT 77h)
1067 .equ IRQ15_SEL, .-IDT_BASE
1068 .word 0 # offset 15:0
1069 .long SYS_CODE64_SEL # selector 15:0
1070 .byte 0 # 0 for interrupt gate
1071 .byte 0x0e | 0x80 # type = 386 interrupt gate, present
1072 .word 0 # offset 31:16
1073 .long 0 # offset 63:32
1074 .long 0 # 0 for reserved
1080 MemoryMapSize: .long 0
1081 MemoryMap: .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
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
1112 .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
1116 # below is the pieces of the IVT that is used to redirect INT 68h - 6fh
1117 # back to INT 08h - 0fh when in real mode... It is 'org'ed to a
1118 # known low address (20f00) so it can be set up by PlMapIrqToVect in