summaryrefslogtreecommitdiff
path: root/Core/CPU/IA32
diff options
context:
space:
mode:
authorraywu <raywu0301@gmail.com>2018-06-15 00:00:50 +0800
committerraywu <raywu0301@gmail.com>2018-06-15 00:00:50 +0800
commitb7c51c9cf4864df6aabb99a1ae843becd577237c (patch)
treeeebe9b0d0ca03062955223097e57da84dd618b9a /Core/CPU/IA32
downloadzprj-b7c51c9cf4864df6aabb99a1ae843becd577237c.tar.xz
init. 1AQQW051HEADmaster
Diffstat (limited to 'Core/CPU/IA32')
-rw-r--r--Core/CPU/IA32/AmiIa32Lib.cif12
-rw-r--r--Core/CPU/IA32/AmiIa32Lib.mak67
-rw-r--r--Core/CPU/IA32/AmiIa32Lib.sdl19
-rw-r--r--Core/CPU/IA32/FoundationIa32.cif16
-rw-r--r--Core/CPU/IA32/FoundationIa32.mak69
-rw-r--r--Core/CPU/IA32/FoundationIa32.sdl19
-rw-r--r--Core/CPU/IA32/IA32AsmLib/EnableLongMode.asm143
-rw-r--r--Core/CPU/IA32/IA32AsmLib/EnableMachineCheck.asm78
-rw-r--r--Core/CPU/IA32/IA32CLib.c1959
-rw-r--r--Core/CPU/IA32/IA32Core.cif9
-rw-r--r--Core/CPU/IA32/IA32Core.sdl33
-rw-r--r--Core/CPU/IA32/IA32rules.mak62
-rw-r--r--Core/CPU/IA32/PeCoffLoaderEx.c93
-rw-r--r--Core/CPU/IA32/PeCoffLoaderEx.h85
-rw-r--r--Core/CPU/IA32/Processor.c140
-rw-r--r--Core/CPU/IA32/Processor.h27
-rw-r--r--Core/CPU/IA32/ProcessorAsms.Asm223
-rw-r--r--Core/CPU/IA32/SwitchCoreStacks.asm104
-rw-r--r--Core/CPU/IA32/efijump.h34
19 files changed, 3192 insertions, 0 deletions
diff --git a/Core/CPU/IA32/AmiIa32Lib.cif b/Core/CPU/IA32/AmiIa32Lib.cif
new file mode 100644
index 0000000..e86bed7
--- /dev/null
+++ b/Core/CPU/IA32/AmiIa32Lib.cif
@@ -0,0 +1,12 @@
+<component>
+ name = "AmiIa32Lib"
+ category = ModulePart
+ LocalRoot = "Core\CPU\IA32\"
+ RefName = "AmiIa32Lib"
+[files]
+"AmiIa32Lib.sdl"
+"AmiIa32Lib.mak"
+"IA32CLib.c"
+"IA32AsmLib\EnableLongMode.asm"
+"IA32AsmLib\EnableMachineCheck.asm"
+<endComponent>
diff --git a/Core/CPU/IA32/AmiIa32Lib.mak b/Core/CPU/IA32/AmiIa32Lib.mak
new file mode 100644
index 0000000..304209c
--- /dev/null
+++ b/Core/CPU/IA32/AmiIa32Lib.mak
@@ -0,0 +1,67 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2006, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Core/Modules/IA32Core/AmiIa32Lib.mak 1 10/13/06 8:36p Felixp $
+#
+# $Revision: 1 $
+#
+# $Date: 10/13/06 8:36p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Core/Modules/IA32Core/AmiIa32Lib.mak $
+#
+# 1 10/13/06 8:36p Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: AmiIa32Lib.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+AmiIa32Lib : $(BUILD_DIR)\AmiIa32Lib.mak AmiIa32LibBin
+
+$(BUILD_DIR)\AmiIa32Lib.mak : $(AmiIa32Lib_DIR)\$(@B).cif $(AmiIa32Lib_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(AmiIa32Lib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+!IF "$(PROCESSOR)"=="" || "$(PROCESSOR)"=="IA32"
+AmiDxeLibBin : $(BUILD_DIR)\AmiIa32Lib.lib
+AmiPeiLibBin : $(BUILD_DIR)\AmiIa32Lib.lib
+$(BUILD_DIR)\AmiIa32Lib.lib : AmiIa32Lib
+!ELSEIF "$(PROCESSOR)"=="x64"
+AmiPeiLibBin : $(BUILD_DIR)\AmiIa32Lib.lib
+$(BUILD_DIR)\AmiIa32Lib.lib : AmiIa32Lib
+!ENDIF
+
+AmiIa32LibBin :
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\AmiIa32Lib.mak all\
+ TYPE=PEI_LIBRARY
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2006, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/CPU/IA32/AmiIa32Lib.sdl b/Core/CPU/IA32/AmiIa32Lib.sdl
new file mode 100644
index 0000000..8581f00
--- /dev/null
+++ b/Core/CPU/IA32/AmiIa32Lib.sdl
@@ -0,0 +1,19 @@
+TOKEN
+ Name = "AmiIa32Lib_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable AmiIa32Lib support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "AmiIa32Lib_DIR"
+End
+
+MODULE
+ Help = "Includes AmiIa32Lib.mak to Project"
+ File = "AmiIa32Lib.mak"
+End
+
diff --git a/Core/CPU/IA32/FoundationIa32.cif b/Core/CPU/IA32/FoundationIa32.cif
new file mode 100644
index 0000000..8f9a179
--- /dev/null
+++ b/Core/CPU/IA32/FoundationIa32.cif
@@ -0,0 +1,16 @@
+<component>
+ name = "FoundationIa32"
+ category = ModulePart
+ LocalRoot = "Core\CPU\IA32\"
+ RefName = "FoundationIa32"
+[files]
+"FoundationIa32.sdl"
+"FoundationIa32.mak"
+"efijump.h"
+"PeCoffLoaderEx.c"
+"PeCoffLoaderEx.h"
+"Processor.c"
+"ProcessorAsms.Asm"
+"SwitchCoreStacks.asm"
+"Processor.h"
+<endComponent>
diff --git a/Core/CPU/IA32/FoundationIa32.mak b/Core/CPU/IA32/FoundationIa32.mak
new file mode 100644
index 0000000..93f45d4
--- /dev/null
+++ b/Core/CPU/IA32/FoundationIa32.mak
@@ -0,0 +1,69 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2006, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Core/EDK/IA32/FoundationIa32.mak 1 8/24/06 12:35p Felixp $
+#
+# $Revision: 1 $
+#
+# $Date: 8/24/06 12:35p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Core/EDK/IA32/FoundationIa32.mak $
+#
+# 1 8/24/06 12:35p Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: FoundationIa32.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+FoundationIa32 : $(BUILD_DIR)\FoundationIa32.mak FoundationIa32Bin
+
+$(BUILD_DIR)\FoundationIa32.mak : $(FoundationIa32_DIR)\$(@B).cif $(FoundationIa32_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(FoundationIa32_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+!IF "$(PROCESSOR)"=="" || "$(PROCESSOR)"=="IA32"
+FoundationBin : $(BUILD_DIR)\FoundationIa32.lib
+FoundationPeiBin : $(BUILD_DIR)\FoundationIa32.lib
+$(BUILD_DIR)\FoundationIa32.lib : FoundationIa32
+!ELSEIF "$(PROCESSOR)"=="x64"
+FoundationPeiBin : $(BUILD_DIR)\FoundationIa32.lib
+$(BUILD_DIR)\FoundationIa32.lib : FoundationIa32
+!ENDIF
+
+
+FoundationIa32Bin :
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\FoundationIa32.mak all\
+ "CFLAGS=$(CFLAGS) /I$(Foundation_DIR)"\
+ TYPE=PEI_LIBRARY
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2006, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/CPU/IA32/FoundationIa32.sdl b/Core/CPU/IA32/FoundationIa32.sdl
new file mode 100644
index 0000000..67f7c70
--- /dev/null
+++ b/Core/CPU/IA32/FoundationIa32.sdl
@@ -0,0 +1,19 @@
+TOKEN
+ Name = "FoundationIa32_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable FoundationIa32 support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "FoundationIa32_DIR"
+End
+
+MODULE
+ Help = "Includes FoundationIa32.mak to Project"
+ File = "FoundationIa32.mak"
+End
+
diff --git a/Core/CPU/IA32/IA32AsmLib/EnableLongMode.asm b/Core/CPU/IA32/IA32AsmLib/EnableLongMode.asm
new file mode 100644
index 0000000..14af3dd
--- /dev/null
+++ b/Core/CPU/IA32/IA32AsmLib/EnableLongMode.asm
@@ -0,0 +1,143 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2012, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/IA32Core/IA32AsmLib/EnableLongMode.asm 2 8/06/12 2:43p Markw $
+;
+; $Revision: 2 $
+;
+; $Date: 8/06/12 2:43p $Log:$
+;
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.686p
+.xmm
+.model flat
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: EnableLongMode
+;
+; Description:
+; VOID EnableLongMode(IN VOID *PageTable, IN VOID *Function,
+; IN VOID *Parameter1, IN VOID *Parameter2) enables long mode then calls the
+; provided function with the provided parameters.
+;
+; Input:
+; IN VOID *PageTable
+; Pointer to level 4 page map.
+;
+; IN VOID *Function
+; Pointer to function to call.
+;
+; IN VOID *Parameter1
+; Parameter 1 for above function call.
+;
+; IN VOID *Parameter2
+; Parameter 2 for above function call.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+EnableLongMode proc C public PageTable:DWORD, Function:DWORD, Parameter1:DWORD, Parameter2:DWORD
+ mov eax, PageTable
+ mov cr3, eax ;Set CR3 to first page directory pointer table
+
+ mov eax, cr4
+ or ax, 620h ;Enable PAE and XMM in case it was turned off.
+ mov cr4, eax
+
+ ;Enable long mode in msr register. Doesn't actually enter long mode yet.
+ mov ecx, 0c0000080h
+ rdmsr
+ bts eax, 8
+ wrmsr
+
+ ;Enable paging
+ mov eax, cr0
+ bts eax, 31
+ mov cr0, eax ;Now in long mode compatiblity.
+ jmp @f
+@@:
+
+ ;jmp far segment:offset
+ db 67h, 0eah
+ dd offset long_mode_64
+ dw 38h ;SYS_CODE64_SEL
+long_mode_64:
+ ;in 64-bit long mode
+
+ db 48h
+ xor eax, eax ;xor rax, rax
+ db 48h
+ xor ebx, ebx ;xor rbx, rbx
+ db 48h
+ xor ecx, ecx ;xor rcx, rcx
+ db 48h
+ xor edx, edx ;xor rdx, rdx
+
+ mov ecx, Parameter1
+ mov edx, Parameter2
+ mov ebx, Function
+
+ mov ax, 30h ;SYS_DATA64_SEL
+ mov ds, ax
+ mov es, ax
+ mov ss, ax
+
+ push 37fh
+ fldcw word ptr [esp] ;Uses rsp. Set FP control word according UEFI
+ db 48h
+ add esp, 8 ;add rsp, 8
+
+
+ mov eax, 0fffffff0h
+ db 48h
+ and esp, eax ;rsp must be on a 16 byte boundary. C compiler expects that.
+ call ebx ;call rbx
+ ret
+EnableLongMode endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2012, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
diff --git a/Core/CPU/IA32/IA32AsmLib/EnableMachineCheck.asm b/Core/CPU/IA32/IA32AsmLib/EnableMachineCheck.asm
new file mode 100644
index 0000000..8b3cd2a
--- /dev/null
+++ b/Core/CPU/IA32/IA32AsmLib/EnableMachineCheck.asm
@@ -0,0 +1,78 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/IA32Core/IA32AsmLib/EnableMachineCheck.asm 1 10/01/10 4:56p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 4:56p $Log:$
+;
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.686p
+.xmm
+.model flat
+.code
+
+;*************************************************************************
+;
+; Name: EnableMachineCheck
+;
+; Description:
+; VOID EnableMachineCheck(VOID) sets the Machine Check Exception bit in CR4,
+; which enables machine check interrupts to occur.
+;
+; Input:
+; VOID.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;*************************************************************************
+_EnableMachineCheck proc
+ mov eax, cr4
+ or eax, 1 SHL 6
+ mov cr4, eax
+ ret
+_EnableMachineCheck endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
diff --git a/Core/CPU/IA32/IA32CLib.c b/Core/CPU/IA32/IA32CLib.c
new file mode 100644
index 0000000..4cf579c
--- /dev/null
+++ b/Core/CPU/IA32/IA32CLib.c
@@ -0,0 +1,1959 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Core/Modules/IA32Core/IA32CLib.c 14 11/11/11 3:39p Artems $
+//
+// $Revision: 14 $
+//
+// $Date: 11/11/11 3:39p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/Modules/IA32Core/IA32CLib.c $
+//
+// 14 11/11/11 3:39p Artems
+// Bug fix: Verify pointer is not NULL when return value
+//
+// 13 10/18/11 11:47a Yakovlevs
+// [TAG] EIP71694
+// [Category] Bug Fix
+// [Symptom] Option ROM is corrupted when copied from device on Rosecity
+// Core 4.6.5.1.
+// [RootCause] MemCpy was updated to use 8 bytes at a time.
+// PCI ROM BAR was not able to handle this type of request.
+// [Solution] Introducesd MemCpy32 functiom.
+// [Files] AmiLib.h; AmiX64Lib.cif; IA32CLib.c
+// MemCpy32.asm - added
+//
+// 12 10/01/10 4:57p Felixp
+// Most of the functions from IA32AsmLib.asm moved here
+//
+// 11 11/25/09 1:55p Felixp
+//
+// 10 11/24/09 5:24p Oleksiyy
+// EIP 27605: Added ACPI 4.0 support. InitLongMode function modified.
+//
+// 9 11/05/09 5:03p Oleksiyy
+// EIP 27821 Support for 64 bit operations in IoRead and IoWrite added.
+//
+// 8 7/10/09 9:26a Felixp
+// Function headers are added
+//
+// 7 4/17/08 2:30p Markw
+// Update InitLongMode to create pages above 32-bits.
+//
+// 6 3/24/08 2:18p Markw
+// Added support for pages tables above 4GB. Currently, disabled.
+//
+// 5 3/18/08 2:41p Markw
+// Update page table for first 2MB to have 4k pages. This is so cache
+// attributes will not be different in a page.
+//
+// 4 4/25/07 5:36p Felixp
+// InitLongMode and EnableLongMode routines extended so support calling of
+// the x64 routine with 2 parameters
+//
+// 3 12/28/06 6:21p Felixp
+// VC8 32-bit compiler support added
+//
+// 2 10/09/06 10:09a Felixp
+// Clean up
+//
+// 1 8/24/06 12:54p Felixp
+//
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: IA32CLib.c
+//
+// Description:
+// Generic CPU library functions for the IA32 architecture. See function
+// definitions in the x64 library; most IA32 functions have been removed
+// from help builder output to fix a name collision issue.
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+#include <PEI.h>
+#include <AmiLib.h>
+#include <Hob.h>
+
+//*************************************************************************
+// Math
+//*************************************************************************
+
+//*************************************************************************
+//
+// Name: Shr64
+//
+// Description:
+// UINT64 Shr64(IN UINT64 Value, IN UINT8 Shift) shifts the 64-bit Value
+// right the provided number of bits, Shift.
+//
+// Input:
+// IN UINT64 Value
+// The value to be shifted.
+//
+// IN UINT8 Shift
+// The number of bits to shift right.
+//
+// Output:
+// UINT64 Value shifted right Shift number of bits.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+UINT64 Shr64(
+ IN UINT64 Value,
+ IN UINT8 Shift
+ )
+{
+ _asm {
+ mov edx, dword ptr Value[4]
+ mov eax, dword ptr Value
+ mov cl, Shift
+
+ cmp cl, 64
+ jb less_64
+ xor eax, eax
+ xor edx, edx
+ jmp exit
+less_64:
+ cmp cl, 32 //Shift is 32 modulo
+ jb less_32
+
+ mov eax, edx
+ xor edx, edx
+less_32:
+ shrd eax, edx, cl
+ shr edx, cl
+exit:
+ }
+}
+
+//*************************************************************************
+//
+// Name: Shl64
+//
+// Description:
+// UINT64 Shl64(IN UINT64 Value, IN UINT8 Shift) shifts the 64-bit Value
+// left the provided number of bits, Shift.
+//
+// Input:
+// IN UINT64 Value
+// The value to be shifted left.
+//
+// IN UINT8 Shift
+// The number of bits to shift.
+//
+// Output:
+// UINT64 Value shifted left Shift number of bits.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+UINT64 Shl64(
+ IN UINT64 Value,
+ IN UINT8 Shift
+ )
+{
+ _asm {
+ mov edx, dword ptr Value[4]
+ mov eax, dword ptr Value
+ mov cl, Shift
+
+ cmp cl, 64
+ jb less_64
+ xor eax, eax
+ xor edx, edx
+ jmp exit
+less_64:
+ cmp cl, 32 //Shift is 32 modulo
+ jb less_32
+
+ mov edx, eax
+ xor eax, eax
+less_32:
+ shld edx, eax, cl
+ shl eax, cl
+exit:
+ }
+}
+
+//*************************************************************************
+//
+// Name: Div64
+//
+// Description:
+// UINT64 Div64(IN UINT64 Dividend, IN UINTN Divisor,
+// OUT UINTN *Remainder OPTIONAL) divides a 64-bit number, Dividend, by the
+// Divisor, which can be up to 31-bits.
+//
+// Input:
+// IN UINT64 Dividend
+// The 64-bit number to be divided.
+//
+// IN UINT Divisor
+// The number to divide Dividend by; may not exceed 31-bits in size.
+//
+// OUT UINTN *Remainder OPTIONAL
+// The remainder of the division. Provide NULL if undesired; otherwise user
+// is responsible for handling the necessary memory resources.
+//
+// Output:
+// UINT64 result of dividing Dividend by Divisor.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+UINT64 Div64 (
+ IN UINT64 Dividend,
+ IN UINTN Divisor, //Can only be 31 bits.
+ OUT UINTN *Remainder OPTIONAL
+ )
+{
+ UINT64 Result;
+ UINT32 Rem;
+ _asm
+ {
+ mov eax, dword ptr Dividend[0]
+ mov edx, dword ptr Dividend[4]
+ mov esi, Divisor
+ xor edi, edi ; Remainder
+ mov ecx, 64 ; 64 bits
+Div64_loop:
+ shl eax, 1 ;Shift dividend left. This clears bit 0.
+ rcl edx, 1
+ rcl edi, 1 ;Shift remainder left. Bit 0 = previous dividend bit 63.
+
+ cmp edi, esi ; If Rem >= Divisor, don't adjust
+ cmc ; else adjust dividend and subtract divisor.
+ sbb ebx, ebx ; if Rem >= Divisor, ebx = 0, else ebx = -1.
+ sub eax, ebx ; if adjust, bit 0 of dividend = 1
+ and ebx, esi ; if adjust, ebx = Divisor, else ebx = 0.
+ sub edi, ebx ; if adjust, subtract divisor from remainder.
+ loop Div64_loop
+
+ mov dword ptr Result[0], eax
+ mov dword ptr Result[4], edx
+ mov Rem, edi
+ }
+
+ if (Remainder) *Remainder = Rem;
+
+ return Result;
+}
+//*************************************************************************
+//
+// Name: Mul64
+//
+// Description:
+// UINT64 Mul64(IN UINT64 Value64, IN UINTN Value32) multiplies a 64-bit
+// number by a 32-bit number and returns the 64-bit result.
+//
+// Input:
+// IN UINTN64 Value64
+// The 64-bit number to multiply by.
+//
+// IN UINTN Value32
+// The 32-bit number to multiply by.
+//
+// Output:
+// UINT64 result of multiplying Value64 by Value32.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+UINT64 Mul64(
+ IN UINT64 Value64,
+ IN UINTN Value32
+ )
+{
+ UINT64 Result;
+
+ _asm {
+ mov eax, dword ptr Value64[0]
+ mul Value32
+ mov dword ptr Result[0], eax
+ mov dword ptr Result[4], edx
+ mov eax, dword ptr Value64[4]
+ mul Value32
+ add dword ptr Result[4], eax
+ }
+
+ return Result;
+}
+
+//*************************************************************************
+// Memory Operations
+//*************************************************************************
+
+//*************************************************************************
+//
+// Name: MemCpy
+//
+// Description:
+// VOID MemCpy(OUT VOID *pDestination, IN VOID *pSource, IN UINTN Count)
+// copies Count bytes of memory from Source to Destination.
+//
+// Input:
+// OUT VOID *pDestination
+// Memory address where data shall be copied. User is responsible for
+// allocating the necessary memory resources.
+//
+// IN VOID *pSource
+// Memory address from where data shall be copied.
+//
+// IN UINTN Count
+// Number of bytes to copy from pSource.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+// This function checks for overlapping of source and destination and
+// selects copy direction that prevents memory corruption.
+//
+//*************************************************************************
+VOID MemCpy(VOID* pDestination, VOID* pSource, UINTN Count)
+{
+ _asm{
+// esi, edi, ebx are saved/restores in compiler prolog/epilog code
+ pushf
+ mov esi, pSource
+ mov edi, pDestination
+ mov ecx, Count
+ mov dl, 0
+ mov eax, esi
+ sub eax, edi
+ jnb CopyForward
+ lea ebx, [esi+ecx]
+ neg eax
+ cmp ebx, edi
+ jb CopyForward
+ mov esi, ebx
+ lea edi, [edi+ecx]
+ mov dl, 1
+ std
+CopyForward:
+ cmp ecx, 4
+ jb m8
+ cmp eax, 4
+ jb m8
+ mov eax, esi
+ mov ebx, edi
+ and eax, 3
+ and ebx, 3
+ test dl, dl
+ jz skip1
+ dec esi
+ dec edi
+skip1:
+ cmp eax, ebx
+ jne m32
+ test eax, eax
+ jz m32
+ test dl, dl
+ jnz skip_nz1
+ neg eax
+ add eax, 4
+skip_nz1:
+ xchg eax, ecx
+ sub eax, ecx
+ rep movsb
+ mov ecx, eax
+m32:
+ test dl, dl
+ jz skip2
+ sub esi, 3
+ sub edi, 3
+skip2:
+ mov eax, ecx
+ shr ecx, 2
+ rep movsd
+ and eax, 3
+ jz end
+ test dl, dl
+ jz skip3
+ add esi, 4
+ add edi, 4
+skip3:
+ mov ecx, eax
+m8:
+ test dl, dl
+ jz skip4
+ dec esi
+ dec edi
+skip4:
+ rep movsb
+end:
+ popf
+// esi, edi, ebx are saved/restores in compiler prolog/epilog code
+ }
+}
+
+VOID MemCpy32(VOID* pDestination, VOID* pSource, UINTN Count){
+ MemCpy(pDestination, pSource, Count);
+}
+
+//*************************************************************************
+//<AMI_PHDR_START>
+//
+// Name: memcpy
+//
+// Description:
+// VOID memcpy(OUT VOID *pDestination, IN VOID *pSource, IN UINTN Count) is
+// a wrapper for MemCpy, which copies Count bytes of memory from Source to
+// Destination.
+//
+// Input:
+// OUT VOID *pDestination
+// Memory address where data shall be copied. User is responsible for
+// allocating the necessary memory resources.
+//
+// IN VOID *pSource
+// Memory address from where data shall be copied.
+//
+// IN UINTN Count
+// Number of bytes to copy from pSource.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+// MemCpy
+//
+// Notes:
+// MemCpy checks for overlapping of source and destination and selects copy
+// direction that prevents memory corruption.
+//
+//<AMI_PHDR_END>
+//*************************************************************************
+VOID memcpy(VOID* pDestination, VOID* pSource, UINTN Count)
+{
+ MemCpy(pDestination,pSource,Count);
+}
+
+//*************************************************************************
+//
+// Name: MemSet
+//
+// Description:
+// VOID MemSet(IN VOID *pBuffer, IN UINTN Count, IN UINT8 Value) fills Count
+// bytes of memory in pBuffer with Value.
+//
+// Input:
+// IN VOID *pBuffer
+// The starting location in memory where to begin filling.
+//
+// IN UINTN Count
+// The number of bytes to fill with Value.
+//
+// IN UINT8 Value
+// The value to fill memory with starting at pBuffer.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID MemSet(VOID* pBuffer, UINTN Count, UINT8 Value)
+{
+ _asm{
+// edi, ebx are saved/restores in compiler prolog/epilog code
+ // fill EAX with the Value so that we can perform DWORD operatins
+ mov al,Value
+ mov ah, al
+ mov bx,ax
+ shl eax,16
+ mov ax,bx
+ mov edi, pBuffer
+ // if Counter is less then 4, jump to byte copy
+ mov ecx, Count
+ cmp ecx, 4
+ jb CopyByte
+ // check if the Buffer is 4-bytes aligned
+ mov edx,edi
+ and edx, 3
+ // if the Buffer is 4-bytes aligned, jump to DWORD copy
+ jz CopyDword
+ // Buffer is not 4-bytes aligned
+ // Calculate 4-(Buffer%4), which is a number of bytes we have to copy before
+ // Buffer will reach 4-bytes boundary, and perform byte copy
+ neg edx
+ add edx, 4
+ xchg ecx, edx
+ sub edx, ecx
+ rep stosb
+ mov ecx, edx
+CopyDword:
+ // perform DWORD copy
+ mov edx, ecx
+ shr ecx, 2
+ rep stosd
+ // copy the remainder
+ and edx,3
+ mov ecx, edx
+CopyByte:
+ rep stosb
+ ///
+// edi, ebx are saved/restores in compiler prolog/epilog code
+ }
+}
+
+//*************************************************************************
+//
+// Name: memset
+//
+// Description:
+// VOID memset(IN VOID *pBuffer, IN UINT8 Value, IN UINTN Count) is a
+// wrapper for MemSet which fills Count bytes of memory in pBuffer with
+// Value.
+//
+// Input:
+// IN VOID *pBuffer
+// The starting location in memory where to begin filling.
+//
+// IN UINT8 Value
+// The value to fill memory with starting at pBuffer.
+//
+// IN UINTN Count
+// The number of bytes to fill with Value.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID memset(VOID* pBuffer, UINTN Value, UINTN Count)
+{
+ MemSet(pBuffer,Count,(UINT8)Value);
+}
+//*************************************************************************
+// Debug routines
+//*************************************************************************
+
+//*************************************************************************
+//
+// Name: checkpoint
+//
+// Description:
+// VOID checkpoint(IN UINT8 c) writes the value c to port 0x80.
+//
+// Input:
+// IN UINT8 c
+// The value/checkpoint to write to 0x80.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+// This routine should only be used if the PROGRESS_CODE or
+// PEI_PROGRESS_CODE macros are unavailable.
+//
+//*************************************************************************
+VOID checkpoint(UINT8 c){
+ _asm{
+ mov al, c
+ out 0x80,al
+ }
+}
+
+//*************************************************************************
+//
+// Name: GetCpuTimer
+//
+// Description:
+// UINT64 GetCpuTimer() returns the value of the CPU timer.
+//
+// Input:
+// None.
+//
+// Output:
+// UINT64 value of the CPU timer.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+UINT64 GetCpuTimer(){_asm rdtsc}
+
+//*************************************************************************
+// I/O Operations
+//*************************************************************************
+
+//*************************************************************************
+//
+// Name: IoRead8
+//
+// Description:
+// UINT8 IoRead8(IN UINT16 Port) reads the 8-bit value stored at the I/O
+// port defined by Port.
+//
+// Input:
+// IN UINT16 Port
+// I/O port to read 8-bits from.
+//
+// Output:
+// UINT8 value stored at I/O Port.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+UINT8 IoRead8(UINT16 Port)
+{
+ _asm {
+ mov dx, Port
+ in al, dx
+ }
+}
+
+//*************************************************************************
+//
+// Name: IoWrite8
+//
+// Description:
+// VOID IoWrite8(IN UINT16 Port, IN UINT8 Value) writes the 8-bit Value to
+// the I/O port defined by Port.
+//
+// Input:
+// IN UINT16 Port
+// I/O port to write 8-bits to.
+//
+// IN UINT8 Value
+// 8-bits to write to the I/O Port.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+void IoWrite8(UINT16 Port,UINT8 Value)
+{
+ _asm {
+ mov dx, Port
+ mov al, Value
+ out dx, al
+ }
+}
+
+//*************************************************************************
+//
+// Name: IoRead16
+//
+// Description:
+// UINT16 IoRead16(IN UINT16 Port) reads the 16-bit value stored at the I/O
+// port defined by Port.
+//
+// Input:
+// IN UINT16 Port
+// I/O port to read 16-bits from.
+//
+// Output:
+// UINT16 value stored at I/O Port.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+UINT16 IoRead16(UINT16 Port)
+{
+ _asm {
+ mov dx, Port
+ in ax, dx
+ }
+}
+
+//*************************************************************************
+//
+// Name: IoWrite16
+//
+// Description:
+// VOID IoWrite16(IN UINT16 Port, IN UINT16 Value) writes the 16-bit Value
+// to the I/O port defined by Port.
+//
+// Input:
+// IN UINT16 Port
+// I/O port to write 16-bits to.
+//
+// IN UINT16 Value
+// 16-bits to write to the I/O Port.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+void IoWrite16(UINT16 Port,UINT16 Value)
+{
+ _asm {
+ mov dx, Port
+ mov ax, Value
+ out dx, ax
+ }
+}
+
+//*************************************************************************
+//
+// Name: IoRead32
+//
+// Description:
+// UINT32 IoRead32(IN UINT16 Port) reads the 32-bit value stored at the I/O
+// port defined by Port.
+//
+// Input:
+// IN UINT16 Port
+// I/O port to read 32-bits from.
+//
+// Output:
+// UINT32 value stored at I/O Port.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+UINT32 IoRead32(UINT16 Port)
+{
+ _asm {
+ mov dx, Port
+ in eax, dx
+ }
+}
+
+//*************************************************************************
+//
+// Name: IoWrite32
+//
+// Description:
+// VOID IoWrite32(IN UINT16 Port, IN UINT32 Value) writes the 32-bit Value
+// to the I/O port defined by Port.
+//
+// Input:
+// IN UINT16 Port
+// I/O port to write 32-bits to.
+//
+// IN UINT32 Value
+// 32-bits to write to the I/O Port.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+void IoWrite32(UINT16 Port,UINT32 Value)
+{
+ _asm {
+ mov dx, Port
+ mov eax, Value
+ out dx, eax
+ }
+}
+
+//*************************************************************************
+//
+// Name: IoRead64
+//
+// Description:
+// UINT32 IoRead64(IN UINT16 Port) reads the 64-bit value stored at the I/O
+// port defined by Port.
+//
+// Input:
+// IN UINT16 Port
+// I/O port to read 64-bits from.
+//
+// Output:
+// UINT64 value stored at I/O Port.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+UINT64 IoRead64(UINT16 Port)
+{
+
+ UINT64 Result;
+ UINT64 *Buffer = &Result;
+
+ _asm {
+ xor edx, edx
+ mov dx, Port
+ mov esi, Buffer
+ in eax, dx
+ mov dword ptr[esi],eax
+ add esi, 4
+ add dx, 4
+ in eax, dx
+ mov dword ptr[esi],eax
+ }
+ return Result;
+}
+
+//*************************************************************************
+//
+// Name: IoWrite64
+//
+// Description:
+// VOID IoWrite64(IN UINT16 Port, IN UINT64 Value) writes the 64-bit Value
+// to the I/O port defined by Port.
+//
+// Input:
+// IN UINT16 Port
+// I/O port to write 64-bits to.
+//
+// IN UINT64 Value
+// 64-bits to write to the I/O Port.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+void IoWrite64(UINT16 Port, UINT64 Value)
+{
+// UINT32 Lo=(UINT32)Value, Hi=(UINT32)Shr64(Value,32);
+
+ VOID* Buffer=&Value;
+
+
+ _asm {
+ xor edx, edx
+ mov dx, Port
+ mov esi, Buffer
+ mov eax, dword ptr[esi]
+ out dx, eax
+ add esi, 4
+ add dx, 4
+ mov eax, dword ptr[esi]
+ out dx, eax
+ }
+
+
+
+}
+
+VOID EnableLongMode(VOID *PageTable, VOID *Function, VOID *Parameter1, VOID *Parameter2);
+
+//*************************************************************************
+//<AMI_PHDR_START>
+//
+// Name: InitLongModeExt
+//
+// Description:
+// VOID InitLongMode(IN EFI_PEI_SERVICES **PeiServices, IN VOID *Function,
+// IN VOID *Parameter1, IN VOID *Parameter2) initializes memory page mapping,
+// enables long mode and jumps to a provided function.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// Double pointer to the PEI Services table.
+//
+// IN VOID *Function
+// Pointer to a function for EnableLongMode to call.
+//
+// IN VOID *Parameter1
+// First parameter to provide the Function to be called.
+//
+// IN VOID *Parameter2
+// Second parameter to provide the Function to be called.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+// FindNextHobByType
+// EFI_ERROR
+// GetPageTableNumPages
+// FillPageTable
+// EnableLongMode
+//
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//*************************************************************************
+VOID InitLongModeExt(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN VOID *Function,
+ IN VOID *Parameter1,
+ IN VOID *Parameter2,
+ IN UINT8 NumMemBits
+)
+{
+ EFI_PHYSICAL_ADDRESS PageTable;
+ UINT32 NumPages;
+ EFI_STATUS Status;
+//TODO: In AllocatePages below, change EfiACPIMemoryNVS to EfiBootServicesData.
+//TODO: It is left as EfiACPIMemoryNVS until future projects can be updated to
+//TODO: a later CPU module. Future CPU modules will allocate EfiACPIMemoryNVS
+//TODO: for only 32-bits.
+
+ NumPages = GetPageTableNumPages(NumMemBits);
+
+ Status = (*PeiServices)->AllocatePages(
+ PeiServices,
+ EfiACPIMemoryNVS,
+ NumPages,
+ &PageTable
+ );
+ //ASSERT_PEI_ERROR(PeiServices,Status);
+
+ FillPageTable(NumMemBits, (VOID*)PageTable);
+
+ EnableLongMode((VOID*)PageTable, Function, Parameter1, Parameter2);
+}
+//*************************************************************************
+//<AMI_PHDR_START>
+//
+// Name: InitLongMode
+//
+// Description:
+// VOID InitLongMode(IN EFI_PEI_SERVICES **PeiServices, IN VOID *Function,
+// IN VOID *Parameter1, IN VOID *Parameter2) initializes memory page mapping,
+// enables long mode and jumps to a provided function.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// Double pointer to the PEI Services table.
+//
+// IN VOID *Function
+// Pointer to a function for EnableLongMode to call.
+//
+// IN VOID *Parameter1
+// First parameter to provide the Function to be called.
+//
+// IN VOID *Parameter2
+// Second parameter to provide the Function to be called.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+// FindNextHobByType
+// EFI_ERROR
+// GetPageTableNumPages
+// FillPageTable
+// EnableLongMode
+//
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//*************************************************************************
+VOID InitLongMode(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN VOID *Function,
+ IN VOID *Parameter1,
+ IN VOID *Parameter2
+)
+{
+
+
+ UINT8 NumMemBits = 32;
+ EFI_HOB_CPU *CpuHob;
+ VOID *FirstHob;
+ EFI_STATUS Status;
+
+ (*PeiServices)->GetHobList(PeiServices, &FirstHob);
+ //if (!FirstHob) ASSERT_PEI_ERROR(PeiServices, EFI_NOT_FOUND);
+
+ CpuHob = (EFI_HOB_CPU*) FirstHob;
+ Status = FindNextHobByType(EFI_HOB_TYPE_CPU, &CpuHob);
+
+ //If error during release mode, The memory cache size will be 32-bits.
+ //During debug mode, an assert will happen to alert that the CPU HOB is
+ //not produced, so that all memory will not be paged.
+ //ASSERT_PEI_ERROR(PeiServices, Status);
+
+ //Find APIC ID Hob.
+ if (!EFI_ERROR(Status)) {
+ NumMemBits = CpuHob->SizeOfMemorySpace;
+ }
+
+ InitLongModeExt (PeiServices, Function, Parameter1, Parameter2, NumMemBits);
+}
+
+//*************************************************************************
+//
+// Name: GetPowerOfTwo64
+//
+// Description:
+// UINT64 GetPowerOfTwo64(IN UINT64 Input) returns the highest bit set in
+// the provided UINT64 Input. Equivalent to 1 << log2(x).
+//
+// Input:
+// IN UINT64 Input
+// The 64-bit value to check for its highest bit.
+//
+// Output:
+// UINT64 value of the highest bit; if Input is 0, returns 0.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+UINT64 GetPowerOfTwo64(
+ IN UINT64 Input
+)
+{
+ UINT64 Result = 0;
+
+ if (Input > 0xffffffff) {
+ _asm {
+ bsr eax, dword ptr Input[4]
+ bts dword ptr Result[4], eax
+ }
+ } else {
+ _asm {
+ bsr eax, dword ptr Input[0]
+ bts dword ptr Result[0], eax
+ }
+ }
+ return Result;
+}
+
+//*************************************************************************
+//
+// Name: ReadMsr
+//
+// Description:
+// UINT64 ReadMsr(IN UINT32 Msr) reads the CPU MSR index defined by Msr and
+// returns the value.
+//
+// Input:
+// IN UINT32 Msr
+// 32-bit MSR index to be read.
+//
+// Output:
+// UINT64 MSR value at MSR index, Msr.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+UINT64 ReadMsr(IN UINT32 Msr){
+ _asm{
+ mov ecx, Msr ;MSR register
+ rdmsr
+ }
+}
+
+//*************************************************************************
+//
+// Name: WriteMsr
+//
+// Description:
+// VOID WriteMsr(IN UINT32 Msr, IN UINT64 Value) writes the Value to the
+// supplied MSR index, Msr.
+//
+// Input:
+// IN UINT32 Msr
+// 32-bit MSR index to be written to.
+//
+// IN UINT64 Value
+// Value to be written to MSR index.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID WriteMsr(IN UINT32 Msr, IN UINT64 Value){
+ _asm{
+ mov ecx, Msr ;MSR register
+ mov edx, dword ptr Value[4] ;Upper 32 bit MSR Value
+ mov eax, dword ptr Value[0] ;Lower 32 bit MSR Value
+ wrmsr
+ }
+}
+//*************************************************************************
+//
+// Name: CPULib_CpuID
+//
+// Description:
+// VOID CPULib_CpuID(IN UINT32 CpuIDIndex, IN OUT UINT32 *pRegEAX,
+// IN OUT UINT32 *pRegEBX, IN OUT UINT32 *pRegECX, IN OUT UINT32 *pRegEDX)
+// issues the CPUID instruction with the index provided and returns the
+// register values.
+//
+// Input:
+// IN UINT32 CpuIDIndex
+// 32-bit CPUID index.
+//
+// IN OUT UINT32 *pRegEAX
+// Pointer to UINT32 for EAX return value.
+//
+// IN OUT UINT32 *pRegEBX
+// Pointer to UINT32 for EBX return value.
+//
+// IN OUT UINT32 *pRegECX
+// Pointer to UINT32 for ECX return value.
+//
+// IN OUT UINT32 *pRegEDX
+// Pointer to UINT32 for EDX return value.
+//
+// Output:
+// IN OUT UINT32 *pRegEAX
+// Value of EAX after CPUID instruction.
+//
+// IN OUT UINT32 *pRegEBX
+// Value of EBX after CPUID instruction.
+//
+// IN OUT UINT32 *pRegECX
+// Value of ECX after CPUID instruction.
+//
+// IN OUT UINT32 *pRegEDX
+// Value of EDX after CPUID instruction.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID CPULib_CpuID(
+ IN UINT32 CpuIDIndex,
+ IN OUT UINT32 *pRegEAX,
+ IN OUT UINT32 *pRegEBX,
+ IN OUT UINT32 *pRegECX,
+ IN OUT UINT32 *pRegEDX)
+{
+ _asm{
+ push ebx
+ push ecx
+ push edx
+ push esi
+ mov esi, pRegECX
+ mov ecx, [esi]
+ mov eax, CpuIDIndex
+ cpuid
+ mov esi, pRegEAX
+ or esi, esi
+ jz skip1
+ mov [esi], eax
+skip1:
+ mov esi, pRegEBX
+ or esi, esi
+ jz skip2
+ mov [esi], ebx
+skip2:
+ mov esi, pRegECX
+ or esi, esi
+ jz skip3
+ mov [esi], ecx
+skip3:
+ mov esi, pRegEDX
+ or esi, esi
+ jz skip4
+ mov [esi], edx
+skip4:
+ pop esi
+ pop edx
+ pop ecx
+ pop ebx
+ }
+}
+
+//*************************************************************************
+//
+// Name: DisableCacheInCR0
+//
+// Description:
+// VOID DisableCacheInCR0(VOID) disables the CPU cache using the CR0 register.
+//
+// Input:
+// VOID.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID DisableCacheInCR0(VOID){
+ _asm{
+ wbinvd
+ mov eax, cr0
+ or eax, 060000000h ;SET CD, NW
+ mov cr0, eax
+ wbinvd ;Invalidate cache
+ }
+}
+
+//*************************************************************************
+//
+// Name: EnableCacheInCR0
+//
+// Description:
+// VOID EnableCacheInCR0(VOID) enables the CPU cache using the CR0 register.
+//
+// Input:
+// VOID.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID EnableCacheInCR0(VOID){
+ _asm{
+ // Enable cache
+ mov eax, cr0
+ and eax, 09fffffffh ;SET CD, NW
+ mov cr0, eax
+ wbinvd
+ }
+}
+//*************************************************************************
+//
+// Name: ReadCr3
+//
+// Description:
+// UINTN ReadCr3(VOID) reads the register CR3 and returns its value.
+//
+// Input:
+// VOID.
+//
+// Output:
+// Returns UINTN value stored in the CR3 register.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+UINTN ReadCr3(VOID){
+ _asm{
+ mov eax, cr3
+ }
+}
+//*************************************************************************
+//
+// Name: WriteCr3
+//
+// Description:
+// VOID WriteCr3(IN UINTN CR3) writes the provided value to the CR3 register.
+//
+// Input:
+// IN UINTN CR3
+// Value to be written to the CR3 register.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID WriteCr3(IN UINTN CR3){
+ _asm{
+ mov eax, CR3
+ mov cr3, eax
+ }
+}
+//*************************************************************************
+//
+// Name: CPULib_EnableInterrupt
+//
+// Description:
+// VOID CPULib_EnableInterrupt(VOID) enables interrupts on the CPU.
+//
+// Input:
+// VOID.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID CPULib_EnableInterrupt(VOID){
+ _asm{
+ // Enable Interrupt
+ sti
+ }
+}
+
+//*************************************************************************
+//
+// Name: CPULib_DisableInterrupt
+//
+// Description:
+// VOID CPULib_DisableInterrupt() disables interrupts on the CPU.
+//
+// Input:
+// VOID.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID CPULib_DisableInterrupt(){
+ _asm{
+ // Disable Interrupt
+ cli
+ }
+}
+
+//*************************************************************************
+//
+// Name: CPULib_GetInterruptState
+//
+// Description:
+// BOOLEAN CPULib_GetInterruptState(VOID)returns the current CPU interrupt
+// state.
+//
+// Input:
+// VOID.
+//
+// Output:
+// Returns FALSE if interrupts are disabled; otherwise TRUE.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+BOOLEAN CPULib_GetInterruptState(VOID){
+ _asm{
+ xor bl, bl
+ pushfd ; push flags onto stack.
+ pop eax ; eax = flags.
+ bt eax,9 ; IF (bit 9) if set, set carry flag.
+ ; Interrupts are allowed if IF is set.
+ adc bl, 0 ; BL = IF = CF.
+
+ mov al, bl ; Return value
+ }
+}
+
+//*************************************************************************
+//
+// Name: GetCsSegment
+//
+// Description:
+// UINT16 GetCsSegment(VOID) retreives the value of the CS register.
+//
+// Input:
+// VOID.
+//
+// Output:
+// Returns UINT16 value of CS.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+UINT16 GetCsSegment(VOID){
+ _asm{
+ mov ax, cs
+ }
+}
+
+//*************************************************************************
+//
+// Name: ReadRtdsc
+//
+// Description:
+// UINT64 ReadRtdsc(VOID) retrieves the time stamp counter.
+//
+// Input:
+// VOID.
+//
+// Output:
+// Returns UINT64 value of the time stamp counter.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+UINT64 ReadRtdsc(VOID){
+ _asm{
+ rdtsc
+ }
+}
+
+//*************************************************************************
+//
+// Name: WaitForever
+//
+// Description:
+// VOID WaitForever(VOID) performs an infinite loop which does nothing.
+//
+// Input:
+// VOID.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID WaitForever(VOID){
+ _asm{
+ bbb:
+ jmp bbb
+ }
+}
+
+//*************************************************************************
+//
+// Name: HltCpu
+//
+// Description:
+// VOID HltCpu(VOID) halts the CPU.
+//
+// Input:
+// VOID.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID HltCpu(VOID){
+ _asm{
+ bbb:
+ cli
+ hlt
+ jmp bbb
+ }
+}
+
+//*************************************************************************
+//
+// Name: CPULib_Pause
+//
+// Description:
+// VOID CPULib_Pause(VOID) performs the pause assembly instruction.
+//
+// Input:
+// VOID.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID CPULib_Pause(VOID){
+ _asm{
+ pause
+ }
+}
+
+//*************************************************************************
+//
+// Name: WaitForSemaphore
+//
+// Description:
+// VOID WaitForSemaphore(IN volatile UINT8 *Semaphore) waits for the
+// semaphore to become available; once available, it claims the semaphore and
+// returns.
+//
+// Input:
+// IN volatile UINT8 *Semaphore
+// Pointer to the desired semaphore.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID WaitForSemaphore(IN volatile UINT8 *Semaphore){
+ _asm{
+ push ebx
+ mov al, 1
+ mov ebx, Semaphore
+ bbb:
+ xchg al, [ebx]
+ or al, al
+ pause
+ jnz bbb
+ pop ebx
+ }
+}
+
+//*************************************************************************
+//
+// Name: WaitUntilZero8
+//
+// Description:
+// VOID WaitUntilZero8(IN volatile UINT8 *Value) waits until the byte stored
+// at Value becomes 0, then continues.
+//
+// Input:
+// IN volatile UINT8 *Value
+// Address of the byte value to be monitored.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID WaitUntilZero8(IN volatile UINT8 *Value){
+ _asm{
+ push ebx
+ mov ebx, Value
+ bbb:
+ mov al, [ebx]
+ or al, al
+ pause
+ jnz bbb
+ pop ebx
+ }
+}
+
+//*************************************************************************
+//
+// Name: WaitUntilZero32
+//
+// Description:
+// VOID WaitUntilZero32(IN volatile UINT32 *Value) waits until the UINT32
+// value stored at the Value address becomes 0, then continues.
+//
+// Input:
+// IN volatile UINT32 *Value
+// Address of the UINT32 value to be monitored.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID WaitUntilZero32(IN volatile UINT32 *Value) {
+ _asm{
+ push ebx
+ mov ebx, Value
+ bbb:
+ mov eax, [ebx]
+ or eax, eax
+ pause
+ jnz bbb
+ pop ebx
+ }
+}
+
+//*************************************************************************
+//
+// Name: CPULib_LockByteInc
+//
+// Description:
+// VOID CPULib_LockByteInc(IN UINT8 *ptr) locks the next byte after the
+// address pointed to by ptr.
+//
+// Input:
+// IN UINT8 *ptr// Address to the byte which preceeds the desired byte to be locked.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID CPULib_LockByteInc(IN UINT8 *xptr){
+ _asm{
+ mov eax, xptr
+ lock inc byte ptr [eax]
+ }
+}
+
+//*************************************************************************
+//
+// Name: CPULib_LockByteDec
+//
+// Description:
+// VOID CPULib_LockByteDec(IN UINT8 *ptr) locks the preceeding byte before
+// the address pointed to by ptr.
+//
+// Input:
+// IN UINT8 *ptr
+// Address to the byte which follows the desired byte to be locked.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID CPULib_LockByteDec(IN UINT8 *xptr) {
+ _asm{
+ mov eax, xptr
+ lock dec byte ptr [eax]
+ }
+}
+
+//*************************************************************************
+//
+// Name: CPULib_LoadGdt
+//
+// Description:
+// VOID CPULib_LoadGdt(IN VOID *ptr) loads the GDT at the location pointed to
+// by ptr.
+//
+// Input:
+// IN VOID *ptr
+// Address of the GDT to be loaded.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID CPULib_LoadGdt(IN VOID *xptr) {
+ _asm{
+ mov eax, xptr
+ lgdt fword ptr [eax]
+ }
+}
+
+//*************************************************************************
+//
+// Name: CPULib_SaveGdt
+//
+// Description:
+// VOID CPULib_SaveGdt(IN VOID *ptr) stores the loaded GDT at the location
+// provided by ptr.
+//
+// Input:
+// IN VOID *ptr
+// Address to save the GDT. User is responsible for allocating the necessary
+// memory resources.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID CPULib_SaveGdt(IN VOID *xptr) {
+ _asm{
+ mov eax, xptr
+ sgdt fword ptr [eax]
+ }
+}
+
+//*************************************************************************
+//
+// Name: CPULib_LoadIdt
+//
+// Description:
+// VOID CPULib_LoadIdt(IN VOID *ptr) loads the IDT at the location provided
+// by ptr.
+//
+// Input:
+// IN VOID *ptr
+// Address of the IDT to be loaded.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID CPULib_LoadIdt(IN VOID *xptr) {
+ _asm{
+ mov eax, xptr
+ lidt fword ptr [eax]
+ }
+}
+
+//*************************************************************************
+//
+// Name: CPULib_SaveIdt
+//
+// Description:
+// VOID CPULib_SaveIdt(IN VOID *ptr) stores the loaded IDT at the location
+// provided by ptr.
+//
+// Input:
+// IN VOID *ptr
+// Address to save the IDT. User is responsible for allocating the necessary
+// memory resources.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID CPULib_SaveIdt(IN VOID *xptr) {
+ _asm{
+ mov eax, xptr
+ sidt fword ptr [eax]
+ }
+}
+
+//*************************************************************************
+//
+// Name: MemRead32
+//
+// Description:
+// UINT32 MemRead32(IN UINT32 *Address) reads and returns the 32-bit value
+// stored at the user provided address.
+//
+// Input:
+// IN UINT32 *Address
+// Address to read 32-bits from.
+//
+// Output:
+// UINT32 value stored at Address.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+UINT32 MemRead32(IN UINT32 *Address) {
+ _asm{
+ push esi
+ mov esi, Address ;esi = address
+ mov eax, [esi]
+ pop esi
+ }
+}
+
+//*************************************************************************
+//
+// Name: MemReadWrite32
+//
+// Description:
+// VOID MemReadWrite32(IN UINT32 *Address, IN UINT32 Value, IN UINT32 Mask)
+// reads the 32-bit value stored at Address, ANDs it with Mask, ORs the result
+// with Value, then writes the result back to Address.
+//
+// Input:
+// IN UINT32 *Address
+// Address which shall be read from and subsequently written to.
+//
+// IN UINT32 Value
+// Value to be ORed with the value stored at Address after it has been ANDed
+// with the provided Mask.
+//
+// IN UINT32 Mask
+// Mask to be ANDed with the original value stored at Address.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID MemReadWrite32(
+ IN UINT32 *Address,
+ IN UINT32 Value,
+ IN UINT32 Mask)
+{
+ _asm{
+ push esi
+ mov esi, Address ;esi = address
+ mov eax, [esi]
+ and eax, Mask ;Mask
+ or eax, Value ;Value
+ mov [esi], eax
+ pop esi
+ }
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/CPU/IA32/IA32Core.cif b/Core/CPU/IA32/IA32Core.cif
new file mode 100644
index 0000000..352c150
--- /dev/null
+++ b/Core/CPU/IA32/IA32Core.cif
@@ -0,0 +1,9 @@
+<component>
+ name = "IA32 Core"
+ category = ModulePart
+ LocalRoot = "Core\CPU\IA32\"
+ RefName = "IA32Core"
+[files]
+"IA32Core.sdl"
+"IA32rules.mak"
+<endComponent>
diff --git a/Core/CPU/IA32/IA32Core.sdl b/Core/CPU/IA32/IA32Core.sdl
new file mode 100644
index 0000000..98f179a
--- /dev/null
+++ b/Core/CPU/IA32/IA32Core.sdl
@@ -0,0 +1,33 @@
+TOKEN
+ Name = "IA32Core_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable IA32 support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "AFLAGSIA32"
+ Value = "/coff"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+PATH
+ Name = "IA32Core_DIR"
+End
+
+ELINK
+ Name = "IA32"
+ Parent = "PROCESSOR"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(IA32Core_DIR)\IA32rules.mak"
+ Parent = "PROCESSOR_RULES"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/CPU/IA32/IA32rules.mak b/Core/CPU/IA32/IA32rules.mak
new file mode 100644
index 0000000..8f58110
--- /dev/null
+++ b/Core/CPU/IA32/IA32rules.mak
@@ -0,0 +1,62 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2006, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/BIN/Core/Modules/IA32Core/IA32rules.mak 2 12/28/06 6:22p Felixp $
+#
+# $Revision: 2 $
+#
+# $Date: 12/28/06 6:22p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Core/Modules/IA32Core/IA32rules.mak $
+#
+# 2 12/28/06 6:22p Felixp
+# VC8 32-bit compiler support added
+#
+# 1 10/13/06 8:30p Felixp
+#
+# 1 8/24/06 12:54p Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: IA32rules.mak
+#
+# Description: Defines IA32-specific build rules.
+# This file is included into the template makefile rules.mak
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+!IF "$(TOOLS)"=="vc8"
+EXTRA_CFLAGS=$(EXTRA_CFLAGS) /GS-
+!ENDIF
+
+EXTRA_CFLAGS=$(EXTRA_CFLAGS) $(CFLAGSIA32)
+EXTRA_LFLAGS=$(EXTRA_LFLAGS) $(LFLAGSIA32)
+EXTRA_AFLAGS=$(EXTRA_AFLAGS) $(AFLAGSIA32)
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2006, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/CPU/IA32/PeCoffLoaderEx.c b/Core/CPU/IA32/PeCoffLoaderEx.c
new file mode 100644
index 0000000..3e08c1c
--- /dev/null
+++ b/Core/CPU/IA32/PeCoffLoaderEx.c
@@ -0,0 +1,93 @@
+/*++
+
+Copyright (c) 2004 - 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:
+
+ PeCoffLoaderEx.c
+
+Abstract:
+
+ IA-32 Specific relocation fixups
+
+Revision History
+
+--*/
+
+#include "Tiano.h"
+#include "EfiImage.h"
+
+EFI_STATUS
+PeCoffLoaderRelocateImageEx (
+ IN UINT16 *Reloc,
+ IN OUT CHAR8 *Fixup,
+ IN OUT CHAR8 **FixupData,
+ IN UINT64 Adjust
+ )
+/*++
+
+Routine Description:
+
+ Performs an IA-32 specific relocation fixup
+
+Arguments:
+
+ Reloc - Pointer to the relocation record
+
+ Fixup - Pointer to the address to fix up
+
+ FixupData - Pointer to a buffer to log the fixups
+
+ Adjust - The offset to adjust the fixup
+
+Returns:
+
+ EFI_UNSUPPORTED - relocate unsupported
+
+--*/
+{
+ return EFI_UNSUPPORTED;
+}
+
+BOOLEAN
+PeCoffLoaderImageFormatSupported (
+ IN UINT16 Machine
+ )
+/*++
+Routine Description:
+
+ Returns TRUE if the machine type of PE/COFF image is supported. Supported
+ does not mean the image can be executed it means the PE/COFF loader supports
+ loading and relocating of the image type. It's up to the caller to support
+ the entry point.
+
+ This function implies the basic PE/COFF loader/relocator supports IA32, EBC,
+ & X64 images. Calling the entry point in a correct mannor is up to the
+ consumer of this library.
+
+Arguments:
+
+ Machine - Machine type from the PE Header.
+
+Returns:
+
+ TRUE - if this PE/COFF loader can load the image
+ FALSE - if this PE/COFF loader cannot load the image
+
+--*/
+{
+ if ((Machine == EFI_IMAGE_MACHINE_IA32) || (Machine == EFI_IMAGE_MACHINE_X64) ||
+ (Machine == EFI_IMAGE_MACHINE_EBC)) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
diff --git a/Core/CPU/IA32/PeCoffLoaderEx.h b/Core/CPU/IA32/PeCoffLoaderEx.h
new file mode 100644
index 0000000..a83282d
--- /dev/null
+++ b/Core/CPU/IA32/PeCoffLoaderEx.h
@@ -0,0 +1,85 @@
+/*++
+
+Copyright (c) 2004 - 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:
+
+ PeCoffLoaderEx.h
+
+Abstract:
+
+ IA-32 Specific relocation fixups
+
+Revision History
+
+--*/
+
+#ifndef _PE_COFF_LOADER_EX_H_
+#define _PE_COFF_LOADER_EX_H_
+
+EFI_STATUS
+PeCoffLoaderRelocateImageEx (
+ IN UINT16 *Reloc,
+ IN OUT CHAR8 *Fixup,
+ IN OUT CHAR8 **FixupData,
+ IN UINT64 Adjust
+ )
+/*++
+
+Routine Description:
+
+ Performs an IA-32 specific relocation fixup
+
+Arguments:
+
+ Reloc - Pointer to the relocation record
+
+ Fixup - Pointer to the address to fix up
+
+ FixupData - Pointer to a buffer to log the fixups
+
+ Adjust - The offset to adjust the fixup
+
+Returns:
+
+ EFI_UNSUPPORTED - relocate unsupported
+
+--*/
+;
+
+BOOLEAN
+PeCoffLoaderImageFormatSupported (
+ IN UINT16 Machine
+ )
+/*++
+Routine Description:
+
+ Returns TRUE if the machine type of PE/COFF image is supported. Supported
+ does not mean the image can be executed it means the PE/COFF loader supports
+ loading and relocating of the image type. It's up to the caller to support
+ the entry point.
+
+ This function implies the basic PE/COFF loader/relocator supports IA32, EBC,
+ & X64 images. Calling the entry point in a correct mannor is up to the
+ consumer of this library.
+
+Arguments:
+
+ Machine - Machine type from the PE Header.
+
+Returns:
+
+ TRUE - if this PE/COFF loader can load the image
+ FALSE - if this PE/COFF loader cannot load the image
+
+--*/
+;
+
+#endif
diff --git a/Core/CPU/IA32/Processor.c b/Core/CPU/IA32/Processor.c
new file mode 100644
index 0000000..fcdd4bf
--- /dev/null
+++ b/Core/CPU/IA32/Processor.c
@@ -0,0 +1,140 @@
+/*++
+
+Copyright (c) 2004 - 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:
+
+ Processor.c
+
+Abstract:
+
+--*/
+
+#include "Tiano.h"
+#include "EfiJump.h"
+#include EFI_GUID_DEFINITION (PeiFlushInstructionCache)
+#include EFI_GUID_DEFINITION (PeiTransferControl)
+
+//
+// Prototypes
+//
+EFI_STATUS
+EFIAPI
+TransferControlSetJump (
+ IN EFI_PEI_TRANSFER_CONTROL_PROTOCOL *This,
+ IN EFI_JUMP_BUFFER *Jump
+ );
+
+EFI_STATUS
+EFIAPI
+TransferControlLongJump (
+ IN EFI_PEI_TRANSFER_CONTROL_PROTOCOL *This,
+ IN EFI_JUMP_BUFFER *Jump
+ );
+
+EFI_STATUS
+EFIAPI
+FlushInstructionCacheFlush (
+ IN EFI_PEI_FLUSH_INSTRUCTION_CACHE_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS Start,
+ IN UINT64 Length
+ );
+
+//
+// Table declarations
+//
+EFI_PEI_TRANSFER_CONTROL_PROTOCOL mTransferControl = {
+ TransferControlSetJump,
+ TransferControlLongJump,
+ sizeof (EFI_JUMP_BUFFER)
+};
+
+EFI_PEI_FLUSH_INSTRUCTION_CACHE_PROTOCOL mFlushInstructionCache = {
+ FlushInstructionCacheFlush
+};
+
+
+EFI_STATUS
+InstallEfiPeiTransferControl (
+ IN OUT EFI_PEI_TRANSFER_CONTROL_PROTOCOL **This
+ )
+/*++
+
+Routine Description:
+
+ Installs the pointer to the transfer control mechanism
+
+Arguments:
+
+ This - Pointer to transfer control mechanism.
+
+Returns:
+
+ EFI_SUCCESS - Successfully installed.
+
+--*/
+{
+ *This = &mTransferControl;
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+InstallEfiPeiFlushInstructionCache (
+ IN OUT EFI_PEI_FLUSH_INSTRUCTION_CACHE_PROTOCOL **This
+ )
+/*++
+
+Routine Description:
+
+ Installs the pointer to the flush instruction cache mechanism
+
+Arguments:
+
+ This - Pointer to flush instruction cache mechanism.
+
+Returns:
+
+ EFI_SUCCESS - Successfully installed
+
+--*/
+{
+ *This = &mFlushInstructionCache;
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+FlushInstructionCacheFlush (
+ IN EFI_PEI_FLUSH_INSTRUCTION_CACHE_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS Start,
+ IN UINT64 Length
+ )
+/*++
+
+Routine Description:
+
+ This routine would provide support for flushing the CPU instruction cache.
+ In the case of IA32, this flushing is not necessary and is thus not implemented.
+
+Arguments:
+
+ This - Pointer to CPU Architectural Protocol interface
+ Start - Start adddress in memory to flush
+ Length - Length of memory to flush
+
+Returns:
+
+ Status
+ EFI_SUCCESS
+
+--*/
+{
+ return EFI_SUCCESS;
+}
diff --git a/Core/CPU/IA32/Processor.h b/Core/CPU/IA32/Processor.h
new file mode 100644
index 0000000..0084d4a
--- /dev/null
+++ b/Core/CPU/IA32/Processor.h
@@ -0,0 +1,27 @@
+/*++
+
+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:
+ Processor.h
+
+Abstract:
+ This file contains the IA-32 processor specific definitions
+
+--*/
+
+#ifndef _PROCESSOR_H_
+#define _PROCESSOR_H_
+
+#define EFI_ACPI_RUNTIME_PAGE_ALLOCATION_ALIGNMENT (EFI_PAGE_SIZE)
+
+#define DEFAULT_PAGE_ALLOCATION (EFI_PAGE_SIZE)
+
+#endif \ No newline at end of file
diff --git a/Core/CPU/IA32/ProcessorAsms.Asm b/Core/CPU/IA32/ProcessorAsms.Asm
new file mode 100644
index 0000000..86f4606
--- /dev/null
+++ b/Core/CPU/IA32/ProcessorAsms.Asm
@@ -0,0 +1,223 @@
+;
+; 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:
+;
+; ProcessorAsms.Asm
+;
+; Abstract:
+; This is separated from processor.c to allow this functions to be built with /O1
+;
+; Notes:
+; - Masm uses "This", "ebx", etc as a directive.
+; - H2INC is still not embedded in our build process so I translated the struc manually.
+; - Unreferenced variables/arguments (This, NewBsp, NewStack) were causing compile errors and
+; did not know of "pragma" mechanism in MASM and I did not want to reduce the warning level.
+; Instead, I did a dummy referenced.
+;
+
+ .686P
+ .MMX
+ .MODEL SMALL
+ .CODE
+
+EFI_SUCCESS equ 0
+EFI_WARN_RETURN_FROM_LONG_JUMP equ 5
+
+;
+; Generated by h2inc run manually
+;
+_EFI_JUMP_BUFFER STRUCT 2t
+_ebx DWORD ?
+_esi DWORD ?
+_edi DWORD ?
+_ebp DWORD ?
+_esp DWORD ?
+_eip DWORD ?
+_EFI_JUMP_BUFFER ENDS
+
+EFI_JUMP_BUFFER TYPEDEF _EFI_JUMP_BUFFER
+
+TransferControlSetJump PROTO C \
+ _This:PTR EFI_PEI_TRANSFER_CONTROL_PROTOCOL, \
+ Jump:PTR EFI_JUMP_BUFFER
+
+TransferControlLongJump PROTO C \
+ _This:PTR EFI_PEI_TRANSFER_CONTROL_PROTOCOL, \
+ Jump:PTR EFI_JUMP_BUFFER
+
+SwitchStacks PROTO C \
+ EntryPoint:PTR DWORD, \
+ Parameter:DWORD, \
+ NewStack:PTR DWORD, \
+ NewBsp:PTR DWORD
+
+SwitchIplStacks PROTO C \
+ EntryPoint:PTR DWORD, \
+ Parameter1:DWORD, \
+ Parameter2:DWORD, \
+ NewStack:PTR DWORD, \
+ NewBsp:PTR DWORD
+
+;
+;Routine Description:
+;
+; This routine implements the IA32 variant of the SetJump call. Its
+; responsibility is to store system state information for a possible
+; subsequent LongJump.
+;
+;Arguments:
+;
+; Pointer to CPU context save buffer.
+;
+;Returns:
+;
+; EFI_SUCCESS
+;
+TransferControlSetJump PROC C \
+ _This:PTR EFI_PEI_TRANSFER_CONTROL_PROTOCOL, \
+ Jump:PTR EFI_JUMP_BUFFER
+
+ mov eax, _This
+ mov ecx, Jump
+ mov (EFI_JUMP_BUFFER PTR [ecx])._ebx, ebx
+ mov (EFI_JUMP_BUFFER PTR [ecx])._esi, esi
+ mov (EFI_JUMP_BUFFER PTR [ecx])._edi, edi
+ mov eax, [ebp]
+ mov (EFI_JUMP_BUFFER PTR [ecx])._ebp, eax
+ lea eax, [ebp+4]
+ mov (EFI_JUMP_BUFFER PTR [ecx])._esp, eax
+ mov eax, [ebp+4]
+ mov (EFI_JUMP_BUFFER PTR [ecx])._eip, eax
+ mov eax, EFI_SUCCESS
+
+ ret
+
+TransferControlSetJump ENDP
+
+;
+; Routine Description:
+;
+; This routine implements the IA32 variant of the LongJump call. Its
+; responsibility is restore the system state to the Context Buffer and
+; pass control back.
+;
+; Arguments:
+;
+; Pointer to CPU context save buffer.
+;
+; Returns:
+;
+; EFI_WARN_RETURN_FROM_LONG_JUMP
+;
+
+TransferControlLongJump PROC C \
+ _This:PTR EFI_PEI_TRANSFER_CONTROL_PROTOCOL, \
+ Jump:PTR EFI_JUMP_BUFFER
+
+ push ebx
+ push esi
+ push edi
+
+ mov eax, _This
+ ; set return from SetJump to EFI_WARN_RETURN_FROM_LONG_JUMP
+ mov eax, EFI_WARN_RETURN_FROM_LONG_JUMP
+ mov ecx, Jump
+ mov ebx, (EFI_JUMP_BUFFER PTR [ecx])._ebx
+ mov esi, (EFI_JUMP_BUFFER PTR [ecx])._esi
+ mov edi, (EFI_JUMP_BUFFER PTR [ecx])._edi
+ mov ebp, (EFI_JUMP_BUFFER PTR [ecx])._ebp
+ mov esp, (EFI_JUMP_BUFFER PTR [ecx])._esp
+ add esp, 4 ;pop the eip
+ jmp DWORD PTR (EFI_JUMP_BUFFER PTR [ecx])._eip
+ mov eax, EFI_WARN_RETURN_FROM_LONG_JUMP
+
+ pop edi
+ pop esi
+ pop ebx
+ ret
+
+TransferControlLongJump ENDP
+
+;
+; Routine Description:
+; This allows the caller to switch the stack and goes to the new entry point
+;
+; Arguments:
+; EntryPoint - Pointer to the location to enter
+; Parameter - Parameter to pass in
+; NewStack - New Location of the stack
+; NewBsp - New BSP
+;
+; Returns:
+;
+; Nothing. Goes to the Entry Point passing in the new parameters
+;
+SwitchStacks PROC C \
+ EntryPoint:PTR DWORD, \
+ Parameter:DWORD, \
+ NewStack:PTR DWORD, \
+ NewBsp:PTR DWORD
+
+ push ebx
+ mov eax, NewBsp
+ mov ebx, Parameter
+ mov ecx, EntryPoint
+ mov eax, NewStack
+ mov esp, eax
+ push ebx
+ push 0
+ jmp ecx
+
+ pop ebx
+ ret
+
+SwitchStacks ENDP
+
+;
+; Routine Description:
+; This allows the caller to switch the stack and goes to the new entry point
+;
+; Arguments:
+; EntryPoint - Pointer to the location to enter
+; Parameter1/Parameter2 - Parameter to pass in
+; NewStack - New Location of the stack
+; NewBsp - New BSP
+;
+; Returns:
+;
+; Nothing. Goes to the Entry Point passing in the new parameters
+;
+SwitchIplStacks PROC C \
+ EntryPoint:PTR DWORD, \
+ Parameter1:DWORD, \
+ Parameter2:DWORD, \
+ NewStack:PTR DWORD, \
+ NewBsp:PTR DWORD
+
+ push ebx
+ mov eax, NewBsp
+ mov ebx, Parameter1
+ mov edx, Parameter2
+ mov ecx, EntryPoint
+ mov eax, NewStack
+ mov esp, eax
+
+ push edx
+ push ebx
+ call ecx
+
+ pop ebx
+ ret
+
+SwitchIplStacks ENDP
+
+ END
+
diff --git a/Core/CPU/IA32/SwitchCoreStacks.asm b/Core/CPU/IA32/SwitchCoreStacks.asm
new file mode 100644
index 0000000..dbb664d
--- /dev/null
+++ b/Core/CPU/IA32/SwitchCoreStacks.asm
@@ -0,0 +1,104 @@
+ TITLE SwitchCoreStacks.asm: Core stack switching routine
+
+;------------------------------------------------------------------------------
+;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:
+;
+; SwitchCoreStacks.asm
+;
+;Abstract:
+;
+; Core stack switching routine, invoked when real system memory is
+; discovered and installed.
+;
+;------------------------------------------------------------------------------
+
+ .686P
+ .XMM
+ .MODEL SMALL
+ .CODE
+
+
+include token.equ
+
+AsmWriteMm7 PROTO C
+
+AsmWriteMm7 PROC C
+;------------------------------------------------------------------------------
+; VOID
+; EFIAPI
+; AsmWriteMm7 (
+; IN UINT64 Value
+; );
+;------------------------------------------------------------------------------
+ movq mm7, [esp + 4]
+ ret
+AsmWriteMm7 ENDP
+
+IF MKF_PI_SPECIFICATION_VERSION GE 00010000h
+SwitchCoreStacks PROTO C EntryPoint: DWORD, Parameter1: DWORD, Parameter2: DWORD, Parameter3: DWORD, NewStack: DWORD
+
+SwitchCoreStacks PROC C EntryPoint: DWORD, Parameter1: DWORD, Parameter2: DWORD, Parameter3: DWORD, NewStack: DWORD
+ELSE
+SwitchCoreStacks PROTO C EntryPoint: DWORD, Parameter1: DWORD, Parameter2: DWORD, NewStack: DWORD
+
+SwitchCoreStacks PROC C EntryPoint: DWORD, Parameter1: DWORD, Parameter2: DWORD, NewStack: DWORD
+ENDIF
+
+;------------------------------------------------------------------------------
+; VOID
+; SwitchCoreStacks (
+; IN VOID *EntryPoint,
+; IN UINTN Parameter1,
+; IN UINTN Parameter2,
+; IN UINTN Parameter3,
+; IN VOID *NewStack
+; )
+;
+; Routine Description:
+;
+; Routine for PEI switching stacks.
+;
+; Arguments:
+;
+; EntryPoint - Entry point with new stack.
+; Parameter1 - First parameter for entry point.
+; Parameter2 - Second parameter for entry point.
+; Parameter3 - Third parameter for entry point.
+; NewStack - Pointer to new stack.
+;
+; Returns:
+;
+; None
+;
+;----------------------------------------------------
+
+ mov ebx, Parameter1
+ mov edx, Parameter2
+IF MKF_PI_SPECIFICATION_VERSION GE 00010000h
+ mov eax, Parameter3
+ENDIF
+ mov ecx, EntryPoint
+ mov esp, NewStack
+
+ ; First push Parameter3, and then Parameter2 ,at last Parameter1.
+IF MKF_PI_SPECIFICATION_VERSION GE 00010000h
+ push eax
+ENDIF
+ push edx
+ push ebx
+ call ecx
+
+ ret
+
+SwitchCoreStacks ENDP
+
+END
diff --git a/Core/CPU/IA32/efijump.h b/Core/CPU/IA32/efijump.h
new file mode 100644
index 0000000..d676f88
--- /dev/null
+++ b/Core/CPU/IA32/efijump.h
@@ -0,0 +1,34 @@
+/*++
+
+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:
+
+ EfiJump.h
+
+Abstract:
+
+ This is the Setjump/Longjump pair for an IA32 processor.
+
+--*/
+
+#ifndef _EFI_JUMP_H_
+#define _EFI_JUMP_H_
+
+typedef struct {
+ UINT32 ebx;
+ UINT32 esi;
+ UINT32 edi;
+ UINT32 ebp;
+ UINT32 esp;
+ UINT32 eip;
+} EFI_JUMP_BUFFER;
+
+#endif