diff --git a/IntelFsp2Pkg/Include/FspStatusCode.h b/IntelFsp2Pkg/Include/FspStatusCode.h index e294aa343565..c7afff5cf943 100644 --- a/IntelFsp2Pkg/Include/FspStatusCode.h +++ b/IntelFsp2Pkg/Include/FspStatusCode.h @@ -16,6 +16,7 @@ #define FSP_STATUS_CODE_MEMORY_INIT 0xD000 #define FSP_STATUS_CODE_TEMP_RAM_EXIT 0xB000 #define FSP_STATUS_CODE_SILICON_INIT 0x9000 +#define FSP_STATUS_CODE_FSPSMM_INIT 0x7000 #define FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION 0x6000 #define FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION 0x4000 #define FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION 0x2000 diff --git a/IntelFsp2WrapperPkg/FspiWrapperPeim/FspiWrapperPeim.c b/IntelFsp2WrapperPkg/FspiWrapperPeim/FspiWrapperPeim.c new file mode 100644 index 000000000000..211dd26060f7 --- /dev/null +++ b/IntelFsp2WrapperPkg/FspiWrapperPeim/FspiWrapperPeim.c @@ -0,0 +1,269 @@ +/** @file + This will be invoked only once. It will call FspSmmInit API, + to call MmIplPei to load MM Core and dispatch all Standalone + MM drivers. + + Copyright (c) 2024, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + Call FspSmmInit API. + + @return Status returned by FspSmmInit API. +**/ +EFI_STATUS +FspiWrapperInitApiMode ( + VOID + ) +{ + FSP_INFO_HEADER *FspiHeaderPtr; + EFI_STATUS Status; + UINT64 TimeStampCounterStart; + EFI_HOB_GUID_TYPE *GuidHob; + VOID *FspHobListPtr; + VOID *FspiUpdDataPtr; + UINTN *SourceData; + + DEBUG ((DEBUG_INFO, "PeiFspSmmInit enter\n")); + + FspHobListPtr = NULL; + FspiUpdDataPtr = NULL; + + FspiHeaderPtr = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32 (PcdFspiBaseAddress)); + DEBUG ((DEBUG_INFO, "FspiHeaderPtr - 0x%x\n", FspiHeaderPtr)); + if (FspiHeaderPtr == NULL) { + return EFI_DEVICE_ERROR; + } + + if ((PcdGet64 (PcdFspiUpdDataAddress) == 0) && (FspiHeaderPtr->CfgRegionSize != 0) && (FspiHeaderPtr->CfgRegionOffset != 0)) { + // + // Copy default FSP-I UPD data from Flash + // + FspiUpdDataPtr = AllocateZeroPool ((UINTN)FspiHeaderPtr->CfgRegionSize); + ASSERT (FspiUpdDataPtr != NULL); + SourceData = (UINTN *)((UINTN)FspiHeaderPtr->ImageBase + (UINTN)FspiHeaderPtr->CfgRegionOffset); + CopyMem (FspiUpdDataPtr, SourceData, (UINTN)FspiHeaderPtr->CfgRegionSize); + } else { + // + // External UPD is ready, get the buffer from PCD pointer. + // + FspiUpdDataPtr = (VOID *)(UINTN)PcdGet64 (PcdFspiUpdDataAddress); + ASSERT (FspiUpdDataPtr != NULL); + } + + DEBUG ((DEBUG_INFO, "UpdateFspiUpdData enter\n")); + UpdateFspiUpdData (FspiUpdDataPtr); + DEBUG ((DEBUG_INFO, " BootloaderSmmFvBaseAddress - 0x%lx\n", ((FSPI_UPD_COMMON *)FspiUpdDataPtr)->FspiArchUpd.BootloaderSmmFvBaseAddress)); + DEBUG ((DEBUG_INFO, " BootloaderSmmFvLength - 0x%lx\n", ((FSPI_UPD_COMMON *)FspiUpdDataPtr)->FspiArchUpd.BootloaderSmmFvLength)); + DEBUG ((DEBUG_INFO, " BootloaderSmmFvContextData - 0x%lx\n", ((FSPI_UPD_COMMON *)FspiUpdDataPtr)->FspiArchUpd.BootloaderSmmFvContextData)); + DEBUG ((DEBUG_INFO, " BootloaderSmmFvContextDataLength - 0x%lx\n", ((FSPI_UPD_COMMON *)FspiUpdDataPtr)->FspiArchUpd.BootloaderSmmFvContextDataLength)); + + // + // Get FspHobList + // + GuidHob = GetFirstGuidHob (&gFspHobGuid); + ASSERT (GuidHob != NULL); + FspHobListPtr = *(VOID **)GET_GUID_HOB_DATA (GuidHob); + DEBUG ((DEBUG_INFO, " HobListPtr - 0x%x\n", &FspHobListPtr)); + + TimeStampCounterStart = AsmReadTsc (); + Status = CallFspSmmInit (FspiUpdDataPtr); + + // + // 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, "FspSmmInitApi requested reset %r\n", Status)); + CallFspWrapperResetSystem (Status); + } + + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "ERROR - Failed to execute FspSmmInitApi(), Status = %r\n", Status)); + ASSERT_EFI_ERROR (Status); + } + + DEBUG ((DEBUG_INFO, "FspSmmInit status: %r\n", Status)); + // + // Create hobs after FspSmmInit. Hence passing the recorded timestamp here + // + PERF_START_EX (&gFspApiPerformanceGuid, "EventRec", NULL, TimeStampCounterStart, FSP_STATUS_CODE_FSPSMM_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY); + PERF_END_EX (&gFspApiPerformanceGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_FSPSMM_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT); + DEBUG ((DEBUG_INFO, "Total time spent executing FspSmmInitApi: %d millisecond\n", DivU64x32 (GetTimeInNanoSecond (AsmReadTsc () - TimeStampCounterStart), 1000000))); + + Status = TestFspSmmInitApiOutput (FspiUpdDataPtr); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "ERROR - TestFspSmmInitApiOutput () fail, Status = %r\n", Status)); + } + + DEBUG ((DEBUG_INFO, " FspHobListPtr (returned) - 0x%x\n", FspHobListPtr)); + ASSERT (FspHobListPtr != NULL); + + PostFspiHobProcess (FspHobListPtr); + + return Status; +} + +/** + Do FSP SMM initialization in Dispatch mode. + + @retval FSP SMM initialization status. +**/ +EFI_STATUS +EFIAPI +FspiWrapperInitDispatchMode ( + VOID + ) +{ + EFI_STATUS Status; + EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_PPI *MeasurementExcludedFvPpi; + EFI_PEI_PPI_DESCRIPTOR *MeasurementExcludedPpiList; + + MeasurementExcludedFvPpi = AllocatePool (sizeof (*MeasurementExcludedFvPpi)); + if (MeasurementExcludedFvPpi != NULL) { + MeasurementExcludedFvPpi->Count = 1; + MeasurementExcludedFvPpi->Fv[0].FvBase = PcdGet32 (PcdFspiBaseAddress); + MeasurementExcludedFvPpi->Fv[0].FvLength = ((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)PcdGet32 (PcdFspiBaseAddress))->FvLength; + } else { + ASSERT (MeasurementExcludedFvPpi != NULL); + } + + MeasurementExcludedPpiList = AllocatePool (sizeof (*MeasurementExcludedPpiList)); + if (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); + } else { + ASSERT (MeasurementExcludedPpiList != NULL); + } + + // + // FSP-I Wrapper running in Dispatch mode and reports FSP-I FV to PEI dispatcher. + // + PeiServicesInstallFvInfoPpi ( + &((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)PcdGet32 (PcdFspiBaseAddress))->FileSystemGuid, + (VOID *)(UINTN)PcdGet32 (PcdFspiBaseAddress), + (UINT32)((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)PcdGet32 (PcdFspiBaseAddress))->FvLength, + NULL, + NULL + ); + + return EFI_SUCCESS; +} + +/** + 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 FSPI\n")); + + FspMeasureMask = PcdGet32 (PcdFspMeasurementConfig); + + if ((FspMeasureMask & FSP_MEASURE_FSPI) != 0) { + MeasureFspFirmwareBlob ( + 0, + "FSPI", + PcdGet32 (PcdFspiBaseAddress), + (UINT32)((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)PcdGet32 (PcdFspiBaseAddress))->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 +FspiWrapperPeimEntryPoint ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + + DEBUG ((DEBUG_INFO, "FspiWrapperPeimEntryPoint\n")); + + Status = PeiServicesNotifyPpi (&mTcgPpiNotifyDesc); + ASSERT_EFI_ERROR (Status); + + if (PcdGet8 (PcdFspModeSelection) == 1) { + Status = FspiWrapperInitApiMode (); + } else { + Status = FspiWrapperInitDispatchMode (); + } + + return Status; +} diff --git a/IntelFsp2WrapperPkg/FspiWrapperPeim/FspiWrapperPeim.inf b/IntelFsp2WrapperPkg/FspiWrapperPeim/FspiWrapperPeim.inf new file mode 100644 index 000000000000..e03434cccacd --- /dev/null +++ b/IntelFsp2WrapperPkg/FspiWrapperPeim/FspiWrapperPeim.inf @@ -0,0 +1,70 @@ +## @file +# FSP-I wrapper PEI Module +# +# This PEIM initialize FSP. +# This will be invoked only once. It will call FspSmmInit API, +# to call MmIplPei to load MM Core and dispatch all Standalone +# MM drivers. +# +# Copyright (c) 2024, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010017 + BASE_NAME = FspiWrapperPeim + FILE_GUID = 64D6CA11-6F4C-4B79-B77F-37A281CF0FCC + VERSION_STRING = 1.0 + MODULE_TYPE = PEIM + ENTRY_POINT = FspiWrapperPeimEntryPoint + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[LibraryClasses] + PeimEntryPoint + PeiServicesLib + PeiServicesTablePointerLib + BaseMemoryLib + TimerLib + DebugLib + HobLib + MemoryAllocationLib + FspWrapperPlatformLib + FspWrapperHobProcessLib + PerformanceLib + FspWrapperApiLib + FspWrapperApiTestLib + FspMeasurementLib + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + IntelFsp2Pkg/IntelFsp2Pkg.dec + SecurityPkg/SecurityPkg.dec + IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec + +[Ppis] + gEdkiiTcgPpiGuid ## NOTIFY + gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid ## PRODUCES + +[Pcd] + gIntelFsp2WrapperTokenSpaceGuid.PcdFspiBaseAddress ## CONSUMES + gIntelFsp2WrapperTokenSpaceGuid.PcdFspModeSelection ## CONSUMES + gIntelFsp2WrapperTokenSpaceGuid.PcdFspiUpdDataAddress ## CONSUMES + gIntelFsp2WrapperTokenSpaceGuid.PcdFspMeasurementConfig ## CONSUMES + +[Guids] + gFspHobGuid ## CONSUMES ## HOB + gFspApiPerformanceGuid ## SOMETIMES_CONSUMES ## GUID + +[Sources] + FspiWrapperPeim.c + +[Depex] + gEfiPeiMemoryDiscoveredPpiGuid diff --git a/IntelFsp2WrapperPkg/Include/Library/FspMeasurementLib.h b/IntelFsp2WrapperPkg/Include/Library/FspMeasurementLib.h index db599cc1f835..7b303dab3ed6 100644 --- a/IntelFsp2WrapperPkg/Include/Library/FspMeasurementLib.h +++ b/IntelFsp2WrapperPkg/Include/Library/FspMeasurementLib.h @@ -13,6 +13,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #define FSP_MEASURE_FSPT BIT1 #define FSP_MEASURE_FSPM BIT2 #define FSP_MEASURE_FSPS BIT3 +#define FSP_MEASURE_FSPI BIT4 #define FSP_MEASURE_FSPUPD BIT31 /** diff --git a/IntelFsp2WrapperPkg/Include/Library/FspWrapperApiLib.h b/IntelFsp2WrapperPkg/Include/Library/FspWrapperApiLib.h index d38582d3e591..59df1d7cd7d7 100644 --- a/IntelFsp2WrapperPkg/Include/Library/FspWrapperApiLib.h +++ b/IntelFsp2WrapperPkg/Include/Library/FspWrapperApiLib.h @@ -78,4 +78,17 @@ CallFspSiliconInit ( IN VOID *FspsUpdDataPtr ); +/** + Call FSP API - FspSmmInit. + + @param[in] FspiUpdDataPtr Pointer to the FSPI_UPD data structure. + + @return EFI status returned by FspSmmInit API. +**/ +EFI_STATUS +EFIAPI +CallFspSmmInit ( + IN VOID *FspiUpdDataPtr + ); + #endif diff --git a/IntelFsp2WrapperPkg/Include/Library/FspWrapperApiTestLib.h b/IntelFsp2WrapperPkg/Include/Library/FspWrapperApiTestLib.h index 2ff2d0cbced3..26ad8f0dbd5b 100644 --- a/IntelFsp2WrapperPkg/Include/Library/FspWrapperApiTestLib.h +++ b/IntelFsp2WrapperPkg/Include/Library/FspWrapperApiTestLib.h @@ -52,4 +52,17 @@ TestFspSiliconInitApiOutput ( IN VOID *FspsUpdDataPtr ); +/** + Test the output of FSP API - FspSmmInit. + + @param[in] FspiUpdDataPtr Address pointer to the Smm Init parameters structure. + + @return test result on output of FspSmmInit API. +**/ +EFI_STATUS +EFIAPI +TestFspSmmInitApiOutput ( + IN VOID *FspiUpdDataPtr + ); + #endif diff --git a/IntelFsp2WrapperPkg/Include/Library/FspWrapperHobProcessLib.h b/IntelFsp2WrapperPkg/Include/Library/FspWrapperHobProcessLib.h index c91dbb5ea209..9ae9d67960a9 100644 --- a/IntelFsp2WrapperPkg/Include/Library/FspWrapperHobProcessLib.h +++ b/IntelFsp2WrapperPkg/Include/Library/FspWrapperHobProcessLib.h @@ -35,4 +35,17 @@ PostFspsHobProcess ( IN VOID *FspHobList ); +/** + Post FSP-I HOB process. + + @param[in] FspHobList Pointer to the HOB data structure produced by FSP. + + @return If platform process the FSP hob list successfully. +**/ +EFI_STATUS +EFIAPI +PostFspiHobProcess ( + IN VOID *FspHobList + ); + #endif diff --git a/IntelFsp2WrapperPkg/Include/Library/FspWrapperPlatformLib.h b/IntelFsp2WrapperPkg/Include/Library/FspWrapperPlatformLib.h index fe9f0d7408cd..8e3cd6430751 100644 --- a/IntelFsp2WrapperPkg/Include/Library/FspWrapperPlatformLib.h +++ b/IntelFsp2WrapperPkg/Include/Library/FspWrapperPlatformLib.h @@ -77,4 +77,16 @@ CallFspWrapperResetSystem ( IN EFI_STATUS FspStatusResetType ); +/** + This function overrides the default configurations in the FSP-I UPD data region. + + @param[in,out] FspUpdRgnPtr A pointer to the UPD data region data structure. + +**/ +VOID +EFIAPI +UpdateFspiUpdData ( + IN OUT VOID *FspUpdRgnPtr + ); + #endif diff --git a/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec b/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec index 6865ffaf1373..2a3b270777bf 100644 --- a/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec +++ b/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec @@ -98,10 +98,11 @@ gIntelFsp2WrapperTokenSpaceGuid.PcdFspModeSelection|0x00000001|UINT8|0x4000000A # - ## These are the base address of FSP-M/S + ## These are the base address of FSP-M/S/I # gIntelFsp2WrapperTokenSpaceGuid.PcdFspmBaseAddress|0x00000000|UINT32|0x00001000 gIntelFsp2WrapperTokenSpaceGuid.PcdFspsBaseAddress|0x00000000|UINT32|0x00001001 + gIntelFsp2WrapperTokenSpaceGuid.PcdFspiBaseAddress|0x00000000|UINT32|0x00001002 # # To provide flexibility for platform to pre-allocate FSP UPD buffer # @@ -137,3 +138,12 @@ #1: measure FSP UPD region in one record (PCR1), the FSP code without UPD in another record (PCR0). # gIntelFsp2WrapperTokenSpaceGuid.PcdFspMeasurementConfig|0x00000000|UINT32|0x50000004 + # + # To provide flexibility for platform to pre-allocate FSP UPD buffer + # + # The PCDs define the pre-allocated FSPI 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.PcdFspiUpdDataAddress|0x00000000|UINT64|0x50000005 diff --git a/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dsc b/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dsc index fe621244a61b..f51e1c89f622 100644 --- a/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dsc +++ b/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dsc @@ -78,7 +78,7 @@ DevicePathLib|MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.inf HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf -[Components.Ia32] +[Components.Ia32, Components.X64] IntelFsp2WrapperPkg/Library/BaseFspWrapperApiTestLibNull/BaseFspWrapperApiTestLibNull.inf IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecFspWrapperPlatformSecLibSample.inf IntelFsp2WrapperPkg/Library/PeiFspWrapperHobProcessLibSample/PeiFspWrapperHobProcessLibSample.inf @@ -87,6 +87,7 @@ IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.inf IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.inf + IntelFsp2WrapperPkg/FspiWrapperPeim/FspiWrapperPeim.inf [Components.IA32, Components.X64] IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/BaseFspWrapperApiLib.inf diff --git a/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/BaseFspWrapperApiLib.inf b/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/BaseFspWrapperApiLib.inf index 1e348b539fe7..14760df0014a 100644 --- a/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/BaseFspWrapperApiLib.inf +++ b/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/BaseFspWrapperApiLib.inf @@ -63,3 +63,4 @@ [Pcd] gIntelFsp2WrapperTokenSpaceGuid.PcdFspmBaseAddress ## CONSUMES gIntelFsp2WrapperTokenSpaceGuid.PcdFspsBaseAddress ## CONSUMES + gIntelFsp2WrapperTokenSpaceGuid.PcdFspiBaseAddress ## CONSUMES diff --git a/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/FspWrapperApiLib.c b/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/FspWrapperApiLib.c index 2e82a0c1b59a..4d4cc8b5be62 100644 --- a/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/FspWrapperApiLib.c +++ b/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/FspWrapperApiLib.c @@ -230,3 +230,39 @@ CallFspSiliconInit ( return Status; } + +/** + Call FSP API - FspSmmInit. + + @param[in] FspiUpdDataPtr Address pointer to the Smm Init parameters structure. + + @return EFI status returned by FspSmmInit API. +**/ +EFI_STATUS +EFIAPI +CallFspSmmInit ( + IN VOID *FspiUpdDataPtr + ) +{ + FSP_INFO_HEADER *FspHeader; + FSP_SMM_INIT FspSmmInitApi; + EFI_STATUS Status; + BOOLEAN InterruptState; + + FspHeader = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32 (PcdFspiBaseAddress)); + if (FspHeader == NULL) { + return EFI_DEVICE_ERROR; + } + + FspSmmInitApi = (FSP_SMM_INIT)((UINTN)FspHeader->ImageBase + FspHeader->FspSmmInitEntryOffset); + InterruptState = SaveAndDisableInterrupts (); + if ((FspHeader->ImageAttribute & IMAGE_ATTRIBUTE_64BIT_MODE_SUPPORT) == FSP_IA32) { + Status = Execute32BitCode ((UINTN)FspSmmInitApi, (UINTN)FspiUpdDataPtr, (UINTN)NULL); + } else { + Status = Execute64BitCode ((UINTN)FspSmmInitApi, (UINTN)FspiUpdDataPtr, (UINTN)NULL); + } + + SetInterruptState (InterruptState); + + return Status; +} diff --git a/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiTestLibNull/FspWrapperApiTestNull.c b/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiTestLibNull/FspWrapperApiTestNull.c index 4ac5d3d738fa..beaf56bd0902 100644 --- a/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiTestLibNull/FspWrapperApiTestNull.c +++ b/IntelFsp2WrapperPkg/Library/BaseFspWrapperApiTestLibNull/FspWrapperApiTestNull.c @@ -57,3 +57,19 @@ TestFspSiliconInitApiOutput ( { return RETURN_UNSUPPORTED; } + +/** + Test the output of FSP API - FspSmmInit. + + @param[in] FspiUpdDataPtr Address pointer to the Smm Init parameters structure. + + @return test result on output of FspSmmInit API. +**/ +EFI_STATUS +EFIAPI +TestFspSmmInitApiOutput ( + IN VOID *FspiUpdDataPtr + ) +{ + return RETURN_SUCCESS; +} diff --git a/IntelFsp2WrapperPkg/Library/BaseFspWrapperPlatformLibSample/FspWrapperPlatformLibSample.c b/IntelFsp2WrapperPkg/Library/BaseFspWrapperPlatformLibSample/FspWrapperPlatformLibSample.c index 00b4799fb493..6e0e8942ef25 100644 --- a/IntelFsp2WrapperPkg/Library/BaseFspWrapperPlatformLibSample/FspWrapperPlatformLibSample.c +++ b/IntelFsp2WrapperPkg/Library/BaseFspWrapperPlatformLibSample/FspWrapperPlatformLibSample.c @@ -95,3 +95,17 @@ CallFspWrapperResetSystem ( CpuDeadLoop (); } + +/** + This function overrides the default configurations in the FSP-I UPD data region. + + @param[in,out] FspUpdRgnPtr A pointer to the UPD data region data structure. + +**/ +VOID +EFIAPI +UpdateFspiUpdData ( + IN OUT VOID *FspUpdRgnPtr + ) +{ +} diff --git a/IntelFsp2WrapperPkg/Library/PeiFspWrapperApiTestLib/FspWrapperApiTest.c b/IntelFsp2WrapperPkg/Library/PeiFspWrapperApiTestLib/FspWrapperApiTest.c index 0b48677b77a1..24722ea2875f 100644 --- a/IntelFsp2WrapperPkg/Library/PeiFspWrapperApiTestLib/FspWrapperApiTest.c +++ b/IntelFsp2WrapperPkg/Library/PeiFspWrapperApiTestLib/FspWrapperApiTest.c @@ -83,3 +83,19 @@ TestFspSiliconInitApiOutput ( { return RETURN_SUCCESS; } + +/** + Test the output of FSP API - FspSmmInit. + + @param[in] FspiUpdDataPtr Address pointer to the Smm Init parameters structure. + + @return test result on output of FspSmmInit API. +**/ +EFI_STATUS +EFIAPI +TestFspSmmInitApiOutput ( + IN VOID *FspiUpdDataPtr + ) +{ + return RETURN_SUCCESS; +} diff --git a/IntelFsp2WrapperPkg/Library/PeiFspWrapperHobProcessLibSample/FspWrapperHobProcessLibSample.c b/IntelFsp2WrapperPkg/Library/PeiFspWrapperHobProcessLibSample/FspWrapperHobProcessLibSample.c index 84360ac6e3a9..c11df5894c02 100644 --- a/IntelFsp2WrapperPkg/Library/PeiFspWrapperHobProcessLibSample/FspWrapperHobProcessLibSample.c +++ b/IntelFsp2WrapperPkg/Library/PeiFspWrapperHobProcessLibSample/FspWrapperHobProcessLibSample.c @@ -400,3 +400,19 @@ PostFspsHobProcess ( return EFI_SUCCESS; } + +/** + Post FSP-I HOB process. + + @param[in] FspHobList Pointer to the HOB data structure produced by FSP. + + @return If platform process the FSP hob list successfully. +**/ +EFI_STATUS +EFIAPI +PostFspiHobProcess ( + IN VOID *FspHobList + ) +{ + return EFI_SUCCESS; +} diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/MmFoundationHob.c b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/MmFoundationHob.c index b2611f2b4961..27103a456420 100644 --- a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/MmFoundationHob.c +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/MmFoundationHob.c @@ -803,6 +803,49 @@ GetRemainingHobSize ( } } +/** + Check if FV HOB was created. + + Check if FV HOB was created on HOB list, + if yes, skip building MM Core FV HOB, + if No, continue to build MM Core FV HOB + + @param[in] HobList HOB list. + @param[in] HobSize HOB size. + + @retval TRUE Skip building MM Core FV HOB. + FALSE Continue to build MM Core FV HOB. +**/ +BOOLEAN +IsFvHobExist ( + IN UINT8 *HobList, + IN UINTN HobSize + ) +{ + EFI_PEI_HOB_POINTERS Hob; + UINTN HobLength; + + if ((HobList == NULL) || (HobSize == 0)) { + return FALSE; + } + + Hob.Raw = (UINT8 *)HobList; + HobLength = GET_HOB_LENGTH (Hob); + // + // Parse the HOB list until end of list or matching type is found. + // + while (HobLength <= HobSize) { + if (Hob.Header->HobType == EFI_HOB_TYPE_FV) { + return TRUE; + } + + Hob.Raw = GET_NEXT_HOB (Hob); + HobLength += GET_HOB_LENGTH (Hob); + } + + return FALSE; +} + /** Create the MM foundation specific HOB list which StandaloneMm Core needed. @@ -892,11 +935,16 @@ CreateMmFoundationHobList ( UsedSize += HobLength; // - // BFV address for StandaloneMm Core + // Skip to report FV that contains MmCore when Platform reports FV // - HobLength = GetRemainingHobSize (*FoundationHobSize, UsedSize); - MmIplBuildFvHob (FoundationHobList + UsedSize, &HobLength, MmFvBase, MmFvSize); - UsedSize += HobLength; + if (!IsFvHobExist (PlatformHobList, PlatformHobSize)) { + // + // BFV address for StandaloneMm Core + // + HobLength = GetRemainingHobSize (*FoundationHobSize, UsedSize); + MmIplBuildFvHob (FoundationHobList + UsedSize, &HobLength, MmFvBase, MmFvSize); + UsedSize += HobLength; + } // // Build MM ACPI S3 Enable HOB diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c index 1a01d7a465c5..d8112b0fef42 100644 --- a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c @@ -147,12 +147,47 @@ LocateMmCoreFv ( OUT VOID **MmCoreImageAddress ) { - EFI_STATUS Status; - UINTN FvIndex; - EFI_PEI_FV_HANDLE VolumeHandle; - EFI_PEI_FILE_HANDLE FileHandle; - EFI_PE32_SECTION *SectionData; - EFI_FV_INFO VolumeInfo; + EFI_STATUS Status; + UINTN FvIndex; + EFI_PEI_FV_HANDLE VolumeHandle; + EFI_PEI_FILE_HANDLE FileHandle; + EFI_PE32_SECTION *SectionData; + EFI_FV_INFO VolumeInfo; + MM_CORE_FV_LOCATION_PPI *MmCoreFvLocation; + + // + // The producer of the MmCoreFvLocation PPI is responsible for ensuring + // that it reports the correct Firmware Volume (FV) containing the MmCore. + // If the gMmCoreFvLocationPpiGuid is not found, the system will search + // all Firmware Volumes (FVs) to locate the FV that contains the MM Core. + // + Status = PeiServicesLocatePpi (&gMmCoreFvLocationPpiGuid, 0, NULL, (VOID **)&MmCoreFvLocation); + if (Status == EFI_SUCCESS) { + *MmFvBase = MmCoreFvLocation->Address; + *MmFvSize = MmCoreFvLocation->Size; + FileHandle = NULL; + Status = PeiServicesFfsFindNextFile (EFI_FV_FILETYPE_MM_CORE_STANDALONE, (VOID *)(UINTN)MmCoreFvLocation->Address, &FileHandle); + ASSERT_EFI_ERROR (Status); + if (Status == EFI_SUCCESS) { + ASSERT (FileHandle != NULL); + if (FileHandle != NULL) { + CopyGuid (MmCoreFileName, &((EFI_FFS_FILE_HEADER *)FileHandle)->Name); + // + // Search Section + // + Status = PeiServicesFfsFindSectionData (EFI_SECTION_PE32, FileHandle, MmCoreImageAddress); + ASSERT_EFI_ERROR (Status); + + // + // Get MM Core section data. + // + SectionData = (EFI_PE32_SECTION *)((UINT8 *)*MmCoreImageAddress - sizeof (EFI_PE32_SECTION)); + ASSERT (SectionData->Type == EFI_SECTION_PE32); + } + } + + return EFI_SUCCESS; + } // // Search all FV diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h index 9301b8f3f5c4..e385c7768dd5 100644 --- a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h @@ -23,6 +23,7 @@ #include #include #include +#include #include #include diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf index dfc181218ed0..f07f26ee4144 100644 --- a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf @@ -61,6 +61,7 @@ gEfiPeiMmControlPpiGuid gEfiPeiMmCommunicationPpiGuid gEfiEndOfPeiSignalPpiGuid + gMmCoreFvLocationPpiGuid [Protocols] gEfiMmEndOfPeiProtocol diff --git a/StandaloneMmPkg/Include/Ppi/MmCoreFvLocationPpi.h b/StandaloneMmPkg/Include/Ppi/MmCoreFvLocationPpi.h new file mode 100644 index 000000000000..5769ac421211 --- /dev/null +++ b/StandaloneMmPkg/Include/Ppi/MmCoreFvLocationPpi.h @@ -0,0 +1,34 @@ +/** @file + MM Core FV location PPI header file. + + MM Core FV location PPI is used by StandaloneMm IPL to find MM Core. + + Copyright (c) 2024, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef MM_CORE_FV_LOCATION_PPI_H_ +#define MM_CORE_FV_LOCATION_PPI_H_ + +#pragma pack(1) + +/// +/// Global ID for the MM_CORE_FV_LOCATION_PPI. +/// +#define MM_CORE_FV_LOCATION_GUID \ + { \ + 0x47a00618, 0x237a, 0x4386, { 0x8f, 0xc5, 0x2a, 0x86, 0xd8, 0xac, 0x41, 0x05 } \ + } + +typedef struct { + EFI_PHYSICAL_ADDRESS Address; + UINT64 Size; +} MM_CORE_FV_LOCATION_PPI; + +extern EFI_GUID gMmCoreFvLocationPpiGuid; + +#pragma pack() + +#endif diff --git a/StandaloneMmPkg/StandaloneMmPkg.dec b/StandaloneMmPkg/StandaloneMmPkg.dec index 5ac57c1013c5..dc2313ea1218 100644 --- a/StandaloneMmPkg/StandaloneMmPkg.dec +++ b/StandaloneMmPkg/StandaloneMmPkg.dec @@ -51,6 +51,9 @@ gEventMmDispatchGuid = { 0x7e6efffa, 0x69b4, 0x4c1b, { 0xa4, 0xc7, 0xaf, 0xf9, 0xc9, 0x24, 0x4f, 0xee }} +[Ppis] + gMmCoreFvLocationPpiGuid = { 0x47a00618, 0x237a, 0x4386, { 0x8f, 0xc5, 0x2a, 0x86, 0xd8, 0xac, 0x41, 0x05 }} + [PcdsFixedAtBuild, PcdsPatchableInModule] ## Maximum permitted encapsulation levels of sections in a firmware volume, # in the MM phase. Minimum value is 1. Sections nested more deeply are rejected. diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c index 4862cf075fed..f28da7e0fbc0 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c @@ -749,6 +749,7 @@ InitSmmProfileInternal ( UINTN MsrDsAreaSizePerCpu; UINT64 SmmProfileSize; + Status = EFI_SUCCESS; mPFEntryCount = (UINTN *)AllocateZeroPool (sizeof (UINTN) * mMaxNumberOfCpus); ASSERT (mPFEntryCount != NULL); mLastPFEntryValue = (UINT64 (*)[MAX_PF_ENTRY_COUNT])AllocateZeroPool ( @@ -840,12 +841,14 @@ InitSmmProfileInternal ( // // Start SMM profile when SmmReadyToLock protocol is installed. // - Status = gMmst->MmRegisterProtocolNotify ( - &gEfiSmmReadyToLockProtocolGuid, - InitSmmProfileCallBack, - &Registration - ); - ASSERT_EFI_ERROR (Status); + if (!mIsStandaloneMm) { + Status = gMmst->MmRegisterProtocolNotify ( + &gEfiSmmReadyToLockProtocolGuid, + InitSmmProfileCallBack, + &Registration + ); + ASSERT_EFI_ERROR (Status); + } return; }