diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 16:49:04 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 16:49:04 +0000 |
commit | 16f504a9dca3fe3b70568f67b7d41241ae485288 (patch) | |
tree | c60f36ada0496ba928b7161059ba5ab1ab224f9d /src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library | |
parent | Initial commit. (diff) | |
download | virtualbox-upstream.tar.xz virtualbox-upstream.zip |
Adding upstream version 7.0.6-dfsg.upstream/7.0.6-dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Library')
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 ; +} |