mirror of
https://github.com/acidanthera/audk.git
synced 2025-08-17 23:58:12 +02:00
Save FspHobList pointer to HOB right after FspMemoryInit exits so that FspHobList pointer is available when performing platform related reset in CallFspWrapperResetSystem(). Some platforms may consume FSP HOBs prior to performing platform related reset. Signed-off-by: Du Lin <du.lin@intel.com>
358 lines
12 KiB
C
358 lines
12 KiB
C
/** @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 - 2024, 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/FspWrapperMultiPhaseProcessLib.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>
|
|
#include <FspGlobalData.h>
|
|
#include <Library/FspCommonLib.h>
|
|
#include <Guid/MigratedFvInfo.h>
|
|
|
|
extern EFI_GUID gFspHobGuid;
|
|
|
|
/**
|
|
Get the FSP M UPD Data address
|
|
|
|
@return FSP-M UPD Data Address
|
|
**/
|
|
UINTN
|
|
GetFspmUpdDataAddress (
|
|
VOID
|
|
)
|
|
{
|
|
if (PcdGet64 (PcdFspmUpdDataAddress64) != 0) {
|
|
return (UINTN)PcdGet64 (PcdFspmUpdDataAddress64);
|
|
} else {
|
|
return (UINTN)PcdGet32 (PcdFspmUpdDataAddress);
|
|
}
|
|
}
|
|
|
|
/**
|
|
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;
|
|
VOID *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 ((GetFspmUpdDataAddress () == 0) && (FspmHeaderPtr->CfgRegionSize != 0) && (FspmHeaderPtr->CfgRegionOffset != 0)) {
|
|
//
|
|
// Copy default FSP-M UPD data from Flash
|
|
//
|
|
FspmUpdDataPtr = 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 = (VOID *)GetFspmUpdDataAddress ();
|
|
ASSERT (FspmUpdDataPtr != NULL);
|
|
}
|
|
|
|
DEBUG ((DEBUG_INFO, "UpdateFspmUpdData enter\n"));
|
|
UpdateFspmUpdData (FspmUpdDataPtr);
|
|
if (((FSPM_UPD_COMMON *)FspmUpdDataPtr)->FspmArchUpd.Revision >= 3) {
|
|
DEBUG ((DEBUG_INFO, " StackBase - 0x%lx\n", ((FSPM_UPD_COMMON_FSP24 *)FspmUpdDataPtr)->FspmArchUpd.StackBase));
|
|
DEBUG ((DEBUG_INFO, " StackSize - 0x%lx\n", ((FSPM_UPD_COMMON_FSP24 *)FspmUpdDataPtr)->FspmArchUpd.StackSize));
|
|
DEBUG ((DEBUG_INFO, " BootLoaderTolumSize - 0x%x\n", ((FSPM_UPD_COMMON_FSP24 *)FspmUpdDataPtr)->FspmArchUpd.BootLoaderTolumSize));
|
|
DEBUG ((DEBUG_INFO, " BootMode - 0x%x\n", ((FSPM_UPD_COMMON_FSP24 *)FspmUpdDataPtr)->FspmArchUpd.BootMode));
|
|
} else {
|
|
DEBUG ((DEBUG_INFO, " NvsBufferPtr - 0x%x\n", ((FSPM_UPD_COMMON *)FspmUpdDataPtr)->FspmArchUpd.NvsBufferPtr));
|
|
DEBUG ((DEBUG_INFO, " StackBase - 0x%x\n", ((FSPM_UPD_COMMON *)FspmUpdDataPtr)->FspmArchUpd.StackBase));
|
|
DEBUG ((DEBUG_INFO, " StackSize - 0x%x\n", ((FSPM_UPD_COMMON *)FspmUpdDataPtr)->FspmArchUpd.StackSize));
|
|
DEBUG ((DEBUG_INFO, " BootLoaderTolumSize - 0x%x\n", ((FSPM_UPD_COMMON *)FspmUpdDataPtr)->FspmArchUpd.BootLoaderTolumSize));
|
|
DEBUG ((DEBUG_INFO, " BootMode - 0x%x\n", ((FSPM_UPD_COMMON *)FspmUpdDataPtr)->FspmArchUpd.BootMode));
|
|
}
|
|
|
|
DEBUG ((DEBUG_INFO, " HobListPtr - 0x%x\n", &FspHobListPtr));
|
|
|
|
TimeStampCounterStart = AsmReadTsc ();
|
|
Status = CallFspMemoryInit (FspmUpdDataPtr, &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));
|
|
|
|
//
|
|
// 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 %r\n", Status));
|
|
CallFspWrapperResetSystem (Status);
|
|
}
|
|
|
|
if ((Status != FSP_STATUS_VARIABLE_REQUEST) && EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "ERROR - Failed to execute FspMemoryInitApi(), Status = %r\n", Status));
|
|
ASSERT_EFI_ERROR (Status);
|
|
}
|
|
|
|
DEBUG ((DEBUG_INFO, "FspMemoryInit status: %r\n", Status));
|
|
if (Status == FSP_STATUS_VARIABLE_REQUEST) {
|
|
//
|
|
// call to Variable request handler
|
|
//
|
|
FspWrapperVariableRequestHandler (&FspHobListPtr, FspMultiPhaseMemInitApiIndex);
|
|
}
|
|
|
|
//
|
|
// See if MultiPhase process is required or not
|
|
//
|
|
FspWrapperMultiPhaseHandler (&FspHobListPtr, FspMultiPhaseMemInitApiIndex); // FspM MultiPhase
|
|
|
|
//
|
|
// 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)));
|
|
|
|
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);
|
|
|
|
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);
|
|
if (MeasurementExcludedFvPpi == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
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);
|
|
if (MeasurementExcludedPpiList == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
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 (
|
|
&((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)PcdGet32 (PcdFspmBaseAddress))->FileSystemGuid,
|
|
(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;
|
|
EFI_PHYSICAL_ADDRESS FsptBaseAddress;
|
|
EFI_PHYSICAL_ADDRESS FspmBaseAddress;
|
|
EDKII_MIGRATED_FV_INFO *MigratedFvInfo;
|
|
EFI_PEI_HOB_POINTERS Hob;
|
|
|
|
DEBUG ((DEBUG_INFO, "TcgPpiNotify FSPM\n"));
|
|
|
|
FspMeasureMask = PcdGet32 (PcdFspMeasurementConfig);
|
|
FsptBaseAddress = (EFI_PHYSICAL_ADDRESS)PcdGet32 (PcdFsptBaseAddress);
|
|
FspmBaseAddress = (EFI_PHYSICAL_ADDRESS)PcdGet32 (PcdFspmBaseAddress);
|
|
Hob.Raw = GetFirstGuidHob (&gEdkiiMigratedFvInfoGuid);
|
|
while (Hob.Raw != NULL) {
|
|
MigratedFvInfo = GET_GUID_HOB_DATA (Hob);
|
|
if ((MigratedFvInfo->FvOrgBase == PcdGet32 (PcdFsptBaseAddress)) && (MigratedFvInfo->FvDataBase != 0)) {
|
|
//
|
|
// Found the migrated FspT raw data
|
|
//
|
|
FsptBaseAddress = MigratedFvInfo->FvDataBase;
|
|
}
|
|
|
|
if ((MigratedFvInfo->FvOrgBase == PcdGet32 (PcdFspmBaseAddress)) && (MigratedFvInfo->FvDataBase != 0)) {
|
|
FspmBaseAddress = MigratedFvInfo->FvDataBase;
|
|
}
|
|
|
|
Hob.Raw = GET_NEXT_HOB (Hob);
|
|
Hob.Raw = GetNextGuidHob (&gEdkiiMigratedFvInfoGuid, Hob.Raw);
|
|
}
|
|
|
|
if ((FspMeasureMask & FSP_MEASURE_FSPT) != 0) {
|
|
MeasureFspFirmwareBlob (
|
|
0,
|
|
"FSPT",
|
|
FsptBaseAddress,
|
|
(UINT32)((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)FsptBaseAddress)->FvLength
|
|
);
|
|
}
|
|
|
|
if ((FspMeasureMask & FSP_MEASURE_FSPM) != 0) {
|
|
MeasureFspFirmwareBlob (
|
|
0,
|
|
"FSPM",
|
|
FspmBaseAddress,
|
|
(UINT32)((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)FspmBaseAddress)->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;
|
|
}
|