public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [edk2-test][PATCH v1 1/1] uefi-sct/SctPkg: Check for memory below 4G
@ 2022-10-10  2:05 Dimitrije Pavlov
  2022-12-01 15:19 ` [edk2-devel] " G Edhaya Chandran
  2022-12-01 17:11 ` Sunny Wang
  0 siblings, 2 replies; 5+ messages in thread
From: Dimitrije Pavlov @ 2022-10-10  2:05 UTC (permalink / raw)
  To: devel
  Cc: G Edhaya Chandran, Jeff Booher-Kaeding, Samer El-Haj-Mahmoud,
	Sunny Wang

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.Chandran@arm.com>
Cc: Jeff Booher-Kaeding <Jeff.Booher-Kaeding@arm.com>
Cc: Samer El-Haj-Mahmoud <Samer.El-Haj-Mahmoud@arm.com>
Cc: Sunny Wang <Sunny.Wang@arm.com>

Signed-off-by: Dimitrije Pavlov <Dimitrije.Pavlov@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


^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2023-07-20 15:40 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-10-10  2:05 [edk2-test][PATCH v1 1/1] uefi-sct/SctPkg: Check for memory below 4G Dimitrije Pavlov
2022-12-01 15:19 ` [edk2-devel] " G Edhaya Chandran
2022-12-01 17:11 ` Sunny Wang
2023-07-20 14:29   ` [edk2-devel] " G Edhaya Chandran
2023-07-20 15:40     ` Ard Biesheuvel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox