]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Add a DMA lib for the OMAP. It is a combination of PCI IO (generic ARM) DMA functions...
authorandrewfish <andrewfish@6f19259b-4bc3-4df7-8a09-765794883524>
Sat, 8 May 2010 19:32:03 +0000 (19:32 +0000)
committerandrewfish <andrewfish@6f19259b-4bc3-4df7-8a09-765794883524>
Sat, 8 May 2010 19:32:03 +0000 (19:32 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10469 6f19259b-4bc3-4df7-8a09-765794883524

14 files changed:
Omap35xxPkg/Include/Library/OmapDmaLib.h [new file with mode: 0755]
Omap35xxPkg/Include/Library/OmapLib.h
Omap35xxPkg/Include/Omap3530/Omap3530Dma.h
Omap35xxPkg/Include/Omap3530/Omap3530MMCHS.h
Omap35xxPkg/Library/OmapDmaLib/OmapDmaLib.c [new file with mode: 0755]
Omap35xxPkg/Library/OmapDmaLib/OmapDmaLib.inf [new file with mode: 0755]
Omap35xxPkg/MMCHSDxe/MMCHS.c
Omap35xxPkg/MMCHSDxe/MMCHS.h
Omap35xxPkg/MMCHSDxe/MMCHS.inf
Omap35xxPkg/Omap35xxPkg.dec
Omap35xxPkg/Omap35xxPkg.dsc
Omap35xxPkg/PciEmulation/PciEmulation.c
Omap35xxPkg/PciEmulation/PciEmulation.h
Omap35xxPkg/PciEmulation/PciEmulation.inf

diff --git a/Omap35xxPkg/Include/Library/OmapDmaLib.h b/Omap35xxPkg/Include/Library/OmapDmaLib.h
new file mode 100755 (executable)
index 0000000..9c60d44
--- /dev/null
@@ -0,0 +1,200 @@
+/** @file
+
+  Abstractions for simple OMAP DMA. The DMA functions are modeled on 
+  the PCI IO protocol and follow the same rules as outlined in the UEFI specification.
+  OMAP_DMA4 structure elements are described in the OMAP35xx TRM. Currently 
+  there is no PCI'less DMA protocol, if one existed it could be used to
+  replace this library.
+
+  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __OMAP_DMA_LIB_H__
+#define __OMAP_DMA_LIB_H__
+
+typedef enum {\r
+  ///\r
+  /// A read operation from system memory by a bus master.\r
+  ///\r
+  MapOperationBusMasterRead,\r
+  ///\r
+  /// A write operation from system memory by a bus master.\r
+  ///\r
+  MapOperationBusMasterWrite,\r
+  ///\r
+  /// Provides both read and write access to system memory by both the processor and a\r
+  /// bus master. The buffer is coherent from both the processor's and the bus master's point of view.\r
+  ///\r
+  MapOperationBusMasterCommonBuffer,\r
+  MapOperationMaximum\r
+} DMA_MAP_OPERATION;\r
+
+
+// Example from DMA chapter of the OMAP35xx spec
+typedef struct {\r
+  UINT8     DataType;                      // DMA4_CSDPi[1:0]\r
+  UINT8     ReadPortAccessType;            // DMA4_CSDPi[8:7]\r
+  UINT8     WritePortAccessType;           // DMA4_CSDPi[15:14]\r
+  UINT8     SourceEndiansim;               // DMA4_CSDPi[21]\r
+  UINT8     DestinationEndianism;          // DMA4_CSDPi[19]\r
+  UINT8     WriteMode;                     // DMA4_CSDPi[17:16]\r
+  UINT8     SourcePacked;                  // DMA4_CSDPi[6]\r
+  UINT8     DestinationPacked;             // DMA4_CSDPi[13]\r
+  UINT32    NumberOfElementPerFrame;       // DMA4_CENi\r
+  UINT32    NumberOfFramePerTransferBlock; // DMA4_CFNi\r
+  UINT32    SourceStartAddress;            // DMA4_CSSAi\r
+  UINT32    DestinationStartAddress;       // DMA4_CDSAi\r
+  UINT32    SourceElementIndex;            // DMA4_CSEi\r
+  UINT32    SourceFrameIndex;              // DMA4_CSFi\r
+  UINT32    DestinationElementIndex;       // DMA4_CDEi\r
+  UINT32    DestinationFrameIndex;         // DMA4_CDFi\r
+  UINT8     ReadPortAccessMode;            // DMA4_CCRi[13:12]\r
+  UINT8     WritePortAccessMode;           // DMA4_CCRi[15:14]\r
+  UINT8     ReadPriority;                  // DMA4_CCRi[6]\r
+  UINT8     WritePriority;                 // DMA4_CCRi[23]\r
+  UINT8     ReadRequestNumber;             // DMA4_CCRi[4:0]\r
+  UINT8     WriteRequestNumber;            // DMA4_CCRi[20:19]
+} OMAP_DMA4;
+
+
+/**                                                                 \r
+  Configure OMAP DMA Channel\r
+            \r
+  @param  Channel               DMA Channel to configure\r
+  @param  Dma4                  Pointer to structure used to initialize DMA registers for the Channel                                                \r
+                                  \r
+  @retval EFI_SUCCESS           The range was mapped for the returned NumberOfBytes.\r
+  @retval EFI_INVALID_PARAMETER Channel is not valid\r
+  @retval EFI_DEVICE_ERROR      The system hardware could not map the requested information.\r
+                                   \r
+**/
+EFI_STATUS
+EFIAPI
+EnableDmaChannel (
+  IN  UINTN       Channel,
+  IN  OMAP_DMA4   *Dma4
+  );
+
+/**                                                                 \r
+  Turn of DMA channel configured by EnableDma().\r
+            \r
+  @param  Channel               DMA Channel to configure\r
+                                  \r
+  @retval EFI_SUCCESS           DMA hardware disabled\r
+  @retval EFI_INVALID_PARAMETER Channel is not valid\r
+  @retval EFI_DEVICE_ERROR      The system hardware could not map the requested information.\r
+                                   \r
+**/
+EFI_STATUS
+EFIAPI
+DisableDmaChannel (
+  IN  UINTN       Channel
+  );
+
+
+/**                                                                 \r
+  Provides the DMA controller-specific addresses needed to access system memory.\r
+  \r
+  Operation is relative to the DMA bus master.\r
+            \r
+  @param  Operation             Indicates if the bus master is going to read or write to system memory.\r
+  @param  HostAddress           The system memory address to map to the DMA controller.\r
+  @param  NumberOfBytes         On input the number of bytes to map. On output the number of bytes\r
+                                that were mapped.                                                 \r
+  @param  DeviceAddress         The resulting map address for the bus master controller to use to\r
+                                access the hosts HostAddress.                                        \r
+  @param  Mapping               A resulting value to pass to Unmap().\r
+                                  \r
+  @retval EFI_SUCCESS           The range was mapped for the returned NumberOfBytes.\r
+  @retval EFI_UNSUPPORTED       The HostAddress cannot be mapped as a common buffer.                                \r
+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.\r
+  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.\r
+  @retval EFI_DEVICE_ERROR      The system hardware could not map the requested address.\r
+                                   \r
+**/
+EFI_STATUS
+EFIAPI
+DmaMap (
+  IN     DMA_MAP_OPERATION              Operation,
+  IN     VOID                           *HostAddress,\r
+  IN OUT UINTN                          *NumberOfBytes,\r
+  OUT    PHYSICAL_ADDRESS               *DeviceAddress,\r
+  OUT    VOID                           **Mapping\r
+  );
+
+
+
+
+/**                                                                 \r
+  Completes the DmaMapBusMasterRead(), DmaMapBusMasterWrite(), or DmaMapBusMasterCommonBuffer()\r
+  operation and releases any corresponding resources.\r
+            \r
+  @param  Mapping               The mapping value returned from DmaMap*().\r
+                                  \r
+  @retval EFI_SUCCESS           The range was unmapped.\r
+  @retval EFI_DEVICE_ERROR      The data was not committed to the target system memory.\r
+                                   \r
+**/
+EFI_STATUS
+EFIAPI
+DmaUnmap (
+  IN  VOID                         *Mapping\r
+  );
+
+
+/**                                                                 \r
+  Allocates pages that are suitable for an DmaMap() of type MapOperationBusMasterCommonBuffer.\r
+  mapping.                                                                       \r
+            \r
+  @param  MemoryType            The type of memory to allocate, EfiBootServicesData or\r
+                                EfiRuntimeServicesData.                               \r
+  @param  Pages                 The number of pages to allocate.                                \r
+  @param  HostAddress           A pointer to store the base system memory address of the\r
+                                allocated range.                                        \r
+\r
+                                @retval EFI_SUCCESS           The requested memory pages were allocated.\r
+  @retval EFI_UNSUPPORTED       Attributes is unsupported. The only legal attribute bits are\r
+                                MEMORY_WRITE_COMBINE and MEMORY_CACHED.                     \r
+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.\r
+  @retval EFI_OUT_OF_RESOURCES  The memory pages could not be allocated.  \r
+                                   \r
+**/
+EFI_STATUS
+EFIAPI
+DmaAllocateBuffer (
+  IN  EFI_MEMORY_TYPE              MemoryType,
+  IN  UINTN                        Pages,\r
+  OUT VOID                         **HostAddress\r
+  );\r
+
+
+/**                                                                 \r
+  Frees memory that was allocated with DmaAllocateBuffer().\r
+            \r
+  @param  Pages                 The number of pages to free.                                \r
+  @param  HostAddress           The base system memory address of the allocated range.                                    \r
+                                  \r
+  @retval EFI_SUCCESS           The requested memory pages were freed.\r
+  @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and Pages\r
+                                was not allocated with DmaAllocateBuffer().\r
+                                     \r
+**/\r
+EFI_STATUS
+EFIAPI
+DmaFreeBuffer (
+  IN  UINTN                        Pages,\r
+  IN  VOID                         *HostAddress\r
+  );\r
+
+
+#endif 
+
index ae9aac100b032fbf3cad8d416b03b0640efd8dd4..4192275157dcc1b7cf9766cd2edb5d84d6702701 100644 (file)
@@ -1,6 +1,6 @@
 /** @file
 
-  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
 
   This program and the accompanying materials
   are licensed and made available under the terms and conditions of the BSD License
 #define __OMAPLIB_H__
 
 UINT32 
+EFIAPI
 GpioBase (
   IN  UINTN Port
   );
 
 UINT32 
+EFIAPI
 TimerBase (
   IN  UINTN Timer
   );
 
 UINTN
+EFIAPI
 InterruptVectorForTimer (
   IN  UINTN TImer
   );
 
 UINT32
+EFIAPI
 UartBase (
   IN  UINTN Uart
   );
 
+
 #endif // __OMAPLIB_H__
 
index 927c6f2702b421f94201816e7137d4c8e58a4a73..4e397d52e5c1a8f5d7c237f7b25df17b497b72d6 100755 (executable)
 #ifndef __OMAP3530DMA_H__
 #define __OMAP3530DMA_H__
 
-#define DMA4_IRQENABLE_L(_i)  (0x48056018 + (0x4*(i)))
-
-#define DMA4_CCR(_i)  (0x48056080 + (0x60*(i)))
-#define DMA4_CICR(_i) (0x48056088 + (0x60*(i)))
-#define DMA4_CSDP(_i) (0x48056090 + (0x60*(i)))
-#define DMA4_CEN(_i)  (0x48056094 + (0x60*(i)))
-#define DMA4_CFN(_i)  (0x48056098 + (0x60*(i)))
-#define DMA4_CSSA(_i) (0x4805609c + (0x60*(i)))
-#define DMA4_CDSA(_i) (0x480560a0 + (0x60*(i)))
-#define DMA4_CSE(_i)  (0x480560a4 + (0x60*(i)))
-#define DMA4_CSF(_i)  (0x480560a8 + (0x60*(i)))
-#define DMA4_CDE(_i)  (0x480560ac + (0x60*(i)))
+
+#define DMA4_MAX_CHANNEL 31
+
+#define DMA4_IRQENABLE_L(_i)  (0x48056018 + (0x4*(_i)))
+
+#define DMA4_CCR(_i)  (0x48056080 + (0x60*(_i)))
+#define DMA4_CICR(_i) (0x48056088 + (0x60*(_i)))
+#define DMA4_CSDP(_i) (0x48056090 + (0x60*(_i)))
+#define DMA4_CEN(_i)  (0x48056094 + (0x60*(_i)))
+#define DMA4_CFN(_i)  (0x48056098 + (0x60*(_i)))
+#define DMA4_CSSA(_i) (0x4805609c + (0x60*(_i)))
+#define DMA4_CDSA(_i) (0x480560a0 + (0x60*(_i)))
+#define DMA4_CSEI(_i) (0x480560a4 + (0x60*(_i)))
+#define DMA4_CSFI(_i) (0x480560a8 + (0x60*(_i)))
+#define DMA4_CDEI(_i) (0x480560ac + (0x60*(_i)))
+#define DMA4_CDFI(_i) (0x480560b0 + (0x60*(_i)))
+
+#define DMA4_GCR      (0x48056078)
 
 // Channel Source Destination parameters
 #define DMA4_CSDP_DATA_TYPE8    0
 #define DMA4_CCR_CONST_FILL_ENABLE        BIT16
 #define DMA4_CCR_TRANSPARENT_COPY_ENABLE  BIT17
   
+#define DMA4_CCR_SEL_SRC_DEST_SYNC_SOURCE BIT24
+
 #endif 
 
index d4abf305f01dbae517d8e30edf581249db865510..1b3e734d6a24b5b662b51c48e0d598a2d1622147 100644 (file)
 #define CMD24             (INDX(24) | DP_ENABLE | CICE_ENABLE | CCCE_ENABLE | RSP_TYPE_48BITS | DDIR_WRITE)
 #define CMD24_INT_EN      (CERR_EN | CIE_EN | CCRC_EN | CC_EN | TC_EN | BWR_EN | CTO_EN | DTO_EN | DCRC_EN | DEB_EN | CEB_EN)
 
+#define CMD25             (INDX(25) | DP_ENABLE | CICE_ENABLE | CCCE_ENABLE | RSP_TYPE_48BITS | MSBS_MULTBLK | DDIR_READ | BCE_ENABLE | DE_ENABLE)
+#define CMD25_INT_EN      (CERR_EN | CIE_EN | CCRC_EN | CC_EN | TC_EN | BRR_EN | CTO_EN | DTO_EN | DCRC_EN | DEB_EN | CEB_EN)
+
 #define CMD55             (INDX(55) | CICE_ENABLE | CCCE_ENABLE | RSP_TYPE_48BITS)
 #define CMD55_INT_EN      (CERR_EN | CIE_EN | CCRC_EN | CC_EN | CEB_EN | CTO_EN)
 
diff --git a/Omap35xxPkg/Library/OmapDmaLib/OmapDmaLib.c b/Omap35xxPkg/Library/OmapDmaLib/OmapDmaLib.c
new file mode 100755 (executable)
index 0000000..f979b94
--- /dev/null
@@ -0,0 +1,348 @@
+/** @file\r
+  OMAP35xx DMA abstractions modeled on PCI IO protocol. EnableDma()/DisableDma()\r
+  are from OMAP35xx TRM. \r
+\r
+  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>\r
+  \r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <Base.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/OmapDmaLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/UncachedMemoryAllocationLib.h>\r
+#include <Library/IoLib.h>\r
+#include <Omap3530/Omap3530.h>\r
+\r
+#include <Protocol/Cpu.h>\r
+\r
+typedef struct {\r
+  EFI_PHYSICAL_ADDRESS      HostAddress;\r
+  EFI_PHYSICAL_ADDRESS      DeviceAddress;\r
+  UINTN                     NumberOfBytes;\r
+  DMA_MAP_OPERATION         Operation;\r
+} MAP_INFO_INSTANCE;\r
+\r
+\r
+\r
+EFI_CPU_ARCH_PROTOCOL      *gCpu;
+\r
+/**                                                                 \r
+  Configure OMAP DMA Channel\r
+            \r
+  @param  Channel               DMA Channel to configure\r
+  @param  Dma4                  Pointer to structure used to initialize DMA registers for the Channel                                                \r
+                                  \r
+  @retval EFI_SUCCESS           The range was mapped for the returned NumberOfBytes.\r
+  @retval EFI_INVALID_PARAMETER Channel is not valid\r
+  @retval EFI_DEVICE_ERROR      The system hardware could not map the requested information.\r
+                                   \r
+**/
+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 */\r
+  /*-------------------------------------------------------------------*/\r
+\r
+  /* a) Set the data type CSDP[1:0], the Read/Write Port access type \r
+        CSDP[8:7]/[15:14], the Source/dest endianism CSDP[21]/CSDP[19], \r
+        write mode CSDP[17:16], source/dest packed or nonpacked CSDP[6]/CSDP[13] */\r
+  \r
+  // Read CSDP\r
+  RegVal = MmioRead32 (DMA4_CSDP (Channel));\r
+  \r
+  // Build reg\r
+  RegVal = ((RegVal & ~ 0x3) | DMA4->DataType );\r
+  RegVal = ((RegVal & ~(0x3 <<  7)) | (DMA4->ReadPortAccessType << 7));\r
+  RegVal = ((RegVal & ~(0x3 << 14)) | (DMA4->WritePortAccessType << 14));\r
+  RegVal = ((RegVal & ~(0x1 << 21)) | (DMA4->SourceEndiansim << 21));\r
+  RegVal = ((RegVal & ~(0x1 << 19)) | (DMA4->DestinationEndianism << 19));\r
+  RegVal = ((RegVal & ~(0x3 << 16)) | (DMA4->WriteMode << 16));\r
+  RegVal = ((RegVal & ~(0x1 <<  6)) | (DMA4->SourcePacked << 6));\r
+  RegVal = ((RegVal & ~(0x1 << 13)) | (DMA4->DestinationPacked << 13));\r
+  // Write CSDP\r
+  MmioWrite32 (DMA4_CSDP (Channel), RegVal);\r
+  \r
+  /* b) Set the number of element per frame CEN[23:0]*/\r
+  MmioWrite32 (DMA4_CEN (Channel), DMA4->NumberOfElementPerFrame);\r
\r
+  /* c) Set the number of frame per block CFN[15:0]*/\r
+  MmioWrite32 (DMA4_CFN (Channel), DMA4->NumberOfFramePerTransferBlock);\r
+  \r
+  /* d) Set the Source/dest start address index CSSA[31:0]/CDSA[31:0]*/\r
+  MmioWrite32 (DMA4_CSSA (Channel), DMA4->SourceStartAddress);\r
+  MmioWrite32 (DMA4_CDSA (Channel), DMA4->DestinationStartAddress);\r
+  \r
+  /* e) Set the Read Port addressing mode CCR[13:12], the Write Port addressing mode CCR[15:14],\r
+        read/write priority CCR[6]/CCR[26]\r
+        I changed LCH CCR[20:19]=00 and CCR[4:0]=00000 to \r
+        LCH CCR[20:19]= DMA4->WriteRequestNumber and CCR[4:0]=DMA4->ReadRequestNumber\r
+  */\r
+  \r
+  // Read CCR\r
+  RegVal = MmioRead32 (DMA4_CCR (Channel));\r
+\r
+  // Build reg\r
+  RegVal  = ((RegVal &  ~0x1f)            | DMA4->ReadRequestNumber);\r
+  RegVal  = ((RegVal &  ~(BIT20 | BIT19)) | DMA4->WriteRequestNumber << 19);\r
+  RegVal  = ((RegVal & ~(0x3 << 12)) | (DMA4->ReadPortAccessMode << 12));\r
+  RegVal  = ((RegVal & ~(0x3 << 14)) | (DMA4->WritePortAccessMode << 14));\r
+  RegVal  = ((RegVal & ~(0x1 <<  6)) | (DMA4->ReadPriority << 6));\r
+  RegVal  = ((RegVal & ~(0x1 << 26)) | (DMA4->WritePriority << 26));\r
+  \r
+  // Write CCR\r
+  MmioWrite32 (DMA4_CCR (Channel), RegVal);\r
+  \r
+  /* f)- Set the source element index CSEI[15:0]*/\r
+  MmioWrite32 (DMA4_CSEI (Channel), DMA4->SourceElementIndex);\r
+  \r
+  /* - Set the source frame index CSFI[15:0]*/\r
+  MmioWrite32 (DMA4_CSFI (Channel), DMA4->SourceFrameIndex);\r
+\r
+\r
+  /* - Set the destination element index CDEI[15:0]*/\r
+  MmioWrite32 (DMA4_CDEI (Channel), DMA4->DestinationElementIndex);\r
+\r
+  /* - Set the destination frame index CDFI[31:0]*/\r
+  MmioWrite32 (DMA4_CDFI (Channel), DMA4->DestinationFrameIndex);\r
+  \r
+  /* 2) Start the DMA transfer by Setting the enable bit CCR[7]=1 */\r
+  /*--------------------------------------------------------------*/\r
+  //write enable bit\r
+  MmioOr32 (DMA4_CCR(0), DMA4_CCR_ENABLE); //Launch transfer
+
+  return EFI_SUCCESS;
+}
+
+/**                                                                 \r
+  Turn of DMA channel configured by EnableDma().\r
+            \r
+  @param  Channel               DMA Channel to configure\r
+                                  \r
+  @retval EFI_SUCCESS           DMA hardware disabled\r
+  @retval EFI_INVALID_PARAMETER Channel is not valid\r
+  @retval EFI_DEVICE_ERROR      The system hardware could not map the requested information.\r
+                                   \r
+**/
+EFI_STATUS
+EFIAPI
+DisableDmaChannel (
+  IN  UINTN       Channel
+  )
+{
+  if (Channel > DMA4_MAX_CHANNEL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  MmioAnd32 (DMA4_CCR(0), ~(DMA4_CCR_ENABLE | DMA4_CCR_RD_ACTIVE | DMA4_CCR_WR_ACTIVE)); 
+  return EFI_SUCCESS;
+}
+
+/**                                                                 \r
+  Provides the DMA controller-specific addresses needed to access system memory.\r
+  \r
+  Operation is relative to the DMA bus master.\r
+            \r
+  @param  Operation             Indicates if the bus master is going to read or write to system memory.\r
+  @param  HostAddress           The system memory address to map to the DMA controller.\r
+  @param  NumberOfBytes         On input the number of bytes to map. On output the number of bytes\r
+                                that were mapped.                                                 \r
+  @param  DeviceAddress         The resulting map address for the bus master controller to use to\r
+                                access the hosts HostAddress.                                        \r
+  @param  Mapping               A resulting value to pass to Unmap().\r
+                                  \r
+  @retval EFI_SUCCESS           The range was mapped for the returned NumberOfBytes.\r
+  @retval EFI_UNSUPPORTED       The HostAddress cannot be mapped as a common buffer.                                \r
+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.\r
+  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.\r
+  @retval EFI_DEVICE_ERROR      The system hardware could not map the requested address.\r
+                                   \r
+**/
+EFI_STATUS
+EFIAPI
+DmaMap (
+  IN     DMA_MAP_OPERATION              Operation,
+  IN     VOID                           *HostAddress,\r
+  IN OUT UINTN                          *NumberOfBytes,\r
+  OUT    PHYSICAL_ADDRESS               *DeviceAddress,\r
+  OUT    VOID                           **Mapping\r
+  )
+{
+  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;
+}
+
+
+/**                                                                 \r
+  Completes the DmaMapBusMasterRead(), DmaMapBusMasterWrite(), or DmaMapBusMasterCommonBuffer()\r
+  operation and releases any corresponding resources.\r
+            \r
+  @param  Mapping               The mapping value returned from DmaMap*().\r
+                                  \r
+  @retval EFI_SUCCESS           The range was unmapped.\r
+  @retval EFI_DEVICE_ERROR      The data was not committed to the target system memory.\r
+                                   \r
+**/
+EFI_STATUS
+EFIAPI
+DmaUnmap (
+  IN  VOID                         *Mapping\r
+  )
+{
+  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;
+}
+
+/**                                                                 \r
+  Allocates pages that are suitable for an DmaMap() of type MapOperationBusMasterCommonBuffer.\r
+  mapping.                                                                       \r
+            \r
+  @param  MemoryType            The type of memory to allocate, EfiBootServicesData or\r
+                                EfiRuntimeServicesData.                               \r
+  @param  Pages                 The number of pages to allocate.                                \r
+  @param  HostAddress           A pointer to store the base system memory address of the\r
+                                allocated range.                                        \r
+\r
+                                @retval EFI_SUCCESS           The requested memory pages were allocated.\r
+  @retval EFI_UNSUPPORTED       Attributes is unsupported. The only legal attribute bits are\r
+                                MEMORY_WRITE_COMBINE and MEMORY_CACHED.                     \r
+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.\r
+  @retval EFI_OUT_OF_RESOURCES  The memory pages could not be allocated.  \r
+                                   \r
+**/EFI_STATUS
+EFIAPI
+DmaAllocateBuffer (
+  IN  EFI_MEMORY_TYPE              MemoryType,
+  IN  UINTN                        Pages,\r
+  OUT VOID                         **HostAddress\r
+  )\r
+{
+  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;
+}
+
+
+/**                                                                 \r
+  Frees memory that was allocated with DmaAllocateBuffer().\r
+            \r
+  @param  Pages                 The number of pages to free.                                \r
+  @param  HostAddress           The base system memory address of the allocated range.                                    \r
+                                  \r
+  @retval EFI_SUCCESS           The requested memory pages were freed.\r
+  @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and Pages\r
+                                was not allocated with DmaAllocateBuffer().\r
+                                     \r
+**/\r
+EFI_STATUS
+EFIAPI
+DmaFreeBuffer (
+  IN  UINTN                        Pages,\r
+  IN  VOID                         *HostAddress\r
+  )\r
+{
+  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;
+}
+
diff --git a/Omap35xxPkg/Library/OmapDmaLib/OmapDmaLib.inf b/Omap35xxPkg/Library/OmapDmaLib/OmapDmaLib.inf
new file mode 100755 (executable)
index 0000000..78f2d01
--- /dev/null
@@ -0,0 +1,48 @@
+#/** @file\r
+#  \r
+#  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>\r
+#  This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution.  The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php\r
+#  \r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#  \r
+#**/\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = OmapDmaLib\r
+  FILE_GUID                      = 09B17D99-BB07-49a8-B0D2-06D6AFCBE3AB\r
+  MODULE_TYPE                    = UEFI_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = OmapDmaLib \r
+  CONSTRUCTOR                    = OmapDmaLibConstructor\r
+\r
+[Sources.common]\r
+  OmapDmaLib.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  EmbeddedPkg/EmbeddedPkg.dec\r
+  ArmPkg/ArmPkg.dec\r
+  Omap35xxPkg/Omap35xxPkg.dec\r
+\r
+[LibraryClasses]\r
+  DebugLib\r
+  UefiBootServicesTableLib\r
+  MemoryAllocationLib\r
+  UncachedMemoryAllocationLib\r
+  IoLib\r
+  \r
+  \r
+[Protocols]\r
+  gEfiCpuArchProtocolGuid\r
+  \r
+[Guids]\r
\r
+[Pcd]\r
+\r
+[Depex]\r
+  gEfiCpuArchProtocolGuid
\ No newline at end of file
index a6d2940cc92c8f3f4f5b77f1c73087757c8cbbb3..3238d61829bfe33be1d5d1f9fe38e50d70f9010d 100644 (file)
@@ -21,8 +21,6 @@
 
 **/
 
-#include <Uefi.h>
-
 #include "MMCHS.h"
 
 EFI_BLOCK_IO_MEDIA gMMCHSMedia = {
@@ -223,6 +221,9 @@ CalculateCardCLKD (
 
   MaxDataTransferRate = gCardInfo.CSDData.TRAN_SPEED;
 
+  // For SD Cards  we would need to send CMD6 to set
+  // speeds abouve 25MHz. High Speed mode 50 MHz and up
+
   //Calculate Transfer rate unit (Bits 2:0 of TRAN_SPEED)
   switch (MaxDataTransferRate & 0x7) {
     case 0:
@@ -593,9 +594,6 @@ GetCardSpecificData (
   //Calculate total number of blocks and max. data transfer rate supported by the detected card.
   GetCardConfigurationData();
 
-  //Change MMCHS clock frequency to what detected card can support.
-  UpdateMMCHSClkFrequency(gCardInfo.ClockFrequencySelect);
-
   return Status;
 }
 
@@ -641,6 +639,9 @@ PerformCardConfiguration (
     return Status;
   }
 
+  //Change MMCHS clock frequency to what detected card can support.
+  UpdateMMCHSClkFrequency(gCardInfo.ClockFrequencySelect);
+
   return EFI_SUCCESS;
 }
 
@@ -729,27 +730,158 @@ WriteBlockData (
   return EFI_SUCCESS;
 }
 
+EFI_STATUS
+DmaBlocks (
+  IN EFI_BLOCK_IO_PROTOCOL        *This,
+  IN  UINTN                       Lba,
+  IN OUT VOID                     *Buffer,
+  IN  UINTN                       BlockCount,
+  IN  OPERATION_TYPE              OperationType
+  )
+{
+  EFI_STATUS            Status;
+  UINTN                 RetryCount = 0;
+  UINTN                 Cmd = 0;
+  UINTN                 CmdInterruptEnable;
+  UINTN                 CmdArgument;
+  VOID                  *BufferMap;
+  EFI_PHYSICAL_ADDRESS BufferAddress;
+  OMAP_DMA4             Dma4;
+  DMA_MAP_OPERATION     DmaOperation;
+
+
+  //Populate the command information based on the operation type.
+  if (OperationType == READ) {
+    Cmd = CMD18; //Multiple block read
+    CmdInterruptEnable = CMD18_INT_EN;
+    DmaOperation = MapOperationBusMasterCommonBuffer;
+  } else if (OperationType == WRITE) { 
+    Cmd = CMD25; //Multiple block write
+    CmdInterruptEnable = CMD25_INT_EN;
+    DmaOperation = MapOperationBusMasterRead;
+  } else {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  // Map passed in buffer for DMA xfer
+  RetryCount = BlockCount * This->Media->BlockSize;
+  Status = DmaMap (DmaOperation, Buffer, &RetryCount, &BufferAddress, &BufferMap);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  #if 0
+  MmioWrite32 (DMA4_CSDP(0), DMA4_CSDP_DATA_TYPE32 | DMA4_CSDP_SRC_BURST_EN64 | DMA4_CSDP_WRITE_MODE_POSTED);
+  MmioWrite32 (DMA4_CEN(0), 0x4096); // Channel Element number
+  MmioWrite32 (DMA4_CFN(0), 0x1);    // Channel Frame number
+  if () {
+    MmioWrite32 (DMA4_CCR(0), X | DMA4_CCR_FS_PACKET | DMA4_CCR_RD_ACTIVE | DMA4_CCR_WR_ACTIVE | DMA4_CCR_DST_AMODE_POST_INC | DMA4_CCR_SEL_SRC_DEST_SYNC_SOURCE);
+    MmioWrite32 (DMA4_CSSA(0), MMCHS_DATA);            // Src is SD Card
+    MmioWrite32 (DMA4_CDSA(0), (UINT32)BufferAddress); // Dst memory
+  } else {
+    MmioWrite32 (DMA4_CCR(0), X | DMA4_CCR_FS_PACKET | DMA4_CCR_RD_ACTIVE | DMA4_CCR_WR_ACTIVE | DMA4_CCR_SRC_AMODE_POST_INC);
+    MmioWrite32 (DMA4_CSSA(0), (UINT32)BufferAddress); // Src memory
+    MmioWrite32 (DMA4_CDSA(0), MMCHS_DATA);            // Dst SD Card
+  }
+  MmioWrite32 (DMA4_CSE(0), 1);
+  MmioWrite32 (DMA4_CSF(0), This->Media->BlockSize);
+  MmioWrite32 (DMA4_CDE(0), 1);
+#endif
+  Dma4.DataType = 0;                      // DMA4_CSDPi[1:0]\r
+  Dma4.ReadPortAccessType =0;             // DMA4_CSDPi[8:7]\r
+  Dma4.WritePortAccessType =0;            // DMA4_CSDPi[15:14]\r
+  Dma4.SourceEndiansim = 0;               // DMA4_CSDPi[21]\r
+  Dma4.DestinationEndianism = 0;          // DMA4_CSDPi[19]\r
+  Dma4.WriteMode = 0;                     // DMA4_CSDPi[17:16]\r
+  Dma4.SourcePacked = 0;                  // DMA4_CSDPi[6]\r
+  Dma4.DestinationPacked = 0;             // DMA4_CSDPi[13]\r
+  Dma4.NumberOfElementPerFrame = 0;       // DMA4_CENi\r
+  Dma4.NumberOfFramePerTransferBlock = 0; // DMA4_CFNi\r
+  Dma4.SourceStartAddress = 0;            // DMA4_CSSAi\r
+  Dma4.DestinationStartAddress = 0;       // DMA4_CDSAi\r
+  Dma4.SourceElementIndex = 0;            // DMA4_CSEi\r
+  Dma4.SourceFrameIndex = 0;              // DMA4_CSFi\r
+  Dma4.DestinationElementIndex = 0;       // DMA4_CDEi\r
+  Dma4.DestinationFrameIndex = 0;         // DMA4_CDFi\r
+  Dma4.ReadPortAccessMode = 0;            // DMA4_CCRi[13:12]\r
+  Dma4.WritePortAccessMode = 0;           // DMA4_CCRi[15:14]\r
+  Dma4.ReadPriority = 0;                  // DMA4_CCRi[6]\r
+  Dma4.WritePriority = 0;                 // DMA4_CCRi[23]\r
+  Dma4.ReadRequestNumber = 0;             // DMA4_CCRi[4:0]\r
+  Dma4.WriteRequestNumber = 0;            // DMA4_CCRi[20:19]
+
+  EnableDmaChannel (2, &Dma4);
+  
+
+  //Set command argument based on the card access mode (Byte mode or Block mode)
+  if (gCardInfo.OCRData.AccessMode & BIT1) {
+    CmdArgument = Lba;
+  } else {
+    CmdArgument = Lba * This->Media->BlockSize;
+  }
+
+  //Send Command.
+  Status = SendCmd (Cmd, CmdInterruptEnable, CmdArgument);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "CMD fails. Status: %x\n", Status));
+    return Status;
+  }
+
+  DisableDmaChannel (2);
+  Status = DmaUnmap (BufferMap);
+
+  return Status;
+}
+
 
 EFI_STATUS
-TransferBlockData (
-  IN  EFI_BLOCK_IO_PROTOCOL       *This,
-  OUT VOID                        *Buffer,
+TransferBlock (
+  IN EFI_BLOCK_IO_PROTOCOL        *This,
+  IN  UINTN                       Lba,
+  IN OUT VOID                     *Buffer,
   IN  OPERATION_TYPE              OperationType
   )
 {
   EFI_STATUS Status;
   UINTN      MmcStatus;
   UINTN      RetryCount = 0;
+  UINTN      Cmd = 0;
+  UINTN      CmdInterruptEnable = 0;
+  UINTN      CmdArgument = 0;
+
+
+  //Populate the command information based on the operation type.
+  if (OperationType == READ) {
+    Cmd = CMD17; //Single block read
+    CmdInterruptEnable = CMD18_INT_EN;
+  } else if (OperationType == WRITE) { 
+    Cmd = CMD24; //Single block write
+    CmdInterruptEnable = CMD24_INT_EN;
+  }
+
+  //Set command argument based on the card access mode (Byte mode or Block mode)
+  if (gCardInfo.OCRData.AccessMode & BIT1) {
+    CmdArgument = Lba;
+  } else {
+    CmdArgument = Lba * This->Media->BlockSize;
+  }
+
+  //Send Command.
+  Status = SendCmd (Cmd, CmdInterruptEnable, CmdArgument);
+  if (EFI_ERROR(Status)) {
+    DEBUG ((EFI_D_ERROR, "CMD fails. Status: %x\n", Status));
+    return Status;
+  }
 
   //Read or Write data.
   if (OperationType == READ) {
-    Status = ReadBlockData(This, Buffer);
+    Status = ReadBlockData (This, Buffer);
     if (EFI_ERROR(Status)) {
       DEBUG((EFI_D_ERROR, "ReadBlockData fails.\n"));
       return Status;
     }
   } else if (OperationType == WRITE) {
-    Status = WriteBlockData(This, Buffer);
+    Status = WriteBlockData (This, Buffer);
     if (EFI_ERROR(Status)) {
       DEBUG((EFI_D_ERROR, "WriteBlockData fails.\n"));
       return Status;
@@ -891,9 +1023,8 @@ DetectCard (
   gMMCHSMedia.ReadOnly     = (MmioRead32 (GPIO1_BASE + GPIO_DATAIN) & BIT23) == BIT23;
   gMMCHSMedia.MediaPresent = TRUE; 
   gMMCHSMedia.MediaId++; 
-  gMediaChange = FALSE;
 
-  DEBUG ((EFI_D_INFO, "SD Card Media Change\n"));
+  DEBUG ((EFI_D_INFO, "SD Card Media Change on Handle 0x%08x\n", gImageHandle));
 
   return Status;
 }
@@ -910,26 +1041,17 @@ SdReadWrite (
 {
   EFI_STATUS Status = EFI_SUCCESS;
   UINTN      RetryCount = 0;
-  UINTN      NumBlocks;
-  UINTN      Cmd = 0;
-  UINTN      CmdInterruptEnable = 0;
-  UINTN      CmdArgument = 0;
+  UINTN      BlockCount;
+  UINTN      BytesToBeTranferedThisPass;
+  UINTN      BytesRemainingToBeTransfered;
   EFI_TPL    OldTpl;\r
-  BOOLEAN    MediaPresentLastTime;\r
   BOOLEAN    Update;\r
 
-  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
-
-
-  if (Buffer == NULL) {
-    Status = EFI_INVALID_PARAMETER;
-    goto Done;
-  }
   
   Update               = FALSE;
-  MediaPresentLastTime = gMMCHSMedia.MediaPresent;
 
   if (gMediaChange) {
+    Update = TRUE;
     Status = DetectCard  ();
     if (EFI_ERROR (Status)) {
       // We detected a removal
@@ -937,8 +1059,6 @@ SdReadWrite (
       gMMCHSMedia.LastBlock    = 0;
       gMMCHSMedia.BlockSize    = 512;  // Should be zero but there is a bug in DiskIo
       gMMCHSMedia.ReadOnly     = FALSE; 
-    } else {
-      Update = TRUE;
     }
     gMediaChange             = FALSE;
   } else if (!gMMCHSMedia.MediaPresent) {
@@ -946,7 +1066,8 @@ SdReadWrite (
     goto Done;
   }
 
-  if ((MediaPresentLastTime != gMMCHSMedia.MediaPresent) || Update) {
+  if (Update) {
+    DEBUG ((EFI_D_INFO, "SD Card ReinstallProtocolInterface ()\n"));
     gBS->ReinstallProtocolInterface (\r
           gImageHandle,\r
           &gEfiBlockIoProtocolGuid,\r
@@ -959,7 +1080,12 @@ SdReadWrite (
     goto Done;
   }
 
-   if (Lba > This->Media->LastBlock) {
+  if (Buffer == NULL) {
+    Status = EFI_INVALID_PARAMETER;
+    goto Done;
+  }
+
+  if (Lba > This->Media->LastBlock) {
     Status = EFI_INVALID_PARAMETER;
     goto Done;
   }
@@ -976,54 +1102,42 @@ SdReadWrite (
     goto Done;
   }
 
-  //Populate the command information based on the operation type.
-  if (OperationType == READ) {
-    Cmd = CMD17; //Single block read
-    CmdInterruptEnable = CMD17_INT_EN;
-  } else if (OperationType == WRITE) { 
-    Cmd = CMD24; //Single block write
-    CmdInterruptEnable = CMD24_INT_EN;
-  }
+  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
 
-  //Calculate total number of blocks its going to read.
-  NumBlocks = (BufferSize + (This->Media->BlockSize - 1))/This->Media->BlockSize;
+  BytesRemainingToBeTransfered = BufferSize;
+  while (BytesRemainingToBeTransfered > 0) {
 
-  //Set command argument based on the card access mode (Byte mode or Block mode)
-  if (gCardInfo.OCRData.AccessMode & BIT1) {
-    CmdArgument = (UINTN)Lba;
-  } else {
-    CmdArgument = (UINTN)Lba * This->Media->BlockSize;
-  }
+    if (gMediaChange) {
+      Status = EFI_NO_MEDIA;
+      DEBUG ((EFI_D_INFO, "SdReadWrite() EFI_NO_MEDIA due to gMediaChange\n"));
+      goto DoneRestoreTPL;
+    }
 
-  while(NumBlocks) {
-    //Send Command.
-    Status = SendCmd (Cmd, CmdInterruptEnable, CmdArgument);
-    if (EFI_ERROR(Status)) {
-      DEBUG ((EFI_D_ERROR, "CMD fails. Status: %x\n", Status));
-      goto Done;
+    //BytesToBeTranferedThisPass = (BytesToBeTranferedThisPass >= MAX_MMCHS_TRANSFER_SIZE) ? MAX_MMCHS_TRANSFER_SIZE : BytesRemainingToBeTransfered;
+    BytesToBeTranferedThisPass   = This->Media->BlockSize;
+
+    BlockCount = BytesToBeTranferedThisPass/This->Media->BlockSize;
+
+    if (BlockCount > 1) {
+      Status = DmaBlocks (This, Lba, Buffer, BlockCount, OperationType);
+    } else {
+      //Transfer a block worth of data.
+      Status = TransferBlock (This, Lba, Buffer, OperationType);
     }
 
-    //Transfer a block worth of data.
-    Status = TransferBlockData(This, Buffer, OperationType);
     if (EFI_ERROR(Status)) {
       DEBUG ((EFI_D_ERROR, "TransferBlockData fails. %x\n", Status));
-      goto Done;
-    }
-
-    //Adjust command argument.
-    if (gCardInfo.OCRData.AccessMode & BIT1) {
-      CmdArgument++; //Increase BlockIndex by one.
-    } else {
-      CmdArgument += This->Media->BlockSize; //Increase BlockIndex by BlockSize
+      goto DoneRestoreTPL;
     }
 
-    //Adjust Buffer.
+    BytesRemainingToBeTransfered -= BytesToBeTranferedThisPass;
+    Lba    += BlockCount;
     Buffer = (UINT8 *)Buffer + This->Media->BlockSize;
-    NumBlocks--;
   }
 
-Done:\r
+DoneRestoreTPL:\r
   gBS->RestoreTPL (OldTpl);\r
+Done:\r
   return Status;\r
 }
 
@@ -1205,7 +1319,7 @@ MMCHSInitialize (
   ASSERT_EFI_ERROR(Status);
 
   ZeroMem (&gCardInfo, sizeof (CARD_INFO));
+
   Status = gBS->CreateEvent (EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_CALLBACK, TimerCallback, NULL, &gTimerEvent);
   ASSERT_EFI_ERROR (Status);
  
index 8fa1ba1b677a2c9559d07bc25a32cb64c5ab9e7b..e7d8b7e474d37e71a1757dd6c28a7d358eea034e 100644 (file)
@@ -15,6 +15,8 @@
 #ifndef _MMCHS_H_\r
 #define _MMCHS_H_\r
 \r
+#include <Uefi.h>
+\r
 #include <Library/BaseLib.h>
 #include <Library/MemoryAllocationLib.h>
 #include <Library/DebugLib.h>
@@ -22,6 +24,8 @@
 #include <Library/PcdLib.h>
 #include <Library/UefiBootServicesTableLib.h>
 #include <Library/BaseMemoryLib.h>
+#include <Library/OmapLib.h>
+#include <Library/OmapDmaLib.h>
 
 #include <Protocol/EmbeddedExternalDevice.h>\r
 #include <Protocol/BlockIo.h>
index 7ae17968dfc1baadd0048a06d3a60bc5d852f4c4..43327777b79040b61cf529433b72f68a5e523c6f 100644 (file)
@@ -35,6 +35,7 @@
   UefiDriverEntryPoint
   MemoryAllocationLib
   IoLib
+  OmapDmaLib
 
 [Guids]
   
index e257e203b223d72e0aa3e581bd20acd6fd416364..e7884590a508b76dbe4c53bace6352eac8116488 100644 (file)
 [Includes.common]
   Include                        # Root include for the package
 
+[LibraryClasses]\r
+  ##  @libraryclass  Abstract location of basic OMAP components\r
+  ##\r
+  OmapLib|Include/Library/OmapLib.h\r
+  \r
+  ##  @libraryclass  Abstract OMAP and ARM DMA, modeled after PCI IO protocol\r
+  ##\r
+  OmapDmaLib|Include/Library/OmapDmaLib.h\r
+
+
 [Guids.common]
   gOmap35xxTokenSpaceGuid    =  { 0x24b09abe, 0x4e47, 0x481c, { 0xa9, 0xad, 0xce, 0xf1, 0x2c, 0x39, 0x23, 0x27} } 
 
index 5cf160d51663cdcb0893fe7dda8e2d3f4c7084e1..31c0bc7ec00b006ef6a8e8022efc9b0e0465d898 100644 (file)
@@ -49,6 +49,7 @@
 
   IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
   OmapLib|Omap35xxPkg/Library/OmapLib/OmapLib.inf
+  OmapDmaLib|Omap35xxPkg/Library/OmapDmaLib/OmapDmaLib.inf
   
   MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
   UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
 [Components.common]
   Omap35xxPkg/Library/Omap35xxTimerLib/Omap35xxTimerLib.inf  
   Omap35xxPkg/Library/OmapLib/OmapLib.inf
+  Omap35xxPkg/Library/OmapLib/OmapDmaLib.inf
   
   Omap35xxPkg/Flash/Flash.inf
   Omap35xxPkg/MMCHSDxe/MMCHS.inf
index b264349b99b06df44338defa454beae9e1951260..dd5e8f7b67dfbd2a17dbc1979d284fc641cc2d50 100644 (file)
@@ -13,9 +13,7 @@
 **/
 
 #include "PciEmulation.h"
-#include <Omap3530/Omap3530.h>
 
-EFI_CPU_ARCH_PROTOCOL      *gCpu;
 EMBEDDED_EXTERNAL_DEVICE   *gTPS65950;
 
 #define HOST_CONTROLLER_OPERATION_REG_SIZE  0x44
@@ -263,41 +261,18 @@ PciIoMap (
   OUT    VOID                           **Mapping
   )
 {
-  MAP_INFO_INSTANCE     *Map;
-  EFI_STATUS            Status;
-
-  if ( HostAddress == NULL || NumberOfBytes == NULL || 
-       DeviceAddress == NULL || Mapping == NULL ) {
-    
-    return EFI_INVALID_PARAMETER;
-  }
-  
-
-  if (Operation >= EfiPciOperationMaximum) {
+  DMA_MAP_OPERATION   DmaOperation;
+
+  if (Operation == EfiPciIoOperationBusMasterRead) {
+    DmaOperation = MapOperationBusMasterRead;
+  } else if (Operation == EfiPciIoOperationBusMasterWrite) {
+    DmaOperation = MapOperationBusMasterWrite;
+  } else if (Operation == EfiPciIoOperationBusMasterCommonBuffer) {
+    DmaOperation = MapOperationBusMasterCommonBuffer;
+  } else {
     return EFI_INVALID_PARAMETER;
   }
-
-  *DeviceAddress = ConvertToPhysicalAddress (HostAddress);
-
-  // Data cache flush (HostAddress, NumberOfBytes);
-
-  // Remember range so we can flush on the other side
-  Status = gBS->AllocatePool (EfiBootServicesData, sizeof (PCI_DMA_MAP), (VOID **) &Map);
-  if (EFI_ERROR(Status)) {
-    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;
+  return DmaMap (DmaOperation, HostAddress, NumberOfBytes, DeviceAddress, Mapping);
 }
 
 EFI_STATUS
@@ -306,24 +281,7 @@ PciIoUnmap (
   IN  VOID                         *Mapping
   )
 {
-  PCI_DMA_MAP *Map;
-  
-  if (Mapping == NULL) {
-    ASSERT (FALSE);
-    return EFI_INVALID_PARAMETER;
-  }
-  
-  Map = (PCI_DMA_MAP *)Mapping;
-  if (Map->Operation == EfiPciOperationBusMasterWrite) {
-    //
-    // 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;
+  return DmaUnmap (Mapping);
 }
 
 EFI_STATUS
@@ -337,29 +295,14 @@ PciIoAllocateBuffer (
   )
 {
   if (Attributes & EFI_PCI_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER) {
+    // Check this
     return EFI_UNSUPPORTED;
   }
 
-  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;
+  return DmaAllocateBuffer (MemoryType, Pages, HostAddress);
 }
 
+
 EFI_STATUS
 PciIoFreeBuffer (
   IN EFI_PCI_IO_PROTOCOL           *This,
@@ -367,12 +310,7 @@ PciIoFreeBuffer (
   IN  VOID                         *HostAddress
   )
 {
-  if (HostAddress == NULL) {
-     return EFI_INVALID_PARAMETER;
-  } 
-  
-  UncachedFreePages (HostAddress, Pages);
-  return EFI_SUCCESS;
+  return DmaFreeBuffer (Pages, HostAddress);
 }
 
 
@@ -508,9 +446,6 @@ PciEmulationEntryPoint (
   UINT8                   PhysicalPorts;
   UINTN                   Count;
 
-  // Get the Cpu protocol for later use
-  Status = gBS->LocateProtocol(&gEfiCpuArchProtocolGuid, NULL, (VOID **)&gCpu);
-  ASSERT_EFI_ERROR(Status);
 
   //Configure USB host for OMAP3530.
   ConfigureUSBHost();
index 6a8668786fa175e1c12cbd7da519df1fd169fb87..066a553950cff2c57617b0a74fb81044648b14ff 100644 (file)
 #include <Library/PciLib.h>\r
 #include <Library/UefiLib.h>\r
 #include <Library/UefiBootServicesTableLib.h>\r
-#include <Library/UncachedMemoryAllocationLib.h>\r
+#include <Library/OmapDmaLib.h>\r
 \r
 #include <Protocol/EmbeddedExternalDevice.h>\r
-#include <Protocol/Cpu.h>\r
 #include <Protocol/DevicePath.h>\r
 #include <Protocol/PciIo.h>\r
 #include <Protocol/PciRootBridgeIo.h>\r
@@ -40,7 +39,9 @@
 #include <IndustryStandard/Pci22.h>\r
 #include <IndustryStandard/Acpi.h>\r
 \r
-extern EFI_CPU_ARCH_PROTOCOL  *gCpu;\r
+#include <Omap3530/Omap3530.h>
+\r
+\r
 \r
 #define EFI_RESOURCE_NONEXISTENT  0xFFFFFFFFFFFFFFFFULL\r
 #define EFI_RESOURCE_LESS         0xFFFFFFFFFFFFFFFEULL\r
@@ -99,21 +100,6 @@ typedef union {
 } PTR;\r
 \r
 \r
-typedef struct {\r
-  EFI_PHYSICAL_ADDRESS                      HostAddress;\r
-  EFI_PHYSICAL_ADDRESS                      DeviceAddress;\r
-  UINTN                                     NumberOfBytes;\r
-  EFI_PCI_IO_PROTOCOL_OPERATION             Operation;\r
-  \r
-} MAP_INFO_INSTANCE;\r
-\r
-\r
-typedef struct {\r
-  EFI_PHYSICAL_ADDRESS                        HostAddress;\r
-  EFI_PHYSICAL_ADDRESS                        DeviceAddress;\r
-  UINTN                                       NumberOfBytes;\r
-  EFI_PCI_IO_PROTOCOL_OPERATION               Operation;\r
-} PCI_DMA_MAP;\r
 \r
 EFI_STATUS\r
 EFIAPI\r
index 9035f200b4c5ee7a20a08667433dafaae21dfb27..e9da1fb4f7133555f191afaa6f2b75d05b5152c9 100644 (file)
   UefiBootServicesTableLib\r
   UefiDriverEntryPoint\r
   UefiRuntimeServicesTableLib\r
-  UncachedMemoryAllocationLib\r
   IoLib\r
+  OmapDmaLib\r
 \r
 [Protocols]\r
   gEfiPciRootBridgeIoProtocolGuid\r
   gEfiDevicePathProtocolGuid\r
   gEfiPciHostBridgeResourceAllocationProtocolGuid\r
-  gEfiCpuArchProtocolGuid\r
   gEfiPciIoProtocolGuid\r
   gEmbeddedExternalDeviceProtocolGuid\r
 \r
 [Depex]\r
   gEfiMetronomeArchProtocolGuid AND \r
-  gEfiCpuArchProtocolGuid AND\r
   gEmbeddedExternalDeviceProtocolGuid\r
   
\ No newline at end of file