Reviewed-by: Star Zeng <star.z...@intel.com>

-----Original Message-----
From: Liming Gao [mailto:liming....@intel.com] 
Sent: Tuesday, June 30, 2015 2:12 PM
To: edk2-devel@lists.sourceforge.net
Subject: [edk2] [Patch] MdeModulePkg: Merge GCD range before convert it to EFI 
memory

GCD Range is byte address. EFI memory range is page address. To make sure GCD 
range is converted to EFI memory range, the following things are added:
1. Merge adjacent GCD range first.
2. Add ASSERT check on GCD range alignment.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Liming Gao <liming....@intel.com>
---
 MdeModulePkg/Core/Dxe/Mem/Page.c | 78 +++++++++++++++++++++++++++++++---------
 1 file changed, 61 insertions(+), 17 deletions(-)

diff --git a/MdeModulePkg/Core/Dxe/Mem/Page.c b/MdeModulePkg/Core/Dxe/Mem/Page.c
index a285529..9dbb85d 100644
--- a/MdeModulePkg/Core/Dxe/Mem/Page.c
+++ b/MdeModulePkg/Core/Dxe/Mem/Page.c
@@ -1541,10 +1541,11 @@ CoreGetMemoryMap (
   UINTN                             BufferSize;
   UINTN                             NumberOfEntries;
   LIST_ENTRY                        *Link;
   MEMORY_MAP                        *Entry;
   EFI_GCD_MAP_ENTRY                 *GcdMapEntry;
+  EFI_GCD_MAP_ENTRY                 MergeGcdMapEntry;
   EFI_MEMORY_TYPE                   Type;
   EFI_MEMORY_DESCRIPTOR             *MemoryMapStart;
 
   //
   // Make sure the parameters are valid @@ -1652,29 +1653,53 @@ 
CoreGetMemoryMap (
     // existing descriptor if they are adjacent and have the same attributes
     //
     MemoryMap = MergeMemoryMapDescriptor (MemoryMapStart, MemoryMap, Size);
   }
 
-  for (Link = mGcdMemorySpaceMap.ForwardLink; Link != &mGcdMemorySpaceMap; 
Link = Link->ForwardLink) {
-    GcdMapEntry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);
-    if ((GcdMapEntry->GcdMemoryType == EfiGcdMemoryTypeReserved) ||
-        ((GcdMapEntry->GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) &&
-        ((GcdMapEntry->Attributes & EFI_MEMORY_RUNTIME) == 
EFI_MEMORY_RUNTIME))) {
+ 
+  ZeroMem (&MergeGcdMapEntry, sizeof (MergeGcdMapEntry));  GcdMapEntry 
+ = NULL;  for (Link = mGcdMemorySpaceMap.ForwardLink; ; Link = 
+ Link->ForwardLink) {
+    if (Link != &mGcdMemorySpaceMap) {
+      //
+      // Merge adjacent same type and attribute GCD memory range
+      //
+      GcdMapEntry = CR (Link, EFI_GCD_MAP_ENTRY, Link, 
+ EFI_GCD_MAP_SIGNATURE);
+  
+      if ((MergeGcdMapEntry.Capabilities == GcdMapEntry->Capabilities) && 
+          (MergeGcdMapEntry.Attributes == GcdMapEntry->Attributes) &&
+          (MergeGcdMapEntry.GcdMemoryType == GcdMapEntry->GcdMemoryType) &&
+          (MergeGcdMapEntry.GcdIoType == GcdMapEntry->GcdIoType)) {
+        MergeGcdMapEntry.EndAddress  = GcdMapEntry->EndAddress;
+        continue;
+      }
+    }
+
+    if ((MergeGcdMapEntry.GcdMemoryType == EfiGcdMemoryTypeReserved) ||
+        ((MergeGcdMapEntry.GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) &&
+        ((MergeGcdMapEntry.Attributes & EFI_MEMORY_RUNTIME) == 
EFI_MEMORY_RUNTIME))) {
+      //
+      // Page Align GCD range is required. When it is converted to 
EFI_MEMORY_DESCRIPTOR, 
+      // it will be recorded as page PhysicalStart and NumberOfPages. 
+      //
+      ASSERT ((MergeGcdMapEntry.BaseAddress & EFI_PAGE_MASK) == 0);
+      ASSERT (((MergeGcdMapEntry.EndAddress - 
+ MergeGcdMapEntry.BaseAddress + 1) & EFI_PAGE_MASK) == 0);
+      
       // 
       // Create EFI_MEMORY_DESCRIPTOR for every Reserved and runtime MMIO GCD 
entries
       //
-      MemoryMap->PhysicalStart = GcdMapEntry->BaseAddress;
+      MemoryMap->PhysicalStart = MergeGcdMapEntry.BaseAddress;
       MemoryMap->VirtualStart  = 0;
-      MemoryMap->NumberOfPages = RShiftU64 ((GcdMapEntry->EndAddress - 
GcdMapEntry->BaseAddress + 1), EFI_PAGE_SHIFT);
-      MemoryMap->Attribute     = (GcdMapEntry->Attributes & 
~EFI_MEMORY_PORT_IO) | 
-                                (GcdMapEntry->Capabilities & (EFI_MEMORY_RP | 
EFI_MEMORY_WP | EFI_MEMORY_XP | EFI_MEMORY_RO |
+      MemoryMap->NumberOfPages = RShiftU64 ((MergeGcdMapEntry.EndAddress - 
MergeGcdMapEntry.BaseAddress + 1), EFI_PAGE_SHIFT);
+      MemoryMap->Attribute     = (MergeGcdMapEntry.Attributes & 
~EFI_MEMORY_PORT_IO) | 
+                                (MergeGcdMapEntry.Capabilities & 
+ (EFI_MEMORY_RP | EFI_MEMORY_WP | EFI_MEMORY_XP | EFI_MEMORY_RO |
                                 EFI_MEMORY_UC | EFI_MEMORY_UCE | EFI_MEMORY_WC 
| EFI_MEMORY_WT | EFI_MEMORY_WB));
 
-      if (GcdMapEntry->GcdMemoryType == EfiGcdMemoryTypeReserved) {
+      if (MergeGcdMapEntry.GcdMemoryType == EfiGcdMemoryTypeReserved) {
         MemoryMap->Type = EfiReservedMemoryType;
-      } else if (GcdMapEntry->GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) 
{
-        if ((GcdMapEntry->Attributes & EFI_MEMORY_PORT_IO) == 
EFI_MEMORY_PORT_IO) {
+      } else if (MergeGcdMapEntry.GcdMemoryType == 
EfiGcdMemoryTypeMemoryMappedIo) {
+        if ((MergeGcdMapEntry.Attributes & EFI_MEMORY_PORT_IO) == 
+ EFI_MEMORY_PORT_IO) {
           MemoryMap->Type = EfiMemoryMappedIOPortSpace;
         } else {
           MemoryMap->Type = EfiMemoryMappedIO;
         }
       }
@@ -1684,28 +1709,47 @@ CoreGetMemoryMap (
       // existing descriptor if they are adjacent and have the same attributes
       //
       MemoryMap = MergeMemoryMapDescriptor (MemoryMapStart, MemoryMap, Size);
     }
     
-    if (GcdMapEntry->GcdMemoryType == EfiGcdMemoryTypePersistentMemory) {
+    if (MergeGcdMapEntry.GcdMemoryType == EfiGcdMemoryTypePersistentMemory) {
+      //
+      // Page Align GCD range is required. When it is converted to 
EFI_MEMORY_DESCRIPTOR, 
+      // it will be recorded as page PhysicalStart and NumberOfPages. 
+      //
+      ASSERT ((MergeGcdMapEntry.BaseAddress & EFI_PAGE_MASK) == 0);
+      ASSERT (((MergeGcdMapEntry.EndAddress - 
+ MergeGcdMapEntry.BaseAddress + 1) & EFI_PAGE_MASK) == 0);
+
       // 
       // Create EFI_MEMORY_DESCRIPTOR for every Persistent GCD entries
       //
-      MemoryMap->PhysicalStart = GcdMapEntry->BaseAddress;
+      MemoryMap->PhysicalStart = MergeGcdMapEntry.BaseAddress;
       MemoryMap->VirtualStart  = 0;
-      MemoryMap->NumberOfPages = RShiftU64 ((GcdMapEntry->EndAddress - 
GcdMapEntry->BaseAddress + 1), EFI_PAGE_SHIFT);
-      MemoryMap->Attribute     = GcdMapEntry->Attributes | EFI_MEMORY_NV | 
-                                (GcdMapEntry->Capabilities & (EFI_MEMORY_RP | 
EFI_MEMORY_WP | EFI_MEMORY_XP | EFI_MEMORY_RO |
+      MemoryMap->NumberOfPages = RShiftU64 ((MergeGcdMapEntry.EndAddress - 
MergeGcdMapEntry.BaseAddress + 1), EFI_PAGE_SHIFT);
+      MemoryMap->Attribute     = MergeGcdMapEntry.Attributes | EFI_MEMORY_NV | 
+                                (MergeGcdMapEntry.Capabilities & 
+ (EFI_MEMORY_RP | EFI_MEMORY_WP | EFI_MEMORY_XP | EFI_MEMORY_RO |
                                 EFI_MEMORY_UC | EFI_MEMORY_UCE | EFI_MEMORY_WC 
| EFI_MEMORY_WT | EFI_MEMORY_WB));
       MemoryMap->Type          = EfiPersistentMemory;
       
       //
       // Check to see if the new Memory Map Descriptor can be merged with an 
       // existing descriptor if they are adjacent and have the same attributes
       //
       MemoryMap = MergeMemoryMapDescriptor (MemoryMapStart, MemoryMap, Size);
     }
+    if (Link == &mGcdMemorySpaceMap) {
+      //
+      // break loop when arrive at head.
+      //
+      break;
+    }
+    if (GcdMapEntry != NULL) {
+      //
+      // Copy new GCD map entry for the following GCD range merge
+      //
+      CopyMem (&MergeGcdMapEntry, GcdMapEntry, sizeof (MergeGcdMapEntry));
+    }
   }
 
   //
   // Compute the size of the buffer actually used after all memory map 
descriptor merge operations
   //
--
1.9.5.msysgit.0


------------------------------------------------------------------------------
Don't Limit Your Business. Reach for the Cloud.
GigeNET's Cloud Solutions provide you with the tools and support that
you need to offload your IT needs and focus on growing your business.
Configured For All Businesses. Start Your Cloud Today.
https://www.gigenetcloud.com/
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel

------------------------------------------------------------------------------
Don't Limit Your Business. Reach for the Cloud.
GigeNET's Cloud Solutions provide you with the tools and support that
you need to offload your IT needs and focus on growing your business.
Configured For All Businesses. Start Your Cloud Today.
https://www.gigenetcloud.com/
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Reply via email to