summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MdeModulePkg/Core/DxeIplPeim/DxeIpl.h12
-rw-r--r--MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf8
-rw-r--r--MdeModulePkg/Core/DxeIplPeim/DxeLoad.c211
-rw-r--r--MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c174
-rw-r--r--MdeModulePkg/Core/Pei/FwVol/FwVol.c217
-rw-r--r--MdeModulePkg/Core/Pei/Image/Image.c2
-rw-r--r--MdeModulePkg/Core/Pei/PeiMain.h30
-rw-r--r--MdeModulePkg/Core/Pei/PeiMain.inf4
8 files changed, 384 insertions, 274 deletions
diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.h b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.h
index e82cf38..bd7e905 100644
--- a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.h
+++ b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.h
@@ -54,7 +54,6 @@ Abstract:
#include <Library/PeCoffLib.h>
#include <Library/S3Lib.h>
#include <Library/RecoveryLib.h>
-#include <Library/PeiPiLib.h>
#define STACK_SIZE 0x20000
#define BSP_STORE_SIZE 0x4000
@@ -73,16 +72,7 @@ PeiLoadFile (
;
EFI_STATUS
-DxeIplAddEncapsulatedFirmwareVolumes (
- VOID
- )
-;
-
-EFI_STATUS
-DxeIplFindFirmwareVolumeInstance (
- IN OUT UINTN *Instance,
- IN EFI_FV_FILETYPE SeachType,
- OUT EFI_PEI_FV_HANDLE *VolumeHandle,
+DxeIplFindDxeCore (
OUT EFI_PEI_FILE_HANDLE *FileHandle
)
;
diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
index 898e67e..b9b4b32 100644
--- a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
+++ b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
@@ -78,13 +78,7 @@
DebugLib
S3Lib
RecoveryLib
- PeiPiLib
-
-[Protocols]
- gEfiCustomizedDecompressProtocolGuid # PROTOCOL SOMETIMES_PRODUCED
- gEfiTianoDecompressProtocolGuid # PROTOCOL SOMETIMES_PRODUCED
- gEfiDecompressProtocolGuid # PROTOCOL SOMETIMES_PRODUCED
-
+ PerformanceLib
[Ppis]
gEfiPeiSecurityPpiGuid # PPI SOMETIMES_CONSUMED
diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c b/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c
index b7caded..65d0e86 100644
--- a/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c
+++ b/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c
@@ -135,11 +135,11 @@ PeimInitializeDxeIpl (
}
//
- // Install FvFileLoader and DxeIpl PPIs.
+ // Install DxeIpl and Decompress PPIs.
//
Status = PeiServicesInstallPpi (mPpiList);
- ASSERT_EFI_ERROR(Status);
-
+ ASSERT_EFI_ERROR(Status);
+
return Status;
}
@@ -167,9 +167,7 @@ DxeLoadCore (
UINT64 DxeCoreSize;
EFI_PHYSICAL_ADDRESS DxeCoreEntryPoint;
EFI_BOOT_MODE BootMode;
- EFI_PEI_FV_HANDLE VolumeHandle;
EFI_PEI_FILE_HANDLE FileHandle;
- UINTN Instance;
EFI_PEI_READ_ONLY_VARIABLE2_PPI *Variable;
UINTN DataSize;
EFI_MEMORY_TYPE_INFORMATION MemoryData [EfiMaxMemoryType + 1];
@@ -194,7 +192,7 @@ DxeLoadCore (
// Now should have a HOB with the DXE core w/ the old HOB destroyed
//
}
-
+
Status = PeiServicesLocatePpi (
&gEfiPeiReadOnlyVariable2PpiGuid,
0,
@@ -223,16 +221,12 @@ DxeLoadCore (
DataSize
);
}
- //
- // If any FV contains an encapsulated FV extract that FV
- //
- DxeIplAddEncapsulatedFirmwareVolumes ();
-
+
//
// Look in all the FVs present in PEI and find the DXE Core
//
- Instance = 0;
- Status = DxeIplFindFirmwareVolumeInstance (&Instance, EFI_FV_FILETYPE_DXE_CORE, &VolumeHandle, &FileHandle);
+ FileHandle = NULL;
+ Status = DxeIplFindDxeCore (&FileHandle);
ASSERT_EFI_ERROR (Status);
CopyMem(&DxeCoreFileName, &(((EFI_FFS_FILE_HEADER*)FileHandle)->Name), sizeof (EFI_GUID));
@@ -297,171 +291,38 @@ DxeLoadCore (
return EFI_OUT_OF_RESOURCES;
}
-
-STATIC
-EFI_STATUS
-GetFvAlignment (
- IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader,
- OUT UINT32 *FvAlignment
- )
-{
- //
- // Because FvLength in FvHeader is UINT64 type,
- // so FvHeader must meed at least 8 bytes alignment.
- // Get the appropriate alignment requirement.
- //
- if ((FvHeader->Attributes & EFI_FVB2_ALIGNMENT) < EFI_FVB2_ALIGNMENT_8) {
- return EFI_UNSUPPORTED;
- }
-
- *FvAlignment = 1 << ((FvHeader->Attributes & EFI_FVB2_ALIGNMENT) >> 16);
- return EFI_SUCCESS;
-}
-
-/**
- Search EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE image and expand
- as memory FV
-
- @return EFI_OUT_OF_RESOURCES There are no memory space to exstract FV
- @return EFI_SUCESS Sucess to find the FV
-**/
-EFI_STATUS
-DxeIplAddEncapsulatedFirmwareVolumes (
- VOID
- )
-{
- EFI_STATUS Status;
- EFI_STATUS VolumeStatus;
- UINTN Index;
- EFI_FV_INFO VolumeInfo;
- EFI_PEI_FV_HANDLE VolumeHandle;
- EFI_PEI_FILE_HANDLE FileHandle;
- UINT32 SectionLength;
- EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
- EFI_FIRMWARE_VOLUME_IMAGE_SECTION *SectionHeader;
- VOID *DstBuffer;
- UINT32 FvAlignment;
-
- Status = EFI_NOT_FOUND;
- Index = 0;
-
- do {
- VolumeStatus = DxeIplFindFirmwareVolumeInstance (
- &Index,
- EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE,
- &VolumeHandle,
- &FileHandle
- );
-
- if (!EFI_ERROR (VolumeStatus)) {
- Status = PeiServicesFfsFindSectionData (
- EFI_SECTION_FIRMWARE_VOLUME_IMAGE,
- (EFI_FFS_FILE_HEADER *)FileHandle,
- (VOID **)&FvHeader
- );
-
- if (!EFI_ERROR (Status)) {
- if (FvHeader->Signature == EFI_FVH_SIGNATURE) {
- //
- // Because FvLength in FvHeader is UINT64 type,
- // so FvHeader must meed at least 8 bytes alignment.
- // If current FvImage base address doesn't meet its alignment,
- // we need to reload this FvImage to another correct memory address.
- //
- Status = GetFvAlignment(FvHeader, &FvAlignment);
- if (EFI_ERROR(Status)) {
- return Status;
- }
- if (((UINTN) FvHeader % FvAlignment) != 0) {
- SectionHeader = (EFI_FIRMWARE_VOLUME_IMAGE_SECTION*)((UINTN)FvHeader - sizeof(EFI_FIRMWARE_VOLUME_IMAGE_SECTION));
- SectionLength = *(UINT32 *)SectionHeader->Size & 0x00FFFFFF;
-
- DstBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINTN) SectionLength - sizeof (EFI_COMMON_SECTION_HEADER)), FvAlignment);
- if (DstBuffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- CopyMem (DstBuffer, FvHeader, (UINTN) SectionLength - sizeof (EFI_COMMON_SECTION_HEADER));
- FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) DstBuffer;
- }
-
- //
- // This new Firmware Volume comes from a firmware file within a firmware volume.
- // Record the original Firmware Volume Name.
- //
- PeiServicesFfsGetVolumeInfo (&VolumeHandle, &VolumeInfo);
-
- PiLibInstallFvInfoPpi (
- NULL,
- FvHeader,
- (UINT32) FvHeader->FvLength,
- &(VolumeInfo.FvName),
- &(((EFI_FFS_FILE_HEADER*)FileHandle)->Name)
- );
-
- //
- // Inform HOB consumer phase, i.e. DXE core, the existance of this FV
- //
- BuildFvHob (
- (EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader,
- FvHeader->FvLength
- );
-
- ASSERT_EFI_ERROR (Status);
-
- //
- // Makes the encapsulated volume show up in DXE phase to skip processing of
- // encapsulated file again.
- //
- BuildFv2Hob (
- (EFI_PHYSICAL_ADDRESS)(UINTN)FvHeader,
- FvHeader->FvLength,
- &VolumeInfo.FvName,
- &(((EFI_FFS_FILE_HEADER *)FileHandle)->Name)
- );
- return Status;
- }
- }
- }
- } while (!EFI_ERROR (VolumeStatus));
-
- return Status;
-}
-
/**
- Find the First Volume that contains the first FileType.
+ Find DxeCore driver from all First Volumes.
- @param Instance The Fv instance.
- @param SeachType The type of file to search.
- @param VolumeHandle Pointer to Fv which contains the file to search.
@param FileHandle Pointer to FFS file to search.
@return EFI_SUCESS Success to find the FFS in specificed FV
@return others Fail to find the FFS in specificed FV
*/
EFI_STATUS
-DxeIplFindFirmwareVolumeInstance (
- IN OUT UINTN *Instance,
- IN EFI_FV_FILETYPE SeachType,
- OUT EFI_PEI_FV_HANDLE *VolumeHandle,
+DxeIplFindDxeCore (
OUT EFI_PEI_FILE_HANDLE *FileHandle
)
{
- EFI_STATUS Status;
- EFI_STATUS VolumeStatus;
+ EFI_STATUS Status;
+ EFI_STATUS FileStatus;
+ UINTN Instance;
+ EFI_PEI_FV_HANDLE VolumeHandle;
+
+ Instance = 0;
+ *FileHandle = NULL;
do {
- VolumeStatus = PeiServicesFfsFindNextVolume (*Instance, VolumeHandle);
- if (!EFI_ERROR (VolumeStatus)) {
- *FileHandle = NULL;
- Status = PeiServicesFfsFindNextFile (SeachType, *VolumeHandle, FileHandle);
- if (!EFI_ERROR (Status)) {
- return Status;
+ Status = PeiServicesFfsFindNextVolume (Instance++, &VolumeHandle);
+ if (!EFI_ERROR (Status)) {
+ FileStatus = PeiServicesFfsFindNextFile (EFI_FV_FILETYPE_DXE_CORE, VolumeHandle, FileHandle);
+ if (!EFI_ERROR (FileStatus)) {
+ return FileStatus;
}
}
- *Instance += 1;
- } while (!EFI_ERROR (VolumeStatus));
+ } while (!EFI_ERROR (Status));
- return VolumeStatus;
+ return EFI_NOT_FOUND;
}
/**
@@ -646,10 +507,16 @@ CustomGuidedSectionExtract (
//
// Allocate output buffer
//
- *OutputBuffer = AllocatePages (EFI_SIZE_TO_PAGES (OutputBufferSize));
+ *OutputBuffer = AllocatePages (EFI_SIZE_TO_PAGES (OutputBufferSize) + 1);
if (*OutputBuffer == NULL) {
return EFI_OUT_OF_RESOURCES;
}
+ DEBUG ((EFI_D_INFO, "Customed Guided section Memory Size required is 0x%x and address is 0x%p\n", OutputBufferSize, *OutputBuffer));
+ //
+ // *OutputBuffer still is one section. Adjust *OutputBuffer offset,
+ // skip EFI section header to make section data at page alignment.
+ //
+ *OutputBuffer = (VOID *)((UINT8 *) *OutputBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER));
}
Status = ExtractGuidedSectionDecode (
@@ -728,13 +595,18 @@ Decompress (
return EFI_OUT_OF_RESOURCES;
}
//
- // Allocate destination buffer
+ // Allocate destination buffer, extra one page for adjustment
//
- DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize));
+ DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize) + 1);
if (DstBuffer == NULL) {
return EFI_OUT_OF_RESOURCES;
}
//
+ // DstBuffer still is one section. Adjust DstBuffer offset, skip EFI section header
+ // to make section data at page alignment.
+ //
+ DstBuffer = DstBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER);
+ //
// Call decompress function
//
Status = UefiDecompress (
@@ -751,18 +623,21 @@ Decompress (
}
break;
- // porting note the original branch for customized compress is removed, it should be change to use GUID compress
-
case EFI_NOT_COMPRESSED:
//
// Allocate destination buffer
//
DstBufferSize = CompressionSection->UncompressedLength;
- DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize));
+ DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize) + 1);
if (DstBuffer == NULL) {
return EFI_OUT_OF_RESOURCES;
}
//
+ // Adjust DstBuffer offset, skip EFI section header
+ // to make section data at page alignment.
+ //
+ DstBuffer = DstBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER);
+ //
// stream is not actually compressed, just encapsulated. So just copy it.
//
CopyMem (DstBuffer, CompressionSection + 1, DstBufferSize);
diff --git a/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c b/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
index 164c2c8..5a140ed 100644
--- a/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
+++ b/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
@@ -30,7 +30,6 @@ InvokePeiCore (
VOID *Context2
);
-
VOID
DiscoverPeimsAndOrderWithApriori (
IN PEI_CORE_INSTANCE *Private,
@@ -233,11 +232,13 @@ Returns:
VOID *TopOfStack;
PEI_CORE_PARAMETERS PeiCoreParameters;
EFI_DEVICE_HANDLE_EXTENDED_DATA ExtendedData;
+ EFI_FV_FILE_INFO FvFileInfo;
PeiServices = &Private->PS;
PeimEntryPoint = NULL;
PeimFileHandle = NULL;
+ EntryPoint = 0;
if ((Private->PeiMemoryInstalled) && (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) {
//
@@ -327,16 +328,28 @@ Returns:
if (!DepexSatisfied (Private, PeimFileHandle, PeimCount)) {
PeimNeedingDispatch = TRUE;
} else {
- Status = PeiLoadImage (
- PeiServices,
- PeimFileHandle,
- &EntryPoint,
- &AuthenticationState
- );
+ Status = PeiFfsGetFileInfo (PeimFileHandle, &FvFileInfo);
+ ASSERT_EFI_ERROR (Status);
+ if (FvFileInfo.FileType == EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) {
+ //
+ // For Fv type file, Produce new FV PPI and FV hob
+ //
+ Status = ProcessFvFile (PeiServices, PeimFileHandle, &AuthenticationState);
+ } else {
+ //
+ // For PEIM driver, Load its entry point
+ //
+ Status = PeiLoadImage (
+ PeiServices,
+ PeimFileHandle,
+ &EntryPoint,
+ &AuthenticationState
+ );
+ }
+
if ((Status == EFI_SUCCESS)) {
//
- // The PEIM has its dependencies satisfied, and its entry point
- // has been found, so invoke it.
+ // The PEIM has its dependencies satisfied, and is processed.
//
PERF_START (0, "PEIM", NULL, 0);
@@ -355,12 +368,17 @@ Returns:
// PEIM_STATE_NOT_DISPATCHED move to PEIM_STATE_DISPATCHED
//
Private->Fv[FvCount].PeimState[PeimCount]++;
-
+
+ if (FvFileInfo.FileType != EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) {
+ //
+ // Call the PEIM entry point for PEIM driver
+ //
+ PeimEntryPoint = (EFI_PEIM_ENTRY_POINT)(UINTN)EntryPoint;
+ PeimEntryPoint (PeimFileHandle, PeiServices);
+ }
//
- // Call the PEIM entry point
+ // One module has been dispatched.
//
- PeimEntryPoint = (EFI_PEIM_ENTRY_POINT)(UINTN)EntryPoint;
- PeimEntryPoint (PeimFileHandle, PeiServices);
PeimDispatchOnThisPass = TRUE;
}
@@ -572,8 +590,8 @@ Returns:
--*/
{
- EFI_STATUS Status;
- VOID *DepexData;
+ EFI_STATUS Status;
+ VOID *DepexData;
if (PeimCount < Private->AprioriCount) {
//
@@ -581,8 +599,16 @@ Returns:
//
return TRUE;
}
+
+ //
+ // Depex section not in the encapsulated section.
+ //
+ Status = PeiServicesFfsFindSectionData (
+ EFI_SECTION_PEI_DEPEX,
+ FileHandle,
+ (VOID **)&DepexData
+ );
- Status = PeiServicesFfsFindSectionData (EFI_SECTION_PEI_DEPEX, FileHandle, (VOID **) &DepexData);
if (EFI_ERROR (Status)) {
//
// If there is no DEPEX, assume the module can be executed
@@ -675,3 +701,119 @@ InvokePeiCore (
ASSERT (FALSE);
CpuDeadLoop ();
}
+
+/**
+ Get Fv image from the FV type file, then install FV INFO ppi, Build FV hob.
+
+ @param PeiServices Pointer to the PEI Core Services Table.
+ @param FileHandle File handle of a Fv type file.
+ @param AuthenticationState Pointer to attestation authentication state of image.
+
+
+ @retval EFI_NOT_FOUND FV image can't be found.
+ @retval EFI_SUCCESS Successfully to process it.
+
+**/
+EFI_STATUS
+ProcessFvFile (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_FILE_HANDLE FvFileHandle,
+ OUT UINT32 *AuthenticationState
+ )
+{
+ EFI_STATUS Status;
+ EFI_PEI_FV_HANDLE FvImageHandle;
+ EFI_FV_INFO FvImageInfo;
+ UINT32 FvAlignment;
+ VOID *FvBuffer;
+ EFI_PEI_HOB_POINTERS HobFv2;
+
+ FvBuffer = NULL;
+ *AuthenticationState = 0;
+
+ //
+ // Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has already
+ // been extracted.
+ //
+ HobFv2.Raw = GetHobList ();
+ while ((HobFv2.Raw = GetNextHob (EFI_HOB_TYPE_FV2, HobFv2.Raw)) != NULL) {
+ if (CompareGuid (&(((EFI_FFS_FILE_HEADER *)FvFileHandle)->Name), &HobFv2.FirmwareVolume2->FileName)) {
+ //
+ // this FILE has been dispatched, it will not be dispatched again.
+ //
+ return EFI_SUCCESS;
+ }
+ HobFv2.Raw = GET_NEXT_HOB (HobFv2);
+ }
+
+ //
+ // Find FvImage in FvFile
+ //
+ Status = PeiFfsFindSectionData (
+ (CONST EFI_PEI_SERVICES **) PeiServices,
+ EFI_SECTION_FIRMWARE_VOLUME_IMAGE,
+ FvFileHandle,
+ (VOID **)&FvImageHandle
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // Collect FvImage Info.
+ //
+ Status = PeiFfsGetVolumeInfo (FvImageHandle, &FvImageInfo);
+ ASSERT_EFI_ERROR (Status);
+ //
+ // FvAlignment must be more than 8 bytes required by FvHeader structure.
+ //
+ FvAlignment = 1 << ((FvImageInfo.FvAttributes & EFI_FVB2_ALIGNMENT) >> 16);
+ if (FvAlignment < 8) {
+ FvAlignment = 8;
+ }
+ //
+ // Check FvImage
+ //
+ if ((UINTN) FvImageInfo.FvStart % FvAlignment != 0) {
+ FvBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINT32) FvImageInfo.FvSize), FvAlignment);
+ if (FvBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ CopyMem (FvBuffer, FvImageInfo.FvStart, (UINTN) FvImageInfo.FvSize);
+ //
+ // Update FvImageInfo after reload FvImage to new aligned memory
+ //
+ PeiFfsGetVolumeInfo ((EFI_PEI_FV_HANDLE) FvBuffer, &FvImageInfo);
+ }
+
+ //
+ // Install FvPpi and Build FvHob
+ //
+ PiLibInstallFvInfoPpi (
+ NULL,
+ FvImageInfo.FvStart,
+ (UINT32) FvImageInfo.FvSize,
+ &(FvImageInfo.FvName),
+ &(((EFI_FFS_FILE_HEADER*)FvFileHandle)->Name)
+ );
+
+ //
+ // Inform HOB consumer phase, i.e. DXE core, the existance of this FV
+ //
+ BuildFvHob (
+ (EFI_PHYSICAL_ADDRESS) (UINTN) FvImageInfo.FvStart,
+ FvImageInfo.FvSize
+ );
+ //
+ // Makes the encapsulated volume show up in DXE phase to skip processing of
+ // encapsulated file again.
+ //
+ BuildFv2Hob (
+ (EFI_PHYSICAL_ADDRESS) (UINTN) FvImageInfo.FvStart,
+ FvImageInfo.FvSize,
+ &FvImageInfo.FvName,
+ &(((EFI_FFS_FILE_HEADER *)FvFileHandle)->Name)
+ );
+
+ return EFI_SUCCESS;
+}
diff --git a/MdeModulePkg/Core/Pei/FwVol/FwVol.c b/MdeModulePkg/Core/Pei/FwVol/FwVol.c
index 57b45d0..621fb16 100644
--- a/MdeModulePkg/Core/Pei/FwVol/FwVol.c
+++ b/MdeModulePkg/Core/Pei/FwVol/FwVol.c
@@ -258,7 +258,8 @@ Returns:
}
} else if (SearchType == PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE) {
if ((FfsFileHeader->Type == EFI_FV_FILETYPE_PEIM) ||
- (FfsFileHeader->Type == EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER)) {
+ (FfsFileHeader->Type == EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER) ||
+ (FfsFileHeader->Type == EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE)) {
*FileHeader = FfsFileHeader;
return EFI_SUCCESS;
@@ -366,8 +367,15 @@ Returns:
UINT8 FvCount;
EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *Fv;
PEI_CORE_INSTANCE *PrivateData;
+ EFI_PEI_FILE_HANDLE FileHandle;
+ VOID *DepexData;
+ UINT32 AuthenticationStatus;
+ EFI_STATUS Status;
- PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
+ FileHandle = NULL;
+ DepexData = NULL;
+ Status = EFI_SUCCESS;
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
if (PrivateData->FvCount >= FixedPcdGet32 (PcdPeiCoreMaxFvSupported)) {
ASSERT (FALSE);
@@ -375,19 +383,53 @@ Returns:
Fv = (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *)Ppi;
- if (CompareGuid (&Fv->FvFormat, &gEfiFirmwareFileSystem2Guid)) {
- for (FvCount = 0; FvCount < PrivateData->FvCount; FvCount ++) {
- if ((UINTN)PrivateData->Fv[FvCount].FvHeader == (UINTN)Fv->FvInfo) {
- return EFI_SUCCESS;
- }
- }
+ if (CompareGuid (&Fv->FvFormat, &gEfiFirmwareFileSystem2Guid)) {
+ for (FvCount = 0; FvCount < PrivateData->FvCount; FvCount ++) {
+ if ((UINTN)PrivateData->Fv[FvCount].FvHeader == (UINTN)Fv->FvInfo) {
+ return EFI_SUCCESS;
+ }
+ }
PrivateData->Fv[PrivateData->FvCount++].FvHeader = (EFI_FIRMWARE_VOLUME_HEADER*)Fv->FvInfo;
- }
- //
- // Allways add to the All list
- //
- PrivateData->AllFv[PrivateData->AllFvCount++] = (EFI_PEI_FV_HANDLE)Fv->FvInfo;
+ //
+ // Only add FileSystem2 Fv to the All list
+ //
+ PrivateData->AllFv[PrivateData->AllFvCount++] = (EFI_PEI_FV_HANDLE)Fv->FvInfo;
+
+ DEBUG ((EFI_D_INFO, "The %dth FvImage start address is 0x%10p and size is 0x%08x\n", PrivateData->AllFvCount, (VOID *) Fv->FvInfo, Fv->FvInfoSize));
+ //
+ // Preprocess all FV type files in this new FileSystem2 Fv image
+ //
+ do {
+ Status = PeiFindFileEx (
+ (EFI_PEI_FV_HANDLE)Fv->FvInfo,
+ NULL,
+ EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE,
+ &FileHandle,
+ NULL
+ );
+ if (!EFI_ERROR (Status)) {
+ Status = PeiFfsFindSectionData (
+ (CONST EFI_PEI_SERVICES **) PeiServices,
+ EFI_SECTION_PEI_DEPEX,
+ FileHandle,
+ (VOID **)&DepexData
+ );
+ if (!EFI_ERROR (Status)) {
+ if (!PeimDispatchReadiness (PeiServices, DepexData)) {
+ //
+ // Dependency is not satisfied.
+ //
+ continue;
+ }
+ }
+ //
+ // Process FvFile to install FvInfo ppi and build FvHob
+ //
+ ProcessFvFile (PeiServices, FileHandle, &AuthenticationStatus);
+ }
+ } while (FileHandle != NULL);
+ }
return EFI_SUCCESS;
}
@@ -398,25 +440,21 @@ PeiFfsProcessSection (
IN EFI_SECTION_TYPE SectionType,
IN EFI_COMMON_SECTION_HEADER *Section,
IN UINTN SectionSize,
- OUT VOID **OutputBuffer,
- OUT UINTN *OutputSize,
- OUT UINT32 *Authentication
+ OUT VOID **OutputBuffer
)
/*++
Routine Description:
Go through the file to search SectionType section,
- when meeting an encapsuled section, search recursively.
+ when meeting an encapsuled section.
Arguments:
- PeiServices - Pointer to the PEI Core Services Table.
+ PeiServices - General purpose services available to every PEIM.
SearchType - Filter to find only section of this type.
Section - From where to search.
SectionSize - The file size to search.
OutputBuffer - Pointer to the section to search.
- OutputSize - The size of the section to search.
- Authentication - Authenticate the section.
Returns:
EFI_STATUS
@@ -426,58 +464,95 @@ Returns:
EFI_STATUS Status;
UINT32 SectionLength;
UINT32 ParsedLength;
- EFI_GUID_DEFINED_SECTION *GuidSection;
EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI *GuidSectionPpi;
- EFI_COMPRESSION_SECTION *CompressionSection;
EFI_PEI_DECOMPRESS_PPI *DecompressPpi;
VOID *PpiOutput;
UINTN PpiOutputSize;
+ UINTN Index;
+ UINT32 Authentication;
+ PEI_CORE_INSTANCE *PrivateData;
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
*OutputBuffer = NULL;
- ParsedLength = 0;
+ ParsedLength = 0;
+ Index = 0;
+ Status = EFI_NOT_FOUND;
+ PpiOutput = NULL;
+ PpiOutputSize = 0;
while (ParsedLength < SectionSize) {
if (Section->Type == SectionType) {
*OutputBuffer = (VOID *)(Section + 1);
return EFI_SUCCESS;
- } else if (Section->Type == EFI_SECTION_GUID_DEFINED) {
- GuidSection = (EFI_GUID_DEFINED_SECTION *)Section;
- Status = PeiServicesLocatePpi (&GuidSection->SectionDefinitionGuid, 0, NULL, (VOID **) &GuidSectionPpi);
- if (!EFI_ERROR (Status)) {
- Status = GuidSectionPpi->ExtractSection (
- GuidSectionPpi,
- Section,
- &PpiOutput,
- &PpiOutputSize,
- Authentication
- );
- if (!EFI_ERROR (Status)) {
+ } else if ((Section->Type == EFI_SECTION_GUID_DEFINED) || (Section->Type == EFI_SECTION_COMPRESSION)) {
+ //
+ // Check the encapsulated section is extracted into the cache data.
+ //
+ for (Index = 0; Index < PrivateData->CacheSection.AllSectionCount; Index ++) {
+ if (Section == PrivateData->CacheSection.Section[Index]) {
+ PpiOutput = PrivateData->CacheSection.SectionData[Index];
+ PpiOutputSize = PrivateData->CacheSection.SectionSize[Index];
+ //
+ // Search section directly from the cache data.
+ //
return PeiFfsProcessSection (
PeiServices,
SectionType,
PpiOutput,
PpiOutputSize,
- OutputBuffer,
- OutputSize,
- Authentication
+ OutputBuffer
);
}
}
- } else if (Section->Type == EFI_SECTION_COMPRESSION) {
- CompressionSection = (EFI_COMPRESSION_SECTION *)Section;
- Status = PeiServicesLocatePpi (&gEfiPeiDecompressPpiGuid, 0, NULL, (VOID **) &DecompressPpi);
- if (!EFI_ERROR (Status)) {
- Status = DecompressPpi->Decompress (
- DecompressPpi,
- CompressionSection,
- &PpiOutput,
- &PpiOutputSize
- );
+
+ Status = EFI_NOT_FOUND;
+ if (Section->Type == EFI_SECTION_GUID_DEFINED) {
+ Status = PeiServicesLocatePpi (
+ &((EFI_GUID_DEFINED_SECTION *)Section)->SectionDefinitionGuid,
+ 0,
+ NULL,
+ (VOID **) &GuidSectionPpi
+ );
if (!EFI_ERROR (Status)) {
- return PeiFfsProcessSection (
- PeiServices, SectionType, PpiOutput, PpiOutputSize, OutputBuffer, OutputSize, Authentication
- );
+ Status = GuidSectionPpi->ExtractSection (
+ GuidSectionPpi,
+ Section,
+ &PpiOutput,
+ &PpiOutputSize,
+ &Authentication
+ );
+ }
+ } else if (Section->Type == EFI_SECTION_COMPRESSION) {
+ Status = PeiServicesLocatePpi (&gEfiPeiDecompressPpiGuid, 0, NULL, (VOID **) &DecompressPpi);
+ if (!EFI_ERROR (Status)) {
+ Status = DecompressPpi->Decompress (
+ DecompressPpi,
+ (CONST EFI_COMPRESSION_SECTION*) Section,
+ &PpiOutput,
+ &PpiOutputSize
+ );
}
}
+
+ if (!EFI_ERROR (Status)) {
+ //
+ // Update cache section data.
+ //
+ if (PrivateData->CacheSection.AllSectionCount < CACHE_SETION_MAX_NUMBER) {
+ PrivateData->CacheSection.AllSectionCount ++;
+ }
+ PrivateData->CacheSection.Section [PrivateData->CacheSection.SectionIndex] = Section;
+ PrivateData->CacheSection.SectionData [PrivateData->CacheSection.SectionIndex] = PpiOutput;
+ PrivateData->CacheSection.SectionSize [PrivateData->CacheSection.SectionIndex] = PpiOutputSize;
+ PrivateData->CacheSection.SectionIndex = (PrivateData->CacheSection.SectionIndex + 1)%CACHE_SETION_MAX_NUMBER;
+
+ return PeiFfsProcessSection (
+ PeiServices,
+ SectionType,
+ PpiOutput,
+ PpiOutputSize,
+ OutputBuffer
+ );
+ }
}
//
@@ -526,9 +601,6 @@ Returns:
EFI_FFS_FILE_HEADER *FfsFileHeader;
UINT32 FileSize;
EFI_COMMON_SECTION_HEADER *Section;
- UINTN OutputSize;
- UINT32 AuthenticationStatus;
-
FfsFileHeader = (EFI_FFS_FILE_HEADER *)(FileHandle);
@@ -542,13 +614,11 @@ Returns:
FileSize -= sizeof (EFI_FFS_FILE_HEADER);
return PeiFfsProcessSection (
- PeiServices,
+ PeiServices,
SectionType,
Section,
FileSize,
- SectionData,
- &OutputSize,
- &AuthenticationStatus
+ SectionData
);
}
@@ -601,7 +671,7 @@ PeiFvFindNextVolume (
Routine Description:
- Return the BFV location
+ Return the firmware volumes.
BugBug -- Move this to the location of this code to where the
other FV and FFS support code lives.
@@ -761,21 +831,32 @@ Returns:
--*/
{
- EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
+ EFI_FIRMWARE_VOLUME_HEADER FwVolHeader;
EFI_FIRMWARE_VOLUME_EXT_HEADER *FwVolExHeaderInfo;
if (VolumeInfo == NULL) {
return EFI_INVALID_PARAMETER;
}
+
+ //
+ // VolumeHandle may not align at 8 byte,
+ // but FvLength is UINT64 type, which requires FvHeader align at least 8 byte.
+ // So, Copy FvHeader into the local FvHeader structure.
+ //
+ CopyMem (&FwVolHeader, VolumeHandle, sizeof (EFI_FIRMWARE_VOLUME_HEADER));
+ //
+ // Check Fv Image Signature
+ //
+ if (FwVolHeader.Signature != EFI_FVH_SIGNATURE) {
+ return EFI_INVALID_PARAMETER;
+ }
+ VolumeInfo->FvAttributes = FwVolHeader.Attributes;
+ VolumeInfo->FvStart = (VOID *) VolumeHandle;
+ VolumeInfo->FvSize = FwVolHeader.FvLength;
+ CopyMem (&VolumeInfo->FvFormat, &FwVolHeader.FileSystemGuid, sizeof(EFI_GUID));
- FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(VolumeHandle);
- VolumeInfo->FvAttributes = FwVolHeader->Attributes;
- VolumeInfo->FvStart = FwVolHeader;
- VolumeInfo->FvSize = FwVolHeader->FvLength;
- CopyMem (&VolumeInfo->FvFormat, &FwVolHeader->FileSystemGuid,sizeof(EFI_GUID));
-
- if (FwVolHeader->ExtHeaderOffset != 0) {
- FwVolExHeaderInfo = (EFI_FIRMWARE_VOLUME_EXT_HEADER*)(((UINT8 *)FwVolHeader) + FwVolHeader->ExtHeaderOffset);
+ if (FwVolHeader.ExtHeaderOffset != 0) {
+ FwVolExHeaderInfo = (EFI_FIRMWARE_VOLUME_EXT_HEADER*)(((UINT8 *)VolumeHandle) + FwVolHeader.ExtHeaderOffset);
CopyMem (&VolumeInfo->FvName, &FwVolExHeaderInfo->FvName, sizeof(EFI_GUID));
}
return EFI_SUCCESS;
diff --git a/MdeModulePkg/Core/Pei/Image/Image.c b/MdeModulePkg/Core/Pei/Image/Image.c
index 0c627c1..2c7e584 100644
--- a/MdeModulePkg/Core/Pei/Image/Image.c
+++ b/MdeModulePkg/Core/Pei/Image/Image.c
@@ -241,7 +241,7 @@ Returns:
// When Image has no reloc section, it can't be relocated into memory.
//
if (ImageContext.RelocationsStripped) {
- DEBUG ((EFI_D_ERROR, "The image at 0x%08x without reloc section can't be loaded into memory", (UINTN) Pe32Data));
+ DEBUG ((EFI_D_ERROR, "The image at 0x%08x without reloc section can't be loaded into memory\n", (UINTN) Pe32Data));
return EFI_INVALID_PARAMETER;
}
//
diff --git a/MdeModulePkg/Core/Pei/PeiMain.h b/MdeModulePkg/Core/Pei/PeiMain.h
index 61641b3..84d187e 100644
--- a/MdeModulePkg/Core/Pei/PeiMain.h
+++ b/MdeModulePkg/Core/Pei/PeiMain.h
@@ -53,6 +53,7 @@ Revision History
#include <IndustryStandard/PeImage.h>
#include <Library/PeiServicesTablePointerLib.h>
#include <Library/MemoryAllocationLib.h>
+#include <Library/PeiPiLib.h>
#include <Guid/FirmwareFileSystem2.h>
#include <Guid/AprioriFileName.h>
@@ -98,6 +99,15 @@ typedef struct {
BOOLEAN ScanFv;
} PEI_CORE_FV_HANDLE;
+#define CACHE_SETION_MAX_NUMBER 0x10
+typedef struct {
+ EFI_COMMON_SECTION_HEADER* Section[CACHE_SETION_MAX_NUMBER];
+ VOID* SectionData[CACHE_SETION_MAX_NUMBER];
+ UINTN SectionSize[CACHE_SETION_MAX_NUMBER];
+ UINTN AllSectionCount;
+ UINTN SectionIndex;
+} CACHE_SECTION_DATA;
+
//
// Pei Core private data structure instance
//
@@ -130,6 +140,7 @@ typedef struct{
UINTN SizeOfCacheAsRam;
VOID *MaxTopOfCarHeap;
EFI_PEI_PPI_DESCRIPTOR *XipLoadFile;
+ CACHE_SECTION_DATA CacheSection;
} PEI_CORE_INSTANCE;
//
@@ -1379,4 +1390,23 @@ Returns:
--*/
;
+/**
+ Get Fv image from the FV type file, then install FV INFO ppi, Build FV hob.
+
+ @param PeiServices Pointer to the PEI Core Services Table.
+ @param FileHandle File handle of a Fv type file.
+ @param AuthenticationState Pointer to attestation authentication state of image.
+
+
+ @retval EFI_NOT_FOUND FV image can't be found.
+ @retval EFI_SUCCESS Successfully to process it.
+
+**/
+EFI_STATUS
+ProcessFvFile (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_FILE_HANDLE FvFileHandle,
+ OUT UINT32 *AuthenticationState
+ );
+
#endif
diff --git a/MdeModulePkg/Core/Pei/PeiMain.inf b/MdeModulePkg/Core/Pei/PeiMain.inf
index 360f027..0d58f95 100644
--- a/MdeModulePkg/Core/Pei/PeiMain.inf
+++ b/MdeModulePkg/Core/Pei/PeiMain.inf
@@ -81,6 +81,7 @@
MemoryAllocationLib
CacheMaintenanceLib
PeCoffLib
+ PeiPiLib
[Guids]
gPeiAprioriFileNameGuid
@@ -103,6 +104,3 @@
[FeaturePcd.common]
gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreImageLoaderSearchTeSectionFirst
-
-
-