diff options
author | rsun3 <rsun3@6f19259b-4bc3-4df7-8a09-765794883524> | 2011-07-13 08:40:55 +0000 |
---|---|---|
committer | rsun3 <rsun3@6f19259b-4bc3-4df7-8a09-765794883524> | 2011-07-13 08:40:55 +0000 |
commit | c4c085a2a680afc712b40e37f5aeb69ce25478ce (patch) | |
tree | 7d69186aa7c4ae740c93af1016da3428b8f1e282 /MdeModulePkg/Core/Dxe | |
parent | f26b6a9cda0c5dd29eb045992ad7a41991971ede (diff) | |
download | edk2-c4c085a2a680afc712b40e37f5aeb69ce25478ce.zip edk2-c4c085a2a680afc712b40e37f5aeb69ce25478ce.tar.gz edk2-c4c085a2a680afc712b40e37f5aeb69ce25478ce.tar.bz2 |
Fix an issue that there may be an infinite loop in the CoreInitializeMemoryServices() in Gcd.c of the DXE Core. Also update logic to use continue statements to reduce the level of nesting in the two loops that search the HOB lists. More comment are added.
Signed-off-by: rsun3
Reviewed-by: mdkinney
Reviewed-by: lgao4
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12015 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'MdeModulePkg/Core/Dxe')
-rw-r--r-- | MdeModulePkg/Core/Dxe/Gcd/Gcd.c | 179 |
1 files changed, 109 insertions, 70 deletions
diff --git a/MdeModulePkg/Core/Dxe/Gcd/Gcd.c b/MdeModulePkg/Core/Dxe/Gcd/Gcd.c index 0ec75ca..ab8677a 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;
|