\r
--*/\r
\r
-#include <DxeIpl.h>\r
+#include "DxeIpl.h"\r
+\r
+#ifndef __GNUC__\r
+#pragma warning( disable : 4305 )\r
+#endif\r
\r
BOOLEAN gInMemory = FALSE;\r
\r
DxeIplLoadFile\r
};\r
\r
-static EFI_PEI_PPI_DESCRIPTOR mPpiLoadFile = {\r
- (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
+static EFI_PEI_PPI_DESCRIPTOR mPpiList[] = {\r
+ {\r
+ EFI_PEI_PPI_DESCRIPTOR_PPI,\r
&gEfiPeiFvFileLoaderPpiGuid,\r
&mLoadFilePpi\r
-};\r
-\r
-static EFI_PEI_PPI_DESCRIPTOR mPpiList = {\r
+ },\r
+ {\r
(EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
&gEfiDxeIplPpiGuid,\r
&mDxeIplPpi\r
-};\r
-\r
-static EFI_PEI_PPI_DESCRIPTOR mPpiPeiInMemory = {\r
- (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
- &gPeiInMemoryGuid,\r
- NULL\r
+ }\r
};\r
\r
static EFI_PEI_PPI_DESCRIPTOR mPpiSignal = {\r
NULL\r
};\r
\r
-DECOMPRESS_LIBRARY gEfiDecompress = {\r
+GLOBAL_REMOVE_IF_UNREFERENCED DECOMPRESS_LIBRARY gEfiDecompress = {\r
UefiDecompressGetInfo,\r
UefiDecompress\r
};\r
\r
-DECOMPRESS_LIBRARY gTianoDecompress = {\r
+GLOBAL_REMOVE_IF_UNREFERENCED DECOMPRESS_LIBRARY gTianoDecompress = {\r
TianoDecompressGetInfo,\r
TianoDecompress\r
};\r
\r
-DECOMPRESS_LIBRARY gCustomDecompress = {\r
+GLOBAL_REMOVE_IF_UNREFERENCED DECOMPRESS_LIBRARY gCustomDecompress = {\r
CustomDecompressGetInfo,\r
CustomDecompress\r
};\r
\r
-STATIC\r
-UINTN\r
-GetOccupiedSize (\r
- IN UINTN ActualSize,\r
- IN UINTN Alignment\r
- )\r
-{\r
- UINTN OccupiedSize;\r
-\r
- OccupiedSize = ActualSize;\r
- while ((OccupiedSize & (Alignment - 1)) != 0) {\r
- OccupiedSize++;\r
- }\r
-\r
- return OccupiedSize;\r
-}\r
-\r
EFI_STATUS\r
EFIAPI\r
PeimInitializeDxeIpl (\r
EFI_BOOT_MODE BootMode;\r
\r
Status = PeiServicesGetBootMode (&BootMode);\r
-\r
ASSERT_EFI_ERROR (Status);\r
\r
- Status = PeiServicesLocatePpi (\r
- &gPeiInMemoryGuid,\r
- 0,\r
- NULL,\r
- NULL\r
- );\r
-\r
- if (EFI_ERROR (Status) && (BootMode != BOOT_ON_S3_RESUME)) {\r
+ if (!gInMemory && (BootMode != BOOT_ON_S3_RESUME)) { \r
//\r
// The DxeIpl has not yet been shadowed\r
//\r
// Shadow DxeIpl and then re-run its entry point\r
//\r
Status = ShadowDxeIpl (FfsHeader, PeiEfiPeiPeCoffLoader);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
} else {\r
- if (BootMode != BOOT_ON_S3_RESUME) {\r
- //\r
- // The DxeIpl has been shadowed\r
- //\r
- gInMemory = TRUE;\r
-\r
//\r
- // Install LoadFile PPI\r
+ // Install FvFileLoader and DxeIpl PPIs.\r
//\r
- Status = PeiServicesInstallPpi (&mPpiLoadFile);\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- }\r
- //\r
- // Install DxeIpl PPI\r
- //\r
- PeiServicesInstallPpi (&mPpiList);\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
+ Status = PeiServicesInstallPpi (mPpiList);\r
+ ASSERT_EFI_ERROR(Status);\r
}\r
-\r
- return EFI_SUCCESS;\r
+ \r
+ return Status;\r
}\r
\r
EFI_STATUS\r
--*/\r
{\r
EFI_STATUS Status;\r
- VOID *TopOfStack;\r
- VOID *BaseOfStack;\r
+ EFI_PHYSICAL_ADDRESS TopOfStack;\r
+ EFI_PHYSICAL_ADDRESS BaseOfStack;\r
EFI_PHYSICAL_ADDRESS BspStore;\r
EFI_GUID DxeCoreFileName;\r
EFI_GUID FirmwareFileName;\r
VOID *Pe32Data;\r
+ VOID *FvImageData; \r
EFI_PHYSICAL_ADDRESS DxeCoreAddress;\r
UINT64 DxeCoreSize;\r
EFI_PHYSICAL_ADDRESS DxeCoreEntryPoint;\r
EFI_BOOT_MODE BootMode;\r
EFI_PEI_RECOVERY_MODULE_PPI *PeiRecovery;\r
EFI_PEI_S3_RESUME_PPI *S3Resume;\r
+ EFI_PHYSICAL_ADDRESS PageTables;\r
\r
// PERF_START (PeiServices, L"DxeIpl", NULL, 0);\r
- TopOfStack = NULL;\r
- BaseOfStack = NULL;\r
+ TopOfStack = 0;\r
+ BaseOfStack = 0;\r
BspStore = 0;\r
- Status = EFI_SUCCESS;\r
+ PageTables = 0;\r
\r
//\r
// if in S3 Resume, restore configure\r
//\r
Status = PeiServicesGetBootMode (&BootMode);\r
+ ASSERT_EFI_ERROR(Status);\r
\r
- if (!EFI_ERROR (Status) && (BootMode == BOOT_ON_S3_RESUME)) {\r
+ if (BootMode == BOOT_ON_S3_RESUME) {\r
Status = PeiServicesLocatePpi (\r
&gEfiPeiS3ResumePpiGuid,\r
0,\r
NULL,\r
(VOID **)&S3Resume\r
);\r
-\r
ASSERT_EFI_ERROR (Status);\r
\r
Status = S3Resume->S3RestoreConfig (PeiServices);\r
+ ASSERT_EFI_ERROR (Status);\r
+ } else if (BootMode == BOOT_IN_RECOVERY_MODE) {\r
\r
+ Status = PeiServicesLocatePpi (\r
+ &gEfiPeiRecoveryModulePpiGuid,\r
+ 0,\r
+ NULL,\r
+ (VOID **)&PeiRecovery\r
+ );\r
ASSERT_EFI_ERROR (Status);\r
- }\r
\r
- Status = EFI_SUCCESS;\r
+ Status = PeiRecovery->LoadRecoveryCapsule (PeiServices, PeiRecovery);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "Load Recovery Capsule Failed.(Status = %r)\n", Status));\r
+ CpuDeadLoop ();\r
+ }\r
+\r
+ //\r
+ // Now should have a HOB with the DXE core w/ the old HOB destroyed\r
+ //\r
+ }\r
\r
//\r
// Install the PEI Protocols that are shared between PEI and DXE\r
PeiEfiPeiPeCoffLoader = (EFI_PEI_PE_COFF_LOADER_PROTOCOL *)GetPeCoffLoaderProtocol ();\r
ASSERT (PeiEfiPeiPeCoffLoader != NULL);\r
\r
-\r
//\r
// Allocate 128KB for the Stack\r
//\r
- BaseOfStack = AllocatePages (EFI_SIZE_TO_PAGES (STACK_SIZE));\r
- ASSERT (BaseOfStack != NULL);\r
-\r
- //\r
- // Compute the top of the stack we were allocated. Pre-allocate a UINTN\r
- // for safety.\r
- //\r
- TopOfStack = (VOID *)((UINTN)BaseOfStack + EFI_SIZE_TO_PAGES (STACK_SIZE) * EFI_PAGE_SIZE - sizeof (UINTN));\r
+ PeiServicesAllocatePages (EfiBootServicesData, EFI_SIZE_TO_PAGES (STACK_SIZE), &BaseOfStack);\r
+ ASSERT (BaseOfStack != 0);\r
\r
//\r
// Add architecture-specifc HOBs (including the BspStore HOB)\r
//\r
Status = CreateArchSpecificHobs (&BspStore);\r
-\r
ASSERT_EFI_ERROR (Status);\r
\r
//\r
- // Add HOB for the EFI Decompress Protocol\r
- //\r
- BuildGuidDataHob (\r
- &gEfiDecompressProtocolGuid,\r
- (VOID *)&gEfiDecompress,\r
- sizeof (gEfiDecompress)\r
- );\r
-\r
- //\r
- // Add HOB for the Tiano Decompress Protocol\r
- //\r
- BuildGuidDataHob (\r
- &gEfiTianoDecompressProtocolGuid,\r
- (VOID *)&gTianoDecompress,\r
- sizeof (gTianoDecompress)\r
- );\r
-\r
- //\r
- // Add HOB for the user customized Decompress Protocol\r
- //\r
- BuildGuidDataHob (\r
- &gEfiCustomizedDecompressProtocolGuid,\r
- (VOID *)&gCustomDecompress,\r
- sizeof (gCustomDecompress)\r
- );\r
-\r
- //\r
- // Add HOB for the PE/COFF Loader Protocol\r
- //\r
- BuildGuidDataHob (\r
- &gEfiPeiPeCoffLoaderGuid,\r
- (VOID *)&PeiEfiPeiPeCoffLoader,\r
- sizeof (VOID *)\r
- );\r
-\r
- //\r
- // See if we are in crisis recovery\r
- //\r
- Status = PeiServicesGetBootMode (&BootMode);\r
-\r
- if (!EFI_ERROR (Status) && (BootMode == BOOT_IN_RECOVERY_MODE)) {\r
-\r
- Status = PeiServicesLocatePpi (\r
- &gEfiPeiRecoveryModulePpiGuid,\r
- 0,\r
- NULL,\r
- (VOID **)&PeiRecovery\r
- );\r
-\r
- ASSERT_EFI_ERROR (Status);\r
- Status = PeiRecovery->LoadRecoveryCapsule (PeiServices, PeiRecovery);\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // Now should have a HOB with the DXE core w/ the old HOB destroyed\r
- //\r
- }\r
-\r
- //\r
- // Find the EFI_FV_FILETYPE_RAW type compressed Firmware Volume file in FTW spare block\r
+ // Find the EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE type compressed Firmware Volume file\r
// The file found will be processed by PeiProcessFile: It will first be decompressed to\r
- // a normal FV, then a corresponding FV type hob will be built which is provided for DXE\r
- // core to find and dispatch drivers in this FV. Because PeiProcessFile typically checks\r
- // for EFI_FV_FILETYPE_DXE_CORE type file, in this condition we need not check returned\r
- // status\r
+ // a normal FV, then a corresponding FV type hob will be built. \r
//\r
Status = PeiFindFile (\r
- EFI_FV_FILETYPE_RAW,\r
- EFI_SECTION_PE32,\r
- &FirmwareFileName,\r
- &Pe32Data\r
- );\r
+ EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE,\r
+ EFI_SECTION_FIRMWARE_VOLUME_IMAGE,\r
+ &FirmwareFileName,\r
+ &FvImageData\r
+ );\r
\r
//\r
// Find the DXE Core in a Firmware Volume\r
&DxeCoreFileName,\r
&Pe32Data\r
);\r
-\r
ASSERT_EFI_ERROR (Status);\r
\r
//\r
// Load the DXE Core from a Firmware Volume\r
//\r
Status = PeiLoadFile (\r
- PeiEfiPeiPeCoffLoader,\r
- Pe32Data,\r
- &DxeCoreAddress,\r
- &DxeCoreSize,\r
- &DxeCoreEntryPoint\r
- );\r
-\r
+ PeiEfiPeiPeCoffLoader,\r
+ Pe32Data,\r
+ &DxeCoreAddress,\r
+ &DxeCoreSize,\r
+ &DxeCoreEntryPoint\r
+ );\r
ASSERT_EFI_ERROR (Status);\r
\r
//\r
// Transfer control to the DXE Core\r
// The handoff state is simply a pointer to the HOB list\r
//\r
-// PERF_END (PeiServices, L"DxeIpl", NULL, 0);\r
\r
Status = PeiServicesInstallPpi (&mPpiSignal);\r
-\r
ASSERT_EFI_ERROR (Status);\r
\r
//\r
);\r
\r
DEBUG ((EFI_D_INFO, "DXE Core Entry\n"));\r
- SwitchIplStacks (\r
- (SWITCH_STACK_ENTRY_POINT)(UINTN)DxeCoreEntryPoint,\r
- HobList.Raw,\r
- NULL,\r
- TopOfStack,\r
- (VOID *) (UINTN) BspStore\r
- );\r
+ if (FeaturePcdGet(PcdDxeIplSwitchToLongMode)) {\r
+ //\r
+ // Compute the top of the stack we were allocated, which is used to load X64 dxe core. \r
+ // Pre-allocate a 32 bytes which confroms to x64 calling convention.\r
+ //\r
+ // The first four parameters to a function are passed in rcx, rdx, r8 and r9. \r
+ // Any further parameters are pushed on the stack. Furthermore, space (4 * 8bytes) for the \r
+ // register parameters is reserved on the stack, in case the called function \r
+ // wants to spill them; this is important if the function is variadic. \r
+ //\r
+ TopOfStack = BaseOfStack + EFI_SIZE_TO_PAGES (STACK_SIZE) * EFI_PAGE_SIZE - 32;\r
+\r
+ //\r
+ // X64 Calling Conventions requires that the stack must be aligned to 16 bytes\r
+ //\r
+ TopOfStack = (EFI_PHYSICAL_ADDRESS) (UINTN) ALIGN_POINTER (TopOfStack, 16);\r
+ //\r
+ // Load the GDT of Go64. Since the GDT of 32-bit Tiano locates in the BS_DATA\r
+ // memory, it may be corrupted when copying FV to high-end memory \r
+ //\r
+ LoadGo64Gdt();\r
+ //\r
+ // Limit to 36 bits of addressing for debug. Should get it from CPU\r
+ //\r
+ PageTables = CreateIdentityMappingPageTables (36);\r
+ //\r
+ // Go to Long Mode. Interrupts will not get turned on until the CPU AP is loaded.\r
+ // Call x64 drivers passing in single argument, a pointer to the HOBs.\r
+ //\r
+ ActivateLongMode (\r
+ PageTables, \r
+ (EFI_PHYSICAL_ADDRESS)(UINTN)(HobList.Raw), \r
+ TopOfStack,\r
+ 0x00000000,\r
+ DxeCoreEntryPoint\r
+ );\r
+ } else {\r
+ //\r
+ // Add HOB for the EFI Decompress Protocol\r
+ //\r
+ BuildGuidDataHob (\r
+ &gEfiDecompressProtocolGuid,\r
+ (VOID *)&gEfiDecompress,\r
+ sizeof (gEfiDecompress)\r
+ );\r
+\r
+ //\r
+ // Add HOB for the Tiano Decompress Protocol\r
+ //\r
+ BuildGuidDataHob (\r
+ &gEfiTianoDecompressProtocolGuid,\r
+ (VOID *)&gTianoDecompress,\r
+ sizeof (gTianoDecompress)\r
+ );\r
+\r
+ //\r
+ // Add HOB for the user customized Decompress Protocol\r
+ //\r
+ BuildGuidDataHob (\r
+ &gEfiCustomizedDecompressProtocolGuid,\r
+ (VOID *)&gCustomDecompress,\r
+ sizeof (gCustomDecompress)\r
+ );\r
\r
+ //\r
+ // Add HOB for the PE/COFF Loader Protocol\r
+ //\r
+ BuildGuidDataHob (\r
+ &gEfiPeiPeCoffLoaderGuid,\r
+ (VOID *)&PeiEfiPeiPeCoffLoader,\r
+ sizeof (VOID *)\r
+ );\r
+ //\r
+ // Compute the top of the stack we were allocated. Pre-allocate a UINTN\r
+ // for safety.\r
+ //\r
+ TopOfStack = BaseOfStack + EFI_SIZE_TO_PAGES (STACK_SIZE) * EFI_PAGE_SIZE - CPU_STACK_ALIGNMENT;\r
+ TopOfStack = (EFI_PHYSICAL_ADDRESS) (UINTN) ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);\r
+\r
+ SwitchIplStacks (\r
+ (SWITCH_STACK_ENTRY_POINT)(UINTN)DxeCoreEntryPoint,\r
+ HobList.Raw,\r
+ NULL,\r
+ (VOID *) (UINTN) TopOfStack,\r
+ (VOID *) (UINTN) BspStore\r
+ );\r
+ } \r
//\r
// If we get here, then the DXE Core returned. This is an error\r
+ // Dxe Core should not return.\r
//\r
- ASSERT_EFI_ERROR (Status);\r
+ ASSERT (FALSE);\r
+ CpuDeadLoop ();\r
\r
return EFI_OUT_OF_RESOURCES;\r
}\r
FwVolHeader = NULL;\r
FfsFileHeader = NULL;\r
SectionData = NULL;\r
+ Status = EFI_SUCCESS;\r
\r
//\r
- // Foreach Firmware Volume, look for a specified type\r
- // of file and break out when one is found\r
+ // For each Firmware Volume, look for a specified type\r
+ // of file and break out until no one is found \r
//\r
Hob.Raw = GetHobList ();\r
while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_FV, Hob.Raw)) != NULL) {\r
if (!EFI_ERROR (Status)) {\r
Status = PeiProcessFile (\r
SectionType,\r
- &FfsFileHeader,\r
- Pe32Data\r
+ FfsFileHeader,\r
+ Pe32Data,\r
+ &Hob\r
);\r
CopyMem (FileName, &FfsFileHeader->Name, sizeof (EFI_GUID));\r
- return Status;\r
+ if (!EFI_ERROR (Status)) {\r
+ return EFI_SUCCESS;\r
+ }\r
}\r
Hob.Raw = GET_NEXT_HOB (Hob);\r
}\r
\r
while ((Section->Type != EFI_SECTION_PE32) && (Section->Type != EFI_SECTION_TE)) {\r
SectionLength = *(UINT32 *) (Section->Size) & 0x00ffffff;\r
- OccupiedSectionLength = GetOccupiedSize (SectionLength, 4);\r
+ OccupiedSectionLength = GET_OCCUPIED_SIZE (SectionLength, 4);\r
Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) Section + OccupiedSectionLength);\r
}\r
//\r
\r
if (Status == EFI_SUCCESS) {\r
//\r
- // Install PeiInMemory to indicate the Dxeipl is shadowed\r
+ // Set gInMemory global variable to TRUE to indicate the dxeipl is shadowed.\r
//\r
- Status = PeiServicesInstallPpi (&mPpiPeiInMemory);\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
+ *(BOOLEAN *) ((UINTN) &gInMemory + (UINTN) DxeIplEntryPoint - (UINTN) _ModuleEntryPoint) = TRUE;\r
Status = ((EFI_PEIM_ENTRY_POINT) (UINTN) DxeIplEntryPoint) (DxeIplFileHeader, GetPeiServicesTablePointer());\r
}\r
\r
//\r
Status = PeiProcessFile (\r
EFI_SECTION_PE32,\r
- &FfsHeader,\r
- &Pe32Data\r
+ FfsHeader,\r
+ &Pe32Data,\r
+ NULL\r
);\r
\r
if (EFI_ERROR (Status)) {\r
EFI_STATUS\r
PeiProcessFile (\r
IN UINT16 SectionType,\r
- IN OUT EFI_FFS_FILE_HEADER **RealFfsFileHeader,\r
- OUT VOID **Pe32Data\r
+ IN EFI_FFS_FILE_HEADER *FfsFileHeader,\r
+ OUT VOID **Pe32Data,\r
+ IN EFI_PEI_HOB_POINTERS *OrigHob\r
)\r
/*++\r
\r
EFI_GUID TempGuid;\r
EFI_FIRMWARE_VOLUME_HEADER *FvHeader;\r
EFI_COMPRESSION_SECTION *CompressionSection;\r
- EFI_FFS_FILE_HEADER *FfsFileHeader;\r
-\r
- FfsFileHeader = *RealFfsFileHeader;\r
+ UINT32 FvAlignment;\r
\r
Status = PeiServicesFfsFindSectionData (\r
EFI_SECTION_COMPRESSION,\r
);\r
\r
//\r
- // Upon finding a DXE Core file, see if there is first a compression section\r
+ // First process the compression section\r
//\r
if (!EFI_ERROR (Status)) {\r
//\r
\r
do {\r
SectionLength = *(UINT32 *) (Section->Size) & 0x00ffffff;\r
- OccupiedSectionLength = GetOccupiedSize (SectionLength, 4);\r
+ OccupiedSectionLength = GET_OCCUPIED_SIZE (SectionLength, 4);\r
\r
//\r
// Was the DXE Core file encapsulated in a GUID'd section?\r
\r
switch (CompressionSection->CompressionType) {\r
case EFI_STANDARD_COMPRESSION:\r
- DecompressLibrary = &gTianoDecompress;\r
+ if (FeaturePcdGet (PcdDxeIplSupportTianoDecompress)) {\r
+ DecompressLibrary = &gTianoDecompress;\r
+ } else {\r
+ ASSERT (FALSE);\r
+ return EFI_NOT_FOUND;\r
+ }\r
break;\r
\r
case EFI_CUSTOMIZED_COMPRESSION:\r
//\r
// Load user customized compression protocol.\r
//\r
- DecompressLibrary = &gCustomDecompress;\r
+ if (FeaturePcdGet (PcdDxeIplSupportCustomDecompress)) {\r
+ DecompressLibrary = &gCustomDecompress;\r
+ } else {\r
+ ASSERT (FALSE);\r
+ return EFI_NOT_FOUND;\r
+ }\r
break;\r
\r
case EFI_NOT_COMPRESSED:\r
);\r
\r
CmpSection = (EFI_COMMON_SECTION_HEADER *) DstBuffer;\r
- if (CmpSection->Type == EFI_SECTION_RAW) {\r
- //\r
- // Skip the section header and\r
- // adjust the pointer alignment to 16\r
+ if (CmpSection->Type == EFI_SECTION_FIRMWARE_VOLUME_IMAGE) {\r
+ // \r
+ // Firmware Volume Image in this Section\r
+ // Skip the section header to get FvHeader\r
//\r
- FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (DstBuffer + 16);\r
+ FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (CmpSection + 1);\r
\r
- if (FvHeader->Signature == EFI_FVH_SIGNATURE) {\r
- FfsFileHeader = NULL;\r
+ if (FvHeader->Signature == EFI_FVH_SIGNATURE) { \r
+ //\r
+ // Adjust Fv Base Address Alignment based on Align Attributes in Fv Header\r
+ //\r
+ \r
+ //\r
+ // When FvImage support Alignment, we need to check whether \r
+ // its alignment is correct. \r
+ //\r
+ if (FvHeader->Attributes | EFI_FVB_ALIGNMENT_CAP) {\r
+ \r
+ //\r
+ // Calculate the mini alignment for this FvImage\r
+ //\r
+ FvAlignment = 1 << (LowBitSet32 (FvHeader->Attributes >> 16) + 1);\r
+ \r
+ //\r
+ // If current FvImage base address doesn't meet the its alignment,\r
+ // we need to reload this FvImage to another correct memory address.\r
+ //\r
+ if (((UINTN) FvHeader % FvAlignment) != 0) {\r
+ DstBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINTN) FvHeader->FvLength), FvAlignment);\r
+ if (DstBuffer == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ CopyMem (DstBuffer, FvHeader, (UINTN) FvHeader->FvLength);\r
+ FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) DstBuffer; \r
+ }\r
+ }\r
+ //\r
+ // Build new FvHob for new decompressed Fv image.\r
+ //\r
BuildFvHob ((EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader, FvHeader->FvLength);\r
- Status = PeiServicesFfsFindNextFile (\r
- EFI_FV_FILETYPE_DXE_CORE,\r
- FvHeader,\r
- &FfsFileHeader\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return EFI_NOT_FOUND;\r
+ \r
+ //\r
+ // Set the original FvHob to unused.\r
+ //\r
+ if (OrigHob != NULL) {\r
+ OrigHob->Header->HobType = EFI_HOB_TYPE_UNUSED;\r
}\r
-\r
+ \r
//\r
- // Reture the FfsHeader that contain Pe32Data.\r
+ // when search FvImage Section return true.\r
//\r
- *RealFfsFileHeader = FfsFileHeader;\r
- return PeiProcessFile (SectionType, RealFfsFileHeader, Pe32Data);\r
+ if (SectionType == EFI_SECTION_FIRMWARE_VOLUME_IMAGE) {\r
+ *Pe32Data = (VOID *) FvHeader;\r
+ return EFI_SUCCESS;\r
+ } else {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
}\r
}\r
//\r
return EFI_SUCCESS;\r
}\r
\r
- OccupiedCmpSectionLength = GetOccupiedSize (CmpSectionLength, 4);\r
+ OccupiedCmpSectionLength = GET_OCCUPIED_SIZE (CmpSectionLength, 4);\r
CmpSection = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) CmpSection + OccupiedCmpSectionLength);\r
} while (CmpSection->Type != 0 && (UINTN) ((UINT8 *) CmpSection - (UINT8 *) CmpFileData) < CmpFileSize);\r
}\r
+ //\r
+ // End of the decompression activity\r
+ //\r
\r
Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) Section + OccupiedSectionLength);\r
FileSize = FfsFileHeader->Size[0] & 0xFF;\r
FileSize += (FfsFileHeader->Size[2] << 16) & 0xFF0000;\r
FileSize &= 0x00FFFFFF;\r
} while (Section->Type != 0 && (UINTN) ((UINT8 *) Section - (UINT8 *) FfsFileHeader) < FileSize);\r
-\r
+ \r
//\r
- // End of the decompression activity\r
+ // search all sections (compression and non compression) in this FFS, don't \r
+ // find expected section.\r
//\r
+ return EFI_NOT_FOUND;\r
} else {\r
+ //\r
+ // For those FFS that doesn't contain compression section, directly search \r
+ // PE or TE section in this FFS.\r
+ //\r
\r
Status = PeiServicesFfsFindSectionData (\r
EFI_SECTION_PE32,\r
\r
return EFI_SUCCESS;\r
}\r
+\r