/** @file
  The file contains the GCD related services in the EFI Boot Services Table.
  The GCD services are used to manage the memory and I/O regions that
  are accessible to the CPU that is executing the DXE core.

Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include <Pi/PrePiDxeCis.h>
#include <Pi/PrePiHob.h>
#include "DxeMain.h"
#include "Gcd.h"
#include "Mem/HeapGuard.h"

#define MINIMUM_INITIAL_MEMORY_SIZE  0x10000

#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      )

#define INITIALIZED_MEMORY_ATTRIBUTES  (EFI_RESOURCE_ATTRIBUTE_PRESENT     |\
                                       EFI_RESOURCE_ATTRIBUTE_INITIALIZED )

#define PRESENT_MEMORY_ATTRIBUTES  (EFI_RESOURCE_ATTRIBUTE_PRESENT)

//
// Module Variables
//
EFI_LOCK    mGcdMemorySpaceLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_NOTIFY);
EFI_LOCK    mGcdIoSpaceLock     = EFI_INITIALIZE_LOCK_VARIABLE (TPL_NOTIFY);
LIST_ENTRY  mGcdMemorySpaceMap  = INITIALIZE_LIST_HEAD_VARIABLE (mGcdMemorySpaceMap);
LIST_ENTRY  mGcdIoSpaceMap      = INITIALIZE_LIST_HEAD_VARIABLE (mGcdIoSpaceMap);

EFI_GCD_MAP_ENTRY  mGcdMemorySpaceMapEntryTemplate = {
  EFI_GCD_MAP_SIGNATURE,
  {
    NULL,
    NULL
  },
  0,
  0,
  0,
  0,
  EfiGcdMemoryTypeNonExistent,
  (EFI_GCD_IO_TYPE)0,
  NULL,
  NULL
};

EFI_GCD_MAP_ENTRY  mGcdIoSpaceMapEntryTemplate = {
  EFI_GCD_MAP_SIGNATURE,
  {
    NULL,
    NULL
  },
  0,
  0,
  0,
  0,
  (EFI_GCD_MEMORY_TYPE)0,
  EfiGcdIoTypeNonExistent,
  NULL,
  NULL
};

GCD_ATTRIBUTE_CONVERSION_ENTRY  mAttributeConversionTable[] = {
  { EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE,             EFI_MEMORY_UC,            TRUE  },
  { EFI_RESOURCE_ATTRIBUTE_UNCACHED_EXPORTED,       EFI_MEMORY_UCE,           TRUE  },
  { EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE,       EFI_MEMORY_WC,            TRUE  },
  { EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE, EFI_MEMORY_WT,            TRUE  },
  { EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE,    EFI_MEMORY_WB,            TRUE  },
  { EFI_RESOURCE_ATTRIBUTE_READ_PROTECTABLE,        EFI_MEMORY_RP,            TRUE  },
  { EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTABLE,       EFI_MEMORY_WP,            TRUE  },
  { EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTABLE,   EFI_MEMORY_XP,            TRUE  },
  { EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTABLE,   EFI_MEMORY_RO,            TRUE  },
  { EFI_RESOURCE_ATTRIBUTE_PRESENT,                 EFI_MEMORY_PRESENT,       FALSE },
  { EFI_RESOURCE_ATTRIBUTE_INITIALIZED,             EFI_MEMORY_INITIALIZED,   FALSE },
  { EFI_RESOURCE_ATTRIBUTE_TESTED,                  EFI_MEMORY_TESTED,        FALSE },
  { EFI_RESOURCE_ATTRIBUTE_PERSISTABLE,             EFI_MEMORY_NV,            TRUE  },
  { EFI_RESOURCE_ATTRIBUTE_MORE_RELIABLE,           EFI_MEMORY_MORE_RELIABLE, TRUE  },
  { 0,                                              0,                        FALSE }
};

///
/// Lookup table used to print GCD Memory Space Map
///
GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8  *mGcdMemoryTypeNames[] = {
  "NonExist ",  // EfiGcdMemoryTypeNonExistent
  "Reserved ",  // EfiGcdMemoryTypeReserved
  "SystemMem",  // EfiGcdMemoryTypeSystemMemory
  "MMIO     ",  // EfiGcdMemoryTypeMemoryMappedIo
  "PersisMem",  // EfiGcdMemoryTypePersistent
  "MoreRelia",  // EfiGcdMemoryTypeMoreReliable
  "Unaccepte",  // EFI_GCD_MEMORY_TYPE_UNACCEPTED
  "Unknown  "   // EfiGcdMemoryTypeMaximum
};

///
/// Lookup table used to print GCD I/O Space Map
///
GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8  *mGcdIoTypeNames[] = {
  "NonExist",  // EfiGcdIoTypeNonExistent
  "Reserved",  // EfiGcdIoTypeReserved
  "I/O     ",  // EfiGcdIoTypeIo
  "Unknown "   // EfiGcdIoTypeMaximum
};

///
/// Lookup table used to print GCD Allocation Types
///
GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8  *mGcdAllocationTypeNames[] = {
  "AnySearchBottomUp        ",  // EfiGcdAllocateAnySearchBottomUp
  "MaxAddressSearchBottomUp ",  // EfiGcdAllocateMaxAddressSearchBottomUp
  "AtAddress                ",  // EfiGcdAllocateAddress
  "AnySearchTopDown         ",  // EfiGcdAllocateAnySearchTopDown
  "MaxAddressSearchTopDown  ",  // EfiGcdAllocateMaxAddressSearchTopDown
  "Unknown                  "   // EfiGcdMaxAllocateType
};

/**
  Dump the entire contents if the GCD Memory Space Map using DEBUG() macros when
  PcdDebugPrintErrorLevel has the DEBUG_GCD bit set.

  @param  InitialMap  TRUE if the initial GCD Memory Map is being dumped.  Otherwise, FALSE.

**/
VOID
EFIAPI
CoreDumpGcdMemorySpaceMap (
  BOOLEAN  InitialMap
  )
{
  DEBUG_CODE_BEGIN ();
  EFI_STATUS                       Status;
  UINTN                            NumberOfDescriptors;
  EFI_GCD_MEMORY_SPACE_DESCRIPTOR  *MemorySpaceMap;
  UINTN                            Index;

  Status = CoreGetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap);
  ASSERT (Status == EFI_SUCCESS && MemorySpaceMap != NULL);

  if (InitialMap) {
    DEBUG ((DEBUG_GCD, "GCD:Initial GCD Memory Space Map\n"));
  }

  DEBUG ((DEBUG_GCD, "GCDMemType Range                             Capabilities     Attributes      \n"));
  DEBUG ((DEBUG_GCD, "========== ================================= ================ ================\n"));
  for (Index = 0; Index < NumberOfDescriptors; Index++) {
    DEBUG ((
      DEBUG_GCD,
      "%a  %016lx-%016lx %016lx %016lx%c\n",
      mGcdMemoryTypeNames[MIN (MemorySpaceMap[Index].GcdMemoryType, EfiGcdMemoryTypeMaximum)],
      MemorySpaceMap[Index].BaseAddress,
      MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length - 1,
      MemorySpaceMap[Index].Capabilities,
      MemorySpaceMap[Index].Attributes,
      MemorySpaceMap[Index].ImageHandle == NULL ? ' ' : '*'
      ));
  }

  DEBUG ((DEBUG_GCD, "\n"));
  FreePool (MemorySpaceMap);
  DEBUG_CODE_END ();
}

/**
  Dump the entire contents if the GCD I/O Space Map using DEBUG() macros when
  PcdDebugPrintErrorLevel has the DEBUG_GCD bit set.

  @param  InitialMap  TRUE if the initial GCD I/O Map is being dumped.  Otherwise, FALSE.

**/
VOID
EFIAPI
CoreDumpGcdIoSpaceMap (
  BOOLEAN  InitialMap
  )
{
  DEBUG_CODE_BEGIN ();
  EFI_STATUS                   Status;
  UINTN                        NumberOfDescriptors;
  EFI_GCD_IO_SPACE_DESCRIPTOR  *IoSpaceMap;
  UINTN                        Index;

  Status = CoreGetIoSpaceMap (&NumberOfDescriptors, &IoSpaceMap);
  ASSERT (Status == EFI_SUCCESS && IoSpaceMap != NULL);

  if (InitialMap) {
    DEBUG ((DEBUG_GCD, "GCD:Initial GCD I/O Space Map\n"));
  }

  DEBUG ((DEBUG_GCD, "GCDIoType  Range                            \n"));
  DEBUG ((DEBUG_GCD, "========== =================================\n"));
  for (Index = 0; Index < NumberOfDescriptors; Index++) {
    DEBUG ((
      DEBUG_GCD,
      "%a   %016lx-%016lx%c\n",
      mGcdIoTypeNames[MIN (IoSpaceMap[Index].GcdIoType, EfiGcdIoTypeMaximum)],
      IoSpaceMap[Index].BaseAddress,
      IoSpaceMap[Index].BaseAddress + IoSpaceMap[Index].Length - 1,
      IoSpaceMap[Index].ImageHandle == NULL ? ' ' : '*'
      ));
  }

  DEBUG ((DEBUG_GCD, "\n"));
  FreePool (IoSpaceMap);
  DEBUG_CODE_END ();
}

/**
  Validate resource descriptor HOB's attributes.

  If Attributes includes some memory resource's settings, it should include
  the corresponding capabilites also.

  @param  Attributes  Resource descriptor HOB attributes.

**/
VOID
CoreValidateResourceDescriptorHobAttributes (
  IN UINT64  Attributes
  )
{
  ASSERT (
    ((Attributes & EFI_RESOURCE_ATTRIBUTE_READ_PROTECTED) == 0) ||
    ((Attributes & EFI_RESOURCE_ATTRIBUTE_READ_PROTECTABLE) != 0)
    );
  ASSERT (
    ((Attributes & EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED) == 0) ||
    ((Attributes & EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTABLE) != 0)
    );
  ASSERT (
    ((Attributes & EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTED) == 0) ||
    ((Attributes & EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTABLE) != 0)
    );
  ASSERT (
    ((Attributes & EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTED) == 0) ||
    ((Attributes & EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTABLE) != 0)
    );
  ASSERT (
    ((Attributes & EFI_RESOURCE_ATTRIBUTE_PERSISTENT) == 0) ||
    ((Attributes & EFI_RESOURCE_ATTRIBUTE_PERSISTABLE) != 0)
    );
}

/**
  Acquire memory lock on mGcdMemorySpaceLock.

**/
VOID
CoreAcquireGcdMemoryLock (
  VOID
  )
{
  CoreAcquireLock (&mGcdMemorySpaceLock);
}

/**
  Release memory lock on mGcdMemorySpaceLock.

**/
VOID
CoreReleaseGcdMemoryLock (
  VOID
  )
{
  CoreReleaseLock (&mGcdMemorySpaceLock);
}

/**
  Acquire memory lock on mGcdIoSpaceLock.

**/
VOID
CoreAcquireGcdIoLock (
  VOID
  )
{
  CoreAcquireLock (&mGcdIoSpaceLock);
}

/**
  Release memory lock on mGcdIoSpaceLock.

**/
VOID
CoreReleaseGcdIoLock (
  VOID
  )
{
  CoreReleaseLock (&mGcdIoSpaceLock);
}

//
// GCD Initialization Worker Functions
//

/**
  Aligns a value to the specified boundary.

  @param  Value                  64 bit value to align
  @param  Alignment              Log base 2 of the boundary to align Value to
  @param  RoundUp                TRUE if Value is to be rounded up to the nearest
                                 aligned boundary.  FALSE is Value is to be
                                 rounded down to the nearest aligned boundary.

  @return A 64 bit value is the aligned to the value nearest Value with an alignment by Alignment.

**/
UINT64
AlignValue (
  IN UINT64   Value,
  IN UINTN    Alignment,
  IN BOOLEAN  RoundUp
  )
{
  UINT64  AlignmentMask;

  AlignmentMask = LShiftU64 (1, Alignment) - 1;
  if (RoundUp) {
    Value += AlignmentMask;
  }

  return Value & (~AlignmentMask);
}

/**
  Aligns address to the page boundary.

  @param  Value                  64 bit address to align

  @return A 64 bit value is the aligned to the value nearest Value with an alignment by Alignment.

**/
UINT64
PageAlignAddress (
  IN UINT64  Value
  )
{
  return AlignValue (Value, EFI_PAGE_SHIFT, TRUE);
}

/**
  Aligns length to the page boundary.

  @param  Value                  64 bit length to align

  @return A 64 bit value is the aligned to the value nearest Value with an alignment by Alignment.

**/
UINT64
PageAlignLength (
  IN UINT64  Value
  )
{
  return AlignValue (Value, EFI_PAGE_SHIFT, FALSE);
}

//
// GCD Memory Space Worker Functions
//

/**
  Allocate pool for two entries.

  @param  TopEntry               An entry of GCD map
  @param  BottomEntry            An entry of GCD map

  @retval EFI_OUT_OF_RESOURCES   No enough buffer to be allocated.
  @retval EFI_SUCCESS            Both entries successfully allocated.

**/
EFI_STATUS
CoreAllocateGcdMapEntry (
  IN OUT EFI_GCD_MAP_ENTRY  **TopEntry,
  IN OUT EFI_GCD_MAP_ENTRY  **BottomEntry
  )
{
  //
  // Set to mOnGuarding to TRUE before memory allocation. This will make sure
  // that the entry memory is not "guarded" by HeapGuard. Otherwise it might
  // cause problem when it's freed (if HeapGuard is enabled).
  //
  mOnGuarding = TRUE;
  *TopEntry   = AllocateZeroPool (sizeof (EFI_GCD_MAP_ENTRY));
  mOnGuarding = FALSE;
  if (*TopEntry == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  mOnGuarding  = TRUE;
  *BottomEntry = AllocateZeroPool (sizeof (EFI_GCD_MAP_ENTRY));
  mOnGuarding  = FALSE;
  if (*BottomEntry == NULL) {
    CoreFreePool (*TopEntry);
    return EFI_OUT_OF_RESOURCES;
  }

  return EFI_SUCCESS;
}

/**
  Internal function.  Inserts a new descriptor into a sorted list

  @param  Link                   The linked list to insert the range BaseAddress
                                 and Length into
  @param  Entry                  A pointer to the entry that is inserted
  @param  BaseAddress            The base address of the new range
  @param  Length                 The length of the new range in bytes
  @param  TopEntry               Top pad entry to insert if needed.
  @param  BottomEntry            Bottom pad entry to insert if needed.

  @retval EFI_SUCCESS            The new range was inserted into the linked list

**/
EFI_STATUS
CoreInsertGcdMapEntry (
  IN LIST_ENTRY            *Link,
  IN EFI_GCD_MAP_ENTRY     *Entry,
  IN EFI_PHYSICAL_ADDRESS  BaseAddress,
  IN UINT64                Length,
  IN EFI_GCD_MAP_ENTRY     *TopEntry,
  IN EFI_GCD_MAP_ENTRY     *BottomEntry
  )
{
  ASSERT (Length != 0);

  if (BaseAddress > Entry->BaseAddress) {
    ASSERT (BottomEntry->Signature == 0);

    CopyMem (BottomEntry, Entry, sizeof (EFI_GCD_MAP_ENTRY));
    Entry->BaseAddress      = BaseAddress;
    BottomEntry->EndAddress = BaseAddress - 1;
    InsertTailList (Link, &BottomEntry->Link);
  }

  if ((BaseAddress + Length - 1) < Entry->EndAddress) {
    ASSERT (TopEntry->Signature == 0);

    CopyMem (TopEntry, Entry, sizeof (EFI_GCD_MAP_ENTRY));
    TopEntry->BaseAddress = BaseAddress + Length;
    Entry->EndAddress     = BaseAddress + Length - 1;
    InsertHeadList (Link, &TopEntry->Link);
  }

  return EFI_SUCCESS;
}

/**
  Merge the Gcd region specified by Link and its adjacent entry.

  @param  Link                   Specify the entry to be merged (with its
                                 adjacent entry).
  @param  Forward                Direction (forward or backward).
  @param  Map                    Boundary.

  @retval EFI_SUCCESS            Successfully returned.
  @retval EFI_UNSUPPORTED        These adjacent regions could not merge.

**/
EFI_STATUS
CoreMergeGcdMapEntry (
  IN LIST_ENTRY  *Link,
  IN BOOLEAN     Forward,
  IN LIST_ENTRY  *Map
  )
{
  LIST_ENTRY         *AdjacentLink;
  EFI_GCD_MAP_ENTRY  *Entry;
  EFI_GCD_MAP_ENTRY  *AdjacentEntry;

  //
  // Get adjacent entry
  //
  if (Forward) {
    AdjacentLink = Link->ForwardLink;
  } else {
    AdjacentLink = Link->BackLink;
  }

  //
  // If AdjacentLink is the head of the list, then no merge can be performed
  //
  if (AdjacentLink == Map) {
    return EFI_SUCCESS;
  }

  Entry         = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);
  AdjacentEntry = CR (AdjacentLink, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);

  if (Entry->Capabilities != AdjacentEntry->Capabilities) {
    return EFI_UNSUPPORTED;
  }

  if (Entry->Attributes != AdjacentEntry->Attributes) {
    return EFI_UNSUPPORTED;
  }

  if (Entry->GcdMemoryType != AdjacentEntry->GcdMemoryType) {
    return EFI_UNSUPPORTED;
  }

  if (Entry->GcdIoType != AdjacentEntry->GcdIoType) {
    return EFI_UNSUPPORTED;
  }

  if (Entry->ImageHandle != AdjacentEntry->ImageHandle) {
    return EFI_UNSUPPORTED;
  }

  if (Entry->DeviceHandle != AdjacentEntry->DeviceHandle) {
    return EFI_UNSUPPORTED;
  }

  if (Forward) {
    Entry->EndAddress = AdjacentEntry->EndAddress;
  } else {
    Entry->BaseAddress = AdjacentEntry->BaseAddress;
  }

  RemoveEntryList (AdjacentLink);
  CoreFreePool (AdjacentEntry);

  return EFI_SUCCESS;
}

/**
  Merge adjacent entries on total chain.

  @param  TopEntry               Top entry of GCD map.
  @param  BottomEntry            Bottom entry of GCD map.
  @param  StartLink              Start link of the list for this loop.
  @param  EndLink                End link of the list for this loop.
  @param  Map                    Boundary.

  @retval EFI_SUCCESS            GCD map successfully cleaned up.

**/
EFI_STATUS
CoreCleanupGcdMapEntry (
  IN EFI_GCD_MAP_ENTRY  *TopEntry,
  IN EFI_GCD_MAP_ENTRY  *BottomEntry,
  IN LIST_ENTRY         *StartLink,
  IN LIST_ENTRY         *EndLink,
  IN LIST_ENTRY         *Map
  )
{
  LIST_ENTRY  *Link;

  if (TopEntry->Signature == 0) {
    CoreFreePool (TopEntry);
  }

  if (BottomEntry->Signature == 0) {
    CoreFreePool (BottomEntry);
  }

  Link = StartLink;
  while (Link != EndLink->ForwardLink) {
    CoreMergeGcdMapEntry (Link, FALSE, Map);
    Link = Link->ForwardLink;
  }

  CoreMergeGcdMapEntry (EndLink, TRUE, Map);

  return EFI_SUCCESS;
}

/**
  Search a segment of memory space in GCD map. The result is a range of GCD entry list.

  @param  BaseAddress            The start address of the segment.
  @param  Length                 The length of the segment.
  @param  StartLink              The first GCD entry involves this segment of
                                 memory space.
  @param  EndLink                The first GCD entry involves this segment of
                                 memory space.
  @param  Map                    Points to the start entry to search.

  @retval EFI_SUCCESS            Successfully found the entry.
  @retval EFI_NOT_FOUND          Not found.

**/
EFI_STATUS
CoreSearchGcdMapEntry (
  IN  EFI_PHYSICAL_ADDRESS  BaseAddress,
  IN  UINT64                Length,
  OUT LIST_ENTRY            **StartLink,
  OUT LIST_ENTRY            **EndLink,
  IN  LIST_ENTRY            *Map
  )
{
  LIST_ENTRY         *Link;
  EFI_GCD_MAP_ENTRY  *Entry;

  ASSERT (Length != 0);

  *StartLink = NULL;
  *EndLink   = NULL;

  Link = Map->ForwardLink;
  while (Link != Map) {
    Entry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);
    if ((BaseAddress >= Entry->BaseAddress) && (BaseAddress <= Entry->EndAddress)) {
      *StartLink = Link;
    }

    if (*StartLink != NULL) {
      if (((BaseAddress + Length - 1) >= Entry->BaseAddress) &&
          ((BaseAddress + Length - 1) <= Entry->EndAddress))
      {
        *EndLink = Link;
        return EFI_SUCCESS;
      }
    }

    Link = Link->ForwardLink;
  }

  return EFI_NOT_FOUND;
}

/**
  Count the amount of GCD map entries.

  @param  Map                    Points to the start entry to do the count loop.

  @return The count.

**/
UINTN
CoreCountGcdMapEntry (
  IN LIST_ENTRY  *Map
  )
{
  UINTN       Count;
  LIST_ENTRY  *Link;

  Count = 0;
  Link  = Map->ForwardLink;
  while (Link != Map) {
    Count++;
    Link = Link->ForwardLink;
  }

  return Count;
}

/**
  Return the memory attribute specified by Attributes

  @param  Attributes             A num with some attribute bits on.

  @return The enum value of memory attribute.

**/
UINT64
ConverToCpuArchAttributes (
  UINT64  Attributes
  )
{
  UINT64  CpuArchAttributes;

  CpuArchAttributes = Attributes & EFI_MEMORY_ATTRIBUTE_MASK;

  if ((Attributes & EFI_MEMORY_UC) == EFI_MEMORY_UC) {
    CpuArchAttributes |= EFI_MEMORY_UC;
  } else if ((Attributes & EFI_MEMORY_WC) == EFI_MEMORY_WC) {
    CpuArchAttributes |= EFI_MEMORY_WC;
  } else if ((Attributes & EFI_MEMORY_WT) == EFI_MEMORY_WT) {
    CpuArchAttributes |= EFI_MEMORY_WT;
  } else if ((Attributes & EFI_MEMORY_WB) == EFI_MEMORY_WB) {
    CpuArchAttributes |= EFI_MEMORY_WB;
  } else if ((Attributes & EFI_MEMORY_UCE) == EFI_MEMORY_UCE) {
    CpuArchAttributes |= EFI_MEMORY_UCE;
  } else if ((Attributes & EFI_MEMORY_WP) == EFI_MEMORY_WP) {
    CpuArchAttributes |= EFI_MEMORY_WP;
  }

  return CpuArchAttributes;
}

/**
  Do operation on a segment of memory space specified (add, free, remove, change attribute ...).

  @param  Operation              The type of the operation
  @param  GcdMemoryType          Additional information for the operation
  @param  GcdIoType              Additional information for the operation
  @param  BaseAddress            Start address of the segment
  @param  Length                 length of the segment
  @param  Capabilities           The alterable attributes of a newly added entry
  @param  Attributes             The attributes needs to be set

  @retval EFI_INVALID_PARAMETER  Length is 0 or address (length) not aligned when
                                 setting attribute.
  @retval EFI_SUCCESS            Action successfully done.
  @retval EFI_UNSUPPORTED        Could not find the proper descriptor on this
                                 segment or  set an upsupported attribute.
  @retval EFI_ACCESS_DENIED      Operate on an space non-exist or is used for an
                                 image.
  @retval EFI_NOT_FOUND          Free a non-using space or remove a non-exist
                                 space, and so on.
  @retval EFI_OUT_OF_RESOURCES   No buffer could be allocated.
  @retval EFI_NOT_AVAILABLE_YET  The attributes cannot be set because CPU architectural protocol
                                 is not available yet.
**/
EFI_STATUS
CoreConvertSpace (
  IN UINTN                 Operation,
  IN EFI_GCD_MEMORY_TYPE   GcdMemoryType,
  IN EFI_GCD_IO_TYPE       GcdIoType,
  IN EFI_PHYSICAL_ADDRESS  BaseAddress,
  IN UINT64                Length,
  IN UINT64                Capabilities,
  IN UINT64                Attributes
  )
{
  EFI_STATUS         Status;
  LIST_ENTRY         *Map;
  LIST_ENTRY         *Link;
  EFI_GCD_MAP_ENTRY  *Entry;
  EFI_GCD_MAP_ENTRY  *TopEntry;
  EFI_GCD_MAP_ENTRY  *BottomEntry;
  LIST_ENTRY         *StartLink;
  LIST_ENTRY         *EndLink;
  UINT64             CpuArchAttributes;

  if (Length == 0) {
    DEBUG ((DEBUG_GCD, "  Status = %r\n", EFI_INVALID_PARAMETER));
    return EFI_INVALID_PARAMETER;
  }

  Map = NULL;
  if ((Operation & GCD_MEMORY_SPACE_OPERATION) != 0) {
    CoreAcquireGcdMemoryLock ();
    Map = &mGcdMemorySpaceMap;
  } else if ((Operation & GCD_IO_SPACE_OPERATION) != 0) {
    CoreAcquireGcdIoLock ();
    Map = &mGcdIoSpaceMap;
  } else {
    ASSERT (FALSE);
  }

  //
  // Search for the list of descriptors that cover the range BaseAddress to BaseAddress+Length
  //
  Status = CoreSearchGcdMapEntry (BaseAddress, Length, &StartLink, &EndLink, Map);
  if (EFI_ERROR (Status)) {
    Status = EFI_UNSUPPORTED;

    goto Done;
  }

  ASSERT (StartLink != NULL && EndLink != NULL);

  //
  // Verify that the list of descriptors are unallocated non-existent memory.
  //
  Link = StartLink;
  while (Link != EndLink->ForwardLink) {
    Entry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);
    switch (Operation) {
      //
      // Add operations
      //
      case GCD_ADD_MEMORY_OPERATION:
        if ((Entry->GcdMemoryType != EfiGcdMemoryTypeNonExistent) ||
            (Entry->ImageHandle   != NULL))
        {
          Status = EFI_ACCESS_DENIED;
          goto Done;
        }

        break;
      case GCD_ADD_IO_OPERATION:
        if ((Entry->GcdIoType   != EfiGcdIoTypeNonExistent) ||
            (Entry->ImageHandle != NULL))
        {
          Status = EFI_ACCESS_DENIED;
          goto Done;
        }

        break;
      //
      // Free operations
      //
      case GCD_FREE_MEMORY_OPERATION:
      case GCD_FREE_IO_OPERATION:
        if (Entry->ImageHandle == NULL) {
          Status = EFI_NOT_FOUND;
          goto Done;
        }

        break;
      //
      // Remove operations
      //
      case GCD_REMOVE_MEMORY_OPERATION:
        if (Entry->GcdMemoryType == EfiGcdMemoryTypeNonExistent) {
          Status = EFI_NOT_FOUND;
          goto Done;
        }

        if (Entry->ImageHandle != NULL) {
          Status = EFI_ACCESS_DENIED;
          goto Done;
        }

        break;
      case GCD_REMOVE_IO_OPERATION:
        if (Entry->GcdIoType == EfiGcdIoTypeNonExistent) {
          Status = EFI_NOT_FOUND;
          goto Done;
        }

        if (Entry->ImageHandle != NULL) {
          Status = EFI_ACCESS_DENIED;
          goto Done;
        }

        break;
      //
      // Set attributes operation
      //
      case GCD_SET_ATTRIBUTES_MEMORY_OPERATION:
        if ((Attributes & EFI_MEMORY_RUNTIME) != 0) {
          if (((BaseAddress & EFI_PAGE_MASK) != 0) || ((Length & EFI_PAGE_MASK) != 0)) {
            Status = EFI_INVALID_PARAMETER;
            goto Done;
          }
        }

        if ((Entry->Capabilities & Attributes) != Attributes) {
          Status = EFI_UNSUPPORTED;
          goto Done;
        }

        break;
      //
      // Set capabilities operation
      //
      case GCD_SET_CAPABILITIES_MEMORY_OPERATION:
        if (((BaseAddress & EFI_PAGE_MASK) != 0) || ((Length & EFI_PAGE_MASK) != 0)) {
          Status = EFI_INVALID_PARAMETER;

          goto Done;
        }

        //
        // Current attributes must still be supported with new capabilities
        //
        if ((Capabilities & Entry->Attributes) != Entry->Attributes) {
          Status = EFI_UNSUPPORTED;
          goto Done;
        }

        break;
    }

    Link = Link->ForwardLink;
  }

  //
  // Allocate work space to perform this operation
  //
  Status = CoreAllocateGcdMapEntry (&TopEntry, &BottomEntry);
  if (EFI_ERROR (Status)) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Done;
  }

  ASSERT (TopEntry != NULL && BottomEntry != NULL);

  //
  // Initialize CpuArchAttributes to suppress incorrect compiler/analyzer warnings.
  //
  CpuArchAttributes = 0;
  if (Operation == GCD_SET_ATTRIBUTES_MEMORY_OPERATION) {
    //
    // Call CPU Arch Protocol to attempt to set attributes on the range
    //
    CpuArchAttributes = ConverToCpuArchAttributes (Attributes);
    //
    // CPU arch attributes include page attributes and cache attributes.
    // Only page attributes supports to be cleared, but not cache attributes.
    // Caller is expected to use GetMemorySpaceDescriptor() to get the current
    // attributes, AND/OR attributes, and then calls SetMemorySpaceAttributes()
    // to set the new attributes.
    // So 0 CPU arch attributes should not happen as memory should always have
    // a cache attribute (no matter UC or WB, etc).
    //
    // Here, 0 CPU arch attributes will be filtered to be compatible with the
    // case that caller just calls SetMemorySpaceAttributes() with none CPU
    // arch attributes (for example, RUNTIME) as the purpose of the case is not
    // to clear CPU arch attributes.
    //
    if (CpuArchAttributes != 0) {
      if (gCpu == NULL) {
        Status = EFI_NOT_AVAILABLE_YET;
      } else {
        Status = gCpu->SetMemoryAttributes (
                         gCpu,
                         BaseAddress,
                         Length,
                         CpuArchAttributes
                         );
      }

      if (EFI_ERROR (Status)) {
        CoreFreePool (TopEntry);
        CoreFreePool (BottomEntry);
        goto Done;
      }
    }
  }

  //
  // Convert/Insert the list of descriptors from StartLink to EndLink
  //
  Link = StartLink;
  while (Link != EndLink->ForwardLink) {
    Entry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);
    CoreInsertGcdMapEntry (Link, Entry, BaseAddress, Length, TopEntry, BottomEntry);
    switch (Operation) {
      //
      // Add operations
      //
      case GCD_ADD_MEMORY_OPERATION:
        Entry->GcdMemoryType = GcdMemoryType;
        if (GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) {
          Entry->Capabilities = Capabilities | EFI_MEMORY_RUNTIME | EFI_MEMORY_PORT_IO;
        } else {
          Entry->Capabilities = Capabilities | EFI_MEMORY_RUNTIME;
        }

        break;
      case GCD_ADD_IO_OPERATION:
        Entry->GcdIoType = GcdIoType;
        break;
      //
      // Free operations
      //
      case GCD_FREE_MEMORY_OPERATION:
      case GCD_FREE_IO_OPERATION:
        Entry->ImageHandle  = NULL;
        Entry->DeviceHandle = NULL;
        break;
      //
      // Remove operations
      //
      case GCD_REMOVE_MEMORY_OPERATION:
        Entry->GcdMemoryType = EfiGcdMemoryTypeNonExistent;
        Entry->Capabilities  = 0;
        break;
      case GCD_REMOVE_IO_OPERATION:
        Entry->GcdIoType = EfiGcdIoTypeNonExistent;
        break;
      //
      // Set attributes operation
      //
      case GCD_SET_ATTRIBUTES_MEMORY_OPERATION:
        if (CpuArchAttributes == 0) {
          //
          // Keep original CPU arch attributes when caller just calls
          // SetMemorySpaceAttributes() with none CPU arch attributes (for example, RUNTIME).
          //
          Attributes |= (Entry->Attributes & (EFI_CACHE_ATTRIBUTE_MASK | EFI_MEMORY_ATTRIBUTE_MASK));
        }

        Entry->Attributes = Attributes;
        break;
      //
      // Set capabilities operation
      //
      case GCD_SET_CAPABILITIES_MEMORY_OPERATION:
        Entry->Capabilities = Capabilities;
        break;
    }

    Link = Link->ForwardLink;
  }

  //
  // Cleanup
  //
  Status = CoreCleanupGcdMapEntry (TopEntry, BottomEntry, StartLink, EndLink, Map);

Done:
  DEBUG ((DEBUG_GCD, "  Status = %r\n", Status));

  if ((Operation & GCD_MEMORY_SPACE_OPERATION) != 0) {
    CoreReleaseGcdMemoryLock ();
    CoreDumpGcdMemorySpaceMap (FALSE);
  }

  if ((Operation & GCD_IO_SPACE_OPERATION) != 0) {
    CoreReleaseGcdIoLock ();
    CoreDumpGcdIoSpaceMap (FALSE);
  }

  return Status;
}

/**
  Check whether an entry could be used to allocate space.

  @param  Operation              Allocate memory or IO
  @param  Entry                  The entry to be tested
  @param  GcdMemoryType          The desired memory type
  @param  GcdIoType              The desired IO type

  @retval EFI_NOT_FOUND          The memory type does not match or there's an
                                 image handle on the entry.
  @retval EFI_UNSUPPORTED        The operation unsupported.
  @retval EFI_SUCCESS            It's ok for this entry to be used to allocate
                                 space.

**/
EFI_STATUS
CoreAllocateSpaceCheckEntry (
  IN UINTN                Operation,
  IN EFI_GCD_MAP_ENTRY    *Entry,
  IN EFI_GCD_MEMORY_TYPE  GcdMemoryType,
  IN EFI_GCD_IO_TYPE      GcdIoType
  )
{
  if (Entry->ImageHandle != NULL) {
    return EFI_NOT_FOUND;
  }

  switch (Operation) {
    case GCD_ALLOCATE_MEMORY_OPERATION:
      if (Entry->GcdMemoryType != GcdMemoryType) {
        return EFI_NOT_FOUND;
      }

      break;
    case GCD_ALLOCATE_IO_OPERATION:
      if (Entry->GcdIoType != GcdIoType) {
        return EFI_NOT_FOUND;
      }

      break;
    default:
      return EFI_UNSUPPORTED;
  }

  return EFI_SUCCESS;
}

/**
  Allocate space on specified address and length.

  @param  Operation              The type of operation (memory or IO)
  @param  GcdAllocateType        The type of allocate operation
  @param  GcdMemoryType          The desired memory type
  @param  GcdIoType              The desired IO type
  @param  Alignment              Align with 2^Alignment
  @param  Length                 Length to allocate
  @param  BaseAddress            Base address to allocate
  @param  ImageHandle            The image handle consume the allocated space.
  @param  DeviceHandle           The device handle consume the allocated space.

  @retval EFI_INVALID_PARAMETER  Invalid parameter.
  @retval EFI_NOT_FOUND          No descriptor for the desired space exists.
  @retval EFI_SUCCESS            Space successfully allocated.

**/
EFI_STATUS
CoreAllocateSpace (
  IN     UINTN                  Operation,
  IN     EFI_GCD_ALLOCATE_TYPE  GcdAllocateType,
  IN     EFI_GCD_MEMORY_TYPE    GcdMemoryType,
  IN     EFI_GCD_IO_TYPE        GcdIoType,
  IN     UINTN                  Alignment,
  IN     UINT64                 Length,
  IN OUT EFI_PHYSICAL_ADDRESS   *BaseAddress,
  IN     EFI_HANDLE             ImageHandle,
  IN     EFI_HANDLE             DeviceHandle OPTIONAL
  )
{
  EFI_STATUS            Status;
  EFI_PHYSICAL_ADDRESS  AlignmentMask;
  EFI_PHYSICAL_ADDRESS  MaxAddress;
  LIST_ENTRY            *Map;
  LIST_ENTRY            *Link;
  LIST_ENTRY            *SubLink;
  EFI_GCD_MAP_ENTRY     *Entry;
  EFI_GCD_MAP_ENTRY     *TopEntry;
  EFI_GCD_MAP_ENTRY     *BottomEntry;
  LIST_ENTRY            *StartLink;
  LIST_ENTRY            *EndLink;
  BOOLEAN               Found;

  //
  // Make sure parameters are valid
  //
  if ((UINT32)GcdAllocateType >= EfiGcdMaxAllocateType) {
    DEBUG ((DEBUG_GCD, "  Status = %r\n", EFI_INVALID_PARAMETER));
    return EFI_INVALID_PARAMETER;
  }

  if ((UINT32)GcdMemoryType >= EfiGcdMemoryTypeMaximum) {
    DEBUG ((DEBUG_GCD, "  Status = %r\n", EFI_INVALID_PARAMETER));
    return EFI_INVALID_PARAMETER;
  }

  if ((UINT32)GcdIoType >= EfiGcdIoTypeMaximum) {
    DEBUG ((DEBUG_GCD, "  Status = %r\n", EFI_INVALID_PARAMETER));
    return EFI_INVALID_PARAMETER;
  }

  if (BaseAddress == NULL) {
    DEBUG ((DEBUG_GCD, "  Status = %r\n", EFI_INVALID_PARAMETER));
    return EFI_INVALID_PARAMETER;
  }

  if (ImageHandle == NULL) {
    DEBUG ((DEBUG_GCD, "  Status = %r\n", EFI_INVALID_PARAMETER));
    return EFI_INVALID_PARAMETER;
  }

  if (Alignment >= 64) {
    DEBUG ((DEBUG_GCD, "  Status = %r\n", EFI_NOT_FOUND));
    return EFI_NOT_FOUND;
  }

  if (Length == 0) {
    DEBUG ((DEBUG_GCD, "  Status = %r\n", EFI_INVALID_PARAMETER));
    return EFI_INVALID_PARAMETER;
  }

  Map = NULL;
  if ((Operation & GCD_MEMORY_SPACE_OPERATION) != 0) {
    CoreAcquireGcdMemoryLock ();
    Map = &mGcdMemorySpaceMap;
  } else if ((Operation & GCD_IO_SPACE_OPERATION) != 0) {
    CoreAcquireGcdIoLock ();
    Map = &mGcdIoSpaceMap;
  } else {
    ASSERT (FALSE);
  }

  Found     = FALSE;
  StartLink = NULL;
  EndLink   = NULL;
  //
  // Compute alignment bit mask
  //
  AlignmentMask = LShiftU64 (1, Alignment) - 1;

  if (GcdAllocateType == EfiGcdAllocateAddress) {
    //
    // Verify that the BaseAddress passed in is aligned correctly
    //
    if ((*BaseAddress & AlignmentMask) != 0) {
      Status = EFI_NOT_FOUND;
      goto Done;
    }

    //
    // Search for the list of descriptors that cover the range BaseAddress to BaseAddress+Length
    //
    Status = CoreSearchGcdMapEntry (*BaseAddress, Length, &StartLink, &EndLink, Map);
    if (EFI_ERROR (Status)) {
      Status = EFI_NOT_FOUND;
      goto Done;
    }

    ASSERT (StartLink != NULL && EndLink != NULL);

    //
    // Verify that the list of descriptors are unallocated memory matching GcdMemoryType.
    //
    Link = StartLink;
    while (Link != EndLink->ForwardLink) {
      Entry  = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);
      Link   = Link->ForwardLink;
      Status = CoreAllocateSpaceCheckEntry (Operation, Entry, GcdMemoryType, GcdIoType);
      if (EFI_ERROR (Status)) {
        goto Done;
      }
    }

    Found = TRUE;
  } else {
    Entry = CR (Map->BackLink, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);

    //
    // Compute the maximum address to use in the search algorithm
    //
    if ((GcdAllocateType == EfiGcdAllocateMaxAddressSearchBottomUp) ||
        (GcdAllocateType == EfiGcdAllocateMaxAddressSearchTopDown))
    {
      MaxAddress = *BaseAddress;
    } else {
      MaxAddress = Entry->EndAddress;
    }

    //
    // Verify that the list of descriptors are unallocated memory matching GcdMemoryType.
    //
    if ((GcdAllocateType == EfiGcdAllocateMaxAddressSearchTopDown) ||
        (GcdAllocateType == EfiGcdAllocateAnySearchTopDown))
    {
      Link = Map->BackLink;
    } else {
      Link = Map->ForwardLink;
    }

    while (Link != Map) {
      Entry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);

      if ((GcdAllocateType == EfiGcdAllocateMaxAddressSearchTopDown) ||
          (GcdAllocateType == EfiGcdAllocateAnySearchTopDown))
      {
        Link = Link->BackLink;
      } else {
        Link = Link->ForwardLink;
      }

      Status = CoreAllocateSpaceCheckEntry (Operation, Entry, GcdMemoryType, GcdIoType);
      if (EFI_ERROR (Status)) {
        continue;
      }

      if ((GcdAllocateType == EfiGcdAllocateMaxAddressSearchTopDown) ||
          (GcdAllocateType == EfiGcdAllocateAnySearchTopDown))
      {
        if ((Entry->BaseAddress + Length) > MaxAddress) {
          continue;
        }

        if (Length > (Entry->EndAddress + 1)) {
          Status = EFI_NOT_FOUND;
          goto Done;
        }

        if (Entry->EndAddress > MaxAddress) {
          *BaseAddress = MaxAddress;
        } else {
          *BaseAddress = Entry->EndAddress;
        }

        *BaseAddress = (*BaseAddress + 1 - Length) & (~AlignmentMask);
      } else {
        *BaseAddress = (Entry->BaseAddress + AlignmentMask) & (~AlignmentMask);
        if ((*BaseAddress + Length - 1) > MaxAddress) {
          Status = EFI_NOT_FOUND;
          goto Done;
        }
      }

      //
      // Search for the list of descriptors that cover the range BaseAddress to BaseAddress+Length
      //
      Status = CoreSearchGcdMapEntry (*BaseAddress, Length, &StartLink, &EndLink, Map);
      if (EFI_ERROR (Status)) {
        Status = EFI_NOT_FOUND;
        goto Done;
      }

      ASSERT (StartLink != NULL && EndLink != NULL);

      Link = StartLink;
      //
      // Verify that the list of descriptors are unallocated memory matching GcdMemoryType.
      //
      Found   = TRUE;
      SubLink = StartLink;
      while (SubLink != EndLink->ForwardLink) {
        Entry  = CR (SubLink, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);
        Status = CoreAllocateSpaceCheckEntry (Operation, Entry, GcdMemoryType, GcdIoType);
        if (EFI_ERROR (Status)) {
          Link  = SubLink;
          Found = FALSE;
          break;
        }

        SubLink = SubLink->ForwardLink;
      }

      if (Found) {
        break;
      }
    }
  }

  if (!Found) {
    Status = EFI_NOT_FOUND;
    goto Done;
  }

  //
  // Allocate work space to perform this operation
  //
  Status = CoreAllocateGcdMapEntry (&TopEntry, &BottomEntry);
  if (EFI_ERROR (Status)) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Done;
  }

  ASSERT (TopEntry != NULL && BottomEntry != NULL);

  //
  // Convert/Insert the list of descriptors from StartLink to EndLink
  //
  Link = StartLink;
  while (Link != EndLink->ForwardLink) {
    Entry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);
    CoreInsertGcdMapEntry (Link, Entry, *BaseAddress, Length, TopEntry, BottomEntry);
    Entry->ImageHandle  = ImageHandle;
    Entry->DeviceHandle = DeviceHandle;
    Link                = Link->ForwardLink;
  }

  //
  // Cleanup
  //
  Status = CoreCleanupGcdMapEntry (TopEntry, BottomEntry, StartLink, EndLink, Map);

Done:
  DEBUG ((DEBUG_GCD, "  Status = %r", Status));
  if (!EFI_ERROR (Status)) {
    DEBUG ((DEBUG_GCD, "  (BaseAddress = %016lx)", *BaseAddress));
  }

  DEBUG ((DEBUG_GCD, "\n"));

  if ((Operation & GCD_MEMORY_SPACE_OPERATION) != 0) {
    CoreReleaseGcdMemoryLock ();
    CoreDumpGcdMemorySpaceMap (FALSE);
  }

  if ((Operation & GCD_IO_SPACE_OPERATION) != 0) {
    CoreReleaseGcdIoLock ();
    CoreDumpGcdIoSpaceMap (FALSE);
  }

  return Status;
}

/**
  Add a segment of memory to GCD map.

  @param  GcdMemoryType          Memory type of the segment.
  @param  BaseAddress            Base address of the segment.
  @param  Length                 Length of the segment.
  @param  Capabilities           alterable attributes of the segment.

  @retval EFI_INVALID_PARAMETER  Invalid parameters.
  @retval EFI_SUCCESS            Successfully add a segment of memory space.

**/
EFI_STATUS
CoreInternalAddMemorySpace (
  IN EFI_GCD_MEMORY_TYPE   GcdMemoryType,
  IN EFI_PHYSICAL_ADDRESS  BaseAddress,
  IN UINT64                Length,
  IN UINT64                Capabilities
  )
{
  DEBUG ((DEBUG_GCD, "GCD:AddMemorySpace(Base=%016lx,Length=%016lx)\n", BaseAddress, Length));
  DEBUG ((DEBUG_GCD, "  GcdMemoryType   = %a\n", mGcdMemoryTypeNames[MIN (GcdMemoryType, EfiGcdMemoryTypeMaximum)]));
  DEBUG ((DEBUG_GCD, "  Capabilities    = %016lx\n", Capabilities));

  //
  // Make sure parameters are valid
  //
  if ((GcdMemoryType <= EfiGcdMemoryTypeNonExistent) || (GcdMemoryType >= EfiGcdMemoryTypeMaximum)) {
    return EFI_INVALID_PARAMETER;
  }

  return CoreConvertSpace (GCD_ADD_MEMORY_OPERATION, GcdMemoryType, (EFI_GCD_IO_TYPE)0, BaseAddress, Length, Capabilities, 0);
}

//
// GCD Core Services
//

/**
  Allocates nonexistent memory, reserved memory, system memory, or memorymapped
  I/O resources from the global coherency domain of the processor.

  @param  GcdAllocateType        The type of allocate operation
  @param  GcdMemoryType          The desired memory type
  @param  Alignment              Align with 2^Alignment
  @param  Length                 Length to allocate
  @param  BaseAddress            Base address to allocate
  @param  ImageHandle            The image handle consume the allocated space.
  @param  DeviceHandle           The device handle consume the allocated space.

  @retval EFI_INVALID_PARAMETER  Invalid parameter.
  @retval EFI_NOT_FOUND          No descriptor contains the desired space.
  @retval EFI_SUCCESS            Memory space successfully allocated.

**/
EFI_STATUS
EFIAPI
CoreAllocateMemorySpace (
  IN     EFI_GCD_ALLOCATE_TYPE  GcdAllocateType,
  IN     EFI_GCD_MEMORY_TYPE    GcdMemoryType,
  IN     UINTN                  Alignment,
  IN     UINT64                 Length,
  IN OUT EFI_PHYSICAL_ADDRESS   *BaseAddress,
  IN     EFI_HANDLE             ImageHandle,
  IN     EFI_HANDLE             DeviceHandle OPTIONAL
  )
{
  if (BaseAddress != NULL) {
    DEBUG ((DEBUG_GCD, "GCD:AllocateMemorySpace(Base=%016lx,Length=%016lx)\n", *BaseAddress, Length));
  } else {
    DEBUG ((DEBUG_GCD, "GCD:AllocateMemorySpace(Base=<NULL>,Length=%016lx)\n", Length));
  }

  DEBUG ((DEBUG_GCD, "  GcdAllocateType = %a\n", mGcdAllocationTypeNames[MIN (GcdAllocateType, EfiGcdMaxAllocateType)]));
  DEBUG ((DEBUG_GCD, "  GcdMemoryType   = %a\n", mGcdMemoryTypeNames[MIN (GcdMemoryType, EfiGcdMemoryTypeMaximum)]));
  DEBUG ((DEBUG_GCD, "  Alignment       = %016lx\n", LShiftU64 (1, Alignment)));
  DEBUG ((DEBUG_GCD, "  ImageHandle     = %p\n", ImageHandle));
  DEBUG ((DEBUG_GCD, "  DeviceHandle    = %p\n", DeviceHandle));

  return CoreAllocateSpace (
           GCD_ALLOCATE_MEMORY_OPERATION,
           GcdAllocateType,
           GcdMemoryType,
           (EFI_GCD_IO_TYPE)0,
           Alignment,
           Length,
           BaseAddress,
           ImageHandle,
           DeviceHandle
           );
}

/**
  Adds reserved memory, system memory, or memory-mapped I/O resources to the
  global coherency domain of the processor.

  @param  GcdMemoryType          Memory type of the memory space.
  @param  BaseAddress            Base address of the memory space.
  @param  Length                 Length of the memory space.
  @param  Capabilities           alterable attributes of the memory space.

  @retval EFI_SUCCESS            Merged this memory space into GCD map.

**/
EFI_STATUS
EFIAPI
CoreAddMemorySpace (
  IN EFI_GCD_MEMORY_TYPE   GcdMemoryType,
  IN EFI_PHYSICAL_ADDRESS  BaseAddress,
  IN UINT64                Length,
  IN UINT64                Capabilities
  )
{
  EFI_STATUS            Status;
  EFI_PHYSICAL_ADDRESS  PageBaseAddress;
  UINT64                PageLength;

  Status = CoreInternalAddMemorySpace (GcdMemoryType, BaseAddress, Length, Capabilities);

  if (!EFI_ERROR (Status) && ((GcdMemoryType == EfiGcdMemoryTypeSystemMemory) || (GcdMemoryType == EfiGcdMemoryTypeMoreReliable))) {
    PageBaseAddress = PageAlignAddress (BaseAddress);
    PageLength      = PageAlignLength (BaseAddress + Length - PageBaseAddress);

    Status = CoreAllocateMemorySpace (
               EfiGcdAllocateAddress,
               GcdMemoryType,
               EFI_PAGE_SHIFT,
               PageLength,
               &PageBaseAddress,
               gDxeCoreImageHandle,
               NULL
               );

    if (!EFI_ERROR (Status)) {
      CoreAddMemoryDescriptor (
        EfiConventionalMemory,
        PageBaseAddress,
        RShiftU64 (PageLength, EFI_PAGE_SHIFT),
        Capabilities
        );
    } else {
      for ( ; PageLength != 0; PageLength -= EFI_PAGE_SIZE, PageBaseAddress += EFI_PAGE_SIZE) {
        Status = CoreAllocateMemorySpace (
                   EfiGcdAllocateAddress,
                   GcdMemoryType,
                   EFI_PAGE_SHIFT,
                   EFI_PAGE_SIZE,
                   &PageBaseAddress,
                   gDxeCoreImageHandle,
                   NULL
                   );

        if (!EFI_ERROR (Status)) {
          CoreAddMemoryDescriptor (
            EfiConventionalMemory,
            PageBaseAddress,
            1,
            Capabilities
            );
        }
      }
    }
  }

  return Status;
}

/**
  Frees nonexistent memory, reserved memory, system memory, or memory-mapped
  I/O resources from the global coherency domain of the processor.

  @param  BaseAddress            Base address of the memory space.
  @param  Length                 Length of the memory space.

  @retval EFI_SUCCESS            Space successfully freed.

**/
EFI_STATUS
EFIAPI
CoreFreeMemorySpace (
  IN EFI_PHYSICAL_ADDRESS  BaseAddress,
  IN UINT64                Length
  )
{
  DEBUG ((DEBUG_GCD, "GCD:FreeMemorySpace(Base=%016lx,Length=%016lx)\n", BaseAddress, Length));

  return CoreConvertSpace (GCD_FREE_MEMORY_OPERATION, (EFI_GCD_MEMORY_TYPE)0, (EFI_GCD_IO_TYPE)0, BaseAddress, Length, 0, 0);
}

/**
  Removes reserved memory, system memory, or memory-mapped I/O resources from
  the global coherency domain of the processor.

  @param  BaseAddress            Base address of the memory space.
  @param  Length                 Length of the memory space.

  @retval EFI_SUCCESS            Successfully remove a segment of memory space.

**/
EFI_STATUS
EFIAPI
CoreRemoveMemorySpace (
  IN EFI_PHYSICAL_ADDRESS  BaseAddress,
  IN UINT64                Length
  )
{
  DEBUG ((DEBUG_GCD, "GCD:RemoveMemorySpace(Base=%016lx,Length=%016lx)\n", BaseAddress, Length));

  return CoreConvertSpace (GCD_REMOVE_MEMORY_OPERATION, (EFI_GCD_MEMORY_TYPE)0, (EFI_GCD_IO_TYPE)0, BaseAddress, Length, 0, 0);
}

/**
  Build a memory descriptor according to an entry.

  @param  Descriptor             The descriptor to be built
  @param  Entry                  According to this entry

**/
VOID
BuildMemoryDescriptor (
  IN OUT EFI_GCD_MEMORY_SPACE_DESCRIPTOR  *Descriptor,
  IN EFI_GCD_MAP_ENTRY                    *Entry
  )
{
  Descriptor->BaseAddress   = Entry->BaseAddress;
  Descriptor->Length        = Entry->EndAddress - Entry->BaseAddress + 1;
  Descriptor->Capabilities  = Entry->Capabilities;
  Descriptor->Attributes    = Entry->Attributes;
  Descriptor->GcdMemoryType = Entry->GcdMemoryType;
  Descriptor->ImageHandle   = Entry->ImageHandle;
  Descriptor->DeviceHandle  = Entry->DeviceHandle;
}

/**
  Retrieves the descriptor for a memory region containing a specified address.

  @param  BaseAddress            Specified start address
  @param  Descriptor             Specified length

  @retval EFI_INVALID_PARAMETER  Invalid parameter
  @retval EFI_SUCCESS            Successfully get memory space descriptor.

**/
EFI_STATUS
EFIAPI
CoreGetMemorySpaceDescriptor (
  IN  EFI_PHYSICAL_ADDRESS             BaseAddress,
  OUT EFI_GCD_MEMORY_SPACE_DESCRIPTOR  *Descriptor
  )
{
  EFI_STATUS         Status;
  LIST_ENTRY         *StartLink;
  LIST_ENTRY         *EndLink;
  EFI_GCD_MAP_ENTRY  *Entry;

  //
  // Make sure parameters are valid
  //
  if (Descriptor == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  CoreAcquireGcdMemoryLock ();

  //
  // Search for the list of descriptors that contain BaseAddress
  //
  Status = CoreSearchGcdMapEntry (BaseAddress, 1, &StartLink, &EndLink, &mGcdMemorySpaceMap);
  if (EFI_ERROR (Status)) {
    Status = EFI_NOT_FOUND;
  } else {
    ASSERT (StartLink != NULL && EndLink != NULL);
    //
    // Copy the contents of the found descriptor into Descriptor
    //
    Entry = CR (StartLink, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);
    BuildMemoryDescriptor (Descriptor, Entry);
  }

  CoreReleaseGcdMemoryLock ();

  return Status;
}

/**
  Modifies the attributes for a memory region in the global coherency domain of the
  processor.

  @param  BaseAddress            Specified start address
  @param  Length                 Specified length
  @param  Attributes             Specified attributes

  @retval EFI_SUCCESS           The attributes were set for the memory region.
  @retval EFI_INVALID_PARAMETER Length is zero.
  @retval EFI_UNSUPPORTED       The processor does not support one or more bytes of the memory
                                resource range specified by BaseAddress and Length.
  @retval EFI_UNSUPPORTED       The bit mask of attributes is not support for the memory resource
                                range specified by BaseAddress and Length.
  @retval EFI_ACCESS_DEFINED    The attributes for the memory resource range specified by
                                BaseAddress and Length cannot be modified.
  @retval EFI_OUT_OF_RESOURCES  There are not enough system resources to modify the attributes of
                                the memory resource range.
  @retval EFI_NOT_AVAILABLE_YET The attributes cannot be set because CPU architectural protocol is
                                not available yet.

**/
EFI_STATUS
EFIAPI
CoreSetMemorySpaceAttributes (
  IN EFI_PHYSICAL_ADDRESS  BaseAddress,
  IN UINT64                Length,
  IN UINT64                Attributes
  )
{
  DEBUG ((DEBUG_GCD, "GCD:SetMemorySpaceAttributes(Base=%016lx,Length=%016lx)\n", BaseAddress, Length));
  DEBUG ((DEBUG_GCD, "  Attributes  = %016lx\n", Attributes));

  return CoreConvertSpace (GCD_SET_ATTRIBUTES_MEMORY_OPERATION, (EFI_GCD_MEMORY_TYPE)0, (EFI_GCD_IO_TYPE)0, BaseAddress, Length, 0, Attributes);
}

/**
  Modifies the capabilities for a memory region in the global coherency domain of the
  processor.

  @param  BaseAddress      The physical address that is the start address of a memory region.
  @param  Length           The size in bytes of the memory region.
  @param  Capabilities     The bit mask of capabilities that the memory region supports.

  @retval EFI_SUCCESS           The capabilities were set for the memory region.
  @retval EFI_INVALID_PARAMETER Length is zero.
  @retval EFI_UNSUPPORTED       The capabilities specified by Capabilities do not include the
                                memory region attributes currently in use.
  @retval EFI_ACCESS_DENIED     The capabilities for the memory resource range specified by
                                BaseAddress and Length cannot be modified.
  @retval EFI_OUT_OF_RESOURCES  There are not enough system resources to modify the capabilities
                                of the memory resource range.
**/
EFI_STATUS
EFIAPI
CoreSetMemorySpaceCapabilities (
  IN EFI_PHYSICAL_ADDRESS  BaseAddress,
  IN UINT64                Length,
  IN UINT64                Capabilities
  )
{
  EFI_STATUS  Status;

  DEBUG ((DEBUG_GCD, "GCD:CoreSetMemorySpaceCapabilities(Base=%016lx,Length=%016lx)\n", BaseAddress, Length));
  DEBUG ((DEBUG_GCD, "  Capabilities  = %016lx\n", Capabilities));

  Status = CoreConvertSpace (GCD_SET_CAPABILITIES_MEMORY_OPERATION, (EFI_GCD_MEMORY_TYPE)0, (EFI_GCD_IO_TYPE)0, BaseAddress, Length, Capabilities, 0);
  if (!EFI_ERROR (Status)) {
    CoreUpdateMemoryAttributes (BaseAddress, RShiftU64 (Length, EFI_PAGE_SHIFT), Capabilities & (~EFI_MEMORY_RUNTIME));
  }

  return Status;
}

/**
  Returns a map of the memory resources in the global coherency domain of the
  processor.

  @param  NumberOfDescriptors    Number of descriptors.
  @param  MemorySpaceMap         Descriptor array

  @retval EFI_INVALID_PARAMETER  Invalid parameter
  @retval EFI_OUT_OF_RESOURCES   No enough buffer to allocate
  @retval EFI_SUCCESS            Successfully get memory space map.

**/
EFI_STATUS
EFIAPI
CoreGetMemorySpaceMap (
  OUT UINTN                            *NumberOfDescriptors,
  OUT EFI_GCD_MEMORY_SPACE_DESCRIPTOR  **MemorySpaceMap
  )
{
  LIST_ENTRY                       *Link;
  EFI_GCD_MAP_ENTRY                *Entry;
  EFI_GCD_MEMORY_SPACE_DESCRIPTOR  *Descriptor;
  UINTN                            DescriptorCount;

  //
  // Make sure parameters are valid
  //
  if (NumberOfDescriptors == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (MemorySpaceMap == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  *NumberOfDescriptors = 0;
  *MemorySpaceMap      = NULL;

  //
  // Take the lock, for entering the loop with the lock held.
  //
  CoreAcquireGcdMemoryLock ();
  while (TRUE) {
    //
    // Count descriptors. It might be done more than once because the
    // AllocatePool() called below has to be running outside the GCD lock.
    //
    DescriptorCount = CoreCountGcdMapEntry (&mGcdMemorySpaceMap);
    if ((DescriptorCount == *NumberOfDescriptors) && (*MemorySpaceMap != NULL)) {
      //
      // Fill in the MemorySpaceMap if no memory space map change.
      //
      Descriptor = *MemorySpaceMap;
      Link       = mGcdMemorySpaceMap.ForwardLink;
      while (Link != &mGcdMemorySpaceMap) {
        Entry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);
        BuildMemoryDescriptor (Descriptor, Entry);
        Descriptor++;
        Link = Link->ForwardLink;
      }

      //
      // We're done; exit the loop with the lock held.
      //
      break;
    }

    //
    // Release the lock before memory allocation, because it might cause
    // GCD lock conflict in one of calling path in AllocatPool().
    //
    CoreReleaseGcdMemoryLock ();

    //
    // Allocate memory to store the MemorySpaceMap. Note it might be already
    // allocated if there's map descriptor change during memory allocation at
    // last time.
    //
    if (*MemorySpaceMap != NULL) {
      FreePool (*MemorySpaceMap);
    }

    *MemorySpaceMap = AllocatePool (
                        DescriptorCount *
                        sizeof (EFI_GCD_MEMORY_SPACE_DESCRIPTOR)
                        );
    if (*MemorySpaceMap == NULL) {
      *NumberOfDescriptors = 0;
      return EFI_OUT_OF_RESOURCES;
    }

    //
    // Save the descriptor count got before for another round of check to make
    // sure we won't miss any, since we have code running outside the GCD lock.
    //
    *NumberOfDescriptors = DescriptorCount;
    //
    // Re-acquire the lock, for the next iteration.
    //
    CoreAcquireGcdMemoryLock ();
  }

  //
  // We exited the loop with the lock held, release it.
  //
  CoreReleaseGcdMemoryLock ();

  return EFI_SUCCESS;
}

/**
  Adds reserved I/O or I/O resources to the global coherency domain of the processor.

  @param  GcdIoType              IO type of the segment.
  @param  BaseAddress            Base address of the segment.
  @param  Length                 Length of the segment.

  @retval EFI_SUCCESS            Merged this segment into GCD map.
  @retval EFI_INVALID_PARAMETER  Parameter not valid

**/
EFI_STATUS
EFIAPI
CoreAddIoSpace (
  IN EFI_GCD_IO_TYPE       GcdIoType,
  IN EFI_PHYSICAL_ADDRESS  BaseAddress,
  IN UINT64                Length
  )
{
  DEBUG ((DEBUG_GCD, "GCD:AddIoSpace(Base=%016lx,Length=%016lx)\n", BaseAddress, Length));
  DEBUG ((DEBUG_GCD, "  GcdIoType    = %a\n", mGcdIoTypeNames[MIN (GcdIoType, EfiGcdIoTypeMaximum)]));

  //
  // Make sure parameters are valid
  //
  if ((GcdIoType <= EfiGcdIoTypeNonExistent) || (GcdIoType >= EfiGcdIoTypeMaximum)) {
    return EFI_INVALID_PARAMETER;
  }

  return CoreConvertSpace (GCD_ADD_IO_OPERATION, (EFI_GCD_MEMORY_TYPE)0, GcdIoType, BaseAddress, Length, 0, 0);
}

/**
  Allocates nonexistent I/O, reserved I/O, or I/O resources from the global coherency
  domain of the processor.

  @param  GcdAllocateType        The type of allocate operation
  @param  GcdIoType              The desired IO type
  @param  Alignment              Align with 2^Alignment
  @param  Length                 Length to allocate
  @param  BaseAddress            Base address to allocate
  @param  ImageHandle            The image handle consume the allocated space.
  @param  DeviceHandle           The device handle consume the allocated space.

  @retval EFI_INVALID_PARAMETER  Invalid parameter.
  @retval EFI_NOT_FOUND          No descriptor contains the desired space.
  @retval EFI_SUCCESS            IO space successfully allocated.

**/
EFI_STATUS
EFIAPI
CoreAllocateIoSpace (
  IN     EFI_GCD_ALLOCATE_TYPE  GcdAllocateType,
  IN     EFI_GCD_IO_TYPE        GcdIoType,
  IN     UINTN                  Alignment,
  IN     UINT64                 Length,
  IN OUT EFI_PHYSICAL_ADDRESS   *BaseAddress,
  IN     EFI_HANDLE             ImageHandle,
  IN     EFI_HANDLE             DeviceHandle OPTIONAL
  )
{
  if (BaseAddress != NULL) {
    DEBUG ((DEBUG_GCD, "GCD:AllocateIoSpace(Base=%016lx,Length=%016lx)\n", *BaseAddress, Length));
  } else {
    DEBUG ((DEBUG_GCD, "GCD:AllocateIoSpace(Base=<NULL>,Length=%016lx)\n", Length));
  }

  DEBUG ((DEBUG_GCD, "  GcdAllocateType = %a\n", mGcdAllocationTypeNames[MIN (GcdAllocateType, EfiGcdMaxAllocateType)]));
  DEBUG ((DEBUG_GCD, "  GcdIoType       = %a\n", mGcdIoTypeNames[MIN (GcdIoType, EfiGcdIoTypeMaximum)]));
  DEBUG ((DEBUG_GCD, "  Alignment       = %016lx\n", LShiftU64 (1, Alignment)));
  DEBUG ((DEBUG_GCD, "  ImageHandle     = %p\n", ImageHandle));
  DEBUG ((DEBUG_GCD, "  DeviceHandle    = %p\n", DeviceHandle));

  return CoreAllocateSpace (
           GCD_ALLOCATE_IO_OPERATION,
           GcdAllocateType,
           (EFI_GCD_MEMORY_TYPE)0,
           GcdIoType,
           Alignment,
           Length,
           BaseAddress,
           ImageHandle,
           DeviceHandle
           );
}

/**
  Frees nonexistent I/O, reserved I/O, or I/O resources from the global coherency
  domain of the processor.

  @param  BaseAddress            Base address of the segment.
  @param  Length                 Length of the segment.

  @retval EFI_SUCCESS            Space successfully freed.

**/
EFI_STATUS
EFIAPI
CoreFreeIoSpace (
  IN EFI_PHYSICAL_ADDRESS  BaseAddress,
  IN UINT64                Length
  )
{
  DEBUG ((DEBUG_GCD, "GCD:FreeIoSpace(Base=%016lx,Length=%016lx)\n", BaseAddress, Length));

  return CoreConvertSpace (GCD_FREE_IO_OPERATION, (EFI_GCD_MEMORY_TYPE)0, (EFI_GCD_IO_TYPE)0, BaseAddress, Length, 0, 0);
}

/**
  Removes reserved I/O or I/O resources from the global coherency domain of the
  processor.

  @param  BaseAddress            Base address of the segment.
  @param  Length                 Length of the segment.

  @retval EFI_SUCCESS            Successfully removed a segment of IO space.

**/
EFI_STATUS
EFIAPI
CoreRemoveIoSpace (
  IN EFI_PHYSICAL_ADDRESS  BaseAddress,
  IN UINT64                Length
  )
{
  DEBUG ((DEBUG_GCD, "GCD:RemoveIoSpace(Base=%016lx,Length=%016lx)\n", BaseAddress, Length));

  return CoreConvertSpace (GCD_REMOVE_IO_OPERATION, (EFI_GCD_MEMORY_TYPE)0, (EFI_GCD_IO_TYPE)0, BaseAddress, Length, 0, 0);
}

/**
  Build a IO descriptor according to an entry.

  @param  Descriptor             The descriptor to be built
  @param  Entry                  According to this entry

**/
VOID
BuildIoDescriptor (
  IN EFI_GCD_IO_SPACE_DESCRIPTOR  *Descriptor,
  IN EFI_GCD_MAP_ENTRY            *Entry
  )
{
  Descriptor->BaseAddress  = Entry->BaseAddress;
  Descriptor->Length       = Entry->EndAddress - Entry->BaseAddress + 1;
  Descriptor->GcdIoType    = Entry->GcdIoType;
  Descriptor->ImageHandle  = Entry->ImageHandle;
  Descriptor->DeviceHandle = Entry->DeviceHandle;
}

/**
  Retrieves the descriptor for an I/O region containing a specified address.

  @param  BaseAddress            Specified start address
  @param  Descriptor             Specified length

  @retval EFI_INVALID_PARAMETER  Descriptor is NULL.
  @retval EFI_SUCCESS            Successfully get the IO space descriptor.

**/
EFI_STATUS
EFIAPI
CoreGetIoSpaceDescriptor (
  IN  EFI_PHYSICAL_ADDRESS         BaseAddress,
  OUT EFI_GCD_IO_SPACE_DESCRIPTOR  *Descriptor
  )
{
  EFI_STATUS         Status;
  LIST_ENTRY         *StartLink;
  LIST_ENTRY         *EndLink;
  EFI_GCD_MAP_ENTRY  *Entry;

  //
  // Make sure parameters are valid
  //
  if (Descriptor == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  CoreAcquireGcdIoLock ();

  //
  // Search for the list of descriptors that contain BaseAddress
  //
  Status = CoreSearchGcdMapEntry (BaseAddress, 1, &StartLink, &EndLink, &mGcdIoSpaceMap);
  if (EFI_ERROR (Status)) {
    Status = EFI_NOT_FOUND;
  } else {
    ASSERT (StartLink != NULL && EndLink != NULL);
    //
    // Copy the contents of the found descriptor into Descriptor
    //
    Entry = CR (StartLink, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);
    BuildIoDescriptor (Descriptor, Entry);
  }

  CoreReleaseGcdIoLock ();

  return Status;
}

/**
  Returns a map of the I/O resources in the global coherency domain of the processor.

  @param  NumberOfDescriptors    Number of descriptors.
  @param  IoSpaceMap             Descriptor array

  @retval EFI_INVALID_PARAMETER  Invalid parameter
  @retval EFI_OUT_OF_RESOURCES   No enough buffer to allocate
  @retval EFI_SUCCESS            Successfully get IO space map.

**/
EFI_STATUS
EFIAPI
CoreGetIoSpaceMap (
  OUT UINTN                        *NumberOfDescriptors,
  OUT EFI_GCD_IO_SPACE_DESCRIPTOR  **IoSpaceMap
  )
{
  EFI_STATUS                   Status;
  LIST_ENTRY                   *Link;
  EFI_GCD_MAP_ENTRY            *Entry;
  EFI_GCD_IO_SPACE_DESCRIPTOR  *Descriptor;

  //
  // Make sure parameters are valid
  //
  if (NumberOfDescriptors == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (IoSpaceMap == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  CoreAcquireGcdIoLock ();

  //
  // Count the number of descriptors
  //
  *NumberOfDescriptors = CoreCountGcdMapEntry (&mGcdIoSpaceMap);

  //
  // Allocate the IoSpaceMap
  //
  *IoSpaceMap = AllocatePool (*NumberOfDescriptors * sizeof (EFI_GCD_IO_SPACE_DESCRIPTOR));
  if (*IoSpaceMap == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Done;
  }

  //
  // Fill in the IoSpaceMap
  //
  Descriptor = *IoSpaceMap;
  Link       = mGcdIoSpaceMap.ForwardLink;
  while (Link != &mGcdIoSpaceMap) {
    Entry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);
    BuildIoDescriptor (Descriptor, Entry);
    Descriptor++;
    Link = Link->ForwardLink;
  }

  Status = EFI_SUCCESS;

Done:
  CoreReleaseGcdIoLock ();
  return Status;
}

/**
  Converts a Resource Descriptor HOB attributes mask to an EFI Memory Descriptor
  capabilities mask

  @param  GcdMemoryType          Type of resource in the GCD memory map.
  @param  Attributes             The attribute mask in the Resource Descriptor
                                 HOB.

  @return The capabilities mask for an EFI Memory Descriptor.

**/
UINT64
CoreConvertResourceDescriptorHobAttributesToCapabilities (
  EFI_GCD_MEMORY_TYPE  GcdMemoryType,
  UINT64               Attributes
  )
{
  UINT64                          Capabilities;
  GCD_ATTRIBUTE_CONVERSION_ENTRY  *Conversion;

  //
  // Convert the Resource HOB Attributes to an EFI Memory Capabilities mask
  //
  for (Capabilities = 0, Conversion = mAttributeConversionTable; Conversion->Attribute != 0; Conversion++) {
    if (Conversion->Memory || ((GcdMemoryType != EfiGcdMemoryTypeSystemMemory) && (GcdMemoryType != EfiGcdMemoryTypeMoreReliable))) {
      if (Attributes & Conversion->Attribute) {
        Capabilities |= Conversion->Capability;
      }
    }
  }

  return Capabilities;
}

/**
  Calculate total memory bin size neeeded.

  @return The total memory bin size neeeded.

**/
UINT64
CalculateTotalMemoryBinSizeNeeded (
  VOID
  )
{
  UINTN   Index;
  UINT64  TotalSize;

  //
  // Loop through each memory type in the order specified by the gMemoryTypeInformation[] array
  //
  TotalSize = 0;
  for (Index = 0; gMemoryTypeInformation[Index].Type != EfiMaxMemoryType; Index++) {
    TotalSize += LShiftU64 (gMemoryTypeInformation[Index].NumberOfPages, EFI_PAGE_SHIFT);
  }

  return TotalSize;
}

/**
   Find the largest region in the specified region that is not covered by an existing memory allocation

   @param BaseAddress   On input start of the region to check.
                        On output start of the largest free region.
   @param Length        On input size of region to check.
                        On output size of the largest free region.
   @param MemoryHob     Hob pointer for the first memory allocation pointer to check
**/
VOID
FindLargestFreeRegion (
  IN OUT EFI_PHYSICAL_ADDRESS   *BaseAddress,
  IN OUT UINT64                 *Length,
  IN EFI_HOB_MEMORY_ALLOCATION  *MemoryHob
  )
{
  EFI_PHYSICAL_ADDRESS  TopAddress;
  EFI_PHYSICAL_ADDRESS  AllocatedTop;
  EFI_PHYSICAL_ADDRESS  LowerBase;
  UINT64                LowerSize;
  EFI_PHYSICAL_ADDRESS  UpperBase;
  UINT64                UpperSize;

  TopAddress = *BaseAddress + *Length;
  while (MemoryHob != NULL) {
    AllocatedTop = MemoryHob->AllocDescriptor.MemoryBaseAddress + MemoryHob->AllocDescriptor.MemoryLength;

    if ((MemoryHob->AllocDescriptor.MemoryBaseAddress >= *BaseAddress) &&
        (AllocatedTop <= TopAddress))
    {
      LowerBase = *BaseAddress;
      LowerSize = MemoryHob->AllocDescriptor.MemoryBaseAddress - *BaseAddress;
      UpperBase = AllocatedTop;
      UpperSize = TopAddress - AllocatedTop;

      if (LowerSize != 0) {
        FindLargestFreeRegion (&LowerBase, &LowerSize, (EFI_HOB_MEMORY_ALLOCATION *)GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, GET_NEXT_HOB (MemoryHob)));
      }

      if (UpperSize != 0) {
        FindLargestFreeRegion (&UpperBase, &UpperSize, (EFI_HOB_MEMORY_ALLOCATION *)GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, GET_NEXT_HOB (MemoryHob)));
      }

      if (UpperSize >= LowerSize) {
        *Length      = UpperSize;
        *BaseAddress = UpperBase;
      } else {
        *Length      = LowerSize;
        *BaseAddress = LowerBase;
      }

      return;
    }

    MemoryHob = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, GET_NEXT_HOB (MemoryHob));
  }
}

/**
  External function. Initializes memory services based on the memory
  descriptor HOBs.  This function is responsible for priming the memory
  map, so memory allocations and resource allocations can be made.
  The first part of this function can not depend on any memory services
  until at least one memory descriptor is provided to the memory services.

  @param  HobStart               The start address of the HOB.
  @param  MemoryBaseAddress      Start address of memory region found to init DXE
                                 core.
  @param  MemoryLength           Length of memory region found to init DXE core.

  @retval EFI_SUCCESS            Memory services successfully initialized.

**/
EFI_STATUS
CoreInitializeMemoryServices (
  IN  VOID                  **HobStart,
  OUT EFI_PHYSICAL_ADDRESS  *MemoryBaseAddress,
  OUT UINT64                *MemoryLength
  )
{
  EFI_PEI_HOB_POINTERS         Hob;
  EFI_MEMORY_TYPE_INFORMATION  *EfiMemoryTypeInformation;
  UINTN                        DataSize;
  BOOLEAN                      Found;
  EFI_HOB_HANDOFF_INFO_TABLE   *PhitHob;
  EFI_HOB_RESOURCE_DESCRIPTOR  *ResourceHob;
  EFI_HOB_RESOURCE_DESCRIPTOR  *PhitResourceHob;
  EFI_PHYSICAL_ADDRESS         BaseAddress;
  UINT64                       Length;
  UINT64                       Attributes;
  UINT64                       Capabilities;
  EFI_PHYSICAL_ADDRESS         TestedMemoryBaseAddress;
  UINT64                       TestedMemoryLength;
  EFI_PHYSICAL_ADDRESS         HighAddress;
  EFI_HOB_GUID_TYPE            *GuidHob;
  UINT32                       ReservedCodePageNumber;
  UINT64                       MinimalMemorySizeNeeded;

  //
  // Point at the first HOB.  This must be the PHIT HOB.
  //
  Hob.Raw = *HobStart;
  ASSERT (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_HANDOFF);

  //
  // Initialize the spin locks and maps in the memory services.
  // Also fill in the memory services into the EFI Boot Services Table
  //
  CoreInitializePool ();

  //
  // Initialize Local Variables
  //
  PhitResourceHob = NULL;
  ResourceHob     = NULL;
  BaseAddress     = 0;
  Length          = 0;
  Attributes      = 0;

  //
  // Cache the PHIT HOB for later use
  //
  PhitHob = Hob.HandoffInformationTable;

  if (PcdGet64 (PcdLoadModuleAtFixAddressEnable) != 0) {
    ReservedCodePageNumber  = PcdGet32 (PcdLoadFixAddressRuntimeCodePageNumber);
    ReservedCodePageNumber += PcdGet32 (PcdLoadFixAddressBootTimeCodePageNumber);

    //
    // cache the Top address for loading modules at Fixed Address
    //
    gLoadModuleAtFixAddressConfigurationTable.DxeCodeTopAddress = PhitHob->EfiMemoryTop
                                                                  + EFI_PAGES_TO_SIZE (ReservedCodePageNumber);
  }

  //
  // See if a Memory Type Information HOB is available
  //
  GuidHob = GetFirstGuidHob (&gEfiMemoryTypeInformationGuid);
  if (GuidHob != NULL) {
    EfiMemoryTypeInformation = GET_GUID_HOB_DATA (GuidHob);
    DataSize                 = GET_GUID_HOB_DATA_SIZE (GuidHob);
    if ((EfiMemoryTypeInformation != NULL) && (DataSize > 0) && (DataSize <= (EfiMaxMemoryType + 1) * sizeof (EFI_MEMORY_TYPE_INFORMATION))) {
      CopyMem (&gMemoryTypeInformation, EfiMemoryTypeInformation, DataSize);
    }
  }

  //
  // Include the total memory bin size needed to make sure memory bin could be allocated successfully.
  //
  MinimalMemorySizeNeeded = MINIMUM_INITIAL_MEMORY_SIZE + CalculateTotalMemoryBinSizeNeeded ();

  //
  // Find the Resource Descriptor HOB that contains PHIT range EfiFreeMemoryBottom..EfiFreeMemoryTop
  //
  Found = FALSE;
  for (Hob.Raw = *HobStart; !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 (PhitHob->EfiFreeMemoryBottom < ResourceHob->PhysicalStart) {
      continue;
    }

    if (PhitHob->EfiFreeMemoryTop > (ResourceHob->PhysicalStart + ResourceHob->ResourceLength)) {
      continue;
    }

    //
    // Cache the resource descriptor HOB for the memory region described by the PHIT HOB
    //
    PhitResourceHob = ResourceHob;
    Found           = TRUE;

    //
    // Compute range between PHIT EfiMemoryTop and the end of the Resource Descriptor HOB
    //
    Attributes  = PhitResourceHob->ResourceAttribute;
    BaseAddress = PageAlignAddress (PhitHob->EfiMemoryTop);
    Length      = PageAlignLength (ResourceHob->PhysicalStart + ResourceHob->ResourceLength - BaseAddress);
    FindLargestFreeRegion (&BaseAddress, &Length, (EFI_HOB_MEMORY_ALLOCATION *)GetFirstHob (EFI_HOB_TYPE_MEMORY_ALLOCATION));
    if (Length < MinimalMemorySizeNeeded) {
      //
      // If that range is not large enough to intialize the DXE Core, then
      // Compute range between PHIT EfiFreeMemoryBottom and PHIT EfiFreeMemoryTop
      //
      BaseAddress = PageAlignAddress (PhitHob->EfiFreeMemoryBottom);
      Length      = PageAlignLength (PhitHob->EfiFreeMemoryTop - BaseAddress);
      // This region is required to have no memory allocation inside it, skip check for entries in HOB List
      if (Length < MinimalMemorySizeNeeded) {
        //
        // If that range is not large enough to intialize the DXE Core, then
        // Compute range between the start of the Resource Descriptor HOB and the start of the HOB List
        //
        BaseAddress = PageAlignAddress (ResourceHob->PhysicalStart);
        Length      = PageAlignLength ((UINT64)((UINTN)*HobStart - BaseAddress));
        FindLargestFreeRegion (&BaseAddress, &Length, (EFI_HOB_MEMORY_ALLOCATION *)GetFirstHob (EFI_HOB_TYPE_MEMORY_ALLOCATION));
      }
    }

    break;
  }

  //
  // Assert if a resource descriptor HOB for the memory region described by the PHIT was not found
  //
  ASSERT (Found);

  //
  // Take the range in the resource descriptor HOB for the memory region described
  // by the PHIT as higher priority if it is big enough. It can make the memory bin
  // allocated to be at the same memory region with PHIT that has more better compatibility
  // to avoid memory fragmentation for some code practices assume and allocate <4G ACPI memory.
  //
  if (Length < MinimalMemorySizeNeeded) {
    //
    // Search all the resource descriptor HOBs from the highest possible addresses down for a memory
    // region that is big enough to initialize the DXE core.  Always skip the PHIT Resource HOB.
    // The max address must be within the physically addressible range for the processor.
    //
    HighAddress = MAX_ALLOC_ADDRESS;
    for (Hob.Raw = *HobStart; !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) {
      //
      // Skip the Resource Descriptor HOB that contains the PHIT
      //
      if (Hob.ResourceDescriptor == PhitResourceHob) {
        continue;
      }

      //
      // 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 below MAX_ALLOC_ADDRESS
      //
      ResourceHob = Hob.ResourceDescriptor;
      if (ResourceHob->ResourceType != EFI_RESOURCE_SYSTEM_MEMORY) {
        continue;
      }

      if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) != TESTED_MEMORY_ATTRIBUTES) {
        continue;
      }

      if ((ResourceHob->PhysicalStart + ResourceHob->ResourceLength) > (EFI_PHYSICAL_ADDRESS)MAX_ALLOC_ADDRESS) {
        continue;
      }

      //
      // Skip Resource Descriptor HOBs that are below a previously found Resource Descriptor HOB
      //
      if ((HighAddress != (EFI_PHYSICAL_ADDRESS)MAX_ALLOC_ADDRESS) && (ResourceHob->PhysicalStart <= HighAddress)) {
        continue;
      }

      //
      // Skip Resource Descriptor HOBs that are not large enough to initilize the DXE Core
      //
      TestedMemoryBaseAddress = PageAlignAddress (ResourceHob->PhysicalStart);
      TestedMemoryLength      = PageAlignLength (ResourceHob->PhysicalStart + ResourceHob->ResourceLength - TestedMemoryBaseAddress);
      FindLargestFreeRegion (&TestedMemoryBaseAddress, &TestedMemoryLength, (EFI_HOB_MEMORY_ALLOCATION *)GetFirstHob (EFI_HOB_TYPE_MEMORY_ALLOCATION));
      if (TestedMemoryLength < MinimalMemorySizeNeeded) {
        continue;
      }

      //
      // Save the range described by the Resource Descriptor that is large enough to initilize the DXE Core
      //
      BaseAddress = TestedMemoryBaseAddress;
      Length      = TestedMemoryLength;
      Attributes  = ResourceHob->ResourceAttribute;
      HighAddress = ResourceHob->PhysicalStart;
    }
  }

  DEBUG ((DEBUG_INFO, "CoreInitializeMemoryServices:\n"));
  DEBUG ((DEBUG_INFO, "  BaseAddress - 0x%lx Length - 0x%lx MinimalMemorySizeNeeded - 0x%lx\n", BaseAddress, Length, MinimalMemorySizeNeeded));

  //
  // If no memory regions are found that are big enough to initialize the DXE core, then ASSERT().
  //
  ASSERT (Length >= MinimalMemorySizeNeeded);

  //
  // Convert the Resource HOB Attributes to an EFI Memory Capabilities mask
  //
  if ((Attributes & EFI_RESOURCE_ATTRIBUTE_MORE_RELIABLE) == EFI_RESOURCE_ATTRIBUTE_MORE_RELIABLE) {
    Capabilities = CoreConvertResourceDescriptorHobAttributesToCapabilities (EfiGcdMemoryTypeMoreReliable, Attributes);
  } else {
    Capabilities = CoreConvertResourceDescriptorHobAttributesToCapabilities (EfiGcdMemoryTypeSystemMemory, Attributes);
  }

  //
  // Declare the very first memory region, so the EFI Memory Services are available.
  //
  CoreAddMemoryDescriptor (
    EfiConventionalMemory,
    BaseAddress,
    RShiftU64 (Length, EFI_PAGE_SHIFT),
    Capabilities
    );

  *MemoryBaseAddress = BaseAddress;
  *MemoryLength      = Length;

  return EFI_SUCCESS;
}

/**
  External function. Initializes the GCD and memory services based on the memory
  descriptor HOBs.  This function is responsible for priming the GCD map and the
  memory map, so memory allocations and resource allocations can be made. The
  HobStart will be relocated to a pool buffer.

  @param  HobStart               The start address of the HOB
  @param  MemoryBaseAddress      Start address of memory region found to init DXE
                                 core.
  @param  MemoryLength           Length of memory region found to init DXE core.

  @retval EFI_SUCCESS            GCD services successfully initialized.

**/
EFI_STATUS
CoreInitializeGcdServices (
  IN OUT VOID              **HobStart,
  IN EFI_PHYSICAL_ADDRESS  MemoryBaseAddress,
  IN UINT64                MemoryLength
  )
{
  EFI_PEI_HOB_POINTERS             Hob;
  VOID                             *NewHobList;
  EFI_HOB_HANDOFF_INFO_TABLE       *PhitHob;
  UINT8                            SizeOfMemorySpace;
  UINT8                            SizeOfIoSpace;
  EFI_HOB_RESOURCE_DESCRIPTOR      *ResourceHob;
  EFI_PHYSICAL_ADDRESS             BaseAddress;
  UINT64                           Length;
  EFI_STATUS                       Status;
  EFI_GCD_MAP_ENTRY                *Entry;
  EFI_GCD_MEMORY_TYPE              GcdMemoryType;
  EFI_GCD_IO_TYPE                  GcdIoType;
  EFI_GCD_MEMORY_SPACE_DESCRIPTOR  Descriptor;
  EFI_HOB_MEMORY_ALLOCATION        *MemoryHob;
  EFI_HOB_FIRMWARE_VOLUME          *FirmwareVolumeHob;
  UINTN                            NumberOfDescriptors;
  EFI_GCD_MEMORY_SPACE_DESCRIPTOR  *MemorySpaceMap;
  UINTN                            Index;
  UINT64                           Capabilities;
  EFI_HOB_CPU                      *CpuHob;
  EFI_GCD_MEMORY_SPACE_DESCRIPTOR  *MemorySpaceMapHobList;

  //
  // Cache the PHIT HOB for later use
  //
  PhitHob = (EFI_HOB_HANDOFF_INFO_TABLE *)(*HobStart);

  //
  // Get the number of address lines in the I/O and Memory space for the CPU
  //
  CpuHob = GetFirstHob (EFI_HOB_TYPE_CPU);
  ASSERT (CpuHob != NULL);
  SizeOfMemorySpace = CpuHob->SizeOfMemorySpace;
  SizeOfIoSpace     = CpuHob->SizeOfIoSpace;

  //
  // Initialize the GCD Memory Space Map
  //
  Entry = AllocateCopyPool (sizeof (EFI_GCD_MAP_ENTRY), &mGcdMemorySpaceMapEntryTemplate);
  ASSERT (Entry != NULL);

  Entry->EndAddress = LShiftU64 (1, SizeOfMemorySpace) - 1;

  InsertHeadList (&mGcdMemorySpaceMap, &Entry->Link);

  CoreDumpGcdMemorySpaceMap (TRUE);

  //
  // Initialize the GCD I/O Space Map
  //
  Entry = AllocateCopyPool (sizeof (EFI_GCD_MAP_ENTRY), &mGcdIoSpaceMapEntryTemplate);
  ASSERT (Entry != NULL);

  Entry->EndAddress = LShiftU64 (1, SizeOfIoSpace) - 1;

  InsertHeadList (&mGcdIoSpaceMap, &Entry->Link);

  CoreDumpGcdIoSpaceMap (TRUE);

  //
  // Walk the HOB list and add all resource descriptors to the GCD
  //
  for (Hob.Raw = *HobStart; !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) {
    GcdMemoryType = EfiGcdMemoryTypeNonExistent;
    GcdIoType     = EfiGcdIoTypeNonExistent;

    if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
      ResourceHob = Hob.ResourceDescriptor;

      switch (ResourceHob->ResourceType) {
        case EFI_RESOURCE_SYSTEM_MEMORY:
          if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) == TESTED_MEMORY_ATTRIBUTES) {
            if ((ResourceHob->ResourceAttribute & EFI_RESOURCE_ATTRIBUTE_MORE_RELIABLE) == EFI_RESOURCE_ATTRIBUTE_MORE_RELIABLE) {
              GcdMemoryType = EfiGcdMemoryTypeMoreReliable;
            } else {
              GcdMemoryType = EfiGcdMemoryTypeSystemMemory;
            }
          }

          if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) == INITIALIZED_MEMORY_ATTRIBUTES) {
            GcdMemoryType = EfiGcdMemoryTypeReserved;
          }

          if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) == PRESENT_MEMORY_ATTRIBUTES) {
            GcdMemoryType = EfiGcdMemoryTypeReserved;
          }

          if ((ResourceHob->ResourceAttribute & EFI_RESOURCE_ATTRIBUTE_PERSISTENT) == EFI_RESOURCE_ATTRIBUTE_PERSISTENT) {
            GcdMemoryType = EfiGcdMemoryTypePersistent;
          }

          break;
        case EFI_RESOURCE_MEMORY_MAPPED_IO:
        case EFI_RESOURCE_FIRMWARE_DEVICE:
          GcdMemoryType = EfiGcdMemoryTypeMemoryMappedIo;
          break;
        case EFI_RESOURCE_MEMORY_MAPPED_IO_PORT:
        case EFI_RESOURCE_MEMORY_RESERVED:
          GcdMemoryType = EfiGcdMemoryTypeReserved;
          break;
        case BZ3937_EFI_RESOURCE_MEMORY_UNACCEPTED:
          GcdMemoryType = EFI_GCD_MEMORY_TYPE_UNACCEPTED;
          break;
        case EFI_RESOURCE_IO:
          GcdIoType = EfiGcdIoTypeIo;
          break;
        case EFI_RESOURCE_IO_RESERVED:
          GcdIoType = EfiGcdIoTypeReserved;
          break;
      }

      if (GcdMemoryType != EfiGcdMemoryTypeNonExistent) {
        //
        // Validate the Resource HOB Attributes
        //
        CoreValidateResourceDescriptorHobAttributes (ResourceHob->ResourceAttribute);

        //
        // Convert the Resource HOB Attributes to an EFI Memory Capabilities mask
        //
        Capabilities = CoreConvertResourceDescriptorHobAttributesToCapabilities (
                         GcdMemoryType,
                         ResourceHob->ResourceAttribute
                         );

        Status = CoreInternalAddMemorySpace (
                   GcdMemoryType,
                   ResourceHob->PhysicalStart,
                   ResourceHob->ResourceLength,
                   Capabilities
                   );
      }

      if (GcdIoType != EfiGcdIoTypeNonExistent) {
        Status = CoreAddIoSpace (
                   GcdIoType,
                   ResourceHob->PhysicalStart,
                   ResourceHob->ResourceLength
                   );
      }
    }
  }

  //
  // Allocate first memory region from the GCD by the DXE core
  //
  Status = CoreGetMemorySpaceDescriptor (MemoryBaseAddress, &Descriptor);
  if (!EFI_ERROR (Status)) {
    ASSERT (
      (Descriptor.GcdMemoryType == EfiGcdMemoryTypeSystemMemory) ||
      (Descriptor.GcdMemoryType == EfiGcdMemoryTypeMoreReliable)
      );
    Status = CoreAllocateMemorySpace (
               EfiGcdAllocateAddress,
               Descriptor.GcdMemoryType,
               0,
               MemoryLength,
               &MemoryBaseAddress,
               gDxeCoreImageHandle,
               NULL
               );
  }

  //
  // Walk the HOB list and allocate all memory space that is consumed by memory allocation HOBs,
  // and Firmware Volume HOBs.  Also update the EFI Memory Map with the memory allocation HOBs.
  //
  for (Hob.Raw = *HobStart; !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) {
    if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_MEMORY_ALLOCATION) {
      MemoryHob   = Hob.MemoryAllocation;
      BaseAddress = MemoryHob->AllocDescriptor.MemoryBaseAddress;
      Status      = CoreGetMemorySpaceDescriptor (BaseAddress, &Descriptor);
      if (!EFI_ERROR (Status)) {
        Status = CoreAllocateMemorySpace (
                   EfiGcdAllocateAddress,
                   Descriptor.GcdMemoryType,
                   0,
                   MemoryHob->AllocDescriptor.MemoryLength,
                   &BaseAddress,
                   gDxeCoreImageHandle,
                   NULL
                   );
        if (!EFI_ERROR (Status) &&
            ((Descriptor.GcdMemoryType == EfiGcdMemoryTypeSystemMemory) ||
             (Descriptor.GcdMemoryType == EfiGcdMemoryTypeMoreReliable)))
        {
          CoreAddMemoryDescriptor (
            MemoryHob->AllocDescriptor.MemoryType,
            MemoryHob->AllocDescriptor.MemoryBaseAddress,
            RShiftU64 (MemoryHob->AllocDescriptor.MemoryLength, EFI_PAGE_SHIFT),
            Descriptor.Capabilities & (~EFI_MEMORY_RUNTIME)
            );
        }
      }
    }

    if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_FV) {
      FirmwareVolumeHob = Hob.FirmwareVolume;
      BaseAddress       = FirmwareVolumeHob->BaseAddress;
      Status            = CoreAllocateMemorySpace (
                            EfiGcdAllocateAddress,
                            EfiGcdMemoryTypeMemoryMappedIo,
                            0,
                            FirmwareVolumeHob->Length,
                            &BaseAddress,
                            gDxeCoreImageHandle,
                            NULL
                            );
    }
  }

  //
  // Add and allocate the remaining unallocated system memory to the memory services.
  //
  Status = CoreGetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap);
  ASSERT (Status == EFI_SUCCESS);

  MemorySpaceMapHobList = NULL;
  for (Index = 0; Index < NumberOfDescriptors; Index++) {
    if ((MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeSystemMemory) ||
        (MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeMoreReliable))
    {
      if (MemorySpaceMap[Index].ImageHandle == NULL) {
        BaseAddress = PageAlignAddress (MemorySpaceMap[Index].BaseAddress);
        Length      = PageAlignLength (MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length - BaseAddress);
        if ((Length == 0) || (MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length < BaseAddress)) {
          continue;
        }

        if (((UINTN)MemorySpaceMap[Index].BaseAddress <= (UINTN)(*HobStart)) &&
            ((UINTN)(MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length) >= (UINTN)PhitHob->EfiFreeMemoryBottom))
        {
          //
          // Skip the memory space that covers HOB List, it should be processed
          // after HOB List relocation to avoid the resources allocated by others
          // to corrupt HOB List before its relocation.
          //
          MemorySpaceMapHobList = &MemorySpaceMap[Index];
          continue;
        }

        CoreAddMemoryDescriptor (
          EfiConventionalMemory,
          BaseAddress,
          RShiftU64 (Length, EFI_PAGE_SHIFT),
          MemorySpaceMap[Index].Capabilities & (~EFI_MEMORY_RUNTIME)
          );
        Status = CoreAllocateMemorySpace (
                   EfiGcdAllocateAddress,
                   MemorySpaceMap[Index].GcdMemoryType,
                   0,
                   Length,
                   &BaseAddress,
                   gDxeCoreImageHandle,
                   NULL
                   );
      }
    }
  }

  //
  // Relocate HOB List to an allocated pool buffer.
  // The relocation should be at after all the tested memory resources added
  // (except the memory space that covers HOB List) to the memory services,
  // because the memory resource found in CoreInitializeMemoryServices()
  // may have not enough remaining resource for HOB List.
  //
  NewHobList = AllocateCopyPool (
                 (UINTN)PhitHob->EfiFreeMemoryBottom - (UINTN)(*HobStart),
                 *HobStart
                 );
  ASSERT (NewHobList != NULL);

  *HobStart = NewHobList;
  gHobList  = NewHobList;

  if (MemorySpaceMapHobList != NULL) {
    //
    // Add and allocate the memory space that covers HOB List to the memory services
    // after HOB List relocation.
    //
    BaseAddress = PageAlignAddress (MemorySpaceMapHobList->BaseAddress);
    Length      = PageAlignLength (MemorySpaceMapHobList->BaseAddress + MemorySpaceMapHobList->Length - BaseAddress);
    CoreAddMemoryDescriptor (
      EfiConventionalMemory,
      BaseAddress,
      RShiftU64 (Length, EFI_PAGE_SHIFT),
      MemorySpaceMapHobList->Capabilities & (~EFI_MEMORY_RUNTIME)
      );
    Status = CoreAllocateMemorySpace (
               EfiGcdAllocateAddress,
               MemorySpaceMapHobList->GcdMemoryType,
               0,
               Length,
               &BaseAddress,
               gDxeCoreImageHandle,
               NULL
               );
  }

  CoreFreePool (MemorySpaceMap);

  return EFI_SUCCESS;
}
