]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Core/Dxe/Gcd/Gcd.c
MdeModulePkg/Gcd: Check memory allocation when initializing memory
[mirror_edk2.git] / MdeModulePkg / Core / Dxe / Gcd / Gcd.c
index 2d8c076f71135c00210f4840ee73d15c6921adb0..51b082b7e7eb2fe1f1eeebc23f07f0950b99be92 100644 (file)
@@ -2097,6 +2097,60 @@ CalculateTotalMemoryBinSizeNeeded (
   return TotalSize;\r
 }\r
 \r
+/**\r
+   Find the largest region in the specified region that is not covered by an existing memory allocation\r
+\r
+   @param BaseAddress   On input start of the region to check.\r
+                        On output start of the largest free region.\r
+   @param Length        On input size of region to check.\r
+                        On output size of the largest free region.\r
+   @param MemoryHob     Hob pointer for the first memory allocation pointer to check\r
+**/\r
+VOID\r
+FindLargestFreeRegion (\r
+    IN OUT EFI_PHYSICAL_ADDRESS  *BaseAddress,\r
+    IN OUT UINT64                *Length,\r
+    IN EFI_HOB_MEMORY_ALLOCATION *MemoryHob\r
+    )\r
+{\r
+  EFI_PHYSICAL_ADDRESS TopAddress;\r
+  EFI_PHYSICAL_ADDRESS AllocatedTop;\r
+  EFI_PHYSICAL_ADDRESS LowerBase;\r
+  UINT64               LowerSize;\r
+  EFI_PHYSICAL_ADDRESS UpperBase;\r
+  UINT64               UpperSize;\r
+\r
+  TopAddress = *BaseAddress + *Length;\r
+  while (MemoryHob != NULL) {\r
+    AllocatedTop = MemoryHob->AllocDescriptor.MemoryBaseAddress + MemoryHob->AllocDescriptor.MemoryLength;\r
+\r
+    if ((MemoryHob->AllocDescriptor.MemoryBaseAddress >= *BaseAddress) &&\r
+        (AllocatedTop <= TopAddress)) {\r
+      LowerBase = *BaseAddress;\r
+      LowerSize = MemoryHob->AllocDescriptor.MemoryBaseAddress - *BaseAddress;\r
+      UpperBase = AllocatedTop;\r
+      UpperSize = TopAddress - AllocatedTop;\r
+\r
+      if (LowerSize != 0) {\r
+        FindLargestFreeRegion (&LowerBase, &LowerSize, (EFI_HOB_MEMORY_ALLOCATION *) GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, GET_NEXT_HOB (MemoryHob)));\r
+      }\r
+      if (UpperSize != 0) {\r
+        FindLargestFreeRegion (&UpperBase, &UpperSize, (EFI_HOB_MEMORY_ALLOCATION *) GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, GET_NEXT_HOB (MemoryHob)));\r
+      }\r
+\r
+      if (UpperSize >= LowerSize) {\r
+        *Length = UpperSize;\r
+        *BaseAddress = UpperBase;\r
+      } else {\r
+        *Length = LowerSize;\r
+        *BaseAddress = LowerBase;\r
+      }\r
+      return;\r
+    }\r
+    MemoryHob = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, GET_NEXT_HOB (MemoryHob));\r
+  }\r
+}\r
+\r
 /**\r
   External function. Initializes memory services based on the memory\r
   descriptor HOBs.  This function is responsible for priming the memory\r
@@ -2235,6 +2289,7 @@ CoreInitializeMemoryServices (
     Attributes  = PhitResourceHob->ResourceAttribute;\r
     BaseAddress = PageAlignAddress (PhitHob->EfiMemoryTop);\r
     Length      = PageAlignLength  (ResourceHob->PhysicalStart + ResourceHob->ResourceLength - BaseAddress);\r
+    FindLargestFreeRegion (&BaseAddress, &Length, (EFI_HOB_MEMORY_ALLOCATION *)GetFirstHob (EFI_HOB_TYPE_MEMORY_ALLOCATION));\r
     if (Length < MinimalMemorySizeNeeded) {\r
       //\r
       // If that range is not large enough to intialize the DXE Core, then\r
@@ -2242,6 +2297,7 @@ CoreInitializeMemoryServices (
       //\r
       BaseAddress = PageAlignAddress (PhitHob->EfiFreeMemoryBottom);\r
       Length      = PageAlignLength  (PhitHob->EfiFreeMemoryTop - BaseAddress);\r
+      //This region is required to have no memory allocation inside it, skip check for entries in HOB List\r
       if (Length < MinimalMemorySizeNeeded) {\r
         //\r
         // If that range is not large enough to intialize the DXE Core, then\r
@@ -2249,6 +2305,7 @@ CoreInitializeMemoryServices (
         //\r
         BaseAddress = PageAlignAddress (ResourceHob->PhysicalStart);\r
         Length      = PageAlignLength  ((UINT64)((UINTN)*HobStart - BaseAddress));\r
+        FindLargestFreeRegion (&BaseAddress, &Length, (EFI_HOB_MEMORY_ALLOCATION *)GetFirstHob (EFI_HOB_TYPE_MEMORY_ALLOCATION));\r
       }\r
     }\r
     break;\r
@@ -2312,6 +2369,7 @@ CoreInitializeMemoryServices (
       //\r
       TestedMemoryBaseAddress = PageAlignAddress (ResourceHob->PhysicalStart);\r
       TestedMemoryLength      = PageAlignLength  (ResourceHob->PhysicalStart + ResourceHob->ResourceLength - TestedMemoryBaseAddress);\r
+      FindLargestFreeRegion (&TestedMemoryBaseAddress, &TestedMemoryLength, (EFI_HOB_MEMORY_ALLOCATION *)GetFirstHob (EFI_HOB_TYPE_MEMORY_ALLOCATION));\r
       if (TestedMemoryLength < MinimalMemorySizeNeeded) {\r
         continue;\r
       }\r