Porting Duet module from EDKI to EDKII
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@5076 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
fcf03596d1
commit
c69dd9dfad
30
DuetPkg/BootSector/BootSector.inf
Normal file
30
DuetPkg/BootSector/BootSector.inf
Normal file
@ -0,0 +1,30 @@
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = BootSector
|
||||
FILE_GUID = A36495C1-C205-414e-B71F-4BE3476D699C
|
||||
MODULE_TYPE = USER_DEFINED
|
||||
VERSION_STRING = 1.0
|
||||
EDK_RELEASE_VERSION = 0x00020000
|
||||
EFI_SPECIFICATION_VERSION = 0x00020000
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
DuetPkg/DuetPkg.dec
|
||||
|
||||
[Sources]
|
||||
bootsect.asm
|
||||
bs16.asm
|
||||
bs32.asm
|
||||
Gpt.asm
|
||||
Mbr.asm
|
||||
Start.asm
|
||||
Start16.asm
|
||||
Start32.asm
|
||||
Efi32.asm
|
||||
|
||||
[BuildOptions.common]
|
||||
#MSFT:*_*_IA32_DLINK_FLAGS = /out:"$(BIN_DIR)\SecMain.exe" /base:0x10000000 /pdb:"$(BIN_DIR)\SecMain.pdb" /LIBPATH:"$(VCINSTALLDIR)\Lib" /LIBPATH:"$(VCINSTALLDIR)\PlatformSdk\Lib" /NOLOGO /SUBSYSTEM:CONSOLE /NODEFAULTLIB /IGNORE:4086 /MAP /OPT:REF /DEBUG /MACHINE:I386 /LTCG Kernel32.lib MSVCRTD.lib Gdi32.lib User32.lib Winmm.lib
|
||||
MSFT:*_*_IA32_CC_FLAGS = /nologo /W4 /WX /Gy /c /D UNICODE /Od /FI$(DEST_DIR_DEBUG)/AutoGen.h /EHs-c- /GF /Gs8192 /Zi /Gm /D _CRT_SECURE_NO_WARNINGS /D _CRT_SECURE_NO_DEPRECATE
|
||||
MSFT:*_*_IA32_PP_FLAGS = /nologo /E /TC /FI$(DEST_DIR_DEBUG)/AutoGen.h
|
||||
MSFT:*_*_IA32_ASM_FLAGS = /nologo /W3 /WX /c /coff /Cx /Zd /W0 /Zi
|
||||
MSFT:*_*_IA32_ASMLINK_FLAGS = /link /nologo /tiny
|
26
DuetPkg/BootSector/FILE.LST
Normal file
26
DuetPkg/BootSector/FILE.LST
Normal file
@ -0,0 +1,26 @@
|
||||
IA32
|
||||
====
|
||||
FAT12 FAT16 FAT32
|
||||
bootsect.asm bs16.asm bs32.asm
|
||||
start.asm start16.asm start32.asm
|
||||
\ | /
|
||||
\ | /
|
||||
efi32.asm
|
||||
|
||||
X64
|
||||
===
|
||||
FAT12 FAT16 FAT32
|
||||
bootsect.asm bs16.asm bs32.asm
|
||||
start64.asm st16_64.asm st32_64.asm
|
||||
\ | /
|
||||
\ | /
|
||||
efi64.asm
|
||||
|
||||
MBR
|
||||
===
|
||||
Mbr.asm
|
||||
|
||||
|
||||
GPT
|
||||
===
|
||||
Gpt.asm
|
294
DuetPkg/BootSector/Gpt.asm
Normal file
294
DuetPkg/BootSector/Gpt.asm
Normal file
@ -0,0 +1,294 @@
|
||||
;------------------------------------------------------------------------------
|
||||
;*
|
||||
;* Copyright 2006 - 2007, Intel Corporation
|
||||
;* All rights reserved. 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.
|
||||
;*
|
||||
;* gpt.asm
|
||||
;*
|
||||
;* Abstract:
|
||||
;*
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
.model small
|
||||
; .dosseg
|
||||
.stack
|
||||
.486p
|
||||
.code
|
||||
|
||||
BLOCK_SIZE EQU 0200h
|
||||
BLOCK_MASK EQU 01ffh
|
||||
BLOCK_SHIFT EQU 9
|
||||
|
||||
; ****************************************************************************
|
||||
; Code loaded by BIOS at 0x0000:0x7C00
|
||||
; ****************************************************************************
|
||||
|
||||
org 0h
|
||||
Start:
|
||||
|
||||
; ****************************************************************************
|
||||
; Start Print
|
||||
; ****************************************************************************
|
||||
|
||||
mov ax,0b800h
|
||||
mov es,ax
|
||||
mov ax, 07c0h
|
||||
mov ds, ax
|
||||
lea si, cs:[StartString]
|
||||
mov cx, 10
|
||||
mov di, 160
|
||||
rep movsw
|
||||
|
||||
; ****************************************************************************
|
||||
; Print over
|
||||
; ****************************************************************************
|
||||
|
||||
; ****************************************************************************
|
||||
; Initialize segment registers and copy code at 0x0000:0x7c00 to 0x0000:0x0600
|
||||
; ****************************************************************************
|
||||
xor ax, ax ; AX = 0x0000
|
||||
mov bx, 07c00h ; BX = 0x7C00
|
||||
mov bp, 0600h ; BP = 0x0600
|
||||
mov si, OFFSET RelocatedStart ; SI = Offset(RelocatedStart)
|
||||
mov cx, 0200h ; CX = 0x0200
|
||||
sub cx, si ; CS = 0x0200 - Offset(RelocatedStart)
|
||||
lea di, [bp+si] ; DI = 0x0600 + Offset(RelocatedStart)
|
||||
lea si, [bx+si] ; BX = 0x7C00 + Offset(RelocatedStart)
|
||||
mov ss, ax ; SS = 0x0000
|
||||
mov sp, bx ; SP = 0x7C00
|
||||
mov es,ax ; ES = 0x0000
|
||||
mov ds,ax ; DS = 0x0000
|
||||
push ax ; PUSH 0x0000
|
||||
push di ; PUSH 0x0600 + Offset(RelocatedStart)
|
||||
cld ; Clear the direction flag
|
||||
rep movsb ; Copy 0x0200 bytes from 0x7C00 to 0x0600
|
||||
retf ; JMP 0x0000:0x0600 + Offset(RelocatedStart)
|
||||
|
||||
; ****************************************************************************
|
||||
; Code relocated to 0x0000:0x0600
|
||||
; ****************************************************************************
|
||||
|
||||
RelocatedStart:
|
||||
; ****************************************************************************
|
||||
; Get Driver Parameters to 0x0000:0x7BFC
|
||||
; ****************************************************************************
|
||||
xor ax,ax ; ax = 0
|
||||
mov ss,ax ; ss = 0
|
||||
add ax,1000h
|
||||
mov ds,ax
|
||||
|
||||
mov sp,07c00h ; sp = 0x7c00
|
||||
mov bp,sp ; bp = 0x7c00
|
||||
|
||||
mov ah,8 ; ah = 8 - Get Drive Parameters Function
|
||||
mov byte ptr [bp+PhysicalDrive],dl ; BBS defines that BIOS would pass the booting driver number to the loader through DL
|
||||
int 13h ; Get Drive Parameters
|
||||
xor ax,ax ; ax = 0
|
||||
mov al,dh ; al = dh
|
||||
inc al ; MaxHead = al + 1
|
||||
push ax ; 0000:7bfe = MaxHead
|
||||
mov al,cl ; al = cl
|
||||
and al,03fh ; MaxSector = al & 0x3f
|
||||
push ax ; 0000:7bfc = MaxSector
|
||||
|
||||
; ****************************************************************************
|
||||
; Read GPT Header from hard disk to 0x0000:0x0800
|
||||
; ****************************************************************************
|
||||
xor ax, ax
|
||||
mov es, ax ; Read to 0x0000:0x0800
|
||||
mov di, 0800h ; Read to 0x0000:0x0800
|
||||
mov eax, 1 ; Read LBA #1
|
||||
mov edx, 0 ; Read LBA #1
|
||||
mov bx, 1 ; Read 1 Block
|
||||
push es
|
||||
call ReadBlocks
|
||||
pop es
|
||||
|
||||
; ****************************************************************************
|
||||
; Read Target GPT Entry from hard disk to 0x0000:0x0A00
|
||||
; ****************************************************************************
|
||||
cmp dword ptr es:[di], 020494645h ; Check for "EFI "
|
||||
jne BadGpt
|
||||
cmp dword ptr es:[di + 4], 054524150h ; Check for "PART"
|
||||
jne BadGpt
|
||||
cmp dword ptr es:[di + 8], 000010000h ; Check Revision - 0x10000
|
||||
jne BadGpt
|
||||
|
||||
mov eax, dword ptr es:[di + 84] ; EAX = SizeOfPartitionEntry
|
||||
mul byte ptr [bp+GptPartitionIndicator] ; EAX = SizeOfPartitionEntry * GptPartitionIndicator
|
||||
mov edx, eax ; EDX = SizeOfPartitionEntry * GptPartitionIndicator
|
||||
shr eax, BLOCK_SHIFT ; EAX = (SizeOfPartitionEntry * GptPartitionIndicator) / BLOCK_SIZE
|
||||
and edx, BLOCK_MASK ; EDX = Targer PartitionEntryLBA Offset
|
||||
; = (SizeOfPartitionEntry * GptPartitionIndicator) % BLOCK_SIZE
|
||||
push edx
|
||||
mov ecx, dword ptr es:[di + 72] ; ECX = PartitionEntryLBA (Low)
|
||||
mov ebx, dword ptr es:[di + 76] ; EBX = PartitionEntryLBA (High)
|
||||
add eax, ecx ; EAX = Target PartitionEntryLBA (Low)
|
||||
; = (PartitionEntryLBA +
|
||||
; (SizeOfPartitionEntry * GptPartitionIndicator) / BLOCK_SIZE)
|
||||
adc edx, ebx ; EDX = Target PartitionEntryLBA (High)
|
||||
|
||||
mov di, 0A00h ; Read to 0x0000:0x0A00
|
||||
mov bx, 1 ; Read 1 Block
|
||||
push es
|
||||
call ReadBlocks
|
||||
pop es
|
||||
|
||||
; ****************************************************************************
|
||||
; Read Target DBR from hard disk to 0x0000:0x7C00
|
||||
; ****************************************************************************
|
||||
pop edx ; EDX = (SizeOfPartitionEntry * GptPartitionIndicator) % BLOCK_SIZE
|
||||
add di, dx ; DI = Targer PartitionEntryLBA Offset
|
||||
cmp dword ptr es:[di], 0C12A7328h ; Check for EFI System Partition "C12A7328-F81F-11d2-BA4B-00A0C93EC93B"
|
||||
jne BadGpt
|
||||
cmp dword ptr es:[di + 4], 011d2F81Fh ;
|
||||
jne BadGpt
|
||||
cmp dword ptr es:[di + 8], 0A0004BBAh ;
|
||||
jne BadGpt
|
||||
cmp dword ptr es:[di + 0ch], 03BC93EC9h ;
|
||||
jne BadGpt
|
||||
|
||||
mov eax, dword ptr es:[di + 32] ; EAX = StartingLBA (Low)
|
||||
mov edx, dword ptr es:[di + 36] ; EDX = StartingLBA (High)
|
||||
mov di, 07C00h ; Read to 0x0000:0x7C00
|
||||
mov bx, 1 ; Read 1 Block
|
||||
call ReadBlocks
|
||||
|
||||
; ****************************************************************************
|
||||
; Transfer control to BootSector - Jump to 0x0000:0x7C00
|
||||
; ****************************************************************************
|
||||
xor ax, ax
|
||||
push ax ; PUSH 0x0000
|
||||
mov di, 07c00h
|
||||
push di ; PUSH 0x7C00
|
||||
retf ; JMP 0x0000:0x7C00
|
||||
|
||||
; ****************************************************************************
|
||||
; ReadBlocks - Reads a set of blocks from a block device
|
||||
;
|
||||
; EDX:EAX = Start LBA
|
||||
; BX = Number of Blocks to Read (must < 127)
|
||||
; ES:DI = Buffer to store sectors read from disk
|
||||
; ****************************************************************************
|
||||
|
||||
; si = DiskAddressPacket
|
||||
|
||||
ReadBlocks:
|
||||
pushad
|
||||
push ds
|
||||
xor cx, cx
|
||||
mov ds, cx
|
||||
mov bp, 0600h ; bp = 0x600
|
||||
lea si, [bp + OFFSET AddressPacket] ; DS:SI = Disk Address Packet
|
||||
mov BYTE PTR ds:[si+2],bl ; 02 = Number Of Block transfered
|
||||
mov WORD PTR ds:[si+4],di ; 04 = Transfer Buffer Offset
|
||||
mov WORD PTR ds:[si+6],es ; 06 = Transfer Buffer Segment
|
||||
mov DWORD PTR ds:[si+8],eax ; 08 = Starting LBA (Low)
|
||||
mov DWORD PTR ds:[si+0ch],edx ; 0C = Starting LBA (High)
|
||||
mov ah, 42h ; ah = Function 42
|
||||
mov dl,byte ptr [bp+PhysicalDrive] ; dl = Drive Number
|
||||
int 13h
|
||||
jc BadGpt
|
||||
pop ds
|
||||
popad
|
||||
ret
|
||||
|
||||
; ****************************************************************************
|
||||
; Address Packet used by ReadBlocks
|
||||
; ****************************************************************************
|
||||
AddressPacket:
|
||||
db 10h ; Size of address packet
|
||||
db 00h ; Reserved. Must be 0
|
||||
db 01h ; Read blocks at a time (To be fixed each times)
|
||||
db 00h ; Reserved. Must be 0
|
||||
dw 0000h ; Destination Address offset (To be fixed each times)
|
||||
dw 0000h ; Destination Address segment (To be fixed each times)
|
||||
AddressPacketLba:
|
||||
dd 0h, 0h ; Start LBA (To be fixed each times)
|
||||
AddressPacketEnd:
|
||||
|
||||
; ****************************************************************************
|
||||
; ERROR Condition:
|
||||
; ****************************************************************************
|
||||
|
||||
BadGpt:
|
||||
mov ax,0b800h
|
||||
mov es,ax
|
||||
mov ax, 060h
|
||||
mov ds, ax
|
||||
lea si, cs:[ErrorString]
|
||||
mov cx, 10
|
||||
mov di, 320
|
||||
rep movsw
|
||||
Halt:
|
||||
jmp Halt
|
||||
|
||||
StartString:
|
||||
db 'G', 0ch, 'P', 0ch, 'T', 0ch, ' ', 0ch, 'S', 0ch, 't', 0ch, 'a', 0ch, 'r', 0ch, 't', 0ch, '!', 0ch
|
||||
ErrorString:
|
||||
db 'G', 0ch, 'P', 0ch, 'T', 0ch, ' ', 0ch, 'E', 0ch, 'r', 0ch, 'r', 0ch, 'o', 0ch, 'r', 0ch, '!', 0ch
|
||||
|
||||
; ****************************************************************************
|
||||
; PhysicalDrive - Used to indicate which disk to be boot
|
||||
; Can be patched by tool
|
||||
; ****************************************************************************
|
||||
org 01B6h
|
||||
PhysicalDrive db 80h
|
||||
|
||||
; ****************************************************************************
|
||||
; GptPartitionIndicator - Used to indicate which GPT partition to be boot
|
||||
; Can be patched by tool
|
||||
; ****************************************************************************
|
||||
org 01B7h
|
||||
GptPartitionIndicator db 0
|
||||
|
||||
; ****************************************************************************
|
||||
; Unique MBR signature
|
||||
; ****************************************************************************
|
||||
org 01B8h
|
||||
db 'DUET'
|
||||
|
||||
; ****************************************************************************
|
||||
; Unknown
|
||||
; ****************************************************************************
|
||||
org 01BCh
|
||||
dw 0
|
||||
|
||||
; ****************************************************************************
|
||||
; PMBR Entry - Can be patched by tool
|
||||
; ****************************************************************************
|
||||
org 01BEh
|
||||
db 0 ; Boot Indicator
|
||||
db 0ffh ; Start Header
|
||||
db 0ffh ; Start Sector
|
||||
db 0ffh ; Start Track
|
||||
db 0eeh ; OS Type
|
||||
db 0ffh ; End Header
|
||||
db 0ffh ; End Sector
|
||||
db 0ffh ; End Track
|
||||
dd 1 ; Starting LBA
|
||||
dd 0FFFFFFFFh ; End LBA
|
||||
|
||||
org 01CEh
|
||||
dd 0, 0, 0, 0
|
||||
org 01DEh
|
||||
dd 0, 0, 0, 0
|
||||
org 01EEh
|
||||
dd 0, 0, 0, 0
|
||||
|
||||
; ****************************************************************************
|
||||
; Sector Signature
|
||||
; ****************************************************************************
|
||||
|
||||
org 01FEh
|
||||
SectorSignature:
|
||||
dw 0aa55h ; Boot Sector Signature
|
||||
|
||||
end
|
||||
|
276
DuetPkg/BootSector/Makefile
Normal file
276
DuetPkg/BootSector/Makefile
Normal file
@ -0,0 +1,276 @@
|
||||
|
||||
#
|
||||
# Platform Macro Definition
|
||||
#
|
||||
PLATFORM_NAME = DuetPkg
|
||||
PLATFORM_GUID = 199E24E0-0989-42aa-87F2-611A8C397E72
|
||||
PLATFORM_VERSION = 0.3
|
||||
PLATFORM_RELATIVE_DIR = DuetPkg
|
||||
PLATFORM_DIR = $(WORKSPACE)\DuetPkg
|
||||
PLATFORM_OUTPUT_DIR = Build\DuetPkg
|
||||
|
||||
#
|
||||
# Module Macro Definition
|
||||
#
|
||||
MODULE_NAME = BootSector
|
||||
MODULE_GUID = 2410F0DF-D915-4137-BD04-AAB6BA4C50E0
|
||||
MODULE_VERSION = 1.0
|
||||
MODULE_TYPE = USER_DEFINED
|
||||
MODULE_FILE_BASE_NAME = BootSector
|
||||
BASE_NAME = $(MODULE_NAME)
|
||||
MODULE_RELATIVE_DIR = DuetPkg\BootSector
|
||||
MODULE_DIR = $(WORKSPACE)\DuetPkg\BootSector
|
||||
|
||||
#
|
||||
# Build Configuration Macro Definition
|
||||
#
|
||||
ARCH = IA32
|
||||
TOOLCHAIN_TAG = MYTOOLS
|
||||
TARGET = DEBUG
|
||||
BASETOOLS_DIR=m:\tree\working\BaseTools\Bin\Win32
|
||||
|
||||
#
|
||||
# Build Directory Macro Definition
|
||||
#
|
||||
# PLATFORM_BUILD_DIR = m:\tree\working\Build\DuetPkg\DEBUG_MYTOOLS
|
||||
BUILD_DIR = $(WORKSPACE)\Build\DuetPkg\DEBUG_MYTOOLS
|
||||
BIN_DIR = $(BUILD_DIR)\IA32
|
||||
LIB_DIR = $(BIN_DIR)
|
||||
MODULE_BUILD_DIR = $(BUILD_DIR)\IA32\DuetPkg\BootSector\BootSector
|
||||
OUTPUT_DIR = $(MODULE_BUILD_DIR)\OUTPUT
|
||||
DEBUG_DIR = $(MODULE_BUILD_DIR)\DEBUG
|
||||
DEST_DIR_OUTPUT = $(OUTPUT_DIR)
|
||||
DEST_DIR_DEBUG = $(DEBUG_DIR)
|
||||
|
||||
#
|
||||
# Default Tools Flags Macro Definition (from tools_def.txt by default)
|
||||
#
|
||||
DEFAULT_PP_FLAGS = /nologo /E /TC /FIAutoGen.h
|
||||
DEFAULT_SLINK_FLAGS = /nologo /LTCG
|
||||
DEFAULT_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs8192 /Gy /D UNICODE /O1ib2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Zi /Gm
|
||||
DEFAULT_APP_FLAGS = /nologo /E /TC
|
||||
DEFAULT_VFRPP_FLAGS = /nologo /E /TC /DVFRCOMPILE /FIAutoGen.h
|
||||
DEFAULT_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4086 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /MACHINE:I386 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:CONSOLE /SAFESEH:NO /BASE:0 /DRIVER /DEBUG /PDB:$(DEBUG_DIR)/$(BASE_NAME).pdb
|
||||
DEFAULT_ASM_FLAGS = /nologo /c /WX /W3 /coff /Cx /Zd /Zi
|
||||
DEFAULT_TIANO_FLAGS =
|
||||
DEFAULT_MAKE_FLAGS = /nologo
|
||||
DEFAULT_ASMLINK_FLAGS = /nologo /tiny
|
||||
DEFAULT_ASL_FLAGS =
|
||||
|
||||
|
||||
#
|
||||
# Platform Tools Flags Macro Definition (from platform description file)
|
||||
#
|
||||
PLATFORM_PP_FLAGS =
|
||||
PLATFORM_SLINK_FLAGS =
|
||||
PLATFORM_CC_FLAGS =
|
||||
PLATFORM_APP_FLAGS =
|
||||
PLATFORM_VFRPP_FLAGS =
|
||||
PLATFORM_DLINK_FLAGS =
|
||||
PLATFORM_ASM_FLAGS =
|
||||
PLATFORM_TIANO_FLAGS =
|
||||
PLATFORM_MAKE_FLAGS =
|
||||
PLATFORM_ASMLINK_FLAGS =
|
||||
PLATFORM_ASL_FLAGS =
|
||||
|
||||
|
||||
#
|
||||
# Module Tools Flags Macro Definition (from platform/module description file)
|
||||
#
|
||||
MODULE_PP_FLAGS =
|
||||
MODULE_SLINK_FLAGS =
|
||||
MODULE_CC_FLAGS =
|
||||
MODULE_APP_FLAGS =
|
||||
MODULE_VFRPP_FLAGS =
|
||||
MODULE_DLINK_FLAGS =
|
||||
MODULE_ASM_FLAGS =
|
||||
MODULE_TIANO_FLAGS =
|
||||
MODULE_MAKE_FLAGS =
|
||||
MODULE_ASMLINK_FLAGS =
|
||||
MODULE_ASL_FLAGS =
|
||||
|
||||
|
||||
#
|
||||
# Tools Flag Macro
|
||||
#
|
||||
PP_FLAGS = $(DEFAULT_PP_FLAGS) $(PLATFORM_PP_FLAGS) $(MODULE_PP_FLAGS)
|
||||
SLINK_FLAGS = $(DEFAULT_SLINK_FLAGS) $(PLATFORM_SLINK_FLAGS) $(MODULE_SLINK_FLAGS)
|
||||
CC_FLAGS = $(DEFAULT_CC_FLAGS) $(PLATFORM_CC_FLAGS) $(MODULE_CC_FLAGS)
|
||||
APP_FLAGS = $(DEFAULT_APP_FLAGS) $(PLATFORM_APP_FLAGS) $(MODULE_APP_FLAGS)
|
||||
VFRPP_FLAGS = $(DEFAULT_VFRPP_FLAGS) $(PLATFORM_VFRPP_FLAGS) $(MODULE_VFRPP_FLAGS)
|
||||
DLINK_FLAGS = $(DEFAULT_DLINK_FLAGS) $(PLATFORM_DLINK_FLAGS) $(MODULE_DLINK_FLAGS)
|
||||
ASM_FLAGS = $(DEFAULT_ASM_FLAGS) $(PLATFORM_ASM_FLAGS) $(MODULE_ASM_FLAGS)
|
||||
TIANO_FLAGS = $(DEFAULT_TIANO_FLAGS) $(PLATFORM_TIANO_FLAGS) $(MODULE_TIANO_FLAGS)
|
||||
MAKE_FLAGS = $(DEFAULT_MAKE_FLAGS) $(PLATFORM_MAKE_FLAGS) $(MODULE_MAKE_FLAGS)
|
||||
ASMLINK_FLAGS = $(DEFAULT_ASMLINK_FLAGS) $(PLATFORM_ASMLINK_FLAGS) $(MODULE_ASMLINK_FLAGS)
|
||||
ASL_FLAGS = $(DEFAULT_ASL_FLAGS) $(PLATFORM_ASL_FLAGS) $(MODULE_ASL_FLAGS)
|
||||
|
||||
|
||||
#
|
||||
# Tools Path Macro
|
||||
#
|
||||
PP = C:\Program Files\Microsoft Visual Studio 8\Vc\bin\cl.exe
|
||||
SLINK = C:\Program Files\Microsoft Visual Studio 8\Vc\bin\lib.exe
|
||||
CC = C:\Program Files\Microsoft Visual Studio 8\Vc\bin\cl.exe
|
||||
APP = C:\Program Files\Microsoft Visual Studio 8\Vc\bin\cl.exe
|
||||
VFRPP = C:\Program Files\Microsoft Visual Studio 8\Vc\bin\cl.exe
|
||||
DLINK = C:\Program Files\Microsoft Visual Studio 8\Vc\bin\link.exe
|
||||
ASM = C:\WINDDK\3790.1830\bin\x86\ml.exe
|
||||
TIANO = TianoCompress.exe
|
||||
MAKE = C:\Program Files\Microsoft Visual Studio 8\Vc\bin\nmake.exe
|
||||
#ASMLINK = C:\WINDDK\3790.1830\bin\bin16\link.exe
|
||||
ASMLINK = C:\WINDDK\3790.1830\bin\bin16\link16.exe
|
||||
ASL = C:\ASL\iasl.exe
|
||||
|
||||
|
||||
MAKE_FILE = $(MODULE_BUILD_DIR)\Makefile
|
||||
|
||||
#
|
||||
# Shell Command Macro
|
||||
#
|
||||
RD = rmdir /s /q
|
||||
RM = del /f /q
|
||||
MD = mkdir
|
||||
CP = copy /y
|
||||
MV = move /y
|
||||
|
||||
|
||||
#
|
||||
# Build Macro
|
||||
#
|
||||
ASSEMBLY_CODE_FILE_LIST = $(MODULE_DIR)\bootsect.asm \
|
||||
$(MODULE_DIR)\bs16.asm \
|
||||
$(MODULE_DIR)\bs32.asm \
|
||||
$(MODULE_DIR)\efi32.asm \
|
||||
$(MODULE_DIR)\Gpt.asm \
|
||||
$(MODULE_DIR)\Mbr.asm \
|
||||
$(MODULE_DIR)\start.asm \
|
||||
$(MODULE_DIR)\start16.asm \
|
||||
$(MODULE_DIR)\start32.asm
|
||||
|
||||
TARGET_FILES = $(OUTPUT_DIR)\bootsect.com \
|
||||
$(OUTPUT_DIR)\bs16.com \
|
||||
$(OUTPUT_DIR)\bs32.com \
|
||||
$(OUTPUT_DIR)\Gpt.com \
|
||||
$(OUTPUT_DIR)\Mbr.com \
|
||||
$(OUTPUT_DIR)\Start.com \
|
||||
$(OUTPUT_DIR)\Start16.com \
|
||||
$(OUTPUT_DIR)\Start32.com \
|
||||
$(OUTPUT_DIR)\efi32.com2
|
||||
|
||||
INC =
|
||||
|
||||
|
||||
#OBJECTS =
|
||||
|
||||
LIBS =
|
||||
|
||||
COMMON_DEPS =
|
||||
|
||||
all: init $(TARGET_FILES) loader
|
||||
|
||||
init:
|
||||
if not exist $(OUTPUT_DIR) mkdir $(OUTPUT_DIR)
|
||||
if not exist $(DEBUG_DIR) mkdir $(DEBUG_DIR)
|
||||
|
||||
#=============
|
||||
$(OUTPUT_DIR)\bootsect.obj:$(MODULE_DIR)\bootsect.asm
|
||||
$(ASM) /c /omf /Fo"$(OUTPUT_DIR)\bootsect.obj" /FR"$(OUTPUT_DIR)\bootsect.txt" "$(MODULE_DIR)\bootsect.asm"
|
||||
|
||||
$(OUTPUT_DIR)\bootsect.com:$(OUTPUT_DIR)\bootsect.obj
|
||||
"$(ASMLINK)" /tiny $(OUTPUT_DIR)\bootsect.obj,$(OUTPUT_DIR)\bootsect.com,$(OUTPUT_DIR)\bootsect.map,,,
|
||||
|
||||
#=============
|
||||
|
||||
$(OUTPUT_DIR)\bs16.obj:$(MODULE_DIR)\bs16.asm
|
||||
$(ASM) /c /omf /Fo"$(OUTPUT_DIR)\bs16.obj" "$(MODULE_DIR)\bs16.asm"
|
||||
|
||||
$(OUTPUT_DIR)\bs16.com:$(OUTPUT_DIR)\bs16.obj
|
||||
"$(ASMLINK)" /tiny $(OUTPUT_DIR)\bs16.obj,$(OUTPUT_DIR)\bs16.com,$(OUTPUT_DIR)\bs16.map,,,
|
||||
|
||||
#=============
|
||||
|
||||
$(OUTPUT_DIR)\bs32.obj:$(MODULE_DIR)\bs32.asm
|
||||
$(ASM) /c /omf /Fo"$(OUTPUT_DIR)\bs32.obj" "$(MODULE_DIR)\bs32.asm"
|
||||
|
||||
$(OUTPUT_DIR)\bs32.com:$(OUTPUT_DIR)\bs32.obj
|
||||
"$(ASMLINK)" /tiny $(OUTPUT_DIR)\bs32.obj,$(OUTPUT_DIR)\bs32.com,$(OUTPUT_DIR)\bs32.map,,,
|
||||
|
||||
#=============
|
||||
|
||||
$(OUTPUT_DIR)\Gpt.obj:$(MODULE_DIR)\Gpt.asm
|
||||
$(ASM) /c /omf /Fo"$(OUTPUT_DIR)\Gpt.obj" "$(MODULE_DIR)\Gpt.asm"
|
||||
|
||||
$(OUTPUT_DIR)\Gpt.com:$(OUTPUT_DIR)\Gpt.obj
|
||||
"$(ASMLINK)" /tiny $(OUTPUT_DIR)\Gpt.obj,$(OUTPUT_DIR)\Gpt.com,$(OUTPUT_DIR)\Gpt.map,,,
|
||||
|
||||
#=============
|
||||
|
||||
$(OUTPUT_DIR)\Mbr.obj:$(MODULE_DIR)\Mbr.asm
|
||||
$(ASM) /c /omf /Fo"$(OUTPUT_DIR)\Mbr.obj" "$(MODULE_DIR)\Mbr.asm"
|
||||
|
||||
$(OUTPUT_DIR)\Mbr.com:$(OUTPUT_DIR)\Mbr.obj
|
||||
"$(ASMLINK)" /tiny $(OUTPUT_DIR)\Mbr.obj,$(OUTPUT_DIR)\Mbr.com,$(OUTPUT_DIR)\Mbr.map,,,
|
||||
|
||||
#============
|
||||
|
||||
$(OUTPUT_DIR)\Start.obj:$(MODULE_DIR)\Start.asm
|
||||
$(ASM) /c /omf /Fo"$(OUTPUT_DIR)\Start.obj" "$(MODULE_DIR)\Start.asm"
|
||||
|
||||
$(OUTPUT_DIR)\Start.com:$(OUTPUT_DIR)\Start.obj
|
||||
"$(ASMLINK)" /tiny $(OUTPUT_DIR)\Start.obj,$(OUTPUT_DIR)\Start.com,$(OUTPUT_DIR)\Start.map,,,
|
||||
|
||||
#=============
|
||||
|
||||
$(OUTPUT_DIR)\Start16.obj:$(MODULE_DIR)\Start16.asm
|
||||
$(ASM) /c /omf /Fo"$(OUTPUT_DIR)\Start16.obj" "$(MODULE_DIR)\Start16.asm"
|
||||
|
||||
$(OUTPUT_DIR)\Start16.com:$(OUTPUT_DIR)\Start16.obj
|
||||
"$(ASMLINK)" /tiny $(OUTPUT_DIR)\Start16.obj,$(OUTPUT_DIR)\Start16.com,$(OUTPUT_DIR)\Start16.map,,,
|
||||
|
||||
#=============
|
||||
|
||||
$(OUTPUT_DIR)\Start32.obj:$(MODULE_DIR)\Start32.asm
|
||||
$(ASM) /c /omf /Fo"$(OUTPUT_DIR)\Start32.obj" "$(MODULE_DIR)\Start32.asm"
|
||||
|
||||
$(OUTPUT_DIR)\Start32.com:$(OUTPUT_DIR)\Start32.obj
|
||||
"$(ASMLINK)" /tiny $(OUTPUT_DIR)\Start32.obj,$(OUTPUT_DIR)\Start32.com,$(OUTPUT_DIR)\Start32.map,,,
|
||||
|
||||
#=============
|
||||
|
||||
$(OUTPUT_DIR)\efi32.obj:$(MODULE_DIR)\efi32.asm
|
||||
$(ASM) /c /omf /Fo"$(OUTPUT_DIR)\efi32.obj" "$(MODULE_DIR)\efi32.asm"
|
||||
|
||||
$(OUTPUT_DIR)\efi32.com:$(OUTPUT_DIR)\efi32.obj
|
||||
"$(ASMLINK)" /tiny $(OUTPUT_DIR)\efi32.obj,$(OUTPUT_DIR)\efi32.com,$(OUTPUT_DIR)\efi32.map,,,
|
||||
|
||||
#=============
|
||||
|
||||
$(OUTPUT_DIR)\efi32.com2:$(OUTPUT_DIR)\efi32.com
|
||||
$(BASETOOLS_DIR)\Split.exe -f $(OUTPUT_DIR)\efi32.com -t $(OUTPUT_DIR)\efi32.com2 -s 135168
|
||||
#
|
||||
# clean all generated files
|
||||
#
|
||||
|
||||
loader:$(BUILD_DIR)\FV\Efildr
|
||||
|
||||
$(BUILD_DIR)\FV\DUETEFIMAINFV.z:$(BUILD_DIR)\FV\DUETEFIMAINFV.Fv
|
||||
$(BASETOOLS_DIR)\TianoCompress -e -o $(BUILD_DIR)\FV\DUETEFIMAINFV.z $(BUILD_DIR)\FV\DUETEFIMAINFV.Fv
|
||||
|
||||
$(BUILD_DIR)\FV\DxeMain.z:$(BUILD_DIR)\IA32\DxeMain.efi
|
||||
$(BASETOOLS_DIR)\TianoCompress -e -o $(BUILD_DIR)\FV\DxeMain.z $(BUILD_DIR)\IA32\DxeMain.efi
|
||||
|
||||
$(BUILD_DIR)\FV\DxeIpl.z:$(BUILD_DIR)\IA32\DxeIpl.efi
|
||||
$(BASETOOLS_DIR)\TianoCompress -e -o $(BUILD_DIR)\FV\DxeIpl.z $(BUILD_DIR)\IA32\DxeIpl.efi
|
||||
|
||||
$(BUILD_DIR)\FV\Efildr32:$(BUILD_DIR)\IA32\EfiLoader.efi $(BUILD_DIR)\FV\DxeIpl.z $(BUILD_DIR)\FV\DUETEFIMAINFV.z
|
||||
$(BASETOOLS_DIR)\EfiLdrImage.exe -o $(BUILD_DIR)\FV\Efildr32 $(BUILD_DIR)\IA32\EfiLoader.efi $(BUILD_DIR)\FV\DxeIpl.z $(BUILD_DIR)\FV\DUETEFIMAINFV.z
|
||||
|
||||
$(BUILD_DIR)\FV\Efildr:$(OUTPUT_DIR)\Start.com $(OUTPUT_DIR)\Efi32.com2 $(BUILD_DIR)\FV\Efildr32
|
||||
copy /b $(OUTPUT_DIR)\BootSect.com+$(OUTPUT_DIR)\Efi32.com2+$(BUILD_DIR)\FV\Efildr32 $(BUILD_DIR)\FV\Efildr
|
||||
|
||||
clean:
|
||||
if exist $(DEBUG_DIR) rmdir /s /q $(DEBUG_DIR)
|
||||
if exist $(OUTPUT_DIR) rmdir /s /q $(OUTPUT_DIR)
|
||||
|
||||
|
261
DuetPkg/BootSector/Mbr.asm
Normal file
261
DuetPkg/BootSector/Mbr.asm
Normal file
@ -0,0 +1,261 @@
|
||||
;------------------------------------------------------------------------------
|
||||
;*
|
||||
;* Copyright 2006 - 2007, Intel Corporation
|
||||
;* All rights reserved. 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.
|
||||
;*
|
||||
;* Mbr.asm
|
||||
;*
|
||||
;* Abstract:
|
||||
;*
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
.model small
|
||||
; .dosseg
|
||||
.stack
|
||||
.486p
|
||||
.code
|
||||
|
||||
BLOCK_SIZE EQU 0200h
|
||||
BLOCK_MASK EQU 01ffh
|
||||
BLOCK_SHIFT EQU 9
|
||||
|
||||
; ****************************************************************************
|
||||
; Code loaded by BIOS at 0x0000:0x7C00
|
||||
; ****************************************************************************
|
||||
|
||||
org 0h
|
||||
Start:
|
||||
|
||||
; ****************************************************************************
|
||||
; Start Print
|
||||
; ****************************************************************************
|
||||
|
||||
mov ax,0b800h
|
||||
mov es,ax
|
||||
mov ax, 07c0h
|
||||
mov ds, ax
|
||||
lea si, cs:[StartString]
|
||||
mov cx, 10
|
||||
mov di, 160
|
||||
rep movsw
|
||||
|
||||
; ****************************************************************************
|
||||
; Print over
|
||||
; ****************************************************************************
|
||||
|
||||
; ****************************************************************************
|
||||
; Initialize segment registers and copy code at 0x0000:0x7c00 to 0x0000:0x0600
|
||||
; ****************************************************************************
|
||||
xor ax, ax ; AX = 0x0000
|
||||
mov bx, 07c00h ; BX = 0x7C00
|
||||
mov bp, 0600h ; BP = 0x0600
|
||||
mov si, OFFSET RelocatedStart ; SI = Offset(RelocatedStart)
|
||||
mov cx, 0200h ; CX = 0x0200
|
||||
sub cx, si ; CS = 0x0200 - Offset(RelocatedStart)
|
||||
lea di, [bp+si] ; DI = 0x0600 + Offset(RelocatedStart)
|
||||
lea si, [bx+si] ; BX = 0x7C00 + Offset(RelocatedStart)
|
||||
mov ss, ax ; SS = 0x0000
|
||||
mov sp, bx ; SP = 0x7C00
|
||||
mov es,ax ; ES = 0x0000
|
||||
mov ds,ax ; DS = 0x0000
|
||||
push ax ; PUSH 0x0000
|
||||
push di ; PUSH 0x0600 + Offset(RelocatedStart)
|
||||
cld ; Clear the direction flag
|
||||
rep movsb ; Copy 0x0200 bytes from 0x7C00 to 0x0600
|
||||
retf ; JMP 0x0000:0x0600 + Offset(RelocatedStart)
|
||||
|
||||
; ****************************************************************************
|
||||
; Code relocated to 0x0000:0x0600
|
||||
; ****************************************************************************
|
||||
|
||||
RelocatedStart:
|
||||
; ****************************************************************************
|
||||
; Get Driver Parameters to 0x0000:0x7BFC
|
||||
; ****************************************************************************
|
||||
|
||||
xor ax,ax ; AX = 0
|
||||
mov ss,ax ; SS = 0
|
||||
add ax,1000h
|
||||
mov ds,ax
|
||||
|
||||
mov sp,07c00h ; SP = 0x7c00
|
||||
mov bp,sp ; BP = 0x7c00
|
||||
|
||||
mov ah,8 ; AH = 8 - Get Drive Parameters Function
|
||||
mov byte ptr [bp+PhysicalDrive],dl ; BBS defines that BIOS would pass the booting driver number to the loader through DL
|
||||
int 13h ; Get Drive Parameters
|
||||
xor ax,ax ; AX = 0
|
||||
mov al,dh ; AL = DH
|
||||
inc al ; MaxHead = AL + 1
|
||||
push ax ; 0000:7bfe = MaxHead
|
||||
mov al,cl ; AL = CL
|
||||
and al,03fh ; MaxSector = AL & 0x3f
|
||||
push ax ; 0000:7bfc = MaxSector
|
||||
|
||||
; ****************************************************************************
|
||||
; Read Target DBR from hard disk to 0x0000:0x7C00
|
||||
; ****************************************************************************
|
||||
|
||||
xor ax, ax
|
||||
mov al, byte ptr [bp+MbrPartitionIndicator] ; AX = MbrPartitionIndex
|
||||
cmp al, 0ffh ; 0xFF means do legacy MBR boot
|
||||
jnz EfiDbr
|
||||
LegacyMbr:
|
||||
mov eax, 00000600h ; Assume LegacyMBR is backuped in Sector 6
|
||||
jmp StartReadTo7C00 ; EAX = Header/Sector/Tracker/Zero
|
||||
|
||||
EfiDbr:
|
||||
cmp al, 4 ; MbrPartitionIndex should < 4
|
||||
jae BadDbr
|
||||
shl ax, 4 ; AX = MBREntrySize * Index
|
||||
add ax, 1beh ; AX = MBREntryOffset
|
||||
mov di, ax ; DI = MBREntryOffset
|
||||
|
||||
; Here we don't use the C/H/S information provided by Partition table
|
||||
; but calculate C/H/S from LBA ourselves
|
||||
; Ci: Cylinder number
|
||||
; Hi: Header number
|
||||
; Si: Sector number
|
||||
mov eax, dword ptr es:[bp + di + 8] ; Start LBA
|
||||
mov edx, eax
|
||||
shr edx, 16 ; DX:AX = Start LBA
|
||||
; = Ci * (H * S) + Hi * S + (Si - 1)
|
||||
|
||||
; Calculate C/H/S according to LBA
|
||||
mov bp, 7bfah
|
||||
div word ptr [bp+2] ; AX = Hi + H*Ci
|
||||
; DX = Si - 1
|
||||
inc dx ; DX = Si
|
||||
push dx ; 0000:7bfa = Si <----
|
||||
xor dx, dx ; DX:AX = Hi + H*Ci
|
||||
div word ptr [bp+4] ; AX = Ci <----
|
||||
; DX = Hi <----
|
||||
|
||||
StartReadTo7C00:
|
||||
|
||||
mov cl, byte ptr [bp] ; Si
|
||||
mov ch, al ; Ci[0-7]
|
||||
or cl, ah ; Ci[8,9]
|
||||
mov bx, 7c00h ; ES:BX = 0000:7C00h
|
||||
mov ah, 2h ; Function 02h
|
||||
mov al, 1 ; 1 Sector
|
||||
mov dh, dl ; Hi
|
||||
mov bp, 0600h
|
||||
mov dl, byte ptr [bp + PhysicalDrive] ; Drive number
|
||||
int 13h
|
||||
jc BadDbr
|
||||
|
||||
|
||||
|
||||
; ****************************************************************************
|
||||
; Transfer control to BootSector - Jump to 0x0000:0x7C00
|
||||
; ****************************************************************************
|
||||
xor ax, ax
|
||||
push ax ; PUSH 0x0000 - Segment
|
||||
mov di, 07c00h
|
||||
push di ; PUSH 0x7C00 - Offset
|
||||
retf ; JMP 0x0000:0x7C00
|
||||
|
||||
; ****************************************************************************
|
||||
; ERROR Condition:
|
||||
; ****************************************************************************
|
||||
|
||||
BadDbr:
|
||||
push ax
|
||||
mov ax, 0b800h
|
||||
mov es, ax
|
||||
mov ax, 060h
|
||||
mov ds, ax
|
||||
lea si, cs:[ErrorString]
|
||||
mov di, 320
|
||||
pop ax
|
||||
call A2C
|
||||
mov [si+16], ah
|
||||
mov [si+18], al
|
||||
mov cx, 10
|
||||
rep movsw
|
||||
Halt:
|
||||
jmp Halt
|
||||
|
||||
StartString:
|
||||
db 'M', 0ch, 'B', 0ch, 'R', 0ch, ' ', 0ch, 'S', 0ch, 't', 0ch, 'a', 0ch, 'r', 0ch, 't', 0ch, '!', 0ch
|
||||
ErrorString:
|
||||
db 'M', 0ch, 'B', 0ch, 'R', 0ch, ' ', 0ch, 'E', 0ch, 'r', 0ch, 'r', 0ch, ':', 0ch, '?', 0ch, '?', 0ch
|
||||
|
||||
; ****************************************************************************
|
||||
; A2C - convert Ascii code stored in AH to character stored in AX
|
||||
; ****************************************************************************
|
||||
A2C:
|
||||
mov al, ah
|
||||
shr ah, 4
|
||||
and al, 0Fh
|
||||
add ah, '0'
|
||||
add al, '0'
|
||||
|
||||
cmp ah, '9'
|
||||
jle @f
|
||||
add ah, 7
|
||||
@@:
|
||||
|
||||
cmp al, '9'
|
||||
jle @f
|
||||
add al, 7
|
||||
@@:
|
||||
ret
|
||||
|
||||
|
||||
; ****************************************************************************
|
||||
; PhysicalDrive - Used to indicate which disk to be boot
|
||||
; Can be patched by tool
|
||||
; ****************************************************************************
|
||||
org 01B6h
|
||||
PhysicalDrive db 80h
|
||||
|
||||
; ****************************************************************************
|
||||
; MbrPartitionIndicator - Used to indicate which MBR partition to be boot
|
||||
; Can be patched by tool
|
||||
; OxFF means boot to legacy MBR. (LBA OFFSET 6)
|
||||
; ****************************************************************************
|
||||
org 01B7h
|
||||
MbrPartitionIndicator db 0
|
||||
|
||||
; ****************************************************************************
|
||||
; Unique MBR signature
|
||||
; ****************************************************************************
|
||||
org 01B8h
|
||||
db 'DUET'
|
||||
|
||||
; ****************************************************************************
|
||||
; Unknown
|
||||
; ****************************************************************************
|
||||
org 01BCh
|
||||
dw 0
|
||||
|
||||
; ****************************************************************************
|
||||
; MBR Entry - To be patched
|
||||
; ****************************************************************************
|
||||
org 01BEh
|
||||
dd 0, 0, 0, 0
|
||||
org 01CEh
|
||||
dd 0, 0, 0, 0
|
||||
org 01DEh
|
||||
dd 0, 0, 0, 0
|
||||
org 01EEh
|
||||
dd 0, 0, 0, 0
|
||||
|
||||
; ****************************************************************************
|
||||
; Sector Signature
|
||||
; ****************************************************************************
|
||||
|
||||
org 01FEh
|
||||
SectorSignature:
|
||||
dw 0aa55h ; Boot Sector Signature
|
||||
|
||||
end
|
||||
|
288
DuetPkg/BootSector/bootsect.asm
Normal file
288
DuetPkg/BootSector/bootsect.asm
Normal file
@ -0,0 +1,288 @@
|
||||
;------------------------------------------------------------------------------
|
||||
;*
|
||||
;* Copyright 2006 - 2007, Intel Corporation
|
||||
;* All rights reserved. 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.
|
||||
;*
|
||||
;* bootsect.asm
|
||||
;*
|
||||
;* Abstract:
|
||||
;*
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
.model small
|
||||
.stack
|
||||
.486p
|
||||
.code
|
||||
|
||||
FAT_DIRECTORY_ENTRY_SIZE EQU 020h
|
||||
FAT_DIRECTORY_ENTRY_SHIFT EQU 5
|
||||
BLOCK_SIZE EQU 0200h
|
||||
BLOCK_MASK EQU 01ffh
|
||||
BLOCK_SHIFT EQU 9
|
||||
; "EFILDR_____"
|
||||
LOADER_FILENAME_PART1 EQU 04c494645h ; "EFIL"
|
||||
LOADER_FILENAME_PART2 EQU 020205244h ; "DR__"
|
||||
LOADER_FILENAME_PART3 EQU 020202020h ; "____"
|
||||
|
||||
org 0h
|
||||
Ia32Jump:
|
||||
jmp BootSectorEntryPoint ; JMP inst - 3 bytes
|
||||
nop
|
||||
|
||||
OemId db "INTEL " ; OemId - 8 bytes
|
||||
; BPB data below will be fixed by tool
|
||||
SectorSize dw 0 ; Sector Size - 16 bits
|
||||
SectorsPerCluster db 0 ; Sector Per Cluster - 8 bits
|
||||
ReservedSectors dw 0 ; Reserved Sectors - 16 bits
|
||||
NoFats db 0 ; Number of FATs - 8 bits
|
||||
RootEntries dw 0 ; Root Entries - 16 bits
|
||||
Sectors dw 0 ; Number of Sectors - 16 bits
|
||||
Media db 0 ; Media - 8 bits - ignored
|
||||
SectorsPerFat dw 0 ; Sectors Per FAT - 16 bits
|
||||
SectorsPerTrack dw 0 ; Sectors Per Track - 16 bits - ignored
|
||||
Heads dw 0 ; Heads - 16 bits - ignored
|
||||
HiddenSectors dd 0 ; Hidden Sectors - 32 bits - ignored
|
||||
LargeSectors dd 0 ; Large Sectors - 32 bits
|
||||
PhysicalDrive db 0 ; PhysicalDriveNumber - 8 bits - ignored
|
||||
CurrentHead db 0 ; Current Head - 8 bits
|
||||
Signature db 0 ; Signature - 8 bits - ignored
|
||||
Id db " " ; Id - 4 bytes
|
||||
FatLabel db " " ; Label - 11 bytes
|
||||
SystemId db "FAT12 " ; SystemId - 8 bytes
|
||||
|
||||
BootSectorEntryPoint:
|
||||
ASSUME ds:@code
|
||||
ASSUME ss:@code
|
||||
|
||||
; ****************************************************************************
|
||||
; Start Print
|
||||
; ****************************************************************************
|
||||
lea si, cs:[StartString]
|
||||
call PrintString
|
||||
|
||||
; ****************************************************************************
|
||||
; Print over
|
||||
; ****************************************************************************
|
||||
|
||||
mov ax,cs ; ax = 0
|
||||
mov ss,ax ; ss = 0
|
||||
add ax,1000h
|
||||
mov ds,ax
|
||||
|
||||
mov sp,07c00h ; sp = 0x7c00
|
||||
mov bp,sp ; bp = 0x7c00
|
||||
|
||||
mov ah,8 ; ah = 8 - Get Drive Parameters Function
|
||||
mov byte ptr [bp+PhysicalDrive],dl ; BBS defines that BIOS would pass the booting driver number to the loader through DL
|
||||
int 13h ; Get Drive Parameters
|
||||
xor ax,ax ; ax = 0
|
||||
mov al,dh ; al = dh
|
||||
inc al ; MaxHead = al + 1
|
||||
push ax ; 0000:7bfe = MaxHead
|
||||
mov al,cl ; al = cl
|
||||
and al,03fh ; MaxSector = al & 0x3f
|
||||
push ax ; 0000:7bfc = MaxSector
|
||||
|
||||
cmp word ptr [bp+SectorSignature],0aa55h ; Verify Boot Sector Signature
|
||||
jne BadBootSector
|
||||
mov cx,word ptr [bp+RootEntries] ; cx = RootEntries
|
||||
shl cx,FAT_DIRECTORY_ENTRY_SHIFT ; cx = cx * 32 = cx * sizeof(FAT_DIRECTORY_ENTRY) = Size of Root Directory in bytes
|
||||
mov bx,cx ; bx = size of the Root Directory in bytes
|
||||
and bx,BLOCK_MASK ; See if it is an even number of sectors long
|
||||
jne BadBootSector ; If is isn't, then the boot sector is bad.
|
||||
mov bx,cx ; bx = size of the Root Directory in bytes
|
||||
shr bx,BLOCK_SHIFT ; bx = size of Root Directory in sectors
|
||||
mov al,byte ptr [bp+NoFats] ; al = NoFats
|
||||
xor ah,ah ; ah = 0 ==> ax = NoFats
|
||||
mul word ptr [bp+SectorsPerFat] ; ax = NoFats * SectorsPerFat
|
||||
add ax,word ptr [bp+ReservedSectors] ; ax = NoFats * SectorsPerFat + ReservedSectors = RootLBA
|
||||
push ds
|
||||
pop es
|
||||
xor di,di ; Store directory in es:di = 1000:0000
|
||||
call ReadBlocks ; Read entire Root Directory
|
||||
add ax,bx ; ax = NoFats * SectorsPerFat + ReservedSectors + RootDirSectors = FirstClusterLBA (FirstDataSector)
|
||||
mov word ptr [bp],ax ; Save FirstClusterLBA (FirstDataSector) for later use
|
||||
|
||||
; dx - variable storage (initial value is 0)
|
||||
; bx - loader (initial value is 0)
|
||||
xor dx, dx
|
||||
xor bx, bx
|
||||
|
||||
FindEFILDR:
|
||||
cmp dword ptr [di],LOADER_FILENAME_PART1 ; Compare to "EFIL"
|
||||
jne FindVARSTORE
|
||||
cmp dword ptr [di+4],LOADER_FILENAME_PART2
|
||||
jne FindVARSTORE
|
||||
cmp dword ptr [di+7],LOADER_FILENAME_PART3
|
||||
jne FindVARSTORE
|
||||
mov bx, word ptr [di+26] ; bx = Start Cluster for EFILDR <----------------------------------
|
||||
test dx, dx
|
||||
je FindNext ; Efivar.bin is not loaded
|
||||
jmp FoundAll
|
||||
|
||||
FindVARSTORE:
|
||||
; if the file is not loader file, see if it's "EFIVAR BIN"
|
||||
cmp dword ptr [di], 056494645h ; Compare to "EFIV"
|
||||
jne FindNext
|
||||
cmp dword ptr [di+4], 020205241h ; Compare to "AR "
|
||||
jne FindNext
|
||||
cmp dword ptr [di+7], 04e494220h ; Compare to " BIN"
|
||||
jne FindNext
|
||||
mov dx, di ; dx = Offset of Start Cluster for Efivar.bin <---------------------
|
||||
add dx, 26
|
||||
test bx, bx
|
||||
je FindNext ; Efildr is not loaded
|
||||
jmp FoundAll
|
||||
|
||||
FindNext:
|
||||
; go to next find
|
||||
add di,FAT_DIRECTORY_ENTRY_SIZE ; Increment di
|
||||
sub cx,FAT_DIRECTORY_ENTRY_SIZE ; Decrement cx
|
||||
; TODO: jump to FindVarStore if ...
|
||||
jne FindEFILDR
|
||||
jmp NotFoundAll
|
||||
|
||||
FoundAll:
|
||||
FoundEFILDR:
|
||||
mov cx,bx ; cx = Start Cluster for EFILDR <----------------------------------
|
||||
mov ax,cs ; Destination = 2000:0000
|
||||
add ax,2000h
|
||||
mov es,ax
|
||||
xor di,di
|
||||
ReadFirstClusterOfEFILDR:
|
||||
mov ax,cx ; ax = StartCluster
|
||||
sub ax,2 ; ax = StartCluster - 2
|
||||
xor bh,bh
|
||||
mov bl,byte ptr [bp+SectorsPerCluster] ; bx = SectorsPerCluster
|
||||
push dx
|
||||
mul bx
|
||||
pop dx ; ax = (StartCluster - 2) * SectorsPerCluster
|
||||
add ax, word ptr [bp] ; ax = FirstClusterLBA + (StartCluster-2)*SectorsPerCluster
|
||||
xor bh,bh
|
||||
mov bl,byte ptr [bp+SectorsPerCluster] ; bx = Number of Sectors in a cluster
|
||||
push es
|
||||
call ReadBlocks
|
||||
pop ax
|
||||
JumpIntoFirstSectorOfEFILDR:
|
||||
mov word ptr [bp+JumpSegment],ax
|
||||
JumpFarInstruction:
|
||||
db 0eah
|
||||
JumpOffset:
|
||||
dw 0000h
|
||||
JumpSegment:
|
||||
dw 2000h
|
||||
|
||||
|
||||
PrintString:
|
||||
mov ax,0b800h
|
||||
mov es,ax
|
||||
mov ax, 07c0h
|
||||
mov ds, ax
|
||||
mov cx, 7
|
||||
mov di, 160
|
||||
rep movsw
|
||||
ret
|
||||
; ****************************************************************************
|
||||
; ReadBlocks - Reads a set of blocks from a block device
|
||||
;
|
||||
; AX = Start LBA
|
||||
; BX = Number of Blocks to Read
|
||||
; ES:DI = Buffer to store sectors read from disk
|
||||
; ****************************************************************************
|
||||
|
||||
; cx = Blocks
|
||||
; bx = NumberOfBlocks
|
||||
; si = StartLBA
|
||||
|
||||
ReadBlocks:
|
||||
pusha
|
||||
add eax,dword ptr [bp+LBAOffsetForBootSector] ; Add LBAOffsetForBootSector to Start LBA
|
||||
add eax,dword ptr [bp+HiddenSectors] ; Add HiddenSectors to Start LBA
|
||||
mov esi,eax ; esi = Start LBA
|
||||
mov cx,bx ; cx = Number of blocks to read
|
||||
ReadCylinderLoop:
|
||||
mov bp,07bfch ; bp = 0x7bfc
|
||||
mov eax,esi ; eax = Start LBA
|
||||
xor edx,edx ; edx = 0
|
||||
movzx ebx,word ptr [bp] ; bx = MaxSector
|
||||
div ebx ; ax = StartLBA / MaxSector
|
||||
inc dx ; dx = (StartLBA % MaxSector) + 1
|
||||
sub bx,dx ; bx = MaxSector - Sector
|
||||
inc bx ; bx = MaxSector - Sector + 1
|
||||
cmp cx,bx ; Compare (Blocks) to (MaxSector - Sector + 1)
|
||||
jg LimitTransfer
|
||||
mov bx,cx ; bx = Blocks
|
||||
LimitTransfer:
|
||||
push cx
|
||||
mov cl,dl ; cl = (StartLBA % MaxSector) + 1 = Sector
|
||||
xor dx,dx ; dx = 0
|
||||
div word ptr [bp+2] ; ax = ax / (MaxHead + 1) = Cylinder
|
||||
; dx = ax % (MaxHead + 1) = Head
|
||||
|
||||
push bx ; Save number of blocks to transfer
|
||||
mov dh,dl ; dh = Head
|
||||
mov bp,07c00h ; bp = 0x7c00
|
||||
mov dl,byte ptr [bp+PhysicalDrive] ; dl = Drive Number
|
||||
mov ch,al ; ch = Cylinder
|
||||
mov al,bl ; al = Blocks
|
||||
mov ah,2 ; ah = Function 2
|
||||
mov bx,di ; es:bx = Buffer address
|
||||
int 013h
|
||||
jc DiskError
|
||||
pop bx
|
||||
pop cx
|
||||
movzx ebx,bx
|
||||
add esi,ebx ; StartLBA = StartLBA + NumberOfBlocks
|
||||
sub cx,bx ; Blocks = Blocks - NumberOfBlocks
|
||||
mov ax,es
|
||||
shl bx,(BLOCK_SHIFT-4)
|
||||
add ax,bx
|
||||
mov es,ax ; es:di = es:di + NumberOfBlocks*BLOCK_SIZE
|
||||
cmp cx,0
|
||||
jne ReadCylinderLoop
|
||||
popa
|
||||
ret
|
||||
|
||||
; ****************************************************************************
|
||||
; ERROR Condition:
|
||||
; ****************************************************************************
|
||||
NotFoundAll:
|
||||
; if we found EFILDR, continue
|
||||
test bx,bx
|
||||
jne FoundEFILDR
|
||||
BadBootSector:
|
||||
DiskError:
|
||||
lea si, cs:[ErrorString]
|
||||
call PrintString
|
||||
Halt:
|
||||
jmp Halt
|
||||
|
||||
StartString:
|
||||
db 'B', 0ch, 'S', 0ch, 't', 0ch, 'a', 0ch, 'r', 0ch, 't', 0ch, '!', 0ch
|
||||
ErrorString:
|
||||
db 'B', 0ch, 'E', 0ch, 'r', 0ch, 'r', 0ch, 'o', 0ch, 'r', 0ch, '!', 0ch
|
||||
|
||||
; ****************************************************************************
|
||||
; LBA Offset for BootSector, need patched by tool for HD boot.
|
||||
; ****************************************************************************
|
||||
|
||||
org 01fah
|
||||
LBAOffsetForBootSector:
|
||||
dd 0h
|
||||
|
||||
; ****************************************************************************
|
||||
; Sector Signature
|
||||
; ****************************************************************************
|
||||
|
||||
org 01feh
|
||||
SectorSignature:
|
||||
dw 0aa55h ; Boot Sector Signature
|
||||
|
||||
end
|
||||
|
288
DuetPkg/BootSector/bs16.asm
Normal file
288
DuetPkg/BootSector/bs16.asm
Normal file
@ -0,0 +1,288 @@
|
||||
;------------------------------------------------------------------------------
|
||||
;*
|
||||
;* Copyright 2006 - 2007, Intel Corporation
|
||||
;* All rights reserved. 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.
|
||||
;*
|
||||
;* bs16.asm
|
||||
;*
|
||||
;* Abstract:
|
||||
;*
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
.model small
|
||||
.stack
|
||||
.486p
|
||||
.code
|
||||
|
||||
FAT_DIRECTORY_ENTRY_SIZE EQU 020h
|
||||
FAT_DIRECTORY_ENTRY_SHIFT EQU 5
|
||||
BLOCK_SIZE EQU 0200h
|
||||
BLOCK_MASK EQU 01ffh
|
||||
BLOCK_SHIFT EQU 9
|
||||
; "EFILDR_____"
|
||||
LOADER_FILENAME_PART1 EQU 04c494645h ; "EFIL"
|
||||
LOADER_FILENAME_PART2 EQU 036315244h ; "DR16"
|
||||
LOADER_FILENAME_PART3 EQU 020202036h ; "6___"
|
||||
|
||||
org 0h
|
||||
Ia32Jump:
|
||||
jmp BootSectorEntryPoint ; JMP inst - 3 bytes
|
||||
nop
|
||||
|
||||
OemId db "INTEL " ; OemId - 8 bytes
|
||||
; BPB data below will be fixed by tool
|
||||
SectorSize dw 0 ; Sector Size - 16 bits
|
||||
SectorsPerCluster db 0 ; Sector Per Cluster - 8 bits
|
||||
ReservedSectors dw 0 ; Reserved Sectors - 16 bits
|
||||
NoFats db 0 ; Number of FATs - 8 bits
|
||||
RootEntries dw 0 ; Root Entries - 16 bits
|
||||
Sectors dw 0 ; Number of Sectors - 16 bits
|
||||
Media db 0 ; Media - 8 bits - ignored
|
||||
SectorsPerFat dw 0 ; Sectors Per FAT - 16 bits
|
||||
SectorsPerTrack dw 0 ; Sectors Per Track - 16 bits - ignored
|
||||
Heads dw 0 ; Heads - 16 bits - ignored
|
||||
HiddenSectors dd 0 ; Hidden Sectors - 32 bits - ignored
|
||||
LargeSectors dd 0 ; Large Sectors - 32 bits
|
||||
PhysicalDrive db 0 ; PhysicalDriveNumber - 8 bits - ignored
|
||||
CurrentHead db 0 ; Current Head - 8 bits
|
||||
Signature db 0 ; Signature - 8 bits - ignored
|
||||
Id db " " ; Id - 4 bytes
|
||||
FatLabel db " " ; Label - 11 bytes
|
||||
SystemId db "FAT16 " ; SystemId - 8 bytes
|
||||
|
||||
BootSectorEntryPoint:
|
||||
ASSUME ds:@code
|
||||
ASSUME ss:@code
|
||||
|
||||
; ****************************************************************************
|
||||
; Start Print
|
||||
; ****************************************************************************
|
||||
lea si, cs:[StartString]
|
||||
call PrintString
|
||||
|
||||
; ****************************************************************************
|
||||
; Print over
|
||||
; ****************************************************************************
|
||||
|
||||
mov ax,cs ; ax = 0
|
||||
mov ss,ax ; ss = 0
|
||||
add ax,1000h
|
||||
mov ds,ax
|
||||
|
||||
mov sp,07c00h ; sp = 0x7c00
|
||||
mov bp,sp ; bp = 0x7c00
|
||||
|
||||
mov ah,8 ; ah = 8 - Get Drive Parameters Function
|
||||
mov byte ptr [bp+PhysicalDrive],dl ; BBS defines that BIOS would pass the booting driver number to the loader through DL
|
||||
int 13h ; Get Drive Parameters
|
||||
xor ax,ax ; ax = 0
|
||||
mov al,dh ; al = dh
|
||||
inc al ; MaxHead = al + 1
|
||||
push ax ; 0000:7bfe = MaxHead
|
||||
mov al,cl ; al = cl
|
||||
and al,03fh ; MaxSector = al & 0x3f
|
||||
push ax ; 0000:7bfc = MaxSector
|
||||
|
||||
cmp word ptr [bp+SectorSignature],0aa55h ; Verify Boot Sector Signature
|
||||
jne BadBootSector
|
||||
mov cx,word ptr [bp+RootEntries] ; cx = RootEntries
|
||||
shl cx,FAT_DIRECTORY_ENTRY_SHIFT ; cx = cx * 32 = cx * sizeof(FAT_DIRECTORY_ENTRY) = Size of Root Directory in bytes
|
||||
mov bx,cx ; bx = size of the Root Directory in bytes
|
||||
and bx,BLOCK_MASK ; See if it is an even number of sectors long
|
||||
jne BadBootSector ; If is isn't, then the boot sector is bad.
|
||||
mov bx,cx ; bx = size of the Root Directory in bytes
|
||||
shr bx,BLOCK_SHIFT ; bx = size of Root Directory in sectors
|
||||
mov al,byte ptr [bp+NoFats] ; al = NoFats
|
||||
xor ah,ah ; ah = 0 ==> ax = NoFats
|
||||
mul word ptr [bp+SectorsPerFat] ; ax = NoFats * SectorsPerFat
|
||||
add ax,word ptr [bp+ReservedSectors] ; ax = NoFats * SectorsPerFat + ReservedSectors = RootLBA
|
||||
push ds
|
||||
pop es
|
||||
xor di,di ; Store directory in es:di = 1000:0000
|
||||
call ReadBlocks ; Read entire Root Directory
|
||||
add ax,bx ; ax = NoFats * SectorsPerFat + ReservedSectors + RootDirSectors = FirstClusterLBA (FirstDataSector)
|
||||
mov word ptr [bp],ax ; Save FirstClusterLBA (FirstDataSector) for later use
|
||||
|
||||
; dx - variable storage (initial value is 0)
|
||||
; bx - loader (initial value is 0)
|
||||
xor dx, dx
|
||||
xor bx, bx
|
||||
|
||||
FindEFILDR:
|
||||
cmp dword ptr [di],LOADER_FILENAME_PART1 ; Compare to "EFIL"
|
||||
jne FindVARSTORE
|
||||
cmp dword ptr [di+4],LOADER_FILENAME_PART2
|
||||
jne FindVARSTORE
|
||||
cmp dword ptr [di+7],LOADER_FILENAME_PART3
|
||||
jne FindVARSTORE
|
||||
mov bx, word ptr [di+26] ; bx = Start Cluster for EFILDR <----------------------------------
|
||||
test dx, dx
|
||||
je FindNext ; Efivar.bin is not loaded
|
||||
jmp FoundAll
|
||||
|
||||
FindVARSTORE:
|
||||
; if the file is not loader file, see if it's "EFIVAR BIN"
|
||||
cmp dword ptr [di], 056494645h ; Compare to "EFIV"
|
||||
jne FindNext
|
||||
cmp dword ptr [di+4], 020205241h ; Compare to "AR "
|
||||
jne FindNext
|
||||
cmp dword ptr [di+7], 04e494220h ; Compare to " BIN"
|
||||
jne FindNext
|
||||
mov dx, di ; dx = Offset of Start Cluster for Efivar.bin <---------------------
|
||||
add dx, 26
|
||||
test bx, bx
|
||||
je FindNext ; Efildr is not loaded
|
||||
jmp FoundAll
|
||||
|
||||
FindNext:
|
||||
; go to next find
|
||||
add di,FAT_DIRECTORY_ENTRY_SIZE ; Increment di
|
||||
sub cx,FAT_DIRECTORY_ENTRY_SIZE ; Decrement cx
|
||||
; TODO: jump to FindVarStore if ...
|
||||
jne FindEFILDR
|
||||
jmp NotFoundAll
|
||||
|
||||
FoundAll:
|
||||
FoundEFILDR:
|
||||
mov cx,bx ; cx = Start Cluster for EFILDR <----------------------------------
|
||||
mov ax,cs ; Destination = 2000:0000
|
||||
add ax,2000h
|
||||
mov es,ax
|
||||
xor di,di
|
||||
ReadFirstClusterOfEFILDR:
|
||||
mov ax,cx ; ax = StartCluster
|
||||
sub ax,2 ; ax = StartCluster - 2
|
||||
xor bh,bh
|
||||
mov bl,byte ptr [bp+SectorsPerCluster] ; bx = SectorsPerCluster
|
||||
push dx
|
||||
mul bx
|
||||
pop dx ; ax = (StartCluster - 2) * SectorsPerCluster
|
||||
add ax, word ptr [bp] ; ax = FirstClusterLBA + (StartCluster-2)*SectorsPerCluster
|
||||
xor bh,bh
|
||||
mov bl,byte ptr [bp+SectorsPerCluster] ; bx = Number of Sectors in a cluster
|
||||
push es
|
||||
call ReadBlocks
|
||||
pop ax
|
||||
JumpIntoFirstSectorOfEFILDR:
|
||||
mov word ptr [bp+JumpSegment],ax
|
||||
JumpFarInstruction:
|
||||
db 0eah
|
||||
JumpOffset:
|
||||
dw 0000h
|
||||
JumpSegment:
|
||||
dw 2000h
|
||||
|
||||
|
||||
PrintString:
|
||||
mov ax,0b800h
|
||||
mov es,ax
|
||||
mov ax, 07c0h
|
||||
mov ds, ax
|
||||
mov cx, 7
|
||||
mov di, 160
|
||||
rep movsw
|
||||
ret
|
||||
; ****************************************************************************
|
||||
; ReadBlocks - Reads a set of blocks from a block device
|
||||
;
|
||||
; AX = Start LBA
|
||||
; BX = Number of Blocks to Read
|
||||
; ES:DI = Buffer to store sectors read from disk
|
||||
; ****************************************************************************
|
||||
|
||||
; cx = Blocks
|
||||
; bx = NumberOfBlocks
|
||||
; si = StartLBA
|
||||
|
||||
ReadBlocks:
|
||||
pusha
|
||||
add eax,dword ptr [bp+LBAOffsetForBootSector] ; Add LBAOffsetForBootSector to Start LBA
|
||||
add eax,dword ptr [bp+HiddenSectors] ; Add HiddenSectors to Start LBA
|
||||
mov esi,eax ; esi = Start LBA
|
||||
mov cx,bx ; cx = Number of blocks to read
|
||||
ReadCylinderLoop:
|
||||
mov bp,07bfch ; bp = 0x7bfc
|
||||
mov eax,esi ; eax = Start LBA
|
||||
xor edx,edx ; edx = 0
|
||||
movzx ebx,word ptr [bp] ; bx = MaxSector
|
||||
div ebx ; ax = StartLBA / MaxSector
|
||||
inc dx ; dx = (StartLBA % MaxSector) + 1
|
||||
sub bx,dx ; bx = MaxSector - Sector
|
||||
inc bx ; bx = MaxSector - Sector + 1
|
||||
cmp cx,bx ; Compare (Blocks) to (MaxSector - Sector + 1)
|
||||
jg LimitTransfer
|
||||
mov bx,cx ; bx = Blocks
|
||||
LimitTransfer:
|
||||
push cx
|
||||
mov cl,dl ; cl = (StartLBA % MaxSector) + 1 = Sector
|
||||
xor dx,dx ; dx = 0
|
||||
div word ptr [bp+2] ; ax = ax / (MaxHead + 1) = Cylinder
|
||||
; dx = ax % (MaxHead + 1) = Head
|
||||
|
||||
push bx ; Save number of blocks to transfer
|
||||
mov dh,dl ; dh = Head
|
||||
mov bp,07c00h ; bp = 0x7c00
|
||||
mov dl,byte ptr [bp+PhysicalDrive] ; dl = Drive Number
|
||||
mov ch,al ; ch = Cylinder
|
||||
mov al,bl ; al = Blocks
|
||||
mov ah,2 ; ah = Function 2
|
||||
mov bx,di ; es:bx = Buffer address
|
||||
int 013h
|
||||
jc DiskError
|
||||
pop bx
|
||||
pop cx
|
||||
movzx ebx,bx
|
||||
add esi,ebx ; StartLBA = StartLBA + NumberOfBlocks
|
||||
sub cx,bx ; Blocks = Blocks - NumberOfBlocks
|
||||
mov ax,es
|
||||
shl bx,(BLOCK_SHIFT-4)
|
||||
add ax,bx
|
||||
mov es,ax ; es:di = es:di + NumberOfBlocks*BLOCK_SIZE
|
||||
cmp cx,0
|
||||
jne ReadCylinderLoop
|
||||
popa
|
||||
ret
|
||||
|
||||
; ****************************************************************************
|
||||
; ERROR Condition:
|
||||
; ****************************************************************************
|
||||
NotFoundAll:
|
||||
; if we found EFILDR, continue
|
||||
test bx,bx
|
||||
jne FoundEFILDR
|
||||
BadBootSector:
|
||||
DiskError:
|
||||
lea si, cs:[ErrorString]
|
||||
call PrintString
|
||||
Halt:
|
||||
jmp Halt
|
||||
|
||||
StartString:
|
||||
db 'B', 0ch, 'S', 0ch, 't', 0ch, 'a', 0ch, 'r', 0ch, 't', 0ch, '!', 0ch
|
||||
ErrorString:
|
||||
db 'B', 0ch, 'E', 0ch, 'r', 0ch, 'r', 0ch, 'o', 0ch, 'r', 0ch, '!', 0ch
|
||||
|
||||
; ****************************************************************************
|
||||
; LBA Offset for BootSector, need patched by tool for HD boot.
|
||||
; ****************************************************************************
|
||||
|
||||
org 01fah
|
||||
LBAOffsetForBootSector:
|
||||
dd 0h
|
||||
|
||||
; ****************************************************************************
|
||||
; Sector Signature
|
||||
; ****************************************************************************
|
||||
|
||||
org 01feh
|
||||
SectorSignature:
|
||||
dw 0aa55h ; Boot Sector Signature
|
||||
|
||||
end
|
||||
|
310
DuetPkg/BootSector/bs32.asm
Normal file
310
DuetPkg/BootSector/bs32.asm
Normal file
@ -0,0 +1,310 @@
|
||||
;------------------------------------------------------------------------------
|
||||
;*
|
||||
;* Copyright 2006 - 2007, Intel Corporation
|
||||
;* All rights reserved. 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.
|
||||
;*
|
||||
;* bs32.asm
|
||||
;*
|
||||
;* Abstract:
|
||||
;*
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
.model small
|
||||
.stack
|
||||
.486p
|
||||
.code
|
||||
|
||||
FAT_DIRECTORY_ENTRY_SIZE EQU 020h
|
||||
FAT_DIRECTORY_ENTRY_SHIFT EQU 5
|
||||
BLOCK_SIZE EQU 0200h
|
||||
BLOCK_MASK EQU 01ffh
|
||||
BLOCK_SHIFT EQU 9
|
||||
; "EFILDR_____"
|
||||
LOADER_FILENAME_PART1 EQU 04c494645h ; "EFIL"
|
||||
LOADER_FILENAME_PART2 EQU 030325244h ; "DR20"
|
||||
LOADER_FILENAME_PART3 EQU 020202030h ; "0___"
|
||||
|
||||
org 0h
|
||||
Ia32Jump:
|
||||
jmp BootSectorEntryPoint ; JMP inst - 3 bytes
|
||||
nop
|
||||
|
||||
OemId db "INTEL " ; OemId - 8 bytes
|
||||
; BPB data below will be fixed by tool
|
||||
SectorSize dw 0 ; Sector Size - 16 bits
|
||||
SectorsPerCluster db 0 ; Sector Per Cluster - 8 bits
|
||||
ReservedSectors dw 0 ; Reserved Sectors - 16 bits
|
||||
NoFats db 0 ; Number of FATs - 8 bits
|
||||
RootEntries dw 0 ; Root Entries - 16 bits
|
||||
Sectors dw 0 ; Number of Sectors - 16 bits
|
||||
Media db 0 ; Media - 8 bits - ignored
|
||||
SectorsPerFat dw 0 ; Sectors Per FAT - 16 bits
|
||||
SectorsPerTrack dw 0 ; Sectors Per Track - 16 bits - ignored
|
||||
Heads dw 0 ; Heads - 16 bits - ignored
|
||||
HiddenSectors dd 0 ; Hidden Sectors - 32 bits - ignored
|
||||
LargeSectors dd 0 ; Large Sectors - 32 bits
|
||||
|
||||
;******************************************************************************
|
||||
;
|
||||
;The structure for FAT32 starting at offset 36 of the boot sector. (At this point,
|
||||
;the BPB/boot sector for FAT12 and FAT16 differs from the BPB/boot sector for FAT32.)
|
||||
;
|
||||
;******************************************************************************
|
||||
|
||||
SectorsPerFat32 dd 0 ; Sectors Per FAT for FAT32 - 4 bytes
|
||||
ExtFlags dw 0 ; Mirror Flag - 2 bytes
|
||||
FSVersion dw 0 ; File System Version - 2 bytes
|
||||
RootCluster dd 0 ; 1st Cluster Number of Root Dir - 4 bytes
|
||||
FSInfo dw 0 ; Sector Number of FSINFO - 2 bytes
|
||||
BkBootSector dw 0 ; Sector Number of Bk BootSector - 2 bytes
|
||||
Reserved db 12 dup(0) ; Reserved Field - 12 bytes
|
||||
PhysicalDrive db 0 ; Physical Drive Number - 1 byte
|
||||
Reserved1 db 0 ; Reserved Field - 1 byte
|
||||
Signature db 0 ; Extended Boot Signature - 1 byte
|
||||
VolId db " " ; Volume Serial Number - 4 bytes
|
||||
FatLabel db " " ; Volume Label - 11 bytes
|
||||
FileSystemType db "FAT32 " ; File System Type - 8 bytes
|
||||
|
||||
BootSectorEntryPoint:
|
||||
ASSUME ds:@code
|
||||
ASSUME ss:@code
|
||||
|
||||
; ****************************************************************************
|
||||
; Start Print
|
||||
; ****************************************************************************
|
||||
lea si, cs:[StartString]
|
||||
call PrintString
|
||||
|
||||
; ****************************************************************************
|
||||
; Print over
|
||||
; ****************************************************************************
|
||||
|
||||
mov ax,cs ; ax = 0
|
||||
mov ss,ax ; ss = 0
|
||||
add ax,1000h
|
||||
mov ds,ax
|
||||
|
||||
mov sp,07c00h ; sp = 0x7c00
|
||||
mov bp,sp ; bp = 0x7c00
|
||||
|
||||
mov ah,8 ; ah = 8 - Get Drive Parameters Function
|
||||
mov byte ptr [bp+PhysicalDrive],dl ; BBS defines that BIOS would pass the booting driver number to the loader through DL
|
||||
int 13h ; Get Drive Parameters
|
||||
xor ax,ax ; ax = 0
|
||||
mov al,dh ; al = dh
|
||||
inc al ; MaxHead = al + 1
|
||||
push ax ; 0000:7bfe = MaxHead
|
||||
mov al,cl ; al = cl
|
||||
and al,03fh ; MaxSector = al & 0x3f
|
||||
push ax ; 0000:7bfc = MaxSector
|
||||
|
||||
cmp word ptr [bp+SectorSignature],0aa55h ; Verify Boot Sector Signature
|
||||
jne BadBootSector
|
||||
mov cx,word ptr [bp+RootEntries] ; cx = RootEntries
|
||||
shl cx,FAT_DIRECTORY_ENTRY_SHIFT ; cx = cx * 32 = cx * sizeof(FAT_DIRECTORY_ENTRY) = Size of Root Directory in bytes
|
||||
mov bx,cx ; bx = size of the Root Directory in bytes
|
||||
and bx,BLOCK_MASK ; See if it is an even number of sectors long
|
||||
jne BadBootSector ; If is isn't, then the boot sector is bad.
|
||||
mov bx,cx ; bx = size of the Root Directory in bytes
|
||||
shr bx,BLOCK_SHIFT ; bx = size of Root Directory in sectors
|
||||
mov al,byte ptr [bp+NoFats] ; al = NoFats
|
||||
xor ah,ah ; ah = 0 ==> ax = NoFats
|
||||
mul word ptr [bp+SectorsPerFat32] ; ax = NoFats * SectorsPerFat
|
||||
add ax,word ptr [bp+ReservedSectors] ; ax = NoFats * SectorsPerFat + ReservedSectors = RootLBA
|
||||
add ax,bx ; ax = NoFats * SectorsPerFat + ReservedSectors + RootDirSectors = FirstClusterLBA
|
||||
mov word ptr [bp],ax ; Save FirstClusterLBA for later use
|
||||
|
||||
mov ax,word ptr [bp+RootCluster] ; ax = StartCluster of Root Directory
|
||||
sub ax,2 ; ax = StartCluster - 2
|
||||
xor bh,bh
|
||||
mov bl,byte ptr [bp+SectorsPerCluster]; bx = SectorsPerCluster
|
||||
mul bx ; ax = (StartCluster - 2) * SectorsPerCluster
|
||||
add ax, word ptr [bp] ; ax = FirstClusterLBA + (StartCluster-2)*SectorsPerCluster
|
||||
push ds
|
||||
pop es
|
||||
xor di,di ; Store directory in es:di = 1000:0000
|
||||
call ReadBlocks ; Read StartCluster of Root Directory
|
||||
|
||||
; dx - variable storage (initial value is 0)
|
||||
; bx - loader (initial value is 0)
|
||||
xor dx, dx
|
||||
xor bx, bx
|
||||
|
||||
FindEFILDR:
|
||||
cmp dword ptr [di],LOADER_FILENAME_PART1 ; Compare to "EFIL"
|
||||
jne FindVARSTORE
|
||||
cmp dword ptr [di+4],LOADER_FILENAME_PART2
|
||||
jne FindVARSTORE
|
||||
cmp dword ptr [di+7],LOADER_FILENAME_PART3
|
||||
jne FindVARSTORE
|
||||
mov bx, word ptr [di+26] ; bx = Start Cluster for EFILDR <----------------------------------
|
||||
test dx, dx
|
||||
je FindNext ; Efivar.bin is not loaded
|
||||
jmp FoundAll
|
||||
|
||||
FindVARSTORE:
|
||||
; if the file is not loader file, see if it's "EFIVAR BIN"
|
||||
cmp dword ptr [di], 056494645h ; Compare to "EFIV"
|
||||
jne FindNext
|
||||
cmp dword ptr [di+4], 020205241h ; Compare to "AR "
|
||||
jne FindNext
|
||||
cmp dword ptr [di+7], 04e494220h ; Compare to " BIN"
|
||||
jne FindNext
|
||||
mov dx, di ; dx = Offset of Start Cluster for Efivar.bin <---------------------
|
||||
add dx, 26
|
||||
test bx, bx
|
||||
je FindNext ; Efildr is not loaded
|
||||
jmp FoundAll
|
||||
|
||||
FindNext:
|
||||
; go to next find
|
||||
add di,FAT_DIRECTORY_ENTRY_SIZE ; Increment di
|
||||
sub cx,FAT_DIRECTORY_ENTRY_SIZE ; Decrement cx
|
||||
; TODO: jump to FindVarStore if ...
|
||||
jne FindEFILDR
|
||||
jmp NotFoundAll
|
||||
|
||||
FoundAll:
|
||||
FoundEFILDR:
|
||||
mov cx,bx ; cx = Start Cluster for EFILDR <----------------------------------
|
||||
mov ax,cs ; Destination = 2000:0000
|
||||
add ax,2000h
|
||||
mov es,ax
|
||||
xor di,di
|
||||
ReadFirstClusterOfEFILDR:
|
||||
mov ax,cx ; ax = StartCluster
|
||||
sub ax,2 ; ax = StartCluster - 2
|
||||
xor bh,bh
|
||||
mov bl,byte ptr [bp+SectorsPerCluster] ; bx = SectorsPerCluster
|
||||
push dx
|
||||
mul bx
|
||||
pop dx ; ax = (StartCluster - 2) * SectorsPerCluster
|
||||
add ax, word ptr [bp] ; ax = FirstClusterLBA + (StartCluster-2)*SectorsPerCluster
|
||||
xor bh,bh
|
||||
mov bl,byte ptr [bp+SectorsPerCluster] ; bx = Number of Sectors in a cluster
|
||||
push es
|
||||
call ReadBlocks
|
||||
pop ax
|
||||
JumpIntoFirstSectorOfEFILDR:
|
||||
mov word ptr [bp+JumpSegment],ax
|
||||
JumpFarInstruction:
|
||||
db 0eah
|
||||
JumpOffset:
|
||||
dw 0000h
|
||||
JumpSegment:
|
||||
dw 2000h
|
||||
|
||||
|
||||
PrintString:
|
||||
mov ax,0b800h
|
||||
mov es,ax
|
||||
mov ax, 07c0h
|
||||
mov ds, ax
|
||||
mov cx, 7
|
||||
mov di, 160
|
||||
rep movsw
|
||||
ret
|
||||
; ****************************************************************************
|
||||
; ReadBlocks - Reads a set of blocks from a block device
|
||||
;
|
||||
; AX = Start LBA
|
||||
; BX = Number of Blocks to Read
|
||||
; ES:DI = Buffer to store sectors read from disk
|
||||
; ****************************************************************************
|
||||
|
||||
; cx = Blocks
|
||||
; bx = NumberOfBlocks
|
||||
; si = StartLBA
|
||||
|
||||
ReadBlocks:
|
||||
pusha
|
||||
add eax,dword ptr [bp+LBAOffsetForBootSector] ; Add LBAOffsetForBootSector to Start LBA
|
||||
add eax,dword ptr [bp+HiddenSectors] ; Add HiddenSectors to Start LBA
|
||||
mov esi,eax ; esi = Start LBA
|
||||
mov cx,bx ; cx = Number of blocks to read
|
||||
ReadCylinderLoop:
|
||||
mov bp,07bfch ; bp = 0x7bfc
|
||||
mov eax,esi ; eax = Start LBA
|
||||
xor edx,edx ; edx = 0
|
||||
movzx ebx,word ptr [bp] ; bx = MaxSector
|
||||
div ebx ; ax = StartLBA / MaxSector
|
||||
inc dx ; dx = (StartLBA % MaxSector) + 1
|
||||
sub bx,dx ; bx = MaxSector - Sector
|
||||
inc bx ; bx = MaxSector - Sector + 1
|
||||
cmp cx,bx ; Compare (Blocks) to (MaxSector - Sector + 1)
|
||||
jg LimitTransfer
|
||||
mov bx,cx ; bx = Blocks
|
||||
LimitTransfer:
|
||||
push cx
|
||||
mov cl,dl ; cl = (StartLBA % MaxSector) + 1 = Sector
|
||||
xor dx,dx ; dx = 0
|
||||
div word ptr [bp+2] ; ax = ax / (MaxHead + 1) = Cylinder
|
||||
; dx = ax % (MaxHead + 1) = Head
|
||||
|
||||
push bx ; Save number of blocks to transfer
|
||||
mov dh,dl ; dh = Head
|
||||
mov bp,07c00h ; bp = 0x7c00
|
||||
mov dl,byte ptr [bp+PhysicalDrive] ; dl = Drive Number
|
||||
mov ch,al ; ch = Cylinder
|
||||
mov al,bl ; al = Blocks
|
||||
mov ah,2 ; ah = Function 2
|
||||
mov bx,di ; es:bx = Buffer address
|
||||
int 013h
|
||||
jc DiskError
|
||||
pop bx
|
||||
pop cx
|
||||
movzx ebx,bx
|
||||
add esi,ebx ; StartLBA = StartLBA + NumberOfBlocks
|
||||
sub cx,bx ; Blocks = Blocks - NumberOfBlocks
|
||||
mov ax,es
|
||||
shl bx,(BLOCK_SHIFT-4)
|
||||
add ax,bx
|
||||
mov es,ax ; es:di = es:di + NumberOfBlocks*BLOCK_SIZE
|
||||
cmp cx,0
|
||||
jne ReadCylinderLoop
|
||||
popa
|
||||
ret
|
||||
|
||||
; ****************************************************************************
|
||||
; ERROR Condition:
|
||||
; ****************************************************************************
|
||||
NotFoundAll:
|
||||
; if we found EFILDR, continue
|
||||
test bx,bx
|
||||
jne FoundEFILDR
|
||||
BadBootSector:
|
||||
DiskError:
|
||||
lea si, cs:[ErrorString]
|
||||
call PrintString
|
||||
Halt:
|
||||
jmp Halt
|
||||
|
||||
StartString:
|
||||
db 'B', 0ch, 'S', 0ch, 't', 0ch, 'a', 0ch, 'r', 0ch, 't', 0ch, '!', 0ch
|
||||
ErrorString:
|
||||
db 'B', 0ch, 'E', 0ch, 'r', 0ch, 'r', 0ch, 'o', 0ch, 'r', 0ch, '!', 0ch
|
||||
|
||||
; ****************************************************************************
|
||||
; LBA Offset for BootSector, need patched by tool for HD boot.
|
||||
; ****************************************************************************
|
||||
|
||||
org 01fah
|
||||
LBAOffsetForBootSector:
|
||||
dd 0h
|
||||
|
||||
; ****************************************************************************
|
||||
; Sector Signature
|
||||
; ****************************************************************************
|
||||
|
||||
org 01feh
|
||||
SectorSignature:
|
||||
dw 0aa55h ; Boot Sector Signature
|
||||
|
||||
end
|
||||
|
581
DuetPkg/BootSector/efi32.asm
Normal file
581
DuetPkg/BootSector/efi32.asm
Normal file
@ -0,0 +1,581 @@
|
||||
;------------------------------------------------------------------------------
|
||||
;*
|
||||
;* Copyright 2006, Intel Corporation
|
||||
;* All rights reserved. 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.
|
||||
;*
|
||||
;* efi32.asm
|
||||
;*
|
||||
;* Abstract:
|
||||
;*
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; Now in 32-bit protected mode.
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
.486
|
||||
.model flat
|
||||
.stack
|
||||
.code
|
||||
org 21000h
|
||||
|
||||
DEFAULT_HANDLER_SIZE EQU INT1 - INT0
|
||||
|
||||
JmpCommonIdtEntry macro
|
||||
; jmp commonIdtEntry - this must be hand coded to keep the assembler from
|
||||
; using a 8 bit reletive jump when the entries are
|
||||
; within 255 bytes of the common entry. This must
|
||||
; be done to maintain the consistency of the size
|
||||
; of entry points...
|
||||
db 0e9h ; jmp 16 bit relative
|
||||
dd commonIdtEntry - $ - 4 ; offset to jump to
|
||||
endm
|
||||
|
||||
|
||||
Start:
|
||||
mov ds,ax
|
||||
mov es,ax
|
||||
mov fs,ax
|
||||
mov gs,ax
|
||||
mov ss,ax
|
||||
mov esp,0001ffff0h
|
||||
|
||||
call ClearScreen
|
||||
|
||||
; Populate IDT with meaningful offsets for exception handlers...
|
||||
sidt fword ptr [Idtr] ; get fword address of IDT
|
||||
|
||||
mov eax, offset Halt
|
||||
mov ebx, eax ; use bx to copy 15..0 to descriptors
|
||||
shr eax, 16 ; use ax to copy 31..16 to descriptors
|
||||
mov ecx, 78h ; 78h IDT entries to initialize with unique entry points (exceptions)
|
||||
mov esi, [offset Idtr + 2]
|
||||
mov edi, [esi]
|
||||
|
||||
@@: ; loop through all IDT entries exception handlers and initialize to default handler
|
||||
mov word ptr [edi], bx ; write bits 15..0 of offset
|
||||
mov word ptr [edi+2], 20h ; SYS_CODE_SEL from GDT
|
||||
mov word ptr [edi+4], 0e00h OR 8000h ; type = 386 interrupt gate, present
|
||||
mov word ptr [edi+6], ax ; write bits 31..16 of offset
|
||||
add edi, 8 ; move up to next descriptor
|
||||
add bx, DEFAULT_HANDLER_SIZE ; move to next entry point
|
||||
loop @b ; loop back through again until all descriptors are initialized
|
||||
|
||||
;; at this point edi contains the offset of the descriptor for INT 20
|
||||
;; and bx contains the low 16 bits of the offset of the default handler
|
||||
;; so initialize all the rest of the descriptors with these two values...
|
||||
; mov ecx, 101 ; there are 100 descriptors left (INT 20 (14h) - INT 119 (77h)
|
||||
;@@: ; loop through all IDT entries exception handlers and initialize to default handler
|
||||
; mov word ptr [edi], bx ; write bits 15..0 of offset
|
||||
; mov word ptr [edi+2], 20h ; SYS_CODE_SEL from GDT
|
||||
; mov word ptr [edi+4], 0e00h OR 8000h ; type = 386 interrupt gate, present
|
||||
; mov word ptr [edi+6], ax ; write bits 31..16 of offset
|
||||
; add edi, 8 ; move up to next descriptor
|
||||
; loop @b ; loop back through again until all descriptors are initialized
|
||||
|
||||
|
||||
;; DUMP location of IDT and several of the descriptors
|
||||
; mov ecx, 8
|
||||
; mov eax, [offset Idtr + 2]
|
||||
; mov eax, [eax]
|
||||
; mov edi, 0b8000h
|
||||
; call PrintDword
|
||||
; mov esi, eax
|
||||
; mov edi, 0b80a0h
|
||||
; jmp OuterLoop
|
||||
|
||||
;;
|
||||
;; just for fun, let's do a software interrupt to see if we correctly land in the exception handler...
|
||||
; mov eax, 011111111h
|
||||
; mov ebx, 022222222h
|
||||
; mov ecx, 033333333h
|
||||
; mov edx, 044444444h
|
||||
; mov ebp, 055555555h
|
||||
; mov esi, 066666666h
|
||||
; mov edi, 077777777h
|
||||
; push 011111111h
|
||||
; push 022222222h
|
||||
; push 033333333h
|
||||
; int 119
|
||||
|
||||
|
||||
mov esi,022000h ; esi = 22000
|
||||
mov eax,[esi+014h] ; eax = [22014]
|
||||
add esi,eax ; esi = 22000 + [22014] = Base of EFILDR.C
|
||||
mov ebp,[esi+03ch] ; ebp = [22000 + [22014] + 3c] = NT Image Header for EFILDR.C
|
||||
add ebp,esi
|
||||
mov edi,[ebp+034h] ; edi = [[22000 + [22014] + 3c] + 30] = ImageBase
|
||||
mov eax,[ebp+028h] ; eax = [[22000 + [22014] + 3c] + 24] = EntryPoint
|
||||
add eax,edi ; eax = ImageBase + EntryPoint
|
||||
mov dword ptr [EfiLdrOffset],eax ; Modify far jump instruction for correct entry point
|
||||
|
||||
mov bx,word ptr[ebp+6] ; bx = Number of sections
|
||||
xor eax,eax
|
||||
mov ax,word ptr[ebp+014h] ; ax = Optional Header Size
|
||||
add ebp,eax
|
||||
add ebp,018h ; ebp = Start of 1st Section
|
||||
|
||||
SectionLoop:
|
||||
push esi ; Save Base of EFILDR.C
|
||||
push edi ; Save ImageBase
|
||||
add esi,[ebp+014h] ; esi = Base of EFILDR.C + PointerToRawData
|
||||
add edi,[ebp+00ch] ; edi = ImageBase + VirtualAddress
|
||||
mov ecx,[ebp+010h] ; ecs = SizeOfRawData
|
||||
|
||||
cld
|
||||
shr ecx,2
|
||||
rep movsd
|
||||
|
||||
pop edi ; Restore ImageBase
|
||||
pop esi ; Restore Base of EFILDR.C
|
||||
|
||||
add bp,028h ; ebp = ebp + 028h = Pointer to next section record
|
||||
dec bx
|
||||
cmp bx,0
|
||||
jne SectionLoop
|
||||
|
||||
movzx eax, word ptr [Idtr] ; get size of IDT
|
||||
inc eax
|
||||
add eax, dword ptr [Idtr + 2] ; add to base of IDT to get location of memory map...
|
||||
push eax ; push memory map location on stack for call to EFILDR...
|
||||
|
||||
push eax ; push return address (useless, just for stack balance)
|
||||
db 0b8h
|
||||
EfiLdrOffset:
|
||||
dd 000401000h ; Offset of EFILDR
|
||||
; mov eax, 401000h
|
||||
push eax
|
||||
ret
|
||||
|
||||
; db "**** DEFAULT IDT ENTRY ***",0
|
||||
align 02h
|
||||
Halt:
|
||||
INT0:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 0h
|
||||
JmpCommonIdtEntry
|
||||
; db 0e9h ; jmp 16 bit reletive
|
||||
; dd commonIdtEntry - $ - 4 ; offset to jump to
|
||||
|
||||
INT1:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 1h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT2:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 2h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT3:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 3h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT4:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 4h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT5:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 5h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT6:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 6h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT7:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 7h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT8:
|
||||
; Double fault causes an error code to be pushed so no phony push necessary
|
||||
nop
|
||||
nop
|
||||
push 8h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT9:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 9h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT10:
|
||||
; Invalid TSS causes an error code to be pushed so no phony push necessary
|
||||
nop
|
||||
nop
|
||||
push 10
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT11:
|
||||
; Segment Not Present causes an error code to be pushed so no phony push necessary
|
||||
nop
|
||||
nop
|
||||
push 11
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT12:
|
||||
; Stack fault causes an error code to be pushed so no phony push necessary
|
||||
nop
|
||||
nop
|
||||
push 12
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT13:
|
||||
; GP fault causes an error code to be pushed so no phony push necessary
|
||||
nop
|
||||
nop
|
||||
push 13
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT14:
|
||||
; Page fault causes an error code to be pushed so no phony push necessary
|
||||
nop
|
||||
nop
|
||||
push 14
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT15:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 15
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT16:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 16
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT17:
|
||||
; Alignment check causes an error code to be pushed so no phony push necessary
|
||||
nop
|
||||
nop
|
||||
push 17
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT18:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 18
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT19:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 19
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INTUnknown:
|
||||
REPEAT (78h - 20)
|
||||
push 0h ; push error code place holder on the stack
|
||||
; push xxh ; push vector number
|
||||
db 06ah
|
||||
db ( $ - INTUnknown - 3 ) / 9 + 20 ; vector number
|
||||
JmpCommonIdtEntry
|
||||
ENDM
|
||||
|
||||
commonIdtEntry:
|
||||
pushad
|
||||
mov ebp, esp
|
||||
;;
|
||||
;; At this point the stack looks like this:
|
||||
;;
|
||||
;; eflags
|
||||
;; Calling CS
|
||||
;; Calling EIP
|
||||
;; Error code or 0
|
||||
;; Int num or 0ffh for unknown int num
|
||||
;; eax
|
||||
;; ecx
|
||||
;; edx
|
||||
;; ebx
|
||||
;; esp
|
||||
;; ebp
|
||||
;; esi
|
||||
;; edi <------- ESP, EBP
|
||||
;;
|
||||
|
||||
call ClearScreen
|
||||
mov esi, offset String1
|
||||
call PrintString
|
||||
mov eax, [ebp + 32] ;; move Int number into EAX
|
||||
cmp eax, 19
|
||||
ja PrintDefaultString
|
||||
PrintExceptionString:
|
||||
shl eax, 2 ;; multiply by 4 to get offset from StringTable to actual string address
|
||||
add eax, offset StringTable
|
||||
mov esi, [eax]
|
||||
jmp PrintTheString
|
||||
PrintDefaultString:
|
||||
mov esi, offset IntUnknownString
|
||||
; patch Int number
|
||||
mov edx, eax
|
||||
call A2C
|
||||
mov [esi + 1], al
|
||||
mov eax, edx
|
||||
shr eax, 4
|
||||
call A2C
|
||||
mov [esi], al
|
||||
PrintTheString:
|
||||
call PrintString
|
||||
mov esi, offset String2
|
||||
call PrintString
|
||||
mov eax, [ebp+44] ; CS
|
||||
call PrintDword
|
||||
mov al, ':'
|
||||
mov byte ptr [edi], al
|
||||
add edi, 2
|
||||
mov eax, [ebp+40] ; EIP
|
||||
call PrintDword
|
||||
mov esi, offset String3
|
||||
call PrintString
|
||||
|
||||
mov edi, 0b8140h
|
||||
|
||||
mov esi, offset StringEax ; eax
|
||||
call PrintString
|
||||
mov eax, [ebp+28]
|
||||
call PrintDword
|
||||
|
||||
mov esi, offset StringEbx ; ebx
|
||||
call PrintString
|
||||
mov eax, [ebp+16]
|
||||
call PrintDword
|
||||
|
||||
mov esi, offset StringEcx ; ecx
|
||||
call PrintString
|
||||
mov eax, [ebp+24]
|
||||
call PrintDword
|
||||
|
||||
mov esi, offset StringEdx ; edx
|
||||
call PrintString
|
||||
mov eax, [ebp+20]
|
||||
call PrintDword
|
||||
|
||||
mov esi, offset StringEcode ; error code
|
||||
call PrintString
|
||||
mov eax, [ebp+36]
|
||||
call PrintDword
|
||||
|
||||
mov edi, 0b81e0h
|
||||
|
||||
mov esi, offset StringEsp ; esp
|
||||
call PrintString
|
||||
mov eax, [ebp+12]
|
||||
call PrintDword
|
||||
|
||||
mov esi, offset StringEbp ; ebp
|
||||
call PrintString
|
||||
mov eax, [ebp+8]
|
||||
call PrintDword
|
||||
|
||||
mov esi, offset StringEsi ; esi
|
||||
call PrintString
|
||||
mov eax, [ebp+4]
|
||||
call PrintDword
|
||||
|
||||
mov esi, offset StringEdi ; edi
|
||||
call PrintString
|
||||
mov eax, [ebp]
|
||||
call PrintDword
|
||||
|
||||
mov esi, offset StringEflags ; eflags
|
||||
call PrintString
|
||||
mov eax, [ebp+48]
|
||||
call PrintDword
|
||||
|
||||
mov edi, 0b8320h
|
||||
|
||||
mov esi, ebp
|
||||
add esi, 52
|
||||
mov ecx, 8
|
||||
|
||||
|
||||
OuterLoop:
|
||||
push ecx
|
||||
mov ecx, 8
|
||||
mov edx, edi
|
||||
|
||||
InnerLoop:
|
||||
mov eax, [esi]
|
||||
call PrintDword
|
||||
add esi, 4
|
||||
mov al, ' '
|
||||
mov [edi], al
|
||||
add edi, 2
|
||||
loop InnerLoop
|
||||
|
||||
pop ecx
|
||||
add edx, 0a0h
|
||||
mov edi, edx
|
||||
loop OuterLoop
|
||||
|
||||
|
||||
mov edi, 0b8960h
|
||||
|
||||
mov eax, [ebp+40] ; EIP
|
||||
sub eax, 32 * 4
|
||||
mov esi, eax ; esi = eip - 32 DWORD linear (total 64 DWORD)
|
||||
|
||||
mov ecx, 8
|
||||
|
||||
OuterLoop1:
|
||||
push ecx
|
||||
mov ecx, 8
|
||||
mov edx, edi
|
||||
|
||||
InnerLoop1:
|
||||
mov eax, [esi]
|
||||
call PrintDword
|
||||
add esi, 4
|
||||
mov al, ' '
|
||||
mov [edi], al
|
||||
add edi, 2
|
||||
loop InnerLoop1
|
||||
|
||||
pop ecx
|
||||
add edx, 0a0h
|
||||
mov edi, edx
|
||||
loop OuterLoop1
|
||||
|
||||
|
||||
|
||||
; wbinvd ; Ken: this intruction does not support in early than 486 arch
|
||||
@@:
|
||||
jmp @b
|
||||
;
|
||||
; return
|
||||
;
|
||||
mov esp, ebp
|
||||
popad
|
||||
add esp, 8 ; error code and INT number
|
||||
|
||||
iretd
|
||||
|
||||
|
||||
PrintString:
|
||||
push eax
|
||||
@@:
|
||||
mov al, byte ptr [esi]
|
||||
cmp al, 0
|
||||
je @f
|
||||
mov byte ptr [edi], al
|
||||
inc esi
|
||||
add edi, 2
|
||||
jmp @b
|
||||
@@:
|
||||
pop eax
|
||||
ret
|
||||
|
||||
;; EAX contains dword to print
|
||||
;; EDI contains memory location (screen location) to print it to
|
||||
PrintDword:
|
||||
push ecx
|
||||
push ebx
|
||||
push eax
|
||||
|
||||
mov ecx, 8
|
||||
looptop:
|
||||
rol eax, 4
|
||||
mov bl, al
|
||||
and bl, 0fh
|
||||
add bl, '0'
|
||||
cmp bl, '9'
|
||||
jle @f
|
||||
add bl, 7
|
||||
@@:
|
||||
mov byte ptr [edi], bl
|
||||
add edi, 2
|
||||
loop looptop
|
||||
wbinvd
|
||||
|
||||
pop eax
|
||||
pop ebx
|
||||
pop ecx
|
||||
ret
|
||||
|
||||
ClearScreen:
|
||||
push eax
|
||||
push ecx
|
||||
|
||||
mov al, ' '
|
||||
mov ah, 0ch
|
||||
mov edi, 0b8000h
|
||||
mov ecx, 80 * 24
|
||||
@@:
|
||||
mov word ptr [edi], ax
|
||||
add edi, 2
|
||||
loop @b
|
||||
mov edi, 0b8000h
|
||||
|
||||
pop ecx
|
||||
pop eax
|
||||
|
||||
ret
|
||||
|
||||
A2C:
|
||||
and al, 0fh
|
||||
add al, '0'
|
||||
cmp al, '9'
|
||||
jle @f
|
||||
add al, 7
|
||||
@@:
|
||||
ret
|
||||
|
||||
String1 db "*** INT ",0
|
||||
|
||||
Int0String db "00h Divide by 0 -",0
|
||||
Int1String db "01h Debug exception -",0
|
||||
Int2String db "02h NMI -",0
|
||||
Int3String db "03h Breakpoint -",0
|
||||
Int4String db "04h Overflow -",0
|
||||
Int5String db "05h Bound -",0
|
||||
Int6String db "06h Invalid opcode -",0
|
||||
Int7String db "07h Device not available -",0
|
||||
Int8String db "08h Double fault -",0
|
||||
Int9String db "09h Coprocessor seg overrun (reserved) -",0
|
||||
Int10String db "0Ah Invalid TSS -",0
|
||||
Int11String db "0Bh Segment not present -",0
|
||||
Int12String db "0Ch Stack fault -",0
|
||||
Int13String db "0Dh General protection fault -",0
|
||||
Int14String db "0Eh Page fault -",0
|
||||
Int15String db "0Fh (Intel reserved) -",0
|
||||
Int16String db "10h Floating point error -",0
|
||||
Int17String db "11h Alignment check -",0
|
||||
Int18String db "12h Machine check -",0
|
||||
Int19String db "13h SIMD Floating-Point Exception -",0
|
||||
IntUnknownString db "??h Unknown interrupt -",0
|
||||
|
||||
StringTable dd offset Int0String, offset Int1String, offset Int2String, offset Int3String,
|
||||
offset Int4String, offset Int5String, offset Int6String, offset Int7String,
|
||||
offset Int8String, offset Int9String, offset Int10String, offset Int11String,
|
||||
offset Int12String, offset Int13String, offset Int14String, offset Int15String,
|
||||
offset Int16String, offset Int17String, offset Int18String, offset Int19String
|
||||
|
||||
String2 db " HALT!! *** (",0
|
||||
String3 db ")",0
|
||||
StringEax db "EAX=",0
|
||||
StringEbx db " EBX=",0
|
||||
StringEcx db " ECX=",0
|
||||
StringEdx db " EDX=",0
|
||||
StringEcode db " ECODE=",0
|
||||
StringEsp db "ESP=",0
|
||||
StringEbp db " EBP=",0
|
||||
StringEsi db " ESI=",0
|
||||
StringEdi db " EDI=",0
|
||||
StringEflags db " EFLAGS=",0
|
||||
|
||||
Idtr df 0
|
||||
|
||||
org 21ffeh
|
||||
BlockSignature:
|
||||
dw 0aa55h
|
||||
|
||||
end
|
787
DuetPkg/BootSector/efi64.asm
Normal file
787
DuetPkg/BootSector/efi64.asm
Normal file
@ -0,0 +1,787 @@
|
||||
;------------------------------------------------------------------------------
|
||||
;*
|
||||
;* Copyright 2006, Intel Corporation
|
||||
;* All rights reserved. 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.
|
||||
;*
|
||||
;* efi64.asm
|
||||
;*
|
||||
;* Abstract:
|
||||
;*
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; Now in 64-bit long mode.
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
.486
|
||||
.model flat
|
||||
.stack
|
||||
.code
|
||||
org 21000h
|
||||
|
||||
DEFAULT_HANDLER_SIZE EQU INT1 - INT0
|
||||
|
||||
JmpCommonIdtEntry macro
|
||||
; jmp commonIdtEntry - this must be hand coded to keep the assembler from
|
||||
; using a 8 bit reletive jump when the entries are
|
||||
; within 255 bytes of the common entry. This must
|
||||
; be done to maintain the consistency of the size
|
||||
; of entry points...
|
||||
db 0e9h ; jmp 16 bit reletive
|
||||
dd commonIdtEntry - $ - 4 ; offset to jump to
|
||||
endm
|
||||
|
||||
|
||||
Start:
|
||||
|
||||
mov esp,0001fffe8h ; make final stack aligned
|
||||
|
||||
; set OSFXSR and OSXMMEXCPT because some code will use XMM register
|
||||
db 0fh
|
||||
db 20h
|
||||
db 0e0h
|
||||
; mov rax, cr4
|
||||
bts eax, 9
|
||||
bts eax, 0ah
|
||||
db 0fh
|
||||
db 22h
|
||||
db 0e0h
|
||||
; mov cr4, rax
|
||||
|
||||
call ClearScreen
|
||||
|
||||
; Populate IDT with meaningful offsets for exception handlers...
|
||||
mov eax, offset Idtr
|
||||
sidt fword ptr [eax] ; get fword address of IDT
|
||||
|
||||
mov eax, offset Halt
|
||||
mov ebx, eax ; use bx to copy 15..0 to descriptors
|
||||
shr eax, 16 ; use ax to copy 31..16 to descriptors
|
||||
; 63..32 of descriptors is 0
|
||||
mov ecx, 78h ; 78h IDT entries to initialize with unique entry points (exceptions)
|
||||
mov esi, [offset Idtr + 2]
|
||||
mov edi, [esi]
|
||||
|
||||
@@: ; loop through all IDT entries exception handlers and initialize to default handler
|
||||
mov word ptr [edi], bx ; write bits 15..0 of offset
|
||||
mov word ptr [edi+2], 38h ; SYS_CODE64_SEL from GDT
|
||||
mov word ptr [edi+4], 0e00h OR 8000h ; type = 386 interrupt gate, present
|
||||
mov word ptr [edi+6], ax ; write bits 31..16 of offset
|
||||
mov dword ptr [edi+8], 0 ; write bits 63..32 of offset
|
||||
add edi, 16 ; move up to next descriptor
|
||||
add bx, DEFAULT_HANDLER_SIZE ; move to next entry point
|
||||
loop @b ; loop back through again until all descriptors are initialized
|
||||
|
||||
;; at this point edi contains the offset of the descriptor for INT 20
|
||||
;; and bx contains the low 16 bits of the offset of the default handler
|
||||
;; so initialize all the rest of the descriptors with these two values...
|
||||
; mov ecx, 101 ; there are 100 descriptors left (INT 20 (14h) - INT 119 (77h)
|
||||
;@@: ; loop through all IDT entries exception handlers and initialize to default handler
|
||||
; mov word ptr [edi], bx ; write bits 15..0 of offset
|
||||
; mov word ptr [edi+2], 38h ; SYS_CODE64_SEL from GDT
|
||||
; mov word ptr [edi+4], 0e00h OR 8000h ; type = 386 interrupt gate, present
|
||||
; mov word ptr [edi+6], ax ; write bits 31..16 of offset
|
||||
; mov dword ptr [edi+8], 0 ; write bits 63..32 of offset
|
||||
; add edi, 16 ; move up to next descriptor
|
||||
; loop @b ; loop back through again until all descriptors are initialized
|
||||
|
||||
|
||||
;; DUMP location of IDT and several of the descriptors
|
||||
; mov ecx, 8
|
||||
; mov eax, [offset Idtr + 2]
|
||||
; mov eax, [eax]
|
||||
; mov edi, 0b8000h
|
||||
; call PrintQword
|
||||
; mov esi, eax
|
||||
; mov edi, 0b80a0h
|
||||
; jmp OuterLoop
|
||||
|
||||
;;
|
||||
;; just for fun, let's do a software interrupt to see if we correctly land in the exception handler...
|
||||
; mov eax, 011111111h
|
||||
; mov ebx, 022222222h
|
||||
; mov ecx, 033333333h
|
||||
; mov edx, 044444444h
|
||||
; mov ebp, 055555555h
|
||||
; mov esi, 066666666h
|
||||
; mov edi, 077777777h
|
||||
; push 011111111h
|
||||
; push 022222222h
|
||||
; push 033333333h
|
||||
; int 119
|
||||
|
||||
mov esi,022000h ; esi = 22000
|
||||
mov eax,[esi+014h] ; eax = [22014]
|
||||
add esi,eax ; esi = 22000 + [22014] = Base of EFILDR.C
|
||||
mov ebp,[esi+03ch] ; ebp = [22000 + [22014] + 3c] = NT Image Header for EFILDR.C
|
||||
add ebp,esi
|
||||
mov edi,[ebp+030h] ; edi = [[22000 + [22014] + 3c] + 2c] = ImageBase (63..32 is zero, ignore)
|
||||
mov eax,[ebp+028h] ; eax = [[22000 + [22014] + 3c] + 24] = EntryPoint
|
||||
add eax,edi ; eax = ImageBase + EntryPoint
|
||||
mov ebx, offset EfiLdrOffset
|
||||
mov dword ptr [ebx],eax ; Modify far jump instruction for correct entry point
|
||||
|
||||
mov bx,word ptr[ebp+6] ; bx = Number of sections
|
||||
xor eax,eax
|
||||
mov ax,word ptr[ebp+014h] ; ax = Optional Header Size
|
||||
add ebp,eax
|
||||
add ebp,018h ; ebp = Start of 1st Section
|
||||
|
||||
SectionLoop:
|
||||
push esi ; Save Base of EFILDR.C
|
||||
push edi ; Save ImageBase
|
||||
add esi,[ebp+014h] ; esi = Base of EFILDR.C + PointerToRawData
|
||||
add edi,[ebp+00ch] ; edi = ImageBase + VirtualAddress
|
||||
mov ecx,[ebp+010h] ; ecs = SizeOfRawData
|
||||
|
||||
cld
|
||||
shr ecx,2
|
||||
rep movsd
|
||||
|
||||
pop edi ; Restore ImageBase
|
||||
pop esi ; Restore Base of EFILDR.C
|
||||
|
||||
add bp,028h ; ebp = ebp + 028h = Pointer to next section record
|
||||
db 66h
|
||||
db 0ffh
|
||||
db 0cbh
|
||||
; dec bx
|
||||
cmp bx,0
|
||||
jne SectionLoop
|
||||
|
||||
mov edx, offset Idtr
|
||||
movzx eax, word ptr [edx] ; get size of IDT
|
||||
db 0ffh
|
||||
db 0c0h
|
||||
; inc eax
|
||||
add eax, dword ptr [edx + 2] ; add to base of IDT to get location of memory map...
|
||||
xor ecx, ecx
|
||||
mov ecx, eax ; put argument to RCX
|
||||
|
||||
db 48h
|
||||
db 0c7h
|
||||
db 0c0h
|
||||
EfiLdrOffset:
|
||||
dd 000401000h ; Offset of EFILDR
|
||||
; mov rax, 401000h
|
||||
db 50h
|
||||
; push rax
|
||||
|
||||
; ret
|
||||
db 0c3h
|
||||
|
||||
; db "**** DEFAULT IDT ENTRY ***",0
|
||||
align 02h
|
||||
Halt:
|
||||
INT0:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 0h
|
||||
JmpCommonIdtEntry
|
||||
; db 0e9h ; jmp 16 bit reletive
|
||||
; dd commonIdtEntry - $ - 4 ; offset to jump to
|
||||
|
||||
INT1:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 1h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT2:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 2h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT3:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 3h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT4:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 4h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT5:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 5h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT6:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 6h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT7:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 7h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT8:
|
||||
; Double fault causes an error code to be pushed so no phony push necessary
|
||||
nop
|
||||
nop
|
||||
push 8h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT9:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 9h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT10:
|
||||
; Invalid TSS causes an error code to be pushed so no phony push necessary
|
||||
nop
|
||||
nop
|
||||
push 10
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT11:
|
||||
; Segment Not Present causes an error code to be pushed so no phony push necessary
|
||||
nop
|
||||
nop
|
||||
push 11
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT12:
|
||||
; Stack fault causes an error code to be pushed so no phony push necessary
|
||||
nop
|
||||
nop
|
||||
push 12
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT13:
|
||||
; GP fault causes an error code to be pushed so no phony push necessary
|
||||
nop
|
||||
nop
|
||||
push 13
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT14:
|
||||
; Page fault causes an error code to be pushed so no phony push necessary
|
||||
nop
|
||||
nop
|
||||
push 14
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT15:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 15
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT16:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 16
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT17:
|
||||
; Alignment check causes an error code to be pushed so no phony push necessary
|
||||
nop
|
||||
nop
|
||||
push 17
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT18:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 18
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT19:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 19
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INTUnknown:
|
||||
REPEAT (78h - 20)
|
||||
push 0h ; push error code place holder on the stack
|
||||
; push xxh ; push vector number
|
||||
db 06ah
|
||||
db ( $ - INTUnknown - 3 ) / 9 + 20 ; vector number
|
||||
JmpCommonIdtEntry
|
||||
ENDM
|
||||
|
||||
commonIdtEntry:
|
||||
push eax
|
||||
push ecx
|
||||
push edx
|
||||
push ebx
|
||||
push esp
|
||||
push ebp
|
||||
push esi
|
||||
push edi
|
||||
db 41h
|
||||
db 50h
|
||||
; push r8
|
||||
db 41h
|
||||
db 51h
|
||||
; push r9
|
||||
db 41h
|
||||
db 52h
|
||||
; push r10
|
||||
db 41h
|
||||
db 53h
|
||||
; push r11
|
||||
db 41h
|
||||
db 54h
|
||||
; push r12
|
||||
db 41h
|
||||
db 55h
|
||||
; push r13
|
||||
db 41h
|
||||
db 56h
|
||||
; push r14
|
||||
db 41h
|
||||
db 57h
|
||||
; push r15
|
||||
db 48h
|
||||
mov ebp, esp
|
||||
; mov rbp, rsp
|
||||
|
||||
;;
|
||||
;; At this point the stack looks like this:
|
||||
;;
|
||||
;; Calling SS
|
||||
;; Calling RSP
|
||||
;; rflags
|
||||
;; Calling CS
|
||||
;; Calling RIP
|
||||
;; Error code or 0
|
||||
;; Int num or 0ffh for unknown int num
|
||||
;; rax
|
||||
;; rcx
|
||||
;; rdx
|
||||
;; rbx
|
||||
;; rsp
|
||||
;; rbp
|
||||
;; rsi
|
||||
;; rdi
|
||||
;; r8
|
||||
;; r9
|
||||
;; r10
|
||||
;; r11
|
||||
;; r12
|
||||
;; r13
|
||||
;; r14
|
||||
;; r15 <------- RSP, RBP
|
||||
;;
|
||||
|
||||
call ClearScreen
|
||||
mov esi, offset String1
|
||||
call PrintString
|
||||
db 48h
|
||||
mov eax, [ebp + 16*8] ;; move Int number into RAX
|
||||
db 48h
|
||||
cmp eax, 18
|
||||
ja PrintDefaultString
|
||||
PrintExceptionString:
|
||||
shl eax, 3 ;; multiply by 8 to get offset from StringTable to actual string address
|
||||
add eax, offset StringTable
|
||||
mov esi, [eax]
|
||||
jmp PrintTheString
|
||||
PrintDefaultString:
|
||||
mov esi, offset IntUnknownString
|
||||
; patch Int number
|
||||
mov edx, eax
|
||||
call A2C
|
||||
mov [esi + 1], al
|
||||
mov eax, edx
|
||||
shr eax, 4
|
||||
call A2C
|
||||
mov [esi], al
|
||||
PrintTheString:
|
||||
call PrintString
|
||||
mov esi, offset String2
|
||||
call PrintString
|
||||
db 48h
|
||||
mov eax, [ebp+19*8] ; CS
|
||||
call PrintQword
|
||||
mov al, ':'
|
||||
mov byte ptr [edi], al
|
||||
add edi, 2
|
||||
db 48h
|
||||
mov eax, [ebp+18*8] ; RIP
|
||||
call PrintQword
|
||||
mov esi, offset String3
|
||||
call PrintString
|
||||
|
||||
mov edi, 0b8140h
|
||||
|
||||
mov esi, offset StringRax ; rax
|
||||
call PrintString
|
||||
db 48h
|
||||
mov eax, [ebp+15*8]
|
||||
call PrintQword
|
||||
|
||||
mov esi, offset StringRcx ; rcx
|
||||
call PrintString
|
||||
db 48h
|
||||
mov eax, [ebp+14*8]
|
||||
call PrintQword
|
||||
|
||||
mov esi, offset StringRdx ; rdx
|
||||
call PrintString
|
||||
db 48h
|
||||
mov eax, [ebp+13*8]
|
||||
call PrintQword
|
||||
|
||||
mov edi, 0b81e0h
|
||||
|
||||
mov esi, offset StringRbx ; rbx
|
||||
call PrintString
|
||||
db 48h
|
||||
mov eax, [ebp+12*8]
|
||||
call PrintQword
|
||||
|
||||
mov esi, offset StringRsp ; rsp
|
||||
call PrintString
|
||||
db 48h
|
||||
mov eax, [ebp+21*8]
|
||||
call PrintQword
|
||||
|
||||
mov esi, offset StringRbp ; rbp
|
||||
call PrintString
|
||||
db 48h
|
||||
mov eax, [ebp+10*8]
|
||||
call PrintQword
|
||||
|
||||
mov edi, 0b8280h
|
||||
|
||||
mov esi, offset StringRsi ; rsi
|
||||
call PrintString
|
||||
db 48h
|
||||
mov eax, [ebp+9*8]
|
||||
call PrintQword
|
||||
|
||||
mov esi, offset StringRdi ; rdi
|
||||
call PrintString
|
||||
db 48h
|
||||
mov eax, [ebp+8*8]
|
||||
call PrintQword
|
||||
|
||||
mov esi, offset StringEcode ; error code
|
||||
call PrintString
|
||||
db 48h
|
||||
mov eax, [ebp+17*8]
|
||||
call PrintQword
|
||||
|
||||
mov edi, 0b8320h
|
||||
|
||||
mov esi, offset StringR8 ; r8
|
||||
call PrintString
|
||||
db 48h
|
||||
mov eax, [ebp+7*8]
|
||||
call PrintQword
|
||||
|
||||
mov esi, offset StringR9 ; r9
|
||||
call PrintString
|
||||
db 48h
|
||||
mov eax, [ebp+6*8]
|
||||
call PrintQword
|
||||
|
||||
mov esi, offset StringR10 ; r10
|
||||
call PrintString
|
||||
db 48h
|
||||
mov eax, [ebp+5*8]
|
||||
call PrintQword
|
||||
|
||||
mov edi, 0b83c0h
|
||||
|
||||
mov esi, offset StringR11 ; r11
|
||||
call PrintString
|
||||
db 48h
|
||||
mov eax, [ebp+4*8]
|
||||
call PrintQword
|
||||
|
||||
mov esi, offset StringR12 ; r12
|
||||
call PrintString
|
||||
db 48h
|
||||
mov eax, [ebp+3*8]
|
||||
call PrintQword
|
||||
|
||||
mov esi, offset StringR13 ; r13
|
||||
call PrintString
|
||||
db 48h
|
||||
mov eax, [ebp+2*8]
|
||||
call PrintQword
|
||||
|
||||
mov edi, 0b8460h
|
||||
|
||||
mov esi, offset StringR14 ; r14
|
||||
call PrintString
|
||||
db 48h
|
||||
mov eax, [ebp+1*8]
|
||||
call PrintQword
|
||||
|
||||
mov esi, offset StringR15 ; r15
|
||||
call PrintString
|
||||
db 48h
|
||||
mov eax, [ebp+0*8]
|
||||
call PrintQword
|
||||
|
||||
mov esi, offset StringSs ; ss
|
||||
call PrintString
|
||||
db 48h
|
||||
mov eax, [ebp+22*8]
|
||||
call PrintQword
|
||||
|
||||
mov edi, 0b8500h
|
||||
|
||||
mov esi, offset StringRflags ; rflags
|
||||
call PrintString
|
||||
db 48h
|
||||
mov eax, [ebp+20*8]
|
||||
call PrintQword
|
||||
|
||||
mov edi, 0b8640h
|
||||
|
||||
mov esi, ebp
|
||||
add esi, 23*8
|
||||
mov ecx, 4
|
||||
|
||||
|
||||
OuterLoop:
|
||||
push ecx
|
||||
mov ecx, 4
|
||||
db 48h
|
||||
mov edx, edi
|
||||
|
||||
InnerLoop:
|
||||
db 48h
|
||||
mov eax, [esi]
|
||||
call PrintQword
|
||||
add esi, 8
|
||||
mov al, ' '
|
||||
mov [edi], al
|
||||
add edi, 2
|
||||
loop InnerLoop
|
||||
|
||||
pop ecx
|
||||
add edx, 0a0h
|
||||
mov edi, edx
|
||||
loop OuterLoop
|
||||
|
||||
|
||||
mov edi, 0b8960h
|
||||
|
||||
db 48h
|
||||
mov eax, [ebp+18*8] ; RIP
|
||||
sub eax, 8 * 8
|
||||
db 48h
|
||||
mov esi, eax ; esi = rip - 8 QWORD linear (total 16 QWORD)
|
||||
|
||||
mov ecx, 4
|
||||
|
||||
OuterLoop1:
|
||||
push ecx
|
||||
mov ecx, 4
|
||||
mov edx, edi
|
||||
|
||||
InnerLoop1:
|
||||
db 48h
|
||||
mov eax, [esi]
|
||||
call PrintQword
|
||||
add esi, 8
|
||||
mov al, ' '
|
||||
mov [edi], al
|
||||
add edi, 2
|
||||
loop InnerLoop1
|
||||
|
||||
pop ecx
|
||||
add edx, 0a0h
|
||||
mov edi, edx
|
||||
loop OuterLoop1
|
||||
|
||||
|
||||
|
||||
wbinvd
|
||||
@@:
|
||||
jmp @b
|
||||
|
||||
;
|
||||
; return
|
||||
;
|
||||
mov esp, ebp
|
||||
; mov rsp, rbp
|
||||
db 41h
|
||||
db 5fh
|
||||
; pop r15
|
||||
db 41h
|
||||
db 5eh
|
||||
; pop r14
|
||||
db 41h
|
||||
db 5dh
|
||||
; pop r13
|
||||
db 41h
|
||||
db 5ch
|
||||
; pop r12
|
||||
db 41h
|
||||
db 5bh
|
||||
; pop r11
|
||||
db 41h
|
||||
db 5ah
|
||||
; pop r10
|
||||
db 41h
|
||||
db 59h
|
||||
; pop r9
|
||||
db 41h
|
||||
db 58h
|
||||
; pop r8
|
||||
pop edi
|
||||
pop esi
|
||||
pop ebp
|
||||
pop eax ; esp
|
||||
pop ebx
|
||||
pop edx
|
||||
pop ecx
|
||||
pop eax
|
||||
|
||||
db 48h
|
||||
db 83h
|
||||
db 0c4h
|
||||
db 10h
|
||||
; add esp, 16 ; error code and INT number
|
||||
|
||||
db 48h
|
||||
db 0cfh
|
||||
; iretq
|
||||
|
||||
PrintString:
|
||||
push eax
|
||||
@@:
|
||||
mov al, byte ptr [esi]
|
||||
cmp al, 0
|
||||
je @f
|
||||
mov byte ptr [edi], al
|
||||
db 0ffh
|
||||
db 0c6h
|
||||
; inc esi
|
||||
add edi, 2
|
||||
jmp @b
|
||||
@@:
|
||||
pop eax
|
||||
ret
|
||||
|
||||
;; RAX contains qword to print
|
||||
;; RDI contains memory location (screen location) to print it to
|
||||
PrintQword:
|
||||
push ecx
|
||||
push ebx
|
||||
push eax
|
||||
|
||||
db 48h
|
||||
db 0c7h
|
||||
db 0c1h
|
||||
dd 16
|
||||
; mov rcx, 16
|
||||
looptop:
|
||||
db 48h
|
||||
rol eax, 4
|
||||
mov bl, al
|
||||
and bl, 0fh
|
||||
add bl, '0'
|
||||
cmp bl, '9'
|
||||
jle @f
|
||||
add bl, 7
|
||||
@@:
|
||||
mov byte ptr [edi], bl
|
||||
add edi, 2
|
||||
loop looptop
|
||||
wbinvd
|
||||
|
||||
pop eax
|
||||
pop ebx
|
||||
pop ecx
|
||||
ret
|
||||
|
||||
ClearScreen:
|
||||
push eax
|
||||
push ecx
|
||||
|
||||
mov al, ' '
|
||||
mov ah, 0ch
|
||||
mov edi, 0b8000h
|
||||
mov ecx, 80 * 24
|
||||
@@:
|
||||
mov word ptr [edi], ax
|
||||
add edi, 2
|
||||
loop @b
|
||||
mov edi, 0b8000h
|
||||
|
||||
pop ecx
|
||||
pop eax
|
||||
|
||||
ret
|
||||
|
||||
A2C:
|
||||
and al, 0fh
|
||||
add al, '0'
|
||||
cmp al, '9'
|
||||
jle @f
|
||||
add al, 7
|
||||
@@:
|
||||
ret
|
||||
|
||||
String1 db "*** INT ",0
|
||||
|
||||
Int0String db "00h Divide by 0 -",0
|
||||
Int1String db "01h Debug exception -",0
|
||||
Int2String db "02h NMI -",0
|
||||
Int3String db "03h Breakpoint -",0
|
||||
Int4String db "04h Overflow -",0
|
||||
Int5String db "05h Bound -",0
|
||||
Int6String db "06h Invalid opcode -",0
|
||||
Int7String db "07h Device not available -",0
|
||||
Int8String db "08h Double fault -",0
|
||||
Int9String db "09h Coprocessor seg overrun (reserved) -",0
|
||||
Int10String db "0Ah Invalid TSS -",0
|
||||
Int11String db "0Bh Segment not present -",0
|
||||
Int12String db "0Ch Stack fault -",0
|
||||
Int13String db "0Dh General protection fault -",0
|
||||
Int14String db "0Eh Page fault -",0
|
||||
Int15String db "0Fh (Intel reserved) -",0
|
||||
Int16String db "10h Floating point error -",0
|
||||
Int17String db "11h Alignment check -",0
|
||||
Int18String db "12h Machine check -",0
|
||||
Int19String db "13h SIMD Floating-Point Exception -",0
|
||||
IntUnknownString db "??h Unknown interrupt -",0
|
||||
|
||||
StringTable dq offset Int0String, offset Int1String, offset Int2String, offset Int3String,
|
||||
offset Int4String, offset Int5String, offset Int6String, offset Int7String,
|
||||
offset Int8String, offset Int9String, offset Int10String, offset Int11String,
|
||||
offset Int12String, offset Int13String, offset Int14String, offset Int15String,
|
||||
offset Int16String, offset Int17String, offset Int18String, offset Int19String
|
||||
|
||||
String2 db " HALT!! *** (",0
|
||||
String3 db ")",0
|
||||
StringRax db "RAX=",0
|
||||
StringRcx db " RCX=",0
|
||||
StringRdx db " RDX=",0
|
||||
StringRbx db "RBX=",0
|
||||
StringRsp db " RSP=",0
|
||||
StringRbp db " RBP=",0
|
||||
StringRsi db "RSI=",0
|
||||
StringRdi db " RDI=",0
|
||||
StringEcode db " ECODE=",0
|
||||
StringR8 db "R8 =",0
|
||||
StringR9 db " R9 =",0
|
||||
StringR10 db " R10=",0
|
||||
StringR11 db "R11=",0
|
||||
StringR12 db " R12=",0
|
||||
StringR13 db " R13=",0
|
||||
StringR14 db "R14=",0
|
||||
StringR15 db " R15=",0
|
||||
StringSs db " SS =",0
|
||||
StringRflags db "RFLAGS=",0
|
||||
|
||||
Idtr df 0
|
||||
df 0
|
||||
|
||||
org 21ffeh
|
||||
BlockSignature:
|
||||
dw 0aa55h
|
||||
|
||||
end
|
1140
DuetPkg/BootSector/st16_64.asm
Normal file
1140
DuetPkg/BootSector/st16_64.asm
Normal file
File diff suppressed because it is too large
Load Diff
1156
DuetPkg/BootSector/st32_64.asm
Normal file
1156
DuetPkg/BootSector/st32_64.asm
Normal file
File diff suppressed because it is too large
Load Diff
921
DuetPkg/BootSector/start.asm
Normal file
921
DuetPkg/BootSector/start.asm
Normal file
@ -0,0 +1,921 @@
|
||||
;------------------------------------------------------------------------------
|
||||
;*
|
||||
;* Copyright 2006 - 2007, Intel Corporation
|
||||
;* All rights reserved. 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.
|
||||
;*
|
||||
;* start.asm
|
||||
;*
|
||||
;* Abstract:
|
||||
;*
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
.model small
|
||||
.stack
|
||||
.486p
|
||||
.code
|
||||
|
||||
FAT_DIRECTORY_ENTRY_SIZE EQU 020h
|
||||
FAT_DIRECTORY_ENTRY_SHIFT EQU 5
|
||||
BLOCK_SIZE EQU 0200h
|
||||
BLOCK_MASK EQU 01ffh
|
||||
BLOCK_SHIFT EQU 9
|
||||
|
||||
org 0h
|
||||
Ia32Jump:
|
||||
jmp BootSectorEntryPoint ; JMP inst - 3 bytes
|
||||
nop
|
||||
|
||||
OemId db "INTEL " ; OemId - 8 bytes
|
||||
|
||||
SectorSize dw 0 ; Sector Size - 16 bits
|
||||
SectorsPerCluster db 0 ; Sector Per Cluster - 8 bits
|
||||
ReservedSectors dw 0 ; Reserved Sectors - 16 bits
|
||||
NoFats db 0 ; Number of FATs - 8 bits
|
||||
RootEntries dw 0 ; Root Entries - 16 bits
|
||||
Sectors dw 0 ; Number of Sectors - 16 bits
|
||||
Media db 0 ; Media - 8 bits - ignored
|
||||
SectorsPerFat dw 0 ; Sectors Per FAT - 16 bits
|
||||
SectorsPerTrack dw 0 ; Sectors Per Track - 16 bits - ignored
|
||||
Heads dw 0 ; Heads - 16 bits - ignored
|
||||
HiddenSectors dd 0 ; Hidden Sectors - 32 bits - ignored
|
||||
LargeSectors dd 0 ; Large Sectors - 32 bits
|
||||
PhysicalDrive db 0 ; PhysicalDriveNumber - 8 bits - ignored
|
||||
CurrentHead db 0 ; Current Head - 8 bits
|
||||
Signature db 0 ; Signature - 8 bits - ignored
|
||||
VolId db " " ; Volume Serial Number- 4 bytes
|
||||
FatLabel db " " ; Label - 11 bytes
|
||||
SystemId db "FAT12 " ; SystemId - 8 bytes
|
||||
|
||||
BootSectorEntryPoint:
|
||||
ASSUME ds:@code
|
||||
ASSUME ss:@code
|
||||
; ds = 1000, es = 2000 + x (size of first cluster >> 4)
|
||||
; cx = Start Cluster of EfiLdr
|
||||
; dx = Start Cluster of Efivar.bin
|
||||
|
||||
; Re use the BPB data stored in Boot Sector
|
||||
mov bp,07c00h
|
||||
|
||||
push cx
|
||||
; Read Efivar.bin
|
||||
; 1000:dx = DirectoryEntry of Efivar.bin -> BS.com has filled already
|
||||
mov ax,01900h
|
||||
mov es,ax
|
||||
test dx,dx
|
||||
jnz CheckVarStoreSize
|
||||
|
||||
mov al,1
|
||||
NoVarStore:
|
||||
push es
|
||||
; Set the 5th byte start @ 0:19000 to non-zero indicating we should init var store header in DxeIpl
|
||||
mov byte ptr es:[4],al
|
||||
jmp SaveVolumeId
|
||||
|
||||
CheckVarStoreSize:
|
||||
mov di,dx
|
||||
cmp dword ptr ds:[di+2], 04000h
|
||||
mov al,2
|
||||
jne NoVarStore
|
||||
|
||||
LoadVarStore:
|
||||
mov al,0
|
||||
mov byte ptr es:[4],al
|
||||
mov cx,word ptr[di]
|
||||
; ES:DI = 1500:0
|
||||
xor di,di
|
||||
push es
|
||||
mov ax,01500h
|
||||
mov es,ax
|
||||
call ReadFile
|
||||
SaveVolumeId:
|
||||
pop es
|
||||
mov ax,word ptr [bp+VolId]
|
||||
mov word ptr es:[0],ax ; Save Volume Id to 0:19000. we will find the correct volume according to this VolumeId
|
||||
mov ax,word ptr [bp+VolId+2]
|
||||
mov word ptr es:[2],ax
|
||||
|
||||
; Read Efildr
|
||||
pop cx
|
||||
; cx = Start Cluster of Efildr -> BS.com has filled already
|
||||
; ES:DI = 2000:0, first cluster will be read again
|
||||
xor di,di ; di = 0
|
||||
mov ax,02000h
|
||||
mov es,ax
|
||||
call ReadFile
|
||||
mov ax,cs
|
||||
mov word ptr cs:[JumpSegment],ax
|
||||
|
||||
JumpFarInstruction:
|
||||
db 0eah
|
||||
JumpOffset:
|
||||
dw 0200h
|
||||
JumpSegment:
|
||||
dw 2000h
|
||||
|
||||
|
||||
|
||||
; ****************************************************************************
|
||||
; ReadFile
|
||||
;
|
||||
; Arguments:
|
||||
; CX = Start Cluster of File
|
||||
; ES:DI = Buffer to store file content read from disk
|
||||
;
|
||||
; Return:
|
||||
; (ES << 4 + DI) = end of file content Buffer
|
||||
;
|
||||
; ****************************************************************************
|
||||
ReadFile:
|
||||
; si = NumberOfClusters
|
||||
; cx = ClusterNumber
|
||||
; dx = CachedFatSectorNumber
|
||||
; ds:0000 = CacheFatSectorBuffer
|
||||
; es:di = Buffer to load file
|
||||
; bx = NextClusterNumber
|
||||
pusha
|
||||
mov si,1 ; NumberOfClusters = 1
|
||||
push cx ; Push Start Cluster onto stack
|
||||
mov dx,0fffh ; CachedFatSectorNumber = 0xfff
|
||||
FatChainLoop:
|
||||
mov ax,cx ; ax = ClusterNumber
|
||||
and ax,0ff8h ; ax = ax & 0xff8
|
||||
cmp ax,0ff8h ; See if this is the last cluster
|
||||
je FoundLastCluster ; Jump if last cluster found
|
||||
mov ax,cx ; ax = ClusterNumber
|
||||
shl ax,1 ; ax = ClusterNumber * 2
|
||||
add ax,cx ; ax = ClusterNumber * 2 + ClusterNumber = ClusterNumber * 3
|
||||
shr ax,1 ; FatOffset = ClusterNumber*3 / 2
|
||||
push si ; Save si
|
||||
mov si,ax ; si = FatOffset
|
||||
shr ax,BLOCK_SHIFT ; ax = FatOffset >> BLOCK_SHIFT
|
||||
add ax,word ptr [bp+ReservedSectors] ; ax = FatSectorNumber = ReservedSectors + (FatOffset >> BLOCK_OFFSET)
|
||||
and si,BLOCK_MASK ; si = FatOffset & BLOCK_MASK
|
||||
cmp ax,dx ; Compare FatSectorNumber to CachedFatSectorNumber
|
||||
je SkipFatRead
|
||||
mov bx,2
|
||||
push es
|
||||
push ds
|
||||
pop es
|
||||
call ReadBlocks ; Read 2 blocks starting at AX storing at ES:DI
|
||||
pop es
|
||||
mov dx,ax ; CachedFatSectorNumber = FatSectorNumber
|
||||
SkipFatRead:
|
||||
mov bx,word ptr [si] ; bx = NextClusterNumber
|
||||
mov ax,cx ; ax = ClusterNumber
|
||||
and ax,1 ; See if this is an odd cluster number
|
||||
je EvenFatEntry
|
||||
shr bx,4 ; NextClusterNumber = NextClusterNumber >> 4
|
||||
EvenFatEntry:
|
||||
and bx,0fffh ; Strip upper 4 bits of NextClusterNumber
|
||||
pop si ; Restore si
|
||||
dec bx ; bx = NextClusterNumber - 1
|
||||
cmp bx,cx ; See if (NextClusterNumber-1)==ClusterNumber
|
||||
jne ReadClusters
|
||||
inc bx ; bx = NextClusterNumber
|
||||
inc si ; NumberOfClusters++
|
||||
mov cx,bx ; ClusterNumber = NextClusterNumber
|
||||
jmp FatChainLoop
|
||||
ReadClusters:
|
||||
inc bx
|
||||
pop ax ; ax = StartCluster
|
||||
push bx ; StartCluster = NextClusterNumber
|
||||
mov cx,bx ; ClusterNumber = NextClusterNumber
|
||||
sub ax,2 ; ax = StartCluster - 2
|
||||
xor bh,bh
|
||||
mov bl,byte ptr [bp+SectorsPerCluster] ; bx = SectorsPerCluster
|
||||
mul bx ; ax = (StartCluster - 2) * SectorsPerCluster
|
||||
add ax, word ptr [bp] ; ax = FirstClusterLBA + (StartCluster-2)*SectorsPerCluster
|
||||
push ax ; save start sector
|
||||
mov ax,si ; ax = NumberOfClusters
|
||||
mul bx ; ax = NumberOfClusters * SectorsPerCluster
|
||||
mov bx,ax ; bx = Number of Sectors
|
||||
pop ax ; ax = Start Sector
|
||||
call ReadBlocks
|
||||
mov si,1 ; NumberOfClusters = 1
|
||||
jmp FatChainLoop
|
||||
FoundLastCluster:
|
||||
pop cx
|
||||
popa
|
||||
ret
|
||||
|
||||
|
||||
; ****************************************************************************
|
||||
; ReadBlocks - Reads a set of blocks from a block device
|
||||
;
|
||||
; AX = Start LBA
|
||||
; BX = Number of Blocks to Read
|
||||
; ES:DI = Buffer to store sectors read from disk
|
||||
; ****************************************************************************
|
||||
|
||||
; cx = Blocks
|
||||
; bx = NumberOfBlocks
|
||||
; si = StartLBA
|
||||
|
||||
ReadBlocks:
|
||||
pusha
|
||||
add eax,dword ptr [bp+LBAOffsetForBootSector] ; Add LBAOffsetForBootSector to Start LBA
|
||||
add eax,dword ptr [bp+HiddenSectors] ; Add HiddenSectors to Start LBA
|
||||
mov esi,eax ; esi = Start LBA
|
||||
mov cx,bx ; cx = Number of blocks to read
|
||||
ReadCylinderLoop:
|
||||
mov bp,07bfch ; bp = 0x7bfc
|
||||
mov eax,esi ; eax = Start LBA
|
||||
xor edx,edx ; edx = 0
|
||||
movzx ebx,word ptr [bp] ; bx = MaxSector
|
||||
div ebx ; ax = StartLBA / MaxSector
|
||||
inc dx ; dx = (StartLBA % MaxSector) + 1
|
||||
|
||||
mov bx,word ptr [bp] ; bx = MaxSector
|
||||
sub bx,dx ; bx = MaxSector - Sector
|
||||
inc bx ; bx = MaxSector - Sector + 1
|
||||
cmp cx,bx ; Compare (Blocks) to (MaxSector - Sector + 1)
|
||||
jg LimitTransfer
|
||||
mov bx,cx ; bx = Blocks
|
||||
LimitTransfer:
|
||||
push ax ; save ax
|
||||
mov ax,es ; ax = es
|
||||
shr ax,(BLOCK_SHIFT-4) ; ax = Number of blocks into mem system
|
||||
and ax,07fh ; ax = Number of blocks into current seg
|
||||
add ax,bx ; ax = End Block number of transfer
|
||||
cmp ax,080h ; See if it crosses a 64K boundry
|
||||
jle NotCrossing64KBoundry ; Branch if not crossing 64K boundry
|
||||
sub ax,080h ; ax = Number of blocks past 64K boundry
|
||||
sub bx,ax ; Decrease transfer size by block overage
|
||||
NotCrossing64KBoundry:
|
||||
pop ax ; restore ax
|
||||
|
||||
push cx
|
||||
mov cl,dl ; cl = (StartLBA % MaxSector) + 1 = Sector
|
||||
xor dx,dx ; dx = 0
|
||||
div word ptr [bp+2] ; ax = ax / (MaxHead + 1) = Cylinder
|
||||
; dx = ax % (MaxHead + 1) = Head
|
||||
|
||||
push bx ; Save number of blocks to transfer
|
||||
mov dh,dl ; dh = Head
|
||||
mov bp,07c00h ; bp = 0x7c00
|
||||
mov dl,byte ptr [bp+PhysicalDrive] ; dl = Drive Number
|
||||
mov ch,al ; ch = Cylinder
|
||||
mov al,bl ; al = Blocks
|
||||
mov ah,2 ; ah = Function 2
|
||||
mov bx,di ; es:bx = Buffer address
|
||||
int 013h
|
||||
jc DiskError
|
||||
pop bx
|
||||
pop cx
|
||||
movzx ebx,bx
|
||||
add esi,ebx ; StartLBA = StartLBA + NumberOfBlocks
|
||||
sub cx,bx ; Blocks = Blocks - NumberOfBlocks
|
||||
mov ax,es
|
||||
shl bx,(BLOCK_SHIFT-4)
|
||||
add ax,bx
|
||||
mov es,ax ; es:di = es:di + NumberOfBlocks*BLOCK_SIZE
|
||||
cmp cx,0
|
||||
jne ReadCylinderLoop
|
||||
popa
|
||||
ret
|
||||
|
||||
DiskError:
|
||||
push cs
|
||||
pop ds
|
||||
lea si, [ErrorString]
|
||||
mov cx, 7
|
||||
jmp PrintStringAndHalt
|
||||
|
||||
PrintStringAndHalt:
|
||||
mov ax,0b800h
|
||||
mov es,ax
|
||||
mov di,160
|
||||
rep movsw
|
||||
Halt:
|
||||
jmp Halt
|
||||
|
||||
ErrorString:
|
||||
db 'S', 0ch, 'E', 0ch, 'r', 0ch, 'r', 0ch, 'o', 0ch, 'r', 0ch, '!', 0ch
|
||||
|
||||
org 01fah
|
||||
LBAOffsetForBootSector:
|
||||
dd 0h
|
||||
|
||||
org 01feh
|
||||
dw 0aa55h
|
||||
|
||||
;******************************************************************************
|
||||
;******************************************************************************
|
||||
;******************************************************************************
|
||||
|
||||
DELAY_PORT equ 0edh ; Port to use for 1uS delay
|
||||
KBD_CONTROL_PORT equ 060h ; 8042 control port
|
||||
KBD_STATUS_PORT equ 064h ; 8042 status port
|
||||
WRITE_DATA_PORT_CMD equ 0d1h ; 8042 command to write the data port
|
||||
ENABLE_A20_CMD equ 0dfh ; 8042 command to enable A20
|
||||
|
||||
org 200h
|
||||
jmp start
|
||||
Em64String:
|
||||
db 'E', 0ch, 'm', 0ch, '6', 0ch, '4', 0ch, 'T', 0ch, ' ', 0ch, 'U', 0ch, 'n', 0ch, 's', 0ch, 'u', 0ch, 'p', 0ch, 'p', 0ch, 'o', 0ch, 'r', 0ch, 't', 0ch, 'e', 0ch, 'd', 0ch, '!', 0ch
|
||||
|
||||
start:
|
||||
mov ax,cs
|
||||
mov ds,ax
|
||||
mov es,ax
|
||||
mov ss,ax
|
||||
mov sp,MyStack
|
||||
|
||||
; mov ax,0b800h
|
||||
; mov es,ax
|
||||
; mov byte ptr es:[160],'a'
|
||||
; mov ax,cs
|
||||
; mov es,ax
|
||||
|
||||
mov ebx,0
|
||||
lea edi,MemoryMap
|
||||
MemMapLoop:
|
||||
mov eax,0e820h
|
||||
mov ecx,20
|
||||
mov edx,'SMAP'
|
||||
int 15h
|
||||
jc MemMapDone
|
||||
add edi,20
|
||||
cmp ebx,0
|
||||
je MemMapDone
|
||||
jmp MemMapLoop
|
||||
MemMapDone:
|
||||
lea eax,MemoryMap
|
||||
sub edi,eax ; Get the address of the memory map
|
||||
mov dword ptr [MemoryMapSize],edi ; Save the size of the memory map
|
||||
|
||||
xor ebx,ebx
|
||||
mov bx,cs ; BX=segment
|
||||
shl ebx,4 ; BX="linear" address of segment base
|
||||
lea eax,[GDT_BASE + ebx] ; EAX=PHYSICAL address of gdt
|
||||
mov dword ptr [gdtr + 2],eax ; Put address of gdt into the gdtr
|
||||
lea eax,[IDT_BASE + ebx] ; EAX=PHYSICAL address of idt
|
||||
mov dword ptr [idtr + 2],eax ; Put address of idt into the idtr
|
||||
lea edx,[MemoryMapSize + ebx] ; Physical base address of the memory map
|
||||
|
||||
add ebx,01000h ; Source of EFI32
|
||||
mov dword ptr [JUMP+2],ebx
|
||||
add ebx,01000h
|
||||
mov esi,ebx ; Source of EFILDR32
|
||||
|
||||
; mov ax,0b800h
|
||||
; mov es,ax
|
||||
; mov byte ptr es:[162],'b'
|
||||
; mov ax,cs
|
||||
; mov es,ax
|
||||
|
||||
;
|
||||
; Enable A20 Gate
|
||||
;
|
||||
|
||||
mov ax,2401h ; Enable A20 Gate
|
||||
int 15h
|
||||
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
|
||||
out DELAY_PORT,ax ; Delay 1 uS
|
||||
mov al,WRITE_DATA_PORT_CMD ; 8042 cmd to write output port
|
||||
out KBD_STATUS_PORT,al ; Send command to the 8042
|
||||
call Empty8042InputBuffer ; Empty the Input Buffer on the 8042 controller
|
||||
jnz Timeout8042 ; Jump if the 8042 timed out
|
||||
mov al,ENABLE_A20_CMD ; gate address bit 20 on
|
||||
out KBD_CONTROL_PORT,al ; Send command to thre 8042
|
||||
call Empty8042InputBuffer ; Empty the Input Buffer on the 8042 controller
|
||||
mov cx,25 ; Delay 25 uS for the command to complete on the 8042
|
||||
Delay25uS:
|
||||
out DELAY_PORT,ax ; Delay 1 uS
|
||||
loop Delay25uS
|
||||
Timeout8042:
|
||||
|
||||
|
||||
A20GateEnabled:
|
||||
|
||||
;
|
||||
; DISABLE INTERRUPTS - Entering Protected Mode
|
||||
;
|
||||
|
||||
cli
|
||||
|
||||
; mov ax,0b800h
|
||||
; mov es,ax
|
||||
; mov byte ptr es:[164],'c'
|
||||
; mov ax,cs
|
||||
; mov es,ax
|
||||
|
||||
db 66h
|
||||
lgdt fword ptr [gdtr]
|
||||
db 66h
|
||||
lidt fword ptr [idtr]
|
||||
|
||||
mov eax,cr0
|
||||
or al,1
|
||||
mov cr0,eax
|
||||
|
||||
mov eax,0008h ; Flat data descriptor
|
||||
mov ebp,000400000h ; Destination of EFILDR32
|
||||
mov ebx,000070000h ; Length of copy
|
||||
|
||||
JUMP:
|
||||
; jmp far 0010:00020000
|
||||
db 066h
|
||||
db 0eah
|
||||
dd 000020000h
|
||||
dw 00010h
|
||||
|
||||
Empty8042InputBuffer:
|
||||
mov cx,0
|
||||
Empty8042Loop:
|
||||
out DELAY_PORT,ax ; Delay 1us
|
||||
in al,KBD_STATUS_PORT ; Read the 8042 Status Port
|
||||
and al,02h ; Check the Input Buffer Full Flag
|
||||
loopnz Empty8042Loop ; Loop until the input buffer is empty or a timout of 65536 uS
|
||||
ret
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; data
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
align 02h
|
||||
|
||||
gdtr dw GDT_END - GDT_BASE - 1 ; GDT limit
|
||||
dd 0 ; (GDT base gets set above)
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; global descriptor table (GDT)
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
align 02h
|
||||
|
||||
public GDT_BASE
|
||||
GDT_BASE:
|
||||
; null descriptor
|
||||
NULL_SEL equ $-GDT_BASE
|
||||
dw 0 ; limit 15:0
|
||||
dw 0 ; base 15:0
|
||||
db 0 ; base 23:16
|
||||
db 0 ; type
|
||||
db 0 ; limit 19:16, flags
|
||||
db 0 ; base 31:24
|
||||
|
||||
; linear data segment descriptor
|
||||
LINEAR_SEL equ $-GDT_BASE
|
||||
dw 0FFFFh ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 092h ; present, ring 0, data, expand-up, writable
|
||||
db 0CFh ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
; linear code segment descriptor
|
||||
LINEAR_CODE_SEL equ $-GDT_BASE
|
||||
dw 0FFFFh ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 09Ah ; present, ring 0, data, expand-up, writable
|
||||
db 0CFh ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
; system data segment descriptor
|
||||
SYS_DATA_SEL equ $-GDT_BASE
|
||||
dw 0FFFFh ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 092h ; present, ring 0, data, expand-up, writable
|
||||
db 0CFh ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
; system code segment descriptor
|
||||
SYS_CODE_SEL equ $-GDT_BASE
|
||||
dw 0FFFFh ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 09Ah ; present, ring 0, data, expand-up, writable
|
||||
db 0CFh ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
; spare segment descriptor
|
||||
SPARE3_SEL equ $-GDT_BASE
|
||||
dw 0 ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 0 ; present, ring 0, data, expand-up, writable
|
||||
db 0 ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
; spare segment descriptor
|
||||
SPARE4_SEL equ $-GDT_BASE
|
||||
dw 0 ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 0 ; present, ring 0, data, expand-up, writable
|
||||
db 0 ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
; spare segment descriptor
|
||||
SPARE5_SEL equ $-GDT_BASE
|
||||
dw 0 ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 0 ; present, ring 0, data, expand-up, writable
|
||||
db 0 ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
GDT_END:
|
||||
|
||||
align 02h
|
||||
|
||||
|
||||
|
||||
idtr dw IDT_END - IDT_BASE - 1 ; IDT limit
|
||||
dd 0 ; (IDT base gets set 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.
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;idt_tag db "IDT",0
|
||||
align 02h
|
||||
|
||||
public IDT_BASE
|
||||
IDT_BASE:
|
||||
; divide by zero (INT 0)
|
||||
DIV_ZERO_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; debug exception (INT 1)
|
||||
DEBUG_EXCEPT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; NMI (INT 2)
|
||||
NMI_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; soft breakpoint (INT 3)
|
||||
BREAKPOINT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; overflow (INT 4)
|
||||
OVERFLOW_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; bounds check (INT 5)
|
||||
BOUNDS_CHECK_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; invalid opcode (INT 6)
|
||||
INVALID_OPCODE_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; device not available (INT 7)
|
||||
DEV_NOT_AVAIL_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; double fault (INT 8)
|
||||
DOUBLE_FAULT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; Coprocessor segment overrun - reserved (INT 9)
|
||||
RSVD_INTR_SEL1 equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; invalid TSS (INT 0ah)
|
||||
INVALID_TSS_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; segment not present (INT 0bh)
|
||||
SEG_NOT_PRESENT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; stack fault (INT 0ch)
|
||||
STACK_FAULT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; general protection (INT 0dh)
|
||||
GP_FAULT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; page fault (INT 0eh)
|
||||
PAGE_FAULT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; Intel reserved - do not use (INT 0fh)
|
||||
RSVD_INTR_SEL2 equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; floating point error (INT 10h)
|
||||
FLT_POINT_ERR_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; alignment check (INT 11h)
|
||||
ALIGNMENT_CHECK_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; machine check (INT 12h)
|
||||
MACHINE_CHECK_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; SIMD floating-point exception (INT 13h)
|
||||
SIMD_EXCEPTION_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; 85 unspecified descriptors, First 12 of them are reserved, the rest are avail
|
||||
db (85 * 8) dup(0)
|
||||
|
||||
; IRQ 0 (System timer) - (INT 68h)
|
||||
IRQ0_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 1 (8042 Keyboard controller) - (INT 69h)
|
||||
IRQ1_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; Reserved - IRQ 2 redirect (IRQ 2) - DO NOT USE!!! - (INT 6ah)
|
||||
IRQ2_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 3 (COM 2) - (INT 6bh)
|
||||
IRQ3_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 4 (COM 1) - (INT 6ch)
|
||||
IRQ4_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 5 (LPT 2) - (INT 6dh)
|
||||
IRQ5_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 6 (Floppy controller) - (INT 6eh)
|
||||
IRQ6_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 7 (LPT 1) - (INT 6fh)
|
||||
IRQ7_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 8 (RTC Alarm) - (INT 70h)
|
||||
IRQ8_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 9 - (INT 71h)
|
||||
IRQ9_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 10 - (INT 72h)
|
||||
IRQ10_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 11 - (INT 73h)
|
||||
IRQ11_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 12 (PS/2 mouse) - (INT 74h)
|
||||
IRQ12_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 13 (Floating point error) - (INT 75h)
|
||||
IRQ13_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 14 (Secondary IDE) - (INT 76h)
|
||||
IRQ14_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 15 (Primary IDE) - (INT 77h)
|
||||
IRQ15_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
IDT_END:
|
||||
|
||||
align 02h
|
||||
|
||||
MemoryMapSize dd 0
|
||||
MemoryMap dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
|
||||
dd 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
|
||||
dd 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
|
||||
|
||||
org 0fe0h
|
||||
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 0ffeh
|
||||
BlockSignature:
|
||||
dw 0aa55h
|
||||
|
||||
end
|
914
DuetPkg/BootSector/start16.asm
Normal file
914
DuetPkg/BootSector/start16.asm
Normal file
@ -0,0 +1,914 @@
|
||||
;------------------------------------------------------------------------------
|
||||
;*
|
||||
;* Copyright 2006 - 2007, Intel Corporation
|
||||
;* All rights reserved. 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.
|
||||
;*
|
||||
;* start16.asm
|
||||
;*
|
||||
;* Abstract:
|
||||
;*
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
.model small
|
||||
.stack
|
||||
.486p
|
||||
.code
|
||||
|
||||
FAT_DIRECTORY_ENTRY_SIZE EQU 020h
|
||||
FAT_DIRECTORY_ENTRY_SHIFT EQU 5
|
||||
BLOCK_SIZE EQU 0200h
|
||||
BLOCK_MASK EQU 01ffh
|
||||
BLOCK_SHIFT EQU 9
|
||||
|
||||
org 0h
|
||||
Ia32Jump:
|
||||
jmp BootSectorEntryPoint ; JMP inst - 3 bytes
|
||||
nop
|
||||
|
||||
OemId db "INTEL " ; OemId - 8 bytes
|
||||
|
||||
SectorSize dw 0 ; Sector Size - 16 bits
|
||||
SectorsPerCluster db 0 ; Sector Per Cluster - 8 bits
|
||||
ReservedSectors dw 0 ; Reserved Sectors - 16 bits
|
||||
NoFats db 0 ; Number of FATs - 8 bits
|
||||
RootEntries dw 0 ; Root Entries - 16 bits
|
||||
Sectors dw 0 ; Number of Sectors - 16 bits
|
||||
Media db 0 ; Media - 8 bits - ignored
|
||||
SectorsPerFat dw 0 ; Sectors Per FAT - 16 bits
|
||||
SectorsPerTrack dw 0 ; Sectors Per Track - 16 bits - ignored
|
||||
Heads dw 0 ; Heads - 16 bits - ignored
|
||||
HiddenSectors dd 0 ; Hidden Sectors - 32 bits - ignored
|
||||
LargeSectors dd 0 ; Large Sectors - 32 bits
|
||||
PhysicalDrive db 0 ; PhysicalDriveNumber - 8 bits - ignored
|
||||
CurrentHead db 0 ; Current Head - 8 bits
|
||||
Signature db 0 ; Signature - 8 bits - ignored
|
||||
VolId db " " ; Volume Serial Number- 4 bytes
|
||||
FatLabel db " " ; Label - 11 bytes
|
||||
SystemId db "FAT16 " ; SystemId - 8 bytes
|
||||
|
||||
BootSectorEntryPoint:
|
||||
ASSUME ds:@code
|
||||
ASSUME ss:@code
|
||||
; ds = 1000, es = 2000 + x (size of first cluster >> 4)
|
||||
; cx = Start Cluster of EfiLdr
|
||||
; dx = Start Cluster of Efivar.bin
|
||||
|
||||
; Re use the BPB data stored in Boot Sector
|
||||
mov bp,07c00h
|
||||
|
||||
push cx
|
||||
; Read Efivar.bin
|
||||
; 1000:dx = DirectoryEntry of Efivar.bin -> BS.com has filled already
|
||||
mov ax,01900h
|
||||
mov es,ax
|
||||
test dx,dx
|
||||
jnz CheckVarStoreSize
|
||||
|
||||
mov al,1
|
||||
NoVarStore:
|
||||
push es
|
||||
; Set the 5th byte start @ 0:19000 to non-zero indicating we should init var store header in DxeIpl
|
||||
mov byte ptr es:[4],al
|
||||
jmp SaveVolumeId
|
||||
|
||||
CheckVarStoreSize:
|
||||
mov di,dx
|
||||
cmp dword ptr ds:[di+2], 04000h
|
||||
mov al,2
|
||||
jne NoVarStore
|
||||
|
||||
LoadVarStore:
|
||||
mov al,0
|
||||
mov byte ptr es:[4],al
|
||||
mov cx,word ptr[di]
|
||||
; ES:DI = 1500:0
|
||||
xor di,di
|
||||
push es
|
||||
mov ax,01500h
|
||||
mov es,ax
|
||||
call ReadFile
|
||||
SaveVolumeId:
|
||||
pop es
|
||||
mov ax,word ptr [bp+VolId]
|
||||
mov word ptr es:[0],ax ; Save Volume Id to 0:19000. we will find the correct volume according to this VolumeId
|
||||
mov ax,word ptr [bp+VolId+2]
|
||||
mov word ptr es:[2],ax
|
||||
|
||||
; Read Efildr
|
||||
pop cx
|
||||
; cx = Start Cluster of Efildr -> BS.com has filled already
|
||||
; ES:DI = 2000:0, first cluster will be read again
|
||||
xor di,di ; di = 0
|
||||
mov ax,02000h
|
||||
mov es,ax
|
||||
call ReadFile
|
||||
mov ax,cs
|
||||
mov word ptr cs:[JumpSegment],ax
|
||||
|
||||
JumpFarInstruction:
|
||||
db 0eah
|
||||
JumpOffset:
|
||||
dw 0200h
|
||||
JumpSegment:
|
||||
dw 2000h
|
||||
|
||||
|
||||
|
||||
; ****************************************************************************
|
||||
; ReadFile
|
||||
;
|
||||
; Arguments:
|
||||
; CX = Start Cluster of File
|
||||
; ES:DI = Buffer to store file content read from disk
|
||||
;
|
||||
; Return:
|
||||
; (ES << 4 + DI) = end of file content Buffer
|
||||
;
|
||||
; ****************************************************************************
|
||||
ReadFile:
|
||||
; si = NumberOfClusters
|
||||
; cx = ClusterNumber
|
||||
; dx = CachedFatSectorNumber
|
||||
; ds:0000 = CacheFatSectorBuffer
|
||||
; es:di = Buffer to load file
|
||||
; bx = NextClusterNumber
|
||||
pusha
|
||||
mov si,1 ; NumberOfClusters = 1
|
||||
push cx ; Push Start Cluster onto stack
|
||||
mov dx,0fffh ; CachedFatSectorNumber = 0xfff
|
||||
FatChainLoop:
|
||||
mov ax,cx ; ax = ClusterNumber
|
||||
and ax,0fff8h ; ax = ax & 0xfff8
|
||||
cmp ax,0fff8h ; See if this is the last cluster
|
||||
je FoundLastCluster ; Jump if last cluster found
|
||||
mov ax,cx ; ax = ClusterNumber
|
||||
shl ax,1 ; FatOffset = ClusterNumber * 2
|
||||
push si ; Save si
|
||||
mov si,ax ; si = FatOffset
|
||||
shr ax,BLOCK_SHIFT ; ax = FatOffset >> BLOCK_SHIFT
|
||||
add ax,word ptr [bp+ReservedSectors] ; ax = FatSectorNumber = ReservedSectors + (FatOffset >> BLOCK_OFFSET)
|
||||
and si,BLOCK_MASK ; si = FatOffset & BLOCK_MASK
|
||||
cmp ax,dx ; Compare FatSectorNumber to CachedFatSectorNumber
|
||||
je SkipFatRead
|
||||
mov bx,2
|
||||
push es
|
||||
push ds
|
||||
pop es
|
||||
call ReadBlocks ; Read 2 blocks starting at AX storing at ES:DI
|
||||
pop es
|
||||
mov dx,ax ; CachedFatSectorNumber = FatSectorNumber
|
||||
SkipFatRead:
|
||||
mov bx,word ptr [si] ; bx = NextClusterNumber
|
||||
mov ax,cx ; ax = ClusterNumber
|
||||
pop si ; Restore si
|
||||
dec bx ; bx = NextClusterNumber - 1
|
||||
cmp bx,cx ; See if (NextClusterNumber-1)==ClusterNumber
|
||||
jne ReadClusters
|
||||
inc bx ; bx = NextClusterNumber
|
||||
inc si ; NumberOfClusters++
|
||||
mov cx,bx ; ClusterNumber = NextClusterNumber
|
||||
jmp FatChainLoop
|
||||
ReadClusters:
|
||||
inc bx
|
||||
pop ax ; ax = StartCluster
|
||||
push bx ; StartCluster = NextClusterNumber
|
||||
mov cx,bx ; ClusterNumber = NextClusterNumber
|
||||
sub ax,2 ; ax = StartCluster - 2
|
||||
xor bh,bh
|
||||
mov bl,byte ptr [bp+SectorsPerCluster] ; bx = SectorsPerCluster
|
||||
mul bx ; ax = (StartCluster - 2) * SectorsPerCluster
|
||||
add ax, word ptr [bp] ; ax = FirstClusterLBA + (StartCluster-2)*SectorsPerCluster
|
||||
push ax ; save start sector
|
||||
mov ax,si ; ax = NumberOfClusters
|
||||
mul bx ; ax = NumberOfClusters * SectorsPerCluster
|
||||
mov bx,ax ; bx = Number of Sectors
|
||||
pop ax ; ax = Start Sector
|
||||
call ReadBlocks
|
||||
mov si,1 ; NumberOfClusters = 1
|
||||
jmp FatChainLoop
|
||||
FoundLastCluster:
|
||||
pop cx
|
||||
popa
|
||||
ret
|
||||
|
||||
|
||||
; ****************************************************************************
|
||||
; ReadBlocks - Reads a set of blocks from a block device
|
||||
;
|
||||
; AX = Start LBA
|
||||
; BX = Number of Blocks to Read
|
||||
; ES:DI = Buffer to store sectors read from disk
|
||||
; ****************************************************************************
|
||||
|
||||
; cx = Blocks
|
||||
; bx = NumberOfBlocks
|
||||
; si = StartLBA
|
||||
|
||||
ReadBlocks:
|
||||
pusha
|
||||
add eax,dword ptr [bp+LBAOffsetForBootSector] ; Add LBAOffsetForBootSector to Start LBA
|
||||
add eax,dword ptr [bp+HiddenSectors] ; Add HiddenSectors to Start LBA
|
||||
mov esi,eax ; esi = Start LBA
|
||||
mov cx,bx ; cx = Number of blocks to read
|
||||
ReadCylinderLoop:
|
||||
mov bp,07bfch ; bp = 0x7bfc
|
||||
mov eax,esi ; eax = Start LBA
|
||||
xor edx,edx ; edx = 0
|
||||
movzx ebx,word ptr [bp] ; bx = MaxSector
|
||||
div ebx ; ax = StartLBA / MaxSector
|
||||
inc dx ; dx = (StartLBA % MaxSector) + 1
|
||||
|
||||
mov bx,word ptr [bp] ; bx = MaxSector
|
||||
sub bx,dx ; bx = MaxSector - Sector
|
||||
inc bx ; bx = MaxSector - Sector + 1
|
||||
cmp cx,bx ; Compare (Blocks) to (MaxSector - Sector + 1)
|
||||
jg LimitTransfer
|
||||
mov bx,cx ; bx = Blocks
|
||||
LimitTransfer:
|
||||
push ax ; save ax
|
||||
mov ax,es ; ax = es
|
||||
shr ax,(BLOCK_SHIFT-4) ; ax = Number of blocks into mem system
|
||||
and ax,07fh ; ax = Number of blocks into current seg
|
||||
add ax,bx ; ax = End Block number of transfer
|
||||
cmp ax,080h ; See if it crosses a 64K boundry
|
||||
jle NotCrossing64KBoundry ; Branch if not crossing 64K boundry
|
||||
sub ax,080h ; ax = Number of blocks past 64K boundry
|
||||
sub bx,ax ; Decrease transfer size by block overage
|
||||
NotCrossing64KBoundry:
|
||||
pop ax ; restore ax
|
||||
|
||||
push cx
|
||||
mov cl,dl ; cl = (StartLBA % MaxSector) + 1 = Sector
|
||||
xor dx,dx ; dx = 0
|
||||
div word ptr [bp+2] ; ax = ax / (MaxHead + 1) = Cylinder
|
||||
; dx = ax % (MaxHead + 1) = Head
|
||||
|
||||
push bx ; Save number of blocks to transfer
|
||||
mov dh,dl ; dh = Head
|
||||
mov bp,07c00h ; bp = 0x7c00
|
||||
mov dl,byte ptr [bp+PhysicalDrive] ; dl = Drive Number
|
||||
mov ch,al ; ch = Cylinder
|
||||
mov al,bl ; al = Blocks
|
||||
mov ah,2 ; ah = Function 2
|
||||
mov bx,di ; es:bx = Buffer address
|
||||
int 013h
|
||||
jc DiskError
|
||||
pop bx
|
||||
pop cx
|
||||
movzx ebx,bx
|
||||
add esi,ebx ; StartLBA = StartLBA + NumberOfBlocks
|
||||
sub cx,bx ; Blocks = Blocks - NumberOfBlocks
|
||||
mov ax,es
|
||||
shl bx,(BLOCK_SHIFT-4)
|
||||
add ax,bx
|
||||
mov es,ax ; es:di = es:di + NumberOfBlocks*BLOCK_SIZE
|
||||
cmp cx,0
|
||||
jne ReadCylinderLoop
|
||||
popa
|
||||
ret
|
||||
|
||||
DiskError:
|
||||
push cs
|
||||
pop ds
|
||||
lea si, [ErrorString]
|
||||
mov cx, 7
|
||||
jmp PrintStringAndHalt
|
||||
|
||||
PrintStringAndHalt:
|
||||
mov ax,0b800h
|
||||
mov es,ax
|
||||
mov di,160
|
||||
rep movsw
|
||||
Halt:
|
||||
jmp Halt
|
||||
|
||||
ErrorString:
|
||||
db 'S', 0ch, 'E', 0ch, 'r', 0ch, 'r', 0ch, 'o', 0ch, 'r', 0ch, '!', 0ch
|
||||
|
||||
org 01fah
|
||||
LBAOffsetForBootSector:
|
||||
dd 0h
|
||||
|
||||
org 01feh
|
||||
dw 0aa55h
|
||||
|
||||
;******************************************************************************
|
||||
;******************************************************************************
|
||||
;******************************************************************************
|
||||
|
||||
DELAY_PORT equ 0edh ; Port to use for 1uS delay
|
||||
KBD_CONTROL_PORT equ 060h ; 8042 control port
|
||||
KBD_STATUS_PORT equ 064h ; 8042 status port
|
||||
WRITE_DATA_PORT_CMD equ 0d1h ; 8042 command to write the data port
|
||||
ENABLE_A20_CMD equ 0dfh ; 8042 command to enable A20
|
||||
|
||||
org 200h
|
||||
jmp start
|
||||
Em64String:
|
||||
db 'E', 0ch, 'm', 0ch, '6', 0ch, '4', 0ch, 'T', 0ch, ' ', 0ch, 'U', 0ch, 'n', 0ch, 's', 0ch, 'u', 0ch, 'p', 0ch, 'p', 0ch, 'o', 0ch, 'r', 0ch, 't', 0ch, 'e', 0ch, 'd', 0ch, '!', 0ch
|
||||
|
||||
start:
|
||||
mov ax,cs
|
||||
mov ds,ax
|
||||
mov es,ax
|
||||
mov ss,ax
|
||||
mov sp,MyStack
|
||||
|
||||
; mov ax,0b800h
|
||||
; mov es,ax
|
||||
; mov byte ptr es:[160],'a'
|
||||
; mov ax,cs
|
||||
; mov es,ax
|
||||
|
||||
mov ebx,0
|
||||
lea edi,MemoryMap
|
||||
MemMapLoop:
|
||||
mov eax,0e820h
|
||||
mov ecx,20
|
||||
mov edx,'SMAP'
|
||||
int 15h
|
||||
jc MemMapDone
|
||||
add edi,20
|
||||
cmp ebx,0
|
||||
je MemMapDone
|
||||
jmp MemMapLoop
|
||||
MemMapDone:
|
||||
lea eax,MemoryMap
|
||||
sub edi,eax ; Get the address of the memory map
|
||||
mov dword ptr [MemoryMapSize],edi ; Save the size of the memory map
|
||||
|
||||
xor ebx,ebx
|
||||
mov bx,cs ; BX=segment
|
||||
shl ebx,4 ; BX="linear" address of segment base
|
||||
lea eax,[GDT_BASE + ebx] ; EAX=PHYSICAL address of gdt
|
||||
mov dword ptr [gdtr + 2],eax ; Put address of gdt into the gdtr
|
||||
lea eax,[IDT_BASE + ebx] ; EAX=PHYSICAL address of idt
|
||||
mov dword ptr [idtr + 2],eax ; Put address of idt into the idtr
|
||||
lea edx,[MemoryMapSize + ebx] ; Physical base address of the memory map
|
||||
|
||||
add ebx,01000h ; Source of EFI32
|
||||
mov dword ptr [JUMP+2],ebx
|
||||
add ebx,01000h
|
||||
mov esi,ebx ; Source of EFILDR32
|
||||
|
||||
; mov ax,0b800h
|
||||
; mov es,ax
|
||||
; mov byte ptr es:[162],'b'
|
||||
; mov ax,cs
|
||||
; mov es,ax
|
||||
|
||||
;
|
||||
; Enable A20 Gate
|
||||
;
|
||||
|
||||
mov ax,2401h ; Enable A20 Gate
|
||||
int 15h
|
||||
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
|
||||
out DELAY_PORT,ax ; Delay 1 uS
|
||||
mov al,WRITE_DATA_PORT_CMD ; 8042 cmd to write output port
|
||||
out KBD_STATUS_PORT,al ; Send command to the 8042
|
||||
call Empty8042InputBuffer ; Empty the Input Buffer on the 8042 controller
|
||||
jnz Timeout8042 ; Jump if the 8042 timed out
|
||||
mov al,ENABLE_A20_CMD ; gate address bit 20 on
|
||||
out KBD_CONTROL_PORT,al ; Send command to thre 8042
|
||||
call Empty8042InputBuffer ; Empty the Input Buffer on the 8042 controller
|
||||
mov cx,25 ; Delay 25 uS for the command to complete on the 8042
|
||||
Delay25uS:
|
||||
out DELAY_PORT,ax ; Delay 1 uS
|
||||
loop Delay25uS
|
||||
Timeout8042:
|
||||
|
||||
|
||||
A20GateEnabled:
|
||||
|
||||
;
|
||||
; DISABLE INTERRUPTS - Entering Protected Mode
|
||||
;
|
||||
|
||||
cli
|
||||
|
||||
; mov ax,0b800h
|
||||
; mov es,ax
|
||||
; mov byte ptr es:[164],'c'
|
||||
; mov ax,cs
|
||||
; mov es,ax
|
||||
|
||||
db 66h
|
||||
lgdt fword ptr [gdtr]
|
||||
db 66h
|
||||
lidt fword ptr [idtr]
|
||||
|
||||
mov eax,cr0
|
||||
or al,1
|
||||
mov cr0,eax
|
||||
|
||||
mov eax,0008h ; Flat data descriptor
|
||||
mov ebp,000400000h ; Destination of EFILDR32
|
||||
mov ebx,000070000h ; Length of copy
|
||||
|
||||
JUMP:
|
||||
; jmp far 0010:00020000
|
||||
db 066h
|
||||
db 0eah
|
||||
dd 000020000h
|
||||
dw 00010h
|
||||
|
||||
Empty8042InputBuffer:
|
||||
mov cx,0
|
||||
Empty8042Loop:
|
||||
out DELAY_PORT,ax ; Delay 1us
|
||||
in al,KBD_STATUS_PORT ; Read the 8042 Status Port
|
||||
and al,02h ; Check the Input Buffer Full Flag
|
||||
loopnz Empty8042Loop ; Loop until the input buffer is empty or a timout of 65536 uS
|
||||
ret
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; data
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
align 02h
|
||||
|
||||
gdtr dw GDT_END - GDT_BASE - 1 ; GDT limit
|
||||
dd 0 ; (GDT base gets set above)
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; global descriptor table (GDT)
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
align 02h
|
||||
|
||||
public GDT_BASE
|
||||
GDT_BASE:
|
||||
; null descriptor
|
||||
NULL_SEL equ $-GDT_BASE
|
||||
dw 0 ; limit 15:0
|
||||
dw 0 ; base 15:0
|
||||
db 0 ; base 23:16
|
||||
db 0 ; type
|
||||
db 0 ; limit 19:16, flags
|
||||
db 0 ; base 31:24
|
||||
|
||||
; linear data segment descriptor
|
||||
LINEAR_SEL equ $-GDT_BASE
|
||||
dw 0FFFFh ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 092h ; present, ring 0, data, expand-up, writable
|
||||
db 0CFh ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
; linear code segment descriptor
|
||||
LINEAR_CODE_SEL equ $-GDT_BASE
|
||||
dw 0FFFFh ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 09Ah ; present, ring 0, data, expand-up, writable
|
||||
db 0CFh ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
; system data segment descriptor
|
||||
SYS_DATA_SEL equ $-GDT_BASE
|
||||
dw 0FFFFh ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 092h ; present, ring 0, data, expand-up, writable
|
||||
db 0CFh ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
; system code segment descriptor
|
||||
SYS_CODE_SEL equ $-GDT_BASE
|
||||
dw 0FFFFh ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 09Ah ; present, ring 0, data, expand-up, writable
|
||||
db 0CFh ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
; spare segment descriptor
|
||||
SPARE3_SEL equ $-GDT_BASE
|
||||
dw 0 ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 0 ; present, ring 0, data, expand-up, writable
|
||||
db 0 ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
; spare segment descriptor
|
||||
SPARE4_SEL equ $-GDT_BASE
|
||||
dw 0 ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 0 ; present, ring 0, data, expand-up, writable
|
||||
db 0 ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
; spare segment descriptor
|
||||
SPARE5_SEL equ $-GDT_BASE
|
||||
dw 0 ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 0 ; present, ring 0, data, expand-up, writable
|
||||
db 0 ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
GDT_END:
|
||||
|
||||
align 02h
|
||||
|
||||
|
||||
|
||||
idtr dw IDT_END - IDT_BASE - 1 ; IDT limit
|
||||
dd 0 ; (IDT base gets set 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.
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;idt_tag db "IDT",0
|
||||
align 02h
|
||||
|
||||
public IDT_BASE
|
||||
IDT_BASE:
|
||||
; divide by zero (INT 0)
|
||||
DIV_ZERO_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; debug exception (INT 1)
|
||||
DEBUG_EXCEPT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; NMI (INT 2)
|
||||
NMI_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; soft breakpoint (INT 3)
|
||||
BREAKPOINT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; overflow (INT 4)
|
||||
OVERFLOW_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; bounds check (INT 5)
|
||||
BOUNDS_CHECK_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; invalid opcode (INT 6)
|
||||
INVALID_OPCODE_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; device not available (INT 7)
|
||||
DEV_NOT_AVAIL_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; double fault (INT 8)
|
||||
DOUBLE_FAULT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; Coprocessor segment overrun - reserved (INT 9)
|
||||
RSVD_INTR_SEL1 equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; invalid TSS (INT 0ah)
|
||||
INVALID_TSS_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; segment not present (INT 0bh)
|
||||
SEG_NOT_PRESENT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; stack fault (INT 0ch)
|
||||
STACK_FAULT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; general protection (INT 0dh)
|
||||
GP_FAULT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; page fault (INT 0eh)
|
||||
PAGE_FAULT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; Intel reserved - do not use (INT 0fh)
|
||||
RSVD_INTR_SEL2 equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; floating point error (INT 10h)
|
||||
FLT_POINT_ERR_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; alignment check (INT 11h)
|
||||
ALIGNMENT_CHECK_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; machine check (INT 12h)
|
||||
MACHINE_CHECK_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; SIMD floating-point exception (INT 13h)
|
||||
SIMD_EXCEPTION_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; 85 unspecified descriptors, First 12 of them are reserved, the rest are avail
|
||||
db (85 * 8) dup(0)
|
||||
|
||||
; IRQ 0 (System timer) - (INT 68h)
|
||||
IRQ0_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 1 (8042 Keyboard controller) - (INT 69h)
|
||||
IRQ1_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; Reserved - IRQ 2 redirect (IRQ 2) - DO NOT USE!!! - (INT 6ah)
|
||||
IRQ2_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 3 (COM 2) - (INT 6bh)
|
||||
IRQ3_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 4 (COM 1) - (INT 6ch)
|
||||
IRQ4_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 5 (LPT 2) - (INT 6dh)
|
||||
IRQ5_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 6 (Floppy controller) - (INT 6eh)
|
||||
IRQ6_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 7 (LPT 1) - (INT 6fh)
|
||||
IRQ7_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 8 (RTC Alarm) - (INT 70h)
|
||||
IRQ8_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 9 - (INT 71h)
|
||||
IRQ9_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 10 - (INT 72h)
|
||||
IRQ10_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 11 - (INT 73h)
|
||||
IRQ11_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 12 (PS/2 mouse) - (INT 74h)
|
||||
IRQ12_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 13 (Floating point error) - (INT 75h)
|
||||
IRQ13_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 14 (Secondary IDE) - (INT 76h)
|
||||
IRQ14_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 15 (Primary IDE) - (INT 77h)
|
||||
IRQ15_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
IDT_END:
|
||||
|
||||
align 02h
|
||||
|
||||
MemoryMapSize dd 0
|
||||
MemoryMap dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
|
||||
dd 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
|
||||
dd 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
|
||||
|
||||
org 0fe0h
|
||||
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 0ffeh
|
||||
BlockSignature:
|
||||
dw 0aa55h
|
||||
|
||||
end
|
929
DuetPkg/BootSector/start32.asm
Normal file
929
DuetPkg/BootSector/start32.asm
Normal file
@ -0,0 +1,929 @@
|
||||
;------------------------------------------------------------------------------
|
||||
;*
|
||||
;* Copyright 2006 - 2007, Intel Corporation
|
||||
;* All rights reserved. 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.
|
||||
;*
|
||||
;* start32.asm
|
||||
;*
|
||||
;* Abstract:
|
||||
;*
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
.model small
|
||||
.stack
|
||||
.486p
|
||||
.code
|
||||
|
||||
FAT_DIRECTORY_ENTRY_SIZE EQU 020h
|
||||
FAT_DIRECTORY_ENTRY_SHIFT EQU 5
|
||||
BLOCK_SIZE EQU 0200h
|
||||
BLOCK_MASK EQU 01ffh
|
||||
BLOCK_SHIFT EQU 9
|
||||
|
||||
org 0h
|
||||
Ia32Jump:
|
||||
jmp BootSectorEntryPoint ; JMP inst - 3 bytes
|
||||
nop
|
||||
|
||||
OemId db "INTEL " ; OemId - 8 bytes
|
||||
SectorSize dw 0 ; Sector Size - 2 bytes
|
||||
SectorsPerCluster db 0 ; Sector Per Cluster - 1 byte
|
||||
ReservedSectors dw 0 ; Reserved Sectors - 2 bytes
|
||||
NoFats db 0 ; Number of FATs - 1 byte
|
||||
RootEntries dw 0 ; Root Entries - 2 bytes
|
||||
Sectors dw 0 ; Number of Sectors - 2 bytes
|
||||
Media db 0 ; Media - 1 byte
|
||||
SectorsPerFat16 dw 0 ; Sectors Per FAT for FAT12/FAT16 - 2 byte
|
||||
SectorsPerTrack dw 0 ; Sectors Per Track - 2 bytes
|
||||
Heads dw 0 ; Heads - 2 bytes
|
||||
HiddenSectors dd 0 ; Hidden Sectors - 4 bytes
|
||||
LargeSectors dd 0 ; Large Sectors - 4 bytes
|
||||
|
||||
;******************************************************************************
|
||||
;
|
||||
;The structure for FAT32 starting at offset 36 of the boot sector. (At this point,
|
||||
;the BPB/boot sector for FAT12 and FAT16 differs from the BPB/boot sector for FAT32.)
|
||||
;
|
||||
;******************************************************************************
|
||||
|
||||
SectorsPerFat32 dd 0 ; Sectors Per FAT for FAT32 - 4 bytes
|
||||
ExtFlags dw 0 ; Mirror Flag - 2 bytes
|
||||
FSVersion dw 0 ; File System Version - 2 bytes
|
||||
RootCluster dd 0 ; 1st Cluster Number of Root Dir - 4 bytes
|
||||
FSInfo dw 0 ; Sector Number of FSINFO - 2 bytes
|
||||
BkBootSector dw 0 ; Sector Number of Bk BootSector - 2 bytes
|
||||
Reserved db 12 dup(0) ; Reserved Field - 12 bytes
|
||||
PhysicalDrive db 0 ; Physical Drive Number - 1 byte
|
||||
Reserved1 db 0 ; Reserved Field - 1 byte
|
||||
Signature db 0 ; Extended Boot Signature - 1 byte
|
||||
VolId db " " ; Volume Serial Number - 4 bytes
|
||||
FatLabel db " " ; Volume Label - 11 bytes
|
||||
FileSystemType db "FAT32 " ; File System Type - 8 bytes
|
||||
|
||||
BootSectorEntryPoint:
|
||||
ASSUME ds:@code
|
||||
ASSUME ss:@code
|
||||
; ds = 1000, es = 2000 + x (size of first cluster >> 4)
|
||||
; cx = Start Cluster of EfiLdr
|
||||
; dx = Start Cluster of Efivar.bin
|
||||
|
||||
; Re use the BPB data stored in Boot Sector
|
||||
mov bp,07c00h
|
||||
|
||||
|
||||
push cx
|
||||
; Read Efivar.bin
|
||||
; 1000:dx = DirectoryEntry of Efivar.bin -> BS.com has filled already
|
||||
mov ax,01900h
|
||||
mov es,ax
|
||||
test dx,dx
|
||||
jnz CheckVarStoreSize
|
||||
|
||||
mov al,1
|
||||
NoVarStore:
|
||||
push es
|
||||
; Set the 5th byte start @ 0:19000 to non-zero indicating we should init var store header in DxeIpl
|
||||
mov byte ptr es:[4],al
|
||||
jmp SaveVolumeId
|
||||
|
||||
CheckVarStoreSize:
|
||||
mov di,dx
|
||||
cmp dword ptr ds:[di+2], 04000h
|
||||
mov al,2
|
||||
jne NoVarStore
|
||||
|
||||
LoadVarStore:
|
||||
mov al,0
|
||||
mov byte ptr es:[4],al
|
||||
mov cx,word ptr[di]
|
||||
; ES:DI = 1500:0
|
||||
xor di,di
|
||||
push es
|
||||
mov ax,01500h
|
||||
mov es,ax
|
||||
call ReadFile
|
||||
SaveVolumeId:
|
||||
pop es
|
||||
mov ax,word ptr [bp+VolId]
|
||||
mov word ptr es:[0],ax ; Save Volume Id to 0:19000. we will find the correct volume according to this VolumeId
|
||||
mov ax,word ptr [bp+VolId+2]
|
||||
mov word ptr es:[2],ax
|
||||
|
||||
; Read Efildr
|
||||
pop cx
|
||||
; cx = Start Cluster of Efildr -> BS.com has filled already
|
||||
; ES:DI = 2000:0, first cluster will be read again
|
||||
xor di,di ; di = 0
|
||||
mov ax,02000h
|
||||
mov es,ax
|
||||
call ReadFile
|
||||
mov ax,cs
|
||||
mov word ptr cs:[JumpSegment],ax
|
||||
JumpFarInstruction:
|
||||
db 0eah
|
||||
JumpOffset:
|
||||
dw 0200h
|
||||
JumpSegment:
|
||||
dw 2000h
|
||||
|
||||
|
||||
|
||||
|
||||
; ****************************************************************************
|
||||
; ReadFile
|
||||
;
|
||||
; Arguments:
|
||||
; CX = Start Cluster of File
|
||||
; ES:DI = Buffer to store file content read from disk
|
||||
;
|
||||
; Return:
|
||||
; (ES << 4 + DI) = end of file content Buffer
|
||||
;
|
||||
; ****************************************************************************
|
||||
ReadFile:
|
||||
; si = NumberOfClusters
|
||||
; cx = ClusterNumber
|
||||
; dx = CachedFatSectorNumber
|
||||
; ds:0000 = CacheFatSectorBuffer
|
||||
; es:di = Buffer to load file
|
||||
; bx = NextClusterNumber
|
||||
pusha
|
||||
mov si,1 ; NumberOfClusters = 1
|
||||
push cx ; Push Start Cluster onto stack
|
||||
mov dx,0fffh ; CachedFatSectorNumber = 0xfff
|
||||
FatChainLoop:
|
||||
mov ax,cx ; ax = ClusterNumber
|
||||
and ax,0fff8h ; ax = ax & 0xfff8
|
||||
cmp ax,0fff8h ; See if this is the last cluster
|
||||
je FoundLastCluster ; Jump if last cluster found
|
||||
mov ax,cx ; ax = ClusterNumber
|
||||
shl ax,2 ; FatOffset = ClusterNumber * 4
|
||||
push si ; Save si
|
||||
mov si,ax ; si = FatOffset
|
||||
shr ax,BLOCK_SHIFT ; ax = FatOffset >> BLOCK_SHIFT
|
||||
add ax,word ptr [bp+ReservedSectors] ; ax = FatSectorNumber = ReservedSectors + (FatOffset >> BLOCK_OFFSET)
|
||||
and si,BLOCK_MASK ; si = FatOffset & BLOCK_MASK
|
||||
cmp ax,dx ; Compare FatSectorNumber to CachedFatSectorNumber
|
||||
je SkipFatRead
|
||||
mov bx,2
|
||||
push es
|
||||
push ds
|
||||
pop es
|
||||
call ReadBlocks ; Read 2 blocks starting at AX storing at ES:DI
|
||||
pop es
|
||||
mov dx,ax ; CachedFatSectorNumber = FatSectorNumber
|
||||
SkipFatRead:
|
||||
mov bx,word ptr [si] ; bx = NextClusterNumber
|
||||
mov ax,cx ; ax = ClusterNumber
|
||||
pop si ; Restore si
|
||||
dec bx ; bx = NextClusterNumber - 1
|
||||
cmp bx,cx ; See if (NextClusterNumber-1)==ClusterNumber
|
||||
jne ReadClusters
|
||||
inc bx ; bx = NextClusterNumber
|
||||
inc si ; NumberOfClusters++
|
||||
mov cx,bx ; ClusterNumber = NextClusterNumber
|
||||
jmp FatChainLoop
|
||||
ReadClusters:
|
||||
inc bx
|
||||
pop ax ; ax = StartCluster
|
||||
push bx ; StartCluster = NextClusterNumber
|
||||
mov cx,bx ; ClusterNumber = NextClusterNumber
|
||||
sub ax,2 ; ax = StartCluster - 2
|
||||
xor bh,bh
|
||||
mov bl,byte ptr [bp+SectorsPerCluster] ; bx = SectorsPerCluster
|
||||
mul bx ; ax = (StartCluster - 2) * SectorsPerCluster
|
||||
add ax, word ptr [bp] ; ax = FirstClusterLBA + (StartCluster-2)*SectorsPerCluster
|
||||
push ax ; save start sector
|
||||
mov ax,si ; ax = NumberOfClusters
|
||||
mul bx ; ax = NumberOfClusters * SectorsPerCluster
|
||||
mov bx,ax ; bx = Number of Sectors
|
||||
pop ax ; ax = Start Sector
|
||||
call ReadBlocks
|
||||
mov si,1 ; NumberOfClusters = 1
|
||||
jmp FatChainLoop
|
||||
FoundLastCluster:
|
||||
pop cx
|
||||
popa
|
||||
ret
|
||||
|
||||
|
||||
; ****************************************************************************
|
||||
; ReadBlocks - Reads a set of blocks from a block device
|
||||
;
|
||||
; AX = Start LBA
|
||||
; BX = Number of Blocks to Read
|
||||
; ES:DI = Buffer to store sectors read from disk
|
||||
; ****************************************************************************
|
||||
|
||||
; cx = Blocks
|
||||
; bx = NumberOfBlocks
|
||||
; si = StartLBA
|
||||
|
||||
ReadBlocks:
|
||||
pusha
|
||||
add eax,dword ptr [bp+LBAOffsetForBootSector] ; Add LBAOffsetForBootSector to Start LBA
|
||||
add eax,dword ptr [bp+HiddenSectors] ; Add HiddenSectors to Start LBA
|
||||
mov esi,eax ; esi = Start LBA
|
||||
mov cx,bx ; cx = Number of blocks to read
|
||||
ReadCylinderLoop:
|
||||
mov bp,07bfch ; bp = 0x7bfc
|
||||
mov eax,esi ; eax = Start LBA
|
||||
xor edx,edx ; edx = 0
|
||||
movzx ebx,word ptr [bp] ; bx = MaxSector
|
||||
div ebx ; ax = StartLBA / MaxSector
|
||||
inc dx ; dx = (StartLBA % MaxSector) + 1
|
||||
|
||||
mov bx,word ptr [bp] ; bx = MaxSector
|
||||
sub bx,dx ; bx = MaxSector - Sector
|
||||
inc bx ; bx = MaxSector - Sector + 1
|
||||
cmp cx,bx ; Compare (Blocks) to (MaxSector - Sector + 1)
|
||||
jg LimitTransfer
|
||||
mov bx,cx ; bx = Blocks
|
||||
LimitTransfer:
|
||||
push ax ; save ax
|
||||
mov ax,es ; ax = es
|
||||
shr ax,(BLOCK_SHIFT-4) ; ax = Number of blocks into mem system
|
||||
and ax,07fh ; ax = Number of blocks into current seg
|
||||
add ax,bx ; ax = End Block number of transfer
|
||||
cmp ax,080h ; See if it crosses a 64K boundry
|
||||
jle NotCrossing64KBoundry ; Branch if not crossing 64K boundry
|
||||
sub ax,080h ; ax = Number of blocks past 64K boundry
|
||||
sub bx,ax ; Decrease transfer size by block overage
|
||||
NotCrossing64KBoundry:
|
||||
pop ax ; restore ax
|
||||
|
||||
push cx
|
||||
mov cl,dl ; cl = (StartLBA % MaxSector) + 1 = Sector
|
||||
xor dx,dx ; dx = 0
|
||||
div word ptr [bp+2] ; ax = ax / (MaxHead + 1) = Cylinder
|
||||
; dx = ax % (MaxHead + 1) = Head
|
||||
|
||||
push bx ; Save number of blocks to transfer
|
||||
mov dh,dl ; dh = Head
|
||||
mov bp,07c00h ; bp = 0x7c00
|
||||
mov dl,byte ptr [bp+PhysicalDrive] ; dl = Drive Number
|
||||
mov ch,al ; ch = Cylinder
|
||||
mov al,bl ; al = Blocks
|
||||
mov ah,2 ; ah = Function 2
|
||||
mov bx,di ; es:bx = Buffer address
|
||||
int 013h
|
||||
jc DiskError
|
||||
pop bx
|
||||
pop cx
|
||||
movzx ebx,bx
|
||||
add esi,ebx ; StartLBA = StartLBA + NumberOfBlocks
|
||||
sub cx,bx ; Blocks = Blocks - NumberOfBlocks
|
||||
mov ax,es
|
||||
shl bx,(BLOCK_SHIFT-4)
|
||||
add ax,bx
|
||||
mov es,ax ; es:di = es:di + NumberOfBlocks*BLOCK_SIZE
|
||||
cmp cx,0
|
||||
jne ReadCylinderLoop
|
||||
popa
|
||||
ret
|
||||
|
||||
DiskError:
|
||||
push cs
|
||||
pop ds
|
||||
lea si, [ErrorString]
|
||||
mov cx, 7
|
||||
jmp PrintStringAndHalt
|
||||
|
||||
PrintStringAndHalt:
|
||||
mov ax,0b800h
|
||||
mov es,ax
|
||||
mov di,160
|
||||
rep movsw
|
||||
Halt:
|
||||
jmp Halt
|
||||
|
||||
ErrorString:
|
||||
db 'S', 0ch, 'E', 0ch, 'r', 0ch, 'r', 0ch, 'o', 0ch, 'r', 0ch, '!', 0ch
|
||||
|
||||
org 01fah
|
||||
LBAOffsetForBootSector:
|
||||
dd 0h
|
||||
|
||||
org 01feh
|
||||
dw 0aa55h
|
||||
|
||||
;******************************************************************************
|
||||
;******************************************************************************
|
||||
;******************************************************************************
|
||||
|
||||
DELAY_PORT equ 0edh ; Port to use for 1uS delay
|
||||
KBD_CONTROL_PORT equ 060h ; 8042 control port
|
||||
KBD_STATUS_PORT equ 064h ; 8042 status port
|
||||
WRITE_DATA_PORT_CMD equ 0d1h ; 8042 command to write the data port
|
||||
ENABLE_A20_CMD equ 0dfh ; 8042 command to enable A20
|
||||
|
||||
org 200h
|
||||
jmp start
|
||||
Em64String:
|
||||
db 'E', 0ch, 'm', 0ch, '6', 0ch, '4', 0ch, 'T', 0ch, ' ', 0ch, 'U', 0ch, 'n', 0ch, 's', 0ch, 'u', 0ch, 'p', 0ch, 'p', 0ch, 'o', 0ch, 'r', 0ch, 't', 0ch, 'e', 0ch, 'd', 0ch, '!', 0ch
|
||||
|
||||
start:
|
||||
mov ax,cs
|
||||
mov ds,ax
|
||||
mov es,ax
|
||||
mov ss,ax
|
||||
mov sp,MyStack
|
||||
|
||||
; mov ax,0b800h
|
||||
; mov es,ax
|
||||
; mov byte ptr es:[160],'a'
|
||||
; mov ax,cs
|
||||
; mov es,ax
|
||||
|
||||
mov ebx,0
|
||||
lea edi,MemoryMap
|
||||
MemMapLoop:
|
||||
mov eax,0e820h
|
||||
mov ecx,20
|
||||
mov edx,'SMAP'
|
||||
int 15h
|
||||
jc MemMapDone
|
||||
add edi,20
|
||||
cmp ebx,0
|
||||
je MemMapDone
|
||||
jmp MemMapLoop
|
||||
MemMapDone:
|
||||
lea eax,MemoryMap
|
||||
sub edi,eax ; Get the address of the memory map
|
||||
mov dword ptr [MemoryMapSize],edi ; Save the size of the memory map
|
||||
|
||||
xor ebx,ebx
|
||||
mov bx,cs ; BX=segment
|
||||
shl ebx,4 ; BX="linear" address of segment base
|
||||
lea eax,[GDT_BASE + ebx] ; EAX=PHYSICAL address of gdt
|
||||
mov dword ptr [gdtr + 2],eax ; Put address of gdt into the gdtr
|
||||
lea eax,[IDT_BASE + ebx] ; EAX=PHYSICAL address of idt
|
||||
mov dword ptr [idtr + 2],eax ; Put address of idt into the idtr
|
||||
lea edx,[MemoryMapSize + ebx] ; Physical base address of the memory map
|
||||
|
||||
add ebx,01000h ; Source of EFI32
|
||||
mov dword ptr [JUMP+2],ebx
|
||||
add ebx,01000h
|
||||
mov esi,ebx ; Source of EFILDR32
|
||||
|
||||
; mov ax,0b800h
|
||||
; mov es,ax
|
||||
; mov byte ptr es:[162],'b'
|
||||
; mov ax,cs
|
||||
; mov es,ax
|
||||
|
||||
;
|
||||
; Enable A20 Gate
|
||||
;
|
||||
|
||||
mov ax,2401h ; Enable A20 Gate
|
||||
int 15h
|
||||
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
|
||||
out DELAY_PORT,ax ; Delay 1 uS
|
||||
mov al,WRITE_DATA_PORT_CMD ; 8042 cmd to write output port
|
||||
out KBD_STATUS_PORT,al ; Send command to the 8042
|
||||
call Empty8042InputBuffer ; Empty the Input Buffer on the 8042 controller
|
||||
jnz Timeout8042 ; Jump if the 8042 timed out
|
||||
mov al,ENABLE_A20_CMD ; gate address bit 20 on
|
||||
out KBD_CONTROL_PORT,al ; Send command to thre 8042
|
||||
call Empty8042InputBuffer ; Empty the Input Buffer on the 8042 controller
|
||||
mov cx,25 ; Delay 25 uS for the command to complete on the 8042
|
||||
Delay25uS:
|
||||
out DELAY_PORT,ax ; Delay 1 uS
|
||||
loop Delay25uS
|
||||
Timeout8042:
|
||||
|
||||
|
||||
A20GateEnabled:
|
||||
|
||||
;
|
||||
; DISABLE INTERRUPTS - Entering Protected Mode
|
||||
;
|
||||
|
||||
cli
|
||||
|
||||
; mov ax,0b800h
|
||||
; mov es,ax
|
||||
; mov byte ptr es:[164],'c'
|
||||
; mov ax,cs
|
||||
; mov es,ax
|
||||
|
||||
db 66h
|
||||
lgdt fword ptr [gdtr]
|
||||
db 66h
|
||||
lidt fword ptr [idtr]
|
||||
|
||||
mov eax,cr0
|
||||
or al,1
|
||||
mov cr0,eax
|
||||
|
||||
mov eax,0008h ; Flat data descriptor
|
||||
mov ebp,000400000h ; Destination of EFILDR32
|
||||
mov ebx,000070000h ; Length of copy
|
||||
|
||||
JUMP:
|
||||
; jmp far 0010:00020000
|
||||
db 066h
|
||||
db 0eah
|
||||
dd 000020000h
|
||||
dw 00010h
|
||||
|
||||
Empty8042InputBuffer:
|
||||
mov cx,0
|
||||
Empty8042Loop:
|
||||
out DELAY_PORT,ax ; Delay 1us
|
||||
in al,KBD_STATUS_PORT ; Read the 8042 Status Port
|
||||
and al,02h ; Check the Input Buffer Full Flag
|
||||
loopnz Empty8042Loop ; Loop until the input buffer is empty or a timout of 65536 uS
|
||||
ret
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; data
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
align 02h
|
||||
|
||||
gdtr dw GDT_END - GDT_BASE - 1 ; GDT limit
|
||||
dd 0 ; (GDT base gets set above)
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; global descriptor table (GDT)
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
align 02h
|
||||
|
||||
public GDT_BASE
|
||||
GDT_BASE:
|
||||
; null descriptor
|
||||
NULL_SEL equ $-GDT_BASE
|
||||
dw 0 ; limit 15:0
|
||||
dw 0 ; base 15:0
|
||||
db 0 ; base 23:16
|
||||
db 0 ; type
|
||||
db 0 ; limit 19:16, flags
|
||||
db 0 ; base 31:24
|
||||
|
||||
; linear data segment descriptor
|
||||
LINEAR_SEL equ $-GDT_BASE
|
||||
dw 0FFFFh ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 092h ; present, ring 0, data, expand-up, writable
|
||||
db 0CFh ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
; linear code segment descriptor
|
||||
LINEAR_CODE_SEL equ $-GDT_BASE
|
||||
dw 0FFFFh ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 09Ah ; present, ring 0, data, expand-up, writable
|
||||
db 0CFh ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
; system data segment descriptor
|
||||
SYS_DATA_SEL equ $-GDT_BASE
|
||||
dw 0FFFFh ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 092h ; present, ring 0, data, expand-up, writable
|
||||
db 0CFh ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
; system code segment descriptor
|
||||
SYS_CODE_SEL equ $-GDT_BASE
|
||||
dw 0FFFFh ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 09Ah ; present, ring 0, data, expand-up, writable
|
||||
db 0CFh ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
; spare segment descriptor
|
||||
SPARE3_SEL equ $-GDT_BASE
|
||||
dw 0 ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 0 ; present, ring 0, data, expand-up, writable
|
||||
db 0 ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
; spare segment descriptor
|
||||
SPARE4_SEL equ $-GDT_BASE
|
||||
dw 0 ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 0 ; present, ring 0, data, expand-up, writable
|
||||
db 0 ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
; spare segment descriptor
|
||||
SPARE5_SEL equ $-GDT_BASE
|
||||
dw 0 ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 0 ; present, ring 0, data, expand-up, writable
|
||||
db 0 ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
GDT_END:
|
||||
|
||||
align 02h
|
||||
|
||||
|
||||
|
||||
idtr dw IDT_END - IDT_BASE - 1 ; IDT limit
|
||||
dd 0 ; (IDT base gets set 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.
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;idt_tag db "IDT",0
|
||||
align 02h
|
||||
|
||||
public IDT_BASE
|
||||
IDT_BASE:
|
||||
; divide by zero (INT 0)
|
||||
DIV_ZERO_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; debug exception (INT 1)
|
||||
DEBUG_EXCEPT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; NMI (INT 2)
|
||||
NMI_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; soft breakpoint (INT 3)
|
||||
BREAKPOINT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; overflow (INT 4)
|
||||
OVERFLOW_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; bounds check (INT 5)
|
||||
BOUNDS_CHECK_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; invalid opcode (INT 6)
|
||||
INVALID_OPCODE_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; device not available (INT 7)
|
||||
DEV_NOT_AVAIL_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; double fault (INT 8)
|
||||
DOUBLE_FAULT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; Coprocessor segment overrun - reserved (INT 9)
|
||||
RSVD_INTR_SEL1 equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; invalid TSS (INT 0ah)
|
||||
INVALID_TSS_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; segment not present (INT 0bh)
|
||||
SEG_NOT_PRESENT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; stack fault (INT 0ch)
|
||||
STACK_FAULT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; general protection (INT 0dh)
|
||||
GP_FAULT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; page fault (INT 0eh)
|
||||
PAGE_FAULT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; Intel reserved - do not use (INT 0fh)
|
||||
RSVD_INTR_SEL2 equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; floating point error (INT 10h)
|
||||
FLT_POINT_ERR_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; alignment check (INT 11h)
|
||||
ALIGNMENT_CHECK_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; machine check (INT 12h)
|
||||
MACHINE_CHECK_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; SIMD floating-point exception (INT 13h)
|
||||
SIMD_EXCEPTION_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; 85 unspecified descriptors, First 12 of them are reserved, the rest are avail
|
||||
db (85 * 8) dup(0)
|
||||
|
||||
; IRQ 0 (System timer) - (INT 68h)
|
||||
IRQ0_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 1 (8042 Keyboard controller) - (INT 69h)
|
||||
IRQ1_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; Reserved - IRQ 2 redirect (IRQ 2) - DO NOT USE!!! - (INT 6ah)
|
||||
IRQ2_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 3 (COM 2) - (INT 6bh)
|
||||
IRQ3_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 4 (COM 1) - (INT 6ch)
|
||||
IRQ4_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 5 (LPT 2) - (INT 6dh)
|
||||
IRQ5_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 6 (Floppy controller) - (INT 6eh)
|
||||
IRQ6_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 7 (LPT 1) - (INT 6fh)
|
||||
IRQ7_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 8 (RTC Alarm) - (INT 70h)
|
||||
IRQ8_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 9 - (INT 71h)
|
||||
IRQ9_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 10 - (INT 72h)
|
||||
IRQ10_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 11 - (INT 73h)
|
||||
IRQ11_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 12 (PS/2 mouse) - (INT 74h)
|
||||
IRQ12_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 13 (Floating point error) - (INT 75h)
|
||||
IRQ13_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 14 (Secondary IDE) - (INT 76h)
|
||||
IRQ14_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 15 (Primary IDE) - (INT 77h)
|
||||
IRQ15_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
IDT_END:
|
||||
|
||||
align 02h
|
||||
|
||||
MemoryMapSize dd 0
|
||||
MemoryMap dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
dd 0,0,0,0,0,0,0,0
|
||||
|
||||
dd 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
|
||||
dd 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
|
||||
|
||||
org 0fe0h
|
||||
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 0ffeh
|
||||
BlockSignature:
|
||||
dw 0aa55h
|
||||
|
||||
end
|
1147
DuetPkg/BootSector/start64.asm
Normal file
1147
DuetPkg/BootSector/start64.asm
Normal file
File diff suppressed because it is too large
Load Diff
1151
DuetPkg/CpuDxe/Cpu.c
Normal file
1151
DuetPkg/CpuDxe/Cpu.c
Normal file
File diff suppressed because it is too large
Load Diff
25
DuetPkg/CpuDxe/Cpu.dxs
Normal file
25
DuetPkg/CpuDxe/Cpu.dxs
Normal file
@ -0,0 +1,25 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. 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.
|
||||
|
||||
Module Name:
|
||||
Cpu.dxs
|
||||
|
||||
Abstract:
|
||||
Dependency expression source file.
|
||||
|
||||
--*/
|
||||
|
||||
#include "EfiDepex.h"
|
||||
#include EFI_PROTOCOL_DEFINITION (Legacy8259)
|
||||
|
||||
DEPENDENCY_START
|
||||
EFI_LEGACY_8259_PROTOCOL_GUID
|
||||
DEPENDENCY_END
|
53
DuetPkg/CpuDxe/Cpu.inf
Normal file
53
DuetPkg/CpuDxe/Cpu.inf
Normal file
@ -0,0 +1,53 @@
|
||||
#/*++
|
||||
#
|
||||
# Copyright (c) 2006, Intel Corporation
|
||||
# All rights reserved. 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.
|
||||
#
|
||||
# Module Name:
|
||||
# Cpu.inf
|
||||
#
|
||||
# Abstract:
|
||||
#
|
||||
#--*/
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = Cpu
|
||||
FILE_GUID = 10527025-78B2-4d3e-A9DF-41E75C220F5A
|
||||
MODULE_TYPE = DXE_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
EDK_RELEASE_VERSION = 0x00020000
|
||||
EFI_SPECIFICATION_VERSION = 0x00020000
|
||||
|
||||
ENTRY_POINT = InitializeCpu
|
||||
|
||||
[Packages]
|
||||
DuetPkg/DuetPkg.dec
|
||||
MdePkg/MdePkg.dec
|
||||
IntelFrameworkPkg/IntelFrameworkPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
UefiDriverEntryPoint
|
||||
PrintLib
|
||||
UefiBootServicesTableLib
|
||||
|
||||
[Sources.IA32]
|
||||
IA32/CpuInterrupt.asm
|
||||
|
||||
[Sources.X64]
|
||||
X64/CpuInterrupt.asm
|
||||
|
||||
[Sources.common]
|
||||
Cpu.c
|
||||
CpuDxe.h
|
||||
|
||||
[Protocols]
|
||||
gEfiCpuArchProtocolGuid
|
||||
gEfiLegacyBiosThunkProtocolGuid
|
||||
gEfiLegacy8259ProtocolGuid
|
148
DuetPkg/CpuDxe/CpuDxe.h
Normal file
148
DuetPkg/CpuDxe/CpuDxe.h
Normal file
@ -0,0 +1,148 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. 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.
|
||||
|
||||
Module Name:
|
||||
CpuDxe.h
|
||||
|
||||
Abstract:
|
||||
|
||||
--*/
|
||||
#ifndef _CPU_DXE_H
|
||||
#define _CPU_DXE_H
|
||||
|
||||
#include <PiDxe.h>
|
||||
|
||||
#include <Protocol/Cpu.h>
|
||||
#include <Protocol/Legacy8259.h>
|
||||
|
||||
#include <Protocol/LegacyBios.h>
|
||||
#include <Protocol/LegacyBiosThunk.h>
|
||||
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/PrintLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
|
||||
#define CPU_EXCEPTION_DEBUG_OUTPUT 1
|
||||
#define CPU_EXCEPTION_VGA_SWITCH 1
|
||||
|
||||
#define INTERRUPT_VECTOR_NUMBER 0x100
|
||||
|
||||
//
|
||||
// Print primitives
|
||||
//
|
||||
//#define LEFT_JUSTIFY 0x01
|
||||
#define PREFIX_SIGN 0x02
|
||||
#define PREFIX_BLANK 0x04
|
||||
//#define COMMA_TYPE 0x08
|
||||
#define LONG_TYPE 0x10
|
||||
//#define PREFIX_ZERO 0x20
|
||||
#define OUTPUT_UNICODE 0x40
|
||||
//#define RADIX_HEX 0x80
|
||||
#define FORMAT_UNICODE 0x100
|
||||
#define PAD_TO_WIDTH 0x200
|
||||
#define ARGUMENT_UNICODE 0x400
|
||||
#define PRECISION 0x800
|
||||
#define ARGUMENT_REVERSED 0x1000
|
||||
|
||||
//
|
||||
// Function declarations
|
||||
//
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
InitializeCpu (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CpuFlushCpuDataCache (
|
||||
IN EFI_CPU_ARCH_PROTOCOL *This,
|
||||
IN EFI_PHYSICAL_ADDRESS Start,
|
||||
IN UINT64 Length,
|
||||
IN EFI_CPU_FLUSH_TYPE FlushType
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CpuEnableInterrupt (
|
||||
IN EFI_CPU_ARCH_PROTOCOL *This
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CpuDisableInterrupt (
|
||||
IN EFI_CPU_ARCH_PROTOCOL *This
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CpuGetInterruptState (
|
||||
IN EFI_CPU_ARCH_PROTOCOL *This,
|
||||
OUT BOOLEAN *State
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CpuInit (
|
||||
IN EFI_CPU_ARCH_PROTOCOL *This,
|
||||
IN EFI_CPU_INIT_TYPE InitType
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CpuRegisterInterruptHandler (
|
||||
IN EFI_CPU_ARCH_PROTOCOL *This,
|
||||
IN EFI_EXCEPTION_TYPE InterruptType,
|
||||
IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CpuGetTimerValue (
|
||||
IN EFI_CPU_ARCH_PROTOCOL *This,
|
||||
IN UINT32 TimerIndex,
|
||||
OUT UINT64 *TimerValue,
|
||||
OUT UINT64 *TimerPeriod OPTIONAL
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CpuSetMemoryAttributes(
|
||||
IN EFI_CPU_ARCH_PROTOCOL *This,
|
||||
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
||||
IN UINT64 Length,
|
||||
IN UINT64 Attributes
|
||||
);
|
||||
|
||||
VOID
|
||||
InstallInterruptHandler (
|
||||
UINTN Vector,
|
||||
VOID (*Handler)(VOID)
|
||||
);
|
||||
|
||||
VOID
|
||||
SystemExceptionHandler (
|
||||
VOID
|
||||
);
|
||||
|
||||
VOID
|
||||
SystemTimerHandler (
|
||||
VOID
|
||||
);
|
||||
|
||||
VOID
|
||||
InitDescriptor (
|
||||
VOID
|
||||
);
|
||||
|
||||
#endif
|
835
DuetPkg/CpuDxe/Ia32/CpuInterrupt.asm
Normal file
835
DuetPkg/CpuDxe/Ia32/CpuInterrupt.asm
Normal file
@ -0,0 +1,835 @@
|
||||
TITLE CpuInterrupt.asm:
|
||||
;------------------------------------------------------------------------------
|
||||
;*
|
||||
;* Copyright 2006, Intel Corporation
|
||||
;* All rights reserved. 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.
|
||||
;*
|
||||
;* CpuInterrupt.asm
|
||||
;*
|
||||
;* Abstract:
|
||||
;*
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
.686p
|
||||
.model flat, C
|
||||
|
||||
PUBLIC SystemTimerHandler
|
||||
PUBLIC SystemExceptionHandler
|
||||
EXTERNDEF mExceptionCodeSize:DWORD
|
||||
|
||||
.code
|
||||
.stack
|
||||
.MMX
|
||||
.XMM
|
||||
|
||||
EXTERN TimerHandler: NEAR
|
||||
EXTERN ExceptionHandler: NEAR
|
||||
EXTERN mTimerVector: DWORD
|
||||
|
||||
mExceptionCodeSize DD 9
|
||||
|
||||
InitDescriptor PROC C
|
||||
lea eax, [GDT_BASE] ; EAX=PHYSICAL address of gdt
|
||||
mov dword ptr [gdtr + 2],eax ; Put address of gdt into the gdtr
|
||||
lgdt fword ptr [gdtr]
|
||||
lea eax, [IDT_BASE] ; EAX=PHYSICAL address of idt
|
||||
mov dword ptr [idtr + 2],eax ; Put address of idt into the idtr
|
||||
lidt fword ptr [idtr]
|
||||
ret
|
||||
InitDescriptor ENDP
|
||||
|
||||
; VOID
|
||||
; InstallInterruptHandler (
|
||||
; UINTN Vector,
|
||||
; VOID (*Handler)(VOID)
|
||||
; )
|
||||
InstallInterruptHandler PROC C \
|
||||
Vector:DWORD, \
|
||||
Handler:DWORD
|
||||
|
||||
push edi
|
||||
pushfd ; save eflags
|
||||
cli ; turn off interrupts
|
||||
sub esp, 6 ; open some space on the stack
|
||||
mov edi, esp
|
||||
sidt es:[edi] ; get fword address of IDT
|
||||
mov edi, es:[edi+2] ; move offset of IDT into EDI
|
||||
add esp, 6 ; correct stack
|
||||
mov eax, Vector ; Get vector number
|
||||
shl eax, 3 ; multiply by 8 to get offset
|
||||
add edi, eax ; add to IDT base to get entry
|
||||
mov eax, Handler ; load new address into IDT entry
|
||||
mov word ptr es:[edi], ax ; write bits 15..0 of offset
|
||||
shr eax, 16 ; use ax to copy 31..16 to descriptors
|
||||
mov word ptr es:[edi+6], ax ; write bits 31..16 of offset
|
||||
popfd ; restore flags (possible enabling interrupts)
|
||||
pop edi
|
||||
ret
|
||||
|
||||
InstallInterruptHandler ENDP
|
||||
|
||||
JmpCommonIdtEntry macro
|
||||
; jmp commonIdtEntry - this must be hand coded to keep the assembler from
|
||||
; using a 8 bit reletive jump when the entries are
|
||||
; within 255 bytes of the common entry. This must
|
||||
; be done to maintain the consistency of the size
|
||||
; of entry points...
|
||||
db 0e9h ; jmp 16 bit reletive
|
||||
dd commonIdtEntry - $ - 4 ; offset to jump to
|
||||
endm
|
||||
|
||||
align 02h
|
||||
SystemExceptionHandler PROC
|
||||
INT0:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 0h
|
||||
JmpCommonIdtEntry
|
||||
; db 0e9h ; jmp 16 bit reletive
|
||||
; dd commonIdtEntry - $ - 4 ; offset to jump to
|
||||
|
||||
INT1:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 1h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT2:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 2h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT3:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 3h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT4:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 4h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT5:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 5h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT6:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 6h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT7:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 7h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT8:
|
||||
; Double fault causes an error code to be pushed so no phony push necessary
|
||||
nop
|
||||
nop
|
||||
push 8h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT9:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 9h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT10:
|
||||
; Invalid TSS causes an error code to be pushed so no phony push necessary
|
||||
nop
|
||||
nop
|
||||
push 10
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT11:
|
||||
; Segment Not Present causes an error code to be pushed so no phony push necessary
|
||||
nop
|
||||
nop
|
||||
push 11
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT12:
|
||||
; Stack fault causes an error code to be pushed so no phony push necessary
|
||||
nop
|
||||
nop
|
||||
push 12
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT13:
|
||||
; GP fault causes an error code to be pushed so no phony push necessary
|
||||
nop
|
||||
nop
|
||||
push 13
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT14:
|
||||
; Page fault causes an error code to be pushed so no phony push necessary
|
||||
nop
|
||||
nop
|
||||
push 14
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT15:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 15
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT16:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 16
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT17:
|
||||
; Alignment check causes an error code to be pushed so no phony push necessary
|
||||
nop
|
||||
nop
|
||||
push 17
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT18:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 18
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT19:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 19
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INTUnknown:
|
||||
REPEAT (32 - 20)
|
||||
push 0h ; push error code place holder on the stack
|
||||
; push xxh ; push vector number
|
||||
db 06ah
|
||||
db ( $ - INTUnknown - 3 ) / 9 + 20 ; vector number
|
||||
JmpCommonIdtEntry
|
||||
ENDM
|
||||
SystemExceptionHandler ENDP
|
||||
|
||||
SystemTimerHandler PROC
|
||||
push 0
|
||||
push mTimerVector
|
||||
JmpCommonIdtEntry
|
||||
SystemTimerHandler ENDP
|
||||
|
||||
commonIdtEntry:
|
||||
; +---------------------+
|
||||
; + EFlags +
|
||||
; +---------------------+
|
||||
; + CS +
|
||||
; +---------------------+
|
||||
; + EIP +
|
||||
; +---------------------+
|
||||
; + Error Code +
|
||||
; +---------------------+
|
||||
; + Vector Number +
|
||||
; +---------------------+
|
||||
; + EBP +
|
||||
; +---------------------+ <-- EBP
|
||||
|
||||
cli
|
||||
push ebp
|
||||
mov ebp, esp
|
||||
|
||||
;
|
||||
; Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32
|
||||
; is 16-byte aligned
|
||||
;
|
||||
and esp, 0fffffff0h
|
||||
sub esp, 12
|
||||
|
||||
;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
|
||||
push eax
|
||||
push ecx
|
||||
push edx
|
||||
push ebx
|
||||
lea ecx, [ebp + 6 * 4]
|
||||
push ecx ; ESP
|
||||
push dword ptr [ebp] ; EBP
|
||||
push esi
|
||||
push edi
|
||||
|
||||
;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;
|
||||
mov eax, ss
|
||||
push eax
|
||||
movzx eax, word ptr [ebp + 4 * 4]
|
||||
push eax
|
||||
mov eax, ds
|
||||
push eax
|
||||
mov eax, es
|
||||
push eax
|
||||
mov eax, fs
|
||||
push eax
|
||||
mov eax, gs
|
||||
push eax
|
||||
|
||||
;; UINT32 Eip;
|
||||
push dword ptr [ebp + 3 * 4]
|
||||
|
||||
;; UINT32 Gdtr[2], Idtr[2];
|
||||
sub esp, 8
|
||||
sidt fword ptr [esp]
|
||||
sub esp, 8
|
||||
sgdt fword ptr [esp]
|
||||
|
||||
;; UINT32 Ldtr, Tr;
|
||||
xor eax, eax
|
||||
str ax
|
||||
push eax
|
||||
sldt ax
|
||||
push eax
|
||||
|
||||
;; UINT32 EFlags;
|
||||
push dword ptr [ebp + 5 * 4]
|
||||
|
||||
;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
|
||||
mov eax, cr4
|
||||
or eax, 208h
|
||||
mov cr4, eax
|
||||
push eax
|
||||
mov eax, cr3
|
||||
push eax
|
||||
mov eax, cr2
|
||||
push eax
|
||||
xor eax, eax
|
||||
push eax
|
||||
mov eax, cr0
|
||||
push eax
|
||||
|
||||
;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
|
||||
mov eax, dr7
|
||||
push eax
|
||||
;; clear Dr7 while executing debugger itself
|
||||
xor eax, eax
|
||||
mov dr7, eax
|
||||
|
||||
mov eax, dr6
|
||||
push eax
|
||||
;; insure all status bits in dr6 are clear...
|
||||
xor eax, eax
|
||||
mov dr6, eax
|
||||
|
||||
mov eax, dr3
|
||||
push eax
|
||||
mov eax, dr2
|
||||
push eax
|
||||
mov eax, dr1
|
||||
push eax
|
||||
mov eax, dr0
|
||||
push eax
|
||||
|
||||
;; FX_SAVE_STATE_IA32 FxSaveState;
|
||||
sub esp, 512
|
||||
mov edi, esp
|
||||
db 0fh, 0aeh, 00000111y ;fxsave [edi]
|
||||
|
||||
;; UINT32 ExceptionData;
|
||||
push dword ptr [ebp + 2 * 4]
|
||||
|
||||
;; Prepare parameter and call
|
||||
mov edx, esp
|
||||
push edx
|
||||
mov eax, dword ptr [ebp + 1 * 4]
|
||||
push eax
|
||||
cmp eax, 32
|
||||
jb CallException
|
||||
call TimerHandler
|
||||
jmp ExceptionDone
|
||||
CallException:
|
||||
call ExceptionHandler
|
||||
ExceptionDone:
|
||||
add esp, 8
|
||||
|
||||
cli
|
||||
;; UINT32 ExceptionData;
|
||||
add esp, 4
|
||||
|
||||
;; FX_SAVE_STATE_IA32 FxSaveState;
|
||||
mov esi, esp
|
||||
db 0fh, 0aeh, 00001110y ; fxrstor [esi]
|
||||
add esp, 512
|
||||
|
||||
;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
|
||||
pop eax
|
||||
mov dr0, eax
|
||||
pop eax
|
||||
mov dr1, eax
|
||||
pop eax
|
||||
mov dr2, eax
|
||||
pop eax
|
||||
mov dr3, eax
|
||||
;; skip restore of dr6. We cleared dr6 during the context save.
|
||||
add esp, 4
|
||||
pop eax
|
||||
mov dr7, eax
|
||||
|
||||
;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
|
||||
pop eax
|
||||
mov cr0, eax
|
||||
add esp, 4 ; not for Cr1
|
||||
pop eax
|
||||
mov cr2, eax
|
||||
pop eax
|
||||
mov cr3, eax
|
||||
pop eax
|
||||
mov cr4, eax
|
||||
|
||||
;; UINT32 EFlags;
|
||||
pop dword ptr [ebp + 5 * 4]
|
||||
|
||||
;; UINT32 Ldtr, Tr;
|
||||
;; UINT32 Gdtr[2], Idtr[2];
|
||||
;; Best not let anyone mess with these particular registers...
|
||||
add esp, 24
|
||||
|
||||
;; UINT32 Eip;
|
||||
pop dword ptr [ebp + 3 * 4]
|
||||
|
||||
;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;
|
||||
;; NOTE - modified segment registers could hang the debugger... We
|
||||
;; could attempt to insulate ourselves against this possibility,
|
||||
;; but that poses risks as well.
|
||||
;;
|
||||
pop gs
|
||||
pop fs
|
||||
pop es
|
||||
pop ds
|
||||
pop dword ptr [ebp + 4 * 4]
|
||||
pop ss
|
||||
|
||||
;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
|
||||
pop edi
|
||||
pop esi
|
||||
add esp, 4 ; not for ebp
|
||||
add esp, 4 ; not for esp
|
||||
pop ebx
|
||||
pop edx
|
||||
pop ecx
|
||||
pop eax
|
||||
|
||||
mov esp, ebp
|
||||
pop ebp
|
||||
add esp, 8
|
||||
iretd
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; data
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
align 02h
|
||||
|
||||
gdtr dw GDT_END - GDT_BASE - 1 ; GDT limit
|
||||
dd 0 ; (GDT base gets set above)
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; global descriptor table (GDT)
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
align 02h
|
||||
|
||||
public GDT_BASE
|
||||
GDT_BASE:
|
||||
; null descriptor
|
||||
NULL_SEL equ $-GDT_BASE
|
||||
dw 0 ; limit 15:0
|
||||
dw 0 ; base 15:0
|
||||
db 0 ; base 23:16
|
||||
db 0 ; type
|
||||
db 0 ; limit 19:16, flags
|
||||
db 0 ; base 31:24
|
||||
|
||||
; linear data segment descriptor
|
||||
LINEAR_SEL equ $-GDT_BASE
|
||||
dw 0FFFFh ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 092h ; present, ring 0, data, expand-up, writable
|
||||
db 0CFh ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
; linear code segment descriptor
|
||||
LINEAR_CODE_SEL equ $-GDT_BASE
|
||||
dw 0FFFFh ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 09Ah ; present, ring 0, data, expand-up, writable
|
||||
db 0CFh ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
; system data segment descriptor
|
||||
SYS_DATA_SEL equ $-GDT_BASE
|
||||
dw 0FFFFh ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 092h ; present, ring 0, data, expand-up, writable
|
||||
db 0CFh ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
; system code segment descriptor
|
||||
SYS_CODE_SEL equ $-GDT_BASE
|
||||
dw 0FFFFh ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 09Ah ; present, ring 0, data, expand-up, writable
|
||||
db 0CFh ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
; spare segment descriptor
|
||||
SPARE3_SEL equ $-GDT_BASE
|
||||
dw 0 ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 0 ; present, ring 0, data, expand-up, writable
|
||||
db 0 ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
; spare segment descriptor
|
||||
SPARE4_SEL equ $-GDT_BASE
|
||||
dw 0 ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 0 ; present, ring 0, data, expand-up, writable
|
||||
db 0 ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
; spare segment descriptor
|
||||
SPARE5_SEL equ $-GDT_BASE
|
||||
dw 0 ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 0 ; present, ring 0, data, expand-up, writable
|
||||
db 0 ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
GDT_END:
|
||||
|
||||
align 02h
|
||||
|
||||
|
||||
|
||||
idtr dw IDT_END - IDT_BASE - 1 ; IDT limit
|
||||
dd 0 ; (IDT base gets set 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.
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;idt_tag db "IDT",0
|
||||
align 02h
|
||||
|
||||
public IDT_BASE
|
||||
IDT_BASE:
|
||||
; divide by zero (INT 0)
|
||||
DIV_ZERO_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; debug exception (INT 1)
|
||||
DEBUG_EXCEPT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; NMI (INT 2)
|
||||
NMI_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; soft breakpoint (INT 3)
|
||||
BREAKPOINT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; overflow (INT 4)
|
||||
OVERFLOW_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; bounds check (INT 5)
|
||||
BOUNDS_CHECK_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; invalid opcode (INT 6)
|
||||
INVALID_OPCODE_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; device not available (INT 7)
|
||||
DEV_NOT_AVAIL_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; double fault (INT 8)
|
||||
DOUBLE_FAULT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; Coprocessor segment overrun - reserved (INT 9)
|
||||
RSVD_INTR_SEL1 equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; invalid TSS (INT 0ah)
|
||||
INVALID_TSS_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; segment not present (INT 0bh)
|
||||
SEG_NOT_PRESENT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; stack fault (INT 0ch)
|
||||
STACK_FAULT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; general protection (INT 0dh)
|
||||
GP_FAULT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; page fault (INT 0eh)
|
||||
PAGE_FAULT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; Intel reserved - do not use (INT 0fh)
|
||||
RSVD_INTR_SEL2 equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; floating point error (INT 10h)
|
||||
FLT_POINT_ERR_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; alignment check (INT 11h)
|
||||
ALIGNMENT_CHECK_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; machine check (INT 12h)
|
||||
MACHINE_CHECK_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; SIMD floating-point exception (INT 13h)
|
||||
SIMD_EXCEPTION_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
REPEAT (32 - 20)
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
ENDM
|
||||
|
||||
; 72 unspecified descriptors
|
||||
db (72 * 8) dup(0)
|
||||
|
||||
; IRQ 0 (System timer) - (INT 68h)
|
||||
IRQ0_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 1 (8042 Keyboard controller) - (INT 69h)
|
||||
IRQ1_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; Reserved - IRQ 2 redirect (IRQ 2) - DO NOT USE!!! - (INT 6ah)
|
||||
IRQ2_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 3 (COM 2) - (INT 6bh)
|
||||
IRQ3_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 4 (COM 1) - (INT 6ch)
|
||||
IRQ4_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 5 (LPT 2) - (INT 6dh)
|
||||
IRQ5_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 6 (Floppy controller) - (INT 6eh)
|
||||
IRQ6_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 7 (LPT 1) - (INT 6fh)
|
||||
IRQ7_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 8 (RTC Alarm) - (INT 70h)
|
||||
IRQ8_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 9 - (INT 71h)
|
||||
IRQ9_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 10 - (INT 72h)
|
||||
IRQ10_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 11 - (INT 73h)
|
||||
IRQ11_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 12 (PS/2 mouse) - (INT 74h)
|
||||
IRQ12_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 13 (Floating point error) - (INT 75h)
|
||||
IRQ13_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 14 (Secondary IDE) - (INT 76h)
|
||||
IRQ14_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
; IRQ 15 (Primary IDE) - (INT 77h)
|
||||
IRQ15_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
|
||||
db (1 * 8) dup(0)
|
||||
|
||||
IDT_END:
|
||||
|
||||
END
|
949
DuetPkg/CpuDxe/x64/CpuInterrupt.asm
Normal file
949
DuetPkg/CpuDxe/x64/CpuInterrupt.asm
Normal file
@ -0,0 +1,949 @@
|
||||
TITLE CpuInterrupt.asm:
|
||||
;------------------------------------------------------------------------------
|
||||
;*
|
||||
;* Copyright 2006, Intel Corporation
|
||||
;* All rights reserved. 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.
|
||||
;*
|
||||
;* CpuInterrupt.asm
|
||||
;*
|
||||
;* Abstract:
|
||||
;*
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
EXTERNDEF mExceptionCodeSize:DWORD
|
||||
|
||||
.code
|
||||
|
||||
EXTERN TimerHandler: FAR
|
||||
EXTERN ExceptionHandler: NEAR
|
||||
EXTERN mTimerVector: QWORD
|
||||
|
||||
mExceptionCodeSize DD 9
|
||||
|
||||
InitDescriptor PROC
|
||||
lea rax, [GDT_BASE] ; RAX=PHYSICAL address of gdt
|
||||
mov qword ptr [gdtr + 2], rax ; Put address of gdt into the gdtr
|
||||
lgdt fword ptr [gdtr]
|
||||
mov rax, 18h
|
||||
mov gs, rax
|
||||
mov fs, rax
|
||||
lea rax, [IDT_BASE] ; RAX=PHYSICAL address of idt
|
||||
mov qword ptr [idtr + 2], rax ; Put address of idt into the idtr
|
||||
lidt fword ptr [idtr]
|
||||
ret
|
||||
InitDescriptor ENDP
|
||||
|
||||
; VOID
|
||||
; InstallInterruptHandler (
|
||||
; UINTN Vector, // rcx
|
||||
; void (*Handler)(void) // rdx
|
||||
; )
|
||||
InstallInterruptHandler PROC
|
||||
push rbx
|
||||
pushfq ; save eflags
|
||||
cli ; turn off interrupts
|
||||
sub rsp, 10h ; open some space on the stack
|
||||
mov rbx, rsp
|
||||
sidt [rbx] ; get fword address of IDT
|
||||
mov rbx, [rbx+2] ; move offset of IDT into RBX
|
||||
add rsp, 10h ; correct stack
|
||||
mov rax, rcx ; Get vector number
|
||||
shl rax, 4 ; multiply by 16 to get offset
|
||||
add rbx, rax ; add to IDT base to get entry
|
||||
mov rax, rdx ; load new address into IDT entry
|
||||
mov word ptr [rbx], ax ; write bits 15..0 of offset
|
||||
shr rax, 16 ; use ax to copy 31..16 to descriptors
|
||||
mov word ptr [rbx+6], ax ; write bits 31..16 of offset
|
||||
shr rax, 16 ; use eax to copy 63..32 to descriptors
|
||||
mov dword ptr [rbx+8], eax ; write bits 63..32 of offset
|
||||
popfq ; restore flags (possible enabling interrupts)
|
||||
pop rbx
|
||||
ret
|
||||
|
||||
InstallInterruptHandler ENDP
|
||||
|
||||
JmpCommonIdtEntry macro
|
||||
; jmp commonIdtEntry - this must be hand coded to keep the assembler from
|
||||
; using a 8 bit reletive jump when the entries are
|
||||
; within 255 bytes of the common entry. This must
|
||||
; be done to maintain the consistency of the size
|
||||
; of entry points...
|
||||
db 0e9h ; jmp 16 bit reletive
|
||||
dd commonIdtEntry - $ - 4 ; offset to jump to
|
||||
endm
|
||||
|
||||
align 02h
|
||||
SystemExceptionHandler PROC
|
||||
INT0:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 0h
|
||||
JmpCommonIdtEntry
|
||||
; db 0e9h ; jmp 16 bit reletive
|
||||
; dd commonIdtEntry - $ - 4 ; offset to jump to
|
||||
|
||||
INT1:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 1h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT2:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 2h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT3:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 3h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT4:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 4h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT5:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 5h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT6:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 6h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT7:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 7h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT8:
|
||||
; Double fault causes an error code to be pushed so no phony push necessary
|
||||
nop
|
||||
nop
|
||||
push 8h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT9:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 9h
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT10:
|
||||
; Invalid TSS causes an error code to be pushed so no phony push necessary
|
||||
nop
|
||||
nop
|
||||
push 10
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT11:
|
||||
; Segment Not Present causes an error code to be pushed so no phony push necessary
|
||||
nop
|
||||
nop
|
||||
push 11
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT12:
|
||||
; Stack fault causes an error code to be pushed so no phony push necessary
|
||||
nop
|
||||
nop
|
||||
push 12
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT13:
|
||||
; GP fault causes an error code to be pushed so no phony push necessary
|
||||
nop
|
||||
nop
|
||||
push 13
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT14:
|
||||
; Page fault causes an error code to be pushed so no phony push necessary
|
||||
nop
|
||||
nop
|
||||
push 14
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT15:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 15
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT16:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 16
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT17:
|
||||
; Alignment check causes an error code to be pushed so no phony push necessary
|
||||
nop
|
||||
nop
|
||||
push 17
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT18:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 18
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INT19:
|
||||
push 0h ; push error code place holder on the stack
|
||||
push 19
|
||||
JmpCommonIdtEntry
|
||||
|
||||
INTUnknown:
|
||||
REPEAT (32 - 20)
|
||||
push 0h ; push error code place holder on the stack
|
||||
; push xxh ; push vector number
|
||||
db 06ah
|
||||
db ( $ - INTUnknown - 3 ) / 9 + 20 ; vector number
|
||||
JmpCommonIdtEntry
|
||||
ENDM
|
||||
SystemExceptionHandler ENDP
|
||||
|
||||
SystemTimerHandler PROC
|
||||
push 0
|
||||
push mTimerVector
|
||||
JmpCommonIdtEntry
|
||||
SystemTimerHandler ENDP
|
||||
|
||||
commonIdtEntry:
|
||||
; +---------------------+ <-- 16-byte aligned ensured by processor
|
||||
; + Old SS +
|
||||
; +---------------------+
|
||||
; + Old RSP +
|
||||
; +---------------------+
|
||||
; + RFlags +
|
||||
; +---------------------+
|
||||
; + CS +
|
||||
; +---------------------+
|
||||
; + RIP +
|
||||
; +---------------------+
|
||||
; + Error Code +
|
||||
; +---------------------+
|
||||
; + Vector Number +
|
||||
; +---------------------+
|
||||
; + RBP +
|
||||
; +---------------------+ <-- RBP, 16-byte aligned
|
||||
|
||||
cli
|
||||
push rbp
|
||||
mov rbp, rsp
|
||||
|
||||
;
|
||||
; Since here the stack pointer is 16-byte aligned, so
|
||||
; EFI_FX_SAVE_STATE_X64 of EFI_SYSTEM_CONTEXT_x64
|
||||
; is 16-byte aligned
|
||||
;
|
||||
|
||||
;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;
|
||||
;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;
|
||||
push r15
|
||||
push r14
|
||||
push r13
|
||||
push r12
|
||||
push r11
|
||||
push r10
|
||||
push r9
|
||||
push r8
|
||||
push rax
|
||||
push rcx
|
||||
push rdx
|
||||
push rbx
|
||||
push qword ptr [rbp + 6 * 8] ; RSP
|
||||
push qword ptr [rbp] ; RBP
|
||||
push rsi
|
||||
push rdi
|
||||
|
||||
;; UINT64 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero
|
||||
movzx rax, word ptr [rbp + 7 * 8]
|
||||
push rax ; for ss
|
||||
movzx rax, word ptr [rbp + 4 * 8]
|
||||
push rax ; for cs
|
||||
mov rax, ds
|
||||
push rax
|
||||
mov rax, es
|
||||
push rax
|
||||
mov rax, fs
|
||||
push rax
|
||||
mov rax, gs
|
||||
push rax
|
||||
|
||||
;; UINT64 Rip;
|
||||
push qword ptr [rbp + 3 * 8]
|
||||
|
||||
;; UINT64 Gdtr[2], Idtr[2];
|
||||
sub rsp, 16
|
||||
sidt fword ptr [rsp]
|
||||
sub rsp, 16
|
||||
sgdt fword ptr [rsp]
|
||||
|
||||
;; UINT64 Ldtr, Tr;
|
||||
xor rax, rax
|
||||
str ax
|
||||
push rax
|
||||
sldt ax
|
||||
push rax
|
||||
|
||||
;; UINT64 RFlags;
|
||||
push qword ptr [rbp + 5 * 8]
|
||||
|
||||
;; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;
|
||||
mov rax, cr8
|
||||
push rax
|
||||
mov rax, cr4
|
||||
or rax, 208h
|
||||
mov cr4, rax
|
||||
push rax
|
||||
mov rax, cr3
|
||||
push rax
|
||||
mov rax, cr2
|
||||
push rax
|
||||
xor rax, rax
|
||||
push rax
|
||||
mov rax, cr0
|
||||
push rax
|
||||
|
||||
;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
|
||||
mov rax, dr7
|
||||
push rax
|
||||
;; clear Dr7 while executing debugger itself
|
||||
xor rax, rax
|
||||
mov dr7, rax
|
||||
|
||||
mov rax, dr6
|
||||
push rax
|
||||
;; insure all status bits in dr6 are clear...
|
||||
xor rax, rax
|
||||
mov dr6, rax
|
||||
|
||||
mov rax, dr3
|
||||
push rax
|
||||
mov rax, dr2
|
||||
push rax
|
||||
mov rax, dr1
|
||||
push rax
|
||||
mov rax, dr0
|
||||
push rax
|
||||
|
||||
;; FX_SAVE_STATE_X64 FxSaveState;
|
||||
|
||||
sub rsp, 512
|
||||
mov rdi, rsp
|
||||
db 0fh, 0aeh, 00000111y ;fxsave [rdi]
|
||||
|
||||
;; UINT32 ExceptionData;
|
||||
push qword ptr [rbp + 2 * 8]
|
||||
|
||||
;; call into exception handler
|
||||
;; Prepare parameter and call
|
||||
mov rcx, qword ptr [rbp + 1 * 8]
|
||||
mov rdx, rsp
|
||||
;
|
||||
; Per X64 calling convention, allocate maximum parameter stack space
|
||||
; and make sure RSP is 16-byte aligned
|
||||
;
|
||||
sub rsp, 4 * 8 + 8
|
||||
cmp rcx, 32
|
||||
jb CallException
|
||||
call TimerHandler
|
||||
jmp ExceptionDone
|
||||
CallException:
|
||||
call ExceptionHandler
|
||||
ExceptionDone:
|
||||
add rsp, 4 * 8 + 8
|
||||
|
||||
cli
|
||||
;; UINT64 ExceptionData;
|
||||
add rsp, 8
|
||||
|
||||
;; FX_SAVE_STATE_X64 FxSaveState;
|
||||
|
||||
mov rsi, rsp
|
||||
db 0fh, 0aeh, 00001110y ; fxrstor [rsi]
|
||||
add rsp, 512
|
||||
|
||||
;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
|
||||
pop rax
|
||||
mov dr0, rax
|
||||
pop rax
|
||||
mov dr1, rax
|
||||
pop rax
|
||||
mov dr2, rax
|
||||
pop rax
|
||||
mov dr3, rax
|
||||
;; skip restore of dr6. We cleared dr6 during the context save.
|
||||
add rsp, 8
|
||||
pop rax
|
||||
mov dr7, rax
|
||||
|
||||
;; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;
|
||||
pop rax
|
||||
mov cr0, rax
|
||||
add rsp, 8 ; not for Cr1
|
||||
pop rax
|
||||
mov cr2, rax
|
||||
pop rax
|
||||
mov cr3, rax
|
||||
pop rax
|
||||
mov cr4, rax
|
||||
pop rax
|
||||
mov cr8, rax
|
||||
|
||||
;; UINT64 RFlags;
|
||||
pop qword ptr [rbp + 5 * 8]
|
||||
|
||||
;; UINT64 Ldtr, Tr;
|
||||
;; UINT64 Gdtr[2], Idtr[2];
|
||||
;; Best not let anyone mess with these particular registers...
|
||||
add rsp, 48
|
||||
|
||||
;; UINT64 Rip;
|
||||
pop qword ptr [rbp + 3 * 8]
|
||||
|
||||
;; UINT64 Gs, Fs, Es, Ds, Cs, Ss;
|
||||
pop rax
|
||||
; mov gs, rax ; not for gs
|
||||
pop rax
|
||||
; mov fs, rax ; not for fs
|
||||
; (X64 will not use fs and gs, so we do not restore it)
|
||||
pop rax
|
||||
mov es, rax
|
||||
pop rax
|
||||
mov ds, rax
|
||||
pop qword ptr [rbp + 4 * 8] ; for cs
|
||||
pop qword ptr [rbp + 7 * 8] ; for ss
|
||||
|
||||
;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;
|
||||
;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;
|
||||
pop rdi
|
||||
pop rsi
|
||||
add rsp, 8 ; not for rbp
|
||||
pop qword ptr [rbp + 6 * 8] ; for rsp
|
||||
pop rbx
|
||||
pop rdx
|
||||
pop rcx
|
||||
pop rax
|
||||
pop r8
|
||||
pop r9
|
||||
pop r10
|
||||
pop r11
|
||||
pop r12
|
||||
pop r13
|
||||
pop r14
|
||||
pop r15
|
||||
|
||||
mov rsp, rbp
|
||||
pop rbp
|
||||
add rsp, 16
|
||||
iretq
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; data
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
align 010h
|
||||
|
||||
gdtr dw GDT_END - GDT_BASE - 1 ; GDT limit
|
||||
dq 0 ; (GDT base gets set above)
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; global descriptor table (GDT)
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
align 010h
|
||||
|
||||
public GDT_BASE
|
||||
GDT_BASE:
|
||||
; null descriptor
|
||||
NULL_SEL equ $-GDT_BASE ; Selector [0x0]
|
||||
dw 0 ; limit 15:0
|
||||
dw 0 ; base 15:0
|
||||
db 0 ; base 23:16
|
||||
db 0 ; type
|
||||
db 0 ; limit 19:16, flags
|
||||
db 0 ; base 31:24
|
||||
|
||||
; linear data segment descriptor
|
||||
LINEAR_SEL equ $-GDT_BASE ; Selector [0x8]
|
||||
dw 0FFFFh ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 092h ; present, ring 0, data, expand-up, writable
|
||||
db 0CFh ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
; linear code segment descriptor
|
||||
LINEAR_CODE_SEL equ $-GDT_BASE ; Selector [0x10]
|
||||
dw 0FFFFh ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 09Ah ; present, ring 0, data, expand-up, writable
|
||||
db 0CFh ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
; system data segment descriptor
|
||||
SYS_DATA_SEL equ $-GDT_BASE ; Selector [0x18]
|
||||
dw 0FFFFh ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 092h ; present, ring 0, data, expand-up, writable
|
||||
db 0CFh ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
; system code segment descriptor
|
||||
SYS_CODE_SEL equ $-GDT_BASE ; Selector [0x20]
|
||||
dw 0FFFFh ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 09Ah ; present, ring 0, data, expand-up, writable
|
||||
db 0CFh ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
; spare segment descriptor
|
||||
SPARE3_SEL equ $-GDT_BASE ; Selector [0x28]
|
||||
dw 0 ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 0 ; present, ring 0, data, expand-up, writable
|
||||
db 0 ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
;
|
||||
; system data segment descriptor
|
||||
;
|
||||
SYS_DATA64_SEL equ $-GDT_BASE ; Selector [0x30]
|
||||
dw 0FFFFh ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 092h ; P | DPL [1..2] | 1 | 1 | C | R | A
|
||||
db 0CFh ; G | D | L | AVL | Segment [19..16]
|
||||
db 0
|
||||
|
||||
;
|
||||
; system code segment descriptor
|
||||
;
|
||||
SYS_CODE64_SEL equ $-GDT_BASE ; Selector [0x38]
|
||||
dw 0FFFFh ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 09Ah ; P | DPL [1..2] | 1 | 1 | C | R | A
|
||||
db 0AFh ; G | D | L | AVL | Segment [19..16]
|
||||
db 0
|
||||
|
||||
; spare segment descriptor
|
||||
SPARE4_SEL equ $-GDT_BASE ; Selector [0x40]
|
||||
dw 0 ; limit 0xFFFFF
|
||||
dw 0 ; base 0
|
||||
db 0
|
||||
db 0 ; present, ring 0, data, expand-up, writable
|
||||
db 0 ; page-granular, 32-bit
|
||||
db 0
|
||||
|
||||
GDT_END:
|
||||
|
||||
align 02h
|
||||
|
||||
|
||||
|
||||
idtr dw IDT_END - IDT_BASE - 1 ; IDT limit
|
||||
dq 0 ; (IDT base gets set 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.
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;idt_tag db "IDT",0
|
||||
align 02h
|
||||
|
||||
public IDT_BASE
|
||||
IDT_BASE:
|
||||
; divide by zero (INT 0)
|
||||
DIV_ZERO_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE64_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
dd 0 ; offset 63:32
|
||||
dd 0 ; 0 for reserved
|
||||
|
||||
; debug exception (INT 1)
|
||||
DEBUG_EXCEPT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE64_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
dd 0 ; offset 63:32
|
||||
dd 0 ; 0 for reserved
|
||||
|
||||
; NMI (INT 2)
|
||||
NMI_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE64_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
dd 0 ; offset 63:32
|
||||
dd 0 ; 0 for reserved
|
||||
|
||||
; soft breakpoint (INT 3)
|
||||
BREAKPOINT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE64_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
dd 0 ; offset 63:32
|
||||
dd 0 ; 0 for reserved
|
||||
|
||||
; overflow (INT 4)
|
||||
OVERFLOW_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE64_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
dd 0 ; offset 63:32
|
||||
dd 0 ; 0 for reserved
|
||||
|
||||
; bounds check (INT 5)
|
||||
BOUNDS_CHECK_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE64_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
dd 0 ; offset 63:32
|
||||
dd 0 ; 0 for reserved
|
||||
|
||||
; invalid opcode (INT 6)
|
||||
INVALID_OPCODE_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE64_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
dd 0 ; offset 63:32
|
||||
dd 0 ; 0 for reserved
|
||||
|
||||
; device not available (INT 7)
|
||||
DEV_NOT_AVAIL_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE64_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
dd 0 ; offset 63:32
|
||||
dd 0 ; 0 for reserved
|
||||
|
||||
; double fault (INT 8)
|
||||
DOUBLE_FAULT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE64_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
dd 0 ; offset 63:32
|
||||
dd 0 ; 0 for reserved
|
||||
|
||||
; Coprocessor segment overrun - reserved (INT 9)
|
||||
RSVD_INTR_SEL1 equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE64_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
dd 0 ; offset 63:32
|
||||
dd 0 ; 0 for reserved
|
||||
|
||||
; invalid TSS (INT 0ah)
|
||||
INVALID_TSS_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE64_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
dd 0 ; offset 63:32
|
||||
dd 0 ; 0 for reserved
|
||||
|
||||
; segment not present (INT 0bh)
|
||||
SEG_NOT_PRESENT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE64_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
dd 0 ; offset 63:32
|
||||
dd 0 ; 0 for reserved
|
||||
|
||||
; stack fault (INT 0ch)
|
||||
STACK_FAULT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE64_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
dd 0 ; offset 63:32
|
||||
dd 0 ; 0 for reserved
|
||||
|
||||
; general protection (INT 0dh)
|
||||
GP_FAULT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE64_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
dd 0 ; offset 63:32
|
||||
dd 0 ; 0 for reserved
|
||||
|
||||
; page fault (INT 0eh)
|
||||
PAGE_FAULT_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE64_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
dd 0 ; offset 63:32
|
||||
dd 0 ; 0 for reserved
|
||||
|
||||
; Intel reserved - do not use (INT 0fh)
|
||||
RSVD_INTR_SEL2 equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE64_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
dd 0 ; offset 63:32
|
||||
dd 0 ; 0 for reserved
|
||||
|
||||
; floating point error (INT 10h)
|
||||
FLT_POINT_ERR_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE64_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
dd 0 ; offset 63:32
|
||||
dd 0 ; 0 for reserved
|
||||
|
||||
; alignment check (INT 11h)
|
||||
ALIGNMENT_CHECK_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE64_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
dd 0 ; offset 63:32
|
||||
dd 0 ; 0 for reserved
|
||||
|
||||
; machine check (INT 12h)
|
||||
MACHINE_CHECK_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE64_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
dd 0 ; offset 63:32
|
||||
dd 0 ; 0 for reserved
|
||||
|
||||
; SIMD floating-point exception (INT 13h)
|
||||
SIMD_EXCEPTION_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE64_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
dd 0 ; offset 63:32
|
||||
dd 0 ; 0 for reserved
|
||||
|
||||
REPEAT (32 - 20)
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE64_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
dd 0 ; offset 63:32
|
||||
dd 0 ; 0 for reserved
|
||||
ENDM
|
||||
|
||||
; 72 unspecified descriptors
|
||||
db (72 * 16) dup(0)
|
||||
|
||||
; IRQ 0 (System timer) - (INT 68h)
|
||||
IRQ0_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE64_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
dd 0 ; offset 63:32
|
||||
dd 0 ; 0 for reserved
|
||||
|
||||
; IRQ 1 (8042 Keyboard controller) - (INT 69h)
|
||||
IRQ1_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE64_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
dd 0 ; offset 63:32
|
||||
dd 0 ; 0 for reserved
|
||||
|
||||
; Reserved - IRQ 2 redirect (IRQ 2) - DO NOT USE!!! - (INT 6ah)
|
||||
IRQ2_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE64_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
dd 0 ; offset 63:32
|
||||
dd 0 ; 0 for reserved
|
||||
|
||||
; IRQ 3 (COM 2) - (INT 6bh)
|
||||
IRQ3_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE64_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
dd 0 ; offset 63:32
|
||||
dd 0 ; 0 for reserved
|
||||
|
||||
; IRQ 4 (COM 1) - (INT 6ch)
|
||||
IRQ4_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE64_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
dd 0 ; offset 63:32
|
||||
dd 0 ; 0 for reserved
|
||||
|
||||
; IRQ 5 (LPT 2) - (INT 6dh)
|
||||
IRQ5_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE64_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
dd 0 ; offset 63:32
|
||||
dd 0 ; 0 for reserved
|
||||
|
||||
; IRQ 6 (Floppy controller) - (INT 6eh)
|
||||
IRQ6_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE64_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
dd 0 ; offset 63:32
|
||||
dd 0 ; 0 for reserved
|
||||
|
||||
; IRQ 7 (LPT 1) - (INT 6fh)
|
||||
IRQ7_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE64_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
dd 0 ; offset 63:32
|
||||
dd 0 ; 0 for reserved
|
||||
|
||||
; IRQ 8 (RTC Alarm) - (INT 70h)
|
||||
IRQ8_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE64_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
dd 0 ; offset 63:32
|
||||
dd 0 ; 0 for reserved
|
||||
|
||||
; IRQ 9 - (INT 71h)
|
||||
IRQ9_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE64_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
dd 0 ; offset 63:32
|
||||
dd 0 ; 0 for reserved
|
||||
|
||||
; IRQ 10 - (INT 72h)
|
||||
IRQ10_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE64_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
dd 0 ; offset 63:32
|
||||
dd 0 ; 0 for reserved
|
||||
|
||||
; IRQ 11 - (INT 73h)
|
||||
IRQ11_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE64_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
dd 0 ; offset 63:32
|
||||
dd 0 ; 0 for reserved
|
||||
|
||||
; IRQ 12 (PS/2 mouse) - (INT 74h)
|
||||
IRQ12_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE64_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
dd 0 ; offset 63:32
|
||||
dd 0 ; 0 for reserved
|
||||
|
||||
; IRQ 13 (Floating point error) - (INT 75h)
|
||||
IRQ13_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE64_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
dd 0 ; offset 63:32
|
||||
dd 0 ; 0 for reserved
|
||||
|
||||
; IRQ 14 (Secondary IDE) - (INT 76h)
|
||||
IRQ14_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE64_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
dd 0 ; offset 63:32
|
||||
dd 0 ; 0 for reserved
|
||||
|
||||
; IRQ 15 (Primary IDE) - (INT 77h)
|
||||
IRQ15_SEL equ $-IDT_BASE
|
||||
dw 0 ; offset 15:0
|
||||
dw SYS_CODE64_SEL ; selector 15:0
|
||||
db 0 ; 0 for interrupt gate
|
||||
db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present
|
||||
dw 0 ; offset 31:16
|
||||
dd 0 ; offset 63:32
|
||||
dd 0 ; 0 for reserved
|
||||
|
||||
db (1 * 16) dup(0)
|
||||
|
||||
IDT_END:
|
||||
|
||||
align 02h
|
||||
|
||||
END
|
533
DuetPkg/CpuIoDxe/CpuIo.c
Normal file
533
DuetPkg/CpuIoDxe/CpuIo.c
Normal file
@ -0,0 +1,533 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2004 - 2007, Intel Corporation
|
||||
All rights reserved. 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.
|
||||
|
||||
Module Name:
|
||||
CpuIo.c
|
||||
|
||||
Abstract:
|
||||
|
||||
This is the code that publishes the CPU I/O Protocol.
|
||||
The intent herein is to have a single I/O service that can load
|
||||
as early as possible, extend into runtime, and be layered upon by
|
||||
the implementations of architectural protocols and the PCI Root
|
||||
Bridge I/O Protocol.
|
||||
|
||||
--*/
|
||||
|
||||
#include "CpuIo.h"
|
||||
#include "CpuIoAccess.h"
|
||||
|
||||
#define IA32_MAX_IO_ADDRESS 0xFFFF
|
||||
|
||||
EFI_CPU_IO_PROTOCOL mCpuIo = {
|
||||
{
|
||||
CpuMemoryServiceRead,
|
||||
CpuMemoryServiceWrite
|
||||
},
|
||||
{
|
||||
CpuIoServiceRead,
|
||||
CpuIoServiceWrite
|
||||
}
|
||||
};
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
CpuIoMemRW (
|
||||
IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
|
||||
IN UINTN Count,
|
||||
IN BOOLEAN DestinationStrideFlag,
|
||||
OUT PTR Destination,
|
||||
IN BOOLEAN SourceStrideFlag,
|
||||
IN PTR Source
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Private service to perform memory mapped I/O read/write
|
||||
|
||||
Arguments:
|
||||
|
||||
Width - Width of the memory mapped I/O operation
|
||||
Count - Count of the number of accesses to perform
|
||||
DestinationStrideFlag - Boolean flag indicates if the destination is to be incremented
|
||||
Destination - Destination of the memory mapped I/O operation
|
||||
SourceStrideFlag - Boolean flag indicates if the source is to be incremented
|
||||
Source - Source of the memory mapped I/O operation
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - Successful operation
|
||||
EFI_INVALID_PARAMETER - Width is invalid
|
||||
|
||||
--*/
|
||||
{
|
||||
UINTN Stride;
|
||||
UINTN DestinationStride;
|
||||
UINTN SourceStride;
|
||||
|
||||
Width = Width & 0x03;
|
||||
Stride = (UINTN)1 << Width;
|
||||
DestinationStride = DestinationStrideFlag ? Stride : 0;
|
||||
SourceStride = SourceStrideFlag ? Stride : 0;
|
||||
|
||||
//
|
||||
// Loop for each iteration and move the data
|
||||
//
|
||||
switch (Width) {
|
||||
case EfiCpuIoWidthUint8:
|
||||
for (; Count > 0; Count--, Destination.buf += DestinationStride, Source.buf += SourceStride) {
|
||||
MemoryFence();
|
||||
*Destination.ui8 = *Source.ui8;
|
||||
MemoryFence();
|
||||
}
|
||||
break;
|
||||
|
||||
case EfiCpuIoWidthUint16:
|
||||
for (; Count > 0; Count--, Destination.buf += DestinationStride, Source.buf += SourceStride) {
|
||||
MemoryFence ();
|
||||
*Destination.ui16 = *Source.ui16;
|
||||
MemoryFence ();
|
||||
}
|
||||
break;
|
||||
|
||||
case EfiCpuIoWidthUint32:
|
||||
for (; Count > 0; Count--, Destination.buf += DestinationStride, Source.buf += SourceStride) {
|
||||
MemoryFence ();
|
||||
*Destination.ui32 = *Source.ui32;
|
||||
MemoryFence ();
|
||||
}
|
||||
break;
|
||||
|
||||
case EfiCpuIoWidthUint64:
|
||||
for (; Count > 0; Count--, Destination.buf += DestinationStride, Source.buf += SourceStride) {
|
||||
MemoryFence ();
|
||||
*Destination.ui64 = *Source.ui64;
|
||||
MemoryFence ();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CpuMemoryServiceRead (
|
||||
IN EFI_CPU_IO_PROTOCOL *This,
|
||||
IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
|
||||
IN UINT64 Address,
|
||||
IN UINTN Count,
|
||||
OUT VOID *Buffer
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Perform the memory mapped I/O read service
|
||||
|
||||
Arguments:
|
||||
|
||||
This - Pointer to an instance of the CPU I/O Protocol
|
||||
Width - Width of the memory mapped I/O operation
|
||||
Address - Base address of the memory mapped I/O operation
|
||||
Count - Count of the number of accesses to perform
|
||||
Buffer - Pointer to the destination buffer to store the results
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - The data was read.
|
||||
EFI_INVALID_PARAMETER - Width is invalid.
|
||||
EFI_INVALID_PARAMETER - Buffer is NULL.
|
||||
EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.
|
||||
EFI_UNSUPPORTED - The address range specified by Address, Width,
|
||||
and Count is not valid.
|
||||
|
||||
--*/
|
||||
{
|
||||
PTR Source;
|
||||
PTR Destination;
|
||||
EFI_STATUS Status;
|
||||
|
||||
Status = CpuIoCheckParameter (Width, Address, Count, Buffer, EFI_MAX_ADDRESS);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
Destination.buf = Buffer;
|
||||
Source.buf = (VOID *) (UINTN) Address;
|
||||
|
||||
if (Width >= EfiCpuIoWidthUint8 && Width <= EfiCpuIoWidthUint64) {
|
||||
return CpuIoMemRW (Width, Count, TRUE, Destination, TRUE, Source);
|
||||
}
|
||||
|
||||
if (Width >= EfiCpuIoWidthFifoUint8 && Width <= EfiCpuIoWidthFifoUint64) {
|
||||
return CpuIoMemRW (Width, Count, TRUE, Destination, FALSE, Source);
|
||||
}
|
||||
|
||||
if (Width >= EfiCpuIoWidthFillUint8 && Width <= EfiCpuIoWidthFillUint64) {
|
||||
return CpuIoMemRW (Width, Count, FALSE, Destination, TRUE, Source);
|
||||
}
|
||||
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CpuMemoryServiceWrite (
|
||||
IN EFI_CPU_IO_PROTOCOL *This,
|
||||
IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
|
||||
IN UINT64 Address,
|
||||
IN UINTN Count,
|
||||
IN VOID *Buffer
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Perform the memory mapped I/O write service
|
||||
|
||||
Arguments:
|
||||
|
||||
This - Pointer to an instance of the CPU I/O Protocol
|
||||
Width - Width of the memory mapped I/O operation
|
||||
Address - Base address of the memory mapped I/O operation
|
||||
Count - Count of the number of accesses to perform
|
||||
Buffer - Pointer to the source buffer from which to write data
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - The data was written.
|
||||
EFI_INVALID_PARAMETER - Width is invalid.
|
||||
EFI_INVALID_PARAMETER - Buffer is NULL.
|
||||
EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.
|
||||
EFI_UNSUPPORTED - The address range specified by Address, Width,
|
||||
and Count is not valid.
|
||||
|
||||
--*/
|
||||
{
|
||||
PTR Source;
|
||||
PTR Destination;
|
||||
EFI_STATUS Status;
|
||||
|
||||
Status = CpuIoCheckParameter (Width, Address, Count, Buffer, EFI_MAX_ADDRESS);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
Destination.buf = (VOID *) (UINTN) Address;
|
||||
Source.buf = Buffer;
|
||||
|
||||
if (Width >= EfiCpuIoWidthUint8 && Width <= EfiCpuIoWidthUint64) {
|
||||
return CpuIoMemRW (Width, Count, TRUE, Destination, TRUE, Source);
|
||||
}
|
||||
|
||||
if (Width >= EfiCpuIoWidthFifoUint8 && Width <= EfiCpuIoWidthFifoUint64) {
|
||||
return CpuIoMemRW (Width, Count, FALSE, Destination, TRUE, Source);
|
||||
}
|
||||
|
||||
if (Width >= EfiCpuIoWidthFillUint8 && Width <= EfiCpuIoWidthFillUint64) {
|
||||
return CpuIoMemRW (Width, Count, TRUE, Destination, FALSE, Source);
|
||||
}
|
||||
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CpuIoServiceRead (
|
||||
IN EFI_CPU_IO_PROTOCOL *This,
|
||||
IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
|
||||
IN UINT64 UserAddress,
|
||||
IN UINTN Count,
|
||||
OUT VOID *UserBuffer
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Perform the port I/O read service
|
||||
|
||||
Arguments:
|
||||
|
||||
This - Pointer to an instance of the CPU I/O Protocol
|
||||
Width - Width of the port I/O operation
|
||||
Address - Base address of the port I/O operation
|
||||
Count - Count of the number of accesses to perform
|
||||
Buffer - Pointer to the destination buffer to store the results
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - The data was read.
|
||||
EFI_INVALID_PARAMETER - Width is invalid.
|
||||
EFI_INVALID_PARAMETER - Buffer is NULL.
|
||||
EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.
|
||||
EFI_UNSUPPORTED - The address range specified by Address, Width,
|
||||
and Count is not valid.
|
||||
|
||||
--*/
|
||||
{
|
||||
UINTN InStride;
|
||||
UINTN OutStride;
|
||||
UINTN Address;
|
||||
PTR Buffer;
|
||||
EFI_STATUS Status;
|
||||
|
||||
Buffer.buf = (UINT8 *) UserBuffer;
|
||||
|
||||
if (Width >= EfiCpuIoWidthMaximum) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Status = CpuIoCheckParameter (Width, UserAddress, Count, UserBuffer, IA32_MAX_IO_ADDRESS);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
Address = (UINTN) UserAddress;
|
||||
InStride = (UINTN)1 << (Width & 0x03);
|
||||
OutStride = InStride;
|
||||
if (Width >= EfiCpuIoWidthFifoUint8 && Width <= EfiCpuIoWidthFifoUint64) {
|
||||
InStride = 0;
|
||||
}
|
||||
|
||||
if (Width >= EfiCpuIoWidthFillUint8 && Width <= EfiCpuIoWidthFillUint64) {
|
||||
OutStride = 0;
|
||||
}
|
||||
|
||||
Width = Width & 0x03;
|
||||
|
||||
//
|
||||
// Loop for each iteration and move the data
|
||||
//
|
||||
switch (Width) {
|
||||
case EfiCpuIoWidthUint8:
|
||||
for (; Count > 0; Count--, Buffer.buf += OutStride, Address += InStride) {
|
||||
*Buffer.ui8 = CpuIoRead8 ((UINT16) Address);
|
||||
}
|
||||
break;
|
||||
|
||||
case EfiCpuIoWidthUint16:
|
||||
for (; Count > 0; Count--, Buffer.buf += OutStride, Address += InStride) {
|
||||
*Buffer.ui16 = CpuIoRead16 ((UINT16) Address);
|
||||
}
|
||||
break;
|
||||
|
||||
case EfiCpuIoWidthUint32:
|
||||
for (; Count > 0; Count--, Buffer.buf += OutStride, Address += InStride) {
|
||||
*Buffer.ui32 = CpuIoRead32 ((UINT16) Address);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CpuIoServiceWrite (
|
||||
IN EFI_CPU_IO_PROTOCOL *This,
|
||||
IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
|
||||
IN UINT64 UserAddress,
|
||||
IN UINTN Count,
|
||||
IN VOID *UserBuffer
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Perform the port I/O write service
|
||||
|
||||
Arguments:
|
||||
|
||||
This - Pointer to an instance of the CPU I/O Protocol
|
||||
Width - Width of the port I/O operation
|
||||
Address - Base address of the port I/O operation
|
||||
Count - Count of the number of accesses to perform
|
||||
Buffer - Pointer to the source buffer from which to write data
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - The data was written.
|
||||
EFI_INVALID_PARAMETER - Width is invalid.
|
||||
EFI_INVALID_PARAMETER - Buffer is NULL.
|
||||
EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.
|
||||
EFI_UNSUPPORTED - The address range specified by Address, Width,
|
||||
and Count is not valid.
|
||||
|
||||
--*/
|
||||
{
|
||||
UINTN InStride;
|
||||
UINTN OutStride;
|
||||
UINTN Address;
|
||||
PTR Buffer;
|
||||
EFI_STATUS Status;
|
||||
|
||||
Buffer.buf = (UINT8 *) UserBuffer;
|
||||
|
||||
if (Width >= EfiCpuIoWidthMaximum) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Status = CpuIoCheckParameter (Width, UserAddress, Count, UserBuffer, IA32_MAX_IO_ADDRESS);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
Address = (UINTN) UserAddress;
|
||||
InStride = (UINTN)1 << (Width & 0x03);
|
||||
OutStride = InStride;
|
||||
if (Width >= EfiCpuIoWidthFifoUint8 && Width <= EfiCpuIoWidthFifoUint64) {
|
||||
InStride = 0;
|
||||
}
|
||||
|
||||
if (Width >= EfiCpuIoWidthFillUint8 && Width <= EfiCpuIoWidthFillUint64) {
|
||||
OutStride = 0;
|
||||
}
|
||||
|
||||
Width = Width & 0x03;
|
||||
|
||||
//
|
||||
// Loop for each iteration and move the data
|
||||
//
|
||||
switch (Width) {
|
||||
case EfiCpuIoWidthUint8:
|
||||
for (; Count > 0; Count--, Buffer.buf += OutStride, Address += InStride) {
|
||||
CpuIoWrite8 ((UINT16) Address, *Buffer.ui8);
|
||||
}
|
||||
break;
|
||||
|
||||
case EfiCpuIoWidthUint16:
|
||||
for (; Count > 0; Count--, Buffer.buf += OutStride, Address += InStride) {
|
||||
CpuIoWrite16 ((UINT16) Address, *Buffer.ui16);
|
||||
}
|
||||
break;
|
||||
|
||||
case EfiCpuIoWidthUint32:
|
||||
for (; Count > 0; Count--, Buffer.buf += OutStride, Address += InStride) {
|
||||
CpuIoWrite32 ((UINT16) Address, *Buffer.ui32);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CpuIoInitialize (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
CpuIo driver entry point.
|
||||
|
||||
Arguments:
|
||||
|
||||
ImageHandle - The firmware allocated handle for the EFI image.
|
||||
SystemTable - A pointer to the EFI System Table.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - The driver was initialized.
|
||||
EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of resources.
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_HANDLE Handle;
|
||||
|
||||
Handle = NULL;
|
||||
Status = SystemTable->BootServices->InstallProtocolInterface (
|
||||
&Handle,
|
||||
&gEfiCpuIoProtocolGuid,
|
||||
EFI_NATIVE_INTERFACE,
|
||||
&mCpuIo
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
CpuIoCheckParameter (
|
||||
IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
|
||||
IN UINT64 Address,
|
||||
IN UINTN Count,
|
||||
IN VOID *Buffer,
|
||||
IN UINT64 Limit
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Check the validation of parameters for CPU I/O interface functions.
|
||||
|
||||
Arguments:
|
||||
|
||||
Width - Width of the Memory Access
|
||||
Address - Address of the Memory access
|
||||
Count - Count of the number of accesses to perform
|
||||
Buffer - Pointer to the buffer to read from memory
|
||||
Buffer - Memory buffer for the I/O operation
|
||||
Limit - Maximum address supported
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_INVALID_PARAMETER - Buffer is NULL
|
||||
EFI_UNSUPPORTED - The address range specified by Width, Address and Count is invalid
|
||||
EFI_UNSUPPORTED - The memory buffer is not aligned
|
||||
EFI_SUCCESS - Parameters are OK
|
||||
|
||||
--*/
|
||||
{
|
||||
UINTN AlignMask;
|
||||
|
||||
if (Buffer == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (Address > Limit) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
//
|
||||
// For FiFo type, the target address won't increase during the access,
|
||||
// so treat count as 1
|
||||
//
|
||||
if (Width >= EfiCpuIoWidthFifoUint8 && Width <= EfiCpuIoWidthFifoUint64) {
|
||||
Count = 1;
|
||||
}
|
||||
|
||||
Width = Width & 0x03;
|
||||
if (Address - 1 + ((UINTN)1 << Width) * Count > Limit) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
AlignMask = ((UINTN)1 << Width) - 1;
|
||||
if ((UINTN) Buffer & AlignMask) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
245
DuetPkg/CpuIoDxe/CpuIo.h
Normal file
245
DuetPkg/CpuIoDxe/CpuIo.h
Normal file
@ -0,0 +1,245 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2004, Intel Corporation
|
||||
All rights reserved. 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.
|
||||
|
||||
Module Name:
|
||||
CpuIo.h
|
||||
|
||||
Abstract:
|
||||
*.h file for the driver
|
||||
|
||||
Note: the EFIAPI on the CpuIo functions is used to glue MASM (assembler) code
|
||||
into C code. By making the MASM functions EFIAPI it ensures that a standard
|
||||
C calling convention is assumed by the compiler, reguardless of the compiler
|
||||
flags.
|
||||
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef _CPU_IO_H
|
||||
#define _CPU_IO_H
|
||||
|
||||
#include <PiDxe.h>
|
||||
|
||||
#include <Protocol/CpuIo.h>
|
||||
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
|
||||
#define VOLATILE volatile
|
||||
|
||||
typedef union {
|
||||
UINT8 VOLATILE *buf;
|
||||
UINT8 VOLATILE *ui8;
|
||||
UINT16 VOLATILE *ui16;
|
||||
UINT32 VOLATILE *ui32;
|
||||
UINT64 VOLATILE *ui64;
|
||||
UINTN VOLATILE ui;
|
||||
} PTR;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CpuIoInitialize (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
CpuIo driver entry point.
|
||||
|
||||
Arguments:
|
||||
|
||||
ImageHandle - The firmware allocated handle for the EFI image.
|
||||
SystemTable - A pointer to the EFI System Table.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - The driver was initialized.
|
||||
EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of resources.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CpuMemoryServiceRead (
|
||||
IN EFI_CPU_IO_PROTOCOL *This,
|
||||
IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
|
||||
IN UINT64 Address,
|
||||
IN UINTN Count,
|
||||
OUT VOID *Buffer
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Perform the memory mapped I/O read service
|
||||
|
||||
Arguments:
|
||||
|
||||
This - Pointer to an instance of the CPU I/O Protocol
|
||||
Width - Width of the memory mapped I/O operation
|
||||
Address - Base address of the memory mapped I/O operation
|
||||
Count - Count of the number of accesses to perform
|
||||
Buffer - Pointer to the destination buffer to store the results
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - The data was read.
|
||||
EFI_INVALID_PARAMETER - Width is invalid.
|
||||
EFI_INVALID_PARAMETER - Buffer is NULL.
|
||||
EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.
|
||||
EFI_UNSUPPORTED - The address range specified by Address, Width,
|
||||
and Count is not valid.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CpuMemoryServiceWrite (
|
||||
IN EFI_CPU_IO_PROTOCOL *This,
|
||||
IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
|
||||
IN UINT64 Address,
|
||||
IN UINTN Count,
|
||||
IN VOID *Buffer
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Perform the memory mapped I/O write service
|
||||
|
||||
Arguments:
|
||||
|
||||
This - Pointer to an instance of the CPU I/O Protocol
|
||||
Width - Width of the memory mapped I/O operation
|
||||
Address - Base address of the memory mapped I/O operation
|
||||
Count - Count of the number of accesses to perform
|
||||
Buffer - Pointer to the source buffer from which to write data
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - The data was written.
|
||||
EFI_INVALID_PARAMETER - Width is invalid.
|
||||
EFI_INVALID_PARAMETER - Buffer is NULL.
|
||||
EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.
|
||||
EFI_UNSUPPORTED - The address range specified by Address, Width,
|
||||
and Count is not valid.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CpuIoServiceRead (
|
||||
IN EFI_CPU_IO_PROTOCOL *This,
|
||||
IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
|
||||
IN UINT64 UserAddress,
|
||||
IN UINTN Count,
|
||||
OUT VOID *UserBuffer
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Perform the port I/O read service
|
||||
|
||||
Arguments:
|
||||
|
||||
This - Pointer to an instance of the CPU I/O Protocol
|
||||
Width - Width of the port I/O operation
|
||||
Address - Base address of the port I/O operation
|
||||
Count - Count of the number of accesses to perform
|
||||
Buffer - Pointer to the destination buffer to store the results
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - The data was read.
|
||||
EFI_INVALID_PARAMETER - Width is invalid.
|
||||
EFI_INVALID_PARAMETER - Buffer is NULL.
|
||||
EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.
|
||||
EFI_UNSUPPORTED - The address range specified by Address, Width,
|
||||
and Count is not valid.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CpuIoServiceWrite (
|
||||
IN EFI_CPU_IO_PROTOCOL *This,
|
||||
IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
|
||||
IN UINT64 UserAddress,
|
||||
IN UINTN Count,
|
||||
IN VOID *UserBuffer
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Perform the port I/O write service
|
||||
|
||||
Arguments:
|
||||
|
||||
This - Pointer to an instance of the CPU I/O Protocol
|
||||
Width - Width of the port I/O operation
|
||||
Address - Base address of the port I/O operation
|
||||
Count - Count of the number of accesses to perform
|
||||
Buffer - Pointer to the source buffer from which to write data
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - The data was written.
|
||||
EFI_INVALID_PARAMETER - Width is invalid.
|
||||
EFI_INVALID_PARAMETER - Buffer is NULL.
|
||||
EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.
|
||||
EFI_UNSUPPORTED - The address range specified by Address, Width,
|
||||
and Count is not valid.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
CpuIoCheckParameter (
|
||||
IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
|
||||
IN UINT64 Address,
|
||||
IN UINTN Count,
|
||||
IN VOID *Buffer,
|
||||
IN UINT64 Limit
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Check the validation of parameters for CPU I/O interface functions.
|
||||
|
||||
Arguments:
|
||||
|
||||
Width - Width of the Memory Access
|
||||
Address - Address of the Memory access
|
||||
Count - Count of the number of accesses to perform
|
||||
Buffer - Pointer to the buffer to read from memory
|
||||
Buffer - Memory buffer for the I/O operation
|
||||
Limit - Maximum address supported
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_INVALID_PARAMETER - Buffer is NULL
|
||||
EFI_UNSUPPORTED - The address range specified by Width, Address and Count is invalid
|
||||
EFI_UNSUPPORTED - The memory buffer is not aligned
|
||||
EFI_SUCCESS - Parameters are OK
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
#endif
|
56
DuetPkg/CpuIoDxe/CpuIo.inf
Normal file
56
DuetPkg/CpuIoDxe/CpuIo.inf
Normal file
@ -0,0 +1,56 @@
|
||||
#/*++
|
||||
#
|
||||
# Copyright (c) 2004, Intel Corporation
|
||||
# All rights reserved. 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.
|
||||
#
|
||||
# Module Name:
|
||||
#
|
||||
# CpuIo.inf
|
||||
#
|
||||
# Abstract:
|
||||
#
|
||||
# Component description file for CpuIo module
|
||||
#
|
||||
#--*/
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = CpuIo
|
||||
FILE_GUID = BAE7599F-3C6B-43b7-BDF0-9CE07AA91AA6
|
||||
MODULE_TYPE = DXE_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
EDK_RELEASE_VERSION = 0x00020000
|
||||
EFI_SPECIFICATION_VERSION = 0x00020000
|
||||
|
||||
ENTRY_POINT = CpuIoInitialize
|
||||
|
||||
[Packages]
|
||||
DuetPkg/DuetPkg.dec
|
||||
MdePkg/MdePkg.dec
|
||||
IntelFrameworkPkg/IntelFrameworkPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
DebugLib
|
||||
UefiDriverEntryPoint
|
||||
IoLib
|
||||
|
||||
[Sources.common]
|
||||
CpuIo.c
|
||||
CpuIo.h
|
||||
CpuIoAccess.h
|
||||
|
||||
[Sources.IA32]
|
||||
IA32\CpuIoAccess.asm
|
||||
|
||||
[Sources.X64]
|
||||
X64\CpuIoAccess.asm
|
||||
|
||||
[Protocols]
|
||||
gEfiCpuIoProtocolGuid
|
216
DuetPkg/CpuIoDxe/CpuIoAccess.h
Normal file
216
DuetPkg/CpuIoDxe/CpuIoAccess.h
Normal file
@ -0,0 +1,216 @@
|
||||
/*++
|
||||
#
|
||||
# Copyright (c) 2004, Intel Corporation
|
||||
# All rights reserved. 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.
|
||||
|
||||
|
||||
Module Name:
|
||||
|
||||
CpuIoAccess.h
|
||||
|
||||
Abstract:
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef _CPU_IO_ACCESS_H
|
||||
#define _CPU_IO_ACCESS_H
|
||||
|
||||
|
||||
#define IA32API __cdecl
|
||||
|
||||
UINT8
|
||||
IA32API
|
||||
CpuIoRead8 (
|
||||
IN UINT16 Port
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
GC_TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
Port - GC_TODO: add argument description
|
||||
|
||||
Returns:
|
||||
|
||||
GC_TODO: add return values
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
/*++
|
||||
Routine Description:
|
||||
Cpu I/O read port
|
||||
Arguments:
|
||||
Port: - Port number to read
|
||||
Returns:
|
||||
Return read 8 bit value
|
||||
--*/
|
||||
UINT16
|
||||
IA32API
|
||||
CpuIoRead16 (
|
||||
IN UINT16 Port
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
GC_TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
Port - GC_TODO: add argument description
|
||||
|
||||
Returns:
|
||||
|
||||
GC_TODO: add return values
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
/*++
|
||||
Routine Description:
|
||||
Cpu I/O read port
|
||||
Arguments:
|
||||
Port: - Port number to read
|
||||
Returns:
|
||||
Return read 16 bit value
|
||||
--*/
|
||||
UINT32
|
||||
IA32API
|
||||
CpuIoRead32 (
|
||||
IN UINT16 Port
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
GC_TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
Port - GC_TODO: add argument description
|
||||
|
||||
Returns:
|
||||
|
||||
GC_TODO: add return values
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
/*++
|
||||
Routine Description:
|
||||
Cpu I/O read port
|
||||
Arguments:
|
||||
Port: - Port number to read
|
||||
Returns:
|
||||
Return read 32 bit value
|
||||
--*/
|
||||
VOID
|
||||
IA32API
|
||||
CpuIoWrite8 (
|
||||
IN UINT16 Port,
|
||||
IN UINT32 Data
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
GC_TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
Port - GC_TODO: add argument description
|
||||
Data - GC_TODO: add argument description
|
||||
|
||||
Returns:
|
||||
|
||||
GC_TODO: add return values
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
/*++
|
||||
Routine Description:
|
||||
Cpu I/O write 8 bit data to port
|
||||
Arguments:
|
||||
Port: - Port number to read
|
||||
Data: - Data to write to the Port
|
||||
Returns:
|
||||
None
|
||||
--*/
|
||||
VOID
|
||||
IA32API
|
||||
CpuIoWrite16 (
|
||||
IN UINT16 Port,
|
||||
IN UINT32 Data
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
GC_TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
Port - GC_TODO: add argument description
|
||||
Data - GC_TODO: add argument description
|
||||
|
||||
Returns:
|
||||
|
||||
GC_TODO: add return values
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
/*++
|
||||
Routine Description:
|
||||
Cpu I/O write 16 bit data to port
|
||||
Arguments:
|
||||
Port: - Port number to read
|
||||
Data: - Data to write to the Port
|
||||
Returns:
|
||||
None
|
||||
--*/
|
||||
VOID
|
||||
IA32API
|
||||
CpuIoWrite32 (
|
||||
IN UINT16 Port,
|
||||
IN UINT32 Data
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
GC_TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
Port - GC_TODO: add argument description
|
||||
Data - GC_TODO: add argument description
|
||||
|
||||
Returns:
|
||||
|
||||
GC_TODO: add return values
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
/*++
|
||||
Routine Description:
|
||||
Cpu I/O write 32 bit data to port
|
||||
Arguments:
|
||||
Port: - Port number to read
|
||||
Data: - Data to write to the Port
|
||||
Returns:
|
||||
None
|
||||
--*/
|
||||
#endif
|
120
DuetPkg/CpuIoDxe/Ia32/CpuIoAccess.asm
Normal file
120
DuetPkg/CpuIoDxe/Ia32/CpuIoAccess.asm
Normal file
@ -0,0 +1,120 @@
|
||||
title CpuIoAccess.asm
|
||||
;------------------------------------------------------------------------------
|
||||
;*
|
||||
;* Copyright (c) 2005, Intel Corporation
|
||||
;* All rights reserved. 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.
|
||||
;*
|
||||
;* Module Name:
|
||||
;* CpuIoAccess.asm
|
||||
;*
|
||||
;* Abstract:
|
||||
;* Supports IA32 CPU IO operation
|
||||
;*
|
||||
;------------------------------------------------------------------------------
|
||||
;
|
||||
;
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
.686
|
||||
.MODEL FLAT,C
|
||||
.CODE
|
||||
|
||||
|
||||
UINT8 TYPEDEF BYTE
|
||||
UINT16 TYPEDEF WORD
|
||||
UINT32 TYPEDEF DWORD
|
||||
UINT64 TYPEDEF QWORD
|
||||
UINTN TYPEDEF UINT32
|
||||
|
||||
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; UINT8
|
||||
; CpuIoRead8 (
|
||||
; IN UINT16 Port
|
||||
; )
|
||||
;------------------------------------------------------------------------------
|
||||
CpuIoRead8 PROC PUBLIC Port:UINT16
|
||||
mov dx, Port
|
||||
in al, dx
|
||||
ret
|
||||
CpuIoRead8 ENDP
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; UINT16
|
||||
; CpuIoRead16 (
|
||||
; IN UINT16 Port
|
||||
; )
|
||||
;------------------------------------------------------------------------------
|
||||
CpuIoRead16 PROC PUBLIC Port:UINT16
|
||||
mov dx, Port
|
||||
in ax, dx
|
||||
ret
|
||||
CpuIoRead16 ENDP
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; UINT32
|
||||
; CpuIoRead32 (
|
||||
; IN UINT16 Port
|
||||
; )
|
||||
;------------------------------------------------------------------------------
|
||||
CpuIoRead32 PROC PUBLIC Port:UINT16
|
||||
mov dx, Port
|
||||
in eax, dx
|
||||
ret
|
||||
CpuIoRead32 ENDP
|
||||
|
||||
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; VOID
|
||||
; CpuIoWrite8 (
|
||||
; IN UINT16 Port,
|
||||
; IN UINT32 Data
|
||||
; )
|
||||
;------------------------------------------------------------------------------
|
||||
CpuIoWrite8 PROC PUBLIC Port:UINT16, Data:UINT32
|
||||
mov eax, Data
|
||||
mov dx, Port
|
||||
out dx, al
|
||||
ret
|
||||
CpuIoWrite8 ENDP
|
||||
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; VOID
|
||||
; CpuIoWrite16 (
|
||||
; IN UINT16 Port,
|
||||
; IN UINT32 Data
|
||||
; )
|
||||
;------------------------------------------------------------------------------
|
||||
CpuIoWrite16 PROC PUBLIC Port:UINT16, Data:UINT32
|
||||
mov eax, Data
|
||||
mov dx, Port
|
||||
out dx, ax
|
||||
ret
|
||||
CpuIoWrite16 ENDP
|
||||
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; VOID
|
||||
; CpuIoWrite32 (
|
||||
; IN UINT16 Port,
|
||||
; IN UINT32 Data
|
||||
; )
|
||||
;------------------------------------------------------------------------------
|
||||
CpuIoWrite32 PROC PUBLIC Port:UINT16, Data:UINT32
|
||||
mov eax, Data
|
||||
mov dx, Port
|
||||
out dx, eax
|
||||
ret
|
||||
CpuIoWrite32 ENDP
|
||||
|
||||
|
||||
END
|
26
DuetPkg/CpuIoDxe/Ia32CpuIo.dxs
Normal file
26
DuetPkg/CpuIoDxe/Ia32CpuIo.dxs
Normal file
@ -0,0 +1,26 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2004, Intel Corporation
|
||||
All rights reserved. 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.
|
||||
|
||||
Module Name:
|
||||
Ia32CpuIo.dxs
|
||||
|
||||
Abstract:
|
||||
|
||||
Dependency expression source file.
|
||||
|
||||
--*/
|
||||
|
||||
#include "EfiDepex.h"
|
||||
|
||||
|
||||
DEPENDENCY_START
|
||||
TRUE
|
||||
DEPENDENCY_END
|
111
DuetPkg/CpuIoDxe/x64/CpuIoAccess.asm
Normal file
111
DuetPkg/CpuIoDxe/x64/CpuIoAccess.asm
Normal file
@ -0,0 +1,111 @@
|
||||
title CpuIoAccess.asm
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
;*
|
||||
;* Copyright (c) 2005 - 2007, Intel Corporation
|
||||
;* All rights reserved. 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.
|
||||
;*
|
||||
;* Module Name:
|
||||
;* CpuIoAccess.asm
|
||||
;*
|
||||
;* Abstract:
|
||||
;* Supports x64 CPU IO operation
|
||||
;*
|
||||
;------------------------------------------------------------------------------
|
||||
;
|
||||
;
|
||||
;
|
||||
; Abstract:
|
||||
;
|
||||
;
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
.CODE
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; UINT8
|
||||
; CpuIoRead8 (
|
||||
; UINT16 Port // rcx
|
||||
; )
|
||||
;------------------------------------------------------------------------------
|
||||
CpuIoRead8 PROC PUBLIC
|
||||
xor eax, eax
|
||||
mov dx, cx
|
||||
in al, dx
|
||||
ret
|
||||
CpuIoRead8 ENDP
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; VOID
|
||||
; CpuIoWrite8 (
|
||||
; UINT16 Port, // rcx
|
||||
; UINT32 Data // rdx
|
||||
; )
|
||||
;------------------------------------------------------------------------------
|
||||
CpuIoWrite8 PROC PUBLIC
|
||||
mov eax, edx
|
||||
mov dx, cx
|
||||
out dx, al
|
||||
ret
|
||||
CpuIoWrite8 ENDP
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; UINT16
|
||||
; CpuIoRead16 (
|
||||
; UINT16 Port // rcx
|
||||
; )
|
||||
;------------------------------------------------------------------------------
|
||||
CpuIoRead16 PROC PUBLIC
|
||||
xor eax, eax
|
||||
mov dx, cx
|
||||
in ax, dx
|
||||
ret
|
||||
CpuIoRead16 ENDP
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; VOID
|
||||
; CpuIoWrite16 (
|
||||
; UINT16 Port, // rcx
|
||||
; UINT32 Data // rdx
|
||||
; )
|
||||
;------------------------------------------------------------------------------
|
||||
CpuIoWrite16 PROC PUBLIC
|
||||
mov eax, edx
|
||||
mov dx, cx
|
||||
out dx, ax
|
||||
ret
|
||||
CpuIoWrite16 ENDP
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; UINT32
|
||||
; CpuIoRead32 (
|
||||
; UINT16 Port // rcx
|
||||
; )
|
||||
;------------------------------------------------------------------------------
|
||||
CpuIoRead32 PROC PUBLIC
|
||||
mov dx, cx
|
||||
in eax, dx
|
||||
ret
|
||||
CpuIoRead32 ENDP
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; VOID
|
||||
; CpuIoWrite32 (
|
||||
; UINT16 Port, // rcx
|
||||
; UINT32 Data // rdx
|
||||
; )
|
||||
;------------------------------------------------------------------------------
|
||||
CpuIoWrite32 PROC PUBLIC
|
||||
mov eax, edx
|
||||
mov dx, cx
|
||||
out dx, eax
|
||||
ret
|
||||
CpuIoWrite32 ENDP
|
||||
|
||||
END
|
@ -9,4 +9,8 @@
|
||||
|
||||
[Guids.common]
|
||||
gEfiPciExpressBaseAddressGuid = {0x3677d529, 0x326f, 0x4603, {0xa9, 0x26, 0xea, 0xac, 0xe0, 0x1d, 0xcb, 0xb0 }}
|
||||
gEfiAcpiDescriptionGuid = {0x3c699197, 0x093c, 0x4c69, {0xb0, 0x6b, 0x12, 0x8a, 0xe3, 0x48, 0x1d, 0xc9 }}
|
||||
gEfiAcpiDescriptionGuid = {0x3c699197, 0x093c, 0x4c69, {0xb0, 0x6b, 0x12, 0x8a, 0xe3, 0x48, 0x1d, 0xc9 }}
|
||||
gEfiFlashMapHobGuid = { 0xb091e7d2, 0x5a0, 0x4198, {0x94, 0xf0, 0x74, 0xb7, 0xb8, 0xc5, 0x54, 0x59 }}
|
||||
|
||||
[Protocols.common]
|
||||
gEfiLegacyBiosThunkProtocolGuid = {0x4c51a7ba, 0x7195, 0x442d, {0x87, 0x92, 0xbe, 0xea, 0x6e, 0x2f, 0xf6, 0xec}}
|
@ -9,7 +9,7 @@
|
||||
SUPPORTED_ARCHITECTURES = IA32|X64
|
||||
BUILD_TARGETS = DEBUG
|
||||
SKUID_IDENTIFIER = DEFAULT
|
||||
#FLASH_DEFINITION = DuetPkg/DuetPkg.fdf
|
||||
FLASH_DEFINITION = DuetPkg/DuetPkg.fdf
|
||||
|
||||
[LibraryClasses.common]
|
||||
BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
|
||||
@ -26,15 +26,106 @@
|
||||
HiiLib|MdePkg/Library/HiiLib/HiiLib.inf
|
||||
UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
|
||||
DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
|
||||
DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
|
||||
DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
|
||||
UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
|
||||
UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
|
||||
UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
|
||||
BaseUefiTianoDecompressLib|IntelFrameworkModulePkg/Library/BaseUefiTianoCustomDecompressLib/BaseUefiTianoCustomDecompressLib.inf
|
||||
ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf
|
||||
PlatformBdsLib|DuetPkg/Library/DuetBdsLib/PlatformBds.inf
|
||||
IfrSupportLib|MdePkg/Library/IfrSupportLib/IfrSupportLib.inf
|
||||
ExtendedIfrSupportLib|MdeModulePkg/Library/ExtendedIfrSupportLib/ExtendedIfrSupportLib.inf
|
||||
GenericBdsLib|MdeModulePkg/Library/GenericBdsLib/GenericBdsLib.inf
|
||||
PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
|
||||
GraphicsLib|MdeModulePkg/Library/GraphicsLib/GraphicsLib.inf
|
||||
ExtendedHiiLib|MdeModulePkg/Library/ExtendedHiiLib/ExtendedHiiLib.inf
|
||||
CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
|
||||
DxePiLib|MdePkg/Library/DxePiLib/DxePiLib.inf
|
||||
PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
|
||||
DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
|
||||
CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf
|
||||
PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
|
||||
OemHookStatusCodeLib|IntelFrameworkModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
|
||||
|
||||
[LibraryClasses.common.DXE_DRIVER]
|
||||
MemoryAllocationLib|MdePkg/Library/DxeMemoryAllocationLib/DxeMemoryAllocationLib.inf
|
||||
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
|
||||
ReportStatusCodeLib|IntelFrameworkModulePkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf
|
||||
SerialPortLib|MdePkg/Library/SerialPortLibNull/SerialPortLibNull.inf
|
||||
MemoryAllocationLib|MdePkg/Library/DxeMemoryAllocationLib/DxeMemoryAllocationLib.inf
|
||||
IoLib|IntelFrameworkPkg/Library/DxeIoLibCpuIo/DxeIoLibCpuIo.inf
|
||||
UsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
|
||||
|
||||
[Components.IA32]
|
||||
[LibraryClasses.common.DXE_CORE]
|
||||
HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
|
||||
PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
|
||||
DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
|
||||
MemoryAllocationLib|MdePkg/Library/DxeMemoryAllocationLib/DxeMemoryAllocationLib.inf
|
||||
UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
|
||||
|
||||
[LibraryClasses.common.DXE_RUNTIME_DRIVER]
|
||||
MemoryAllocationLib|MdePkg/Library/DxeMemoryAllocationLib/DxeMemoryAllocationLib.inf
|
||||
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
|
||||
ReportStatusCodeLib|IntelFrameworkModulePkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf
|
||||
SerialPortLib|MdePkg/Library/SerialPortLibNull/SerialPortLibNull.inf
|
||||
IoLib|IntelFrameworkPkg/Library/DxeIoLibCpuIo/DxeIoLibCpuIo.inf
|
||||
TimerLib|MdePkg/Library/SecPeiDxeTimerLibCpu/SecPeiDxeTimerLibCpu.inf
|
||||
|
||||
[LibraryClasses.common.UEFI_DRIVER]
|
||||
MemoryAllocationLib|MdePkg/Library/DxeMemoryAllocationLib/DxeMemoryAllocationLib.inf
|
||||
|
||||
[LibraryClasses.common.UEFI_APPLICATION]
|
||||
MemoryAllocationLib|MdePkg/Library/DxeMemoryAllocationLib/DxeMemoryAllocationLib.inf
|
||||
|
||||
[Components.common]
|
||||
DuetPkg/DxeIpl/DxeIpl.inf
|
||||
|
||||
MdeModulePkg/Core/Dxe/DxeMain.inf
|
||||
MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
|
||||
MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
|
||||
MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
|
||||
|
||||
DuetPkg/FSVariable/FSVariable.inf
|
||||
|
||||
MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf
|
||||
MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
|
||||
IntelFrameworkModulePkg/Universal/StatusCode/Dxe/DxeStatusCode.inf
|
||||
MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
|
||||
MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
|
||||
MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
|
||||
MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
|
||||
|
||||
IntelFrameworkModulePkg/Universal/DataHubDxe/DataHubDxe.inf
|
||||
MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
|
||||
MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
|
||||
MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
|
||||
|
||||
DuetPkg/DataHubGenDxe/DataHubGen.inf
|
||||
DuetPkg/FvbRuntimeService/DUETFwh.inf
|
||||
DuetPkg/EfiLdr/EfiLdr.inf
|
||||
MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
|
||||
DuetPkg/CpuIoDxe/CpuIo.inf
|
||||
DuetPkg/CpuDxe/Cpu.inf
|
||||
|
||||
IntelFrameworkModulePkg/Universal/Legacy8259Dxe/8259.inf
|
||||
DuetPkg/KbcResetDxe/Reset.inf
|
||||
DuetPkg/LegacyMetronome/Metronome.inf
|
||||
|
||||
[Components.X64]
|
||||
DuetPkg/DxeIpl/DxeIpl.inf
|
||||
DuetPkg/DataHubGenDxe/DataHubGen.inf
|
||||
DuetPkg/PcRtc/RealTimeClock.inf
|
||||
DuetPkg/PciRootBridgeNoEnumerationDxe/PciRootBridgeNoEnumeration.inf
|
||||
IntelFrameworkModulePkg/Universal/Console/VgaClassDxe/VgaClassDxe.inf
|
||||
|
||||
# IDE Support
|
||||
#IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/IdeBusDxe.inf
|
||||
|
||||
# Usb Support
|
||||
MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf
|
||||
MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
|
||||
MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
|
||||
MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
|
||||
MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouseDxe.inf
|
||||
|
||||
# ISA Support
|
||||
DuetPkg/IsaAcpiDxe/IsaAcpi.inf
|
||||
DuetPkg/BootSector/BootSector.inf
|
||||
|
189
DuetPkg/DuetPkg.fdf
Normal file
189
DuetPkg/DuetPkg.fdf
Normal file
@ -0,0 +1,189 @@
|
||||
# This is NT32 FDF file with UEFI HII features enabled
|
||||
#
|
||||
# Copyright (c) 2007, Intel Corporation
|
||||
#
|
||||
# All rights reserved. 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.
|
||||
#
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# FD Section
|
||||
# The [FD] Section is made up of the definition statements and a
|
||||
# description of what goes into the Flash Device Image. Each FD section
|
||||
# defines one flash "device" image. A flash device image may be one of
|
||||
# the following: Removable media bootable image (like a boot floppy
|
||||
# image,) an Option ROM image (that would be "flashed" into an add-in
|
||||
# card,) a System "Flash" image (that would be burned into a system's
|
||||
# flash) or an Update ("Capsule") image that will be used to update and
|
||||
# existing system flash.
|
||||
#
|
||||
################################################################################
|
||||
[FD.DuetMainFd]
|
||||
BaseAddress = 0x0 #The base address of the FLASH Device.
|
||||
Size = 0x002a0000 #The size in bytes of the FLASH Device
|
||||
ErasePolarity = 1
|
||||
BlockSize = 0x10000
|
||||
NumBlocks = 0x2a
|
||||
|
||||
0x00000000|0x002a0000
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# FV Section
|
||||
#
|
||||
# [FV] section is used to define what components or modules are placed within a flash
|
||||
# device file. This section also defines order the components and modules are positioned
|
||||
# within the image. The [FV] section consists of define statements, set statements and
|
||||
# module statements.
|
||||
#
|
||||
################################################################################
|
||||
[FV.DuetEfiMainFv]
|
||||
FvAlignment = 16 #FV alignment and FV attributes setting.
|
||||
ERASE_POLARITY = 1
|
||||
MEMORY_MAPPED = TRUE
|
||||
STICKY_WRITE = TRUE
|
||||
LOCK_CAP = TRUE
|
||||
LOCK_STATUS = TRUE
|
||||
WRITE_DISABLED_CAP = TRUE
|
||||
WRITE_ENABLED_CAP = TRUE
|
||||
WRITE_STATUS = TRUE
|
||||
WRITE_LOCK_CAP = TRUE
|
||||
WRITE_LOCK_STATUS = TRUE
|
||||
READ_DISABLED_CAP = TRUE
|
||||
READ_ENABLED_CAP = TRUE
|
||||
READ_STATUS = TRUE
|
||||
READ_LOCK_CAP = TRUE
|
||||
READ_LOCK_STATUS = TRUE
|
||||
|
||||
INF MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
|
||||
INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
|
||||
INF MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
|
||||
|
||||
INF DuetPkg/FSVariable/FSVariable.inf
|
||||
|
||||
INF MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf
|
||||
INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
|
||||
INF IntelFrameworkModulePkg/Universal/StatusCode/Dxe/DxeStatusCode.inf
|
||||
INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
|
||||
INF MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
|
||||
INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
|
||||
INF MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
|
||||
|
||||
INF IntelFrameworkModulePkg/Universal/DataHubDxe/DataHubDxe.inf
|
||||
INF MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
|
||||
INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
|
||||
INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
|
||||
|
||||
INF DuetPkg/DataHubGenDxe/DataHubGen.inf
|
||||
INF DuetPkg/FvbRuntimeService/DUETFwh.inf
|
||||
INF MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
|
||||
INF DuetPkg/CpuIoDxe/CpuIo.inf
|
||||
INF DuetPkg/CpuDxe/Cpu.inf
|
||||
|
||||
INF IntelFrameworkModulePkg/Universal/Legacy8259Dxe/8259.inf
|
||||
INF DuetPkg/KbcResetDxe/Reset.inf
|
||||
INF DuetPkg/LegacyMetronome/Metronome.inf
|
||||
|
||||
INF DuetPkg/PcRtc/RealTimeClock.inf
|
||||
INF DuetPkg/PciRootBridgeNoEnumerationDxe/PciRootBridgeNoEnumeration.inf
|
||||
INF IntelFrameworkModulePkg/Universal/Console/VgaClassDxe/VgaClassDxe.inf
|
||||
|
||||
# IDE Support
|
||||
#IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/IdeBusDxe.inf
|
||||
|
||||
# Usb Support
|
||||
INF MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf
|
||||
INF MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
|
||||
INF MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
|
||||
INF MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
|
||||
INF MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouseDxe.inf
|
||||
|
||||
# ISA Support
|
||||
INF DuetPkg/IsaAcpiDxe/IsaAcpi.inf
|
||||
|
||||
[Rule.Common.PEI_CORE]
|
||||
FILE PEI_CORE = $(NAMED_GUID) {
|
||||
PE32 PE32 |.efi
|
||||
UI STRING ="$(MODULE_NAME)" Optional
|
||||
VERSION STRING ="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
}
|
||||
|
||||
[Rule.Common.PEIM]
|
||||
FILE PEIM = $(NAMED_GUID) {
|
||||
PEI_DEPEX PEI_DEPEX Optional |.depex
|
||||
PE32 PE32 |.efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
}
|
||||
|
||||
[Rule.Common.PEIM.TIANOCOMPRESSED]
|
||||
FILE PEIM = $(NAMED_GUID) DEBUG_MYTOOLS_IA32 {
|
||||
PEI_DEPEX PEI_DEPEX Optional |.depex
|
||||
GUIDED A31280AD-481E-41B6-95E8-127F4C984779 PROCESSING_REQUIRED = TRUE {
|
||||
PE32 PE32 |.efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
}
|
||||
}
|
||||
|
||||
[Rule.Common.DXE_CORE]
|
||||
FILE DXE_CORE = $(NAMED_GUID) {
|
||||
COMPRESS PI_STD {
|
||||
PE32 PE32 |.efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
}
|
||||
}
|
||||
|
||||
[Rule.Common.UEFI_DRIVER]
|
||||
FILE DRIVER = $(NAMED_GUID) {
|
||||
DXE_DEPEX DXE_DEPEX Optional |.depex
|
||||
COMPRESS PI_STD {
|
||||
GUIDED {
|
||||
PE32 PE32 |.efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Rule.Common.DXE_DRIVER]
|
||||
FILE DRIVER = $(NAMED_GUID) {
|
||||
DXE_DEPEX DXE_DEPEX Optional |.depex
|
||||
COMPRESS PI_STD {
|
||||
GUIDED {
|
||||
PE32 PE32 |.efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Rule.Common.DXE_RUNTIME_DRIVER]
|
||||
FILE DRIVER = $(NAMED_GUID) {
|
||||
DXE_DEPEX DXE_DEPEX Optional |.depex
|
||||
COMPRESS PI_STD {
|
||||
GUIDED {
|
||||
PE32 PE32 |.efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Rule.Common.UEFI_APPLICATION]
|
||||
FILE APPLICATION = $(NAMED_GUID) {
|
||||
COMPRESS PI_STD {
|
||||
GUIDED {
|
||||
PE32 PE32 |.efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
}
|
||||
}
|
||||
}
|
@ -20,7 +20,7 @@
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = DxeIpl
|
||||
FILE_GUID = 2119BBD7-9432-4f47-B5E2-5C4EA31B6BDC
|
||||
MODULE_TYPE = USER_DEFINED
|
||||
MODULE_TYPE = DXE_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
EDK_RELEASE_VERSION = 0x00020000
|
||||
EFI_SPECIFICATION_VERSION = 0x00020000
|
||||
@ -38,6 +38,7 @@
|
||||
BaseMemoryLib
|
||||
PrintLib
|
||||
ReportStatusCodeLib
|
||||
UefiDriverEntryPoint
|
||||
|
||||
[Sources.common]
|
||||
DxeIpl.h
|
||||
@ -65,9 +66,9 @@
|
||||
Ia32\Paging.c
|
||||
Ia32\VirtualMemory.h
|
||||
|
||||
[BuildOptions.common]
|
||||
#[BuildOptions.common]
|
||||
#MSFT:*_*_IA32_DLINK_FLAGS = /out:"$(BIN_DIR)\SecMain.exe" /base:0x10000000 /pdb:"$(BIN_DIR)\SecMain.pdb" /LIBPATH:"$(VCINSTALLDIR)\Lib" /LIBPATH:"$(VCINSTALLDIR)\PlatformSdk\Lib" /NOLOGO /SUBSYSTEM:CONSOLE /NODEFAULTLIB /IGNORE:4086 /MAP /OPT:REF /DEBUG /MACHINE:I386 /LTCG Kernel32.lib MSVCRTD.lib Gdi32.lib User32.lib Winmm.lib
|
||||
MSFT:*_*_IA32_CC_FLAGS = /nologo /W4 /WX /Gy /c /D UNICODE /Od /FI$(DEST_DIR_DEBUG)/AutoGen.h /EHs-c- /GF /Gs8192 /Zi /Gm /D _CRT_SECURE_NO_WARNINGS /D _CRT_SECURE_NO_DEPRECATE
|
||||
MSFT:*_*_IA32_PP_FLAGS = /nologo /E /TC /FI$(DEST_DIR_DEBUG)/AutoGen.h
|
||||
MSFT:*_*_IA32_ASM_FLAGS = /nologo /W3 /WX /c /coff /Cx /Zd /W0 /Zi
|
||||
MSFT:*_*_IA32_ASMLINK_FLAGS = /link /nologo /tiny
|
||||
#MSFT:*_*_IA32_CC_FLAGS = /nologo /W4 /WX /Gy /c /D UNICODE /Od /FI$(DEST_DIR_DEBUG)/AutoGen.h /EHs-c- /GF /Gs8192 /Zi /Gm /D _CRT_SECURE_NO_WARNINGS /D _CRT_SECURE_NO_DEPRECATE
|
||||
#MSFT:*_*_IA32_PP_FLAGS = /nologo /E /TC /FI$(DEST_DIR_DEBUG)/AutoGen.h
|
||||
#MSFT:*_*_IA32_ASM_FLAGS = /nologo /W3 /WX /c /coff /Cx /Zd /W0 /Zi
|
||||
#MSFT:*_*_IA32_ASMLINK_FLAGS = /link /nologo /tiny
|
||||
|
@ -22,7 +22,6 @@ Abstract:
|
||||
#ifndef _EFI_FLASHMAP_H_
|
||||
#define _EFI_FLASHMAP_H_
|
||||
|
||||
|
||||
//
|
||||
// Definition for flash map GUIDed HOBs
|
||||
//
|
||||
@ -59,6 +58,7 @@ typedef UINT8 EFI_FLASH_AREA_TYPE;
|
||||
// An individual sub-area Entry.
|
||||
// A single flash area may consist of more than one sub-area.
|
||||
//
|
||||
/**
|
||||
typedef struct {
|
||||
EFI_FLASH_AREA_ATTRIBUTES Attributes;
|
||||
UINT32 Reserved;
|
||||
@ -121,6 +121,32 @@ typedef struct {
|
||||
UINT8 Reserved[3];
|
||||
EFI_GUID AreaTypeGuid;
|
||||
} EFI_FLASH_AREA_DATA;
|
||||
**/
|
||||
|
||||
typedef struct {
|
||||
EFI_FLASH_AREA_ATTRIBUTES Attributes;
|
||||
UINT32 Reserved;
|
||||
EFI_PHYSICAL_ADDRESS Base;
|
||||
EFI_PHYSICAL_ADDRESS Length;
|
||||
EFI_GUID FileSystem;
|
||||
} EFI_FLASH_SUBAREA_ENTRY;
|
||||
|
||||
typedef struct {
|
||||
UINT8 Reserved[3];
|
||||
EFI_FLASH_AREA_TYPE AreaType;
|
||||
EFI_GUID AreaTypeGuid;
|
||||
UINT32 NumberOfEntries;
|
||||
EFI_FLASH_SUBAREA_ENTRY Entries[1];
|
||||
//
|
||||
// Extended Hob data.
|
||||
//
|
||||
// VolumeId and FilePath indicating a unique file.
|
||||
//
|
||||
UINT32 VolumeId;
|
||||
CHAR16 FilePath[256];
|
||||
UINT32 ActuralSize;
|
||||
UINT32 Offset;
|
||||
} EFI_FLASH_MAP_FS_ENTRY_DATA;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
|
170
DuetPkg/IsaAcpiDxe/ComponentName.c
Normal file
170
DuetPkg/IsaAcpiDxe/ComponentName.c
Normal file
@ -0,0 +1,170 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006 - 2007, Intel Corporation
|
||||
All rights reserved. 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.
|
||||
|
||||
|
||||
Module Name:
|
||||
|
||||
ComponentName.c
|
||||
|
||||
Abstract:
|
||||
|
||||
--*/
|
||||
|
||||
#include "PcatIsaAcpi.h"
|
||||
|
||||
//
|
||||
// EFI Component Name Functions
|
||||
//
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PcatIsaAcpiComponentNameGetDriverName (
|
||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **DriverName
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PcatIsaAcpiComponentNameGetControllerName (
|
||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_HANDLE ChildHandle OPTIONAL,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **ControllerName
|
||||
);
|
||||
|
||||
//
|
||||
// EFI Component Name Protocol
|
||||
//
|
||||
|
||||
EFI_COMPONENT_NAME2_PROTOCOL gPcatIsaAcpiComponentName2 = {
|
||||
(EFI_COMPONENT_NAME2_GET_DRIVER_NAME) PcatIsaAcpiComponentNameGetDriverName,
|
||||
(EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) PcatIsaAcpiComponentNameGetControllerName,
|
||||
"en"
|
||||
};
|
||||
|
||||
EFI_COMPONENT_NAME_PROTOCOL gPcatIsaAcpiComponentName = {
|
||||
PcatIsaAcpiComponentNameGetDriverName,
|
||||
PcatIsaAcpiComponentNameGetControllerName,
|
||||
"eng"
|
||||
};
|
||||
|
||||
|
||||
static EFI_UNICODE_STRING_TABLE mPcatIsaAcpiDriverNameTable[] = {
|
||||
{
|
||||
"eng;en",
|
||||
L"PC-AT ISA Device Enumeration Driver"
|
||||
},
|
||||
{
|
||||
NULL,
|
||||
NULL
|
||||
}
|
||||
};
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PcatIsaAcpiComponentNameGetDriverName (
|
||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **DriverName
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Retrieves a Unicode string that is the user readable name of the EFI Driver.
|
||||
|
||||
Arguments:
|
||||
This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
|
||||
Language - A pointer to a three character ISO 639-2 language identifier.
|
||||
This is the language of the driver name that that the caller
|
||||
is requesting, and it must match one of the languages specified
|
||||
in SupportedLanguages. The number of languages supported by a
|
||||
driver is up to the driver writer.
|
||||
DriverName - A pointer to the Unicode string to return. This Unicode string
|
||||
is the name of the driver specified by This in the language
|
||||
specified by Language.
|
||||
|
||||
Returns:
|
||||
EFI_SUCCES - The Unicode string for the Driver specified by This
|
||||
and the language specified by Language was returned
|
||||
in DriverName.
|
||||
EFI_INVALID_PARAMETER - Language is NULL.
|
||||
EFI_INVALID_PARAMETER - DriverName is NULL.
|
||||
EFI_UNSUPPORTED - The driver specified by This does not support the
|
||||
language specified by Language.
|
||||
|
||||
--*/
|
||||
{
|
||||
return LookupUnicodeString2 (
|
||||
Language,
|
||||
This->SupportedLanguages,
|
||||
mPcatIsaAcpiDriverNameTable,
|
||||
DriverName,
|
||||
(BOOLEAN)(This == &gPcatIsaAcpiComponentName)
|
||||
);
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PcatIsaAcpiComponentNameGetControllerName (
|
||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_HANDLE ChildHandle OPTIONAL,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **ControllerName
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Retrieves a Unicode string that is the user readable name of the controller
|
||||
that is being managed by an EFI Driver.
|
||||
|
||||
Arguments:
|
||||
This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
|
||||
ControllerHandle - The handle of a controller that the driver specified by
|
||||
This is managing. This handle specifies the controller
|
||||
whose name is to be returned.
|
||||
ChildHandle - The handle of the child controller to retrieve the name
|
||||
of. This is an optional parameter that may be NULL. It
|
||||
will be NULL for device drivers. It will also be NULL
|
||||
for a bus drivers that wish to retrieve the name of the
|
||||
bus controller. It will not be NULL for a bus driver
|
||||
that wishes to retrieve the name of a child controller.
|
||||
Language - A pointer to a three character ISO 639-2 language
|
||||
identifier. This is the language of the controller name
|
||||
that that the caller is requesting, and it must match one
|
||||
of the languages specified in SupportedLanguages. The
|
||||
number of languages supported by a driver is up to the
|
||||
driver writer.
|
||||
ControllerName - A pointer to the Unicode string to return. This Unicode
|
||||
string is the name of the controller specified by
|
||||
ControllerHandle and ChildHandle in the language specified
|
||||
by Language from the point of view of the driver specified
|
||||
by This.
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - The Unicode string for the user readable name in the
|
||||
language specified by Language for the driver
|
||||
specified by This was returned in DriverName.
|
||||
EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
|
||||
EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.
|
||||
EFI_INVALID_PARAMETER - Language is NULL.
|
||||
EFI_INVALID_PARAMETER - ControllerName is NULL.
|
||||
EFI_UNSUPPORTED - The driver specified by This is not currently managing
|
||||
the controller specified by ControllerHandle and
|
||||
ChildHandle.
|
||||
EFI_UNSUPPORTED - The driver specified by This does not support the
|
||||
language specified by Language.
|
||||
|
||||
--*/
|
||||
{
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
306
DuetPkg/IsaAcpiDxe/IsaAcpi.c
Normal file
306
DuetPkg/IsaAcpiDxe/IsaAcpi.c
Normal file
@ -0,0 +1,306 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. 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.
|
||||
|
||||
|
||||
Module Name:
|
||||
|
||||
IsaAcpi.c
|
||||
|
||||
Abstract:
|
||||
|
||||
ISA ACPI Protocol Implementation
|
||||
|
||||
Revision History
|
||||
|
||||
--*/
|
||||
|
||||
#include "PcatIsaAcpi.h"
|
||||
|
||||
//
|
||||
// Platform specific data for the ISA devices that are present.in the platform
|
||||
//
|
||||
|
||||
//
|
||||
// COM 1 UART Controller
|
||||
//
|
||||
static EFI_ISA_ACPI_RESOURCE mPcatIsaAcpiCom1DeviceResources[] = {
|
||||
{EfiIsaAcpiResourceIo, 0, 0x3f8, 0x3ff},
|
||||
{EfiIsaAcpiResourceInterrupt, 0, 4, 0},
|
||||
{EfiIsaAcpiResourceEndOfList, 0, 0, 0}
|
||||
};
|
||||
|
||||
//
|
||||
// COM 2 UART Controller
|
||||
//
|
||||
static EFI_ISA_ACPI_RESOURCE mPcatIsaAcpiCom2DeviceResources[] = {
|
||||
{EfiIsaAcpiResourceIo, 0, 0x2f8, 0x2ff},
|
||||
{EfiIsaAcpiResourceInterrupt, 0, 3, 0},
|
||||
{EfiIsaAcpiResourceEndOfList, 0, 0, 0}
|
||||
};
|
||||
|
||||
//
|
||||
// PS/2 Keyboard Controller
|
||||
//
|
||||
static EFI_ISA_ACPI_RESOURCE mPcatIsaAcpiPs2KeyboardDeviceResources[] = {
|
||||
{EfiIsaAcpiResourceIo, 0, 0x60, 0x64},
|
||||
{EfiIsaAcpiResourceInterrupt, 0, 1, 0},
|
||||
{EfiIsaAcpiResourceEndOfList, 0, 0, 0}
|
||||
};
|
||||
|
||||
//
|
||||
// PS/2 Mouse Controller
|
||||
//
|
||||
static EFI_ISA_ACPI_RESOURCE mPcatIsaAcpiPs2MouseDeviceResources[] = {
|
||||
{EfiIsaAcpiResourceIo, 0, 0x60, 0x64},
|
||||
{EfiIsaAcpiResourceInterrupt, 0, 12, 0},
|
||||
{EfiIsaAcpiResourceEndOfList, 0, 0, 0}
|
||||
};
|
||||
|
||||
//
|
||||
// Floppy Disk Controller
|
||||
//
|
||||
static EFI_ISA_ACPI_RESOURCE mPcatIsaAcpiFloppyResources[] = {
|
||||
{EfiIsaAcpiResourceIo, 0, 0x3f0, 0x3f7},
|
||||
{EfiIsaAcpiResourceInterrupt, 0, 6, 0},
|
||||
{EfiIsaAcpiResourceDma, EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_COMPATIBLE | EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_WIDTH_8 | EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SINGLE_MODE, 2, 0},
|
||||
{EfiIsaAcpiResourceEndOfList, 0, 0, 0}
|
||||
};
|
||||
|
||||
//
|
||||
// Table of ISA Controllers
|
||||
//
|
||||
EFI_ISA_ACPI_RESOURCE_LIST gPcatIsaAcpiDeviceList[] = {
|
||||
{{EISA_PNP_ID(0x501), 0}, mPcatIsaAcpiCom1DeviceResources }, // COM 1 UART Controller
|
||||
{{EISA_PNP_ID(0x501), 1}, mPcatIsaAcpiCom2DeviceResources }, // COM 2 UART Controller
|
||||
{{EISA_PNP_ID(0x303), 0}, mPcatIsaAcpiPs2KeyboardDeviceResources }, // PS/2 Keyboard Controller
|
||||
{{EISA_PNP_ID(0x303), 1}, mPcatIsaAcpiPs2MouseDeviceResources }, // PS/2 Mouse Controller
|
||||
{{EISA_PNP_ID(0x604), 0}, mPcatIsaAcpiFloppyResources }, // Floppy Disk Controller A:
|
||||
{{EISA_PNP_ID(0x604), 1}, mPcatIsaAcpiFloppyResources }, // Floppy Disk Controller B:
|
||||
{{0, 0}, NULL } // End if ISA Controllers
|
||||
};
|
||||
|
||||
//
|
||||
// ISA ACPI Protocol Functions
|
||||
//
|
||||
VOID
|
||||
IsaDeviceLookup (
|
||||
IN EFI_ISA_ACPI_DEVICE_ID *Device,
|
||||
OUT EFI_ISA_ACPI_RESOURCE_LIST **IsaAcpiDevice,
|
||||
OUT EFI_ISA_ACPI_RESOURCE_LIST **NextIsaAcpiDevice
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Enumerate the ISA devices on the ISA bus
|
||||
|
||||
Arguments:
|
||||
|
||||
Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
UINTN Index;
|
||||
|
||||
*IsaAcpiDevice = NULL;
|
||||
if (NextIsaAcpiDevice != NULL) {
|
||||
*NextIsaAcpiDevice = NULL;
|
||||
}
|
||||
if (Device == NULL) {
|
||||
Index = 0;
|
||||
} else {
|
||||
for(Index = 0; gPcatIsaAcpiDeviceList[Index].ResourceItem != NULL; Index++) {
|
||||
if (Device->HID == gPcatIsaAcpiDeviceList[Index].Device.HID &&
|
||||
Device->UID == gPcatIsaAcpiDeviceList[Index].Device.UID ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (gPcatIsaAcpiDeviceList[Index].ResourceItem == NULL) {
|
||||
return;
|
||||
}
|
||||
*IsaAcpiDevice = &(gPcatIsaAcpiDeviceList[Index]);
|
||||
Index++;
|
||||
}
|
||||
if (gPcatIsaAcpiDeviceList[Index].ResourceItem != NULL && NextIsaAcpiDevice != NULL) {
|
||||
*NextIsaAcpiDevice = &(gPcatIsaAcpiDeviceList[Index]);
|
||||
}
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
IsaDeviceEnumerate (
|
||||
IN EFI_ISA_ACPI_PROTOCOL *This,
|
||||
OUT EFI_ISA_ACPI_DEVICE_ID **Device
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Enumerate the ISA devices on the ISA bus
|
||||
|
||||
Arguments:
|
||||
|
||||
Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_ISA_ACPI_RESOURCE_LIST *IsaAcpiDevice;
|
||||
EFI_ISA_ACPI_RESOURCE_LIST *NextIsaAcpiDevice;
|
||||
|
||||
IsaDeviceLookup (*Device, &IsaAcpiDevice, &NextIsaAcpiDevice);
|
||||
if (NextIsaAcpiDevice == NULL) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
*Device = &(NextIsaAcpiDevice->Device);
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
IsaDeviceSetPower (
|
||||
IN EFI_ISA_ACPI_PROTOCOL *This,
|
||||
IN EFI_ISA_ACPI_DEVICE_ID *Device,
|
||||
IN BOOLEAN OnOff
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Set ISA device power
|
||||
|
||||
Arguments:
|
||||
|
||||
Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
IsaGetCurrentResource (
|
||||
IN EFI_ISA_ACPI_PROTOCOL *This,
|
||||
IN EFI_ISA_ACPI_DEVICE_ID *Device,
|
||||
OUT EFI_ISA_ACPI_RESOURCE_LIST **ResourceList
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Get current Resource of the specific ISA device
|
||||
|
||||
Arguments:
|
||||
|
||||
Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
IsaDeviceLookup (Device, ResourceList, NULL);
|
||||
if (*ResourceList == NULL) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
IsaGetPossibleResource (
|
||||
IN EFI_ISA_ACPI_PROTOCOL *This,
|
||||
IN EFI_ISA_ACPI_DEVICE_ID *Device,
|
||||
OUT EFI_ISA_ACPI_RESOURCE_LIST **ResourceList
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Arguments:
|
||||
|
||||
Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
IsaSetResource (
|
||||
IN EFI_ISA_ACPI_PROTOCOL *This,
|
||||
IN EFI_ISA_ACPI_DEVICE_ID *Device,
|
||||
IN EFI_ISA_ACPI_RESOURCE_LIST *ResourceList
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Arguments:
|
||||
|
||||
Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
IsaEnableDevice (
|
||||
IN EFI_ISA_ACPI_PROTOCOL *This,
|
||||
IN EFI_ISA_ACPI_DEVICE_ID *Device,
|
||||
IN BOOLEAN Enable
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Arguments:
|
||||
|
||||
Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
IsaInitDevice (
|
||||
IN EFI_ISA_ACPI_PROTOCOL *This,
|
||||
IN EFI_ISA_ACPI_DEVICE_ID *Device
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Arguments:
|
||||
|
||||
Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
IsaInterfaceInit (
|
||||
IN EFI_ISA_ACPI_PROTOCOL *This
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Arguments:
|
||||
|
||||
Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
return EFI_SUCCESS;
|
||||
}
|
50
DuetPkg/IsaAcpiDxe/IsaAcpi.inf
Normal file
50
DuetPkg/IsaAcpiDxe/IsaAcpi.inf
Normal file
@ -0,0 +1,50 @@
|
||||
#/*++
|
||||
#
|
||||
# Copyright (c) 2005, Intel Corporation
|
||||
# All rights reserved. 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.
|
||||
#
|
||||
# Module Name:
|
||||
# IsaAcpi.inf
|
||||
#
|
||||
# Abstract:
|
||||
# Component description file for PCAT ISA ACPI driver
|
||||
#
|
||||
#--*/
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = IsaAcpi
|
||||
FILE_GUID = 38A0EC22-FBE7-4911-8BC1-176E0D6C1DBD
|
||||
MODULE_TYPE = DXE_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
EDK_RELEASE_VERSION = 0x00020000
|
||||
EFI_SPECIFICATION_VERSION = 0x0002000A
|
||||
|
||||
ENTRY_POINT = PcatIsaAcpiDriverEntryPoint
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
IntelFrameworkPkg/IntelFrameworkPkg.dec
|
||||
IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
|
||||
DuetPkg/DuetPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
UefiDriverEntryPoint
|
||||
UefiBootServicesTableLib
|
||||
UefiLib
|
||||
|
||||
[Sources]
|
||||
PcatIsaAcpi.h
|
||||
PcatIsaAcpi.c
|
||||
IsaAcpi.c
|
||||
ComponentName.c
|
||||
|
||||
[Protocols]
|
||||
gEfiPciIoProtocolGuid
|
||||
gEfiIsaAcpiProtocolGuid
|
329
DuetPkg/IsaAcpiDxe/PcatIsaAcpi.c
Normal file
329
DuetPkg/IsaAcpiDxe/PcatIsaAcpi.c
Normal file
@ -0,0 +1,329 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. 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.
|
||||
|
||||
|
||||
Module Name:
|
||||
|
||||
PcatIsaAcpi.c
|
||||
|
||||
Abstract:
|
||||
|
||||
EFI PCAT ISA ACPI Driver for a Generic PC Platform
|
||||
|
||||
Revision History
|
||||
|
||||
--*/
|
||||
|
||||
#include "PcatIsaAcpi.h"
|
||||
|
||||
//
|
||||
// PcatIsaAcpi Driver Binding Protocol
|
||||
//
|
||||
EFI_DRIVER_BINDING_PROTOCOL gPcatIsaAcpiDriverBinding = {
|
||||
PcatIsaAcpiDriverBindingSupported,
|
||||
PcatIsaAcpiDriverBindingStart,
|
||||
PcatIsaAcpiDriverBindingStop,
|
||||
0xa,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PcatIsaAcpiDriverEntryPoint (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
the entry point of the PcatIsaAcpi driver
|
||||
|
||||
Arguments:
|
||||
|
||||
Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
return EfiLibInstallDriverBindingComponentName2 (
|
||||
ImageHandle,
|
||||
SystemTable,
|
||||
&gPcatIsaAcpiDriverBinding,
|
||||
ImageHandle,
|
||||
&gPcatIsaAcpiComponentName,
|
||||
&gPcatIsaAcpiComponentName2
|
||||
);
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PcatIsaAcpiDriverBindingSupported (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE Controller,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
ControllerDriver Protocol Method
|
||||
|
||||
Arguments:
|
||||
|
||||
Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_PCI_IO_PROTOCOL *PciIo;
|
||||
PCI_TYPE00 Pci;
|
||||
|
||||
//
|
||||
// Get PciIo protocol instance
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
Controller,
|
||||
&gEfiPciIoProtocolGuid,
|
||||
&PciIo,
|
||||
This->DriverBindingHandle,
|
||||
Controller,
|
||||
EFI_OPEN_PROTOCOL_BY_DRIVER
|
||||
);
|
||||
if (EFI_ERROR(Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = PciIo->Pci.Read (
|
||||
PciIo,
|
||||
EfiPciIoWidthUint32,
|
||||
0,
|
||||
sizeof(Pci) / sizeof(UINT32),
|
||||
&Pci);
|
||||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
Status = EFI_UNSUPPORTED;
|
||||
if ((Pci.Hdr.Command & 0x03) == 0x03) {
|
||||
if (Pci.Hdr.ClassCode[2] == PCI_CLASS_BRIDGE) {
|
||||
//
|
||||
// See if this is a standard PCI to ISA Bridge from the Base Code and Class Code
|
||||
//
|
||||
if (Pci.Hdr.ClassCode[1] == PCI_CLASS_ISA) {
|
||||
Status = EFI_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// See if this is an Intel PCI to ISA bridge in Positive Decode Mode
|
||||
//
|
||||
if (Pci.Hdr.ClassCode[1] == PCI_CLASS_ISA_POSITIVE_DECODE &&
|
||||
Pci.Hdr.VendorId == 0x8086 &&
|
||||
Pci.Hdr.DeviceId == 0x7110) {
|
||||
Status = EFI_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gBS->CloseProtocol (
|
||||
Controller,
|
||||
&gEfiPciIoProtocolGuid,
|
||||
This->DriverBindingHandle,
|
||||
Controller
|
||||
);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PcatIsaAcpiDriverBindingStart (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE Controller,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Install EFI_ISA_ACPI_PROTOCOL
|
||||
|
||||
Arguments:
|
||||
|
||||
Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_PCI_IO_PROTOCOL *PciIo;
|
||||
PCAT_ISA_ACPI_DEV *PcatIsaAcpiDev;
|
||||
|
||||
PcatIsaAcpiDev = NULL;
|
||||
//
|
||||
// Open the PCI I/O Protocol Interface
|
||||
//
|
||||
PciIo = NULL;
|
||||
Status = gBS->OpenProtocol (
|
||||
Controller,
|
||||
&gEfiPciIoProtocolGuid,
|
||||
&PciIo,
|
||||
This->DriverBindingHandle,
|
||||
Controller,
|
||||
EFI_OPEN_PROTOCOL_BY_DRIVER
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Done;
|
||||
}
|
||||
|
||||
Status = PciIo->Attributes (
|
||||
PciIo,
|
||||
EfiPciIoAttributeOperationEnable,
|
||||
EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_ISA_IO | EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO,
|
||||
NULL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Done;
|
||||
}
|
||||
|
||||
//
|
||||
// Allocate memory for the PCAT ISA ACPI Device structure
|
||||
//
|
||||
PcatIsaAcpiDev = NULL;
|
||||
Status = gBS->AllocatePool (
|
||||
EfiBootServicesData,
|
||||
sizeof(PCAT_ISA_ACPI_DEV),
|
||||
&PcatIsaAcpiDev
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Done;
|
||||
}
|
||||
|
||||
//
|
||||
// Initialize the PCAT ISA ACPI Device structure
|
||||
//
|
||||
PcatIsaAcpiDev->Signature = PCAT_ISA_ACPI_DEV_SIGNATURE;
|
||||
PcatIsaAcpiDev->Handle = Controller;
|
||||
PcatIsaAcpiDev->PciIo = PciIo;
|
||||
|
||||
//
|
||||
// IsaAcpi interface
|
||||
//
|
||||
(PcatIsaAcpiDev->IsaAcpi).DeviceEnumerate = IsaDeviceEnumerate;
|
||||
(PcatIsaAcpiDev->IsaAcpi).SetPower = IsaDeviceSetPower;
|
||||
(PcatIsaAcpiDev->IsaAcpi).GetCurResource = IsaGetCurrentResource;
|
||||
(PcatIsaAcpiDev->IsaAcpi).GetPosResource = IsaGetPossibleResource;
|
||||
(PcatIsaAcpiDev->IsaAcpi).SetResource = IsaSetResource;
|
||||
(PcatIsaAcpiDev->IsaAcpi).EnableDevice = IsaEnableDevice;
|
||||
(PcatIsaAcpiDev->IsaAcpi).InitDevice = IsaInitDevice;
|
||||
(PcatIsaAcpiDev->IsaAcpi).InterfaceInit = IsaInterfaceInit;
|
||||
|
||||
//
|
||||
// Install the ISA ACPI Protocol interface
|
||||
//
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
&Controller,
|
||||
&gEfiIsaAcpiProtocolGuid, &PcatIsaAcpiDev->IsaAcpi,
|
||||
NULL
|
||||
);
|
||||
|
||||
Done:
|
||||
if (EFI_ERROR (Status)) {
|
||||
if (PciIo) {
|
||||
PciIo->Attributes (
|
||||
PciIo,
|
||||
EfiPciIoAttributeOperationDisable,
|
||||
EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_ISA_IO | EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO,
|
||||
NULL
|
||||
);
|
||||
}
|
||||
gBS->CloseProtocol (
|
||||
Controller,
|
||||
&gEfiPciIoProtocolGuid,
|
||||
This->DriverBindingHandle,
|
||||
Controller
|
||||
);
|
||||
if (PcatIsaAcpiDev != NULL) {
|
||||
gBS->FreePool (PcatIsaAcpiDev);
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PcatIsaAcpiDriverBindingStop (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE Controller,
|
||||
IN UINTN NumberOfChildren,
|
||||
IN EFI_HANDLE *ChildHandleBuffer
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Arguments:
|
||||
|
||||
Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_ISA_ACPI_PROTOCOL *IsaAcpi;
|
||||
PCAT_ISA_ACPI_DEV *PcatIsaAcpiDev;
|
||||
|
||||
//
|
||||
// Get the ISA ACPI Protocol Interface
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
Controller,
|
||||
&gEfiIsaAcpiProtocolGuid,
|
||||
&IsaAcpi,
|
||||
This->DriverBindingHandle,
|
||||
Controller,
|
||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Get the PCAT ISA ACPI Device structure from the ISA ACPI Protocol
|
||||
//
|
||||
PcatIsaAcpiDev = PCAT_ISA_ACPI_DEV_FROM_THIS (IsaAcpi);
|
||||
|
||||
PcatIsaAcpiDev->PciIo->Attributes (
|
||||
PcatIsaAcpiDev->PciIo,
|
||||
EfiPciIoAttributeOperationDisable,
|
||||
EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_ISA_IO | EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO,
|
||||
NULL
|
||||
);
|
||||
|
||||
//
|
||||
// Uninstall protocol interface: EFI_ISA_ACPI_PROTOCOL
|
||||
//
|
||||
Status = gBS->UninstallProtocolInterface (
|
||||
Controller,
|
||||
&gEfiIsaAcpiProtocolGuid, &PcatIsaAcpiDev->IsaAcpi
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
gBS->CloseProtocol (
|
||||
Controller,
|
||||
&gEfiPciIoProtocolGuid,
|
||||
This->DriverBindingHandle,
|
||||
Controller
|
||||
);
|
||||
|
||||
gBS->FreePool (PcatIsaAcpiDev);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
159
DuetPkg/IsaAcpiDxe/PcatIsaAcpi.h
Normal file
159
DuetPkg/IsaAcpiDxe/PcatIsaAcpi.h
Normal file
@ -0,0 +1,159 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006 - 2007, Intel Corporation
|
||||
All rights reserved. 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.
|
||||
|
||||
|
||||
Module Name:
|
||||
|
||||
PcatIsaAcpi.h
|
||||
|
||||
Abstract:
|
||||
|
||||
EFI PCAT ISA ACPI Driver for a Generic PC Platform
|
||||
|
||||
Revision History
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef _PCAT_ISA_ACPI_H_
|
||||
#define _PCAT_ISA_ACPI_H_
|
||||
|
||||
#include <PiDxe.h>
|
||||
|
||||
#include <IndustryStandard/Pci.h>
|
||||
|
||||
#include <Protocol/DevicePath.h>
|
||||
#include <Protocol/PciIo.h>
|
||||
#include <Protocol/IsaIo.h>
|
||||
#include <Protocol/DriverBinding.h>
|
||||
#include <Protocol/ComponentName.h>
|
||||
#include <Protocol/ComponentName2.h>
|
||||
|
||||
|
||||
#include <Library/UefiLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
|
||||
#include <Protocol/IsaAcpi.h>
|
||||
//
|
||||
// PCAT ISA ACPI device private data structure
|
||||
//
|
||||
#define PCAT_ISA_ACPI_DEV_SIGNATURE EFI_SIGNATURE_32('L','P','C','D')
|
||||
|
||||
typedef struct {
|
||||
UINTN Signature;
|
||||
EFI_HANDLE Handle;
|
||||
EFI_ISA_ACPI_PROTOCOL IsaAcpi;
|
||||
EFI_PCI_IO_PROTOCOL *PciIo;
|
||||
} PCAT_ISA_ACPI_DEV;
|
||||
|
||||
#define PCAT_ISA_ACPI_DEV_FROM_THIS(a) _CR(a, PCAT_ISA_ACPI_DEV, IsaAcpi)
|
||||
|
||||
//
|
||||
// Global Variables
|
||||
//
|
||||
extern EFI_DRIVER_BINDING_PROTOCOL gPcatIsaAcpiDriverBinding;
|
||||
|
||||
extern EFI_COMPONENT_NAME2_PROTOCOL gPcatIsaAcpiComponentName2;
|
||||
|
||||
extern EFI_COMPONENT_NAME_PROTOCOL gPcatIsaAcpiComponentName;
|
||||
|
||||
|
||||
//
|
||||
// Prototypes for Driver model protocol interface
|
||||
//
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PcatIsaAcpiDriverBindingSupported (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE Controller,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PcatIsaAcpiDriverBindingStart (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE Controller,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PcatIsaAcpiDriverBindingStop (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE Controller,
|
||||
IN UINTN NumberOfChildren,
|
||||
IN EFI_HANDLE *ChildHandleBuffer
|
||||
);
|
||||
|
||||
//
|
||||
// Prototypes for the ISA ACPI protocol interface
|
||||
//
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
IsaDeviceEnumerate (
|
||||
IN EFI_ISA_ACPI_PROTOCOL *This,
|
||||
OUT EFI_ISA_ACPI_DEVICE_ID **Device
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
IsaDeviceSetPower (
|
||||
IN EFI_ISA_ACPI_PROTOCOL *This,
|
||||
IN EFI_ISA_ACPI_DEVICE_ID *Device,
|
||||
IN BOOLEAN OnOff
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
IsaGetCurrentResource (
|
||||
IN EFI_ISA_ACPI_PROTOCOL *This,
|
||||
IN EFI_ISA_ACPI_DEVICE_ID *Device,
|
||||
OUT EFI_ISA_ACPI_RESOURCE_LIST **ResourceList
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
IsaGetPossibleResource (
|
||||
IN EFI_ISA_ACPI_PROTOCOL *This,
|
||||
IN EFI_ISA_ACPI_DEVICE_ID *Device,
|
||||
OUT EFI_ISA_ACPI_RESOURCE_LIST **ResourceList
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
IsaSetResource (
|
||||
IN EFI_ISA_ACPI_PROTOCOL *This,
|
||||
IN EFI_ISA_ACPI_DEVICE_ID *Device,
|
||||
IN EFI_ISA_ACPI_RESOURCE_LIST *ResourceList
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
IsaEnableDevice (
|
||||
IN EFI_ISA_ACPI_PROTOCOL *This,
|
||||
IN EFI_ISA_ACPI_DEVICE_ID *Device,
|
||||
IN BOOLEAN Enable
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
IsaInitDevice (
|
||||
IN EFI_ISA_ACPI_PROTOCOL *This,
|
||||
IN EFI_ISA_ACPI_DEVICE_ID *Device
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
IsaInterfaceInit (
|
||||
IN EFI_ISA_ACPI_PROTOCOL *This
|
||||
);
|
||||
|
||||
#endif
|
79
DuetPkg/KbcResetDxe/Ia32/Ia32Reset.c
Normal file
79
DuetPkg/KbcResetDxe/Ia32/Ia32Reset.c
Normal file
@ -0,0 +1,79 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. 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.
|
||||
|
||||
Module Name:
|
||||
Ia32Reset.c
|
||||
|
||||
Abstract:
|
||||
|
||||
--*/
|
||||
|
||||
#include "Reset.h"
|
||||
|
||||
//
|
||||
// The handle onto which the Reset Architectural Protocol is installed
|
||||
//
|
||||
EFI_HANDLE mResetHandle = NULL;
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
InitializeReset (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Initialize the state information for the Reset Architectural Protocol
|
||||
|
||||
Arguments:
|
||||
|
||||
ImageHandle of the loaded driver
|
||||
Pointer to the System Table
|
||||
|
||||
Returns:
|
||||
|
||||
Status
|
||||
|
||||
EFI_SUCCESS - thread can be successfully created
|
||||
EFI_OUT_OF_RESOURCES - cannot allocate protocol data structure
|
||||
EFI_DEVICE_ERROR - cannot create the timer service
|
||||
|
||||
--*/
|
||||
// TODO: SystemTable - add argument and description to function comment
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
//
|
||||
// Make sure the Reset Architectural Protocol is not already installed in the system
|
||||
//
|
||||
ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiResetArchProtocolGuid);
|
||||
|
||||
//
|
||||
// Hook the runtime service table
|
||||
//
|
||||
SystemTable->RuntimeServices->ResetSystem = KbcResetSystem;
|
||||
|
||||
//
|
||||
// Now install the Reset RT AP on a new handle
|
||||
//
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
&mResetHandle,
|
||||
&gEfiResetArchProtocolGuid,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
return Status;
|
||||
}
|
27
DuetPkg/KbcResetDxe/Ia32Reset.dxs
Normal file
27
DuetPkg/KbcResetDxe/Ia32Reset.dxs
Normal file
@ -0,0 +1,27 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. 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.
|
||||
|
||||
Module Name:
|
||||
Ia32Reset.dxs
|
||||
|
||||
Abstract:
|
||||
Dependency expression source file.
|
||||
|
||||
--*/
|
||||
|
||||
|
||||
#include "EfiDepex.h"
|
||||
|
||||
#include EFI_PROTOCOL_DEFINITION (CpuIO)
|
||||
|
||||
DEPENDENCY_START
|
||||
EFI_CPU_IO_PROTOCOL_GUID
|
||||
DEPENDENCY_END
|
117
DuetPkg/KbcResetDxe/Ipf/IpfReset.c
Normal file
117
DuetPkg/KbcResetDxe/Ipf/IpfReset.c
Normal file
@ -0,0 +1,117 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. 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.
|
||||
|
||||
Module Name:
|
||||
IpfReset.c
|
||||
|
||||
Abstract:
|
||||
|
||||
--*/
|
||||
|
||||
#include "Cf9Reset.h"
|
||||
|
||||
SAL_RETURN_REGS
|
||||
ResetEsalServicesClassCommonEntry (
|
||||
IN UINT64 FunctionId,
|
||||
IN UINT64 Arg2,
|
||||
IN UINT64 Arg3,
|
||||
IN UINT64 Arg4,
|
||||
IN UINT64 Arg5,
|
||||
IN UINT64 Arg6,
|
||||
IN UINT64 Arg7,
|
||||
IN UINT64 Arg8,
|
||||
IN SAL_EXTENDED_SAL_PROC ExtendedSalProc,
|
||||
IN BOOLEAN VirtualMode,
|
||||
IN VOID *Global
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Main entry for Extended SAL Reset Services
|
||||
|
||||
Arguments:
|
||||
|
||||
FunctionId Function Id which needed to be called.
|
||||
Arg2 EFI_RESET_TYPE, whether WARM of COLD reset
|
||||
Arg3 Last EFI_STATUS
|
||||
Arg4 Data Size of UNICODE STRING passed in ARG5
|
||||
Arg5 Unicode String which CHAR16*
|
||||
|
||||
Returns:
|
||||
|
||||
SAL_RETURN_REGS
|
||||
|
||||
--*/
|
||||
// TODO: Arg6 - add argument and description to function comment
|
||||
// TODO: Arg7 - add argument and description to function comment
|
||||
// TODO: Arg8 - add argument and description to function comment
|
||||
// TODO: ExtendedSalProc - add argument and description to function comment
|
||||
// TODO: VirtualMode - add argument and description to function comment
|
||||
// TODO: Global - add argument and description to function comment
|
||||
{
|
||||
SAL_RETURN_REGS ReturnVal;
|
||||
|
||||
switch (FunctionId) {
|
||||
case ResetSystem:
|
||||
KbcResetSystem (Arg2, Arg3, (UINTN) Arg4, (VOID *) Arg5);
|
||||
ReturnVal.Status = EFI_SUCCESS;
|
||||
break;
|
||||
|
||||
default:
|
||||
ReturnVal.Status = EFI_SAL_INVALID_ARGUMENT;
|
||||
break;
|
||||
}
|
||||
|
||||
return ReturnVal;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
InitializeReset (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Initialize the state information for the Reset Architectural Protocol
|
||||
|
||||
Arguments:
|
||||
|
||||
ImageHandle of the loaded driver
|
||||
Pointer to the System Table
|
||||
|
||||
Returns:
|
||||
|
||||
Status
|
||||
|
||||
EFI_SUCCESS - thread can be successfully created
|
||||
EFI_OUT_OF_RESOURCES - cannot allocate protocol data structure
|
||||
EFI_DEVICE_ERROR - cannot create the timer service
|
||||
|
||||
--*/
|
||||
// TODO: SystemTable - add argument and description to function comment
|
||||
{
|
||||
EfiInitializeRuntimeDriverLib (ImageHandle, SystemTable, NULL);
|
||||
|
||||
RegisterEsalClass (
|
||||
&gEfiExtendedSalResetServicesProtocolGuid,
|
||||
NULL,
|
||||
ResetEsalServicesClassCommonEntry,
|
||||
ResetSystem,
|
||||
NULL
|
||||
);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
27
DuetPkg/KbcResetDxe/IpfReset.dxs
Normal file
27
DuetPkg/KbcResetDxe/IpfReset.dxs
Normal file
@ -0,0 +1,27 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. 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.
|
||||
|
||||
Module Name:
|
||||
IpfReset.dxs
|
||||
|
||||
Abstract:
|
||||
Dependency expression source file.
|
||||
|
||||
--*/
|
||||
|
||||
|
||||
#include "EfiDepex.h"
|
||||
|
||||
#include EFI_PROTOCOL_DEFINITION (ExtendedSalGuid)
|
||||
|
||||
DEPENDENCY_START
|
||||
EFI_EXTENDED_SAL_BASE_IO_SERVICES_PROTOCOL_GUID
|
||||
DEPENDENCY_END
|
70
DuetPkg/KbcResetDxe/Reset.c
Normal file
70
DuetPkg/KbcResetDxe/Reset.c
Normal file
@ -0,0 +1,70 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. 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.
|
||||
|
||||
Module Name:
|
||||
Reset.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Reset Architectural Protocol implementation
|
||||
|
||||
--*/
|
||||
|
||||
#include "Reset.h"
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
KbcResetSystem (
|
||||
IN EFI_RESET_TYPE ResetType,
|
||||
IN EFI_STATUS ResetStatus,
|
||||
IN UINTN DataSize,
|
||||
IN CHAR16 *ResetData OPTIONAL
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Reset the system.
|
||||
|
||||
Arguments:
|
||||
|
||||
ResetType - warm or cold
|
||||
ResetStatus - possible cause of reset
|
||||
DataSize - Size of ResetData in bytes
|
||||
ResetData - Optional Unicode string
|
||||
For details, see efiapi.h
|
||||
|
||||
Returns:
|
||||
Does not return if the reset takes place.
|
||||
EFI_INVALID_PARAMETER If ResetType is invalid.
|
||||
|
||||
--*/
|
||||
{
|
||||
UINT8 Data;
|
||||
|
||||
switch (ResetType) {
|
||||
case EfiResetWarm:
|
||||
case EfiResetCold:
|
||||
case EfiResetShutdown:
|
||||
Data = 0xfe;
|
||||
IoWrite8 (0x64, Data);
|
||||
break;
|
||||
|
||||
default:
|
||||
return ;
|
||||
}
|
||||
|
||||
//
|
||||
// Given we should have reset getting here would be bad
|
||||
//
|
||||
ASSERT (FALSE);
|
||||
}
|
||||
|
85
DuetPkg/KbcResetDxe/Reset.h
Normal file
85
DuetPkg/KbcResetDxe/Reset.h
Normal file
@ -0,0 +1,85 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. 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.
|
||||
|
||||
Module Name:
|
||||
Reset.h
|
||||
|
||||
Abstract:
|
||||
|
||||
some definitions for reset
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef _KBC_RESET_H
|
||||
#define _KBC_RESET_H
|
||||
|
||||
#include <PiDxe.h>
|
||||
|
||||
#include <Library/IoLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
|
||||
#include <Protocol/Reset.h>
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
InitializeReset (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
ImageHandle - TODO: add argument description
|
||||
SystemTable - TODO: add argument description
|
||||
|
||||
Returns:
|
||||
|
||||
TODO: add return values
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
KbcResetSystem (
|
||||
IN EFI_RESET_TYPE ResetType,
|
||||
IN EFI_STATUS ResetStatus,
|
||||
IN UINTN DataSize,
|
||||
IN CHAR16 *ResetData OPTIONAL
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
ResetType - TODO: add argument description
|
||||
ResetStatus - TODO: add argument description
|
||||
DataSize - TODO: add argument description
|
||||
ResetData - TODO: add argument description
|
||||
|
||||
Returns:
|
||||
|
||||
TODO: add return values
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
#endif
|
59
DuetPkg/KbcResetDxe/Reset.inf
Normal file
59
DuetPkg/KbcResetDxe/Reset.inf
Normal file
@ -0,0 +1,59 @@
|
||||
#/*++
|
||||
#
|
||||
# Copyright (c) 2006, Intel Corporation
|
||||
# All rights reserved. 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.
|
||||
#
|
||||
# Module Name:
|
||||
# Reset.inf
|
||||
#
|
||||
# Abstract:
|
||||
#
|
||||
#--*/
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = KbcReset
|
||||
FILE_GUID = 6F0198AA-1F1D-426D-AE3E-39AB633FCC28
|
||||
MODULE_TYPE = DXE_RUNTIME_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
EDK_RELEASE_VERSION = 0x00020000
|
||||
EFI_SPECIFICATION_VERSION = 0x00020000
|
||||
|
||||
ENTRY_POINT = InitializeReset
|
||||
|
||||
[Packages]
|
||||
DuetPkg/DuetPkg.dec
|
||||
MdePkg/MdePkg.dec
|
||||
IntelFrameworkPkg/IntelFrameworkPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
DebugLib
|
||||
UefiBootServicesTableLib
|
||||
UefiDriverEntryPoint
|
||||
IoLib
|
||||
|
||||
[Sources.common]
|
||||
Reset.c
|
||||
Reset.h
|
||||
|
||||
[Sources.ipf]
|
||||
Ipf\IpfReset.c
|
||||
|
||||
[Sources.ia32]
|
||||
Ia32\Ia32Reset.c
|
||||
|
||||
[Sources.x64]
|
||||
x64\x64Reset.c
|
||||
|
||||
[Protocols]
|
||||
gEfiResetArchProtocolGuid
|
||||
|
||||
[Depex]
|
||||
gEfiCpuIoProtocolGuid
|
||||
|
||||
|
79
DuetPkg/KbcResetDxe/x64/x64Reset.c
Normal file
79
DuetPkg/KbcResetDxe/x64/x64Reset.c
Normal file
@ -0,0 +1,79 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. 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.
|
||||
|
||||
Module Name:
|
||||
x64Reset.c
|
||||
|
||||
Abstract:
|
||||
|
||||
--*/
|
||||
|
||||
#include "Reset.h"
|
||||
|
||||
//
|
||||
// The handle onto which the Reset Architectural Protocol is installed
|
||||
//
|
||||
EFI_HANDLE mResetHandle = NULL;
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
InitializeReset (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Initialize the state information for the Reset Architectural Protocol
|
||||
|
||||
Arguments:
|
||||
|
||||
ImageHandle of the loaded driver
|
||||
Pointer to the System Table
|
||||
|
||||
Returns:
|
||||
|
||||
Status
|
||||
|
||||
EFI_SUCCESS - thread can be successfully created
|
||||
EFI_OUT_OF_RESOURCES - cannot allocate protocol data structure
|
||||
EFI_DEVICE_ERROR - cannot create the timer service
|
||||
|
||||
--*/
|
||||
// TODO: SystemTable - add argument and description to function comment
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
//
|
||||
// Make sure the Reset Architectural Protocol is not already installed in the system
|
||||
//
|
||||
ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiResetArchProtocolGuid);
|
||||
|
||||
//
|
||||
// Hook the runtime service table
|
||||
//
|
||||
SystemTable->RuntimeServices->ResetSystem = KbcResetSystem;
|
||||
|
||||
//
|
||||
// Now install the Reset RT AP on a new handle
|
||||
//
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
&mResetHandle,
|
||||
&gEfiResetArchProtocolGuid,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
return Status;
|
||||
}
|
27
DuetPkg/KbcResetDxe/x64Reset.dxs
Normal file
27
DuetPkg/KbcResetDxe/x64Reset.dxs
Normal file
@ -0,0 +1,27 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. 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.
|
||||
|
||||
Module Name:
|
||||
x64Reset.dxs
|
||||
|
||||
Abstract:
|
||||
Dependency expression source file.
|
||||
|
||||
--*/
|
||||
|
||||
|
||||
#include "EfiDepex.h"
|
||||
|
||||
#include EFI_PROTOCOL_DEFINITION (CpuIO)
|
||||
|
||||
DEPENDENCY_START
|
||||
EFI_CPU_IO_PROTOCOL_GUID
|
||||
DEPENDENCY_END
|
201
DuetPkg/LegacyMetronome/Metronome.c
Normal file
201
DuetPkg/LegacyMetronome/Metronome.c
Normal file
@ -0,0 +1,201 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2005, Intel Corporation
|
||||
All rights reserved. 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.
|
||||
|
||||
Module Name:
|
||||
LegacyMetronome.c
|
||||
|
||||
Abstract:
|
||||
|
||||
This contains the installation function for the driver.
|
||||
|
||||
--*/
|
||||
|
||||
#include "Metronome.h"
|
||||
|
||||
//
|
||||
// Handle for the Metronome Architectural Protocol instance produced by this driver
|
||||
//
|
||||
EFI_HANDLE mMetronomeHandle = NULL;
|
||||
|
||||
//
|
||||
// The Metronome Architectural Protocol instance produced by this driver
|
||||
//
|
||||
EFI_METRONOME_ARCH_PROTOCOL mMetronome = {
|
||||
WaitForTick,
|
||||
TICK_PERIOD
|
||||
};
|
||||
|
||||
//
|
||||
// The CPU I/O Protocol used to access system hardware
|
||||
//
|
||||
EFI_CPU_IO_PROTOCOL *mCpuIo = NULL;
|
||||
|
||||
//
|
||||
// Worker Functions
|
||||
//
|
||||
VOID
|
||||
IoWrite8 (
|
||||
UINT16 Port,
|
||||
UINT8 Data
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Write an 8 bit value to an I/O port and save it to the S3 script
|
||||
|
||||
Arguments:
|
||||
|
||||
Returns:
|
||||
|
||||
None.
|
||||
|
||||
--*/
|
||||
// TODO: Port - add argument and description to function comment
|
||||
// TODO: Data - add argument and description to function comment
|
||||
{
|
||||
mCpuIo->Io.Write (
|
||||
mCpuIo,
|
||||
EfiCpuIoWidthUint8,
|
||||
Port,
|
||||
1,
|
||||
&Data
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
UINT8
|
||||
ReadRefresh (
|
||||
VOID
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Read the refresh bit from the REFRESH_PORT
|
||||
|
||||
Arguments:
|
||||
|
||||
Returns:
|
||||
|
||||
None.
|
||||
|
||||
--*/
|
||||
{
|
||||
UINT8 Data;
|
||||
|
||||
mCpuIo->Io.Read (
|
||||
mCpuIo,
|
||||
EfiCpuIoWidthUint8,
|
||||
REFRESH_PORT,
|
||||
1,
|
||||
&Data
|
||||
);
|
||||
return (UINT8) (Data & REFRESH_ON);
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
WaitForTick (
|
||||
IN EFI_METRONOME_ARCH_PROTOCOL *This,
|
||||
IN UINT32 TickNumber
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Waits for the TickNumber of ticks from a known platform time source.
|
||||
|
||||
Arguments:
|
||||
|
||||
This Pointer to the protocol instance.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS If number of ticks occurred.
|
||||
EFI_NOT_FOUND Could not locate CPU IO protocol
|
||||
|
||||
--*/
|
||||
// TODO: TickNumber - add argument and description to function comment
|
||||
{
|
||||
//
|
||||
// Wait for TickNumber toggles of the Refresh bit
|
||||
//
|
||||
for (; TickNumber != 0x00; TickNumber--) {
|
||||
while (ReadRefresh () == REFRESH_ON)
|
||||
;
|
||||
while (ReadRefresh () == REFRESH_OFF)
|
||||
;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
InstallMetronome (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Install the LegacyMetronome driver. Loads a Metronome Arch Protocol based
|
||||
on the Port 61 timer.
|
||||
|
||||
Arguments:
|
||||
|
||||
(Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - Metronome Architectural Protocol Installed
|
||||
|
||||
--*/
|
||||
// TODO: ImageHandle - add argument and description to function comment
|
||||
// TODO: SystemTable - add argument and description to function comment
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
//
|
||||
// Make sure the Metronome Architectural Protocol is not already installed in the system
|
||||
//
|
||||
ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiMetronomeArchProtocolGuid);
|
||||
|
||||
//
|
||||
// Get the CPU I/O Protocol that this driver requires
|
||||
// If the CPU I/O Protocol is not found, then ASSERT because the dependency expression
|
||||
// should guarantee that it is present in the handle database.
|
||||
//
|
||||
Status = gBS->LocateProtocol (&gEfiCpuIoProtocolGuid, NULL, &mCpuIo);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
//
|
||||
// Program port 61 timer 1 as refresh timer. We could use ACPI timer in the
|
||||
// future.
|
||||
//
|
||||
IoWrite8 (TIMER1_CONTROL_PORT, LOAD_COUNTER1_LSB);
|
||||
IoWrite8 (TIMER1_COUNT_PORT, COUNTER1_COUNT);
|
||||
|
||||
//
|
||||
// Install on a new handle
|
||||
//
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
&mMetronomeHandle,
|
||||
&gEfiMetronomeArchProtocolGuid,
|
||||
&mMetronome,
|
||||
NULL
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
return Status;
|
||||
}
|
28
DuetPkg/LegacyMetronome/Metronome.dxs
Normal file
28
DuetPkg/LegacyMetronome/Metronome.dxs
Normal file
@ -0,0 +1,28 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2005, Intel Corporation
|
||||
All rights reserved. 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.
|
||||
|
||||
Module Name:
|
||||
LegacyMetronome.dxs
|
||||
|
||||
Abstract:
|
||||
Dependency expression source file.
|
||||
|
||||
--*/
|
||||
|
||||
|
||||
#include "EfiDepex.h"
|
||||
|
||||
#include EFI_PROTOCOL_DEFINITION (CpuIo)
|
||||
|
||||
DEPENDENCY_START
|
||||
EFI_CPU_IO_PROTOCOL_GUID
|
||||
DEPENDENCY_END
|
||||
|
75
DuetPkg/LegacyMetronome/Metronome.h
Normal file
75
DuetPkg/LegacyMetronome/Metronome.h
Normal file
@ -0,0 +1,75 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2005, Intel Corporation
|
||||
All rights reserved. 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.
|
||||
|
||||
Module Name:
|
||||
LegacyMetronome.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Driver implementing the EFI 2.0 metronome protocol using the legacy PORT 61
|
||||
timer.
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef _LEGACY_METRONOME_H
|
||||
#define _LEGACY_METRONOME_H
|
||||
|
||||
//
|
||||
// Statements that include other files
|
||||
//
|
||||
#include <PiDxe.h>
|
||||
|
||||
#include <Protocol/CpuIo.h>
|
||||
#include <Protocol/Metronome.h>
|
||||
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
|
||||
//
|
||||
// Private definitions
|
||||
//
|
||||
#define TICK_PERIOD 300
|
||||
#define REFRESH_PORT 0x61
|
||||
#define REFRESH_ON 0x10
|
||||
#define REFRESH_OFF 0x00
|
||||
#define TIMER1_CONTROL_PORT 0x43
|
||||
#define TIMER1_COUNT_PORT 0x41
|
||||
#define LOAD_COUNTER1_LSB 0x54
|
||||
#define COUNTER1_COUNT 0x12
|
||||
|
||||
//
|
||||
// Function Prototypes
|
||||
//
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
WaitForTick (
|
||||
IN EFI_METRONOME_ARCH_PROTOCOL *This,
|
||||
IN UINT32 TickNumber
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
This - TODO: add argument description
|
||||
TickNumber - TODO: add argument description
|
||||
|
||||
Returns:
|
||||
|
||||
TODO: add return values
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
#endif
|
48
DuetPkg/LegacyMetronome/Metronome.inf
Normal file
48
DuetPkg/LegacyMetronome/Metronome.inf
Normal file
@ -0,0 +1,48 @@
|
||||
#/*++
|
||||
#
|
||||
# Copyright (c) 2005, Intel Corporation
|
||||
# All rights reserved. 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.
|
||||
#
|
||||
# Module Name:
|
||||
#
|
||||
# Abstract:
|
||||
#
|
||||
#--*/
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = Metronome
|
||||
FILE_GUID = 07A9330A-F347-11d4-9A49-0090273FC14D
|
||||
MODULE_TYPE = DXE_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
EDK_RELEASE_VERSION = 0x00020000
|
||||
EFI_SPECIFICATION_VERSION = 0x00020000
|
||||
|
||||
ENTRY_POINT = InstallMetronome
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
IntelFrameworkPkg/IntelFrameworkPkg.dec
|
||||
DuetPkg/DuetPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
UefiDriverEntryPoint
|
||||
DebugLib
|
||||
UefiBootServicesTableLib
|
||||
|
||||
[Sources.common]
|
||||
Metronome.c
|
||||
Metronome.h
|
||||
|
||||
[Protocols]
|
||||
gEfiMetronomeArchProtocolGuid
|
||||
gEfiCpuIoProtocolGuid
|
||||
|
||||
[Depex]
|
||||
gEfiCpuIoProtocolGuid
|
1720
DuetPkg/Library/DuetBdsLib/BdsPlatform.c
Normal file
1720
DuetPkg/Library/DuetBdsLib/BdsPlatform.c
Normal file
File diff suppressed because it is too large
Load Diff
312
DuetPkg/Library/DuetBdsLib/BdsPlatform.h
Normal file
312
DuetPkg/Library/DuetBdsLib/BdsPlatform.h
Normal file
@ -0,0 +1,312 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006 - 2007, Intel Corporation
|
||||
All rights reserved. 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.
|
||||
|
||||
Module Name:
|
||||
|
||||
BdsPlatform.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Head file for BDS Platform specific code
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef _PLATFORM_SPECIFIC_BDS_PLATFORM_H_
|
||||
#define _PLATFORM_SPECIFIC_BDS_PLATFORM_H_
|
||||
|
||||
|
||||
#include <PiDxe.h>
|
||||
|
||||
#include <IndustryStandard/Pci.h>
|
||||
#include <IndustryStandard/Acpi.h>
|
||||
#include <IndustryStandard/Smbios.h>
|
||||
#include <IndustryStandard/LegacyBiosMpTable.h>
|
||||
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/PcdLib.h>
|
||||
#include <Library/GenericBdsLib.h>
|
||||
#include <Library/PlatformBdsLib.h>
|
||||
#include <Library/GraphicsLib.h>
|
||||
#include <Library/HobLib.h>
|
||||
#include <Library/UefiLib.h>
|
||||
#include <Library/DxeServicesTableLib.h>
|
||||
#include <Library/DevicePathLib.h>
|
||||
|
||||
#include <Protocol/PciIo.h>
|
||||
|
||||
#include <Guid/Bmp.h>
|
||||
#include <Guid/Acpi.h>
|
||||
#include <Guid/Smbios.h>
|
||||
#include <Guid/Mps.h>
|
||||
#include <Guid/HobList.h>
|
||||
#include <Guid/PciExpressBaseAddress.h>
|
||||
#include <Guid/GlobalVariable.h>
|
||||
|
||||
extern BDS_CONSOLE_CONNECT_ENTRY gPlatformConsole[];
|
||||
extern EFI_DEVICE_PATH_PROTOCOL *gPlatformConnectSequence[];
|
||||
extern EFI_DEVICE_PATH_PROTOCOL *gPlatformDriverOption[];
|
||||
extern EFI_DEVICE_PATH_PROTOCOL *gPlatformRootBridges[];
|
||||
extern ACPI_HID_DEVICE_PATH gPnpPs2KeyboardDeviceNode;
|
||||
extern ACPI_HID_DEVICE_PATH gPnp16550ComPortDeviceNode;
|
||||
extern UART_DEVICE_PATH gUartDeviceNode;
|
||||
extern VENDOR_DEVICE_PATH gTerminalTypeDeviceNode;
|
||||
//
|
||||
//
|
||||
//
|
||||
#define VarConsoleInpDev L"ConInDev"
|
||||
#define VarConsoleInp L"ConIn"
|
||||
#define VarConsoleOutDev L"ConOutDev"
|
||||
#define VarConsoleOut L"ConOut"
|
||||
#define VarErrorOutDev L"ErrOutDev"
|
||||
#define VarErrorOut L"ErrOut"
|
||||
|
||||
#define PCI_DEVICE_PATH_NODE(Func, Dev) \
|
||||
{ \
|
||||
HARDWARE_DEVICE_PATH, \
|
||||
HW_PCI_DP, \
|
||||
(UINT8) (sizeof (PCI_DEVICE_PATH)), \
|
||||
(UINT8) ((sizeof (PCI_DEVICE_PATH)) >> 8), \
|
||||
(Func), \
|
||||
(Dev) \
|
||||
}
|
||||
|
||||
#define PNPID_DEVICE_PATH_NODE(PnpId) \
|
||||
{ \
|
||||
ACPI_DEVICE_PATH, \
|
||||
ACPI_DP, \
|
||||
(UINT8) (sizeof (ACPI_HID_DEVICE_PATH)), \
|
||||
(UINT8) ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8), \
|
||||
EISA_PNP_ID((PnpId)), \
|
||||
0 \
|
||||
}
|
||||
|
||||
#define gPciRootBridge \
|
||||
PNPID_DEVICE_PATH_NODE(0x0A03)
|
||||
|
||||
#define gPciIsaBridge \
|
||||
PCI_DEVICE_PATH_NODE(0, 0x1f)
|
||||
|
||||
#define gP2PBridge \
|
||||
PCI_DEVICE_PATH_NODE(0, 0x1e)
|
||||
|
||||
#define gPnpPs2Keyboard \
|
||||
PNPID_DEVICE_PATH_NODE(0x0303)
|
||||
|
||||
#define gPnp16550ComPort \
|
||||
PNPID_DEVICE_PATH_NODE(0x0501)
|
||||
|
||||
#define gUart \
|
||||
{ \
|
||||
MESSAGING_DEVICE_PATH, \
|
||||
MSG_UART_DP, \
|
||||
(UINT8) (sizeof (UART_DEVICE_PATH)), \
|
||||
(UINT8) ((sizeof (UART_DEVICE_PATH)) >> 8), \
|
||||
0, \
|
||||
115200, \
|
||||
8, \
|
||||
1, \
|
||||
1 \
|
||||
}
|
||||
|
||||
#define gPcAnsiTerminal \
|
||||
{ \
|
||||
MESSAGING_DEVICE_PATH, \
|
||||
MSG_VENDOR_DP, \
|
||||
(UINT8) (sizeof (VENDOR_DEVICE_PATH)), \
|
||||
(UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8), \
|
||||
DEVICE_PATH_MESSAGING_PC_ANSI \
|
||||
}
|
||||
|
||||
#define gEndEntire \
|
||||
{ \
|
||||
END_DEVICE_PATH_TYPE, \
|
||||
END_ENTIRE_DEVICE_PATH_SUBTYPE, \
|
||||
END_DEVICE_PATH_LENGTH, \
|
||||
0 \
|
||||
}
|
||||
|
||||
#define PCI_CLASS_SCC 0x07
|
||||
#define PCI_SUBCLASS_SERIAL 0x00
|
||||
#define PCI_IF_16550 0x02
|
||||
#define IS_PCI_16550SERIAL(_p) IS_CLASS3 (_p, PCI_CLASS_SCC, PCI_SUBCLASS_SERIAL, PCI_IF_16550)
|
||||
|
||||
#define EFI_SYSTEM_TABLE_MAX_ADDRESS 0xFFFFFFFF
|
||||
#define SYS_TABLE_PAD(ptr) (((~ptr) +1) & 0x07 )
|
||||
//
|
||||
// Platform Root Bridge
|
||||
//
|
||||
typedef struct {
|
||||
ACPI_HID_DEVICE_PATH PciRootBridge;
|
||||
EFI_DEVICE_PATH_PROTOCOL End;
|
||||
} PLATFORM_ROOT_BRIDGE_DEVICE_PATH;
|
||||
|
||||
typedef struct {
|
||||
ACPI_HID_DEVICE_PATH PciRootBridge;
|
||||
PCI_DEVICE_PATH IsaBridge;
|
||||
ACPI_HID_DEVICE_PATH Keyboard;
|
||||
EFI_DEVICE_PATH_PROTOCOL End;
|
||||
} PLATFORM_DUMMY_ISA_KEYBOARD_DEVICE_PATH;
|
||||
|
||||
typedef struct {
|
||||
ACPI_HID_DEVICE_PATH PciRootBridge;
|
||||
PCI_DEVICE_PATH IsaBridge;
|
||||
ACPI_HID_DEVICE_PATH IsaSerial;
|
||||
UART_DEVICE_PATH Uart;
|
||||
VENDOR_DEVICE_PATH TerminalType;
|
||||
EFI_DEVICE_PATH_PROTOCOL End;
|
||||
} PLATFORM_DUMMY_ISA_SERIAL_DEVICE_PATH;
|
||||
|
||||
typedef struct {
|
||||
ACPI_HID_DEVICE_PATH PciRootBridge;
|
||||
PCI_DEVICE_PATH VgaDevice;
|
||||
EFI_DEVICE_PATH_PROTOCOL End;
|
||||
} PLATFORM_DUMMY_PCI_VGA_DEVICE_PATH;
|
||||
|
||||
typedef struct {
|
||||
ACPI_HID_DEVICE_PATH PciRootBridge;
|
||||
PCI_DEVICE_PATH PciBridge;
|
||||
PCI_DEVICE_PATH SerialDevice;
|
||||
UART_DEVICE_PATH Uart;
|
||||
VENDOR_DEVICE_PATH TerminalType;
|
||||
EFI_DEVICE_PATH_PROTOCOL End;
|
||||
} PLATFORM_DUMMY_PCI_SERIAL_DEVICE_PATH;
|
||||
|
||||
//
|
||||
// the short form device path for Usb keyboard
|
||||
//
|
||||
#define CLASS_HID 3
|
||||
#define SUBCLASS_BOOT 1
|
||||
#define PROTOCOL_KEYBOARD 1
|
||||
|
||||
typedef struct {
|
||||
USB_CLASS_DEVICE_PATH UsbClass;
|
||||
EFI_DEVICE_PATH_PROTOCOL End;
|
||||
} USB_CLASS_FORMAT_DEVICE_PATH;
|
||||
|
||||
extern PLATFORM_ROOT_BRIDGE_DEVICE_PATH gPlatformRootBridge0;
|
||||
|
||||
//
|
||||
// Platform BDS Functions
|
||||
//
|
||||
VOID
|
||||
PlatformBdsInit (
|
||||
IN EFI_BDS_ARCH_PROTOCOL_INSTANCE *PrivateData
|
||||
)
|
||||
;
|
||||
|
||||
VOID
|
||||
PlatformBdsPolicyBehavior (
|
||||
IN EFI_BDS_ARCH_PROTOCOL_INSTANCE *PrivateData,
|
||||
IN LIST_ENTRY *DriverOptionList,
|
||||
IN LIST_ENTRY *BootOptionList
|
||||
)
|
||||
;
|
||||
|
||||
VOID
|
||||
PlatformBdsGetDriverOption (
|
||||
IN LIST_ENTRY *BdsDriverLists
|
||||
)
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
BdsMemoryTest (
|
||||
EXTENDMEM_COVERAGE_LEVEL Level
|
||||
)
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
PlatformBdsShowProgress (
|
||||
EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleForeground,
|
||||
EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleBackground,
|
||||
CHAR16 *Title,
|
||||
EFI_GRAPHICS_OUTPUT_BLT_PIXEL ProgressColor,
|
||||
UINTN Progress,
|
||||
UINTN PreviousValue
|
||||
)
|
||||
;
|
||||
|
||||
VOID
|
||||
PlatformBdsConnectSequence (
|
||||
VOID
|
||||
)
|
||||
;
|
||||
|
||||
VOID
|
||||
PlatformBdsBootFail (
|
||||
IN BDS_COMMON_OPTION *Option,
|
||||
IN EFI_STATUS Status,
|
||||
IN CHAR16 *ExitData,
|
||||
IN UINTN ExitDataSize
|
||||
)
|
||||
;
|
||||
|
||||
VOID
|
||||
PlatformBdsBootSuccess (
|
||||
IN BDS_COMMON_OPTION *Option
|
||||
)
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
ProcessCapsules (
|
||||
EFI_BOOT_MODE BootMode
|
||||
)
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
PlatformBdsConnectConsole (
|
||||
IN BDS_CONSOLE_CONNECT_ENTRY *PlatformConsole
|
||||
)
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
PlatformBdsNoConsoleAction (
|
||||
VOID
|
||||
)
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
ConvertMpsTable (
|
||||
IN OUT VOID **Table
|
||||
)
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
ConvertSmbiosTable (
|
||||
IN OUT VOID **Table
|
||||
)
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
ConvertAcpiTable (
|
||||
IN UINTN TableLen,
|
||||
IN OUT VOID **Table
|
||||
)
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
ConvertSystemTable (
|
||||
IN EFI_GUID *TableGuid,
|
||||
IN OUT VOID **Table
|
||||
)
|
||||
;
|
||||
|
||||
VOID
|
||||
PlatformBdsEnterFrontPage (
|
||||
IN UINT16 TimeoutDefault,
|
||||
IN BOOLEAN ConnectAllHappened
|
||||
)
|
||||
;
|
||||
|
||||
#endif // _PLATFORM_SPECIFIC_BDS_PLATFORM_H_
|
64
DuetPkg/Library/DuetBdsLib/PlatformBds.inf
Normal file
64
DuetPkg/Library/DuetBdsLib/PlatformBds.inf
Normal file
@ -0,0 +1,64 @@
|
||||
#/*++
|
||||
#
|
||||
# Copyright (c) 2006 - 2007, Intel Corporation
|
||||
# All rights reserved. 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.
|
||||
#
|
||||
# Module Name:
|
||||
#
|
||||
# PlatformBds.inf
|
||||
#
|
||||
# Abstract:
|
||||
#
|
||||
# Component description file for Bds module.
|
||||
#
|
||||
#--*/
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = DuetBds
|
||||
FILE_GUID = A6F691AC-31C8-4444-854C-E2C1A6950F92
|
||||
MODULE_TYPE = DXE_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = PlatformBdsLib|DXE_DRIVER
|
||||
EDK_RELEASE_VERSION = 0x00020000
|
||||
EFI_SPECIFICATION_VERSION = 0x0002000A
|
||||
|
||||
|
||||
[Sources.common]
|
||||
BdsPlatform.c
|
||||
PlatformData.c
|
||||
BdsPlatform.h
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
Nt32Pkg/Nt32Pkg.dec
|
||||
DuetPkg/DuetPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
MemoryAllocationLib
|
||||
UefiBootServicesTableLib
|
||||
BaseMemoryLib
|
||||
DebugLib
|
||||
PcdLib
|
||||
GraphicsLib
|
||||
GenericBdsLib
|
||||
HobLib
|
||||
UefiLib
|
||||
DevicePathLib
|
||||
|
||||
[Guids]
|
||||
gEfiDefaultBmpLogoGuid
|
||||
gEfiGlobalVariableGuid
|
||||
gEfiPciExpressBaseAddressGuid
|
||||
gEfiAcpi20TableGuid
|
||||
gEfiMpsTableGuid
|
||||
gEfiSmbiosTableGuid
|
||||
gEfiAcpiTableGuid
|
157
DuetPkg/Library/DuetBdsLib/PlatformData.c
Normal file
157
DuetPkg/Library/DuetBdsLib/PlatformData.c
Normal file
@ -0,0 +1,157 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006 - 2007, Intel Corporation
|
||||
All rights reserved. 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.
|
||||
|
||||
Module Name:
|
||||
|
||||
PlatformData.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Defined the platform specific device path which will be used by
|
||||
platform Bbd to perform the platform policy connect.
|
||||
|
||||
--*/
|
||||
|
||||
#include "BdsPlatform.h"
|
||||
|
||||
//
|
||||
// Predefined platform default time out value
|
||||
//
|
||||
UINT16 gPlatformBootTimeOutDefault = 3;
|
||||
|
||||
ACPI_HID_DEVICE_PATH gPnpPs2KeyboardDeviceNode = gPnpPs2Keyboard;
|
||||
ACPI_HID_DEVICE_PATH gPnp16550ComPortDeviceNode = gPnp16550ComPort;
|
||||
UART_DEVICE_PATH gUartDeviceNode = gUart;
|
||||
VENDOR_DEVICE_PATH gTerminalTypeDeviceNode = gPcAnsiTerminal;
|
||||
|
||||
//
|
||||
// Predefined platform root bridge
|
||||
//
|
||||
PLATFORM_ROOT_BRIDGE_DEVICE_PATH gPlatformRootBridge0 = {
|
||||
gPciRootBridge,
|
||||
gEndEntire
|
||||
};
|
||||
|
||||
EFI_DEVICE_PATH_PROTOCOL *gPlatformRootBridges[] = {
|
||||
(EFI_DEVICE_PATH_PROTOCOL *) &gPlatformRootBridge0,
|
||||
NULL
|
||||
};
|
||||
|
||||
USB_CLASS_FORMAT_DEVICE_PATH gUsbClassKeyboardDevicePath = {
|
||||
{
|
||||
{
|
||||
MESSAGING_DEVICE_PATH,
|
||||
MSG_USB_CLASS_DP,
|
||||
(UINT8) (sizeof (USB_CLASS_DEVICE_PATH)),
|
||||
(UINT8) ((sizeof (USB_CLASS_DEVICE_PATH)) >> 8)
|
||||
},
|
||||
0xffff, // VendorId
|
||||
0xffff, // ProductId
|
||||
CLASS_HID, // DeviceClass
|
||||
SUBCLASS_BOOT, // DeviceSubClass
|
||||
PROTOCOL_KEYBOARD // DeviceProtocol
|
||||
},
|
||||
|
||||
{
|
||||
END_DEVICE_PATH_TYPE,
|
||||
END_ENTIRE_DEVICE_PATH_SUBTYPE,
|
||||
END_DEVICE_PATH_LENGTH,
|
||||
0
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
//
|
||||
// Platform specific Dummy ISA keyboard device path
|
||||
//
|
||||
PLATFORM_DUMMY_ISA_KEYBOARD_DEVICE_PATH gDummyIsaKeyboardDevicePath = {
|
||||
gPciRootBridge,
|
||||
gPciIsaBridge,
|
||||
gPnpPs2Keyboard,
|
||||
gEndEntire
|
||||
};
|
||||
|
||||
//
|
||||
// Platform specific Dummy ISA serial device path
|
||||
//
|
||||
PLATFORM_DUMMY_ISA_SERIAL_DEVICE_PATH gDummyIsaSerialDevicePath = {
|
||||
gPciRootBridge,
|
||||
gPciIsaBridge,
|
||||
gPnp16550ComPort,
|
||||
gUart,
|
||||
gPcAnsiTerminal,
|
||||
gEndEntire
|
||||
};
|
||||
|
||||
//
|
||||
// Platform specific Dummy PCI VGA device path
|
||||
//
|
||||
PLATFORM_DUMMY_PCI_VGA_DEVICE_PATH gDummyPciVgaDevicePath = {
|
||||
gPciRootBridge,
|
||||
PCI_DEVICE_PATH_NODE(0, 0x2),
|
||||
gEndEntire
|
||||
};
|
||||
|
||||
//
|
||||
// Platform specific Dummy PCI serial device path
|
||||
//
|
||||
PLATFORM_DUMMY_PCI_SERIAL_DEVICE_PATH gDummyPciSerialDevicePath = {
|
||||
gPciRootBridge,
|
||||
gP2PBridge,
|
||||
PCI_DEVICE_PATH_NODE(0, 0x0),
|
||||
gUart,
|
||||
gPcAnsiTerminal,
|
||||
gEndEntire
|
||||
};
|
||||
*/
|
||||
//
|
||||
// Predefined platform default console device path
|
||||
//
|
||||
BDS_CONSOLE_CONNECT_ENTRY gPlatformConsole[] = {
|
||||
//
|
||||
// need update dynamically
|
||||
//
|
||||
// {
|
||||
// (EFI_DEVICE_PATH_PROTOCOL *) &gDummyIsaSerialDevicePath,
|
||||
// (CONSOLE_OUT | CONSOLE_IN | STD_ERROR)
|
||||
// },
|
||||
// {
|
||||
// (EFI_DEVICE_PATH_PROTOCOL *) &gDummyIsaKeyboardDevicePath,
|
||||
// (CONSOLE_IN | STD_ERROR)
|
||||
// },
|
||||
// {
|
||||
// (EFI_DEVICE_PATH_PROTOCOL *) &gDummyPciVgaDevicePath,
|
||||
// CONSOLE_OUT
|
||||
// },
|
||||
// {
|
||||
// (EFI_DEVICE_PATH_PROTOCOL *) &gDummyPciSerialDevicePath,
|
||||
// (CONSOLE_OUT | CONSOLE_IN | STD_ERROR)
|
||||
// },
|
||||
{
|
||||
(EFI_DEVICE_PATH_PROTOCOL*) &gUsbClassKeyboardDevicePath,
|
||||
CONSOLE_IN
|
||||
},
|
||||
{
|
||||
NULL,
|
||||
0
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// Predefined platform specific driver option
|
||||
//
|
||||
EFI_DEVICE_PATH_PROTOCOL *gPlatformDriverOption[] = { NULL };
|
||||
|
||||
//
|
||||
// Predefined platform connect sequence
|
||||
//
|
||||
EFI_DEVICE_PATH_PROTOCOL *gPlatformConnectSequence[] = { NULL };
|
||||
|
170
DuetPkg/PcRtc/Ia32/RealTimeClock.c
Normal file
170
DuetPkg/PcRtc/Ia32/RealTimeClock.c
Normal file
@ -0,0 +1,170 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2005, Intel Corporation
|
||||
All rights reserved. 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.
|
||||
|
||||
Module Name:
|
||||
Ia32PcRtc.c
|
||||
|
||||
Abstract:
|
||||
|
||||
--*/
|
||||
#include "RealTimeClock.h"
|
||||
|
||||
static PC_RTC_MODULE_GLOBALS mModuleGlobal;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PcRtcEfiGetTime (
|
||||
OUT EFI_TIME *Time,
|
||||
OUT EFI_TIME_CAPABILITIES *Capabilities
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
Time - TODO: add argument description
|
||||
Capabilities - TODO: add argument description
|
||||
|
||||
Returns:
|
||||
|
||||
TODO: add return values
|
||||
|
||||
--*/
|
||||
{
|
||||
return PcRtcGetTime (Time, Capabilities, &mModuleGlobal);
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PcRtcEfiSetTime (
|
||||
IN EFI_TIME *Time
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
Time - TODO: add argument description
|
||||
|
||||
Returns:
|
||||
|
||||
TODO: add return values
|
||||
|
||||
--*/
|
||||
{
|
||||
return PcRtcSetTime (Time, &mModuleGlobal);
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PcRtcEfiGetWakeupTime (
|
||||
OUT BOOLEAN *Enabled,
|
||||
OUT BOOLEAN *Pending,
|
||||
OUT EFI_TIME *Time
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
Enabled - TODO: add argument description
|
||||
Pending - TODO: add argument description
|
||||
Time - TODO: add argument description
|
||||
|
||||
Returns:
|
||||
|
||||
TODO: add return values
|
||||
|
||||
--*/
|
||||
{
|
||||
return PcRtcGetWakeupTime (Enabled, Pending, Time, &mModuleGlobal);
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PcRtcEfiSetWakeupTime (
|
||||
IN BOOLEAN Enabled,
|
||||
OUT EFI_TIME *Time
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
Enabled - TODO: add argument description
|
||||
Time - TODO: add argument description
|
||||
|
||||
Returns:
|
||||
|
||||
TODO: add return values
|
||||
|
||||
--*/
|
||||
{
|
||||
return PcRtcSetWakeupTime (Enabled, Time, &mModuleGlobal);
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
InitializeRealTimeClock (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Arguments:
|
||||
|
||||
|
||||
|
||||
Returns:
|
||||
--*/
|
||||
// TODO: ImageHandle - add argument and description to function comment
|
||||
// TODO: SystemTable - add argument and description to function comment
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_HANDLE NewHandle;
|
||||
|
||||
|
||||
EfiInitializeLock (&mModuleGlobal.RtcLock, TPL_HIGH_LEVEL);
|
||||
|
||||
Status = PcRtcInit (&mModuleGlobal);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
SystemTable->RuntimeServices->GetTime = PcRtcEfiGetTime;
|
||||
SystemTable->RuntimeServices->SetTime = PcRtcEfiSetTime;
|
||||
SystemTable->RuntimeServices->GetWakeupTime = PcRtcEfiGetWakeupTime;
|
||||
SystemTable->RuntimeServices->SetWakeupTime = PcRtcEfiSetWakeupTime;
|
||||
|
||||
NewHandle = NULL;
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
&NewHandle,
|
||||
&gEfiRealTimeClockArchProtocolGuid,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
|
||||
return Status;
|
||||
}
|
29
DuetPkg/PcRtc/Ia32RealTimeClock.dxs
Normal file
29
DuetPkg/PcRtc/Ia32RealTimeClock.dxs
Normal file
@ -0,0 +1,29 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2005, Intel Corporation
|
||||
All rights reserved. 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.
|
||||
|
||||
Module Name:
|
||||
Ia32PcRtc.dxs
|
||||
|
||||
Abstract:
|
||||
Dependency expression source file.
|
||||
|
||||
--*/
|
||||
|
||||
|
||||
#include "EfiDepex.h"
|
||||
|
||||
#include EFI_ARCH_PROTOCOL_DEFINITION (Cpu)
|
||||
#include EFI_ARCH_PROTOCOL_DEFINITION (Metronome)
|
||||
#include EFI_PROTOCOL_DEFINITION (CpuIo)
|
||||
|
||||
DEPENDENCY_START
|
||||
EFI_CPU_ARCH_PROTOCOL_GUID AND EFI_METRONOME_ARCH_PROTOCOL_GUID AND EFI_CPU_IO_PROTOCOL_GUID
|
||||
DEPENDENCY_END
|
185
DuetPkg/PcRtc/Ipf/IpfPcRtc.c
Normal file
185
DuetPkg/PcRtc/Ipf/IpfPcRtc.c
Normal file
@ -0,0 +1,185 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2005, Intel Corporation
|
||||
All rights reserved. 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.
|
||||
|
||||
Module Name:
|
||||
IpfPcRtc.c
|
||||
|
||||
Abstract:
|
||||
Register the extended SAL infrastructure.
|
||||
|
||||
Make the EFI RT APIs call extended SAL calls via the RT lib wrappers.
|
||||
We can not do this on IA-32 as RT lib wrappers call via rRT.
|
||||
|
||||
--*/
|
||||
|
||||
#include "RealTimeClock.h"
|
||||
|
||||
//
|
||||
// Don't use directly after virtual address have been registered.
|
||||
//
|
||||
static PC_RTC_MODULE_GLOBALS mModuleGlobal;
|
||||
|
||||
SAL_RETURN_REGS
|
||||
PcRtcEsalServicesClassCommonEntry (
|
||||
IN UINT64 FunctionId,
|
||||
IN UINT64 Arg2,
|
||||
IN UINT64 Arg3,
|
||||
IN UINT64 Arg4,
|
||||
IN UINT64 Arg5,
|
||||
IN UINT64 Arg6,
|
||||
IN UINT64 Arg7,
|
||||
IN UINT64 Arg8,
|
||||
IN SAL_EXTENDED_SAL_PROC ExtendedSalProc,
|
||||
IN BOOLEAN VirtualMode,
|
||||
IN PC_RTC_MODULE_GLOBALS *Global
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Main entry for Extended SAL Reset Services
|
||||
|
||||
Arguments:
|
||||
|
||||
FunctionId Function Id which needed to be called.
|
||||
Arg2 EFI_RESET_TYPE, whether WARM of COLD reset
|
||||
Arg3 Last EFI_STATUS
|
||||
Arg4 Data Size of UNICODE STRING passed in ARG5
|
||||
Arg5 Unicode String which CHAR16*
|
||||
|
||||
Returns:
|
||||
|
||||
SAL_RETURN_REGS
|
||||
|
||||
--*/
|
||||
// TODO: Arg6 - add argument and description to function comment
|
||||
// TODO: Arg7 - add argument and description to function comment
|
||||
// TODO: Arg8 - add argument and description to function comment
|
||||
// TODO: ExtendedSalProc - add argument and description to function comment
|
||||
// TODO: VirtualMode - add argument and description to function comment
|
||||
// TODO: Global - add argument and description to function comment
|
||||
{
|
||||
EFI_STATUS EfiStatus;
|
||||
SAL_RETURN_REGS ReturnVal;
|
||||
|
||||
switch (FunctionId) {
|
||||
case GetTime:
|
||||
EfiStatus = PcRtcGetTime ((EFI_TIME *) Arg2, (EFI_TIME_CAPABILITIES *) Arg3, Global);
|
||||
break;
|
||||
|
||||
case SetTime:
|
||||
EfiStatus = PcRtcSetTime ((EFI_TIME *) Arg2, Global);
|
||||
break;
|
||||
|
||||
case GetWakeupTime:
|
||||
EfiStatus = PcRtcGetWakeupTime ((BOOLEAN *) Arg2, (BOOLEAN *) Arg3, (EFI_TIME *) Arg4, Global);
|
||||
break;
|
||||
|
||||
case SetWakeupTime:
|
||||
EfiStatus = PcRtcSetWakeupTime ((BOOLEAN) Arg2, (EFI_TIME *) Arg3, Global);
|
||||
break;
|
||||
|
||||
case InitializeThreshold:
|
||||
EfiStatus = EFI_SAL_NOT_IMPLEMENTED;
|
||||
break;
|
||||
|
||||
case BumpThresholdCount:
|
||||
EfiStatus = EFI_SAL_NOT_IMPLEMENTED;
|
||||
break;
|
||||
|
||||
case GetThresholdCount:
|
||||
EfiStatus = EFI_SAL_NOT_IMPLEMENTED;
|
||||
break;
|
||||
|
||||
case GetRtcFreq:
|
||||
EfiStatus = EFI_SAL_NOT_IMPLEMENTED;
|
||||
break;
|
||||
|
||||
default:
|
||||
EfiStatus = EFI_SAL_INVALID_ARGUMENT;
|
||||
break;;
|
||||
}
|
||||
|
||||
ReturnVal.Status = EfiStatus;
|
||||
return ReturnVal;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
InitializePcRtc (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Arguments:
|
||||
|
||||
|
||||
|
||||
Returns:
|
||||
--*/
|
||||
// TODO: ImageHandle - add argument and description to function comment
|
||||
// TODO: SystemTable - add argument and description to function comment
|
||||
// TODO: EFI_SUCCESS - add return value to function comment
|
||||
{
|
||||
EFI_TIME Time;
|
||||
EFI_TIME_CAPABILITIES Capabilities;
|
||||
EFI_STATUS EfiStatus;
|
||||
|
||||
EfiInitializeRuntimeDriverLib (ImageHandle, SystemTable, NULL);
|
||||
|
||||
EfiInitializeLock (&mModuleGlobal.RtcLock, EFI_TPL_HIGH_LEVEL);
|
||||
|
||||
EfiStatus = PcRtcInit (&mModuleGlobal);
|
||||
if (EFI_ERROR (EfiStatus)) {
|
||||
return EfiStatus;
|
||||
}
|
||||
|
||||
RegisterEsalClass (
|
||||
&gEfiExtendedSalRtcServicesProtocolGuid,
|
||||
&mModuleGlobal,
|
||||
PcRtcEsalServicesClassCommonEntry,
|
||||
GetTime,
|
||||
PcRtcEsalServicesClassCommonEntry,
|
||||
SetTime,
|
||||
PcRtcEsalServicesClassCommonEntry,
|
||||
GetWakeupTime,
|
||||
PcRtcEsalServicesClassCommonEntry,
|
||||
SetWakeupTime,
|
||||
PcRtcEsalServicesClassCommonEntry,
|
||||
GetRtcFreq,
|
||||
PcRtcEsalServicesClassCommonEntry,
|
||||
InitializeThreshold,
|
||||
PcRtcEsalServicesClassCommonEntry,
|
||||
BumpThresholdCount,
|
||||
PcRtcEsalServicesClassCommonEntry,
|
||||
GetThresholdCount,
|
||||
NULL
|
||||
);
|
||||
//
|
||||
// the following code is to initialize the RTC fields in case the values read
|
||||
// back from CMOS are invalid at the first time.
|
||||
//
|
||||
EfiStatus = PcRtcGetTime (&Time, &Capabilities, &mModuleGlobal);
|
||||
if (EFI_ERROR (EfiStatus)) {
|
||||
Time.Second = RTC_INIT_SECOND;
|
||||
Time.Minute = RTC_INIT_MINUTE;
|
||||
Time.Hour = RTC_INIT_HOUR;
|
||||
Time.Day = RTC_INIT_DAY;
|
||||
Time.Month = RTC_INIT_MONTH;
|
||||
Time.Year = RTC_INIT_YEAR;
|
||||
PcRtcSetTime (&Time, &mModuleGlobal);
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
28
DuetPkg/PcRtc/IpfRealTimeClock.dxs
Normal file
28
DuetPkg/PcRtc/IpfRealTimeClock.dxs
Normal file
@ -0,0 +1,28 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2005, Intel Corporation
|
||||
All rights reserved. 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.
|
||||
|
||||
Module Name:
|
||||
IpfPcRtc.dxs
|
||||
|
||||
Abstract:
|
||||
Dependency expression source file.
|
||||
|
||||
--*/
|
||||
|
||||
|
||||
#include "EfiDepex.h"
|
||||
|
||||
#include EFI_PROTOCOL_DEFINITION (ExtendedSalGuid)
|
||||
#include EFI_ARCH_PROTOCOL_DEFINITION (Metronome)
|
||||
|
||||
DEPENDENCY_START
|
||||
EFI_EXTENDED_SAL_BASE_IO_SERVICES_PROTOCOL_GUID AND EFI_METRONOME_ARCH_PROTOCOL_GUID
|
||||
DEPENDENCY_END
|
1065
DuetPkg/PcRtc/RealTimeClock.c
Normal file
1065
DuetPkg/PcRtc/RealTimeClock.c
Normal file
File diff suppressed because it is too large
Load Diff
491
DuetPkg/PcRtc/RealTimeClock.h
Normal file
491
DuetPkg/PcRtc/RealTimeClock.h
Normal file
@ -0,0 +1,491 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2005, Intel Corporation
|
||||
All rights reserved. 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.
|
||||
|
||||
Module Name:
|
||||
PcRtc.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Include for real time clock driver
|
||||
|
||||
Revision History
|
||||
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef _RTC_H_
|
||||
#define _RTC_H_
|
||||
|
||||
#include <FrameworkDxe.h>
|
||||
|
||||
#include <Protocol/RealTimeClock.h>
|
||||
|
||||
#include <Library/UefiLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/IoLib.h>
|
||||
#include <Library/TimerLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
|
||||
typedef struct {
|
||||
EFI_LOCK RtcLock;
|
||||
UINT16 SavedTimeZone;
|
||||
UINT8 Daylight;
|
||||
} PC_RTC_MODULE_GLOBALS;
|
||||
|
||||
#define PCAT_RTC_ADDRESS_REGISTER 0x70
|
||||
#define PCAT_RTC_DATA_REGISTER 0x71
|
||||
|
||||
//
|
||||
// Dallas DS12C887 Real Time Clock
|
||||
//
|
||||
#define RTC_ADDRESS_SECONDS 0 // R/W Range 0..59
|
||||
#define RTC_ADDRESS_SECONDS_ALARM 1 // R/W Range 0..59
|
||||
#define RTC_ADDRESS_MINUTES 2 // R/W Range 0..59
|
||||
#define RTC_ADDRESS_MINUTES_ALARM 3 // R/W Range 0..59
|
||||
#define RTC_ADDRESS_HOURS 4 // R/W Range 1..12 or 0..23 Bit 7 is AM/PM
|
||||
#define RTC_ADDRESS_HOURS_ALARM 5 // R/W Range 1..12 or 0..23 Bit 7 is AM/PM
|
||||
#define RTC_ADDRESS_DAY_OF_THE_WEEK 6 // R/W Range 1..7
|
||||
#define RTC_ADDRESS_DAY_OF_THE_MONTH 7 // R/W Range 1..31
|
||||
#define RTC_ADDRESS_MONTH 8 // R/W Range 1..12
|
||||
#define RTC_ADDRESS_YEAR 9 // R/W Range 0..99
|
||||
#define RTC_ADDRESS_REGISTER_A 10 // R/W[0..6] R0[7]
|
||||
#define RTC_ADDRESS_REGISTER_B 11 // R/W
|
||||
#define RTC_ADDRESS_REGISTER_C 12 // RO
|
||||
#define RTC_ADDRESS_REGISTER_D 13 // RO
|
||||
#define RTC_ADDRESS_CENTURY 50 // R/W Range 19..20 Bit 8 is R/W
|
||||
//
|
||||
// Date and time initial values.
|
||||
// They are used if the RTC values are invalid during driver initialization
|
||||
//
|
||||
#define RTC_INIT_SECOND 0
|
||||
#define RTC_INIT_MINUTE 0
|
||||
#define RTC_INIT_HOUR 0
|
||||
#define RTC_INIT_DAY 1
|
||||
#define RTC_INIT_MONTH 1
|
||||
#define RTC_INIT_YEAR 2001
|
||||
|
||||
//
|
||||
// Register initial values
|
||||
//
|
||||
#define RTC_INIT_REGISTER_A 0x26
|
||||
#define RTC_INIT_REGISTER_B 0x02
|
||||
#define RTC_INIT_REGISTER_D 0x0
|
||||
|
||||
#pragma pack(1)
|
||||
//
|
||||
// Register A
|
||||
//
|
||||
typedef struct {
|
||||
UINT8 RS : 4; // Rate Selection Bits
|
||||
UINT8 DV : 3; // Divisor
|
||||
UINT8 UIP : 1; // Update in progress
|
||||
} RTC_REGISTER_A_BITS;
|
||||
|
||||
typedef union {
|
||||
RTC_REGISTER_A_BITS Bits;
|
||||
UINT8 Data;
|
||||
} RTC_REGISTER_A;
|
||||
|
||||
//
|
||||
// Register B
|
||||
//
|
||||
typedef struct {
|
||||
UINT8 DSE : 1; // 0 - Daylight saving disabled 1 - Daylight savings enabled
|
||||
UINT8 MIL : 1; // 0 - 12 hour mode 1 - 24 hour mode
|
||||
UINT8 DM : 1; // 0 - BCD Format 1 - Binary Format
|
||||
UINT8 SQWE : 1; // 0 - Disable SQWE output 1 - Enable SQWE output
|
||||
UINT8 UIE : 1; // 0 - Update INT disabled 1 - Update INT enabled
|
||||
UINT8 AIE : 1; // 0 - Alarm INT disabled 1 - Alarm INT Enabled
|
||||
UINT8 PIE : 1; // 0 - Periodic INT disabled 1 - Periodic INT Enabled
|
||||
UINT8 SET : 1; // 0 - Normal operation. 1 - Updates inhibited
|
||||
} RTC_REGISTER_B_BITS;
|
||||
|
||||
typedef union {
|
||||
RTC_REGISTER_B_BITS Bits;
|
||||
UINT8 Data;
|
||||
} RTC_REGISTER_B;
|
||||
|
||||
//
|
||||
// Register C
|
||||
//
|
||||
typedef struct {
|
||||
UINT8 Reserved : 4; // Read as zero. Can not be written.
|
||||
UINT8 UF : 1; // Update End Interrupt Flag
|
||||
UINT8 AF : 1; // Alarm Interrupt Flag
|
||||
UINT8 PF : 1; // Periodic Interrupt Flag
|
||||
UINT8 IRQF : 1; // Iterrupt Request Flag = PF & PIE | AF & AIE | UF & UIE
|
||||
} RTC_REGISTER_C_BITS;
|
||||
|
||||
typedef union {
|
||||
RTC_REGISTER_C_BITS Bits;
|
||||
UINT8 Data;
|
||||
} RTC_REGISTER_C;
|
||||
|
||||
//
|
||||
// Register D
|
||||
//
|
||||
typedef struct {
|
||||
UINT8 Reserved : 7; // Read as zero. Can not be written.
|
||||
UINT8 VRT : 1; // Valid RAM and Time
|
||||
} RTC_REGISTER_D_BITS;
|
||||
|
||||
typedef union {
|
||||
RTC_REGISTER_D_BITS Bits;
|
||||
UINT8 Data;
|
||||
} RTC_REGISTER_D;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
EFI_STATUS
|
||||
PcRtcInit (
|
||||
IN PC_RTC_MODULE_GLOBALS *Global
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
Global - TODO: add argument description
|
||||
|
||||
Returns:
|
||||
|
||||
TODO: add return values
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
PcRtcSetTime (
|
||||
IN EFI_TIME *Time,
|
||||
IN PC_RTC_MODULE_GLOBALS *Global
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
Time - TODO: add argument description
|
||||
Global - TODO: add argument description
|
||||
|
||||
Returns:
|
||||
|
||||
TODO: add return values
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
PcRtcGetTime (
|
||||
OUT EFI_TIME *Time,
|
||||
IN EFI_TIME_CAPABILITIES *Capabilities,
|
||||
IN PC_RTC_MODULE_GLOBALS *Global
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
Time - TODO: add argument description
|
||||
Capabilities - TODO: add argument description
|
||||
Global - TODO: add argument description
|
||||
|
||||
Returns:
|
||||
|
||||
TODO: add return values
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PcRtcSetWakeupTime (
|
||||
IN BOOLEAN Enable,
|
||||
OUT EFI_TIME *Time,
|
||||
IN PC_RTC_MODULE_GLOBALS *Global
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
Enable - TODO: add argument description
|
||||
Time - TODO: add argument description
|
||||
Global - TODO: add argument description
|
||||
|
||||
Returns:
|
||||
|
||||
TODO: add return values
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PcRtcGetWakeupTime (
|
||||
OUT BOOLEAN *Enabled,
|
||||
OUT BOOLEAN *Pending,
|
||||
OUT EFI_TIME *Time,
|
||||
IN PC_RTC_MODULE_GLOBALS *Global
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
Enabled - TODO: add argument description
|
||||
Pending - TODO: add argument description
|
||||
Time - TODO: add argument description
|
||||
Global - TODO: add argument description
|
||||
|
||||
Returns:
|
||||
|
||||
TODO: add return values
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
InitializePcRtc (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
ImageHandle - TODO: add argument description
|
||||
SystemTable - TODO: add argument description
|
||||
|
||||
Returns:
|
||||
|
||||
TODO: add return values
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
UINT8
|
||||
BcdToDecimal (
|
||||
IN UINT8 BcdValue
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
BcdValue - TODO: add argument description
|
||||
|
||||
Returns:
|
||||
|
||||
TODO: add return values
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
RtcTimeFieldsValid (
|
||||
IN EFI_TIME *Time
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
Time - TODO: add argument description
|
||||
|
||||
Returns:
|
||||
|
||||
TODO: add return values
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
UINT8
|
||||
DecimaltoBcd (
|
||||
IN UINT8 DecValue
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
DecValue - TODO: add argument description
|
||||
|
||||
Returns:
|
||||
|
||||
TODO: add return values
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
VOID
|
||||
ConvertEfiTimeToRtcTime (
|
||||
IN EFI_TIME *Time,
|
||||
IN RTC_REGISTER_B RegisterB,
|
||||
IN UINT8 *Century
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
Time - TODO: add argument description
|
||||
RegisterB - TODO: add argument description
|
||||
Century - TODO: add argument description
|
||||
|
||||
Returns:
|
||||
|
||||
TODO: add return values
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
RtcTestCenturyRegister (
|
||||
VOID
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
None
|
||||
|
||||
Returns:
|
||||
|
||||
TODO: add return values
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
VOID
|
||||
ConvertRtcTimeToEfiTime (
|
||||
IN EFI_TIME *Time,
|
||||
IN RTC_REGISTER_B RegisterB
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
Time - TODO: add argument description
|
||||
RegisterB - TODO: add argument description
|
||||
|
||||
Returns:
|
||||
|
||||
TODO: add return values
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
RtcWaitToUpdate (
|
||||
UINTN Timeout
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
Timeout - TODO: add argument description
|
||||
|
||||
Returns:
|
||||
|
||||
TODO: add return values
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
UINT8
|
||||
RtcSaveContext (
|
||||
IN PC_RTC_MODULE_GLOBALS *Global
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
Global - TODO: add argument description
|
||||
|
||||
Returns:
|
||||
|
||||
TODO: add return values
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
VOID
|
||||
RtcRestoreContext (
|
||||
IN UINT8 SavedAddressRegister,
|
||||
IN PC_RTC_MODULE_GLOBALS *Global
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
SavedAddressRegister - TODO: add argument description
|
||||
Global - TODO: add argument description
|
||||
|
||||
Returns:
|
||||
|
||||
TODO: add return values
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
#endif
|
63
DuetPkg/PcRtc/RealTimeClock.inf
Normal file
63
DuetPkg/PcRtc/RealTimeClock.inf
Normal file
@ -0,0 +1,63 @@
|
||||
#/*++
|
||||
#
|
||||
# Copyright (c) 2005, Intel Corporation
|
||||
# All rights reserved. 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.
|
||||
#
|
||||
# Module Name:
|
||||
#
|
||||
# Abstract:
|
||||
#
|
||||
#--*/
|
||||
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = RealTimeClock
|
||||
FILE_GUID = 378D7B65-8DA9-4773-B6E4-A47826A833E1
|
||||
MODULE_TYPE = DXE_RUNTIME_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
EDK_RELEASE_VERSION = 0x00020000
|
||||
EFI_SPECIFICATION_VERSION = 0x00020000
|
||||
|
||||
ENTRY_POINT = InitializeRealTimeClock
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
IntelFrameworkPkg/IntelFrameworkPkg.dec
|
||||
DuetPkg/DuetPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
UefiDriverEntryPoint
|
||||
UefiBootServicesTableLib
|
||||
UefiLib
|
||||
IoLib
|
||||
TimerLib
|
||||
BaseMemoryLib
|
||||
|
||||
[Sources.common]
|
||||
RealTimeClock.c
|
||||
RealTimeClock.h
|
||||
|
||||
[Sources.ia32]
|
||||
Ia32/RealTimeClock.c
|
||||
|
||||
[Sources.x64]
|
||||
x64/RealTimeClock.c
|
||||
|
||||
[Sources.ipf]
|
||||
Ipf/RealTimeClock.c
|
||||
|
||||
[Protocols]
|
||||
gEfiCpuArchProtocolGuid
|
||||
gEfiMetronomeArchProtocolGuid
|
||||
gEfiCpuIoProtocolGuid
|
||||
gEfiRealTimeClockArchProtocolGuid
|
||||
|
||||
[Depex]
|
||||
gEfiCpuArchProtocolGuid AND gEfiMetronomeArchProtocolGuid AND gEfiCpuIoProtocolGuid
|
170
DuetPkg/PcRtc/x64/RealTimeClock.c
Normal file
170
DuetPkg/PcRtc/x64/RealTimeClock.c
Normal file
@ -0,0 +1,170 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2005, Intel Corporation
|
||||
All rights reserved. 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.
|
||||
|
||||
Module Name:
|
||||
x64PcRtc.c
|
||||
|
||||
Abstract:
|
||||
|
||||
--*/
|
||||
|
||||
#include "RealTimeClock.h"
|
||||
|
||||
static PC_RTC_MODULE_GLOBALS mModuleGlobal;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PcRtcEfiGetTime (
|
||||
OUT EFI_TIME *Time,
|
||||
OUT EFI_TIME_CAPABILITIES *Capabilities
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
Time - TODO: add argument description
|
||||
Capabilities - TODO: add argument description
|
||||
|
||||
Returns:
|
||||
|
||||
TODO: add return values
|
||||
|
||||
--*/
|
||||
{
|
||||
return PcRtcGetTime (Time, Capabilities, &mModuleGlobal);
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PcRtcEfiSetTime (
|
||||
IN EFI_TIME *Time
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
Time - TODO: add argument description
|
||||
|
||||
Returns:
|
||||
|
||||
TODO: add return values
|
||||
|
||||
--*/
|
||||
{
|
||||
return PcRtcSetTime (Time, &mModuleGlobal);
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PcRtcEfiGetWakeupTime (
|
||||
OUT BOOLEAN *Enabled,
|
||||
OUT BOOLEAN *Pending,
|
||||
OUT EFI_TIME *Time
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
Enabled - TODO: add argument description
|
||||
Pending - TODO: add argument description
|
||||
Time - TODO: add argument description
|
||||
|
||||
Returns:
|
||||
|
||||
TODO: add return values
|
||||
|
||||
--*/
|
||||
{
|
||||
return PcRtcGetWakeupTime (Enabled, Pending, Time, &mModuleGlobal);
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PcRtcEfiSetWakeupTime (
|
||||
IN BOOLEAN Enabled,
|
||||
OUT EFI_TIME *Time
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
TODO: Add function description
|
||||
|
||||
Arguments:
|
||||
|
||||
Enabled - TODO: add argument description
|
||||
Time - TODO: add argument description
|
||||
|
||||
Returns:
|
||||
|
||||
TODO: add return values
|
||||
|
||||
--*/
|
||||
{
|
||||
return PcRtcSetWakeupTime (Enabled, Time, &mModuleGlobal);
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
InitializeRealTimeClock (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Arguments:
|
||||
|
||||
|
||||
|
||||
Returns:
|
||||
--*/
|
||||
// TODO: ImageHandle - add argument and description to function comment
|
||||
// TODO: SystemTable - add argument and description to function comment
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_HANDLE NewHandle;
|
||||
|
||||
EfiInitializeLock (&mModuleGlobal.RtcLock, TPL_HIGH_LEVEL);
|
||||
|
||||
Status = PcRtcInit (&mModuleGlobal);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
SystemTable->RuntimeServices->GetTime = PcRtcEfiGetTime;
|
||||
SystemTable->RuntimeServices->SetTime = PcRtcEfiSetTime;
|
||||
SystemTable->RuntimeServices->GetWakeupTime = PcRtcEfiGetWakeupTime;
|
||||
SystemTable->RuntimeServices->SetWakeupTime = PcRtcEfiSetWakeupTime;
|
||||
|
||||
NewHandle = NULL;
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
&NewHandle,
|
||||
&gEfiRealTimeClockArchProtocolGuid,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
|
||||
return Status;
|
||||
}
|
29
DuetPkg/PcRtc/x64RealTimeClock.dxs
Normal file
29
DuetPkg/PcRtc/x64RealTimeClock.dxs
Normal file
@ -0,0 +1,29 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2005, Intel Corporation
|
||||
All rights reserved. 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.
|
||||
|
||||
Module Name:
|
||||
x64PcRtc.dxs
|
||||
|
||||
Abstract:
|
||||
Dependency expression source file.
|
||||
|
||||
--*/
|
||||
|
||||
|
||||
#include "EfiDepex.h"
|
||||
|
||||
#include EFI_ARCH_PROTOCOL_DEFINITION (Cpu)
|
||||
#include EFI_ARCH_PROTOCOL_DEFINITION (Metronome)
|
||||
#include EFI_PROTOCOL_DEFINITION (CpuIo)
|
||||
|
||||
DEPENDENCY_START
|
||||
EFI_CPU_ARCH_PROTOCOL_GUID AND EFI_METRONOME_ARCH_PROTOCOL_GUID AND EFI_CPU_IO_PROTOCOL_GUID
|
||||
DEPENDENCY_END
|
845
DuetPkg/PciRootBridgeNoEnumerationDxe/DeviceIo.c
Normal file
845
DuetPkg/PciRootBridgeNoEnumerationDxe/DeviceIo.c
Normal file
@ -0,0 +1,845 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. 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.
|
||||
|
||||
Module Name:
|
||||
|
||||
DeviceIo.c
|
||||
|
||||
Abstract:
|
||||
|
||||
EFI PC-AT PCI Device IO driver
|
||||
|
||||
--*/
|
||||
#include "PcatPciRootBridge.h"
|
||||
#include "DeviceIo.h"
|
||||
|
||||
EFI_STATUS
|
||||
DeviceIoConstructor (
|
||||
IN EFI_HANDLE Handle,
|
||||
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
|
||||
IN UINT16 PrimaryBus,
|
||||
IN UINT16 SubordinateBus
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Initialize and install a Device IO protocol on a empty device path handle.
|
||||
|
||||
Arguments:
|
||||
|
||||
Handle - Handle of PCI RootBridge IO instance
|
||||
PciRootBridgeIo - PCI RootBridge IO instance
|
||||
DevicePath - Device Path of PCI RootBridge IO instance
|
||||
PrimaryBus - Primary Bus
|
||||
SubordinateBus - Subordinate Bus
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - This driver is added to ControllerHandle.
|
||||
EFI_ALREADY_STARTED - This driver is already running on ControllerHandle.
|
||||
Others - This driver does not support this device.
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
DEVICE_IO_PRIVATE_DATA *Private;
|
||||
|
||||
//
|
||||
// Initialize the Device IO device instance.
|
||||
//
|
||||
Private = AllocateZeroPool (sizeof (DEVICE_IO_PRIVATE_DATA));
|
||||
if (Private == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
Private->Signature = DEVICE_IO_PRIVATE_DATA_SIGNATURE;
|
||||
Private->Handle = Handle;
|
||||
Private->PciRootBridgeIo = PciRootBridgeIo;
|
||||
Private->DevicePath = DevicePath;
|
||||
Private->PrimaryBus = PrimaryBus;
|
||||
Private->SubordinateBus = SubordinateBus;
|
||||
|
||||
Private->DeviceIo.Mem.Read = DeviceIoMemRead;
|
||||
Private->DeviceIo.Mem.Write = DeviceIoMemWrite;
|
||||
Private->DeviceIo.Io.Read = DeviceIoIoRead;
|
||||
Private->DeviceIo.Io.Write = DeviceIoIoWrite;
|
||||
Private->DeviceIo.Pci.Read = DeviceIoPciRead;
|
||||
Private->DeviceIo.Pci.Write = DeviceIoPciWrite;
|
||||
Private->DeviceIo.PciDevicePath = DeviceIoPciDevicePath;
|
||||
Private->DeviceIo.Map = DeviceIoMap;
|
||||
Private->DeviceIo.Unmap = DeviceIoUnmap;
|
||||
Private->DeviceIo.AllocateBuffer = DeviceIoAllocateBuffer;
|
||||
Private->DeviceIo.Flush = DeviceIoFlush;
|
||||
Private->DeviceIo.FreeBuffer = DeviceIoFreeBuffer;
|
||||
|
||||
//
|
||||
// Install protocol interfaces for the Device IO device.
|
||||
//
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
&Private->Handle,
|
||||
&gEfiDeviceIoProtocolGuid,
|
||||
&Private->DeviceIo,
|
||||
NULL
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DeviceIoMemRead (
|
||||
IN EFI_DEVICE_IO_PROTOCOL *This,
|
||||
IN EFI_IO_WIDTH Width,
|
||||
IN UINT64 Address,
|
||||
IN UINTN Count,
|
||||
IN OUT VOID *Buffer
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Perform reading memory mapped I/O space of device.
|
||||
|
||||
Arguments:
|
||||
|
||||
This - A pointer to EFI_DEVICE_IO protocol instance.
|
||||
Width - Width of I/O operations.
|
||||
Address - The base address of I/O operations.
|
||||
Count - The number of I/O operations to perform.
|
||||
Bytes moves is Width size * Count, starting at Address.
|
||||
Buffer - The destination buffer to store results.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - The data was read from the device.
|
||||
EFI_INVALID_PARAMETER - Width is invalid.
|
||||
EFI_OUT_OF_RESOURCES - The request could not be completed due to lack of resources.
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
DEVICE_IO_PRIVATE_DATA *Private;
|
||||
|
||||
Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);
|
||||
|
||||
if (Width > MMIO_COPY_UINT64) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
if (Width >= MMIO_COPY_UINT8) {
|
||||
Width = Width - MMIO_COPY_UINT8;
|
||||
Status = Private->PciRootBridgeIo->CopyMem (
|
||||
Private->PciRootBridgeIo,
|
||||
(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
|
||||
(UINT64) Buffer,
|
||||
Address,
|
||||
Count
|
||||
);
|
||||
} else {
|
||||
Status = Private->PciRootBridgeIo->Mem.Read (
|
||||
Private->PciRootBridgeIo,
|
||||
(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
|
||||
Address,
|
||||
Count,
|
||||
Buffer
|
||||
);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DeviceIoMemWrite (
|
||||
IN EFI_DEVICE_IO_PROTOCOL *This,
|
||||
IN EFI_IO_WIDTH Width,
|
||||
IN UINT64 Address,
|
||||
IN UINTN Count,
|
||||
IN OUT VOID *Buffer
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Perform writing memory mapped I/O space of device.
|
||||
|
||||
Arguments:
|
||||
|
||||
This - A pointer to EFI_DEVICE_IO protocol instance.
|
||||
Width - Width of I/O operations.
|
||||
Address - The base address of I/O operations.
|
||||
Count - The number of I/O operations to perform.
|
||||
Bytes moves is Width size * Count, starting at Address.
|
||||
Buffer - The source buffer of data to be written.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - The data was written to the device.
|
||||
EFI_INVALID_PARAMETER - Width is invalid.
|
||||
EFI_OUT_OF_RESOURCES - The request could not be completed due to lack of resources.
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
DEVICE_IO_PRIVATE_DATA *Private;
|
||||
|
||||
Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);
|
||||
|
||||
if (Width > MMIO_COPY_UINT64) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
if (Width >= MMIO_COPY_UINT8) {
|
||||
Width = Width - MMIO_COPY_UINT8;
|
||||
Status = Private->PciRootBridgeIo->CopyMem (
|
||||
Private->PciRootBridgeIo,
|
||||
(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
|
||||
Address,
|
||||
(UINT64) Buffer,
|
||||
Count
|
||||
);
|
||||
} else {
|
||||
Status = Private->PciRootBridgeIo->Mem.Write (
|
||||
Private->PciRootBridgeIo,
|
||||
(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
|
||||
Address,
|
||||
Count,
|
||||
Buffer
|
||||
);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DeviceIoIoRead (
|
||||
IN EFI_DEVICE_IO_PROTOCOL *This,
|
||||
IN EFI_IO_WIDTH Width,
|
||||
IN UINT64 Address,
|
||||
IN UINTN Count,
|
||||
IN OUT VOID *Buffer
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Perform reading I/O space of device.
|
||||
|
||||
Arguments:
|
||||
|
||||
This - A pointer to EFI_DEVICE_IO protocol instance.
|
||||
Width - Width of I/O operations.
|
||||
Address - The base address of I/O operations.
|
||||
Count - The number of I/O operations to perform.
|
||||
Bytes moves is Width size * Count, starting at Address.
|
||||
Buffer - The destination buffer to store results.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - The data was read from the device.
|
||||
EFI_INVALID_PARAMETER - Width is invalid.
|
||||
EFI_OUT_OF_RESOURCES - The request could not be completed due to lack of resources.
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
DEVICE_IO_PRIVATE_DATA *Private;
|
||||
|
||||
Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);
|
||||
|
||||
if (Width >= MMIO_COPY_UINT8) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Status = Private->PciRootBridgeIo->Io.Read (
|
||||
Private->PciRootBridgeIo,
|
||||
(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
|
||||
Address,
|
||||
Count,
|
||||
Buffer
|
||||
);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DeviceIoIoWrite (
|
||||
IN EFI_DEVICE_IO_PROTOCOL *This,
|
||||
IN EFI_IO_WIDTH Width,
|
||||
IN UINT64 Address,
|
||||
IN UINTN Count,
|
||||
IN OUT VOID *Buffer
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Perform writing I/O space of device.
|
||||
|
||||
Arguments:
|
||||
|
||||
This - A pointer to EFI_DEVICE_IO protocol instance.
|
||||
Width - Width of I/O operations.
|
||||
Address - The base address of I/O operations.
|
||||
Count - The number of I/O operations to perform.
|
||||
Bytes moves is Width size * Count, starting at Address.
|
||||
Buffer - The source buffer of data to be written.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - The data was written to the device.
|
||||
EFI_INVALID_PARAMETER - Width is invalid.
|
||||
EFI_OUT_OF_RESOURCES - The request could not be completed due to lack of resources.
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
DEVICE_IO_PRIVATE_DATA *Private;
|
||||
|
||||
Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);
|
||||
|
||||
if (Width >= MMIO_COPY_UINT8) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Status = Private->PciRootBridgeIo->Io.Write (
|
||||
Private->PciRootBridgeIo,
|
||||
(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
|
||||
Address,
|
||||
Count,
|
||||
Buffer
|
||||
);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DeviceIoPciRead (
|
||||
IN EFI_DEVICE_IO_PROTOCOL *This,
|
||||
IN EFI_IO_WIDTH Width,
|
||||
IN UINT64 Address,
|
||||
IN UINTN Count,
|
||||
IN OUT VOID *Buffer
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Perform reading PCI configuration space of device
|
||||
|
||||
Arguments:
|
||||
|
||||
This - A pointer to EFI_DEVICE_IO protocol instance.
|
||||
Width - Width of I/O operations.
|
||||
Address - The base address of I/O operations.
|
||||
Count - The number of I/O operations to perform.
|
||||
Bytes moves is Width size * Count, starting at Address.
|
||||
Buffer - The destination buffer to store results.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - The data was read from the device.
|
||||
EFI_INVALID_PARAMETER - Width is invalid.
|
||||
EFI_OUT_OF_RESOURCES - The request could not be completed due to lack of resources.
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
DEVICE_IO_PRIVATE_DATA *Private;
|
||||
|
||||
Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);
|
||||
|
||||
if (Width < 0 || Width >= MMIO_COPY_UINT8) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Status = Private->PciRootBridgeIo->Pci.Read (
|
||||
Private->PciRootBridgeIo,
|
||||
(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
|
||||
Address,
|
||||
Count,
|
||||
Buffer
|
||||
);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DeviceIoPciWrite (
|
||||
IN EFI_DEVICE_IO_PROTOCOL *This,
|
||||
IN EFI_IO_WIDTH Width,
|
||||
IN UINT64 Address,
|
||||
IN UINTN Count,
|
||||
IN OUT VOID *Buffer
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Perform writing PCI configuration space of device.
|
||||
|
||||
Arguments:
|
||||
|
||||
This - A pointer to EFI_DEVICE_IO protocol instance.
|
||||
Width - Width of I/O operations.
|
||||
Address - The base address of I/O operations.
|
||||
Count - The number of I/O operations to perform.
|
||||
Bytes moves is Width size * Count, starting at Address.
|
||||
Buffer - The source buffer of data to be written.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - The data was written to the device.
|
||||
EFI_INVALID_PARAMETER - Width is invalid.
|
||||
EFI_OUT_OF_RESOURCES - The request could not be completed due to lack of resources.
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
DEVICE_IO_PRIVATE_DATA *Private;
|
||||
|
||||
Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);
|
||||
|
||||
if (Width < 0 || Width >= MMIO_COPY_UINT8) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Status = Private->PciRootBridgeIo->Pci.Write (
|
||||
Private->PciRootBridgeIo,
|
||||
(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
|
||||
Address,
|
||||
Count,
|
||||
Buffer
|
||||
);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
EFI_DEVICE_PATH_PROTOCOL *
|
||||
AppendPciDevicePath (
|
||||
IN DEVICE_IO_PRIVATE_DATA *Private,
|
||||
IN UINT8 Bus,
|
||||
IN UINT8 Device,
|
||||
IN UINT8 Function,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
|
||||
IN OUT UINT16 *BridgePrimaryBus,
|
||||
IN OUT UINT16 *BridgeSubordinateBus
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Append a PCI device path node to another device path.
|
||||
|
||||
Arguments:
|
||||
|
||||
Private - A pointer to DEVICE_IO_PRIVATE_DATA instance.
|
||||
Bus - PCI bus number of the device.
|
||||
Device - PCI device number of the device.
|
||||
Function - PCI function number of the device.
|
||||
DevicePath - Original device path which will be appended a PCI device path node.
|
||||
BridgePrimaryBus - Primary bus number of the bridge.
|
||||
BridgeSubordinateBus - Subordinate bus number of the bridge.
|
||||
|
||||
Returns:
|
||||
|
||||
Pointer to the appended PCI device path.
|
||||
|
||||
--*/
|
||||
{
|
||||
UINT16 ThisBus;
|
||||
UINT8 ThisDevice;
|
||||
UINT8 ThisFunc;
|
||||
UINT64 Address;
|
||||
PCI_TYPE01 PciBridge;
|
||||
PCI_TYPE01 *PciPtr;
|
||||
EFI_DEVICE_PATH_PROTOCOL *ReturnDevicePath;
|
||||
PCI_DEVICE_PATH PciNode;
|
||||
|
||||
PciPtr = &PciBridge;
|
||||
for (ThisBus = *BridgePrimaryBus; ThisBus <= *BridgeSubordinateBus; ThisBus++) {
|
||||
for (ThisDevice = 0; ThisDevice <= PCI_MAX_DEVICE; ThisDevice++) {
|
||||
for (ThisFunc = 0; ThisFunc <= PCI_MAX_FUNC; ThisFunc++) {
|
||||
Address = EFI_PCI_ADDRESS (ThisBus, ThisDevice, ThisFunc, 0);
|
||||
ZeroMem (PciPtr, sizeof (PCI_TYPE01));
|
||||
Private->DeviceIo.Pci.Read (
|
||||
&Private->DeviceIo,
|
||||
IO_UINT32,
|
||||
Address,
|
||||
1,
|
||||
&(PciPtr->Hdr.VendorId)
|
||||
);
|
||||
if ((PciPtr->Hdr.VendorId == 0xffff) && (ThisFunc == 0)) {
|
||||
break;
|
||||
}
|
||||
if (PciPtr->Hdr.VendorId == 0xffff) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Private->DeviceIo.Pci.Read (
|
||||
&Private->DeviceIo,
|
||||
IO_UINT32,
|
||||
Address,
|
||||
sizeof (PCI_TYPE01) / sizeof (UINT32),
|
||||
PciPtr
|
||||
);
|
||||
if (IS_PCI_BRIDGE (PciPtr)) {
|
||||
if (Bus >= PciPtr->Bridge.SecondaryBus && Bus <= PciPtr->Bridge.SubordinateBus) {
|
||||
|
||||
PciNode.Header.Type = HARDWARE_DEVICE_PATH;
|
||||
PciNode.Header.SubType = HW_PCI_DP;
|
||||
SetDevicePathNodeLength (&PciNode.Header, sizeof (PciNode));
|
||||
|
||||
PciNode.Device = ThisDevice;
|
||||
PciNode.Function = ThisFunc;
|
||||
ReturnDevicePath = AppendDevicePathNode (DevicePath, &PciNode.Header);
|
||||
|
||||
*BridgePrimaryBus = PciPtr->Bridge.SecondaryBus;
|
||||
*BridgeSubordinateBus = PciPtr->Bridge.SubordinateBus;
|
||||
return ReturnDevicePath;
|
||||
}
|
||||
}
|
||||
|
||||
if ((ThisFunc == 0) && ((PciPtr->Hdr.HeaderType & HEADER_TYPE_MULTI_FUNCTION) == 0x0)) {
|
||||
//
|
||||
// Skip sub functions, this is not a multi function device
|
||||
//
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ZeroMem (&PciNode, sizeof (PciNode));
|
||||
PciNode.Header.Type = HARDWARE_DEVICE_PATH;
|
||||
PciNode.Header.SubType = HW_PCI_DP;
|
||||
SetDevicePathNodeLength (&PciNode.Header, sizeof (PciNode));
|
||||
PciNode.Device = Device;
|
||||
PciNode.Function = Function;
|
||||
|
||||
ReturnDevicePath = AppendDevicePathNode (DevicePath, &PciNode.Header);
|
||||
|
||||
*BridgePrimaryBus = 0xffff;
|
||||
*BridgeSubordinateBus = 0xffff;
|
||||
return ReturnDevicePath;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DeviceIoPciDevicePath (
|
||||
IN EFI_DEVICE_IO_PROTOCOL *This,
|
||||
IN UINT64 Address,
|
||||
IN OUT EFI_DEVICE_PATH_PROTOCOL **PciDevicePath
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Provides an EFI Device Path for a PCI device with the given PCI configuration space address.
|
||||
|
||||
Arguments:
|
||||
|
||||
This - A pointer to the EFI_DEVICE_IO_INTERFACE instance.
|
||||
Address - The PCI configuration space address of the device whose Device Path
|
||||
is going to be returned.
|
||||
PciDevicePath - A pointer to the pointer for the EFI Device Path for PciAddress.
|
||||
Memory for the Device Path is allocated from the pool.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - The PciDevicePath returns a pointer to a valid EFI Device Path.
|
||||
EFI_UNSUPPORTED - The PciAddress does not map to a valid EFI Device Path.
|
||||
EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of resources.
|
||||
|
||||
--*/
|
||||
{
|
||||
DEVICE_IO_PRIVATE_DATA *Private;
|
||||
UINT16 PrimaryBus;
|
||||
UINT16 SubordinateBus;
|
||||
UINT8 Bus;
|
||||
UINT8 Device;
|
||||
UINT8 Func;
|
||||
|
||||
Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);
|
||||
|
||||
Bus = (UINT8) (((UINT32) Address >> 24) & 0xff);
|
||||
Device = (UINT8) (((UINT32) Address >> 16) & 0xff);
|
||||
Func = (UINT8) (((UINT32) Address >> 8) & 0xff);
|
||||
|
||||
if (Bus < Private->PrimaryBus || Bus > Private->SubordinateBus) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
*PciDevicePath = Private->DevicePath;
|
||||
PrimaryBus = Private->PrimaryBus;
|
||||
SubordinateBus = Private->SubordinateBus;
|
||||
do {
|
||||
*PciDevicePath = AppendPciDevicePath (
|
||||
Private,
|
||||
Bus,
|
||||
Device,
|
||||
Func,
|
||||
*PciDevicePath,
|
||||
&PrimaryBus,
|
||||
&SubordinateBus
|
||||
);
|
||||
if (*PciDevicePath == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
} while (PrimaryBus != 0xffff);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DeviceIoMap (
|
||||
IN EFI_DEVICE_IO_PROTOCOL *This,
|
||||
IN EFI_IO_OPERATION_TYPE Operation,
|
||||
IN EFI_PHYSICAL_ADDRESS *HostAddress,
|
||||
IN OUT UINTN *NumberOfBytes,
|
||||
OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
|
||||
OUT VOID **Mapping
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Provides the device-specific addresses needed to access system memory.
|
||||
|
||||
Arguments:
|
||||
|
||||
This - A pointer to the EFI_DEVICE_IO_INTERFACE instance.
|
||||
Operation - Indicates if the bus master is going to read or write to system memory.
|
||||
HostAddress - The system memory address to map to the device.
|
||||
NumberOfBytes - On input the number of bytes to map. On output the number of bytes
|
||||
that were mapped.
|
||||
DeviceAddress - The resulting map address for the bus master device to use to access the
|
||||
hosts HostAddress.
|
||||
Mapping - A resulting value to pass to Unmap().
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - The range was mapped for the returned NumberOfBytes.
|
||||
EFI_INVALID_PARAMETER - The Operation or HostAddress is undefined.
|
||||
EFI_UNSUPPORTED - The HostAddress cannot be mapped as a common buffer.
|
||||
EFI_DEVICE_ERROR - The system hardware could not map the requested address.
|
||||
EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of resources.
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
DEVICE_IO_PRIVATE_DATA *Private;
|
||||
|
||||
Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);
|
||||
|
||||
if (Operation < 0 || Operation > EfiBusMasterCommonBuffer) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (((UINTN) (*HostAddress) != (*HostAddress)) && Operation == EfiBusMasterCommonBuffer) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
Status = Private->PciRootBridgeIo->Map (
|
||||
Private->PciRootBridgeIo,
|
||||
(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION) Operation,
|
||||
(VOID *) (UINTN) (*HostAddress),
|
||||
NumberOfBytes,
|
||||
DeviceAddress,
|
||||
Mapping
|
||||
);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DeviceIoUnmap (
|
||||
IN EFI_DEVICE_IO_PROTOCOL *This,
|
||||
IN VOID *Mapping
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Completes the Map() operation and releases any corresponding resources.
|
||||
|
||||
Arguments:
|
||||
|
||||
This - A pointer to the EFI_DEVICE_IO_INTERFACE instance.
|
||||
Mapping - The mapping value returned from Map().
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - The range was unmapped.
|
||||
EFI_DEVICE_ERROR - The data was not committed to the target system memory.
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
DEVICE_IO_PRIVATE_DATA *Private;
|
||||
|
||||
Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);
|
||||
|
||||
Status = Private->PciRootBridgeIo->Unmap (
|
||||
Private->PciRootBridgeIo,
|
||||
Mapping
|
||||
);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DeviceIoAllocateBuffer (
|
||||
IN EFI_DEVICE_IO_PROTOCOL *This,
|
||||
IN EFI_ALLOCATE_TYPE Type,
|
||||
IN EFI_MEMORY_TYPE MemoryType,
|
||||
IN UINTN Pages,
|
||||
IN OUT EFI_PHYSICAL_ADDRESS *PhysicalAddress
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Allocates pages that are suitable for an EFIBusMasterCommonBuffer mapping.
|
||||
|
||||
Arguments:
|
||||
|
||||
This - A pointer to the EFI_DEVICE_IO_INTERFACE instance.
|
||||
Type - The type allocation to perform.
|
||||
MemoryType - The type of memory to allocate, EfiBootServicesData or
|
||||
EfiRuntimeServicesData.
|
||||
Pages - The number of pages to allocate.
|
||||
PhysicalAddress - A pointer to store the base address of the allocated range.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - The requested memory pages were allocated.
|
||||
EFI_OUT_OF_RESOURCES - The memory pages could not be allocated.
|
||||
EFI_INVALID_PARAMETER - The requested memory type is invalid.
|
||||
EFI_UNSUPPORTED - The requested PhysicalAddress is not supported on
|
||||
this platform.
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_PHYSICAL_ADDRESS HostAddress;
|
||||
|
||||
HostAddress = *PhysicalAddress;
|
||||
|
||||
if ((MemoryType != EfiBootServicesData) && (MemoryType != EfiRuntimeServicesData)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if ((Type >= MaxAllocateType) || (Type < AllocateAnyPages)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if ((Type == AllocateAddress) && (HostAddress + EFI_PAGES_TO_SIZE (Pages) - 1 > MAX_COMMON_BUFFER)) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if ((AllocateAnyPages == Type) || (AllocateMaxAddress == Type && HostAddress > MAX_COMMON_BUFFER)) {
|
||||
Type = AllocateMaxAddress;
|
||||
HostAddress = MAX_COMMON_BUFFER;
|
||||
}
|
||||
|
||||
Status = gBS->AllocatePages (
|
||||
Type,
|
||||
MemoryType,
|
||||
Pages,
|
||||
&HostAddress
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
*PhysicalAddress = HostAddress;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DeviceIoFlush (
|
||||
IN EFI_DEVICE_IO_PROTOCOL *This
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Flushes any posted write data to the device.
|
||||
|
||||
Arguments:
|
||||
|
||||
This - A pointer to the EFI_DEVICE_IO_INTERFACE instance.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - The buffers were flushed.
|
||||
EFI_DEVICE_ERROR - The buffers were not flushed due to a hardware error.
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
DEVICE_IO_PRIVATE_DATA *Private;
|
||||
|
||||
Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This);
|
||||
|
||||
Status = Private->PciRootBridgeIo->Flush (Private->PciRootBridgeIo);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DeviceIoFreeBuffer (
|
||||
IN EFI_DEVICE_IO_PROTOCOL *This,
|
||||
IN UINTN Pages,
|
||||
IN EFI_PHYSICAL_ADDRESS HostAddress
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Frees pages that were allocated with AllocateBuffer().
|
||||
|
||||
Arguments:
|
||||
|
||||
This - A pointer to the EFI_DEVICE_IO_INTERFACE instance.
|
||||
Pages - The number of pages to free.
|
||||
HostAddress - The base address of the range to free.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - The requested memory pages were freed.
|
||||
EFI_NOT_FOUND - The requested memory pages were not allocated with
|
||||
AllocateBuffer().
|
||||
EFI_INVALID_PARAMETER - HostAddress is not page aligned or Pages is invalid.
|
||||
|
||||
--*/
|
||||
{
|
||||
if (((HostAddress & EFI_PAGE_MASK) != 0) || (Pages <= 0)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
return gBS->FreePages (HostAddress, Pages);
|
||||
}
|
449
DuetPkg/PciRootBridgeNoEnumerationDxe/DeviceIo.h
Normal file
449
DuetPkg/PciRootBridgeNoEnumerationDxe/DeviceIo.h
Normal file
@ -0,0 +1,449 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. 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.
|
||||
|
||||
Module Name:
|
||||
|
||||
DeviceIo.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Private Data definition for Device IO driver
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef _DEVICE_IO_H
|
||||
#define _DEVICE_IO_H
|
||||
|
||||
|
||||
|
||||
#define DEVICE_IO_PRIVATE_DATA_SIGNATURE EFI_SIGNATURE_32 ('d', 'e', 'v', 'I')
|
||||
|
||||
#define MAX_COMMON_BUFFER 0x00000000FFFFFFFF
|
||||
|
||||
typedef struct {
|
||||
UINTN Signature;
|
||||
EFI_HANDLE Handle;
|
||||
EFI_DEVICE_IO_PROTOCOL DeviceIo;
|
||||
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
|
||||
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
|
||||
UINT16 PrimaryBus;
|
||||
UINT16 SubordinateBus;
|
||||
} DEVICE_IO_PRIVATE_DATA;
|
||||
|
||||
#define DEVICE_IO_PRIVATE_DATA_FROM_THIS(a) CR (a, DEVICE_IO_PRIVATE_DATA, DeviceIo, DEVICE_IO_PRIVATE_DATA_SIGNATURE)
|
||||
|
||||
EFI_STATUS
|
||||
DeviceIoConstructor (
|
||||
IN EFI_HANDLE Handle,
|
||||
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
|
||||
IN UINT16 PrimaryBus,
|
||||
IN UINT16 SubordinateBus
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Initialize and install a Device IO protocol on a empty device path handle.
|
||||
|
||||
Arguments:
|
||||
|
||||
Handle - Handle of PCI RootBridge IO instance
|
||||
PciRootBridgeIo - PCI RootBridge IO instance
|
||||
DevicePath - Device Path of PCI RootBridge IO instance
|
||||
PrimaryBus - Primary Bus
|
||||
SubordinateBus - Subordinate Bus
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - This driver is added to ControllerHandle.
|
||||
EFI_ALREADY_STARTED - This driver is already running on ControllerHandle.
|
||||
Others - This driver does not support this device.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DeviceIoMemRead (
|
||||
IN EFI_DEVICE_IO_PROTOCOL *This,
|
||||
IN EFI_IO_WIDTH Width,
|
||||
IN UINT64 Address,
|
||||
IN UINTN Count,
|
||||
IN OUT VOID *Buffer
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Perform reading memory mapped I/O space of device.
|
||||
|
||||
Arguments:
|
||||
|
||||
This - A pointer to EFI_DEVICE_IO protocol instance.
|
||||
Width - Width of I/O operations.
|
||||
Address - The base address of I/O operations.
|
||||
Count - The number of I/O operations to perform.
|
||||
Bytes moves is Width size * Count, starting at Address.
|
||||
Buffer - The destination buffer to store results.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - The data was read from the device.
|
||||
EFI_INVALID_PARAMETER - Width is invalid.
|
||||
EFI_OUT_OF_RESOURCES - The request could not be completed due to lack of resources.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DeviceIoMemWrite (
|
||||
IN EFI_DEVICE_IO_PROTOCOL *This,
|
||||
IN EFI_IO_WIDTH Width,
|
||||
IN UINT64 Address,
|
||||
IN UINTN Count,
|
||||
IN OUT VOID *Buffer
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Perform writing memory mapped I/O space of device.
|
||||
|
||||
Arguments:
|
||||
|
||||
This - A pointer to EFI_DEVICE_IO protocol instance.
|
||||
Width - Width of I/O operations.
|
||||
Address - The base address of I/O operations.
|
||||
Count - The number of I/O operations to perform.
|
||||
Bytes moves is Width size * Count, starting at Address.
|
||||
Buffer - The source buffer of data to be written.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - The data was written to the device.
|
||||
EFI_INVALID_PARAMETER - Width is invalid.
|
||||
EFI_OUT_OF_RESOURCES - The request could not be completed due to lack of resources.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DeviceIoIoRead (
|
||||
IN EFI_DEVICE_IO_PROTOCOL *This,
|
||||
IN EFI_IO_WIDTH Width,
|
||||
IN UINT64 Address,
|
||||
IN UINTN Count,
|
||||
IN OUT VOID *Buffer
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Perform reading I/O space of device.
|
||||
|
||||
Arguments:
|
||||
|
||||
This - A pointer to EFI_DEVICE_IO protocol instance.
|
||||
Width - Width of I/O operations.
|
||||
Address - The base address of I/O operations.
|
||||
Count - The number of I/O operations to perform.
|
||||
Bytes moves is Width size * Count, starting at Address.
|
||||
Buffer - The destination buffer to store results.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - The data was read from the device.
|
||||
EFI_INVALID_PARAMETER - Width is invalid.
|
||||
EFI_OUT_OF_RESOURCES - The request could not be completed due to lack of resources.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DeviceIoIoWrite (
|
||||
IN EFI_DEVICE_IO_PROTOCOL *This,
|
||||
IN EFI_IO_WIDTH Width,
|
||||
IN UINT64 Address,
|
||||
IN UINTN Count,
|
||||
IN OUT VOID *Buffer
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Perform writing I/O space of device.
|
||||
|
||||
Arguments:
|
||||
|
||||
This - A pointer to EFI_DEVICE_IO protocol instance.
|
||||
Width - Width of I/O operations.
|
||||
Address - The base address of I/O operations.
|
||||
Count - The number of I/O operations to perform.
|
||||
Bytes moves is Width size * Count, starting at Address.
|
||||
Buffer - The source buffer of data to be written.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - The data was written to the device.
|
||||
EFI_INVALID_PARAMETER - Width is invalid.
|
||||
EFI_OUT_OF_RESOURCES - The request could not be completed due to lack of resources.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DeviceIoPciRead (
|
||||
IN EFI_DEVICE_IO_PROTOCOL *This,
|
||||
IN EFI_IO_WIDTH Width,
|
||||
IN UINT64 Address,
|
||||
IN UINTN Count,
|
||||
IN OUT VOID *Buffer
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Perform reading PCI configuration space of device
|
||||
|
||||
Arguments:
|
||||
|
||||
This - A pointer to EFI_DEVICE_IO protocol instance.
|
||||
Width - Width of I/O operations.
|
||||
Address - The base address of I/O operations.
|
||||
Count - The number of I/O operations to perform.
|
||||
Bytes moves is Width size * Count, starting at Address.
|
||||
Buffer - The destination buffer to store results.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - The data was read from the device.
|
||||
EFI_INVALID_PARAMETER - Width is invalid.
|
||||
EFI_OUT_OF_RESOURCES - The request could not be completed due to lack of resources.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DeviceIoPciWrite (
|
||||
IN EFI_DEVICE_IO_PROTOCOL *This,
|
||||
IN EFI_IO_WIDTH Width,
|
||||
IN UINT64 Address,
|
||||
IN UINTN Count,
|
||||
IN OUT VOID *Buffer
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Perform writing PCI configuration space of device.
|
||||
|
||||
Arguments:
|
||||
|
||||
This - A pointer to EFI_DEVICE_IO protocol instance.
|
||||
Width - Width of I/O operations.
|
||||
Address - The base address of I/O operations.
|
||||
Count - The number of I/O operations to perform.
|
||||
Bytes moves is Width size * Count, starting at Address.
|
||||
Buffer - The source buffer of data to be written.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - The data was written to the device.
|
||||
EFI_INVALID_PARAMETER - Width is invalid.
|
||||
EFI_OUT_OF_RESOURCES - The request could not be completed due to lack of resources.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DeviceIoPciDevicePath (
|
||||
IN EFI_DEVICE_IO_PROTOCOL *This,
|
||||
IN UINT64 Address,
|
||||
IN OUT EFI_DEVICE_PATH_PROTOCOL **PciDevicePath
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Append a PCI device path node to another device path.
|
||||
|
||||
Arguments:
|
||||
|
||||
This - A pointer to EFI_DEVICE_IO_PROTOCOL.
|
||||
Address - PCI bus,device, function.
|
||||
PciDevicePath - PCI device path.
|
||||
|
||||
Returns:
|
||||
|
||||
Pointer to the appended PCI device path.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DeviceIoMap (
|
||||
IN EFI_DEVICE_IO_PROTOCOL *This,
|
||||
IN EFI_IO_OPERATION_TYPE Operation,
|
||||
IN EFI_PHYSICAL_ADDRESS *HostAddress,
|
||||
IN OUT UINTN *NumberOfBytes,
|
||||
OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
|
||||
OUT VOID **Mapping
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Provides the device-specific addresses needed to access system memory.
|
||||
|
||||
Arguments:
|
||||
|
||||
This - A pointer to the EFI_DEVICE_IO_INTERFACE instance.
|
||||
Operation - Indicates if the bus master is going to read or write to system memory.
|
||||
HostAddress - The system memory address to map to the device.
|
||||
NumberOfBytes - On input the number of bytes to map. On output the number of bytes
|
||||
that were mapped.
|
||||
DeviceAddress - The resulting map address for the bus master device to use to access the
|
||||
hosts HostAddress.
|
||||
Mapping - A resulting value to pass to Unmap().
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - The range was mapped for the returned NumberOfBytes.
|
||||
EFI_INVALID_PARAMETER - The Operation or HostAddress is undefined.
|
||||
EFI_UNSUPPORTED - The HostAddress cannot be mapped as a common buffer.
|
||||
EFI_DEVICE_ERROR - The system hardware could not map the requested address.
|
||||
EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of resources.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DeviceIoUnmap (
|
||||
IN EFI_DEVICE_IO_PROTOCOL *This,
|
||||
IN VOID *Mapping
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Completes the Map() operation and releases any corresponding resources.
|
||||
|
||||
Arguments:
|
||||
|
||||
This - A pointer to the EFI_DEVICE_IO_INTERFACE instance.
|
||||
Mapping - The mapping value returned from Map().
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - The range was unmapped.
|
||||
EFI_DEVICE_ERROR - The data was not committed to the target system memory.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DeviceIoAllocateBuffer (
|
||||
IN EFI_DEVICE_IO_PROTOCOL *This,
|
||||
IN EFI_ALLOCATE_TYPE Type,
|
||||
IN EFI_MEMORY_TYPE MemoryType,
|
||||
IN UINTN Pages,
|
||||
IN OUT EFI_PHYSICAL_ADDRESS *HostAddress
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Allocates pages that are suitable for an EFIBusMasterCommonBuffer mapping.
|
||||
|
||||
Arguments:
|
||||
|
||||
This - A pointer to the EFI_DEVICE_IO_INTERFACE instance.
|
||||
Type - The type allocation to perform.
|
||||
MemoryType - The type of memory to allocate, EfiBootServicesData or
|
||||
EfiRuntimeServicesData.
|
||||
Pages - The number of pages to allocate.
|
||||
HostAddress - A pointer to store the base address of the allocated range.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - The requested memory pages were allocated.
|
||||
EFI_OUT_OF_RESOURCES - The memory pages could not be allocated.
|
||||
EFI_INVALID_PARAMETER - The requested memory type is invalid.
|
||||
EFI_UNSUPPORTED - The requested PhysicalAddress is not supported on
|
||||
this platform.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DeviceIoFlush (
|
||||
IN EFI_DEVICE_IO_PROTOCOL *This
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Flushes any posted write data to the device.
|
||||
|
||||
Arguments:
|
||||
|
||||
This - A pointer to the EFI_DEVICE_IO_INTERFACE instance.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - The buffers were flushed.
|
||||
EFI_DEVICE_ERROR - The buffers were not flushed due to a hardware error.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DeviceIoFreeBuffer (
|
||||
IN EFI_DEVICE_IO_PROTOCOL *This,
|
||||
IN UINTN Pages,
|
||||
IN EFI_PHYSICAL_ADDRESS HostAddress
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Frees pages that were allocated with AllocateBuffer().
|
||||
|
||||
Arguments:
|
||||
|
||||
This - A pointer to the EFI_DEVICE_IO_INTERFACE instance.
|
||||
Pages - The number of pages to free.
|
||||
HostAddress - The base address of the range to free.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - The requested memory pages were freed.
|
||||
EFI_NOT_FOUND - The requested memory pages were not allocated with
|
||||
AllocateBuffer().
|
||||
EFI_INVALID_PARAMETER - HostAddress is not page aligned or Pages is invalid.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
#endif
|
||||
|
734
DuetPkg/PciRootBridgeNoEnumerationDxe/Ia32/PcatIo.c
Normal file
734
DuetPkg/PciRootBridgeNoEnumerationDxe/Ia32/PcatIo.c
Normal file
@ -0,0 +1,734 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2005 - 2006, Intel Corporation
|
||||
All rights reserved. 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.
|
||||
|
||||
Module Name:
|
||||
PcatPciRootBridgeIo.c
|
||||
|
||||
Abstract:
|
||||
|
||||
EFI PC AT PCI Root Bridge Io Protocol
|
||||
|
||||
Revision History
|
||||
|
||||
--*/
|
||||
|
||||
#include "PcatPciRootBridge.h"
|
||||
|
||||
static BOOLEAN mPciOptionRomTableInstalled = FALSE;
|
||||
static EFI_PCI_OPTION_ROM_TABLE mPciOptionRomTable = {0, NULL};
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PcatRootBridgeIoIoRead (
|
||||
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
|
||||
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
|
||||
IN UINT64 UserAddress,
|
||||
IN UINTN Count,
|
||||
IN OUT VOID *UserBuffer
|
||||
)
|
||||
{
|
||||
return gCpuIo->Io.Read (
|
||||
gCpuIo,
|
||||
(EFI_CPU_IO_PROTOCOL_WIDTH) Width,
|
||||
UserAddress,
|
||||
Count,
|
||||
UserBuffer
|
||||
);
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PcatRootBridgeIoIoWrite (
|
||||
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
|
||||
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
|
||||
IN UINT64 UserAddress,
|
||||
IN UINTN Count,
|
||||
IN OUT VOID *UserBuffer
|
||||
)
|
||||
{
|
||||
return gCpuIo->Io.Write (
|
||||
gCpuIo,
|
||||
(EFI_CPU_IO_PROTOCOL_WIDTH) Width,
|
||||
UserAddress,
|
||||
Count,
|
||||
UserBuffer
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
PcatRootBridgeIoGetIoPortMapping (
|
||||
OUT EFI_PHYSICAL_ADDRESS *IoPortMapping,
|
||||
OUT EFI_PHYSICAL_ADDRESS *MemoryPortMapping
|
||||
)
|
||||
/*++
|
||||
|
||||
Get the IO Port Mapping. For IA-32 it is always 0.
|
||||
|
||||
--*/
|
||||
{
|
||||
*IoPortMapping = 0;
|
||||
*MemoryPortMapping = 0;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
PcatRootBridgeIoPciRW (
|
||||
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
|
||||
IN BOOLEAN Write,
|
||||
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
|
||||
IN UINT64 UserAddress,
|
||||
IN UINTN Count,
|
||||
IN OUT VOID *UserBuffer
|
||||
)
|
||||
{
|
||||
PCI_CONFIG_ACCESS_CF8 Pci;
|
||||
PCI_CONFIG_ACCESS_CF8 PciAligned;
|
||||
UINT32 InStride;
|
||||
UINT32 OutStride;
|
||||
UINTN PciData;
|
||||
UINTN PciDataStride;
|
||||
PCAT_PCI_ROOT_BRIDGE_INSTANCE *PrivateData;
|
||||
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS PciAddress;
|
||||
UINT64 PciExpressRegAddr;
|
||||
BOOLEAN UsePciExpressAccess;
|
||||
|
||||
if (Width < 0 || Width >= EfiPciWidthMaximum) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if ((Width & 0x03) >= EfiPciWidthUint64) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This);
|
||||
|
||||
InStride = 1 << (Width & 0x03);
|
||||
OutStride = InStride;
|
||||
if (Width >= EfiCpuIoWidthFifoUint8 && Width <= EfiCpuIoWidthFifoUint64) {
|
||||
InStride = 0;
|
||||
}
|
||||
|
||||
if (Width >= EfiCpuIoWidthFillUint8 && Width <= EfiCpuIoWidthFillUint64) {
|
||||
OutStride = 0;
|
||||
}
|
||||
|
||||
UsePciExpressAccess = FALSE;
|
||||
|
||||
CopyMem (&PciAddress, &UserAddress, sizeof(UINT64));
|
||||
|
||||
if (PciAddress.ExtendedRegister > 0xFF) {
|
||||
//
|
||||
// Check PciExpressBaseAddress
|
||||
//
|
||||
if ((PrivateData->PciExpressBaseAddress == 0) ||
|
||||
(PrivateData->PciExpressBaseAddress >= EFI_MAX_ADDRESS)) {
|
||||
return EFI_UNSUPPORTED;
|
||||
} else {
|
||||
UsePciExpressAccess = TRUE;
|
||||
}
|
||||
} else {
|
||||
if (PciAddress.ExtendedRegister != 0) {
|
||||
Pci.Bits.Reg = PciAddress.ExtendedRegister & 0xFF;
|
||||
} else {
|
||||
Pci.Bits.Reg = PciAddress.Register;
|
||||
}
|
||||
//
|
||||
// Note: We can also use PciExpress access here, if wanted.
|
||||
//
|
||||
}
|
||||
|
||||
if (!UsePciExpressAccess) {
|
||||
Pci.Bits.Func = PciAddress.Function;
|
||||
Pci.Bits.Dev = PciAddress.Device;
|
||||
Pci.Bits.Bus = PciAddress.Bus;
|
||||
Pci.Bits.Reserved = 0;
|
||||
Pci.Bits.Enable = 1;
|
||||
|
||||
//
|
||||
// PCI Config access are all 32-bit alligned, but by accessing the
|
||||
// CONFIG_DATA_REGISTER (0xcfc) with different widths more cycle types
|
||||
// are possible on PCI.
|
||||
//
|
||||
// To read a byte of PCI config space you load 0xcf8 and
|
||||
// read 0xcfc, 0xcfd, 0xcfe, 0xcff
|
||||
//
|
||||
PciDataStride = Pci.Bits.Reg & 0x03;
|
||||
|
||||
while (Count) {
|
||||
PciAligned = Pci;
|
||||
PciAligned.Bits.Reg &= 0xfc;
|
||||
PciData = (UINTN)PrivateData->PciData + PciDataStride;
|
||||
EfiAcquireLock(&PrivateData->PciLock);
|
||||
This->Io.Write (This, EfiPciWidthUint32, PrivateData->PciAddress, 1, &PciAligned);
|
||||
if (Write) {
|
||||
This->Io.Write (This, Width, PciData, 1, UserBuffer);
|
||||
} else {
|
||||
This->Io.Read (This, Width, PciData, 1, UserBuffer);
|
||||
}
|
||||
EfiReleaseLock(&PrivateData->PciLock);
|
||||
UserBuffer = ((UINT8 *)UserBuffer) + OutStride;
|
||||
PciDataStride = (PciDataStride + InStride) % 4;
|
||||
Pci.Bits.Reg += InStride;
|
||||
Count -= 1;
|
||||
}
|
||||
} else {
|
||||
//
|
||||
// Access PCI-Express space by using memory mapped method.
|
||||
//
|
||||
PciExpressRegAddr = (PrivateData->PciExpressBaseAddress) |
|
||||
(PciAddress.Bus << 20) |
|
||||
(PciAddress.Device << 15) |
|
||||
(PciAddress.Function << 12);
|
||||
if (PciAddress.ExtendedRegister != 0) {
|
||||
PciExpressRegAddr += PciAddress.ExtendedRegister;
|
||||
} else {
|
||||
PciExpressRegAddr += PciAddress.Register;
|
||||
}
|
||||
while (Count) {
|
||||
if (Write) {
|
||||
This->Mem.Write (This, Width, (UINTN) PciExpressRegAddr, 1, UserBuffer);
|
||||
} else {
|
||||
This->Mem.Read (This, Width, (UINTN) PciExpressRegAddr, 1, UserBuffer);
|
||||
}
|
||||
|
||||
UserBuffer = ((UINT8 *) UserBuffer) + OutStride;
|
||||
PciExpressRegAddr += InStride;
|
||||
Count -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
static
|
||||
VOID
|
||||
ScanPciBus(
|
||||
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev,
|
||||
UINT16 MinBus,
|
||||
UINT16 MaxBus,
|
||||
UINT16 MinDevice,
|
||||
UINT16 MaxDevice,
|
||||
UINT16 MinFunc,
|
||||
UINT16 MaxFunc,
|
||||
EFI_PCI_BUS_SCAN_CALLBACK Callback,
|
||||
VOID *Context
|
||||
)
|
||||
|
||||
{
|
||||
UINT16 Bus;
|
||||
UINT16 Device;
|
||||
UINT16 Func;
|
||||
UINT64 Address;
|
||||
PCI_TYPE00 PciHeader;
|
||||
|
||||
//
|
||||
// Loop through all busses
|
||||
//
|
||||
for (Bus = MinBus; Bus <= MaxBus; Bus++) {
|
||||
//
|
||||
// Loop 32 devices per bus
|
||||
//
|
||||
for (Device = MinDevice; Device <= MaxDevice; Device++) {
|
||||
//
|
||||
// Loop through 8 functions per device
|
||||
//
|
||||
for (Func = MinFunc; Func <= MaxFunc; Func++) {
|
||||
|
||||
//
|
||||
// Compute the EFI Address required to access the PCI Configuration Header of this PCI Device
|
||||
//
|
||||
Address = EFI_PCI_ADDRESS (Bus, Device, Func, 0);
|
||||
|
||||
//
|
||||
// Read the VendorID from this PCI Device's Confioguration Header
|
||||
//
|
||||
IoDev->Pci.Read (IoDev, EfiPciWidthUint16, Address, 1, &PciHeader.Hdr.VendorId);
|
||||
|
||||
//
|
||||
// If VendorId = 0xffff, there does not exist a device at this
|
||||
// location. For each device, if there is any function on it,
|
||||
// there must be 1 function at Function 0. So if Func = 0, there
|
||||
// will be no more functions in the same device, so we can break
|
||||
// loop to deal with the next device.
|
||||
//
|
||||
if (PciHeader.Hdr.VendorId == 0xffff && Func == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (PciHeader.Hdr.VendorId != 0xffff) {
|
||||
|
||||
//
|
||||
// Read the HeaderType to determine if this is a multi-function device
|
||||
//
|
||||
IoDev->Pci.Read (IoDev, EfiPciWidthUint8, Address + 0x0e, 1, &PciHeader.Hdr.HeaderType);
|
||||
|
||||
//
|
||||
// Call the callback function for the device that was found
|
||||
//
|
||||
Callback(
|
||||
IoDev,
|
||||
MinBus, MaxBus,
|
||||
MinDevice, MaxDevice,
|
||||
MinFunc, MaxFunc,
|
||||
Bus,
|
||||
Device,
|
||||
Func,
|
||||
Context
|
||||
);
|
||||
|
||||
//
|
||||
// If this is not a multi-function device, we can leave the loop
|
||||
// to deal with the next device.
|
||||
//
|
||||
if ((PciHeader.Hdr.HeaderType & HEADER_TYPE_MULTI_FUNCTION) == 0x00 && Func == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
VOID
|
||||
CheckForRom (
|
||||
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev,
|
||||
UINT16 MinBus,
|
||||
UINT16 MaxBus,
|
||||
UINT16 MinDevice,
|
||||
UINT16 MaxDevice,
|
||||
UINT16 MinFunc,
|
||||
UINT16 MaxFunc,
|
||||
UINT16 Bus,
|
||||
UINT16 Device,
|
||||
UINT16 Func,
|
||||
IN VOID *VoidContext
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
PCAT_PCI_ROOT_BRIDGE_SCAN_FOR_ROM_CONTEXT *Context;
|
||||
UINT64 Address;
|
||||
PCI_TYPE00 PciHeader;
|
||||
PCI_TYPE01 *PciBridgeHeader;
|
||||
UINT32 Register;
|
||||
UINT32 RomBar;
|
||||
UINT32 RomBarSize;
|
||||
EFI_PHYSICAL_ADDRESS RomBuffer;
|
||||
UINT32 MaxRomSize;
|
||||
EFI_PCI_EXPANSION_ROM_HEADER EfiRomHeader;
|
||||
PCI_DATA_STRUCTURE Pcir;
|
||||
EFI_PCI_OPTION_ROM_DESCRIPTOR *TempPciOptionRomDescriptors;
|
||||
BOOLEAN LastImage;
|
||||
|
||||
Context = (PCAT_PCI_ROOT_BRIDGE_SCAN_FOR_ROM_CONTEXT *)VoidContext;
|
||||
|
||||
Address = EFI_PCI_ADDRESS (Bus, Device, Func, 0);
|
||||
|
||||
//
|
||||
// Save the contents of the PCI Configuration Header
|
||||
//
|
||||
IoDev->Pci.Read (IoDev, EfiPciWidthUint32, Address, sizeof(PciHeader)/sizeof(UINT32), &PciHeader);
|
||||
|
||||
if (IS_PCI_BRIDGE(&PciHeader)) {
|
||||
|
||||
PciBridgeHeader = (PCI_TYPE01 *)(&PciHeader);
|
||||
|
||||
//
|
||||
// See if the PCI-PCI Bridge has its secondary interface enabled.
|
||||
//
|
||||
if (PciBridgeHeader->Bridge.SubordinateBus >= PciBridgeHeader->Bridge.SecondaryBus) {
|
||||
|
||||
//
|
||||
// Disable the Prefetchable Memory Window
|
||||
//
|
||||
Register = 0x00000000;
|
||||
IoDev->Pci.Write (IoDev, EfiPciWidthUint16, Address + 0x26, 1, &Register);
|
||||
IoDev->Pci.Write (IoDev, EfiPciWidthUint32, Address + 0x2c, 1, &Register);
|
||||
Register = 0xffffffff;
|
||||
IoDev->Pci.Write (IoDev, EfiPciWidthUint16, Address + 0x24, 1, &Register);
|
||||
IoDev->Pci.Write (IoDev, EfiPciWidthUint16, Address + 0x28, 1, &Register);
|
||||
|
||||
//
|
||||
// Program Memory Window to the PCI Root Bridge Memory Window
|
||||
//
|
||||
IoDev->Pci.Write (IoDev, EfiPciWidthUint16, Address + 0x20, 4, &Context->PpbMemoryWindow);
|
||||
|
||||
//
|
||||
// Enable the Memory decode for the PCI-PCI Bridge
|
||||
//
|
||||
IoDev->Pci.Read (IoDev, EfiPciWidthUint16, Address + 4, 1, &Register);
|
||||
Register |= 0x02;
|
||||
IoDev->Pci.Write (IoDev, EfiPciWidthUint16, Address + 4, 1, &Register);
|
||||
|
||||
//
|
||||
// Recurse on the Secondary Bus Number
|
||||
//
|
||||
ScanPciBus(
|
||||
IoDev,
|
||||
PciBridgeHeader->Bridge.SecondaryBus, PciBridgeHeader->Bridge.SecondaryBus,
|
||||
0, PCI_MAX_DEVICE,
|
||||
0, PCI_MAX_FUNC,
|
||||
CheckForRom, Context
|
||||
);
|
||||
}
|
||||
} else {
|
||||
|
||||
//
|
||||
// Check if an Option ROM Register is present and save the Option ROM Window Register
|
||||
//
|
||||
RomBar = 0xffffffff;
|
||||
IoDev->Pci.Write (IoDev, EfiPciWidthUint32, Address + 0x30, 1, &RomBar);
|
||||
IoDev->Pci.Read (IoDev, EfiPciWidthUint32, Address + 0x30, 1, &RomBar);
|
||||
|
||||
RomBarSize = (~(RomBar & 0xfffff800)) + 1;
|
||||
|
||||
//
|
||||
// Make sure the size of the ROM is between 0 and 16 MB
|
||||
//
|
||||
if (RomBarSize > 0 && RomBarSize <= 0x01000000) {
|
||||
|
||||
//
|
||||
// Program Option ROM Window Register to the PCI Root Bridge Window and Enable the Option ROM Window
|
||||
//
|
||||
RomBar = (Context->PpbMemoryWindow & 0xffff) << 16;
|
||||
RomBar = ((RomBar - 1) & (~(RomBarSize - 1))) + RomBarSize;
|
||||
if (RomBar < (Context->PpbMemoryWindow & 0xffff0000)) {
|
||||
MaxRomSize = (Context->PpbMemoryWindow & 0xffff0000) - RomBar;
|
||||
RomBar = RomBar + 1;
|
||||
IoDev->Pci.Write (IoDev, EfiPciWidthUint32, Address + 0x30, 1, &RomBar);
|
||||
IoDev->Pci.Read (IoDev, EfiPciWidthUint32, Address + 0x30, 1, &RomBar);
|
||||
RomBar = RomBar - 1;
|
||||
|
||||
//
|
||||
// Enable the Memory decode for the PCI Device
|
||||
//
|
||||
IoDev->Pci.Read (IoDev, EfiPciWidthUint16, Address + 4, 1, &Register);
|
||||
Register |= 0x02;
|
||||
IoDev->Pci.Write (IoDev, EfiPciWidthUint16, Address + 4, 1, &Register);
|
||||
|
||||
//
|
||||
// Follow the chain of images to determine the size of the Option ROM present
|
||||
// Keep going until the last image is found by looking at the Indicator field
|
||||
// or the size of an image is 0, or the size of all the images is bigger than the
|
||||
// size of the window programmed into the PPB.
|
||||
//
|
||||
RomBarSize = 0;
|
||||
do {
|
||||
|
||||
LastImage = TRUE;
|
||||
|
||||
ZeroMem (&EfiRomHeader, sizeof(EfiRomHeader));
|
||||
IoDev->Mem.Read (
|
||||
IoDev,
|
||||
EfiPciWidthUint8,
|
||||
RomBar + RomBarSize,
|
||||
sizeof(EfiRomHeader),
|
||||
&EfiRomHeader
|
||||
);
|
||||
|
||||
Pcir.ImageLength = 0;
|
||||
|
||||
if (EfiRomHeader.Signature == 0xaa55) {
|
||||
|
||||
ZeroMem (&Pcir, sizeof(Pcir));
|
||||
IoDev->Mem.Read (
|
||||
IoDev,
|
||||
EfiPciWidthUint8,
|
||||
RomBar + RomBarSize + EfiRomHeader.PcirOffset,
|
||||
sizeof(Pcir),
|
||||
&Pcir
|
||||
);
|
||||
|
||||
if ((Pcir.Indicator & 0x80) == 0x00) {
|
||||
LastImage = FALSE;
|
||||
}
|
||||
|
||||
RomBarSize += Pcir.ImageLength * 512;
|
||||
}
|
||||
} while (!LastImage && RomBarSize < MaxRomSize && Pcir.ImageLength !=0);
|
||||
|
||||
if (RomBarSize > 0) {
|
||||
|
||||
//
|
||||
// Allocate a memory buffer for the Option ROM contents.
|
||||
//
|
||||
Status = gBS->AllocatePages(
|
||||
AllocateAnyPages,
|
||||
EfiBootServicesData,
|
||||
EFI_SIZE_TO_PAGES(RomBarSize),
|
||||
&RomBuffer
|
||||
);
|
||||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
|
||||
//
|
||||
// Copy the contents of the Option ROM to the memory buffer
|
||||
//
|
||||
IoDev->Mem.Read (IoDev, EfiPciWidthUint32, RomBar, RomBarSize / sizeof(UINT32), (VOID *)(UINTN)RomBuffer);
|
||||
|
||||
Status = gBS->AllocatePool(
|
||||
EfiBootServicesData,
|
||||
((UINT32)mPciOptionRomTable.PciOptionRomCount + 1) * sizeof(EFI_PCI_OPTION_ROM_DESCRIPTOR),
|
||||
&TempPciOptionRomDescriptors
|
||||
);
|
||||
if (mPciOptionRomTable.PciOptionRomCount > 0) {
|
||||
CopyMem(
|
||||
TempPciOptionRomDescriptors,
|
||||
mPciOptionRomTable.PciOptionRomDescriptors,
|
||||
(UINT32)mPciOptionRomTable.PciOptionRomCount * sizeof(EFI_PCI_OPTION_ROM_DESCRIPTOR)
|
||||
);
|
||||
|
||||
gBS->FreePool(mPciOptionRomTable.PciOptionRomDescriptors);
|
||||
}
|
||||
|
||||
mPciOptionRomTable.PciOptionRomDescriptors = TempPciOptionRomDescriptors;
|
||||
|
||||
TempPciOptionRomDescriptors = &(mPciOptionRomTable.PciOptionRomDescriptors[(UINT32)mPciOptionRomTable.PciOptionRomCount]);
|
||||
|
||||
TempPciOptionRomDescriptors->RomAddress = RomBuffer;
|
||||
TempPciOptionRomDescriptors->MemoryType = EfiBootServicesData;
|
||||
TempPciOptionRomDescriptors->RomLength = RomBarSize;
|
||||
TempPciOptionRomDescriptors->Seg = (UINT32)IoDev->SegmentNumber;
|
||||
TempPciOptionRomDescriptors->Bus = (UINT8)Bus;
|
||||
TempPciOptionRomDescriptors->Dev = (UINT8)Device;
|
||||
TempPciOptionRomDescriptors->Func = (UINT8)Func;
|
||||
TempPciOptionRomDescriptors->ExecutedLegacyBiosImage = TRUE;
|
||||
TempPciOptionRomDescriptors->DontLoadEfiRom = FALSE;
|
||||
|
||||
mPciOptionRomTable.PciOptionRomCount++;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Disable the Memory decode for the PCI-PCI Bridge
|
||||
//
|
||||
IoDev->Pci.Read (IoDev, EfiPciWidthUint16, Address + 4, 1, &Register);
|
||||
Register &= (~0x02);
|
||||
IoDev->Pci.Write (IoDev, EfiPciWidthUint16, Address + 4, 1, &Register);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Restore the PCI Configuration Header
|
||||
//
|
||||
IoDev->Pci.Write (IoDev, EfiPciWidthUint32, Address, sizeof(PciHeader)/sizeof(UINT32), &PciHeader);
|
||||
}
|
||||
|
||||
static
|
||||
VOID
|
||||
SaveCommandRegister (
|
||||
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev,
|
||||
UINT16 MinBus,
|
||||
UINT16 MaxBus,
|
||||
UINT16 MinDevice,
|
||||
UINT16 MaxDevice,
|
||||
UINT16 MinFunc,
|
||||
UINT16 MaxFunc,
|
||||
UINT16 Bus,
|
||||
UINT16 Device,
|
||||
UINT16 Func,
|
||||
IN VOID *VoidContext
|
||||
)
|
||||
|
||||
{
|
||||
PCAT_PCI_ROOT_BRIDGE_SCAN_FOR_ROM_CONTEXT *Context;
|
||||
UINT64 Address;
|
||||
UINTN Index;
|
||||
UINT16 Command;
|
||||
|
||||
Context = (PCAT_PCI_ROOT_BRIDGE_SCAN_FOR_ROM_CONTEXT *)VoidContext;
|
||||
|
||||
Address = EFI_PCI_ADDRESS (Bus, Device, Func, 4);
|
||||
|
||||
Index = (Bus - MinBus) * (PCI_MAX_DEVICE+1) * (PCI_MAX_FUNC+1) + Device * (PCI_MAX_FUNC+1) + Func;
|
||||
|
||||
IoDev->Pci.Read (IoDev, EfiPciWidthUint16, Address, 1, &Context->CommandRegisterBuffer[Index]);
|
||||
|
||||
//
|
||||
// Clear the memory enable bit
|
||||
//
|
||||
Command = Context->CommandRegisterBuffer[Index] & (~0x02);
|
||||
|
||||
IoDev->Pci.Write (IoDev, EfiPciWidthUint16, Address, 1, &Command);
|
||||
}
|
||||
|
||||
static
|
||||
VOID
|
||||
RestoreCommandRegister (
|
||||
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev,
|
||||
UINT16 MinBus,
|
||||
UINT16 MaxBus,
|
||||
UINT16 MinDevice,
|
||||
UINT16 MaxDevice,
|
||||
UINT16 MinFunc,
|
||||
UINT16 MaxFunc,
|
||||
UINT16 Bus,
|
||||
UINT16 Device,
|
||||
UINT16 Func,
|
||||
IN VOID *VoidContext
|
||||
)
|
||||
|
||||
{
|
||||
PCAT_PCI_ROOT_BRIDGE_SCAN_FOR_ROM_CONTEXT *Context;
|
||||
UINT64 Address;
|
||||
UINTN Index;
|
||||
|
||||
Context = (PCAT_PCI_ROOT_BRIDGE_SCAN_FOR_ROM_CONTEXT *)VoidContext;
|
||||
|
||||
Address = EFI_PCI_ADDRESS (Bus, Device, Func, 4);
|
||||
|
||||
Index = (Bus - MinBus) * (PCI_MAX_DEVICE+1) * (PCI_MAX_FUNC+1) + Device * (PCI_MAX_FUNC+1) + Func;
|
||||
|
||||
IoDev->Pci.Write (IoDev, EfiPciWidthUint16, Address, 1, &Context->CommandRegisterBuffer[Index]);
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
ScanPciRootBridgeForRoms(
|
||||
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev
|
||||
)
|
||||
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;
|
||||
UINT16 MinBus;
|
||||
UINT16 MaxBus;
|
||||
UINT64 RootWindowBase;
|
||||
UINT64 RootWindowLimit;
|
||||
PCAT_PCI_ROOT_BRIDGE_SCAN_FOR_ROM_CONTEXT Context;
|
||||
|
||||
if (mPciOptionRomTableInstalled == FALSE) {
|
||||
gBS->InstallConfigurationTable(&gEfiPciOptionRomTableGuid, &mPciOptionRomTable);
|
||||
mPciOptionRomTableInstalled = TRUE;
|
||||
}
|
||||
|
||||
Status = IoDev->Configuration(IoDev, &Descriptors);
|
||||
if (EFI_ERROR (Status) || Descriptors == NULL) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
MinBus = 0xffff;
|
||||
MaxBus = 0xffff;
|
||||
RootWindowBase = 0;
|
||||
RootWindowLimit = 0;
|
||||
while (Descriptors->Desc != ACPI_END_TAG_DESCRIPTOR) {
|
||||
//
|
||||
// Find bus range
|
||||
//
|
||||
if (Descriptors->ResType == ACPI_ADDRESS_SPACE_TYPE_BUS) {
|
||||
MinBus = (UINT16)Descriptors->AddrRangeMin;
|
||||
MaxBus = (UINT16)Descriptors->AddrRangeMax;
|
||||
}
|
||||
//
|
||||
// Find memory descriptors that are not prefetchable
|
||||
//
|
||||
if (Descriptors->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM && Descriptors->SpecificFlag == 0) {
|
||||
//
|
||||
// Find Memory Descriptors that are less than 4GB, so the PPB Memory Window can be used for downstream devices
|
||||
//
|
||||
if (Descriptors->AddrRangeMax < 0x100000000) {
|
||||
//
|
||||
// Find the largest Non-Prefetchable Memory Descriptor that is less than 4GB
|
||||
//
|
||||
if ((Descriptors->AddrRangeMax - Descriptors->AddrRangeMin) > (RootWindowLimit - RootWindowBase)) {
|
||||
RootWindowBase = Descriptors->AddrRangeMin;
|
||||
RootWindowLimit = Descriptors->AddrRangeMax;
|
||||
}
|
||||
}
|
||||
}
|
||||
Descriptors ++;
|
||||
}
|
||||
|
||||
//
|
||||
// Make sure a bus range was found
|
||||
//
|
||||
if (MinBus == 0xffff || MaxBus == 0xffff) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
//
|
||||
// Make sure a non-prefetchable memory region was found
|
||||
//
|
||||
if (RootWindowBase == 0 && RootWindowLimit == 0) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
//
|
||||
// Round the Base and Limit values to 1 MB boudaries
|
||||
//
|
||||
RootWindowBase = ((RootWindowBase - 1) & 0xfff00000) + 0x00100000;
|
||||
RootWindowLimit = ((RootWindowLimit + 1) & 0xfff00000) - 1;
|
||||
|
||||
//
|
||||
// Make sure that the size of the rounded window is greater than zero
|
||||
//
|
||||
if (RootWindowLimit <= RootWindowBase) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
//
|
||||
// Allocate buffer to save the Command register from all the PCI devices
|
||||
//
|
||||
Context.CommandRegisterBuffer = NULL;
|
||||
Status = gBS->AllocatePool(
|
||||
EfiBootServicesData,
|
||||
sizeof(UINT16) * (MaxBus - MinBus + 1) * (PCI_MAX_DEVICE+1) * (PCI_MAX_FUNC+1),
|
||||
&Context.CommandRegisterBuffer
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
Context.PpbMemoryWindow = (((UINT32)RootWindowBase) >> 16) | ((UINT32)RootWindowLimit & 0xffff0000);
|
||||
|
||||
//
|
||||
// Save the Command register from all the PCI devices, and disable the I/O, Mem, and BusMaster bits
|
||||
//
|
||||
ScanPciBus(
|
||||
IoDev,
|
||||
MinBus, MaxBus,
|
||||
0, PCI_MAX_DEVICE,
|
||||
0, PCI_MAX_FUNC,
|
||||
SaveCommandRegister, &Context
|
||||
);
|
||||
|
||||
//
|
||||
// Recursively scan all the busses for PCI Option ROMs
|
||||
//
|
||||
ScanPciBus(
|
||||
IoDev,
|
||||
MinBus, MinBus,
|
||||
0, PCI_MAX_DEVICE,
|
||||
0, PCI_MAX_FUNC,
|
||||
CheckForRom, &Context
|
||||
);
|
||||
|
||||
//
|
||||
// Restore the Command register in all the PCI devices
|
||||
//
|
||||
ScanPciBus(
|
||||
IoDev,
|
||||
MinBus, MaxBus,
|
||||
0, PCI_MAX_DEVICE,
|
||||
0, PCI_MAX_FUNC,
|
||||
RestoreCommandRegister, &Context
|
||||
);
|
||||
|
||||
//
|
||||
// Free the buffer used to save all the Command register values
|
||||
//
|
||||
gBS->FreePool(Context.CommandRegisterBuffer);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
459
DuetPkg/PciRootBridgeNoEnumerationDxe/Ipf/PcatIo.c
Normal file
459
DuetPkg/PciRootBridgeNoEnumerationDxe/Ipf/PcatIo.c
Normal file
@ -0,0 +1,459 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2005, Intel Corporation
|
||||
All rights reserved. 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.
|
||||
|
||||
Module Name:
|
||||
PcatPciRootBridgeIo.c
|
||||
|
||||
Abstract:
|
||||
|
||||
EFI PC AT PCI Root Bridge Io Protocol
|
||||
|
||||
Revision History
|
||||
|
||||
--*/
|
||||
|
||||
#include "PcatPciRootBridge.h"
|
||||
#include "pci22.h"
|
||||
#include "SalProc.h"
|
||||
|
||||
#include EFI_GUID_DEFINITION (SalSystemTable)
|
||||
|
||||
//
|
||||
// Might be good to put this in an include file, but people may start
|
||||
// using it! They should always access the EFI abstraction that is
|
||||
// contained in this file. Just a little information hiding.
|
||||
//
|
||||
#define PORT_TO_MEM(_Port) ( ((_Port) & 0xffffffffffff0000) | (((_Port) & 0xfffc) << 10) | ((_Port) & 0x0fff) )
|
||||
|
||||
//
|
||||
// Macro's with casts make this much easier to use and read.
|
||||
//
|
||||
#define PORT_TO_MEM8(_Port) (*(UINT8 *)(PORT_TO_MEM(_Port)))
|
||||
#define PORT_TO_MEM16(_Port) (*(UINT16 *)(PORT_TO_MEM(_Port)))
|
||||
#define PORT_TO_MEM32(_Port) (*(UINT32 *)(PORT_TO_MEM(_Port)))
|
||||
|
||||
#define EFI_PCI_ADDRESS_IA64(_seg, _bus,_dev,_func,_reg) \
|
||||
( (UINT64) ( (((UINTN)_seg) << 24) + (((UINTN)_bus) << 16) + (((UINTN)_dev) << 11) + (((UINTN)_func) << 8) + ((UINTN)_reg)) )
|
||||
|
||||
//
|
||||
// Local variables for performing SAL Proc calls
|
||||
//
|
||||
static PLABEL mSalProcPlabel;
|
||||
static CALL_SAL_PROC mGlobalSalProc;
|
||||
|
||||
EFI_STATUS
|
||||
PcatRootBridgeIoIoRead (
|
||||
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
|
||||
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
|
||||
IN UINT64 UserAddress,
|
||||
IN UINTN Count,
|
||||
IN OUT VOID *UserBuffer
|
||||
)
|
||||
{
|
||||
PCAT_PCI_ROOT_BRIDGE_INSTANCE *PrivateData;
|
||||
UINTN InStride;
|
||||
UINTN OutStride;
|
||||
UINTN AlignMask;
|
||||
UINTN Address;
|
||||
PTR Buffer;
|
||||
UINT16 Data16;
|
||||
UINT32 Data32;
|
||||
|
||||
|
||||
if ( UserBuffer == NULL ) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This);
|
||||
|
||||
Address = (UINTN) UserAddress;
|
||||
Buffer.buf = (UINT8 *)UserBuffer;
|
||||
|
||||
if ( Address < PrivateData->IoBase || Address > PrivateData->IoLimit ) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (Width < 0 || Width >= EfiPciWidthMaximum) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if ((Width & 0x03) == EfiPciWidthUint64) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
AlignMask = (1 << (Width & 0x03)) - 1;
|
||||
if ( Address & AlignMask ) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
InStride = 1 << (Width & 0x03);
|
||||
OutStride = InStride;
|
||||
if (Width >=EfiPciWidthFifoUint8 && Width <= EfiPciWidthFifoUint64) {
|
||||
InStride = 0;
|
||||
}
|
||||
if (Width >=EfiPciWidthFillUint8 && Width <= EfiPciWidthFillUint64) {
|
||||
OutStride = 0;
|
||||
}
|
||||
Width = Width & 0x03;
|
||||
|
||||
Address += PrivateData->PhysicalIoBase;
|
||||
|
||||
//
|
||||
// Loop for each iteration and move the data
|
||||
//
|
||||
|
||||
switch (Width) {
|
||||
case EfiPciWidthUint8:
|
||||
for (; Count > 0; Count--, Buffer.buf += OutStride, Address += InStride) {
|
||||
MEMORY_FENCE();
|
||||
*Buffer.ui8 = PORT_TO_MEM8(Address);
|
||||
MEMORY_FENCE();
|
||||
}
|
||||
break;
|
||||
|
||||
case EfiPciWidthUint16:
|
||||
for (; Count > 0; Count--, Buffer.buf += OutStride, Address += InStride) {
|
||||
MEMORY_FENCE();
|
||||
if (Buffer.ui & 0x1) {
|
||||
Data16 = PORT_TO_MEM16(Address);
|
||||
*Buffer.ui8 = (UINT8)(Data16 & 0xff);
|
||||
*(Buffer.ui8+1) = (UINT8)((Data16 >> 8) & 0xff);
|
||||
} else {
|
||||
*Buffer.ui16 = PORT_TO_MEM16(Address);
|
||||
}
|
||||
MEMORY_FENCE();
|
||||
}
|
||||
break;
|
||||
|
||||
case EfiPciWidthUint32:
|
||||
for (; Count > 0; Count--, Buffer.buf += OutStride, Address += InStride) {
|
||||
MEMORY_FENCE();
|
||||
if (Buffer.ui & 0x3) {
|
||||
Data32 = PORT_TO_MEM32(Address);
|
||||
*Buffer.ui8 = (UINT8)(Data32 & 0xff);
|
||||
*(Buffer.ui8+1) = (UINT8)((Data32 >> 8) & 0xff);
|
||||
*(Buffer.ui8+2) = (UINT8)((Data32 >> 16) & 0xff);
|
||||
*(Buffer.ui8+3) = (UINT8)((Data32 >> 24) & 0xff);
|
||||
} else {
|
||||
*Buffer.ui32 = PORT_TO_MEM32(Address);
|
||||
}
|
||||
MEMORY_FENCE();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
PcatRootBridgeIoIoWrite (
|
||||
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
|
||||
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
|
||||
IN UINT64 UserAddress,
|
||||
IN UINTN Count,
|
||||
IN OUT VOID *UserBuffer
|
||||
)
|
||||
{
|
||||
PCAT_PCI_ROOT_BRIDGE_INSTANCE *PrivateData;
|
||||
UINTN InStride;
|
||||
UINTN OutStride;
|
||||
UINTN AlignMask;
|
||||
UINTN Address;
|
||||
PTR Buffer;
|
||||
UINT16 Data16;
|
||||
UINT32 Data32;
|
||||
|
||||
if ( UserBuffer == NULL ) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This);
|
||||
|
||||
Address = (UINTN) UserAddress;
|
||||
Buffer.buf = (UINT8 *)UserBuffer;
|
||||
|
||||
if ( Address < PrivateData->IoBase || Address > PrivateData->IoLimit ) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (Width < 0 || Width >= EfiPciWidthMaximum) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if ((Width & 0x03) == EfiPciWidthUint64) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
AlignMask = (1 << (Width & 0x03)) - 1;
|
||||
if ( Address & AlignMask ) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
InStride = 1 << (Width & 0x03);
|
||||
OutStride = InStride;
|
||||
if (Width >=EfiPciWidthFifoUint8 && Width <= EfiPciWidthFifoUint64) {
|
||||
InStride = 0;
|
||||
}
|
||||
if (Width >=EfiPciWidthFillUint8 && Width <= EfiPciWidthFillUint64) {
|
||||
OutStride = 0;
|
||||
}
|
||||
Width = Width & 0x03;
|
||||
|
||||
Address += PrivateData->PhysicalIoBase;
|
||||
|
||||
//
|
||||
// Loop for each iteration and move the data
|
||||
//
|
||||
|
||||
switch (Width) {
|
||||
case EfiPciWidthUint8:
|
||||
for (; Count > 0; Count--, Buffer.buf += OutStride, Address += InStride) {
|
||||
MEMORY_FENCE();
|
||||
PORT_TO_MEM8(Address) = *Buffer.ui8;
|
||||
MEMORY_FENCE();
|
||||
}
|
||||
break;
|
||||
|
||||
case EfiPciWidthUint16:
|
||||
for (; Count > 0; Count--, Buffer.buf += OutStride, Address += InStride) {
|
||||
MEMORY_FENCE();
|
||||
if (Buffer.ui & 0x1) {
|
||||
Data16 = *Buffer.ui8;
|
||||
Data16 = Data16 | (*(Buffer.ui8+1) << 8);
|
||||
PORT_TO_MEM16(Address) = Data16;
|
||||
} else {
|
||||
PORT_TO_MEM16(Address) = *Buffer.ui16;
|
||||
}
|
||||
MEMORY_FENCE();
|
||||
}
|
||||
break;
|
||||
case EfiPciWidthUint32:
|
||||
for (; Count > 0; Count--, Buffer.buf += OutStride, Address += InStride) {
|
||||
MEMORY_FENCE();
|
||||
if (Buffer.ui & 0x3) {
|
||||
Data32 = *Buffer.ui8;
|
||||
Data32 = Data32 | (*(Buffer.ui8+1) << 8);
|
||||
Data32 = Data32 | (*(Buffer.ui8+2) << 16);
|
||||
Data32 = Data32 | (*(Buffer.ui8+3) << 24);
|
||||
PORT_TO_MEM32(Address) = Data32;
|
||||
} else {
|
||||
PORT_TO_MEM32(Address) = *Buffer.ui32;
|
||||
}
|
||||
MEMORY_FENCE();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
PcatRootBridgeIoGetIoPortMapping (
|
||||
OUT EFI_PHYSICAL_ADDRESS *IoPortMapping,
|
||||
OUT EFI_PHYSICAL_ADDRESS *MemoryPortMapping
|
||||
)
|
||||
/*++
|
||||
|
||||
Get the IO Port Map from the SAL System Table.
|
||||
|
||||
--*/
|
||||
{
|
||||
SAL_SYSTEM_TABLE_ASCENDING_ORDER *SalSystemTable;
|
||||
SAL_ST_MEMORY_DESCRIPTOR_ENTRY *SalMemDesc;
|
||||
EFI_STATUS Status;
|
||||
|
||||
//
|
||||
// On all Itanium architectures, bit 63 is the I/O bit for performming Memory Mapped I/O operations
|
||||
//
|
||||
*MemoryPortMapping = 0x8000000000000000;
|
||||
|
||||
Status = EfiLibGetSystemConfigurationTable(&gEfiSalSystemTableGuid, &SalSystemTable);
|
||||
if (EFI_ERROR(Status)) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
//
|
||||
// BugBug: Add code to test checksum on the Sal System Table
|
||||
//
|
||||
if (SalSystemTable->Entry0.Type != 0) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
mSalProcPlabel.ProcEntryPoint = SalSystemTable->Entry0.SalProcEntry;
|
||||
mSalProcPlabel.GP = SalSystemTable->Entry0.GlobalDataPointer;
|
||||
mGlobalSalProc = (CALL_SAL_PROC)&mSalProcPlabel.ProcEntryPoint;
|
||||
|
||||
//
|
||||
// The SalSystemTable pointer includes the Type 0 entry.
|
||||
// The SalMemDesc is Type 1 so it comes next.
|
||||
//
|
||||
SalMemDesc = (SAL_ST_MEMORY_DESCRIPTOR_ENTRY *)(SalSystemTable + 1);
|
||||
while (SalMemDesc->Type == SAL_ST_MEMORY_DESCRIPTOR) {
|
||||
if (SalMemDesc->MemoryType == SAL_IO_PORT_MAPPING) {
|
||||
*IoPortMapping = SalMemDesc->PhysicalMemoryAddress;
|
||||
*IoPortMapping |= 0x8000000000000000;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
SalMemDesc++;
|
||||
}
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
PcatRootBridgeIoPciRW (
|
||||
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
|
||||
IN BOOLEAN Write,
|
||||
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
|
||||
IN UINT64 UserAddress,
|
||||
IN UINTN Count,
|
||||
IN OUT UINT8 *UserBuffer
|
||||
)
|
||||
{
|
||||
PCAT_PCI_ROOT_BRIDGE_INSTANCE *PrivateData;
|
||||
UINTN AlignMask;
|
||||
UINTN InStride;
|
||||
UINTN OutStride;
|
||||
UINT64 Address;
|
||||
DEFIO_PCI_ADDR *Defio;
|
||||
PTR Buffer;
|
||||
UINT32 Data32;
|
||||
UINT16 Data16;
|
||||
rArg Return;
|
||||
|
||||
if (Width < 0 || Width >= EfiPciWidthMaximum) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if ((Width & 0x03) == EfiPciWidthUint64) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
AlignMask = (1 << (Width & 0x03)) - 1;
|
||||
if ( UserAddress & AlignMask ) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
InStride = 1 << (Width & 0x03);
|
||||
OutStride = InStride;
|
||||
if (Width >=EfiPciWidthFifoUint8 && Width <= EfiPciWidthFifoUint64) {
|
||||
InStride = 0;
|
||||
}
|
||||
if (Width >=EfiPciWidthFillUint8 && Width <= EfiPciWidthFillUint64) {
|
||||
OutStride = 0;
|
||||
}
|
||||
Width = Width & 0x03;
|
||||
|
||||
Defio = (DEFIO_PCI_ADDR *)&UserAddress;
|
||||
|
||||
if ((Defio->Function > PCI_MAX_FUNC) || (Defio->Device > PCI_MAX_DEVICE)) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
Buffer.buf = (UINT8 *)UserBuffer;
|
||||
|
||||
PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This);
|
||||
|
||||
Address = EFI_PCI_ADDRESS_IA64(
|
||||
This->SegmentNumber,
|
||||
Defio->Bus,
|
||||
Defio->Device,
|
||||
Defio->Function,
|
||||
Defio->Register
|
||||
);
|
||||
|
||||
//
|
||||
// PCI Config access are all 32-bit alligned, but by accessing the
|
||||
// CONFIG_DATA_REGISTER (0xcfc) with different widths more cycle types
|
||||
// are possible on PCI.
|
||||
//
|
||||
// SalProc takes care of reading the proper register depending on stride
|
||||
//
|
||||
|
||||
EfiAcquireLock(&PrivateData->PciLock);
|
||||
|
||||
while (Count) {
|
||||
|
||||
if(Write) {
|
||||
|
||||
if (Buffer.ui & 0x3) {
|
||||
Data32 = (*(Buffer.ui8+0) << 0);
|
||||
Data32 |= (*(Buffer.ui8+1) << 8);
|
||||
Data32 |= (*(Buffer.ui8+2) << 16);
|
||||
Data32 |= (*(Buffer.ui8+3) << 24);
|
||||
} else {
|
||||
Data32 = *Buffer.ui32;
|
||||
}
|
||||
|
||||
Return.p0 = -3;
|
||||
Return = mGlobalSalProc((UINT64) SAL_PCI_CONFIG_WRITE,
|
||||
Address, 1 << Width, Data32, 0, 0, 0, 0);
|
||||
|
||||
if(Return.p0) {
|
||||
EfiReleaseLock(&PrivateData->PciLock);
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
Return.p0 = -3;
|
||||
Return = mGlobalSalProc((UINT64) SAL_PCI_CONFIG_READ,
|
||||
Address, 1 << Width, 0, 0, 0, 0, 0);
|
||||
|
||||
if(Return.p0) {
|
||||
EfiReleaseLock(&PrivateData->PciLock);
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
switch (Width) {
|
||||
case EfiPciWidthUint8:
|
||||
*Buffer.ui8 = (UINT8)Return.p1;
|
||||
break;
|
||||
case EfiPciWidthUint16:
|
||||
if (Buffer.ui & 0x1) {
|
||||
Data16 = (UINT16)Return.p1;
|
||||
*(Buffer.ui8 + 0) = Data16 & 0xff;
|
||||
*(Buffer.ui8 + 1) = (Data16 >> 8) & 0xff;
|
||||
} else {
|
||||
*Buffer.ui16 = (UINT16)Return.p1;
|
||||
}
|
||||
break;
|
||||
case EfiPciWidthUint32:
|
||||
if (Buffer.ui & 0x3) {
|
||||
Data32 = (UINT32)Return.p1;
|
||||
*(Buffer.ui8 + 0) = (UINT8)(Data32 & 0xff);
|
||||
*(Buffer.ui8 + 1) = (UINT8)((Data32 >> 8) & 0xff);
|
||||
*(Buffer.ui8 + 2) = (UINT8)((Data32 >> 16) & 0xff);
|
||||
*(Buffer.ui8 + 3) = (UINT8)((Data32 >> 24) & 0xff);
|
||||
} else {
|
||||
*Buffer.ui32 = (UINT32)Return.p1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Address += InStride;
|
||||
Buffer.buf += OutStride;
|
||||
Count -= 1;
|
||||
}
|
||||
|
||||
EfiReleaseLock(&PrivateData->PciLock);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
ScanPciRootBridgeForRoms(
|
||||
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev
|
||||
)
|
||||
|
||||
{
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
1018
DuetPkg/PciRootBridgeNoEnumerationDxe/PcatPciRootBridge.c
Normal file
1018
DuetPkg/PciRootBridgeNoEnumerationDxe/PcatPciRootBridge.c
Normal file
File diff suppressed because it is too large
Load Diff
215
DuetPkg/PciRootBridgeNoEnumerationDxe/PcatPciRootBridge.h
Normal file
215
DuetPkg/PciRootBridgeNoEnumerationDxe/PcatPciRootBridge.h
Normal file
@ -0,0 +1,215 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2005 - 2006, Intel Corporation
|
||||
All rights reserved. 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.
|
||||
|
||||
Module Name:
|
||||
PcatPciRootBridge.h
|
||||
|
||||
Abstract:
|
||||
|
||||
The driver for the host to pci bridge (root bridge).
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef _PCAT_PCI_ROOT_BRIDGE_H_
|
||||
#define _PCAT_PCI_ROOT_BRIDGE_H_
|
||||
|
||||
#include <PiDxe.h>
|
||||
#include <Protocol/PciRootBridgeIo.h>
|
||||
#include <Protocol/DeviceIo.h>
|
||||
#include <Protocol/CpuIo.h>
|
||||
|
||||
#include <Library/UefiLib.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/DevicePathLib.h>
|
||||
#include <Library/HobLib.h>
|
||||
|
||||
#include <Guid/PciOptionRomTable.h>
|
||||
#include <Guid/HobList.h>
|
||||
#include <Guid/PciExpressBaseAddress.h>
|
||||
|
||||
#include <IndustryStandard/Acpi.h>
|
||||
#include <IndustryStandard/Pci.h>
|
||||
//
|
||||
// Driver Instance Data Prototypes
|
||||
//
|
||||
#define PCAT_PCI_ROOT_BRIDGE_SIGNATURE EFI_SIGNATURE_32('p', 'c', 'r', 'b')
|
||||
|
||||
typedef struct {
|
||||
UINT32 Signature;
|
||||
EFI_HANDLE Handle;
|
||||
|
||||
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
|
||||
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL Io;
|
||||
EFI_CPU_IO_PROTOCOL *CpuIo;
|
||||
|
||||
UINT32 RootBridgeNumber;
|
||||
UINT32 PrimaryBus;
|
||||
UINT32 SubordinateBus;
|
||||
|
||||
UINT64 MemBase; // Offsets host to bus memory addr.
|
||||
UINT64 MemLimit; // Max allowable memory access
|
||||
|
||||
UINT64 IoBase; // Offsets host to bus io addr.
|
||||
UINT64 IoLimit; // Max allowable io access
|
||||
|
||||
UINT64 PciAddress;
|
||||
UINT64 PciData;
|
||||
|
||||
UINT64 PhysicalMemoryBase;
|
||||
UINT64 PhysicalIoBase;
|
||||
|
||||
EFI_LOCK PciLock;
|
||||
|
||||
UINT64 Attributes;
|
||||
|
||||
UINT64 Mem32Base;
|
||||
UINT64 Mem32Limit;
|
||||
UINT64 Pmem32Base;
|
||||
UINT64 Pmem32Limit;
|
||||
UINT64 Mem64Base;
|
||||
UINT64 Mem64Limit;
|
||||
UINT64 Pmem64Base;
|
||||
UINT64 Pmem64Limit;
|
||||
|
||||
UINT64 PciExpressBaseAddress;
|
||||
|
||||
EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Configuration;
|
||||
|
||||
LIST_ENTRY MapInfo;
|
||||
} PCAT_PCI_ROOT_BRIDGE_INSTANCE;
|
||||
|
||||
//
|
||||
// Driver Instance Data Macros
|
||||
//
|
||||
#define DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(a) \
|
||||
CR(a, PCAT_PCI_ROOT_BRIDGE_INSTANCE, Io, PCAT_PCI_ROOT_BRIDGE_SIGNATURE)
|
||||
|
||||
#define VOLATILE volatile
|
||||
//
|
||||
// Private data types
|
||||
//
|
||||
typedef union {
|
||||
UINT8 VOLATILE *buf;
|
||||
UINT8 VOLATILE *ui8;
|
||||
UINT16 VOLATILE *ui16;
|
||||
UINT32 VOLATILE *ui32;
|
||||
UINT64 VOLATILE *ui64;
|
||||
UINTN VOLATILE ui;
|
||||
} PTR;
|
||||
|
||||
typedef struct {
|
||||
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION Operation;
|
||||
UINTN NumberOfBytes;
|
||||
UINTN NumberOfPages;
|
||||
EFI_PHYSICAL_ADDRESS HostAddress;
|
||||
EFI_PHYSICAL_ADDRESS MappedHostAddress;
|
||||
} MAP_INFO;
|
||||
|
||||
typedef struct {
|
||||
LIST_ENTRY Link;
|
||||
MAP_INFO * Map;
|
||||
} MAP_INFO_INSTANCE;
|
||||
|
||||
typedef
|
||||
VOID
|
||||
(*EFI_PCI_BUS_SCAN_CALLBACK) (
|
||||
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev,
|
||||
UINT16 MinBus,
|
||||
UINT16 MaxBus,
|
||||
UINT16 MinDevice,
|
||||
UINT16 MaxDevice,
|
||||
UINT16 MinFunc,
|
||||
UINT16 MaxFunc,
|
||||
UINT16 Bus,
|
||||
UINT16 Device,
|
||||
UINT16 Func,
|
||||
IN VOID *Context
|
||||
);
|
||||
|
||||
typedef struct {
|
||||
UINT16 *CommandRegisterBuffer;
|
||||
UINT32 PpbMemoryWindow;
|
||||
} PCAT_PCI_ROOT_BRIDGE_SCAN_FOR_ROM_CONTEXT;
|
||||
|
||||
//
|
||||
// Driver Protocol Constructor Prototypes
|
||||
//
|
||||
EFI_STATUS
|
||||
ConstructConfiguration(
|
||||
IN OUT PCAT_PCI_ROOT_BRIDGE_INSTANCE *PrivateData
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
PcatPciRootBridgeParseBars (
|
||||
IN PCAT_PCI_ROOT_BRIDGE_INSTANCE *PrivateData,
|
||||
IN UINT16 Command,
|
||||
IN UINTN Bus,
|
||||
IN UINTN Device,
|
||||
IN UINTN Function
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
ScanPciRootBridgeForRoms(
|
||||
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
PcatRootBridgeDevicePathConstructor (
|
||||
IN EFI_DEVICE_PATH_PROTOCOL **Protocol,
|
||||
IN UINTN RootBridgeNumber,
|
||||
IN BOOLEAN IsPciExpress
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
PcatRootBridgeIoConstructor (
|
||||
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *Protocol,
|
||||
IN UINTN SegmentNumber
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
PcatRootBridgeIoGetIoPortMapping (
|
||||
OUT EFI_PHYSICAL_ADDRESS *IoPortMapping,
|
||||
OUT EFI_PHYSICAL_ADDRESS *MemoryPortMapping
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
PcatRootBridgeIoPciRW (
|
||||
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
|
||||
IN BOOLEAN Write,
|
||||
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
|
||||
IN UINT64 UserAddress,
|
||||
IN UINTN Count,
|
||||
IN OUT VOID *UserBuffer
|
||||
);
|
||||
|
||||
UINT64
|
||||
GetPciExpressBaseAddressForRootBridge (
|
||||
IN UINTN HostBridgeNumber,
|
||||
IN UINTN RootBridgeNumber
|
||||
);
|
||||
|
||||
//
|
||||
// Driver entry point prototype
|
||||
//
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
InitializePcatPciRootBridge (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
);
|
||||
|
||||
extern EFI_CPU_IO_PROTOCOL *gCpuIo;
|
||||
|
||||
#endif
|
@ -0,0 +1,87 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2005 - 2006, Intel Corporation
|
||||
All rights reserved. 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.
|
||||
|
||||
Module Name:
|
||||
PcatPciRootBridgeDevicePath.c
|
||||
|
||||
Abstract:
|
||||
|
||||
EFI PCAT PCI Root Bridge Device Path Protocol
|
||||
|
||||
Revision History
|
||||
|
||||
--*/
|
||||
|
||||
#include "PcatPciRootBridge.h"
|
||||
|
||||
//
|
||||
// Static device path declarations for this driver.
|
||||
//
|
||||
|
||||
typedef struct {
|
||||
ACPI_HID_DEVICE_PATH AcpiDevicePath;
|
||||
EFI_DEVICE_PATH_PROTOCOL EndDevicePath;
|
||||
} EFI_PCI_ROOT_BRIDGE_DEVICE_PATH;
|
||||
|
||||
static EFI_PCI_ROOT_BRIDGE_DEVICE_PATH mEfiPciRootBridgeDevicePath = {
|
||||
{
|
||||
ACPI_DEVICE_PATH,
|
||||
ACPI_DP,
|
||||
(UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
|
||||
(UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8),
|
||||
EISA_PNP_ID(0x0A03),
|
||||
0
|
||||
},
|
||||
{
|
||||
END_DEVICE_PATH_TYPE,
|
||||
END_ENTIRE_DEVICE_PATH_SUBTYPE,
|
||||
END_DEVICE_PATH_LENGTH,
|
||||
0
|
||||
}
|
||||
};
|
||||
|
||||
EFI_STATUS
|
||||
PcatRootBridgeDevicePathConstructor (
|
||||
IN EFI_DEVICE_PATH_PROTOCOL **Protocol,
|
||||
IN UINTN RootBridgeNumber,
|
||||
IN BOOLEAN IsPciExpress
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Construct the device path protocol
|
||||
|
||||
Arguments:
|
||||
|
||||
Protocol - protocol to initialize
|
||||
|
||||
Returns:
|
||||
|
||||
None
|
||||
|
||||
--*/
|
||||
{
|
||||
ACPI_HID_DEVICE_PATH *AcpiDevicePath;
|
||||
|
||||
*Protocol = DuplicateDevicePath((EFI_DEVICE_PATH_PROTOCOL *)(&mEfiPciRootBridgeDevicePath));
|
||||
|
||||
AcpiDevicePath = (ACPI_HID_DEVICE_PATH *)(*Protocol);
|
||||
|
||||
AcpiDevicePath->UID = (UINT32)RootBridgeNumber;
|
||||
|
||||
if (IsPciExpress) {
|
||||
AcpiDevicePath->HID = EISA_PNP_ID(0x0A08);
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
1054
DuetPkg/PciRootBridgeNoEnumerationDxe/PcatPciRootBridgeIo.c
Normal file
1054
DuetPkg/PciRootBridgeNoEnumerationDxe/PcatPciRootBridgeIo.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,70 @@
|
||||
#/*++
|
||||
#
|
||||
# Copyright (c) 2005 - 2006, Intel Corporation
|
||||
# All rights reserved. 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.
|
||||
#
|
||||
# Module Name:
|
||||
#
|
||||
# Abstract:
|
||||
#
|
||||
#--*/
|
||||
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = PcatPciRootBridge
|
||||
FILE_GUID = 0F7EC77A-1EE1-400f-A99D-7CBD1FEB181E
|
||||
MODULE_TYPE = DXE_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
EDK_RELEASE_VERSION = 0x00020000
|
||||
EFI_SPECIFICATION_VERSION = 0x00020000
|
||||
|
||||
ENTRY_POINT = InitializePcatPciRootBridge
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
DuetPkg/DuetPkg.dec
|
||||
IntelFrameworkPkg/IntelFrameworkPkg.dec
|
||||
IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
UefiDriverEntryPoint
|
||||
UefiLib
|
||||
MemoryAllocationLib
|
||||
UefiBootServicesTableLib
|
||||
DebugLib
|
||||
BaseMemoryLib
|
||||
DevicePathLib
|
||||
HobLib
|
||||
|
||||
[Sources.common]
|
||||
PcatPciRootBridge.h
|
||||
PcatPciRootBridge.c
|
||||
PcatPciRootBridgeDevicePath.c
|
||||
PcatPciRootBridgeIo.c
|
||||
DeviceIo.h
|
||||
DeviceIo.c
|
||||
|
||||
[Sources.ia32]
|
||||
ia32\PcatIo.c
|
||||
|
||||
[Sources.x64]
|
||||
x64\PcatIo.c
|
||||
|
||||
[Sources.ipf]
|
||||
Ipf\PcatIo.c
|
||||
|
||||
[Protocols]
|
||||
gEfiPciRootBridgeIoProtocolGuid
|
||||
gEfiDeviceIoProtocolGuid
|
||||
gEfiPciExpressBaseAddressGuid
|
||||
gEfiCpuIoProtocolGuid
|
||||
|
||||
[Guids]
|
||||
gEfiPciOptionRomTableGuid
|
732
DuetPkg/PciRootBridgeNoEnumerationDxe/x64/PcatIo.c
Normal file
732
DuetPkg/PciRootBridgeNoEnumerationDxe/x64/PcatIo.c
Normal file
@ -0,0 +1,732 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2005 - 2006, Intel Corporation
|
||||
All rights reserved. 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.
|
||||
|
||||
Module Name:
|
||||
PcatPciRootBridgeIo.c
|
||||
|
||||
Abstract:
|
||||
|
||||
EFI PC AT PCI Root Bridge Io Protocol
|
||||
|
||||
Revision History
|
||||
|
||||
--*/
|
||||
|
||||
#include "PcatPciRootBridge.h"
|
||||
|
||||
static BOOLEAN mPciOptionRomTableInstalled = FALSE;
|
||||
static EFI_PCI_OPTION_ROM_TABLE mPciOptionRomTable = {0, NULL};
|
||||
|
||||
EFI_STATUS
|
||||
PcatRootBridgeIoIoRead (
|
||||
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
|
||||
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
|
||||
IN UINT64 UserAddress,
|
||||
IN UINTN Count,
|
||||
IN OUT VOID *UserBuffer
|
||||
)
|
||||
{
|
||||
return gCpuIo->Io.Read (
|
||||
gCpuIo,
|
||||
(EFI_CPU_IO_PROTOCOL_WIDTH) Width,
|
||||
UserAddress,
|
||||
Count,
|
||||
UserBuffer
|
||||
);
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
PcatRootBridgeIoIoWrite (
|
||||
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
|
||||
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
|
||||
IN UINT64 UserAddress,
|
||||
IN UINTN Count,
|
||||
IN OUT VOID *UserBuffer
|
||||
)
|
||||
{
|
||||
return gCpuIo->Io.Write (
|
||||
gCpuIo,
|
||||
(EFI_CPU_IO_PROTOCOL_WIDTH) Width,
|
||||
UserAddress,
|
||||
Count,
|
||||
UserBuffer
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
PcatRootBridgeIoGetIoPortMapping (
|
||||
OUT EFI_PHYSICAL_ADDRESS *IoPortMapping,
|
||||
OUT EFI_PHYSICAL_ADDRESS *MemoryPortMapping
|
||||
)
|
||||
/*++
|
||||
|
||||
Get the IO Port Mapping. For IA-32 it is always 0.
|
||||
|
||||
--*/
|
||||
{
|
||||
*IoPortMapping = 0;
|
||||
*MemoryPortMapping = 0;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
PcatRootBridgeIoPciRW (
|
||||
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
|
||||
IN BOOLEAN Write,
|
||||
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
|
||||
IN UINT64 UserAddress,
|
||||
IN UINTN Count,
|
||||
IN OUT VOID *UserBuffer
|
||||
)
|
||||
{
|
||||
PCI_CONFIG_ACCESS_CF8 Pci;
|
||||
PCI_CONFIG_ACCESS_CF8 PciAligned;
|
||||
UINT32 InStride;
|
||||
UINT32 OutStride;
|
||||
UINTN PciData;
|
||||
UINTN PciDataStride;
|
||||
PCAT_PCI_ROOT_BRIDGE_INSTANCE *PrivateData;
|
||||
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS PciAddress;
|
||||
UINT64 PciExpressRegAddr;
|
||||
BOOLEAN UsePciExpressAccess;
|
||||
|
||||
if (Width < 0 || Width >= EfiPciWidthMaximum) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if ((Width & 0x03) >= EfiPciWidthUint64) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This);
|
||||
|
||||
InStride = 1 << (Width & 0x03);
|
||||
OutStride = InStride;
|
||||
if (Width >= EfiCpuIoWidthFifoUint8 && Width <= EfiCpuIoWidthFifoUint64) {
|
||||
InStride = 0;
|
||||
}
|
||||
|
||||
if (Width >= EfiCpuIoWidthFillUint8 && Width <= EfiCpuIoWidthFillUint64) {
|
||||
OutStride = 0;
|
||||
}
|
||||
|
||||
UsePciExpressAccess = FALSE;
|
||||
|
||||
EfiCopyMem (&PciAddress, &UserAddress, sizeof(UINT64));
|
||||
|
||||
if (PciAddress.ExtendedRegister > 0xFF) {
|
||||
//
|
||||
// Check PciExpressBaseAddress
|
||||
//
|
||||
if ((PrivateData->PciExpressBaseAddress == 0) ||
|
||||
(PrivateData->PciExpressBaseAddress >= EFI_MAX_ADDRESS)) {
|
||||
return EFI_UNSUPPORTED;
|
||||
} else {
|
||||
UsePciExpressAccess = TRUE;
|
||||
}
|
||||
} else {
|
||||
if (PciAddress.ExtendedRegister != 0) {
|
||||
Pci.Reg = PciAddress.ExtendedRegister & 0xFF;
|
||||
} else {
|
||||
Pci.Reg = PciAddress.Register;
|
||||
}
|
||||
//
|
||||
// Note: We can also use PciExpress access here, if wanted.
|
||||
//
|
||||
}
|
||||
|
||||
if (!UsePciExpressAccess) {
|
||||
Pci.Func = PciAddress.Function;
|
||||
Pci.Dev = PciAddress.Device;
|
||||
Pci.Bus = PciAddress.Bus;
|
||||
Pci.Reserved = 0;
|
||||
Pci.Enable = 1;
|
||||
|
||||
//
|
||||
// PCI Config access are all 32-bit alligned, but by accessing the
|
||||
// CONFIG_DATA_REGISTER (0xcfc) with different widths more cycle types
|
||||
// are possible on PCI.
|
||||
//
|
||||
// To read a byte of PCI config space you load 0xcf8 and
|
||||
// read 0xcfc, 0xcfd, 0xcfe, 0xcff
|
||||
//
|
||||
PciDataStride = Pci.Reg & 0x03;
|
||||
|
||||
while (Count) {
|
||||
PciAligned = Pci;
|
||||
PciAligned.Reg &= 0xfc;
|
||||
PciData = (UINTN)PrivateData->PciData + PciDataStride;
|
||||
EfiAcquireLock(&PrivateData->PciLock);
|
||||
This->Io.Write (This, EfiPciWidthUint32, PrivateData->PciAddress, 1, &PciAligned);
|
||||
if (Write) {
|
||||
This->Io.Write (This, Width, PciData, 1, UserBuffer);
|
||||
} else {
|
||||
This->Io.Read (This, Width, PciData, 1, UserBuffer);
|
||||
}
|
||||
EfiReleaseLock(&PrivateData->PciLock);
|
||||
UserBuffer = ((UINT8 *)UserBuffer) + OutStride;
|
||||
PciDataStride = (PciDataStride + InStride) % 4;
|
||||
Pci.Reg += InStride;
|
||||
Count -= 1;
|
||||
}
|
||||
} else {
|
||||
//
|
||||
// Access PCI-Express space by using memory mapped method.
|
||||
//
|
||||
PciExpressRegAddr = (PrivateData->PciExpressBaseAddress) |
|
||||
(PciAddress.Bus << 20) |
|
||||
(PciAddress.Device << 15) |
|
||||
(PciAddress.Function << 12);
|
||||
if (PciAddress.ExtendedRegister != 0) {
|
||||
PciExpressRegAddr += PciAddress.ExtendedRegister;
|
||||
} else {
|
||||
PciExpressRegAddr += PciAddress.Register;
|
||||
}
|
||||
while (Count) {
|
||||
if (Write) {
|
||||
This->Mem.Write (This, Width, (UINTN) PciExpressRegAddr, 1, UserBuffer);
|
||||
} else {
|
||||
This->Mem.Read (This, Width, (UINTN) PciExpressRegAddr, 1, UserBuffer);
|
||||
}
|
||||
|
||||
UserBuffer = ((UINT8 *) UserBuffer) + OutStride;
|
||||
PciExpressRegAddr += InStride;
|
||||
Count -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
static
|
||||
VOID
|
||||
ScanPciBus(
|
||||
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev,
|
||||
UINT16 MinBus,
|
||||
UINT16 MaxBus,
|
||||
UINT16 MinDevice,
|
||||
UINT16 MaxDevice,
|
||||
UINT16 MinFunc,
|
||||
UINT16 MaxFunc,
|
||||
EFI_PCI_BUS_SCAN_CALLBACK Callback,
|
||||
VOID *Context
|
||||
)
|
||||
|
||||
{
|
||||
UINT16 Bus;
|
||||
UINT16 Device;
|
||||
UINT16 Func;
|
||||
UINT64 Address;
|
||||
PCI_TYPE00 PciHeader;
|
||||
|
||||
//
|
||||
// Loop through all busses
|
||||
//
|
||||
for (Bus = MinBus; Bus <= MaxBus; Bus++) {
|
||||
//
|
||||
// Loop 32 devices per bus
|
||||
//
|
||||
for (Device = MinDevice; Device <= MaxDevice; Device++) {
|
||||
//
|
||||
// Loop through 8 functions per device
|
||||
//
|
||||
for (Func = MinFunc; Func <= MaxFunc; Func++) {
|
||||
|
||||
//
|
||||
// Compute the EFI Address required to access the PCI Configuration Header of this PCI Device
|
||||
//
|
||||
Address = EFI_PCI_ADDRESS (Bus, Device, Func, 0);
|
||||
|
||||
//
|
||||
// Read the VendorID from this PCI Device's Confioguration Header
|
||||
//
|
||||
IoDev->Pci.Read (IoDev, EfiPciWidthUint16, Address, 1, &PciHeader.Hdr.VendorId);
|
||||
|
||||
//
|
||||
// If VendorId = 0xffff, there does not exist a device at this
|
||||
// location. For each device, if there is any function on it,
|
||||
// there must be 1 function at Function 0. So if Func = 0, there
|
||||
// will be no more functions in the same device, so we can break
|
||||
// loop to deal with the next device.
|
||||
//
|
||||
if (PciHeader.Hdr.VendorId == 0xffff && Func == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (PciHeader.Hdr.VendorId != 0xffff) {
|
||||
|
||||
//
|
||||
// Read the HeaderType to determine if this is a multi-function device
|
||||
//
|
||||
IoDev->Pci.Read (IoDev, EfiPciWidthUint8, Address + 0x0e, 1, &PciHeader.Hdr.HeaderType);
|
||||
|
||||
//
|
||||
// Call the callback function for the device that was found
|
||||
//
|
||||
Callback(
|
||||
IoDev,
|
||||
MinBus, MaxBus,
|
||||
MinDevice, MaxDevice,
|
||||
MinFunc, MaxFunc,
|
||||
Bus,
|
||||
Device,
|
||||
Func,
|
||||
Context
|
||||
);
|
||||
|
||||
//
|
||||
// If this is not a multi-function device, we can leave the loop
|
||||
// to deal with the next device.
|
||||
//
|
||||
if ((PciHeader.Hdr.HeaderType & HEADER_TYPE_MULTI_FUNCTION) == 0x00 && Func == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
VOID
|
||||
CheckForRom (
|
||||
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev,
|
||||
UINT16 MinBus,
|
||||
UINT16 MaxBus,
|
||||
UINT16 MinDevice,
|
||||
UINT16 MaxDevice,
|
||||
UINT16 MinFunc,
|
||||
UINT16 MaxFunc,
|
||||
UINT16 Bus,
|
||||
UINT16 Device,
|
||||
UINT16 Func,
|
||||
IN VOID *VoidContext
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
PCAT_PCI_ROOT_BRIDGE_SCAN_FOR_ROM_CONTEXT *Context;
|
||||
UINT64 Address;
|
||||
PCI_TYPE00 PciHeader;
|
||||
PCI_TYPE01 *PciBridgeHeader;
|
||||
UINT32 Register;
|
||||
UINT32 RomBar;
|
||||
UINT32 RomBarSize;
|
||||
EFI_PHYSICAL_ADDRESS RomBuffer;
|
||||
UINT32 MaxRomSize;
|
||||
EFI_PCI_EXPANSION_ROM_HEADER EfiRomHeader;
|
||||
PCI_DATA_STRUCTURE Pcir;
|
||||
EFI_PCI_OPTION_ROM_DESCRIPTOR *TempPciOptionRomDescriptors;
|
||||
BOOLEAN LastImage;
|
||||
|
||||
Context = (PCAT_PCI_ROOT_BRIDGE_SCAN_FOR_ROM_CONTEXT *)VoidContext;
|
||||
|
||||
Address = EFI_PCI_ADDRESS (Bus, Device, Func, 0);
|
||||
|
||||
//
|
||||
// Save the contents of the PCI Configuration Header
|
||||
//
|
||||
IoDev->Pci.Read (IoDev, EfiPciWidthUint32, Address, sizeof(PciHeader)/sizeof(UINT32), &PciHeader);
|
||||
|
||||
if (IS_PCI_BRIDGE(&PciHeader)) {
|
||||
|
||||
PciBridgeHeader = (PCI_TYPE01 *)(&PciHeader);
|
||||
|
||||
//
|
||||
// See if the PCI-PCI Bridge has its secondary interface enabled.
|
||||
//
|
||||
if (PciBridgeHeader->Bridge.SubordinateBus >= PciBridgeHeader->Bridge.SecondaryBus) {
|
||||
|
||||
//
|
||||
// Disable the Prefetchable Memory Window
|
||||
//
|
||||
Register = 0x00000000;
|
||||
IoDev->Pci.Write (IoDev, EfiPciWidthUint16, Address + 0x26, 1, &Register);
|
||||
IoDev->Pci.Write (IoDev, EfiPciWidthUint32, Address + 0x2c, 1, &Register);
|
||||
Register = 0xffffffff;
|
||||
IoDev->Pci.Write (IoDev, EfiPciWidthUint16, Address + 0x24, 1, &Register);
|
||||
IoDev->Pci.Write (IoDev, EfiPciWidthUint16, Address + 0x28, 1, &Register);
|
||||
|
||||
//
|
||||
// Program Memory Window to the PCI Root Bridge Memory Window
|
||||
//
|
||||
IoDev->Pci.Write (IoDev, EfiPciWidthUint16, Address + 0x20, 4, &Context->PpbMemoryWindow);
|
||||
|
||||
//
|
||||
// Enable the Memory decode for the PCI-PCI Bridge
|
||||
//
|
||||
IoDev->Pci.Read (IoDev, EfiPciWidthUint16, Address + 4, 1, &Register);
|
||||
Register |= 0x02;
|
||||
IoDev->Pci.Write (IoDev, EfiPciWidthUint16, Address + 4, 1, &Register);
|
||||
|
||||
//
|
||||
// Recurse on the Secondary Bus Number
|
||||
//
|
||||
ScanPciBus(
|
||||
IoDev,
|
||||
PciBridgeHeader->Bridge.SecondaryBus, PciBridgeHeader->Bridge.SecondaryBus,
|
||||
0, PCI_MAX_DEVICE,
|
||||
0, PCI_MAX_FUNC,
|
||||
CheckForRom, Context
|
||||
);
|
||||
}
|
||||
} else {
|
||||
|
||||
//
|
||||
// Check if an Option ROM Register is present and save the Option ROM Window Register
|
||||
//
|
||||
RomBar = 0xffffffff;
|
||||
IoDev->Pci.Write (IoDev, EfiPciWidthUint32, Address + 0x30, 1, &RomBar);
|
||||
IoDev->Pci.Read (IoDev, EfiPciWidthUint32, Address + 0x30, 1, &RomBar);
|
||||
|
||||
RomBarSize = (~(RomBar & 0xfffff800)) + 1;
|
||||
|
||||
//
|
||||
// Make sure the size of the ROM is between 0 and 16 MB
|
||||
//
|
||||
if (RomBarSize > 0 && RomBarSize <= 0x01000000) {
|
||||
|
||||
//
|
||||
// Program Option ROM Window Register to the PCI Root Bridge Window and Enable the Option ROM Window
|
||||
//
|
||||
RomBar = (Context->PpbMemoryWindow & 0xffff) << 16;
|
||||
RomBar = ((RomBar - 1) & (~(RomBarSize - 1))) + RomBarSize;
|
||||
if (RomBar < (Context->PpbMemoryWindow & 0xffff0000)) {
|
||||
MaxRomSize = (Context->PpbMemoryWindow & 0xffff0000) - RomBar;
|
||||
RomBar = RomBar + 1;
|
||||
IoDev->Pci.Write (IoDev, EfiPciWidthUint32, Address + 0x30, 1, &RomBar);
|
||||
IoDev->Pci.Read (IoDev, EfiPciWidthUint32, Address + 0x30, 1, &RomBar);
|
||||
RomBar = RomBar - 1;
|
||||
|
||||
//
|
||||
// Enable the Memory decode for the PCI Device
|
||||
//
|
||||
IoDev->Pci.Read (IoDev, EfiPciWidthUint16, Address + 4, 1, &Register);
|
||||
Register |= 0x02;
|
||||
IoDev->Pci.Write (IoDev, EfiPciWidthUint16, Address + 4, 1, &Register);
|
||||
|
||||
//
|
||||
// Follow the chain of images to determine the size of the Option ROM present
|
||||
// Keep going until the last image is found by looking at the Indicator field
|
||||
// or the size of an image is 0, or the size of all the images is bigger than the
|
||||
// size of the window programmed into the PPB.
|
||||
//
|
||||
RomBarSize = 0;
|
||||
do {
|
||||
|
||||
LastImage = TRUE;
|
||||
|
||||
EfiZeroMem (&EfiRomHeader, sizeof(EfiRomHeader));
|
||||
IoDev->Mem.Read (
|
||||
IoDev,
|
||||
EfiPciWidthUint8,
|
||||
RomBar + RomBarSize,
|
||||
sizeof(EfiRomHeader),
|
||||
&EfiRomHeader
|
||||
);
|
||||
|
||||
Pcir.ImageLength = 0;
|
||||
|
||||
if (EfiRomHeader.Signature == 0xaa55) {
|
||||
|
||||
EfiZeroMem (&Pcir, sizeof(Pcir));
|
||||
IoDev->Mem.Read (
|
||||
IoDev,
|
||||
EfiPciWidthUint8,
|
||||
RomBar + RomBarSize + EfiRomHeader.PcirOffset,
|
||||
sizeof(Pcir),
|
||||
&Pcir
|
||||
);
|
||||
|
||||
if ((Pcir.Indicator & 0x80) == 0x00) {
|
||||
LastImage = FALSE;
|
||||
}
|
||||
|
||||
RomBarSize += Pcir.ImageLength * 512;
|
||||
}
|
||||
} while (!LastImage && RomBarSize < MaxRomSize && Pcir.ImageLength !=0);
|
||||
|
||||
if (RomBarSize > 0) {
|
||||
|
||||
//
|
||||
// Allocate a memory buffer for the Option ROM contents.
|
||||
//
|
||||
Status = gBS->AllocatePages(
|
||||
AllocateAnyPages,
|
||||
EfiBootServicesData,
|
||||
EFI_SIZE_TO_PAGES(RomBarSize),
|
||||
&RomBuffer
|
||||
);
|
||||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
|
||||
//
|
||||
// Copy the contents of the Option ROM to the memory buffer
|
||||
//
|
||||
IoDev->Mem.Read (IoDev, EfiPciWidthUint32, RomBar, RomBarSize / sizeof(UINT32), (VOID *)(UINTN)RomBuffer);
|
||||
|
||||
Status = gBS->AllocatePool(
|
||||
EfiBootServicesData,
|
||||
((UINT32)mPciOptionRomTable.PciOptionRomCount + 1) * sizeof(EFI_PCI_OPTION_ROM_DESCRIPTOR),
|
||||
&TempPciOptionRomDescriptors
|
||||
);
|
||||
if (mPciOptionRomTable.PciOptionRomCount > 0) {
|
||||
EfiCopyMem(
|
||||
TempPciOptionRomDescriptors,
|
||||
mPciOptionRomTable.PciOptionRomDescriptors,
|
||||
(UINT32)mPciOptionRomTable.PciOptionRomCount * sizeof(EFI_PCI_OPTION_ROM_DESCRIPTOR)
|
||||
);
|
||||
|
||||
gBS->FreePool(mPciOptionRomTable.PciOptionRomDescriptors);
|
||||
}
|
||||
|
||||
mPciOptionRomTable.PciOptionRomDescriptors = TempPciOptionRomDescriptors;
|
||||
|
||||
TempPciOptionRomDescriptors = &(mPciOptionRomTable.PciOptionRomDescriptors[(UINT32)mPciOptionRomTable.PciOptionRomCount]);
|
||||
|
||||
TempPciOptionRomDescriptors->RomAddress = RomBuffer;
|
||||
TempPciOptionRomDescriptors->MemoryType = EfiBootServicesData;
|
||||
TempPciOptionRomDescriptors->RomLength = RomBarSize;
|
||||
TempPciOptionRomDescriptors->Seg = (UINT32)IoDev->SegmentNumber;
|
||||
TempPciOptionRomDescriptors->Bus = (UINT8)Bus;
|
||||
TempPciOptionRomDescriptors->Dev = (UINT8)Device;
|
||||
TempPciOptionRomDescriptors->Func = (UINT8)Func;
|
||||
TempPciOptionRomDescriptors->ExecutedLegacyBiosImage = TRUE;
|
||||
TempPciOptionRomDescriptors->DontLoadEfiRom = FALSE;
|
||||
|
||||
mPciOptionRomTable.PciOptionRomCount++;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Disable the Memory decode for the PCI-PCI Bridge
|
||||
//
|
||||
IoDev->Pci.Read (IoDev, EfiPciWidthUint16, Address + 4, 1, &Register);
|
||||
Register &= (~0x02);
|
||||
IoDev->Pci.Write (IoDev, EfiPciWidthUint16, Address + 4, 1, &Register);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Restore the PCI Configuration Header
|
||||
//
|
||||
IoDev->Pci.Write (IoDev, EfiPciWidthUint32, Address, sizeof(PciHeader)/sizeof(UINT32), &PciHeader);
|
||||
}
|
||||
|
||||
static
|
||||
VOID
|
||||
SaveCommandRegister (
|
||||
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev,
|
||||
UINT16 MinBus,
|
||||
UINT16 MaxBus,
|
||||
UINT16 MinDevice,
|
||||
UINT16 MaxDevice,
|
||||
UINT16 MinFunc,
|
||||
UINT16 MaxFunc,
|
||||
UINT16 Bus,
|
||||
UINT16 Device,
|
||||
UINT16 Func,
|
||||
IN VOID *VoidContext
|
||||
)
|
||||
|
||||
{
|
||||
PCAT_PCI_ROOT_BRIDGE_SCAN_FOR_ROM_CONTEXT *Context;
|
||||
UINT64 Address;
|
||||
UINTN Index;
|
||||
UINT16 Command;
|
||||
|
||||
Context = (PCAT_PCI_ROOT_BRIDGE_SCAN_FOR_ROM_CONTEXT *)VoidContext;
|
||||
|
||||
Address = EFI_PCI_ADDRESS (Bus, Device, Func, 4);
|
||||
|
||||
Index = (Bus - MinBus) * (PCI_MAX_DEVICE+1) * (PCI_MAX_FUNC+1) + Device * (PCI_MAX_FUNC+1) + Func;
|
||||
|
||||
IoDev->Pci.Read (IoDev, EfiPciWidthUint16, Address, 1, &Context->CommandRegisterBuffer[Index]);
|
||||
|
||||
//
|
||||
// Clear the memory enable bit
|
||||
//
|
||||
Command = Context->CommandRegisterBuffer[Index] & (~0x02);
|
||||
|
||||
IoDev->Pci.Write (IoDev, EfiPciWidthUint16, Address, 1, &Command);
|
||||
}
|
||||
|
||||
static
|
||||
VOID
|
||||
RestoreCommandRegister (
|
||||
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev,
|
||||
UINT16 MinBus,
|
||||
UINT16 MaxBus,
|
||||
UINT16 MinDevice,
|
||||
UINT16 MaxDevice,
|
||||
UINT16 MinFunc,
|
||||
UINT16 MaxFunc,
|
||||
UINT16 Bus,
|
||||
UINT16 Device,
|
||||
UINT16 Func,
|
||||
IN VOID *VoidContext
|
||||
)
|
||||
|
||||
{
|
||||
PCAT_PCI_ROOT_BRIDGE_SCAN_FOR_ROM_CONTEXT *Context;
|
||||
UINT64 Address;
|
||||
UINTN Index;
|
||||
|
||||
Context = (PCAT_PCI_ROOT_BRIDGE_SCAN_FOR_ROM_CONTEXT *)VoidContext;
|
||||
|
||||
Address = EFI_PCI_ADDRESS (Bus, Device, Func, 4);
|
||||
|
||||
Index = (Bus - MinBus) * (PCI_MAX_DEVICE+1) * (PCI_MAX_FUNC+1) + Device * (PCI_MAX_FUNC+1) + Func;
|
||||
|
||||
IoDev->Pci.Write (IoDev, EfiPciWidthUint16, Address, 1, &Context->CommandRegisterBuffer[Index]);
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
ScanPciRootBridgeForRoms(
|
||||
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev
|
||||
)
|
||||
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;
|
||||
UINT16 MinBus;
|
||||
UINT16 MaxBus;
|
||||
UINT64 RootWindowBase;
|
||||
UINT64 RootWindowLimit;
|
||||
PCAT_PCI_ROOT_BRIDGE_SCAN_FOR_ROM_CONTEXT Context;
|
||||
|
||||
if (mPciOptionRomTableInstalled == FALSE) {
|
||||
gBS->InstallConfigurationTable(&gEfiPciOptionRomTableGuid, &mPciOptionRomTable);
|
||||
mPciOptionRomTableInstalled = TRUE;
|
||||
}
|
||||
|
||||
Status = IoDev->Configuration(IoDev, &Descriptors);
|
||||
if (EFI_ERROR (Status) || Descriptors == NULL) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
MinBus = 0xffff;
|
||||
MaxBus = 0xffff;
|
||||
RootWindowBase = 0;
|
||||
RootWindowLimit = 0;
|
||||
while (Descriptors->Desc != ACPI_END_TAG_DESCRIPTOR) {
|
||||
//
|
||||
// Find bus range
|
||||
//
|
||||
if (Descriptors->ResType == ACPI_ADDRESS_SPACE_TYPE_BUS) {
|
||||
MinBus = (UINT16)Descriptors->AddrRangeMin;
|
||||
MaxBus = (UINT16)Descriptors->AddrRangeMax;
|
||||
}
|
||||
//
|
||||
// Find memory descriptors that are not prefetchable
|
||||
//
|
||||
if (Descriptors->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM && Descriptors->SpecificFlag == 0) {
|
||||
//
|
||||
// Find Memory Descriptors that are less than 4GB, so the PPB Memory Window can be used for downstream devices
|
||||
//
|
||||
if (Descriptors->AddrRangeMax < 0x100000000) {
|
||||
//
|
||||
// Find the largest Non-Prefetchable Memory Descriptor that is less than 4GB
|
||||
//
|
||||
if ((Descriptors->AddrRangeMax - Descriptors->AddrRangeMin) > (RootWindowLimit - RootWindowBase)) {
|
||||
RootWindowBase = Descriptors->AddrRangeMin;
|
||||
RootWindowLimit = Descriptors->AddrRangeMax;
|
||||
}
|
||||
}
|
||||
}
|
||||
Descriptors ++;
|
||||
}
|
||||
|
||||
//
|
||||
// Make sure a bus range was found
|
||||
//
|
||||
if (MinBus == 0xffff || MaxBus == 0xffff) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
//
|
||||
// Make sure a non-prefetchable memory region was found
|
||||
//
|
||||
if (RootWindowBase == 0 && RootWindowLimit == 0) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
//
|
||||
// Round the Base and Limit values to 1 MB boudaries
|
||||
//
|
||||
RootWindowBase = ((RootWindowBase - 1) & 0xfff00000) + 0x00100000;
|
||||
RootWindowLimit = ((RootWindowLimit + 1) & 0xfff00000) - 1;
|
||||
|
||||
//
|
||||
// Make sure that the size of the rounded window is greater than zero
|
||||
//
|
||||
if (RootWindowLimit <= RootWindowBase) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
//
|
||||
// Allocate buffer to save the Command register from all the PCI devices
|
||||
//
|
||||
Context.CommandRegisterBuffer = NULL;
|
||||
Status = gBS->AllocatePool(
|
||||
EfiBootServicesData,
|
||||
sizeof(UINT16) * (MaxBus - MinBus + 1) * (PCI_MAX_DEVICE+1) * (PCI_MAX_FUNC+1),
|
||||
&Context.CommandRegisterBuffer
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
Context.PpbMemoryWindow = (((UINT32)RootWindowBase) >> 16) | ((UINT32)RootWindowLimit & 0xffff0000);
|
||||
|
||||
//
|
||||
// Save the Command register from all the PCI devices, and disable the I/O, Mem, and BusMaster bits
|
||||
//
|
||||
ScanPciBus(
|
||||
IoDev,
|
||||
MinBus, MaxBus,
|
||||
0, PCI_MAX_DEVICE,
|
||||
0, PCI_MAX_FUNC,
|
||||
SaveCommandRegister, &Context
|
||||
);
|
||||
|
||||
//
|
||||
// Recursively scan all the busses for PCI Option ROMs
|
||||
//
|
||||
ScanPciBus(
|
||||
IoDev,
|
||||
MinBus, MinBus,
|
||||
0, PCI_MAX_DEVICE,
|
||||
0, PCI_MAX_FUNC,
|
||||
CheckForRom, &Context
|
||||
);
|
||||
|
||||
//
|
||||
// Restore the Command register in all the PCI devices
|
||||
//
|
||||
ScanPciBus(
|
||||
IoDev,
|
||||
MinBus, MaxBus,
|
||||
0, PCI_MAX_DEVICE,
|
||||
0, PCI_MAX_FUNC,
|
||||
RestoreCommandRegister, &Context
|
||||
);
|
||||
|
||||
//
|
||||
// Free the buffer used to save all the Command register values
|
||||
//
|
||||
gBS->FreePool(Context.CommandRegisterBuffer);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
146
DuetPkg/RtPlatformStatusCode/RtPlatformStatusCode.c
Normal file
146
DuetPkg/RtPlatformStatusCode/RtPlatformStatusCode.c
Normal file
@ -0,0 +1,146 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. 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.
|
||||
|
||||
Module Name:
|
||||
|
||||
RtPlatformStatusCode.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Contains NT32 specific implementations required to use status codes.
|
||||
|
||||
--*/
|
||||
|
||||
//
|
||||
// Statements that include other files.
|
||||
//
|
||||
#include "Tiano.h"
|
||||
#include "EfiCommonLib.h"
|
||||
#include "EfiRuntimeLib.h"
|
||||
#include "EfiStatusCode.h"
|
||||
#include "EfiHobLib.h"
|
||||
#include "RtMemoryStatusCodeLib.h"
|
||||
#include "BsDataHubStatusCodeLib.h"
|
||||
|
||||
//
|
||||
// Consumed protocols
|
||||
//
|
||||
#include EFI_ARCH_PROTOCOL_CONSUMER (StatusCode)
|
||||
|
||||
//
|
||||
// GUID definitions
|
||||
//
|
||||
#include EFI_GUID_DEFINITION (Hob)
|
||||
|
||||
//
|
||||
// Globals only work at BootService Time. NOT at Runtime!
|
||||
//
|
||||
EFI_REPORT_STATUS_CODE mPeiReportStatusCode;
|
||||
|
||||
//
|
||||
// Function implementations
|
||||
//
|
||||
EFI_RUNTIMESERVICE
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
RtPlatformReportStatusCode (
|
||||
IN EFI_STATUS_CODE_TYPE CodeType,
|
||||
IN EFI_STATUS_CODE_VALUE Value,
|
||||
IN UINT32 Instance,
|
||||
IN EFI_GUID * CallerId,
|
||||
IN EFI_STATUS_CODE_DATA * Data OPTIONAL
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Call all status code listeners in the MonoStatusCode.
|
||||
|
||||
Arguments:
|
||||
|
||||
Same as ReportStatusCode service
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS Always returns success.
|
||||
|
||||
--*/
|
||||
{
|
||||
RtMemoryReportStatusCode (CodeType, Value, Instance, CallerId, Data);
|
||||
if (EfiAtRuntime ()) {
|
||||
//
|
||||
// For now all we do is post code at runtime
|
||||
//
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
BsDataHubReportStatusCode (CodeType, Value, Instance, CallerId, Data);
|
||||
|
||||
//
|
||||
// Call back into PEI to get status codes. This is because SecMain contains
|
||||
// status code that reports to Win32.
|
||||
//
|
||||
if (mPeiReportStatusCode != NULL) {
|
||||
return mPeiReportStatusCode (CodeType, Value, Instance, CallerId, Data);
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_BOOTSERVICE
|
||||
VOID
|
||||
EFIAPI
|
||||
RtPlatformInitializeStatusCode (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Initialize the status code listeners.
|
||||
|
||||
Arguments:
|
||||
|
||||
(Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)
|
||||
|
||||
Returns:
|
||||
|
||||
None
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
VOID *HobList;
|
||||
VOID *Pointer;
|
||||
|
||||
RtMemoryInitializeStatusCode (ImageHandle, SystemTable);
|
||||
BsDataHubInitializeStatusCode (ImageHandle, SystemTable);
|
||||
|
||||
//
|
||||
// Play any prior status codes to the data hub.
|
||||
//
|
||||
PlaybackStatusCodes (BsDataHubReportStatusCode);
|
||||
|
||||
//
|
||||
// If PEI has a ReportStatusCode callback find it and use it before StdErr
|
||||
// is connected.
|
||||
//
|
||||
mPeiReportStatusCode = NULL;
|
||||
|
||||
Status = EfiLibGetSystemConfigurationTable (&gEfiHobListGuid, &HobList);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
Status = GetNextGuidHob (&HobList, &gEfiStatusCodeRuntimeProtocolGuid, &Pointer, NULL);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
mPeiReportStatusCode = (EFI_REPORT_STATUS_CODE) (*(UINTN *) Pointer);
|
||||
}
|
||||
}
|
||||
}
|
47
DuetPkg/RtPlatformStatusCode/RtPlatformStatusCode.inf
Normal file
47
DuetPkg/RtPlatformStatusCode/RtPlatformStatusCode.inf
Normal file
@ -0,0 +1,47 @@
|
||||
#/*++
|
||||
#
|
||||
# Copyright (c) 2006, Intel Corporation
|
||||
# All rights reserved. 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.
|
||||
#
|
||||
# Module Name:
|
||||
#
|
||||
# RtPlatformStatusCode.inf
|
||||
#
|
||||
# Abstract:
|
||||
#
|
||||
# Library selecting the listeners for the platform
|
||||
#
|
||||
#--*/
|
||||
|
||||
[defines]
|
||||
BASE_NAME = RtPlatformStatusCodeLib
|
||||
COMPONENT_TYPE = LIBRARY
|
||||
|
||||
[sources.common]
|
||||
RtPlatformStatusCode.c
|
||||
|
||||
[includes.common]
|
||||
$(EDK_SOURCE)\Foundation\Framework
|
||||
$(EDK_SOURCE)\Foundation
|
||||
$(EDK_SOURCE)\Foundation\Efi
|
||||
.
|
||||
$(EDK_SOURCE)\Sample\Platform\Generic\RuntimeDxe\StatusCode\Lib\Include
|
||||
$(EDK_SOURCE)\Foundation\Include
|
||||
$(EDK_SOURCE)\Foundation\Efi\Include
|
||||
$(EDK_SOURCE)\Foundation\Framework\Include
|
||||
$(EDK_SOURCE)\Foundation\Include\IndustryStandard
|
||||
$(EDK_SOURCE)\Foundation\Core\Dxe
|
||||
$(EDK_SOURCE)\Foundation\Library\Dxe\Include
|
||||
|
||||
[libraries.common]
|
||||
HobLib
|
||||
RtMemoryStatusCodeLib
|
||||
BsDataHubStatusCodeLib
|
||||
|
||||
[nmake.common]
|
Loading…
x
Reference in New Issue
Block a user