]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Core/Dxe/Mem/Page.c
MdeModulePkg: Merge GCD range before convert it to EFI memory
[mirror_edk2.git] / MdeModulePkg / Core / Dxe / Mem / Page.c
index a28552934f6baba5d2402b241c23edfd60e3e917..9dbb85da7c871b61582499fb6ebac4689a99f13c 100644 (file)
@@ -1543,6 +1543,7 @@ CoreGetMemoryMap (
   LIST_ENTRY                        *Link;\r
   MEMORY_MAP                        *Entry;\r
   EFI_GCD_MAP_ENTRY                 *GcdMapEntry;\r
+  EFI_GCD_MAP_ENTRY                 MergeGcdMapEntry;\r
   EFI_MEMORY_TYPE                   Type;\r
   EFI_MEMORY_DESCRIPTOR             *MemoryMapStart;\r
 \r
@@ -1654,25 +1655,49 @@ CoreGetMemoryMap (
     MemoryMap = MergeMemoryMapDescriptor (MemoryMapStart, MemoryMap, Size);\r
   }\r
 \r
-  for (Link = mGcdMemorySpaceMap.ForwardLink; Link != &mGcdMemorySpaceMap; Link = Link->ForwardLink) {\r
-    GcdMapEntry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);\r
-    if ((GcdMapEntry->GcdMemoryType == EfiGcdMemoryTypeReserved) ||\r
-        ((GcdMapEntry->GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) &&\r
-        ((GcdMapEntry->Attributes & EFI_MEMORY_RUNTIME) == EFI_MEMORY_RUNTIME))) {\r
\r
+  ZeroMem (&MergeGcdMapEntry, sizeof (MergeGcdMapEntry));\r
+  GcdMapEntry = NULL;\r
+  for (Link = mGcdMemorySpaceMap.ForwardLink; ; Link = Link->ForwardLink) {\r
+    if (Link != &mGcdMemorySpaceMap) {\r
+      //\r
+      // Merge adjacent same type and attribute GCD memory range\r
+      //\r
+      GcdMapEntry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);\r
+  \r
+      if ((MergeGcdMapEntry.Capabilities == GcdMapEntry->Capabilities) && \r
+          (MergeGcdMapEntry.Attributes == GcdMapEntry->Attributes) &&\r
+          (MergeGcdMapEntry.GcdMemoryType == GcdMapEntry->GcdMemoryType) &&\r
+          (MergeGcdMapEntry.GcdIoType == GcdMapEntry->GcdIoType)) {\r
+        MergeGcdMapEntry.EndAddress  = GcdMapEntry->EndAddress;\r
+        continue;\r
+      }\r
+    }\r
+\r
+    if ((MergeGcdMapEntry.GcdMemoryType == EfiGcdMemoryTypeReserved) ||\r
+        ((MergeGcdMapEntry.GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) &&\r
+        ((MergeGcdMapEntry.Attributes & EFI_MEMORY_RUNTIME) == EFI_MEMORY_RUNTIME))) {\r
+      //\r
+      // Page Align GCD range is required. When it is converted to EFI_MEMORY_DESCRIPTOR, \r
+      // it will be recorded as page PhysicalStart and NumberOfPages. \r
+      //\r
+      ASSERT ((MergeGcdMapEntry.BaseAddress & EFI_PAGE_MASK) == 0);\r
+      ASSERT (((MergeGcdMapEntry.EndAddress - MergeGcdMapEntry.BaseAddress + 1) & EFI_PAGE_MASK) == 0);\r
+      \r
       // \r
       // Create EFI_MEMORY_DESCRIPTOR for every Reserved and runtime MMIO GCD entries\r
       //\r
-      MemoryMap->PhysicalStart = GcdMapEntry->BaseAddress;\r
+      MemoryMap->PhysicalStart = MergeGcdMapEntry.BaseAddress;\r
       MemoryMap->VirtualStart  = 0;\r
-      MemoryMap->NumberOfPages = RShiftU64 ((GcdMapEntry->EndAddress - GcdMapEntry->BaseAddress + 1), EFI_PAGE_SHIFT);\r
-      MemoryMap->Attribute     = (GcdMapEntry->Attributes & ~EFI_MEMORY_PORT_IO) | \r
-                                (GcdMapEntry->Capabilities & (EFI_MEMORY_RP | EFI_MEMORY_WP | EFI_MEMORY_XP | EFI_MEMORY_RO |\r
+      MemoryMap->NumberOfPages = RShiftU64 ((MergeGcdMapEntry.EndAddress - MergeGcdMapEntry.BaseAddress + 1), EFI_PAGE_SHIFT);\r
+      MemoryMap->Attribute     = (MergeGcdMapEntry.Attributes & ~EFI_MEMORY_PORT_IO) | \r
+                                (MergeGcdMapEntry.Capabilities & (EFI_MEMORY_RP | EFI_MEMORY_WP | EFI_MEMORY_XP | EFI_MEMORY_RO |\r
                                 EFI_MEMORY_UC | EFI_MEMORY_UCE | EFI_MEMORY_WC | EFI_MEMORY_WT | EFI_MEMORY_WB));\r
 \r
-      if (GcdMapEntry->GcdMemoryType == EfiGcdMemoryTypeReserved) {\r
+      if (MergeGcdMapEntry.GcdMemoryType == EfiGcdMemoryTypeReserved) {\r
         MemoryMap->Type = EfiReservedMemoryType;\r
-      } else if (GcdMapEntry->GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) {\r
-        if ((GcdMapEntry->Attributes & EFI_MEMORY_PORT_IO) == EFI_MEMORY_PORT_IO) {\r
+      } else if (MergeGcdMapEntry.GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) {\r
+        if ((MergeGcdMapEntry.Attributes & EFI_MEMORY_PORT_IO) == EFI_MEMORY_PORT_IO) {\r
           MemoryMap->Type = EfiMemoryMappedIOPortSpace;\r
         } else {\r
           MemoryMap->Type = EfiMemoryMappedIO;\r
@@ -1686,15 +1711,22 @@ CoreGetMemoryMap (
       MemoryMap = MergeMemoryMapDescriptor (MemoryMapStart, MemoryMap, Size);\r
     }\r
     \r
-    if (GcdMapEntry->GcdMemoryType == EfiGcdMemoryTypePersistentMemory) {\r
+    if (MergeGcdMapEntry.GcdMemoryType == EfiGcdMemoryTypePersistentMemory) {\r
+      //\r
+      // Page Align GCD range is required. When it is converted to EFI_MEMORY_DESCRIPTOR, \r
+      // it will be recorded as page PhysicalStart and NumberOfPages. \r
+      //\r
+      ASSERT ((MergeGcdMapEntry.BaseAddress & EFI_PAGE_MASK) == 0);\r
+      ASSERT (((MergeGcdMapEntry.EndAddress - MergeGcdMapEntry.BaseAddress + 1) & EFI_PAGE_MASK) == 0);\r
+\r
       // \r
       // Create EFI_MEMORY_DESCRIPTOR for every Persistent GCD entries\r
       //\r
-      MemoryMap->PhysicalStart = GcdMapEntry->BaseAddress;\r
+      MemoryMap->PhysicalStart = MergeGcdMapEntry.BaseAddress;\r
       MemoryMap->VirtualStart  = 0;\r
-      MemoryMap->NumberOfPages = RShiftU64 ((GcdMapEntry->EndAddress - GcdMapEntry->BaseAddress + 1), EFI_PAGE_SHIFT);\r
-      MemoryMap->Attribute     = GcdMapEntry->Attributes | EFI_MEMORY_NV | \r
-                                (GcdMapEntry->Capabilities & (EFI_MEMORY_RP | EFI_MEMORY_WP | EFI_MEMORY_XP | EFI_MEMORY_RO |\r
+      MemoryMap->NumberOfPages = RShiftU64 ((MergeGcdMapEntry.EndAddress - MergeGcdMapEntry.BaseAddress + 1), EFI_PAGE_SHIFT);\r
+      MemoryMap->Attribute     = MergeGcdMapEntry.Attributes | EFI_MEMORY_NV | \r
+                                (MergeGcdMapEntry.Capabilities & (EFI_MEMORY_RP | EFI_MEMORY_WP | EFI_MEMORY_XP | EFI_MEMORY_RO |\r
                                 EFI_MEMORY_UC | EFI_MEMORY_UCE | EFI_MEMORY_WC | EFI_MEMORY_WT | EFI_MEMORY_WB));\r
       MemoryMap->Type          = EfiPersistentMemory;\r
       \r
@@ -1704,6 +1736,18 @@ CoreGetMemoryMap (
       //\r
       MemoryMap = MergeMemoryMapDescriptor (MemoryMapStart, MemoryMap, Size);\r
     }\r
+    if (Link == &mGcdMemorySpaceMap) {\r
+      //\r
+      // break loop when arrive at head.\r
+      //\r
+      break;\r
+    }\r
+    if (GcdMapEntry != NULL) {\r
+      //\r
+      // Copy new GCD map entry for the following GCD range merge\r
+      //\r
+      CopyMem (&MergeGcdMapEntry, GcdMapEntry, sizeof (MergeGcdMapEntry));\r
+    }\r
   }\r
 \r
   //\r