REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4009
Check if there is usable memory below 4 GiB before testing for allocation without the EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE attribute. Cc: G Edhaya Chandran <edhaya.chand...@arm.com> Cc: Jeff Booher-Kaeding <jeff.booher-kaed...@arm.com> Cc: Samer El-Haj-Mahmoud <samer.el-haj-mahm...@arm.com> Cc: Sunny Wang <sunny.w...@arm.com> Signed-off-by: Dimitrije Pavlov <dimitrije.pav...@arm.com> --- uefi-sct/SctPkg/TestCase/UEFI/EFI/Protocol/PciRootBridgeIo/BlackBoxTest/PciRootBridgeIoBBTestFunction_2.c | 142 +++++++++++++++++++- 1 file changed, 140 insertions(+), 2 deletions(-) diff --git a/uefi-sct/SctPkg/TestCase/UEFI/EFI/Protocol/PciRootBridgeIo/BlackBoxTest/PciRootBridgeIoBBTestFunction_2.c b/uefi-sct/SctPkg/TestCase/UEFI/EFI/Protocol/PciRootBridgeIo/BlackBoxTest/PciRootBridgeIoBBTestFunction_2.c index 89adcba91e70..fafbf62f77c6 100644 --- a/uefi-sct/SctPkg/TestCase/UEFI/EFI/Protocol/PciRootBridgeIo/BlackBoxTest/PciRootBridgeIoBBTestFunction_2.c +++ b/uefi-sct/SctPkg/TestCase/UEFI/EFI/Protocol/PciRootBridgeIo/BlackBoxTest/PciRootBridgeIoBBTestFunction_2.c @@ -4118,7 +4118,69 @@ AllocateBuffer_Func ( UINTN AttributesNum; EFI_PCI_ROOT_BRIDGE_IO_DEVICE *RBDev; EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *RootBridgeIo; + EFI_MEMORY_DESCRIPTOR *MemoryMap; + EFI_MEMORY_DESCRIPTOR *Entry; + UINTN MemoryMapSize; + UINTN MapKey; + UINTN DescriptorSize; + UINT32 DescriptorVersion; + UINTN Iterator; + BOOLEAN UsableMemoryBelow4G; + // + // Obtain the memory map size + // + MemoryMapSize = 0; + Status = gBS->GetMemoryMap ( + &MemoryMapSize, + NULL, + &MapKey, + &DescriptorSize, + &DescriptorVersion + ); + ASSERT (Status == EFI_BUFFER_TOO_SMALL); + // + // Allocating a buffer for the memory map will change + // the memory map, so we increase the size here just in case + // + MemoryMapSize += EFI_PAGE_SIZE; + Status = gBS->AllocatePool ( + EfiLoaderData, + MemoryMapSize, + (VOID **)&MemoryMap + ); + if (EFI_ERROR (Status)) { + return Status; + } + // + // Get the actual memory map + // + Status = gBS->GetMemoryMap ( + &MemoryMapSize, + MemoryMap, + &MapKey, + &DescriptorSize, + &DescriptorVersion + ); + if (EFI_ERROR (Status)) { + gBS->FreePool (MemoryMap); + } + + // + // Check each entry in the memory map for free memory below 4 GiB and set + // UsableMemoryBelow4G accordingly + // + UsableMemoryBelow4G = FALSE; + for (Iterator = 0; Iterator < MemoryMapSize; Iterator += DescriptorSize) { + Entry = (EFI_MEMORY_DESCRIPTOR *)((UINTN)MemoryMap + Iterator); + if ( Entry->PhysicalStart < (EFI_PHYSICAL_ADDRESS)SIZE_4GB + && ( Entry->Type == EfiConventionalMemory || Entry->Type == EfiPersistentMemory)) + { + UsableMemoryBelow4G = TRUE; + break; + } + } + gBS->FreePool (MemoryMap); AllocateType = 0; @@ -4188,7 +4250,14 @@ AllocateBuffer_Func ( for (MemoryTypeNum = 0; MemoryTypeNum < 2; MemoryTypeNum++) { for (AttributesNum = 0; AttributesNum < 8; AttributesNum++) { - + // + // If there is no usable memory below 4 GiB, skip 32-bit allocations + // + if ( !UsableMemoryBelow4G + && !(Attributes[AttributesNum] & EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE)) + { + continue; + } Status = RootBridgeIo->AllocateBuffer ( RootBridgeIo, AllocateType, @@ -4298,7 +4367,69 @@ FreeBuffer_Func ( UINTN AttributesNum; EFI_PCI_ROOT_BRIDGE_IO_DEVICE *RBDev; EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *RootBridgeIo; + EFI_MEMORY_DESCRIPTOR *MemoryMap; + EFI_MEMORY_DESCRIPTOR *Entry; + UINTN MemoryMapSize; + UINTN MapKey; + UINTN DescriptorSize; + UINT32 DescriptorVersion; + UINTN Iterator; + BOOLEAN UsableMemoryBelow4G; + // + // Obtain the memory map size + // + MemoryMapSize = 0; + Status = gBS->GetMemoryMap ( + &MemoryMapSize, + NULL, + &MapKey, + &DescriptorSize, + &DescriptorVersion + ); + ASSERT (Status == EFI_BUFFER_TOO_SMALL); + // + // Allocating a buffer for the memory map will change + // the memory map, so we increase the size here just in case + // + MemoryMapSize += EFI_PAGE_SIZE; + Status = gBS->AllocatePool ( + EfiLoaderData, + MemoryMapSize, + (VOID **)&MemoryMap + ); + if (EFI_ERROR (Status)) { + return Status; + } + // + // Get the actual memory map + // + Status = gBS->GetMemoryMap ( + &MemoryMapSize, + MemoryMap, + &MapKey, + &DescriptorSize, + &DescriptorVersion + ); + if (EFI_ERROR (Status)) { + gBS->FreePool (MemoryMap); + } + + // + // Check each entry in the memory map for free memory below 4 GiB and set + // UsableMemoryBelow4G accordingly + // + UsableMemoryBelow4G = FALSE; + for (Iterator = 0; Iterator < MemoryMapSize; Iterator += DescriptorSize) { + Entry = (EFI_MEMORY_DESCRIPTOR *)((UINTN)MemoryMap + Iterator); + if ( Entry->PhysicalStart < (EFI_PHYSICAL_ADDRESS)SIZE_4GB + && ( Entry->Type == EfiConventionalMemory || Entry->Type == EfiPersistentMemory)) + { + UsableMemoryBelow4G = TRUE; + break; + } + } + gBS->FreePool (MemoryMap); AllocateType = 0 ; @@ -4368,7 +4499,14 @@ FreeBuffer_Func ( for (MemoryTypeNum = 0; MemoryTypeNum < 2; MemoryTypeNum++) { for (AttributesNum = 0; AttributesNum < 8; AttributesNum++) { - + // + // If there is no usable memory below 4 GiB, skip 32-bit allocations + // + if ( !UsableMemoryBelow4G + && !(Attributes[AttributesNum] & EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE)) + { + continue; + } Status = RootBridgeIo->AllocateBuffer ( RootBridgeIo, AllocateType, -- 2.37.3 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#94859): https://edk2.groups.io/g/devel/message/94859 Mute This Topic: https://groups.io/mt/94228672/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-