summaryrefslogtreecommitdiffstats
path: root/IntelFsp2Pkg/Library
diff options
context:
space:
mode:
Diffstat (limited to 'IntelFsp2Pkg/Library')
-rw-r--r--IntelFsp2Pkg/Library/BaseCacheAsRamLibNull/BaseCacheAsRamLibNull.inf31
-rw-r--r--IntelFsp2Pkg/Library/BaseCacheAsRamLibNull/DisableCacheAsRamNull.c41
-rw-r--r--IntelFsp2Pkg/Library/BaseCacheLib/BaseCacheLib.inf34
-rw-r--r--IntelFsp2Pkg/Library/BaseCacheLib/CacheLib.c703
-rw-r--r--IntelFsp2Pkg/Library/BaseCacheLib/CacheLibInternal.h59
-rw-r--r--IntelFsp2Pkg/Library/BaseDebugDeviceLibNull/BaseDebugDeviceLibNull.inf34
-rw-r--r--IntelFsp2Pkg/Library/BaseDebugDeviceLibNull/DebugDeviceLibNull.c31
-rw-r--r--IntelFsp2Pkg/Library/BaseFspCommonLib/BaseFspCommonLib.inf39
-rw-r--r--IntelFsp2Pkg/Library/BaseFspCommonLib/FspCommonLib.c546
-rw-r--r--IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/BaseFspDebugLibSerialPort.inf51
-rw-r--r--IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/DebugLib.c328
-rw-r--r--IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/Ia32/FspDebug.asm34
-rw-r--r--IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/Ia32/FspDebug.s30
-rw-r--r--IntelFsp2Pkg/Library/BaseFspPlatformLib/BaseFspPlatformLib.inf50
-rw-r--r--IntelFsp2Pkg/Library/BaseFspPlatformLib/FspPlatformMemory.c189
-rw-r--r--IntelFsp2Pkg/Library/BaseFspPlatformLib/FspPlatformNotify.c279
-rw-r--r--IntelFsp2Pkg/Library/BaseFspSwitchStackLib/BaseFspSwitchStackLib.inf43
-rw-r--r--IntelFsp2Pkg/Library/BaseFspSwitchStackLib/FspSwitchStackLib.c42
-rw-r--r--IntelFsp2Pkg/Library/BaseFspSwitchStackLib/Ia32/Stack.asm77
-rw-r--r--IntelFsp2Pkg/Library/BaseFspSwitchStackLib/Ia32/Stack.s78
-rw-r--r--IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/Flat32.asm131
-rw-r--r--IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/Flat32.s110
-rw-r--r--IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/SecCarInit.asm51
-rw-r--r--IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/SecCarInit.s37
-rw-r--r--IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/PlatformSecLibNull.c33
-rw-r--r--IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/SecFspSecPlatformLibNull.inf58
26 files changed, 3139 insertions, 0 deletions
diff --git a/IntelFsp2Pkg/Library/BaseCacheAsRamLibNull/BaseCacheAsRamLibNull.inf b/IntelFsp2Pkg/Library/BaseCacheAsRamLibNull/BaseCacheAsRamLibNull.inf
new file mode 100644
index 0000000000..bdb6744f37
--- /dev/null
+++ b/IntelFsp2Pkg/Library/BaseCacheAsRamLibNull/BaseCacheAsRamLibNull.inf
@@ -0,0 +1,31 @@
+## @file
+# NULL instance of Base cache as RAM.
+#
+# Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[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/IntelFsp2Pkg/Library/BaseCacheAsRamLibNull/DisableCacheAsRamNull.c b/IntelFsp2Pkg/Library/BaseCacheAsRamLibNull/DisableCacheAsRamNull.c
new file mode 100644
index 0000000000..9b45163c34
--- /dev/null
+++ b/IntelFsp2Pkg/Library/BaseCacheAsRamLibNull/DisableCacheAsRamNull.c
@@ -0,0 +1,41 @@
+/** @file
+
+ Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#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/IntelFsp2Pkg/Library/BaseCacheLib/BaseCacheLib.inf b/IntelFsp2Pkg/Library/BaseCacheLib/BaseCacheLib.inf
new file mode 100644
index 0000000000..7b026b1dfc
--- /dev/null
+++ b/IntelFsp2Pkg/Library/BaseCacheLib/BaseCacheLib.inf
@@ -0,0 +1,34 @@
+## @file
+# Instance of BaseCache.
+#
+# Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[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/IntelFsp2Pkg/Library/BaseCacheLib/CacheLib.c b/IntelFsp2Pkg/Library/BaseCacheLib/CacheLib.c
new file mode 100644
index 0000000000..b38dce32a8
--- /dev/null
+++ b/IntelFsp2Pkg/Library/BaseCacheLib/CacheLib.c
@@ -0,0 +1,703 @@
+/** @file
+
+ Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#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 Alligned.
+ @retval Non-Zero Not alligned.
+
+**/
+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 inital 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 Alligned.
+ @retval Non-Zero Not alligned.
+
+**/
+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/IntelFsp2Pkg/Library/BaseCacheLib/CacheLibInternal.h b/IntelFsp2Pkg/Library/BaseCacheLib/CacheLibInternal.h
new file mode 100644
index 0000000000..fbbf551dde
--- /dev/null
+++ b/IntelFsp2Pkg/Library/BaseCacheLib/CacheLibInternal.h
@@ -0,0 +1,59 @@
+/** @file
+
+ Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#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/IntelFsp2Pkg/Library/BaseDebugDeviceLibNull/BaseDebugDeviceLibNull.inf b/IntelFsp2Pkg/Library/BaseDebugDeviceLibNull/BaseDebugDeviceLibNull.inf
new file mode 100644
index 0000000000..5e4c572973
--- /dev/null
+++ b/IntelFsp2Pkg/Library/BaseDebugDeviceLibNull/BaseDebugDeviceLibNull.inf
@@ -0,0 +1,34 @@
+## @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>
+#
+# 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.
+#
+##
+
+[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/IntelFsp2Pkg/Library/BaseDebugDeviceLibNull/DebugDeviceLibNull.c b/IntelFsp2Pkg/Library/BaseDebugDeviceLibNull/DebugDeviceLibNull.c
new file mode 100644
index 0000000000..95c100472c
--- /dev/null
+++ b/IntelFsp2Pkg/Library/BaseDebugDeviceLibNull/DebugDeviceLibNull.c
@@ -0,0 +1,31 @@
+/** @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>
+ 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.
+
+**/
+
+#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/IntelFsp2Pkg/Library/BaseFspCommonLib/BaseFspCommonLib.inf b/IntelFsp2Pkg/Library/BaseFspCommonLib/BaseFspCommonLib.inf
new file mode 100644
index 0000000000..0b0741b1c6
--- /dev/null
+++ b/IntelFsp2Pkg/Library/BaseFspCommonLib/BaseFspCommonLib.inf
@@ -0,0 +1,39 @@
+## @file
+# Instance of FspCommonLib
+# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[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
+
+[Pcd]
+ gIntelFsp2PkgTokenSpaceGuid.PcdGlobalDataPointerAddress ## CONSUMES
+
+[FixedPcd]
+ gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxPatchEntry ## CONSUMES
+ gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxPerfEntry ## CONSUMES
+ gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamBase ## CONSUMES
+ gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamSize ## CONSUMES
diff --git a/IntelFsp2Pkg/Library/BaseFspCommonLib/FspCommonLib.c b/IntelFsp2Pkg/Library/BaseFspCommonLib/FspCommonLib.c
new file mode 100644
index 0000000000..efd55f464c
--- /dev/null
+++ b/IntelFsp2Pkg/Library/BaseFspCommonLib/FspCommonLib.c
@@ -0,0 +1,546 @@
+/** @file
+
+ Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PiPei.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <FspGlobalData.h>
+#include <FspEas.h>
+#include <FspDataTable.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 bootlaoder.
+
+ @retval ApiParameter FSP API first parameter passed by the bootlaoder.
+**/
+UINT32
+EFIAPI
+GetFspApiParameter (
+ VOID
+ )
+{
+ FSP_GLOBAL_DATA *FspData;
+
+ FspData = GetFspGlobalDataPointer ();
+ return *(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(ApiParam[0]));
+}
+
+/**
+ This function gets back the FSP API second parameter passed by the bootlaoder.
+
+ @retval ApiParameter FSP API second parameter passed by the bootlaoder.
+**/
+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 memory init UPD data pointer.
+
+ @param[in] MemoryInitUpdPtr memory init UPD data pointer.
+**/
+VOID
+EFIAPI
+SetFspMemoryInitUpdDataPointer (
+ IN VOID *MemoryInitUpdPtr
+ )
+{
+ FSP_GLOBAL_DATA *FspData;
+
+ //
+ // Get the Fsp Global Data Pointer
+ //
+ FspData = GetFspGlobalDataPointer ();
+
+ //
+ // Set the memory init UPD pointer.
+ //
+ FspData->MemoryInitUpdPtr = MemoryInitUpdPtr;
+}
+
+/**
+ This function gets the memory init UPD data pointer.
+
+ @return memory init UPD data pointer.
+**/
+VOID *
+EFIAPI
+GetFspMemoryInitUpdDataPointer (
+ VOID
+ )
+{
+ FSP_GLOBAL_DATA *FspData;
+
+ FspData = GetFspGlobalDataPointer ();
+ return FspData->MemoryInitUpdPtr;
+}
+
+
+/**
+ This function sets the silicon init UPD data pointer.
+
+ @param[in] SiliconInitUpdPtr silicon init UPD data pointer.
+**/
+VOID
+EFIAPI
+SetFspSiliconInitUpdDataPointer (
+ IN VOID *SiliconInitUpdPtr
+ )
+{
+ FSP_GLOBAL_DATA *FspData;
+
+ //
+ // Get the Fsp Global Data Pointer
+ //
+ FspData = GetFspGlobalDataPointer ();
+
+ //
+ // Set the silicon init UPD data pointer.
+ //
+ FspData->SiliconInitUpdPtr = SiliconInitUpdPtr;
+}
+
+/**
+ This function gets the silicon init UPD data pointer.
+
+ @return silicon init 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 VPD data pointer.
+
+ @return VpdDataRgnPtr VPD data pointer.
+**/
+VOID *
+EFIAPI
+GetFspVpdDataPointer (
+ 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 gets FSP CAR base.
+
+**/
+UINT32
+EFIAPI
+GetFspCarBase (
+ VOID
+ )
+{
+ FSP_GLOBAL_DATA *FspData;
+ UINT32 CarBase;
+
+ FspData = GetFspGlobalDataPointer ();
+ CarBase = FspData->PlatformData.CarBase;
+ if (CarBase == 0) {
+ CarBase = PcdGet32(PcdTemporaryRamBase);
+ }
+ return CarBase;
+}
+
+/**
+ This function gets FSP CAR size.
+
+**/
+UINT32
+EFIAPI
+GetFspCarSize (
+ VOID
+ )
+{
+ FSP_GLOBAL_DATA *FspData;
+ UINT32 CarSize;
+
+ FspData = GetFspGlobalDataPointer ();
+ CarSize = FspData->PlatformData.CarSize;
+ if (FspData->PlatformData.CarBase == 0) {
+ CarSize = PcdGet32(PcdTemporaryRamSize);
+ }
+ return CarSize;
+}
diff --git a/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/BaseFspDebugLibSerialPort.inf b/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/BaseFspDebugLibSerialPort.inf
new file mode 100644
index 0000000000..a7f10d4262
--- /dev/null
+++ b/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/BaseFspDebugLibSerialPort.inf
@@ -0,0 +1,51 @@
+## @file
+# Instance of BaseFspDebugLib
+#
+# Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[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.asm | MSFT
+ Ia32/FspDebug.s | GCC
+
+[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/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/DebugLib.c b/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/DebugLib.c
new file mode 100644
index 0000000000..73bb08e357
--- /dev/null
+++ b/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/DebugLib.c
@@ -0,0 +1,328 @@
+/** @file
+
+ Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#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";
+
+/**
+ 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,
+ ...
+ )
+{
+ CHAR8 Buffer[MAX_DEBUG_MESSAGE_LENGTH];
+ VA_LIST Marker;
+
+ //
+ // 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
+ //
+ VA_START (Marker, Format);
+ AsciiVSPrint (Buffer, sizeof (Buffer), Format, Marker);
+ VA_END (Marker);
+
+ //
+ // Send the print string to a Serial Port
+ //
+ SerialPortWrite ((UINT8 *)Buffer, AsciiStrLen (Buffer));
+}
+
+/**
+ Convert an UINT32 value into HEX string sepcified 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
+ PcdDebugProperyMask is set then CpuBreakpoint() is called. Otherwise, if
+ DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED bit of PcdDebugProperyMask 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
+ PcdDebugProperyMask is set then CpuBreakpoint() is called. Otherwise, if
+ DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED bit of PcdDebugProperyMask 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
+ PcdDebugProperyMask is set. Otherwise FALSE is returned.
+
+ @retval TRUE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is set.
+ @retval FALSE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask 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
+ PcdDebugProperyMask is set. Otherwise FALSE is returned.
+
+ @retval TRUE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is set.
+ @retval FALSE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask 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
+ PcdDebugProperyMask is set. Otherwise FALSE is returned.
+
+ @retval TRUE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is set.
+ @retval FALSE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask 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
+ PcdDebugProperyMask is set. Otherwise FALSE is returned.
+
+ @retval TRUE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is set.
+ @retval FALSE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask 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/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/Ia32/FspDebug.asm b/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/Ia32/FspDebug.asm
new file mode 100644
index 0000000000..8ac18ec4ec
--- /dev/null
+++ b/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/Ia32/FspDebug.asm
@@ -0,0 +1,34 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;
+; Abstract:
+;
+; FSP Debug functions
+;
+;------------------------------------------------------------------------------
+
+ .386
+ .model flat,C
+ .code
+
+;------------------------------------------------------------------------------
+; UINT32 *
+; EFIAPI
+; GetStackFramePointer (
+; VOID
+; );
+;------------------------------------------------------------------------------
+GetStackFramePointer PROC PUBLIC
+ mov eax, ebp
+ ret
+GetStackFramePointer ENDP
+
+ END
diff --git a/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/Ia32/FspDebug.s b/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/Ia32/FspDebug.s
new file mode 100644
index 0000000000..0f8475fa62
--- /dev/null
+++ b/IntelFsp2Pkg/Library/BaseFspDebugLibSerialPort/Ia32/FspDebug.s
@@ -0,0 +1,30 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+# Abstract:
+#
+# FSP Debug functions
+#
+#------------------------------------------------------------------------------
+
+#------------------------------------------------------------------------------
+# UINT32 *
+# EFIAPI
+# GetStackFramePointer (
+# VOID
+# )
+#------------------------------------------------------------------------------
+ASM_GLOBAL ASM_PFX(GetStackFramePointer)
+ASM_PFX(GetStackFramePointer):
+ mov %ebp, %eax
+ ret
+
+
diff --git a/IntelFsp2Pkg/Library/BaseFspPlatformLib/BaseFspPlatformLib.inf b/IntelFsp2Pkg/Library/BaseFspPlatformLib/BaseFspPlatformLib.inf
new file mode 100644
index 0000000000..d04689ef88
--- /dev/null
+++ b/IntelFsp2Pkg/Library/BaseFspPlatformLib/BaseFspPlatformLib.inf
@@ -0,0 +1,50 @@
+## @file
+# Instance of FspPlatformLib
+#
+# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[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
+
+[Pcd]
+ gIntelFsp2PkgTokenSpaceGuid.PcdGlobalDataPointerAddress ## CONSUMES
+ gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamBase ## CONSUMES
+ gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamSize ## CONSUMES
+ gIntelFsp2PkgTokenSpaceGuid.PcdFspTemporaryRamSize ## CONSUMES
+
+[Guids]
+ gFspPerformanceDataGuid ## CONSUMES ## GUID
+ gFspEventEndOfFirmwareGuid ## PRODUCES ## GUID
+
+[FixedPcd]
+ gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxPatchEntry ## CONSUMES
+ gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxPerfEntry ## CONSUMES
diff --git a/IntelFsp2Pkg/Library/BaseFspPlatformLib/FspPlatformMemory.c b/IntelFsp2Pkg/Library/BaseFspPlatformLib/FspPlatformMemory.c
new file mode 100644
index 0000000000..d6684f3b06
--- /dev/null
+++ b/IntelFsp2Pkg/Library/BaseFspPlatformLib/FspPlatformMemory.c
@@ -0,0 +1,189 @@
+/** @file
+
+ Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#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);
+ }
+}
+
+/**
+ Migrate BootLoader data before destroying CAR.
+
+**/
+VOID
+EFIAPI
+FspMigrateTemporaryMemory (
+ VOID
+ )
+{
+ UINT32 BootLoaderTempRamStart;
+ UINT32 BootLoaderTempRamEnd;
+ UINT32 BootLoaderTempRamSize;
+ UINT32 OffsetGap;
+ UINT32 FspParamPtr;
+ VOID *BootLoaderTempRamHob;
+ UINT32 MemoryInitUpdPtr;
+ VOID *PlatformDataPtr;
+
+ //
+ // Get the temporary memory range used by the BootLoader
+ //
+ BootLoaderTempRamStart = GetFspCarBase ();
+ BootLoaderTempRamSize = GetFspCarSize () - PcdGet32(PcdFspTemporaryRamSize);
+
+ BootLoaderTempRamEnd = BootLoaderTempRamStart + BootLoaderTempRamSize;
+
+ //
+ // Build a Boot Loader Temporary Memory GUID HOB
+ //
+ BootLoaderTempRamHob = (VOID *)AllocatePages (EFI_SIZE_TO_PAGES (BootLoaderTempRamSize));
+ ASSERT(BootLoaderTempRamHob != NULL);
+
+ DEBUG ((DEBUG_INFO, "FSP_BOOT_LOADER_TEMPORARY_MEMORY_HOB\n"));
+ DEBUG ((DEBUG_INFO, "FspBootLoaderTemporaryMemory Base : %x\n", BootLoaderTempRamStart));
+ DEBUG ((DEBUG_INFO, "FspBootLoaderTemporaryMemory Size : %x\n", BootLoaderTempRamSize));
+
+ CopyMem (BootLoaderTempRamHob, (VOID *)BootLoaderTempRamStart, BootLoaderTempRamSize);
+ OffsetGap = (UINT32)BootLoaderTempRamHob - BootLoaderTempRamStart;
+
+ //
+ // Fix the FspMemoryinit Parameter Pointers to the new location.
+ //
+ FspParamPtr = GetFspApiParameter ();
+ if ((VOID *)FspParamPtr != NULL && FspParamPtr >= BootLoaderTempRamStart &&
+ FspParamPtr < BootLoaderTempRamEnd) {
+ SetFspApiParameter (FspParamPtr + OffsetGap);
+ }
+
+ //
+ // Update UPD pointer in FSP Global Data
+ //
+ MemoryInitUpdPtr = (UINT32)((UINT32 *)GetFspMemoryInitUpdDataPointer ());
+ if (MemoryInitUpdPtr >= BootLoaderTempRamStart && MemoryInitUpdPtr < BootLoaderTempRamEnd) {
+ SetFspMemoryInitUpdDataPointer ((VOID *)(MemoryInitUpdPtr + OffsetGap));
+ }
+
+ //
+ // Update Platform data pointer in FSP Global Data
+ //
+ PlatformDataPtr = GetFspPlatformDataPointer ();
+ if (((UINT32)PlatformDataPtr >= BootLoaderTempRamStart) &&
+ ((UINT32)PlatformDataPtr < BootLoaderTempRamEnd)) {
+ SetFspPlatformDataPointer ((UINT8 *)PlatformDataPtr + OffsetGap);
+ }
+}
diff --git a/IntelFsp2Pkg/Library/BaseFspPlatformLib/FspPlatformNotify.c b/IntelFsp2Pkg/Library/BaseFspPlatformLib/FspPlatformNotify.c
new file mode 100644
index 0000000000..66b6cdb878
--- /dev/null
+++ b/IntelFsp2Pkg/Library/BaseFspPlatformLib/FspPlatformNotify.c
@@ -0,0 +1,279 @@
+/** @file
+
+ Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#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.
+
+**/
+VOID
+EFIAPI
+FspSiliconInitDone (
+ VOID
+ )
+{
+ //
+ // 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() - End\n"));
+
+ PERF_END_EX (&gFspPerformanceDataGuid, "EventRec", NULL, 0, 0x907F);
+
+ REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
+ SetFspApiReturnStatus (EFI_SUCCESS);
+
+ Pei2LoaderSwitchStack();
+
+ PERF_START_EX (&gFspPerformanceDataGuid, "EventRec", NULL, 0, 0x6000);
+}
+
+/**
+ This function returns control to BootLoader after MemoryInitApi.
+
+ @param[in,out] HobListPtr The address of HobList pointer.
+**/
+VOID
+EFIAPI
+FspMemoryInitDone (
+ IN OUT VOID **HobListPtr
+ )
+{
+ //
+ // Calling use FspMemoryInit API
+ // Update HOB and return the control directly
+ //
+ if (HobListPtr != NULL) {
+ *HobListPtr = (VOID *) GetHobList ();
+ }
+
+ //
+ // This is the end of the FspMemoryInit API
+ // Give control back to the boot loader
+ //
+ SetFspMeasurePoint (FSP_PERF_ID_API_FSP_MEMORY_INIT_EXIT);
+ DEBUG ((DEBUG_INFO | DEBUG_INIT, "FspMemoryInitApi() - End\n"));
+ REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_MEMORY_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
+ SetFspApiReturnStatus (EFI_SUCCESS);
+ Pei2LoaderSwitchStack ();
+
+ //
+ // The TempRamExitApi is called
+ //
+ if (GetFspApiCallingIndex () == TempRamExitApiIndex) {
+ SetPhaseStatusCode (FSP_STATUS_CODE_TEMP_RAM_EXIT);
+ REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_TEMP_RAM_EXIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
+ SetFspMeasurePoint (FSP_PERF_ID_API_TEMP_RAM_EXIT_ENTRY);
+ DEBUG ((DEBUG_INFO | DEBUG_INIT, "TempRamExitApi() - Begin\n"));
+ } else {
+ SetFspMeasurePoint (FSP_PERF_ID_API_FSP_SILICON_INIT_ENTRY);
+ DEBUG ((DEBUG_INFO | DEBUG_INIT, "FspSiliconInitApi() - Begin\n"));
+ SetPhaseStatusCode (FSP_STATUS_CODE_SILICON_INIT);
+ REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_SILICON_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
+ }
+}
+
+/**
+ This function returns control to BootLoader after TempRamExitApi.
+
+**/
+VOID
+EFIAPI
+FspTempRamExitDone (
+ VOID
+ )
+{
+
+ //
+ // This is the end of the TempRamExit API
+ // Give control back to the boot loader
+ //
+ SetFspMeasurePoint (FSP_PERF_ID_API_TEMP_RAM_EXIT_EXIT);
+ DEBUG ((DEBUG_INFO | DEBUG_INIT, "TempRamExitApi() - End\n"));
+ REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_TEMP_RAM_EXIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
+ SetFspApiReturnStatus (EFI_SUCCESS);
+ Pei2LoaderSwitchStack ();
+
+ SetPhaseStatusCode (FSP_STATUS_CODE_SILICON_INIT);
+ SetFspMeasurePoint (FSP_PERF_ID_API_FSP_SILICON_INIT_ENTRY);
+ DEBUG ((DEBUG_INFO | DEBUG_INIT, "SiliconInitApi() - Begin\n"));
+ REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_SILICON_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
+}
+
+/**
+ 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;
+
+ 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);
+ 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);
+ 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);
+ 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++;
+ }
+ }
+
+ SetFspApiReturnStatus(Status);
+ 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) {
+ 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) {
+ 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) {
+ REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
+ }
+ Pei2LoaderSwitchStack();
+ }
+
+ //
+ // 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.
+ //
+}
+
diff --git a/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/BaseFspSwitchStackLib.inf b/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/BaseFspSwitchStackLib.inf
new file mode 100644
index 0000000000..bbeeb744ff
--- /dev/null
+++ b/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/BaseFspSwitchStackLib.inf
@@ -0,0 +1,43 @@
+## @file
+# Instance of BaseFspSwitchStackLib
+#
+# Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[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.asm | MSFT
+ Ia32/Stack.s | GCC
+
+[Packages]
+ MdePkg/MdePkg.dec
+ IntelFsp2Pkg/IntelFsp2Pkg.dec
+
+[LibraryClasses]
+ BaseLib
+ IoLib
+
+[FixedPcd]
+ gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxPatchEntry ## CONSUMES
+ gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxPerfEntry ## CONSUMES
+
+
+
diff --git a/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/FspSwitchStackLib.c b/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/FspSwitchStackLib.c
new file mode 100644
index 0000000000..42a57a27c0
--- /dev/null
+++ b/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/FspSwitchStackLib.c
@@ -0,0 +1,42 @@
+/** @file
+
+ Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#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/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/Ia32/Stack.asm b/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/Ia32/Stack.asm
new file mode 100644
index 0000000000..1efab52059
--- /dev/null
+++ b/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/Ia32/Stack.asm
@@ -0,0 +1,77 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;
+; Abstract:
+;
+; Switch the stack from temporary memory to permenent memory.
+;
+;------------------------------------------------------------------------------
+
+ .586p
+ .model flat,C
+ .code
+
+;------------------------------------------------------------------------------
+; UINT32
+; EFIAPI
+; Pei2LoaderSwitchStack (
+; VOID
+; )
+;------------------------------------------------------------------------------
+EXTERNDEF C MeasurePoint:PROC
+Pei2LoaderSwitchStack PROC C PUBLIC
+ xor eax, eax
+ jmp FspSwitchStack
+Pei2LoaderSwitchStack ENDP
+
+;------------------------------------------------------------------------------
+; UINT32
+; EFIAPI
+; Loader2PeiSwitchStack (
+; VOID
+; )
+;------------------------------------------------------------------------------
+Loader2PeiSwitchStack PROC C PUBLIC
+ jmp FspSwitchStack
+Loader2PeiSwitchStack ENDP
+
+;------------------------------------------------------------------------------
+; UINT32
+; EFIAPI
+; FspSwitchStack (
+; VOID
+; )
+;------------------------------------------------------------------------------
+EXTERNDEF C SwapStack:PROC
+FspSwitchStack PROC C PUBLIC
+ ; Save current contexts
+ push eax
+ pushfd
+ cli
+ pushad
+ sub esp, 8
+ sidt fword ptr [esp]
+
+ ; Load new stack
+ push esp
+ call SwapStack
+ mov esp, eax
+
+ ; Restore previous contexts
+ lidt fword ptr [esp]
+ add esp, 8
+ popad
+ popfd
+ add esp, 4
+ ret
+FspSwitchStack ENDP
+
+ END
diff --git a/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/Ia32/Stack.s b/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/Ia32/Stack.s
new file mode 100644
index 0000000000..a21a5b6c61
--- /dev/null
+++ b/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/Ia32/Stack.s
@@ -0,0 +1,78 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+# Abstract:
+#
+# Switch the stack from temporary memory to permenent memory.
+#
+#------------------------------------------------------------------------------
+
+
+#------------------------------------------------------------------------------
+# UINT32
+# EFIAPI
+# Pei2LoaderSwitchStack (
+# VOID
+# )
+#------------------------------------------------------------------------------
+ASM_GLOBAL ASM_PFX(Pei2LoaderSwitchStack)
+ASM_PFX(Pei2LoaderSwitchStack):
+ xorl %eax, %eax
+ jmp ASM_PFX(FspSwitchStack)
+
+#------------------------------------------------------------------------------
+# UINT32
+# EFIAPI
+# Loader2PeiSwitchStack (
+# VOID
+# )
+#------------------------------------------------------------------------------
+ASM_GLOBAL ASM_PFX(Loader2PeiSwitchStack)
+ASM_PFX(Loader2PeiSwitchStack):
+ jmp ASM_PFX(FspSwitchStack)
+
+#------------------------------------------------------------------------------
+# UINT32
+# EFIAPI
+# FspSwitchStack (
+# VOID
+# )
+#------------------------------------------------------------------------------
+ASM_GLOBAL ASM_PFX(FspSwitchStack)
+ASM_PFX(FspSwitchStack):
+ #
+ #Save current contexts
+ #
+ push %eax
+ pushf
+ cli
+ pusha
+ sub $0x08, %esp
+ sidt (%esp)
+
+ #
+ # Load new stack
+ #
+ push %esp
+ call ASM_PFX(SwapStack)
+ movl %eax, %esp
+
+ #
+ # Restore previous contexts
+ #
+ lidt (%esp)
+ add $0x08,%esp
+ popa
+ popf
+ add $0x04,%esp
+ ret
+
+
diff --git a/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/Flat32.asm b/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/Flat32.asm
new file mode 100644
index 0000000000..9f144fc4ca
--- /dev/null
+++ b/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/Flat32.asm
@@ -0,0 +1,131 @@
+;; @file
+; This is the code that goes from real-mode to protected mode.
+; It consumes the reset vector, configures the stack.
+;
+; Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;;
+
+;
+; Define assembler characteristics
+;
+.586p
+.xmm
+.model flat, c
+
+EXTRN TempRamInitApi:NEAR
+
+.code
+
+RET_ESI MACRO
+
+ movd esi, mm7 ; restore ESP from MM7
+ jmp esi
+
+ENDM
+
+;
+; Perform early platform initialization
+;
+SecPlatformInit PROC NEAR PUBLIC
+
+ RET_ESI
+
+SecPlatformInit ENDP
+
+;
+; 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 initilaisation
+; Setup a stack
+;
+;----------------------------------------------------------------------------
+
+ProtectedModeEntryPoint PROC NEAR C PUBLIC
+ ;
+ ; Dummy function. Consume 2 API to make sure they can be linked.
+ ;
+ mov eax, TempRamInitApi
+
+ ; Should never return
+ jmp $
+
+ProtectedModeEntryPoint ENDP
+
+;
+; ROM-based Global-Descriptor Table for the PEI Phase
+;
+align 16
+PUBLIC BootGdtTable
+
+;
+; GDT[0]: 0x00: Null entry, never used.
+;
+NULL_SEL equ $ - GDT_BASE ; Selector [0]
+GDT_BASE:
+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 $ - BootGDTtable ; Size, in bytes
+
+;
+; GDT Descriptor
+;
+GdtDesc: ; GDT descriptor
+ DW GDT_SIZE - 1 ; GDT limit
+ DD OFFSET BootGdtTable ; GDT base address
+
+ProtectedModeEntryLinearAddress LABEL FWORD
+ProtectedModeEntryLinearOffset LABEL DWORD
+ DD OFFSET ProtectedModeEntryPoint ; Offset of our 32 bit code
+ DW LINEAR_CODE_SEL
+
+END
diff --git a/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/Flat32.s b/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/Flat32.s
new file mode 100644
index 0000000000..d46d792477
--- /dev/null
+++ b/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/Flat32.s
@@ -0,0 +1,110 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+# Abstract:
+#
+# This is the code that goes from real-mode to protected mode.
+# It consumes the reset vector, configures the stack.
+#
+#------------------------------------------------------------------------------
+
+
+#
+# Contrary to the name, this file contains 16 bit code as well.
+#
+.text
+
+ASM_GLOBAL ASM_PFX(SecPlatformInit)
+ASM_PFX(SecPlatformInit):
+ movd %mm7, %esi # restore ESP from MM7
+ jmp *%esi
+
+#----------------------------------------------------------------------------
+#
+# 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 initilaisation
+# Setup a stack
+#
+#----------------------------------------------------------------------------
+ProtectedModeEntryPoint:
+ #
+ # Dummy function. Consume 2 API to make sure they can be linked.
+ #
+ movl ASM_PFX(TempRamInitApi), %eax
+ #
+ # Should never return
+ #
+ jmp . #'$'
+
+#
+# ROM-based Global-Descriptor Table for the PEI Phase
+#
+.align 16
+#
+# GDT[0]: 000h: Null entry, never used.
+#
+.equ NULL_SEL, . - GDT_BASE # Selector [0]
+GDT_BASE:
+BootGdtTable:
+ .long 0
+ .long 0
+#
+# Linear code segment descriptor
+#
+.equ LINEAR_CODE_SEL, . - GDT_BASE # Selector [08h]
+ .word 0xFFFF # limit 0FFFFh
+ .word 0 # base 0
+ .byte 0
+ .byte 0x9B # present, ring 0, data, expand-up, not-writable
+ .byte 0xCF # page-granular, 32-bit
+ .byte 0
+#
+# System data segment descriptor
+#
+.equ SYS_DATA_SEL, . - GDT_BASE # Selector [010h]
+ .word 0xFFFF # limit 0FFFFh
+ .word 0 # base 0
+ .byte 0
+ .byte 0x93 # present, ring 0, data, expand-up, not-writable
+ .byte 0xCF # page-granular, 32-bit
+ .byte 0
+
+.equ GDT_SIZE, . - BootGdtTable # Size, in bytes
+
+#
+# GDT Descriptor
+#
+GdtDesc: # GDT descriptor
+ .word GDT_SIZE - 1
+ .long BootGdtTable
+
+ProtectedModeEntryLinearAddress:
+ProtectedModeEntryLinearOffset:
+ .long ProtectedModeEntryPoint
+ .word LINEAR_CODE_SEL
diff --git a/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/SecCarInit.asm b/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/SecCarInit.asm
new file mode 100644
index 0000000000..31296e0043
--- /dev/null
+++ b/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/SecCarInit.asm
@@ -0,0 +1,51 @@
+;; @file
+; SEC CAR function
+;
+; Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;;
+
+;
+; Define assembler characteristics
+;
+.586p
+.xmm
+.model flat, c
+
+RET_ESI MACRO
+
+ movd esi, mm7 ; move ReturnAddress from MM7 to ESI
+ jmp esi
+
+ENDM
+
+.code
+
+;-----------------------------------------------------------------------------
+;
+; Section: SecCarInit
+;
+; Description: This function initializes the Cache for Data, Stack, and Code
+;
+;-----------------------------------------------------------------------------
+SecCarInit PROC NEAR PUBLIC
+
+ ;
+ ; Set up CAR
+ ;
+
+ xor eax, eax
+
+SecCarInitExit:
+
+ RET_ESI
+
+SecCarInit ENDP
+
+END
diff --git a/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/SecCarInit.s b/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/SecCarInit.s
new file mode 100644
index 0000000000..7bd40df36a
--- /dev/null
+++ b/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/Ia32/SecCarInit.s
@@ -0,0 +1,37 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+# Abstract:
+#
+# SEC CAR function
+#
+#------------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------
+#
+# Section: SecCarInit
+#
+# Description: This function initializes the Cache for Data, Stack, and Code
+#
+#-----------------------------------------------------------------------------
+ASM_GLOBAL ASM_PFX(SecCarInit)
+ASM_PFX(SecCarInit):
+
+ #
+ # Set up CAR
+ #
+
+ xor %eax, %eax
+
+SecCarInitExit:
+
+ movd %mm7, %esi #RET_ESI
+ jmp *%esi
diff --git a/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/PlatformSecLibNull.c b/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/PlatformSecLibNull.c
new file mode 100644
index 0000000000..7bb95a9054
--- /dev/null
+++ b/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/PlatformSecLibNull.c
@@ -0,0 +1,33 @@
+/** @file
+ Null instance of Platform Sec Lib.
+
+ Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PiPei.h>
+#include <Library/FspCommonLib.h>
+
+/**
+ This function check the signture 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;
+}
diff --git a/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/SecFspSecPlatformLibNull.inf b/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/SecFspSecPlatformLibNull.inf
new file mode 100644
index 0000000000..1c18a587c3
--- /dev/null
+++ b/IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/SecFspSecPlatformLibNull.inf
@@ -0,0 +1,58 @@
+## @file
+# NULL instance of Platform Sec Lib.
+#
+# Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+################################################################################
+#
+# 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.asm
+ Ia32/Flat32.s
+ Ia32/SecCarInit.asm
+ Ia32/SecCarInit.s
+
+################################################################################
+#
+# Package Dependency Section - list of Package files that are required for
+# this module.
+#
+################################################################################
+
+[Packages]
+ MdePkg/MdePkg.dec
+ IntelFsp2Pkg/IntelFsp2Pkg.dec