mirror of https://github.com/acidanthera/audk.git
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
This commit is contained in:
parent
f26b6a9cda
commit
c4c085a2a6
|
@ -1930,9 +1930,9 @@ CoreInitializeMemoryServices (
|
||||||
EFI_PHYSICAL_ADDRESS MaxMemoryBaseAddress;
|
EFI_PHYSICAL_ADDRESS MaxMemoryBaseAddress;
|
||||||
UINT64 MaxMemoryLength;
|
UINT64 MaxMemoryLength;
|
||||||
UINT64 MaxMemoryAttributes;
|
UINT64 MaxMemoryAttributes;
|
||||||
EFI_PHYSICAL_ADDRESS MaxAddress;
|
EFI_PHYSICAL_ADDRESS TestedMemoryBaseAddress;
|
||||||
|
UINT64 TestedMemoryLength;
|
||||||
EFI_PHYSICAL_ADDRESS HighAddress;
|
EFI_PHYSICAL_ADDRESS HighAddress;
|
||||||
EFI_HOB_RESOURCE_DESCRIPTOR *MaxResourceHob;
|
|
||||||
EFI_HOB_GUID_TYPE *GuidHob;
|
EFI_HOB_GUID_TYPE *GuidHob;
|
||||||
UINT32 ReservedCodePageNumber;
|
UINT32 ReservedCodePageNumber;
|
||||||
|
|
||||||
|
@ -1952,7 +1952,6 @@ CoreInitializeMemoryServices (
|
||||||
// Initialize Local Variables
|
// Initialize Local Variables
|
||||||
//
|
//
|
||||||
PhitResourceHob = NULL;
|
PhitResourceHob = NULL;
|
||||||
MaxResourceHob = NULL;
|
|
||||||
ResourceHob = NULL;
|
ResourceHob = NULL;
|
||||||
BaseAddress = 0;
|
BaseAddress = 0;
|
||||||
Length = 0;
|
Length = 0;
|
||||||
|
@ -1989,21 +1988,38 @@ CoreInitializeMemoryServices (
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Find the Resource Descriptor HOB that contains range FreeMemoryBaseAddress..FreeMemoryLength
|
// Find the Resource Descriptor HOB that contains PHIT range EfiFreeMemoryBottom..EfiFreeMemoryTop
|
||||||
//
|
//
|
||||||
Length = 0;
|
Length = 0;
|
||||||
Found = FALSE;
|
Found = FALSE;
|
||||||
for (Hob.Raw = *HobStart; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) {
|
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;
|
ResourceHob = Hob.ResourceDescriptor;
|
||||||
|
if (ResourceHob->ResourceType != EFI_RESOURCE_SYSTEM_MEMORY) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) != TESTED_MEMORY_ATTRIBUTES) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (ResourceHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY &&
|
//
|
||||||
(ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) == TESTED_MEMORY_ATTRIBUTES ) {
|
// Skip Resource Descriptor HOBs that do not contain the PHIT range EfiFreeMemoryBottom..EfiFreeMemoryTop
|
||||||
|
//
|
||||||
if (PhitHob->EfiFreeMemoryBottom >= ResourceHob->PhysicalStart &&
|
if (PhitHob->EfiFreeMemoryBottom < ResourceHob->PhysicalStart) {
|
||||||
PhitHob->EfiFreeMemoryTop <= (ResourceHob->PhysicalStart + ResourceHob->ResourceLength) ) {
|
continue;
|
||||||
|
}
|
||||||
|
if (PhitHob->EfiFreeMemoryTop > (ResourceHob->PhysicalStart + ResourceHob->ResourceLength)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Cache the resource descriptor HOB for the memory region described by the PHIT HOB
|
// Cache the resource descriptor HOB for the memory region described by the PHIT HOB
|
||||||
|
@ -2011,22 +2027,30 @@ CoreInitializeMemoryServices (
|
||||||
PhitResourceHob = ResourceHob;
|
PhitResourceHob = ResourceHob;
|
||||||
Found = TRUE;
|
Found = TRUE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Compute range between PHIT EfiFreeMemoryTop and the end of the Resource Descriptor HOB
|
||||||
|
//
|
||||||
Attributes = PhitResourceHob->ResourceAttribute;
|
Attributes = PhitResourceHob->ResourceAttribute;
|
||||||
BaseAddress = PageAlignAddress (PhitHob->EfiMemoryTop);
|
BaseAddress = PageAlignAddress (PhitHob->EfiMemoryTop);
|
||||||
Length = PageAlignLength (ResourceHob->PhysicalStart + ResourceHob->ResourceLength - BaseAddress);
|
Length = PageAlignLength (ResourceHob->PhysicalStart + ResourceHob->ResourceLength - BaseAddress);
|
||||||
if (Length < MINIMUM_INITIAL_MEMORY_SIZE) {
|
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);
|
BaseAddress = PageAlignAddress (PhitHob->EfiFreeMemoryBottom);
|
||||||
Length = PageAlignLength (PhitHob->EfiFreeMemoryTop - BaseAddress);
|
Length = PageAlignLength (PhitHob->EfiFreeMemoryTop - BaseAddress);
|
||||||
if (Length < MINIMUM_INITIAL_MEMORY_SIZE) {
|
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);
|
BaseAddress = PageAlignAddress (ResourceHob->PhysicalStart);
|
||||||
Length = PageAlignLength ((UINT64)((UINTN)*HobStart - BaseAddress));
|
Length = PageAlignLength ((UINT64)((UINTN)*HobStart - BaseAddress));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Assert if a resource descriptor HOB for the memory region described by the PHIT was not found
|
// Assert if a resource descriptor HOB for the memory region described by the PHIT was not found
|
||||||
|
@ -2038,51 +2062,66 @@ CoreInitializeMemoryServices (
|
||||||
// region that is big enough to initialize the DXE core. Always skip the PHIT Resource HOB.
|
// 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.
|
// The max address must be within the physically addressible range for the processor.
|
||||||
//
|
//
|
||||||
MaxMemoryLength = 0;
|
HighAddress = MAX_ADDRESS;
|
||||||
MaxAddress = MAX_ADDRESS;
|
|
||||||
do {
|
|
||||||
HighAddress = 0;
|
|
||||||
Found = FALSE;
|
|
||||||
//
|
|
||||||
// Search for a tested memory region that is below MaxAddress
|
|
||||||
//
|
|
||||||
for (Hob.Raw = *HobStart; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) {
|
for (Hob.Raw = *HobStart; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) {
|
||||||
|
//
|
||||||
|
// Skip the Resource Descriptor HOB that contains the PHIT
|
||||||
|
//
|
||||||
|
if (Hob.ResourceDescriptor == PhitResourceHob) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Skip all HOBs except Resource Descriptor HOBs
|
||||||
|
//
|
||||||
|
if (GET_HOB_TYPE (Hob) != EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// See if this is a resource descriptor HOB that does not contain the PHIT.
|
// Skip Resource Descriptor HOBs that do not describe tested system memory below MAX_ADDRESS
|
||||||
//
|
//
|
||||||
if (Hob.ResourceDescriptor != PhitResourceHob && GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
|
|
||||||
|
|
||||||
ResourceHob = Hob.ResourceDescriptor;
|
ResourceHob = Hob.ResourceDescriptor;
|
||||||
//
|
if (ResourceHob->ResourceType != EFI_RESOURCE_SYSTEM_MEMORY) {
|
||||||
// See if this resource descrior HOB describes tested system memory below MaxAddress
|
continue;
|
||||||
//
|
}
|
||||||
if (ResourceHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY &&
|
if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) != TESTED_MEMORY_ATTRIBUTES) {
|
||||||
(ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) == TESTED_MEMORY_ATTRIBUTES &&
|
continue;
|
||||||
ResourceHob->PhysicalStart + ResourceHob->ResourceLength <= MaxAddress) {
|
}
|
||||||
//
|
if ((ResourceHob->PhysicalStart + ResourceHob->ResourceLength) > (EFI_PHYSICAL_ADDRESS)MAX_ADDRESS) {
|
||||||
// See if this is the highest tested system memory region below MaxAddress
|
continue;
|
||||||
//
|
}
|
||||||
if (ResourceHob->PhysicalStart > HighAddress) {
|
|
||||||
|
|
||||||
MaxResourceHob = ResourceHob;
|
|
||||||
HighAddress = MaxResourceHob->PhysicalStart;
|
|
||||||
Found = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Found) {
|
|
||||||
//
|
//
|
||||||
// Compute the size of the tested memory region below MaxAddrees
|
// Skip Resource Descriptor HOBs that are below a previously found Resource Descriptor HOB
|
||||||
//
|
//
|
||||||
MaxMemoryBaseAddress = PageAlignAddress (MaxResourceHob->PhysicalStart);
|
if (HighAddress != (EFI_PHYSICAL_ADDRESS)MAX_ADDRESS && ResourceHob->PhysicalStart <= HighAddress) {
|
||||||
MaxMemoryLength = PageAlignLength (MaxResourceHob->PhysicalStart + MaxResourceHob->ResourceLength - MaxMemoryBaseAddress);
|
continue;
|
||||||
MaxMemoryAttributes = MaxResourceHob->ResourceAttribute;
|
|
||||||
}
|
}
|
||||||
MaxAddress = ResourceHob->PhysicalStart;
|
|
||||||
} while (Found && MaxMemoryLength < MINIMUM_INITIAL_MEMORY_SIZE);
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// 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) ||
|
if ((Length < MINIMUM_INITIAL_MEMORY_SIZE) ||
|
||||||
(MaxMemoryBaseAddress > BaseAddress && MaxMemoryLength >= MINIMUM_INITIAL_MEMORY_SIZE)) {
|
(MaxMemoryBaseAddress > BaseAddress && MaxMemoryLength >= MINIMUM_INITIAL_MEMORY_SIZE)) {
|
||||||
BaseAddress = MaxMemoryBaseAddress;
|
BaseAddress = MaxMemoryBaseAddress;
|
||||||
|
|
Loading…
Reference in New Issue