summaryrefslogtreecommitdiff
path: root/MdeModulePkg/Core/Dxe/Gcd/Gcd.c
diff options
context:
space:
mode:
Diffstat (limited to 'MdeModulePkg/Core/Dxe/Gcd/Gcd.c')
-rw-r--r--MdeModulePkg/Core/Dxe/Gcd/Gcd.c179
1 files changed, 109 insertions, 70 deletions
diff --git a/MdeModulePkg/Core/Dxe/Gcd/Gcd.c b/MdeModulePkg/Core/Dxe/Gcd/Gcd.c
index 0ec75ca502..ab8677a972 100644
--- a/MdeModulePkg/Core/Dxe/Gcd/Gcd.c
+++ b/MdeModulePkg/Core/Dxe/Gcd/Gcd.c
@@ -1930,9 +1930,9 @@ CoreInitializeMemoryServices (
EFI_PHYSICAL_ADDRESS MaxMemoryBaseAddress;
UINT64 MaxMemoryLength;
UINT64 MaxMemoryAttributes;
- EFI_PHYSICAL_ADDRESS MaxAddress;
+ EFI_PHYSICAL_ADDRESS TestedMemoryBaseAddress;
+ UINT64 TestedMemoryLength;
EFI_PHYSICAL_ADDRESS HighAddress;
- EFI_HOB_RESOURCE_DESCRIPTOR *MaxResourceHob;
EFI_HOB_GUID_TYPE *GuidHob;
UINT32 ReservedCodePageNumber;
@@ -1952,7 +1952,6 @@ CoreInitializeMemoryServices (
// Initialize Local Variables
//
PhitResourceHob = NULL;
- MaxResourceHob = NULL;
ResourceHob = NULL;
BaseAddress = 0;
Length = 0;
@@ -1989,43 +1988,68 @@ CoreInitializeMemoryServices (
}
//
- // Find the Resource Descriptor HOB that contains range FreeMemoryBaseAddress..FreeMemoryLength
+ // Find the Resource Descriptor HOB that contains PHIT range EfiFreeMemoryBottom..EfiFreeMemoryTop
//
Length = 0;
Found = FALSE;
for (Hob.Raw = *HobStart; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) {
+ //
+ // Skip all HOBs except Resource Descriptor HOBs
+ //
+ if (GET_HOB_TYPE (Hob) != EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
+ continue;
+ }
- if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
+ //
+ // Skip Resource Descriptor HOBs that do not describe tested system memory
+ //
+ ResourceHob = Hob.ResourceDescriptor;
+ if (ResourceHob->ResourceType != EFI_RESOURCE_SYSTEM_MEMORY) {
+ continue;
+ }
+ if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) != TESTED_MEMORY_ATTRIBUTES) {
+ continue;
+ }
- ResourceHob = Hob.ResourceDescriptor;
+ //
+ // Skip Resource Descriptor HOBs that do not contain the PHIT range EfiFreeMemoryBottom..EfiFreeMemoryTop
+ //
+ if (PhitHob->EfiFreeMemoryBottom < ResourceHob->PhysicalStart) {
+ continue;
+ }
+ if (PhitHob->EfiFreeMemoryTop > (ResourceHob->PhysicalStart + ResourceHob->ResourceLength)) {
+ continue;
+ }
- if (ResourceHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY &&
- (ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) == TESTED_MEMORY_ATTRIBUTES ) {
-
- if (PhitHob->EfiFreeMemoryBottom >= ResourceHob->PhysicalStart &&
- PhitHob->EfiFreeMemoryTop <= (ResourceHob->PhysicalStart + ResourceHob->ResourceLength) ) {
-
- //
- // Cache the resource descriptor HOB for the memory region described by the PHIT HOB
- //
- PhitResourceHob = ResourceHob;
- Found = TRUE;
-
- Attributes = PhitResourceHob->ResourceAttribute;
- BaseAddress = PageAlignAddress (PhitHob->EfiMemoryTop);
- Length = PageAlignLength (ResourceHob->PhysicalStart + ResourceHob->ResourceLength - BaseAddress);
- if (Length < MINIMUM_INITIAL_MEMORY_SIZE) {
- BaseAddress = PageAlignAddress (PhitHob->EfiFreeMemoryBottom);
- Length = PageAlignLength (PhitHob->EfiFreeMemoryTop - BaseAddress);
- if (Length < MINIMUM_INITIAL_MEMORY_SIZE) {
- BaseAddress = PageAlignAddress (ResourceHob->PhysicalStart);
- Length = PageAlignLength ((UINT64)((UINTN)*HobStart - BaseAddress));
- }
- }
- break;
- }
+ //
+ // Cache the resource descriptor HOB for the memory region described by the PHIT HOB
+ //
+ PhitResourceHob = ResourceHob;
+ Found = TRUE;
+
+ //
+ // Compute range between PHIT EfiFreeMemoryTop and the end of the Resource Descriptor HOB
+ //
+ Attributes = PhitResourceHob->ResourceAttribute;
+ BaseAddress = PageAlignAddress (PhitHob->EfiMemoryTop);
+ Length = PageAlignLength (ResourceHob->PhysicalStart + ResourceHob->ResourceLength - BaseAddress);
+ if (Length < MINIMUM_INITIAL_MEMORY_SIZE) {
+ //
+ // If that range is not large enough to intialize the DXE Core, then
+ // Compute range between PHIT EfiFreeMemoryBottom and PHIT EfiFreeMemoryTop
+ //
+ BaseAddress = PageAlignAddress (PhitHob->EfiFreeMemoryBottom);
+ Length = PageAlignLength (PhitHob->EfiFreeMemoryTop - BaseAddress);
+ if (Length < MINIMUM_INITIAL_MEMORY_SIZE) {
+ //
+ // If that range is not large enough to intialize the DXE Core, then
+ // Compute range between the start of the Resource Descriptor HOB and the start of the HOB List
+ //
+ BaseAddress = PageAlignAddress (ResourceHob->PhysicalStart);
+ Length = PageAlignLength ((UINT64)((UINTN)*HobStart - BaseAddress));
}
}
+ break;
}
//
@@ -2038,51 +2062,66 @@ CoreInitializeMemoryServices (
// region that is big enough to initialize the DXE core. Always skip the PHIT Resource HOB.
// The max address must be within the physically addressible range for the processor.
//
- MaxMemoryLength = 0;
- MaxAddress = MAX_ADDRESS;
- do {
- HighAddress = 0;
- Found = FALSE;
+ HighAddress = MAX_ADDRESS;
+ for (Hob.Raw = *HobStart; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) {
//
- // Search for a tested memory region that is below MaxAddress
+ // Skip the Resource Descriptor HOB that contains the PHIT
//
- for (Hob.Raw = *HobStart; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) {
-
- //
- // See if this is a resource descriptor HOB that does not contain the PHIT.
- //
- if (Hob.ResourceDescriptor != PhitResourceHob && GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
+ if (Hob.ResourceDescriptor == PhitResourceHob) {
+ continue;
+ }
+ //
+ // Skip all HOBs except Resource Descriptor HOBs
+ //
+ if (GET_HOB_TYPE (Hob) != EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
+ continue;
+ }
- ResourceHob = Hob.ResourceDescriptor;
- //
- // See if this resource descrior HOB describes tested system memory below MaxAddress
- //
- if (ResourceHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY &&
- (ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) == TESTED_MEMORY_ATTRIBUTES &&
- ResourceHob->PhysicalStart + ResourceHob->ResourceLength <= MaxAddress) {
- //
- // See if this is the highest tested system memory region below MaxAddress
- //
- if (ResourceHob->PhysicalStart > HighAddress) {
-
- MaxResourceHob = ResourceHob;
- HighAddress = MaxResourceHob->PhysicalStart;
- Found = TRUE;
- }
- }
- }
+ //
+ // Skip Resource Descriptor HOBs that do not describe tested system memory below MAX_ADDRESS
+ //
+ ResourceHob = Hob.ResourceDescriptor;
+ if (ResourceHob->ResourceType != EFI_RESOURCE_SYSTEM_MEMORY) {
+ continue;
}
- if (Found) {
- //
- // Compute the size of the tested memory region below MaxAddrees
- //
- MaxMemoryBaseAddress = PageAlignAddress (MaxResourceHob->PhysicalStart);
- MaxMemoryLength = PageAlignLength (MaxResourceHob->PhysicalStart + MaxResourceHob->ResourceLength - MaxMemoryBaseAddress);
- MaxMemoryAttributes = MaxResourceHob->ResourceAttribute;
+ if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) != TESTED_MEMORY_ATTRIBUTES) {
+ continue;
+ }
+ if ((ResourceHob->PhysicalStart + ResourceHob->ResourceLength) > (EFI_PHYSICAL_ADDRESS)MAX_ADDRESS) {
+ continue;
}
- MaxAddress = ResourceHob->PhysicalStart;
- } while (Found && MaxMemoryLength < MINIMUM_INITIAL_MEMORY_SIZE);
+
+ //
+ // Skip Resource Descriptor HOBs that are below a previously found Resource Descriptor HOB
+ //
+ if (HighAddress != (EFI_PHYSICAL_ADDRESS)MAX_ADDRESS && ResourceHob->PhysicalStart <= HighAddress) {
+ continue;
+ }
+
+ //
+ // Skip Resource Descriptor HOBs that are not large enough to initilize the DXE Core
+ //
+ TestedMemoryBaseAddress = PageAlignAddress (ResourceHob->PhysicalStart);
+ TestedMemoryLength = PageAlignLength (ResourceHob->PhysicalStart + ResourceHob->ResourceLength - TestedMemoryBaseAddress);
+ if (TestedMemoryLength < MINIMUM_INITIAL_MEMORY_SIZE) {
+ continue;
+ }
+
+ //
+ // Save the Resource Descriptor HOB context that is large enough to initilize the DXE Core
+ //
+ MaxMemoryBaseAddress = TestedMemoryBaseAddress;
+ MaxMemoryLength = TestedMemoryLength;
+ MaxMemoryAttributes = ResourceHob->ResourceAttribute;
+ HighAddress = ResourceHob->PhysicalStart;
+ }
+ //
+ // If Length is not large enough to initialize the DXE Core or a Resource
+ // Descriptor HOB was found above the PHIT HOB that is large enough to initialize
+ // the DXE Core, then use the range described by the Resource Descriptor
+ // HOB that was found above the PHIT HOB.
+ //
if ((Length < MINIMUM_INITIAL_MEMORY_SIZE) ||
(MaxMemoryBaseAddress > BaseAddress && MaxMemoryLength >= MINIMUM_INITIAL_MEMORY_SIZE)) {
BaseAddress = MaxMemoryBaseAddress;