\r
#include "DxeIpl.h"\r
\r
-#ifndef __GNUC__\r
-#pragma warning( disable : 4305 )\r
-#endif\r
-\r
BOOLEAN gInMemory = FALSE;\r
\r
//\r
--*/\r
{\r
EFI_STATUS Status;\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
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 = 0;\r
- BaseOfStack = 0;\r
- BspStore = 0;\r
- PageTables = 0;\r
\r
//\r
// if in S3 Resume, restore configure\r
PeiEfiPeiPeCoffLoader = (EFI_PEI_PE_COFF_LOADER_PROTOCOL *)GetPeCoffLoaderProtocol ();\r
ASSERT (PeiEfiPeiPeCoffLoader != NULL);\r
\r
- //\r
- // Allocate 128KB for the Stack\r
- //\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
- ASSERT_EFI_ERROR (Status);\r
\r
//\r
// Find the EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE type compressed Firmware Volume file\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
-\r
- Status = PeiServicesInstallPpi (&mPpiSignal);\r
- ASSERT_EFI_ERROR (Status);\r
-\r
//\r
// Add HOB for the DXE Core\r
//\r
EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_CORE_PC_HANDOFF_TO_NEXT\r
);\r
\r
- DEBUG ((EFI_D_INFO, "DXE Core Entry\n"));\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
+ if (FeaturePcdGet (PcdDxeIplBuildShareCodeHobs)) {\r
+ if (FeaturePcdGet (PcdDxeIplSupportEfiDecompress)) {\r
+ //\r
+ // Add HOB for the EFI Decompress Protocol\r
+ //\r
+ BuildGuidDataHob (\r
+ &gEfiDecompressProtocolGuid,\r
+ (VOID *)&gEfiDecompress,\r
+ sizeof (gEfiDecompress)\r
+ );\r
+ }\r
+ if (FeaturePcdGet (PcdDxeIplSupportTianoDecompress)) {\r
+ //\r
+ // Add HOB for the Tiano Decompress Protocol\r
+ //\r
+ BuildGuidDataHob (\r
+ &gEfiTianoDecompressProtocolGuid,\r
+ (VOID *)&gTianoDecompress,\r
+ sizeof (gTianoDecompress)\r
+ );\r
+ }\r
+ if (FeaturePcdGet (PcdDxeIplSupportCustomDecompress)) {\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
//\r
// Add HOB for the PE/COFF Loader Protocol\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
+\r
+ //\r
+ // Transfer control to the DXE Core\r
+ // The handoff state is simply a pointer to the HOB list\r
+ //\r
+\r
+ DEBUG ((EFI_D_INFO, "DXE Core Entry Point 0x%08x\n", (UINTN) DxeCoreEntryPoint));\r
+ HandOffToDxeCore (DxeCoreEntryPoint, HobList, &mPpiSignal);\r
//\r
// If we get here, then the DXE Core returned. This is an error\r
// Dxe Core should not return.\r
{\r
EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;\r
EFI_FFS_FILE_HEADER *FfsFileHeader;\r
- VOID *SectionData;\r
EFI_STATUS Status;\r
EFI_PEI_HOB_POINTERS Hob;\r
\r
\r
FwVolHeader = NULL;\r
FfsFileHeader = NULL;\r
- SectionData = NULL;\r
Status = EFI_SUCCESS;\r
\r
//\r
&Hob\r
);\r
CopyMem (FileName, &FfsFileHeader->Name, sizeof (EFI_GUID));\r
- if (!EFI_ERROR (Status)) {\r
+ //\r
+ // Find all Fv type ffs to get all FvImage and add them into FvHob\r
+ //\r
+ if (!EFI_ERROR (Status) && (Type != EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE)) {\r
return EFI_SUCCESS;\r
}\r
}\r
UINTN SectionLength;\r
UINTN OccupiedSectionLength;\r
UINT64 FileSize;\r
- EFI_GUID_DEFINED_SECTION *GuidedSectionHeader;\r
UINT32 AuthenticationStatus;\r
EFI_PEI_SECTION_EXTRACTION_PPI *SectionExtract;\r
UINT32 BufferSize;\r
EFI_GUID TempGuid;\r
EFI_FIRMWARE_VOLUME_HEADER *FvHeader;\r
EFI_COMPRESSION_SECTION *CompressionSection;\r
- UINT32 FvAlignment;\r
+\r
+ //\r
+ // Initialize local variables.\r
+ //\r
+ DecompressLibrary = NULL;\r
+ DstBuffer = NULL;\r
+ DstBufferSize = 0;\r
\r
Status = PeiServicesFfsFindSectionData (\r
EFI_SECTION_COMPRESSION,\r
// Was the DXE Core file encapsulated in a GUID'd section?\r
//\r
if (Section->Type == EFI_SECTION_GUID_DEFINED) {\r
- //\r
- // Locate the GUID'd Section Extractor\r
- //\r
- GuidedSectionHeader = (VOID *) (Section + 1);\r
\r
//\r
// This following code constitutes the addition of the security model\r
\r
switch (CompressionSection->CompressionType) {\r
case EFI_STANDARD_COMPRESSION:\r
+ //\r
+ // Load EFI standard compression.\r
+ //\r
if (FeaturePcdGet (PcdDxeIplSupportTianoDecompress)) {\r
- DecompressLibrary = &gTianoDecompress;\r
+ DecompressLibrary = &gEfiDecompress;\r
} else {\r
ASSERT (FALSE);\r
return EFI_NOT_FOUND;\r
\r
case EFI_CUSTOMIZED_COMPRESSION:\r
//\r
- // Load user customized compression protocol.\r
+ // Load user customized compression.\r
//\r
if (FeaturePcdGet (PcdDxeIplSupportCustomDecompress)) {\r
DecompressLibrary = &gCustomDecompress;\r
break;\r
\r
case EFI_NOT_COMPRESSED:\r
- default:\r
//\r
- // Need to support not compressed file\r
+ // Allocate destination buffer\r
//\r
- ASSERT_EFI_ERROR (Status);\r
- return EFI_NOT_FOUND;\r
- }\r
+ DstBufferSize = CompressionSection->UncompressedLength;\r
+ DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize));\r
+ if (DstBuffer == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ //\r
+ // stream is not actually compressed, just encapsulated. So just copy it.\r
+ //\r
+ CopyMem (DstBuffer, CompressionSection + 1, DstBufferSize);\r
+ break;\r
\r
- Status = DecompressLibrary->GetInfo (\r
- (UINT8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),\r
- (UINT32) SectionLength - sizeof (EFI_COMPRESSION_SECTION),\r
- &DstBufferSize,\r
- &ScratchBufferSize\r
- );\r
- if (EFI_ERROR (Status)) {\r
+ default:\r
//\r
- // GetInfo failed\r
+ // Don't support other unknown compression type.\r
//\r
+ ASSERT_EFI_ERROR (Status);\r
return EFI_NOT_FOUND;\r
}\r
-\r
- //\r
- // Allocate scratch buffer\r
- //\r
- ScratchBuffer = AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize));\r
- if (ScratchBuffer == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- //\r
- // Allocate destination buffer\r
- //\r
- DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize));\r
- if (DstBuffer == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- //\r
- // Call decompress function\r
- //\r
- Status = DecompressLibrary->Decompress (\r
- (CHAR8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),\r
- DstBuffer,\r
- ScratchBuffer\r
- );\r
-\r
- CmpSection = (EFI_COMMON_SECTION_HEADER *) DstBuffer;\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
+ if (CompressionSection->CompressionType != EFI_NOT_COMPRESSED) {\r
//\r
- FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (CmpSection + 1);\r
-\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
- \r
+ // For compressed data, decompress them to dstbuffer.\r
+ //\r
+ Status = DecompressLibrary->GetInfo (\r
+ (UINT8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),\r
+ (UINT32) SectionLength - sizeof (EFI_COMPRESSION_SECTION),\r
+ &DstBufferSize,\r
+ &ScratchBufferSize\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
//\r
- // Set the original FvHob to unused.\r
+ // GetInfo failed\r
//\r
- if (OrigHob != NULL) {\r
- OrigHob->Header->HobType = EFI_HOB_TYPE_UNUSED;\r
- }\r
- \r
+ DEBUG ((EFI_D_ERROR, "Decompress GetInfo Failed - %r\n", Status));\r
+ return EFI_NOT_FOUND;\r
+ }\r
+ \r
+ //\r
+ // Allocate scratch buffer\r
+ //\r
+ ScratchBuffer = AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize));\r
+ if (ScratchBuffer == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ \r
+ //\r
+ // Allocate destination buffer\r
+ //\r
+ DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize));\r
+ if (DstBuffer == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ \r
+ //\r
+ // Call decompress function\r
+ //\r
+ Status = DecompressLibrary->Decompress (\r
+ (CHAR8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),\r
+ DstBuffer,\r
+ ScratchBuffer\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
//\r
- // when search FvImage Section return true.\r
+ // Decompress failed\r
//\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
+ DEBUG ((EFI_D_ERROR, "Decompress Failed - %r\n", Status));\r
+ return EFI_NOT_FOUND;\r
}\r
}\r
+\r
//\r
// Decompress successfully.\r
// Loop the decompressed data searching for expected section.\r
//\r
+ CmpSection = (EFI_COMMON_SECTION_HEADER *) DstBuffer;\r
CmpFileData = (VOID *) DstBuffer;\r
CmpFileSize = DstBufferSize;\r
do {\r
CmpSectionLength = *(UINT32 *) (CmpSection->Size) & 0x00ffffff;\r
- if (CmpSection->Type == EFI_SECTION_PE32) {\r
+ if (CmpSection->Type == SectionType) {\r
//\r
// This is what we want\r
//\r
- *Pe32Data = (VOID *) (CmpSection + 1);\r
- return EFI_SUCCESS;\r
- }\r
+ if (SectionType == EFI_SECTION_PE32) {\r
+ *Pe32Data = (VOID *) (CmpSection + 1);\r
+ return EFI_SUCCESS;\r
+ } else if (SectionType == 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 *) (CmpSection + 1);\r
+ \r
+ if (FvHeader->Signature == EFI_FVH_SIGNATURE) {\r
+ //\r
+ // Because FvLength in FvHeader is UINT64 type, \r
+ // so FvHeader must meed at least 8 bytes alignment.\r
+ // If current FvImage base address doesn't meet its alignment,\r
+ // we need to reload this FvImage to another correct memory address.\r
+ //\r
+ if (((UINTN) FvHeader % sizeof (UINT64)) != 0) {\r
+ DstBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINTN) CmpSectionLength - sizeof (EFI_COMMON_SECTION_HEADER)), sizeof (UINT64));\r
+ if (DstBuffer == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ CopyMem (DstBuffer, FvHeader, (UINTN) CmpSectionLength - sizeof (EFI_COMMON_SECTION_HEADER));\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
+ \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
+ // return found FvImage data.\r
+ //\r
+ *Pe32Data = (VOID *) FvHeader;\r
+ return EFI_SUCCESS;\r
+ }\r
+ }\r
+ }\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