]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Core/Dxe/Gcd/Gcd.c
MdeModulePkg/Gcd: Suppress incorrect compiler/analyzer warnings
[mirror_edk2.git] / MdeModulePkg / Core / Dxe / Gcd / Gcd.c
index bff13b3bf666148325e72545e0045c12932b0cfe..e17e98230b79beb063c5a00cbe38c251e86e9fc3 100644 (file)
@@ -1,21 +1,22 @@
-/** @file \r
+/** @file\r
+  The file contains the GCD related services in the EFI Boot Services Table.\r
+  The GCD services are used to manage the memory and I/O regions that\r
+  are accessible to the CPU that is executing the DXE core.\r
 \r
-    The file contains the GCD related services in the EFI Boot Services Table.\r
-    The GCD services are used to manage the memory and I/O regions that \r
-    are accessible to the CPU that is executing the DXE core.\r
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
 \r
-Copyright (c) 2006 - 2008, Intel Corporation                                                         \r
-All rights reserved. This program and the accompanying materials                          \r
-are licensed and made available under the terms and conditions of the BSD License         \r
-which accompanies this distribution.  The full text of the license may be found at        \r
-http://opensource.org/licenses/bsd-license.php                                            \r
-                                                                                          \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
 \r
 **/\r
 \r
-#include <DxeMain.h>\r
+#include "DxeMain.h"\r
+#include "Gcd.h"\r
+#include "Mem/HeapGuard.h"\r
 \r
 #define MINIMUM_INITIAL_MEMORY_SIZE 0x10000\r
 \r
@@ -25,9 +26,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
                                        EFI_RESOURCE_ATTRIBUTE_READ_PROTECTED      | \\r
                                        EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED     | \\r
                                        EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTED | \\r
+                                       EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTED | \\r
                                        EFI_RESOURCE_ATTRIBUTE_16_BIT_IO           | \\r
                                        EFI_RESOURCE_ATTRIBUTE_32_BIT_IO           | \\r
-                                       EFI_RESOURCE_ATTRIBUTE_64_BIT_IO           ) \r
+                                       EFI_RESOURCE_ATTRIBUTE_64_BIT_IO           | \\r
+                                       EFI_RESOURCE_ATTRIBUTE_PERSISTENT          )\r
 \r
 #define TESTED_MEMORY_ATTRIBUTES      (EFI_RESOURCE_ATTRIBUTE_PRESENT     | \\r
                                        EFI_RESOURCE_ATTRIBUTE_INITIALIZED | \\r
@@ -38,7 +41,12 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 #define PRESENT_MEMORY_ATTRIBUTES     (EFI_RESOURCE_ATTRIBUTE_PRESENT)\r
 \r
-#define INVALID_CPU_ARCH_ATTRIBUTES   0xffffffff\r
+#define EXCLUSIVE_MEMORY_ATTRIBUTES   (EFI_MEMORY_UC | EFI_MEMORY_WC | \\r
+                                       EFI_MEMORY_WT | EFI_MEMORY_WB | \\r
+                                       EFI_MEMORY_WP | EFI_MEMORY_UCE)\r
+\r
+#define NONEXCLUSIVE_MEMORY_ATTRIBUTES (EFI_MEMORY_XP | EFI_MEMORY_RP | \\r
+                                        EFI_MEMORY_RO)\r
 \r
 //\r
 // Module Variables\r
@@ -50,7 +58,10 @@ LIST_ENTRY         mGcdIoSpaceMap      = INITIALIZE_LIST_HEAD_VARIABLE (mGcdIoSp
 \r
 EFI_GCD_MAP_ENTRY mGcdMemorySpaceMapEntryTemplate = {\r
   EFI_GCD_MAP_SIGNATURE,\r
-  { NULL, NULL },\r
+  {\r
+    NULL,\r
+    NULL\r
+  },\r
   0,\r
   0,\r
   0,\r
@@ -63,7 +74,10 @@ EFI_GCD_MAP_ENTRY mGcdMemorySpaceMapEntryTemplate = {
 \r
 EFI_GCD_MAP_ENTRY mGcdIoSpaceMapEntryTemplate = {\r
   EFI_GCD_MAP_SIGNATURE,\r
-  { NULL, NULL },\r
+  {\r
+    NULL,\r
+    NULL\r
+  },\r
   0,\r
   0,\r
   0,\r
@@ -75,20 +89,166 @@ EFI_GCD_MAP_ENTRY mGcdIoSpaceMapEntryTemplate = {
 };\r
 \r
 GCD_ATTRIBUTE_CONVERSION_ENTRY mAttributeConversionTable[] = {\r
-  { EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE,             EFI_MEMORY_UC,          TRUE  },\r
-  { EFI_RESOURCE_ATTRIBUTE_UNCACHED_EXPORTED,       EFI_MEMORY_UCE,         TRUE  },   \r
-  { EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE,       EFI_MEMORY_WC,          TRUE  },\r
-  { EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE, EFI_MEMORY_WT,          TRUE  },\r
-  { EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE,    EFI_MEMORY_WB,          TRUE  },\r
-  { EFI_RESOURCE_ATTRIBUTE_READ_PROTECTED,          EFI_MEMORY_RP,          TRUE  },\r
-  { EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED,         EFI_MEMORY_WP,          TRUE  },\r
-  { EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTED,     EFI_MEMORY_XP,          TRUE  },\r
-  { EFI_RESOURCE_ATTRIBUTE_PRESENT,                 EFI_MEMORY_PRESENT,     FALSE },\r
-  { EFI_RESOURCE_ATTRIBUTE_INITIALIZED,             EFI_MEMORY_INITIALIZED, FALSE },\r
-  { EFI_RESOURCE_ATTRIBUTE_TESTED,                  EFI_MEMORY_TESTED,      FALSE },\r
-  { 0, 0, FALSE }\r
+  { EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE,             EFI_MEMORY_UC,              TRUE  },\r
+  { EFI_RESOURCE_ATTRIBUTE_UNCACHED_EXPORTED,       EFI_MEMORY_UCE,             TRUE  },\r
+  { EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE,       EFI_MEMORY_WC,              TRUE  },\r
+  { EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE, EFI_MEMORY_WT,              TRUE  },\r
+  { EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE,    EFI_MEMORY_WB,              TRUE  },\r
+  { EFI_RESOURCE_ATTRIBUTE_READ_PROTECTABLE,        EFI_MEMORY_RP,              TRUE  },\r
+  { EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTABLE,       EFI_MEMORY_WP,              TRUE  },\r
+  { EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTABLE,   EFI_MEMORY_XP,              TRUE  },\r
+  { EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTABLE,   EFI_MEMORY_RO,              TRUE  },\r
+  { EFI_RESOURCE_ATTRIBUTE_PRESENT,                 EFI_MEMORY_PRESENT,         FALSE },\r
+  { EFI_RESOURCE_ATTRIBUTE_INITIALIZED,             EFI_MEMORY_INITIALIZED,     FALSE },\r
+  { EFI_RESOURCE_ATTRIBUTE_TESTED,                  EFI_MEMORY_TESTED,          FALSE },\r
+  { EFI_RESOURCE_ATTRIBUTE_PERSISTABLE,             EFI_MEMORY_NV,              TRUE  },\r
+  { EFI_RESOURCE_ATTRIBUTE_MORE_RELIABLE,           EFI_MEMORY_MORE_RELIABLE,   TRUE  },\r
+  { 0,                                              0,                          FALSE }\r
+};\r
+\r
+///\r
+/// Lookup table used to print GCD Memory Space Map\r
+///\r
+GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 *mGcdMemoryTypeNames[] = {\r
+  "NonExist ",  // EfiGcdMemoryTypeNonExistent\r
+  "Reserved ",  // EfiGcdMemoryTypeReserved\r
+  "SystemMem",  // EfiGcdMemoryTypeSystemMemory\r
+  "MMIO     ",  // EfiGcdMemoryTypeMemoryMappedIo\r
+  "PersisMem",  // EfiGcdMemoryTypePersistent\r
+  "MoreRelia",  // EfiGcdMemoryTypeMoreReliable\r
+  "Unknown  "   // EfiGcdMemoryTypeMaximum\r
+};\r
+\r
+///\r
+/// Lookup table used to print GCD I/O Space Map\r
+///\r
+GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 *mGcdIoTypeNames[] = {\r
+  "NonExist",  // EfiGcdIoTypeNonExistent\r
+  "Reserved",  // EfiGcdIoTypeReserved\r
+  "I/O     ",  // EfiGcdIoTypeIo\r
+  "Unknown "   // EfiGcdIoTypeMaximum \r
 };\r
 \r
+///\r
+/// Lookup table used to print GCD Allocation Types\r
+///\r
+GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 *mGcdAllocationTypeNames[] = {\r
+  "AnySearchBottomUp        ",  // EfiGcdAllocateAnySearchBottomUp\r
+  "MaxAddressSearchBottomUp ",  // EfiGcdAllocateMaxAddressSearchBottomUp\r
+  "AtAddress                ",  // EfiGcdAllocateAddress\r
+  "AnySearchTopDown         ",  // EfiGcdAllocateAnySearchTopDown\r
+  "MaxAddressSearchTopDown  ",  // EfiGcdAllocateMaxAddressSearchTopDown\r
+  "Unknown                  "   // EfiGcdMaxAllocateType\r
+};\r
+\r
+/**\r
+  Dump the entire contents if the GCD Memory Space Map using DEBUG() macros when\r
+  PcdDebugPrintErrorLevel has the DEBUG_GCD bit set.\r
+\r
+  @param  InitialMap  TRUE if the initial GCD Memory Map is being dumped.  Otherwise, FALSE.\r
+  \r
+**/\r
+VOID\r
+EFIAPI\r
+CoreDumpGcdMemorySpaceMap (\r
+  BOOLEAN  InitialMap\r
+  )\r
+{\r
+  DEBUG_CODE (\r
+    EFI_STATUS                       Status;\r
+    UINTN                            NumberOfDescriptors;\r
+    EFI_GCD_MEMORY_SPACE_DESCRIPTOR  *MemorySpaceMap;\r
+    UINTN                            Index;\r
+   \r
+    Status = CoreGetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap);\r
+    ASSERT (Status == EFI_SUCCESS && MemorySpaceMap != NULL);\r
+\r
+    if (InitialMap) {\r
+      DEBUG ((DEBUG_GCD, "GCD:Initial GCD Memory Space Map\n"));\r
+    }\r
+    DEBUG ((DEBUG_GCD, "GCDMemType Range                             Capabilities     Attributes      \n"));\r
+    DEBUG ((DEBUG_GCD, "========== ================================= ================ ================\n"));\r
+    for (Index = 0; Index < NumberOfDescriptors; Index++) {\r
+      DEBUG ((DEBUG_GCD, "%a  %016lx-%016lx %016lx %016lx%c\n", \r
+        mGcdMemoryTypeNames[MIN (MemorySpaceMap[Index].GcdMemoryType, EfiGcdMemoryTypeMaximum)],\r
+        MemorySpaceMap[Index].BaseAddress, \r
+        MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length - 1,\r
+        MemorySpaceMap[Index].Capabilities, \r
+        MemorySpaceMap[Index].Attributes,\r
+        MemorySpaceMap[Index].ImageHandle == NULL ? ' ' : '*'\r
+        ));\r
+    }\r
+    DEBUG ((DEBUG_GCD, "\n"));\r
+    FreePool (MemorySpaceMap);\r
+  );\r
+}\r
+\r
+/**\r
+  Dump the entire contents if the GCD I/O Space Map using DEBUG() macros when \r
+  PcdDebugPrintErrorLevel has the DEBUG_GCD bit set.\r
+\r
+  @param  InitialMap  TRUE if the initial GCD I/O Map is being dumped.  Otherwise, FALSE.\r
+  \r
+**/\r
+VOID\r
+EFIAPI\r
+CoreDumpGcdIoSpaceMap (\r
+  BOOLEAN  InitialMap\r
+  )\r
+{\r
+  DEBUG_CODE (\r
+    EFI_STATUS                   Status;\r
+    UINTN                        NumberOfDescriptors;\r
+    EFI_GCD_IO_SPACE_DESCRIPTOR  *IoSpaceMap;\r
+    UINTN                        Index;\r
+    \r
+    Status = CoreGetIoSpaceMap (&NumberOfDescriptors, &IoSpaceMap);\r
+    ASSERT (Status == EFI_SUCCESS && IoSpaceMap != NULL);\r
+    \r
+    if (InitialMap) {\r
+      DEBUG ((DEBUG_GCD, "GCD:Initial GCD I/O Space Map\n"));\r
+    }  \r
+    \r
+    DEBUG ((DEBUG_GCD, "GCDIoType  Range                            \n"));\r
+    DEBUG ((DEBUG_GCD, "========== =================================\n"));\r
+    for (Index = 0; Index < NumberOfDescriptors; Index++) {\r
+      DEBUG ((DEBUG_GCD, "%a   %016lx-%016lx%c\n", \r
+        mGcdIoTypeNames[MIN (IoSpaceMap[Index].GcdIoType, EfiGcdIoTypeMaximum)],\r
+        IoSpaceMap[Index].BaseAddress, \r
+        IoSpaceMap[Index].BaseAddress + IoSpaceMap[Index].Length - 1,\r
+        IoSpaceMap[Index].ImageHandle == NULL ? ' ' : '*'\r
+        ));\r
+    }\r
+    DEBUG ((DEBUG_GCD, "\n"));\r
+    FreePool (IoSpaceMap);\r
+  );\r
+}\r
+  \r
+/**\r
+  Validate resource descriptor HOB's attributes.\r
+\r
+  If Attributes includes some memory resource's settings, it should include \r
+  the corresponding capabilites also.\r
+\r
+  @param  Attributes  Resource descriptor HOB attributes.\r
+\r
+**/\r
+VOID\r
+CoreValidateResourceDescriptorHobAttributes (\r
+  IN UINT64  Attributes\r
+  )\r
+{\r
+  ASSERT (((Attributes & EFI_RESOURCE_ATTRIBUTE_READ_PROTECTED) == 0) ||\r
+          ((Attributes & EFI_RESOURCE_ATTRIBUTE_READ_PROTECTABLE) != 0));\r
+  ASSERT (((Attributes & EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED) == 0) ||\r
+          ((Attributes & EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTABLE) != 0));\r
+  ASSERT (((Attributes & EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTED) == 0) ||\r
+          ((Attributes & EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTABLE) != 0));\r
+  ASSERT (((Attributes & EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTED) == 0) ||\r
+          ((Attributes & EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTABLE) != 0));\r
+  ASSERT (((Attributes & EFI_RESOURCE_ATTRIBUTE_PERSISTENT) == 0) ||\r
+          ((Attributes & EFI_RESOURCE_ATTRIBUTE_PERSISTABLE) != 0));\r
+}\r
 \r
 /**\r
   Acquire memory lock on mGcdMemorySpaceLock.\r
@@ -122,7 +282,6 @@ CoreReleaseGcdMemoryLock (
   Acquire memory lock on mGcdIoSpaceLock.\r
 \r
 **/\r
-STATIC\r
 VOID\r
 CoreAcquireGcdIoLock (\r
   VOID\r
@@ -136,7 +295,6 @@ CoreAcquireGcdIoLock (
   Release memory lock on mGcdIoSpaceLock.\r
 \r
 **/\r
-STATIC\r
 VOID\r
 CoreReleaseGcdIoLock (\r
   VOID\r
@@ -150,20 +308,18 @@ CoreReleaseGcdIoLock (
 //\r
 // GCD Initialization Worker Functions\r
 //\r
-\r
 /**\r
   Aligns a value to the specified boundary.\r
 \r
-  @param  Value                  64 bit value to align \r
-  @param  Alignment              Log base 2 of the boundary to align Value to \r
-  @param  RoundUp                TRUE if Value is to be rounded up to the nearest \r
-                                 aligned boundary.  FALSE is Value is to be \r
-                                 rounded down to the nearest aligned boundary. \r
+  @param  Value                  64 bit value to align\r
+  @param  Alignment              Log base 2 of the boundary to align Value to\r
+  @param  RoundUp                TRUE if Value is to be rounded up to the nearest\r
+                                 aligned boundary.  FALSE is Value is to be\r
+                                 rounded down to the nearest aligned boundary.\r
 \r
   @return A 64 bit value is the aligned to the value nearest Value with an alignment by Alignment.\r
 \r
 **/\r
-STATIC\r
 UINT64\r
 AlignValue (\r
   IN UINT64   Value,\r
@@ -184,12 +340,11 @@ AlignValue (
 /**\r
   Aligns address to the page boundary.\r
 \r
-  @param  Value                  64 bit address to align \r
+  @param  Value                  64 bit address to align\r
 \r
   @return A 64 bit value is the aligned to the value nearest Value with an alignment by Alignment.\r
 \r
 **/\r
-STATIC\r
 UINT64\r
 PageAlignAddress (\r
   IN UINT64 Value\r
@@ -202,12 +357,11 @@ PageAlignAddress (
 /**\r
   Aligns length to the page boundary.\r
 \r
-  @param  Value                  64 bit length to align \r
+  @param  Value                  64 bit length to align\r
 \r
   @return A 64 bit value is the aligned to the value nearest Value with an alignment by Alignment.\r
 \r
 **/\r
-STATIC\r
 UINT64\r
 PageAlignLength (\r
   IN UINT64 Value\r
@@ -223,26 +377,34 @@ PageAlignLength (
 /**\r
   Allocate pool for two entries.\r
 \r
-  @param  TopEntry               An entry of GCD map \r
-  @param  BottomEntry            An entry of GCD map \r
+  @param  TopEntry               An entry of GCD map\r
+  @param  BottomEntry            An entry of GCD map\r
 \r
-  @retval EFI_OUT_OF_RESOURCES   No enough buffer to be allocated. \r
+  @retval EFI_OUT_OF_RESOURCES   No enough buffer to be allocated.\r
   @retval EFI_SUCCESS            Both entries successfully allocated.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 CoreAllocateGcdMapEntry (\r
   IN OUT EFI_GCD_MAP_ENTRY  **TopEntry,\r
   IN OUT EFI_GCD_MAP_ENTRY  **BottomEntry\r
   )\r
 {\r
-  *TopEntry = CoreAllocateZeroBootServicesPool (sizeof (EFI_GCD_MAP_ENTRY));\r
+  //\r
+  // Set to mOnGuarding to TRUE before memory allocation. This will make sure\r
+  // that the entry memory is not "guarded" by HeapGuard. Otherwise it might\r
+  // cause problem when it's freed (if HeapGuard is enabled).\r
+  //\r
+  mOnGuarding = TRUE;\r
+  *TopEntry = AllocateZeroPool (sizeof (EFI_GCD_MAP_ENTRY));\r
+  mOnGuarding = FALSE;\r
   if (*TopEntry == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  *BottomEntry = CoreAllocateZeroBootServicesPool (sizeof (EFI_GCD_MAP_ENTRY));\r
+  mOnGuarding = TRUE;\r
+  *BottomEntry = AllocateZeroPool (sizeof (EFI_GCD_MAP_ENTRY));\r
+  mOnGuarding = FALSE;\r
   if (*BottomEntry == NULL) {\r
     CoreFreePool (*TopEntry);\r
     return EFI_OUT_OF_RESOURCES;\r
@@ -255,18 +417,17 @@ CoreAllocateGcdMapEntry (
 /**\r
   Internal function.  Inserts a new descriptor into a sorted list\r
 \r
-  @param  Link                   The linked list to insert the range BaseAddress \r
-                                 and Length into \r
-  @param  Entry                  A pointer to the entry that is inserted \r
-  @param  BaseAddress            The base address of the new range \r
-  @param  Length                 The length of the new range in bytes \r
-  @param  TopEntry               Top pad entry to insert if needed. \r
-  @param  BottomEntry            Bottom pad entry to insert if needed. \r
+  @param  Link                   The linked list to insert the range BaseAddress\r
+                                 and Length into\r
+  @param  Entry                  A pointer to the entry that is inserted\r
+  @param  BaseAddress            The base address of the new range\r
+  @param  Length                 The length of the new range in bytes\r
+  @param  TopEntry               Top pad entry to insert if needed.\r
+  @param  BottomEntry            Bottom pad entry to insert if needed.\r
 \r
   @retval EFI_SUCCESS            The new range was inserted into the linked list\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 CoreInsertGcdMapEntry (\r
   IN LIST_ENTRY           *Link,\r
@@ -278,17 +439,19 @@ CoreInsertGcdMapEntry (
   )\r
 {\r
   ASSERT (Length != 0);\r
-  ASSERT (TopEntry->Signature == 0);\r
-  ASSERT (BottomEntry->Signature == 0);\r
 \r
   if (BaseAddress > Entry->BaseAddress) {\r
+    ASSERT (BottomEntry->Signature == 0);\r
+\r
     CopyMem (BottomEntry, Entry, sizeof (EFI_GCD_MAP_ENTRY));\r
     Entry->BaseAddress      = BaseAddress;\r
     BottomEntry->EndAddress = BaseAddress - 1;\r
     InsertTailList (Link, &BottomEntry->Link);\r
-  } \r
+  }\r
 \r
   if ((BaseAddress + Length - 1) < Entry->EndAddress) {\r
+    ASSERT (TopEntry->Signature == 0);\r
+\r
     CopyMem (TopEntry, Entry, sizeof (EFI_GCD_MAP_ENTRY));\r
     TopEntry->BaseAddress = BaseAddress + Length;\r
     Entry->EndAddress     = BaseAddress + Length - 1;\r
@@ -300,18 +463,17 @@ CoreInsertGcdMapEntry (
 \r
 \r
 /**\r
-  Merge the Gcd region specified by Link and its adjacent entry\r
+  Merge the Gcd region specified by Link and its adjacent entry.\r
 \r
-  @param  Link                   Specify the entry to be merged (with its \r
-                                 adjacent entry). \r
-  @param  Forward                Direction (forward or backward). \r
-  @param  Map                    Boundary. \r
+  @param  Link                   Specify the entry to be merged (with its\r
+                                 adjacent entry).\r
+  @param  Forward                Direction (forward or backward).\r
+  @param  Map                    Boundary.\r
 \r
-  @retval EFI_SUCCESS            Successfully returned. \r
+  @retval EFI_SUCCESS            Successfully returned.\r
   @retval EFI_UNSUPPORTED        These adjacent regions could not merge.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 CoreMergeGcdMapEntry (\r
   IN LIST_ENTRY      *Link,\r
@@ -376,16 +538,15 @@ CoreMergeGcdMapEntry (
 /**\r
   Merge adjacent entries on total chain.\r
 \r
-  @param  TopEntry               Top entry of GCD map. \r
-  @param  BottomEntry            Bottom entry of GCD map. \r
-  @param  StartLink              Start link of the list for this loop. \r
-  @param  EndLink                End link of the list for this loop. \r
-  @param  Map                    Boundary. \r
+  @param  TopEntry               Top entry of GCD map.\r
+  @param  BottomEntry            Bottom entry of GCD map.\r
+  @param  StartLink              Start link of the list for this loop.\r
+  @param  EndLink                End link of the list for this loop.\r
+  @param  Map                    Boundary.\r
 \r
   @retval EFI_SUCCESS            GCD map successfully cleaned up.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 CoreCleanupGcdMapEntry (\r
   IN EFI_GCD_MAP_ENTRY  *TopEntry,\r
@@ -418,19 +579,18 @@ CoreCleanupGcdMapEntry (
 /**\r
   Search a segment of memory space in GCD map. The result is a range of GCD entry list.\r
 \r
-  @param  BaseAddress            The start address of the segment. \r
-  @param  Length                 The length of the segment. \r
-  @param  StartLink              The first GCD entry involves this segment of \r
-                                 memory space. \r
-  @param  EndLink                The first GCD entry involves this segment of \r
-                                 memory space. \r
-  @param  Map                    Points to the start entry to search. \r
+  @param  BaseAddress            The start address of the segment.\r
+  @param  Length                 The length of the segment.\r
+  @param  StartLink              The first GCD entry involves this segment of\r
+                                 memory space.\r
+  @param  EndLink                The first GCD entry involves this segment of\r
+                                 memory space.\r
+  @param  Map                    Points to the start entry to search.\r
 \r
-  @retval EFI_SUCCESS            Successfully found the entry. \r
+  @retval EFI_SUCCESS            Successfully found the entry.\r
   @retval EFI_NOT_FOUND          Not found.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 CoreSearchGcdMapEntry (\r
   IN  EFI_PHYSICAL_ADDRESS  BaseAddress,\r
@@ -455,7 +615,7 @@ CoreSearchGcdMapEntry (
       *StartLink = Link;\r
     }\r
     if (*StartLink != NULL) {\r
-      if ((BaseAddress + Length - 1) >= Entry->BaseAddress && \r
+      if ((BaseAddress + Length - 1) >= Entry->BaseAddress &&\r
           (BaseAddress + Length - 1) <= Entry->EndAddress     ) {\r
         *EndLink = Link;\r
         return EFI_SUCCESS;\r
@@ -463,6 +623,7 @@ CoreSearchGcdMapEntry (
     }\r
     Link = Link->ForwardLink;\r
   }\r
+\r
   return EFI_NOT_FOUND;\r
 }\r
 \r
@@ -470,12 +631,11 @@ CoreSearchGcdMapEntry (
 /**\r
   Count the amount of GCD map entries.\r
 \r
-  @param  Map                    Points to the start entry to do the count loop. \r
+  @param  Map                    Points to the start entry to do the count loop.\r
 \r
   @return The count.\r
 \r
 **/\r
-STATIC\r
 UINTN\r
 CoreCountGcdMapEntry (\r
   IN LIST_ENTRY  *Map\r
@@ -490,6 +650,7 @@ CoreCountGcdMapEntry (
     Count++;\r
     Link = Link->ForwardLink;\r
   }\r
+\r
   return Count;\r
 }\r
 \r
@@ -498,66 +659,62 @@ CoreCountGcdMapEntry (
 /**\r
   Return the memory attribute specified by Attributes\r
 \r
-  @param  Attributes             A num with some attribute bits on. \r
+  @param  Attributes             A num with some attribute bits on.\r
 \r
   @return The enum value of memory attribute.\r
 \r
 **/\r
-STATIC\r
 UINT64\r
 ConverToCpuArchAttributes (\r
   UINT64 Attributes\r
-  ) \r
+  )\r
 {\r
-  if ( (Attributes & EFI_MEMORY_UC) == EFI_MEMORY_UC) {\r
-    return EFI_MEMORY_UC;\r
-  }\r
-\r
-  if ( (Attributes & EFI_MEMORY_WC ) == EFI_MEMORY_WC) {\r
-    return EFI_MEMORY_WC;\r
-  }\r
+  UINT64      CpuArchAttributes;\r
 \r
-  if ( (Attributes & EFI_MEMORY_WT ) == EFI_MEMORY_WT) {\r
-    return EFI_MEMORY_WT;\r
-  }\r
-\r
-  if ( (Attributes & EFI_MEMORY_WB) == EFI_MEMORY_WB) {\r
-    return EFI_MEMORY_WB;\r
-  }\r
-\r
-  if ( (Attributes & EFI_MEMORY_WP) == EFI_MEMORY_WP) {\r
-    return EFI_MEMORY_WP;\r
-  }\r
-\r
-  return INVALID_CPU_ARCH_ATTRIBUTES;\r
+  CpuArchAttributes = Attributes & NONEXCLUSIVE_MEMORY_ATTRIBUTES;\r
 \r
+  if ( (Attributes & EFI_MEMORY_UC) == EFI_MEMORY_UC) {\r
+    CpuArchAttributes |= EFI_MEMORY_UC;\r
+  } else if ( (Attributes & EFI_MEMORY_WC ) == EFI_MEMORY_WC) {\r
+    CpuArchAttributes |= EFI_MEMORY_WC;\r
+  } else if ( (Attributes & EFI_MEMORY_WT ) == EFI_MEMORY_WT) {\r
+    CpuArchAttributes |= EFI_MEMORY_WT;\r
+  } else if ( (Attributes & EFI_MEMORY_WB) == EFI_MEMORY_WB) {\r
+    CpuArchAttributes |= EFI_MEMORY_WB;\r
+  } else if ( (Attributes & EFI_MEMORY_UCE) == EFI_MEMORY_UCE) {\r
+    CpuArchAttributes |= EFI_MEMORY_UCE;\r
+  } else if ( (Attributes & EFI_MEMORY_WP) == EFI_MEMORY_WP) {\r
+    CpuArchAttributes |= EFI_MEMORY_WP;\r
+  }\r
+\r
+  return CpuArchAttributes;\r
 }\r
 \r
 \r
 /**\r
   Do operation on a segment of memory space specified (add, free, remove, change attribute ...).\r
 \r
-  @param  Operation              The type of the operation \r
-  @param  GcdMemoryType          Additional information for the operation \r
-  @param  GcdIoType              Additional information for the operation \r
-  @param  BaseAddress            Start address of the segment \r
-  @param  Length                 length of the segment \r
-  @param  Capabilities           The alterable attributes of a newly added entry \r
-  @param  Attributes             The attributes needs to be set \r
-\r
-  @retval EFI_INVALID_PARAMETER  Length is 0 or address (length) not aligned when \r
-                                 setting attribute. \r
-  @retval EFI_SUCCESS            Action successfully done. \r
-  @retval EFI_UNSUPPORTED        Could not find the proper descriptor on this \r
-                                 segment or  set an upsupported attribute. \r
-  @retval EFI_ACCESS_DENIED      Operate on an space non-exist or is used for an \r
-                                 image. \r
-  @retval EFI_NOT_FOUND          Free a non-using space or remove a non-exist \r
-                                 space, and so on. \r
+  @param  Operation              The type of the operation\r
+  @param  GcdMemoryType          Additional information for the operation\r
+  @param  GcdIoType              Additional information for the operation\r
+  @param  BaseAddress            Start address of the segment\r
+  @param  Length                 length of the segment\r
+  @param  Capabilities           The alterable attributes of a newly added entry\r
+  @param  Attributes             The attributes needs to be set\r
+\r
+  @retval EFI_INVALID_PARAMETER  Length is 0 or address (length) not aligned when\r
+                                 setting attribute.\r
+  @retval EFI_SUCCESS            Action successfully done.\r
+  @retval EFI_UNSUPPORTED        Could not find the proper descriptor on this\r
+                                 segment or  set an upsupported attribute.\r
+  @retval EFI_ACCESS_DENIED      Operate on an space non-exist or is used for an\r
+                                 image.\r
+  @retval EFI_NOT_FOUND          Free a non-using space or remove a non-exist\r
+                                 space, and so on.\r
   @retval EFI_OUT_OF_RESOURCES   No buffer could be allocated.\r
-\r
+  @retval EFI_NOT_AVAILABLE_YET  The attributes cannot be set because CPU architectural protocol\r
+                                 is not available yet.\r
 **/\r
-STATIC\r
 EFI_STATUS\r
 CoreConvertSpace (\r
   IN UINTN                 Operation,\r
@@ -577,11 +734,10 @@ CoreConvertSpace (
   EFI_GCD_MAP_ENTRY  *BottomEntry;\r
   LIST_ENTRY         *StartLink;\r
   LIST_ENTRY         *EndLink;\r
-  \r
-  EFI_CPU_ARCH_PROTOCOL           *CpuArch;\r
-  UINT64                          CpuArchAttributes;\r
+  UINT64             CpuArchAttributes;\r
 \r
   if (Length == 0) {\r
+    DEBUG ((DEBUG_GCD, "  Status = %r\n", EFI_INVALID_PARAMETER));\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -589,10 +745,11 @@ CoreConvertSpace (
   if ((Operation & GCD_MEMORY_SPACE_OPERATION) != 0) {\r
     CoreAcquireGcdMemoryLock ();\r
     Map = &mGcdMemorySpaceMap;\r
-  }\r
-  if ((Operation & GCD_IO_SPACE_OPERATION) != 0) {\r
+  } else if ((Operation & GCD_IO_SPACE_OPERATION) != 0) {\r
     CoreAcquireGcdIoLock ();\r
     Map = &mGcdIoSpaceMap;\r
+  } else {\r
+    ASSERT (FALSE);\r
   }\r
 \r
   //\r
@@ -604,6 +761,7 @@ CoreConvertSpace (
 \r
     goto Done;\r
   }\r
+  ASSERT (StartLink != NULL && EndLink != NULL);\r
 \r
   //\r
   // Verify that the list of descriptors are unallocated non-existent memory.\r
@@ -663,13 +821,12 @@ CoreConvertSpace (
       }\r
       break;\r
     //\r
-    // Set attribute operations\r
+    // Set attributes operation\r
     //\r
     case GCD_SET_ATTRIBUTES_MEMORY_OPERATION:\r
       if ((Attributes & EFI_MEMORY_RUNTIME) != 0) {\r
         if ((BaseAddress & EFI_PAGE_MASK) != 0 || (Length & EFI_PAGE_MASK) != 0) {\r
           Status = EFI_INVALID_PARAMETER;\r
-\r
           goto Done;\r
         }\r
       }\r
@@ -678,6 +835,23 @@ CoreConvertSpace (
         goto Done;\r
       }\r
       break;\r
+    //\r
+    // Set capabilities operation\r
+    //\r
+    case GCD_SET_CAPABILITIES_MEMORY_OPERATION:\r
+      if ((BaseAddress & EFI_PAGE_MASK) != 0 || (Length & EFI_PAGE_MASK) != 0) {\r
+        Status = EFI_INVALID_PARAMETER;\r
+\r
+        goto Done;\r
+      }\r
+      //\r
+      // Current attributes must still be supported with new capabilities\r
+      //\r
+      if ((Capabilities & Entry->Attributes) != Entry->Attributes) {\r
+        Status = EFI_UNSUPPORTED;\r
+        goto Done;\r
+      }\r
+      break;\r
     }\r
     Link = Link->ForwardLink;\r
   }\r
@@ -690,33 +864,48 @@ CoreConvertSpace (
     Status = EFI_OUT_OF_RESOURCES;\r
     goto Done;\r
   }\r
+  ASSERT (TopEntry != NULL && BottomEntry != NULL);\r
 \r
   //\r
+  // Initialize CpuArchAttributes to suppress incorrect compiler/analyzer warnings.\r
   //\r
-  //\r
+  CpuArchAttributes = 0;\r
   if (Operation == GCD_SET_ATTRIBUTES_MEMORY_OPERATION) {\r
     //\r
     // Call CPU Arch Protocol to attempt to set attributes on the range\r
     //\r
     CpuArchAttributes = ConverToCpuArchAttributes (Attributes);\r
-    if ( CpuArchAttributes != INVALID_CPU_ARCH_ATTRIBUTES ) {\r
-      Status = CoreLocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&CpuArch);\r
-      if (EFI_ERROR (Status)) {\r
-        Status = EFI_ACCESS_DENIED;\r
-        goto Done;\r
+    //\r
+    // CPU arch attributes include page attributes and cache attributes. \r
+    // Only page attributes supports to be cleared, but not cache attributes.\r
+    // Caller is expected to use GetMemorySpaceDescriptor() to get the current\r
+    // attributes, AND/OR attributes, and then calls SetMemorySpaceAttributes()\r
+    // to set the new attributes.\r
+    // So 0 CPU arch attributes should not happen as memory should always have\r
+    // a cache attribute (no matter UC or WB, etc). \r
+    //\r
+    // Here, 0 CPU arch attributes will be filtered to be compatible with the\r
+    // case that caller just calls SetMemorySpaceAttributes() with none CPU\r
+    // arch attributes (for example, RUNTIME) as the purpose of the case is not\r
+    // to clear CPU arch attributes.\r
+    //\r
+    if (CpuArchAttributes != 0) {\r
+      if (gCpu == NULL) {\r
+        Status = EFI_NOT_AVAILABLE_YET;\r
+      } else {\r
+        Status = gCpu->SetMemoryAttributes (\r
+                         gCpu,\r
+                         BaseAddress,\r
+                         Length,\r
+                         CpuArchAttributes\r
+                         );\r
       }\r
-\r
-      Status = CpuArch->SetMemoryAttributes (\r
-                          CpuArch,\r
-                          BaseAddress,\r
-                          Length,\r
-                          CpuArchAttributes\r
-                          );\r
       if (EFI_ERROR (Status)) {\r
+        CoreFreePool (TopEntry);\r
+        CoreFreePool (BottomEntry);\r
         goto Done;\r
       }\r
     }\r
-\r
   }\r
 \r
   //\r
@@ -760,11 +949,24 @@ CoreConvertSpace (
       Entry->GcdIoType = EfiGcdIoTypeNonExistent;\r
       break;\r
     //\r
-    // Set attribute operations\r
+    // Set attributes operation\r
     //\r
     case GCD_SET_ATTRIBUTES_MEMORY_OPERATION:\r
+      if (CpuArchAttributes == 0) {\r
+        //\r
+        // Keep original CPU arch attributes when caller just calls\r
+        // SetMemorySpaceAttributes() with none CPU arch attributes (for example, RUNTIME).\r
+        //\r
+        Attributes |= (Entry->Attributes & (EXCLUSIVE_MEMORY_ATTRIBUTES | NONEXCLUSIVE_MEMORY_ATTRIBUTES));\r
+      }\r
       Entry->Attributes = Attributes;\r
       break;\r
+    //\r
+    // Set capabilities operation\r
+    //\r
+    case GCD_SET_CAPABILITIES_MEMORY_OPERATION:\r
+      Entry->Capabilities = Capabilities;\r
+      break;\r
     }\r
     Link = Link->ForwardLink;\r
   }\r
@@ -775,11 +977,15 @@ CoreConvertSpace (
   Status = CoreCleanupGcdMapEntry (TopEntry, BottomEntry, StartLink, EndLink, Map);\r
 \r
 Done:\r
+  DEBUG ((DEBUG_GCD, "  Status = %r\n", Status));\r
+\r
   if ((Operation & GCD_MEMORY_SPACE_OPERATION) != 0) {\r
     CoreReleaseGcdMemoryLock ();\r
+    CoreDumpGcdMemorySpaceMap (FALSE);\r
   }\r
   if ((Operation & GCD_IO_SPACE_OPERATION) != 0) {\r
     CoreReleaseGcdIoLock ();\r
+    CoreDumpGcdIoSpaceMap (FALSE);\r
   }\r
 \r
   return Status;\r
@@ -789,19 +995,18 @@ Done:
 /**\r
   Check whether an entry could be used to allocate space.\r
 \r
-  @param  Operation              Allocate memory or IO \r
-  @param  Entry                  The entry to be tested \r
-  @param  GcdMemoryType          The desired memory type \r
-  @param  GcdIoType              The desired IO type \r
+  @param  Operation              Allocate memory or IO\r
+  @param  Entry                  The entry to be tested\r
+  @param  GcdMemoryType          The desired memory type\r
+  @param  GcdIoType              The desired IO type\r
 \r
-  @retval EFI_NOT_FOUND          The memory type does not match or there's an \r
-                                 image handle on the entry. \r
-  @retval EFI_UNSUPPORTED        The operation unsupported. \r
-  @retval EFI_SUCCESS            It's ok for this entry to be used to allocate \r
+  @retval EFI_NOT_FOUND          The memory type does not match or there's an\r
+                                 image handle on the entry.\r
+  @retval EFI_UNSUPPORTED        The operation unsupported.\r
+  @retval EFI_SUCCESS            It's ok for this entry to be used to allocate\r
                                  space.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 CoreAllocateSpaceCheckEntry (\r
   IN UINTN                Operation,\r
@@ -834,22 +1039,21 @@ CoreAllocateSpaceCheckEntry (
 /**\r
   Allocate space on specified address and length.\r
 \r
-  @param  Operation              The type of operation (memory or IO) \r
-  @param  GcdAllocateType        The type of allocate operation \r
-  @param  GcdMemoryType          The desired memory type \r
-  @param  GcdIoType              The desired IO type \r
-  @param  Alignment              Align with 2^Alignment \r
-  @param  Length                 Length to allocate \r
-  @param  BaseAddress            Base address to allocate \r
-  @param  ImageHandle            The image handle consume the allocated space. \r
-  @param  DeviceHandle           The device handle consume the allocated space. \r
-\r
-  @retval EFI_INVALID_PARAMETER  Invalid parameter. \r
-  @retval EFI_NOT_FOUND          No descriptor for the desired space exists. \r
+  @param  Operation              The type of operation (memory or IO)\r
+  @param  GcdAllocateType        The type of allocate operation\r
+  @param  GcdMemoryType          The desired memory type\r
+  @param  GcdIoType              The desired IO type\r
+  @param  Alignment              Align with 2^Alignment\r
+  @param  Length                 Length to allocate\r
+  @param  BaseAddress            Base address to allocate\r
+  @param  ImageHandle            The image handle consume the allocated space.\r
+  @param  DeviceHandle           The device handle consume the allocated space.\r
+\r
+  @retval EFI_INVALID_PARAMETER  Invalid parameter.\r
+  @retval EFI_NOT_FOUND          No descriptor for the desired space exists.\r
   @retval EFI_SUCCESS            Space successfully allocated.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 CoreAllocateSpace (\r
   IN     UINTN                  Operation,\r
@@ -879,25 +1083,32 @@ CoreAllocateSpace (
   //\r
   // Make sure parameters are valid\r
   //\r
-  if (GcdAllocateType < 0 || GcdAllocateType >= EfiGcdMaxAllocateType) {\r
+  if ((UINT32)GcdAllocateType >= EfiGcdMaxAllocateType) {\r
+    DEBUG ((DEBUG_GCD, "  Status = %r\n", EFI_INVALID_PARAMETER));\r
     return EFI_INVALID_PARAMETER;\r
   }\r
-  if (GcdMemoryType < 0 || GcdMemoryType >= EfiGcdMemoryTypeMaximum) {\r
+  if ((UINT32)GcdMemoryType >= EfiGcdMemoryTypeMaximum) {\r
+    DEBUG ((DEBUG_GCD, "  Status = %r\n", EFI_INVALID_PARAMETER));\r
     return EFI_INVALID_PARAMETER;\r
   }\r
-  if (GcdIoType < 0 || GcdIoType >= EfiGcdIoTypeMaximum) {\r
+  if ((UINT32)GcdIoType >= EfiGcdIoTypeMaximum) {\r
+    DEBUG ((DEBUG_GCD, "  Status = %r\n", EFI_INVALID_PARAMETER));\r
     return EFI_INVALID_PARAMETER;\r
   }\r
   if (BaseAddress == NULL) {\r
+    DEBUG ((DEBUG_GCD, "  Status = %r\n", EFI_INVALID_PARAMETER));\r
     return EFI_INVALID_PARAMETER;\r
   }\r
   if (ImageHandle == NULL) {\r
+    DEBUG ((DEBUG_GCD, "  Status = %r\n", EFI_INVALID_PARAMETER));\r
     return EFI_INVALID_PARAMETER;\r
   }\r
   if (Alignment >= 64) {\r
+    DEBUG ((DEBUG_GCD, "  Status = %r\n", EFI_NOT_FOUND));\r
     return EFI_NOT_FOUND;\r
   }\r
   if (Length == 0) {\r
+    DEBUG ((DEBUG_GCD, "  Status = %r\n", EFI_INVALID_PARAMETER));\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -905,10 +1116,11 @@ CoreAllocateSpace (
   if ((Operation & GCD_MEMORY_SPACE_OPERATION) != 0) {\r
     CoreAcquireGcdMemoryLock ();\r
     Map = &mGcdMemorySpaceMap;\r
-  }\r
-  if ((Operation & GCD_IO_SPACE_OPERATION) != 0) {\r
+  } else if ((Operation & GCD_IO_SPACE_OPERATION) != 0) {\r
     CoreAcquireGcdIoLock ();\r
     Map = &mGcdIoSpaceMap;\r
+  } else {\r
+    ASSERT (FALSE);\r
   }\r
 \r
   Found     = FALSE;\r
@@ -936,6 +1148,7 @@ CoreAllocateSpace (
       Status = EFI_NOT_FOUND;\r
       goto Done;\r
     }\r
+    ASSERT (StartLink != NULL && EndLink != NULL);\r
 \r
     //\r
     // Verify that the list of descriptors are unallocated memory matching GcdMemoryType.\r
@@ -989,7 +1202,7 @@ CoreAllocateSpace (
       }\r
 \r
       if (GcdAllocateType == EfiGcdAllocateMaxAddressSearchTopDown ||\r
-          GcdAllocateType == EfiGcdAllocateAnySearchTopDown           ) {\r
+          GcdAllocateType == EfiGcdAllocateAnySearchTopDown) {\r
         if ((Entry->BaseAddress + Length) > MaxAddress) {\r
           continue;\r
         }\r
@@ -1019,6 +1232,7 @@ CoreAllocateSpace (
         Status = EFI_NOT_FOUND;\r
         goto Done;\r
       }\r
+      ASSERT (StartLink != NULL && EndLink != NULL);\r
 \r
       Link = StartLink;\r
       //\r
@@ -1054,6 +1268,7 @@ CoreAllocateSpace (
     Status = EFI_OUT_OF_RESOURCES;\r
     goto Done;\r
   }\r
+  ASSERT (TopEntry != NULL && BottomEntry != NULL);\r
 \r
   //\r
   // Convert/Insert the list of descriptors from StartLink to EndLink\r
@@ -1073,11 +1288,19 @@ CoreAllocateSpace (
   Status = CoreCleanupGcdMapEntry (TopEntry, BottomEntry, StartLink, EndLink, Map);\r
 \r
 Done:\r
+  DEBUG ((DEBUG_GCD, "  Status = %r", Status));\r
+  if (!EFI_ERROR (Status)) {\r
+    DEBUG ((DEBUG_GCD, "  (BaseAddress = %016lx)", *BaseAddress));\r
+  }\r
+  DEBUG ((DEBUG_GCD, "\n"));\r
+  \r
   if ((Operation & GCD_MEMORY_SPACE_OPERATION) != 0) {\r
     CoreReleaseGcdMemoryLock ();\r
+    CoreDumpGcdMemorySpaceMap (FALSE);\r
   }\r
   if ((Operation & GCD_IO_SPACE_OPERATION) !=0) {\r
     CoreReleaseGcdIoLock ();\r
+    CoreDumpGcdIoSpaceMap (FALSE);\r
   }\r
 \r
   return Status;\r
@@ -1087,16 +1310,15 @@ Done:
 /**\r
   Add a segment of memory to GCD map.\r
 \r
-  @param  GcdMemoryType          Memory type of the segment. \r
-  @param  BaseAddress            Base address of the segment. \r
-  @param  Length                 Length of the segment. \r
-  @param  Capabilities           alterable attributes of the segment. \r
+  @param  GcdMemoryType          Memory type of the segment.\r
+  @param  BaseAddress            Base address of the segment.\r
+  @param  Length                 Length of the segment.\r
+  @param  Capabilities           alterable attributes of the segment.\r
 \r
-  @retval EFI_INVALID_PARAMETER  Invalid parameters. \r
+  @retval EFI_INVALID_PARAMETER  Invalid parameters.\r
   @retval EFI_SUCCESS            Successfully add a segment of memory space.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 CoreInternalAddMemorySpace (\r
   IN EFI_GCD_MEMORY_TYPE   GcdMemoryType,\r
@@ -1105,6 +1327,10 @@ CoreInternalAddMemorySpace (
   IN UINT64                Capabilities\r
   )\r
 {\r
+  DEBUG ((DEBUG_GCD, "GCD:AddMemorySpace(Base=%016lx,Length=%016lx)\n", BaseAddress, Length));\r
+  DEBUG ((DEBUG_GCD, "  GcdMemoryType   = %a\n", mGcdMemoryTypeNames[MIN (GcdMemoryType, EfiGcdMemoryTypeMaximum)]));\r
+  DEBUG ((DEBUG_GCD, "  Capabilities    = %016lx\n", Capabilities));\r
+\r
   //\r
   // Make sure parameters are valid\r
   //\r
@@ -1123,20 +1349,21 @@ CoreInternalAddMemorySpace (
   Allocates nonexistent memory, reserved memory, system memory, or memorymapped\r
   I/O resources from the global coherency domain of the processor.\r
 \r
-  @param  GcdAllocateType        The type of allocate operation \r
-  @param  GcdMemoryType          The desired memory type \r
-  @param  Alignment              Align with 2^Alignment \r
-  @param  Length                 Length to allocate \r
-  @param  BaseAddress            Base address to allocate \r
-  @param  ImageHandle            The image handle consume the allocated space. \r
-  @param  DeviceHandle           The device handle consume the allocated space. \r
+  @param  GcdAllocateType        The type of allocate operation\r
+  @param  GcdMemoryType          The desired memory type\r
+  @param  Alignment              Align with 2^Alignment\r
+  @param  Length                 Length to allocate\r
+  @param  BaseAddress            Base address to allocate\r
+  @param  ImageHandle            The image handle consume the allocated space.\r
+  @param  DeviceHandle           The device handle consume the allocated space.\r
 \r
-  @retval EFI_INVALID_PARAMETER  Invalid parameter. \r
-  @retval EFI_NOT_FOUND          No descriptor contains the desired space. \r
+  @retval EFI_INVALID_PARAMETER  Invalid parameter.\r
+  @retval EFI_NOT_FOUND          No descriptor contains the desired space.\r
   @retval EFI_SUCCESS            Memory space successfully allocated.\r
 \r
 **/\r
 EFI_STATUS\r
+EFIAPI\r
 CoreAllocateMemorySpace (\r
   IN     EFI_GCD_ALLOCATE_TYPE  GcdAllocateType,\r
   IN     EFI_GCD_MEMORY_TYPE    GcdMemoryType,\r
@@ -1147,15 +1374,26 @@ CoreAllocateMemorySpace (
   IN     EFI_HANDLE             DeviceHandle OPTIONAL\r
   )\r
 {\r
+  if (BaseAddress != NULL) {\r
+    DEBUG ((DEBUG_GCD, "GCD:AllocateMemorySpace(Base=%016lx,Length=%016lx)\n", *BaseAddress, Length));\r
+  } else {\r
+    DEBUG ((DEBUG_GCD, "GCD:AllocateMemorySpace(Base=<NULL>,Length=%016lx)\n", Length));\r
+  }\r
+  DEBUG ((DEBUG_GCD, "  GcdAllocateType = %a\n", mGcdAllocationTypeNames[MIN (GcdAllocateType, EfiGcdMaxAllocateType)]));\r
+  DEBUG ((DEBUG_GCD, "  GcdMemoryType   = %a\n", mGcdMemoryTypeNames[MIN (GcdMemoryType, EfiGcdMemoryTypeMaximum)]));\r
+  DEBUG ((DEBUG_GCD, "  Alignment       = %016lx\n", LShiftU64 (1, Alignment)));\r
+  DEBUG ((DEBUG_GCD, "  ImageHandle     = %p\n", ImageHandle));\r
+  DEBUG ((DEBUG_GCD, "  DeviceHandle    = %p\n", DeviceHandle));\r
+  \r
   return CoreAllocateSpace (\r
-           GCD_ALLOCATE_MEMORY_OPERATION, \r
-           GcdAllocateType, \r
-           GcdMemoryType, \r
-           (EFI_GCD_IO_TYPE) 0, \r
-           Alignment, \r
-           Length, \r
-           BaseAddress, \r
-           ImageHandle, \r
+           GCD_ALLOCATE_MEMORY_OPERATION,\r
+           GcdAllocateType,\r
+           GcdMemoryType,\r
+           (EFI_GCD_IO_TYPE) 0,\r
+           Alignment,\r
+           Length,\r
+           BaseAddress,\r
+           ImageHandle,\r
            DeviceHandle\r
            );\r
 }\r
@@ -1165,15 +1403,16 @@ CoreAllocateMemorySpace (
   Adds reserved memory, system memory, or memory-mapped I/O resources to the\r
   global coherency domain of the processor.\r
 \r
-  @param  GcdMemoryType          Memory type of the memory space. \r
-  @param  BaseAddress            Base address of the memory space. \r
-  @param  Length                 Length of the memory space. \r
-  @param  Capabilities           alterable attributes of the memory space. \r
+  @param  GcdMemoryType          Memory type of the memory space.\r
+  @param  BaseAddress            Base address of the memory space.\r
+  @param  Length                 Length of the memory space.\r
+  @param  Capabilities           alterable attributes of the memory space.\r
 \r
   @retval EFI_SUCCESS            Merged this memory space into GCD map.\r
 \r
 **/\r
 EFI_STATUS\r
+EFIAPI\r
 CoreAddMemorySpace (\r
   IN EFI_GCD_MEMORY_TYPE   GcdMemoryType,\r
   IN EFI_PHYSICAL_ADDRESS  BaseAddress,\r
@@ -1187,15 +1426,15 @@ CoreAddMemorySpace (
 \r
   Status = CoreInternalAddMemorySpace (GcdMemoryType, BaseAddress, Length, Capabilities);\r
 \r
-  if (!EFI_ERROR (Status) && GcdMemoryType == EfiGcdMemoryTypeSystemMemory) {\r
+  if (!EFI_ERROR (Status) && ((GcdMemoryType == EfiGcdMemoryTypeSystemMemory) || (GcdMemoryType == EfiGcdMemoryTypeMoreReliable))) {\r
 \r
-    PageBaseAddress = PageAlignLength (BaseAddress);\r
+    PageBaseAddress = PageAlignAddress (BaseAddress);\r
     PageLength      = PageAlignLength (BaseAddress + Length - PageBaseAddress);\r
 \r
     Status = CoreAllocateMemorySpace (\r
                EfiGcdAllocateAddress,\r
                GcdMemoryType,\r
-               EFI_PAGE_SHIFT,         \r
+               EFI_PAGE_SHIFT,\r
                PageLength,\r
                &PageBaseAddress,\r
                gDxeCoreImageHandle,\r
@@ -1214,7 +1453,7 @@ CoreAddMemorySpace (
         Status = CoreAllocateMemorySpace (\r
                    EfiGcdAllocateAddress,\r
                    GcdMemoryType,\r
-                   EFI_PAGE_SHIFT,         \r
+                   EFI_PAGE_SHIFT,\r
                    EFI_PAGE_SIZE,\r
                    &PageBaseAddress,\r
                    gDxeCoreImageHandle,\r
@@ -1240,18 +1479,21 @@ CoreAddMemorySpace (
   Frees nonexistent memory, reserved memory, system memory, or memory-mapped\r
   I/O resources from the global coherency domain of the processor.\r
 \r
-  @param  BaseAddress            Base address of the memory space. \r
-  @param  Length                 Length of the memory space. \r
+  @param  BaseAddress            Base address of the memory space.\r
+  @param  Length                 Length of the memory space.\r
 \r
   @retval EFI_SUCCESS            Space successfully freed.\r
 \r
 **/\r
 EFI_STATUS\r
+EFIAPI\r
 CoreFreeMemorySpace (\r
   IN EFI_PHYSICAL_ADDRESS  BaseAddress,\r
   IN UINT64                Length\r
   )\r
 {\r
+  DEBUG ((DEBUG_GCD, "GCD:FreeMemorySpace(Base=%016lx,Length=%016lx)\n", BaseAddress, Length));\r
+\r
   return CoreConvertSpace (GCD_FREE_MEMORY_OPERATION, (EFI_GCD_MEMORY_TYPE) 0, (EFI_GCD_IO_TYPE) 0, BaseAddress, Length, 0, 0);\r
 }\r
 \r
@@ -1260,18 +1502,21 @@ CoreFreeMemorySpace (
   Removes reserved memory, system memory, or memory-mapped I/O resources from\r
   the global coherency domain of the processor.\r
 \r
-  @param  BaseAddress            Base address of the memory space. \r
-  @param  Length                 Length of the memory space. \r
+  @param  BaseAddress            Base address of the memory space.\r
+  @param  Length                 Length of the memory space.\r
 \r
   @retval EFI_SUCCESS            Successfully remove a segment of memory space.\r
 \r
 **/\r
 EFI_STATUS\r
+EFIAPI\r
 CoreRemoveMemorySpace (\r
   IN EFI_PHYSICAL_ADDRESS  BaseAddress,\r
   IN UINT64                Length\r
   )\r
 {\r
+  DEBUG ((DEBUG_GCD, "GCD:RemoveMemorySpace(Base=%016lx,Length=%016lx)\n", BaseAddress, Length));\r
+  \r
   return CoreConvertSpace (GCD_REMOVE_MEMORY_OPERATION, (EFI_GCD_MEMORY_TYPE) 0, (EFI_GCD_IO_TYPE) 0, BaseAddress, Length, 0, 0);\r
 }\r
 \r
@@ -1279,11 +1524,10 @@ CoreRemoveMemorySpace (
 /**\r
   Build a memory descriptor according to an entry.\r
 \r
-  @param  Descriptor             The descriptor to be built \r
+  @param  Descriptor             The descriptor to be built\r
   @param  Entry                  According to this entry\r
 \r
 **/\r
-STATIC\r
 VOID\r
 BuildMemoryDescriptor (\r
   IN OUT EFI_GCD_MEMORY_SPACE_DESCRIPTOR  *Descriptor,\r
@@ -1303,14 +1547,15 @@ BuildMemoryDescriptor (
 /**\r
   Retrieves the descriptor for a memory region containing a specified address.\r
 \r
-  @param  BaseAddress            Specified start address \r
-  @param  Descriptor             Specified length \r
+  @param  BaseAddress            Specified start address\r
+  @param  Descriptor             Specified length\r
 \r
-  @retval EFI_INVALID_PARAMETER  Invalid parameter \r
+  @retval EFI_INVALID_PARAMETER  Invalid parameter\r
   @retval EFI_SUCCESS            Successfully get memory space descriptor.\r
 \r
 **/\r
 EFI_STATUS\r
+EFIAPI\r
 CoreGetMemorySpaceDescriptor (\r
   IN  EFI_PHYSICAL_ADDRESS             BaseAddress,\r
   OUT EFI_GCD_MEMORY_SPACE_DESCRIPTOR  *Descriptor\r
@@ -1331,12 +1576,13 @@ CoreGetMemorySpaceDescriptor (
   CoreAcquireGcdMemoryLock ();\r
 \r
   //\r
-  // Search for the list of descriptors that contain BaseAddress \r
+  // Search for the list of descriptors that contain BaseAddress\r
   //\r
   Status = CoreSearchGcdMapEntry (BaseAddress, 1, &StartLink, &EndLink, &mGcdMemorySpaceMap);\r
   if (EFI_ERROR (Status)) {\r
     Status = EFI_NOT_FOUND;\r
   } else {\r
+    ASSERT (StartLink != NULL && EndLink != NULL);\r
     //\r
     // Copy the contents of the found descriptor into Descriptor\r
     //\r
@@ -1354,38 +1600,92 @@ CoreGetMemorySpaceDescriptor (
   Modifies the attributes for a memory region in the global coherency domain of the\r
   processor.\r
 \r
-  @param  BaseAddress            Specified start address \r
-  @param  Length                 Specified length \r
-  @param  Attributes             Specified attributes \r
-\r
-  @retval EFI_SUCCESS            Successfully set attribute of a segment of \r
-                                 memory space.\r
+  @param  BaseAddress            Specified start address\r
+  @param  Length                 Specified length\r
+  @param  Attributes             Specified attributes\r
+\r
+  @retval EFI_SUCCESS           The attributes were set for the memory region.\r
+  @retval EFI_INVALID_PARAMETER Length is zero. \r
+  @retval EFI_UNSUPPORTED       The processor does not support one or more bytes of the memory\r
+                                resource range specified by BaseAddress and Length.\r
+  @retval EFI_UNSUPPORTED       The bit mask of attributes is not support for the memory resource\r
+                                range specified by BaseAddress and Length.\r
+  @retval EFI_ACCESS_DEFINED    The attributes for the memory resource range specified by\r
+                                BaseAddress and Length cannot be modified.\r
+  @retval EFI_OUT_OF_RESOURCES  There are not enough system resources to modify the attributes of\r
+                                the memory resource range.\r
+  @retval EFI_NOT_AVAILABLE_YET The attributes cannot be set because CPU architectural protocol is\r
+                                not available yet.\r
 \r
 **/\r
 EFI_STATUS\r
+EFIAPI\r
 CoreSetMemorySpaceAttributes (\r
   IN EFI_PHYSICAL_ADDRESS  BaseAddress,\r
   IN UINT64                Length,\r
   IN UINT64                Attributes\r
   )\r
 {\r
+  DEBUG ((DEBUG_GCD, "GCD:SetMemorySpaceAttributes(Base=%016lx,Length=%016lx)\n", BaseAddress, Length));\r
+  DEBUG ((DEBUG_GCD, "  Attributes  = %016lx\n", Attributes));\r
+\r
   return CoreConvertSpace (GCD_SET_ATTRIBUTES_MEMORY_OPERATION, (EFI_GCD_MEMORY_TYPE) 0, (EFI_GCD_IO_TYPE) 0, BaseAddress, Length, 0, Attributes);\r
 }\r
 \r
 \r
+/**\r
+  Modifies the capabilities for a memory region in the global coherency domain of the\r
+  processor.\r
+\r
+  @param  BaseAddress      The physical address that is the start address of a memory region.\r
+  @param  Length           The size in bytes of the memory region.\r
+  @param  Capabilities     The bit mask of capabilities that the memory region supports.\r
+\r
+  @retval EFI_SUCCESS           The capabilities were set for the memory region.\r
+  @retval EFI_INVALID_PARAMETER Length is zero.\r
+  @retval EFI_UNSUPPORTED       The capabilities specified by Capabilities do not include the\r
+                                memory region attributes currently in use.\r
+  @retval EFI_ACCESS_DENIED     The capabilities for the memory resource range specified by\r
+                                BaseAddress and Length cannot be modified.\r
+  @retval EFI_OUT_OF_RESOURCES  There are not enough system resources to modify the capabilities\r
+                                of the memory resource range.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+CoreSetMemorySpaceCapabilities (\r
+  IN EFI_PHYSICAL_ADDRESS  BaseAddress,\r
+  IN UINT64                Length,\r
+  IN UINT64                Capabilities\r
+  )\r
+{\r
+  EFI_STATUS    Status;\r
+\r
+  DEBUG ((DEBUG_GCD, "GCD:CoreSetMemorySpaceCapabilities(Base=%016lx,Length=%016lx)\n", BaseAddress, Length));\r
+  DEBUG ((DEBUG_GCD, "  Capabilities  = %016lx\n", Capabilities));\r
+\r
+  Status = CoreConvertSpace (GCD_SET_CAPABILITIES_MEMORY_OPERATION, (EFI_GCD_MEMORY_TYPE) 0, (EFI_GCD_IO_TYPE) 0, BaseAddress, Length, Capabilities, 0);\r
+  if (!EFI_ERROR(Status)) {\r
+    CoreUpdateMemoryAttributes(BaseAddress, RShiftU64(Length, EFI_PAGE_SHIFT), Capabilities & (~EFI_MEMORY_RUNTIME));\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+\r
 /**\r
   Returns a map of the memory resources in the global coherency domain of the\r
   processor.\r
 \r
-  @param  NumberOfDescriptors    Number of descriptors. \r
-  @param  MemorySpaceMap         Descriptor array \r
+  @param  NumberOfDescriptors    Number of descriptors.\r
+  @param  MemorySpaceMap         Descriptor array\r
 \r
-  @retval EFI_INVALID_PARAMETER  Invalid parameter \r
-  @retval EFI_OUT_OF_RESOURCES   No enough buffer to allocate \r
+  @retval EFI_INVALID_PARAMETER  Invalid parameter\r
+  @retval EFI_OUT_OF_RESOURCES   No enough buffer to allocate\r
   @retval EFI_SUCCESS            Successfully get memory space map.\r
 \r
 **/\r
 EFI_STATUS\r
+EFIAPI\r
 CoreGetMemorySpaceMap (\r
   OUT UINTN                            *NumberOfDescriptors,\r
   OUT EFI_GCD_MEMORY_SPACE_DESCRIPTOR  **MemorySpaceMap\r
@@ -1416,7 +1716,7 @@ CoreGetMemorySpaceMap (
   //\r
   // Allocate the MemorySpaceMap\r
   //\r
-  *MemorySpaceMap = CoreAllocateBootServicesPool (*NumberOfDescriptors * sizeof (EFI_GCD_MEMORY_SPACE_DESCRIPTOR));\r
+  *MemorySpaceMap = AllocatePool (*NumberOfDescriptors * sizeof (EFI_GCD_MEMORY_SPACE_DESCRIPTOR));\r
   if (*MemorySpaceMap == NULL) {\r
     Status = EFI_OUT_OF_RESOURCES;\r
     goto Done;\r
@@ -1444,21 +1744,25 @@ Done:
 /**\r
   Adds reserved I/O or I/O resources to the global coherency domain of the processor.\r
 \r
-  @param  GcdIoType              IO type of the segment. \r
-  @param  BaseAddress            Base address of the segment. \r
-  @param  Length                 Length of the segment. \r
+  @param  GcdIoType              IO type of the segment.\r
+  @param  BaseAddress            Base address of the segment.\r
+  @param  Length                 Length of the segment.\r
 \r
-  @retval EFI_SUCCESS            Merged this segment into GCD map. \r
+  @retval EFI_SUCCESS            Merged this segment into GCD map.\r
   @retval EFI_INVALID_PARAMETER  Parameter not valid\r
 \r
 **/\r
 EFI_STATUS\r
+EFIAPI\r
 CoreAddIoSpace (\r
   IN EFI_GCD_IO_TYPE       GcdIoType,\r
   IN EFI_PHYSICAL_ADDRESS  BaseAddress,\r
   IN UINT64                Length\r
   )\r
 {\r
+  DEBUG ((DEBUG_GCD, "GCD:AddIoSpace(Base=%016lx,Length=%016lx)\n", BaseAddress, Length));\r
+  DEBUG ((DEBUG_GCD, "  GcdIoType    = %a\n", mGcdIoTypeNames[MIN (GcdIoType, EfiGcdIoTypeMaximum)]));\r
+  \r
   //\r
   // Make sure parameters are valid\r
   //\r
@@ -1473,20 +1777,21 @@ CoreAddIoSpace (
   Allocates nonexistent I/O, reserved I/O, or I/O resources from the global coherency\r
   domain of the processor.\r
 \r
-  @param  GcdAllocateType        The type of allocate operation \r
-  @param  GcdIoType              The desired IO type \r
-  @param  Alignment              Align with 2^Alignment \r
-  @param  Length                 Length to allocate \r
-  @param  BaseAddress            Base address to allocate \r
-  @param  ImageHandle            The image handle consume the allocated space. \r
-  @param  DeviceHandle           The device handle consume the allocated space. \r
+  @param  GcdAllocateType        The type of allocate operation\r
+  @param  GcdIoType              The desired IO type\r
+  @param  Alignment              Align with 2^Alignment\r
+  @param  Length                 Length to allocate\r
+  @param  BaseAddress            Base address to allocate\r
+  @param  ImageHandle            The image handle consume the allocated space.\r
+  @param  DeviceHandle           The device handle consume the allocated space.\r
 \r
-  @retval EFI_INVALID_PARAMETER  Invalid parameter. \r
-  @retval EFI_NOT_FOUND          No descriptor contains the desired space. \r
+  @retval EFI_INVALID_PARAMETER  Invalid parameter.\r
+  @retval EFI_NOT_FOUND          No descriptor contains the desired space.\r
   @retval EFI_SUCCESS            IO space successfully allocated.\r
 \r
 **/\r
 EFI_STATUS\r
+EFIAPI\r
 CoreAllocateIoSpace (\r
   IN     EFI_GCD_ALLOCATE_TYPE  GcdAllocateType,\r
   IN     EFI_GCD_IO_TYPE        GcdIoType,\r
@@ -1497,15 +1802,26 @@ CoreAllocateIoSpace (
   IN     EFI_HANDLE             DeviceHandle OPTIONAL\r
   )\r
 {\r
+  if (BaseAddress != NULL) {\r
+    DEBUG ((DEBUG_GCD, "GCD:AllocateIoSpace(Base=%016lx,Length=%016lx)\n", *BaseAddress, Length));\r
+  } else {\r
+    DEBUG ((DEBUG_GCD, "GCD:AllocateIoSpace(Base=<NULL>,Length=%016lx)\n", Length));\r
+  }\r
+  DEBUG ((DEBUG_GCD, "  GcdAllocateType = %a\n", mGcdAllocationTypeNames[MIN (GcdAllocateType, EfiGcdMaxAllocateType)]));\r
+  DEBUG ((DEBUG_GCD, "  GcdIoType       = %a\n", mGcdIoTypeNames[MIN (GcdIoType, EfiGcdIoTypeMaximum)]));\r
+  DEBUG ((DEBUG_GCD, "  Alignment       = %016lx\n", LShiftU64 (1, Alignment)));\r
+  DEBUG ((DEBUG_GCD, "  ImageHandle     = %p\n", ImageHandle));\r
+  DEBUG ((DEBUG_GCD, "  DeviceHandle    = %p\n", DeviceHandle));\r
+  \r
   return CoreAllocateSpace (\r
-           GCD_ALLOCATE_IO_OPERATION, \r
-           GcdAllocateType, \r
-           (EFI_GCD_MEMORY_TYPE) 0, \r
-           GcdIoType, \r
-           Alignment, \r
-           Length, \r
-           BaseAddress, \r
-           ImageHandle, \r
+           GCD_ALLOCATE_IO_OPERATION,\r
+           GcdAllocateType,\r
+           (EFI_GCD_MEMORY_TYPE) 0,\r
+           GcdIoType,\r
+           Alignment,\r
+           Length,\r
+           BaseAddress,\r
+           ImageHandle,\r
            DeviceHandle\r
            );\r
 }\r
@@ -1515,18 +1831,21 @@ CoreAllocateIoSpace (
   Frees nonexistent I/O, reserved I/O, or I/O resources from the global coherency\r
   domain of the processor.\r
 \r
-  @param  BaseAddress            Base address of the segment. \r
-  @param  Length                 Length of the segment. \r
+  @param  BaseAddress            Base address of the segment.\r
+  @param  Length                 Length of the segment.\r
 \r
   @retval EFI_SUCCESS            Space successfully freed.\r
 \r
 **/\r
 EFI_STATUS\r
+EFIAPI\r
 CoreFreeIoSpace (\r
   IN EFI_PHYSICAL_ADDRESS  BaseAddress,\r
   IN UINT64                Length\r
   )\r
 {\r
+  DEBUG ((DEBUG_GCD, "GCD:FreeIoSpace(Base=%016lx,Length=%016lx)\n", BaseAddress, Length));\r
+\r
   return CoreConvertSpace (GCD_FREE_IO_OPERATION, (EFI_GCD_MEMORY_TYPE) 0, (EFI_GCD_IO_TYPE) 0, BaseAddress, Length, 0, 0);\r
 }\r
 \r
@@ -1535,18 +1854,21 @@ CoreFreeIoSpace (
   Removes reserved I/O or I/O resources from the global coherency domain of the\r
   processor.\r
 \r
-  @param  BaseAddress            Base address of the segment. \r
-  @param  Length                 Length of the segment. \r
+  @param  BaseAddress            Base address of the segment.\r
+  @param  Length                 Length of the segment.\r
 \r
   @retval EFI_SUCCESS            Successfully removed a segment of IO space.\r
 \r
 **/\r
 EFI_STATUS\r
+EFIAPI\r
 CoreRemoveIoSpace (\r
   IN EFI_PHYSICAL_ADDRESS  BaseAddress,\r
   IN UINT64                Length\r
   )\r
 {\r
+  DEBUG ((DEBUG_GCD, "GCD:RemoveIoSpace(Base=%016lx,Length=%016lx)\n", BaseAddress, Length));\r
+  \r
   return CoreConvertSpace (GCD_REMOVE_IO_OPERATION, (EFI_GCD_MEMORY_TYPE) 0, (EFI_GCD_IO_TYPE) 0, BaseAddress, Length, 0, 0);\r
 }\r
 \r
@@ -1554,11 +1876,10 @@ CoreRemoveIoSpace (
 /**\r
   Build a IO descriptor according to an entry.\r
 \r
-  @param  Descriptor             The descriptor to be built \r
+  @param  Descriptor             The descriptor to be built\r
   @param  Entry                  According to this entry\r
 \r
 **/\r
-STATIC\r
 VOID\r
 BuildIoDescriptor (\r
   IN EFI_GCD_IO_SPACE_DESCRIPTOR  *Descriptor,\r
@@ -1576,14 +1897,15 @@ BuildIoDescriptor (
 /**\r
   Retrieves the descriptor for an I/O region containing a specified address.\r
 \r
-  @param  BaseAddress            Specified start address \r
-  @param  Descriptor             Specified length \r
+  @param  BaseAddress            Specified start address\r
+  @param  Descriptor             Specified length\r
 \r
-  @retval EFI_INVALID_PARAMETER  Descriptor is NULL. \r
+  @retval EFI_INVALID_PARAMETER  Descriptor is NULL.\r
   @retval EFI_SUCCESS            Successfully get the IO space descriptor.\r
 \r
 **/\r
 EFI_STATUS\r
+EFIAPI\r
 CoreGetIoSpaceDescriptor (\r
   IN  EFI_PHYSICAL_ADDRESS         BaseAddress,\r
   OUT EFI_GCD_IO_SPACE_DESCRIPTOR  *Descriptor\r
@@ -1604,12 +1926,13 @@ CoreGetIoSpaceDescriptor (
   CoreAcquireGcdIoLock ();\r
 \r
   //\r
-  // Search for the list of descriptors that contain BaseAddress \r
+  // Search for the list of descriptors that contain BaseAddress\r
   //\r
   Status = CoreSearchGcdMapEntry (BaseAddress, 1, &StartLink, &EndLink, &mGcdIoSpaceMap);\r
   if (EFI_ERROR (Status)) {\r
     Status = EFI_NOT_FOUND;\r
   } else {\r
+    ASSERT (StartLink != NULL && EndLink != NULL);\r
     //\r
     // Copy the contents of the found descriptor into Descriptor\r
     //\r
@@ -1626,15 +1949,16 @@ CoreGetIoSpaceDescriptor (
 /**\r
   Returns a map of the I/O resources in the global coherency domain of the processor.\r
 \r
-  @param  NumberOfDescriptors    Number of descriptors. \r
-  @param  IoSpaceMap             Descriptor array \r
+  @param  NumberOfDescriptors    Number of descriptors.\r
+  @param  IoSpaceMap             Descriptor array\r
 \r
-  @retval EFI_INVALID_PARAMETER  Invalid parameter \r
-  @retval EFI_OUT_OF_RESOURCES   No enough buffer to allocate \r
+  @retval EFI_INVALID_PARAMETER  Invalid parameter\r
+  @retval EFI_OUT_OF_RESOURCES   No enough buffer to allocate\r
   @retval EFI_SUCCESS            Successfully get IO space map.\r
 \r
 **/\r
 EFI_STATUS\r
+EFIAPI\r
 CoreGetIoSpaceMap (\r
   OUT UINTN                        *NumberOfDescriptors,\r
   OUT EFI_GCD_IO_SPACE_DESCRIPTOR  **IoSpaceMap\r
@@ -1665,7 +1989,7 @@ CoreGetIoSpaceMap (
   //\r
   // Allocate the IoSpaceMap\r
   //\r
-  *IoSpaceMap = CoreAllocateBootServicesPool (*NumberOfDescriptors * sizeof (EFI_GCD_IO_SPACE_DESCRIPTOR));\r
+  *IoSpaceMap = AllocatePool (*NumberOfDescriptors * sizeof (EFI_GCD_IO_SPACE_DESCRIPTOR));\r
   if (*IoSpaceMap == NULL) {\r
     Status = EFI_OUT_OF_RESOURCES;\r
     goto Done;\r
@@ -1687,21 +2011,20 @@ CoreGetIoSpaceMap (
 Done:\r
   CoreReleaseGcdIoLock ();\r
   return Status;\r
-}  \r
+}\r
 \r
 \r
 /**\r
   Converts a Resource Descriptor HOB attributes mask to an EFI Memory Descriptor\r
   capabilities mask\r
 \r
-  @param  GcdMemoryType          Type of resource in the GCD memory map. \r
-  @param  Attributes             The attribute mask in the Resource Descriptor \r
-                                 HOB. \r
+  @param  GcdMemoryType          Type of resource in the GCD memory map.\r
+  @param  Attributes             The attribute mask in the Resource Descriptor\r
+                                 HOB.\r
 \r
   @return The capabilities mask for an EFI Memory Descriptor.\r
 \r
 **/\r
-STATIC\r
 UINT64\r
 CoreConvertResourceDescriptorHobAttributesToCapabilities (\r
   EFI_GCD_MEMORY_TYPE  GcdMemoryType,\r
@@ -1710,34 +2033,57 @@ CoreConvertResourceDescriptorHobAttributesToCapabilities (
 {\r
   UINT64                          Capabilities;\r
   GCD_ATTRIBUTE_CONVERSION_ENTRY  *Conversion;\r
-  \r
+\r
   //\r
   // Convert the Resource HOB Attributes to an EFI Memory Capabilities mask\r
   //\r
   for (Capabilities = 0, Conversion = mAttributeConversionTable; Conversion->Attribute != 0; Conversion++) {\r
-    if (Conversion->Memory || (GcdMemoryType != EfiGcdMemoryTypeSystemMemory)) {\r
+    if (Conversion->Memory || ((GcdMemoryType != EfiGcdMemoryTypeSystemMemory) && (GcdMemoryType != EfiGcdMemoryTypeMoreReliable))) {\r
       if (Attributes & Conversion->Attribute) {\r
         Capabilities |= Conversion->Capability;\r
       }\r
     }\r
   }\r
-  \r
+\r
   return Capabilities;\r
 }\r
 \r
+/**\r
+  Calculate total memory bin size neeeded.\r
+\r
+  @return The total memory bin size neeeded.\r
+\r
+**/\r
+UINT64\r
+CalculateTotalMemoryBinSizeNeeded (\r
+  VOID\r
+  )\r
+{\r
+  UINTN     Index;\r
+  UINT64    TotalSize;\r
+\r
+  //\r
+  // Loop through each memory type in the order specified by the gMemoryTypeInformation[] array\r
+  //\r
+  TotalSize = 0;\r
+  for (Index = 0; gMemoryTypeInformation[Index].Type != EfiMaxMemoryType; Index++) {\r
+    TotalSize += LShiftU64 (gMemoryTypeInformation[Index].NumberOfPages, EFI_PAGE_SHIFT);\r
+  }\r
+\r
+  return TotalSize;\r
+}\r
 \r
 /**\r
-  External function. Initializes the GCD and memory services based on the memory\r
-  descriptor HOBs.  This function is responsible for priming the GCD map and the\r
-  memory map, so memory allocations and resource allocations can be made.  The first\r
-  part of this function can not depend on any memory services until at least one\r
-  memory descriptor is provided to the memory services.  Then the memory services\r
-  can be used to intialize the GCD map.\r
+  External function. Initializes memory services based on the memory\r
+  descriptor HOBs.  This function is responsible for priming the memory\r
+  map, so memory allocations and resource allocations can be made.\r
+  The first part of this function can not depend on any memory services\r
+  until at least one memory descriptor is provided to the memory services.\r
 \r
-  @param  HobStart               The start address of the HOB. \r
-  @param  MemoryBaseAddress      Start address of memory region found to init DXE \r
-                                 core. \r
-  @param  MemoryLength           Length of memory region found to init DXE core. \r
+  @param  HobStart               The start address of the HOB.\r
+  @param  MemoryBaseAddress      Start address of memory region found to init DXE\r
+                                 core.\r
+  @param  MemoryLength           Length of memory region found to init DXE core.\r
 \r
   @retval EFI_SUCCESS            Memory services successfully initialized.\r
 \r
@@ -1760,13 +2106,12 @@ CoreInitializeMemoryServices (
   UINT64                             Length;\r
   UINT64                             Attributes;\r
   UINT64                             Capabilities;\r
-  EFI_PHYSICAL_ADDRESS               MaxMemoryBaseAddress;\r
-  UINT64                             MaxMemoryLength;\r
-  UINT64                             MaxMemoryAttributes;\r
-  EFI_PHYSICAL_ADDRESS               MaxAddress;\r
+  EFI_PHYSICAL_ADDRESS               TestedMemoryBaseAddress;\r
+  UINT64                             TestedMemoryLength;\r
   EFI_PHYSICAL_ADDRESS               HighAddress;\r
-  EFI_HOB_RESOURCE_DESCRIPTOR        *MaxResourceHob;\r
   EFI_HOB_GUID_TYPE                  *GuidHob;\r
+  UINT32                             ReservedCodePageNumber;\r
+  UINT64                             MinimalMemorySizeNeeded;\r
 \r
   //\r
   // Point at the first HOB.  This must be the PHIT HOB.\r
@@ -1784,20 +2129,26 @@ CoreInitializeMemoryServices (
   // Initialize Local Variables\r
   //\r
   PhitResourceHob       = NULL;\r
-  MaxResourceHob        = NULL;\r
   ResourceHob           = NULL;\r
   BaseAddress           = 0;\r
   Length                = 0;\r
   Attributes            = 0;\r
-  MaxMemoryBaseAddress  = 0;\r
-  MaxMemoryLength       = 0;\r
-  MaxMemoryAttributes   = 0;\r
 \r
   //\r
   // Cache the PHIT HOB for later use\r
   //\r
   PhitHob = Hob.HandoffInformationTable;\r
-\r
+  \r
+  if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0) {\r
+       ReservedCodePageNumber = PcdGet32(PcdLoadFixAddressRuntimeCodePageNumber);\r
+       ReservedCodePageNumber += PcdGet32(PcdLoadFixAddressBootTimeCodePageNumber);\r
+   \r
+       //\r
+       // cache the Top address for loading modules at Fixed Address \r
+       //\r
+    gLoadModuleAtFixAddressConfigurationTable.DxeCodeTopAddress = PhitHob->EfiMemoryTop \r
+                                                                   + EFI_PAGES_TO_SIZE(ReservedCodePageNumber);\r
+  }\r
   //\r
   // See if a Memory Type Information HOB is available\r
   //\r
@@ -1811,43 +2162,72 @@ CoreInitializeMemoryServices (
   }\r
 \r
   //\r
-  // Find the Resource Descriptor HOB that contains range FreeMemoryBaseAddress..FreeMemoryLength\r
+  // Include the total memory bin size needed to make sure memory bin could be allocated successfully.\r
+  //\r
+  MinimalMemorySizeNeeded = MINIMUM_INITIAL_MEMORY_SIZE + CalculateTotalMemoryBinSizeNeeded ();\r
+\r
+  //\r
+  // Find the Resource Descriptor HOB that contains PHIT range EfiFreeMemoryBottom..EfiFreeMemoryTop\r
   //\r
-  Length = 0;\r
   Found  = FALSE;\r
   for (Hob.Raw = *HobStart; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) {\r
+    //\r
+    // Skip all HOBs except Resource Descriptor HOBs\r
+    //\r
+    if (GET_HOB_TYPE (Hob) != EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {\r
+      continue;\r
+    }\r
 \r
-    if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {\r
-\r
-      ResourceHob = Hob.ResourceDescriptor;\r
+    //\r
+    // Skip Resource Descriptor HOBs that do not describe tested system memory\r
+    //\r
+    ResourceHob = Hob.ResourceDescriptor;\r
+    if (ResourceHob->ResourceType != EFI_RESOURCE_SYSTEM_MEMORY) {\r
+      continue;\r
+    }\r
+    if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) != TESTED_MEMORY_ATTRIBUTES) {\r
+      continue;\r
+    }\r
 \r
-      if (ResourceHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY                                       &&\r
-          (ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) == TESTED_MEMORY_ATTRIBUTES    ) {\r
+    //\r
+    // Skip Resource Descriptor HOBs that do not contain the PHIT range EfiFreeMemoryBottom..EfiFreeMemoryTop\r
+    //\r
+    if (PhitHob->EfiFreeMemoryBottom < ResourceHob->PhysicalStart) {\r
+      continue;\r
+    }\r
+    if (PhitHob->EfiFreeMemoryTop > (ResourceHob->PhysicalStart + ResourceHob->ResourceLength)) {\r
+      continue;\r
+    }\r
 \r
-        if (PhitHob->EfiFreeMemoryBottom >= ResourceHob->PhysicalStart                         && \r
-            PhitHob->EfiFreeMemoryTop    <= (ResourceHob->PhysicalStart + ResourceHob->ResourceLength)    ) {\r
+    //\r
+    // Cache the resource descriptor HOB for the memory region described by the PHIT HOB\r
+    //\r
+    PhitResourceHob = ResourceHob;\r
+    Found = TRUE;\r
 \r
-          //\r
-          // Cache the resource descriptor HOB for the memory region described by the PHIT HOB\r
-          //\r
-          PhitResourceHob = ResourceHob;\r
-          Found = TRUE;\r
-\r
-          Attributes  = PhitResourceHob->ResourceAttribute;\r
-          BaseAddress = PageAlignAddress (PhitHob->EfiMemoryTop);\r
-          Length      = PageAlignLength  (ResourceHob->PhysicalStart + ResourceHob->ResourceLength - BaseAddress);\r
-          if (Length < MINIMUM_INITIAL_MEMORY_SIZE) {\r
-            BaseAddress = PageAlignAddress (PhitHob->EfiFreeMemoryBottom);\r
-            Length      = PageAlignLength  (PhitHob->EfiFreeMemoryTop - BaseAddress);\r
-            if (Length < MINIMUM_INITIAL_MEMORY_SIZE) {\r
-              BaseAddress = PageAlignAddress (ResourceHob->PhysicalStart);\r
-              Length      = PageAlignLength  ((UINT64)((UINTN)*HobStart - BaseAddress));\r
-            }\r
-          }\r
-          break;\r
-        }\r
+    //\r
+    // Compute range between PHIT EfiMemoryTop and the end of the Resource Descriptor HOB\r
+    //\r
+    Attributes  = PhitResourceHob->ResourceAttribute;\r
+    BaseAddress = PageAlignAddress (PhitHob->EfiMemoryTop);\r
+    Length      = PageAlignLength  (ResourceHob->PhysicalStart + ResourceHob->ResourceLength - BaseAddress);\r
+    if (Length < MinimalMemorySizeNeeded) {\r
+      //\r
+      // If that range is not large enough to intialize the DXE Core, then \r
+      // Compute range between PHIT EfiFreeMemoryBottom and PHIT EfiFreeMemoryTop\r
+      //\r
+      BaseAddress = PageAlignAddress (PhitHob->EfiFreeMemoryBottom);\r
+      Length      = PageAlignLength  (PhitHob->EfiFreeMemoryTop - BaseAddress);\r
+      if (Length < MinimalMemorySizeNeeded) {\r
+        //\r
+        // If that range is not large enough to intialize the DXE Core, then \r
+        // Compute range between the start of the Resource Descriptor HOB and the start of the HOB List\r
+        //\r
+        BaseAddress = PageAlignAddress (ResourceHob->PhysicalStart);\r
+        Length      = PageAlignLength  ((UINT64)((UINTN)*HobStart - BaseAddress));\r
       }\r
     }\r
+    break;\r
   }\r
 \r
   //\r
@@ -1856,75 +2236,88 @@ CoreInitializeMemoryServices (
   ASSERT (Found);\r
 \r
   //\r
-  // Search all the resource descriptor HOBs from the highest possible addresses down for a memory\r
-  // region that is big enough to initialize the DXE core.  Always skip the PHIT Resource HOB.\r
-  // The max address must be within the physically addressible range for the processor.\r
+  // Take the range in the resource descriptor HOB for the memory region described\r
+  // by the PHIT as higher priority if it is big enough. It can make the memory bin\r
+  // allocated to be at the same memory region with PHIT that has more better compatibility\r
+  // to avoid memory fragmentation for some code practices assume and allocate <4G ACPI memory.\r
   //\r
-  MaxMemoryLength = 0;\r
-  MaxAddress      = EFI_MAX_ADDRESS;\r
-  do {\r
-    HighAddress = 0;\r
-    Found       = FALSE;\r
+  if (Length < MinimalMemorySizeNeeded) {\r
     //\r
-    // Search for a tested memory region that is below MaxAddress\r
+    // Search all the resource descriptor HOBs from the highest possible addresses down for a memory\r
+    // region that is big enough to initialize the DXE core.  Always skip the PHIT Resource HOB.\r
+    // The max address must be within the physically addressible range for the processor.\r
     //\r
+    HighAddress = MAX_ADDRESS;\r
     for (Hob.Raw = *HobStart; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) {\r
-\r
       //\r
-      // See if this is a resource descriptor HOB that does not contain the PHIT.\r
+      // Skip the Resource Descriptor HOB that contains the PHIT\r
       //\r
-      if (Hob.ResourceDescriptor != PhitResourceHob && GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {\r
+      if (Hob.ResourceDescriptor == PhitResourceHob) {\r
+        continue;\r
+      }\r
+      //\r
+      // Skip all HOBs except Resource Descriptor HOBs\r
+      //\r
+      if (GET_HOB_TYPE (Hob) != EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {\r
+        continue;\r
+      }\r
 \r
-        ResourceHob = Hob.ResourceDescriptor;\r
-        //\r
-        // See if this resource descrior HOB describes tested system memory below MaxAddress\r
-        //\r
-        if (ResourceHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY                                       &&\r
-            (ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) == TESTED_MEMORY_ATTRIBUTES &&\r
-            ResourceHob->PhysicalStart + ResourceHob->ResourceLength <= MaxAddress                            ) {\r
+      //\r
+      // Skip Resource Descriptor HOBs that do not describe tested system memory below MAX_ADDRESS\r
+      //\r
+      ResourceHob = Hob.ResourceDescriptor;\r
+      if (ResourceHob->ResourceType != EFI_RESOURCE_SYSTEM_MEMORY) {\r
+        continue;\r
+      }\r
+      if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) != TESTED_MEMORY_ATTRIBUTES) {\r
+        continue;\r
+      }\r
+      if ((ResourceHob->PhysicalStart + ResourceHob->ResourceLength) > (EFI_PHYSICAL_ADDRESS)MAX_ADDRESS) {\r
+        continue;\r
+      }\r
 \r
-          //\r
-          // See if this is the highest tested system memory region below MaxAddress\r
-          //\r
-          if (ResourceHob->PhysicalStart > HighAddress) {\r
+      //\r
+      // Skip Resource Descriptor HOBs that are below a previously found Resource Descriptor HOB\r
+      //\r
+      if (HighAddress != (EFI_PHYSICAL_ADDRESS)MAX_ADDRESS && ResourceHob->PhysicalStart <= HighAddress) {\r
+        continue;\r
+      }\r
 \r
-            MaxResourceHob = ResourceHob;\r
-            HighAddress = MaxResourceHob->PhysicalStart;\r
-            Found = TRUE;\r
-          }\r
-        }\r
+      //\r
+      // Skip Resource Descriptor HOBs that are not large enough to initilize the DXE Core\r
+      //\r
+      TestedMemoryBaseAddress = PageAlignAddress (ResourceHob->PhysicalStart);\r
+      TestedMemoryLength      = PageAlignLength  (ResourceHob->PhysicalStart + ResourceHob->ResourceLength - TestedMemoryBaseAddress);\r
+      if (TestedMemoryLength < MinimalMemorySizeNeeded) {\r
+        continue;\r
       }\r
-    }\r
-    if (Found) {\r
+\r
       //\r
-      // Compute the size of the tested memory region below MaxAddrees\r
+      // Save the range described by the Resource Descriptor that is large enough to initilize the DXE Core\r
       //\r
-      MaxMemoryBaseAddress = PageAlignAddress (MaxResourceHob->PhysicalStart);\r
-      MaxMemoryLength      = PageAlignLength  (MaxResourceHob->PhysicalStart + MaxResourceHob->ResourceLength - MaxMemoryBaseAddress);\r
-      MaxMemoryAttributes  = MaxResourceHob->ResourceAttribute;\r
+      BaseAddress = TestedMemoryBaseAddress;\r
+      Length      = TestedMemoryLength;\r
+      Attributes  = ResourceHob->ResourceAttribute; \r
+      HighAddress = ResourceHob->PhysicalStart;\r
     }\r
-    MaxAddress = ResourceHob->PhysicalStart;\r
-  } while (Found && MaxMemoryLength < MINIMUM_INITIAL_MEMORY_SIZE);\r
-\r
-  //\r
-  //\r
-  //\r
-  if ((Length < MINIMUM_INITIAL_MEMORY_SIZE)                                                 ||\r
-      (MaxMemoryBaseAddress > BaseAddress && MaxMemoryLength >= MINIMUM_INITIAL_MEMORY_SIZE)    ) {\r
-    BaseAddress = MaxMemoryBaseAddress;\r
-    Length      = MaxMemoryLength;\r
-    Attributes  = MaxMemoryAttributes;\r
   }\r
 \r
+  DEBUG ((EFI_D_INFO, "CoreInitializeMemoryServices:\n"));\r
+  DEBUG ((EFI_D_INFO, "  BaseAddress - 0x%lx Length - 0x%lx MinimalMemorySizeNeeded - 0x%lx\n", BaseAddress, Length, MinimalMemorySizeNeeded));\r
+\r
   //\r
   // If no memory regions are found that are big enough to initialize the DXE core, then ASSERT().\r
   //\r
-  ASSERT (Length >= MINIMUM_INITIAL_MEMORY_SIZE);\r
+  ASSERT (Length >= MinimalMemorySizeNeeded);\r
 \r
   //\r
   // Convert the Resource HOB Attributes to an EFI Memory Capabilities mask\r
   //\r
-  Capabilities = CoreConvertResourceDescriptorHobAttributesToCapabilities (EfiGcdMemoryTypeSystemMemory, Attributes);\r
+  if ((Attributes & EFI_RESOURCE_ATTRIBUTE_MORE_RELIABLE) == EFI_RESOURCE_ATTRIBUTE_MORE_RELIABLE) {\r
+    Capabilities = CoreConvertResourceDescriptorHobAttributesToCapabilities (EfiGcdMemoryTypeMoreReliable, Attributes);\r
+  } else {\r
+    Capabilities = CoreConvertResourceDescriptorHobAttributesToCapabilities (EfiGcdMemoryTypeSystemMemory, Attributes);\r
+  }\r
 \r
   //\r
   // Declare the very first memory region, so the EFI Memory Services are available.\r
@@ -1946,30 +2339,27 @@ CoreInitializeMemoryServices (
 /**\r
   External function. Initializes the GCD and memory services based on the memory\r
   descriptor HOBs.  This function is responsible for priming the GCD map and the\r
-  memory map, so memory allocations and resource allocations can be made.  The first\r
-  part of this function can not depend on any memory services until at least one\r
-  memory descriptor is provided to the memory services.  Then the memory services\r
-  can be used to intialize the GCD map. The HobStart will be relocated to a pool\r
-  buffer.\r
+  memory map, so memory allocations and resource allocations can be made. The\r
+  HobStart will be relocated to a pool buffer.\r
 \r
-  @param  HobStart               The start address of the HOB \r
-  @param  MemoryBaseAddress      Start address of memory region found to init DXE \r
-                                 core. \r
-  @param  MemoryLength           Length of memory region found to init DXE core. \r
+  @param  HobStart               The start address of the HOB\r
+  @param  MemoryBaseAddress      Start address of memory region found to init DXE\r
+                                 core.\r
+  @param  MemoryLength           Length of memory region found to init DXE core.\r
 \r
   @retval EFI_SUCCESS            GCD services successfully initialized.\r
 \r
 **/\r
 EFI_STATUS\r
 CoreInitializeGcdServices (\r
-  IN OUT VOID                  **HobStart,\r
+  IN OUT VOID              **HobStart,\r
   IN EFI_PHYSICAL_ADDRESS  MemoryBaseAddress,\r
   IN UINT64                MemoryLength\r
   )\r
 {\r
-  EFI_PEI_HOB_POINTERS                   Hob;\r
+  EFI_PEI_HOB_POINTERS               Hob;\r
   VOID                               *NewHobList;\r
-  EFI_HOB_HANDOFF_INFO_TABLE  *PhitHob;\r
+  EFI_HOB_HANDOFF_INFO_TABLE         *PhitHob;\r
   UINT8                              SizeOfMemorySpace;\r
   UINT8                              SizeOfIoSpace;\r
   EFI_HOB_RESOURCE_DESCRIPTOR        *ResourceHob;\r
@@ -1987,6 +2377,8 @@ CoreInitializeGcdServices (
   UINTN                              Index;\r
   UINT64                             Capabilities;\r
   EFI_HOB_CPU *                      CpuHob;\r
+  EFI_GCD_MEMORY_SPACE_DESCRIPTOR    *MemorySpaceMapHobList;\r
+\r
   //\r
   // Cache the PHIT HOB for later use\r
   //\r
@@ -1999,29 +2391,33 @@ CoreInitializeGcdServices (
   ASSERT (CpuHob != NULL);\r
   SizeOfMemorySpace = CpuHob->SizeOfMemorySpace;\r
   SizeOfIoSpace     = CpuHob->SizeOfIoSpace;\r
\r
+\r
   //\r
   // Initialize the GCD Memory Space Map\r
   //\r
-  Entry = CoreAllocateCopyPool (sizeof (EFI_GCD_MAP_ENTRY), &mGcdMemorySpaceMapEntryTemplate);\r
+  Entry = AllocateCopyPool (sizeof (EFI_GCD_MAP_ENTRY), &mGcdMemorySpaceMapEntryTemplate);\r
   ASSERT (Entry != NULL);\r
 \r
   Entry->EndAddress = LShiftU64 (1, SizeOfMemorySpace) - 1;\r
 \r
   InsertHeadList (&mGcdMemorySpaceMap, &Entry->Link);\r
 \r
+  CoreDumpGcdMemorySpaceMap (TRUE);\r
+  \r
   //\r
   // Initialize the GCD I/O Space Map\r
   //\r
-  Entry = CoreAllocateCopyPool (sizeof (EFI_GCD_MAP_ENTRY), &mGcdIoSpaceMapEntryTemplate);\r
+  Entry = AllocateCopyPool (sizeof (EFI_GCD_MAP_ENTRY), &mGcdIoSpaceMapEntryTemplate);\r
   ASSERT (Entry != NULL);\r
 \r
   Entry->EndAddress = LShiftU64 (1, SizeOfIoSpace) - 1;\r
 \r
   InsertHeadList (&mGcdIoSpaceMap, &Entry->Link);\r
 \r
+  CoreDumpGcdIoSpaceMap (TRUE);\r
+  \r
   //\r
-  // Walk the HOB list and add all resource descriptors to the GCD \r
+  // Walk the HOB list and add all resource descriptors to the GCD\r
   //\r
   for (Hob.Raw = *HobStart; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) {\r
 \r
@@ -2035,7 +2431,11 @@ CoreInitializeGcdServices (
       switch (ResourceHob->ResourceType) {\r
       case EFI_RESOURCE_SYSTEM_MEMORY:\r
         if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) == TESTED_MEMORY_ATTRIBUTES) {\r
-          GcdMemoryType = EfiGcdMemoryTypeSystemMemory;\r
+          if ((ResourceHob->ResourceAttribute & EFI_RESOURCE_ATTRIBUTE_MORE_RELIABLE) == EFI_RESOURCE_ATTRIBUTE_MORE_RELIABLE) {\r
+            GcdMemoryType = EfiGcdMemoryTypeMoreReliable;\r
+          } else {\r
+            GcdMemoryType = EfiGcdMemoryTypeSystemMemory;\r
+          }\r
         }\r
         if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) == INITIALIZED_MEMORY_ATTRIBUTES) {\r
           GcdMemoryType = EfiGcdMemoryTypeReserved;\r
@@ -2043,6 +2443,9 @@ CoreInitializeGcdServices (
         if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) == PRESENT_MEMORY_ATTRIBUTES) {\r
           GcdMemoryType = EfiGcdMemoryTypeReserved;\r
         }\r
+        if ((ResourceHob->ResourceAttribute & EFI_RESOURCE_ATTRIBUTE_PERSISTENT) == EFI_RESOURCE_ATTRIBUTE_PERSISTENT) {\r
+          GcdMemoryType = EfiGcdMemoryTypePersistent;\r
+        }\r
         break;\r
       case EFI_RESOURCE_MEMORY_MAPPED_IO:\r
       case EFI_RESOURCE_FIRMWARE_DEVICE:\r
@@ -2061,6 +2464,10 @@ CoreInitializeGcdServices (
       }\r
 \r
       if (GcdMemoryType != EfiGcdMemoryTypeNonExistent) {\r
+        //\r
+        // Validate the Resource HOB Attributes\r
+        //\r
+        CoreValidateResourceDescriptorHobAttributes (ResourceHob->ResourceAttribute);\r
 \r
         //\r
         // Convert the Resource HOB Attributes to an EFI Memory Capabilities mask\r
@@ -2091,15 +2498,20 @@ CoreInitializeGcdServices (
   //\r
   // Allocate first memory region from the GCD by the DXE core\r
   //\r
-  Status = CoreAllocateMemorySpace (\r
-             EfiGcdAllocateAddress,\r
-             EfiGcdMemoryTypeSystemMemory,\r
-             0,\r
-             MemoryLength,\r
-             &MemoryBaseAddress,\r
-             gDxeCoreImageHandle,\r
-             NULL\r
-             );\r
+  Status = CoreGetMemorySpaceDescriptor (MemoryBaseAddress, &Descriptor);\r
+  if (!EFI_ERROR (Status)) {\r
+    ASSERT ((Descriptor.GcdMemoryType == EfiGcdMemoryTypeSystemMemory) ||\r
+            (Descriptor.GcdMemoryType == EfiGcdMemoryTypeMoreReliable));\r
+    Status = CoreAllocateMemorySpace (\r
+               EfiGcdAllocateAddress,\r
+               Descriptor.GcdMemoryType,\r
+               0,\r
+               MemoryLength,\r
+               &MemoryBaseAddress,\r
+               gDxeCoreImageHandle,\r
+               NULL\r
+               );\r
+  }\r
 \r
   //\r
   // Walk the HOB list and allocate all memory space that is consumed by memory allocation HOBs,\r
@@ -2113,14 +2525,16 @@ CoreInitializeGcdServices (
       if (!EFI_ERROR (Status)) {\r
         Status = CoreAllocateMemorySpace (\r
                    EfiGcdAllocateAddress,\r
-                   Descriptor.GcdMemoryType, \r
+                   Descriptor.GcdMemoryType,\r
                    0,\r
                    MemoryHob->AllocDescriptor.MemoryLength,\r
                    &BaseAddress,\r
                    gDxeCoreImageHandle,\r
                    NULL\r
                    );\r
-        if (!EFI_ERROR (Status) && Descriptor.GcdMemoryType == EfiGcdMemoryTypeSystemMemory) {\r
+        if (!EFI_ERROR (Status) &&\r
+            ((Descriptor.GcdMemoryType == EfiGcdMemoryTypeSystemMemory) ||\r
+             (Descriptor.GcdMemoryType == EfiGcdMemoryTypeMoreReliable))) {\r
           CoreAddMemoryDescriptor (\r
             MemoryHob->AllocDescriptor.MemoryType,\r
             MemoryHob->AllocDescriptor.MemoryBaseAddress,\r
@@ -2136,7 +2550,7 @@ CoreInitializeGcdServices (
       BaseAddress = FirmwareVolumeHob->BaseAddress;\r
       Status = CoreAllocateMemorySpace (\r
                  EfiGcdAllocateAddress,\r
-                 EfiGcdMemoryTypeMemoryMappedIo, \r
+                 EfiGcdMemoryTypeMemoryMappedIo,\r
                  0,\r
                  FirmwareVolumeHob->Length,\r
                  &BaseAddress,\r
@@ -2146,30 +2560,32 @@ CoreInitializeGcdServices (
     }\r
   }\r
 \r
-  //\r
-  // Relocate HOB List to an allocated pool buffer.\r
-  //\r
-  NewHobList = CoreAllocateCopyPool (\r
-                 (UINTN)PhitHob->EfiFreeMemoryBottom - (UINTN)(*HobStart), \r
-                 *HobStart\r
-                 );\r
-  ASSERT (NewHobList != NULL);\r
-\r
-  *HobStart = NewHobList;\r
-  gHobList  = NewHobList;\r
-\r
   //\r
   // Add and allocate the remaining unallocated system memory to the memory services.\r
   //\r
   Status = CoreGetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap);\r
+  ASSERT (Status == EFI_SUCCESS);\r
+\r
+  MemorySpaceMapHobList = NULL;\r
   for (Index = 0; Index < NumberOfDescriptors; Index++) {\r
-    if (MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeSystemMemory) {\r
+    if ((MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeSystemMemory) ||\r
+        (MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeMoreReliable)) {\r
       if (MemorySpaceMap[Index].ImageHandle == NULL) {\r
         BaseAddress  = PageAlignAddress (MemorySpaceMap[Index].BaseAddress);\r
         Length       = PageAlignLength  (MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length - BaseAddress);\r
         if (Length == 0 || MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length < BaseAddress) {\r
           continue;\r
         }\r
+        if (((UINTN) MemorySpaceMap[Index].BaseAddress <= (UINTN) (*HobStart)) &&\r
+            ((UINTN) (MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length) >= (UINTN) PhitHob->EfiFreeMemoryBottom)) {\r
+          //\r
+          // Skip the memory space that covers HOB List, it should be processed\r
+          // after HOB List relocation to avoid the resources allocated by others\r
+          // to corrupt HOB List before its relocation.\r
+          //\r
+          MemorySpaceMapHobList = &MemorySpaceMap[Index];\r
+          continue;\r
+        }\r
         CoreAddMemoryDescriptor (\r
           EfiConventionalMemory,\r
           BaseAddress,\r
@@ -2178,7 +2594,7 @@ CoreInitializeGcdServices (
           );\r
         Status = CoreAllocateMemorySpace (\r
                    EfiGcdAllocateAddress,\r
-                   EfiGcdMemoryTypeSystemMemory,\r
+                   MemorySpaceMap[Index].GcdMemoryType,\r
                    0,\r
                    Length,\r
                    &BaseAddress,\r
@@ -2188,6 +2604,47 @@ CoreInitializeGcdServices (
       }\r
     }\r
   }\r
+\r
+  //\r
+  // Relocate HOB List to an allocated pool buffer.\r
+  // The relocation should be at after all the tested memory resources added\r
+  // (except the memory space that covers HOB List) to the memory services,\r
+  // because the memory resource found in CoreInitializeMemoryServices()\r
+  // may have not enough remaining resource for HOB List.\r
+  //\r
+  NewHobList = AllocateCopyPool (\r
+                 (UINTN) PhitHob->EfiFreeMemoryBottom - (UINTN) (*HobStart),\r
+                 *HobStart\r
+                 );\r
+  ASSERT (NewHobList != NULL);\r
+\r
+  *HobStart = NewHobList;\r
+  gHobList  = NewHobList;\r
+\r
+  if (MemorySpaceMapHobList != NULL) {\r
+    //\r
+    // Add and allocate the memory space that covers HOB List to the memory services\r
+    // after HOB List relocation.\r
+    //\r
+    BaseAddress = PageAlignAddress (MemorySpaceMapHobList->BaseAddress);\r
+    Length      = PageAlignLength  (MemorySpaceMapHobList->BaseAddress + MemorySpaceMapHobList->Length - BaseAddress);\r
+    CoreAddMemoryDescriptor (\r
+      EfiConventionalMemory,\r
+      BaseAddress,\r
+      RShiftU64 (Length, EFI_PAGE_SHIFT),\r
+      MemorySpaceMapHobList->Capabilities & (~EFI_MEMORY_RUNTIME)\r
+      );\r
+    Status = CoreAllocateMemorySpace (\r
+               EfiGcdAllocateAddress,\r
+               MemorySpaceMapHobList->GcdMemoryType,\r
+               0,\r
+               Length,\r
+               &BaseAddress,\r
+               gDxeCoreImageHandle,\r
+               NULL\r
+               );\r
+  }\r
+\r
   CoreFreePool (MemorySpaceMap);\r
 \r
   return EFI_SUCCESS;\r