summaryrefslogtreecommitdiffstats
path: root/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library')
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseCacheAsRamLibNull/BaseCacheAsRamLibNull.inf26
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseCacheAsRamLibNull/DisableCacheAsRamNull.c35
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseCacheLib/BaseCacheLib.inf29
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseCacheLib/CacheLib.c697
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseCacheLib/CacheLibInternal.h53
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseDebugDeviceLibNull/BaseDebugDeviceLibNull.inf29
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseDebugDeviceLibNull/DebugDeviceLibNull.c25
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseFspCommonLib/BaseFspCommonLib.inf30
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseFspCommonLib/FspCommonLib.c545
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/BaseFspDebugLibSerialPort.inf45
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/DebugLib.c415
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/Ia32/FspDebug.nasm25
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseFspPlatformLib/BaseFspPlatformLib.inf40
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseFspPlatformLib/FspPlatformMemory.c116
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseFspPlatformLib/FspPlatformNotify.c409
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/BaseFspSwitchStackLib.inf33
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/FspSwitchStackLib.c36
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/Ia32/Stack.nasm68
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/Flat32.nasm121
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/SecCarInit.nasm40
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/PlatformSecLibNull.c44
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/SecFspSecPlatformLibNull.inf51
22 files changed, 2912 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseCacheAsRamLibNull/BaseCacheAsRamLibNull.inf b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseCacheAsRamLibNull/BaseCacheAsRamLibNull.inf
new file mode 100644
index 00000000..2bfebf17
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseCacheAsRamLibNull/BaseCacheAsRamLibNull.inf
@@ -0,0 +1,26 @@
+## @file
+# NULL instance of Base cache as RAM.
+#
+# Copyright (c) 2014 - 2017, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = BaseCacheAsRamLibNull
+ FILE_GUID = 630AEB10-2106-4234-9DB3-836A3663F50D
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = CacheAsRamLib
+
+[Sources.common]
+ DisableCacheAsRamNull.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ IntelFsp2Pkg/IntelFsp2Pkg.dec
+
+[LibraryClasses]
+
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseCacheAsRamLibNull/DisableCacheAsRamNull.c b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseCacheAsRamLibNull/DisableCacheAsRamNull.c
new file mode 100644
index 00000000..5c8aa938
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseCacheAsRamLibNull/DisableCacheAsRamNull.c
@@ -0,0 +1,35 @@
+/** @file
+
+ Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/CacheAsRamLib.h>
+
+/**
+ This function disable CAR.
+
+ @param[in] DisableCar TRUE means use INVD, FALSE means use WBINVD
+
+**/
+VOID
+EFIAPI
+DisableCacheAsRam (
+ IN BOOLEAN DisableCar
+ )
+{
+ //
+ // Disable CAR
+ //
+
+ if (DisableCar) {
+ AsmInvd ();
+ } else {
+ AsmWbinvd();
+ }
+
+ return ;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseCacheLib/BaseCacheLib.inf b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseCacheLib/BaseCacheLib.inf
new file mode 100644
index 00000000..d0bcab04
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseCacheLib/BaseCacheLib.inf
@@ -0,0 +1,29 @@
+## @file
+# Instance of BaseCache.
+#
+# Copyright (c) 2014 - 2017, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = BaseCacheLib
+ FILE_GUID = 8EF3A653-DA8B-4FFA-BB85-FF47406DB9F0
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = CacheLib
+
+[Sources.IA32]
+ CacheLib.c
+ CacheLibInternal.h
+
+[Packages]
+ MdePkg/MdePkg.dec
+ IntelFsp2Pkg/IntelFsp2Pkg.dec
+
+[LibraryClasses]
+ BaseMemoryLib
+ CacheAsRamLib
+
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseCacheLib/CacheLib.c b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseCacheLib/CacheLib.c
new file mode 100644
index 00000000..503715f8
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseCacheLib/CacheLib.c
@@ -0,0 +1,697 @@
+/** @file
+
+ Copyright (c) 2014 - 2019, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/CacheLib.h>
+#include <Library/CacheAsRamLib.h>
+#include "CacheLibInternal.h"
+
+/**
+ Search the memory cache type for specific memory from MTRR.
+
+ @param[in] MemoryAddress the address of target memory
+ @param[in] MemoryLength the length of target memory
+ @param[in] ValidMtrrAddressMask the MTRR address mask
+ @param[out] UsedMsrNum the used MSR number
+ @param[out] UsedMemoryCacheType the cache type for the target memory
+
+ @retval EFI_SUCCESS The memory is found in MTRR and cache type is returned
+ @retval EFI_NOT_FOUND The memory is not found in MTRR
+
+**/
+EFI_STATUS
+SearchForExactMtrr (
+ IN EFI_PHYSICAL_ADDRESS MemoryAddress,
+ IN UINT64 MemoryLength,
+ IN UINT64 ValidMtrrAddressMask,
+ OUT UINT32 *UsedMsrNum,
+ OUT EFI_MEMORY_CACHE_TYPE *MemoryCacheType
+ );
+
+/**
+ Check if CacheType match current default setting.
+
+ @param[in] MemoryCacheType input cache type to be checked.
+
+ @retval TRUE MemoryCacheType is default MTRR setting.
+ @retval FALSE MemoryCacheType is NOT default MTRR setting.
+**/
+BOOLEAN
+IsDefaultType (
+ IN EFI_MEMORY_CACHE_TYPE MemoryCacheType
+ );
+
+/**
+ Return MTRR alignment requirement for base address and size.
+
+ @param[in] BaseAddress Base address.
+ @param[in] Size Size.
+
+ @retval Zero Aligned.
+ @retval Non-Zero Not aligned.
+
+**/
+UINT32
+CheckMtrrAlignment (
+ IN UINT64 BaseAddress,
+ IN UINT64 Size
+ );
+
+typedef struct {
+ UINT32 Msr;
+ UINT32 BaseAddress;
+ UINT32 Length;
+} EFI_FIXED_MTRR;
+
+EFI_FIXED_MTRR mFixedMtrrTable[] = {
+ { EFI_MSR_IA32_MTRR_FIX64K_00000, 0, 0x10000},
+ { EFI_MSR_IA32_MTRR_FIX16K_80000, 0x80000, 0x4000},
+ { EFI_MSR_IA32_MTRR_FIX16K_A0000, 0xA0000, 0x4000},
+ { EFI_MSR_IA32_MTRR_FIX4K_C0000, 0xC0000, 0x1000},
+ { EFI_MSR_IA32_MTRR_FIX4K_C8000, 0xC8000, 0x1000},
+ { EFI_MSR_IA32_MTRR_FIX4K_D0000, 0xD0000, 0x1000},
+ { EFI_MSR_IA32_MTRR_FIX4K_D8000, 0xD8000, 0x1000},
+ { EFI_MSR_IA32_MTRR_FIX4K_E0000, 0xE0000, 0x1000},
+ { EFI_MSR_IA32_MTRR_FIX4K_E8000, 0xE8000, 0x1000},
+ { EFI_MSR_IA32_MTRR_FIX4K_F0000, 0xF0000, 0x1000},
+ { EFI_MSR_IA32_MTRR_FIX4K_F8000, 0xF8000, 0x1000}
+};
+
+/**
+ Given the input, check if the number of MTRR is lesser.
+ if positive or subtractive.
+
+ @param[in] Input Length of Memory to program MTRR.
+
+ @retval Zero do positive.
+ @retval Non-Zero do subtractive.
+
+**/
+INT8
+CheckDirection (
+ IN UINT64 Input
+ )
+{
+ return 0;
+}
+
+/**
+ Disable cache and its mtrr.
+
+ @param[out] OldMtrr To return the Old MTRR value
+
+**/
+VOID
+EfiDisableCacheMtrr (
+ OUT UINT64 *OldMtrr
+ )
+{
+ UINT64 TempQword;
+
+ //
+ // Disable Cache MTRR
+ //
+ *OldMtrr = AsmReadMsr64(EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE);
+ TempQword = (*OldMtrr) & ~B_EFI_MSR_GLOBAL_MTRR_ENABLE & ~B_EFI_MSR_FIXED_MTRR_ENABLE;
+ AsmWriteMsr64(EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE, TempQword);
+ AsmDisableCache ();
+}
+
+/**
+ Recover cache MTRR.
+
+ @param[in] EnableMtrr Whether to enable the MTRR
+ @param[in] OldMtrr The saved old MTRR value to restore when not to enable the MTRR
+
+**/
+VOID
+EfiRecoverCacheMtrr (
+ IN BOOLEAN EnableMtrr,
+ IN UINT64 OldMtrr
+ )
+{
+ UINT64 TempQword;
+
+ //
+ // Enable Cache MTRR
+ //
+ if (EnableMtrr) {
+ TempQword = AsmReadMsr64(EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE);
+ TempQword |= (UINT64)(B_EFI_MSR_GLOBAL_MTRR_ENABLE | B_EFI_MSR_FIXED_MTRR_ENABLE);
+ } else {
+ TempQword = OldMtrr;
+ }
+
+ AsmWriteMsr64 (EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE, TempQword);
+
+ AsmEnableCache ();
+}
+
+/**
+ Programming MTRR according to Memory address, length, and type.
+
+ @param[in] MtrrNumber the variable MTRR index number
+ @param[in] MemoryAddress the address of target memory
+ @param[in] MemoryLength the length of target memory
+ @param[in] MemoryCacheType the cache type of target memory
+ @param[in] ValidMtrrAddressMask the MTRR address mask
+
+**/
+VOID
+EfiProgramMtrr (
+ IN UINTN MtrrNumber,
+ IN EFI_PHYSICAL_ADDRESS MemoryAddress,
+ IN UINT64 MemoryLength,
+ IN EFI_MEMORY_CACHE_TYPE MemoryCacheType,
+ IN UINT64 ValidMtrrAddressMask
+ )
+{
+ UINT64 TempQword;
+ UINT64 OldMtrr;
+
+ if (MemoryLength == 0) {
+ return;
+ }
+
+ EfiDisableCacheMtrr (&OldMtrr);
+
+ //
+ // MTRR Physical Base
+ //
+ TempQword = (MemoryAddress & ValidMtrrAddressMask) | MemoryCacheType;
+ AsmWriteMsr64 (MtrrNumber, TempQword);
+
+ //
+ // MTRR Physical Mask
+ //
+ TempQword = ~(MemoryLength - 1);
+ AsmWriteMsr64 (MtrrNumber + 1, (TempQword & ValidMtrrAddressMask) | B_EFI_MSR_CACHE_MTRR_VALID);
+
+ EfiRecoverCacheMtrr (TRUE, OldMtrr);
+}
+
+/**
+ Calculate the maximum value which is a power of 2, but less the MemoryLength.
+
+ @param[in] MemoryAddress Memory address.
+ @param[in] MemoryLength The number to pass in.
+
+ @return The maximum value which is align to power of 2 and less the MemoryLength
+
+**/
+UINT64
+Power2MaxMemory (
+ IN UINT64 MemoryAddress,
+ IN UINT64 MemoryLength
+ )
+{
+ UINT64 Result;
+
+ if (MemoryLength == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Compute initial power of 2 size to return
+ //
+ Result = GetPowerOfTwo64(MemoryLength);
+
+ //
+ // Special case base of 0 as all ranges are valid
+ //
+ if (MemoryAddress == 0) {
+ return Result;
+ }
+
+ //
+ // Loop till a value that can be mapped to this base address is found
+ //
+ while (CheckMtrrAlignment (MemoryAddress, Result) != 0) {
+ //
+ // Need to try the next smaller power of 2
+ //
+ Result = RShiftU64 (Result, 1);
+ }
+
+ return Result;
+}
+
+/**
+ Return MTRR alignment requirement for base address and size.
+
+ @param[in] BaseAddress Base address.
+ @param[in] Size Size.
+
+ @retval Zero Aligned.
+ @retval Non-Zero Not aligned.
+
+**/
+UINT32
+CheckMtrrAlignment (
+ IN UINT64 BaseAddress,
+ IN UINT64 Size
+ )
+{
+ UINT32 ShiftedBase;
+ UINT32 ShiftedSize;
+
+ //
+ // Shift base and size right 12 bits to allow for larger memory sizes. The
+ // MTRRs do not use the first 12 bits so this is safe for now. Only supports
+ // up to 52 bits of physical address space.
+ //
+ ShiftedBase = (UINT32) RShiftU64 (BaseAddress, 12);
+ ShiftedSize = (UINT32) RShiftU64 (Size, 12);
+
+ //
+ // Return the results to the caller of the MOD
+ //
+ return ShiftedBase % ShiftedSize;
+}
+
+/**
+ Programs fixed MTRRs registers.
+
+ @param[in] MemoryCacheType The memory type to set.
+ @param[in] Base The base address of memory range.
+ @param[in] Length The length of memory range.
+
+ @retval RETURN_SUCCESS The cache type was updated successfully
+ @retval RETURN_UNSUPPORTED The requested range or cache type was invalid
+ for the fixed MTRRs.
+
+**/
+EFI_STATUS
+ProgramFixedMtrr (
+ IN EFI_MEMORY_CACHE_TYPE MemoryCacheType,
+ IN UINT64 *Base,
+ IN UINT64 *Len
+ )
+{
+ UINT32 MsrNum;
+ UINT32 ByteShift;
+ UINT64 TempQword;
+ UINT64 OrMask;
+ UINT64 ClearMask;
+
+ TempQword = 0;
+ OrMask = 0;
+ ClearMask = 0;
+
+ for (MsrNum = 0; MsrNum < V_EFI_FIXED_MTRR_NUMBER; MsrNum++) {
+ if ((*Base >= mFixedMtrrTable[MsrNum].BaseAddress) &&
+ (*Base < (mFixedMtrrTable[MsrNum].BaseAddress + 8 * mFixedMtrrTable[MsrNum].Length))) {
+ break;
+ }
+ }
+ if (MsrNum == V_EFI_FIXED_MTRR_NUMBER ) {
+ return EFI_DEVICE_ERROR;
+ }
+ //
+ // We found the fixed MTRR to be programmed
+ //
+ for (ByteShift=0; ByteShift < 8; ByteShift++) {
+ if ( *Base == (mFixedMtrrTable[MsrNum].BaseAddress + ByteShift * mFixedMtrrTable[MsrNum].Length)) {
+ break;
+ }
+ }
+ if (ByteShift == 8 ) {
+ return EFI_DEVICE_ERROR;
+ }
+ for (; ((ByteShift<8) && (*Len >= mFixedMtrrTable[MsrNum].Length));ByteShift++) {
+ OrMask |= LShiftU64((UINT64) MemoryCacheType, (UINT32) (ByteShift* 8));
+ ClearMask |= LShiftU64((UINT64) 0xFF, (UINT32) (ByteShift * 8));
+ *Len -= mFixedMtrrTable[MsrNum].Length;
+ *Base += mFixedMtrrTable[MsrNum].Length;
+ }
+ TempQword = (AsmReadMsr64 (mFixedMtrrTable[MsrNum].Msr) & (~ClearMask)) | OrMask;
+ AsmWriteMsr64 (mFixedMtrrTable[MsrNum].Msr, TempQword);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Check if there is a valid variable MTRR that overlaps the given range.
+
+ @param[in] Start Base Address of the range to check.
+ @param[in] End End address of the range to check.
+
+ @retval TRUE Mtrr overlap.
+ @retval FALSE Mtrr not overlap.
+**/
+BOOLEAN
+CheckMtrrOverlap (
+ IN EFI_PHYSICAL_ADDRESS Start,
+ IN EFI_PHYSICAL_ADDRESS End
+ )
+{
+ return FALSE;
+}
+
+/**
+ Given the memory range and cache type, programs the MTRRs.
+
+ @param[in] MemoryAddress Base Address of Memory to program MTRR.
+ @param[in] MemoryLength Length of Memory to program MTRR.
+ @param[in] MemoryCacheType Cache Type.
+
+ @retval EFI_SUCCESS Mtrr are set successfully.
+ @retval EFI_LOAD_ERROR No empty MTRRs to use.
+ @retval EFI_INVALID_PARAMETER The input parameter is not valid.
+ @retval others An error occurs when setting MTTR.
+
+**/
+EFI_STATUS
+EFIAPI
+SetCacheAttributes (
+ IN EFI_PHYSICAL_ADDRESS MemoryAddress,
+ IN UINT64 MemoryLength,
+ IN EFI_MEMORY_CACHE_TYPE MemoryCacheType
+ )
+{
+ EFI_STATUS Status;
+ UINT32 MsrNum, MsrNumEnd;
+ UINT64 TempQword;
+ UINT32 LastVariableMtrrForBios;
+ UINT64 OldMtrr;
+ UINT32 UsedMsrNum;
+ EFI_MEMORY_CACHE_TYPE UsedMemoryCacheType;
+ UINT64 ValidMtrrAddressMask;
+ UINT32 Cpuid_RegEax;
+
+ AsmCpuid (CPUID_EXTENDED_FUNCTION, &Cpuid_RegEax, NULL, NULL, NULL);
+ if (Cpuid_RegEax >= CPUID_VIR_PHY_ADDRESS_SIZE) {
+ AsmCpuid (CPUID_VIR_PHY_ADDRESS_SIZE, &Cpuid_RegEax, NULL, NULL, NULL);
+ ValidMtrrAddressMask = (LShiftU64((UINT64) 1, (Cpuid_RegEax & 0xFF)) - 1) & (~(UINT64)0x0FFF);
+ } else {
+ ValidMtrrAddressMask = (LShiftU64((UINT64) 1, 36) - 1) & (~(UINT64)0x0FFF);
+ }
+
+ //
+ // Check for invalid parameter
+ //
+ if ((MemoryAddress & ~ValidMtrrAddressMask) != 0 || (MemoryLength & ~ValidMtrrAddressMask) != 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (MemoryLength == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ switch (MemoryCacheType) {
+ case EFI_CACHE_UNCACHEABLE:
+ case EFI_CACHE_WRITECOMBINING:
+ case EFI_CACHE_WRITETHROUGH:
+ case EFI_CACHE_WRITEPROTECTED:
+ case EFI_CACHE_WRITEBACK:
+ break;
+
+ default:
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Check if Fixed MTRR
+ //
+ if ((MemoryAddress + MemoryLength) <= (1 << 20)) {
+ Status = EFI_SUCCESS;
+ EfiDisableCacheMtrr (&OldMtrr);
+ while ((MemoryLength > 0) && (Status == EFI_SUCCESS)) {
+ Status = ProgramFixedMtrr (MemoryCacheType, &MemoryAddress, &MemoryLength);
+ }
+ EfiRecoverCacheMtrr (TRUE, OldMtrr);
+ return Status;
+ }
+
+ //
+ // Search if the range attribute has been set before
+ //
+ Status = SearchForExactMtrr(
+ MemoryAddress,
+ MemoryLength,
+ ValidMtrrAddressMask,
+ &UsedMsrNum,
+ &UsedMemoryCacheType
+ );
+
+ if (!EFI_ERROR(Status)) {
+ //
+ // Compare if it has the same type as current setting
+ //
+ if (UsedMemoryCacheType == MemoryCacheType) {
+ return EFI_SUCCESS;
+ } else {
+ //
+ // Different type
+ //
+
+ //
+ // Check if the set type is the same as Default Type
+ //
+ if (IsDefaultType(MemoryCacheType)) {
+ //
+ // Clear the MTRR
+ //
+ AsmWriteMsr64(UsedMsrNum, 0);
+ AsmWriteMsr64(UsedMsrNum + 1, 0);
+
+ return EFI_SUCCESS;
+ } else {
+ //
+ // Modify the MTRR type
+ //
+ EfiProgramMtrr(UsedMsrNum,
+ MemoryAddress,
+ MemoryLength,
+ MemoryCacheType,
+ ValidMtrrAddressMask
+ );
+ return EFI_SUCCESS;
+ }
+ }
+ }
+
+#if 0
+ //
+ // @bug - Need to create memory map so that when checking for overlap we
+ // can determine if an overlap exists based on all caching requests.
+ //
+ // Don't waste a variable MTRR if the caching attrib is same as default in MTRR_DEF_TYPE
+ //
+ if (MemoryCacheType == (AsmReadMsr64(EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE) & B_EFI_MSR_CACHE_MEMORY_TYPE)) {
+ if (!CheckMtrrOverlap (MemoryAddress, MemoryAddress+MemoryLength-1)) {
+ return EFI_SUCCESS;
+ }
+ }
+#endif
+
+ //
+ // Find first unused MTRR
+ //
+ MsrNumEnd = EFI_MSR_CACHE_VARIABLE_MTRR_BASE + (2 * (UINT32)(AsmReadMsr64(EFI_MSR_IA32_MTRR_CAP) & B_EFI_MSR_IA32_MTRR_CAP_VARIABLE_SUPPORT));
+ for (MsrNum = EFI_MSR_CACHE_VARIABLE_MTRR_BASE; MsrNum < MsrNumEnd; MsrNum +=2) {
+ if ((AsmReadMsr64(MsrNum+1) & B_EFI_MSR_CACHE_MTRR_VALID) == 0 ) {
+ break;
+ }
+ }
+
+ //
+ // Reserve 1 MTRR pair for OS.
+ //
+ LastVariableMtrrForBios = MsrNumEnd - 1 - (EFI_CACHE_NUM_VAR_MTRR_PAIRS_FOR_OS * 2);
+ if (MsrNum > LastVariableMtrrForBios) {
+ return EFI_LOAD_ERROR;
+ }
+
+ //
+ // Special case for 1 MB base address
+ //
+ if (MemoryAddress == BASE_1MB) {
+ MemoryAddress = 0;
+ }
+
+ //
+ // Program MTRRs
+ //
+ TempQword = MemoryLength;
+
+ if (TempQword == Power2MaxMemory(MemoryAddress, TempQword)) {
+ EfiProgramMtrr(MsrNum,
+ MemoryAddress,
+ MemoryLength,
+ MemoryCacheType,
+ ValidMtrrAddressMask
+ );
+
+ } else {
+ //
+ // Fill in MTRRs with values. Direction can not be checked for this method
+ // as we are using WB as the default cache type and only setting areas to UC.
+ //
+ do {
+ //
+ // Do boundary check so we don't go past last MTRR register
+ // for BIOS use. Leave one MTRR pair for OS use.
+ //
+ if (MsrNum > LastVariableMtrrForBios) {
+ return EFI_LOAD_ERROR;
+ }
+
+ //
+ // Set next power of 2 region
+ //
+ MemoryLength = Power2MaxMemory(MemoryAddress, TempQword);
+ EfiProgramMtrr(MsrNum,
+ MemoryAddress,
+ MemoryLength,
+ MemoryCacheType,
+ ValidMtrrAddressMask
+ );
+ MemoryAddress += MemoryLength;
+ TempQword -= MemoryLength;
+ MsrNum += 2;
+ } while (TempQword != 0);
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Reset all the MTRRs to a known state.
+
+ @retval EFI_SUCCESS All MTRRs have been reset successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+ResetCacheAttributes (
+ VOID
+ )
+{
+ UINT32 MsrNum, MsrNumEnd;
+ UINT16 Index;
+ UINT64 OldMtrr;
+ UINT64 CacheType;
+ BOOLEAN DisableCar;
+ Index = 0;
+ DisableCar = TRUE;
+
+ //
+ // Determine default cache type
+ //
+ CacheType = EFI_CACHE_UNCACHEABLE;
+
+ //
+ // Set default cache type
+ //
+ AsmWriteMsr64(EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE, CacheType);
+
+ //
+ // Disable CAR
+ //
+ DisableCacheAsRam (DisableCar);
+
+ EfiDisableCacheMtrr (&OldMtrr);
+
+ //
+ // Reset Fixed MTRRs
+ //
+ for (Index = 0; Index < V_EFI_FIXED_MTRR_NUMBER; Index++) {
+ AsmWriteMsr64 (mFixedMtrrTable[Index].Msr, 0);
+ }
+
+ //
+ // Reset Variable MTRRs
+ //
+ MsrNumEnd = EFI_MSR_CACHE_VARIABLE_MTRR_BASE + (2 * (UINT32)(AsmReadMsr64(EFI_MSR_IA32_MTRR_CAP) & B_EFI_MSR_IA32_MTRR_CAP_VARIABLE_SUPPORT));
+ for (MsrNum = EFI_MSR_CACHE_VARIABLE_MTRR_BASE; MsrNum < MsrNumEnd; MsrNum++) {
+ AsmWriteMsr64 (MsrNum, 0);
+ }
+
+ //
+ // Enable Fixed and Variable MTRRs
+ //
+ EfiRecoverCacheMtrr (TRUE, OldMtrr);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Search the memory cache type for specific memory from MTRR.
+
+ @param[in] MemoryAddress the address of target memory
+ @param[in] MemoryLength the length of target memory
+ @param[in] ValidMtrrAddressMask the MTRR address mask
+ @param[out] UsedMsrNum the used MSR number
+ @param[out] UsedMemoryCacheType the cache type for the target memory
+
+ @retval EFI_SUCCESS The memory is found in MTRR and cache type is returned
+ @retval EFI_NOT_FOUND The memory is not found in MTRR
+
+**/
+EFI_STATUS
+SearchForExactMtrr (
+ IN EFI_PHYSICAL_ADDRESS MemoryAddress,
+ IN UINT64 MemoryLength,
+ IN UINT64 ValidMtrrAddressMask,
+ OUT UINT32 *UsedMsrNum,
+ OUT EFI_MEMORY_CACHE_TYPE *UsedMemoryCacheType
+ )
+{
+ UINT32 MsrNum, MsrNumEnd;
+ UINT64 TempQword;
+
+ if (MemoryLength == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ MsrNumEnd = EFI_MSR_CACHE_VARIABLE_MTRR_BASE + (2 * (UINT32)(AsmReadMsr64(EFI_MSR_IA32_MTRR_CAP) & B_EFI_MSR_IA32_MTRR_CAP_VARIABLE_SUPPORT));
+ for (MsrNum = EFI_MSR_CACHE_VARIABLE_MTRR_BASE; MsrNum < MsrNumEnd; MsrNum +=2) {
+ TempQword = AsmReadMsr64(MsrNum+1);
+ if ((TempQword & B_EFI_MSR_CACHE_MTRR_VALID) == 0) {
+ continue;
+ }
+
+ if ((TempQword & ValidMtrrAddressMask) != ((~(MemoryLength - 1)) & ValidMtrrAddressMask)) {
+ continue;
+ }
+
+ TempQword = AsmReadMsr64 (MsrNum);
+ if ((TempQword & ValidMtrrAddressMask) != (MemoryAddress & ValidMtrrAddressMask)) {
+ continue;
+ }
+
+ *UsedMemoryCacheType = (EFI_MEMORY_CACHE_TYPE)(TempQword & B_EFI_MSR_CACHE_MEMORY_TYPE);
+ *UsedMsrNum = MsrNum;
+
+ return EFI_SUCCESS;
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+/**
+ Check if CacheType match current default setting.
+
+ @param[in] MemoryCacheType input cache type to be checked.
+
+ @retval TRUE MemoryCacheType is default MTRR setting.
+ @retval TRUE MemoryCacheType is NOT default MTRR setting.
+**/
+BOOLEAN
+IsDefaultType (
+ IN EFI_MEMORY_CACHE_TYPE MemoryCacheType
+ )
+{
+ if ((AsmReadMsr64(EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE) & B_EFI_MSR_CACHE_MEMORY_TYPE) != MemoryCacheType) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseCacheLib/CacheLibInternal.h b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseCacheLib/CacheLibInternal.h
new file mode 100644
index 00000000..2b82476d
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseCacheLib/CacheLibInternal.h
@@ -0,0 +1,53 @@
+/** @file
+
+ Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _CACHE_LIB_INTERNAL_H_
+#define _CACHE_LIB_INTERNAL_H_
+
+#define EFI_MSR_CACHE_VARIABLE_MTRR_BASE 0x00000200
+#define EFI_MSR_CACHE_VARIABLE_MTRR_END 0x0000020F
+#define V_EFI_FIXED_MTRR_NUMBER 11
+
+#define EFI_MSR_IA32_MTRR_FIX64K_00000 0x00000250
+#define EFI_MSR_IA32_MTRR_FIX16K_80000 0x00000258
+#define EFI_MSR_IA32_MTRR_FIX16K_A0000 0x00000259
+#define EFI_MSR_IA32_MTRR_FIX4K_C0000 0x00000268
+#define EFI_MSR_IA32_MTRR_FIX4K_C8000 0x00000269
+#define EFI_MSR_IA32_MTRR_FIX4K_D0000 0x0000026A
+#define EFI_MSR_IA32_MTRR_FIX4K_D8000 0x0000026B
+#define EFI_MSR_IA32_MTRR_FIX4K_E0000 0x0000026C
+#define EFI_MSR_IA32_MTRR_FIX4K_E8000 0x0000026D
+#define EFI_MSR_IA32_MTRR_FIX4K_F0000 0x0000026E
+#define EFI_MSR_IA32_MTRR_FIX4K_F8000 0x0000026F
+#define EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE 0x000002FF
+#define B_EFI_MSR_CACHE_MTRR_VALID BIT11
+#define B_EFI_MSR_GLOBAL_MTRR_ENABLE BIT11
+#define B_EFI_MSR_FIXED_MTRR_ENABLE BIT10
+#define B_EFI_MSR_CACHE_MEMORY_TYPE (BIT2 | BIT1 | BIT0)
+
+#define EFI_MSR_VALID_MASK 0xFFFFFFFFF
+#define EFI_CACHE_VALID_ADDRESS 0xFFFFFF000
+#define EFI_SMRR_CACHE_VALID_ADDRESS 0xFFFFF000
+#define EFI_CACHE_VALID_EXTENDED_ADDRESS 0xFFFFFFFFFF000
+
+// Leave one MTRR pairs for OS use
+#define EFI_CACHE_NUM_VAR_MTRR_PAIRS_FOR_OS 1
+#define EFI_CACHE_LAST_VARIABLE_MTRR_FOR_BIOS (EFI_MSR_CACHE_VARIABLE_MTRR_END) - \
+ (EFI_CACHE_NUM_VAR_MTRR_PAIRS_FOR_OS * 2)
+
+#define EFI_MSR_IA32_MTRR_CAP 0x000000FE
+#define B_EFI_MSR_IA32_MTRR_CAP_EMRR_SUPPORT BIT12
+#define B_EFI_MSR_IA32_MTRR_CAP_SMRR_SUPPORT BIT11
+#define B_EFI_MSR_IA32_MTRR_CAP_WC_SUPPORT BIT10
+#define B_EFI_MSR_IA32_MTRR_CAP_FIXED_SUPPORT BIT8
+#define B_EFI_MSR_IA32_MTRR_CAP_VARIABLE_SUPPORT (BIT7 | BIT6 | BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0)
+
+#define CPUID_VIR_PHY_ADDRESS_SIZE 0x80000008
+#define CPUID_EXTENDED_FUNCTION 0x80000000
+
+#endif
+
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseDebugDeviceLibNull/BaseDebugDeviceLibNull.inf b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseDebugDeviceLibNull/BaseDebugDeviceLibNull.inf
new file mode 100644
index 00000000..26e91e9d
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseDebugDeviceLibNull/BaseDebugDeviceLibNull.inf
@@ -0,0 +1,29 @@
+## @file
+# Debug device library instance that retrieves the current enabling state for
+# the platform debug output device.
+#
+# Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = BaseDebugDeviceLibNull
+ FILE_GUID = 5E975522-176F-4E2D-BB25-64ADCC7792A4
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = DebugDeviceLib
+
+#
+# VALID_ARCHITECTURES = IA32
+#
+
+[Sources]
+ DebugDeviceLibNull.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ IntelFsp2Pkg/IntelFsp2Pkg.dec
+
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseDebugDeviceLibNull/DebugDeviceLibNull.c b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseDebugDeviceLibNull/DebugDeviceLibNull.c
new file mode 100644
index 00000000..76c57320
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseDebugDeviceLibNull/DebugDeviceLibNull.c
@@ -0,0 +1,25 @@
+/** @file
+ Debug device library instance that retrieves the current enabling state for
+ the platform debug output device.
+
+ Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Base.h>
+
+/**
+ Returns the debug print device enable state.
+
+ @return Debug print device enable state.
+
+**/
+UINT8
+EFIAPI
+GetDebugPrintDeviceEnable (
+ VOID
+ )
+{
+ return 1;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseFspCommonLib/BaseFspCommonLib.inf b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseFspCommonLib/BaseFspCommonLib.inf
new file mode 100644
index 00000000..9c377ba8
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseFspCommonLib/BaseFspCommonLib.inf
@@ -0,0 +1,30 @@
+## @file
+# Instance of FspCommonLib
+# Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = BaseFspCommonLib
+ FILE_GUID = 38BE57E8-902C-485A-AB5E-D5AEC613194D
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = FspCommonLib
+
+[Sources]
+ FspCommonLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ IntelFsp2Pkg/IntelFsp2Pkg.dec
+
+[LibraryClasses]
+ BaseMemoryLib
+ FspSwitchStackLib
+
+[Pcd]
+ gIntelFsp2PkgTokenSpaceGuid.PcdGlobalDataPointerAddress ## CONSUMES
+
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseFspCommonLib/FspCommonLib.c b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseFspCommonLib/FspCommonLib.c
new file mode 100644
index 00000000..a0f54afe
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseFspCommonLib/FspCommonLib.c
@@ -0,0 +1,545 @@
+/** @file
+
+ Copyright (c) 2014 - 2019, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <FspGlobalData.h>
+#include <FspEas.h>
+#include <Library/FspSwitchStackLib.h>
+
+#pragma pack(1)
+
+//
+// API Parameter +0x34
+// API return address +0x30
+//
+// push FspInfoHeader +0x2C
+// pushfd +0x28
+// cli
+// pushad +0x24
+// sub esp, 8 +0x00
+// sidt fword ptr [esp]
+//
+typedef struct {
+ UINT16 IdtrLimit;
+ UINT32 IdtrBase;
+ UINT16 Reserved;
+ UINT32 Edi;
+ UINT32 Esi;
+ UINT32 Ebp;
+ UINT32 Esp;
+ UINT32 Ebx;
+ UINT32 Edx;
+ UINT32 Ecx;
+ UINT32 Eax;
+ UINT16 Flags[2];
+ UINT32 FspInfoHeader;
+ UINT32 ApiRet;
+ UINT32 ApiParam[2];
+} CONTEXT_STACK;
+
+#define CONTEXT_STACK_OFFSET(x) (UINT32)&((CONTEXT_STACK *)(UINTN)0)->x
+
+#pragma pack()
+
+/**
+ This function sets the FSP global data pointer.
+
+ @param[in] FspData FSP global data pointer.
+
+**/
+VOID
+EFIAPI
+SetFspGlobalDataPointer (
+ IN FSP_GLOBAL_DATA *FspData
+ )
+{
+ ASSERT (FspData != NULL);
+ *((volatile UINT32 *)(UINTN)PcdGet32(PcdGlobalDataPointerAddress)) = (UINT32)(UINTN)FspData;
+}
+
+/**
+ This function gets the FSP global data pointer.
+
+**/
+FSP_GLOBAL_DATA *
+EFIAPI
+GetFspGlobalDataPointer (
+ VOID
+ )
+{
+ FSP_GLOBAL_DATA *FspData;
+
+ FspData = *(FSP_GLOBAL_DATA **)(UINTN)PcdGet32(PcdGlobalDataPointerAddress);
+ return FspData;
+}
+
+/**
+ This function gets back the FSP API first parameter passed by the bootloader.
+
+ @retval ApiParameter FSP API first parameter passed by the bootloader.
+**/
+UINT32
+EFIAPI
+GetFspApiParameter (
+ VOID
+ )
+{
+ FSP_GLOBAL_DATA *FspData;
+
+ FspData = GetFspGlobalDataPointer ();
+ return *(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(ApiParam[0]));
+}
+
+/**
+ This function returns the FSP entry stack pointer from address of the first API parameter.
+
+ @retval FSP entry stack pointer.
+**/
+VOID*
+EFIAPI
+GetFspEntryStack (
+ VOID
+ )
+{
+ FSP_GLOBAL_DATA *FspData;
+
+ FspData = GetFspGlobalDataPointer ();
+ return (VOID*)(FspData->CoreStack + CONTEXT_STACK_OFFSET(ApiParam[0]));
+}
+
+/**
+ This function gets back the FSP API second parameter passed by the bootloader.
+
+ @retval ApiParameter FSP API second parameter passed by the bootloader.
+**/
+UINT32
+EFIAPI
+GetFspApiParameter2 (
+ VOID
+ )
+{
+ FSP_GLOBAL_DATA *FspData;
+
+ FspData = GetFspGlobalDataPointer ();
+ return *(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(ApiParam[1]));
+}
+
+/**
+ This function sets the FSP API parameter in the stack.
+
+ @param[in] Value New parameter value.
+
+**/
+VOID
+EFIAPI
+SetFspApiParameter (
+ IN UINT32 Value
+ )
+{
+ FSP_GLOBAL_DATA *FspData;
+
+ FspData = GetFspGlobalDataPointer ();
+ *(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(ApiParam)) = Value;
+}
+
+/**
+ This function set the API status code returned to the BootLoader.
+
+ @param[in] ReturnStatus Status code to return.
+
+**/
+VOID
+EFIAPI
+SetFspApiReturnStatus (
+ IN UINT32 ReturnStatus
+ )
+{
+ FSP_GLOBAL_DATA *FspData;
+
+ FspData = GetFspGlobalDataPointer ();
+ *(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(Eax)) = ReturnStatus;
+}
+
+/**
+ This function sets the context switching stack to a new stack frame.
+
+ @param[in] NewStackTop New core stack to be set.
+
+**/
+VOID
+EFIAPI
+SetFspCoreStackPointer (
+ IN VOID *NewStackTop
+ )
+{
+ FSP_GLOBAL_DATA *FspData;
+ UINT32 *OldStack;
+ UINT32 *NewStack;
+ UINT32 StackContextLen;
+
+ FspData = GetFspGlobalDataPointer ();
+ StackContextLen = sizeof(CONTEXT_STACK) / sizeof(UINT32);
+
+ //
+ // Reserve space for the ContinuationFunc two parameters
+ //
+ OldStack = (UINT32 *)FspData->CoreStack;
+ NewStack = (UINT32 *)NewStackTop - StackContextLen - 2;
+ FspData->CoreStack = (UINT32)NewStack;
+ while (StackContextLen-- != 0) {
+ *NewStack++ = *OldStack++;
+ }
+}
+
+/**
+ This function sets the platform specific data pointer.
+
+ @param[in] PlatformData FSP platform specific data pointer.
+
+**/
+VOID
+EFIAPI
+SetFspPlatformDataPointer (
+ IN VOID *PlatformData
+ )
+{
+ FSP_GLOBAL_DATA *FspData;
+
+ FspData = GetFspGlobalDataPointer ();
+ FspData->PlatformData.DataPtr = PlatformData;
+}
+
+
+/**
+ This function gets the platform specific data pointer.
+
+ @param[in] PlatformData FSP platform specific data pointer.
+
+**/
+VOID *
+EFIAPI
+GetFspPlatformDataPointer (
+ VOID
+ )
+{
+ FSP_GLOBAL_DATA *FspData;
+
+ FspData = GetFspGlobalDataPointer ();
+ return FspData->PlatformData.DataPtr;
+}
+
+
+/**
+ This function sets the UPD data pointer.
+
+ @param[in] UpdDataPtr UPD data pointer.
+**/
+VOID
+EFIAPI
+SetFspUpdDataPointer (
+ IN VOID *UpdDataPtr
+ )
+{
+ FSP_GLOBAL_DATA *FspData;
+
+ //
+ // Get the FSP Global Data Pointer
+ //
+ FspData = GetFspGlobalDataPointer ();
+
+ //
+ // Set the UPD pointer.
+ //
+ FspData->UpdDataPtr = UpdDataPtr;
+}
+
+/**
+ This function gets the UPD data pointer.
+
+ @return UpdDataPtr UPD data pointer.
+**/
+VOID *
+EFIAPI
+GetFspUpdDataPointer (
+ VOID
+ )
+{
+ FSP_GLOBAL_DATA *FspData;
+
+ FspData = GetFspGlobalDataPointer ();
+ return FspData->UpdDataPtr;
+}
+
+
+/**
+ This function sets the FspMemoryInit UPD data pointer.
+
+ @param[in] MemoryInitUpdPtr FspMemoryInit UPD data pointer.
+**/
+VOID
+EFIAPI
+SetFspMemoryInitUpdDataPointer (
+ IN VOID *MemoryInitUpdPtr
+ )
+{
+ FSP_GLOBAL_DATA *FspData;
+
+ //
+ // Get the FSP Global Data Pointer
+ //
+ FspData = GetFspGlobalDataPointer ();
+
+ //
+ // Set the FspMemoryInit UPD pointer.
+ //
+ FspData->MemoryInitUpdPtr = MemoryInitUpdPtr;
+}
+
+/**
+ This function gets the FspMemoryInit UPD data pointer.
+
+ @return FspMemoryInit UPD data pointer.
+**/
+VOID *
+EFIAPI
+GetFspMemoryInitUpdDataPointer (
+ VOID
+ )
+{
+ FSP_GLOBAL_DATA *FspData;
+
+ FspData = GetFspGlobalDataPointer ();
+ return FspData->MemoryInitUpdPtr;
+}
+
+
+/**
+ This function sets the FspSiliconInit UPD data pointer.
+
+ @param[in] SiliconInitUpdPtr FspSiliconInit UPD data pointer.
+**/
+VOID
+EFIAPI
+SetFspSiliconInitUpdDataPointer (
+ IN VOID *SiliconInitUpdPtr
+ )
+{
+ FSP_GLOBAL_DATA *FspData;
+
+ //
+ // Get the FSP Global Data Pointer
+ //
+ FspData = GetFspGlobalDataPointer ();
+
+ //
+ // Set the FspSiliconInit UPD data pointer.
+ //
+ FspData->SiliconInitUpdPtr = SiliconInitUpdPtr;
+}
+
+/**
+ This function gets the FspSiliconInit UPD data pointer.
+
+ @return FspSiliconInit UPD data pointer.
+**/
+VOID *
+EFIAPI
+GetFspSiliconInitUpdDataPointer (
+ VOID
+ )
+{
+ FSP_GLOBAL_DATA *FspData;
+
+ FspData = GetFspGlobalDataPointer ();
+ return FspData->SiliconInitUpdPtr;
+}
+
+
+/**
+ Set FSP measurement point timestamp.
+
+ @param[in] Id Measurement point ID.
+
+ @return performance timestamp.
+**/
+UINT64
+EFIAPI
+SetFspMeasurePoint (
+ IN UINT8 Id
+ )
+{
+ FSP_GLOBAL_DATA *FspData;
+
+ //
+ // Bit [55: 0] will be the timestamp
+ // Bit [63:56] will be the ID
+ //
+ FspData = GetFspGlobalDataPointer ();
+ if (FspData->PerfIdx < sizeof(FspData->PerfData) / sizeof(FspData->PerfData[0])) {
+ FspData->PerfData[FspData->PerfIdx] = AsmReadTsc ();
+ ((UINT8 *)(&FspData->PerfData[FspData->PerfIdx]))[7] = Id;
+ }
+
+ return FspData->PerfData[(FspData->PerfIdx)++];
+}
+
+/**
+ This function gets the FSP info header pointer.
+
+ @retval FspInfoHeader FSP info header pointer
+**/
+FSP_INFO_HEADER *
+EFIAPI
+GetFspInfoHeader (
+ VOID
+ )
+{
+ return GetFspGlobalDataPointer()->FspInfoHeader;
+}
+
+/**
+ This function sets the FSP info header pointer.
+
+ @param[in] FspInfoHeader FSP info header pointer
+**/
+VOID
+EFIAPI
+SetFspInfoHeader (
+ FSP_INFO_HEADER *FspInfoHeader
+ )
+{
+ GetFspGlobalDataPointer()->FspInfoHeader = FspInfoHeader;
+}
+
+/**
+ This function gets the FSP info header pointer using the API stack context.
+
+ @retval FspInfoHeader FSP info header pointer using the API stack context
+**/
+FSP_INFO_HEADER *
+EFIAPI
+GetFspInfoHeaderFromApiContext (
+ VOID
+ )
+{
+ FSP_GLOBAL_DATA *FspData;
+
+ FspData = GetFspGlobalDataPointer ();
+ return (FSP_INFO_HEADER *)(*(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(FspInfoHeader)));
+}
+
+/**
+ This function gets the CfgRegion data pointer.
+
+ @return CfgRegion data pointer.
+**/
+VOID *
+EFIAPI
+GetFspCfgRegionDataPointer (
+ VOID
+ )
+{
+ FSP_INFO_HEADER *FspInfoHeader;
+
+ FspInfoHeader = GetFspInfoHeader ();
+ return (VOID *)(FspInfoHeader->ImageBase + FspInfoHeader->CfgRegionOffset);
+}
+
+/**
+ This function gets FSP API calling index.
+
+ @retval API calling index
+**/
+UINT8
+EFIAPI
+GetFspApiCallingIndex (
+ VOID
+ )
+{
+ return GetFspGlobalDataPointer()->ApiIdx;
+}
+
+/**
+ This function sets FSP API calling mode.
+
+ @param[in] Index API calling index
+**/
+VOID
+EFIAPI
+SetFspApiCallingIndex (
+ UINT8 Index
+ )
+{
+ FSP_GLOBAL_DATA *FspData;
+
+ FspData = GetFspGlobalDataPointer ();
+ FspData->ApiIdx = Index;
+}
+
+/**
+ This function gets FSP Phase StatusCode.
+
+ @retval StatusCode
+**/
+UINT32
+EFIAPI
+GetPhaseStatusCode (
+ VOID
+ )
+{
+ return GetFspGlobalDataPointer()->StatusCode;
+}
+
+/**
+ This function sets FSP Phase StatusCode.
+
+ @param[in] Mode Phase StatusCode
+**/
+VOID
+EFIAPI
+SetPhaseStatusCode (
+ UINT32 StatusCode
+ )
+{
+ FSP_GLOBAL_DATA *FspData;
+
+ FspData = GetFspGlobalDataPointer ();
+ FspData->StatusCode = StatusCode;
+}
+
+/**
+ This function updates the return status of the FSP API with requested reset type and returns to Boot Loader.
+
+ @param[in] FspResetType Reset type that needs to returned as API return status
+
+**/
+VOID
+EFIAPI
+FspApiReturnStatusReset (
+ IN UINT32 FspResetType
+ )
+{
+ volatile BOOLEAN LoopUntilReset;
+
+ LoopUntilReset = TRUE;
+ DEBUG ((DEBUG_INFO, "FSP returning control to Bootloader with reset required return status %x\n",FspResetType));
+ if (GetFspGlobalDataPointer ()->FspMode == FSP_IN_API_MODE) {
+ ///
+ /// Below code is not an infinite loop.The control will go back to API calling function in BootLoader each time BootLoader
+ /// calls the FSP API without honoring the reset request by FSP
+ ///
+ do {
+ SetFspApiReturnStatus ((EFI_STATUS)FspResetType);
+ Pei2LoaderSwitchStack ();
+ DEBUG ((DEBUG_ERROR, "!!!ERROR: FSP has requested BootLoader for reset. But BootLoader has not honored the reset\n"));
+ DEBUG ((DEBUG_ERROR, "!!!ERROR: Please add support in BootLoader to honor the reset request from FSP\n"));
+ } while (LoopUntilReset);
+ }
+}
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/BaseFspDebugLibSerialPort.inf b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/BaseFspDebugLibSerialPort.inf
new file mode 100644
index 00000000..a90f01a4
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/BaseFspDebugLibSerialPort.inf
@@ -0,0 +1,45 @@
+## @file
+# Instance of BaseFspDebugLib
+#
+# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = BaseFspDebugLibSerialPort
+ FILE_GUID = CEA4FF9C-D7BC-4F07-96F1-03F41F2B17AE
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = DebugLib
+
+#
+# VALID_ARCHITECTURES = IA32
+#
+
+[Sources]
+ DebugLib.c
+
+[Sources.Ia32]
+ Ia32/FspDebug.nasm
+
+[Packages]
+ MdePkg/MdePkg.dec
+ IntelFsp2Pkg/IntelFsp2Pkg.dec
+
+[LibraryClasses]
+ SerialPortLib
+ BaseMemoryLib
+ PcdLib
+ PrintLib
+ BaseLib
+ DebugDeviceLib
+ DebugPrintErrorLevelLib
+
+[Pcd]
+ gEfiMdePkgTokenSpaceGuid.PcdDebugClearMemoryValue ## CONSUMES
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask ## CONSUMES
+ gEfiMdePkgTokenSpaceGuid.PcdFixedDebugPrintErrorLevel ## CONSUMES
+
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/DebugLib.c b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/DebugLib.c
new file mode 100644
index 00000000..5c34a6b8
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/DebugLib.c
@@ -0,0 +1,415 @@
+/** @file
+
+ Copyright (c) 2014 - 2019, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Base.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PrintLib.h>
+#include <Library/PcdLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/SerialPortLib.h>
+#include <Library/DebugDeviceLib.h>
+#include <Library/DebugPrintErrorLevelLib.h>
+
+//
+// Define the maximum debug and assert message length that this library supports
+//
+#define MAX_DEBUG_MESSAGE_LENGTH 0x100
+
+CONST CHAR8 *mHexTable = "0123456789ABCDEF";
+
+//
+// VA_LIST can not initialize to NULL for all compiler, so we use this to
+// indicate a null VA_LIST
+//
+VA_LIST mVaListNull;
+
+/**
+ Get stack frame pointer of function call.
+
+ @return StackFramePointer stack frame pointer of function call.
+**/
+UINT32 *
+EFIAPI
+GetStackFramePointer (
+ VOID
+ );
+
+
+/**
+ Prints a debug message to the debug output device if the specified error level is enabled.
+
+ If any bit in ErrorLevel is also set in DebugPrintErrorLevelLib function
+ GetDebugPrintErrorLevel (), then print the message specified by Format and the
+ associated variable argument list to the debug output device.
+
+ If Format is NULL, then ASSERT().
+
+ @param ErrorLevel The error level of the debug message.
+ @param Format Format string for the debug message to print.
+ @param ... Variable argument list whose contents are accessed
+ based on the format string specified by Format.
+
+**/
+VOID
+EFIAPI
+DebugPrint (
+ IN UINTN ErrorLevel,
+ IN CONST CHAR8 *Format,
+ ...
+ )
+{
+ VA_LIST Marker;
+
+ VA_START (Marker, Format);
+ DebugVPrint (ErrorLevel, Format, Marker);
+ VA_END (Marker);
+}
+
+/**
+ Prints a debug message to the debug output device if the specified
+ error level is enabled base on Null-terminated format string and a
+ VA_LIST argument list or a BASE_LIST argument list.
+
+ If any bit in ErrorLevel is also set in DebugPrintErrorLevelLib function
+ GetDebugPrintErrorLevel (), then print the message specified by Format and
+ the associated variable argument list to the debug output device.
+
+ If Format is NULL, then ASSERT().
+
+ @param ErrorLevel The error level of the debug message.
+ @param Format Format string for the debug message to print.
+ @param VaListMarker VA_LIST marker for the variable argument list.
+ @param BaseListMarker BASE_LIST marker for the variable argument list.
+
+**/
+VOID
+DebugPrintMarker (
+ IN UINTN ErrorLevel,
+ IN CONST CHAR8 *Format,
+ IN VA_LIST VaListMarker,
+ IN BASE_LIST BaseListMarker
+ )
+{
+ CHAR8 Buffer[MAX_DEBUG_MESSAGE_LENGTH];
+
+ //
+ // If Format is NULL, then ASSERT().
+ //
+ if (!GetDebugPrintDeviceEnable ()) {
+ return;
+ }
+
+ //
+ // Check driver debug mask value and global mask
+ //
+ if ((ErrorLevel & GetDebugPrintErrorLevel ()) == 0) {
+ return;
+ }
+
+ //
+ // If Format is NULL, then ASSERT().
+ //
+ ASSERT (Format != NULL);
+
+ //
+ // Convert the DEBUG() message to an ASCII String
+ //
+ if (BaseListMarker == NULL) {
+ AsciiVSPrint (Buffer, sizeof (Buffer), Format, VaListMarker);
+ } else {
+ AsciiBSPrint (Buffer, sizeof (Buffer), Format, BaseListMarker);
+ }
+
+ //
+ // Send the print string to a Serial Port
+ //
+ SerialPortWrite ((UINT8 *)Buffer, AsciiStrLen (Buffer));
+}
+
+/**
+ Prints a debug message to the debug output device if the specified
+ error level is enabled.
+
+ If any bit in ErrorLevel is also set in DebugPrintErrorLevelLib function
+ GetDebugPrintErrorLevel (), then print the message specified by Format and
+ the associated variable argument list to the debug output device.
+
+ If Format is NULL, then ASSERT().
+
+ @param ErrorLevel The error level of the debug message.
+ @param Format Format string for the debug message to print.
+ @param VaListMarker VA_LIST marker for the variable argument list.
+
+**/
+VOID
+EFIAPI
+DebugVPrint (
+ IN UINTN ErrorLevel,
+ IN CONST CHAR8 *Format,
+ IN VA_LIST VaListMarker
+ )
+{
+ DebugPrintMarker (ErrorLevel, Format, VaListMarker, NULL);
+}
+
+/**
+ Prints a debug message to the debug output device if the specified
+ error level is enabled.
+ This function use BASE_LIST which would provide a more compatible
+ service than VA_LIST.
+
+ If any bit in ErrorLevel is also set in DebugPrintErrorLevelLib function
+ GetDebugPrintErrorLevel (), then print the message specified by Format and
+ the associated variable argument list to the debug output device.
+
+ If Format is NULL, then ASSERT().
+
+ @param ErrorLevel The error level of the debug message.
+ @param Format Format string for the debug message to print.
+ @param BaseListMarker BASE_LIST marker for the variable argument list.
+
+**/
+VOID
+EFIAPI
+DebugBPrint (
+ IN UINTN ErrorLevel,
+ IN CONST CHAR8 *Format,
+ IN BASE_LIST BaseListMarker
+ )
+{
+ DebugPrintMarker (ErrorLevel, Format, mVaListNull, BaseListMarker);
+}
+
+/**
+ Convert an UINT32 value into HEX string specified by Buffer.
+
+ @param Value The HEX value to convert to string
+ @param Buffer The pointer to the target buffer to be filled with HEX string
+
+**/
+VOID
+FillHex (
+ UINT32 Value,
+ CHAR8 *Buffer
+ )
+{
+ INTN Idx;
+ for (Idx = 7; Idx >= 0; Idx--) {
+ Buffer[Idx] = mHexTable[Value & 0x0F];
+ Value >>= 4;
+ }
+}
+
+/**
+ Prints an assert message containing a filename, line number, and description.
+ This may be followed by a breakpoint or a dead loop.
+
+ Print a message of the form "ASSERT <FileName>(<LineNumber>): <Description>\n"
+ to the debug output device. If DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED bit of
+ PcdDebugPropertyMask is set then CpuBreakpoint() is called. Otherwise, if
+ DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED bit of PcdDebugPropertyMask is set then
+ CpuDeadLoop() is called. If neither of these bits are set, then this function
+ returns immediately after the message is printed to the debug output device.
+ DebugAssert() must actively prevent recursion. If DebugAssert() is called while
+ processing another DebugAssert(), then DebugAssert() must return immediately.
+
+ If FileName is NULL, then a <FileName> string of "(NULL) Filename" is printed.
+ If Description is NULL, then a <Description> string of "(NULL) Description" is printed.
+
+**/
+VOID
+DebugAssertInternal (
+ VOID
+ )
+{
+ CHAR8 Buffer[MAX_DEBUG_MESSAGE_LENGTH];
+ UINT32 *Frame;
+
+ Frame = (UINT32 *)GetStackFramePointer ();
+
+ //
+ // Generate the ASSERT() message in Ascii format
+ //
+ AsciiStrnCpyS (
+ Buffer,
+ sizeof(Buffer) / sizeof(CHAR8),
+ "-> EBP:0x00000000 EIP:0x00000000\n",
+ sizeof(Buffer) / sizeof(CHAR8) - 1
+ );
+ SerialPortWrite ((UINT8 *)"ASSERT DUMP:\n", 13);
+ while (Frame != NULL) {
+ FillHex ((UINT32)Frame, Buffer + 9);
+ FillHex (Frame[1], Buffer + 9 + 8 + 8);
+ SerialPortWrite ((UINT8 *)Buffer, AsciiStrLen (Buffer));
+ if ((Frame[0] > (UINT32)Frame) && (Frame[0] < (UINT32)Frame + 0x00100000)) {
+ Frame = (UINT32 *)Frame[0];
+ } else {
+ Frame = NULL;
+ }
+ }
+
+ //
+ // Dead loop
+ //
+ CpuDeadLoop ();
+}
+
+/**
+ Prints an assert message containing a filename, line number, and description.
+ This may be followed by a breakpoint or a dead loop.
+
+ Print a message of the form "ASSERT <FileName>(<LineNumber>): <Description>\n"
+ to the debug output device. If DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED bit of
+ PcdDebugPropertyMask is set then CpuBreakpoint() is called. Otherwise, if
+ DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED bit of PcdDebugPropertyMask is set then
+ CpuDeadLoop() is called. If neither of these bits are set, then this function
+ returns immediately after the message is printed to the debug output device.
+ DebugAssert() must actively prevent recursion. If DebugAssert() is called while
+ processing another DebugAssert(), then DebugAssert() must return immediately.
+
+ If FileName is NULL, then a <FileName> string of "(NULL) Filename" is printed.
+ If Description is NULL, then a <Description> string of "(NULL) Description" is printed.
+
+ @param FileName The pointer to the name of the source file that generated the assert condition.
+ @param LineNumber The line number in the source file that generated the assert condition
+ @param Description The pointer to the description of the assert condition.
+
+**/
+VOID
+EFIAPI
+DebugAssert (
+ IN CONST CHAR8 *FileName,
+ IN UINTN LineNumber,
+ IN CONST CHAR8 *Description
+ )
+{
+ DebugAssertInternal ();
+}
+
+
+/**
+ Fills a target buffer with PcdDebugClearMemoryValue, and returns the target buffer.
+
+ This function fills Length bytes of Buffer with the value specified by
+ PcdDebugClearMemoryValue, and returns Buffer.
+
+ If Buffer is NULL, then ASSERT().
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+ @param Buffer The pointer to the target buffer to be filled with PcdDebugClearMemoryValue.
+ @param Length The number of bytes in Buffer to fill with zeros PcdDebugClearMemoryValue.
+
+ @return Buffer The pointer to the target buffer filled with PcdDebugClearMemoryValue.
+
+**/
+VOID *
+EFIAPI
+DebugClearMemory (
+ OUT VOID *Buffer,
+ IN UINTN Length
+ )
+{
+ return Buffer;
+}
+
+
+/**
+ Returns TRUE if ASSERT() macros are enabled.
+
+ This function returns TRUE if the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of
+ PcdDebugPropertyMask is set. Otherwise FALSE is returned.
+
+ @retval TRUE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugPropertyMask is set.
+ @retval FALSE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugPropertyMask is clear.
+
+**/
+BOOLEAN
+EFIAPI
+DebugAssertEnabled (
+ VOID
+ )
+{
+ return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED) != 0);
+}
+
+
+/**
+ Returns TRUE if DEBUG() macros are enabled.
+
+ This function returns TRUE if the DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of
+ PcdDebugPropertyMask is set. Otherwise FALSE is returned.
+
+ @retval TRUE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugPropertyMask is set.
+ @retval FALSE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugPropertyMask is clear.
+
+**/
+BOOLEAN
+EFIAPI
+DebugPrintEnabled (
+ VOID
+ )
+{
+ return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_PRINT_ENABLED) != 0);
+}
+
+/**
+ Returns TRUE if DEBUG_CODE() macros are enabled.
+
+ This function returns TRUE if the DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of
+ PcdDebugPropertyMask is set. Otherwise FALSE is returned.
+
+ @retval TRUE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugPropertyMask is set.
+ @retval FALSE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugPropertyMask is clear.
+
+**/
+BOOLEAN
+EFIAPI
+DebugCodeEnabled (
+ VOID
+ )
+{
+ return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_CODE_ENABLED) != 0);
+}
+
+
+/**
+ Returns TRUE if DEBUG_CLEAR_MEMORY() macro is enabled.
+
+ This function returns TRUE if the DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of
+ PcdDebugPropertyMask is set. Otherwise FALSE is returned.
+
+ @retval TRUE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugPropertyMask is set.
+ @retval FALSE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugPropertyMask is clear.
+
+**/
+BOOLEAN
+EFIAPI
+DebugClearMemoryEnabled (
+ VOID
+ )
+{
+ return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED) != 0);
+}
+
+/**
+ Returns TRUE if any one of the bit is set both in ErrorLevel and PcdFixedDebugPrintErrorLevel.
+
+ This function compares the bit mask of ErrorLevel and PcdFixedDebugPrintErrorLevel.
+
+ @retval TRUE Current ErrorLevel is supported.
+ @retval FALSE Current ErrorLevel is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+DebugPrintLevelEnabled (
+ IN CONST UINTN ErrorLevel
+ )
+{
+ return (BOOLEAN) ((ErrorLevel & PcdGet32(PcdFixedDebugPrintErrorLevel)) != 0);
+}
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/Ia32/FspDebug.nasm b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/Ia32/FspDebug.nasm
new file mode 100644
index 00000000..4143ab17
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/Ia32/FspDebug.nasm
@@ -0,0 +1,25 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+; Abstract:
+;
+; FSP Debug functions
+;
+;------------------------------------------------------------------------------
+
+ SECTION .text
+
+;------------------------------------------------------------------------------
+; UINT32 *
+; EFIAPI
+; GetStackFramePointer (
+; VOID
+; );
+;------------------------------------------------------------------------------
+global ASM_PFX(GetStackFramePointer)
+ASM_PFX(GetStackFramePointer):
+ mov eax, ebp
+ ret
+
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseFspPlatformLib/BaseFspPlatformLib.inf b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseFspPlatformLib/BaseFspPlatformLib.inf
new file mode 100644
index 00000000..262b3981
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseFspPlatformLib/BaseFspPlatformLib.inf
@@ -0,0 +1,40 @@
+## @file
+# Instance of FspPlatformLib
+#
+# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = BaseFspPlatformLib
+ FILE_GUID = B6380BFB-7140-4C52-AC42-8C966C9A3F34
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = FspPlatformLib
+
+[Sources]
+ FspPlatformMemory.c
+ FspPlatformNotify.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ IntelFsp2Pkg/IntelFsp2Pkg.dec
+
+[LibraryClasses]
+ BaseMemoryLib
+ MemoryAllocationLib
+ FspCommonLib
+ PerformanceLib
+ ReportStatusCodeLib
+
+[Guids]
+ gFspPerformanceDataGuid ## CONSUMES ## GUID
+ gFspEventEndOfFirmwareGuid ## PRODUCES ## GUID
+ gEfiEventReadyToBootGuid ## CONSUMES ## Event
+
+[Protocols]
+ gEfiPciEnumerationCompleteProtocolGuid ## CONSUMES
+
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseFspPlatformLib/FspPlatformMemory.c b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseFspPlatformLib/FspPlatformMemory.c
new file mode 100644
index 00000000..aa26ba94
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseFspPlatformLib/FspPlatformMemory.c
@@ -0,0 +1,116 @@
+/** @file
+
+ Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/HobLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/FspCommonLib.h>
+#include <FspGlobalData.h>
+#include <FspEas.h>
+
+/**
+ Get system memory resource descriptor by owner.
+
+ @param[in] OwnerGuid resource owner guid
+**/
+EFI_HOB_RESOURCE_DESCRIPTOR *
+EFIAPI
+FspGetResourceDescriptorByOwner (
+ IN EFI_GUID *OwnerGuid
+ )
+{
+ EFI_PEI_HOB_POINTERS Hob;
+
+ //
+ // Get the HOB list for processing
+ //
+ Hob.Raw = GetHobList ();
+
+ //
+ // Collect memory ranges
+ //
+ while (!END_OF_HOB_LIST (Hob)) {
+ if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
+ if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED) && \
+ (CompareGuid (&Hob.ResourceDescriptor->Owner, OwnerGuid))) {
+ return Hob.ResourceDescriptor;
+ }
+ }
+ Hob.Raw = GET_NEXT_HOB (Hob);
+ }
+
+ return NULL;
+}
+
+/**
+ Get system memory from HOB.
+
+ @param[in,out] LowMemoryLength less than 4G memory length
+ @param[in,out] HighMemoryLength greater than 4G memory length
+**/
+VOID
+EFIAPI
+FspGetSystemMemorySize (
+ IN OUT UINT64 *LowMemoryLength,
+ IN OUT UINT64 *HighMemoryLength
+ )
+{
+ EFI_STATUS Status;
+ EFI_BOOT_MODE BootMode;
+ EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute;
+ EFI_PEI_HOB_POINTERS Hob;
+
+ ResourceAttribute = (
+ EFI_RESOURCE_ATTRIBUTE_PRESENT |
+ EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+ EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
+ EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
+ EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
+ EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
+ );
+
+ Status = PeiServicesGetBootMode (&BootMode);
+ ASSERT_EFI_ERROR (Status);
+
+ if (BootMode != BOOT_ON_S3_RESUME) {
+ ResourceAttribute |= EFI_RESOURCE_ATTRIBUTE_TESTED;
+ }
+
+ *HighMemoryLength = 0;
+ *LowMemoryLength = SIZE_1MB;
+ //
+ // Get the HOB list for processing
+ //
+ Hob.Raw = GetHobList ();
+
+ //
+ // Collect memory ranges
+ //
+ while (!END_OF_HOB_LIST (Hob)) {
+ if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
+ if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) ||
+ ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED) &&
+ (Hob.ResourceDescriptor->ResourceAttribute == ResourceAttribute))) {
+ //
+ // Need memory above 1MB to be collected here
+ //
+ if (Hob.ResourceDescriptor->PhysicalStart >= BASE_1MB &&
+ Hob.ResourceDescriptor->PhysicalStart < (EFI_PHYSICAL_ADDRESS) BASE_4GB) {
+ *LowMemoryLength += (UINT64) (Hob.ResourceDescriptor->ResourceLength);
+ } else if (Hob.ResourceDescriptor->PhysicalStart >= (EFI_PHYSICAL_ADDRESS) BASE_4GB) {
+ *HighMemoryLength += (UINT64) (Hob.ResourceDescriptor->ResourceLength);
+ }
+ }
+ }
+ Hob.Raw = GET_NEXT_HOB (Hob);
+ }
+}
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseFspPlatformLib/FspPlatformNotify.c b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseFspPlatformLib/FspPlatformNotify.c
new file mode 100644
index 00000000..48cd6597
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseFspPlatformLib/FspPlatformNotify.c
@@ -0,0 +1,409 @@
+/** @file
+
+ Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PeiServicesTablePointerLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/FspSwitchStackLib.h>
+#include <Library/FspCommonLib.h>
+#include <Guid/EventGroup.h>
+#include <FspEas.h>
+#include <FspStatusCode.h>
+#include <Protocol/PciEnumerationComplete.h>
+#include <Library/ReportStatusCodeLib.h>
+#include <Library/PerformanceLib.h>
+extern EFI_GUID gFspPerformanceDataGuid;
+
+EFI_PEI_PPI_DESCRIPTOR mPeiPostPciEnumerationPpi = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiPciEnumerationCompleteProtocolGuid,
+ NULL
+};
+
+EFI_PEI_PPI_DESCRIPTOR mPeiReadyToBootPpi = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiEventReadyToBootGuid,
+ NULL
+};
+
+EFI_PEI_PPI_DESCRIPTOR mPeiEndOfFirmwarePpi = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gFspEventEndOfFirmwareGuid,
+ NULL
+};
+
+UINT32 mFspNotifySequence[] = {
+ EnumInitPhaseAfterPciEnumeration,
+ EnumInitPhaseReadyToBoot,
+ EnumInitPhaseEndOfFirmware
+};
+
+/**
+ Install FSP notification.
+
+ @param[in] NotificationCode FSP notification code
+
+ @retval EFI_SUCCESS Notify FSP successfully
+ @retval EFI_INVALID_PARAMETER NotificationCode is invalid
+
+**/
+EFI_STATUS
+EFIAPI
+FspNotificationHandler (
+ IN UINT32 NotificationCode
+ )
+{
+ EFI_STATUS Status;
+
+ Status = EFI_SUCCESS;
+
+ switch (NotificationCode) {
+ case EnumInitPhaseAfterPciEnumeration:
+ //
+ // Do POST PCI initialization if needed
+ //
+ DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP Post PCI Enumeration ...\n"));
+ PeiServicesInstallPpi (&mPeiPostPciEnumerationPpi);
+ break;
+
+ case EnumInitPhaseReadyToBoot:
+ //
+ // Ready To Boot
+ //
+ DEBUG ((DEBUG_INFO| DEBUG_INIT, "FSP Ready To Boot ...\n"));
+ PeiServicesInstallPpi (&mPeiReadyToBootPpi);
+ break;
+
+ case EnumInitPhaseEndOfFirmware:
+ //
+ // End of Firmware
+ //
+ DEBUG ((DEBUG_INFO| DEBUG_INIT, "FSP End of Firmware ...\n"));
+ PeiServicesInstallPpi (&mPeiEndOfFirmwarePpi);
+ break;
+
+ default:
+ Status = EFI_INVALID_PARAMETER;
+ break;
+ }
+
+ return Status;
+}
+
+/**
+ This function transfer control back to BootLoader after FspSiliconInit.
+
+ @param[in] Status return status for the FspSiliconInit.
+
+**/
+VOID
+EFIAPI
+FspSiliconInitDone2 (
+ IN EFI_STATUS Status
+ )
+{
+ volatile EFI_STATUS FspStatus;
+
+ FspStatus = Status;
+ //
+ // Convert to FSP EAS defined API return codes
+ //
+ switch (Status) {
+ case EFI_SUCCESS:
+ case EFI_INVALID_PARAMETER:
+ case EFI_UNSUPPORTED:
+ case EFI_DEVICE_ERROR:
+ break;
+ default:
+ DEBUG ((DEBUG_INFO | DEBUG_INIT, "FspSiliconInitApi() Invalid Error - [Status: 0x%08X]\n", Status));
+ Status = EFI_DEVICE_ERROR; // Force to known error.
+ break;
+ }
+ //
+ // This is the end of the FspSiliconInit API
+ // Give control back to the boot loader
+ //
+ SetFspMeasurePoint (FSP_PERF_ID_API_FSP_SILICON_INIT_EXIT);
+ DEBUG ((DEBUG_INFO | DEBUG_INIT, "FspSiliconInitApi() - [Status: 0x%08X] - End\n", Status));
+ PERF_END_EX (&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_SILICON_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
+ REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
+ if (GetFspGlobalDataPointer ()->FspMode == FSP_IN_API_MODE) {
+ do {
+ SetFspApiReturnStatus (Status);
+ Pei2LoaderSwitchStack ();
+ if (Status != EFI_SUCCESS) {
+ DEBUG ((DEBUG_ERROR, "!!!ERROR: FspSiliconInitApi() - [Status: 0x%08X] - Error encountered during previous API and cannot proceed further\n", Status));
+ }
+ } while (FspStatus != EFI_SUCCESS);
+ }
+}
+
+/**
+ This function returns control to BootLoader after MemoryInitApi.
+
+ @param[in] Status return status for the MemoryInitApi.
+ @param[in,out] HobListPtr The address of HobList pointer, if NULL, will get value from GetFspApiParameter2 ()
+**/
+VOID
+EFIAPI
+FspMemoryInitDone2 (
+ IN EFI_STATUS Status,
+ IN OUT VOID **HobListPtr
+ )
+{
+ FSP_GLOBAL_DATA *FspData;
+ volatile EFI_STATUS FspStatus;
+
+ FspStatus = Status;
+ //
+ // Calling use FspMemoryInit API
+ // Update HOB and return the control directly
+ //
+ if (HobListPtr == NULL) {
+ HobListPtr = (VOID **)GetFspApiParameter2 ();
+ }
+ if (HobListPtr != NULL) {
+ *HobListPtr = (VOID *) GetHobList ();
+ }
+ //
+ // Convert to FSP EAS defined API return codes
+ //
+ switch (Status) {
+ case EFI_SUCCESS:
+ case EFI_INVALID_PARAMETER:
+ case EFI_UNSUPPORTED:
+ case EFI_DEVICE_ERROR:
+ case EFI_OUT_OF_RESOURCES:
+ break;
+ default:
+ DEBUG ((DEBUG_INFO | DEBUG_INIT, "FspMemoryInitApi() Invalid Error [Status: 0x%08X]\n", Status));
+ Status = EFI_DEVICE_ERROR; // Force to known error.
+ break;
+ }
+ //
+ // This is the end of the FspMemoryInit API
+ // Give control back to the boot loader
+ //
+ DEBUG ((DEBUG_INFO | DEBUG_INIT, "FspMemoryInitApi() - [Status: 0x%08X] - End\n", Status));
+ SetFspMeasurePoint (FSP_PERF_ID_API_FSP_MEMORY_INIT_EXIT);
+ FspData = GetFspGlobalDataPointer ();
+ PERF_START_EX(&gFspPerformanceDataGuid, "EventRec", NULL, (FspData->PerfData[0] & FSP_PERFORMANCE_DATA_TIMER_MASK), FSP_STATUS_CODE_TEMP_RAM_INIT | FSP_STATUS_CODE_COMMON_CODE| FSP_STATUS_CODE_API_ENTRY);
+ PERF_END_EX(&gFspPerformanceDataGuid, "EventRec", NULL, (FspData->PerfData[1] & FSP_PERFORMANCE_DATA_TIMER_MASK), FSP_STATUS_CODE_TEMP_RAM_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
+ PERF_START_EX(&gFspPerformanceDataGuid, "EventRec", NULL, (FspData->PerfData[2] & FSP_PERFORMANCE_DATA_TIMER_MASK), FSP_STATUS_CODE_MEMORY_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
+ PERF_END_EX(&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_MEMORY_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
+ REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_MEMORY_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
+ if (GetFspGlobalDataPointer ()->FspMode == FSP_IN_API_MODE) {
+ do {
+ SetFspApiReturnStatus (Status);
+ Pei2LoaderSwitchStack ();
+ if (Status != EFI_SUCCESS) {
+ DEBUG ((DEBUG_ERROR, "!!!ERROR: FspMemoryInitApi() - [Status: 0x%08X] - Error encountered during previous API and cannot proceed further\n", Status));
+ }
+ } while (FspStatus != EFI_SUCCESS);
+ }
+
+ //
+ // The TempRamExitApi is called
+ //
+ if (GetFspApiCallingIndex () == TempRamExitApiIndex) {
+ SetPhaseStatusCode (FSP_STATUS_CODE_TEMP_RAM_EXIT);
+ SetFspMeasurePoint (FSP_PERF_ID_API_TEMP_RAM_EXIT_ENTRY);
+ PERF_START_EX(&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_TEMP_RAM_EXIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
+ REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_TEMP_RAM_EXIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
+ DEBUG ((DEBUG_INFO | DEBUG_INIT, "TempRamExitApi() - Begin\n"));
+ } else {
+ SetPhaseStatusCode (FSP_STATUS_CODE_SILICON_INIT);
+ SetFspMeasurePoint (FSP_PERF_ID_API_FSP_SILICON_INIT_ENTRY);
+ PERF_START_EX(&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_SILICON_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
+ REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_SILICON_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
+ DEBUG ((DEBUG_INFO | DEBUG_INIT, "FspSiliconInitApi() - Begin\n"));
+ }
+}
+
+/**
+ This function returns control to BootLoader after TempRamExitApi.
+
+ @param[in] Status return status for the TempRamExitApi.
+
+**/
+VOID
+EFIAPI
+FspTempRamExitDone2 (
+ IN EFI_STATUS Status
+ )
+{
+ //
+ volatile EFI_STATUS FspStatus;
+
+ FspStatus = Status;
+ // Convert to FSP EAS defined API return codes
+ //
+ switch (Status) {
+ case EFI_SUCCESS:
+ case EFI_INVALID_PARAMETER:
+ case EFI_UNSUPPORTED:
+ case EFI_DEVICE_ERROR:
+ break;
+ default:
+ DEBUG ((DEBUG_INFO | DEBUG_INIT, "TempRamExitApi() Invalid Error - [Status: 0x%08X]\n", Status));
+ Status = EFI_DEVICE_ERROR; // Force to known error.
+ break;
+ }
+ //
+ // This is the end of the TempRamExit API
+ // Give control back to the boot loader
+ //
+ DEBUG ((DEBUG_INFO | DEBUG_INIT, "TempRamExitApi() - [Status: 0x%08X] - End\n", Status));
+ SetFspMeasurePoint (FSP_PERF_ID_API_TEMP_RAM_EXIT_EXIT);
+ PERF_END_EX(&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_TEMP_RAM_EXIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
+ REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_TEMP_RAM_EXIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
+ if (GetFspGlobalDataPointer ()->FspMode == FSP_IN_API_MODE) {
+ do {
+ SetFspApiReturnStatus (Status);
+ Pei2LoaderSwitchStack ();
+ if (Status != EFI_SUCCESS) {
+ DEBUG ((DEBUG_ERROR, "!!!ERROR: TempRamExitApi() - [Status: 0x%08X] - Error encountered during previous API and cannot proceed further\n", Status));
+ }
+ } while (FspStatus != EFI_SUCCESS);
+ }
+ SetPhaseStatusCode (FSP_STATUS_CODE_SILICON_INIT);
+ SetFspMeasurePoint (FSP_PERF_ID_API_FSP_SILICON_INIT_ENTRY);
+ PERF_START_EX(&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_SILICON_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
+ REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_SILICON_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
+ DEBUG ((DEBUG_INFO | DEBUG_INIT, "SiliconInitApi() - Begin\n"));
+}
+
+/**
+ This function handle NotifyPhase API call from the BootLoader.
+ It gives control back to the BootLoader after it is handled. If the
+ Notification code is a ReadyToBoot event, this function will return
+ and FSP continues the remaining execution until it reaches the DxeIpl.
+
+**/
+VOID
+FspWaitForNotify (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINT32 NotificationValue;
+ UINT32 NotificationCount;
+ UINT8 Count;
+ volatile EFI_STATUS FspStatus;
+
+ NotificationCount = 0;
+ while (NotificationCount < sizeof(mFspNotifySequence) / sizeof(UINT32)) {
+
+ Count = (UINT8)((NotificationCount << 1) & 0x07);
+ SetFspMeasurePoint (FSP_PERF_ID_API_NOTIFY_POST_PCI_ENTRY + Count);
+
+ if (NotificationCount == 0) {
+ SetPhaseStatusCode (FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION);
+ PERF_START_EX (&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
+ REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
+ } else if (NotificationCount == 1) {
+ SetPhaseStatusCode (FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION);
+ PERF_START_EX(&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
+ REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
+ } else if (NotificationCount == 2) {
+ SetPhaseStatusCode (FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION);
+ PERF_START_EX (&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
+ REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
+ }
+
+ NotificationValue = ((NOTIFY_PHASE_PARAMS *)(UINTN)GetFspApiParameter ())->Phase;
+ DEBUG ((DEBUG_INFO | DEBUG_INIT, "NotifyPhaseApi() - Begin [Phase: %08X]\n", NotificationValue));
+ if (mFspNotifySequence[NotificationCount] != NotificationValue) {
+ //
+ // Notify code does not follow the predefined order
+ //
+ DEBUG ((DEBUG_INFO, "Unsupported FSP Notification Value\n"));
+ Status = EFI_UNSUPPORTED;
+ } else {
+ //
+ // Process Notification and Give control back to the boot loader framework caller
+ //
+ Status = FspNotificationHandler (NotificationValue);
+ if (!EFI_ERROR(Status)) {
+ NotificationCount++;
+ }
+ }
+
+ DEBUG ((DEBUG_INFO | DEBUG_INIT, "NotifyPhaseApi() - End [Status: 0x%08X]\n", Status));
+ SetFspMeasurePoint (FSP_PERF_ID_API_NOTIFY_POST_PCI_EXIT + Count);
+
+ if ((NotificationCount - 1) == 0) {
+ PERF_END_EX(&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
+ REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
+ } else if ((NotificationCount - 1) == 1) {
+ PERF_END_EX(&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
+ REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
+ } else if ((NotificationCount - 1) == 2) {
+ PERF_END_EX(&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
+ REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
+ }
+ if (GetFspGlobalDataPointer ()->FspMode == FSP_IN_API_MODE) {
+ FspStatus = Status;
+ do {
+ SetFspApiReturnStatus(Status);
+ Pei2LoaderSwitchStack();
+ if (Status != EFI_SUCCESS) {
+ DEBUG ((DEBUG_ERROR, "!!!ERROR: NotifyPhaseApi() [Phase: %08X] - Failed - [Status: 0x%08X]\n", NotificationValue, Status));
+ }
+ } while (FspStatus != EFI_SUCCESS);
+ }
+ }
+ //
+ // Control goes back to the PEI Core and it dispatches further PEIMs.
+ // DXEIPL is the final one to transfer control back to the boot loader.
+ //
+}
+
+/**
+ This function transfer control back to BootLoader after FspSiliconInit.
+
+**/
+VOID
+EFIAPI
+FspSiliconInitDone (
+ VOID
+ )
+{
+ FspSiliconInitDone2 (EFI_SUCCESS);
+}
+
+/**
+ This function returns control to BootLoader after MemoryInitApi.
+
+ @param[in,out] HobListPtr The address of HobList pointer.
+**/
+VOID
+EFIAPI
+FspMemoryInitDone (
+ IN OUT VOID **HobListPtr
+ )
+{
+ FspMemoryInitDone2 (EFI_SUCCESS, HobListPtr);
+}
+
+/**
+ This function returns control to BootLoader after TempRamExitApi.
+
+**/
+VOID
+EFIAPI
+FspTempRamExitDone (
+ VOID
+ )
+{
+ FspTempRamExitDone2 (EFI_SUCCESS);
+}
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/BaseFspSwitchStackLib.inf b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/BaseFspSwitchStackLib.inf
new file mode 100644
index 00000000..5f164b5a
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/BaseFspSwitchStackLib.inf
@@ -0,0 +1,33 @@
+## @file
+# Instance of BaseFspSwitchStackLib
+#
+# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = BaseFspSwitchStackLib
+ FILE_GUID = 68E79161-F7CE-4A61-8C72-F4DF6FF35CAA
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = FspSwitchStackLib
+
+[Sources.IA32]
+ FspSwitchStackLib.c
+
+[Sources.IA32]
+ Ia32/Stack.nasm
+
+[Packages]
+ MdePkg/MdePkg.dec
+ IntelFsp2Pkg/IntelFsp2Pkg.dec
+
+[LibraryClasses]
+ BaseLib
+ IoLib
+
+
+
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/FspSwitchStackLib.c b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/FspSwitchStackLib.c
new file mode 100644
index 00000000..27bfdb86
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/FspSwitchStackLib.c
@@ -0,0 +1,36 @@
+/** @file
+
+ Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Base.h>
+#include <Library/BaseLib.h>
+#include <Library/FspCommonLib.h>
+
+/**
+
+ Switch the current stack to the previous saved stack.
+
+ @param[in] NewStack The new stack to be switched.
+
+ @return OldStack After switching to the saved stack,
+ this value will be saved in eax before returning.
+
+
+**/
+UINT32
+SwapStack (
+ IN UINT32 NewStack
+ )
+{
+ FSP_GLOBAL_DATA *FspData;
+ UINT32 OldStack;
+
+ FspData = GetFspGlobalDataPointer ();
+ OldStack = FspData->CoreStack;
+ FspData->CoreStack = NewStack;
+ return OldStack;
+}
+
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/Ia32/Stack.nasm b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/Ia32/Stack.nasm
new file mode 100644
index 00000000..deb7647d
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/Ia32/Stack.nasm
@@ -0,0 +1,68 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.<BR>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+; Abstract:
+;
+; Switch the stack from temporary memory to permanent memory.
+;
+;------------------------------------------------------------------------------
+
+ SECTION .text
+
+extern ASM_PFX(SwapStack)
+
+;------------------------------------------------------------------------------
+; UINT32
+; EFIAPI
+; Pei2LoaderSwitchStack (
+; VOID
+; )
+;------------------------------------------------------------------------------
+global ASM_PFX(Pei2LoaderSwitchStack)
+ASM_PFX(Pei2LoaderSwitchStack):
+ xor eax, eax
+ jmp ASM_PFX(FspSwitchStack)
+
+;------------------------------------------------------------------------------
+; UINT32
+; EFIAPI
+; Loader2PeiSwitchStack (
+; VOID
+; )
+;------------------------------------------------------------------------------
+global ASM_PFX(Loader2PeiSwitchStack)
+ASM_PFX(Loader2PeiSwitchStack):
+ jmp ASM_PFX(FspSwitchStack)
+
+;------------------------------------------------------------------------------
+; UINT32
+; EFIAPI
+; FspSwitchStack (
+; VOID
+; )
+;------------------------------------------------------------------------------
+global ASM_PFX(FspSwitchStack)
+ASM_PFX(FspSwitchStack):
+ ; Save current contexts
+ push eax
+ pushfd
+ cli
+ pushad
+ sub esp, 8
+ sidt [esp]
+
+ ; Load new stack
+ push esp
+ call ASM_PFX(SwapStack)
+ mov esp, eax
+
+ ; Restore previous contexts
+ lidt [esp]
+ add esp, 8
+ popad
+ popfd
+ add esp, 4
+ ret
+
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/Flat32.nasm b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/Flat32.nasm
new file mode 100644
index 00000000..e004de2d
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/Flat32.nasm
@@ -0,0 +1,121 @@
+;; @file
+; This is the code that goes from real-mode to protected mode.
+; It consumes the reset vector, configures the stack.
+;
+; Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.<BR>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;;
+
+;
+; Define assembler characteristics
+;
+
+extern ASM_PFX(TempRamInitApi)
+
+SECTION .text
+
+%macro RET_ESI 0
+
+ movd esi, mm7 ; restore ESP from MM7
+ jmp esi
+
+%endmacro
+
+;
+; Perform early platform initialization
+;
+global ASM_PFX(SecPlatformInit)
+ASM_PFX(SecPlatformInit):
+
+ RET_ESI
+
+;
+; Protected mode portion initializes stack, configures cache, and calls C entry point
+;
+
+;----------------------------------------------------------------------------
+;
+; Procedure: ProtectedModeEntryPoint
+;
+; Input: Executing in 32 Bit Protected (flat) mode
+; cs: 0-4GB
+; ds: 0-4GB
+; es: 0-4GB
+; fs: 0-4GB
+; gs: 0-4GB
+; ss: 0-4GB
+;
+; Output: This function never returns
+;
+; Destroys:
+; ecx
+; edi
+; esi
+; esp
+;
+; Description:
+; Perform any essential early platform initialisation
+; Setup a stack
+;
+;----------------------------------------------------------------------------
+global ASM_PFX(ProtectedModeEntryPoint)
+ASM_PFX(ProtectedModeEntryPoint):
+ ;
+ ; Dummy function. Consume 2 API to make sure they can be linked.
+ ;
+ mov eax, ASM_PFX(TempRamInitApi)
+
+ ; Should never return
+ jmp $
+
+;
+; ROM-based Global-Descriptor Table for the PEI Phase
+;
+align 16
+global ASM_PFX(BootGdtTable)
+
+;
+; GDT[0]: 0x00: Null entry, never used.
+;
+NULL_SEL equ $ - GDT_BASE ; Selector [0]
+GDT_BASE:
+ASM_PFX(BootGdtTable): DD 0
+ DD 0
+;
+; Linear code segment descriptor
+;
+LINEAR_CODE_SEL equ $ - GDT_BASE ; Selector [0x8]
+ DW 0FFFFh ; limit 0xFFFF
+ DW 0 ; base 0
+ DB 0
+ DB 09Bh ; present, ring 0, data, expand-up, not-writable
+ DB 0CFh ; page-granular, 32-bit
+ DB 0
+;
+; System data segment descriptor
+;
+SYS_DATA_SEL equ $ - GDT_BASE ; Selector [0x10]
+ DW 0FFFFh ; limit 0xFFFF
+ DW 0 ; base 0
+ DB 0
+ DB 093h ; present, ring 0, data, expand-up, not-writable
+ DB 0CFh ; page-granular, 32-bit
+ DB 0
+
+GDT_SIZE EQU $ - GDT_BASE ; Size, in bytes
+
+;
+; GDT Descriptor
+;
+GdtDesc: ; GDT descriptor
+ DW GDT_SIZE - 1 ; GDT limit
+ DD GDT_BASE ; GDT base address
+
+global ASM_PFX(ProtectedModeEntryLinearAddress)
+global ASM_PFX(ProtectedModeEntryLinearOffset)
+
+ASM_PFX(ProtectedModeEntryLinearAddress):
+ASM_PFX(ProtectedModeEntryLinearOffset):
+ DD ASM_PFX(ProtectedModeEntryPoint) ; Offset of our 32 bit code
+ DW LINEAR_CODE_SEL
+
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/SecCarInit.nasm b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/SecCarInit.nasm
new file mode 100644
index 00000000..121f2b0c
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/SecCarInit.nasm
@@ -0,0 +1,40 @@
+;; @file
+; SEC CAR function
+;
+; Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;;
+
+;
+; Define assembler characteristics
+;
+
+%macro RET_ESI 0
+
+ movd esi, mm7 ; move ReturnAddress from MM7 to ESI
+ jmp esi
+
+%endmacro
+
+SECTION .text
+
+;-----------------------------------------------------------------------------
+;
+; Section: SecCarInit
+;
+; Description: This function initializes the Cache for Data, Stack, and Code
+;
+;-----------------------------------------------------------------------------
+global ASM_PFX(SecCarInit)
+ASM_PFX(SecCarInit):
+
+ ;
+ ; Set up CAR
+ ;
+
+ xor eax, eax
+
+SecCarInitExit:
+
+ RET_ESI
+
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/PlatformSecLibNull.c b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/PlatformSecLibNull.c
new file mode 100644
index 00000000..09539f4b
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/PlatformSecLibNull.c
@@ -0,0 +1,44 @@
+/** @file
+ Null instance of Platform Sec Lib.
+
+ Copyright (c) 2014 - 2020, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+#include <Library/FspCommonLib.h>
+
+/**
+ This function check the signature of UPD.
+
+ @param[in] ApiIdx Internal index of the FSP API.
+ @param[in] ApiParam Parameter of the FSP API.
+
+**/
+EFI_STATUS
+EFIAPI
+FspUpdSignatureCheck (
+ IN UINT32 ApiIdx,
+ IN VOID *ApiParam
+ )
+{
+ return EFI_SUCCESS;
+}
+
+/**
+ This function handles FspMultiPhaseSiInitApi.
+
+ @param[in] ApiIdx Internal index of the FSP API.
+ @param[in] ApiParam Parameter of the FSP API.
+
+**/
+EFI_STATUS
+EFIAPI
+FspMultiPhaseSiInitApiHandler (
+ IN UINT32 ApiIdx,
+ IN VOID *ApiParam
+ )
+{
+ return EFI_SUCCESS;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/SecFspSecPlatformLibNull.inf b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/SecFspSecPlatformLibNull.inf
new file mode 100644
index 00000000..04129844
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/SecFspSecPlatformLibNull.inf
@@ -0,0 +1,51 @@
+## @file
+# NULL instance of Platform Sec Lib.
+#
+# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = BaseFspSecPlatformLibNull
+ FILE_GUID = C128CADC-623E-4E41-97CB-A7138E627460
+ MODULE_TYPE = SEC
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = FspSecPlatformLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32
+#
+
+################################################################################
+#
+# Sources Section - list of files that are required for the build to succeed.
+#
+################################################################################
+
+[Sources]
+ PlatformSecLibNull.c
+
+[Sources.IA32]
+ Ia32/Flat32.nasm
+ Ia32/SecCarInit.nasm
+
+################################################################################
+#
+# Package Dependency Section - list of Package files that are required for
+# this module.
+#
+################################################################################
+
+[Packages]
+ MdePkg/MdePkg.dec
+ IntelFsp2Pkg/IntelFsp2Pkg.dec