diff options
| author | Zhiguang Liu <zhiguang.liu@intel.com> | 2025-09-25 16:45:44 +0800 |
|---|---|---|
| committer | mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> | 2025-10-30 08:13:29 +0000 |
| commit | 426da7fb1a2d9155d2abf3a68b93ff37ed6898b1 (patch) | |
| tree | d278989619c29f8670350c54930d079e9c344c8f /IntelFsp2WrapperPkg | |
| parent | 29a66468cbabe602c29e770f4382a5979b2d2304 (diff) | |
| download | edk2-426da7fb1a2d9155d2abf3a68b93ff37ed6898b1.tar.gz edk2-426da7fb1a2d9155d2abf3a68b93ff37ed6898b1.zip | |
IntelFsp2WrapperPkg: Rebase FSP-S and FSP-I if Image Base not match
FSP Spec says: "The FSP is not Position Independent Code (PIC) and
each FSP component has to be rebased if it is placed at a location
which is different from the preferred base address specified during
the FSP build."
Normally, the FSP location in flash is the same preferred base
address specified during the FSP build. To avoid FSP-S and FSP-I
running directly from flash, platform may copy the FSP binaries into
physical memory. This causes FSP location to be different from the
preferred base address.
To support this, this commit checks the Image Base from FSP header
and the FSP base address PCD. If these two are different, This commit
assumes the FSP is copied into physical memory and FSP location is
changed. In such scenario, the commit will rebase the FSP to the address
provided by the PCD.
Signed-off-by: Zhiguang Liu <zhiguang.liu@intel.com>
Diffstat (limited to 'IntelFsp2WrapperPkg')
4 files changed, 214 insertions, 0 deletions
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 <Library/FspMeasurementLib.h>
#include <Ppi/Tcg.h>
#include <Ppi/FirmwareVolumeInfoMeasurementExcluded.h>
+#include <Library/PeCoffLib.h>
+#include <Library/FvLib.h>
+
+/**
+ 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 <FspEas.h>
#include <FspStatusCode.h>
#include <FspGlobalData.h>
+#include <Library/FvLib.h>
+#include <Library/PeCoffLib.h>
extern EFI_PEI_NOTIFY_DESCRIPTOR mS3EndOfPeiNotifyDesc;
extern EFI_GUID gFspHobGuid;
@@ -268,6 +270,102 @@ EFI_PEI_NOTIFY_DESCRIPTOR mPeiMemoryDiscoveredNotifyDesc = { };
/**
+ 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.
@param[in] PeiServices Pointer to PEI Services Table.
@@ -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
|
