diff --git a/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c b/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c index de9dbb0b0e..f5d70c59f8 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c +++ b/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c @@ -305,3 +305,50 @@ LoadDxeCore ( return EFI_SUCCESS; } + +/** + Find DXE core from FV and build DXE core HOBs. + + @param[in] DxeFv The FV where to find the DXE core. + @param[out] DxeCoreEntryPoint DXE core entry point + + @retval EFI_SUCCESS If it completed successfully. + @retval EFI_NOT_FOUND If it failed to load DXE FV. +**/ +EFI_STATUS +UniversalLoadDxeCore ( + IN EFI_FIRMWARE_VOLUME_HEADER *DxeFv, + OUT PHYSICAL_ADDRESS *DxeCoreEntryPoint + ) +{ + EFI_STATUS Status; + EFI_FFS_FILE_HEADER *FileHeader; + VOID *PeCoffImage; + EFI_PHYSICAL_ADDRESS ImageAddress; + UINT64 ImageSize; + + // + // Find DXE core file from DXE FV + // + Status = FvFindFile (DxeFv, EFI_FV_FILETYPE_DXE_CORE, &FileHeader); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = FileFindSection (FileHeader, EFI_SECTION_PE32, (VOID **)&PeCoffImage); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Get DXE core info + // + Status = LoadPeCoffImage (PeCoffImage, &ImageAddress, &ImageSize, DxeCoreEntryPoint); + if (EFI_ERROR (Status)) { + return Status; + } + + BuildModuleHob (&FileHeader->Name, ImageAddress, EFI_SIZE_TO_PAGES ((UINT32) ImageSize) * EFI_PAGE_SIZE, *DxeCoreEntryPoint); + + return EFI_SUCCESS; +} diff --git a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h index 1ad7a37023..dff7b6b87f 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h +++ b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h @@ -33,6 +33,8 @@ #include #include #include +#include +#include #define LEGACY_8259_MASK_REGISTER_MASTER 0x21 #define LEGACY_8259_MASK_REGISTER_SLAVE 0xA1 @@ -127,6 +129,21 @@ LoadDxeCore ( OUT PHYSICAL_ADDRESS *DxeCoreEntryPoint ); +/** + Find DXE core from FV and build DXE core HOBs. + + @param[in] DxeFv The FV where to find the DXE core. + @param[out] DxeCoreEntryPoint DXE core entry point + + @retval EFI_SUCCESS If it completed successfully. + @retval EFI_NOT_FOUND If it failed to load DXE FV. +**/ +EFI_STATUS +UniversalLoadDxeCore ( + IN EFI_FIRMWARE_VOLUME_HEADER *DxeFv, + OUT PHYSICAL_ADDRESS *DxeCoreEntryPoint + ); + /** Transfers control to DxeCore. diff --git a/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.c b/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.c index 66e87bcb9b..13f4587cd9 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.c +++ b/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.c @@ -179,7 +179,8 @@ FindAnotherHighestBelow4GResourceDescriptor ( **/ EFI_STATUS BuildHobs ( - IN UINTN BootloaderParameter + IN UINTN BootloaderParameter, + OUT EFI_FIRMWARE_VOLUME_HEADER **DxeFv ) { EFI_PEI_HOB_POINTERS Hob; @@ -190,6 +191,9 @@ BuildHobs ( EFI_PHYSICAL_ADDRESS MemoryTop; EFI_HOB_RESOURCE_DESCRIPTOR *PhitResourceHob; EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob; + UNIVERSAL_PAYLOAD_EXTRA_DATA *ExtraData; + UINT8 *GuidHob; + EFI_HOB_FIRMWARE_VOLUME *FvHob; Hob.Raw = (UINT8 *) BootloaderParameter; MinimalNeededSize = FixedPcdGet32 (PcdSystemMemoryUefiRegionSize); @@ -254,6 +258,10 @@ BuildHobs ( // From now on, mHobList will point to the new Hob range. // + // + // Create an empty FvHob for the DXE FV that contains DXE core. + // + BuildFvHob ((EFI_PHYSICAL_ADDRESS) 0, 0); // // Since payload created new Hob, move all hobs except PHIT from boot loader hob list. // @@ -265,6 +273,25 @@ BuildHobs ( Hob.Raw = GET_NEXT_HOB (Hob); } + // + // Get DXE FV location + // + GuidHob = GetFirstGuidHob(&gUniversalPayloadExtraDataGuid); + ASSERT (GuidHob != NULL); + ExtraData = (UNIVERSAL_PAYLOAD_EXTRA_DATA *) GET_GUID_HOB_DATA (GuidHob); + ASSERT (ExtraData->Count == 1); + ASSERT (AsciiStrCmp (ExtraData->Entry[0].Identifier, "uefi_fv") == 0); + + *DxeFv = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) ExtraData->Entry[0].Base; + ASSERT ((*DxeFv)->FvLength == ExtraData->Entry[0].Size); + + // + // Update DXE FV information to first fv hob in the hob list, which + // is the empty FvHob created before. + // + FvHob = GetFirstHob (EFI_HOB_TYPE_FV); + FvHob->BaseAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) *DxeFv; + FvHob->Length = (*DxeFv)->FvLength; return EFI_SUCCESS; } @@ -280,10 +307,13 @@ _ModuleEntryPoint ( ) { EFI_STATUS Status; + PHYSICAL_ADDRESS DxeCoreEntryPoint; EFI_HOB_HANDOFF_INFO_TABLE *HandoffHobTable; EFI_PEI_HOB_POINTERS Hob; + EFI_FIRMWARE_VOLUME_HEADER *DxeFv; mHobList = (VOID *) BootloaderParameter; + DxeFv = NULL; // Call constructor for all libraries ProcessLibraryConstructorList (); @@ -294,7 +324,11 @@ _ModuleEntryPoint ( InitializeFloatingPointUnits (); // Build HOB based on information from Bootloader - Status = BuildHobs (BootloaderParameter); + Status = BuildHobs (BootloaderParameter, &DxeFv); + ASSERT_EFI_ERROR (Status); + + Status = UniversalLoadDxeCore (DxeFv, &DxeCoreEntryPoint); + ASSERT_EFI_ERROR (Status); // // Mask off all legacy 8259 interrupt sources @@ -304,6 +338,7 @@ _ModuleEntryPoint ( HandoffHobTable = (EFI_HOB_HANDOFF_INFO_TABLE *) GetFirstHob(EFI_HOB_TYPE_HANDOFF); Hob.HandoffInformationTable = HandoffHobTable; + HandOffToDxeCore (DxeCoreEntryPoint, Hob); // Should not get here CpuDeadLoop (); diff --git a/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf b/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf index 58ff87d969..77cd25aafd 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf +++ b/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf @@ -62,6 +62,7 @@ gEfiSmbiosTableGuid gEfiAcpiTableGuid gUefiSerialPortInfoGuid + gUniversalPayloadExtraDataGuid [FeaturePcd.IA32] gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode ## CONSUMES diff --git a/UefiPayloadPkg/UefiPayloadEntry/X64/DxeLoadFunc.c b/UefiPayloadPkg/UefiPayloadEntry/X64/DxeLoadFunc.c index 73ea30e7a2..dec87ee1ef 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/X64/DxeLoadFunc.c +++ b/UefiPayloadPkg/UefiPayloadEntry/X64/DxeLoadFunc.c @@ -66,8 +66,8 @@ HandOffToDxeCore ( // // Get the address and size of the GHCB pages // - GhcbBase = (VOID *) PcdGet64 (PcdGhcbBase); - GhcbSize = PcdGet64 (PcdGhcbSize); + GhcbBase = 0; + GhcbSize = 0; PageTables = 0; if (FeaturePcdGet (PcdDxeIplBuildPageTables)) {