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 memory services based on the memory\r
UINT64 TestedMemoryLength;\r
EFI_PHYSICAL_ADDRESS HighAddress;\r
EFI_HOB_GUID_TYPE *GuidHob;\r
- UINT32 ReservedCodePageNumber;\r
+ UINT32 ReservedCodePageNumber;\r
+ UINT64 MinimalMemorySizeNeeded;\r
\r
//\r
// Point at the first HOB. This must be the PHIT HOB.\r
}\r
}\r
\r
+ //\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
Found = TRUE;\r
\r
//\r
- // Compute range between PHIT EfiFreeMemoryTop and the end of the Resource Descriptor HOB\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 < MINIMUM_INITIAL_MEMORY_SIZE) {\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 < MINIMUM_INITIAL_MEMORY_SIZE) {\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
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
- HighAddress = MAX_ADDRESS;\r
- for (Hob.Raw = *HobStart; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) {\r
- //\r
- // Skip the Resource Descriptor HOB that contains the PHIT\r
- //\r
- if (Hob.ResourceDescriptor == PhitResourceHob) {\r
- continue;\r
- }\r
+ if (Length < MinimalMemorySizeNeeded) {\r
//\r
- // Skip all HOBs except Resource Descriptor HOBs\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
- if (GET_HOB_TYPE (Hob) != EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {\r
- continue;\r
- }\r
+ HighAddress = MAX_ADDRESS;\r
+ for (Hob.Raw = *HobStart; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) {\r
+ //\r
+ // Skip the Resource Descriptor HOB that contains the PHIT\r
+ //\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
- //\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
- // 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
+ // 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
- // 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 < MINIMUM_INITIAL_MEMORY_SIZE) {\r
- continue;\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
+ //\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
+ //\r
+ // Save the range described by the Resource Descriptor that is large enough to initilize the DXE Core\r
+ //\r
+ BaseAddress = TestedMemoryBaseAddress;\r
+ Length = TestedMemoryLength;\r
+ Attributes = ResourceHob->ResourceAttribute; \r
+ HighAddress = ResourceHob->PhysicalStart;\r
}\r
- \r
- //\r
- // Save the Resource Descriptor HOB context that is large enough to initilize the DXE Core\r
- //\r
- MaxMemoryBaseAddress = TestedMemoryBaseAddress;\r
- MaxMemoryLength = TestedMemoryLength;\r
- MaxMemoryAttributes = ResourceHob->ResourceAttribute; \r
- HighAddress = ResourceHob->PhysicalStart;\r
}\r
\r
- //\r
- // If Length is not large enough to initialize the DXE Core or a Resource \r
- // Descriptor HOB was found above the PHIT HOB that is large enough to initialize \r
- // the DXE Core, then use the range described by the Resource Descriptor \r
- // HOB that was found above the PHIT HOB.\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
+ 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