diff mbox series

[edk2,1/5] EmbeddedPkg/DmaLib: add routine to allocate aligned buffers

Message ID 20170825121014.15739-2-ard.biesheuvel@linaro.org
State Accepted
Commit deef290f95e0df80549d2a6cbd7edae104c82709
Headers show
Series ArmPkg et al: remove UncachedMemoryallocationLib | expand

Commit Message

Ard Biesheuvel Aug. 25, 2017, 12:10 p.m. UTC
DmaLib's purpose is to manage memory that is shared between the host
and DMA capable devices. In some cases, this requires a larger alignment
than page size, and we currently don't cater for that in DmaLib. So add
a variant of DmaAllocateBuffer () that takes an alignment parameter.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

---
 EmbeddedPkg/Include/Library/DmaLib.h        | 30 +++++++++++-
 EmbeddedPkg/Library/NullDmaLib/NullDmaLib.c | 48 ++++++++++++++++++--
 2 files changed, 72 insertions(+), 6 deletions(-)

-- 
2.11.0

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
diff mbox series

Patch

diff --git a/EmbeddedPkg/Include/Library/DmaLib.h b/EmbeddedPkg/Include/Library/DmaLib.h
index 3814291c2875..1843814c65ca 100644
--- a/EmbeddedPkg/Include/Library/DmaLib.h
+++ b/EmbeddedPkg/Include/Library/DmaLib.h
@@ -155,5 +155,33 @@  DmaFreeBuffer (
   );
 
 
-#endif
+/**
+  Allocates pages that are suitable for an DmaMap() of type
+  MapOperationBusMasterCommonBuffer mapping, at the requested alignment.
+
+  @param  MemoryType            The type of memory to allocate, EfiBootServicesData or
+                                EfiRuntimeServicesData.
+  @param  Pages                 The number of pages to allocate.
+  @param  Alignment             Alignment in bytes of the base of the returned
+                                buffer (must be a power of 2)
+  @param  HostAddress           A pointer to store the base system memory address of the
+                                allocated range.
 
+  @retval EFI_SUCCESS           The requested memory pages were allocated.
+  @retval EFI_UNSUPPORTED       Attributes is unsupported. The only legal attribute bits are
+                                MEMORY_WRITE_COMBINE and MEMORY_CACHED.
+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
+  @retval EFI_OUT_OF_RESOURCES  The memory pages could not be allocated.
+
+**/
+EFI_STATUS
+EFIAPI
+DmaAllocateAlignedBuffer (
+  IN  EFI_MEMORY_TYPE              MemoryType,
+  IN  UINTN                        Pages,
+  IN  UINTN                        Alignment,
+  OUT VOID                         **HostAddress
+  );
+
+
+#endif
diff --git a/EmbeddedPkg/Library/NullDmaLib/NullDmaLib.c b/EmbeddedPkg/Library/NullDmaLib/NullDmaLib.c
index a0bb57541d60..4cbe349190a9 100644
--- a/EmbeddedPkg/Library/NullDmaLib/NullDmaLib.c
+++ b/EmbeddedPkg/Library/NullDmaLib/NullDmaLib.c
@@ -100,23 +100,61 @@  DmaAllocateBuffer (
   OUT VOID                         **HostAddress
   )
 {
-  if (HostAddress == NULL) {
+  return DmaAllocateAlignedBuffer (MemoryType, Pages, 0, HostAddress);
+}
+
+
+/**
+  Allocates pages that are suitable for an DmaMap() of type
+  MapOperationBusMasterCommonBuffer mapping, at the requested alignment.
+
+  @param  MemoryType            The type of memory to allocate, EfiBootServicesData or
+                                EfiRuntimeServicesData.
+  @param  Pages                 The number of pages to allocate.
+  @param  Alignment             Alignment in bytes of the base of the returned
+                                buffer (must be a power of 2)
+  @param  HostAddress           A pointer to store the base system memory address of the
+                                allocated range.
+
+  @retval EFI_SUCCESS           The requested memory pages were allocated.
+  @retval EFI_UNSUPPORTED       Attributes is unsupported. The only legal attribute bits are
+                                MEMORY_WRITE_COMBINE and MEMORY_CACHED.
+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
+  @retval EFI_OUT_OF_RESOURCES  The memory pages could not be allocated.
+
+**/
+EFI_STATUS
+EFIAPI
+DmaAllocateAlignedBuffer (
+  IN  EFI_MEMORY_TYPE              MemoryType,
+  IN  UINTN                        Pages,
+  IN  UINTN                        Alignment,
+  OUT VOID                         **HostAddress
+  )
+{
+  if (Alignment == 0) {
+    Alignment = EFI_PAGE_SIZE;
+  }
+
+  if (HostAddress == NULL ||
+      (Alignment & (Alignment - 1)) != 0) {
     return EFI_INVALID_PARAMETER;
   }
 
   //
   // The only valid memory types are EfiBootServicesData and EfiRuntimeServicesData
   //
-  // We used uncached memory to keep coherency
-  //
   if (MemoryType == EfiBootServicesData) {
-    *HostAddress = AllocatePages (Pages);
+    *HostAddress = AllocateAlignedPages (Pages, Alignment);
   } else if (MemoryType != EfiRuntimeServicesData) {
-    *HostAddress = AllocateRuntimePages (Pages);
+    *HostAddress = AllocateAlignedRuntimePages (Pages, Alignment);
   } else {
     return EFI_INVALID_PARAMETER;
   }
 
+  if (*HostAddress == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
   return EFI_SUCCESS;
 }