Reviewed-by: Guo Dong <guo.d...@intel.com>
> -----Original Message----- > From: Liu, Zhiguang <zhiguang....@intel.com> > Sent: Sunday, June 20, 2021 8:47 AM > To: devel@edk2.groups.io > Cc: Ma, Maurice <maurice...@intel.com>; Dong, Guo > <guo.d...@intel.com>; You, Benjamin <benjamin....@intel.com> > Subject: [PATCH 05/12] UefiPayloadPkg: Create separate Payload Entry for > UniversalPayload > > This patch create the UniversalPayload Entry based on the UefiPayload > Entry. It implements the logic to find a proper memory range to create the > new Hob and migrate the Hobs from Bootloader. > To make the change history clear, the logic to get the DxeCore will be in > the next patch. > > Cc: Maurice Ma <maurice...@intel.com> > Cc: Guo Dong <guo.d...@intel.com> > Cc: Benjamin You <benjamin....@intel.com> > Signed-off-by: Zhiguang Liu <zhiguang....@intel.com> > --- > UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.c | 311 > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > +++++++++++++++++++++ > UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf | 91 > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > +++++++++++++++++++++++++++++++++ > 2 files changed, 402 insertions(+) > > diff --git a/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.c > b/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.c > new file mode 100644 > index 0000000000..66e87bcb9b > --- /dev/null > +++ b/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.c > @@ -0,0 +1,311 @@ > +/** @file > > + > > + Copyright (c) 2021, Intel Corporation. All rights reserved.<BR> > > + SPDX-License-Identifier: BSD-2-Clause-Patent > > + > > +**/ > > + > > +#include "UefiPayloadEntry.h" > > + > > +#define MEMORY_ATTRIBUTE_MASK > (EFI_RESOURCE_ATTRIBUTE_PRESENT | \ > > + EFI_RESOURCE_ATTRIBUTE_INITIALIZED > | \ > > + EFI_RESOURCE_ATTRIBUTE_TESTED > | \ > > + EFI_RESOURCE_ATTRIBUTE_READ_PROTECTED > | \ > > + > EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED | \ > > + > EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTED | \ > > + > EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTED | > \ > > + EFI_RESOURCE_ATTRIBUTE_16_BIT_IO > | \ > > + EFI_RESOURCE_ATTRIBUTE_32_BIT_IO > | \ > > + EFI_RESOURCE_ATTRIBUTE_64_BIT_IO > | \ > > + EFI_RESOURCE_ATTRIBUTE_PERSISTENT > ) > > + > > +#define TESTED_MEMORY_ATTRIBUTES > (EFI_RESOURCE_ATTRIBUTE_PRESENT | \ > > + EFI_RESOURCE_ATTRIBUTE_INITIALIZED | \ > > + EFI_RESOURCE_ATTRIBUTE_TESTED ) > > + > > +extern VOID *mHobList; > > + > > +/** > > + Add HOB into HOB list > > + > > + @param[in] Hob The HOB to be added into the HOB list. > > +**/ > > +VOID > > +AddNewHob ( > > + IN EFI_PEI_HOB_POINTERS *Hob > > + ) > > +{ > > + EFI_PEI_HOB_POINTERS NewHob; > > + > > + if (Hob->Raw == NULL) { > > + return; > > + } > > + NewHob.Header = CreateHob (Hob->Header->HobType, Hob->Header- > >HobLength); > > + > > + if (NewHob.Header != NULL) { > > + CopyMem (NewHob.Header + 1, Hob->Header + 1, Hob->Header- > >HobLength - sizeof (EFI_HOB_GENERIC_HEADER)); > > + } > > +} > > + > > +/** > > + Found the Resource Descriptor HOB that contains a range > > + > > + @param[in] Base Memory start address > > + @param[in] Top Memory Top. > > + > > + @return The pointer to the Resource Descriptor HOB. > > +**/ > > +EFI_HOB_RESOURCE_DESCRIPTOR * > > +FindResourceDescriptorByRange ( > > + VOID *HobList, > > + EFI_PHYSICAL_ADDRESS Base, > > + EFI_PHYSICAL_ADDRESS Top > > + ) > > +{ > > + EFI_PEI_HOB_POINTERS Hob; > > + EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob; > > + > > + for (Hob.Raw = (UINT8 *) HobList; !END_OF_HOB_LIST(Hob); Hob.Raw = > GET_NEXT_HOB(Hob)) { > > + // > > + // Skip all HOBs except Resource Descriptor HOBs > > + // > > + if (GET_HOB_TYPE (Hob) != EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) { > > + continue; > > + } > > + > > + // > > + // Skip Resource Descriptor HOBs that do not describe tested system > memory > > + // > > + ResourceHob = Hob.ResourceDescriptor; > > + if (ResourceHob->ResourceType != EFI_RESOURCE_SYSTEM_MEMORY) { > > + continue; > > + } > > + if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) != > TESTED_MEMORY_ATTRIBUTES) { > > + continue; > > + } > > + > > + // > > + // Skip Resource Descriptor HOBs that do not contain the PHIT range > EfiFreeMemoryBottom..EfiFreeMemoryTop > > + // > > + if (Base < ResourceHob->PhysicalStart) { > > + continue; > > + } > > + if (Top > (ResourceHob->PhysicalStart + ResourceHob->ResourceLength)) > { > > + continue; > > + } > > + return ResourceHob; > > + } > > + return NULL; > > +} > > + > > +/** > > + Find the highest below 4G memory resource descriptor, except the input > Resource Descriptor. > > + > > + @param[in] HobList Hob start address > > + @param[in] MinimalNeededSize Minimal needed size. > > + @param[in] ExceptResourceHob Ignore this Resource Descriptor. > > + > > + @return The pointer to the Resource Descriptor HOB. > > +**/ > > +EFI_HOB_RESOURCE_DESCRIPTOR * > > +FindAnotherHighestBelow4GResourceDescriptor ( > > + IN VOID *HobList, > > + IN UINTN MinimalNeededSize, > > + IN EFI_HOB_RESOURCE_DESCRIPTOR *ExceptResourceHob > > + ) > > +{ > > + EFI_PEI_HOB_POINTERS Hob; > > + EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob; > > + EFI_HOB_RESOURCE_DESCRIPTOR *ReturnResourceHob; > > + ReturnResourceHob = NULL; > > + > > + for (Hob.Raw = (UINT8 *) HobList; !END_OF_HOB_LIST(Hob); Hob.Raw = > GET_NEXT_HOB(Hob)) { > > + // > > + // Skip all HOBs except Resource Descriptor HOBs > > + // > > + if (GET_HOB_TYPE (Hob) != EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) { > > + continue; > > + } > > + > > + // > > + // Skip Resource Descriptor HOBs that do not describe tested system > memory > > + // > > + ResourceHob = Hob.ResourceDescriptor; > > + if (ResourceHob->ResourceType != EFI_RESOURCE_SYSTEM_MEMORY) { > > + continue; > > + } > > + if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) != > TESTED_MEMORY_ATTRIBUTES) { > > + continue; > > + } > > + > > + // > > + // Skip if the Resource Descriptor HOB equals to ExceptResourceHob > > + // > > + if (ResourceHob == ExceptResourceHob) { > > + continue; > > + } > > + // > > + // Skip Resource Descriptor HOBs that are beyond 4G > > + // > > + if ((ResourceHob->PhysicalStart + ResourceHob->ResourceLength) > > BASE_4GB) { > > + continue; > > + } > > + // > > + // Skip Resource Descriptor HOBs that are too small > > + // > > + if (ResourceHob->ResourceLength < MinimalNeededSize) { > > + continue; > > + } > > + > > + // > > + // Return the topest Resource Descriptor > > + // > > + if (ReturnResourceHob == NULL) { > > + ReturnResourceHob = ResourceHob; > > + } else { > > + if (ReturnResourceHob->PhysicalStart < ResourceHob->PhysicalStart) { > > + ReturnResourceHob = ResourceHob; > > + } > > + } > > + } > > + return ReturnResourceHob; > > +} > > + > > +/** > > + It will build HOBs based on information from bootloaders. > > + > > + @retval EFI_SUCCESS If it completed successfully. > > + @retval Others If it failed to build required HOBs. > > +**/ > > +EFI_STATUS > > +BuildHobs ( > > + IN UINTN BootloaderParameter > > + ) > > +{ > > + EFI_PEI_HOB_POINTERS Hob; > > + UINTN MinimalNeededSize; > > + EFI_PHYSICAL_ADDRESS FreeMemoryBottom; > > + EFI_PHYSICAL_ADDRESS FreeMemoryTop; > > + EFI_PHYSICAL_ADDRESS MemoryBottom; > > + EFI_PHYSICAL_ADDRESS MemoryTop; > > + EFI_HOB_RESOURCE_DESCRIPTOR *PhitResourceHob; > > + EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob; > > + > > + Hob.Raw = (UINT8 *) BootloaderParameter; > > + MinimalNeededSize = FixedPcdGet32 (PcdSystemMemoryUefiRegionSize); > > + > > + ASSERT (Hob.Raw != NULL); > > + ASSERT ((UINTN) Hob.HandoffInformationTable->EfiFreeMemoryTop == > Hob.HandoffInformationTable->EfiFreeMemoryTop); > > + ASSERT ((UINTN) Hob.HandoffInformationTable->EfiMemoryTop == > Hob.HandoffInformationTable->EfiMemoryTop); > > + ASSERT ((UINTN) Hob.HandoffInformationTable->EfiFreeMemoryBottom > == Hob.HandoffInformationTable->EfiFreeMemoryBottom); > > + ASSERT ((UINTN) Hob.HandoffInformationTable->EfiMemoryBottom == > Hob.HandoffInformationTable->EfiMemoryBottom); > > + > > + > > + // > > + // Try to find Resource Descriptor HOB that contains Hob range > EfiMemoryBottom..EfiMemoryTop > > + // > > + PhitResourceHob = FindResourceDescriptorByRange(Hob.Raw, > Hob.HandoffInformationTable->EfiMemoryBottom, > Hob.HandoffInformationTable->EfiMemoryTop); > > + if (PhitResourceHob == NULL) { > > + // > > + // Boot loader's Phit Hob is not in an available Resource Descriptor, > find > another Resource Descriptor for new Phit Hob > > + // > > + ResourceHob = > FindAnotherHighestBelow4GResourceDescriptor(Hob.Raw, > MinimalNeededSize, NULL); > > + if (ResourceHob == NULL) { > > + return EFI_NOT_FOUND; > > + } > > + > > + MemoryBottom = ResourceHob->PhysicalStart + ResourceHob- > >ResourceLength - MinimalNeededSize; > > + FreeMemoryBottom = MemoryBottom; > > + FreeMemoryTop = ResourceHob->PhysicalStart + ResourceHob- > >ResourceLength; > > + MemoryTop = FreeMemoryTop; > > + } else if (PhitResourceHob->PhysicalStart + PhitResourceHob- > >ResourceLength - Hob.HandoffInformationTable->EfiMemoryTop >= > MinimalNeededSize) { > > + // > > + // New availiable Memory range in new hob is right above memory top in > old hob. > > + // > > + MemoryBottom = Hob.HandoffInformationTable->EfiFreeMemoryTop; > > + FreeMemoryBottom = Hob.HandoffInformationTable->EfiMemoryTop; > > + FreeMemoryTop = FreeMemoryBottom + MinimalNeededSize; > > + MemoryTop = FreeMemoryTop; > > + } else if (Hob.HandoffInformationTable->EfiMemoryBottom - > PhitResourceHob->PhysicalStart >= MinimalNeededSize) { > > + // > > + // New availiable Memory range in new hob is right below memory > bottom in old hob. > > + // > > + MemoryBottom = Hob.HandoffInformationTable->EfiMemoryBottom - > MinimalNeededSize; > > + FreeMemoryBottom = MemoryBottom; > > + FreeMemoryTop = Hob.HandoffInformationTable->EfiMemoryBottom; > > + MemoryTop = Hob.HandoffInformationTable->EfiMemoryTop; > > + } else { > > + // > > + // In the Resource Descriptor HOB contains boot loader Hob, there is no > enough free memory size for payload hob > > + // Find another Resource Descriptor Hob > > + // > > + ResourceHob = > FindAnotherHighestBelow4GResourceDescriptor(Hob.Raw, > MinimalNeededSize, PhitResourceHob); > > + if (ResourceHob == NULL) { > > + return EFI_NOT_FOUND; > > + } > > + > > + MemoryBottom = ResourceHob->PhysicalStart + ResourceHob- > >ResourceLength - MinimalNeededSize; > > + FreeMemoryBottom = MemoryBottom; > > + FreeMemoryTop = ResourceHob->PhysicalStart + ResourceHob- > >ResourceLength; > > + MemoryTop = FreeMemoryTop; > > + } > > + HobConstructor ((VOID *) (UINTN) MemoryBottom, (VOID *) (UINTN) > MemoryTop, (VOID *) (UINTN) FreeMemoryBottom, (VOID *) (UINTN) > FreeMemoryTop); > > + // > > + // From now on, mHobList will point to the new Hob range. > > + // > > + > > + // > > + // Since payload created new Hob, move all hobs except PHIT from boot > loader hob list. > > + // > > + while (!END_OF_HOB_LIST (Hob)) { > > + if (Hob.Header->HobType != EFI_HOB_TYPE_HANDOFF) { > > + // Add this hob to payload HOB > > + AddNewHob (&Hob); > > + } > > + Hob.Raw = GET_NEXT_HOB (Hob); > > + } > > + > > + return EFI_SUCCESS; > > +} > > + > > +/** > > + Entry point to the C language phase of UEFI payload. > > + > > + @retval It will not return if SUCCESS, and return error when passing > bootloader parameter. > > +**/ > > +EFI_STATUS > > +EFIAPI > > +_ModuleEntryPoint ( > > + IN UINTN BootloaderParameter > > + ) > > +{ > > + EFI_STATUS Status; > > + EFI_HOB_HANDOFF_INFO_TABLE *HandoffHobTable; > > + EFI_PEI_HOB_POINTERS Hob; > > + > > + mHobList = (VOID *) BootloaderParameter; > > + // Call constructor for all libraries > > + ProcessLibraryConstructorList (); > > + > > + DEBUG ((DEBUG_INFO, "Entering Universal Payload...\n")); > > + DEBUG ((DEBUG_INFO, "sizeof(UINTN) = 0x%x\n", sizeof(UINTN))); > > + > > + // Initialize floating point operating environment to be compliant with > UEFI > spec. > > + InitializeFloatingPointUnits (); > > + > > + // Build HOB based on information from Bootloader > > + Status = BuildHobs (BootloaderParameter); > > + > > + // > > + // Mask off all legacy 8259 interrupt sources > > + // > > + IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0xFF); > > + IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, 0xFF); > > + > > + HandoffHobTable = (EFI_HOB_HANDOFF_INFO_TABLE *) > GetFirstHob(EFI_HOB_TYPE_HANDOFF); > > + Hob.HandoffInformationTable = HandoffHobTable; > > + > > + // Should not get here > > + CpuDeadLoop (); > > + return EFI_SUCCESS; > > +} > > diff --git a/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf > b/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf > new file mode 100644 > index 0000000000..58ff87d969 > --- /dev/null > +++ b/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf > @@ -0,0 +1,91 @@ > +## @file > > +# This is the first module for UEFI payload. > > +# > > +# Copyright (c) 2021, Intel Corporation. All rights reserved.<BR> > > +# > > +# SPDX-License-Identifier: BSD-2-Clause-Patent > > +# > > +## > > + > > +[Defines] > > + INF_VERSION = 0x00010005 > > + BASE_NAME = UniversalPayloadEntry > > + FILE_GUID = D4F0F269-1209-4A66-8039-C4D5A700EA4E > > + MODULE_TYPE = SEC > > + VERSION_STRING = 1.0 > > + > > +# > > +# The following information is for reference only and not required by the > build tools. > > +# > > +# VALID_ARCHITECTURES = IA32 X64 > > +# > > + > > +[Sources] > > + UniversalPayloadEntry.c > > + LoadDxeCore.c > > + MemoryAllocation.c > > + > > +[Sources.Ia32] > > + X64/VirtualMemory.h > > + X64/VirtualMemory.c > > + Ia32/DxeLoadFunc.c > > + Ia32/IdtVectorAsm.nasm > > + > > +[Sources.X64] > > + X64/VirtualMemory.h > > + X64/VirtualMemory.c > > + X64/DxeLoadFunc.c > > + > > +[Packages] > > + MdePkg/MdePkg.dec > > + MdeModulePkg/MdeModulePkg.dec > > + UefiCpuPkg/UefiCpuPkg.dec > > + UefiPayloadPkg/UefiPayloadPkg.dec > > + > > +[LibraryClasses] > > + BaseMemoryLib > > + DebugLib > > + BaseLib > > + SerialPortLib > > + IoLib > > + HobLib > > + PeCoffLib > > + UefiCpuLib > > + > > +[Guids] > > + gEfiMemoryTypeInformationGuid > > + gEfiFirmwareFileSystem2Guid > > + gUefiSystemTableInfoGuid > > + gEfiGraphicsInfoHobGuid > > + gEfiGraphicsDeviceInfoHobGuid > > + gUefiAcpiBoardInfoGuid > > + gEfiSmbiosTableGuid > > + gEfiAcpiTableGuid > > + gUefiSerialPortInfoGuid > > + > > +[FeaturePcd.IA32] > > + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode ## > CONSUMES > > + > > +[FeaturePcd.X64] > > + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplBuildPageTables ## > CONSUMES > > + > > + > > +[Pcd.IA32,Pcd.X64] > > + gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable ## > SOMETIMES_CONSUMES > > + > gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrM > ask ## CONSUMES > > + > gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask > ## CONSUMES > > + gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask > ## CONSUMES > > + gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard ## > CONSUMES > > + gEfiMdeModulePkgTokenSpaceGuid.PcdUse5LevelPageTable ## > SOMETIMES_CONSUMES > > + gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase ## > CONSUMES > > + gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbSize ## > CONSUMES > > + > > + gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemBase > > + gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemSize > > + gUefiPayloadPkgTokenSpaceGuid.PcdPayloadStackTop > > + gUefiPayloadPkgTokenSpaceGuid.PcdSystemMemoryUefiRegionSize > > + > > + gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack ## > SOMETIMES_CONSUMES > > + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy > ## SOMETIMES_CONSUMES > > + gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy ## > SOMETIMES_CONSUMES > > + > > -- > 2.16.2.windows.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#76869): https://edk2.groups.io/g/devel/message/76869 Mute This Topic: https://groups.io/mt/83669559/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-