diff --git a/IntelFsp2WrapperPkg/FspiWrapperPeim/FspiWrapperPeim.c b/IntelFsp2WrapperPkg/FspiWrapperPeim/FspiWrapperPeim.c index 211dd26060..09d6d878f7 100644 --- a/IntelFsp2WrapperPkg/FspiWrapperPeim/FspiWrapperPeim.c +++ b/IntelFsp2WrapperPkg/FspiWrapperPeim/FspiWrapperPeim.c @@ -29,6 +29,104 @@ #include #include #include +#include +#include + +/** + Rebase a PE32/TE Image from an FFS file. + + @param FileHeader Pointer to the FFS file header. + + @return Status of the rebase operation. +**/ +EFI_STATUS +RebasePeTeFromFfs ( + EFI_FFS_FILE_HEADER *FileHeader + ) +{ + EFI_STATUS Status; + VOID *ImageBase; + PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; + UINTN ImageSize; + + Status = FfsFindSectionData (EFI_SECTION_PE32, FileHeader, &ImageBase, &ImageSize); + if (EFI_ERROR (Status)) { + Status = FfsFindSectionData (EFI_SECTION_TE, FileHeader, &ImageBase, &ImageSize); + } + + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + ZeroMem (&ImageContext, sizeof (ImageContext)); + ImageContext.Handle = ImageBase; + ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory; + + Status = PeCoffLoaderGetImageInfo (&ImageContext); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)ImageBase; + Status = PeCoffLoaderRelocateImage (&ImageContext); + ASSERT_EFI_ERROR (Status); + + return Status; +} + +/** + Rebase Fsp Fv. + Only SEC and PEI Core FFS files need to be rebased. Other PEIMs will + be rebased by PEI Core when dispatching. + FSP FV must contain SEC FFS and may contains PEI Core FFS files. + + @param PcdFspFvBaseAddress Fsp Fv base address. + + @return Status of the rebase result. +**/ +EFI_STATUS +RebaseFspFv ( + UINT64 PcdFspFvBaseAddress + ) +{ + EFI_STATUS Status; + EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; + EFI_FFS_FILE_HEADER *FileHeader; + + FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)PcdFspFvBaseAddress; + + // + // Find and rebase SEC FFS file + // + FileHeader = NULL; + Status = FfsFindNextFile (EFI_FV_FILETYPE_SECURITY_CORE, FwVolHeader, &FileHeader); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + Status = RebasePeTeFromFfs (FileHeader); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + // + // Find and rebase PEI Core FFS file + // + FileHeader = NULL; + Status = FfsFindNextFile (EFI_FV_FILETYPE_PEI_CORE, FwVolHeader, &FileHeader); + if (!EFI_ERROR (Status)) { + Status = RebasePeTeFromFfs (FileHeader); + ASSERT_EFI_ERROR (Status); + } else { + return EFI_SUCCESS; + } + + return Status; +} /** Call FspSmmInit API. @@ -59,6 +157,13 @@ FspiWrapperInitApiMode ( return EFI_DEVICE_ERROR; } + if (FspiHeaderPtr->ImageBase != PcdGet32 (PcdFspiBaseAddress)) { + FspiHeaderPtr->ImageBase = PcdGet32 (PcdFspiBaseAddress); + Status = RebaseFspFv (PcdGet32 (PcdFspiBaseAddress)); + ASSERT_EFI_ERROR (Status); + DEBUG ((DEBUG_INFO, "FSP-I Rebase completed.\n")); + } + if ((PcdGet64 (PcdFspiUpdDataAddress) == 0) && (FspiHeaderPtr->CfgRegionSize != 0) && (FspiHeaderPtr->CfgRegionOffset != 0)) { // // Copy default FSP-I UPD data from Flash diff --git a/IntelFsp2WrapperPkg/FspiWrapperPeim/FspiWrapperPeim.inf b/IntelFsp2WrapperPkg/FspiWrapperPeim/FspiWrapperPeim.inf index e03434ccca..d23e5e0c41 100644 --- a/IntelFsp2WrapperPkg/FspiWrapperPeim/FspiWrapperPeim.inf +++ b/IntelFsp2WrapperPkg/FspiWrapperPeim/FspiWrapperPeim.inf @@ -41,6 +41,8 @@ FspWrapperApiLib FspWrapperApiTestLib FspMeasurementLib + PeCoffLib + FvLib [Packages] MdePkg/MdePkg.dec diff --git a/IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.c b/IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.c index 62b5e45348..04b7c75e6c 100644 --- a/IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.c +++ b/IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.c @@ -38,6 +38,8 @@ #include #include #include +#include +#include extern EFI_PEI_NOTIFY_DESCRIPTOR mS3EndOfPeiNotifyDesc; extern EFI_GUID gFspHobGuid; @@ -267,6 +269,102 @@ EFI_PEI_NOTIFY_DESCRIPTOR mPeiMemoryDiscoveredNotifyDesc = { PeiMemoryDiscoveredNotify }; +/** + Rebase a PE32/TE Image from an FFS file. + + @param FileHeader Pointer to the FFS file header. + + @return Status of the rebase operation. +**/ +EFI_STATUS +RebasePeTeFromFfs ( + EFI_FFS_FILE_HEADER *FileHeader + ) +{ + EFI_STATUS Status; + VOID *ImageBase; + PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; + UINTN ImageSize; + + Status = FfsFindSectionData (EFI_SECTION_PE32, FileHeader, &ImageBase, &ImageSize); + if (EFI_ERROR (Status)) { + Status = FfsFindSectionData (EFI_SECTION_TE, FileHeader, &ImageBase, &ImageSize); + } + + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + ZeroMem (&ImageContext, sizeof (ImageContext)); + ImageContext.Handle = ImageBase; + ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory; + + Status = PeCoffLoaderGetImageInfo (&ImageContext); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)ImageBase; + Status = PeCoffLoaderRelocateImage (&ImageContext); + ASSERT_EFI_ERROR (Status); + + return Status; +} + +/** + Rebase Fsp Fv. + Only SEC and PEI Core FFS files need to be rebased. Other PEIMs will + be rebased by PEI Core when dispatching. + FSP FV must contain SEC FFS and may contains PEI Core FFS files. + + @param PcdFspFvBaseAddress Fsp Fv base address. + + @return Status of the rebase result. +**/ +EFI_STATUS +RebaseFspFv ( + UINT64 PcdFspFvBaseAddress + ) +{ + EFI_STATUS Status; + EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; + EFI_FFS_FILE_HEADER *FileHeader; + + FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)PcdFspFvBaseAddress; + + // + // Find and rebase SEC FFS file + // + FileHeader = NULL; + Status = FfsFindNextFile (EFI_FV_FILETYPE_SECURITY_CORE, FwVolHeader, &FileHeader); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + Status = RebasePeTeFromFfs (FileHeader); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + // + // Find and rebase PEI Core FFS file + // + FileHeader = NULL; + Status = FfsFindNextFile (EFI_FV_FILETYPE_PEI_CORE, FwVolHeader, &FileHeader); + if (!EFI_ERROR (Status)) { + Status = RebasePeTeFromFfs (FileHeader); + ASSERT_EFI_ERROR (Status); + } else { + return EFI_SUCCESS; + } + + return Status; +} + /** This function is called after PEI core discover memory and finish migration. @@ -302,6 +400,13 @@ PeiMemoryDiscoveredNotify ( return EFI_DEVICE_ERROR; } + if (FspsHeaderPtr->ImageBase != PcdGet32 (PcdFspsBaseAddress)) { + FspsHeaderPtr->ImageBase = PcdGet32 (PcdFspsBaseAddress); + Status = RebaseFspFv (PcdGet32 (PcdFspsBaseAddress)); + ASSERT_EFI_ERROR (Status); + DEBUG ((DEBUG_INFO, "FSP-S Rebase completed.\n")); + } + if ((GetFspsUpdDataAddress () == 0) && (FspsHeaderPtr->CfgRegionSize != 0) && (FspsHeaderPtr->CfgRegionOffset != 0)) { // // Copy default FSP-S UPD data from Flash diff --git a/IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.inf b/IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.inf index a7b28e56b5..fd153e8dab 100644 --- a/IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.inf +++ b/IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.inf @@ -46,6 +46,8 @@ FspWrapperApiTestLib FspMeasurementLib FspWrapperMultiPhaseProcessLib + PeCoffLib + FvLib [Packages] MdePkg/MdePkg.dec