diff options
author | raywu <raywu0301@gmail.com> | 2018-06-15 00:00:50 +0800 |
---|---|---|
committer | raywu <raywu0301@gmail.com> | 2018-06-15 00:00:50 +0800 |
commit | b7c51c9cf4864df6aabb99a1ae843becd577237c (patch) | |
tree | eebe9b0d0ca03062955223097e57da84dd618b9a /Core/CPU/IA32 | |
download | zprj-master.tar.xz |
Diffstat (limited to 'Core/CPU/IA32')
-rw-r--r-- | Core/CPU/IA32/AmiIa32Lib.cif | 12 | ||||
-rw-r--r-- | Core/CPU/IA32/AmiIa32Lib.mak | 67 | ||||
-rw-r--r-- | Core/CPU/IA32/AmiIa32Lib.sdl | 19 | ||||
-rw-r--r-- | Core/CPU/IA32/FoundationIa32.cif | 16 | ||||
-rw-r--r-- | Core/CPU/IA32/FoundationIa32.mak | 69 | ||||
-rw-r--r-- | Core/CPU/IA32/FoundationIa32.sdl | 19 | ||||
-rw-r--r-- | Core/CPU/IA32/IA32AsmLib/EnableLongMode.asm | 143 | ||||
-rw-r--r-- | Core/CPU/IA32/IA32AsmLib/EnableMachineCheck.asm | 78 | ||||
-rw-r--r-- | Core/CPU/IA32/IA32CLib.c | 1959 | ||||
-rw-r--r-- | Core/CPU/IA32/IA32Core.cif | 9 | ||||
-rw-r--r-- | Core/CPU/IA32/IA32Core.sdl | 33 | ||||
-rw-r--r-- | Core/CPU/IA32/IA32rules.mak | 62 | ||||
-rw-r--r-- | Core/CPU/IA32/PeCoffLoaderEx.c | 93 | ||||
-rw-r--r-- | Core/CPU/IA32/PeCoffLoaderEx.h | 85 | ||||
-rw-r--r-- | Core/CPU/IA32/Processor.c | 140 | ||||
-rw-r--r-- | Core/CPU/IA32/Processor.h | 27 | ||||
-rw-r--r-- | Core/CPU/IA32/ProcessorAsms.Asm | 223 | ||||
-rw-r--r-- | Core/CPU/IA32/SwitchCoreStacks.asm | 104 | ||||
-rw-r--r-- | Core/CPU/IA32/efijump.h | 34 |
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 |