Fix line ending issue. Update DMA Map primatives to double buffer if buffer does not start on cache line boundary. If buffer is not a multiple of a cache line only whole cache lines will be allowed in the buffer. This is part of the MAP API.


git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10547 6f19259b-4bc3-4df7-8a09-765794883524
diff --git a/Omap35xxPkg/Library/OmapDmaLib/OmapDmaLib.c b/Omap35xxPkg/Library/OmapDmaLib/OmapDmaLib.c
index fa4bce8..27617fa 100755
--- a/Omap35xxPkg/Library/OmapDmaLib/OmapDmaLib.c
+++ b/Omap35xxPkg/Library/OmapDmaLib/OmapDmaLib.c
@@ -21,6 +21,8 @@
 #include <Library/UefiBootServicesTableLib.h>

 #include <Library/UncachedMemoryAllocationLib.h>

 #include <Library/IoLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/ArmLib.h>

 #include <Omap3530/Omap3530.h>

 

 #include <Protocol/Cpu.h>

@@ -30,11 +32,13 @@
   EFI_PHYSICAL_ADDRESS      DeviceAddress;

   UINTN                     NumberOfBytes;

   DMA_MAP_OPERATION         Operation;

+  BOOLEAN                   DoubleBuffer;

 } MAP_INFO_INSTANCE;

 

 

 

-EFI_CPU_ARCH_PROTOCOL      *gCpu;
+EFI_CPU_ARCH_PROTOCOL      *gCpu;

+UINTN                      gCacheAlignment = 0;

 

 /**                                                                 

   Configure OMAP DMA Channel

@@ -46,21 +50,21 @@
   @retval EFI_INVALID_PARAMETER Channel is not valid

   @retval EFI_DEVICE_ERROR      The system hardware could not map the requested information.

                                    

-**/
-EFI_STATUS
-EFIAPI
-EnableDmaChannel (
-  IN  UINTN       Channel,
-  IN  OMAP_DMA4   *DMA4
-  )
-{
-  UINT32  RegVal;
-
-
-  if (Channel > DMA4_MAX_CHANNEL) {
-    return EFI_INVALID_PARAMETER;
-  }
-
+**/

+EFI_STATUS

+EFIAPI

+EnableDmaChannel (

+  IN  UINTN       Channel,

+  IN  OMAP_DMA4   *DMA4

+  )

+{

+  UINT32  RegVal;

+

+

+  if (Channel > DMA4_MAX_CHANNEL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

   /* 1) Configure the transfer parameters in the logical DMA registers */

   /*-------------------------------------------------------------------*/

 

@@ -135,11 +139,11 @@
   /* 2) Start the DMA transfer by Setting the enable bit CCR[7]=1 */

   /*--------------------------------------------------------------*/

   //write enable bit

-  MmioOr32 (DMA4_CCR(Channel), DMA4_CCR_ENABLE); //Launch transfer
-
-  return EFI_SUCCESS;
-}
-
+  MmioOr32 (DMA4_CCR(Channel), DMA4_CCR_ENABLE); //Launch transfer

+

+  return EFI_SUCCESS;

+}

+

 /**                                                                 

   Turn of DMA channel configured by EnableDma().

             

@@ -151,43 +155,43 @@
   @retval EFI_INVALID_PARAMETER Channel is not valid

   @retval EFI_DEVICE_ERROR      The system hardware could not map the requested information.

                                    

-**/
-EFI_STATUS
-EFIAPI
-DisableDmaChannel (
-  IN  UINTN       Channel,
-  IN  UINT32      SuccessMask,
-  IN  UINT32      ErrorMask
-  )
-{
-  EFI_STATUS  Status = EFI_SUCCESS;
-  UINT32      Reg;
-
-
-  if (Channel > DMA4_MAX_CHANNEL) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  do {
-    Reg = MmioRead32 (DMA4_CSR(Channel));
-    if ((Reg & ErrorMask) != 0) {
-      Status = EFI_DEVICE_ERROR;
-      DEBUG ((EFI_D_ERROR, "DMA Error (%d) %x\n", Channel, Reg));
-      break;
-    }
-  } while ((Reg & SuccessMask) != SuccessMask);
-
-
-  // Disable all status bits and clear them
+**/

+EFI_STATUS

+EFIAPI

+DisableDmaChannel (

+  IN  UINTN       Channel,

+  IN  UINT32      SuccessMask,

+  IN  UINT32      ErrorMask

+  )

+{

+  EFI_STATUS  Status = EFI_SUCCESS;

+  UINT32      Reg;

+

+

+  if (Channel > DMA4_MAX_CHANNEL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  do {

+    Reg = MmioRead32 (DMA4_CSR(Channel));

+    if ((Reg & ErrorMask) != 0) {

+      Status = EFI_DEVICE_ERROR;

+      DEBUG ((EFI_D_ERROR, "DMA Error (%d) %x\n", Channel, Reg));

+      break;

+    }

+  } while ((Reg & SuccessMask) != SuccessMask);

+

+

+  // Disable all status bits and clear them

   MmioWrite32 (DMA4_CICR (Channel), 0);

-  MmioWrite32 (DMA4_CSR (Channel),  DMA4_CSR_RESET);
-
-  MmioAnd32 (DMA4_CCR(0), ~(DMA4_CCR_ENABLE | DMA4_CCR_RD_ACTIVE | DMA4_CCR_WR_ACTIVE)); 
-  return Status;
-}
-
-
-
+  MmioWrite32 (DMA4_CSR (Channel),  DMA4_CSR_RESET);

+

+  MmioAnd32 (DMA4_CCR(0), ~(DMA4_CCR_ENABLE | DMA4_CCR_RD_ACTIVE | DMA4_CCR_WR_ACTIVE)); 

+  return Status;

+}

+

+

+

 /**                                                                 

   Provides the DMA controller-specific addresses needed to access system memory.

   

@@ -207,51 +211,76 @@
   @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.

   @retval EFI_DEVICE_ERROR      The system hardware could not map the requested address.

                                    

-**/
-EFI_STATUS
-EFIAPI
-DmaMap (
-  IN     DMA_MAP_OPERATION              Operation,
+**/

+EFI_STATUS

+EFIAPI

+DmaMap (

+  IN     DMA_MAP_OPERATION              Operation,

   IN     VOID                           *HostAddress,

   IN OUT UINTN                          *NumberOfBytes,

   OUT    PHYSICAL_ADDRESS               *DeviceAddress,

   OUT    VOID                           **Mapping

-  )
-{
-  MAP_INFO_INSTANCE     *Map;
-
-  if ( HostAddress == NULL || NumberOfBytes == NULL || 
-       DeviceAddress == NULL || Mapping == NULL ) {
-    return EFI_INVALID_PARAMETER;
-  }
-  
-
-  if (Operation >= MapOperationMaximum) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  *DeviceAddress = ConvertToPhysicalAddress (HostAddress);
-
-  // Remember range so we can flush on the other side
-  Map = AllocatePool (sizeof (MAP_INFO_INSTANCE));
-  if (Map == NULL) {
-    return  EFI_OUT_OF_RESOURCES;
-  }
-  
-  *Mapping = Map;
-
-  Map->HostAddress   = (UINTN)HostAddress;
-  Map->DeviceAddress = *DeviceAddress;
-  Map->NumberOfBytes = *NumberOfBytes;
-  Map->Operation     = Operation;
-
-  // EfiCpuFlushTypeWriteBack, EfiCpuFlushTypeInvalidate
-  gCpu->FlushDataCache (gCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)HostAddress, *NumberOfBytes, EfiCpuFlushTypeWriteBackInvalidate);
-  
-  return EFI_SUCCESS;
-}
-
-
+  )

+{

+  EFI_STATUS            Status;

+  MAP_INFO_INSTANCE     *Map;

+  VOID                  *Buffer;

+

+  if ( HostAddress == NULL || NumberOfBytes == NULL || 

+       DeviceAddress == NULL || Mapping == NULL ) {

+    return EFI_INVALID_PARAMETER;

+  }

+  

+

+  if (Operation >= MapOperationMaximum) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  *DeviceAddress = ConvertToPhysicalAddress (HostAddress);

+

+  // Remember range so we can flush on the other side

+  Map = AllocatePool (sizeof (MAP_INFO_INSTANCE));

+  if (Map == NULL) {

+    return  EFI_OUT_OF_RESOURCES;

+  }

+  

+  *Mapping = Map;

+

+  if (((UINTN)HostAddress & (gCacheAlignment - 1)) != 0) {

+    Map->DoubleBuffer  = TRUE;

+    Status = DmaAllocateBuffer (EfiBootServicesData, EFI_SIZE_TO_PAGES (*NumberOfBytes), &Buffer);

+    if (EFI_ERROR (Status)) {

+      return Status;

+    }

+    

+    *DeviceAddress = (PHYSICAL_ADDRESS)(UINTN)Buffer;

+    

+  } else {

+    Map->DoubleBuffer  = FALSE;

+  }

+

+  *NumberOfBytes &= *NumberOfBytes & ~(gCacheAlignment - 1); // Only do it on full cache lines

+  

+  Map->HostAddress   = (UINTN)HostAddress;

+  Map->DeviceAddress = *DeviceAddress;

+  Map->NumberOfBytes = *NumberOfBytes;

+  Map->Operation     = Operation;

+

+  if (Map->DoubleBuffer) {

+    if (Map->Operation == MapOperationBusMasterWrite) {

+      CopyMem ((VOID *)(UINTN)Map->DeviceAddress, (VOID *)(UINTN)Map->HostAddress, Map->NumberOfBytes);

+    }

+  } else {

+    // EfiCpuFlushTypeWriteBack, EfiCpuFlushTypeInvalidate

+    if (Map->Operation == MapOperationBusMasterWrite || Map->Operation == MapOperationBusMasterRead) {

+      gCpu->FlushDataCache (gCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)HostAddress,  Map->NumberOfBytes, EfiCpuFlushTypeWriteBackInvalidate);

+    }

+  }

+  

+  return EFI_SUCCESS;

+}

+

+

 /**                                                                 

   Completes the DmaMapBusMasterRead(), DmaMapBusMasterWrite(), or DmaMapBusMasterCommonBuffer()

   operation and releases any corresponding resources.

@@ -261,33 +290,43 @@
   @retval EFI_SUCCESS           The range was unmapped.

   @retval EFI_DEVICE_ERROR      The data was not committed to the target system memory.

                                    

-**/
-EFI_STATUS
-EFIAPI
-DmaUnmap (
+**/

+EFI_STATUS

+EFIAPI

+DmaUnmap (

   IN  VOID                         *Mapping

-  )
-{
-  MAP_INFO_INSTANCE *Map;
-  
-  if (Mapping == NULL) {
-    ASSERT (FALSE);
-    return EFI_INVALID_PARAMETER;
-  }
-  
-  Map = (MAP_INFO_INSTANCE *)Mapping;
-  if (Map->Operation == MapOperationBusMasterWrite) {
-    //
-    // Make sure we read buffer from uncached memory and not the cache
-    //
-    gCpu->FlushDataCache (gCpu, Map->HostAddress, Map->NumberOfBytes, EfiCpuFlushTypeInvalidate);
-  } 
-  
-  FreePool (Map);
-
-  return EFI_SUCCESS;
-}
-
+  )

+{

+  MAP_INFO_INSTANCE *Map;

+  

+  if (Mapping == NULL) {

+    ASSERT (FALSE);

+    return EFI_INVALID_PARAMETER;

+  }

+  

+  Map = (MAP_INFO_INSTANCE *)Mapping;

+  

+  if (Map->DoubleBuffer) {

+    if (Map->Operation == MapOperationBusMasterRead) {

+      CopyMem ((VOID *)(UINTN)Map->HostAddress, (VOID *)(UINTN)Map->DeviceAddress, Map->NumberOfBytes);

+    }

+    

+    DmaFreeBuffer (EFI_SIZE_TO_PAGES (Map->NumberOfBytes), (VOID *)(UINTN)Map->DeviceAddress);

+  

+  } else {

+    if (Map->Operation == MapOperationBusMasterWrite) {

+      //

+      // Make sure we read buffer from uncached memory and not the cache

+      //

+      gCpu->FlushDataCache (gCpu, Map->HostAddress, Map->NumberOfBytes, EfiCpuFlushTypeInvalidate);

+    }

+  }

+  

+  FreePool (Map);

+

+  return EFI_SUCCESS;

+}

+

 /**                                                                 

   Allocates pages that are suitable for an DmaMap() of type MapOperationBusMasterCommonBuffer.

   mapping.                                                                       

@@ -304,35 +343,36 @@
   @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
-DmaAllocateBuffer (
-  IN  EFI_MEMORY_TYPE              MemoryType,
+**/

+EFI_STATUS

+EFIAPI

+DmaAllocateBuffer (

+  IN  EFI_MEMORY_TYPE              MemoryType,

   IN  UINTN                        Pages,

   OUT VOID                         **HostAddress

   )

-{
-  if (HostAddress == NULL) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  //
-  // The only valid memory types are EfiBootServicesData and EfiRuntimeServicesData
-  //
-  // We used uncached memory to keep coherency
-  //
-  if (MemoryType == EfiBootServicesData) {
-    *HostAddress = UncachedAllocatePages (Pages);
-  } else if (MemoryType != EfiRuntimeServicesData) {
-    *HostAddress = UncachedAllocateRuntimePages (Pages);
-  } else {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  return EFI_SUCCESS;
-}
-
-
+{

+  if (HostAddress == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // The only valid memory types are EfiBootServicesData and EfiRuntimeServicesData

+  //

+  // We used uncached memory to keep coherency

+  //

+  if (MemoryType == EfiBootServicesData) {

+    *HostAddress = UncachedAllocatePages (Pages);

+  } else if (MemoryType != EfiRuntimeServicesData) {

+    *HostAddress = UncachedAllocateRuntimePages (Pages);

+  } else {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  return EFI_SUCCESS;

+}

+

+

 /**                                                                 

   Frees memory that was allocated with DmaAllocateBuffer().

             

@@ -344,35 +384,37 @@
                                 was not allocated with DmaAllocateBuffer().

                                      

 **/

-EFI_STATUS
-EFIAPI
-DmaFreeBuffer (
+EFI_STATUS

+EFIAPI

+DmaFreeBuffer (

   IN  UINTN                        Pages,

   IN  VOID                         *HostAddress

   )

-{
-  if (HostAddress == NULL) {
-     return EFI_INVALID_PARAMETER;
-  } 
-  
-  UncachedFreePages (HostAddress, Pages);
-  return EFI_SUCCESS;
-}
-
-
-EFI_STATUS
-EFIAPI
-OmapDmaLibConstructor (
-  IN EFI_HANDLE       ImageHandle,
-  IN EFI_SYSTEM_TABLE *SystemTable
-  )
-{
-  EFI_STATUS              Status;
-
-  // Get the Cpu protocol for later use
-  Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&gCpu);
-  ASSERT_EFI_ERROR(Status);
-
-  return EFI_SUCCESS;
-}
-
+{

+  if (HostAddress == NULL) {

+     return EFI_INVALID_PARAMETER;

+  } 

+  

+  UncachedFreePages (HostAddress, Pages);

+  return EFI_SUCCESS;

+}

+

+

+EFI_STATUS

+EFIAPI

+OmapDmaLibConstructor (

+  IN EFI_HANDLE       ImageHandle,

+  IN EFI_SYSTEM_TABLE *SystemTable

+  )

+{

+  EFI_STATUS              Status;

+

+  // Get the Cpu protocol for later use

+  Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&gCpu);

+  ASSERT_EFI_ERROR(Status);

+

+  gCacheAlignment = ArmDataCacheLineLength ();

+  

+  return Status;

+}

+

diff --git a/Omap35xxPkg/Library/OmapDmaLib/OmapDmaLib.inf b/Omap35xxPkg/Library/OmapDmaLib/OmapDmaLib.inf
index 78f2d01..04be6e0 100755
--- a/Omap35xxPkg/Library/OmapDmaLib/OmapDmaLib.inf
+++ b/Omap35xxPkg/Library/OmapDmaLib/OmapDmaLib.inf
@@ -35,6 +35,8 @@
   MemoryAllocationLib

   UncachedMemoryAllocationLib

   IoLib

+  BaseMemoryLib

+  ArmLib

   

   

 [Protocols]