summaryrefslogtreecommitdiff
path: root/Platform
diff options
context:
space:
mode:
authorGuo Mang <mang.guo@intel.com>2016-12-23 14:34:18 +0800
committerGuo Mang <mang.guo@intel.com>2016-12-26 19:15:26 +0800
commitb7d3a1c6e9df0b25d55d2855ffb989d5c164e60c (patch)
treef70ed29957d1052d474b3401f512897bf4c960eb /Platform
parent81edad70bc022223fbf68f0ac8cbff5a45cbb947 (diff)
downloadedk2-platforms-b7d3a1c6e9df0b25d55d2855ffb989d5c164e60c.tar.xz
BroxtonPlatformPkg: Add IntelFsp2WrapperPkg
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Guo Mang <mang.guo@intel.com>
Diffstat (limited to 'Platform')
-rw-r--r--Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspInitPei/FindPeiCore.c200
-rw-r--r--Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspInitPei/SecMain.c312
-rw-r--r--Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspInitPei/SecMain.h118
-rw-r--r--Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspNotifyDxe/FspNotifyDxe.c261
-rw-r--r--Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspNotifyDxe/FspNotifyDxe.inf76
-rw-r--r--Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspNotifyDxe/LoadBelow4G.c151
-rw-r--r--Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.c266
-rw-r--r--Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.inf105
-rw-r--r--Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.c332
-rw-r--r--Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.inf105
-rw-r--r--Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Include/Library/FspHobProcessLib.h71
-rw-r--r--Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Include/Library/FspPlatformInfoLib.h167
-rw-r--r--Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Include/Library/FspPlatformSecLib.h71
-rw-r--r--Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec113
-rw-r--r--Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/BaseFspWrapperApiLib.inf73
-rw-r--r--Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/FspWrapperApiLib.c222
-rw-r--r--Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/IA32/DispatchExecute.c61
-rw-r--r--Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/DispatchExecute.c111
-rw-r--r--Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/Thunk64To32.S224
-rw-r--r--Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/Thunk64To32.asm227
-rw-r--r--Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/FspPlatformSecLibSample.c153
-rw-r--r--Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/AsmSaveSecContext.S37
-rw-r--r--Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/AsmSaveSecContext.asm45
-rw-r--r--Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Fsp.h50
-rw-r--r--Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/PeiCoreEntry.S124
-rw-r--r--Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/PeiCoreEntry.asm135
-rw-r--r--Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/SecEntry.S322
-rw-r--r--Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/SecEntry.asm340
-rw-r--r--Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Stack.S74
-rw-r--r--Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Stack.asm81
-rw-r--r--Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/PlatformInit.c44
-rw-r--r--Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SaveSecContext.c115
-rw-r--r--Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecGetPerformance.c92
-rw-r--r--Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPeiFspPlatformSecLibSample.inf97
-rw-r--r--Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPeiFspPlatformSecLibSample.unibin0 -> 1700 bytes
-rw-r--r--Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPlatformInformation.c86
-rw-r--r--Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecRamInitData.c24
-rw-r--r--Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecTempRamSupport.c148
-rw-r--r--Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Tools/fsptool.py365
39 files changed, 5598 insertions, 0 deletions
diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspInitPei/FindPeiCore.c b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspInitPei/FindPeiCore.c
new file mode 100644
index 0000000000..b2bf25349f
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspInitPei/FindPeiCore.c
@@ -0,0 +1,200 @@
+/** @file
+ Locate the entry point for the PEI Core.
+
+ 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/PeCoffGetEntryPointLib.h>
+
+#include "SecMain.h"
+
+/**
+ Find core image base.
+
+ @param[in] BootFirmwareVolumePtr Point to the boot firmware volume.
+ @param[out] SecCoreImageBase The base address of the SEC core image.
+ @param[out] PeiCoreImageBase The base address of the PEI core image.
+
+**/
+EFI_STATUS
+EFIAPI
+FindImageBase (
+ IN EFI_FIRMWARE_VOLUME_HEADER *BootFirmwareVolumePtr,
+ OUT EFI_PHYSICAL_ADDRESS *SecCoreImageBase,
+ OUT EFI_PHYSICAL_ADDRESS *PeiCoreImageBase
+ )
+{
+ EFI_PHYSICAL_ADDRESS CurrentAddress;
+ EFI_PHYSICAL_ADDRESS EndOfFirmwareVolume;
+ EFI_FFS_FILE_HEADER *File;
+ UINT32 Size;
+ EFI_PHYSICAL_ADDRESS EndOfFile;
+ EFI_COMMON_SECTION_HEADER *Section;
+ EFI_PHYSICAL_ADDRESS EndOfSection;
+
+ *SecCoreImageBase = 0;
+ *PeiCoreImageBase = 0;
+
+ CurrentAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) BootFirmwareVolumePtr;
+ EndOfFirmwareVolume = CurrentAddress + BootFirmwareVolumePtr->FvLength;
+
+ //
+ // Loop through the FFS files in the Boot Firmware Volume
+ //
+ for (EndOfFile = CurrentAddress + BootFirmwareVolumePtr->HeaderLength; ; ) {
+
+ CurrentAddress = (EndOfFile + 7) & 0xfffffffffffffff8ULL;
+ if (CurrentAddress > EndOfFirmwareVolume) {
+ return EFI_NOT_FOUND;
+ }
+
+ File = (EFI_FFS_FILE_HEADER*)(UINTN) CurrentAddress;
+ if (IS_FFS_FILE2 (File)) {
+ Size = FFS_FILE2_SIZE (File);
+ if (Size <= 0x00FFFFFF) {
+ return EFI_NOT_FOUND;
+ }
+ } else {
+ Size = FFS_FILE_SIZE (File);
+ if (Size < sizeof (EFI_FFS_FILE_HEADER)) {
+ return EFI_NOT_FOUND;
+ }
+ }
+
+ EndOfFile = CurrentAddress + Size;
+ if (EndOfFile > EndOfFirmwareVolume) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Look for SEC Core / PEI Core files
+ //
+ if (File->Type != EFI_FV_FILETYPE_SECURITY_CORE &&
+ File->Type != EFI_FV_FILETYPE_PEI_CORE) {
+ continue;
+ }
+
+ //
+ // Loop through the FFS file sections within the FFS file
+ //
+ if (IS_FFS_FILE2 (File)) {
+ EndOfSection = (EFI_PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) File + sizeof (EFI_FFS_FILE_HEADER2));
+ } else {
+ EndOfSection = (EFI_PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) File + sizeof (EFI_FFS_FILE_HEADER));
+ }
+ for (;;) {
+ CurrentAddress = (EndOfSection + 3) & 0xfffffffffffffffcULL;
+ Section = (EFI_COMMON_SECTION_HEADER*)(UINTN) CurrentAddress;
+
+ if (IS_SECTION2 (Section)) {
+ Size = SECTION2_SIZE (Section);
+ if (Size <= 0x00FFFFFF) {
+ return EFI_NOT_FOUND;
+ }
+ } else {
+ Size = SECTION_SIZE (Section);
+ if (Size < sizeof (EFI_COMMON_SECTION_HEADER)) {
+ return EFI_NOT_FOUND;
+ }
+ }
+
+ EndOfSection = CurrentAddress + Size;
+ if (EndOfSection > EndOfFile) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Look for executable sections
+ //
+ if (Section->Type == EFI_SECTION_PE32 || Section->Type == EFI_SECTION_TE) {
+ if (File->Type == EFI_FV_FILETYPE_SECURITY_CORE) {
+ if (IS_SECTION2 (Section)) {
+ *SecCoreImageBase = (PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER2));
+ } else {
+ *SecCoreImageBase = (PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER));
+ }
+ } else {
+ if (IS_SECTION2 (Section)) {
+ *PeiCoreImageBase = (PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER2));
+ } else {
+ *PeiCoreImageBase = (PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER));
+ }
+ }
+ break;
+ }
+ }
+
+ //
+ // Both SEC Core and PEI Core images found
+ //
+ if (*SecCoreImageBase != 0 && *PeiCoreImageBase != 0) {
+ return EFI_SUCCESS;
+ }
+ }
+}
+
+/**
+ Find and return Pei Core entry point.
+
+ It also find SEC and PEI Core file debug inforamtion. It will report them if
+ remote debug is enabled.
+
+ @param[in] BootFirmwareVolumePtr Point to the boot firmware volume.
+ @param[out] PeiCoreEntryPoint The entry point of the PEI core.
+
+**/
+VOID
+EFIAPI
+FindAndReportEntryPoints (
+ IN EFI_FIRMWARE_VOLUME_HEADER *BootFirmwareVolumePtr,
+ OUT EFI_PEI_CORE_ENTRY_POINT *PeiCoreEntryPoint
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS SecCoreImageBase;
+ EFI_PHYSICAL_ADDRESS PeiCoreImageBase;
+ PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
+
+ //
+ // Find SEC Core and PEI Core image base
+ //
+ Status = FindImageBase (BootFirmwareVolumePtr, &SecCoreImageBase, &PeiCoreImageBase);
+ ASSERT_EFI_ERROR (Status);
+
+ ZeroMem ((VOID *) &ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT));
+ //
+ // Report SEC Core debug information when remote debug is enabled
+ //
+ ImageContext.ImageAddress = SecCoreImageBase;
+ ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) ImageContext.ImageAddress);
+ PeCoffLoaderRelocateImageExtraAction (&ImageContext);
+
+ //
+ // Report PEI Core debug information when remote debug is enabled
+ //
+ ImageContext.ImageAddress = PeiCoreImageBase;
+ ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) ImageContext.ImageAddress);
+ PeCoffLoaderRelocateImageExtraAction (&ImageContext);
+
+ //
+ // Find PEI Core entry point
+ //
+ Status = PeCoffLoaderGetEntryPoint ((VOID *) (UINTN) PeiCoreImageBase, (VOID**) PeiCoreEntryPoint);
+ if (EFI_ERROR (Status)) {
+ *PeiCoreEntryPoint = 0;
+ }
+
+ return;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspInitPei/SecMain.c b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspInitPei/SecMain.c
new file mode 100644
index 0000000000..05816c5a65
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspInitPei/SecMain.c
@@ -0,0 +1,312 @@
+/** @file
+ C functions in SEC.
+
+ 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 "SecMain.h"
+
+EFI_PEI_PPI_DESCRIPTOR mPeiSecMainPpi[] = {
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI,
+ &gTopOfTemporaryRamPpiGuid,
+ NULL // To be patched later.
+ },
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gFspSiliconInitDonePpiGuid,
+ &gFspSiliconInitDonePpi
+ },
+};
+
+FSP_SILICON_INIT_DONE_PPI gFspSiliconInitDonePpi = {
+ FspSiliconInitDoneGetFspHobList
+};
+
+//
+// These are IDT entries pointing to 10:FFFFFFE4h.
+//
+UINT64 mIdtEntryTemplate = 0xffff8e000010ffe4ULL;
+
+/**
+ Caller provided function to be invoked at the end of InitializeDebugAgent().
+
+ Entry point to the C language phase of SEC. After the SEC assembly
+ code has initialized some temporary memory and set up the stack,
+ the control is transferred to this function.
+
+ @param[in] Context The first input parameter of InitializeDebugAgent().
+
+**/
+VOID
+EFIAPI
+SecStartupPhase2(
+ IN VOID *Context
+ );
+
+
+/**
+ Entry point to the C language phase of SEC. After the SEC assembly
+ code has initialized some temporary memory and set up the stack,
+ the control is transferred to this function.
+
+ @param[in] SizeOfRam Size of the temporary memory available for use.
+ @param[in] TempRamBase Base address of tempory ram
+ @param[in] BootFirmwareVolume Base address of the Boot Firmware Volume.
+
+**/
+VOID
+EFIAPI
+SecStartup (
+ IN UINT32 SizeOfRam,
+ IN UINT32 TempRamBase,
+ IN VOID *BootFirmwareVolume
+ )
+{
+ EFI_SEC_PEI_HAND_OFF SecCoreData;
+ IA32_DESCRIPTOR IdtDescriptor;
+ SEC_IDT_TABLE IdtTableInStack;
+ UINT32 Index;
+ UINT32 PeiStackSize;
+
+ PeiStackSize = PcdGet32 (PcdPeiTemporaryRamStackSize);
+ if (PeiStackSize == 0) {
+ PeiStackSize = (SizeOfRam >> 1);
+ }
+
+ ASSERT (PeiStackSize < SizeOfRam);
+
+ //
+ // Process all libraries constructor function linked to SecCore.
+ //
+ ProcessLibraryConstructorList ();
+
+ DEBUG ((DEBUG_INFO, "FspPei - SecStartup\n"));
+
+ //
+ // Initialize floating point operating environment
+ // to be compliant with UEFI spec.
+ //
+ InitializeFloatingPointUnits ();
+
+
+ // |-------------------|---->
+ // |Idt Table |
+ // |-------------------|
+ // |PeiService Pointer | PeiStackSize
+ // |-------------------|
+ // | |
+ // | Stack |
+ // |-------------------|---->
+ // | |
+ // | |
+ // | Heap | PeiTemporayRamSize
+ // | |
+ // | |
+ // |-------------------|----> TempRamBase
+
+ IdtTableInStack.PeiService = 0;
+ for (Index = 0; Index < SEC_IDT_ENTRY_COUNT; Index ++) {
+ CopyMem ((VOID*)&IdtTableInStack.IdtTable[Index], (VOID*)&mIdtEntryTemplate, sizeof (UINT64));
+ }
+
+ IdtDescriptor.Base = (UINTN) &IdtTableInStack.IdtTable;
+ IdtDescriptor.Limit = (UINT16)(sizeof (IdtTableInStack.IdtTable) - 1);
+
+ AsmWriteIdtr (&IdtDescriptor);
+
+ //
+ // Update the base address and length of Pei temporary memory
+ //
+ SecCoreData.DataSize = (UINT16) sizeof (EFI_SEC_PEI_HAND_OFF);
+ SecCoreData.BootFirmwareVolumeBase = BootFirmwareVolume;
+ SecCoreData.BootFirmwareVolumeSize = (UINTN) (SIZE_4GB - (UINTN) BootFirmwareVolume);
+ SecCoreData.TemporaryRamBase = (VOID*) (UINTN) TempRamBase;
+ SecCoreData.TemporaryRamSize = SizeOfRam;
+ SecCoreData.PeiTemporaryRamBase = SecCoreData.TemporaryRamBase;
+ SecCoreData.PeiTemporaryRamSize = SizeOfRam - PeiStackSize;
+ SecCoreData.StackBase = (VOID*) (UINTN) (TempRamBase + SecCoreData.PeiTemporaryRamSize);
+ SecCoreData.StackSize = PeiStackSize;
+
+ DEBUG ((DEBUG_INFO, "FspWrapper BootFirmwareVolumeBase - 0x%x\n", SecCoreData.BootFirmwareVolumeBase));
+ DEBUG ((DEBUG_INFO, "FspWrapper BootFirmwareVolumeSize - 0x%x\n", SecCoreData.BootFirmwareVolumeSize));
+ DEBUG ((DEBUG_INFO, "FspWrapper TemporaryRamBase - 0x%x\n", SecCoreData.TemporaryRamBase));
+ DEBUG ((DEBUG_INFO, "FspWrapper TemporaryRamSize - 0x%x\n", SecCoreData.TemporaryRamSize));
+ DEBUG ((DEBUG_INFO, "FspWrapper PeiTemporaryRamBase - 0x%x\n", SecCoreData.PeiTemporaryRamBase));
+ DEBUG ((DEBUG_INFO, "FspWrapper PeiTemporaryRamSize - 0x%x\n", SecCoreData.PeiTemporaryRamSize));
+ DEBUG ((DEBUG_INFO, "FspWrapper StackBase - 0x%x\n", SecCoreData.StackBase));
+ DEBUG ((DEBUG_INFO, "FspWrapper StackSize - 0x%x\n", SecCoreData.StackSize));
+
+ //
+ // Initialize Debug Agent to support source level debug in SEC/PEI phases before memory ready.
+ //
+ InitializeDebugAgent (DEBUG_AGENT_INIT_PREMEM_SEC, &SecCoreData, SecStartupPhase2);
+
+}
+
+/**
+ This API patch the TopOfTemporaryRam value in SecPpiList.
+
+ @param[in,out] SecPpiList PPI list to be patched.
+ @param[in] TopOfTemporaryRam The top of Temporary Ram.
+
+**/
+VOID
+PatchTopOfTemporaryRamPpi (
+ IN OUT EFI_PEI_PPI_DESCRIPTOR *SecPpiList,
+ IN VOID *TopOfTemporaryRam
+ )
+{
+ SecPpiList[0].Ppi = TopOfTemporaryRam;
+}
+
+/**
+ Caller provided function to be invoked at the end of InitializeDebugAgent().
+
+ Entry point to the C language phase of SEC. After the SEC assembly
+ code has initialized some temporary memory and set up the stack,
+ the control is transferred to this function.
+
+ @param[in] Context The first input parameter of InitializeDebugAgent().
+
+**/
+VOID
+EFIAPI
+SecStartupPhase2(
+ IN VOID *Context
+ )
+{
+ EFI_SEC_PEI_HAND_OFF *SecCoreData;
+ EFI_PEI_PPI_DESCRIPTOR *PpiList;
+ UINT32 Index;
+ EFI_PEI_PPI_DESCRIPTOR LocalSecPpiList[sizeof (mPeiSecMainPpi) / sizeof (mPeiSecMainPpi[0])];
+ EFI_PEI_PPI_DESCRIPTOR AllSecPpiList[FixedPcdGet32(PcdSecCoreMaxPpiSupported)];
+ EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint;
+
+ SecCoreData = (EFI_SEC_PEI_HAND_OFF *) Context;
+ //
+ // Find Pei Core entry point. It will report SEC and Pei Core debug information if remote debug
+ // is enabled.
+ //
+ FindAndReportEntryPoints ((EFI_FIRMWARE_VOLUME_HEADER *) SecCoreData->BootFirmwareVolumeBase, &PeiCoreEntryPoint);
+ if (PeiCoreEntryPoint == NULL)
+ {
+ CpuDeadLoop ();
+ }
+
+ CopyMem (LocalSecPpiList, mPeiSecMainPpi, sizeof (mPeiSecMainPpi));
+ PatchTopOfTemporaryRamPpi (LocalSecPpiList, (VOID *) ((UINTN) SecCoreData->TemporaryRamBase + SecCoreData->TemporaryRamSize));
+
+ //
+ // Perform platform specific initialization before entering PeiCore.
+ //
+ PpiList = SecPlatformMain (SecCoreData);
+ if (PpiList != NULL) {
+ //
+ // Remove the terminal flag from the terminal Ppi
+ //
+ CopyMem (AllSecPpiList, LocalSecPpiList, sizeof (LocalSecPpiList));
+ for (Index = 0; Index < PcdGet32 (PcdSecCoreMaxPpiSupported); Index ++) {
+ if ((AllSecPpiList[Index].Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) == EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) {
+ break;
+ }
+ }
+ AllSecPpiList[Index].Flags = AllSecPpiList[Index].Flags & (~EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);
+
+ //
+ // Append the platform additional Ppi list
+ //
+ Index += 1;
+ while (Index < PcdGet32 (PcdSecCoreMaxPpiSupported) &&
+ ((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) != EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST)) {
+ CopyMem (&AllSecPpiList[Index], PpiList, sizeof (EFI_PEI_PPI_DESCRIPTOR));
+ Index++;
+ PpiList++;
+ }
+
+ //
+ // Check whether the total Ppis exceeds the max supported Ppi.
+ //
+ if (Index >= PcdGet32 (PcdSecCoreMaxPpiSupported)) {
+ //
+ // the total Ppi is larger than the supported Max
+ // PcdSecCoreMaxPpiSupported can be enlarged to solve it.
+ //
+ CpuDeadLoop ();
+ } else {
+ //
+ // Add the terminal Ppi
+ //
+ CopyMem (&AllSecPpiList[Index], PpiList, sizeof (EFI_PEI_PPI_DESCRIPTOR));
+ }
+
+ //
+ // Set PpiList to the total Ppi
+ //
+ PpiList = &AllSecPpiList[0];
+ } else {
+ //
+ // No addition Ppi, PpiList directly point to the common Ppi list.
+ //
+ PpiList = &LocalSecPpiList[0];
+ }
+
+ //
+ // Transfer the control to the PEI core
+ //
+ ASSERT (PeiCoreEntryPoint != NULL);
+ (*PeiCoreEntryPoint) (SecCoreData, PpiList);
+
+ //
+ // Should not come here.
+ //
+ return ;
+}
+
+/**
+ Return Hob list produced by FSP.
+
+ @param[in] PeiServices The pointer to the PEI Services Table.
+ @param[in] This The pointer to this instance of this PPI.
+ @param[out] FspHobList The pointer to Hob list produced by FSP.
+
+ @return EFI_SUCCESS FReturn Hob list produced by FSP successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+FspSiliconInitDoneGetFspHobList (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN FSP_SILICON_INIT_DONE_PPI *This,
+ OUT VOID **FspHobList
+ )
+{
+ VOID *TopOfTemporaryRamPpi;
+ EFI_STATUS Status;
+
+ Status = (*PeiServices)->LocatePpi (
+ PeiServices,
+ &gTopOfTemporaryRamPpiGuid,
+ 0,
+ NULL,
+ (VOID **) &TopOfTemporaryRamPpi
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_NOT_FOUND;
+ }
+
+ *FspHobList = (VOID *) (UINTN) (*(UINT32 *) ((UINTN) TopOfTemporaryRamPpi - sizeof (UINT32)));
+
+ return EFI_SUCCESS;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspInitPei/SecMain.h b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspInitPei/SecMain.h
new file mode 100644
index 0000000000..68688c5cbd
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspInitPei/SecMain.h
@@ -0,0 +1,118 @@
+/** @file
+ Master header file for SecCore.
+
+ 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.
+
+**/
+
+#ifndef _SEC_CORE_H_
+#define _SEC_CORE_H_
+
+#include <PiPei.h>
+
+#include <Ppi/TopOfTemporaryRam.h>
+#include <Ppi/FspSiliconInitDone.h>
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/FspPlatformSecLib.h>
+#include <Library/FspPlatformInfoLib.h>
+#include <Library/UefiCpuLib.h>
+#include <Library/PeCoffGetEntryPointLib.h>
+#include <Library/PeCoffExtraActionLib.h>
+#include <Library/DebugAgentLib.h>
+
+#include <FspEas.h>
+
+#define SEC_IDT_ENTRY_COUNT 34
+
+typedef struct _SEC_IDT_TABLE {
+ //
+ // Reserved 8 bytes preceding IDT to store EFI_PEI_SERVICES**, since IDT base
+ // address should be 8-byte alignment.
+ // Note: For IA32, only the 4 bytes immediately preceding IDT is used to store
+ // EFI_PEI_SERVICES**
+ //
+ UINT64 PeiService;
+ UINT64 IdtTable[SEC_IDT_ENTRY_COUNT];
+} SEC_IDT_TABLE;
+
+/**
+ Entry point to the C language phase of SEC. After the SEC assembly
+ code has initialized some temporary memory and set up the stack,
+ the control is transferred to this function.
+
+ @param[in] SizeOfRam Size of the temporary memory available for use.
+ @param[in] TempRamBase Base address of tempory ram
+ @param[in] BootFirmwareVolume Base address of the Boot Firmware Volume.
+
+**/
+VOID
+EFIAPI
+SecStartup (
+ IN UINT32 SizeOfRam,
+ IN UINT32 TempRamBase,
+ IN VOID *BootFirmwareVolume
+ );
+
+/**
+ Find and return Pei Core entry point.
+
+ It also find SEC and PEI Core file debug inforamtion. It will report them if
+ remote debug is enabled.
+
+ @param[in] BootFirmwareVolumePtr Point to the boot firmware volume.
+ @param[out] PeiCoreEntryPoint Point to the PEI core entry point.
+
+**/
+VOID
+EFIAPI
+FindAndReportEntryPoints (
+ IN EFI_FIRMWARE_VOLUME_HEADER *BootFirmwareVolumePtr,
+ OUT EFI_PEI_CORE_ENTRY_POINT *PeiCoreEntryPoint
+ );
+
+/**
+ Autogenerated function that calls the library constructors for all of the module's
+ dependent libraries. This function must be called by the SEC Core once a stack has
+ been established.
+
+**/
+VOID
+EFIAPI
+ProcessLibraryConstructorList (
+ VOID
+ );
+
+/**
+ Return Hob list produced by FSP.
+
+ @param[in] PeiServices The pointer to the PEI Services Table.
+ @param[in] This The pointer to this instance of this PPI.
+ @param[out] FspHobList The pointer to Hob list produced by FSP.
+
+ @return EFI_SUCCESS FReturn Hob list produced by FSP successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+FspSiliconInitDoneGetFspHobList (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN FSP_SILICON_INIT_DONE_PPI *This,
+ OUT VOID **FspHobList
+ );
+
+extern FSP_SILICON_INIT_DONE_PPI gFspSiliconInitDonePpi;
+
+#endif
+
diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspNotifyDxe/FspNotifyDxe.c b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspNotifyDxe/FspNotifyDxe.c
new file mode 100644
index 0000000000..8d023416ee
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspNotifyDxe/FspNotifyDxe.c
@@ -0,0 +1,261 @@
+/** @file
+ This driver will register two callbacks to call fsp's notifies.
+
+ 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 <PiDxe.h>
+
+#include <Protocol/PciEnumerationComplete.h>
+
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiLib.h>
+#include <Library/FspWrapperApiLib.h>
+#include <Library/PerformanceLib.h>
+#include <Library/HobLib.h>
+#include <FspStatusCode.h>
+
+typedef
+EFI_STATUS
+(EFIAPI * ADD_PERFORMANCE_RECORDS)(
+ IN CONST VOID *HobStart
+ );
+
+struct _ADD_PERFORMANCE_RECORD_PROTOCOL {
+ ADD_PERFORMANCE_RECORDS AddPerformanceRecords;
+};
+
+typedef struct _ADD_PERFORMANCE_RECORD_PROTOCOL ADD_PERFORMANCE_RECORD_PROTOCOL;
+
+
+extern EFI_GUID gAddPerfRecordProtocolGuid;
+extern EFI_GUID gFspHobGuid;
+extern EFI_GUID gFspApiPerformanceGuid;
+
+EFI_EVENT mExitBootServicesEvent = NULL;
+
+/**
+ Perform platform related reset in FSP wrapper.
+
+ @param[in] ResetType The type of reset the platform has to perform.
+
+ @return Will reset the system based on Reset status provided.
+
+**/
+VOID
+EFIAPI
+CallFspWrapperResetSystem (
+ IN UINT32 ResetType
+ );
+
+/**
+ Relocate this image under 4G memory.
+
+ @param ImageHandle Handle of driver image.
+ @param SystemTable Pointer to system table.
+
+ @retval EFI_SUCCESS Image successfully relocated.
+ @retval EFI_ABORTED Failed to relocate image.
+
+**/
+EFI_STATUS
+RelocateImageUnder4GIfNeeded (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+FSP_INFO_HEADER *mFspHeader = NULL;
+
+/**
+ PciEnumerationComplete Protocol notification event handler.
+
+ @param[in] Event Event whose notification function is being invoked.
+ @param[in] Context Pointer to the notification function's context.
+
+**/
+VOID
+EFIAPI
+OnPciEnumerationComplete (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ return;
+}
+
+/**
+ Notification function of EVT_GROUP_READY_TO_BOOT event group.
+
+ This is a notification function registered on EVT_GROUP_READY_TO_BOOT event group.
+ When the Boot Manager is about to load and execute a boot option, it reclaims variable
+ storage if free size is below the threshold.
+
+ @param[in] Event Event whose notification function is being invoked.
+ @param[in] Context Pointer to the notification function's context.
+
+**/
+VOID
+EFIAPI
+OnReadyToBoot (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ NOTIFY_PHASE_PARAMS NotifyPhaseParams;
+ EFI_STATUS Status;
+ ADD_PERFORMANCE_RECORD_PROTOCOL *AddPerfRecordInterface;
+ EFI_PEI_HOB_POINTERS Hob;
+ VOID **FspHobListPtr;
+
+ gBS->CloseEvent (Event);
+ NotifyPhaseParams.Phase = EnumInitPhaseReadyToBoot;
+ PERF_START_EX (&gFspApiPerformanceGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION | FSP_STATUS_CODE_API_ENTRY);
+ Status = CallFspNotifyPhase (&NotifyPhaseParams);
+ PERF_END_EX (&gFspApiPerformanceGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION | FSP_STATUS_CODE_API_EXIT);
+
+ //
+ // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED status
+ //
+ if ((Status & ~(0xF)) == (FSP_STATUS_RESET_REQUIRED_COLD & ~(0xF))) {
+ DEBUG ((DEBUG_INFO, "FSP NotifyPhase ReadyToBoot requested reset 0x%x\n", Status));
+ CallFspWrapperResetSystem ((UINT32) Status);
+ }
+ if (Status != EFI_SUCCESS) {
+ DEBUG ((DEBUG_ERROR, "FSP NotifyPhase ReadyToBoot failed, status: 0x%x\n", Status));
+ } else {
+ DEBUG ((DEBUG_INFO, "FSP NotifyPhase ReadyToBoot Success.\n"));
+ }
+
+ Status = gBS->LocateProtocol (
+ &gAddPerfRecordProtocolGuid,
+ NULL,
+ (VOID **) &AddPerfRecordInterface
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_INFO, "gAddPerfRecordProtocolGuid - Locate protocol failed\n"));
+ return;
+ } else {
+ Hob.Raw = GetHobList ();
+ if (Hob.Raw != NULL) {
+ Hob.Raw = GetNextGuidHob (&gFspHobGuid, Hob.Raw);
+ FspHobListPtr = GET_GUID_HOB_DATA (Hob.Raw);
+ AddPerfRecordInterface->AddPerformanceRecords ((VOID *) (UINTN) (((UINT32) (UINTN) *FspHobListPtr) & 0xFFFFFFFF));
+ }
+ }
+}
+
+/**
+ This stage is notified just before the firmware/Preboot environment transfers
+ management of all system resources to the OS or next level execution environment.
+
+ @param Event Event whose notification function is being invoked.
+ @param Context Pointer to the notification function's context, which is
+ always zero in current implementation.
+
+**/
+VOID
+EFIAPI
+OnEndOfFirmware (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ NOTIFY_PHASE_PARAMS NotifyPhaseParams;
+ EFI_STATUS Status;
+
+ gBS->CloseEvent (Event);
+
+ NotifyPhaseParams.Phase = EnumInitPhaseEndOfFirmware;
+ PERF_START_EX (&gFspApiPerformanceGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION | FSP_STATUS_CODE_API_ENTRY);
+ Status = CallFspNotifyPhase (&NotifyPhaseParams);
+ PERF_END_EX (&gFspApiPerformanceGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION | FSP_STATUS_CODE_API_EXIT);
+
+ //
+ // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED status
+ //
+ if ((Status & ~(0xF)) == (FSP_STATUS_RESET_REQUIRED_COLD & ~(0xF))) {
+ DEBUG ((DEBUG_INFO, "FSP NotifyPhase EndOfFirmware requested reset 0x%x\n", Status));
+ CallFspWrapperResetSystem ((UINT32) Status);
+ }
+ if (Status != EFI_SUCCESS) {
+ DEBUG ((DEBUG_ERROR, "FSP NotifyPhase EndOfFirmware failed, status: 0x%x\n", Status));
+ } else {
+ DEBUG ((DEBUG_INFO, "FSP NotifyPhase EndOfFirmware Success.\n"));
+ }
+}
+
+
+/**
+ Main entry for the FSP DXE module.
+
+ This routine registers two callbacks to call fsp's notifies.
+
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.
+ @param[in] SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The entry point is executed successfully.
+ @retval other Some error occurs when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+FspDxeEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_EVENT ReadyToBootEvent;
+ VOID *Registration;
+ EFI_EVENT ProtocolNotifyEvent;
+
+ //
+ // Load this driver's image to memory
+ //
+ Status = RelocateImageUnder4GIfNeeded (ImageHandle, SystemTable);
+ if (EFI_ERROR (Status)) {
+ return EFI_SUCCESS;
+ }
+
+ ProtocolNotifyEvent = EfiCreateProtocolNotifyEvent (
+ &gEfiPciEnumerationCompleteProtocolGuid,
+ TPL_CALLBACK,
+ OnPciEnumerationComplete,
+ NULL,
+ &Registration
+ );
+ ASSERT (ProtocolNotifyEvent != NULL);
+
+ Status = EfiCreateEventReadyToBootEx (
+ TPL_CALLBACK,
+ OnReadyToBoot,
+ NULL,
+ &ReadyToBootEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gBS->CreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ OnEndOfFirmware,
+ NULL,
+ &gEfiEventExitBootServicesGuid,
+ &mExitBootServicesEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspNotifyDxe/FspNotifyDxe.inf b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspNotifyDxe/FspNotifyDxe.inf
new file mode 100644
index 0000000000..5300bb1915
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspNotifyDxe/FspNotifyDxe.inf
@@ -0,0 +1,76 @@
+## @file
+# FSP DXE Module
+#
+# This driver will register two callbacks to call fsp's notifies.
+#
+# 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 = FspNotifyDxe
+ FILE_GUID = AD61999A-507E-47E6-BA28-79CC609FA1A4
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = FspDxeEntryPoint
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ FspNotifyDxe.c
+ LoadBelow4G.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec
+ BroxtonPlatformPkg/PlatformPkg.dec
+ BroxtonFspPkg/BroxtonFspPkg.dec
+ IntelFsp2Pkg/IntelFsp2Pkg.dec
+ IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec
+
+[LibraryClasses]
+ UefiDriverEntryPoint
+ UefiBootServicesTableLib
+ DebugLib
+ BaseMemoryLib
+ UefiLib
+ FspWrapperApiLib
+ FspWrapperPlatformResetLib
+ PeCoffLib
+ CacheMaintenanceLib
+ DxeServicesLib
+ PerformanceLib
+ HobLib
+ ReportStatusCodeLib
+
+[Protocols]
+ gEfiPciEnumerationCompleteProtocolGuid ## CONSUMES
+ gAddPerfRecordProtocolGuid ## CONSUMES
+
+[Guids]
+ gEfiEventExitBootServicesGuid ## CONSUMES
+ gFspApiPerformanceGuid ## CONSUMES
+ gFspHobGuid ## CONSUMES
+ gFspPerformanceDataGuid ## CONSUMES
+
+[Pcd]
+ gIntelFsp2WrapperTokenSpaceGuid.PcdFlashFvFspBase ## CONSUMES
+ gIntelFsp2WrapperTokenSpaceGuid.PcdFlashFvSecondFspBase ## CONSUMES
+ gIntelFsp2WrapperTokenSpaceGuid.PcdFlashFvFspSize ## CONSUMES
+ gIntelFsp2WrapperTokenSpaceGuid.PcdFspsBaseAddress ## CONSUMES
+
+[Depex]
+ TRUE
diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspNotifyDxe/LoadBelow4G.c b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspNotifyDxe/LoadBelow4G.c
new file mode 100644
index 0000000000..c055c7f160
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspNotifyDxe/LoadBelow4G.c
@@ -0,0 +1,151 @@
+/** @file
+ 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.
+
+**/
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PeCoffLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DxeServicesLib.h>
+#include <Library/CacheMaintenanceLib.h>
+#include <Library/UefiLib.h>
+
+/**
+ Relocate this image under 4G memory.
+
+ @param ImageHandle Handle of driver image.
+ @param SystemTable Pointer to system table.
+
+ @retval EFI_SUCCESS Image successfully relocated.
+ @retval EFI_ABORTED Failed to relocate image.
+
+**/
+EFI_STATUS
+RelocateImageUnder4GIfNeeded (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ UINT8 *Buffer;
+ UINTN BufferSize;
+ EFI_HANDLE NewImageHandle;
+ UINTN Pages;
+ EFI_PHYSICAL_ADDRESS FfsBuffer;
+ PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
+ VOID *Interface;
+
+ //
+ // If it is already <4G, no need do relocate
+ //
+ if ((UINTN)RelocateImageUnder4GIfNeeded < 0xFFFFFFFF) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // If locate gEfiCallerIdGuid success, it means 2nd entry.
+ //
+ Status = gBS->LocateProtocol (&gEfiCallerIdGuid, NULL, &Interface);
+ if (!EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_INFO, "FspNotifyDxe - 2nd entry\n"));
+ return EFI_SUCCESS;
+ }
+
+ DEBUG ((EFI_D_INFO, "FspNotifyDxe - 1st entry\n"));
+
+ //
+ // Here we install a dummy handle
+ //
+ NewImageHandle = NULL;
+ Status = gBS->InstallProtocolInterface (
+ &NewImageHandle,
+ &gEfiCallerIdGuid,
+ EFI_NATIVE_INTERFACE,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Reload image itself to <4G mem
+ //
+ Status = GetSectionFromAnyFv (
+ &gEfiCallerIdGuid,
+ EFI_SECTION_PE32,
+ 0,
+ (VOID **) &Buffer,
+ &BufferSize
+ );
+ ASSERT_EFI_ERROR (Status);
+ ImageContext.Handle = Buffer;
+ ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;
+ //
+ // Get information about the image being loaded
+ //
+ Status = PeCoffLoaderGetImageInfo (&ImageContext);
+ ASSERT_EFI_ERROR (Status);
+ if (ImageContext.SectionAlignment > EFI_PAGE_SIZE) {
+ Pages = EFI_SIZE_TO_PAGES ((UINTN) (ImageContext.ImageSize + ImageContext.SectionAlignment));
+ } else {
+ Pages = EFI_SIZE_TO_PAGES ((UINTN) ImageContext.ImageSize);
+ }
+ FfsBuffer = 0xFFFFFFFF;
+ Status = gBS->AllocatePages (
+ AllocateMaxAddress,
+ EfiBootServicesCode,
+ Pages,
+ &FfsBuffer
+ );
+ ASSERT_EFI_ERROR (Status);
+ ImageContext.ImageAddress = (PHYSICAL_ADDRESS) (UINTN) FfsBuffer;
+ //
+ // Align buffer on section boundry
+ //
+ ImageContext.ImageAddress += ImageContext.SectionAlignment - 1;
+ ImageContext.ImageAddress &= ~((EFI_PHYSICAL_ADDRESS) (ImageContext.SectionAlignment - 1));
+ //
+ // Load the image to our new buffer
+ //
+ Status = PeCoffLoaderLoadImage (&ImageContext);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Relocate the image in our new buffer
+ //
+ Status = PeCoffLoaderRelocateImage (&ImageContext);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Free the buffer allocated by ReadSection since the image has been relocated in the new buffer
+ //
+ gBS->FreePool (Buffer);
+
+ //
+ // Flush the instruction cache so the image data is written before we execute it
+ //
+ InvalidateInstructionCacheRange ((VOID *) (UINTN) ImageContext.ImageAddress, (UINTN) ImageContext.ImageSize);
+
+ DEBUG ((EFI_D_INFO, "Loading driver at 0x%08x EntryPoint=0x%08x\n", (UINTN) ImageContext.ImageAddress, (UINTN) ImageContext.EntryPoint));
+ Status = ((EFI_IMAGE_ENTRY_POINT) (UINTN) (ImageContext.EntryPoint)) (NewImageHandle, gST);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Error: Image at 0x%08x start failed: %r\n", ImageContext.ImageAddress, Status));
+ gBS->FreePages (FfsBuffer, Pages);
+ }
+
+ //
+ // return error to unload >4G copy, if we already relocate itself to <4G.
+ //
+ return EFI_ALREADY_STARTED;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.c b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.c
new file mode 100644
index 0000000000..f403d1e214
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.c
@@ -0,0 +1,266 @@
+/** @file
+ This will be invoked only once. It will call FspMemoryInit API,
+ register TemporaryRamDonePpi to call TempRamExit API, and register MemoryDiscoveredPpi
+ notify to call FspSiliconInit API.
+
+ 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/PeimEntryPoint.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PeiServicesTablePointerLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/TimerLib.h>
+#include <Library/PerformanceLib.h>
+#include <Library/FspPlatformInfoLib.h>
+#include <Library/FspHobProcessLib.h>
+#include <Library/FspWrapperApiLib.h>
+#include <Ppi/FspSiliconInitDone.h>
+#include <Ppi/EndOfPeiPhase.h>
+#include <Ppi/MemoryDiscovered.h>
+#include <Ppi/TemporaryRamDone.h>
+#include <FspmUpd.h>
+
+BOOLEAN ImageInMemory = FALSE;
+
+
+VOID
+EFIAPI
+FspPolicyInitPreMem (
+ IN OUT FSPM_UPD *FspmUpd
+ );
+/**
+ This function is called after PEI core discover memory and finish migration.
+
+ @param[in] PeiServices Pointer to PEI Services Table.
+ @param[in] NotifyDesc Pointer to the descriptor for the Notification event that
+ caused this function to execute.
+ @param[in] Ppi Pointer to the PPI data associated with this function.
+
+ @retval EFI_STATUS Always return EFI_SUCCESS
+
+**/
+EFI_STATUS
+EFIAPI
+PeiMemoryDiscoveredNotify (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,
+ IN VOID *Ppi
+ );
+
+EFI_PEI_NOTIFY_DESCRIPTOR mPeiPreMemNotifyDesc[] = {
+ {
+ (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiPeiMemoryDiscoveredPpiGuid,
+ PeiMemoryDiscoveredNotify
+ }
+};
+
+EFI_PEI_PPI_DESCRIPTOR mFspTempRamExitPpiList[] = {
+ {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gFspTempRamExitGuid,
+ NULL
+ }
+};
+
+
+/**
+ Call FspMemoryInit API.
+
+ @return Status returned by FspMemoryInit API.
+
+**/
+EFI_STATUS
+PeiFspMemoryInit (
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ FSP_INFO_HEADER *FspmHeaderPtr;
+ EFI_STATUS Status;
+ UINT64 TimeStampCounterStart;
+ VOID *FspHobListPtr;
+ VOID *HobData;
+ FSPM_UPD *FspmUpdDataPtr;
+ UINTN *SourceData;
+
+ DEBUG ((DEBUG_INFO, "PeiFspMemoryInit enter\n"));
+
+ FspHobListPtr = NULL;
+
+ //
+ // Copy default FSP-M UPD data from Flash
+ //
+ FspmHeaderPtr = (FSP_INFO_HEADER *) FspFindFspHeader (PcdGet32 (PcdFspmBaseAddress));
+
+ DEBUG ((DEBUG_INFO, "PcdFspmBaseAddress = 0x%X\n", PcdGet32 (PcdFspmBaseAddress)));
+ DEBUG ((DEBUG_INFO, "FspmHeaderPtr = 0x%X\n", FspmHeaderPtr));
+ DEBUG ((DEBUG_INFO, "FspmHeaderPtr->CfgRegionSize = 0x%X\n", FspmHeaderPtr->CfgRegionSize));
+
+ FspmUpdDataPtr = (FSPM_UPD *) AllocateZeroPool ((UINTN) FspmHeaderPtr->CfgRegionSize);
+ ASSERT (FspmUpdDataPtr != NULL);
+ SourceData = (UINTN *) ((UINTN) FspmHeaderPtr->ImageBase + (UINTN) FspmHeaderPtr->CfgRegionOffset);
+ CopyMem (FspmUpdDataPtr, SourceData, (UINTN)FspmHeaderPtr->CfgRegionSize);
+
+ DEBUG ((DEBUG_INFO, "FspWrapperPlatformInitPreMem enter\n"));
+ FspmUpdDataPtr = UpdateFspUpdConfigs (PeiServices, FspmUpdDataPtr);
+ FspPolicyInitPreMem (FspmUpdDataPtr);
+
+ DEBUG ((DEBUG_INFO, " NvsBufferPtr - 0x%x\n", FspmUpdDataPtr->FspmArchUpd.NvsBufferPtr));
+ DEBUG ((DEBUG_INFO, " StackBase - 0x%x\n", FspmUpdDataPtr->FspmArchUpd.StackBase));
+ DEBUG ((DEBUG_INFO, " StackSize - 0x%x\n", FspmUpdDataPtr->FspmArchUpd.StackSize));
+ DEBUG ((DEBUG_INFO, " BootLoaderTolumSize - 0x%x\n", FspmUpdDataPtr->FspmArchUpd.BootLoaderTolumSize));
+ DEBUG ((DEBUG_INFO, " BootMode - 0x%x\n", FspmUpdDataPtr->FspmArchUpd.BootMode));
+ DEBUG ((DEBUG_INFO, " HobListPtr - 0x%x\n", &FspHobListPtr));
+ TimeStampCounterStart = AsmReadTsc ();
+ Status = CallFspMemoryInit (FspmUpdDataPtr, &FspHobListPtr);
+ PERF_START_EX (&gFspApiPerformanceGuid, "EventRec", NULL, TimeStampCounterStart, 0xD000);
+ PERF_END_EX (&gFspApiPerformanceGuid, "EventRec", NULL, 0, 0xD07F);
+ DEBUG ((DEBUG_INFO, "Total time spent executing FspMemoryInitApi: %d millisecond\n", DivU64x32(GetTimeInNanoSecond(AsmReadTsc() - TimeStampCounterStart), 1000000)));
+ // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED status
+ if ((Status & ~(0xF)) == (FSP_STATUS_RESET_REQUIRED_COLD & ~(0xF))) {
+ DEBUG ((DEBUG_INFO, "FspMemoryInitApi requested reset 0x%x\n", Status));
+ CallFspWrapperResetSystem ((UINT32) Status);
+ }
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "ERROR - Failed to execute FspMemoryInitApi(), Status = %r\n", Status));
+ }
+ DEBUG ((DEBUG_INFO, "FspMemoryInit status: 0x%x\n", Status));
+ ASSERT_EFI_ERROR (Status);
+
+ DEBUG ((DEBUG_INFO, " FspHobListPtr (returned) - 0x%x\n", FspHobListPtr));
+ ASSERT (FspHobListPtr != NULL);
+
+ FspHobProcessForMemoryResource (FspHobListPtr);
+
+ //
+ // FspHobList is not complete at this moment.
+ // Save FspHobList pointer to hob, so that it can be got later
+ //
+ HobData = BuildGuidHob (
+ &gFspHobGuid,
+ sizeof (VOID *)
+ );
+ ASSERT (HobData != NULL);
+ CopyMem (HobData, &FspHobListPtr, sizeof (FspHobListPtr));
+
+ return Status;
+}
+
+/**
+ TemporaryRamDone() disables the use of Temporary RAM. If present, this service is invoked
+ by the PEI Foundation after the EFI_PEI_PERMANANT_MEMORY_INSTALLED_PPI is installed.
+
+ @retval EFI_SUCCESS Use of Temporary RAM was disabled.
+ @retval EFI_INVALID_PARAMETER Temporary RAM could not be disabled.
+
+**/
+EFI_STATUS
+EFIAPI
+PeiMemoryDiscoveredNotify (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,
+ IN VOID *Ppi
+ )
+{
+ UINT64 TimeStampCounterStart;
+ EFI_STATUS Status;
+ VOID *TempRamExitParam;
+
+ DEBUG ((DEBUG_INFO, "PeiTemporaryRamDone enter\n"));
+
+ TempRamExitParam = GetTempRamExitParam ();
+ TimeStampCounterStart = AsmReadTsc ();
+ PERF_START_EX (&gFspApiPerformanceGuid, "EventRec", NULL, 0, 0xB000);
+ Status = CallTempRamExit (TempRamExitParam);
+ PERF_END_EX (&gFspApiPerformanceGuid, "EventRec", NULL, 0, 0xB07F);
+ DEBUG ((DEBUG_INFO, "Total time spent executing FspTempRamExitApi: %d millisecond\n", DivU64x32 (GetTimeInNanoSecond (AsmReadTsc () - TimeStampCounterStart), 1000000)));
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "ERROR - Failed to execute FspTempRamExitApi(), Status = %r\n", Status));
+ }
+ DEBUG ((DEBUG_INFO, "TempRamExit status: 0x%x\n", Status));
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Install gFspTempRamExitGuid to notify wrapper.
+ //
+ Status = PeiServicesInstallPpi (mFspTempRamExitPpiList);
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Do FSP initialization.
+
+ @return FSP initialization status.
+
+**/
+EFI_STATUS
+EFIAPI
+FspmWrapperInit (
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status;
+
+ if (!ImageInMemory) {
+ Status = PeiFspMemoryInit (PeiServices);
+ ASSERT_EFI_ERROR (Status);
+ } else {
+ //
+ // Register MemoryDiscovered Notify to run TempRamExit
+ //
+ Status = PeiServicesNotifyPpi (&mPeiPreMemNotifyDesc[0]);
+ ASSERT_EFI_ERROR (Status);
+ }
+ return Status;
+}
+
+/**
+ This is the entrypoint of PEIM
+
+ @param[in] FileHandle Handle of the file being invoked.
+ @param[in] PeiServices Describes the list of possible PEI Services.
+
+ @retval EFI_SUCCESS if it completed successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+FspmWrapperPeimEntryPoint (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ Status = (*PeiServices)->RegisterForShadow (FileHandle);
+
+ if (Status == EFI_ALREADY_STARTED) {
+ ImageInMemory = TRUE;
+ } else if (Status == EFI_NOT_FOUND) {
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ DEBUG((DEBUG_INFO, "FspmWrapperPeimEntryPoint\n"));
+ FspmWrapperInit (PeiServices);
+
+ return EFI_SUCCESS;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.inf b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.inf
new file mode 100644
index 0000000000..9e5fa965c0
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.inf
@@ -0,0 +1,105 @@
+## @file
+# FSP-M wrapper PEI Module
+#
+# This PEIM initialize FSP.
+# This will be invoked only once. It will call FspMemoryInit API,
+# register TemporaryRamDonePpi to call TempRamExit API, and register MemoryDiscoveredPpi
+# notify to call FspSiliconInit API.
+#
+# 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 = 0x00010017
+ BASE_NAME = FspmWrapperPeim
+ FILE_GUID = 9FAAD0FF-0E0C-4885-A738-BAB4E4FA1E66
+ VERSION_STRING = 1.0
+ MODULE_TYPE = PEIM
+ ENTRY_POINT = FspmWrapperPeimEntryPoint
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32
+#
+
+[LibraryClasses]
+ PeimEntryPoint
+ PeiServicesLib
+ PeiServicesTablePointerLib
+ BaseLib
+ BaseMemoryLib
+ MemoryAllocationLib
+ DebugLib
+ HobLib
+ FspWrapperPlatformLib
+ FspWrapperHobProcessLib
+ DebugAgentLib
+ UefiCpuLib
+ PeCoffGetEntryPointLib
+ PeCoffExtraActionLib
+ PerformanceLib
+ TimerLib
+ FspWrapperApiLib
+ FspWrapperApiTestLib
+ FspPlatformSecLib
+ FspPolicyInitLib
+ PerformanceLib
+ FspWrapperPlatformResetLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+ BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec
+ IntelFsp2Pkg/IntelFsp2Pkg.dec
+ IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec
+ BroxtonPlatformPkg/PlatformPkg.dec
+ BroxtonSiPkg/BroxtonSiPkg.dec
+ BroxtonFspPkg/BroxtonFspPkg.dec
+
+[Pcd]
+ gIntelFsp2WrapperTokenSpaceGuid.PcdFspmBaseAddress ## CONSUMES
+ gIntelFsp2WrapperTokenSpaceGuid.PcdPeiTemporaryRamStackSize ## CONSUMES
+ gIntelFsp2WrapperTokenSpaceGuid.PcdFlashFvFspBase ## CONSUMES
+ gIntelFsp2WrapperTokenSpaceGuid.PcdFlashFvSecondFspBase ## CONSUMES
+ gIntelFsp2WrapperTokenSpaceGuid.PcdFlashFvFspSize ## CONSUMES
+ gIntelFsp2WrapperTokenSpaceGuid.PcdFspsBaseAddress ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase
+ gIntelFsp2PkgTokenSpaceGuid.PcdFspAreaSize
+
+[Sources]
+ FspmWrapperPeim.c
+ ..\FspInitPei\SecMain.c
+ ..\FspInitPei\SecMain.h
+ ..\FspInitPei\FindPeiCore.c
+
+[Ppis]
+ gTopOfTemporaryRamPpiGuid ## PRODUCES
+ gEfiEndOfPeiSignalPpiGuid ## PRODUCES
+ gEfiTemporaryRamDonePpiGuid ## PRODUCES
+ gEfiPeiMemoryDiscoveredPpiGuid ## PRODUCES
+ gEfiPeiMasterBootModePpiGuid
+
+[FixedPcd]
+ gIntelFsp2WrapperTokenSpaceGuid.PcdSecCoreMaxPpiSupported ## CONSUMES
+
+[Guids]
+ gFspHobGuid ## PRODUCES ## HOB
+ gEfiPlatformInfoGuid
+ gEfiSystemNvDataFvGuid
+ gFspApiPerformanceGuid ## CONSUMES
+ gFspTempRamExitGuid
+
+[Depex]
+ TRUE
+
diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.c b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.c
new file mode 100644
index 0000000000..7343b77b58
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.c
@@ -0,0 +1,332 @@
+/** @file
+ This will be invoked only once. It will call FspMemoryInit API,
+ register TemporaryRamDonePpi to call TempRamExit API, and register MemoryDiscoveredPpi
+ notify to call FspSiliconInit API.
+
+ 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/PeimEntryPoint.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PeiServicesTablePointerLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/FspPlatformInfoLib.h>
+#include <Library/FspHobProcessLib.h>
+#include <Library/TimerLib.h>
+#include <Library/PerformanceLib.h>
+#include <Library/FspWrapperApiLib.h>
+#include <Ppi/FspSiliconInitDone.h>
+#include <Ppi/EndOfPeiPhase.h>
+#include <Ppi/MemoryDiscovered.h>
+#include <Ppi/TemporaryRamDone.h>
+#include <FspsUpd.h>
+#include <Ppi/MasterBootMode.h>
+
+extern EFI_PEI_NOTIFY_DESCRIPTOR mS3EndOfPeiNotifyDesc;
+extern EFI_GUID gFspApiPerformanceGuid;
+
+VOID
+EFIAPI
+FspPolicyInit (
+ IN OUT FSPS_UPD *FspsUpd
+ );
+
+/**
+ This function handles S3 resume task at the end of PEI
+
+ @param[in] PeiServices Pointer to PEI Services Table.
+ @param[in] NotifyDesc Pointer to the descriptor for the Notification event that
+ caused this function to execute.
+ @param[in] Ppi Pointer to the PPI data associated with this function.
+
+ @retval EFI_STATUS Always return EFI_SUCCESS
+
+**/
+EFI_STATUS
+EFIAPI
+S3EndOfPeiNotify (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,
+ IN VOID *Ppi
+ );
+
+EFI_PEI_NOTIFY_DESCRIPTOR mS3EndOfPeiNotifyDesc = {
+ (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiEndOfPeiSignalPpiGuid,
+ S3EndOfPeiNotify
+};
+
+/**
+ This function handles S3 resume task at the end of PEI
+
+ @param[in] PeiServices Pointer to PEI Services Table.
+ @param[in] NotifyDesc Pointer to the descriptor for the Notification event that
+ caused this function to execute.
+ @param[in] Ppi Pointer to the PPI data associated with this function.
+
+ @retval EFI_STATUS Always return EFI_SUCCESS
+
+**/
+EFI_STATUS
+EFIAPI
+S3EndOfPeiNotify (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,
+ IN VOID *Ppi
+ )
+{
+ NOTIFY_PHASE_PARAMS NotifyPhaseParams;
+ EFI_STATUS Status;
+
+ DEBUG ((DEBUG_INFO, "S3EndOfPeiNotify enter\n"));
+
+ NotifyPhaseParams.Phase = EnumInitPhaseAfterPciEnumeration;
+ Status = CallFspNotifyPhase (&NotifyPhaseParams);
+ DEBUG((DEBUG_INFO, "FSP S3NotifyPhase AfterPciEnumeration status: 0x%x\n", Status));
+
+ NotifyPhaseParams.Phase = EnumInitPhaseReadyToBoot;
+ Status = CallFspNotifyPhase (&NotifyPhaseParams);
+ DEBUG((DEBUG_INFO, "FSP S3NotifyPhase ReadyToBoot status: 0x%x\n", Status));
+
+ NotifyPhaseParams.Phase = EnumInitPhaseEndOfFirmware;
+ Status = CallFspNotifyPhase (&NotifyPhaseParams);
+ DEBUG((DEBUG_INFO, "FSP S3NotifyPhase EndOfFirmware status: 0x%x\n", Status));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Return Hob list produced by FSP.
+
+ @param[in] PeiServices The pointer to the PEI Services Table.
+ @param[in] This The pointer to this instance of this PPI.
+ @param[out] FspHobList The pointer to Hob list produced by FSP.
+
+ @return EFI_SUCCESS FReturn Hob list produced by FSP successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+FspSiliconInitDoneGetFspHobList (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN FSP_SILICON_INIT_DONE_PPI *This,
+ OUT VOID **FspHobList
+ );
+
+FSP_SILICON_INIT_DONE_PPI mFspSiliconInitDonePpi = {
+ FspSiliconInitDoneGetFspHobList
+};
+
+EFI_PEI_PPI_DESCRIPTOR mPeiFspSiliconInitDonePpi = {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gFspSiliconInitDonePpiGuid,
+ &mFspSiliconInitDonePpi
+};
+
+/**
+ This function is called after PEI core discover memory and finish migration.
+
+ @param[in] PeiServices Pointer to PEI Services Table.
+ @param[in] NotifyDesc Pointer to the descriptor for the Notification event that
+ caused this function to execute.
+ @param[in] Ppi Pointer to the PPI data associated with this function.
+
+ @retval EFI_STATUS Always return EFI_SUCCESS
+
+**/
+EFI_STATUS
+EFIAPI
+PeiMasterBootModeNotify (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,
+ IN VOID *Ppi
+ );
+
+EFI_PEI_NOTIFY_DESCRIPTOR mPeiNotifyDesc[] = {
+ {
+ (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiPeiMasterBootModePpiGuid,
+ PeiMasterBootModeNotify
+ }
+};
+
+/**
+ Return Hob list produced by FSP.
+
+ @param[in] PeiServices The pointer to the PEI Services Table.
+ @param[in] This The pointer to this instance of this PPI.
+ @param[out] FspHobList The pointer to Hob list produced by FSP.
+
+ @return EFI_SUCCESS FReturn Hob list produced by FSP successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+FspSiliconInitDoneGetFspHobList (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN FSP_SILICON_INIT_DONE_PPI *This,
+ OUT VOID **FspHobList
+ )
+{
+ EFI_HOB_GUID_TYPE *GuidHob;
+
+ GuidHob = GetFirstGuidHob (&gFspHobGuid);
+ if (GuidHob != NULL) {
+ *FspHobList = *(VOID **)GET_GUID_HOB_DATA (GuidHob);
+ return EFI_SUCCESS;
+ } else {
+ return EFI_NOT_FOUND;
+ }
+}
+
+
+/**
+ This function is called after PEI core discover memory and finish migration.
+
+ @param[in] PeiServices Pointer to PEI Services Table.
+ @param[in] NotifyDesc Pointer to the descriptor for the Notification event that
+ caused this function to execute.
+ @param[in] Ppi Pointer to the PPI data associated with this function.
+
+ @retval EFI_STATUS Always return EFI_SUCCESS
+
+**/
+EFI_STATUS
+EFIAPI
+PeiMasterBootModeNotify (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,
+ IN VOID *Ppi
+ )
+{
+ FSP_INFO_HEADER *FspsHeaderPtr;
+ UINT64 TimeStampCounterStart;
+ EFI_STATUS Status;
+ VOID *FspHobListPtr;
+ EFI_HOB_GUID_TYPE *GuidHob;
+ FSPS_UPD_COMMON *FspsUpdDataPtr;
+ UINTN *SourceData;
+
+ DEBUG ((DEBUG_INFO, "FspSiliconInit enter\n"));
+
+ //
+ // Copy default FSP-S UPD data from Flash
+ //
+ FspsHeaderPtr = (FSP_INFO_HEADER *) FspFindFspHeader (PcdGet32 (PcdFspsBaseAddress));
+ FspsHeaderPtr->ImageBase = (UINT32) (PcdGet32 (PcdFspsBaseAddress));
+
+ FspsUpdDataPtr = (FSPS_UPD_COMMON *) AllocateZeroPool ((UINTN) FspsHeaderPtr->CfgRegionSize);
+ ASSERT (FspsUpdDataPtr != NULL);
+ SourceData = (UINTN *) ((UINTN) FspsHeaderPtr->ImageBase + (UINTN) FspsHeaderPtr->CfgRegionOffset);
+ CopyMem (FspsUpdDataPtr, SourceData, (UINTN) FspsHeaderPtr->CfgRegionSize);
+ FspPolicyInit ((FSPS_UPD *) FspsUpdDataPtr);
+
+ TimeStampCounterStart = AsmReadTsc ();
+ PERF_START_EX (&gFspApiPerformanceGuid, "EventRec", NULL, 0, 0x9000);
+ Status = CallFspSiliconInit ((VOID *) FspsUpdDataPtr);
+ PERF_END_EX (&gFspApiPerformanceGuid, "EventRec", NULL, 0, 0x907F);
+
+ DEBUG ((DEBUG_INFO, "Total time spent executing FspSiliconInitApi: %d millisecond\n", DivU64x32 (GetTimeInNanoSecond (AsmReadTsc () - TimeStampCounterStart), 1000000)));
+
+ //
+ // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED status
+ //
+ if ((Status & ~(0xF)) == (FSP_STATUS_RESET_REQUIRED_COLD & ~(0xF))) {
+ DEBUG ((DEBUG_INFO, "FspSiliconInitApi requested reset 0x%x\n", Status));
+ CallFspWrapperResetSystem ((UINT32) Status);
+ }
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "ERROR - Failed to execute FspSiliconInitApi(), Status = %r\n", Status));
+ }
+ DEBUG ((DEBUG_INFO, "FspSiliconInit status: 0x%x\n", Status));
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Now FspHobList complete, process it
+ //
+ GuidHob = GetFirstGuidHob (&gFspHobGuid);
+ ASSERT (GuidHob != NULL);
+ FspHobListPtr = *(VOID **) GET_GUID_HOB_DATA (GuidHob);
+ DEBUG ((DEBUG_INFO, "FspHobListPtr - 0x%x\n", FspHobListPtr));
+ FspHobProcessForOtherData (FspHobListPtr);
+ DumpFspSmbiosMemoryInfoHob (FspHobListPtr);
+
+ //
+ // Install FspSiliconInitDonePpi so that any other driver can consume this info.
+ //
+ Status = PeiServicesInstallPpi (&mPeiFspSiliconInitDonePpi);
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
+
+/**
+ Do FSP initialization.
+
+ @return FSP initialization status.
+
+**/
+EFI_STATUS
+FspsWrapperInit (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_BOOT_MODE BootMode;
+
+ //
+ // Register MemoryDiscovered Notify to run FspSiliconInit
+ //
+ Status = PeiServicesNotifyPpi (&mPeiNotifyDesc[0]);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Register EndOfPei Notify for S3 to run FSP NotifyPhase
+ //
+ PeiServicesGetBootMode (&BootMode);
+ if (BootMode == BOOT_ON_S3_RESUME) {
+ Status = PeiServicesNotifyPpi (&mS3EndOfPeiNotifyDesc);
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This is the entrypoint of PEIM
+
+ @param[in] FileHandle Handle of the file being invoked.
+ @param[in] PeiServices Describes the list of possible PEI Services.
+
+ @retval EFI_SUCCESS if it completed successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+FspsWrapperPeimEntryPoint (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ DEBUG ((DEBUG_INFO, "FspsWrapperPeimEntryPoint\n"));
+
+ FspsWrapperInit ();
+
+ return EFI_SUCCESS;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.inf b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.inf
new file mode 100644
index 0000000000..cdb666d9df
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.inf
@@ -0,0 +1,105 @@
+## @file
+# FSP-S wrapper PEI Module
+#
+# This PEIM initialize FSP.
+# This will be invoked only once. It will call FspMemoryInit API,
+# register TemporaryRamDonePpi to call TempRamExit API, and register MemoryDiscoveredPpi
+# notify to call FspSiliconInit API.
+#
+# 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 = 0x00010017
+ BASE_NAME = FspsWrapperPeim
+ FILE_GUID = 0D244DF9-6CE3-4133-A1CF-53200AB663AC
+ VERSION_STRING = 1.0
+ MODULE_TYPE = PEIM
+ ENTRY_POINT = FspsWrapperPeimEntryPoint
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32
+#
+
+[LibraryClasses]
+ PeimEntryPoint
+ PeiServicesLib
+ PeiServicesTablePointerLib
+ BaseLib
+ BaseMemoryLib
+ TimerLib
+ DebugLib
+ HobLib
+ MemoryAllocationLib
+ FspWrapperPlatformLib
+ FspWrapperHobProcessLib
+ DebugAgentLib
+ UefiCpuLib
+ PeCoffGetEntryPointLib
+ PeCoffExtraActionLib
+ PerformanceLib
+ FspWrapperApiLib
+ FspWrapperApiTestLib
+ FspCommonLib
+ FspPolicyInitLib
+ FspPlatformSecLib
+ FspWrapperPlatformResetLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+ BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec
+ IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec
+ BroxtonSiPkg/BroxtonSiPkg.dec
+ BroxtonFspPkg/BroxtonFspPkg.dec
+ IntelFsp2Pkg/IntelFsp2Pkg.dec
+
+[Ppis]
+ gTopOfTemporaryRamPpiGuid ## PRODUCES
+ gFspSiliconInitDonePpiGuid ## PRODUCES
+ gEfiEndOfPeiSignalPpiGuid ## PRODUCES
+ gEfiTemporaryRamDonePpiGuid ## PRODUCES
+ gEfiPeiMemoryDiscoveredPpiGuid ## PRODUCES
+ gEfiPeiMasterBootModePpiGuid
+
+[FixedPcd]
+ gIntelFsp2WrapperTokenSpaceGuid.PcdSecCoreMaxPpiSupported ## CONSUMES
+
+[Pcd]
+ gIntelFsp2WrapperTokenSpaceGuid.PcdFspsBaseAddress ## CONSUMES
+ gIntelFsp2WrapperTokenSpaceGuid.PcdPeiTemporaryRamStackSize ## CONSUMES
+ gIntelFsp2WrapperTokenSpaceGuid.PcdFlashFvFspBase ## CONSUMES
+ gIntelFsp2WrapperTokenSpaceGuid.PcdFlashFvSecondFspBase ## CONSUMES
+ gIntelFsp2WrapperTokenSpaceGuid.PcdFlashFvFspSize ## CONSUMES
+ gIntelFsp2WrapperTokenSpaceGuid.PcdFspsBaseAddress ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase
+ gIntelFsp2PkgTokenSpaceGuid.PcdFspAreaSize
+
+[Guids]
+ gFspHobGuid ## CONSUMES ## HOB
+ gFspApiPerformanceGuid ## CONSUMES ## GUID
+ gEfiPlatformInfoGuid
+ gEfiSystemNvDataFvGuid
+ gFspNonVolatileStorageHobGuid ## CONSUMES
+
+[Sources]
+ FspsWrapperPeim.c
+ ..\FspInitPei\SecMain.c
+ ..\FspInitPei\SecMain.h
+ ..\FspInitPei\FindPeiCore.c
+
+[Depex]
+ TRUE
+
diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Include/Library/FspHobProcessLib.h b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Include/Library/FspHobProcessLib.h
new file mode 100644
index 0000000000..b7ec68e813
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Include/Library/FspHobProcessLib.h
@@ -0,0 +1,71 @@
+/** @file
+ Provide FSP hob process related function.
+
+ 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.
+
+**/
+
+#ifndef __FSP_HOB_PROCESS_LIB_H__
+#define __FSP_HOB_PROCESS_LIB_H__
+
+/**
+ BIOS process FspBobList.
+
+ @param[in] FspHobList Pointer to the HOB data structure produced by FSP.
+
+ @return If platform process the FSP hob list successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+FspHobProcess (
+ IN VOID *FspHobList
+ );
+
+/**
+ BIOS process FspBobList for Memory Resource Descriptor.
+
+ @param[in] FspHobList Pointer to the HOB data structure produced by FSP.
+
+ @return If platform process the FSP hob list successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+FspHobProcessForMemoryResource (
+ IN VOID *FspHobList
+ );
+
+/**
+ BIOS process FspBobList for other data (not Memory Resource Descriptor).
+
+ @param[in] FspHobList Pointer to the HOB data structure produced by FSP.
+
+ @return If platform process the FSP hob list successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+FspHobProcessForOtherData (
+ IN VOID *FspHobList
+ );
+
+/**
+ Dump FSP SMBIOS memory info HOB
+
+**/
+VOID
+DumpFspSmbiosMemoryInfoHob (
+ IN VOID *FspHobList
+ );
+
+#endif
+
diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Include/Library/FspPlatformInfoLib.h b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Include/Library/FspPlatformInfoLib.h
new file mode 100644
index 0000000000..f965b02647
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Include/Library/FspPlatformInfoLib.h
@@ -0,0 +1,167 @@
+/** @file
+ Provide FSP platform information related function.
+
+ 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.
+
+**/
+
+#ifndef __FSP_PLATFORM_INFO_LIB_H__
+#define __FSP_PLATFORM_INFO_LIB_H__
+
+/**
+ Get current boot mode.
+
+ @note At this point, memory is ready, PeiServices are NOT available to use.
+ Platform can get some data from chipset register.
+
+ @return BootMode current boot mode.
+
+**/
+UINT32
+EFIAPI
+GetBootMode (
+ VOID
+ );
+
+/**
+ Get NVS buffer parameter.
+
+ @note At this point, memory is NOT ready, PeiServices are available to use.
+
+ @return NvsBuffer NVS buffer parameter.
+
+**/
+VOID *
+EFIAPI
+GetNvsBuffer (
+ VOID
+ );
+
+/**
+ This function overrides the default configurations in the UPD data region.
+
+ @param[in] PeiServices Describes the list of possible PEI Services.
+ @param[in, out] FspUpdRgnPtr A pointer to the UPD data region data strcture.
+
+ @return FspUpdRgnPtr A pointer to the UPD data region data strcture.
+
+**/
+VOID *
+EFIAPI
+UpdateFspUpdConfigs (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN OUT VOID *FspUpdRgnPtr
+ );
+
+/**
+ Get BootLoader Tolum size.
+
+ @note At this point, memory is NOT ready, PeiServices are available to use.
+
+ @return BootLoader Tolum size.
+
+**/
+UINT32
+EFIAPI
+GetBootLoaderTolumSize (
+ VOID
+ );
+
+/**
+ Get TempRamExit parameter.
+
+ @note At this point, memory is ready, PeiServices are available to use.
+
+ @return TempRamExit parameter.
+
+**/
+VOID *
+EFIAPI
+GetTempRamExitParam (
+ VOID
+ );
+
+/**
+ Get FspSiliconInit parameter.
+
+ @note At this point, memory is ready, PeiServices are available to use.
+
+ @return FspSiliconInit parameter.
+
+**/
+VOID *
+EFIAPI
+GetFspSiliconInitParam (
+ VOID
+ );
+
+/**
+ Get S3 PEI memory information.
+
+ @note At this point, memory is ready, and PeiServices are available to use.
+ Platform can get some data from SMRAM directly.
+
+ @param[out] S3PeiMemSize PEI memory size to be installed in S3 phase.
+ @param[out] S3PeiMemBase PEI memory base to be installed in S3 phase.
+
+ @return If S3 PEI memory information is got successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+GetS3MemoryInfo (
+ OUT UINT64 *S3PeiMemSize,
+ OUT EFI_PHYSICAL_ADDRESS *S3PeiMemBase
+ );
+
+/**
+ Get stack information according to boot mode.
+
+ @note If BootMode is BOOT_ON_S3_RESUME or BOOT_ON_FLASH_UPDATE,
+ this stack should be in some reserved memory space.
+
+ @note If FspInitDone is TRUE, memory is ready, but no PeiServices there.
+ Platform can get some data from SMRAM directly.
+ @note If FspInitDone is FALSE, memory is NOT ready, but PeiServices are available to use.
+ Platform can get some data from variable via VariablePpi.
+
+ @param[in] BootMode Current boot mode.
+ @param[in] FspInitDone If FspInit is called.
+ @param[out] StackSize Stack size to be used in PEI phase.
+ @param[out] StackBase Stack base to be used in PEI phase.
+
+ @return If Stack information is got successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+GetStackInfo (
+ IN UINT32 BootMode,
+ IN BOOLEAN FspInitDone,
+ OUT UINT64 *StackSize,
+ OUT EFI_PHYSICAL_ADDRESS *StackBase
+ );
+
+/**
+ Perform platform related reset in FSP wrapper.
+
+ @param[in] ResetType The type of reset the platform has to perform.
+
+ @return Will reset the system based on Reset status provided.
+
+**/
+VOID
+EFIAPI
+CallFspWrapperResetSystem (
+ IN UINT32 ResetType
+ );
+#endif
+
diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Include/Library/FspPlatformSecLib.h b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Include/Library/FspPlatformSecLib.h
new file mode 100644
index 0000000000..034651b203
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Include/Library/FspPlatformSecLib.h
@@ -0,0 +1,71 @@
+/** @file
+ Provide FSP wrapper platform sec related function.
+
+ 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.
+
+**/
+
+#ifndef __FSP_PLATFORM_SEC_LIB_H__
+#define __FSP_PLATFORM_SEC_LIB_H__
+
+/**
+ A developer supplied function to perform platform specific operations.
+
+ It's a developer supplied function to perform any operations appropriate to a
+ given platform. It's invoked just before passing control to PEI core by SEC
+ core. Platform developer may modify the SecCoreData passed to PEI Core.
+ It returns a platform specific PPI list that platform wishes to pass to PEI core.
+ The Generic SEC core module will merge this list to join the final list passed to
+ PEI core.
+
+ @param[in, out] SecCoreData The same parameter as passing to PEI core. It
+ could be overridden by this function.
+
+ @return The platform specific PPI list to be passed to PEI core or
+ NULL if there is no need of such platform specific PPI list.
+
+**/
+EFI_PEI_PPI_DESCRIPTOR *
+EFIAPI
+SecPlatformMain (
+ IN OUT EFI_SEC_PEI_HAND_OFF *SecCoreData
+ );
+
+/**
+ Call PEI core entry point with new temporary RAM.
+
+ @param[in] FspHobList HobList produced by FSP.
+ @param[in] StartOfRange Start of temporary RAM.
+ @param[in] EndOfRange End of temporary RAM.
+
+**/
+VOID
+EFIAPI
+CallPeiCoreEntryPoint (
+ IN VOID *FspHobList,
+ IN VOID *StartOfRange,
+ IN VOID *EndOfRange
+ );
+
+/**
+ Save SEC context before call FspInit.
+
+ @param[in] PeiServices Pointer to PEI Services Table.
+
+**/
+VOID
+EFIAPI
+SaveSecContext (
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ );
+
+#endif
+
diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec
new file mode 100644
index 0000000000..55d3d167ac
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec
@@ -0,0 +1,113 @@
+## @file
+# Provides drivers and definitions to support fsp in EDKII bios.
+#
+# 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]
+ DEC_SPECIFICATION = 0x00010005
+ PACKAGE_NAME = IntelFsp2WrapperPkg
+ PACKAGE_GUID = FAFE06D4-7245-42D7-9FD2-E5D5E36AB0A0
+ PACKAGE_VERSION = 0.1
+
+[Includes]
+ Include
+
+[LibraryClasses]
+ ## @libraryclass Provide FSP API related function.
+ FspWrapperApiLib|Include/Library/FspWrapperApiLib.h
+ FspWrapperApiTestLib|Include/Library/FspWrapperApiTestLib.h
+
+ ## @libraryclass Provide FSP hob process related function.
+ FspHobProcessLib|Include/Library/FspHobProcessLib.h
+
+ ## @libraryclass Provide FSP platform information related function.
+ FspPlatformInfoLib|Include/Library/FspPlatformInfoLib.h
+
+ ## @libraryclass Provide FSP wrapper platform sec related function.
+ FspPlatformSecLib|Include/Library/FspPlatformSecLib.h
+
+[Guids]
+ #
+ # GUID defined in package
+ #
+ gIntelFsp2WrapperTokenSpaceGuid = { 0xa34cf082, 0xf50, 0x4f0d, { 0x89, 0x8a, 0x3d, 0x39, 0x30, 0x2b, 0xc5, 0x1e } }
+ gFspHobGuid = { 0x6d86fb36, 0xba90, 0x472c, { 0xb5, 0x83, 0x3f, 0xbe, 0xd3, 0xfb, 0x20, 0x9a } }
+
+[Ppis]
+ gFspSiliconInitDonePpiGuid = { 0x4eb6e09c, 0xd256, 0x4e1e, { 0xb5, 0x0a, 0x87, 0x4b, 0xd2, 0x84, 0xb3, 0xde } }
+ gTopOfTemporaryRamPpiGuid = { 0x2f3962b2, 0x57c5, 0x44ec, { 0x9e, 0xfc, 0xa6, 0x9f, 0xd3, 0x02, 0x03, 0x2b } }
+
+[Protocols]
+
+################################################################################
+#
+# PCD Declarations section - list of all PCDs Declared by this Package
+# Only this package should be providing the
+# declaration, other packages should not.
+#
+################################################################################
+[PcdsFixedAtBuild, PcdsPatchableInModule]
+ ## Provides the memory mapped base address of the BIOS CodeCache Flash Device.
+ gIntelFsp2WrapperTokenSpaceGuid.PcdFlashCodeCacheAddress|0xFFE00000|UINT32|0x10000001
+ ## Provides the size of the BIOS Flash Device.
+ gIntelFsp2WrapperTokenSpaceGuid.PcdFlashCodeCacheSize|0x00200000|UINT32|0x10000002
+
+ ## Indicates the base address of the factory FSP binary.
+ gIntelFsp2WrapperTokenSpaceGuid.PcdFlashFvFspBase|0xFFF80000|UINT32|0x10000003
+ ## Indicates the base address of the updatable FSP binary to support Dual FSP.
+ # There could be two FSP images at different locations in a flash -
+ # one factory version (default) and updatable version (updatable).
+ # TempRamInit, FspMemoryInit and TempRamExit are always executed from factory version.
+ # FspSiliconInit and NotifyPhase can be executed from updatable version if it is available,
+ # FspSiliconInit and NotifyPhase are executed from factory version if there is no updateable version,
+ # PcdFlashFvFspBase is base address of factory FSP, and PcdFlashFvSecondFspBase
+ # is base address of updatable FSP. If PcdFlashFvSecondFspBase is 0, that means
+ # there is no updatable FSP.
+ gIntelFsp2WrapperTokenSpaceGuid.PcdFlashFvSecondFspBase|0x00000000|UINT32|0x10000008
+ ## Provides the size of the factory FSP binary.
+ gIntelFsp2WrapperTokenSpaceGuid.PcdFlashFvFspSize|0x00048000|UINT32|0x10000004
+ ## Provides the size of the updatable FSP binary to support Dual FSP.
+ gIntelFsp2WrapperTokenSpaceGuid.PcdFlashFvSecondFspSize|0x00000000|UINT32|0x10000009
+
+ ## Indicates the base address of the first Microcode Patch in the Microcode Region
+ gIntelFsp2WrapperTokenSpaceGuid.PcdCpuMicrocodePatchAddress|0x0|UINT64|0x10000005
+ gIntelFsp2WrapperTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize|0x0|UINT64|0x10000006
+ ## Indicates the offset of the Cpu Microcode.
+ gIntelFsp2WrapperTokenSpaceGuid.PcdFlashMicroCodeOffset|0x90|UINT32|0x10000007
+
+ ##
+ # Maximum number of Ppi is provided by SecCore.
+ ##
+ gIntelFsp2WrapperTokenSpaceGuid.PcdSecCoreMaxPpiSupported|0x6|UINT32|0x20000001
+
+
+ ## Stack size in the temporary RAM.
+ # 0 means half of TemporaryRamSize.
+ gIntelFsp2WrapperTokenSpaceGuid.PcdPeiTemporaryRamStackSize|0|UINT32|0x40000001
+
+ # This is temporary DRAM base and size for StackTop in FspInit
+ gIntelFsp2WrapperTokenSpaceGuid.PcdTemporaryRamBase|0x00080000|UINT32|0x40000002
+ gIntelFsp2WrapperTokenSpaceGuid.PcdTemporaryRamSize|0x00010000|UINT32|0x40000003
+
+ # This is stack base and size for FSP in MemoryInit
+ gIntelFsp2WrapperTokenSpaceGuid.PcdFspStackBase|0x00000000|UINT32|0x40000004
+ gIntelFsp2WrapperTokenSpaceGuid.PcdFspStackSize|0x00000000|UINT32|0x40000005
+
+
+ ## Indicate the PEI memory size platform want to report
+ gIntelFsp2WrapperTokenSpaceGuid.PcdPeiMinMemSize|0x1800000|UINT32|0x40000006
+ ## Indicate the PEI memory size platform want to report
+ gIntelFsp2WrapperTokenSpaceGuid.PcdPeiRecoveryMinMemSize|0x3000000|UINT32|0x40000007
+
+[PcdsDynamic,PcdsDynamicEx]
+ gIntelFsp2WrapperTokenSpaceGuid.PcdFspsBaseAddress|0x00000000|UINT32|0x00001001
diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/BaseFspWrapperApiLib.inf b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/BaseFspWrapperApiLib.inf
new file mode 100644
index 0000000000..c605eb2ad7
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/BaseFspWrapperApiLib.inf
@@ -0,0 +1,73 @@
+## @file
+# Provide FSP API related function.
+#
+# 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 Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = BaseFspWrapperApiLib
+ FILE_GUID = F42C789F-4D66-49AF-8C73-1AADC00437AC
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = FspWrapperApiLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+################################################################################
+#
+# Sources Section - list of files that are required for the build to succeed.
+#
+################################################################################
+
+[Sources]
+ FspWrapperApiLib.c
+
+[Sources.IA32]
+ IA32/DispatchExecute.c
+
+[Sources.X64]
+ X64/DispatchExecute.c
+ X64/Thunk64To32.asm
+ X64/Thunk64To32.S
+
+################################################################################
+#
+# Package Dependency Section - list of Package files that are required for
+# this module.
+#
+################################################################################
+
+[Packages]
+ MdePkg/MdePkg.dec
+ IntelFsp2Pkg/IntelFsp2Pkg.dec
+ BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec
+ IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec
+
+[LibraryClasses]
+ BaseLib
+
+[Guids]
+ gFspHeaderFileGuid ## CONSUMES ## GUID
+
+[Pcd]
+ gIntelFsp2WrapperTokenSpaceGuid.PcdFspmBaseAddress ## CONSUMES
+ gIntelFsp2WrapperTokenSpaceGuid.PcdFspsBaseAddress ## CONSUMES
diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/FspWrapperApiLib.c b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/FspWrapperApiLib.c
new file mode 100644
index 0000000000..f763f86a59
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/FspWrapperApiLib.c
@@ -0,0 +1,222 @@
+/** @file
+ Provide FSP API related function.
+
+ 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 <Guid/FspHeaderFile.h>
+#include <Library/FspWrapperApiLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+
+/**
+ Wrapper for a thunk to transition from long mode to compatibility mode to execute 32-bit code and then transit back to
+ long mode.
+
+ @param[in] Function The 32bit code entry to be executed.
+ @param[in] Param1 The first parameter to pass to 32bit code.
+
+ @return EFI_STATUS
+
+**/
+EFI_STATUS
+Execute32BitCode (
+ IN UINT64 Function,
+ IN UINT64 Param1,
+ IN UINT64 Param2
+ );
+
+/**
+ Find FSP header pointer.
+
+ @param[in] FlashFvFspBase Flash address of FSP FV.
+
+ @return FSP header pointer.
+
+**/
+FSP_INFO_HEADER *
+EFIAPI
+FspFindFspHeader (
+ IN EFI_PHYSICAL_ADDRESS FlashFvFspBase
+ )
+{
+ UINT8 *CheckPointer;
+
+ DEBUG ((DEBUG_INFO, "FspFindFspHeader\n"));
+
+ CheckPointer = (UINT8 *) (UINTN) FlashFvFspBase;
+
+ if (((EFI_FIRMWARE_VOLUME_HEADER *) CheckPointer)->Signature != EFI_FVH_SIGNATURE) {
+ DEBUG ((DEBUG_INFO, "return 1\n"));
+ return NULL;
+ }
+
+ if (((EFI_FIRMWARE_VOLUME_HEADER *) CheckPointer)->ExtHeaderOffset != 0) {
+ CheckPointer = CheckPointer + ((EFI_FIRMWARE_VOLUME_HEADER *) CheckPointer)->ExtHeaderOffset;
+ CheckPointer = CheckPointer + ((EFI_FIRMWARE_VOLUME_EXT_HEADER *) CheckPointer)->ExtHeaderSize;
+ CheckPointer = (UINT8 *) ALIGN_POINTER (CheckPointer, 8);
+ } else {
+ CheckPointer = CheckPointer + ((EFI_FIRMWARE_VOLUME_HEADER *)CheckPointer)->HeaderLength;
+ }
+
+ CheckPointer = CheckPointer + sizeof (EFI_FFS_FILE_HEADER);
+
+ if (((EFI_RAW_SECTION *) CheckPointer)->Type != EFI_SECTION_RAW) {
+ DEBUG ((DEBUG_INFO, "return 2\n"));
+ return NULL;
+ }
+
+ CheckPointer = CheckPointer + sizeof (EFI_RAW_SECTION);
+
+ return (FSP_INFO_HEADER *) CheckPointer;
+}
+
+/**
+ Call FSP API - FspNotifyPhase.
+
+ @param[in] NotifyPhaseParams Address pointer to the NOTIFY_PHASE_PARAMS structure.
+
+ @return EFI status returned by FspNotifyPhase API.
+
+**/
+EFI_STATUS
+EFIAPI
+CallFspNotifyPhase (
+ IN NOTIFY_PHASE_PARAMS *NotifyPhaseParams
+ )
+{
+ FSP_INFO_HEADER *FspHeader;
+ FSP_NOTIFY_PHASE NotifyPhaseApi;
+ EFI_STATUS Status;
+ BOOLEAN InterruptState;
+
+ FspHeader = (FSP_INFO_HEADER *) FspFindFspHeader (PcdGet32 (PcdFspsBaseAddress));
+ if (FspHeader == NULL) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ NotifyPhaseApi = (FSP_NOTIFY_PHASE) (UINTN) (FspHeader->ImageBase + FspHeader->NotifyPhaseEntryOffset);
+ InterruptState = SaveAndDisableInterrupts ();
+ Status = Execute32BitCode ((UINTN) NotifyPhaseApi, (UINTN) NotifyPhaseParams, (UINTN) NULL);
+ SetInterruptState (InterruptState);
+
+ return Status;
+}
+
+/**
+ Call FSP API - FspMemoryInit.
+
+ @param[in,out] FspMemoryInitParams Address pointer to the FSP_MEMORY_INIT_PARAMS structure.
+
+ @return EFI status returned by FspMemoryInit API.
+
+**/
+EFI_STATUS
+EFIAPI
+CallFspMemoryInit (
+ IN VOID *FspmUpdDataPtr,
+ OUT VOID **HobListPtr
+ )
+{
+ FSP_INFO_HEADER *FspHeader;
+ FSP_MEMORY_INIT FspMemoryInitApi;
+ EFI_STATUS Status;
+ BOOLEAN InterruptState;
+
+ FspHeader = (FSP_INFO_HEADER *) FspFindFspHeader (PcdGet32 (PcdFspmBaseAddress));
+ if (FspHeader == NULL) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ FspMemoryInitApi = (FSP_MEMORY_INIT) (UINTN) (FspHeader->ImageBase + FspHeader->FspMemoryInitEntryOffset);
+ InterruptState = SaveAndDisableInterrupts ();
+ Status = Execute32BitCode ((UINTN) FspMemoryInitApi, (UINTN) FspmUpdDataPtr, (UINTN) HobListPtr);
+ SetInterruptState (InterruptState);
+
+ return Status;
+}
+
+/**
+ Call FSP API - TempRamExit.
+
+ @param[in,out] TempRamExitParam Address pointer to the TempRamExit parameters structure.
+
+ @return EFI status returned by TempRamExit API.
+
+**/
+EFI_STATUS
+EFIAPI
+CallTempRamExit (
+ IN VOID *TempRamExitParam
+ )
+{
+ FSP_INFO_HEADER *FspHeader;
+ FSP_TEMP_RAM_EXIT TempRamExitApi;
+ EFI_STATUS Status;
+ BOOLEAN InterruptState;
+
+ FspHeader = (FSP_INFO_HEADER *) FspFindFspHeader (PcdGet32 (PcdFspmBaseAddress));
+ if (FspHeader == NULL) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ TempRamExitApi = (FSP_TEMP_RAM_EXIT) (UINTN) (FspHeader->ImageBase + FspHeader->TempRamExitEntryOffset);
+ InterruptState = SaveAndDisableInterrupts ();
+
+ DEBUG ((DEBUG_INFO, "** calling TempRamExitApi\n"));
+
+ Status = Execute32BitCode ((UINTN) TempRamExitApi, (UINTN) TempRamExitParam, (UINTN) NULL);
+ DEBUG ((DEBUG_INFO, "** TempRamExitApi returns\n"));
+ SetInterruptState (InterruptState);
+ DEBUG ((DEBUG_INFO, "** return\n"));
+ return Status;
+}
+
+/**
+ Call FSP API - FspSiliconInit.
+
+ @param[in,out] FspSiliconInitParam Address pointer to the Silicon Init parameters structure.
+
+ @return EFI status returned by FspSiliconInit API.
+
+**/
+EFI_STATUS
+EFIAPI
+CallFspSiliconInit (
+ IN VOID *FspsUpdDataPtr
+ )
+{
+ FSP_INFO_HEADER *FspHeader;
+ FSP_SILICON_INIT FspSiliconInitApi;
+ EFI_STATUS Status;
+ BOOLEAN InterruptState;
+
+ DEBUG ((DEBUG_INFO, "PcdGet32 (PcdFspsBaseAddress) = 0x%X\n", PcdGet32 (PcdFspsBaseAddress)));
+
+ FspHeader = (FSP_INFO_HEADER *) FspFindFspHeader (PcdGet32 (PcdFspsBaseAddress));
+ if (FspHeader == NULL) {
+ return EFI_DEVICE_ERROR;
+ }
+ DEBUG ((DEBUG_INFO, "FspHeader = 0x%X\n", FspHeader));
+
+ FspSiliconInitApi = (FSP_SILICON_INIT) (UINTN) (FspHeader->ImageBase + FspHeader->FspSiliconInitEntryOffset);
+ DEBUG ((DEBUG_INFO, "FspSiliconInitApi = 0x%X\n", FspSiliconInitApi));
+
+ InterruptState = SaveAndDisableInterrupts ();
+ Status = Execute32BitCode ((UINTN) FspSiliconInitApi, (UINTN) FspsUpdDataPtr, (UINTN) NULL);
+ SetInterruptState (InterruptState);
+
+ return Status;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/IA32/DispatchExecute.c b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/IA32/DispatchExecute.c
new file mode 100644
index 0000000000..018590f4fa
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/IA32/DispatchExecute.c
@@ -0,0 +1,61 @@
+/** @file
+ Execute 32-bit code in Protected Mode.
+
+ 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 <Uefi.h>
+#include <FspEas.h>
+
+/**
+ FSP API functions.
+
+ @param[in] Param1 The first parameter to pass to 32bit code.
+ @param[in] Param2 The second parameter to pass to 32bit code.
+
+ @return EFI_STATUS
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *FSP_FUNCTION) (
+ IN VOID *Param1,
+ IN VOID *Param2
+ );
+
+/**
+ Wrapper for a thunk to transition from long mode to compatibility mode to execute 32-bit code and then transit back to
+ long mode.
+
+ @param[in] Function The 32bit code entry to be executed.
+ @param[in] Param1 The first parameter to pass to 32bit code.
+ @param[in] Param2 The second parameter to pass to 32bit code.
+
+ @return EFI_STATUS
+
+**/
+EFI_STATUS
+Execute32BitCode (
+ IN UINT64 Function,
+ IN UINT64 Param1,
+ IN UINT64 Param2
+ )
+{
+ FSP_FUNCTION EntryFunc;
+ EFI_STATUS Status;
+
+ EntryFunc = (FSP_FUNCTION) (UINTN) (Function);
+ Status = EntryFunc ((VOID *) (UINTN) Param1, (VOID *) (UINTN) Param2);
+
+ return Status;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/DispatchExecute.c b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/DispatchExecute.c
new file mode 100644
index 0000000000..34d85a612b
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/DispatchExecute.c
@@ -0,0 +1,111 @@
+/** @file
+ Execute 32-bit code in Long Mode.
+ Provide a thunk function to transition from long mode to compatibility mode to execute 32-bit code and then transit
+ back to long mode.
+
+ 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 <Uefi.h>
+#include <Library/BaseLib.h>
+#include <FspEas.h>
+
+#pragma pack(1)
+typedef union {
+ struct {
+ UINT32 LimitLow : 16;
+ UINT32 BaseLow : 16;
+ UINT32 BaseMid : 8;
+ UINT32 Type : 4;
+ UINT32 System : 1;
+ UINT32 Dpl : 2;
+ UINT32 Present : 1;
+ UINT32 LimitHigh : 4;
+ UINT32 Software : 1;
+ UINT32 Reserved : 1;
+ UINT32 DefaultSize : 1;
+ UINT32 Granularity : 1;
+ UINT32 BaseHigh : 8;
+ } Bits;
+ UINT64 Uint64;
+} IA32_GDT;
+#pragma pack()
+
+GLOBAL_REMOVE_IF_UNREFERENCED IA32_GDT mGdtEntries[] = {
+ {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 0x0: reserve */
+ {{0xFFFF, 0, 0, 0xB, 1, 0, 1, 0xF, 0, 0, 1, 1, 0}}, /* 0x8: compatibility mode */
+ {{0xFFFF, 0, 0, 0xB, 1, 0, 1, 0xF, 0, 1, 0, 1, 0}}, /* 0x10: for long mode */
+ {{0xFFFF, 0, 0, 0x3, 1, 0, 1, 0xF, 0, 0, 1, 1, 0}}, /* 0x18: data */
+ {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 0x20: reserve */
+};
+
+//
+// IA32 Gdt register
+//
+GLOBAL_REMOVE_IF_UNREFERENCED IA32_DESCRIPTOR mGdt = {
+ sizeof (mGdtEntries) - 1,
+ (UINTN) mGdtEntries
+ };
+
+/**
+ Assembly function to transition from long mode to compatibility mode to execute 32-bit code and then transit back to
+ long mode.
+
+ @param[in] Function The 32bit code entry to be executed.
+ @param[in] Param1 The first parameter to pass to 32bit code
+ @param[in] Param2 The second parameter to pass to 32bit code
+ @param[in] InternalGdtr The GDT and GDT descriptor used by this library
+
+ @return status
+
+**/
+UINT32
+AsmExecute32BitCode (
+ IN UINT64 Function,
+ IN UINT64 Param1,
+ IN UINT64 Param2,
+ IN IA32_DESCRIPTOR *InternalGdtr
+ );
+
+/**
+ Wrapper for a thunk to transition from long mode to compatibility mode to execute 32-bit code and then transit back to
+ long mode.
+
+ @param[in] Function The 32bit code entry to be executed.
+ @param[in] Param1 The first parameter to pass to 32bit code.
+ @param[in] Param2 The second parameter to pass to 32bit code.
+
+ @return EFI_STATUS
+
+**/
+EFI_STATUS
+Execute32BitCode (
+ IN UINT64 Function,
+ IN UINT64 Param1,
+ IN UINT64 Param2
+ )
+{
+ EFI_STATUS Status;
+ IA32_DESCRIPTOR Idtr;
+
+ //
+ // Idtr might be changed inside of FSP. 32bit FSP only knows the <4G address.
+ // If IDTR.Base is >4G, FSP can not handle. So we need save/restore IDTR here for X64 only.
+ // Interrupt is already disabled here, so it is safety to update IDTR.
+ //
+ AsmReadIdtr (&Idtr);
+ Status = AsmExecute32BitCode (Function, Param1, Param2, &mGdt);
+ AsmWriteIdtr (&Idtr);
+
+ return Status;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/Thunk64To32.S b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/Thunk64To32.S
new file mode 100644
index 0000000000..923007cb17
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/Thunk64To32.S
@@ -0,0 +1,224 @@
+## @file
+# This is the assembly code to transition from long mode to compatibility mode to execute 32-bit code and then
+# transit back to long mode.
+#
+# 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
+#
+##
+
+#----------------------------------------------------------------------------
+# Procedure: AsmExecute32BitCode
+#
+# Input: None
+#
+# Output: None
+#
+# Prototype: UINT32
+# AsmExecute32BitCode (
+# IN UINT64 Function,
+# IN UINT64 Param1,
+# IN UINT64 Param2,
+# IN IA32_DESCRIPTOR *InternalGdtr
+# );
+#
+#
+# Description: A thunk function to execute 32-bit code in long mode.
+#
+#----------------------------------------------------------------------------
+
+ASM_GLOBAL ASM_PFX(AsmExecute32BitCode)
+ASM_PFX(AsmExecute32BitCode):
+ #
+ # save IFLAG and disable it
+ #
+ pushfq
+ cli
+
+ #
+ # save orignal GDTR and CS
+ #
+ movl %ds, %eax
+ push %rax
+ movl %cs, %eax
+ push %rax
+ subq $0x10, %rsp
+ sgdt (%rsp)
+ #
+ # load internal GDT
+ #
+ lgdt (%r9)
+ #
+ # Save general purpose register and rflag register
+ #
+ pushfq
+ push %rdi
+ push %rsi
+ push %rbp
+ push %rbx
+
+ #
+ # save CR3
+ #
+ movq %cr3, %rax
+ movq %rax, %rbp
+
+ #
+ # Prepare the CS and return address for the transition from 32-bit to 64-bit mode
+ #
+ movq $0x10, %rax # load long mode selector
+ shl $32, %rax
+ lea ReloadCS(%rip), %r9 #Assume the ReloadCS is under 4G
+ orq %r9, %rax
+ push %rax
+ #
+ # Save parameters for 32-bit function call
+ #
+ movq %r8, %rax
+ shl $32, %rax
+ orq %rdx, %rax
+ push %rax
+ #
+ # save the 32-bit function entry and the return address into stack which will be
+ # retrieve in compatibility mode.
+ #
+ lea ReturnBack(%rip), %rax #Assume the ReloadCS is under 4G
+ shl $32, %rax
+ orq %rcx, %rax
+ push %rax
+
+ #
+ # let rax save DS
+ #
+ movq $0x18, %rax
+
+ #
+ # Change to Compatible Segment
+ #
+ movq $8, %rcx # load compatible mode selector
+ shl $32, %rcx
+ lea Compatible(%rip), %rdx # assume address < 4G
+ orq %rdx, %rcx
+ push %rcx
+ .byte 0xcb # retf
+
+Compatible:
+ # reload DS/ES/SS to make sure they are correct referred to current GDT
+ movw %ax, %ds
+ movw %ax, %es
+ movw %ax, %ss
+
+ #
+ # Disable paging
+ #
+ movq %cr0, %rcx
+ btc $31, %ecx
+ movq %rcx, %cr0
+ #
+ # Clear EFER.LME
+ #
+ movl $0xC0000080, %ecx
+ rdmsr
+ btc $8, %eax
+ wrmsr
+
+# Now we are in protected mode
+ #
+ # Call 32-bit function. Assume the function entry address and parameter value is less than 4G
+ #
+ pop %rax # Here is the function entry
+ #
+ # Now the parameter is at the bottom of the stack, then call in to IA32 function.
+ #
+ jmp *%rax
+ReturnBack:
+ movl %eax, %ebx # save return status
+ pop %rcx # drop param1
+ pop %rcx # drop param2
+
+ #
+ # restore CR4
+ #
+ movq %cr4, %rax
+ bts $5, %eax
+ movq %rax, %cr4
+
+ #
+ # restore CR3
+ #
+ movl %ebp, %eax
+ movq %rax, %cr3
+
+ #
+ # Set EFER.LME to re-enable ia32-e
+ #
+ movl $0xC0000080, %ecx
+ rdmsr
+ bts $8, %eax
+ wrmsr
+ #
+ # Enable paging
+ #
+ movq %cr0, %rax
+ bts $31, %eax
+ mov %rax, %cr0
+# Now we are in compatible mode
+
+ #
+ # Reload cs register
+ #
+ .byte 0xcb # retf
+ReloadCS:
+ #
+ # Now we're in Long Mode
+ #
+ #
+ # Restore C register and eax hold the return status from 32-bit function.
+ # Note: Do not touch rax from now which hold the return value from IA32 function
+ #
+ movl %ebx, %eax # put return status to EAX
+ pop %rbx
+ pop %rbp
+ pop %rsi
+ pop %rdi
+ popfq
+ #
+ # Switch to orignal GDT and CS. here rsp is pointer to the orignal GDT descriptor.
+ #
+ lgdt (%rsp)
+ #
+ # drop GDT descriptor in stack
+ #
+ addq $0x10, %rsp
+ #
+ # switch to orignal CS and GDTR
+ #
+ pop %r9 # get CS
+ shl $32, %r9 # rcx[32..47] <- Cs
+ lea ReturnToLongMode(%rip), %rcx
+ orq %r9, %rcx
+ push %rcx
+ .byte 0xcb # retf
+ReturnToLongMode:
+ #
+ # Reload original DS/ES/SS
+ #
+ pop %rcx
+ movl %ecx, %ds
+ movl %ecx, %es
+ movl %ecx, %ss
+
+ #
+ # Restore IFLAG
+ #
+ popfq
+
+ ret
+
diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/Thunk64To32.asm b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/Thunk64To32.asm
new file mode 100644
index 0000000000..2108893e76
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/Thunk64To32.asm
@@ -0,0 +1,227 @@
+;; @file
+; This is the assembly code to transition from long mode to compatibility mode to execute 32-bit code and then
+; transit back to long mode.
+;
+; 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
+;
+;;
+
+;-------------------------------------------------------------------------------
+ .code
+;----------------------------------------------------------------------------
+; Procedure: AsmExecute32BitCode
+;
+; Input: None
+;
+; Output: None
+;
+; Prototype: UINT32
+; AsmExecute32BitCode (
+; IN UINT64 Function,
+; IN UINT64 Param1,
+; IN UINT64 Param2,
+; IN IA32_DESCRIPTOR *InternalGdtr
+; );
+;
+;
+; Description: A thunk function to execute 32-bit code in long mode.
+;
+;----------------------------------------------------------------------------
+AsmExecute32BitCode PROC
+ ;
+ ; save IFLAG and disable it
+ ;
+ pushfq
+ cli
+
+ ;
+ ; save orignal GDTR and CS
+ ;
+ mov rax, ds
+ push rax
+ mov rax, cs
+ push rax
+ sub rsp, 10h
+ sgdt fword ptr [rsp]
+ ;
+ ; load internal GDT
+ ;
+ lgdt fword ptr [r9]
+ ;
+ ; Save general purpose register and rflag register
+ ;
+ pushfq
+ push rdi
+ push rsi
+ push rbp
+ push rbx
+
+ ;
+ ; save CR3
+ ;
+ mov rax, cr3
+ mov rbp, rax
+
+ ;
+ ; Prepare the CS and return address for the transition from 32-bit to 64-bit mode
+ ;
+ mov rax, 10h ; load long mode selector
+ shl rax, 32
+ mov r9, OFFSET ReloadCS ;Assume the ReloadCS is under 4G
+ or rax, r9
+ push rax
+ ;
+ ; Save parameters for 32-bit function call
+ ;
+ mov rax, r8
+ shl rax, 32
+ or rax, rdx
+ push rax
+ ;
+ ; save the 32-bit function entry and the return address into stack which will be
+ ; retrieve in compatibility mode.
+ ;
+ mov rax, OFFSET ReturnBack ;Assume the ReloadCS is under 4G
+ shl rax, 32
+ or rax, rcx
+ push rax
+
+ ;
+ ; let rax save DS
+ ;
+ mov rax, 018h
+
+ ;
+ ; Change to Compatible Segment
+ ;
+ mov rcx, 08h ; load compatible mode selector
+ shl rcx, 32
+ mov rdx, OFFSET Compatible ; assume address < 4G
+ or rcx, rdx
+ push rcx
+ retf
+
+Compatible:
+ ; reload DS/ES/SS to make sure they are correct referred to current GDT
+ mov ds, ax
+ mov es, ax
+ mov ss, ax
+
+ ;
+ ; Disable paging
+ ;
+ mov rcx, cr0
+ btc ecx, 31
+ mov cr0, rcx
+ ;
+ ; Clear EFER.LME
+ ;
+ mov ecx, 0C0000080h
+ rdmsr
+ btc eax, 8
+ wrmsr
+
+; Now we are in protected mode
+ ;
+ ; Call 32-bit function. Assume the function entry address and parameter value is less than 4G
+ ;
+ pop rax ; Here is the function entry
+ ;
+ ; Now the parameter is at the bottom of the stack, then call in to IA32 function.
+ ;
+ jmp rax
+ReturnBack:
+ mov ebx, eax ; save return status
+ pop rcx ; drop param1
+ pop rcx ; drop param2
+
+ ;
+ ; restore CR4
+ ;
+ mov rax, cr4
+ bts eax, 5
+ mov cr4, rax
+
+ ;
+ ; restore CR3
+ ;
+ mov eax, ebp
+ mov cr3, rax
+
+ ;
+ ; Set EFER.LME to re-enable ia32-e
+ ;
+ mov ecx, 0C0000080h
+ rdmsr
+ bts eax, 8
+ wrmsr
+ ;
+ ; Enable paging
+ ;
+ mov rax, cr0
+ bts eax, 31
+ mov cr0, rax
+; Now we are in compatible mode
+
+ ;
+ ; Reload cs register
+ ;
+ retf
+ReloadCS:
+ ;
+ ; Now we're in Long Mode
+ ;
+ ;
+ ; Restore C register and eax hold the return status from 32-bit function.
+ ; Note: Do not touch rax from now which hold the return value from IA32 function
+ ;
+ mov eax, ebx ; put return status to EAX
+ pop rbx
+ pop rbp
+ pop rsi
+ pop rdi
+ popfq
+ ;
+ ; Switch to orignal GDT and CS. here rsp is pointer to the orignal GDT descriptor.
+ ;
+ lgdt fword ptr[rsp]
+ ;
+ ; drop GDT descriptor in stack
+ ;
+ add rsp, 10h
+ ;
+ ; switch to orignal CS and GDTR
+ ;
+ pop r9 ; get CS
+ shl r9, 32 ; rcx[32..47] <- Cs
+ mov rcx, OFFSET @F
+ or rcx, r9
+ push rcx
+ retf
+@@:
+ ;
+ ; Reload original DS/ES/SS
+ ;
+ pop rcx
+ mov ds, rcx
+ mov es, rcx
+ mov ss, rcx
+
+ ;
+ ; Restore IFLAG
+ ;
+ popfq
+
+ ret
+AsmExecute32BitCode ENDP
+
+ END
+
diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/FspPlatformSecLibSample.c b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/FspPlatformSecLibSample.c
new file mode 100644
index 0000000000..ca0728afc2
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/FspPlatformSecLibSample.c
@@ -0,0 +1,153 @@
+/** @file
+ Sample to provide FSP wrapper platform sec related function.
+
+ 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 <Ppi/SecPlatformInformation.h>
+#include <Ppi/SecPerformance.h>
+#include <Ppi/TemporaryRamSupport.h>
+
+#include <Library/LocalApicLib.h>
+
+/**
+ This interface conveys state information out of the Security (SEC) phase into PEI.
+
+ @param[in] PeiServices Pointer to the PEI Services Table.
+ @param[in,out] StructureSize Pointer to the variable describing size of the input buffer.
+ @param[out] PlatformInformationRecord Pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD.
+
+ @retval EFI_SUCCESS The data was successfully returned.
+ @retval EFI_BUFFER_TOO_SMALL The buffer was too small.
+
+**/
+EFI_STATUS
+EFIAPI
+SecPlatformInformation (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN OUT UINT64 *StructureSize,
+ OUT EFI_SEC_PLATFORM_INFORMATION_RECORD *PlatformInformationRecord
+ );
+
+/**
+ This interface conveys performance information out of the Security (SEC) phase into PEI.
+
+ This service is published by the SEC phase. The SEC phase handoff has an optional
+ EFI_PEI_PPI_DESCRIPTOR list as its final argument when control is passed from SEC into the
+ PEI Foundation. As such, if the platform supports collecting performance data in SEC,
+ this information is encapsulated into the data structure abstracted by this service.
+ This information is collected for the boot-strap processor (BSP) on IA-32.
+
+ @param[in] PeiServices The pointer to the PEI Services Table.
+ @param[in] This The pointer to this instance of the PEI_SEC_PERFORMANCE_PPI.
+ @param[out] Performance The pointer to performance data collected in SEC phase.
+
+ @retval EFI_SUCCESS The data was successfully returned.
+
+**/
+EFI_STATUS
+EFIAPI
+SecGetPerformance (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN PEI_SEC_PERFORMANCE_PPI *This,
+ OUT FIRMWARE_SEC_PERFORMANCE *Performance
+ );
+
+/**
+ This service of the TEMPORARY_RAM_SUPPORT_PPI that migrates temporary RAM into
+ permanent memory.
+
+ @param[in] PeiServices Pointer to the PEI Services Table.
+ @param[in] TemporaryMemoryBase Source Address in temporary memory from which the SEC or PEIM will copy the
+ Temporary RAM contents.
+ @param[in] PermanentMemoryBase Destination Address in permanent memory into which the SEC or PEIM will copy the
+ Temporary RAM contents.
+ @param[in] CopySize Amount of memory to migrate from temporary to permanent memory.
+
+ @retval EFI_SUCCESS The data was successfully returned.
+ @retval EFI_INVALID_PARAMETER PermanentMemoryBase + CopySize > TemporaryMemoryBase when
+ TemporaryMemoryBase > PermanentMemoryBase.
+
+**/
+EFI_STATUS
+EFIAPI
+SecTemporaryRamSupport (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
+ IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
+ IN UINTN CopySize
+ );
+
+EFI_SEC_PLATFORM_INFORMATION_PPI mSecPlatformInformationPpi = {
+ SecPlatformInformation
+};
+
+PEI_SEC_PERFORMANCE_PPI mSecPerformancePpi = {
+ SecGetPerformance
+};
+
+EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI gSecTemporaryRamSupportPpi = {
+ SecTemporaryRamSupport
+};
+
+EFI_PEI_PPI_DESCRIPTOR mPeiSecPlatformPpi[] = {
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI,
+ &gEfiSecPlatformInformationPpiGuid,
+ &mSecPlatformInformationPpi
+ },
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI,
+ &gPeiSecPerformancePpiGuid,
+ &mSecPerformancePpi
+ },
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gEfiTemporaryRamSupportPpiGuid,
+ &gSecTemporaryRamSupportPpi
+ },
+};
+
+/**
+ A developer supplied function to perform platform specific operations.
+
+ It's a developer supplied function to perform any operations appropriate to a
+ given platform. It's invoked just before passing control to PEI core by SEC
+ core. Platform developer may modify the SecCoreData passed to PEI Core.
+ It returns a platform specific PPI list that platform wishes to pass to PEI core.
+ The Generic SEC core module will merge this list to join the final list passed to
+ PEI core.
+
+ @param[in,out] SecCoreData The same parameter as passing to PEI core. It
+ could be overridden by this function.
+
+ @return The platform specific PPI list to be passed to PEI core or
+ NULL if there is no need of such platform specific PPI list.
+
+**/
+EFI_PEI_PPI_DESCRIPTOR *
+EFIAPI
+SecPlatformMain (
+ IN OUT EFI_SEC_PEI_HAND_OFF *SecCoreData
+ )
+{
+ EFI_PEI_PPI_DESCRIPTOR *PpiList;
+
+ InitializeApicTimer (0, (UINT32) -1, TRUE, 5);
+
+ PpiList = &mPeiSecPlatformPpi[0];
+
+ return PpiList;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/AsmSaveSecContext.S b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/AsmSaveSecContext.S
new file mode 100644
index 0000000000..082517eebd
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/AsmSaveSecContext.S
@@ -0,0 +1,37 @@
+## @file
+# Save Sec Conext before call FspInit API.
+#
+# 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
+#
+##
+
+#----------------------------------------------------------------------------
+# MMX Usage:
+# MM0 = BIST State
+# MM5 = Save time-stamp counter value high32bit
+# MM6 = Save time-stamp counter value low32bit.
+#
+# It should be same as SecEntry.asm and PeiCoreEntry.asm.
+#----------------------------------------------------------------------------
+
+ASM_GLOBAL ASM_PFX(AsmSaveBistValue)
+ASM_PFX(AsmSaveBistValue):
+ movl 4(%esp), %eax
+ movd %eax, %mm0
+ ret
+
+ASM_GLOBAL ASM_PFX(AsmSaveTickerValue)
+ASM_PFX(AsmSaveTickerValue):
+ movl 4(%esp), %eax
+ movd %eax, %mm6
+ movl 8(%esp), %eax
+ movd %eax, %mm5
+ ret
diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/AsmSaveSecContext.asm b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/AsmSaveSecContext.asm
new file mode 100644
index 0000000000..c9f872202a
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/AsmSaveSecContext.asm
@@ -0,0 +1,45 @@
+;; @file
+; Save Sec Conext before call FspInit API.
+;
+; 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
+;
+;;
+
+.686p
+.xmm
+.model flat,c
+.code
+
+;----------------------------------------------------------------------------
+; MMX Usage:
+; MM0 = BIST State
+; MM5 = Save time-stamp counter value high32bit
+; MM6 = Save time-stamp counter value low32bit.
+;
+; It should be same as SecEntry.asm and PeiCoreEntry.asm.
+;----------------------------------------------------------------------------
+
+AsmSaveBistValue PROC PUBLIC
+ mov eax, [esp+4]
+ movd mm0, eax
+ ret
+AsmSaveBistValue ENDP
+
+AsmSaveTickerValue PROC PUBLIC
+ mov eax, [esp+4]
+ movd mm6, eax
+ mov eax, [esp+8]
+ movd mm5, eax
+ ret
+AsmSaveTickerValue ENDP
+
+END
+
diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Fsp.h b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Fsp.h
new file mode 100644
index 0000000000..c74d0efd44
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Fsp.h
@@ -0,0 +1,50 @@
+/** @file
+ Fsp related definitions
+
+ 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.
+
+**/
+
+#ifndef __FSP_H__
+#define __FSP_H__
+
+//
+// Fv Header
+//
+#define FVH_SIGINATURE_OFFSET 0x28
+#define FVH_SIGINATURE_VALID_VALUE 0x4856465F // valid signature:_FVH
+#define FVH_HEADER_LENGTH_OFFSET 0x30
+#define FVH_EXTHEADER_OFFSET_OFFSET 0x34
+#define FVH_EXTHEADER_SIZE_OFFSET 0x10
+
+//
+// Ffs Header
+//
+#define FSP_HEADER_GUID_DWORD1 0x912740BE
+#define FSP_HEADER_GUID_DWORD2 0x47342284
+#define FSP_HEADER_GUID_DWORD3 0xB08471B9
+#define FSP_HEADER_GUID_DWORD4 0x0C3F3527
+#define FFS_HEADER_SIZE_VALUE 0x18
+
+//
+// Section Header
+//
+#define SECTION_HEADER_TYPE_OFFSET 0x03
+#define RAW_SECTION_HEADER_SIZE_VALUE 0x04
+
+//
+// Fsp Header
+//
+#define FSP_HEADER_IMAGEBASE_OFFSET 0x1C
+#define FSP_HEADER_TEMPRAMINIT_OFFSET 0x30
+
+#endif
+
diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/PeiCoreEntry.S b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/PeiCoreEntry.S
new file mode 100644
index 0000000000..004d9ff0a0
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/PeiCoreEntry.S
@@ -0,0 +1,124 @@
+## @file
+# Find and call SecStartup.
+#
+# 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
+#
+##
+
+ASM_GLOBAL ASM_PFX(CallPeiCoreEntryPoint)
+ASM_PFX(CallPeiCoreEntryPoint):
+ #
+ # Obtain the hob list pointer
+ #
+ movl 0x4(%esp), %eax
+ #
+ # Obtain the stack information
+ # ECX: start of range
+ # EDX: end of range
+ #
+ movl 0x8(%esp), %ecx
+ movl 0xC(%esp), %edx
+
+ #
+ # Platform init
+ #
+ pushal
+ pushl %edx
+ pushl %ecx
+ pushl %eax
+ call ASM_PFX(PlatformInit)
+ popl %eax
+ popl %eax
+ popl %eax
+ popal
+
+ #
+ # Set stack top pointer
+ #
+ movl %edx, %esp
+
+ #
+ # Push the hob list pointer
+ #
+ pushl %eax
+
+ #
+ # Save the value
+ # ECX: start of range
+ # EDX: end of range
+ #
+ movl %esp, %ebp
+ pushl %ecx
+ pushl %edx
+
+ #
+ # Push processor count to stack first, then BIST status (AP then BSP)
+ #
+ movl $1, %eax
+ cpuid
+ shr $16, %ebx
+ andl $0x000000FF, %ebx
+ cmp $1, %bl
+ jae PushProcessorCount
+
+ #
+ # Some processors report 0 logical processors. Effectively 0 = 1.
+ # So we fix up the processor count
+ #
+ inc %ebx
+
+PushProcessorCount:
+ pushl %ebx
+
+ #
+ # We need to implement a long-term solution for BIST capture. For now, we just copy BSP BIST
+ # for all processor threads
+ #
+ xorl %ecx, %ecx
+ movb %bl, %cl
+PushBist:
+ movd %mm0, %eax
+ pushl %eax
+ loop PushBist
+
+ # Save Time-Stamp Counter
+ movd %mm5, %eax
+ pushl %eax
+
+ movd %mm6, %eax
+ pushl %eax
+
+ #
+ # Pass entry point of the PEI core
+ #
+ movl $0xFFFFFFE0, %edi
+ pushl %ds:(%edi)
+
+ #
+ # Pass BFV into the PEI Core
+ #
+ movl $0xFFFFFFFC, %edi
+ pushl %ds:(%edi)
+
+ #
+ # Pass stack size into the PEI Core
+ #
+ movl -4(%ebp), %ecx
+ movl -8(%ebp), %edx
+ pushl %ecx # RamBase
+
+ subl %ecx, %edx
+ pushl %edx # RamSize
+
+ #
+ # Pass Control into the PEI Core
+ #
+ call ASM_PFX(SecStartup)
diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/PeiCoreEntry.asm b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/PeiCoreEntry.asm
new file mode 100644
index 0000000000..edb7bd1fda
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/PeiCoreEntry.asm
@@ -0,0 +1,135 @@
+;; @file
+; Find and call SecStartup.
+;
+; 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
+;
+;;
+
+.686p
+.xmm
+.model flat, c
+.code
+
+EXTRN SecStartup:NEAR
+EXTRN PlatformInit:NEAR
+
+CallPeiCoreEntryPoint PROC PUBLIC
+ ;
+ ; Obtain the hob list pointer
+ ;
+ mov eax, [esp+4]
+ ;
+ ; Obtain the stack information
+ ; ECX: start of range
+ ; EDX: end of range
+ ;
+ mov ecx, [esp+8]
+ mov edx, [esp+0Ch]
+
+ ;
+ ; Platform init
+ ;
+ pushad
+ push edx
+ push ecx
+ push eax
+ call PlatformInit
+ pop eax
+ pop eax
+ pop eax
+ popad
+
+ ;
+ ; Set stack top pointer
+ ;
+ mov esp, edx
+
+ ;
+ ; Push the hob list pointer
+ ;
+ push eax
+
+ ;
+ ; Save the value
+ ; ECX: start of range
+ ; EDX: end of range
+ ;
+ mov ebp, esp
+ push ecx
+ push edx
+
+ ;
+ ; Push processor count to stack first, then BIST status (AP then BSP)
+ ;
+ mov eax, 1
+ cpuid
+ shr ebx, 16
+ and ebx, 0000000FFh
+ cmp bl, 1
+ jae PushProcessorCount
+
+ ;
+ ; Some processors report 0 logical processors. Effectively 0 = 1.
+ ; So we fix up the processor count
+ ;
+ inc ebx
+
+PushProcessorCount:
+ push ebx
+
+ ;
+ ; We need to implement a long-term solution for BIST capture. For now, we just copy BSP BIST
+ ; for all processor threads
+ ;
+ xor ecx, ecx
+ mov cl, bl
+PushBist:
+ movd eax, mm0
+ push eax
+ loop PushBist
+
+ ; Save Time-Stamp Counter
+ movd eax, mm5
+ push eax
+
+ movd eax, mm6
+ push eax
+
+ ;
+ ; Pass entry point of the PEI core
+ ;
+ mov edi, 0FFFFFFE0h
+ push DWORD PTR ds:[edi]
+
+ ;
+ ; Pass BFV into the PEI Core
+ ;
+ mov edi, 0FFFFFFFCh
+ push DWORD PTR ds:[edi]
+
+ ;
+ ; Pass stack size into the PEI Core
+ ;
+ mov ecx, [ebp - 4]
+ mov edx, [ebp - 8]
+ push ecx ; RamBase
+
+ sub edx, ecx
+ push edx ; RamSize
+
+ ;
+ ; Pass Control into the PEI Core
+ ;
+ call SecStartup
+CallPeiCoreEntryPoint ENDP
+
+END
+
diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/SecEntry.S b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/SecEntry.S
new file mode 100644
index 0000000000..c7870fe42e
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/SecEntry.S
@@ -0,0 +1,322 @@
+## @file
+# This is the code that goes from real-mode to protected mode.
+# It consumes the reset vector, calls TempRamInit API from FSP binary.
+#
+# 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 "Fsp.h"
+
+ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdFlashFvFspBase)
+ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdFlashFvFspSize)
+
+ASM_GLOBAL ASM_PFX(_TEXT_REALMODE)
+ASM_PFX(_TEXT_REALMODE):
+#----------------------------------------------------------------------------
+#
+# Procedure: _ModuleEntryPoint
+#
+# Input: None
+#
+# Output: None
+#
+# Destroys: Assume all registers
+#
+# Description:
+#
+# Transition to non-paged flat-model protected mode from a
+# hard-coded GDT that provides exactly two descriptors.
+# This is a bare bones transition to protected mode only
+# used for a while in PEI and possibly DXE.
+#
+# After enabling protected mode, a far jump is executed to
+# transfer to PEI using the newly loaded GDT.
+#
+# Return: None
+#
+# MMX Usage:
+# MM0 = BIST State
+# MM5 = Save time-stamp counter value high32bit
+# MM6 = Save time-stamp counter value low32bit.
+#
+#----------------------------------------------------------------------------
+
+.align 4
+ASM_GLOBAL ASM_PFX(_ModuleEntryPoint)
+ASM_PFX(_ModuleEntryPoint):
+ fninit # clear any pending Floating point exceptions
+ #
+ # Store the BIST value in mm0
+ #
+ movd %eax, %mm0
+
+ #
+ # Save time-stamp counter value
+ # rdtsc load 64bit time-stamp counter to EDX:EAX
+ #
+ rdtsc
+ movd %edx, %mm5
+ movd %ecx, %mm6
+
+ #
+ # Load the GDT table in GdtDesc
+ #
+ movl $GdtDesc, %esi
+ .byte 0x66
+ lgdt %cs:(%si)
+
+ #
+ # Transition to 16 bit protected mode
+ #
+ movl %cr0, %eax # Get control register 0
+ orl $0x00000003, %eax # Set PE bit (bit #0) & MP bit (bit #1)
+ movl %eax, %cr0 # Activate protected mode
+
+ movl %cr4, %eax # Get control register 4
+ orl $0x00000600, %eax # Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10)
+ movl %eax, %cr4
+
+ #
+ # Now we're in 16 bit protected mode
+ # Set up the selectors for 32 bit protected mode entry
+ #
+ movw SYS_DATA_SEL, %ax
+ movw %ax, %ds
+ movw %ax, %es
+ movw %ax, %fs
+ movw %ax, %gs
+ movw %ax, %ss
+
+ #
+ # Transition to Flat 32 bit protected mode
+ # The jump to a far pointer causes the transition to 32 bit mode
+ #
+ movl ASM_PFX(ProtectedModeEntryLinearAddress), %esi
+ jmp *%cs:(%si)
+
+ASM_GLOBAL ASM_PFX(_TEXT_PROTECTED_MODE)
+ASM_PFX(_TEXT_PROTECTED_MODE):
+
+#----------------------------------------------------------------------------
+#
+# Procedure: ProtectedModeEntryPoint
+#
+# Input: None
+#
+# Output: None
+#
+# Destroys: Assume all registers
+#
+# Description:
+#
+# This function handles:
+# Call two basic APIs from FSP binary
+# Initializes stack with some early data (BIST, PEI entry, etc)
+#
+# Return: None
+#
+#----------------------------------------------------------------------------
+
+.align 4
+ASM_GLOBAL ASM_PFX(ProtectedModeEntryPoint)
+ASM_PFX(ProtectedModeEntryPoint):
+
+ # Find the fsp info header
+ movl ASM_PFX(_gPcd_FixedAtBuild_PcdFlashFvFspBase), %edi
+ movl ASM_PFX(_gPcd_FixedAtBuild_PcdFlashFvFspSize), %ecx
+
+ movl FVH_SIGINATURE_OFFSET(%edi), %eax
+ cmp $FVH_SIGINATURE_VALID_VALUE, %eax
+ jnz FspHeaderNotFound
+
+ xorl %eax, %eax
+ movw FVH_EXTHEADER_OFFSET_OFFSET(%edi), %ax
+ cmp %ax, 0
+ jnz FspFvExtHeaderExist
+
+ xorl %eax, %eax
+ movw FVH_HEADER_LENGTH_OFFSET(%edi), %ax # Bypass Fv Header
+ addl %eax, %edi
+ jmp FspCheckFfsHeader
+
+FspFvExtHeaderExist:
+ addl %eax, %edi
+ movl FVH_EXTHEADER_SIZE_OFFSET(%edi), %eax # Bypass Ext Fv Header
+ addl %eax, %edi
+
+ # Round up to 8 byte alignment
+ movl %edi, %eax
+ andb $0x07, %al
+ jz FspCheckFfsHeader
+
+ and $0xFFFFFFF8, %edi
+ add $0x08, %edi
+
+FspCheckFfsHeader:
+ # Check the ffs guid
+ movl (%edi), %eax
+ cmp $FSP_HEADER_GUID_DWORD1, %eax
+ jnz FspHeaderNotFound
+
+ movl 0x4(%edi), %eax
+ cmp $FSP_HEADER_GUID_DWORD2, %eax
+ jnz FspHeaderNotFound
+
+ movl 0x08(%edi), %eax
+ cmp $FSP_HEADER_GUID_DWORD3, %eax
+ jnz FspHeaderNotFound
+
+ movl 0x0c(%edi), %eax
+ cmp $FSP_HEADER_GUID_DWORD4, %eax
+ jnz FspHeaderNotFound
+
+ add $FFS_HEADER_SIZE_VALUE, %edi # Bypass the ffs header
+
+ # Check the section type as raw section
+ movb SECTION_HEADER_TYPE_OFFSET(%edi), %al
+ cmp $0x19, %al
+ jnz FspHeaderNotFound
+
+ addl $RAW_SECTION_HEADER_SIZE_VALUE, %edi # Bypass the section header
+ jmp FspHeaderFound
+
+FspHeaderNotFound:
+ jmp .
+
+FspHeaderFound:
+ # Get the fsp TempRamInit Api address
+ movl FSP_HEADER_IMAGEBASE_OFFSET(%edi), %eax
+ addl FSP_HEADER_TEMPRAMINIT_OFFSET(%edi), %eax
+
+ # Setup the hardcode stack
+ movl $TempRamInitStack, %esp
+
+ # Call the fsp TempRamInit Api
+ jmp *%eax
+
+TempRamInitDone:
+ cmp $0x0, %eax
+ jnz FspApiFailed
+
+ # ECX: start of range
+ # EDX: end of range
+ movl %edx, %esp
+ pushl %edx
+ pushl %ecx
+ pushl %eax # zero - no hob list yet
+ call ASM_PFX(CallPeiCoreEntryPoint)
+
+FspApiFailed:
+ jmp .
+
+.align 0x10
+TempRamInitStack:
+ .long TempRamInitDone
+ .long ASM_PFX(TempRamInitParams)
+
+#
+# ROM-based Global-Descriptor Table for the Tiano PEI Phase
+#
+.align 16
+
+#
+# GDT[0]: 0x00: Null entry, never used.
+#
+.equ NULL_SEL, . - GDT_BASE # Selector [0]
+GDT_BASE:
+BootGdtTable: .long 0
+ .long 0
+#
+# Linear data segment descriptor
+#
+.equ LINEAR_SEL, . - GDT_BASE # Selector [0x8]
+ .word 0xFFFF # limit 0xFFFFF
+ .word 0 # base 0
+ .byte 0
+ .byte 0x92 # present, ring 0, data, expand-up, writable
+ .byte 0xCF # page-granular, 32-bit
+ .byte 0
+#
+# Linear code segment descriptor
+#
+.equ LINEAR_CODE_SEL, . - GDT_BASE # Selector [0x10]
+ .word 0xFFFF # limit 0xFFFFF
+ .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 [0x18]
+ .word 0xFFFF # limit 0xFFFFF
+ .word 0 # base 0
+ .byte 0
+ .byte 0x93 # present, ring 0, data, expand-up, not-writable
+ .byte 0xCF # page-granular, 32-bit
+ .byte 0
+
+#
+# System code segment descriptor
+#
+.equ SYS_CODE_SEL, . - GDT_BASE # Selector [0x20]
+ .word 0xFFFF # limit 0xFFFFF
+ .word 0 # base 0
+ .byte 0
+ .byte 0x9A # present, ring 0, data, expand-up, writable
+ .byte 0xCF # page-granular, 32-bit
+ .byte 0
+#
+# Spare segment descriptor
+#
+.equ SYS16_CODE_SEL, . - GDT_BASE # Selector [0x28]
+ .word 0xFFFF # limit 0xFFFFF
+ .word 0 # base 0
+ .byte 0x0E # Changed from F000 to E000.
+ .byte 0x9B # present, ring 0, code, expand-up, writable
+ .byte 0x00 # byte-granular, 16-bit
+ .byte 0
+#
+# Spare segment descriptor
+#
+.equ SYS16_DATA_SEL, . - GDT_BASE # Selector [0x30]
+ .word 0xFFFF # limit 0xFFFF
+ .word 0 # base 0
+ .byte 0
+ .byte 0x93 # present, ring 0, data, expand-up, not-writable
+ .byte 0x00 # byte-granular, 16-bit
+ .byte 0
+
+#
+# Spare segment descriptor
+#
+.equ SPARE5_SEL, . - GDT_BASE # Selector [0x38]
+ .word 0 # limit 0
+ .word 0 # base 0
+ .byte 0
+ .byte 0 # present, ring 0, data, expand-up, writable
+ .byte 0 # page-granular, 32-bit
+ .byte 0
+.equ GDT_SIZE, . - BootGdtTable # Size, in bytes
+
+#
+# GDT Descriptor
+#
+GdtDesc: # GDT descriptor
+ .word GDT_SIZE - 1 # GDT limit
+ .long BootGdtTable # GDT base address
+
+ASM_PFX(ProtectedModeEntryLinearAddress):
+ProtectedModeEntryLinearOffset:
+ .long ASM_PFX(ProtectedModeEntryPoint) # Offset of our 32 bit code
+ .word LINEAR_CODE_SEL
diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/SecEntry.asm b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/SecEntry.asm
new file mode 100644
index 0000000000..b7958ddf66
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/SecEntry.asm
@@ -0,0 +1,340 @@
+;; @file
+; This is the code that goes from real-mode to protected mode.
+; It consumes the reset vector, calls TempRamInit API from FSP binary.
+;
+; 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 "Fsp.h"
+
+.686p
+.xmm
+.model small, c
+
+EXTRN CallPeiCoreEntryPoint:NEAR
+EXTRN TempRamInitParams:FAR
+
+; Pcds
+EXTRN PcdGet32 (PcdFlashFvFspBase):DWORD
+EXTRN PcdGet32 (PcdFlashFvFspSize):DWORD
+
+_TEXT_REALMODE SEGMENT PARA PUBLIC USE16 'CODE'
+ ASSUME CS:_TEXT_REALMODE, DS:_TEXT_REALMODE
+
+;----------------------------------------------------------------------------
+;
+; Procedure: _ModuleEntryPoint
+;
+; Input: None
+;
+; Output: None
+;
+; Destroys: Assume all registers
+;
+; Description:
+;
+; Transition to non-paged flat-model protected mode from a
+; hard-coded GDT that provides exactly two descriptors.
+; This is a bare bones transition to protected mode only
+; used for a while in PEI and possibly DXE.
+;
+; After enabling protected mode, a far jump is executed to
+; transfer to PEI using the newly loaded GDT.
+;
+; Return: None
+;
+; MMX Usage:
+; MM0 = BIST State
+; MM5 = Save time-stamp counter value high32bit
+; MM6 = Save time-stamp counter value low32bit.
+;
+;----------------------------------------------------------------------------
+
+align 4
+_ModuleEntryPoint PROC NEAR C PUBLIC
+ fninit ; clear any pending Floating point exceptions
+ ;
+ ; Store the BIST value in mm0
+ ;
+ movd mm0, eax
+
+ ;
+ ; Save time-stamp counter value
+ ; rdtsc load 64bit time-stamp counter to EDX:EAX
+ ;
+ rdtsc
+ movd mm5, edx
+ movd mm6, eax
+
+ ;
+ ; Load the GDT table in GdtDesc
+ ;
+ mov esi, OFFSET GdtDesc
+ DB 66h
+ lgdt fword ptr cs:[si]
+
+ ;
+ ; Transition to 16 bit protected mode
+ ;
+ mov eax, cr0 ; Get control register 0
+ or eax, 00000003h ; Set PE bit (bit #0) & MP bit (bit #1)
+ mov cr0, eax ; Activate protected mode
+
+ mov eax, cr4 ; Get control register 4
+ or eax, 00000600h ; Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10)
+ mov cr4, eax
+
+ ;
+ ; Now we're in 16 bit protected mode
+ ; Set up the selectors for 32 bit protected mode entry
+ ;
+ mov ax, SYS_DATA_SEL
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+ mov ss, ax
+
+ ;
+ ; Transition to Flat 32 bit protected mode
+ ; The jump to a far pointer causes the transition to 32 bit mode
+ ;
+ mov esi, offset ProtectedModeEntryLinearAddress
+ jmp fword ptr cs:[si]
+
+_ModuleEntryPoint ENDP
+_TEXT_REALMODE ENDS
+
+_TEXT_PROTECTED_MODE SEGMENT PARA PUBLIC USE32 'CODE'
+ ASSUME CS:_TEXT_PROTECTED_MODE, DS:_TEXT_PROTECTED_MODE
+
+;----------------------------------------------------------------------------
+;
+; Procedure: ProtectedModeEntryPoint
+;
+; Input: None
+;
+; Output: None
+;
+; Destroys: Assume all registers
+;
+; Description:
+;
+; This function handles:
+; Call two basic APIs from FSP binary
+; Initializes stack with some early data (BIST, PEI entry, etc)
+;
+; Return: None
+;
+;----------------------------------------------------------------------------
+
+align 4
+ProtectedModeEntryPoint PROC NEAR PUBLIC
+
+ ; Find the fsp info header
+ mov edi, PcdGet32 (PcdFlashFvFspBase)
+ mov ecx, PcdGet32 (PcdFlashFvFspSize)
+
+ mov eax, dword ptr [edi + FVH_SIGINATURE_OFFSET]
+ cmp eax, FVH_SIGINATURE_VALID_VALUE
+ jnz FspHeaderNotFound
+
+ xor eax, eax
+ mov ax, word ptr [edi + FVH_EXTHEADER_OFFSET_OFFSET]
+ cmp ax, 0
+ jnz FspFvExtHeaderExist
+
+ xor eax, eax
+ mov ax, word ptr [edi + FVH_HEADER_LENGTH_OFFSET] ; Bypass Fv Header
+ add edi, eax
+ jmp FspCheckFfsHeader
+
+FspFvExtHeaderExist:
+ add edi, eax
+ mov eax, dword ptr [edi + FVH_EXTHEADER_SIZE_OFFSET] ; Bypass Ext Fv Header
+ add edi, eax
+
+ ; Round up to 8 byte alignment
+ mov eax, edi
+ and al, 07h
+ jz FspCheckFfsHeader
+
+ and edi, 0FFFFFFF8h
+ add edi, 08h
+
+FspCheckFfsHeader:
+ ; Check the ffs guid
+ mov eax, dword ptr [edi]
+ cmp eax, FSP_HEADER_GUID_DWORD1
+ jnz FspHeaderNotFound
+
+ mov eax, dword ptr [edi + 4]
+ cmp eax, FSP_HEADER_GUID_DWORD2
+ jnz FspHeaderNotFound
+
+ mov eax, dword ptr [edi + 8]
+ cmp eax, FSP_HEADER_GUID_DWORD3
+ jnz FspHeaderNotFound
+
+ mov eax, dword ptr [edi + 0Ch]
+ cmp eax, FSP_HEADER_GUID_DWORD4
+ jnz FspHeaderNotFound
+
+ add edi, FFS_HEADER_SIZE_VALUE ; Bypass the ffs header
+
+ ; Check the section type as raw section
+ mov al, byte ptr [edi + SECTION_HEADER_TYPE_OFFSET]
+ cmp al, 019h
+ jnz FspHeaderNotFound
+
+ add edi, RAW_SECTION_HEADER_SIZE_VALUE ; Bypass the section header
+ jmp FspHeaderFound
+
+FspHeaderNotFound:
+ jmp $
+
+FspHeaderFound:
+ ; Get the fsp TempRamInit Api address
+ mov eax, dword ptr [edi + FSP_HEADER_IMAGEBASE_OFFSET]
+ add eax, dword ptr [edi + FSP_HEADER_TEMPRAMINIT_OFFSET]
+
+ ; Setup the hardcode stack
+ mov esp, OFFSET TempRamInitStack
+
+ ; Call the fsp TempRamInit Api
+ jmp eax
+
+TempRamInitDone:
+ cmp eax, 0
+ jnz FspApiFailed
+
+ ; ECX: start of range
+ ; EDX: end of range
+ mov esp, edx
+ push edx
+ push ecx
+ push eax ; zero - no hob list yet
+ call CallPeiCoreEntryPoint
+
+FspApiFailed:
+ jmp $
+
+align 10h
+TempRamInitStack:
+ DD OFFSET TempRamInitDone
+ DD OFFSET TempRamInitParams
+
+ProtectedModeEntryPoint ENDP
+
+;
+; ROM-based Global-Descriptor Table for the Tiano 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 data segment descriptor
+;
+LINEAR_SEL EQU $ - GDT_BASE ; Selector [0x8]
+ DW 0FFFFh ; limit 0xFFFFF
+ DW 0 ; base 0
+ DB 0
+ DB 092h ; present, ring 0, data, expand-up, writable
+ DB 0CFh ; page-granular, 32-bit
+ DB 0
+;
+; Linear code segment descriptor
+;
+LINEAR_CODE_SEL EQU $ - GDT_BASE ; Selector [0x10]
+ DW 0FFFFh ; limit 0xFFFFF
+ DW 0 ; base 0
+ DB 0
+ DB 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 [0x18]
+ DW 0FFFFh ; limit 0xFFFFF
+ DW 0 ; base 0
+ DB 0
+ DB 093h ; present, ring 0, data, expand-up, not-writable
+ DB 0CFh ; page-granular, 32-bit
+ DB 0
+
+;
+; System code segment descriptor
+;
+SYS_CODE_SEL EQU $ - GDT_BASE ; Selector [0x20]
+ DW 0FFFFh ; limit 0xFFFFF
+ DW 0 ; base 0
+ DB 0
+ DB 09Ah ; present, ring 0, data, expand-up, writable
+ DB 0CFh ; page-granular, 32-bit
+ DB 0
+;
+; Spare segment descriptor
+;
+SYS16_CODE_SEL EQU $ - GDT_BASE ; Selector [0x28]
+ DW 0FFFFh ; limit 0xFFFFF
+ DW 0 ; base 0
+ DB 0Eh ; Changed from F000 to E000.
+ DB 09Bh ; present, ring 0, code, expand-up, writable
+ DB 00h ; byte-granular, 16-bit
+ DB 0
+;
+; Spare segment descriptor
+;
+SYS16_DATA_SEL EQU $ - GDT_BASE ; Selector [0x30]
+ DW 0FFFFh ; limit 0xFFFF
+ DW 0 ; base 0
+ DB 0
+ DB 093h ; present, ring 0, data, expand-up, not-writable
+ DB 00h ; byte-granular, 16-bit
+ DB 0
+
+;
+; Spare segment descriptor
+;
+SPARE5_SEL EQU $ - GDT_BASE ; Selector [0x38]
+ DW 0 ; limit 0
+ DW 0 ; base 0
+ DB 0
+ DB 0 ; present, ring 0, data, expand-up, writable
+ DB 0 ; 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
+
+_TEXT_PROTECTED_MODE ENDS
+END
+
diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Stack.S b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Stack.S
new file mode 100644
index 0000000000..cf4522c89b
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Stack.S
@@ -0,0 +1,74 @@
+## @file
+# Switch the stack from temporary memory to permenent memory.
+#
+# 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
+#
+##
+
+#------------------------------------------------------------------------------
+# VOID
+# EFIAPI
+# SecSwitchStack (
+# UINT32 TemporaryMemoryBase,
+# UINT32 PermenentMemoryBase
+# )#
+#------------------------------------------------------------------------------
+ASM_GLOBAL ASM_PFX (SecSwitchStack)
+ASM_PFX(SecSwitchStack):
+ #
+ # Save standard registers so they can be used to change stack
+ #
+ pushl %eax
+ pushl %ebx
+ pushl %ecx
+ pushl %edx
+
+ #
+ # !!CAUTION!! this function address's is pushed into stack after
+ # migration of whole temporary memory, so need save it to permenent
+ # memory at first!
+ #
+ movl 20(%esp), %ebx # Save the first parameter
+ movl 24(%esp), %ecx # Save the second parameter
+
+ #
+ # Save this function's return address into permenent memory at first.
+ # Then, Fixup the esp point to permenent memory
+ #
+ movl %esp, %eax
+ subl %ebx, %eax
+ addl %ecx, %eax
+ movl 0(%esp), %edx # copy pushed register's value to permenent memory
+ movl %edx, 0(%eax)
+ movl 4(%esp), %edx
+ movl %edx, 4(%eax)
+ movl 8(%esp), %edx
+ movl %edx, 8(%eax)
+ movl 12(%esp), %edx
+ movl %edx, 12(%eax)
+ movl 16(%esp), %edx # Update this function's return address into permenent memory
+ movl %edx, 16(%eax)
+ movl %eax, %esp # From now, esp is pointed to permenent memory
+
+ #
+ # Fixup the ebp point to permenent memory
+ #
+ movl %ebp, %eax
+ subl %ebx, %eax
+ addl %ecx, %eax
+ movl %eax, %ebp # From now, ebp is pointed to permenent memory
+
+ popl %edx
+ popl %ecx
+ popl %ebx
+ popl %eax
+ ret
+
diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Stack.asm b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Stack.asm
new file mode 100644
index 0000000000..42d6e9a990
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Stack.asm
@@ -0,0 +1,81 @@
+;; @file
+; Switch the stack from temporary memory to permenent memory.
+;
+; 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
+;
+;;
+
+ .586p
+ .model flat,C
+ .code
+
+;------------------------------------------------------------------------------
+; VOID
+; EFIAPI
+; SecSwitchStack (
+; UINT32 TemporaryMemoryBase,
+; UINT32 PermenentMemoryBase
+; );
+;------------------------------------------------------------------------------
+SecSwitchStack PROC
+ ;
+ ; Save three register: eax, ebx, ecx
+ ;
+ push eax
+ push ebx
+ push ecx
+ push edx
+
+ ;
+ ; !!CAUTION!! this function address's is pushed into stack after
+ ; migration of whole temporary memory, so need save it to permenent
+ ; memory at first!
+ ;
+
+ mov ebx, [esp + 20] ; Save the first parameter
+ mov ecx, [esp + 24] ; Save the second parameter
+
+ ;
+ ; Save this function's return address into permenent memory at first.
+ ; Then, Fixup the esp point to permenent memory
+ ;
+ mov eax, esp
+ sub eax, ebx
+ add eax, ecx
+ mov edx, dword ptr [esp] ; copy pushed register's value to permenent memory
+ mov dword ptr [eax], edx
+ mov edx, dword ptr [esp + 4]
+ mov dword ptr [eax + 4], edx
+ mov edx, dword ptr [esp + 8]
+ mov dword ptr [eax + 8], edx
+ mov edx, dword ptr [esp + 12]
+ mov dword ptr [eax + 12], edx
+ mov edx, dword ptr [esp + 16] ; Update this function's return address into permenent memory
+ mov dword ptr [eax + 16], edx
+ mov esp, eax ; From now, esp is pointed to permenent memory
+
+ ;
+ ; Fixup the ebp point to permenent memory
+ ;
+ mov eax, ebp
+ sub eax, ebx
+ add eax, ecx
+ mov ebp, eax ; From now, ebp is pointed to permenent memory
+
+ pop edx
+ pop ecx
+ pop ebx
+ pop eax
+ ret
+SecSwitchStack ENDP
+
+ END
+
diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/PlatformInit.c b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/PlatformInit.c
new file mode 100644
index 0000000000..d6aba92884
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/PlatformInit.c
@@ -0,0 +1,44 @@
+/** @file
+ Sample to provide platform init function.
+
+ 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/DebugLib.h>
+
+/**
+ Platform initialization.
+
+ @param[in] FspHobList HobList produced by FSP.
+ @param[in] StartOfRange Start of temporary RAM.
+ @param[in] EndOfRange End of temporary RAM.
+
+**/
+VOID
+EFIAPI
+PlatformInit (
+ IN VOID *FspHobList,
+ IN VOID *StartOfRange,
+ IN VOID *EndOfRange
+ )
+{
+ //
+ // Platform initialization
+ // Enable Serial port here
+ //
+ DEBUG ((DEBUG_INFO, "PrintPeiCoreEntryPointParam\n"));
+ DEBUG ((DEBUG_INFO, "FspHobList - 0x%x\n", FspHobList));
+ DEBUG ((DEBUG_INFO, "StartOfRange - 0x%x\n", StartOfRange));
+ DEBUG ((DEBUG_INFO, "EndOfRange - 0x%x\n", EndOfRange));
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SaveSecContext.c b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SaveSecContext.c
new file mode 100644
index 0000000000..8458b87aac
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SaveSecContext.c
@@ -0,0 +1,115 @@
+/** @file
+ Sample to provide SaveSecContext function.
+
+ 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/DebugLib.h>
+
+#include <Ppi/TopOfTemporaryRam.h>
+#include <Ppi/SecPlatformInformation.h>
+
+/**
+ Save BIST value before call FspInit.
+
+ @param[in] Bist BIST value.
+
+**/
+VOID
+AsmSaveBistValue (
+ IN UINT32 Bist
+ );
+
+/**
+ Save Ticker value before call FspInit.
+
+ @param[in] Ticker Ticker value.
+
+**/
+VOID
+AsmSaveTickerValue (
+ IN UINT64 Ticker
+ );
+
+/**
+ Save SEC context before call FspInit.
+
+ @param[in] PeiServices Pointer to PEI Services Table.
+
+**/
+VOID
+EFIAPI
+SaveSecContext (
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ UINT32 *Bist;
+ UINT64 *Ticker;
+ UINT32 Size;
+ UINT32 Count;
+ UINT32 TopOfTemporaryRam;
+ VOID *TopOfTemporaryRamPpi;
+ EFI_STATUS Status;
+
+ DEBUG ((DEBUG_INFO, "SaveSecContext - 0x%x\n", PeiServices));
+
+ Status = (*PeiServices)->LocatePpi (
+ PeiServices,
+ &gTopOfTemporaryRamPpiGuid,
+ 0,
+ NULL,
+ (VOID **) &TopOfTemporaryRamPpi
+ );
+ if (EFI_ERROR (Status)) {
+ return ;
+ }
+
+ DEBUG ((DEBUG_INFO, "TopOfTemporaryRamPpi - 0x%x\n", TopOfTemporaryRamPpi));
+
+ //
+ // The entries of BIST information, together with the number of them,
+ // reside in the bottom of stack, left untouched by normal stack operation.
+ // This routine copies the BIST information to the buffer pointed by
+ // PlatformInformationRecord for output.
+ //
+ // |--------------| <- TopOfTemporaryRam
+ // |Number of BSPs|
+ // |--------------|
+ // | BIST |
+ // |--------------|
+ // | .... |
+ // |--------------|
+ // | TSC[63:32] |
+ // |--------------|
+ // | TSC[31:00] |
+ // |--------------|
+ //
+
+ TopOfTemporaryRam = (UINT32) (UINTN) TopOfTemporaryRamPpi - sizeof (UINT32);
+ TopOfTemporaryRam -= sizeof (UINT32) * 2;
+ DEBUG ((DEBUG_INFO, "TopOfTemporaryRam - 0x%x\n", TopOfTemporaryRam));
+ Count = *(UINT32 *) (UINTN) (TopOfTemporaryRam - sizeof (UINT32));
+ DEBUG ((DEBUG_INFO, "Count - 0x%x\n", Count));
+ Size = Count * sizeof (IA32_HANDOFF_STATUS);
+ DEBUG ((DEBUG_INFO, "Size - 0x%x\n", Size));
+
+ Bist = (UINT32 *) (UINTN) (TopOfTemporaryRam - sizeof (UINT32) - Size);
+ DEBUG ((DEBUG_INFO, "Bist - 0x%x\n", *Bist));
+ Ticker = (UINT64 *) (UINTN) (TopOfTemporaryRam - sizeof (UINT32) - Size - sizeof (UINT64));
+ DEBUG ((DEBUG_INFO, "Ticker - 0x%lx\n", *Ticker));
+
+ // Just need record BSP
+ AsmSaveBistValue (*Bist);
+ AsmSaveTickerValue (*Ticker);
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecGetPerformance.c b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecGetPerformance.c
new file mode 100644
index 0000000000..9fe4793415
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecGetPerformance.c
@@ -0,0 +1,92 @@
+/** @file
+ Sample to provide SecGetPerformance function.
+
+ 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 <Ppi/SecPerformance.h>
+#include <Ppi/TopOfTemporaryRam.h>
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/TimerLib.h>
+#include <Library/DebugLib.h>
+
+/**
+ This interface conveys performance information out of the Security (SEC) phase into PEI.
+
+ This service is published by the SEC phase. The SEC phase handoff has an optional
+ EFI_PEI_PPI_DESCRIPTOR list as its final argument when control is passed from SEC into the
+ PEI Foundation. As such, if the platform supports collecting performance data in SEC,
+ this information is encapsulated into the data structure abstracted by this service.
+ This information is collected for the boot-strap processor (BSP) on IA-32.
+
+ @param[in] PeiServices The pointer to the PEI Services Table.
+ @param[in] This The pointer to this instance of the PEI_SEC_PERFORMANCE_PPI.
+ @param[out] Performance The pointer to performance data collected in SEC phase.
+
+ @retval EFI_SUCCESS The data was successfully returned.
+
+**/
+EFI_STATUS
+EFIAPI
+SecGetPerformance (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN PEI_SEC_PERFORMANCE_PPI *This,
+ OUT FIRMWARE_SEC_PERFORMANCE *Performance
+ )
+{
+ UINT32 Size;
+ UINT32 Count;
+ UINT32 TopOfTemporaryRam;
+ UINT64 Ticker;
+ VOID *TopOfTemporaryRamPpi;
+ EFI_STATUS Status;
+
+ DEBUG ((DEBUG_INFO, "SecGetPerformance\n"));
+
+ Status = (*PeiServices)->LocatePpi (
+ PeiServices,
+ &gTopOfTemporaryRamPpiGuid,
+ 0,
+ NULL,
+ (VOID **) &TopOfTemporaryRamPpi
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // |--------------| <- TopOfTemporaryRam
+ // |Number of BSPs|
+ // |--------------|
+ // | BIST |
+ // |--------------|
+ // | .... |
+ // |--------------|
+ // | TSC[63:32] |
+ // |--------------|
+ // | TSC[31:00] |
+ // |--------------|
+ //
+ TopOfTemporaryRam = (UINT32) (UINTN) TopOfTemporaryRamPpi - sizeof (UINT32);
+ TopOfTemporaryRam -= sizeof (UINT32) * 2;
+ Count = *(UINT32 *) (UINTN) (TopOfTemporaryRam - sizeof (UINT32));
+ Size = Count * sizeof (UINT64);
+
+ Ticker = *(UINT64 *) (UINTN) (TopOfTemporaryRam - sizeof (UINT32) - Size - sizeof (UINT32) * 2);
+ Performance->ResetEnd = GetTimeInNanoSecond (Ticker);
+
+ return EFI_SUCCESS;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPeiFspPlatformSecLibSample.inf b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPeiFspPlatformSecLibSample.inf
new file mode 100644
index 0000000000..7dd8c1447f
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPeiFspPlatformSecLibSample.inf
@@ -0,0 +1,97 @@
+## @file
+# Sample to provide FSP wrapper platform sec related function.
+#
+# 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 Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SecPeiFspPlatformSecLibSample
+ FILE_GUID = 5B2B6493-BEBB-4d44-8278-35F40F5289BC
+ MODULE_UNI_FILE = SecPeiFspPlatformSecLibSample.uni
+ MODULE_TYPE = SEC
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = FspPlatformSecLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+################################################################################
+#
+# Sources Section - list of files that are required for the build to succeed.
+#
+################################################################################
+
+[Sources]
+ FspPlatformSecLibSample.c
+ SecRamInitData.c
+ SaveSecContext.c
+ SecPlatformInformation.c
+ SecGetPerformance.c
+ SecTempRamSupport.c
+ PlatformInit.c
+
+[Sources.IA32]
+ Ia32/SecEntry.asm
+ Ia32/PeiCoreEntry.asm
+ Ia32/AsmSaveSecContext.asm
+ Ia32/Stack.asm
+ Ia32/Fsp.h
+ Ia32/SecEntry.S
+ Ia32/PeiCoreEntry.S
+ Ia32/AsmSaveSecContext.S
+ Ia32/Stack.S
+
+################################################################################
+#
+# Package Dependency Section - list of Package files that are required for
+# this module.
+#
+################################################################################
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+ BroxtonFspPkg/BroxtonFspPkg.dec
+ IntelFsp2Pkg/IntelFsp2Pkg.dec
+ BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec #override
+ IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec
+
+[LibraryClasses]
+ LocalApicLib
+
+[Ppis]
+ gEfiSecPlatformInformationPpiGuid ## CONSUMES
+ gPeiSecPerformancePpiGuid ## CONSUMES
+ gEfiTemporaryRamSupportPpiGuid ## CONSUMES
+
+[Pcd]
+ gIntelFsp2WrapperTokenSpaceGuid.PcdPeiTemporaryRamStackSize ## CONSUMES
+ gIntelFsp2WrapperTokenSpaceGuid.PcdFlashFvFspBase ## CONSUMES
+ gIntelFsp2WrapperTokenSpaceGuid.PcdFlashFvFspSize ## CONSUMES
+
+[FixedPcd]
+ gIntelFsp2WrapperTokenSpaceGuid.PcdCpuMicrocodePatchAddress ## CONSUMES
+ gIntelFsp2WrapperTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize ## CONSUMES
+ gIntelFsp2WrapperTokenSpaceGuid.PcdFlashMicroCodeOffset ## CONSUMES
+ gIntelFsp2WrapperTokenSpaceGuid.PcdFlashCodeCacheAddress ## CONSUMES
+ gIntelFsp2WrapperTokenSpaceGuid.PcdFlashCodeCacheSize ## CONSUMES
+
diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPeiFspPlatformSecLibSample.uni b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPeiFspPlatformSecLibSample.uni
new file mode 100644
index 0000000000..50dd05a11b
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPeiFspPlatformSecLibSample.uni
Binary files differ
diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPlatformInformation.c b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPlatformInformation.c
new file mode 100644
index 0000000000..1ab1089054
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPlatformInformation.c
@@ -0,0 +1,86 @@
+/** @file
+ Sample to provide SecPlatformInformation function.
+
+ 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 <Ppi/SecPlatformInformation.h>
+#include <Ppi/TopOfTemporaryRam.h>
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+
+/**
+ This interface conveys state information out of the Security (SEC) phase into PEI.
+
+ @param[in] PeiServices Pointer to the PEI Services Table.
+ @param[in,out] StructureSize Pointer to the variable describing size of the input buffer.
+ @param[out] PlatformInformationRecord Pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD.
+
+ @retval EFI_SUCCESS The data was successfully returned.
+ @retval EFI_BUFFER_TOO_SMALL The buffer was too small.
+
+**/
+EFI_STATUS
+EFIAPI
+SecPlatformInformation (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN OUT UINT64 *StructureSize,
+ OUT EFI_SEC_PLATFORM_INFORMATION_RECORD *PlatformInformationRecord
+ )
+{
+ UINT32 *Bist;
+ UINT32 Size;
+ UINT32 Count;
+ UINT32 TopOfTemporaryRam;
+ VOID *TopOfTemporaryRamPpi;
+ EFI_STATUS Status;
+
+ DEBUG ((DEBUG_INFO, "SecPlatformInformation\n"));
+
+ Status = (*PeiServices)->LocatePpi (
+ PeiServices,
+ &gTopOfTemporaryRamPpiGuid,
+ 0,
+ NULL,
+ (VOID **) &TopOfTemporaryRamPpi
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // The entries of BIST information, together with the number of them,
+ // reside in the bottom of stack, left untouched by normal stack operation.
+ // This routine copies the BIST information to the buffer pointed by
+ // PlatformInformationRecord for output.
+ //
+ TopOfTemporaryRam = (UINT32) (UINTN) TopOfTemporaryRamPpi - sizeof (UINT32);
+ TopOfTemporaryRam -= sizeof (UINT32) * 2;
+ Count = *((UINT32 *) (UINTN) (TopOfTemporaryRam - sizeof (UINT32)));
+ Size = Count * sizeof (IA32_HANDOFF_STATUS);
+
+ if ((*StructureSize) < (UINT64) Size) {
+ *StructureSize = Size;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ *StructureSize = Size;
+ Bist = (UINT32 *) (TopOfTemporaryRam - sizeof (UINT32) - Size);
+
+ CopyMem (PlatformInformationRecord, Bist, Size);
+
+ return EFI_SUCCESS;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecRamInitData.c b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecRamInitData.c
new file mode 100644
index 0000000000..c5beee0d65
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecRamInitData.c
@@ -0,0 +1,24 @@
+/** @file
+ Sample to provide TempRamInitParams data.
+
+ 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 <Library/PcdLib.h>
+
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 TempRamInitParams[4] = {
+ ((UINT32) FixedPcdGet64 (PcdCpuMicrocodePatchAddress) + FixedPcdGet32 (PcdFlashMicroCodeOffset)),
+ ((UINT32) FixedPcdGet64 (PcdCpuMicrocodePatchRegionSize) - FixedPcdGet32 (PcdFlashMicroCodeOffset)),
+ FixedPcdGet32 (PcdFlashCodeCacheAddress),
+ FixedPcdGet32 (PcdFlashCodeCacheSize)
+};
+
diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecTempRamSupport.c b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecTempRamSupport.c
new file mode 100644
index 0000000000..4bd8384cd4
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecTempRamSupport.c
@@ -0,0 +1,148 @@
+/** @file
+ Sample to provide SecTemporaryRamSupport function.
+
+ 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 <Ppi/TemporaryRamSupport.h>
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugAgentLib.h>
+
+/**
+ Switch the stack in the temporary memory to the one in the permanent memory.
+
+ This function must be invoked after the memory migration immediately. The relative
+ position of the stack in the temporary and permanent memory is same.
+
+ @param[in] TemporaryMemoryBase Base address of the temporary memory.
+ @param[in] PermenentMemoryBase Base address of the permanent memory.
+
+**/
+VOID
+EFIAPI
+SecSwitchStack (
+ IN UINT32 TemporaryMemoryBase,
+ IN UINT32 PermenentMemoryBase
+ );
+
+/**
+ This service of the TEMPORARY_RAM_SUPPORT_PPI that migrates temporary RAM into
+ permanent memory.
+
+ @param[in] PeiServices Pointer to the PEI Services Table.
+ @param[in] TemporaryMemoryBase Source Address in temporary memory from which the SEC or PEIM will copy the
+ Temporary RAM contents.
+ @param[in] PermanentMemoryBase Destination Address in permanent memory into which the SEC or PEIM will copy the
+ Temporary RAM contents.
+ @param[in] CopySize Amount of memory to migrate from temporary to permanent memory.
+
+ @retval EFI_SUCCESS The data was successfully returned.
+ @retval EFI_INVALID_PARAMETER PermanentMemoryBase + CopySize > TemporaryMemoryBase when
+ TemporaryMemoryBase > PermanentMemoryBase.
+
+**/
+EFI_STATUS
+EFIAPI
+SecTemporaryRamSupport (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
+ IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
+ IN UINTN CopySize
+ )
+{
+ IA32_DESCRIPTOR IdtDescriptor;
+ VOID* OldHeap;
+ VOID* NewHeap;
+ VOID* OldStack;
+ VOID* NewStack;
+ DEBUG_AGENT_CONTEXT_POSTMEM_SEC DebugAgentContext;
+ BOOLEAN OldStatus;
+ UINTN PeiStackSize;
+
+ PeiStackSize = (UINTN) PcdGet32 (PcdPeiTemporaryRamStackSize);
+ if (PeiStackSize == 0) {
+ PeiStackSize = (CopySize >> 1);
+ }
+
+ ASSERT (PeiStackSize < CopySize);
+
+ //
+ // |-------------------|---->
+ // | Stack | PeiStackSize
+ // |-------------------|---->
+ // | Heap | PeiTemporayRamSize
+ // |-------------------|----> TempRamBase
+ //
+ // |-------------------|---->
+ // | Heap | PeiTemporayRamSize
+ // |-------------------|---->
+ // | Stack | PeiStackSize
+ // |-------------------|----> PermanentMemoryBase
+ //
+
+ OldHeap = (VOID *) (UINTN) TemporaryMemoryBase;
+ NewHeap = (VOID *) ((UINTN) PermanentMemoryBase + PeiStackSize);
+
+ OldStack = (VOID *) ((UINTN) TemporaryMemoryBase + CopySize - PeiStackSize);
+ NewStack = (VOID *) (UINTN) PermanentMemoryBase;
+
+ DebugAgentContext.HeapMigrateOffset = (UINTN) NewHeap - (UINTN) OldHeap;
+ DebugAgentContext.StackMigrateOffset = (UINTN) NewStack - (UINTN) OldStack;
+
+ OldStatus = SaveAndSetDebugTimerInterrupt (FALSE);
+ //
+ // Initialize Debug Agent to support source level debug in PEI phase after memory ready.
+ // It will build HOB and fix up the pointer in IDT table.
+ //
+ InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, (VOID *) &DebugAgentContext, NULL);
+
+ //
+ // Migrate Heap
+ //
+ CopyMem (NewHeap, OldHeap, CopySize - PeiStackSize);
+
+ //
+ // Migrate Stack
+ //
+ CopyMem (NewStack, OldStack, PeiStackSize);
+
+ //
+ // Rebase IDT table in permanent memory
+ //
+ AsmReadIdtr (&IdtDescriptor);
+ IdtDescriptor.Base = IdtDescriptor.Base - (UINTN) OldStack + (UINTN) NewStack;
+
+ AsmWriteIdtr (&IdtDescriptor);
+
+ //
+ // Program MTRR
+ //
+ //
+ // SecSwitchStack function must be invoked after the memory migration
+ // immediatly, also we need fixup the stack change caused by new call into
+ // permenent memory.
+ //
+ SecSwitchStack (
+ (UINT32) (UINTN) OldStack,
+ (UINT32) (UINTN) NewStack
+ );
+
+ SaveAndSetDebugTimerInterrupt (OldStatus);
+
+ return EFI_SUCCESS;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Tools/fsptool.py b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Tools/fsptool.py
new file mode 100644
index 0000000000..83e824d617
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/SampleCode/IntelFsp2WrapperPkg/Tools/fsptool.py
@@ -0,0 +1,365 @@
+## @file
+# !/usr/bin/env python
+#
+# 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.
+#
+##
+
+import os
+import sys
+import uuid
+import copy
+import struct
+import argparse
+from ctypes import *
+
+"""
+This utility supports some operations for Intel FSP image.
+It supports:
+ - Split a FSP 2.0 compatibale image into individual FSP-T/M/S/C
+ and generate the mapping header file.
+"""
+
+class c_uint24(Structure):
+ """Little-Endian 24-bit Unsigned Integer"""
+ _pack_ = 1
+ _fields_ = [
+ ('Data', (c_uint8 * 3))
+ ]
+
+ def __init__(self, val=0):
+ self.set_value(val)
+
+ def __str__(self, indent=0):
+ return '0x%.6x' % self.value
+
+ def get_value(self):
+ return (
+ (self.Data[0] ) +
+ (self.Data[1] << 8) +
+ (self.Data[2] << 16)
+ )
+
+ def set_value(self, val):
+ self.Data[0] = (val ) & 0xff
+ self.Data[1] = (val >> 8) & 0xff
+ self.Data[2] = (val >> 16) & 0xff
+
+ value = property(get_value, set_value)
+
+class EFI_FIRMWARE_VOLUME_HEADER(Structure):
+ _fields_ = [
+ ('ZeroVector', ARRAY(c_uint8, 16)),
+ ('FileSystemGuid', ARRAY(c_char, 16)),
+ ('FvLength', c_uint64),
+ ('Signature', c_uint32),
+ ('Attributes', c_uint32),
+ ('HeaderLength', c_uint16),
+ ('Checksum', c_uint16),
+ ('ExtHeaderOffset', c_uint16),
+ ('Reserved', c_uint8),
+ ('Revision', c_uint8)
+ ]
+
+class EFI_FIRMWARE_VOLUME_EXT_HEADER(Structure):
+ _fields_ = [
+ ('FvName', ARRAY(c_char, 16)),
+ ('ExtHeaderSize', c_uint32)
+ ]
+
+class EFI_FFS_INTEGRITY_CHECK(Structure):
+ _fields_ = [
+ ('Header', c_uint8),
+ ('File', c_uint8)
+ ]
+
+class EFI_FFS_FILE_HEADER(Structure):
+ _fields_ = [
+ ('Name', ARRAY(c_char, 16)),
+ ('IntegrityCheck', EFI_FFS_INTEGRITY_CHECK),
+ ('Type', c_uint8),
+ ('Attributes', c_uint8),
+ ('Size', c_uint24),
+ ('State', c_uint8)
+ ]
+
+class EFI_COMMON_SECTION_HEADER(Structure):
+ _fields_ = [
+ ('Size', c_uint24),
+ ('Type', c_uint8)
+ ]
+
+class FSP_INFORMATION_HEADER(Structure):
+ _fields_ = [
+ ('Signature', c_uint32),
+ ('HeaderLength', c_uint32),
+ ('Reserved1', ARRAY(c_uint8, 3)),
+ ('HeaderRevision', c_uint8),
+ ('ImageRevision', c_uint32),
+ ('ImageId', c_uint64),
+ ('ImageSize', c_uint32),
+ ('ImageBase', c_uint32),
+ ('ImageAttribute', c_uint32),
+ ('CfgRegionOffset', c_uint32),
+ ('CfgRegionSize', c_uint32),
+ ('ApiEntryNum', c_uint32),
+ ('NemInitEntry', c_uint32),
+ ('FspInitEntry', c_uint32),
+ ('NotifyPhaseEntry', c_uint32),
+ ('FspMemoryInitEntry', c_uint32),
+ ('TempRamExitEntry', c_uint32),
+ ('FspSiliconInitEntry', c_uint32)
+ ]
+
+class FspFv:
+ HeaderFile = """/*
+ *
+ * Automatically generated file; DO NOT EDIT.
+ * FSP mapping file
+ *
+ */
+"""
+ FspNameDict = {
+ "0" : "-C.Fv",
+ "1" : "-T.Fv",
+ "2" : "-M.Fv",
+ "3" : "-S.Fv",
+ }
+
+ def __init__(self, FvBin):
+ self.FspFv = {}
+ self.FvList = []
+ self.FspBin = FvBin
+ hfsp = open (self.FspBin, 'r+b')
+ self.FspDat = bytearray(hfsp.read())
+ hfsp.close()
+
+ def OutputStruct (self, obj, indent = 0):
+ max_key_len = 20
+ pstr = (' ' * indent + '{0:<%d} = {1}\n') % max_key_len
+ if indent:
+ s = ''
+ else:
+ s = (' ' * indent + '<%s>:\n') % obj.__class__.__name__
+ for field in obj._fields_:
+ key = field[0]
+ val = getattr(obj, key)
+ rep = ''
+
+ if not isinstance(val, c_uint24) and isinstance(val, Structure):
+ s += pstr.format(key, val.__class__.__name__)
+ s += self.OutputStruct (val, indent + 1)
+ else:
+ if type(val) in (int, long):
+ rep = hex(val)
+ elif isinstance(val, str) and (len(val) == 16):
+ rep = str(uuid.UUID(bytes = val))
+ elif isinstance(val, c_uint24):
+ rep = hex(val.get_value())
+ elif 'c_ubyte_Array' in str(type(val)):
+ rep = str(list(bytearray(val)))
+ else:
+ rep = str(val)
+ s += pstr.format(key, rep)
+ return s
+
+ def PrintFv (self):
+ print ("FV LIST:")
+ idx = 0
+ for (fvh, fvhe, offset) in self.FvList:
+ guid = uuid.UUID(bytes = fvhe.FvName)
+ print ("FV%d FV GUID:%s Offset:0x%08X Length:0x%08X" % (idx, str(guid), offset, fvh.FvLength))
+ idx = idx + 1
+ print ("\nFSP LIST:")
+ for fsp in self.FspFv:
+ print "FSP%s contains FV%s" % (fsp, str(self.FspFv[fsp][1]))
+ print "\nFSP%s Info Header:" % fsp
+ fih = self.FspFv[fsp][0]
+
+ def AlaignPtr (self, offset, alignment = 8):
+ return (offset + alignment - 1) & ~(alignment - 1)
+
+ def GetFspInfoHdr (self, fvh, fvhe, fvoffset):
+ if fvhe:
+ offset = fvh.ExtHeaderOffset + fvhe.ExtHeaderSize
+ else:
+ offset = fvh.HeaderLength
+ offset = self.AlaignPtr(offset)
+
+ # Now it should be 1st FFS
+ ffs = EFI_FFS_FILE_HEADER.from_buffer (self.FspDat, offset)
+ offset += sizeof(ffs)
+ offset = self.AlaignPtr(offset)
+
+ # Now it should be 1st Section
+ sec = EFI_COMMON_SECTION_HEADER.from_buffer (self.FspDat, offset)
+ offset += sizeof(sec)
+
+ # Now it should be FSP_INFO_HEADER
+ offset += fvoffset
+ fih = FSP_INFORMATION_HEADER.from_buffer (self.FspDat, offset)
+ if 'FSPH' != bytearray.fromhex('%08X' % fih.Signature)[::-1]:
+ return None
+
+ return fih
+
+ def GetFvHdr (self, offset):
+ fvh = EFI_FIRMWARE_VOLUME_HEADER.from_buffer (self.FspDat, offset)
+ if '_FVH' != bytearray.fromhex('%08X' % fvh.Signature)[::-1]:
+ return None, None
+ if fvh.ExtHeaderOffset > 0:
+ offset += fvh.ExtHeaderOffset
+ fvhe = EFI_FIRMWARE_VOLUME_EXT_HEADER.from_buffer (self.FspDat, offset)
+ else:
+ fvhe = None
+ return fvh, fvhe
+
+ def GetFvData(self, idx):
+ (fvh, fvhe, offset) = self.FvList[idx]
+ return self.FspDat[offset:offset+fvh.FvLength]
+
+ def CheckFsp (self):
+ if len(self.FspFv) == 0:
+ return
+
+ fih = None
+ for fv in self.FspFv:
+ if not fih:
+ fih = self.FspFv[fv][0]
+ else:
+ newfih = self.FspFv[fv][0]
+ if (newfih.ImageId != fih.ImageId) or (newfih.ImageRevision != fih.ImageRevision):
+ raise Exception("Inconsistent FSP ImageId or ImageRevision detected !")
+ return
+
+ def WriteFsp(self, dir, name):
+ if not name:
+ name = self.FspBin
+ fspname, ext = os.path.splitext(os.path.basename(name))
+ for fv in self.FspFv:
+ filename = os.path.join(dir, fspname + fv + ext)
+ hfsp = open(filename, 'w+b')
+ for fvidx in self.FspFv[fv][1]:
+ hfsp.write (self.GetFvData(fvidx))
+ hfsp.close()
+
+ def WriteMap(self, dir, hfile):
+ if not hfile:
+ hfile = os.path.splitext(os.path.basename(self.FspBin))[0] + '.h'
+ fspname, ext = os.path.splitext(os.path.basename(hfile))
+ filename = os.path.join(dir, fspname + ext)
+ hfsp = open(filename, 'w')
+ hfsp.write ('%s\n\n' % self.HeaderFile)
+
+ firstfv = True
+ for fsp in self.FspFv:
+ fih = self.FspFv[fsp][0]
+ fvs = self.FspFv[fsp][1]
+ if firstfv:
+ IdStr = str(bytearray.fromhex('%016X' % fih.ImageId)[::-1])
+ hfsp.write("#define FSP_IMAGE_ID 0x%016X /* '%s' */\n" % (fih.ImageId, IdStr))
+ hfsp.write("#define FSP_IMAGE_REV 0x%08X \n\n" % fih.ImageRevision)
+ firstfv = False
+ hfsp.write ('#define FSP%s_BASE 0x%08X\n' % (fsp, fih.ImageBase))
+ hfsp.write ('#define FSP%s_OFFSET 0x%08X\n' % (fsp, self.FvList[fvs[0]][-1]))
+ hfsp.write ('#define FSP%s_LENGTH 0x%08X\n\n' % (fsp, fih.ImageSize))
+ hfsp.close()
+
+ def ParseFsp (self):
+ self.FspFv = {}
+ flen = 0
+ for (fvh, fvhe, offset) in self.FvList:
+ fih = self.GetFspInfoHdr (fvh, fvhe, offset)
+ if fih:
+ if flen != 0:
+ raise Exception("Incorrect FV size in image !")
+ ftype = str((fih.ImageAttribute >> 28) & 0xF)
+ if ftype not in self.FspNameDict:
+ raise Exception("Unknown Attribute in image !")
+ fname = self.FspNameDict[str(ftype)]
+ if fname in self.FspFv:
+ raise Exception("Multiple '%s' in image !" % fname)
+ self.FspFv[fname] = (copy.deepcopy(fih), [])
+ flen = fih.ImageSize
+ if flen > 0:
+ flen = flen - fvh.FvLength
+ if flen < 0:
+ raise Exception("Incorrect FV size in image !")
+ self.FspFv[fname][1].append(self.FvList.index((fvh, fvhe, offset)))
+
+ def AddFv(self, offset):
+ fvh, fvhe = self.GetFvHdr (offset)
+ if fvh is None:
+ raise Exception('FV signature is not valid !')
+ fvitem = (copy.deepcopy(fvh), copy.deepcopy(fvhe), offset)
+ self.FvList.append(fvitem)
+ return fvh.FvLength
+
+ def ParseFv(self):
+ offset = 0
+ while (offset < len(self.FspDat)):
+ fv_len = self.AddFv (offset)
+ offset += fv_len
+
+def GenFspHdr (fspfile, outdir, hfile, show):
+ fsp_fv = FspFv(fspfile)
+ fsp_fv.ParseFv()
+ fsp_fv.ParseFsp()
+ fsp_fv.CheckFsp()
+ if show:
+ fsp_fv.PrintFv()
+ fsp_fv.WriteMap(outdir, hfile)
+
+def SplitFspBin (fspfile, outdir, nametemplate, show):
+ fsp_fv = FspFv(fspfile)
+ fsp_fv.ParseFv()
+ fsp_fv.ParseFsp()
+ if show:
+ fsp_fv.PrintFv()
+ fsp_fv.WriteFsp(outdir, nametemplate)
+
+def main ():
+ parser = argparse.ArgumentParser()
+ subparsers = parser.add_subparsers(title='commands')
+
+ parser_split = subparsers.add_parser('split', help='split a FSP into multiple components')
+ parser_split.set_defaults(which='split')
+ parser_split.add_argument('-f', '--fspbin' , dest='FspBinary', type=str, help='FSP binary file path', required = True)
+ parser_split.add_argument('-o', '--outdir' , dest='OutputDir', type=str, help='Output directory path', default = '.')
+ parser_split.add_argument('-n', '--nametpl', dest='NameTemplate', type=str, help='Output name template', default = '')
+ parser_split.add_argument('-p', action='store_true', help='Print FSP FV information', default = False)
+
+ parser_genhdr = subparsers.add_parser('genhdr', help='generate a header file for FSP binary')
+ parser_genhdr.set_defaults(which='genhdr')
+ parser_genhdr.add_argument('-f', '--fspbin' , dest='FspBinary', type=str, help='FSP binary file path', required = True)
+ parser_genhdr.add_argument('-o', '--outdir' , dest='OutputDir', type=str, help='Output directory path', default = '.')
+ parser_genhdr.add_argument('-n', '--hfile', dest='HFileName', type=str, help='Output header file name', default = '')
+ parser_genhdr.add_argument('-p', action='store_true', help='Print FSP FV information', default = False)
+
+ args = parser.parse_args()
+ if args.which in ['split', 'genhdr']:
+ if not os.path.exists(args.FspBinary):
+ raise Exception ("Could not locate FSP binary file '%s' !" % args.FspBinary)
+ if not os.path.exists(args.OutputDir):
+ raise Exception ("Invalid output directory '%s' !" % args.OutputDir)
+
+ if args.which == 'split':
+ SplitFspBin (args.FspBinary, args.OutputDir, args.NameTemplate, args.p)
+ elif args.which == 'genhdr':
+ GenFspHdr (args.FspBinary, args.OutputDir, args.HFileName, args.p)
+ else:
+ pass
+
+ print 'Done!'
+ return 0
+
+if __name__ == '__main__':
+ sys.exit(main())