mirror of
https://github.com/CloverHackyColor/CloverBootloader.git
synced 2024-12-11 14:28:08 +01:00
7c0aa811ec
Signed-off-by: Sergey Isakov <isakov-sl@bk.ru>
853 lines
29 KiB
ArmAsm
853 lines
29 KiB
ArmAsm
#------------------------------------------------------------------------------
|
|
#*
|
|
#* Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
|
|
#* Copyright (c) 2016, Clover Inc. All rights reserved.<BR>
|
|
#* This program and the accompanying materials
|
|
#* are licensed and made available under the terms and conditions of the BSD License
|
|
#* which accompanies this distribution. The full text of the license may be found at
|
|
#* http://opensource.org/licenses/bsd-license.php
|
|
#*
|
|
#* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
#* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
#*
|
|
#* st32_64H.S
|
|
#*
|
|
#* Abstract:
|
|
#*
|
|
#------------------------------------------------------------------------------
|
|
# Build with
|
|
# as -o st32_64H.o st32_64H.S
|
|
# ld --oformat=binary -Ttext=0x200 -o st32_64H.com st32_64H.o
|
|
#
|
|
# To change character displayed use --defsym CHARACTER_TO_SHOW=<int value> parameter to as
|
|
#
|
|
|
|
.code16
|
|
|
|
/*
|
|
.equ DELAY_PORT, 0x0ed # Port to use for 1uS delay
|
|
.equ KBD_CONTROL_PORT, 0x060 # 8042 control port
|
|
.equ KBD_STATUS_PORT, 0x064 # 8042 status port
|
|
.equ WRITE_DATA_PORT_CMD, 0x0d1 # 8042 command to write the data port
|
|
.equ ENABLE_A20_CMD, 0x0df # 8042 command to enable A20
|
|
*/
|
|
.equ FAST_ENABLE_A20_PORT, 0x92
|
|
.equ FAST_ENABLE_A20_MASK, 2
|
|
.equ IA32_EFER, 0xC0000080
|
|
.ifndef CHARACTER_TO_SHOW
|
|
.equ CHARACTER_TO_SHOW, 'T'
|
|
.endif
|
|
|
|
.globl _start
|
|
_start:
|
|
jmp 1f
|
|
|
|
.ascii "CLOVERX64 "
|
|
|
|
1:
|
|
movw %cs,%ax
|
|
movw %ax,%ds
|
|
movw %ax,%es
|
|
movw %ax,%ss
|
|
movw $MyStack, %sp
|
|
|
|
#
|
|
# Retrieve Bios Memory Map
|
|
#
|
|
xorl %ebx,%ebx
|
|
leal MemoryMap,%edi
|
|
MemMapLoop:
|
|
movl $0xe820,%eax
|
|
movl $20,%ecx
|
|
movl $0x534d4150, %edx # SMAP
|
|
int $0x15
|
|
jc MemMapDone
|
|
addw $20,%di
|
|
test %ebx,%ebx
|
|
jne MemMapLoop
|
|
MemMapDone:
|
|
subw $MemoryMap,%di # Get the address of the memory map
|
|
movl %edi, MemoryMapSize # Save the size of the memory map
|
|
|
|
#
|
|
# Rebase Self
|
|
#
|
|
xorl %ebx,%ebx
|
|
movw %cs,%bx # BX=segment
|
|
shll $4,%ebx # BX="linear" address of segment base
|
|
addl %ebx, (gdtr + 2) # Rebase address of GDT
|
|
addl %ebx, (idtr + 2) # Rebase address of IDT
|
|
addl %ebx, JumpToLongMode # Rebase ljmp Real Mode -> Long Mode
|
|
|
|
#
|
|
# Enable A20 Gate
|
|
#
|
|
|
|
movw $0x2401,%ax # Enable A20 Gate
|
|
int $0x15
|
|
jnc A20GateEnabled # Jump if it suceeded
|
|
|
|
#
|
|
# If INT 15 Function 2401 is not supported, then attempt to Enable A20 manually.
|
|
#
|
|
/*
|
|
call Empty8042InputBuffer # Empty the Input Buffer on the 8042 controller
|
|
jnz Timeout8042 # Jump if the 8042 timed out
|
|
outw %ax, $DELAY_PORT # Delay 1 uS
|
|
movb $WRITE_DATA_PORT_CMD, %al # 8042 cmd to write output port
|
|
outb %al, $KBD_STATUS_PORT # Send command to the 8042
|
|
call Empty8042InputBuffer # Empty the Input Buffer on the 8042 controller
|
|
jnz Timeout8042 # Jump if the 8042 timed out
|
|
movb $ENABLE_A20_CMD, %al # gate address bit 20 on
|
|
outb %al, $KBD_CONTROL_PORT # Send command to thre 8042
|
|
call Empty8042InputBuffer # Empty the Input Buffer on the 8042 controller
|
|
movw $25,%cx # Delay 25 uS for the command to complete on the 8042
|
|
Delay25uS:
|
|
outw %ax, $DELAY_PORT # Delay 1 uS
|
|
loop Delay25uS
|
|
Timeout8042:
|
|
*/
|
|
|
|
# WIKI - fast A20gate
|
|
inb $FAST_ENABLE_A20_PORT, %al
|
|
orb $FAST_ENABLE_A20_MASK, %al
|
|
outb %al, $FAST_ENABLE_A20_PORT
|
|
|
|
A20GateEnabled:
|
|
|
|
#
|
|
# Create Page Table
|
|
#
|
|
call CreatePageTable
|
|
|
|
#
|
|
# DISABLE INTERRUPTS - Entering Protected Mode
|
|
# 253668.pdf page 401
|
|
#
|
|
movw $0x000F, %bx
|
|
movw $(0x0E00 | (CHARACTER_TO_SHOW & 255)), %ax
|
|
int $0x10
|
|
|
|
cli
|
|
|
|
#
|
|
# Ready Address of Page Table in EDX
|
|
#
|
|
movzwl PageTableSegment, %edx
|
|
shll $4, %edx
|
|
|
|
#
|
|
# load GDT
|
|
#
|
|
lgdtl gdtr
|
|
|
|
#
|
|
# Enable the 64-bit page-translation-table entries by
|
|
# setting CR4.PAE=1 (this is _required_ before activating
|
|
# long mode). Paging is not enabled until after long mode
|
|
# is enabled.
|
|
#
|
|
movl %cr4, %eax
|
|
orb $0x20, %al
|
|
movl %eax, %cr4
|
|
|
|
#
|
|
# This is the Trapolean Page Tables that are guarenteed
|
|
# under 4GB.
|
|
#
|
|
# Address Map:
|
|
# 10000 ~ 12000 - efildr (loaded)
|
|
# 20000 ~ 21000 - start64.com
|
|
# 21000 ~ 22000 - efi64.com
|
|
# 22000 ~ 90000 - efildr
|
|
# 90000 ~ 96000 - 4G pagetable (will be reload later)
|
|
#
|
|
movl %edx, %cr3
|
|
|
|
#
|
|
# Enable long mode (set EFER.LME=1).
|
|
#
|
|
movl $IA32_EFER, %ecx
|
|
rdmsr
|
|
orw $0x100, %ax
|
|
wrmsr # Write EFER.
|
|
|
|
#
|
|
# Enable protected mode and paging to activate long mode (set CR0.PE=1, CR0.PG=1)
|
|
#
|
|
movl %cr0, %eax # Read CR0.
|
|
orl $0x80000001, %eax # Set PE, PG
|
|
movl %eax, %cr0 # Write CR0.
|
|
|
|
.equ JumpToLongMode, . + 2
|
|
ljmpl $0x38, $InLongMode # 0x38 is SYS_CODE64_SEL
|
|
|
|
InLongMode:
|
|
|
|
.code64
|
|
|
|
movw $SYS_DATA_SEL,%ax
|
|
movw %ax,%ds
|
|
movw %ax,%es
|
|
movw %ax,%ss
|
|
leaq MyStack(%rip), %rsp # Reload RSP
|
|
|
|
#
|
|
# load IDT
|
|
#
|
|
lidtq idtr(%rip)
|
|
|
|
jmp BlockSignature + 2
|
|
|
|
.code16
|
|
|
|
/*
|
|
Empty8042InputBuffer:
|
|
xorw %cx,%cx
|
|
Empty8042Loop:
|
|
outw %ax, $DELAY_PORT # Delay 1us
|
|
inb $KBD_STATUS_PORT, %al # Read the 8042 Status Port
|
|
andb $0x2,%al # Check the Input Buffer Full Flag
|
|
loopnz Empty8042Loop # Loop until the input buffer is empty or a timout of 65536 uS
|
|
ret
|
|
*/
|
|
|
|
#
|
|
# Find place for page table and create it
|
|
#
|
|
|
|
.equ EFILDR_BASE, 0x2000 # Offset to start of EFILDR block
|
|
.equ EFILDR_FILE_LENGTH, 8 # Dword in EFILDR_HEADER holding size of block
|
|
.equ EBDA_SEG, 0x40 # Segment:Offset for finding the EBDA
|
|
.equ EBDA_OFFSET, 0xE
|
|
|
|
CreatePageTable:
|
|
movl (EFILDR_BASE + EFILDR_FILE_LENGTH), %edx # Size of EFILDR block -> EDX
|
|
addl $(EFILDR_BASE + 15), %edx # Add base
|
|
shrl $4, %edx # And round up to multiple of 16
|
|
movw %ds, %ax
|
|
addw %ax, %dx # Add in linear base
|
|
addw $255, %dx
|
|
xorb %dl, %dl # And round up to page size
|
|
# DX holds 16-bit segment of page table
|
|
|
|
movw %ds, %cx # Save DS
|
|
movw $EBDA_SEG, %ax
|
|
addb $6, %dh # Need 6 pages for table
|
|
movw %ax, %ds
|
|
movw EBDA_OFFSET, %ax # EBDA 16-bit segment now in AX
|
|
movw %cx, %ds # Restore DS
|
|
cmpw %dx, %ax # Does page table fit under EBDA?
|
|
jae 1f # Yes, continue
|
|
jmp PageTableError # No, abort
|
|
1:
|
|
subb $6, %dh # Restore DX to start segment of page table
|
|
movw %dx, PageTableSegment # Stash it for client
|
|
pushw %es
|
|
pushw %di # Save ES:DI used to build page table
|
|
|
|
movw %dx, %es
|
|
xorw %di, %di # ES:DI points to start of page table
|
|
incb %dh # Bump DX to next page
|
|
|
|
#
|
|
# Set up page table root page (only 1 entry)
|
|
#
|
|
xorl %eax, %eax
|
|
movw %dx, %ax
|
|
incb %dh # Bump DX to next page
|
|
shll $4, %eax
|
|
orb $3, %al
|
|
stosl
|
|
xorl %eax, %eax
|
|
movw $2046, %cx
|
|
rep stosw # Wipe rest of 1st page
|
|
|
|
#
|
|
# Set up page table 2nd page (depth 1 - 4 entries)
|
|
#
|
|
movw $4, %cx
|
|
2:
|
|
movw %dx, %ax
|
|
incb %dh # Bump DX to next page
|
|
shll $4, %eax
|
|
orb $3, %al
|
|
stosl
|
|
xorl %eax, %eax
|
|
stosl
|
|
loop 2b
|
|
movw $2032, %cx # Wipe rest of 2nd page
|
|
rep stosw
|
|
|
|
#
|
|
# Set up pages 3 - 6 (depth 2 - 2048 entries)
|
|
#
|
|
xorl %edx, %edx # Start at base of memory
|
|
movb $0x83, %dl # Flags at leaf nodes mark large pages (2MB each)
|
|
movw $2048, %cx
|
|
3:
|
|
movl %edx, %eax
|
|
addl $0x200000, %edx # Bump EDX to next large page
|
|
stosl
|
|
xorl %eax, %eax
|
|
stosl
|
|
loop 3b
|
|
|
|
#
|
|
# Done - restore ES:DI and return
|
|
#
|
|
popw %di
|
|
popw %es
|
|
ret
|
|
|
|
#
|
|
# Get here if not enough space between boot file
|
|
# and bottom of the EBDA - print error and halt
|
|
#
|
|
PageTableError:
|
|
addw $2, %sp # Clear return address of CreatePageTable
|
|
movw $15, %bx
|
|
movw $PageErrorMsg, %si
|
|
1:
|
|
lodsb
|
|
testb %al, %al
|
|
jz 2f
|
|
movb $14, %ah
|
|
int $16
|
|
jmp 1b
|
|
2:
|
|
hlt
|
|
jmp 2b
|
|
|
|
##############################################################################
|
|
# data
|
|
##############################################################################
|
|
|
|
.p2align 1
|
|
|
|
PageTableSegment: .word 0
|
|
PageErrorMsg: .asciz "Unable to Allocate Memory for Page Table"
|
|
|
|
.p2align 1
|
|
|
|
gdtr: .word GDT_END - GDT_BASE - 1 # GDT limit
|
|
.long GDT_BASE # (GDT base gets adjusted above)
|
|
##############################################################################
|
|
# global descriptor table (GDT)
|
|
##############################################################################
|
|
|
|
.p2align 1
|
|
|
|
GDT_BASE:
|
|
# null descriptor
|
|
.equ NULL_SEL, .-GDT_BASE # Selector [0x0]
|
|
.word 0 # limit 15:0
|
|
.word 0 # base 15:0
|
|
.byte 0 # base 23:16
|
|
.byte 0 # type
|
|
.byte 0 # limit 19:16, flags
|
|
.byte 0 # base 31:24
|
|
|
|
# linear data segment descriptor
|
|
.equ LINEAR_DATA_SEL, .-GDT_BASE # Selector [0x8]
|
|
.word 0xFFFF # limit 0xFFFFF
|
|
.word 0 # base 0
|
|
.byte 0
|
|
.byte 0x92 # present, ring 0, data, expand-up, writable
|
|
.byte 0xCF # page-granular, 32-bit
|
|
.byte 0
|
|
|
|
# linear code segment descriptor
|
|
.equ LINEAR_CODE_SEL, .-GDT_BASE # Selector [0x10]
|
|
.word 0xFFFF # limit 0xFFFFF
|
|
.word 0 # base 0
|
|
.byte 0
|
|
.byte 0x9A # present, ring 0, code, non-conforming, readable
|
|
.byte 0xCF # page-granular, 32-bit
|
|
.byte 0
|
|
|
|
# system data segment descriptor
|
|
.equ SYS_DATA_SEL, .-GDT_BASE # Selector [0x18]
|
|
.word 0xFFFF # limit 0xFFFFF
|
|
.word 0 # base 0
|
|
.byte 0
|
|
.byte 0x92 # present, ring 0, data, expand-up, writable
|
|
.byte 0xCF # page-granular, 32-bit
|
|
.byte 0
|
|
|
|
# system code segment descriptor
|
|
.equ SYS_CODE_SEL, .-GDT_BASE # Selector [0x20]
|
|
.word 0xFFFF # limit 0xFFFFF
|
|
.word 0 # base 0
|
|
.byte 0
|
|
.byte 0x9A # present, ring 0, code, non-conforming, readable
|
|
.byte 0xCF # page-granular, 32-bit
|
|
.byte 0
|
|
|
|
# spare segment descriptor
|
|
.equ SPARE3_SEL, .-GDT_BASE # Selector [0x28]
|
|
.word 0 # limit 0
|
|
.word 0 # base 0
|
|
.byte 0 #
|
|
.byte 0 # non-present, ring 0, system, reserved
|
|
.byte 0 #
|
|
.byte 0
|
|
|
|
#
|
|
# system data segment descriptor
|
|
#
|
|
.equ SYS_DATA64_SEL, .-GDT_BASE # Selector [0x30]
|
|
.word 0xFFFF # limit 0xFFFFF
|
|
.word 0 # base 0
|
|
.byte 0
|
|
.byte 0x92 # present, ring 0, data, expand-up, writable
|
|
.byte 0xCF # page-granular, 32-bit
|
|
.byte 0
|
|
|
|
#
|
|
# system code segment descriptor
|
|
#
|
|
.equ SYS_CODE64_SEL, .-GDT_BASE # Selector [0x38]
|
|
.word 0xFFFF # limit 0xFFFFF
|
|
.word 0 # base 0
|
|
.byte 0
|
|
.byte 0x9A # present, ring 0, code, non-conforming, readable
|
|
.byte 0xAF # page-granular, 64-bit
|
|
.byte 0
|
|
|
|
# spare segment descriptor
|
|
.equ SPARE4_SEL, .-GDT_BASE # Selector [0x40]
|
|
.word 0 # limit 0
|
|
.word 0 # base 0
|
|
.byte 0
|
|
.byte 0 # non-present, ring 0, system, reserved
|
|
.byte 0 #
|
|
.byte 0
|
|
|
|
GDT_END:
|
|
|
|
.p2align 1
|
|
|
|
idtr: .word IDT_END - IDT_BASE - 1 # IDT limit
|
|
.quad IDT_BASE # (IDT base gets adjusted above)
|
|
|
|
##############################################################################
|
|
# interrupt descriptor table (IDT)
|
|
#
|
|
# Note: The hardware IRQ's specified in this table are the normal PC/AT IRQ
|
|
# mappings. This implementation only uses the system timer and all other
|
|
# IRQs will remain masked. The descriptors for vectors 33+ are provided
|
|
# for convenience.
|
|
##############################################################################
|
|
|
|
.p2align 1
|
|
|
|
IDT_BASE:
|
|
# divide by zero (INT 0)
|
|
.equ DIV_ZERO_SEL, .-IDT_BASE
|
|
.word 0 # offset 15:0
|
|
.word SYS_CODE64_SEL # selector 15:0
|
|
.byte 0 # 0 for interrupt gate
|
|
.byte 0x0e | 0x80 # type = 386 interrupt gate, present
|
|
.word 0 # offset 31:16
|
|
.long 0 # offset 63:32
|
|
.long 0 # 0 for reserved
|
|
|
|
# debug exception (INT 1)
|
|
.equ DEBUG_EXCEPT_SEL, .-IDT_BASE
|
|
.word 0 # offset 15:0
|
|
.word SYS_CODE64_SEL # selector 15:0
|
|
.byte 0 # 0 for interrupt gate
|
|
.byte 0x0e | 0x80 # type = 386 interrupt gate, present
|
|
.word 0 # offset 31:16
|
|
.long 0 # offset 63:32
|
|
.long 0 # 0 for reserved
|
|
|
|
# NMI (INT 2)
|
|
.equ NMI_SEL, .-IDT_BASE
|
|
.word 0 # offset 15:0
|
|
.word SYS_CODE64_SEL # selector 15:0
|
|
.byte 0 # 0 for interrupt gate
|
|
.byte 0x0e | 0x80 # type = 386 interrupt gate, present
|
|
.word 0 # offset 31:16
|
|
.long 0 # offset 63:32
|
|
.long 0 # 0 for reserved
|
|
|
|
# soft breakpoint (INT 3)
|
|
.equ BREAKPOINT_SEL, .-IDT_BASE
|
|
.word 0 # offset 15:0
|
|
.word SYS_CODE64_SEL # selector 15:0
|
|
.byte 0 # 0 for interrupt gate
|
|
.byte 0x0e | 0x80 # type = 386 interrupt gate, present
|
|
.word 0 # offset 31:16
|
|
.long 0 # offset 63:32
|
|
.long 0 # 0 for reserved
|
|
|
|
# overflow (INT 4)
|
|
.equ OVERFLOW_SEL, .-IDT_BASE
|
|
.word 0 # offset 15:0
|
|
.word SYS_CODE64_SEL # selector 15:0
|
|
.byte 0 # 0 for interrupt gate
|
|
.byte 0x0e | 0x80 # type = 386 interrupt gate, present
|
|
.word 0 # offset 31:16
|
|
.long 0 # offset 63:32
|
|
.long 0 # 0 for reserved
|
|
|
|
# bounds check (INT 5)
|
|
.equ BOUNDS_CHECK_SEL, .-IDT_BASE
|
|
.word 0 # offset 15:0
|
|
.word SYS_CODE64_SEL # selector 15:0
|
|
.byte 0 # 0 for interrupt gate
|
|
.byte 0x0e | 0x80 # type = 386 interrupt gate, present
|
|
.word 0 # offset 31:16
|
|
.long 0 # offset 63:32
|
|
.long 0 # 0 for reserved
|
|
|
|
# invalid opcode (INT 6)
|
|
.equ INVALID_OPCODE_SEL, .-IDT_BASE
|
|
.word 0 # offset 15:0
|
|
.word SYS_CODE64_SEL # selector 15:0
|
|
.byte 0 # 0 for interrupt gate
|
|
.byte 0x0e | 0x80 # type = 386 interrupt gate, present
|
|
.word 0 # offset 31:16
|
|
.long 0 # offset 63:32
|
|
.long 0 # 0 for reserved
|
|
|
|
# device not available (INT 7)
|
|
.equ DEV_NOT_AVAIL_SEL, .-IDT_BASE
|
|
.word 0 # offset 15:0
|
|
.word SYS_CODE64_SEL # selector 15:0
|
|
.byte 0 # 0 for interrupt gate
|
|
.byte 0x0e | 0x80 # type = 386 interrupt gate, present
|
|
.word 0 # offset 31:16
|
|
.long 0 # offset 63:32
|
|
.long 0 # 0 for reserved
|
|
|
|
# double fault (INT 8)
|
|
.equ DOUBLE_FAULT_SEL, .-IDT_BASE
|
|
.word 0 # offset 15:0
|
|
.word SYS_CODE64_SEL # selector 15:0
|
|
.byte 0 # 0 for interrupt gate
|
|
.byte 0x0e | 0x80 # type = 386 interrupt gate, present
|
|
.word 0 # offset 31:16
|
|
.long 0 # offset 63:32
|
|
.long 0 # 0 for reserved
|
|
|
|
# Coprocessor segment overrun - reserved (INT 9)
|
|
.equ RSVD_INTR_SEL1, .-IDT_BASE
|
|
.word 0 # offset 15:0
|
|
.word SYS_CODE64_SEL # selector 15:0
|
|
.byte 0 # 0 for interrupt gate
|
|
.byte 0x0e | 0x80 # type = 386 interrupt gate, present
|
|
.word 0 # offset 31:16
|
|
.long 0 # offset 63:32
|
|
.long 0 # 0 for reserved
|
|
|
|
# invalid TSS (INT 0ah)
|
|
.equ INVALID_TSS_SEL, .-IDT_BASE
|
|
.word 0 # offset 15:0
|
|
.word SYS_CODE64_SEL # selector 15:0
|
|
.byte 0 # 0 for interrupt gate
|
|
.byte 0x0e | 0x80 # type = 386 interrupt gate, present
|
|
.word 0 # offset 31:16
|
|
.long 0 # offset 63:32
|
|
.long 0 # 0 for reserved
|
|
|
|
# segment not present (INT 0bh)
|
|
.equ SEG_NOT_PRESENT_SEL, .-IDT_BASE
|
|
.word 0 # offset 15:0
|
|
.word SYS_CODE64_SEL # selector 15:0
|
|
.byte 0 # 0 for interrupt gate
|
|
.byte 0x0e | 0x80 # type = 386 interrupt gate, present
|
|
.word 0 # offset 31:16
|
|
.long 0 # offset 63:32
|
|
.long 0 # 0 for reserved
|
|
|
|
# stack fault (INT 0ch)
|
|
.equ STACK_FAULT_SEL, .-IDT_BASE
|
|
.word 0 # offset 15:0
|
|
.word SYS_CODE64_SEL # selector 15:0
|
|
.byte 0 # 0 for interrupt gate
|
|
.byte 0x0e | 0x80 # type = 386 interrupt gate, present
|
|
.word 0 # offset 31:16
|
|
.long 0 # offset 63:32
|
|
.long 0 # 0 for reserved
|
|
|
|
# general protection (INT 0dh)
|
|
.equ GP_FAULT_SEL, .-IDT_BASE
|
|
.word 0 # offset 15:0
|
|
.word SYS_CODE64_SEL # selector 15:0
|
|
.byte 0 # 0 for interrupt gate
|
|
.byte 0x0e | 0x80 # type = 386 interrupt gate, present
|
|
.word 0 # offset 31:16
|
|
.long 0 # offset 63:32
|
|
.long 0 # 0 for reserved
|
|
|
|
# page fault (INT 0eh)
|
|
.equ PAGE_FAULT_SEL, .-IDT_BASE
|
|
.word 0 # offset 15:0
|
|
.word SYS_CODE64_SEL # selector 15:0
|
|
.byte 0 # 0 for interrupt gate
|
|
.byte 0x0e | 0x80 # type = 386 interrupt gate, present
|
|
.word 0 # offset 31:16
|
|
.long 0 # offset 63:32
|
|
.long 0 # 0 for reserved
|
|
|
|
# Intel reserved - do not use (INT 0fh)
|
|
.equ RSVD_INTR_SEL2, .-IDT_BASE
|
|
.word 0 # offset 15:0
|
|
.word SYS_CODE64_SEL # selector 15:0
|
|
.byte 0 # 0 for interrupt gate
|
|
.byte 0x0e | 0x80 # type = 386 interrupt gate, present
|
|
.word 0 # offset 31:16
|
|
.long 0 # offset 63:32
|
|
.long 0 # 0 for reserved
|
|
|
|
# floating point error (INT 10h)
|
|
.equ FLT_POINT_ERR_SEL, .-IDT_BASE
|
|
.word 0 # offset 15:0
|
|
.word SYS_CODE64_SEL # selector 15:0
|
|
.byte 0 # 0 for interrupt gate
|
|
.byte 0x0e | 0x80 # type = 386 interrupt gate, present
|
|
.word 0 # offset 31:16
|
|
.long 0 # offset 63:32
|
|
.long 0 # 0 for reserved
|
|
|
|
# alignment check (INT 11h)
|
|
.equ ALIGNMENT_CHECK_SEL, .-IDT_BASE
|
|
.word 0 # offset 15:0
|
|
.word SYS_CODE64_SEL # selector 15:0
|
|
.byte 0 # 0 for interrupt gate
|
|
.byte 0x0e | 0x80 # type = 386 interrupt gate, present
|
|
.word 0 # offset 31:16
|
|
.long 0 # offset 63:32
|
|
.long 0 # 0 for reserved
|
|
|
|
# machine check (INT 12h)
|
|
.equ MACHINE_CHECK_SEL, .-IDT_BASE
|
|
.word 0 # offset 15:0
|
|
.word SYS_CODE64_SEL # selector 15:0
|
|
.byte 0 # 0 for interrupt gate
|
|
.byte 0x0e | 0x80 # type = 386 interrupt gate, present
|
|
.word 0 # offset 31:16
|
|
.long 0 # offset 63:32
|
|
.long 0 # 0 for reserved
|
|
|
|
# SIMD floating-point exception (INT 13h)
|
|
.equ SIMD_EXCEPTION_SEL, .-IDT_BASE
|
|
.word 0 # offset 15:0
|
|
.word SYS_CODE64_SEL # selector 15:0
|
|
.byte 0 # 0 for interrupt gate
|
|
.byte 0x0e | 0x80 # type = 386 interrupt gate, present
|
|
.word 0 # offset 31:16
|
|
.long 0 # offset 63:32
|
|
.long 0 # 0 for reserved
|
|
|
|
# 84 unspecified descriptors, First 12 of them are reserved, the rest are avail
|
|
.fill 84 * 16, 1, 0 # db (84 * 16) dup(0)
|
|
|
|
# IRQ 0 (System timer) - (INT 68h)
|
|
.equ IRQ0_SEL, .-IDT_BASE
|
|
.word 0 # offset 15:0
|
|
.word SYS_CODE64_SEL # selector 15:0
|
|
.byte 0 # 0 for interrupt gate
|
|
.byte 0x0e | 0x80 # type = 386 interrupt gate, present
|
|
.word 0 # offset 31:16
|
|
.long 0 # offset 63:32
|
|
.long 0 # 0 for reserved
|
|
|
|
# IRQ 1 (8042 Keyboard controller) - (INT 69h)
|
|
.equ IRQ1_SEL, .-IDT_BASE
|
|
.word 0 # offset 15:0
|
|
.word SYS_CODE64_SEL # selector 15:0
|
|
.byte 0 # 0 for interrupt gate
|
|
.byte 0x0e | 0x80 # type = 386 interrupt gate, present
|
|
.word 0 # offset 31:16
|
|
.long 0 # offset 63:32
|
|
.long 0 # 0 for reserved
|
|
|
|
# Reserved - IRQ 2 redirect (IRQ 2) - DO NOT USE!!! - (INT 6ah)
|
|
.equ IRQ2_SEL, .-IDT_BASE
|
|
.word 0 # offset 15:0
|
|
.word SYS_CODE64_SEL # selector 15:0
|
|
.byte 0 # 0 for interrupt gate
|
|
.byte 0x0e | 0x80 # type = 386 interrupt gate, present
|
|
.word 0 # offset 31:16
|
|
.long 0 # offset 63:32
|
|
.long 0 # 0 for reserved
|
|
|
|
# IRQ 3 (COM 2) - (INT 6bh)
|
|
.equ IRQ3_SEL, .-IDT_BASE
|
|
.word 0 # offset 15:0
|
|
.word SYS_CODE64_SEL # selector 15:0
|
|
.byte 0 # 0 for interrupt gate
|
|
.byte 0x0e | 0x80 # type = 386 interrupt gate, present
|
|
.word 0 # offset 31:16
|
|
.long 0 # offset 63:32
|
|
.long 0 # 0 for reserved
|
|
|
|
# IRQ 4 (COM 1) - (INT 6ch)
|
|
.equ IRQ4_SEL, .-IDT_BASE
|
|
.word 0 # offset 15:0
|
|
.word SYS_CODE64_SEL # selector 15:0
|
|
.byte 0 # 0 for interrupt gate
|
|
.byte 0x0e | 0x80 # type = 386 interrupt gate, present
|
|
.word 0 # offset 31:16
|
|
.long 0 # offset 63:32
|
|
.long 0 # 0 for reserved
|
|
|
|
# IRQ 5 (LPT 2) - (INT 6dh)
|
|
.equ IRQ5_SEL, .-IDT_BASE
|
|
.word 0 # offset 15:0
|
|
.word SYS_CODE64_SEL # selector 15:0
|
|
.byte 0 # 0 for interrupt gate
|
|
.byte 0x0e | 0x80 # type = 386 interrupt gate, present
|
|
.word 0 # offset 31:16
|
|
.long 0 # offset 63:32
|
|
.long 0 # 0 for reserved
|
|
|
|
# IRQ 6 (Floppy controller) - (INT 6eh)
|
|
.equ IRQ6_SEL, .-IDT_BASE
|
|
.word 0 # offset 15:0
|
|
.word SYS_CODE64_SEL # selector 15:0
|
|
.byte 0 # 0 for interrupt gate
|
|
.byte 0x0e | 0x80 # type = 386 interrupt gate, present
|
|
.word 0 # offset 31:16
|
|
.long 0 # offset 63:32
|
|
.long 0 # 0 for reserved
|
|
|
|
# IRQ 7 (LPT 1) - (INT 6fh)
|
|
.equ IRQ7_SEL, .-IDT_BASE
|
|
.word 0 # offset 15:0
|
|
.word SYS_CODE64_SEL # selector 15:0
|
|
.byte 0 # 0 for interrupt gate
|
|
.byte 0x0e | 0x80 # type = 386 interrupt gate, present
|
|
.word 0 # offset 31:16
|
|
.long 0 # offset 63:32
|
|
.long 0 # 0 for reserved
|
|
|
|
# IRQ 8 (RTC Alarm) - (INT 70h)
|
|
.equ IRQ8_SEL, .-IDT_BASE
|
|
.word 0 # offset 15:0
|
|
.word SYS_CODE64_SEL # selector 15:0
|
|
.byte 0 # 0 for interrupt gate
|
|
.byte 0x0e | 0x80 # type = 386 interrupt gate, present
|
|
.word 0 # offset 31:16
|
|
.long 0 # offset 63:32
|
|
.long 0 # 0 for reserved
|
|
|
|
# IRQ 9 - (INT 71h)
|
|
.equ IRQ9_SEL, .-IDT_BASE
|
|
.word 0 # offset 15:0
|
|
.word SYS_CODE64_SEL # selector 15:0
|
|
.byte 0 # 0 for interrupt gate
|
|
.byte 0x0e | 0x80 # type = 386 interrupt gate, present
|
|
.word 0 # offset 31:16
|
|
.long 0 # offset 63:32
|
|
.long 0 # 0 for reserved
|
|
|
|
# IRQ 10 - (INT 72h)
|
|
.equ IRQ10_SEL, .-IDT_BASE
|
|
.word 0 # offset 15:0
|
|
.word SYS_CODE64_SEL # selector 15:0
|
|
.byte 0 # 0 for interrupt gate
|
|
.byte 0x0e | 0x80 # type = 386 interrupt gate, present
|
|
.word 0 # offset 31:16
|
|
.long 0 # offset 63:32
|
|
.long 0 # 0 for reserved
|
|
|
|
# IRQ 11 - (INT 73h)
|
|
.equ IRQ11_SEL, .-IDT_BASE
|
|
.word 0 # offset 15:0
|
|
.word SYS_CODE64_SEL # selector 15:0
|
|
.byte 0 # 0 for interrupt gate
|
|
.byte 0x0e | 0x80 # type = 386 interrupt gate, present
|
|
.word 0 # offset 31:16
|
|
.long 0 # offset 63:32
|
|
.long 0 # 0 for reserved
|
|
|
|
# IRQ 12 (PS/2 mouse) - (INT 74h)
|
|
.equ IRQ12_SEL, .-IDT_BASE
|
|
.word 0 # offset 15:0
|
|
.word SYS_CODE64_SEL # selector 15:0
|
|
.byte 0 # 0 for interrupt gate
|
|
.byte 0x0e | 0x80 # type = 386 interrupt gate, present
|
|
.word 0 # offset 31:16
|
|
.long 0 # offset 63:32
|
|
.long 0 # 0 for reserved
|
|
|
|
# IRQ 13 (Floating point error) - (INT 75h)
|
|
.equ IRQ13_SEL, .-IDT_BASE
|
|
.word 0 # offset 15:0
|
|
.word SYS_CODE64_SEL # selector 15:0
|
|
.byte 0 # 0 for interrupt gate
|
|
.byte 0x0e | 0x80 # type = 386 interrupt gate, present
|
|
.word 0 # offset 31:16
|
|
.long 0 # offset 63:32
|
|
.long 0 # 0 for reserved
|
|
|
|
# IRQ 14 (Secondary IDE) - (INT 76h)
|
|
.equ IRQ14_SEL, .-IDT_BASE
|
|
.word 0 # offset 15:0
|
|
.word SYS_CODE64_SEL # selector 15:0
|
|
.byte 0 # 0 for interrupt gate
|
|
.byte 0x0e | 0x80 # type = 386 interrupt gate, present
|
|
.word 0 # offset 31:16
|
|
.long 0 # offset 63:32
|
|
.long 0 # 0 for reserved
|
|
|
|
# IRQ 15 (Primary IDE) - (INT 77h)
|
|
.equ IRQ15_SEL, .-IDT_BASE
|
|
.word 0 # offset 15:0
|
|
.word SYS_CODE64_SEL # selector 15:0
|
|
.byte 0 # 0 for interrupt gate
|
|
.byte 0x0e | 0x80 # type = 386 interrupt gate, present
|
|
.word 0 # offset 31:16
|
|
.long 0 # offset 63:32
|
|
.long 0 # 0 for reserved
|
|
|
|
.fill 16, 1, 0
|
|
|
|
IDT_END:
|
|
|
|
.p2align 1
|
|
|
|
MemoryMapSize: .long 0
|
|
MemoryMap: .fill 267, 4, 0
|
|
|
|
.org 0x0de0
|
|
|
|
MyStack:
|
|
# below is the pieces of the IVT that is used to redirect INT 68h - 6fh
|
|
# back to INT 08h - 0fh when in real mode... It is 'org'ed to a
|
|
# known low address (20f00) so it can be set up by PlMapIrqToVect in
|
|
# 8259.c
|
|
|
|
int $8
|
|
iret
|
|
|
|
int $9
|
|
iret
|
|
|
|
int $10
|
|
iret
|
|
|
|
int $11
|
|
iret
|
|
|
|
int $12
|
|
iret
|
|
|
|
int $13
|
|
iret
|
|
|
|
int $14
|
|
iret
|
|
|
|
int $15
|
|
iret
|
|
|
|
.org 0x0dfe
|
|
BlockSignature:
|
|
.word 0xaa55
|