summaryrefslogtreecommitdiffstats
path: root/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-11 08:17:27 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-11 08:17:27 +0000
commitf215e02bf85f68d3a6106c2a1f4f7f063f819064 (patch)
tree6bb5b92c046312c4e95ac2620b10ddf482d3fa8b /src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library
parentInitial commit. (diff)
downloadvirtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.tar.xz
virtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.zip
Adding upstream version 7.0.14-dfsg.upstream/7.0.14-dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library')
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/BaseFspMeasurementLib/BaseFspMeasurementLib.inf54
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/BaseFspMeasurementLib/FspMeasurementLib.c248
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/BaseFspWrapperApiLib.inf65
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/FspWrapperApiLib.c197
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/IA32/DispatchExecute.c52
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/DispatchExecute.c103
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/Thunk64To32.nasm224
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiTestLibNull/BaseFspWrapperApiTestLibNull.inf48
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiTestLibNull/FspWrapperApiTestNull.c59
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/BaseFspWrapperPlatformLibSample/BaseFspWrapperPlatformLibSample.inf52
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/BaseFspWrapperPlatformLibSample/FspWrapperPlatformLibSample.c97
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/PeiFspWrapperApiTestLib/FspWrapperApiTest.c82
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/PeiFspWrapperApiTestLib/PeiFspWrapperApiTestLib.inf51
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/PeiFspWrapperHobProcessLibSample/FspWrapperHobProcessLibSample.c396
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/PeiFspWrapperHobProcessLibSample/PeiFspWrapperHobProcessLibSample.inf72
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/FspWrapperPlatformSecLibSample.c129
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/Fsp.h45
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/PeiCoreEntry.nasm130
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/SecEntry.nasm335
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/Stack.nasm73
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/PlatformInit.c39
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecFspWrapperPlatformSecLibSample.inf83
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecGetPerformance.c84
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecPlatformInformation.c78
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecRamInitData.c61
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecTempRamDone.c43
26 files changed, 2900 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/BaseFspMeasurementLib/BaseFspMeasurementLib.inf b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/BaseFspMeasurementLib/BaseFspMeasurementLib.inf
new file mode 100644
index 00000000..47bb8d33
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/BaseFspMeasurementLib/BaseFspMeasurementLib.inf
@@ -0,0 +1,54 @@
+## @file
+# Provides FSP measurement functions.
+#
+# This library provides MeasureFspFirmwareBlob() to measure FSP binary.
+#
+# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = FspMeasurementLib
+ FILE_GUID = 890B12B4-56CC-453E-B062-4597FC6D3D8C
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = FspMeasurementLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ FspMeasurementLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ SecurityPkg/SecurityPkg.dec
+ IntelFsp2Pkg/IntelFsp2Pkg.dec
+ IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ PrintLib
+ PcdLib
+ PeiServicesLib
+ PeiServicesTablePointerLib
+ FspWrapperApiLib
+ TcgEventLogRecordLib
+ HashLib
+
+[Ppis]
+ gEdkiiTcgPpiGuid ## CONSUMES
+
+[Pcd]
+ gIntelFsp2WrapperTokenSpaceGuid.PcdFspMeasurementConfig ## CONSUMES
+ gIntelFsp2WrapperTokenSpaceGuid.PcdFspmBaseAddress ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdTcgPfpMeasurementRevision ## CONSUMES
+
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/BaseFspMeasurementLib/FspMeasurementLib.c b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/BaseFspMeasurementLib/FspMeasurementLib.c
new file mode 100644
index 00000000..251ffbfa
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/BaseFspMeasurementLib/FspMeasurementLib.c
@@ -0,0 +1,248 @@
+/** @file
+ This library is used by FSP modules to measure data to TPM.
+
+Copyright (c) 2020, Intel Corporation. All rights reserved. <BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+#include <Uefi.h>
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PeiServicesTablePointerLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PrintLib.h>
+#include <Library/DebugLib.h>
+#include <Library/FspWrapperApiLib.h>
+#include <Library/TpmMeasurementLib.h>
+#include <Library/FspMeasurementLib.h>
+#include <Library/TcgEventLogRecordLib.h>
+#include <Library/HashLib.h>
+
+#include <Ppi/Tcg.h>
+#include <IndustryStandard/UefiTcgPlatform.h>
+
+/**
+ Tpm measure and log data, and extend the measurement result into a specific PCR.
+
+ @param[in] PcrIndex PCR Index.
+ @param[in] EventType Event type.
+ @param[in] EventLog Measurement event log.
+ @param[in] LogLen Event log length in bytes.
+ @param[in] HashData The start of the data buffer to be hashed, extended.
+ @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData
+ @param[in] Flags Bitmap providing additional information.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_UNSUPPORTED TPM device not available.
+ @retval EFI_OUT_OF_RESOURCES Out of memory.
+ @retval EFI_DEVICE_ERROR The operation was unsuccessful.
+**/
+EFI_STATUS
+EFIAPI
+TpmMeasureAndLogDataWithFlags (
+ IN UINT32 PcrIndex,
+ IN UINT32 EventType,
+ IN VOID *EventLog,
+ IN UINT32 LogLen,
+ IN VOID *HashData,
+ IN UINT64 HashDataLen,
+ IN UINT64 Flags
+ )
+{
+ EFI_STATUS Status;
+ EDKII_TCG_PPI *TcgPpi;
+ TCG_PCR_EVENT_HDR TcgEventHdr;
+
+ Status = PeiServicesLocatePpi(
+ &gEdkiiTcgPpiGuid,
+ 0,
+ NULL,
+ (VOID**)&TcgPpi
+ );
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ TcgEventHdr.PCRIndex = PcrIndex;
+ TcgEventHdr.EventType = EventType;
+ TcgEventHdr.EventSize = LogLen;
+
+ Status = TcgPpi->HashLogExtendEvent (
+ TcgPpi,
+ Flags,
+ HashData,
+ (UINTN)HashDataLen,
+ &TcgEventHdr,
+ EventLog
+ );
+ return Status;
+}
+
+/**
+ Measure a FSP FirmwareBlob.
+
+ @param[in] Description Description for this FirmwareBlob.
+ @param[in] FirmwareBlobBase Base address of this FirmwareBlob.
+ @param[in] FirmwareBlobLength Size in bytes of this FirmwareBlob.
+ @param[in] CfgRegionOffset Configuration region offset in bytes.
+ @param[in] CfgRegionSize Configuration region in bytes.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_UNSUPPORTED TPM device not available.
+ @retval EFI_OUT_OF_RESOURCES Out of memory.
+ @retval EFI_DEVICE_ERROR The operation was unsuccessful.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+MeasureFspFirmwareBlobWithCfg (
+ IN CHAR8 *Description OPTIONAL,
+ IN EFI_PHYSICAL_ADDRESS FirmwareBlobBase,
+ IN UINT64 FirmwareBlobLength,
+ IN UINT32 CfgRegionOffset,
+ IN UINT32 CfgRegionSize
+ )
+{
+ EFI_PLATFORM_FIRMWARE_BLOB FvBlob, UpdBlob;
+ PLATFORM_FIRMWARE_BLOB2_STRUCT FvBlob2, UpdBlob2;
+ VOID *FvName;
+ UINT32 FvEventType;
+ VOID *FvEventLog, *UpdEventLog;
+ UINT32 FvEventLogSize, UpdEventLogSize;
+ EFI_STATUS Status;
+ HASH_HANDLE HashHandle;
+ UINT8 *HashBase;
+ UINTN HashSize;
+ TPML_DIGEST_VALUES DigestList;
+
+ FvName = TpmMeasurementGetFvName (FirmwareBlobBase, FirmwareBlobLength);
+
+ if (((Description != NULL) || (FvName != NULL)) &&
+ (PcdGet32(PcdTcgPfpMeasurementRevision) >= TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2_REV_105)) {
+ if (Description != NULL) {
+ AsciiSPrint((CHAR8*)FvBlob2.BlobDescription, sizeof(FvBlob2.BlobDescription), "%a", Description);
+ AsciiSPrint((CHAR8*)UpdBlob2.BlobDescription, sizeof(UpdBlob2.BlobDescription), "%aUDP", Description);
+ } else {
+ AsciiSPrint((CHAR8*)FvBlob2.BlobDescription, sizeof(FvBlob2.BlobDescription), "Fv(%g)", FvName);
+ AsciiSPrint((CHAR8*)UpdBlob2.BlobDescription, sizeof(UpdBlob2.BlobDescription), "(%g)UDP", FvName);
+ }
+
+ FvBlob2.BlobDescriptionSize = sizeof(FvBlob2.BlobDescription);
+ FvBlob2.BlobBase = FirmwareBlobBase;
+ FvBlob2.BlobLength = FirmwareBlobLength;
+ FvEventType = EV_EFI_PLATFORM_FIRMWARE_BLOB2;
+ FvEventLog = &FvBlob2;
+ FvEventLogSize = sizeof(FvBlob2);
+
+ UpdBlob2.BlobDescriptionSize = sizeof(UpdBlob2.BlobDescription);
+ UpdBlob2.BlobBase = CfgRegionOffset;
+ UpdBlob2.BlobLength = CfgRegionSize;
+ UpdEventLog = &UpdBlob2;
+ UpdEventLogSize = sizeof(UpdBlob2);
+ } else {
+ FvBlob.BlobBase = FirmwareBlobBase;
+ FvBlob.BlobLength = FirmwareBlobLength;
+ FvEventType = EV_EFI_PLATFORM_FIRMWARE_BLOB;
+ FvEventLog = &FvBlob;
+ FvEventLogSize = sizeof(FvBlob);
+
+ UpdBlob.BlobBase = CfgRegionOffset;
+ UpdBlob.BlobLength = CfgRegionSize;
+ UpdEventLog = &UpdBlob;
+ UpdEventLogSize = sizeof(UpdBlob);
+ }
+
+ /** Initialize a SHA hash context. **/
+ Status = HashStart (&HashHandle);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "HashStart failed - %r\n", Status));
+ return Status;
+ }
+
+ /** Hash FSP binary before UDP **/
+ HashBase = (UINT8 *) (UINTN) FirmwareBlobBase;
+ HashSize = (UINTN) CfgRegionOffset;
+ Status = HashUpdate (HashHandle, HashBase, HashSize);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "HashUpdate failed - %r\n", Status));
+ return Status;
+ }
+
+ /** Hash FSP binary after UDP **/
+ HashBase = (UINT8 *) (UINTN) FirmwareBlobBase + CfgRegionOffset + CfgRegionSize;
+ HashSize = (UINTN)(FirmwareBlobLength - CfgRegionOffset - CfgRegionSize);
+ Status = HashUpdate (HashHandle, HashBase, HashSize);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "HashUpdate failed - %r\n", Status));
+ return Status;
+ }
+
+ /** Finalize the SHA hash. **/
+ Status = HashCompleteAndExtend (HashHandle, 0, NULL, 0, &DigestList);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "HashCompleteAndExtend failed - %r\n", Status));
+ return Status;
+ }
+
+ Status = TpmMeasureAndLogDataWithFlags (
+ 0,
+ FvEventType,
+ FvEventLog,
+ FvEventLogSize,
+ (UINT8 *) &DigestList,
+ (UINTN) sizeof(DigestList),
+ EDKII_TCG_PRE_HASH_LOG_ONLY
+ );
+
+ Status = TpmMeasureAndLogData (
+ 1,
+ EV_PLATFORM_CONFIG_FLAGS,
+ UpdEventLog,
+ UpdEventLogSize,
+ (UINT8 *) (UINTN) FirmwareBlobBase + CfgRegionOffset,
+ CfgRegionSize
+ );
+
+ return Status;
+}
+
+/**
+ Measure a FSP FirmwareBlob.
+
+ @param[in] PcrIndex PCR Index.
+ @param[in] Description Description for this FirmwareBlob.
+ @param[in] FirmwareBlobBase Base address of this FirmwareBlob.
+ @param[in] FirmwareBlobLength Size in bytes of this FirmwareBlob.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_UNSUPPORTED TPM device not available.
+ @retval EFI_OUT_OF_RESOURCES Out of memory.
+ @retval EFI_DEVICE_ERROR The operation was unsuccessful.
+**/
+EFI_STATUS
+EFIAPI
+MeasureFspFirmwareBlob (
+ IN UINT32 PcrIndex,
+ IN CHAR8 *Description OPTIONAL,
+ IN EFI_PHYSICAL_ADDRESS FirmwareBlobBase,
+ IN UINT64 FirmwareBlobLength
+ )
+{
+ UINT32 FspMeasureMask;
+ FSP_INFO_HEADER *FspHeaderPtr;
+
+ FspMeasureMask = PcdGet32 (PcdFspMeasurementConfig);
+ if ((FspMeasureMask & FSP_MEASURE_FSPUPD) != 0) {
+ FspHeaderPtr = (FSP_INFO_HEADER *) FspFindFspHeader (FirmwareBlobBase);
+ if (FspHeaderPtr != NULL) {
+ return MeasureFspFirmwareBlobWithCfg(Description, FirmwareBlobBase, FirmwareBlobLength,
+ FspHeaderPtr->CfgRegionOffset, FspHeaderPtr->CfgRegionSize);
+ }
+ }
+
+ return MeasureFirmwareBlob (PcrIndex, Description, FirmwareBlobBase, FirmwareBlobLength);
+}
+
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/BaseFspWrapperApiLib.inf b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/BaseFspWrapperApiLib.inf
new file mode 100644
index 00000000..0f1eeca7
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/BaseFspWrapperApiLib.inf
@@ -0,0 +1,65 @@
+## @file
+# Provide FSP API related function.
+#
+# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = 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.nasm
+
+################################################################################
+#
+# Package Dependency Section - list of Package files that are required for
+# this module.
+#
+################################################################################
+
+[Packages]
+ MdePkg/MdePkg.dec
+ IntelFsp2Pkg/IntelFsp2Pkg.dec
+ IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec
+
+[LibraryClasses]
+ BaseLib
+
+[Guids]
+ gFspHeaderFileGuid ## CONSUMES ## GUID
+
+[Pcd]
+ gIntelFsp2WrapperTokenSpaceGuid.PcdFspmBaseAddress ## CONSUMES
+ gIntelFsp2WrapperTokenSpaceGuid.PcdFspsBaseAddress ## CONSUMES
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/FspWrapperApiLib.c b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/FspWrapperApiLib.c
new file mode 100644
index 00000000..9b686933
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/FspWrapperApiLib.c
@@ -0,0 +1,197 @@
+/** @file
+ Provide FSP API related function.
+
+ Copyright (c) 2014 - 2017, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+
+#include <Library/FspWrapperApiLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.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.
+ @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
+ );
+
+/**
+ 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;
+
+ CheckPointer = (UINT8 *) (UINTN) FlashFvFspBase;
+
+ if (((EFI_FIRMWARE_VOLUME_HEADER *)CheckPointer)->Signature != EFI_FVH_SIGNATURE) {
+ 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) {
+ 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] FspmUpdDataPtr Address pointer to the FSP_MEMORY_INIT_PARAMS structure.
+ @param[out] HobListPtr Address of the HobList pointer.
+
+ @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] 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 ();
+ Status = Execute32BitCode ((UINTN)TempRamExitApi, (UINTN)TempRamExitParam, (UINTN)NULL);
+ SetInterruptState (InterruptState);
+
+ return Status;
+}
+
+/**
+ Call FSP API - FspSiliconInit.
+
+ @param[in] FspsUpdDataPtr 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;
+
+ FspHeader = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32 (PcdFspsBaseAddress));
+ if (FspHeader == NULL) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ FspSiliconInitApi = (FSP_SILICON_INIT)((UINTN)FspHeader->ImageBase + FspHeader->FspSiliconInitEntryOffset);
+ InterruptState = SaveAndDisableInterrupts ();
+ Status = Execute32BitCode ((UINTN)FspSiliconInitApi, (UINTN)FspsUpdDataPtr, (UINTN)NULL);
+ SetInterruptState (InterruptState);
+
+ return Status;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/IA32/DispatchExecute.c b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/IA32/DispatchExecute.c
new file mode 100644
index 00000000..3f6817b5
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/IA32/DispatchExecute.c
@@ -0,0 +1,52 @@
+/** @file
+ Execute 32-bit code in Protected Mode.
+
+ Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#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/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/DispatchExecute.c b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/DispatchExecute.c
new file mode 100644
index 00000000..2d8e999f
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/DispatchExecute.c
@@ -0,0 +1,103 @@
+/** @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 - 2018, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#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
+EFIAPI
+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/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/Thunk64To32.nasm b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/Thunk64To32.nasm
new file mode 100644
index 00000000..ebc8eede
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/Thunk64To32.nasm
@@ -0,0 +1,224 @@
+;
+; Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+;
+; Module Name:
+;
+; Thunk64To32.nasm
+;
+; Abstract:
+;
+; 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.
+;
+;-------------------------------------------------------------------------------
+ DEFAULT REL
+ SECTION .text
+;----------------------------------------------------------------------------
+; 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.
+;
+;----------------------------------------------------------------------------
+global ASM_PFX(AsmExecute32BitCode)
+ASM_PFX(AsmExecute32BitCode):
+ ;
+ ; save IFLAG and disable it
+ ;
+ pushfq
+ cli
+
+ ;
+ ; save original GDTR and CS
+ ;
+ mov rax, ds
+ push rax
+ mov rax, cs
+ push rax
+ sub rsp, 0x10
+ 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
+ ;
+ mov rax, cr3
+ mov rbp, rax
+
+ ;
+ ; Prepare the CS and return address for the transition from 32-bit to 64-bit mode
+ ;
+ mov rax, dword 0x10 ; load long mode selector
+ shl rax, 32
+ lea r9, [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.
+ ;
+ lea rax, [ReturnBack] ;Assume the ReloadCS is under 4G
+ shl rax, 32
+ or rax, rcx
+ push rax
+
+ ;
+ ; let rax save DS
+ ;
+ mov rax, dword 0x18
+
+ ;
+ ; Change to Compatible Segment
+ ;
+ mov rcx, dword 0x8 ; load compatible mode selector
+ shl rcx, 32
+ lea rdx, [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, 0xC0000080
+ 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, 0xC0000080
+ 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 original GDT and CS. here rsp is pointer to the original GDT descriptor.
+ ;
+ lgdt [rsp]
+ ;
+ ; drop GDT descriptor in stack
+ ;
+ add rsp, 0x10
+ ;
+ ; switch to original CS and GDTR
+ ;
+ pop r9 ; get CS
+ shl r9, 32 ; rcx[32..47] <- Cs
+ lea rcx, [.0]
+ or rcx, r9
+ push rcx
+ retf
+.0:
+ ;
+ ; Reload original DS/ES/SS
+ ;
+ pop rcx
+ mov ds, rcx
+ mov es, rcx
+ mov ss, rcx
+
+ ;
+ ; Restore IFLAG
+ ;
+ popfq
+
+ ret
+
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiTestLibNull/BaseFspWrapperApiTestLibNull.inf b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiTestLibNull/BaseFspWrapperApiTestLibNull.inf
new file mode 100644
index 00000000..beb56dd6
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiTestLibNull/BaseFspWrapperApiTestLibNull.inf
@@ -0,0 +1,48 @@
+### @file
+# Provide FSP wrapper API test related function.
+#
+# Copyright (C) 2016, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010017
+ BASE_NAME = BaseFspWrapperApiTestLibNull
+ FILE_GUID = E7E96F88-017B-417C-8DC8-B84C2B877020
+ VERSION_STRING = 1.0
+ MODULE_TYPE = PEIM
+ LIBRARY_CLASS = FspWrapperApiTestLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32
+#
+
+################################################################################
+#
+# Sources Section - list of files that are required for the build to succeed.
+#
+################################################################################
+
+[Sources]
+ FspWrapperApiTestNull.c
+
+################################################################################
+#
+# Package Dependency Section - list of Package files that are required for
+# this module.
+#
+################################################################################
+
+[Packages]
+ MdePkg/MdePkg.dec
+ IntelFsp2Pkg/IntelFsp2Pkg.dec
+ IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec
+
+[LibraryClasses]
+ DebugLib
+
+[Guids]
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiTestLibNull/FspWrapperApiTestNull.c b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiTestLibNull/FspWrapperApiTestNull.c
new file mode 100644
index 00000000..51f88630
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiTestLibNull/FspWrapperApiTestNull.c
@@ -0,0 +1,59 @@
+/** @file
+ Provide FSP wrapper API test related function.
+
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+
+/**
+ Test the output of FSP API - FspMemoryInit.
+
+ @param[in] FspmUpdDataPtr Address pointer to the FSP_MEMORY_INIT_PARAMS structure.
+ @param[in] HobListPtr Address of the HobList pointer.
+
+ @return test result on output of FspMemoryInit API.
+**/
+EFI_STATUS
+EFIAPI
+TestFspMemoryInitApiOutput (
+ IN VOID *FspmUpdDataPtr,
+ IN VOID **HobListPtr
+ )
+{
+ return RETURN_UNSUPPORTED;
+}
+
+/**
+ Test the output of FSP API - TempRamExit.
+
+ @param[in] TempRamExitParam Address pointer to the TempRamExit parameters structure.
+
+ @return test result on output of TempRamExit API.
+**/
+EFI_STATUS
+EFIAPI
+TestFspTempRamExitApiOutput (
+ IN VOID *TempRamExitParam
+ )
+{
+ return RETURN_UNSUPPORTED;
+}
+
+/**
+ Test the output of FSP API - FspSiliconInit.
+
+ @param[in] FspsUpdDataPtr Address pointer to the Silicon Init parameters structure.
+
+ @return test result on output of FspSiliconInit API.
+**/
+EFI_STATUS
+EFIAPI
+TestFspSiliconInitApiOutput (
+ IN VOID *FspsUpdDataPtr
+ )
+{
+ return RETURN_UNSUPPORTED;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/BaseFspWrapperPlatformLibSample/BaseFspWrapperPlatformLibSample.inf b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/BaseFspWrapperPlatformLibSample/BaseFspWrapperPlatformLibSample.inf
new file mode 100644
index 00000000..95e69d57
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/BaseFspWrapperPlatformLibSample/BaseFspWrapperPlatformLibSample.inf
@@ -0,0 +1,52 @@
+## @file
+# Sample to provide FSP wrapper platform related function.
+#
+# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = BaseFspWrapperPlatformLibSample
+ FILE_GUID = 12F38E73-B34D-4559-99E5-AE2DCD002156
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = FspWrapperPlatformLib
+
+#
+# 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]
+ FspWrapperPlatformLibSample.c
+
+
+################################################################################
+#
+# Package Dependency Section - list of Package files that are required for
+# this module.
+#
+################################################################################
+
+[Packages]
+ MdePkg/MdePkg.dec
+ IntelFsp2Pkg/IntelFsp2Pkg.dec
+ IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec
+
+[LibraryClasses]
+
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/BaseFspWrapperPlatformLibSample/FspWrapperPlatformLibSample.c b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/BaseFspWrapperPlatformLibSample/FspWrapperPlatformLibSample.c
new file mode 100644
index 00000000..1ffc871d
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/BaseFspWrapperPlatformLibSample/FspWrapperPlatformLibSample.c
@@ -0,0 +1,97 @@
+/** @file
+ Sample to provide FSP wrapper related function.
+
+ Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+#include <Library/PcdLib.h>
+
+/**
+ This function overrides the default configurations in the FSP-M UPD data region.
+
+ @note At this point, memory is NOT ready, PeiServices are available to use.
+
+ @param[in,out] FspUpdRgnPtr A pointer to the UPD data region data structure.
+
+**/
+VOID
+EFIAPI
+UpdateFspmUpdData (
+ IN OUT VOID *FspUpdRgnPtr
+ )
+{
+}
+
+/**
+ This function overrides the default configurations in the FSP-S UPD data region.
+
+ @param[in,out] FspUpdRgnPtr A pointer to the UPD data region data structure.
+
+**/
+VOID
+EFIAPI
+UpdateFspsUpdData (
+ IN OUT VOID *FspUpdRgnPtr
+ )
+{
+}
+
+/**
+ Update TempRamExit parameter.
+
+ @note At this point, memory is ready, PeiServices are available to use.
+
+ @return TempRamExit parameter.
+**/
+VOID *
+EFIAPI
+UpdateTempRamExitParam (
+ VOID
+ )
+{
+ return NULL;
+}
+
+/**
+ 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
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Perform platform related reset in FSP wrapper.
+
+ This function will reset the system with requested ResetType.
+
+ @param[in] FspStatusResetType The type of reset the platform has to perform.
+**/
+VOID
+EFIAPI
+CallFspWrapperResetSystem (
+ IN UINT32 FspStatusResetType
+ )
+{
+ //
+ // Perform reset according to the type.
+ //
+
+ CpuDeadLoop();
+}
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/PeiFspWrapperApiTestLib/FspWrapperApiTest.c b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/PeiFspWrapperApiTestLib/FspWrapperApiTest.c
new file mode 100644
index 00000000..de34230d
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/PeiFspWrapperApiTestLib/FspWrapperApiTest.c
@@ -0,0 +1,82 @@
+/** @file
+ Provide FSP wrapper API test related function.
+
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Guid/GuidHobFspEas.h>
+
+/**
+ Test the output of FSP API - FspMemoryInit.
+
+ @param[in] FspmUpdDataPtr Address pointer to the FSP_MEMORY_INIT_PARAMS structure.
+ @param[in] HobListPtr Address of the HobList pointer.
+
+ @return test result on output of FspMemoryInit API.
+**/
+EFI_STATUS
+EFIAPI
+TestFspMemoryInitApiOutput (
+ IN VOID *FspmUpdDataPtr,
+ IN VOID **HobListPtr
+ )
+{
+ DEBUG_CODE_BEGIN ();
+ EFI_PEI_HOB_POINTERS Hob;
+
+ Hob.Raw = (UINT8 *)(*(HobListPtr));
+ while (TRUE) {
+ if (END_OF_HOB_LIST(Hob) == TRUE) {
+ DEBUG((DEBUG_INFO, "gFspBootLoaderTolumHobGuid not Found\n"));
+ break;
+ }
+ if ((CompareGuid (&Hob.ResourceDescriptor->Owner, &gFspBootLoaderTolumHobGuid))) {
+ DEBUG ((DEBUG_INFO, "gFspBootLoaderTolumHobGuid Found\n"));
+ DEBUG ((DEBUG_INFO, "Fill Boot Loader reserved memory range with 0x5A for testing purpose\n"));
+ SetMem ((VOID *)(UINTN)Hob.ResourceDescriptor->PhysicalStart, (UINTN)Hob.ResourceDescriptor->ResourceLength, 0x5A);
+ break;
+ }
+ Hob.Raw = GET_NEXT_HOB (Hob);
+ }
+ DEBUG_CODE_END ();
+
+ return RETURN_SUCCESS;
+}
+
+/**
+ Test the output of FSP API - TempRamExit.
+
+ @param[in] TempRamExitParam Address pointer to the TempRamExit parameters structure.
+
+ @return test result on output of TempRamExit API.
+**/
+EFI_STATUS
+EFIAPI
+TestFspTempRamExitApiOutput (
+ IN VOID *TempRamExitParam
+ )
+{
+ return RETURN_SUCCESS;
+}
+
+/**
+ Test the output of FSP API - FspSiliconInit.
+
+ @param[in] FspsUpdDataPtr Address pointer to the Silicon Init parameters structure.
+
+ @return test result on output of FspSiliconInit API.
+**/
+EFI_STATUS
+EFIAPI
+TestFspSiliconInitApiOutput (
+ IN VOID *FspsUpdDataPtr
+ )
+{
+ return RETURN_SUCCESS;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/PeiFspWrapperApiTestLib/PeiFspWrapperApiTestLib.inf b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/PeiFspWrapperApiTestLib/PeiFspWrapperApiTestLib.inf
new file mode 100644
index 00000000..2f266635
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/PeiFspWrapperApiTestLib/PeiFspWrapperApiTestLib.inf
@@ -0,0 +1,51 @@
+### @file
+# Provide FSP-M wrapper API test related function.
+#
+# Copyright (C) 2016 - 2017, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010017
+ BASE_NAME = PeiFspWrapperApiTestLib
+ FILE_GUID = 87DC266A-C8F7-4A66-A0CB-018A6F5305B4
+ VERSION_STRING = 1.0
+ MODULE_TYPE = PEIM
+ LIBRARY_CLASS = FspWrapperApiTestLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32
+#
+
+################################################################################
+#
+# Sources Section - list of files that are required for the build to succeed.
+#
+################################################################################
+
+[Sources]
+ FspWrapperApiTest.c
+
+################################################################################
+#
+# Package Dependency Section - list of Package files that are required for
+# this module.
+#
+################################################################################
+
+[Packages]
+ MdePkg/MdePkg.dec
+ IntelFsp2Pkg/IntelFsp2Pkg.dec
+ IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec
+
+[LibraryClasses]
+ BaseMemoryLib
+ DebugLib
+ HobLib
+
+[Guids]
+ gFspBootLoaderTolumHobGuid ## SOMETIMES_CONSUMES ## GUID
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/PeiFspWrapperHobProcessLibSample/FspWrapperHobProcessLibSample.c b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/PeiFspWrapperHobProcessLibSample/FspWrapperHobProcessLibSample.c
new file mode 100644
index 00000000..3905335a
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/PeiFspWrapperHobProcessLibSample/FspWrapperHobProcessLibSample.c
@@ -0,0 +1,396 @@
+/** @file
+ Sample to provide FSP wrapper hob process related function.
+
+ Copyright (c) 2014 - 2019, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+
+#include <Library/PeiServicesLib.h>
+#include <Library/PeiServicesTablePointerLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/FspWrapperPlatformLib.h>
+
+#include <Guid/GuidHobFspEas.h>
+#include <Guid/MemoryTypeInformation.h>
+#include <Guid/PcdDataBaseHobGuid.h>
+#include <Ppi/Capsule.h>
+
+//
+// Additional pages are used by DXE memory manager.
+// It should be consistent between RetrieveRequiredMemorySize() and GetPeiMemSize()
+//
+#define PEI_ADDITIONAL_MEMORY_SIZE (16 * EFI_PAGE_SIZE)
+
+/**
+ Get the mem size in memory type information table.
+
+ @param[in] PeiServices PEI Services table.
+
+ @return the mem size in memory type information table.
+**/
+UINT64
+GetMemorySizeInMemoryTypeInformation (
+ IN EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status;
+ EFI_PEI_HOB_POINTERS Hob;
+ EFI_MEMORY_TYPE_INFORMATION *MemoryData;
+ UINT8 Index;
+ UINTN TempPageNum;
+
+ MemoryData = NULL;
+ Status = (*PeiServices)->GetHobList ((CONST EFI_PEI_SERVICES**)PeiServices, (VOID **) &Hob.Raw);
+ ASSERT_EFI_ERROR (Status);
+ while (!END_OF_HOB_LIST (Hob)) {
+ if (Hob.Header->HobType == EFI_HOB_TYPE_GUID_EXTENSION &&
+ CompareGuid (&Hob.Guid->Name, &gEfiMemoryTypeInformationGuid)) {
+ MemoryData = (EFI_MEMORY_TYPE_INFORMATION *) (Hob.Raw + sizeof (EFI_HOB_GENERIC_HEADER) + sizeof (EFI_GUID));
+ break;
+ }
+
+ Hob.Raw = GET_NEXT_HOB (Hob);
+ }
+
+ if (MemoryData == NULL) {
+ return 0;
+ }
+
+ TempPageNum = 0;
+ for (Index = 0; MemoryData[Index].Type != EfiMaxMemoryType; Index++) {
+ //
+ // Accumulate default memory size requirements
+ //
+ TempPageNum += MemoryData[Index].NumberOfPages;
+ }
+
+ return TempPageNum * EFI_PAGE_SIZE;
+}
+
+/**
+ Get the mem size need to be reserved in PEI phase.
+
+ @param[in] PeiServices PEI Services table.
+
+ @return the mem size need to be reserved in PEI phase.
+**/
+UINT64
+RetrieveRequiredMemorySize (
+ IN EFI_PEI_SERVICES **PeiServices
+ )
+{
+ UINT64 Size;
+
+ Size = GetMemorySizeInMemoryTypeInformation (PeiServices);
+ return Size + PEI_ADDITIONAL_MEMORY_SIZE;
+}
+
+/**
+ Get the mem size need to be consumed and reserved in PEI phase.
+
+ @param[in] PeiServices PEI Services table.
+ @param[in] BootMode Current boot mode.
+
+ @return the mem size need to be consumed and reserved in PEI phase.
+**/
+UINT64
+GetPeiMemSize (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINT32 BootMode
+ )
+{
+ UINT64 Size;
+ UINT64 MinSize;
+
+ if (BootMode == BOOT_IN_RECOVERY_MODE) {
+ return PcdGet32 (PcdPeiRecoveryMinMemSize);
+ }
+
+ Size = GetMemorySizeInMemoryTypeInformation (PeiServices);
+
+ if (BootMode == BOOT_ON_FLASH_UPDATE) {
+ //
+ // Maybe more size when in CapsuleUpdate phase ?
+ //
+ MinSize = PcdGet32 (PcdPeiMinMemSize);
+ } else {
+ MinSize = PcdGet32 (PcdPeiMinMemSize);
+ }
+
+ return MinSize + Size + PEI_ADDITIONAL_MEMORY_SIZE;
+}
+
+/**
+ Post FSP-M HOB process 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
+PostFspmHobProcess (
+ IN VOID *FspHobList
+ )
+{
+ EFI_PEI_HOB_POINTERS Hob;
+ UINT64 LowMemorySize;
+ UINT64 FspMemorySize;
+ EFI_PHYSICAL_ADDRESS FspMemoryBase;
+ UINT64 PeiMemSize;
+ EFI_PHYSICAL_ADDRESS PeiMemBase;
+ UINT64 S3PeiMemSize;
+ EFI_PHYSICAL_ADDRESS S3PeiMemBase;
+ BOOLEAN FoundFspMemHob;
+ EFI_STATUS Status;
+ EFI_BOOT_MODE BootMode;
+ EFI_PEI_CAPSULE_PPI *Capsule;
+ VOID *CapsuleBuffer;
+ UINTN CapsuleBufferLength;
+ UINT64 RequiredMemSize;
+ EFI_PEI_SERVICES **PeiServices;
+
+ PeiServices = (EFI_PEI_SERVICES **)GetPeiServicesTablePointer ();
+
+ PeiServicesGetBootMode (&BootMode);
+
+ PeiMemBase = 0;
+ LowMemorySize = 0;
+ FspMemorySize = 0;
+ FspMemoryBase = 0;
+ FoundFspMemHob = FALSE;
+
+ //
+ // Parse the hob list from fsp
+ // Report all the resource hob except the memory between 1M and 4G
+ //
+ Hob.Raw = (UINT8 *)(UINTN)FspHobList;
+ DEBUG((DEBUG_INFO, "FspHobList - 0x%x\n", FspHobList));
+
+ while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw)) != NULL) {
+ DEBUG((DEBUG_INFO, "\nResourceType: 0x%x\n", Hob.ResourceDescriptor->ResourceType));
+ if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) ||
+ (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED)) {
+ DEBUG((DEBUG_INFO, "ResourceAttribute: 0x%x\n", Hob.ResourceDescriptor->ResourceAttribute));
+ DEBUG((DEBUG_INFO, "PhysicalStart: 0x%x\n", Hob.ResourceDescriptor->PhysicalStart));
+ DEBUG((DEBUG_INFO, "ResourceLength: 0x%x\n", Hob.ResourceDescriptor->ResourceLength));
+ DEBUG((DEBUG_INFO, "Owner: %g\n\n", &Hob.ResourceDescriptor->Owner));
+ }
+
+ if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) // Found the low memory length below 4G
+ && (Hob.ResourceDescriptor->PhysicalStart >= BASE_1MB)
+ && (Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength <= BASE_4GB)) {
+ LowMemorySize += Hob.ResourceDescriptor->ResourceLength;
+ Hob.Raw = GET_NEXT_HOB (Hob);
+ continue;
+ }
+
+ if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED) // Found the low memory length below 4G
+ && (Hob.ResourceDescriptor->PhysicalStart >= BASE_1MB)
+ && (Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength <= BASE_4GB)
+ && (CompareGuid (&Hob.ResourceDescriptor->Owner, &gFspReservedMemoryResourceHobGuid))) {
+ FoundFspMemHob = TRUE;
+ FspMemoryBase = Hob.ResourceDescriptor->PhysicalStart;
+ FspMemorySize = Hob.ResourceDescriptor->ResourceLength;
+ DEBUG((DEBUG_INFO, "Find fsp mem hob, base 0x%x, len 0x%x\n", FspMemoryBase, FspMemorySize));
+ }
+
+ //
+ // Report the resource hob
+ //
+ BuildResourceDescriptorHob (
+ Hob.ResourceDescriptor->ResourceType,
+ Hob.ResourceDescriptor->ResourceAttribute,
+ Hob.ResourceDescriptor->PhysicalStart,
+ Hob.ResourceDescriptor->ResourceLength
+ );
+
+ Hob.Raw = GET_NEXT_HOB (Hob);
+ }
+
+ if (!FoundFspMemHob) {
+ DEBUG((DEBUG_INFO, "Didn't find the fsp used memory information.\n"));
+ //ASSERT(FALSE);
+ }
+
+ DEBUG((DEBUG_INFO, "LowMemorySize: 0x%x.\n", LowMemorySize));
+ DEBUG((DEBUG_INFO, "FspMemoryBase: 0x%x.\n", FspMemoryBase));
+ DEBUG((DEBUG_INFO, "FspMemorySize: 0x%x.\n", FspMemorySize));
+
+ if (BootMode == BOOT_ON_S3_RESUME) {
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_SYSTEM_MEMORY,
+ (
+ EFI_RESOURCE_ATTRIBUTE_PRESENT |
+ EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+ // EFI_RESOURCE_ATTRIBUTE_TESTED |
+ EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
+ EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
+ EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
+ EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
+ ),
+ BASE_1MB,
+ LowMemorySize
+ );
+
+ S3PeiMemBase = 0;
+ S3PeiMemSize = 0;
+ Status = GetS3MemoryInfo (&S3PeiMemSize, &S3PeiMemBase);
+ ASSERT_EFI_ERROR (Status);
+ DEBUG((DEBUG_INFO, "S3 memory %Xh - %Xh bytes\n", S3PeiMemBase, S3PeiMemSize));
+
+ //
+ // Make sure Stack and PeiMemory are not overlap
+ //
+
+ Status = PeiServicesInstallPeiMemory (
+ S3PeiMemBase,
+ S3PeiMemSize
+ );
+ ASSERT_EFI_ERROR (Status);
+ } else {
+ PeiMemSize = GetPeiMemSize (PeiServices, BootMode);
+ DEBUG((DEBUG_INFO, "PEI memory size = %Xh bytes\n", PeiMemSize));
+
+ //
+ // Capsule mode
+ //
+ Capsule = NULL;
+ CapsuleBuffer = NULL;
+ CapsuleBufferLength = 0;
+ if (BootMode == BOOT_ON_FLASH_UPDATE) {
+ Status = PeiServicesLocatePpi (
+ &gEfiPeiCapsulePpiGuid,
+ 0,
+ NULL,
+ (VOID **) &Capsule
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ if (Status == EFI_SUCCESS) {
+ //
+ // Make sure Stack and CapsuleBuffer are not overlap
+ //
+ CapsuleBuffer = (VOID *)(UINTN)BASE_1MB;
+ CapsuleBufferLength = (UINTN)(LowMemorySize - PeiMemSize);
+ //
+ // Call the Capsule PPI Coalesce function to coalesce the capsule data.
+ //
+ Status = Capsule->Coalesce (PeiServices, &CapsuleBuffer, &CapsuleBufferLength);
+ }
+ }
+
+ RequiredMemSize = RetrieveRequiredMemorySize (PeiServices);
+ DEBUG((DEBUG_INFO, "Required memory size = %Xh bytes\n", RequiredMemSize));
+
+ //
+ // Report the main memory
+ //
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_SYSTEM_MEMORY,
+ (
+ EFI_RESOURCE_ATTRIBUTE_PRESENT |
+ EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+ EFI_RESOURCE_ATTRIBUTE_TESTED |
+ EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
+ EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
+ EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
+ EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
+ ),
+ BASE_1MB,
+ LowMemorySize
+ );
+
+ //
+ // Make sure Stack and CapsuleBuffer are not overlap
+ //
+
+ //
+ // Install efi memory
+ //
+ PeiMemBase = BASE_1MB + LowMemorySize - PeiMemSize;
+ Status = PeiServicesInstallPeiMemory (
+ PeiMemBase,
+ PeiMemSize - RequiredMemSize
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ if (Capsule != NULL) {
+ Status = Capsule->CreateState (PeiServices, CapsuleBuffer, CapsuleBufferLength);
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Process FSP HOB list
+
+ @param[in] FspHobList Pointer to the HOB data structure produced by FSP.
+
+**/
+VOID
+ProcessFspHobList (
+ IN VOID *FspHobList
+ )
+{
+ EFI_PEI_HOB_POINTERS FspHob;
+
+ FspHob.Raw = FspHobList;
+
+ //
+ // Add all the HOBs from FSP binary to FSP wrapper
+ //
+ while (!END_OF_HOB_LIST (FspHob)) {
+ if (FspHob.Header->HobType == EFI_HOB_TYPE_GUID_EXTENSION) {
+ //
+ // Skip FSP binary creates PcdDataBaseHobGuid
+ //
+ if (!CompareGuid(&FspHob.Guid->Name, &gPcdDataBaseHobGuid)) {
+ BuildGuidDataHob (
+ &FspHob.Guid->Name,
+ GET_GUID_HOB_DATA(FspHob),
+ GET_GUID_HOB_DATA_SIZE(FspHob)
+ );
+ }
+ }
+ FspHob.Raw = GET_NEXT_HOB (FspHob);
+ }
+}
+
+/**
+ Post FSP-S HOB process (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
+PostFspsHobProcess (
+ IN VOID *FspHobList
+ )
+{
+ //
+ // PostFspsHobProcess () will be called in both FSP API and Dispatch modes to
+ // align the same behavior and support a variety of boot loader implementations.
+ // Boot loader provided library function is recommended to support both API and
+ // Dispatch modes by checking PcdFspModeSelection.
+ //
+ if (PcdGet8 (PcdFspModeSelection) == 1) {
+ //
+ // Only in FSP API mode the wrapper has to build hobs basing on FSP output data.
+ // In this case FspHobList cannot be NULL.
+ //
+ ASSERT (FspHobList != NULL);
+ ProcessFspHobList (FspHobList);
+ }
+ return EFI_SUCCESS;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/PeiFspWrapperHobProcessLibSample/PeiFspWrapperHobProcessLibSample.inf b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/PeiFspWrapperHobProcessLibSample/PeiFspWrapperHobProcessLibSample.inf
new file mode 100644
index 00000000..4cd8e73d
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/PeiFspWrapperHobProcessLibSample/PeiFspWrapperHobProcessLibSample.inf
@@ -0,0 +1,72 @@
+## @file
+# Sample to provide FSP wrapper hob process related function.
+#
+# Copyright (c) 2014 - 2019, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = PeiFspWrapperHobProcessLibSample
+ FILE_GUID = 864693E2-EDE8-4DF8-8871-38C0BAA157EB
+ MODULE_TYPE = SEC
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = FspWrapperHobProcessLib
+
+#
+# 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]
+ FspWrapperHobProcessLibSample.c
+
+
+################################################################################
+#
+# Package Dependency Section - list of Package files that are required for
+# this module.
+#
+################################################################################
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ IntelFsp2Pkg/IntelFsp2Pkg.dec
+ IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ HobLib
+ DebugLib
+ FspWrapperPlatformLib
+ PeiServicesLib
+ PeiServicesTablePointerLib
+
+[Pcd]
+ gIntelFsp2WrapperTokenSpaceGuid.PcdPeiMinMemSize ## CONSUMES
+ gIntelFsp2WrapperTokenSpaceGuid.PcdPeiRecoveryMinMemSize ## CONSUMES
+ gIntelFsp2WrapperTokenSpaceGuid.PcdFspModeSelection ## CONSUMES
+
+[Guids]
+ gFspReservedMemoryResourceHobGuid ## CONSUMES ## HOB
+ gEfiMemoryTypeInformationGuid ## CONSUMES ## GUID
+ gPcdDataBaseHobGuid ## CONSUMES ## HOB
+
+[Ppis]
+ gEfiPeiCapsulePpiGuid ## CONSUMES
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/FspWrapperPlatformSecLibSample.c b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/FspWrapperPlatformSecLibSample.c
new file mode 100644
index 00000000..399b8fd6
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/FspWrapperPlatformSecLibSample.c
@@ -0,0 +1,129 @@
+/** @file
+ Sample to provide FSP wrapper platform sec related function.
+
+ Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+
+#include <Ppi/SecPlatformInformation.h>
+#include <Ppi/SecPerformance.h>
+
+#include <Library/LocalApicLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.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
+ );
+
+PEI_SEC_PERFORMANCE_PPI mSecPerformancePpi = {
+ SecGetPerformance
+};
+
+EFI_PEI_PPI_DESCRIPTOR mPeiSecPlatformPpi[] = {
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI,
+ &gTopOfTemporaryRamPpiGuid,
+ NULL // To be patched later.
+ },
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gPeiSecPerformancePpiGuid,
+ &mSecPerformancePpi
+ },
+};
+
+/**
+ 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;
+
+ DEBUG((DEBUG_INFO, "SecPlatformMain\n"));
+
+ DEBUG((DEBUG_INFO, "BootFirmwareVolumeBase - 0x%x\n", SecCoreData->BootFirmwareVolumeBase));
+ DEBUG((DEBUG_INFO, "BootFirmwareVolumeSize - 0x%x\n", SecCoreData->BootFirmwareVolumeSize));
+ DEBUG((DEBUG_INFO, "TemporaryRamBase - 0x%x\n", SecCoreData->TemporaryRamBase));
+ DEBUG((DEBUG_INFO, "TemporaryRamSize - 0x%x\n", SecCoreData->TemporaryRamSize));
+ DEBUG((DEBUG_INFO, "PeiTemporaryRamBase - 0x%x\n", SecCoreData->PeiTemporaryRamBase));
+ DEBUG((DEBUG_INFO, "PeiTemporaryRamSize - 0x%x\n", SecCoreData->PeiTemporaryRamSize));
+ DEBUG((DEBUG_INFO, "StackBase - 0x%x\n", SecCoreData->StackBase));
+ DEBUG((DEBUG_INFO, "StackSize - 0x%x\n", SecCoreData->StackSize));
+
+ InitializeApicTimer (0, (UINT32) -1, TRUE, 5);
+
+ //
+ // Use middle of Heap as temp buffer, it will be copied by caller.
+ // Do not use Stack, because it will cause wrong calculation on stack by PeiCore
+ //
+ PpiList = (VOID *)((UINTN)SecCoreData->PeiTemporaryRamBase + (UINTN)SecCoreData->PeiTemporaryRamSize/2);
+ CopyMem (PpiList, mPeiSecPlatformPpi, sizeof(mPeiSecPlatformPpi));
+
+ //
+ // Patch TopOfTemporaryRamPpi
+ //
+ PpiList[0].Ppi = (VOID *)((UINTN)SecCoreData->TemporaryRamBase + SecCoreData->TemporaryRamSize);
+
+ return PpiList;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/Fsp.h b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/Fsp.h
new file mode 100644
index 00000000..d91a2b56
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/Fsp.h
@@ -0,0 +1,45 @@
+/** @file
+ Fsp related definitions
+
+ Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __FSP_H__
+#define __FSP_H__
+
+//
+// Fv Header
+//
+#define FVH_FV_LENGTH_OFFSET 0x20
+#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_SIGNATURE_OFFSET 0x1C
+#define FSP_HEADER_SIGNATURE 0x48505346 ; valid signature:FSPH
+#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/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/PeiCoreEntry.nasm b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/PeiCoreEntry.nasm
new file mode 100644
index 00000000..cf443aa2
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/PeiCoreEntry.nasm
@@ -0,0 +1,130 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+; Module Name:
+;
+; PeiCoreEntry.nasm
+;
+; Abstract:
+;
+; Find and call SecStartup
+;
+;------------------------------------------------------------------------------
+
+SECTION .text
+
+extern ASM_PFX(SecStartup)
+extern ASM_PFX(PlatformInit)
+
+global ASM_PFX(CallPeiCoreEntryPoint)
+ASM_PFX(CallPeiCoreEntryPoint):
+ ;
+ ; 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+0xC]
+
+ ;
+ ; Platform init
+ ;
+ pushad
+ push edx
+ push ecx
+ push eax
+ call ASM_PFX(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, 0xFF
+ 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, 0xFFFFFFE0
+ push DWORD [edi]
+
+ ;
+ ; Pass BFV into the PEI Core
+ ;
+ mov edi, 0xFFFFFFFC
+ push DWORD [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 ASM_PFX(SecStartup)
+
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/SecEntry.nasm b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/SecEntry.nasm
new file mode 100644
index 00000000..b506212b
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/SecEntry.nasm
@@ -0,0 +1,335 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+; Module Name:
+;
+; SecEntry.asm
+;
+; Abstract:
+;
+; This is the code that goes from real-mode to protected mode.
+; It consumes the reset vector, calls TempRamInit API from FSP binary.
+;
+;------------------------------------------------------------------------------
+
+#include "Fsp.h"
+
+SECTION .text
+
+extern ASM_PFX(CallPeiCoreEntryPoint)
+extern ASM_PFX(FsptUpdDataPtr)
+
+; Pcds
+extern ASM_PFX(PcdGet32 (PcdFsptBaseAddress))
+
+;----------------------------------------------------------------------------
+;
+; 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.
+;
+;----------------------------------------------------------------------------
+
+BITS 16
+align 4
+global ASM_PFX(ModuleEntryPoint)
+ASM_PFX(ModuleEntryPoint):
+ 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, GdtDesc
+ DB 66h
+ lgdt [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, ProtectedModeEntryLinearAddress
+ jmp dword far [cs:si]
+
+;----------------------------------------------------------------------------
+;
+; 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
+;
+;----------------------------------------------------------------------------
+
+BITS 32
+align 4
+ProtectedModeEntryPoint:
+
+ ; Find the fsp info header
+ mov edi, [ASM_PFX(PcdGet32 (PcdFsptBaseAddress))]
+
+ mov eax, dword [edi + FVH_SIGINATURE_OFFSET]
+ cmp eax, FVH_SIGINATURE_VALID_VALUE
+ jnz FspHeaderNotFound
+
+ xor eax, eax
+ mov ax, word [edi + FVH_EXTHEADER_OFFSET_OFFSET]
+ cmp ax, 0
+ jnz FspFvExtHeaderExist
+
+ xor eax, eax
+ mov ax, word [edi + FVH_HEADER_LENGTH_OFFSET] ; Bypass Fv Header
+ add edi, eax
+ jmp FspCheckFfsHeader
+
+FspFvExtHeaderExist:
+ add edi, eax
+ mov eax, dword [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 [edi]
+ cmp eax, FSP_HEADER_GUID_DWORD1
+ jnz FspHeaderNotFound
+
+ mov eax, dword [edi + 4]
+ cmp eax, FSP_HEADER_GUID_DWORD2
+ jnz FspHeaderNotFound
+
+ mov eax, dword [edi + 8]
+ cmp eax, FSP_HEADER_GUID_DWORD3
+ jnz FspHeaderNotFound
+
+ mov eax, dword [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 [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 [edi + FSP_HEADER_IMAGEBASE_OFFSET]
+ add eax, dword [edi + FSP_HEADER_TEMPRAMINIT_OFFSET]
+
+ ; Setup the hardcode stack
+ mov esp, TempRamInitStack
+
+ ; Call the fsp TempRamInit Api
+ jmp eax
+
+TempRamInitDone:
+ cmp eax, 8000000Eh ;Check if EFI_NOT_FOUND returned. Error code for Microcode Update not found.
+ je CallSecFspInit ;If microcode not found, don't hang, but continue.
+
+ cmp eax, 0 ;Check if EFI_SUCCESS returned.
+ jnz FspApiFailed
+
+ ; ECX: start of range
+ ; EDX: end of range
+CallSecFspInit:
+ xor eax, eax
+ mov esp, edx
+
+ ; Align the stack at DWORD
+ add esp, 3
+ and esp, 0FFFFFFFCh
+
+ push edx
+ push ecx
+ push eax ; zero - no hob list yet
+ call ASM_PFX(CallPeiCoreEntryPoint)
+
+FspApiFailed:
+ jmp $
+
+align 10h
+TempRamInitStack:
+ DD TempRamInitDone
+ DD ASM_PFX(FsptUpdDataPtr); TempRamInitParams
+
+;
+; ROM-based Global-Descriptor Table for the Tiano PEI Phase
+;
+align 16
+global ASM_PFX(BootGdtTable)
+
+;
+; GDT[0]: 0x00: Null entry, never used.
+;
+NULL_SEL EQU $ - GDT_BASE ; Selector [0]
+GDT_BASE:
+ASM_PFX(BootGdtTable):
+ DD 0
+ DD 0
+;
+; Linear 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 $ - GDT_BASE ; Size, in bytes
+
+;
+; GDT Descriptor
+;
+GdtDesc: ; GDT descriptor
+ DW GDT_SIZE - 1 ; GDT limit
+ DD GDT_BASE ; GDT base address
+
+
+ProtectedModeEntryLinearAddress:
+ProtectedModeEntryLinear:
+ DD ProtectedModeEntryPoint ; Offset of our 32 bit code
+ DW LINEAR_CODE_SEL
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/Stack.nasm b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/Stack.nasm
new file mode 100644
index 00000000..8ce8c059
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/Stack.nasm
@@ -0,0 +1,73 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+; Abstract:
+;
+; Switch the stack from temporary memory to permanent memory.
+;
+;------------------------------------------------------------------------------
+
+ SECTION .text
+
+;------------------------------------------------------------------------------
+; VOID
+; EFIAPI
+; SecSwitchStack (
+; UINT32 TemporaryMemoryBase,
+; UINT32 PermanentMemoryBase
+; );
+;------------------------------------------------------------------------------
+global ASM_PFX(SecSwitchStack)
+ASM_PFX(SecSwitchStack):
+ ;
+ ; 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 permanent
+ ; 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 permanent memory at first.
+ ; Then, Fixup the esp point to permanent memory
+ ;
+ mov eax, esp
+ sub eax, ebx
+ add eax, ecx
+ mov edx, dword [esp] ; copy pushed register's value to permanent memory
+ mov dword [eax], edx
+ mov edx, dword [esp + 4]
+ mov dword [eax + 4], edx
+ mov edx, dword [esp + 8]
+ mov dword [eax + 8], edx
+ mov edx, dword [esp + 12]
+ mov dword [eax + 12], edx
+ mov edx, dword [esp + 16] ; Update this function's return address into permanent memory
+ mov dword [eax + 16], edx
+ mov esp, eax ; From now, esp is pointed to permanent memory
+
+ ;
+ ; Fixup the ebp point to permanent memory
+ ;
+ mov eax, ebp
+ sub eax, ebx
+ add eax, ecx
+ mov ebp, eax ; From now, ebp is pointed to permanent memory
+
+ pop edx
+ pop ecx
+ pop ebx
+ pop eax
+ ret
+
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/PlatformInit.c b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/PlatformInit.c
new file mode 100644
index 00000000..9777ec9a
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/PlatformInit.c
@@ -0,0 +1,39 @@
+/** @file
+ Sample to provide platform init function.
+
+ Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#include <PiPei.h>
+#include <Library/DebugLib.h>
+#include <Library/SerialPortLib.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
+ //
+ SerialPortInitialize ();
+
+ DEBUG ((DEBUG_INFO, "PrintPeiCoreEntryPointParam in PlatformInit\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/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecFspWrapperPlatformSecLibSample.inf b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecFspWrapperPlatformSecLibSample.inf
new file mode 100644
index 00000000..d978a2b6
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecFspWrapperPlatformSecLibSample.inf
@@ -0,0 +1,83 @@
+## @file
+# Sample to provide FSP wrapper platform sec related function.
+#
+# Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SecFspWrapperPlatformSecLibSample
+ FILE_GUID = 8F1AC44A-CE7E-4E29-95BB-92E321BB1573
+ MODULE_TYPE = SEC
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = PlatformSecLib
+
+#
+# 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]
+ FspWrapperPlatformSecLibSample.c
+ SecRamInitData.c
+ SecPlatformInformation.c
+ SecGetPerformance.c
+ SecTempRamDone.c
+ PlatformInit.c
+
+[Sources.IA32]
+ Ia32/Fsp.h
+ Ia32/SecEntry.nasm
+ Ia32/PeiCoreEntry.nasm
+ Ia32/Stack.nasm
+
+################################################################################
+#
+# Package Dependency Section - list of Package files that are required for
+# this module.
+#
+################################################################################
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+ IntelFsp2Pkg/IntelFsp2Pkg.dec
+ IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec
+
+[LibraryClasses]
+ LocalApicLib
+ SerialPortLib
+ DebugLib
+ BaseMemoryLib
+
+[Ppis]
+ gEfiSecPlatformInformationPpiGuid ## CONSUMES
+ gPeiSecPerformancePpiGuid ## CONSUMES
+ gTopOfTemporaryRamPpiGuid ## PRODUCES
+
+[Pcd]
+ gIntelFsp2WrapperTokenSpaceGuid.PcdFsptBaseAddress ## CONSUMES
+ gIntelFsp2WrapperTokenSpaceGuid.PcdFspmBaseAddress ## CONSUMES
+
+[FixedPcd]
+ gIntelFsp2WrapperTokenSpaceGuid.PcdCpuMicrocodePatchAddress ## CONSUMES
+ gIntelFsp2WrapperTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize ## CONSUMES
+ gIntelFsp2WrapperTokenSpaceGuid.PcdFlashMicrocodeOffset ## CONSUMES
+ gIntelFsp2WrapperTokenSpaceGuid.PcdFlashCodeCacheAddress ## CONSUMES
+ gIntelFsp2WrapperTokenSpaceGuid.PcdFlashCodeCacheSize ## CONSUMES
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecGetPerformance.c b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecGetPerformance.c
new file mode 100644
index 00000000..469bf447
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecGetPerformance.c
@@ -0,0 +1,84 @@
+/** @file
+ Sample to provide SecGetPerformance function.
+
+ Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#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/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecPlatformInformation.c b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecPlatformInformation.c
new file mode 100644
index 00000000..b3493546
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecPlatformInformation.c
@@ -0,0 +1,78 @@
+/** @file
+ Sample to provide SecPlatformInformation function.
+
+ Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#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/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecRamInitData.c b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecRamInitData.c
new file mode 100644
index 00000000..6f1f6ddf
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecRamInitData.c
@@ -0,0 +1,61 @@
+/** @file
+ Sample to provide TempRamInitParams data.
+
+ Copyright (c) 2014 - 2020, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/PcdLib.h>
+#include <FspEas.h>
+
+typedef struct {
+ UINT32 MicrocodeRegionBase;
+ UINT32 MicrocodeRegionSize;
+ UINT32 CodeRegionBase;
+ UINT32 CodeRegionSize;
+} FSPT_CORE_UPD;
+
+typedef struct {
+ FSP_UPD_HEADER FspUpdHeader;
+ //
+ // If platform does not support FSP spec 2.2 remove FSPT_ARCH_UPD structure.
+ //
+ FSPT_ARCH_UPD FsptArchUpd;
+ FSPT_CORE_UPD FsptCoreUpd;
+} FSPT_UPD_CORE_DATA;
+
+GLOBAL_REMOVE_IF_UNREFERENCED CONST FSPT_UPD_CORE_DATA FsptUpdDataPtr = {
+ {
+ 0x4450555F54505346,
+ //
+ // UPD header revision must be equal or greater than 2 when the structure is compliant with FSP spec 2.2.
+ //
+ 0x02,
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ }
+ },
+ //
+ // If platform does not support FSP spec 2.2 remove FSPT_ARCH_UPD structure.
+ //
+ {
+ 0x01,
+ {
+ 0x00, 0x00, 0x00
+ },
+ 0x00000020,
+ 0x00000000,
+ {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ }
+ },
+ {
+ ((UINT32)FixedPcdGet64 (PcdCpuMicrocodePatchAddress) + FixedPcdGet32 (PcdFlashMicrocodeOffset)),
+ ((UINT32)FixedPcdGet64 (PcdCpuMicrocodePatchRegionSize) - FixedPcdGet32 (PcdFlashMicrocodeOffset)),
+ FixedPcdGet32 (PcdFlashCodeCacheAddress),
+ FixedPcdGet32 (PcdFlashCodeCacheSize),
+ }
+};
+
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecTempRamDone.c b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecTempRamDone.c
new file mode 100644
index 00000000..75a1c8b2
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecTempRamDone.c
@@ -0,0 +1,43 @@
+/** @file
+ Sample to provide SecTemporaryRamDone function.
+
+ Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/FspWrapperApiLib.h>
+#include <Library/FspWrapperPlatformLib.h>
+#include <Guid/FspHeaderFile.h>
+
+/**
+This interface disables temporary memory in SEC Phase.
+**/
+VOID
+EFIAPI
+SecPlatformDisableTemporaryMemory (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ VOID *TempRamExitParam;
+ FSP_INFO_HEADER *FspHeader;
+
+ FspHeader = FspFindFspHeader (PcdGet32(PcdFspmBaseAddress));
+ if (FspHeader == NULL) {
+ return ;
+ }
+
+ DEBUG((DEBUG_INFO, "SecPlatformDisableTemporaryMemory enter\n"));
+
+ TempRamExitParam = UpdateTempRamExitParam ();
+ Status = CallTempRamExit (TempRamExitParam);
+ DEBUG((DEBUG_INFO, "TempRamExit status: 0x%x\n", Status));
+ ASSERT_EFI_ERROR(Status);
+
+ return ;
+}