diff --git a/UefiPayloadPkg/UefiPayloadEntry/FitUniversalPayloadEntry.c b/UefiPayloadPkg/UefiPayloadEntry/FitUniversalPayloadEntry.c index eb0b325369..7af1276d60 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/FitUniversalPayloadEntry.c +++ b/UefiPayloadPkg/UefiPayloadEntry/FitUniversalPayloadEntry.c @@ -6,6 +6,9 @@ #include "UefiPayloadEntry.h" #include #include +#include +#include +#include #define MEMORY_ATTRIBUTE_MASK (EFI_RESOURCE_ATTRIBUTE_PRESENT | \ EFI_RESOURCE_ATTRIBUTE_INITIALIZED | \ @@ -23,6 +26,15 @@ EFI_RESOURCE_ATTRIBUTE_INITIALIZED | \ EFI_RESOURCE_ATTRIBUTE_TESTED ) +GLOBAL_REMOVE_IF_UNREFERENCED EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation[] = { + { EfiACPIReclaimMemory, FixedPcdGet32 (PcdMemoryTypeEfiACPIReclaimMemory) }, + { EfiACPIMemoryNVS, FixedPcdGet32 (PcdMemoryTypeEfiACPIMemoryNVS) }, + { EfiReservedMemoryType, FixedPcdGet32 (PcdMemoryTypeEfiReservedMemoryType) }, + { EfiRuntimeServicesData, FixedPcdGet32 (PcdMemoryTypeEfiRuntimeServicesData) }, + { EfiRuntimeServicesCode, FixedPcdGet32 (PcdMemoryTypeEfiRuntimeServicesCode) }, + { EfiMaxMemoryType, 0 } +}; + extern VOID *mHobList; CHAR8 *mLineBuffer = NULL; @@ -36,6 +48,12 @@ PrintHob ( IN CONST VOID *HobStart ); +VOID +EFIAPI +ProcessLibraryConstructorList ( + VOID + ); + /** Find the first substring. @param String Point to the string where to find the substring. @@ -191,187 +209,6 @@ FixUpPcdDatabase ( return EFI_SUCCESS; } -/** - 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); - ASSERT (NewHob.Header != NULL); - if (NewHob.Header == NULL) { - return; - } - - CopyMem (NewHob.Header + 1, Hob->Header + 1, Hob->Header->HobLength - sizeof (EFI_HOB_GENERIC_HEADER)); -} - -/** - Found the Resource Descriptor HOB that contains a range (Base, Top) - @param[in] HobList Hob start address - @param[in] Base Memory start address - @param[in] Top Memory end address. - @retval The pointer to the Resource Descriptor HOB. -**/ -EFI_HOB_RESOURCE_DESCRIPTOR * -FindResourceDescriptorByRange ( - IN VOID *HobList, - IN EFI_PHYSICAL_ADDRESS Base, - IN 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. - @retval 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; -} - -/** - Check the HOB and decide if it is need inside Payload - Payload maintainer may make decision which HOB is need or needn't - Then add the check logic in the function. - @param[in] Hob The HOB to check - @retval TRUE If HOB is need inside Payload - @retval FALSE If HOB is needn't inside Payload -**/ -BOOLEAN -IsHobNeed ( - EFI_PEI_HOB_POINTERS Hob - ) -{ - if (Hob.Header->HobType == EFI_HOB_TYPE_HANDOFF) { - return FALSE; - } - - if (Hob.Header->HobType == EFI_HOB_TYPE_MEMORY_ALLOCATION) { - if (CompareGuid (&Hob.MemoryAllocationModule->MemoryAllocationHeader.Name, &gEfiHobMemoryAllocModuleGuid)) { - return FALSE; - } - } - - // Arrive here mean the HOB is need - return TRUE; -} - /** It will build Fv HOBs based on information from bootloaders. @param[out] DxeFv The pointer to the DXE FV in memory. @@ -400,6 +237,8 @@ BuildFitLoadablesFvHob ( UINT32 DataSize; UINT32 *Data32; + Fdt = NULL; + GuidHob = GetFirstGuidHob (&gUniversalPayloadBaseGuid); if (GuidHob != NULL) { PayloadBase = (UNIVERSAL_PAYLOAD_BASE *)GET_GUID_HOB_DATA (GuidHob); @@ -407,6 +246,10 @@ BuildFitLoadablesFvHob ( DEBUG ((DEBUG_INFO, "PayloadBase Entry = 0x%08x\n", PayloadBase->Entry)); } + if (Fdt == NULL) { + return EFI_UNSUPPORTED; + } + Status = FdtCheckHeader (Fdt); if (EFI_ERROR (Status)) { return EFI_UNSUPPORTED; @@ -467,31 +310,25 @@ BuildFitLoadablesFvHob ( } /** - It will build HOBs based on information from bootloaders. - @param[in] BootloaderParameter The starting memory address of bootloader parameter block. - @param[out] DxeFv The pointer to the DXE FV in memory. - @retval EFI_SUCCESS If it completed successfully. - @retval Others If it failed to build required HOBs. + * + Create new HOB for new HOB list + + @param[in] BootloaderParameter The HOB to be added into the HOB list. **/ -EFI_STATUS -BuildHobs ( - IN UINTN BootloaderParameter, - OUT EFI_FIRMWARE_VOLUME_HEADER **DxeFv +VOID +CreatNewHobForHoblist ( + 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; - UINT8 *GuidHob; - EFI_HOB_FIRMWARE_VOLUME *FvHob; - UNIVERSAL_PAYLOAD_ACPI_TABLE *AcpiTable; - ACPI_BOARD_INFO *AcpiBoardInfo; - EFI_HOB_HANDOFF_INFO_TABLE *HobInfo; + 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; + EFI_HOB_HANDOFF_INFO_TABLE *HobInfo; Hob.Raw = (UINT8 *)BootloaderParameter; MinimalNeededSize = FixedPcdGet32 (PcdSystemMemoryUefiRegionSize); @@ -512,7 +349,7 @@ BuildHobs ( // ResourceHob = FindAnotherHighestBelow4GResourceDescriptor (Hob.Raw, MinimalNeededSize, NULL); if (ResourceHob == NULL) { - return EFI_NOT_FOUND; + return; } MemoryBottom = ResourceHob->PhysicalStart + ResourceHob->ResourceLength - MinimalNeededSize; @@ -542,7 +379,7 @@ BuildHobs ( // ResourceHob = FindAnotherHighestBelow4GResourceDescriptor (Hob.Raw, MinimalNeededSize, PhitResourceHob); if (ResourceHob == NULL) { - return EFI_NOT_FOUND; + return; } MemoryBottom = ResourceHob->PhysicalStart + ResourceHob->ResourceLength - MinimalNeededSize; @@ -553,14 +390,7 @@ BuildHobs ( HobInfo = HobConstructor ((VOID *)(UINTN)MemoryBottom, (VOID *)(UINTN)MemoryTop, (VOID *)(UINTN)FreeMemoryBottom, (VOID *)(UINTN)FreeMemoryTop); HobInfo->BootMode = Hob.HandoffInformationTable->BootMode; - // - // 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. // @@ -573,7 +403,58 @@ BuildHobs ( Hob.Raw = GET_NEXT_HOB (Hob); } - BuildFitLoadablesFvHob (DxeFv); + return; +} + +/** + It will build HOBs based on information from bootloaders. + @param[in] NewFdtBase The pointer to New FdtBase. + @param[out] DxeFv The pointer to the DXE FV in memory. + @retval EFI_SUCCESS If it completed successfully. + @retval Others If it failed to build required HOBs. +**/ +EFI_STATUS +FitBuildHobs ( + IN UINTN NewFdtBase, + OUT EFI_FIRMWARE_VOLUME_HEADER **DxeFv + ) +{ + UINT8 *GuidHob; + UINT32 FdtSize; + EFI_HOB_FIRMWARE_VOLUME *FvHob; + UNIVERSAL_PAYLOAD_ACPI_TABLE *AcpiTable; + ACPI_BOARD_INFO *AcpiBoardInfo; + UNIVERSAL_PAYLOAD_DEVICE_TREE *Fdt; + + if (FixedPcdGetBool (PcdHandOffFdtEnable)) { + // + // Back up FDT in Reserved memory region + // + if (NewFdtBase != 0) { + GuidHob = GetFirstGuidHob (&gUniversalPayloadDeviceTreeGuid); + if (GuidHob != NULL) { + Fdt = (UNIVERSAL_PAYLOAD_DEVICE_TREE *)GET_GUID_HOB_DATA (GuidHob); + if (Fdt != NULL) { + DEBUG ((DEBUG_INFO, "Update FDT base to reserved memory\n")); + FdtSize = PcdGet8 (PcdFDTPageSize) * EFI_PAGE_SIZE; + CopyMem ((VOID *)NewFdtBase, (VOID *)(Fdt->DeviceTreeAddress), FdtSize); + Fdt->DeviceTreeAddress = NewFdtBase; + } + } + } + } + + // + // To create Memory Type Information HOB + // + GuidHob = GetFirstGuidHob (&gEfiMemoryTypeInformationGuid); + if (GuidHob == NULL) { + BuildGuidDataHob ( + &gEfiMemoryTypeInformationGuid, + mDefaultMemoryTypeInformation, + sizeof (mDefaultMemoryTypeInformation) + ); + } // // Create guid hob for acpi board information @@ -588,6 +469,12 @@ BuildHobs ( } } + // + // Create an empty FvHob for the DXE FV that contains DXE core. + // + BuildFvHob ((EFI_PHYSICAL_ADDRESS)0, 0); + + BuildFitLoadablesFvHob (DxeFv); // // Update DXE FV information to first fv hob in the hob list, which // is the empty FvHob created before. @@ -600,12 +487,12 @@ BuildHobs ( /** Entry point to the C language phase of UEFI payload. - @param[in] BootloaderParameter The starting address of bootloader parameter block. + @param[in] BootloaderParameter The starting address of FDT . @retval It will not return if SUCCESS, and return error when passing bootloader parameter. **/ EFI_STATUS EFIAPI -_ModuleEntryPoint ( +FitUplEntryPoint ( IN UINTN BootloaderParameter ) { @@ -614,13 +501,51 @@ _ModuleEntryPoint ( EFI_PEI_HOB_POINTERS Hob; EFI_FIRMWARE_VOLUME_HEADER *DxeFv; - mHobList = (VOID *)BootloaderParameter; - DxeFv = NULL; + #if FixedPcdGetBool (PcdHandOffFdtEnable) == 1 + PHYSICAL_ADDRESS HobListPtr; + VOID *FdtBase; + #endif + VOID *FdtBaseResvd; + + if (FixedPcdGetBool (PcdHandOffFdtEnable)) { + mHobList = (VOID *)NULL; + } else { + mHobList = (VOID *)BootloaderParameter; + } + + DxeFv = NULL; + FdtBaseResvd = 0; // Call constructor for all libraries ProcessLibraryConstructorList (); DEBUG ((DEBUG_INFO, "Entering Universal Payload...\n")); DEBUG ((DEBUG_INFO, "sizeof(UINTN) = 0x%x\n", sizeof (UINTN))); + DEBUG ((DEBUG_INFO, "BootloaderParameter = 0x%x\n", BootloaderParameter)); + + DEBUG ((DEBUG_INFO, "Start init Hobs...\n")); + #if FixedPcdGetBool (PcdHandOffFdtEnable) == 1 + HobListPtr = UplInitHob ((VOID *)BootloaderParameter); + + // + // Found hob list node + // + if (HobListPtr != 0) { + FdtBase = (VOID *)BootloaderParameter; + if (FdtCheckHeader (FdtBase) == 0) { + CustomFdtNodeParser ((VOID *)FdtBase, (VOID *)HobListPtr); + FdtBaseResvd = PayloadAllocatePages (PcdGet8 (PcdFDTPageSize), EfiReservedMemoryType); + } + } + + #else + CreatNewHobForHoblist (BootloaderParameter); + #endif + + // Build HOB based on information from Bootloader + Status = FitBuildHobs ((UINTN)FdtBaseResvd, &DxeFv); + + // Call constructor for all libraries again since hobs were built + ProcessLibraryConstructorList (); DEBUG_CODE ( // @@ -629,23 +554,10 @@ _ModuleEntryPoint ( PrintHob (mHobList); ); - // Initialize floating point operating environment to be compliant with UEFI spec. - InitializeFloatingPointUnits (); - - // Build HOB based on information from Bootloader - Status = BuildHobs (BootloaderParameter, &DxeFv); - ASSERT_EFI_ERROR (Status); - FixUpPcdDatabase (DxeFv); Status = UniversalLoadDxeCore (DxeFv, &DxeCoreEntryPoint); ASSERT_EFI_ERROR (Status); - // - // Mask off all legacy 8259 interrupt sources - // - IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0xFF); - IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, 0xFF); - Hob.HandoffInformationTable = (EFI_HOB_HANDOFF_INFO_TABLE *)GetFirstHob (EFI_HOB_TYPE_HANDOFF); HandOffToDxeCore (DxeCoreEntryPoint, Hob); diff --git a/UefiPayloadPkg/UefiPayloadEntry/FitUniversalPayloadEntry.inf b/UefiPayloadPkg/UefiPayloadEntry/FitUniversalPayloadEntry.inf index 04d0a795dc..37e3cc8efa 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/FitUniversalPayloadEntry.inf +++ b/UefiPayloadPkg/UefiPayloadEntry/FitUniversalPayloadEntry.inf @@ -30,13 +30,13 @@ [Sources.Ia32] X64/VirtualMemory.h X64/VirtualMemory.c - Ia32/DxeLoadFunc.c + Ia32/DxeLoadFuncFit.c Ia32/IdtVectorAsm.nasm [Sources.X64] X64/VirtualMemory.h X64/VirtualMemory.c - X64/DxeLoadFunc.c + X64/DxeLoadFuncFit.c [Packages] MdePkg/MdePkg.dec @@ -55,6 +55,8 @@ CpuLib FdtLib HobPrintLib + CustomFdtNodeParserLib + PcdLib [Guids] gEfiMemoryTypeInformationGuid @@ -72,6 +74,7 @@ gUniversalPayloadAcpiTableGuid gUniversalPayloadPciRootBridgeInfoGuid gUniversalPayloadSmbios3TableGuid + gUniversalPayloadDeviceTreeGuid [FeaturePcd.IA32] gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode ## CONSUMES @@ -79,7 +82,6 @@ [FeaturePcd.X64] gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplBuildPageTables ## CONSUMES - [Pcd.IA32,Pcd.X64] gUefiPayloadPkgTokenSpaceGuid.PcdPcdDriverFile gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable ## SOMETIMES_CONSUMES @@ -89,11 +91,20 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbSize ## CONSUMES - gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemBase gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemSize gUefiPayloadPkgTokenSpaceGuid.PcdSystemMemoryUefiRegionSize - gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack ## SOMETIMES_CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy ## SOMETIMES_CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy ## SOMETIMES_CONSUMES + gUefiPayloadPkgTokenSpaceGuid.PcdHandOffFdtEnable + gUefiPayloadPkgTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS + gUefiPayloadPkgTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory + gUefiPayloadPkgTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType + gUefiPayloadPkgTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData + gUefiPayloadPkgTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode + gUefiPayloadPkgTokenSpaceGuid.PcdFDTPageSize + +[BuildOptions] + MSFT:*_*_*_CC_FLAGS = /wd4244 /wd4305 + GCC:*_*_*_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast diff --git a/UefiPayloadPkg/UefiPayloadEntry/Ia32/DxeLoadFunc.c b/UefiPayloadPkg/UefiPayloadEntry/Ia32/DxeLoadFunc.c index 61a9f01ec9..cf9c03a9a8 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/Ia32/DxeLoadFunc.c +++ b/UefiPayloadPkg/UefiPayloadEntry/Ia32/DxeLoadFunc.c @@ -15,12 +15,15 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include +#include #include "VirtualMemory.h" #include "UefiPayloadEntry.h" #define STACK_SIZE 0x20000 #define IDT_ENTRY_COUNT 32 +extern VOID *mHobList; + typedef struct _X64_IDT_TABLE { // // Reserved 4 bytes preceding PeiService and IdtTable, @@ -268,6 +271,15 @@ HandOffToDxeCore ( UINT32 Index; X64_IDT_TABLE *IdtTableForX64; + // Initialize floating point operating environment to be compliant with UEFI spec. + InitializeFloatingPointUnits (); + + // + // Mask off all legacy 8259 interrupt sources + // + IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0xFF); + IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, 0xFF); + // // Clear page 0 and mark it as allocated if NULL pointer detection is enabled. // diff --git a/UefiPayloadPkg/UefiPayloadEntry/MemoryAllocation.c b/UefiPayloadPkg/UefiPayloadEntry/MemoryAllocation.c index 9a65b7dbfe..23bbf196cc 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/MemoryAllocation.c +++ b/UefiPayloadPkg/UefiPayloadEntry/MemoryAllocation.c @@ -10,6 +10,56 @@ #include "UefiPayloadEntry.h" +/** + Allocates one or more pages of type EfiBootServicesData. + + Allocates the number of pages of MemoryType and returns a pointer to the + allocated buffer. The buffer returned is aligned on a 4KB boundary. + If Pages is 0, then NULL is returned. + If there is not enough memory availble to satisfy the request, then NULL + is returned. + + @param Pages The number of 4 KB pages to allocate. + @param MemoryType The MemoryType + @return A pointer to the allocated buffer or NULL if allocation fails. +**/ +VOID * +EFIAPI +PayloadAllocatePages ( + IN UINTN Pages, + IN EFI_MEMORY_TYPE MemoryType + ) +{ + EFI_PEI_HOB_POINTERS Hob; + EFI_PHYSICAL_ADDRESS Offset; + EFI_HOB_HANDOFF_INFO_TABLE *HobTable; + + Hob.Raw = GetHobList (); + HobTable = Hob.HandoffInformationTable; + + if (Pages == 0) { + return NULL; + } + + // Make sure allocation address is page alligned. + Offset = HobTable->EfiFreeMemoryTop & EFI_PAGE_MASK; + if (Offset != 0) { + HobTable->EfiFreeMemoryTop -= Offset; + } + + // + // Check available memory for the allocation + // + if (HobTable->EfiFreeMemoryTop - ((Pages * EFI_PAGE_SIZE) + sizeof (EFI_HOB_MEMORY_ALLOCATION)) < HobTable->EfiFreeMemoryBottom) { + return NULL; + } + + HobTable->EfiFreeMemoryTop -= Pages * EFI_PAGE_SIZE; + BuildMemoryAllocationHob (HobTable->EfiFreeMemoryTop, Pages * EFI_PAGE_SIZE, MemoryType); + + return (VOID *)(UINTN)HobTable->EfiFreeMemoryTop; +} + /** Allocates one or more pages of type EfiBootServicesData. diff --git a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h index 80ccc5072c..09fce8dbcf 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h +++ b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h @@ -35,6 +35,7 @@ #include #include #include +#include #include #define LEGACY_8259_MASK_REGISTER_MASTER 0x21 @@ -134,6 +135,31 @@ UniversalLoadDxeCore ( OUT PHYSICAL_ADDRESS *DxeCoreEntryPoint ); +/** + It will Parse FDT -node based on information. + @param[in] FdtBase The starting memory address of FdtBase + @retval HobList The base address of Hoblist. + +**/ +UINT64 +EFIAPI +FdtNodeParser ( + IN VOID *FdtBase + ); + +/** + It will Parse FDT -custom node based on information. + @param[in] FdtBase The starting memory address of FdtBase + @param[in] HostList The starting memory address of New Hob list. + +**/ +UINTN +EFIAPI +CustomFdtNodeParser ( + IN VOID *FdtBase, + IN VOID *HostList + ); + /** Transfers control to DxeCore. @@ -206,4 +232,46 @@ BuildHobFromAcpi ( IN UINT64 AcpiTableBase ); +/** + Allocates one or more pages . + + Allocates the number of pages of MemoryType and returns a pointer to the + allocated buffer. The buffer returned is aligned on a 4KB boundary. + If Pages is 0, then NULL is returned. + If there is not enough memory availble to satisfy the request, then NULL + is returned. + + @param Pages The number of 4 KB pages to allocate. + @param MemoryType The Memorytype + @return A pointer to the allocated buffer or NULL if allocation fails. +**/ +VOID * +EFIAPI +PayloadAllocatePages ( + IN UINTN Pages, + IN EFI_MEMORY_TYPE MemoryType + ); + +/** + Entry point to the C language phase of UEFI payload. + @param[in] FdtPrt The starting address of FDT . + @retval It will not return if SUCCESS, and return error when passing bootloader parameter. +**/ +EFI_STATUS +EFIAPI +FitUplEntryPoint ( + IN UINTN BootloaderParameter + ); + +/** + Entry point to the C language phase of UEFI payload. + @param[in] BootloaderParameter The starting address of bootloader parameter block. + @retval It will not return if SUCCESS, and return error when passing bootloader parameter. +**/ +EFI_STATUS +EFIAPI +UplEntryPoint ( + IN UINTN BootloaderParameter + ); + #endif diff --git a/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.c b/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.c index f37c00fad7..5b864eeefe 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.c +++ b/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.c @@ -486,12 +486,6 @@ _ModuleEntryPoint ( Status = UniversalLoadDxeCore (DxeFv, &DxeCoreEntryPoint); ASSERT_EFI_ERROR (Status); - // - // Mask off all legacy 8259 interrupt sources - // - IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0xFF); - IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, 0xFF); - Hob.HandoffInformationTable = (EFI_HOB_HANDOFF_INFO_TABLE *)GetFirstHob (EFI_HOB_TYPE_HANDOFF); HandOffToDxeCore (DxeCoreEntryPoint, Hob); diff --git a/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf b/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf index c3571e3c28..01bb9a118a 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf +++ b/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf @@ -6,44 +6,37 @@ # SPDX-License-Identifier: BSD-2-Clause-Patent # ## - [Defines] INF_VERSION = 1.30 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 PrintHob.c AcpiTable.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 @@ -70,14 +63,10 @@ gUniversalPayloadAcpiTableGuid gUniversalPayloadPciRootBridgeInfoGuid gUniversalPayloadSmbios3TableGuid - [FeaturePcd.IA32] gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode ## CONSUMES - [FeaturePcd.X64] gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplBuildPageTables ## CONSUMES - - [Pcd.IA32,Pcd.X64] gUefiPayloadPkgTokenSpaceGuid.PcdPcdDriverFile gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable ## SOMETIMES_CONSUMES @@ -87,12 +76,9 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbSize ## CONSUMES - gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemBase gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemSize gUefiPayloadPkgTokenSpaceGuid.PcdSystemMemoryUefiRegionSize - gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack ## SOMETIMES_CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy ## SOMETIMES_CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy ## SOMETIMES_CONSUMES - diff --git a/UefiPayloadPkg/UefiPayloadEntry/X64/DxeLoadFunc.c b/UefiPayloadPkg/UefiPayloadEntry/X64/DxeLoadFunc.c index 346e3feb04..6c3603f120 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/X64/DxeLoadFunc.c +++ b/UefiPayloadPkg/UefiPayloadEntry/X64/DxeLoadFunc.c @@ -13,10 +13,13 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include +#include #include "X64/VirtualMemory.h" #include "UefiPayloadEntry.h" #define STACK_SIZE 0x20000 +extern VOID *mHobList; + /** Transfers control to DxeCore. @@ -40,6 +43,15 @@ HandOffToDxeCore ( VOID *GhcbBase; UINTN GhcbSize; + // Initialize floating point operating environment to be compliant with UEFI spec. + InitializeFloatingPointUnits (); + + // + // Mask off all legacy 8259 interrupt sources + // + IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0xFF); + IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, 0xFF); + // // Clear page 0 and mark it as allocated if NULL pointer detection is enabled. // diff --git a/UefiPayloadPkg/UefiPayloadPkg.dsc b/UefiPayloadPkg/UefiPayloadPkg.dsc index 6199527a9a..9a73c7fd80 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.dsc +++ b/UefiPayloadPkg/UefiPayloadPkg.dsc @@ -226,6 +226,7 @@ OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf RngLib|MdePkg/Library/BaseRngLib/BaseRngLib.inf HobLib|UefiPayloadPkg/Library/DxeHobLib/DxeHobLib.inf + CustomFdtNodeParserLib|UefiPayloadPkg/Library/CustomFdtNodeParserNullLib/CustomFdtNodeParserNullLib.inf # # UEFI & PI @@ -472,6 +473,8 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress|0x0 gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseMemory|FALSE gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable|TRUE + gUefiPayloadPkgTokenSpaceGuid.PcdHandOffFdtEnable|FALSE + gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 } gUefiPayloadPkgTokenSpaceGuid.PcdPcdDriverFile|{ 0x57, 0x72, 0xcf, 0x80, 0xab, 0x87, 0xf9, 0x47, 0xa3, 0xfe, 0xD5, 0x0B, 0x76, 0xd8, 0x95, 0x41 } @@ -515,10 +518,13 @@ !endif !endif + [PcdsPatchableInModule.X64] !if $(NETWORK_DRIVER_ENABLE) == TRUE gEfiNetworkPkgTokenSpaceGuid.PcdAllowHttpConnections|TRUE !endif + gUefiPayloadPkgTokenSpaceGuid.SizeOfIoSpace|16 + gUefiPayloadPkgTokenSpaceGuid.PcdFDTPageSize|8 [PcdsPatchableInModule.common] gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 } @@ -542,7 +548,7 @@ # The following parameters are set by Library/PlatformHookLib # gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio|FALSE - gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0 + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0x3F8 gEfiMdeModulePkgTokenSpaceGuid.PcdSerialBaudRate|$(BAUD_RATE) gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterStride|1 @@ -638,7 +644,15 @@ !if $(UNIVERSAL_PAYLOAD_FORMAT) == "ELF" UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf !elseif $(UNIVERSAL_PAYLOAD_FORMAT) == "FIT" - UefiPayloadPkg/UefiPayloadEntry/FitUniversalPayloadEntry.inf + UefiPayloadPkg/UefiPayloadEntry/FitUniversalPayloadEntry.inf { + + !if gUefiPayloadPkgTokenSpaceGuid.PcdHandOffFdtEnable == TRUE + FdtLib|MdePkg/Library/BaseFdtLib/BaseFdtLib.inf + CustomFdtNodeParserLib|UefiPayloadPkg/Library/CustomFdtNodeParserLib/CustomFdtNodeParserLib.inf + NULL|UefiPayloadPkg/Library/FdtParserLib/FdtParseLib.inf + !endif + NULL|UefiPayloadPkg/Library/HobParseLib/HobParseLib.inf + } !else UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf !endif @@ -651,7 +665,15 @@ !if $(UNIVERSAL_PAYLOAD_FORMAT) == "ELF" UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf !elseif $(UNIVERSAL_PAYLOAD_FORMAT) == "FIT" - UefiPayloadPkg/UefiPayloadEntry/FitUniversalPayloadEntry.inf + UefiPayloadPkg/UefiPayloadEntry/FitUniversalPayloadEntry.inf { + + !if gUefiPayloadPkgTokenSpaceGuid.PcdHandOffFdtEnable == TRUE + FdtLib|MdePkg/Library/BaseFdtLib/BaseFdtLib.inf + CustomFdtNodeParserLib|UefiPayloadPkg/Library/CustomFdtNodeParserLib/CustomFdtNodeParserLib.inf + NULL|UefiPayloadPkg/Library/FdtParserLib/FdtParseLib.inf + !endif + NULL|UefiPayloadPkg/Library/HobParseLib/HobParseLib.inf + } !else UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf !endif