]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ArmPkg/Library/ArmDmaLib/ArmDmaLib.c
ArmPkg: Fix ARMGCC build
[mirror_edk2.git] / ArmPkg / Library / ArmDmaLib / ArmDmaLib.c
index 9467fa5b474ea9cda23bcf157f2c109fe5314c8b..4764b4237a975c388a228138b763aa0eea9cf9e7 100755 (executable)
 \r
 **/\r
 \r
-#include <Base.h>\r
+#include <PiDxe.h>\r
 #include <Library/DebugLib.h>\r
 #include <Library/DmaLib.h>\r
+#include <Library/DxeServicesTableLib.h>\r
 #include <Library/MemoryAllocationLib.h>\r
 #include <Library/UefiBootServicesTableLib.h>\r
 #include <Library/UncachedMemoryAllocationLib.h>\r
@@ -38,9 +39,6 @@ typedef struct {
 EFI_CPU_ARCH_PROTOCOL      *gCpu;\r
 UINTN                      gCacheAlignment = 0;\r
 \r
-\r
-\r
-\r
 /**                                                                 \r
   Provides the DMA controller-specific addresses needed to access system memory.\r
   \r
@@ -71,15 +69,14 @@ DmaMap (
   OUT    VOID                           **Mapping\r
   )\r
 {\r
-  EFI_STATUS            Status;\r
-  MAP_INFO_INSTANCE     *Map;\r
-  VOID                  *Buffer;\r
+  EFI_STATUS                      Status;\r
+  MAP_INFO_INSTANCE               *Map;\r
+  VOID                            *Buffer;\r
+  EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdDescriptor;\r
 \r
-  if ( HostAddress == NULL || NumberOfBytes == NULL || \r
-       DeviceAddress == NULL || Mapping == NULL ) {\r
+  if (HostAddress == NULL || NumberOfBytes == NULL || DeviceAddress == NULL || Mapping == NULL ) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
-  \r
 \r
   if (Operation >= MapOperationMaximum) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -95,37 +92,53 @@ DmaMap (
   \r
   *Mapping = Map;\r
 \r
-  if (((UINTN)HostAddress & (gCacheAlignment - 1)) != 0) {\r
-    Map->DoubleBuffer  = TRUE;\r
-    Status = DmaAllocateBuffer (EfiBootServicesData, EFI_SIZE_TO_PAGES (*NumberOfBytes), &Buffer);\r
-    if (EFI_ERROR (Status)) {\r
+  if ((((UINTN)HostAddress & (gCacheAlignment - 1)) != 0) ||\r
+      ((*NumberOfBytes % gCacheAlignment) != 0)) {\r
+\r
+    // Get the cacheability of the region\r
+    Status = gDS->GetMemorySpaceDescriptor (*DeviceAddress, &GcdDescriptor);\r
+    if (EFI_ERROR(Status)) {\r
       return Status;\r
     }\r
-    \r
-    *DeviceAddress = (PHYSICAL_ADDRESS)(UINTN)Buffer;\r
-    \r
+\r
+    // If the mapped buffer is not an uncached buffer\r
+    if (GcdDescriptor.Attributes != EFI_MEMORY_UC) {\r
+      //\r
+      // If the buffer does not fill entire cache lines we must double buffer into\r
+      // uncached memory. Device (PCI) address becomes uncached page.\r
+      //\r
+      Map->DoubleBuffer  = TRUE;\r
+      Status = DmaAllocateBuffer (EfiBootServicesData, EFI_SIZE_TO_PAGES (*NumberOfBytes), &Buffer);\r
+      if (EFI_ERROR (Status)) {\r
+        return Status;\r
+      }\r
+\r
+      if ((Operation == MapOperationBusMasterRead) || (Operation == MapOperationBusMasterCommonBuffer)) {\r
+        CopyMem (Buffer, HostAddress, *NumberOfBytes);\r
+      }\r
+\r
+      *DeviceAddress = (PHYSICAL_ADDRESS)(UINTN)Buffer;\r
+    } else {\r
+      Map->DoubleBuffer  = FALSE;\r
+    }\r
   } else {\r
     Map->DoubleBuffer  = FALSE;\r
+\r
+    // Flush the Data Cache (should not have any effect if the memory region is uncached)\r
+    gCpu->FlushDataCache (gCpu, *DeviceAddress, *NumberOfBytes, EfiCpuFlushTypeWriteBackInvalidate);\r
+\r
+    if ((Operation == MapOperationBusMasterRead) || (Operation == MapOperationBusMasterCommonBuffer)) {\r
+      // In case the buffer is used for instance to send command to a PCI controller, we must ensure the memory is uncached\r
+      Status = gDS->SetMemorySpaceAttributes (ALIGN_VALUE(*DeviceAddress - BASE_4KB - 1,BASE_4KB), ALIGN_VALUE(*NumberOfBytes,BASE_4KB), EFI_MEMORY_UC);\r
+      ASSERT_EFI_ERROR (Status);\r
+    }\r
   }\r
 \r
-  *NumberOfBytes &= *NumberOfBytes & ~(gCacheAlignment - 1); // Only do it on full cache lines\r
-  \r
   Map->HostAddress   = (UINTN)HostAddress;\r
   Map->DeviceAddress = *DeviceAddress;\r
   Map->NumberOfBytes = *NumberOfBytes;\r
   Map->Operation     = Operation;\r
 \r
-  if (Map->DoubleBuffer) {\r
-    if (Map->Operation == MapOperationBusMasterWrite) {\r
-      CopyMem ((VOID *)(UINTN)Map->DeviceAddress, (VOID *)(UINTN)Map->HostAddress, Map->NumberOfBytes);\r
-    }\r
-  } else {\r
-    // EfiCpuFlushTypeWriteBack, EfiCpuFlushTypeInvalidate\r
-    if (Map->Operation == MapOperationBusMasterWrite || Map->Operation == MapOperationBusMasterRead) {\r
-      gCpu->FlushDataCache (gCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)HostAddress,  Map->NumberOfBytes, EfiCpuFlushTypeWriteBackInvalidate);\r
-    }\r
-  }\r
-  \r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -156,7 +169,7 @@ DmaUnmap (
   Map = (MAP_INFO_INSTANCE *)Mapping;\r
   \r
   if (Map->DoubleBuffer) {\r
-    if (Map->Operation == MapOperationBusMasterRead) {\r
+    if ((Map->Operation == MapOperationBusMasterWrite) || (Map->Operation == MapOperationBusMasterCommonBuffer)) {\r
       CopyMem ((VOID *)(UINTN)Map->HostAddress, (VOID *)(UINTN)Map->DeviceAddress, Map->NumberOfBytes);\r
     }\r
     \r
@@ -212,7 +225,7 @@ DmaAllocateBuffer (
   //\r
   if (MemoryType == EfiBootServicesData) {\r
     *HostAddress = UncachedAllocatePages (Pages);\r
-  } else if (MemoryType != EfiRuntimeServicesData) {\r
+  } else if (MemoryType == EfiRuntimeServicesData) {\r
     *HostAddress = UncachedAllocateRuntimePages (Pages);\r
   } else {\r
     return EFI_INVALID_PARAMETER;\r