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
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
//\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
//\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
//\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