aboutsummaryrefslogtreecommitdiffstats
path: root/roms/edk2/MdePkg/Library/DxeServicesLib
diff options
context:
space:
mode:
authorAngelos Mouzakitis <a.mouzakitis@virtualopensystems.com>2023-10-10 14:33:42 +0000
committerAngelos Mouzakitis <a.mouzakitis@virtualopensystems.com>2023-10-10 14:33:42 +0000
commitaf1a266670d040d2f4083ff309d732d648afba2a (patch)
tree2fc46203448ddcc6f81546d379abfaeb323575e9 /roms/edk2/MdePkg/Library/DxeServicesLib
parente02cda008591317b1625707ff8e115a4841aa889 (diff)
Add submodule dependency filesHEADmaster
Change-Id: Iaf8d18082d3991dec7c0ebbea540f092188eb4ec
Diffstat (limited to 'roms/edk2/MdePkg/Library/DxeServicesLib')
-rw-r--r--roms/edk2/MdePkg/Library/DxeServicesLib/Allocate.c48
-rw-r--r--roms/edk2/MdePkg/Library/DxeServicesLib/DxeServicesLib.c1092
-rw-r--r--roms/edk2/MdePkg/Library/DxeServicesLib/DxeServicesLib.inf60
-rw-r--r--roms/edk2/MdePkg/Library/DxeServicesLib/DxeServicesLib.uni18
-rw-r--r--roms/edk2/MdePkg/Library/DxeServicesLib/X64/Allocate.c63
5 files changed, 1281 insertions, 0 deletions
diff --git a/roms/edk2/MdePkg/Library/DxeServicesLib/Allocate.c b/roms/edk2/MdePkg/Library/DxeServicesLib/Allocate.c
new file mode 100644
index 000000000..efb65768b
--- /dev/null
+++ b/roms/edk2/MdePkg/Library/DxeServicesLib/Allocate.c
@@ -0,0 +1,48 @@
+/** @file
+ DxeServicesLib memory allocation routines
+
+ Copyright (c) 2018, Linaro, Ltd. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiDxe.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DxeServicesLib.h>
+
+/**
+ Allocates one or more 4KB pages of a given type from a memory region that is
+ accessible to PEI.
+
+ Allocates the number of 4KB pages of type '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 remaining to satisfy the request, then NULL is returned.
+
+ @param[in] MemoryType The memory type to allocate
+ @param[in] Pages The number of 4 KB pages to allocate.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocatePeiAccessiblePages (
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN Pages
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS Memory;
+
+ if (Pages == 0) {
+ return NULL;
+ }
+
+ Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory);
+ if (EFI_ERROR (Status)) {
+ return NULL;
+ }
+ return (VOID *)(UINTN)Memory;
+}
diff --git a/roms/edk2/MdePkg/Library/DxeServicesLib/DxeServicesLib.c b/roms/edk2/MdePkg/Library/DxeServicesLib/DxeServicesLib.c
new file mode 100644
index 000000000..3e3bbf605
--- /dev/null
+++ b/roms/edk2/MdePkg/Library/DxeServicesLib/DxeServicesLib.c
@@ -0,0 +1,1092 @@
+/** @file
+ MDE DXE Services Library provides functions that simplify the development of DXE Drivers.
+ These functions help access data from sections of FFS files or from file path.
+
+ Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+ (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiDxe.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/UefiLib.h>
+#include <Library/DxeServicesLib.h>
+#include <Protocol/FirmwareVolume2.h>
+#include <Protocol/LoadedImage.h>
+#include <Protocol/LoadFile2.h>
+#include <Protocol/LoadFile.h>
+#include <Protocol/SimpleFileSystem.h>
+#include <Guid/FileInfo.h>
+
+/**
+ Identify the device handle from which the Image is loaded from. As this device handle is passed to
+ GetSectionFromFv as the identifier for a Firmware Volume, an EFI_FIRMWARE_VOLUME2_PROTOCOL
+ protocol instance should be located successfully by calling gBS->HandleProtocol ().
+
+ This function locates the EFI_LOADED_IMAGE_PROTOCOL instance installed
+ on ImageHandle. It then returns EFI_LOADED_IMAGE_PROTOCOL.DeviceHandle.
+
+ If ImageHandle is NULL, then ASSERT ();
+ If failed to locate a EFI_LOADED_IMAGE_PROTOCOL on ImageHandle, then ASSERT ();
+
+ @param ImageHandle The firmware allocated handle for UEFI image.
+
+ @retval EFI_HANDLE The device handle from which the Image is loaded from.
+
+**/
+EFI_HANDLE
+InternalImageHandleToFvHandle (
+ EFI_HANDLE ImageHandle
+ )
+{
+ EFI_STATUS Status;
+ EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
+
+ ASSERT (ImageHandle != NULL);
+
+ Status = gBS->HandleProtocol (
+ ImageHandle,
+ &gEfiLoadedImageProtocolGuid,
+ (VOID **) &LoadedImage
+ );
+
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // The LoadedImage->DeviceHandle may be NULL.
+ // For example for DxeCore, there is LoadedImage protocol installed for it, but the
+ // LoadedImage->DeviceHandle could not be initialized before the FV2 (contain DxeCore)
+ // protocol is installed.
+ //
+ return LoadedImage->DeviceHandle;
+
+}
+
+/**
+ Allocate and fill a buffer from a Firmware Section identified by a Firmware File GUID name, a Firmware
+ Section type and instance number from the specified Firmware Volume.
+
+ This functions first locate the EFI_FIRMWARE_VOLUME2_PROTOCOL protocol instance on FvHandle in order to
+ carry out the Firmware Volume read operation. The function then reads the Firmware Section found specified
+ by NameGuid, SectionType and SectionInstance.
+
+ The details of this search order is defined in description of EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadSection ()
+ found in PI Specification.
+
+ If SectionType is EFI_SECTION_TE, EFI_SECTION_TE is used as section type to start the search. If EFI_SECTION_TE section
+ is not found, EFI_SECTION_PE32 will be used to try the search again. If no EFI_SECTION_PE32 section is found, EFI_NOT_FOUND
+ is returned.
+
+ The data and size is returned by Buffer and Size. The caller is responsible to free the Buffer allocated
+ by this function. This function can be only called at TPL_NOTIFY and below.
+
+ If NameGuid is NULL, then ASSERT();
+ If Buffer is NULL, then ASSERT();
+ If Size is NULL, then ASSERT().
+
+ @param FvHandle The device handle that contains a instance of
+ EFI_FIRMWARE_VOLUME2_PROTOCOL instance.
+ @param NameGuid The GUID name of a Firmware File.
+ @param SectionType The Firmware Section type.
+ @param SectionInstance The instance number of Firmware Section to
+ read from starting from 0.
+ @param Buffer On output, Buffer contains the data read
+ from the section in the Firmware File found.
+ @param Size On output, the size of Buffer.
+
+ @retval EFI_SUCCESS The image is found and data and size is returned.
+ @retval EFI_NOT_FOUND The image specified by NameGuid and SectionType
+ can't be found.
+ @retval EFI_OUT_OF_RESOURCES There were not enough resources to allocate the
+ output data buffer or complete the operations.
+ @retval EFI_DEVICE_ERROR A hardware error occurs during reading from the
+ Firmware Volume.
+ @retval EFI_ACCESS_DENIED The firmware volume containing the searched
+ Firmware File is configured to disallow reads.
+
+**/
+EFI_STATUS
+InternalGetSectionFromFv (
+ IN EFI_HANDLE FvHandle,
+ IN CONST EFI_GUID *NameGuid,
+ IN EFI_SECTION_TYPE SectionType,
+ IN UINTN SectionInstance,
+ OUT VOID **Buffer,
+ OUT UINTN *Size
+ )
+{
+ EFI_STATUS Status;
+ EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
+ UINT32 AuthenticationStatus;
+
+ ASSERT (NameGuid != NULL);
+ ASSERT (Buffer != NULL);
+ ASSERT (Size != NULL);
+
+ if (FvHandle == NULL) {
+ //
+ // Return EFI_NOT_FOUND directly for NULL FvHandle.
+ //
+ return EFI_NOT_FOUND;
+ }
+
+ Status = gBS->HandleProtocol (
+ FvHandle,
+ &gEfiFirmwareVolume2ProtocolGuid,
+ (VOID **) &Fv
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Read desired section content in NameGuid file
+ //
+ *Buffer = NULL;
+ *Size = 0;
+ Status = Fv->ReadSection (
+ Fv,
+ NameGuid,
+ SectionType,
+ SectionInstance,
+ Buffer,
+ Size,
+ &AuthenticationStatus
+ );
+
+ if (EFI_ERROR (Status) && (SectionType == EFI_SECTION_TE)) {
+ //
+ // Try reading PE32 section, if the required section is TE type
+ //
+ *Buffer = NULL;
+ *Size = 0;
+ Status = Fv->ReadSection (
+ Fv,
+ NameGuid,
+ EFI_SECTION_PE32,
+ SectionInstance,
+ Buffer,
+ Size,
+ &AuthenticationStatus
+ );
+ }
+
+ return Status;
+}
+
+/**
+ Searches all the available firmware volumes and returns the first matching FFS section.
+
+ This function searches all the firmware volumes for FFS files with FV file type specified by FileType
+ The order that the firmware volumes is searched is not deterministic. For each available FV a search
+ is made for FFS file of type FileType. If the FV contains more than one FFS file with the same FileType,
+ the FileInstance instance will be the matched FFS file. For each FFS file found a search
+ is made for FFS sections of type SectionType. If the FFS file contains at least SectionInstance instances
+ of the FFS section specified by SectionType, then the SectionInstance instance is returned in Buffer.
+ Buffer is allocated using AllocatePool(), and the size of the allocated buffer is returned in Size.
+ It is the caller's responsibility to use FreePool() to free the allocated buffer.
+ See EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadSection() for details on how sections
+ are retrieved from an FFS file based on SectionType and SectionInstance.
+
+ If SectionType is EFI_SECTION_TE, and the search with an FFS file fails,
+ the search will be retried with a section type of EFI_SECTION_PE32.
+ This function must be called with a TPL <= TPL_NOTIFY.
+
+ If Buffer is NULL, then ASSERT().
+ If Size is NULL, then ASSERT().
+
+ @param FileType Indicates the FV file type to search for within all
+ available FVs.
+ @param FileInstance Indicates which file instance within all available
+ FVs specified by FileType.
+ FileInstance starts from zero.
+ @param SectionType Indicates the FFS section type to search for
+ within the FFS file
+ specified by FileType with FileInstance.
+ @param SectionInstance Indicates which section instance within the FFS file
+ specified by FileType with FileInstance to retrieve.
+ SectionInstance starts from zero.
+ @param Buffer On output, a pointer to a callee allocated buffer
+ containing the FFS file section that was found.
+ Is it the caller's responsibility to free this
+ buffer using FreePool().
+ @param Size On output, a pointer to the size, in bytes, of Buffer.
+
+ @retval EFI_SUCCESS The specified FFS section was returned.
+ @retval EFI_NOT_FOUND The specified FFS section could not be found.
+ @retval EFI_OUT_OF_RESOURCES There are not enough resources available to retrieve
+ the matching FFS section.
+ @retval EFI_DEVICE_ERROR The FFS section could not be retrieves due to a
+ device error.
+ @retval EFI_ACCESS_DENIED The FFS section could not be retrieves because
+ the firmware volume that
+ contains the matching FFS section does not allow reads.
+**/
+EFI_STATUS
+EFIAPI
+GetSectionFromAnyFvByFileType (
+ IN EFI_FV_FILETYPE FileType,
+ IN UINTN FileInstance,
+ IN EFI_SECTION_TYPE SectionType,
+ IN UINTN SectionInstance,
+ OUT VOID **Buffer,
+ OUT UINTN *Size
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *HandleBuffer;
+ UINTN HandleCount;
+ UINTN IndexFv;
+ UINTN IndexFile;
+ UINTN Key;
+ EFI_GUID NameGuid;
+ EFI_FV_FILE_ATTRIBUTES Attributes;
+ EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
+
+ ASSERT (Buffer != NULL);
+ ASSERT (Size != NULL);
+
+ //
+ // Locate all available FVs.
+ //
+ HandleBuffer = NULL;
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiFirmwareVolume2ProtocolGuid,
+ NULL,
+ &HandleCount,
+ &HandleBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Go through FVs one by one to find the required section data.
+ //
+ for (IndexFv = 0; IndexFv < HandleCount; IndexFv++) {
+ Status = gBS->HandleProtocol (
+ HandleBuffer[IndexFv],
+ &gEfiFirmwareVolume2ProtocolGuid,
+ (VOID **)&Fv
+ );
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+
+ //
+ // Use Firmware Volume 2 Protocol to search for a file of type FileType in all FVs.
+ //
+ IndexFile = FileInstance + 1;
+ Key = 0;
+ do {
+ Status = Fv->GetNextFile (Fv, &Key, &FileType, &NameGuid, &Attributes, Size);
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+ IndexFile --;
+ } while (IndexFile > 0);
+
+ //
+ // Fv File with the required FV file type is found.
+ // Search the section file in the found FV file.
+ //
+ if (IndexFile == 0) {
+ Status = InternalGetSectionFromFv (
+ HandleBuffer[IndexFv],
+ &NameGuid,
+ SectionType,
+ SectionInstance,
+ Buffer,
+ Size
+ );
+
+ if (!EFI_ERROR (Status)) {
+ goto Done;
+ }
+ }
+ }
+
+ //
+ // The required FFS section file is not found.
+ //
+ if (IndexFv == HandleCount) {
+ Status = EFI_NOT_FOUND;
+ }
+
+Done:
+ if (HandleBuffer != NULL) {
+ FreePool(HandleBuffer);
+ }
+
+ return Status;
+}
+
+/**
+ Searches all the availables firmware volumes and returns the first matching FFS section.
+
+ This function searches all the firmware volumes for FFS files with an FFS filename specified by NameGuid.
+ The order that the firmware volumes is searched is not deterministic. For each FFS file found a search
+ is made for FFS sections of type SectionType. If the FFS file contains at least SectionInstance instances
+ of the FFS section specified by SectionType, then the SectionInstance instance is returned in Buffer.
+ Buffer is allocated using AllocatePool(), and the size of the allocated buffer is returned in Size.
+ It is the caller's responsibility to use FreePool() to free the allocated buffer.
+ See EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadSection() for details on how sections
+ are retrieved from an FFS file based on SectionType and SectionInstance.
+
+ If SectionType is EFI_SECTION_TE, and the search with an FFS file fails,
+ the search will be retried with a section type of EFI_SECTION_PE32.
+ This function must be called with a TPL <= TPL_NOTIFY.
+
+ If NameGuid is NULL, then ASSERT().
+ If Buffer is NULL, then ASSERT().
+ If Size is NULL, then ASSERT().
+
+
+ @param NameGuid A pointer to to the FFS filename GUID to search for
+ within any of the firmware volumes in the platform.
+ @param SectionType Indicates the FFS section type to search for within
+ the FFS file specified by NameGuid.
+ @param SectionInstance Indicates which section instance within the FFS file
+ specified by NameGuid to retrieve.
+ @param Buffer On output, a pointer to a callee allocated buffer
+ containing the FFS file section that was found.
+ Is it the caller's responsibility to free this buffer
+ using FreePool().
+ @param Size On output, a pointer to the size, in bytes, of Buffer.
+
+ @retval EFI_SUCCESS The specified FFS section was returned.
+ @retval EFI_NOT_FOUND The specified FFS section could not be found.
+ @retval EFI_OUT_OF_RESOURCES There are not enough resources available to
+ retrieve the matching FFS section.
+ @retval EFI_DEVICE_ERROR The FFS section could not be retrieves due to a
+ device error.
+ @retval EFI_ACCESS_DENIED The FFS section could not be retrieves because the
+ firmware volume that
+ contains the matching FFS section does not allow reads.
+**/
+EFI_STATUS
+EFIAPI
+GetSectionFromAnyFv (
+ IN CONST EFI_GUID *NameGuid,
+ IN EFI_SECTION_TYPE SectionType,
+ IN UINTN SectionInstance,
+ OUT VOID **Buffer,
+ OUT UINTN *Size
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *HandleBuffer;
+ UINTN HandleCount;
+ UINTN Index;
+ EFI_HANDLE FvHandle;
+
+ //
+ // Search the FV that contain the caller's FFS first.
+ // FV builder can choose to build FFS into the this FV
+ // so that this implementation of GetSectionFromAnyFv
+ // will locate the FFS faster.
+ //
+ FvHandle = InternalImageHandleToFvHandle (gImageHandle);
+ Status = InternalGetSectionFromFv (
+ FvHandle,
+ NameGuid,
+ SectionType,
+ SectionInstance,
+ Buffer,
+ Size
+ );
+ if (!EFI_ERROR (Status)) {
+ return EFI_SUCCESS;
+ }
+
+ HandleBuffer = NULL;
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiFirmwareVolume2ProtocolGuid,
+ NULL,
+ &HandleCount,
+ &HandleBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ for (Index = 0; Index < HandleCount; Index++) {
+ //
+ // Skip the FV that contain the caller's FFS
+ //
+ if (HandleBuffer[Index] != FvHandle) {
+ Status = InternalGetSectionFromFv (
+ HandleBuffer[Index],
+ NameGuid,
+ SectionType,
+ SectionInstance,
+ Buffer,
+ Size
+ );
+
+ if (!EFI_ERROR (Status)) {
+ goto Done;
+ }
+ }
+
+ }
+
+ if (Index == HandleCount) {
+ Status = EFI_NOT_FOUND;
+ }
+
+Done:
+
+ if (HandleBuffer != NULL) {
+ FreePool(HandleBuffer);
+ }
+ return Status;
+
+}
+
+/**
+ Searches the firmware volume that the currently executing module was loaded from and returns the first matching FFS section.
+
+ This function searches the firmware volume that the currently executing module was loaded
+ from for an FFS file with an FFS filename specified by NameGuid. If the FFS file is found a search
+ is made for FFS sections of type SectionType. If the FFS file contains at least SectionInstance
+ instances of the FFS section specified by SectionType, then the SectionInstance instance is returned in Buffer.
+ Buffer is allocated using AllocatePool(), and the size of the allocated buffer is returned in Size.
+ It is the caller's responsibility to use FreePool() to free the allocated buffer.
+ See EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadSection() for details on how sections are retrieved from
+ an FFS file based on SectionType and SectionInstance.
+
+ If the currently executing module was not loaded from a firmware volume, then EFI_NOT_FOUND is returned.
+ If SectionType is EFI_SECTION_TE, and the search with an FFS file fails,
+ the search will be retried with a section type of EFI_SECTION_PE32.
+
+ This function must be called with a TPL <= TPL_NOTIFY.
+ If NameGuid is NULL, then ASSERT().
+ If Buffer is NULL, then ASSERT().
+ If Size is NULL, then ASSERT().
+
+ @param NameGuid A pointer to to the FFS filename GUID to search for
+ within the firmware volumes that the currently
+ executing module was loaded from.
+ @param SectionType Indicates the FFS section type to search for within
+ the FFS file specified by NameGuid.
+ @param SectionInstance Indicates which section instance within the FFS file
+ specified by NameGuid to retrieve.
+ @param Buffer On output, a pointer to a callee allocated buffer
+ containing the FFS file section that was found.
+ Is it the caller's responsibility to free this buffer
+ using FreePool().
+ @param Size On output, a pointer to the size, in bytes, of Buffer.
+
+
+ @retval EFI_SUCCESS The specified FFS section was returned.
+ @retval EFI_NOT_FOUND The specified FFS section could not be found.
+ @retval EFI_OUT_OF_RESOURCES There are not enough resources available to retrieve
+ the matching FFS section.
+ @retval EFI_DEVICE_ERROR The FFS section could not be retrieves due to a
+ device error.
+ @retval EFI_ACCESS_DENIED The FFS section could not be retrieves because the
+ firmware volume that contains the matching FFS
+ section does not allow reads.
+**/
+EFI_STATUS
+EFIAPI
+GetSectionFromFv (
+ IN CONST EFI_GUID *NameGuid,
+ IN EFI_SECTION_TYPE SectionType,
+ IN UINTN SectionInstance,
+ OUT VOID **Buffer,
+ OUT UINTN *Size
+ )
+{
+ return InternalGetSectionFromFv (
+ InternalImageHandleToFvHandle(gImageHandle),
+ NameGuid,
+ SectionType,
+ SectionInstance,
+ Buffer,
+ Size
+ );
+}
+
+
+/**
+ Searches the FFS file the currently executing module was loaded from and returns the first matching FFS section.
+
+ This function searches the FFS file that the currently executing module was loaded from for a FFS sections of type SectionType.
+ If the FFS file contains at least SectionInstance instances of the FFS section specified by SectionType,
+ then the SectionInstance instance is returned in Buffer. Buffer is allocated using AllocatePool(),
+ and the size of the allocated buffer is returned in Size. It is the caller's responsibility
+ to use FreePool() to free the allocated buffer. See EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadSection() for
+ details on how sections are retrieved from an FFS file based on SectionType and SectionInstance.
+
+ If the currently executing module was not loaded from an FFS file, then EFI_NOT_FOUND is returned.
+ If SectionType is EFI_SECTION_TE, and the search with an FFS file fails,
+ the search will be retried with a section type of EFI_SECTION_PE32.
+ This function must be called with a TPL <= TPL_NOTIFY.
+
+ If Buffer is NULL, then ASSERT().
+ If Size is NULL, then ASSERT().
+
+
+ @param SectionType Indicates the FFS section type to search for within
+ the FFS file that the currently executing module
+ was loaded from.
+ @param SectionInstance Indicates which section instance to retrieve within
+ the FFS file that the currently executing module
+ was loaded from.
+ @param Buffer On output, a pointer to a callee allocated buffer
+ containing the FFS file section that was found.
+ Is it the caller's responsibility to free this buffer
+ using FreePool().
+ @param Size On output, a pointer to the size, in bytes, of Buffer.
+
+ @retval EFI_SUCCESS The specified FFS section was returned.
+ @retval EFI_NOT_FOUND The specified FFS section could not be found.
+ @retval EFI_OUT_OF_RESOURCES There are not enough resources available to retrieve
+ the matching FFS section.
+ @retval EFI_DEVICE_ERROR The FFS section could not be retrieves due to a
+ device error.
+ @retval EFI_ACCESS_DENIED The FFS section could not be retrieves because the
+ firmware volume that contains the matching FFS
+ section does not allow reads.
+
+**/
+EFI_STATUS
+EFIAPI
+GetSectionFromFfs (
+ IN EFI_SECTION_TYPE SectionType,
+ IN UINTN SectionInstance,
+ OUT VOID **Buffer,
+ OUT UINTN *Size
+ )
+{
+ return InternalGetSectionFromFv(
+ InternalImageHandleToFvHandle(gImageHandle),
+ &gEfiCallerIdGuid,
+ SectionType,
+ SectionInstance,
+ Buffer,
+ Size
+ );
+}
+
+
+/**
+ Get the image file buffer data and buffer size by its device path.
+
+ Access the file either from a firmware volume, from a file system interface,
+ or from the load file interface.
+
+ Allocate memory to store the found image. The caller is responsible to free memory.
+
+ If FilePath is NULL, then NULL is returned.
+ If FileSize is NULL, then NULL is returned.
+ If AuthenticationStatus is NULL, then NULL is returned.
+
+ @param[in] BootPolicy Policy for Open Image File.If TRUE, indicates
+ that the request originates from the boot
+ manager, and that the boot manager is
+ attempting to load FilePath as a boot
+ selection. If FALSE, then FilePath must
+ match an exact file to be loaded.
+ @param[in] FilePath The pointer to the device path of the file
+ that is abstracted to the file buffer.
+ @param[out] FileSize The pointer to the size of the abstracted
+ file buffer.
+ @param[out] AuthenticationStatus Pointer to the authentication status.
+
+ @retval NULL FilePath is NULL, or FileSize is NULL, or AuthenticationStatus is NULL, or the file can't be found.
+ @retval other The abstracted file buffer. The caller is responsible to free memory.
+**/
+VOID *
+EFIAPI
+GetFileBufferByFilePath (
+ IN BOOLEAN BootPolicy,
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *FilePath,
+ OUT UINTN *FileSize,
+ OUT UINT32 *AuthenticationStatus
+ )
+{
+ EFI_DEVICE_PATH_PROTOCOL *DevicePathNode;
+ EFI_DEVICE_PATH_PROTOCOL *OrigDevicePathNode;
+ EFI_DEVICE_PATH_PROTOCOL *TempDevicePathNode;
+ EFI_HANDLE Handle;
+ EFI_GUID *FvNameGuid;
+ EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol;
+ EFI_SECTION_TYPE SectionType;
+ UINT8 *ImageBuffer;
+ UINTN ImageBufferSize;
+ EFI_FV_FILETYPE Type;
+ EFI_FV_FILE_ATTRIBUTES Attrib;
+ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Volume;
+ EFI_FILE_HANDLE FileHandle;
+ EFI_FILE_HANDLE LastHandle;
+ EFI_FILE_INFO *FileInfo;
+ UINTN FileInfoSize;
+ EFI_LOAD_FILE_PROTOCOL *LoadFile;
+ EFI_LOAD_FILE2_PROTOCOL *LoadFile2;
+ EFI_STATUS Status;
+
+ //
+ // Check input File device path.
+ //
+ if (FilePath == NULL || FileSize == NULL || AuthenticationStatus == NULL) {
+ return NULL;
+ }
+
+ //
+ // Init local variable
+ //
+ TempDevicePathNode = NULL;
+ FvNameGuid = NULL;
+ FileInfo = NULL;
+ FileHandle = NULL;
+ ImageBuffer = NULL;
+ ImageBufferSize = 0;
+ *AuthenticationStatus = 0;
+
+ //
+ // Copy File Device Path
+ //
+ OrigDevicePathNode = DuplicateDevicePath (FilePath);
+ if (OrigDevicePathNode == NULL) {
+ return NULL;
+ }
+
+ //
+ // Check whether this device path support FV2 protocol.
+ // Is so, this device path may contain a Image.
+ //
+ DevicePathNode = OrigDevicePathNode;
+ Status = gBS->LocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid, &DevicePathNode, &Handle);
+ if (!EFI_ERROR (Status)) {
+ //
+ // For FwVol File system there is only a single file name that is a GUID.
+ //
+ FvNameGuid = EfiGetNameGuidFromFwVolDevicePathNode ((CONST MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) DevicePathNode);
+ if (FvNameGuid == NULL) {
+ Status = EFI_INVALID_PARAMETER;
+ } else {
+ //
+ // Read image from the firmware file
+ //
+ Status = gBS->HandleProtocol (Handle, &gEfiFirmwareVolume2ProtocolGuid, (VOID**)&FwVol);
+ if (!EFI_ERROR (Status)) {
+ SectionType = EFI_SECTION_PE32;
+ ImageBuffer = NULL;
+ Status = FwVol->ReadSection (
+ FwVol,
+ FvNameGuid,
+ SectionType,
+ 0,
+ (VOID **)&ImageBuffer,
+ &ImageBufferSize,
+ AuthenticationStatus
+ );
+ if (EFI_ERROR (Status)) {
+ //
+ // Try a raw file, since a PE32 SECTION does not exist
+ //
+ if (ImageBuffer != NULL) {
+ FreePool (ImageBuffer);
+ *AuthenticationStatus = 0;
+ }
+ ImageBuffer = NULL;
+ Status = FwVol->ReadFile (
+ FwVol,
+ FvNameGuid,
+ (VOID **)&ImageBuffer,
+ &ImageBufferSize,
+ &Type,
+ &Attrib,
+ AuthenticationStatus
+ );
+ }
+ }
+ }
+ if (!EFI_ERROR (Status)) {
+ goto Finish;
+ }
+ }
+
+ //
+ // Attempt to access the file via a file system interface
+ //
+ DevicePathNode = OrigDevicePathNode;
+ Status = gBS->LocateDevicePath (&gEfiSimpleFileSystemProtocolGuid, &DevicePathNode, &Handle);
+ if (!EFI_ERROR (Status)) {
+ Status = gBS->HandleProtocol (Handle, &gEfiSimpleFileSystemProtocolGuid, (VOID**)&Volume);
+ if (!EFI_ERROR (Status)) {
+ //
+ // Open the Volume to get the File System handle
+ //
+ Status = Volume->OpenVolume (Volume, &FileHandle);
+ if (!EFI_ERROR (Status)) {
+ //
+ // Duplicate the device path to avoid the access to unaligned device path node.
+ // Because the device path consists of one or more FILE PATH MEDIA DEVICE PATH
+ // nodes, It assures the fields in device path nodes are 2 byte aligned.
+ //
+ TempDevicePathNode = DuplicateDevicePath (DevicePathNode);
+ if (TempDevicePathNode == NULL) {
+ FileHandle->Close (FileHandle);
+ //
+ // Setting Status to an EFI_ERROR value will cause the rest of
+ // the file system support below to be skipped.
+ //
+ Status = EFI_OUT_OF_RESOURCES;
+ }
+ //
+ // Parse each MEDIA_FILEPATH_DP node. There may be more than one, since the
+ // directory information and filename can be separate. The goal is to inch
+ // our way down each device path node and close the previous node
+ //
+ DevicePathNode = TempDevicePathNode;
+ while (!EFI_ERROR (Status) && !IsDevicePathEnd (DevicePathNode)) {
+ if (DevicePathType (DevicePathNode) != MEDIA_DEVICE_PATH ||
+ DevicePathSubType (DevicePathNode) != MEDIA_FILEPATH_DP) {
+ Status = EFI_UNSUPPORTED;
+ break;
+ }
+
+ LastHandle = FileHandle;
+ FileHandle = NULL;
+
+ Status = LastHandle->Open (
+ LastHandle,
+ &FileHandle,
+ ((FILEPATH_DEVICE_PATH *) DevicePathNode)->PathName,
+ EFI_FILE_MODE_READ,
+ 0
+ );
+
+ //
+ // Close the previous node
+ //
+ LastHandle->Close (LastHandle);
+
+ DevicePathNode = NextDevicePathNode (DevicePathNode);
+ }
+
+ if (!EFI_ERROR (Status)) {
+ //
+ // We have found the file. Now we need to read it. Before we can read the file we need to
+ // figure out how big the file is.
+ //
+ FileInfo = NULL;
+ FileInfoSize = 0;
+ Status = FileHandle->GetInfo (
+ FileHandle,
+ &gEfiFileInfoGuid,
+ &FileInfoSize,
+ FileInfo
+ );
+
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ FileInfo = AllocatePool (FileInfoSize);
+ if (FileInfo == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ } else {
+ Status = FileHandle->GetInfo (
+ FileHandle,
+ &gEfiFileInfoGuid,
+ &FileInfoSize,
+ FileInfo
+ );
+ }
+ }
+
+ if (!EFI_ERROR (Status) && (FileInfo != NULL)) {
+ if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) == 0) {
+ //
+ // Allocate space for the file
+ //
+ ImageBuffer = AllocatePool ((UINTN)FileInfo->FileSize);
+ if (ImageBuffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ } else {
+ //
+ // Read the file into the buffer we allocated
+ //
+ ImageBufferSize = (UINTN)FileInfo->FileSize;
+ Status = FileHandle->Read (FileHandle, &ImageBufferSize, ImageBuffer);
+ }
+ }
+ }
+ }
+ //
+ // Close the file and Free FileInfo and TempDevicePathNode since we are done
+ //
+ if (FileInfo != NULL) {
+ FreePool (FileInfo);
+ }
+ if (FileHandle != NULL) {
+ FileHandle->Close (FileHandle);
+ }
+ if (TempDevicePathNode != NULL) {
+ FreePool (TempDevicePathNode);
+ }
+ }
+ }
+ if (!EFI_ERROR (Status)) {
+ goto Finish;
+ }
+ }
+
+ //
+ // Attempt to access the file via LoadFile2 interface
+ //
+ if (!BootPolicy) {
+ DevicePathNode = OrigDevicePathNode;
+ Status = gBS->LocateDevicePath (&gEfiLoadFile2ProtocolGuid, &DevicePathNode, &Handle);
+ if (!EFI_ERROR (Status)) {
+ Status = gBS->HandleProtocol (Handle, &gEfiLoadFile2ProtocolGuid, (VOID**)&LoadFile2);
+ if (!EFI_ERROR (Status)) {
+ //
+ // Call LoadFile2 with the correct buffer size
+ //
+ ImageBufferSize = 0;
+ ImageBuffer = NULL;
+ Status = LoadFile2->LoadFile (
+ LoadFile2,
+ DevicePathNode,
+ FALSE,
+ &ImageBufferSize,
+ ImageBuffer
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ ImageBuffer = AllocatePool (ImageBufferSize);
+ if (ImageBuffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ } else {
+ Status = LoadFile2->LoadFile (
+ LoadFile2,
+ DevicePathNode,
+ FALSE,
+ &ImageBufferSize,
+ ImageBuffer
+ );
+ }
+ }
+ }
+ if (!EFI_ERROR (Status)) {
+ goto Finish;
+ }
+ }
+ }
+
+ //
+ // Attempt to access the file via LoadFile interface
+ //
+ DevicePathNode = OrigDevicePathNode;
+ Status = gBS->LocateDevicePath (&gEfiLoadFileProtocolGuid, &DevicePathNode, &Handle);
+ if (!EFI_ERROR (Status)) {
+ Status = gBS->HandleProtocol (Handle, &gEfiLoadFileProtocolGuid, (VOID**)&LoadFile);
+ if (!EFI_ERROR (Status)) {
+ //
+ // Call LoadFile with the correct buffer size
+ //
+ ImageBufferSize = 0;
+ ImageBuffer = NULL;
+ Status = LoadFile->LoadFile (
+ LoadFile,
+ DevicePathNode,
+ BootPolicy,
+ &ImageBufferSize,
+ ImageBuffer
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ ImageBuffer = AllocatePool (ImageBufferSize);
+ if (ImageBuffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ } else {
+ Status = LoadFile->LoadFile (
+ LoadFile,
+ DevicePathNode,
+ BootPolicy,
+ &ImageBufferSize,
+ ImageBuffer
+ );
+ }
+ }
+ }
+ }
+
+Finish:
+
+ if (EFI_ERROR (Status)) {
+ if (ImageBuffer != NULL) {
+ FreePool (ImageBuffer);
+ ImageBuffer = NULL;
+ }
+ *FileSize = 0;
+ } else {
+ *FileSize = ImageBufferSize;
+ }
+
+ FreePool (OrigDevicePathNode);
+
+ return ImageBuffer;
+}
+
+/**
+ Searches all the available firmware volumes and returns the file device path of first matching
+ FFS section.
+
+ This function searches all the firmware volumes for FFS files with an FFS filename specified by NameGuid.
+ The order that the firmware volumes is searched is not deterministic. For each FFS file found a search
+ is made for FFS sections of type SectionType.
+
+ If SectionType is EFI_SECTION_TE, and the search with an FFS file fails,
+ the search will be retried with a section type of EFI_SECTION_PE32.
+ This function must be called with a TPL <= TPL_NOTIFY.
+
+ If NameGuid is NULL, then ASSERT().
+
+ @param NameGuid A pointer to to the FFS filename GUID to search for
+ within any of the firmware volumes in the platform.
+ @param SectionType Indicates the FFS section type to search for within
+ the FFS file specified by NameGuid.
+ @param SectionInstance Indicates which section instance within the FFS file
+ specified by NameGuid to retrieve.
+ @param FvFileDevicePath Device path for the target FFS
+ file.
+
+ @retval EFI_SUCCESS The specified file device path of FFS section was returned.
+ @retval EFI_NOT_FOUND The specified file device path of FFS section could not be found.
+ @retval EFI_DEVICE_ERROR The FFS section could not be retrieves due to a
+ device error.
+ @retval EFI_ACCESS_DENIED The FFS section could not be retrieves because the
+ firmware volume that contains the matching FFS section does not
+ allow reads.
+ @retval EFI_INVALID_PARAMETER FvFileDevicePath is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+GetFileDevicePathFromAnyFv (
+ IN CONST EFI_GUID *NameGuid,
+ IN EFI_SECTION_TYPE SectionType,
+ IN UINTN SectionInstance,
+ OUT EFI_DEVICE_PATH_PROTOCOL **FvFileDevicePath
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *HandleBuffer;
+ UINTN HandleCount;
+ UINTN Index;
+ EFI_HANDLE FvHandle;
+ EFI_DEVICE_PATH_PROTOCOL *FvDevicePath;
+ MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *TempFvFileDevicePath;
+ VOID *Buffer;
+ UINTN Size;
+
+ if (FvFileDevicePath == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ HandleBuffer = NULL;
+ FvDevicePath = NULL;
+ TempFvFileDevicePath = NULL;
+ Buffer = NULL;
+ Size = 0;
+
+ //
+ // Search the FV that contain the caller's FFS first.
+ // FV builder can choose to build FFS into the this FV
+ // so that this implementation of GetSectionFromAnyFv
+ // will locate the FFS faster.
+ //
+ FvHandle = InternalImageHandleToFvHandle (gImageHandle);
+ Status = InternalGetSectionFromFv (
+ FvHandle,
+ NameGuid,
+ SectionType,
+ SectionInstance,
+ &Buffer,
+ &Size
+ );
+ if (!EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiFirmwareVolume2ProtocolGuid,
+ NULL,
+ &HandleCount,
+ &HandleBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ for (Index = 0; Index < HandleCount; Index++) {
+ //
+ // Skip the FV that contain the caller's FFS
+ //
+ if (HandleBuffer[Index] != FvHandle) {
+ Status = InternalGetSectionFromFv (
+ HandleBuffer[Index],
+ NameGuid,
+ SectionType,
+ SectionInstance,
+ &Buffer,
+ &Size
+ );
+
+ if (!EFI_ERROR (Status)) {
+ //
+ // Update FvHandle to the current handle.
+ //
+ FvHandle = HandleBuffer[Index];
+ goto Done;
+ }
+ }
+ }
+
+ if (Index == HandleCount) {
+ Status = EFI_NOT_FOUND;
+ }
+
+Done:
+ if (Status == EFI_SUCCESS) {
+ //
+ // Build a device path to the file in the FV to pass into gBS->LoadImage
+ //
+ Status = gBS->HandleProtocol (FvHandle, &gEfiDevicePathProtocolGuid, (VOID **)&FvDevicePath);
+ if (EFI_ERROR (Status)) {
+ *FvFileDevicePath = NULL;
+ } else {
+ TempFvFileDevicePath = AllocateZeroPool (sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH) + END_DEVICE_PATH_LENGTH);
+ if (TempFvFileDevicePath == NULL) {
+ *FvFileDevicePath = NULL;
+ return EFI_OUT_OF_RESOURCES;
+ }
+ EfiInitializeFwVolDevicepathNode ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH*)TempFvFileDevicePath, NameGuid);
+ SetDevicePathEndNode (NextDevicePathNode (TempFvFileDevicePath));
+ *FvFileDevicePath = AppendDevicePath (
+ FvDevicePath,
+ (EFI_DEVICE_PATH_PROTOCOL *)TempFvFileDevicePath
+ );
+ FreePool (TempFvFileDevicePath);
+ }
+ }
+
+ if (Buffer != NULL) {
+ FreePool (Buffer);
+ }
+
+ if (HandleBuffer != NULL) {
+ FreePool (HandleBuffer);
+ }
+
+ return Status;
+}
diff --git a/roms/edk2/MdePkg/Library/DxeServicesLib/DxeServicesLib.inf b/roms/edk2/MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
new file mode 100644
index 000000000..ec3e8711c
--- /dev/null
+++ b/roms/edk2/MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
@@ -0,0 +1,60 @@
+## @file
+# DXE Services Library instance provides functions that simplify the development of DXE Drivers.
+#
+# DXE Services Library provides access data from sections of FFS files based on FV protocol.
+# It also provides access file based on file path from a firmware volume,
+# from a file system interface, or from the load file interface.
+#
+# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = DxeServicesLib
+ MODULE_UNI_FILE = DxeServicesLib.uni
+ FILE_GUID = EE680C58-FFC0-4a5d-858F-66FF9C84BC9F
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = DxeServicesLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER SMM_CORE UEFI_APPLICATION UEFI_DRIVER
+
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC ARM AARCH64 RISCV64
+#
+
+[Sources]
+ DxeServicesLib.c
+
+[Sources.IA32, Sources.EBC, Sources.ARM, Sources.AARCH64, Sources.RISCV64]
+ Allocate.c
+
+[Sources.X64]
+ X64/Allocate.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+
+
+[LibraryClasses]
+ MemoryAllocationLib
+ DebugLib
+ DevicePathLib
+ UefiLib
+ UefiBootServicesTableLib
+
+[LibraryClasses.X64]
+ HobLib
+
+[Guids]
+ gEfiFileInfoGuid ## SOMETIMES_CONSUMES ## UNDEFINED
+
+[Protocols]
+ gEfiFirmwareVolume2ProtocolGuid ## SOMETIMES_CONSUMES
+ gEfiLoadedImageProtocolGuid ## SOMETIMES_CONSUMES
+ gEfiLoadFileProtocolGuid ## SOMETIMES_CONSUMES
+ gEfiLoadFile2ProtocolGuid ## SOMETIMES_CONSUMES
+ gEfiSimpleFileSystemProtocolGuid ## SOMETIMES_CONSUMES
+
diff --git a/roms/edk2/MdePkg/Library/DxeServicesLib/DxeServicesLib.uni b/roms/edk2/MdePkg/Library/DxeServicesLib/DxeServicesLib.uni
new file mode 100644
index 000000000..9f1036218
--- /dev/null
+++ b/roms/edk2/MdePkg/Library/DxeServicesLib/DxeServicesLib.uni
@@ -0,0 +1,18 @@
+// /** @file
+// DXE Services Library instance provides functions that simplify the development of DXE Drivers.
+//
+// DXE Services Library provides access data from sections of FFS files based on FV protocol.
+// It also provides access file based on file path from a firmware volume,
+// from a file system interface, or from the load file interface.
+//
+// Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "Provides functions that simplify the development of DXE Drivers"
+
+#string STR_MODULE_DESCRIPTION #language en-US "A DXE Services Library provides access data from sections of FFS files based on FV protocol. It also provides access file based on file path from a firmware volume, from a file system interface, or from the load file interface."
+
diff --git a/roms/edk2/MdePkg/Library/DxeServicesLib/X64/Allocate.c b/roms/edk2/MdePkg/Library/DxeServicesLib/X64/Allocate.c
new file mode 100644
index 000000000..41c4cea39
--- /dev/null
+++ b/roms/edk2/MdePkg/Library/DxeServicesLib/X64/Allocate.c
@@ -0,0 +1,63 @@
+/** @file
+ DxeServicesLib memory allocation routines
+
+ Copyright (c) 2018, Linaro, Ltd. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiDxe.h>
+#include <Library/HobLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DxeServicesLib.h>
+
+/**
+ Allocates one or more 4KB pages of a given type from a memory region that is
+ accessible to PEI.
+
+ Allocates the number of 4KB pages of type '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 remaining to satisfy the request, then NULL is returned.
+
+ @param[in] MemoryType The memory type to allocate
+ @param[in] Pages The number of 4 KB pages to allocate.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocatePeiAccessiblePages (
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN Pages
+ )
+{
+ EFI_STATUS Status;
+ EFI_ALLOCATE_TYPE AllocType;
+ EFI_PHYSICAL_ADDRESS Memory;
+ EFI_HOB_HANDOFF_INFO_TABLE *PhitHob;
+
+ if (Pages == 0) {
+ return NULL;
+ }
+
+ AllocType = AllocateAnyPages;
+ //
+ // A X64 build of DXE may be combined with a 32-bit build of PEI, and so we
+ // need to check the memory limit set by PEI, and allocate below 4 GB if the
+ // limit is set to 4 GB or lower.
+ //
+ PhitHob = (EFI_HOB_HANDOFF_INFO_TABLE *)GetHobList ();
+ if (PhitHob->EfiFreeMemoryTop <= MAX_UINT32) {
+ AllocType = AllocateMaxAddress;
+ Memory = MAX_UINT32;
+ }
+
+ Status = gBS->AllocatePages (AllocType, MemoryType, Pages, &Memory);
+ if (EFI_ERROR (Status)) {
+ return NULL;
+ }
+ return (VOID *)(UINTN)Memory;
+}