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 | |
parent | Initial commit. (diff) | |
download | virtualbox-16f504a9dca3fe3b70568f67b7d41241ae485288.tar.xz virtualbox-16f504a9dca3fe3b70568f67b7d41241ae485288.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')
43 files changed, 4904 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.c b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.c new file mode 100644 index 00000000..3f3859e0 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.c @@ -0,0 +1,277 @@ +/** @file + This driver will register two callbacks to call fsp's notifies. + + Copyright (c) 2014 - 2019, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include <PiDxe.h> + +#include <Protocol/PciEnumerationComplete.h> + +#include <Library/UefiDriverEntryPoint.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Library/DebugLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/UefiLib.h> +#include <Library/FspWrapperApiLib.h> +#include <Library/FspWrapperPlatformLib.h> +#include <Library/PerformanceLib.h> +#include <Library/HobLib.h> +#include <FspStatusCode.h> + +#define FSP_API_NOTIFY_PHASE_AFTER_PCI_ENUMERATION BIT16 + +typedef +EFI_STATUS +(EFIAPI * ADD_PERFORMANCE_RECORDS)( + IN CONST VOID *HobStart + ); + +struct _ADD_PERFORMANCE_RECORD_PROTOCOL { + ADD_PERFORMANCE_RECORDS AddPerformanceRecords; +}; + +typedef struct _ADD_PERFORMANCE_RECORD_PROTOCOL ADD_PERFORMANCE_RECORD_PROTOCOL; + +extern EFI_GUID gAddPerfRecordProtocolGuid; +extern EFI_GUID gFspHobGuid; +extern EFI_GUID gFspApiPerformanceGuid; + +static EFI_EVENT mExitBootServicesEvent = NULL; + +/** + Relocate this image under 4G memory. + + @param ImageHandle Handle of driver image. + @param SystemTable Pointer to system table. + + @retval EFI_SUCCESS Image successfully relocated. + @retval EFI_ABORTED Failed to relocate image. + +**/ +EFI_STATUS +RelocateImageUnder4GIfNeeded ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + PciEnumerationComplete Protocol notification event handler. + + @param[in] Event Event whose notification function is being invoked. + @param[in] Context Pointer to the notification function's context. +**/ +VOID +EFIAPI +OnPciEnumerationComplete ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + NOTIFY_PHASE_PARAMS NotifyPhaseParams; + EFI_STATUS Status; + VOID *Interface; + + // + // Try to locate it because gEfiPciEnumerationCompleteProtocolGuid will trigger it once when registration. + // Just return if it is not found. + // + Status = gBS->LocateProtocol ( + &gEfiPciEnumerationCompleteProtocolGuid, + NULL, + &Interface + ); + if (EFI_ERROR (Status)) { + return ; + } + + NotifyPhaseParams.Phase = EnumInitPhaseAfterPciEnumeration; + PERF_START_EX(&gFspApiPerformanceGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY); + Status = CallFspNotifyPhase (&NotifyPhaseParams); + PERF_END_EX(&gFspApiPerformanceGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT); + + // + // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED status + // + if ((Status >= FSP_STATUS_RESET_REQUIRED_COLD) && (Status <= FSP_STATUS_RESET_REQUIRED_8)) { + DEBUG((DEBUG_INFO, "FSP NotifyPhase AfterPciEnumeration requested reset 0x%x\n", Status)); + CallFspWrapperResetSystem ((UINT32)Status); + } + + if (Status != EFI_SUCCESS) { + DEBUG((DEBUG_ERROR, "FSP NotifyPhase AfterPciEnumeration failed, status: 0x%x\n", Status)); + } else { + DEBUG((DEBUG_INFO, "FSP NotifyPhase AfterPciEnumeration Success.\n")); + } +} + +/** + Notification function of EVT_GROUP_READY_TO_BOOT event group. + + This is a notification function registered on EVT_GROUP_READY_TO_BOOT event group. + When the Boot Manager is about to load and execute a boot option, it reclaims variable + storage if free size is below the threshold. + + @param[in] Event Event whose notification function is being invoked. + @param[in] Context Pointer to the notification function's context. + +**/ +VOID +EFIAPI +OnReadyToBoot ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + NOTIFY_PHASE_PARAMS NotifyPhaseParams; + EFI_STATUS Status; + + gBS->CloseEvent (Event); + + NotifyPhaseParams.Phase = EnumInitPhaseReadyToBoot; + PERF_START_EX(&gFspApiPerformanceGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY); + Status = CallFspNotifyPhase (&NotifyPhaseParams); + PERF_END_EX(&gFspApiPerformanceGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT); + + // + // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED status + // + if ((Status >= FSP_STATUS_RESET_REQUIRED_COLD) && (Status <= FSP_STATUS_RESET_REQUIRED_8)) { + DEBUG((DEBUG_INFO, "FSP NotifyPhase ReadyToBoot requested reset 0x%x\n", Status)); + CallFspWrapperResetSystem ((UINT32)Status); + } + + if (Status != EFI_SUCCESS) { + DEBUG((DEBUG_ERROR, "FSP NotifyPhase ReadyToBoot failed, status: 0x%x\n", Status)); + } else { + DEBUG((DEBUG_INFO, "FSP NotifyPhase ReadyToBoot Success.\n")); + } +} + +/** + This stage is notified just before the firmware/Preboot environment transfers + management of all system resources to the OS or next level execution environment. + + @param Event Event whose notification function is being invoked. + @param Context Pointer to the notification function's context, which is + always zero in current implementation. + +**/ +VOID +EFIAPI +OnEndOfFirmware ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + NOTIFY_PHASE_PARAMS NotifyPhaseParams; + EFI_STATUS Status; + ADD_PERFORMANCE_RECORD_PROTOCOL *AddPerfRecordInterface; + EFI_PEI_HOB_POINTERS Hob; + VOID **FspHobListPtr; + + gBS->CloseEvent (Event); + + NotifyPhaseParams.Phase = EnumInitPhaseEndOfFirmware; + PERF_START_EX(&gFspApiPerformanceGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY); + Status = CallFspNotifyPhase (&NotifyPhaseParams); + PERF_END_EX(&gFspApiPerformanceGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT); + + // + // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED status + // + if ((Status >= FSP_STATUS_RESET_REQUIRED_COLD) && (Status <= FSP_STATUS_RESET_REQUIRED_8)) { + DEBUG((DEBUG_INFO, "FSP NotifyPhase EndOfFirmware requested reset 0x%x\n", Status)); + CallFspWrapperResetSystem ((UINT32)Status); + } + + if (Status != EFI_SUCCESS) { + DEBUG((DEBUG_ERROR, "FSP NotifyPhase EndOfFirmware failed, status: 0x%x\n", Status)); + } else { + DEBUG((DEBUG_INFO, "FSP NotifyPhase EndOfFirmware Success.\n")); + } + Status = gBS->LocateProtocol ( + &gAddPerfRecordProtocolGuid, + NULL, + (VOID**) &AddPerfRecordInterface + ); + if (EFI_ERROR (Status)) { + DEBUG((DEBUG_INFO, "gAddPerfRecordProtocolGuid - Locate protocol failed\n")); + return; + } else { + Hob.Raw = GetFirstGuidHob (&gFspHobGuid); + if (Hob.Raw != NULL) { + FspHobListPtr = GET_GUID_HOB_DATA (Hob.Raw); + AddPerfRecordInterface->AddPerformanceRecords ((VOID *)(UINTN)(((UINT32)(UINTN)*FspHobListPtr) & 0xFFFFFFFF)); + } + } +} + +/** + Main entry for the FSP DXE module. + + This routine registers two callbacks to call fsp's notifies. + + @param[in] ImageHandle The firmware allocated handle for the EFI image. + @param[in] SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The entry point is executed successfully. + @retval other Some error occurs when executing this entry point. + +**/ +EFI_STATUS +EFIAPI +FspWrapperNotifyDxeEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_EVENT ReadyToBootEvent; + VOID *Registration; + EFI_EVENT ProtocolNotifyEvent; + UINT32 FspApiMask; + + // + // Load this driver's image to memory + // + Status = RelocateImageUnder4GIfNeeded (ImageHandle, SystemTable); + if (EFI_ERROR (Status)) { + return EFI_SUCCESS; + } + + FspApiMask = PcdGet32 (PcdSkipFspApi); + if ((FspApiMask & FSP_API_NOTIFY_PHASE_AFTER_PCI_ENUMERATION) == 0) { + ProtocolNotifyEvent = EfiCreateProtocolNotifyEvent ( + &gEfiPciEnumerationCompleteProtocolGuid, + TPL_CALLBACK, + OnPciEnumerationComplete, + NULL, + &Registration + ); + ASSERT (ProtocolNotifyEvent != NULL); + } + + Status = EfiCreateEventReadyToBootEx ( + TPL_CALLBACK, + OnReadyToBoot, + NULL, + &ReadyToBootEvent + ); + ASSERT_EFI_ERROR (Status); + + Status = gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + OnEndOfFirmware, + NULL, + &gEfiEventExitBootServicesGuid, + &mExitBootServicesEvent + ); + ASSERT_EFI_ERROR (Status); + + return EFI_SUCCESS; +} + diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.inf b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.inf new file mode 100644 index 00000000..299d9209 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.inf @@ -0,0 +1,62 @@ +## @file +# FSP DXE Module +# +# This driver will register two callbacks to call fsp's notifies. +# +# Copyright (c) 2014 - 2017, Intel Corporation. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = FspWrapperNotifyDxe + FILE_GUID = AD61999A-507E-47E6-BA28-79CC609FA1A4 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = FspWrapperNotifyDxeEntryPoint + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + FspWrapperNotifyDxe.c + LoadBelow4G.c + +[Packages] + MdePkg/MdePkg.dec + IntelFsp2Pkg/IntelFsp2Pkg.dec + IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec + +[LibraryClasses] + UefiDriverEntryPoint + UefiBootServicesTableLib + DebugLib + BaseMemoryLib + UefiLib + FspWrapperApiLib + PeCoffLib + CacheMaintenanceLib + DxeServicesLib + PerformanceLib + HobLib + FspWrapperPlatformLib + +[Protocols] + gEfiPciEnumerationCompleteProtocolGuid ## CONSUMES + gAddPerfRecordProtocolGuid ## SOMETIMES_CONSUMES + +[Guids] + gFspApiPerformanceGuid ## SOMETIMES_CONSUMES ## GUID + gEfiEventExitBootServicesGuid ## CONSUMES ## Event + gFspHobGuid ## CONSUMES ## HOB + +[Pcd] + gIntelFsp2WrapperTokenSpaceGuid.PcdSkipFspApi ## CONSUMES + +[Depex] + TRUE diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/LoadBelow4G.c b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/LoadBelow4G.c new file mode 100644 index 00000000..5283f485 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/LoadBelow4G.c @@ -0,0 +1,145 @@ +/** @file + +Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR> + +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include <Uefi.h> +#include <Library/BaseLib.h> +#include <Library/UefiDriverEntryPoint.h> +#include <Library/BaseMemoryLib.h> +#include <Library/DebugLib.h> +#include <Library/PeCoffLib.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Library/DxeServicesLib.h> +#include <Library/CacheMaintenanceLib.h> +#include <Library/UefiLib.h> + +/** + Relocate this image under 4G memory. + + @param ImageHandle Handle of driver image. + @param SystemTable Pointer to system table. + + @retval EFI_SUCCESS Image successfully relocated. + @retval EFI_ABORTED Failed to relocate image. + +**/ +EFI_STATUS +RelocateImageUnder4GIfNeeded ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + UINT8 *Buffer; + UINTN BufferSize; + EFI_HANDLE NewImageHandle; + UINTN Pages; + EFI_PHYSICAL_ADDRESS FfsBuffer; + PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; + VOID *Interface; + + // + // If it is already <4G, no need do relocate + // + if ((UINTN)RelocateImageUnder4GIfNeeded < 0xFFFFFFFF) { + return EFI_SUCCESS; + } + + // + // If locate gEfiCallerIdGuid success, it means 2nd entry. + // + Status = gBS->LocateProtocol (&gEfiCallerIdGuid, NULL, &Interface); + if (!EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "FspNotifyDxe - 2nd entry\n")); + return EFI_SUCCESS; + } + + DEBUG ((DEBUG_INFO, "FspNotifyDxe - 1st entry\n")); + + // + // Here we install a dummy handle + // + NewImageHandle = NULL; + Status = gBS->InstallProtocolInterface ( + &NewImageHandle, + &gEfiCallerIdGuid, + EFI_NATIVE_INTERFACE, + NULL + ); + ASSERT_EFI_ERROR (Status); + + // + // Reload image itself to <4G mem + // + Status = GetSectionFromAnyFv ( + &gEfiCallerIdGuid, + EFI_SECTION_PE32, + 0, + (VOID **) &Buffer, + &BufferSize + ); + ASSERT_EFI_ERROR (Status); + ImageContext.Handle = Buffer; + ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory; + // + // Get information about the image being loaded + // + Status = PeCoffLoaderGetImageInfo (&ImageContext); + ASSERT_EFI_ERROR (Status); + if (ImageContext.SectionAlignment > EFI_PAGE_SIZE) { + Pages = EFI_SIZE_TO_PAGES ((UINTN) (ImageContext.ImageSize + ImageContext.SectionAlignment)); + } else { + Pages = EFI_SIZE_TO_PAGES ((UINTN) ImageContext.ImageSize); + } + FfsBuffer = 0xFFFFFFFF; + Status = gBS->AllocatePages ( + AllocateMaxAddress, + EfiBootServicesCode, + Pages, + &FfsBuffer + ); + ASSERT_EFI_ERROR (Status); + ImageContext.ImageAddress = (PHYSICAL_ADDRESS)(UINTN)FfsBuffer; + // + // Align buffer on section boundary + // + ImageContext.ImageAddress += ImageContext.SectionAlignment - 1; + ImageContext.ImageAddress &= ~((EFI_PHYSICAL_ADDRESS)ImageContext.SectionAlignment - 1); + // + // Load the image to our new buffer + // + Status = PeCoffLoaderLoadImage (&ImageContext); + ASSERT_EFI_ERROR (Status); + + // + // Relocate the image in our new buffer + // + Status = PeCoffLoaderRelocateImage (&ImageContext); + ASSERT_EFI_ERROR (Status); + + // + // Free the buffer allocated by ReadSection since the image has been relocated in the new buffer + // + gBS->FreePool (Buffer); + + // + // Flush the instruction cache so the image data is written before we execute it + // + InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize); + + DEBUG ((DEBUG_INFO, "Loading driver at 0x%08x EntryPoint=0x%08x\n", (UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.EntryPoint)); + Status = ((EFI_IMAGE_ENTRY_POINT)(UINTN)(ImageContext.EntryPoint)) (NewImageHandle, gST); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Error: Image at 0x%08x start failed: %r\n", ImageContext.ImageAddress, Status)); + gBS->FreePages (FfsBuffer, Pages); + } + + // + // return error to unload >4G copy, if we already relocate itself to <4G. + // + return EFI_ALREADY_STARTED; +} diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.c b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.c new file mode 100644 index 00000000..43f2f656 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.c @@ -0,0 +1,276 @@ +/** @file + This will be invoked only once. It will call FspMemoryInit API, + register TemporaryRamDonePpi to call TempRamExit API, and register MemoryDiscoveredPpi + notify to call FspSiliconInit API. + + Copyright (c) 2014 - 2020, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + + +#include <PiPei.h> + +#include <Library/PeimEntryPoint.h> +#include <Library/PeiServicesLib.h> +#include <Library/PeiServicesTablePointerLib.h> +#include <Library/BaseLib.h> +#include <Library/DebugLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/HobLib.h> +#include <Library/PcdLib.h> +#include <Library/TimerLib.h> +#include <Library/PerformanceLib.h> +#include <Library/FspWrapperPlatformLib.h> +#include <Library/FspWrapperHobProcessLib.h> +#include <Library/FspWrapperApiLib.h> +#include <Library/FspMeasurementLib.h> + +#include <Ppi/FspSiliconInitDone.h> +#include <Ppi/EndOfPeiPhase.h> +#include <Ppi/MemoryDiscovered.h> +#include <Ppi/SecPlatformInformation.h> +#include <Ppi/Tcg.h> +#include <Ppi/FirmwareVolumeInfoMeasurementExcluded.h> +#include <Library/FspWrapperApiTestLib.h> +#include <FspEas.h> +#include <FspStatusCode.h> + +extern EFI_GUID gFspHobGuid; + +/** + Call FspMemoryInit API. + + @return Status returned by FspMemoryInit API. +**/ +EFI_STATUS +PeiFspMemoryInit ( + VOID + ) +{ + FSP_INFO_HEADER *FspmHeaderPtr; + EFI_STATUS Status; + UINT64 TimeStampCounterStart; + VOID *FspHobListPtr; + VOID *HobData; + FSPM_UPD_COMMON *FspmUpdDataPtr; + UINTN *SourceData; + + DEBUG ((DEBUG_INFO, "PeiFspMemoryInit enter\n")); + + FspHobListPtr = NULL; + FspmUpdDataPtr = NULL; + + FspmHeaderPtr = (FSP_INFO_HEADER *) FspFindFspHeader (PcdGet32 (PcdFspmBaseAddress)); + DEBUG ((DEBUG_INFO, "FspmHeaderPtr - 0x%x\n", FspmHeaderPtr)); + if (FspmHeaderPtr == NULL) { + return EFI_DEVICE_ERROR; + } + + if (PcdGet32 (PcdFspmUpdDataAddress) == 0 && (FspmHeaderPtr->CfgRegionSize != 0) && (FspmHeaderPtr->CfgRegionOffset != 0)) { + // + // Copy default FSP-M UPD data from Flash + // + FspmUpdDataPtr = (FSPM_UPD_COMMON *)AllocateZeroPool ((UINTN)FspmHeaderPtr->CfgRegionSize); + ASSERT (FspmUpdDataPtr != NULL); + SourceData = (UINTN *)((UINTN)FspmHeaderPtr->ImageBase + (UINTN)FspmHeaderPtr->CfgRegionOffset); + CopyMem (FspmUpdDataPtr, SourceData, (UINTN)FspmHeaderPtr->CfgRegionSize); + } else { + // + // External UPD is ready, get the buffer from PCD pointer. + // + FspmUpdDataPtr = (FSPM_UPD_COMMON *)PcdGet32 (PcdFspmUpdDataAddress); + ASSERT (FspmUpdDataPtr != NULL); + } + + DEBUG ((DEBUG_INFO, "UpdateFspmUpdData enter\n")); + UpdateFspmUpdData ((VOID *)FspmUpdDataPtr); + DEBUG ((DEBUG_INFO, " NvsBufferPtr - 0x%x\n", FspmUpdDataPtr->FspmArchUpd.NvsBufferPtr)); + DEBUG ((DEBUG_INFO, " StackBase - 0x%x\n", FspmUpdDataPtr->FspmArchUpd.StackBase)); + DEBUG ((DEBUG_INFO, " StackSize - 0x%x\n", FspmUpdDataPtr->FspmArchUpd.StackSize)); + DEBUG ((DEBUG_INFO, " BootLoaderTolumSize - 0x%x\n", FspmUpdDataPtr->FspmArchUpd.BootLoaderTolumSize)); + DEBUG ((DEBUG_INFO, " BootMode - 0x%x\n", FspmUpdDataPtr->FspmArchUpd.BootMode)); + DEBUG ((DEBUG_INFO, " HobListPtr - 0x%x\n", &FspHobListPtr)); + + TimeStampCounterStart = AsmReadTsc (); + Status = CallFspMemoryInit (FspmUpdDataPtr, &FspHobListPtr); + // Create hobs after memory initialization and not in temp RAM. Hence passing the recorded timestamp here + PERF_START_EX(&gFspApiPerformanceGuid, "EventRec", NULL, TimeStampCounterStart, FSP_STATUS_CODE_MEMORY_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY); + PERF_END_EX(&gFspApiPerformanceGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_MEMORY_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT); + DEBUG ((DEBUG_INFO, "Total time spent executing FspMemoryInitApi: %d millisecond\n", DivU64x32 (GetTimeInNanoSecond (AsmReadTsc () - TimeStampCounterStart), 1000000))); + + // + // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED status + // + if ((Status >= FSP_STATUS_RESET_REQUIRED_COLD) && (Status <= FSP_STATUS_RESET_REQUIRED_8)) { + DEBUG((DEBUG_INFO, "FspMemoryInitApi requested reset 0x%x\n", Status)); + CallFspWrapperResetSystem ((UINT32)Status); + } + + if (EFI_ERROR(Status)) { + DEBUG ((DEBUG_ERROR, "ERROR - Failed to execute FspMemoryInitApi(), Status = %r\n", Status)); + } + DEBUG((DEBUG_INFO, "FspMemoryInit status: 0x%x\n", Status)); + ASSERT_EFI_ERROR (Status); + + + Status = TestFspMemoryInitApiOutput (FspmUpdDataPtr, &FspHobListPtr); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "ERROR - TestFspMemoryInitApiOutput () fail, Status = %r\n", Status)); + } + + DEBUG ((DEBUG_INFO, " FspHobListPtr (returned) - 0x%x\n", FspHobListPtr)); + ASSERT (FspHobListPtr != NULL); + + PostFspmHobProcess (FspHobListPtr); + + // + // FspHobList is not complete at this moment. + // Save FspHobList pointer to hob, so that it can be got later + // + HobData = BuildGuidHob ( + &gFspHobGuid, + sizeof (VOID *) + ); + ASSERT (HobData != NULL); + CopyMem (HobData, &FspHobListPtr, sizeof (FspHobListPtr)); + + return Status; +} + +/** + Do FSP initialization. + + @return FSP initialization status. +**/ +EFI_STATUS +EFIAPI +FspmWrapperInit ( + VOID + ) +{ + EFI_STATUS Status; + EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_PPI *MeasurementExcludedFvPpi; + EFI_PEI_PPI_DESCRIPTOR *MeasurementExcludedPpiList; + + MeasurementExcludedFvPpi = AllocatePool (sizeof(*MeasurementExcludedFvPpi)); + ASSERT(MeasurementExcludedFvPpi != NULL); + MeasurementExcludedFvPpi->Count = 1; + MeasurementExcludedFvPpi->Fv[0].FvBase = PcdGet32 (PcdFspmBaseAddress); + MeasurementExcludedFvPpi->Fv[0].FvLength = ((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) PcdGet32 (PcdFspmBaseAddress))->FvLength; + + MeasurementExcludedPpiList = AllocatePool (sizeof(*MeasurementExcludedPpiList)); + ASSERT(MeasurementExcludedPpiList != NULL); + MeasurementExcludedPpiList->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST; + MeasurementExcludedPpiList->Guid = &gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid; + MeasurementExcludedPpiList->Ppi = MeasurementExcludedFvPpi; + + Status = EFI_SUCCESS; + + if (PcdGet8 (PcdFspModeSelection) == 1) { + Status = PeiFspMemoryInit (); + ASSERT_EFI_ERROR (Status); + } else { + Status = PeiServicesInstallPpi (MeasurementExcludedPpiList); + ASSERT_EFI_ERROR (Status); + + PeiServicesInstallFvInfoPpi ( + NULL, + (VOID *)(UINTN) PcdGet32 (PcdFspmBaseAddress), + (UINT32)((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) PcdGet32 (PcdFspmBaseAddress))->FvLength, + NULL, + NULL + ); + } + + return Status; +} + +/** + This function is called after TCG installed PPI. + + @param[in] PeiServices Pointer to PEI Services Table. + @param[in] NotifyDesc Pointer to the descriptor for the Notification event that + caused this function to execute. + @param[in] Ppi Pointer to the PPI data associated with this function. + + @retval EFI_STATUS Always return EFI_SUCCESS +**/ +EFI_STATUS +EFIAPI +TcgPpiNotify ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc, + IN VOID *Ppi + ); + +EFI_PEI_NOTIFY_DESCRIPTOR mTcgPpiNotifyDesc = { + (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEdkiiTcgPpiGuid, + TcgPpiNotify +}; + +/** + This function is called after TCG installed PPI. + + @param[in] PeiServices Pointer to PEI Services Table. + @param[in] NotifyDesc Pointer to the descriptor for the Notification event that + caused this function to execute. + @param[in] Ppi Pointer to the PPI data associated with this function. + + @retval EFI_STATUS Always return EFI_SUCCESS +**/ +EFI_STATUS +EFIAPI +TcgPpiNotify ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc, + IN VOID *Ppi + ) +{ + UINT32 FspMeasureMask; + + DEBUG ((DEBUG_INFO, "TcgPpiNotify FSPM\n")); + + FspMeasureMask = PcdGet32 (PcdFspMeasurementConfig); + + if ((FspMeasureMask & FSP_MEASURE_FSPT) != 0) { + MeasureFspFirmwareBlob (0, "FSPT", PcdGet32(PcdFsptBaseAddress), + (UINT32)((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) PcdGet32 (PcdFsptBaseAddress))->FvLength); + } + + if ((FspMeasureMask & FSP_MEASURE_FSPM) != 0) { + MeasureFspFirmwareBlob (0, "FSPM", PcdGet32(PcdFspmBaseAddress), + (UINT32)((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) PcdGet32 (PcdFspmBaseAddress))->FvLength); + } + + return EFI_SUCCESS; +} + +/** + This is the entrypoint of PEIM + + @param[in] FileHandle Handle of the file being invoked. + @param[in] PeiServices Describes the list of possible PEI Services. + + @retval EFI_SUCCESS if it completed successfully. +**/ +EFI_STATUS +EFIAPI +FspmWrapperPeimEntryPoint ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + + DEBUG((DEBUG_INFO, "FspmWrapperPeimEntryPoint\n")); + + Status = PeiServicesNotifyPpi (&mTcgPpiNotifyDesc); + ASSERT_EFI_ERROR (Status); + + FspmWrapperInit (); + + return EFI_SUCCESS; +} diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.inf b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.inf new file mode 100644 index 00000000..c1bd297e --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.inf @@ -0,0 +1,76 @@ +## @file +# FSP-M wrapper PEI Module +# +# This PEIM initialize FSP. +# This will be invoked only once. It will call FspMemoryInit API, +# register TemporaryRamDonePpi to call TempRamExit API, and register MemoryDiscoveredPpi +# notify to call FspSiliconInit API. +# +# Copyright (c) 2014 - 2020, Intel Corporation. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010017 + BASE_NAME = FspmWrapperPeim + FILE_GUID = 9FAAD0FF-0E0C-4885-A738-BAB4E4FA1E66 + VERSION_STRING = 1.0 + MODULE_TYPE = PEIM + ENTRY_POINT = FspmWrapperPeimEntryPoint + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 +# + +[LibraryClasses] + PeimEntryPoint + PeiServicesLib + PeiServicesTablePointerLib + BaseLib + BaseMemoryLib + MemoryAllocationLib + DebugLib + HobLib + FspWrapperPlatformLib + FspWrapperHobProcessLib + UefiCpuLib + PeCoffGetEntryPointLib + PeCoffExtraActionLib + PerformanceLib + TimerLib + FspWrapperApiLib + FspWrapperApiTestLib + FspMeasurementLib + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + SecurityPkg/SecurityPkg.dec + IntelFsp2Pkg/IntelFsp2Pkg.dec + IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec + +[Pcd] + gIntelFsp2WrapperTokenSpaceGuid.PcdFspmBaseAddress ## CONSUMES + gIntelFsp2WrapperTokenSpaceGuid.PcdFspmUpdDataAddress ## CONSUMES + gIntelFsp2WrapperTokenSpaceGuid.PcdFspModeSelection ## CONSUMES + gIntelFsp2WrapperTokenSpaceGuid.PcdFsptBaseAddress ## CONSUMES + gIntelFsp2WrapperTokenSpaceGuid.PcdFspMeasurementConfig ## CONSUMES + +[Sources] + FspmWrapperPeim.c + +[Guids] + gFspHobGuid ## PRODUCES ## HOB + gFspApiPerformanceGuid ## SOMETIMES_CONSUMES ## GUID + +[Ppis] + gEdkiiTcgPpiGuid ## NOTIFY + gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid ## PRODUCES + +[Depex] + gEfiPeiMasterBootModePpiGuid diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.c b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.c new file mode 100644 index 00000000..aa5b7f77 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.c @@ -0,0 +1,507 @@ +/** @file + This will be invoked only once. It will call FspMemoryInit API, + register TemporaryRamDonePpi to call TempRamExit API, and register MemoryDiscoveredPpi + notify to call FspSiliconInit API. + + Copyright (c) 2014 - 2020, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include <PiPei.h> + +#include <Library/PeimEntryPoint.h> +#include <Library/PeiServicesLib.h> +#include <Library/PeiServicesTablePointerLib.h> +#include <Library/BaseLib.h> +#include <Library/DebugLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/HobLib.h> +#include <Library/PcdLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/FspWrapperPlatformLib.h> +#include <Library/FspWrapperHobProcessLib.h> +#include <Library/TimerLib.h> +#include <Library/PerformanceLib.h> +#include <Library/FspWrapperApiLib.h> +#include <Library/FspMeasurementLib.h> + +#include <Ppi/FspSiliconInitDone.h> +#include <Ppi/EndOfPeiPhase.h> +#include <Ppi/MemoryDiscovered.h> +#include <Ppi/TemporaryRamDone.h> +#include <Ppi/SecPlatformInformation.h> +#include <Ppi/Tcg.h> +#include <Ppi/FirmwareVolumeInfoMeasurementExcluded.h> +#include <Library/FspWrapperApiTestLib.h> +#include <FspEas.h> +#include <FspStatusCode.h> + +extern EFI_PEI_NOTIFY_DESCRIPTOR mS3EndOfPeiNotifyDesc; +extern EFI_GUID gFspHobGuid; + +/** + This function handles S3 resume task at the end of PEI. + + @param[in] PeiServices Pointer to PEI Services Table. + @param[in] NotifyDesc Pointer to the descriptor for the Notification event that + caused this function to execute. + @param[in] Ppi Pointer to the PPI data associated with this function. + + @retval EFI_STATUS Always return EFI_SUCCESS +**/ +EFI_STATUS +EFIAPI +S3EndOfPeiNotify( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc, + IN VOID *Ppi + ); + +EFI_PEI_NOTIFY_DESCRIPTOR mS3EndOfPeiNotifyDesc = { + (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiEndOfPeiSignalPpiGuid, + S3EndOfPeiNotify +}; + +/** + This function handles S3 resume task at the end of PEI. + + @param[in] PeiServices Pointer to PEI Services Table. + @param[in] NotifyDesc Pointer to the descriptor for the Notification event that + caused this function to execute. + @param[in] Ppi Pointer to the PPI data associated with this function. + + @retval EFI_STATUS Always return EFI_SUCCESS +**/ +EFI_STATUS +EFIAPI +S3EndOfPeiNotify( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc, + IN VOID *Ppi + ) +{ + NOTIFY_PHASE_PARAMS NotifyPhaseParams; + EFI_STATUS Status; + + DEBUG((DEBUG_INFO, "S3EndOfPeiNotify enter\n")); + + NotifyPhaseParams.Phase = EnumInitPhaseAfterPciEnumeration; + Status = CallFspNotifyPhase (&NotifyPhaseParams); + DEBUG((DEBUG_INFO, "FSP S3NotifyPhase AfterPciEnumeration status: 0x%x\n", Status)); + + // + // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED status + // + if ((Status >= FSP_STATUS_RESET_REQUIRED_COLD) && (Status <= FSP_STATUS_RESET_REQUIRED_8)) { + DEBUG((DEBUG_INFO, "FSP S3NotifyPhase AfterPciEnumeration requested reset 0x%x\n", Status)); + CallFspWrapperResetSystem ((UINT32)Status); + } + + NotifyPhaseParams.Phase = EnumInitPhaseReadyToBoot; + Status = CallFspNotifyPhase (&NotifyPhaseParams); + DEBUG((DEBUG_INFO, "FSP S3NotifyPhase ReadyToBoot status: 0x%x\n", Status)); + + // + // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED status + // + if ((Status >= FSP_STATUS_RESET_REQUIRED_COLD) && (Status <= FSP_STATUS_RESET_REQUIRED_8)) { + DEBUG((DEBUG_INFO, "FSP S3NotifyPhase ReadyToBoot requested reset 0x%x\n", Status)); + CallFspWrapperResetSystem ((UINT32)Status); + } + + NotifyPhaseParams.Phase = EnumInitPhaseEndOfFirmware; + Status = CallFspNotifyPhase (&NotifyPhaseParams); + DEBUG((DEBUG_INFO, "FSP S3NotifyPhase EndOfFirmware status: 0x%x\n", Status)); + + // + // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED status + // + if ((Status >= FSP_STATUS_RESET_REQUIRED_COLD) && (Status <= FSP_STATUS_RESET_REQUIRED_8)) { + DEBUG((DEBUG_INFO, "FSP S3NotifyPhase EndOfFirmware requested reset 0x%x\n", Status)); + CallFspWrapperResetSystem ((UINT32)Status); + } + + return EFI_SUCCESS; +} + +/** + Return Hob list produced by FSP. + + @param[in] PeiServices The pointer to the PEI Services Table. + @param[in] This The pointer to this instance of this PPI. + @param[out] FspHobList The pointer to Hob list produced by FSP. + + @return EFI_SUCCESS Return Hob list produced by FSP successfully. +**/ +EFI_STATUS +EFIAPI +FspSiliconInitDoneGetFspHobList ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN FSP_SILICON_INIT_DONE_PPI *This, + OUT VOID **FspHobList + ); + +FSP_SILICON_INIT_DONE_PPI mFspSiliconInitDonePpi = { + FspSiliconInitDoneGetFspHobList +}; + +EFI_PEI_PPI_DESCRIPTOR mPeiFspSiliconInitDonePpi = { + EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, + &gFspSiliconInitDonePpiGuid, + &mFspSiliconInitDonePpi +}; + +/** + Return Hob list produced by FSP. + + @param[in] PeiServices The pointer to the PEI Services Table. + @param[in] This The pointer to this instance of this PPI. + @param[out] FspHobList The pointer to Hob list produced by FSP. + + @return EFI_SUCCESS Return Hob list produced by FSP successfully. +**/ +EFI_STATUS +EFIAPI +FspSiliconInitDoneGetFspHobList ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN FSP_SILICON_INIT_DONE_PPI *This, + OUT VOID **FspHobList + ) +{ + EFI_HOB_GUID_TYPE *GuidHob; + + GuidHob = GetFirstGuidHob (&gFspHobGuid); + if (GuidHob != NULL) { + *FspHobList = *(VOID **)GET_GUID_HOB_DATA(GuidHob); + return EFI_SUCCESS; + } else { + return EFI_NOT_FOUND; + } +} + +/** + This function is for FSP dispatch mode to perform post FSP-S process. + + @param[in] PeiServices Pointer to PEI Services Table. + @param[in] NotifyDesc Pointer to the descriptor for the Notification event that + caused this function to execute. + @param[in] Ppi Pointer to the PPI data associated with this function. + + @retval EFI_STATUS Status returned by PeiServicesInstallPpi () +**/ +EFI_STATUS +EFIAPI +FspsWrapperEndOfPeiNotify ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc, + IN VOID *Ppi + ) +{ + EFI_STATUS Status; + + // + // This step may include platform specific process in some boot loaders so + // aligning the same behavior between API and Dispatch modes. + // Note: In Dispatch mode no FspHobList so passing NULL to function and + // expecting function will handle it. + // + PostFspsHobProcess (NULL); + + // + // Install FspSiliconInitDonePpi so that any other driver can consume this info. + // + Status = PeiServicesInstallPpi (&mPeiFspSiliconInitDonePpi); + ASSERT_EFI_ERROR(Status); + + return Status; +} + +EFI_PEI_NOTIFY_DESCRIPTOR mFspsWrapperEndOfPeiNotifyDesc = { + (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiEndOfPeiSignalPpiGuid, + FspsWrapperEndOfPeiNotify +}; + +/** + This function is called after PEI core discover memory and finish migration. + + @param[in] PeiServices Pointer to PEI Services Table. + @param[in] NotifyDesc Pointer to the descriptor for the Notification event that + caused this function to execute. + @param[in] Ppi Pointer to the PPI data associated with this function. + + @retval EFI_STATUS Always return EFI_SUCCESS +**/ +EFI_STATUS +EFIAPI +PeiMemoryDiscoveredNotify ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc, + IN VOID *Ppi + ); + +EFI_PEI_NOTIFY_DESCRIPTOR mPeiMemoryDiscoveredNotifyDesc = { + (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiPeiMemoryDiscoveredPpiGuid, + PeiMemoryDiscoveredNotify +}; + +/** + This function is called after PEI core discover memory and finish migration. + + @param[in] PeiServices Pointer to PEI Services Table. + @param[in] NotifyDesc Pointer to the descriptor for the Notification event that + caused this function to execute. + @param[in] Ppi Pointer to the PPI data associated with this function. + + @retval EFI_STATUS Always return EFI_SUCCESS +**/ +EFI_STATUS +EFIAPI +PeiMemoryDiscoveredNotify ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc, + IN VOID *Ppi + ) +{ + FSP_INFO_HEADER *FspsHeaderPtr; + UINT64 TimeStampCounterStart; + EFI_STATUS Status; + VOID *FspHobListPtr; + EFI_HOB_GUID_TYPE *GuidHob; + FSPS_UPD_COMMON *FspsUpdDataPtr; + UINTN *SourceData; + + DEBUG ((DEBUG_INFO, "PeiMemoryDiscoveredNotify enter\n")); + FspsUpdDataPtr = NULL; + + FspsHeaderPtr = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32 (PcdFspsBaseAddress)); + DEBUG ((DEBUG_INFO, "FspsHeaderPtr - 0x%x\n", FspsHeaderPtr)); + if (FspsHeaderPtr == NULL) { + return EFI_DEVICE_ERROR; + } + + if (PcdGet32 (PcdFspsUpdDataAddress) == 0 && (FspsHeaderPtr->CfgRegionSize != 0) && (FspsHeaderPtr->CfgRegionOffset != 0)) { + // + // Copy default FSP-S UPD data from Flash + // + FspsUpdDataPtr = (FSPS_UPD_COMMON *)AllocateZeroPool ((UINTN)FspsHeaderPtr->CfgRegionSize); + ASSERT (FspsUpdDataPtr != NULL); + SourceData = (UINTN *)((UINTN)FspsHeaderPtr->ImageBase + (UINTN)FspsHeaderPtr->CfgRegionOffset); + CopyMem (FspsUpdDataPtr, SourceData, (UINTN)FspsHeaderPtr->CfgRegionSize); + } else { + FspsUpdDataPtr = (FSPS_UPD_COMMON *)PcdGet32 (PcdFspsUpdDataAddress); + ASSERT (FspsUpdDataPtr != NULL); + } + + UpdateFspsUpdData ((VOID *)FspsUpdDataPtr); + + TimeStampCounterStart = AsmReadTsc (); + PERF_START_EX(&gFspApiPerformanceGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_SILICON_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY); + Status = CallFspSiliconInit ((VOID *)FspsUpdDataPtr); + PERF_END_EX(&gFspApiPerformanceGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_SILICON_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT); + DEBUG ((DEBUG_INFO, "Total time spent executing FspSiliconInitApi: %d millisecond\n", DivU64x32 (GetTimeInNanoSecond (AsmReadTsc () - TimeStampCounterStart), 1000000))); + + // + // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED status + // + if ((Status >= FSP_STATUS_RESET_REQUIRED_COLD) && (Status <= FSP_STATUS_RESET_REQUIRED_8)) { + DEBUG((DEBUG_INFO, "FspSiliconInitApi requested reset 0x%x\n", Status)); + CallFspWrapperResetSystem ((UINT32)Status); + } + + if (EFI_ERROR(Status)) { + DEBUG ((DEBUG_ERROR, "ERROR - Failed to execute FspSiliconInitApi(), Status = %r\n", Status)); + } + DEBUG((DEBUG_INFO, "FspSiliconInit status: 0x%x\n", Status)); + ASSERT_EFI_ERROR (Status); + + Status = TestFspSiliconInitApiOutput ((VOID *)NULL); + if (RETURN_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "ERROR - TestFspSiliconInitApiOutput () fail, Status = %r\n", Status)); + } + + // + // Now FspHobList complete, process it + // + GuidHob = GetFirstGuidHob (&gFspHobGuid); + ASSERT (GuidHob != NULL); + FspHobListPtr = *(VOID **)GET_GUID_HOB_DATA (GuidHob); + DEBUG ((DEBUG_INFO, "FspHobListPtr - 0x%x\n", FspHobListPtr)); + PostFspsHobProcess (FspHobListPtr); + + // + // Install FspSiliconInitDonePpi so that any other driver can consume this info. + // + Status = PeiServicesInstallPpi (&mPeiFspSiliconInitDonePpi); + ASSERT_EFI_ERROR(Status); + + return Status; +} + +/** + Do FSP initialization in API mode. + + @retval EFI_STATUS Always return EFI_SUCCESS +**/ +EFI_STATUS +FspsWrapperInitApiMode ( + VOID + ) +{ + EFI_STATUS Status; + EFI_BOOT_MODE BootMode; + + // + // Register MemoryDiscovered Notify to run FspSiliconInit + // + Status = PeiServicesNotifyPpi (&mPeiMemoryDiscoveredNotifyDesc); + ASSERT_EFI_ERROR (Status); + + // + // Register EndOfPei Notify for S3 to run FSP NotifyPhase + // + PeiServicesGetBootMode (&BootMode); + if (BootMode == BOOT_ON_S3_RESUME) { + Status = PeiServicesNotifyPpi (&mS3EndOfPeiNotifyDesc); + ASSERT_EFI_ERROR (Status); + } + + return EFI_SUCCESS; +} + +/** + Do FSP initialization in Dispatch mode. + + @retval FSP initialization status. +**/ +EFI_STATUS +FspsWrapperInitDispatchMode ( + VOID + ) +{ + EFI_STATUS Status; + EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_PPI *MeasurementExcludedFvPpi; + EFI_PEI_PPI_DESCRIPTOR *MeasurementExcludedPpiList; + + MeasurementExcludedFvPpi = AllocatePool (sizeof(*MeasurementExcludedFvPpi)); + ASSERT(MeasurementExcludedFvPpi != NULL); + MeasurementExcludedFvPpi->Count = 1; + MeasurementExcludedFvPpi->Fv[0].FvBase = PcdGet32 (PcdFspsBaseAddress); + MeasurementExcludedFvPpi->Fv[0].FvLength = ((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) PcdGet32 (PcdFspsBaseAddress))->FvLength; + + MeasurementExcludedPpiList = AllocatePool (sizeof(*MeasurementExcludedPpiList)); + ASSERT(MeasurementExcludedPpiList != NULL); + MeasurementExcludedPpiList->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST; + MeasurementExcludedPpiList->Guid = &gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid; + MeasurementExcludedPpiList->Ppi = MeasurementExcludedFvPpi; + + Status = PeiServicesInstallPpi (MeasurementExcludedPpiList); + ASSERT_EFI_ERROR (Status); + + // + // FSP-S Wrapper running in Dispatch mode and reports FSP-S FV to PEI dispatcher. + // + PeiServicesInstallFvInfoPpi ( + NULL, + (VOID *)(UINTN) PcdGet32 (PcdFspsBaseAddress), + (UINT32)((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) PcdGet32 (PcdFspsBaseAddress))->FvLength, + NULL, + NULL + ); + // + // Register EndOfPei Nofity to run post FSP-S process. + // + Status = PeiServicesNotifyPpi (&mFspsWrapperEndOfPeiNotifyDesc); + ASSERT_EFI_ERROR (Status); + return Status; +} + +/** + This function is called after TCG installed PPI. + + @param[in] PeiServices Pointer to PEI Services Table. + @param[in] NotifyDesc Pointer to the descriptor for the Notification event that + caused this function to execute. + @param[in] Ppi Pointer to the PPI data associated with this function. + + @retval EFI_STATUS Always return EFI_SUCCESS +**/ +EFI_STATUS +EFIAPI +TcgPpiNotify ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc, + IN VOID *Ppi + ); + +EFI_PEI_NOTIFY_DESCRIPTOR mTcgPpiNotifyDesc = { + (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEdkiiTcgPpiGuid, + TcgPpiNotify +}; + +/** + This function is called after TCG installed PPI. + + @param[in] PeiServices Pointer to PEI Services Table. + @param[in] NotifyDesc Pointer to the descriptor for the Notification event that + caused this function to execute. + @param[in] Ppi Pointer to the PPI data associated with this function. + + @retval EFI_STATUS Always return EFI_SUCCESS +**/ +EFI_STATUS +EFIAPI +TcgPpiNotify ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc, + IN VOID *Ppi + ) +{ + UINT32 FspMeasureMask; + + DEBUG ((DEBUG_INFO, "TcgPpiNotify FSPS\n")); + + FspMeasureMask = PcdGet32 (PcdFspMeasurementConfig); + + if ((FspMeasureMask & FSP_MEASURE_FSPS) != 0) { + MeasureFspFirmwareBlob (0, "FSPS", PcdGet32(PcdFspsBaseAddress), + (UINT32)((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) PcdGet32 (PcdFspsBaseAddress))->FvLength); + } + + return EFI_SUCCESS; +} + +/** + This is the entrypoint of PEIM. + + @param[in] FileHandle Handle of the file being invoked. + @param[in] PeiServices Describes the list of possible PEI Services. + + @retval EFI_SUCCESS if it completed successfully. +**/ +EFI_STATUS +EFIAPI +FspsWrapperPeimEntryPoint ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + + DEBUG ((DEBUG_INFO, "FspsWrapperPeimEntryPoint\n")); + + Status = PeiServicesNotifyPpi (&mTcgPpiNotifyDesc); + ASSERT_EFI_ERROR (Status); + + if (PcdGet8 (PcdFspModeSelection) == 1) { + FspsWrapperInitApiMode (); + } else { + FspsWrapperInitDispatchMode (); + } + + return EFI_SUCCESS; +} diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.inf b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.inf new file mode 100644 index 00000000..933c1936 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.inf @@ -0,0 +1,80 @@ +## @file +# FSP-S wrapper PEI Module +# +# This PEIM initialize FSP. +# This will be invoked only once. It will call FspMemoryInit API, +# register TemporaryRamDonePpi to call TempRamExit API, and register MemoryDiscoveredPpi +# notify to call FspSiliconInit API. +# +# Copyright (c) 2014 - 2020, Intel Corporation. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010017 + BASE_NAME = FspsWrapperPeim + FILE_GUID = 0D244DF9-6CE3-4133-A1CF-53200AB663AC + VERSION_STRING = 1.0 + MODULE_TYPE = PEIM + ENTRY_POINT = FspsWrapperPeimEntryPoint + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 +# + +[LibraryClasses] + PeimEntryPoint + PeiServicesLib + PeiServicesTablePointerLib + BaseLib + BaseMemoryLib + TimerLib + DebugLib + HobLib + MemoryAllocationLib + FspWrapperPlatformLib + FspWrapperHobProcessLib + UefiCpuLib + PeCoffGetEntryPointLib + PeCoffExtraActionLib + PerformanceLib + FspWrapperApiLib + FspWrapperApiTestLib + FspMeasurementLib + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + SecurityPkg/SecurityPkg.dec + IntelFsp2Pkg/IntelFsp2Pkg.dec + IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec + +[Ppis] + gTopOfTemporaryRamPpiGuid ## PRODUCES + gFspSiliconInitDonePpiGuid ## PRODUCES + gEfiEndOfPeiSignalPpiGuid ## PRODUCES + gEfiTemporaryRamDonePpiGuid ## PRODUCES + gEfiPeiMemoryDiscoveredPpiGuid ## NOTIFY + gEdkiiTcgPpiGuid ## NOTIFY + gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid ## PRODUCES + +[Pcd] + gIntelFsp2WrapperTokenSpaceGuid.PcdFspsBaseAddress ## CONSUMES + gIntelFsp2WrapperTokenSpaceGuid.PcdFspsUpdDataAddress ## CONSUMES + gIntelFsp2WrapperTokenSpaceGuid.PcdFspModeSelection ## CONSUMES + gIntelFsp2WrapperTokenSpaceGuid.PcdFspMeasurementConfig ## CONSUMES + +[Guids] + gFspHobGuid ## CONSUMES ## HOB + gFspApiPerformanceGuid ## SOMETIMES_CONSUMES ## GUID + +[Sources] + FspsWrapperPeim.c + +[Depex] + gEfiPeiMemoryDiscoveredPpiGuid diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Include/Library/FspMeasurementLib.h b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Include/Library/FspMeasurementLib.h new file mode 100644 index 00000000..a96d9554 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Include/Library/FspMeasurementLib.h @@ -0,0 +1,39 @@ +/** @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 + +**/ + +#ifndef _FSP_MEASUREMENT_LIB_H_ +#define _FSP_MEASUREMENT_LIB_H_ + +#define FSP_MEASURE_FSP BIT0 +#define FSP_MEASURE_FSPT BIT1 +#define FSP_MEASURE_FSPM BIT2 +#define FSP_MEASURE_FSPS BIT3 +#define FSP_MEASURE_FSPUPD BIT31 + +/** + 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 + ); +#endif diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Include/Library/FspWrapperApiLib.h b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Include/Library/FspWrapperApiLib.h new file mode 100644 index 00000000..9a811c9a --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Include/Library/FspWrapperApiLib.h @@ -0,0 +1,81 @@ +/** @file + Provide FSP wrapper API related function. + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __FSP_WRAPPER_API_LIB_H__ +#define __FSP_WRAPPER_API_LIB_H__ + +#include <FspEas.h> + +/** + 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 + ); + +/** + 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 + ); + +/** + Call FSP API - FspMemoryInit. + + @param[in] FspmUpdDataPtr Pointer to the FSPM_UPD data structure. + @param[out] HobListPtr Pointer to receive the address of the HOB list. + + @return EFI status returned by FspMemoryInit API. +**/ +EFI_STATUS +EFIAPI +CallFspMemoryInit ( + IN VOID *FspmUpdDataPtr, + OUT VOID **HobListPtr + ); + +/** + 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 + ); + +/** + Call FSP API - FspSiliconInit. + + @param[in] FspsUpdDataPtr Pointer to the FSPS_UPD data structure. + + @return EFI status returned by FspSiliconInit API. +**/ +EFI_STATUS +EFIAPI +CallFspSiliconInit ( + IN VOID *FspsUpdDataPtr + ); + +#endif diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Include/Library/FspWrapperApiTestLib.h b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Include/Library/FspWrapperApiTestLib.h new file mode 100644 index 00000000..25d5aeba --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Include/Library/FspWrapperApiTestLib.h @@ -0,0 +1,55 @@ +/** @file + Provide FSP wrapper API test related function. + + Copyright (c) 2016, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __FSP_WRAPPER_API_TEST_LIB_H__ +#define __FSP_WRAPPER_API_TEST_LIB_H__ + +#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 + ); + +/** + 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 + ); + +/** + 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 + ); + +#endif diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Include/Library/FspWrapperHobProcessLib.h b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Include/Library/FspWrapperHobProcessLib.h new file mode 100644 index 00000000..34ad14e7 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Include/Library/FspWrapperHobProcessLib.h @@ -0,0 +1,38 @@ +/** @file + Provide FSP wrapper hob process related function. + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __FSP_WRAPPER_HOB_PROCESS_LIB_H__ +#define __FSP_WRAPPER_HOB_PROCESS_LIB_H__ + +/** + 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 + ); + +/** + 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 + ); + +#endif diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Include/Library/FspWrapperPlatformLib.h b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Include/Library/FspWrapperPlatformLib.h new file mode 100644 index 00000000..710cb92a --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Include/Library/FspWrapperPlatformLib.h @@ -0,0 +1,80 @@ +/** @file + Provide FSP wrapper platform related function. + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __FSP_WRAPPER_PLATFORM_LIB_H__ +#define __FSP_WRAPPER_PLATFORM_LIB_H__ + +/** + This function overrides the default configurations in the FSP-M UPD data region. + + @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 + ); + +/** + 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 + ); + +/** + 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 + ); + +#endif diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Include/Ppi/FspSiliconInitDone.h b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Include/Ppi/FspSiliconInitDone.h new file mode 100644 index 00000000..a7de0530 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Include/Ppi/FspSiliconInitDone.h @@ -0,0 +1,37 @@ +/** @file + Provides the services to return FSP hob list. + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _FSP_SILICON_INIT_DONE_H_ +#define _FSP_SILICON_INIT_DONE_H_ + +typedef struct _FSP_SILICON_INIT_DONE_PPI FSP_SILICON_INIT_DONE_PPI; + +/** + Return Hob list produced by FSP. + + @param[in] PeiServices The pointer to the PEI Services Table. + @param[in] This The pointer to this instance of this PPI. + @param[out] FspHobList The pointer to Hob list produced by FSP. + + @return EFI_SUCCESS FReturn Hob list produced by FSP successfully. +**/ +typedef +EFI_STATUS +(EFIAPI *FSP_SILICON_INIT_DONE_GET_FSP_HOB_LIST)( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN FSP_SILICON_INIT_DONE_PPI *This, + OUT VOID **FspHobList + ); + +struct _FSP_SILICON_INIT_DONE_PPI { + FSP_SILICON_INIT_DONE_GET_FSP_HOB_LIST GetFspHobList; +}; + +extern EFI_GUID gFspSiliconInitDonePpiGuid; + +#endif diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Include/Ppi/TopOfTemporaryRam.h b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Include/Ppi/TopOfTemporaryRam.h new file mode 100644 index 00000000..2c14bc39 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Include/Ppi/TopOfTemporaryRam.h @@ -0,0 +1,14 @@ +/** @file + Provides the pointer to top of temporary ram. + + Copyright (c) 2014, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _TOP_OF_TEMPORARY_RAM_H_ +#define _TOP_OF_TEMPORARY_RAM_H_ + +extern EFI_GUID gTopOfTemporaryRamPpiGuid; + +#endif diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec new file mode 100644 index 00000000..b0eaf0fb --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec @@ -0,0 +1,129 @@ +## @file +# Provides drivers and definitions to support fsp in EDKII bios. +# +# Copyright (c) 2014 - 2020, Intel Corporation. All rights reserved.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + DEC_SPECIFICATION = 0x00010005 + PACKAGE_NAME = IntelFsp2WrapperPkg + PACKAGE_GUID = FAFE06D4-7245-42D7-9FD2-E5D5E36AB0A0 + PACKAGE_VERSION = 0.1 + +[Includes] + Include + +[LibraryClasses] + ## @libraryclass Provide FSP API related function. + FspWrapperApiLib|Include/Library/FspWrapperApiLib.h + FspWrapperApiTestLib|Include/Library/FspWrapperApiTestLib.h + + ## @libraryclass Provide FSP hob process related function. + FspWrapperHobProcessLib|Include/Library/FspWrapperHobProcessLib.h + + ## @libraryclass Provide FSP platform related function. + FspWrapperPlatformLib|Include/Library/FspWrapperPlatformLib.h + + ## @libraryclass Provide FSP TPM measurement related function. + FspMeasurementLib|Include/Library/FspMeasurementLib.h +[Guids] + # + # GUID defined in package + # + gIntelFsp2WrapperTokenSpaceGuid = { 0xa34cf082, 0xf50, 0x4f0d, { 0x89, 0x8a, 0x3d, 0x39, 0x30, 0x2b, 0xc5, 0x1e } } + gFspApiPerformanceGuid = { 0xc9122295, 0x56ed, 0x4d4e, { 0x06, 0xa6, 0x50, 0x8d, 0x89, 0x4d, 0x3e, 0x40 } } + gFspHobGuid = { 0x6d86fb36, 0xba90, 0x472c, { 0xb5, 0x83, 0x3f, 0xbe, 0xd3, 0xfb, 0x20, 0x9a } } + +[Ppis] + gFspSiliconInitDonePpiGuid = { 0x4eb6e09c, 0xd256, 0x4e1e, { 0xb5, 0x0a, 0x87, 0x4b, 0xd2, 0x84, 0xb3, 0xde } } + gTopOfTemporaryRamPpiGuid = { 0x2f3962b2, 0x57c5, 0x44ec, { 0x9e, 0xfc, 0xa6, 0x9f, 0xd3, 0x02, 0x03, 0x2b } } + +[Protocols] + gAddPerfRecordProtocolGuid = { 0xc4a58d6d, 0x3677, 0x49cb, { 0xa0, 0x0a, 0x94, 0x70, 0x76, 0x5f, 0xb5, 0x5e } } + +################################################################################ +# +# PCD Declarations section - list of all PCDs Declared by this Package +# Only this package should be providing the +# declaration, other packages should not. +# +################################################################################ +[PcdsFixedAtBuild, PcdsPatchableInModule] + ## Provides the memory mapped base address of the BIOS CodeCache Flash Device. + gIntelFsp2WrapperTokenSpaceGuid.PcdFlashCodeCacheAddress|0xFFE00000|UINT32|0x10000001 + ## Provides the size of the BIOS Flash Device. + gIntelFsp2WrapperTokenSpaceGuid.PcdFlashCodeCacheSize|0x00200000|UINT32|0x10000002 + + ## Indicates the base address of the first Microcode Patch in the Microcode Region + gIntelFsp2WrapperTokenSpaceGuid.PcdCpuMicrocodePatchAddress|0x0|UINT64|0x10000005 + gIntelFsp2WrapperTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize|0x0|UINT64|0x10000006 + ## Indicates the offset of the Cpu Microcode. + gIntelFsp2WrapperTokenSpaceGuid.PcdFlashMicrocodeOffset|0x90|UINT32|0x10000007 + + ## Indicate the PEI memory size platform want to report + gIntelFsp2WrapperTokenSpaceGuid.PcdPeiMinMemSize|0x1800000|UINT32|0x40000004 + ## Indicate the PEI memory size platform want to report + gIntelFsp2WrapperTokenSpaceGuid.PcdPeiRecoveryMinMemSize|0x3000000|UINT32|0x40000005 + + ## This is the base address of FSP-T + gIntelFsp2WrapperTokenSpaceGuid.PcdFsptBaseAddress|0x00000000|UINT32|0x00000300 + + ## This PCD indicates if FSP APIs are skipped from FSP wrapper.<BR><BR> + # If a bit is set, that means this FSP API is skipped.<BR> + # If a bit is clear, that means this FSP API is NOT skipped.<BR> + # NOTE: Only NotifyPhase Post PCI enumeration (BIT16) is implemented.<BR> + # BIT[15:0] is for function:<BR> + # BIT0 - Skip TempRamInit<BR> + # BIT1 - Skip MemoryInit<BR> + # BIT2 - Skip TempRamExit<BR> + # BIT3 - Skip SiliconInit<BR> + # BIT4 - Skip NotifyPhase<BR> + # BIT[32:16] is for sub-function:<BR> + # BIT16 - Skip NotifyPhase (AfterPciEnumeration)<BR> + # BIT17 - Skip NotifyPhase (ReadyToBoot)<BR> + # BIT18 - Skip NotifyPhase (EndOfFirmware)<BR> + # Any undefined BITs are reserved for future use.<BR> + # @Prompt Skip FSP API from FSP wrapper. + gIntelFsp2WrapperTokenSpaceGuid.PcdSkipFspApi|0x00000000|UINT32|0x40000009 + + ## This PCD decides how Wrapper code utilizes FSP + # 0: DISPATCH mode (FSP Wrapper will load PeiCore from FSP without calling FSP API) + # 1: API mode (FSP Wrapper will call FSP API) + # + gIntelFsp2WrapperTokenSpaceGuid.PcdFspModeSelection|0x00000001|UINT8|0x4000000A + + ## This PCD decides how FSP is measured + # 1) The BootGuard ACM may already measured the FSP component, such as FSPT/FSPM. + # We need a flag (PCD) to indicate if there is need to do such FSP measurement or NOT. + # 2) The FSP binary includes FSP code and FSP UPD region. The UPD region is considered + # as configuration block, and it may be updated by OEM by design. + # This flag (PCD) is to indicate if we need isolate the the UPD region from the FSP code region. + # BIT0: Need measure FSP. (for FSP1.x) - reserved in FSP2. + # BIT1: Need measure FSPT. (for FSP 2.x) + # BIT2: Need measure FSPM. (for FSP 2.x) + # BIT3: Need measure FSPS. (for FSP 2.x) + # BIT4~30: reserved. + # BIT31: Need isolate UPD region measurement. + #0: measure FSP[T|M|S] as one binary in one record (PCR0). + #1: measure FSP UPD region in one record (PCR1), the FSP code without UPD in another record (PCR0). + # + gIntelFsp2WrapperTokenSpaceGuid.PcdFspMeasurementConfig|0x00000000|UINT32|0x4000000B + +[PcdsFixedAtBuild, PcdsPatchableInModule,PcdsDynamic,PcdsDynamicEx] + # + ## These are the base address of FSP-M/S + # + gIntelFsp2WrapperTokenSpaceGuid.PcdFspmBaseAddress|0x00000000|UINT32|0x00001000 + gIntelFsp2WrapperTokenSpaceGuid.PcdFspsBaseAddress|0x00000000|UINT32|0x00001001 + # + # To provide flexibility for platform to pre-allocate FSP UPD buffer + # + # The PCDs define the pre-allocated FSPM and FSPS UPD Data Buffer Address. + # 0x00000000 - Platform will not pre-allocate UPD buffer before FspWrapper module + # non-zero - Platform will pre-allocate UPD buffer and patch this value to + # buffer address before FspWrapper module executing. + # + gIntelFsp2WrapperTokenSpaceGuid.PcdFspmUpdDataAddress|0x00000000|UINT32|0x50000000 + gIntelFsp2WrapperTokenSpaceGuid.PcdFspsUpdDataAddress|0x00000000|UINT32|0x50000001 diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dsc b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dsc new file mode 100644 index 00000000..0c7f3554 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dsc @@ -0,0 +1,101 @@ +## @file +# Provides drivers and definitions to support fsp in EDKII bios. +# +# Copyright (c) 2014 - 2021, Intel Corporation. All rights reserved.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + PLATFORM_NAME = IntelFsp2WrapperPkg + PLATFORM_GUID = 34813E26-C930-427D-8993-80530549EADA + PLATFORM_VERSION = 0.1 + DSC_SPECIFICATION = 0x00010005 + OUTPUT_DIRECTORY = Build/IntelFsp2WrapperPkg + SUPPORTED_ARCHITECTURES = IA32|X64 + BUILD_TARGETS = DEBUG|RELEASE|NOOPT + SKUID_IDENTIFIER = DEFAULT + +!include MdePkg/MdeLibs.dsc.inc + +[LibraryClasses] + BaseLib|MdePkg/Library/BaseLib/BaseLib.inf + BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf + PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf + PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf + DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf + DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf + PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf + IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf + PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf + PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf + PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf + CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf + + PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf + SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf + ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf + TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf + + # MdeModulePkg + DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf + + # UefiCpuPkg + UefiCpuLib|UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf + LocalApicLib|UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.inf + + # FSP Wrapper Lib + FspWrapperApiLib|IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/BaseFspWrapperApiLib.inf + FspWrapperApiTestLib|IntelFsp2WrapperPkg/Library/BaseFspWrapperApiTestLibNull/BaseFspWrapperApiTestLibNull.inf + FspMeasurementLib|IntelFsp2WrapperPkg/Library/BaseFspMeasurementLib/BaseFspMeasurementLib.inf + + # FSP platform sample + FspWrapperPlatformLib|IntelFsp2WrapperPkg/Library/BaseFspWrapperPlatformLibSample/BaseFspWrapperPlatformLibSample.inf + PlatformSecLib|IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecFspWrapperPlatformSecLibSample.inf + FspWrapperHobProcessLib|IntelFsp2WrapperPkg/Library/PeiFspWrapperHobProcessLibSample/PeiFspWrapperHobProcessLibSample.inf + + Tpm2CommandLib|SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf + +[LibraryClasses.common.PEIM,LibraryClasses.common.PEI_CORE] + PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf + PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf + PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf + MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf + HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf + TpmMeasurementLib|SecurityPkg/Library/PeiTpmMeasurementLib/PeiTpmMeasurementLib.inf + TcgEventLogRecordLib|SecurityPkg/Library/TcgEventLogRecordLib/TcgEventLogRecordLib.inf + HashLib|SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterPei.inf + Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2DeviceLibDTpm.inf + +[LibraryClasses.common.DXE_DRIVER] + UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf + UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf + UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf + DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf + UefiLib|MdePkg/Library/UefiLib/UefiLib.inf + MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf + DevicePathLib|MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.inf + HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf + +[Components.Ia32] + IntelFsp2WrapperPkg/Library/BaseFspWrapperApiTestLibNull/BaseFspWrapperApiTestLibNull.inf + IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecFspWrapperPlatformSecLibSample.inf + IntelFsp2WrapperPkg/Library/PeiFspWrapperHobProcessLibSample/PeiFspWrapperHobProcessLibSample.inf + IntelFsp2WrapperPkg/Library/PeiFspWrapperApiTestLib/PeiFspWrapperApiTestLib.inf + IntelFsp2WrapperPkg/Library/BaseFspMeasurementLib/BaseFspMeasurementLib.inf + + IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.inf + IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.inf + +[Components.IA32, Components.X64] + IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/BaseFspWrapperApiLib.inf + IntelFsp2WrapperPkg/Library/BaseFspWrapperPlatformLibSample/BaseFspWrapperPlatformLibSample.inf + IntelFsp2WrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.inf + +[PcdsFixedAtBuild.common] + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x1f + gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80080046 + gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07 + +[BuildOptions] + *_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES 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 ; +} diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Readme.md b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Readme.md new file mode 100644 index 00000000..d42547a9 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/Readme.md @@ -0,0 +1,7 @@ +# IntelFsp2WrapperPkg + +This package provides the component to use an FSP binary. + +Source Repository: https://github.com/tianocore/edk2/tree/master/IntelFsp2WrapperPkg + +A whitepaper to describe the IntelFsp2WrapperPkg: https://firmware.intel.com/sites/default/files/A_Tour_Beyond_BIOS_Using_the_Intel_Firmware_Support_Package_with_the_EFI_Developer_Kit_II_%28FSP2.0%29.pdf |