ArmPkg/BdsLib: Fix GetSystemMemoryResources()

The function was not correctly merging the system memory chunks.



git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11479 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
oliviermartin 2011-03-31 12:17:37 +00:00
parent bad880b172
commit cf3a77a02a

View File

@ -103,81 +103,121 @@ BdsConnectAllDrivers( VOID ) {
return EFI_SUCCESS; return EFI_SUCCESS;
} }
STATIC EFI_STATUS InsertSystemMemoryResources(LIST_ENTRY *ResourceList, EFI_HOB_RESOURCE_DESCRIPTOR *ResHob) { STATIC
BDS_SYSTEM_MEMORY_RESOURCE NewResource; EFI_STATUS
LIST_ENTRY *Link; InsertSystemMemoryResources (
BDS_SYSTEM_MEMORY_RESOURCE *Resource; LIST_ENTRY *ResourceList,
EFI_HOB_RESOURCE_DESCRIPTOR *ResHob
)
{
BDS_SYSTEM_MEMORY_RESOURCE *NewResource;
LIST_ENTRY *Link;
LIST_ENTRY *NextLink;
LIST_ENTRY AttachedResources;
BDS_SYSTEM_MEMORY_RESOURCE *Resource;
EFI_PHYSICAL_ADDRESS NewResourceEnd;
//DEBUG ((EFI_D_ERROR, "** InsertSystemMemoryResources(0x%X,0x%X)\n",(UINT32)ResHob->PhysicalStart,(UINT32)ResHob->ResourceLength)); if (IsListEmpty (ResourceList)) {
NewResource = AllocateZeroPool (sizeof(BDS_SYSTEM_MEMORY_RESOURCE));
if (IsListEmpty (ResourceList)) { NewResource->PhysicalStart = ResHob->PhysicalStart;
ZeroMem(&NewResource,sizeof(BDS_SYSTEM_MEMORY_RESOURCE)); NewResource->ResourceLength = ResHob->ResourceLength;
NewResource.PhysicalStart = ResHob->PhysicalStart; InsertTailList (ResourceList, &NewResource->Link);
NewResource.ResourceLength = ResHob->ResourceLength;
InsertTailList (ResourceList, &NewResource.Link);
return EFI_SUCCESS;
}
//for (Link = GetFirstNode (ResourceList); !IsNull (ResourceList,Link); Link = GetNextNode (ResourceList,Link)) {
Link = ResourceList->ForwardLink;
while (Link != NULL && Link != ResourceList) {
Resource = (BDS_SYSTEM_MEMORY_RESOURCE*)Link;
//DEBUG ((EFI_D_ERROR, " - (0x%X,0x%X)\n",(UINT32)Resource->PhysicalStart,(UINT32)Resource->ResourceLength));
// Sanity Check. The resources should not overlapped.
ASSERT(!((ResHob->PhysicalStart >= Resource->PhysicalStart) && (ResHob->PhysicalStart < (Resource->PhysicalStart + Resource->ResourceLength))));
ASSERT(!((ResHob->PhysicalStart + ResHob->ResourceLength >= Resource->PhysicalStart) &&
((ResHob->PhysicalStart + ResHob->ResourceLength) < (Resource->PhysicalStart + Resource->ResourceLength))));
// The new resource is attached after this resource descriptor
if (ResHob->PhysicalStart == Resource->PhysicalStart + Resource->ResourceLength) {
Resource->ResourceLength = Resource->ResourceLength + ResHob->ResourceLength;
//DEBUG ((EFI_D_ERROR, "** Attached new Length:0x%X\n",(UINT32)Resource->ResourceLength));
return EFI_SUCCESS;
}
// The new resource is attached before this resource descriptor
else if (ResHob->PhysicalStart + ResHob->ResourceLength == Resource->PhysicalStart) {
Resource->PhysicalStart = ResHob->PhysicalStart;
Resource->ResourceLength = Resource->ResourceLength + ResHob->ResourceLength;
//DEBUG ((EFI_D_ERROR, "** Attached2 new Length:0x%X\n",(UINT32)Resource->ResourceLength));
return EFI_SUCCESS;
}
Link = Link->ForwardLink;
}
// None of the Resource of the list is attached to this ResHob. Create a new entry for it
ZeroMem(&NewResource,sizeof(BDS_SYSTEM_MEMORY_RESOURCE));
NewResource.PhysicalStart = ResHob->PhysicalStart;
NewResource.ResourceLength = ResHob->ResourceLength;
InsertTailList (ResourceList, &NewResource.Link);
return EFI_SUCCESS; return EFI_SUCCESS;
} }
EFI_STATUS GetSystemMemoryResources(LIST_ENTRY *ResourceList) { InitializeListHead (&AttachedResources);
EFI_HOB_RESOURCE_DESCRIPTOR *ResHob;
InitializeListHead (ResourceList); Link = ResourceList->ForwardLink;
ASSERT (Link != NULL);
while (Link != ResourceList) {
Resource = (BDS_SYSTEM_MEMORY_RESOURCE*)Link;
// Find the first System Memory Resource Descriptor // Sanity Check. The resources should not overlapped.
ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR); ASSERT(!((ResHob->PhysicalStart >= Resource->PhysicalStart) && (ResHob->PhysicalStart < (Resource->PhysicalStart + Resource->ResourceLength))));
while ((ResHob != NULL) && (ResHob->ResourceType != EFI_RESOURCE_SYSTEM_MEMORY)) { ASSERT(!((ResHob->PhysicalStart + ResHob->ResourceLength - 1 >= Resource->PhysicalStart) &&
ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,(VOID *)((UINTN)ResHob + ResHob->Header.HobLength)); ((ResHob->PhysicalStart + ResHob->ResourceLength - 1) < (Resource->PhysicalStart + Resource->ResourceLength))));
// The new resource is attached after this resource descriptor
if (ResHob->PhysicalStart == Resource->PhysicalStart + Resource->ResourceLength) {
Resource->ResourceLength = Resource->ResourceLength + ResHob->ResourceLength;
NextLink = RemoveEntryList (&Resource->Link);
InsertTailList (&AttachedResources, &Resource->Link);
Link = NextLink;
} }
// The new resource is attached before this resource descriptor
else if (ResHob->PhysicalStart + ResHob->ResourceLength == Resource->PhysicalStart) {
Resource->PhysicalStart = ResHob->PhysicalStart;
Resource->ResourceLength = Resource->ResourceLength + ResHob->ResourceLength;
// Did not find any NextLink = RemoveEntryList (&Resource->Link);
if (ResHob == NULL) { InsertTailList (&AttachedResources, &Resource->Link);
return EFI_NOT_FOUND; Link = NextLink;
} else { } else {
InsertSystemMemoryResources(ResourceList, ResHob); Link = Link->ForwardLink;
} }
}
ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,(VOID *)((UINTN)ResHob + ResHob->Header.HobLength)); if (!IsListEmpty (&AttachedResources)) {
while (ResHob != NULL) { // See if we can merge the attached resource with other resources
if (ResHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) {
InsertSystemMemoryResources(ResourceList, ResHob); NewResource = (BDS_SYSTEM_MEMORY_RESOURCE*)GetFirstNode (&AttachedResources);
} Link = RemoveEntryList (&NewResource->Link);
ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,(VOID *)((UINTN)ResHob + ResHob->Header.HobLength)); while (!IsListEmpty (&AttachedResources)) {
// Merge resources
Resource = (BDS_SYSTEM_MEMORY_RESOURCE*)Link;
// Ensure they overlap each other
ASSERT(
((NewResource->PhysicalStart >= Resource->PhysicalStart) && (NewResource->PhysicalStart < (Resource->PhysicalStart + Resource->ResourceLength))) ||
(((NewResource->PhysicalStart + NewResource->ResourceLength) >= Resource->PhysicalStart) && ((NewResource->PhysicalStart + NewResource->ResourceLength) < (Resource->PhysicalStart + Resource->ResourceLength)))
);
NewResourceEnd = MAX (NewResource->PhysicalStart + NewResource->ResourceLength, Resource->PhysicalStart + Resource->ResourceLength);
NewResource->PhysicalStart = MIN (NewResource->PhysicalStart, Resource->PhysicalStart);
NewResource->ResourceLength = NewResourceEnd - NewResource->PhysicalStart;
Link = RemoveEntryList (Link);
} }
} else {
return EFI_SUCCESS; // None of the Resource of the list is attached to this ResHob. Create a new entry for it
NewResource = AllocateZeroPool (sizeof(BDS_SYSTEM_MEMORY_RESOURCE));
NewResource->PhysicalStart = ResHob->PhysicalStart;
NewResource->ResourceLength = ResHob->ResourceLength;
}
InsertTailList (ResourceList, &NewResource->Link);
return EFI_SUCCESS;
}
EFI_STATUS
GetSystemMemoryResources (
IN LIST_ENTRY *ResourceList
)
{
EFI_HOB_RESOURCE_DESCRIPTOR *ResHob;
InitializeListHead (ResourceList);
// Find the first System Memory Resource Descriptor
ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR);
while ((ResHob != NULL) && (ResHob->ResourceType != EFI_RESOURCE_SYSTEM_MEMORY)) {
ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,(VOID *)((UINTN)ResHob + ResHob->Header.HobLength));
}
// Did not find any
if (ResHob == NULL) {
return EFI_NOT_FOUND;
} else {
InsertSystemMemoryResources (ResourceList, ResHob);
}
ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,(VOID *)((UINTN)ResHob + ResHob->Header.HobLength));
while (ResHob != NULL) {
if (ResHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) {
InsertSystemMemoryResources (ResourceList, ResHob);
}
ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,(VOID *)((UINTN)ResHob + ResHob->Header.HobLength));
}
return EFI_SUCCESS;
} }