Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add fspi wrapper peim #9406

Merged
merged 6 commits into from
Dec 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions IntelFsp2Pkg/Include/FspStatusCode.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
269 changes: 269 additions & 0 deletions IntelFsp2WrapperPkg/FspiWrapperPeim/FspiWrapperPeim.c
Original file line number Diff line number Diff line change
@@ -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.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/

#include <PiPei.h>
#include <FspEas.h>
#include <FspStatusCode.h>
#include <FspGlobalData.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/MemoryAllocationLib.h>
#include <Library/FspWrapperPlatformLib.h>
#include <Library/TimerLib.h>
#include <Library/PerformanceLib.h>
#include <Library/FspWrapperApiLib.h>
#include <Library/FspWrapperHobProcessLib.h>
#include <Library/FspWrapperApiTestLib.h>
#include <Library/FspMeasurementLib.h>
#include <Ppi/Tcg.h>
#include <Ppi/FirmwareVolumeInfoMeasurementExcluded.h>

/**
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;
}
70 changes: 70 additions & 0 deletions IntelFsp2WrapperPkg/FspiWrapperPeim/FspiWrapperPeim.inf
Original file line number Diff line number Diff line change
@@ -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.<BR>
#
# 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
1 change: 1 addition & 0 deletions IntelFsp2WrapperPkg/Include/Library/FspMeasurementLib.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

/**
Expand Down
13 changes: 13 additions & 0 deletions IntelFsp2WrapperPkg/Include/Library/FspWrapperApiLib.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
13 changes: 13 additions & 0 deletions IntelFsp2WrapperPkg/Include/Library/FspWrapperApiTestLib.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Loading
Loading