diff --git a/ArmPkg/Library/BdsLib/BdsHelper.c b/ArmPkg/Library/BdsLib/BdsHelper.c index 896ae73820..88e8fa3453 100644 --- a/ArmPkg/Library/BdsLib/BdsHelper.c +++ b/ArmPkg/Library/BdsLib/BdsHelper.c @@ -103,81 +103,121 @@ BdsConnectAllDrivers( VOID ) { return EFI_SUCCESS; } -STATIC EFI_STATUS InsertSystemMemoryResources(LIST_ENTRY *ResourceList, EFI_HOB_RESOURCE_DESCRIPTOR *ResHob) { - BDS_SYSTEM_MEMORY_RESOURCE NewResource; - LIST_ENTRY *Link; - BDS_SYSTEM_MEMORY_RESOURCE *Resource; +STATIC +EFI_STATUS +InsertSystemMemoryResources ( + 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)) { - ZeroMem(&NewResource,sizeof(BDS_SYSTEM_MEMORY_RESOURCE)); - NewResource.PhysicalStart = ResHob->PhysicalStart; - 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); + if (IsListEmpty (ResourceList)) { + 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(LIST_ENTRY *ResourceList) { - EFI_HOB_RESOURCE_DESCRIPTOR *ResHob; + InitializeListHead (&AttachedResources); - 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)); + Link = ResourceList->ForwardLink; + ASSERT (Link != NULL); + while (Link != ResourceList) { + Resource = (BDS_SYSTEM_MEMORY_RESOURCE*)Link; + + // Sanity Check. The resources should not overlapped. + ASSERT(!((ResHob->PhysicalStart >= Resource->PhysicalStart) && (ResHob->PhysicalStart < (Resource->PhysicalStart + Resource->ResourceLength)))); + ASSERT(!((ResHob->PhysicalStart + ResHob->ResourceLength - 1 >= Resource->PhysicalStart) && + ((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 - if (ResHob == NULL) { - return EFI_NOT_FOUND; + NextLink = RemoveEntryList (&Resource->Link); + InsertTailList (&AttachedResources, &Resource->Link); + Link = NextLink; } else { - InsertSystemMemoryResources(ResourceList, ResHob); + Link = Link->ForwardLink; } + } - 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)); + if (!IsListEmpty (&AttachedResources)) { + // See if we can merge the attached resource with other resources + + NewResource = (BDS_SYSTEM_MEMORY_RESOURCE*)GetFirstNode (&AttachedResources); + Link = RemoveEntryList (&NewResource->Link); + 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); } - - return EFI_SUCCESS; + } else { + // 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; }