}\r
}\r
} else {\r
- ASSERT_EFI_ERROR (FALSE);\r
+ ASSERT (FALSE);\r
}\r
}\r
\r
//\r
- // Install FvFileLoader and DxeIpl PPIs.\r
+ // Install DxeIpl and Decompress PPIs.\r
//\r
Status = PeiServicesInstallPpi (mPpiList);\r
- ASSERT_EFI_ERROR(Status); \r
- \r
+ ASSERT_EFI_ERROR(Status);\r
+\r
return Status;\r
}\r
\r
UINT64 DxeCoreSize;\r
EFI_PHYSICAL_ADDRESS DxeCoreEntryPoint;\r
EFI_BOOT_MODE BootMode;\r
- EFI_PEI_FV_HANDLE VolumeHandle;\r
EFI_PEI_FILE_HANDLE FileHandle;\r
- UINTN Instance;\r
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI *Variable;\r
+ UINTN DataSize;\r
+ EFI_MEMORY_TYPE_INFORMATION MemoryData [EfiMaxMemoryType + 1];\r
\r
//\r
// if in S3 Resume, restore configure\r
// Now should have a HOB with the DXE core w/ the old HOB destroyed\r
//\r
}\r
- \r
- //\r
- // If any FV contains an encapsulated FV extract that FV\r
- //\r
- DxeIplAddEncapsulatedFirmwareVolumes ();\r
- \r
+\r
+ Status = PeiServicesLocatePpi (\r
+ &gEfiPeiReadOnlyVariable2PpiGuid,\r
+ 0,\r
+ NULL,\r
+ (VOID **)&Variable\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ DataSize = sizeof (MemoryData);\r
+ Status = Variable->GetVariable ( \r
+ Variable, \r
+ EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME,\r
+ &gEfiMemoryTypeInformationGuid,\r
+ NULL,\r
+ &DataSize,\r
+ &MemoryData\r
+ );\r
+\r
+ if (!EFI_ERROR (Status)) {\r
+ //\r
+ // Build the GUID'd HOB for DXE\r
+ //\r
+ BuildGuidDataHob (\r
+ &gEfiMemoryTypeInformationGuid,\r
+ MemoryData,\r
+ DataSize\r
+ );\r
+ }\r
+\r
//\r
// Look in all the FVs present in PEI and find the DXE Core\r
//\r
- Instance = 0;\r
- Status = DxeIplFindFirmwareVolumeInstance (&Instance, EFI_FV_FILETYPE_DXE_CORE, &VolumeHandle, &FileHandle);\r
+ FileHandle = NULL;\r
+ Status = DxeIplFindDxeCore (&FileHandle);\r
ASSERT_EFI_ERROR (Status);\r
\r
CopyMem(&DxeCoreFileName, &(((EFI_FFS_FILE_HEADER*)FileHandle)->Name), sizeof (EFI_GUID));\r
\r
//\r
- // Load the DXE Core from a Firmware Volume\r
+ // Load the DXE Core from a Firmware Volume, may use LoadFile ppi to do this for save code size.\r
//\r
Status = PeiLoadFile (\r
FileHandle,\r
EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_CORE_PC_HANDOFF_TO_NEXT\r
);\r
\r
+ DEBUG_CODE_BEGIN ();\r
+\r
+ EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION PtrPeImage;\r
+ PtrPeImage.Pe32 = (EFI_IMAGE_NT_HEADERS32 *) ((UINTN) DxeCoreAddress + ((EFI_IMAGE_DOS_HEADER *) (UINTN) DxeCoreAddress)->e_lfanew);\r
+ \r
+ if (PtrPeImage.Pe32->FileHeader.Machine != IMAGE_FILE_MACHINE_IA64) {\r
+ DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Loading DXE CORE at 0x%10p EntryPoint=0x%10p\n", (VOID *)(UINTN)DxeCoreAddress, (VOID *)(UINTN)DxeCoreEntryPoint));\r
+ } else {\r
+ //\r
+ // For IPF Image, the real entry point should be print.\r
+ //\r
+ DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Loading DXE CORE at 0x%10p EntryPoint=0x%10p\n", (VOID *)(UINTN)DxeCoreAddress, (VOID *)(UINTN)(*(UINT64 *)(UINTN)DxeCoreEntryPoint)));\r
+ }\r
+\r
+ DEBUG_CODE_END ();\r
//\r
// Transfer control to the DXE Core\r
// The handoff state is simply a pointer to the HOB list\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
return EFI_OUT_OF_RESOURCES;\r
}\r
\r
-\r
-STATIC\r
-EFI_STATUS\r
-GetFvAlignment (\r
- IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader,\r
- OUT UINT32 *FvAlignment\r
- )\r
-{\r
- //\r
- // Because FvLength in FvHeader is UINT64 type, \r
- // so FvHeader must meed at least 8 bytes alignment.\r
- // Get the appropriate alignment requirement.\r
- // \r
- if ((FvHeader->Attributes & EFI_FVB2_ALIGNMENT) < EFI_FVB2_ALIGNMENT_8) {\r
- return EFI_UNSUPPORTED;\r
- }\r
- \r
- *FvAlignment = 1 << ((FvHeader->Attributes & EFI_FVB2_ALIGNMENT) >> 16);\r
- return EFI_SUCCESS;\r
-}\r
-\r
/**\r
- Search EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE image and expand \r
- as memory FV \r
- \r
- @return EFI_OUT_OF_RESOURCES There are no memory space to exstract FV\r
- @return EFI_SUCESS Sucess to find the FV \r
-**/\r
-EFI_STATUS\r
-DxeIplAddEncapsulatedFirmwareVolumes (\r
- VOID\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_STATUS VolumeStatus;\r
- UINTN Index;\r
- EFI_FV_INFO VolumeInfo; \r
- EFI_PEI_FV_HANDLE VolumeHandle;\r
- EFI_PEI_FILE_HANDLE FileHandle;\r
- UINT32 SectionLength;\r
- EFI_FIRMWARE_VOLUME_HEADER *FvHeader;\r
- EFI_FIRMWARE_VOLUME_IMAGE_SECTION *SectionHeader;\r
- VOID *DstBuffer;\r
- UINT32 FvAlignment;\r
-\r
- Status = EFI_NOT_FOUND;\r
- Index = 0;\r
+ Find DxeCore driver from all First Volumes.\r
\r
- do {\r
- VolumeStatus = DxeIplFindFirmwareVolumeInstance (\r
- &Index, \r
- EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE, \r
- &VolumeHandle, \r
- &FileHandle\r
- );\r
- \r
- if (!EFI_ERROR (VolumeStatus)) {\r
- Status = PeiServicesFfsFindSectionData (\r
- EFI_SECTION_FIRMWARE_VOLUME_IMAGE, \r
- (EFI_FFS_FILE_HEADER *)FileHandle, \r
- (VOID **)&FvHeader\r
- );\r
- \r
- if (!EFI_ERROR (Status)) {\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
- Status = GetFvAlignment(FvHeader, &FvAlignment); \r
- if (EFI_ERROR(Status)) {\r
- return Status;\r
- }\r
- if (((UINTN) FvHeader % FvAlignment) != 0) {\r
- SectionHeader = (EFI_FIRMWARE_VOLUME_IMAGE_SECTION*)((UINTN)FvHeader - sizeof(EFI_FIRMWARE_VOLUME_IMAGE_SECTION));\r
- SectionLength = *(UINT32 *)SectionHeader->Size & 0x00FFFFFF;\r
- \r
- DstBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINTN) SectionLength - sizeof (EFI_COMMON_SECTION_HEADER)), FvAlignment);\r
- if (DstBuffer == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- CopyMem (DstBuffer, FvHeader, (UINTN) SectionLength - sizeof (EFI_COMMON_SECTION_HEADER));\r
- FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) DstBuffer; \r
- }\r
-\r
- //\r
- // This new Firmware Volume comes from a firmware file within a firmware volume.\r
- // Record the original Firmware Volume Name.\r
- //\r
- PeiServicesFfsGetVolumeInfo (&VolumeHandle, &VolumeInfo);\r
-\r
- PiLibInstallFvInfoPpi (\r
- NULL,\r
- FvHeader,\r
- (UINT32) FvHeader->FvLength,\r
- &(VolumeInfo.FvName),\r
- &(((EFI_FFS_FILE_HEADER*)FileHandle)->Name)\r
- );\r
-\r
- //\r
- // Inform HOB consumer phase, i.e. DXE core, the existance of this FV\r
- //\r
- BuildFvHob (\r
- (EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader,\r
- FvHeader->FvLength\r
- );\r
- \r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // Makes the encapsulated volume show up in DXE phase to skip processing of\r
- // encapsulated file again.\r
- //\r
- BuildFv2Hob (\r
- (EFI_PHYSICAL_ADDRESS)(UINTN)FvHeader,\r
- FvHeader->FvLength, \r
- &VolumeInfo.FvName,\r
- &(((EFI_FFS_FILE_HEADER *)FileHandle)->Name)\r
- );\r
- return Status;\r
- }\r
- }\r
- }\r
- } while (!EFI_ERROR (VolumeStatus));\r
- \r
- return Status;\r
-}\r
-\r
-/**\r
- Find the First Volume that contains the first FileType.\r
-\r
- @param Instance The Fv instance.\r
- @param SeachType The type of file to search.\r
- @param VolumeHandle Pointer to Fv which contains the file to search. \r
@param FileHandle Pointer to FFS file to search.\r
\r
@return EFI_SUCESS Success to find the FFS in specificed FV\r
@return others Fail to find the FFS in specificed FV\r
*/\r
EFI_STATUS\r
-DxeIplFindFirmwareVolumeInstance (\r
- IN OUT UINTN *Instance,\r
- IN EFI_FV_FILETYPE SeachType,\r
- OUT EFI_PEI_FV_HANDLE *VolumeHandle,\r
+DxeIplFindDxeCore (\r
OUT EFI_PEI_FILE_HANDLE *FileHandle\r
)\r
{\r
- EFI_STATUS Status;\r
- EFI_STATUS VolumeStatus;\r
+ EFI_STATUS Status;\r
+ EFI_STATUS FileStatus;\r
+ UINTN Instance;\r
+ EFI_PEI_FV_HANDLE VolumeHandle;\r
+ \r
+ Instance = 0;\r
+ *FileHandle = NULL;\r
\r
do {\r
- VolumeStatus = PeiServicesFfsFindNextVolume (*Instance, VolumeHandle);\r
- if (!EFI_ERROR (VolumeStatus)) {\r
- *FileHandle = NULL;\r
- Status = PeiServicesFfsFindNextFile (SeachType, *VolumeHandle, FileHandle);\r
- if (!EFI_ERROR (Status)) {\r
- return Status;\r
+ Status = PeiServicesFfsFindNextVolume (Instance++, &VolumeHandle);\r
+ if (!EFI_ERROR (Status)) {\r
+ FileStatus = PeiServicesFfsFindNextFile (EFI_FV_FILETYPE_DXE_CORE, VolumeHandle, FileHandle);\r
+ if (!EFI_ERROR (FileStatus)) {\r
+ return FileStatus;\r
}\r
}\r
- *Instance += 1;\r
- } while (!EFI_ERROR (VolumeStatus));\r
+ } while (!EFI_ERROR (Status));\r
\r
- return VolumeStatus;\r
+ return EFI_NOT_FOUND;\r
}\r
\r
/**\r
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
VOID *Pe32Data;\r
//\r
- // First try to find the required section in this ffs file.\r
+ // First try to find the PE32 section in this ffs file.\r
//\r
Status = PeiServicesFfsFindSectionData (\r
EFI_SECTION_PE32,\r
FileHandle,\r
&Pe32Data\r
);\r
-\r
- if (EFI_ERROR (Status)) {\r
- Status = PeiServicesFfsFindSectionData (\r
- EFI_SECTION_TE,\r
- FileHandle,\r
- &Pe32Data\r
- );\r
- }\r
\r
if (EFI_ERROR (Status)) {\r
//\r
ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) AllocatePages (EFI_SIZE_TO_PAGES ((UINT32) ImageContext.ImageSize));\r
ASSERT (ImageContext.ImageAddress != 0);\r
\r
- //\r
- // Skip the reserved space for the stripped PeHeader when load TeImage into memory.\r
- //\r
- if (ImageContext.IsTeImage) {\r
- ImageContext.ImageAddress = ImageContext.ImageAddress + \r
- ((EFI_TE_IMAGE_HEADER *) Pe32Data)->StrippedSize -\r
- sizeof (EFI_TE_IMAGE_HEADER);\r
- }\r
-\r
//\r
// Load the image to our new buffer\r
//\r
//\r
// Allocate output buffer\r
//\r
- *OutputBuffer = AllocatePages (EFI_SIZE_TO_PAGES (OutputBufferSize));\r
+ *OutputBuffer = AllocatePages (EFI_SIZE_TO_PAGES (OutputBufferSize) + 1);\r
if (*OutputBuffer == NULL) {\r
return EFI_OUT_OF_RESOURCES;\r
}\r
+ DEBUG ((EFI_D_INFO, "Customed Guided section Memory Size required is 0x%x and address is 0x%p\n", OutputBufferSize, *OutputBuffer));\r
+ //\r
+ // *OutputBuffer still is one section. Adjust *OutputBuffer offset, \r
+ // skip EFI section header to make section data at page alignment.\r
+ //\r
+ *OutputBuffer = (VOID *)((UINT8 *) *OutputBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER));\r
}\r
\r
Status = ExtractGuidedSectionDecode (\r
return EFI_OUT_OF_RESOURCES;\r
}\r
//\r
- // Allocate destination buffer\r
+ // Allocate destination buffer, extra one page for adjustment \r
//\r
- DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize));\r
+ DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize) + 1);\r
if (DstBuffer == NULL) {\r
return EFI_OUT_OF_RESOURCES;\r
}\r
//\r
+ // DstBuffer still is one section. Adjust DstBuffer offset, skip EFI section header\r
+ // to make section data at page alignment.\r
+ //\r
+ DstBuffer = DstBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER);\r
+ //\r
// Call decompress function\r
//\r
Status = UefiDecompress (\r
}\r
break;\r
\r
- // porting note the original branch for customized compress is removed, it should be change to use GUID compress\r
-\r
case EFI_NOT_COMPRESSED:\r
//\r
// Allocate destination buffer\r
//\r
DstBufferSize = CompressionSection->UncompressedLength;\r
- DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize));\r
+ DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize) + 1);\r
if (DstBuffer == NULL) {\r
return EFI_OUT_OF_RESOURCES;\r
}\r
//\r
+ // Adjust DstBuffer offset, skip EFI section header\r
+ // to make section data at page alignment.\r
+ //\r
+ DstBuffer = DstBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER);\r
+ //\r
// stream is not actually compressed, just encapsulated. So just copy it.\r
//\r
CopyMem (DstBuffer, CompressionSection + 1, DstBufferSize);\r
return EFI_SUCCESS;\r
}\r
\r
+VOID\r
+UpdateStackHob (\r
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
+ IN UINT64 Length\r
+ )\r
+{\r
+ EFI_PEI_HOB_POINTERS Hob;\r
+\r
+ Hob.Raw = GetHobList ();\r
+ while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw)) != NULL) {\r
+ if (CompareGuid (&gEfiHobMemoryAllocStackGuid, &(Hob.MemoryAllocationStack->AllocDescriptor.Name))) {\r
+ //\r
+ // Build a new memory allocation HOB with old stack info with EfiConventionalMemory type\r
+ // to be reclaimed by DXE core.\r
+ //\r
+ BuildMemoryAllocationHob (\r
+ Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress,\r
+ Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength,\r
+ EfiConventionalMemory\r
+ );\r
+ //\r
+ // Update the BSP Stack Hob to reflect the new stack info.\r
+ //\r
+ Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress = BaseAddress;\r
+ Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength = Length;\r
+ break;\r
+ }\r
+ Hob.Raw = GET_NEXT_HOB (Hob);\r
+ }\r
+}\r