view rathaxes_samples_e1000_add_a_dma_abstraction.patch @ 115:5a663f8f0e54

WIP, fix another small bug in rathaxes sequence calls
author Louis Opter <louis@lse.epita.fr>
date Mon, 22 Jul 2013 13:52:00 -0700
parents bfe10def90e3
children f3c7e9b0c5cf
line wrap: on
line source

# HG changeset patch
# Parent af7a1f8589d632497e2f2574570f5153cae59b91
e1000: start a DMA allocation/mapping abstraction

It currently matches a lot the Linux DMA API but it should be usable by
other OSes too. The Linux DMA API is described at the end of the chapter
15 in the LDD3.

This will be useful to remove Linux specific DMA code from
e1000::set_up_device which should be only device independent code.

diff --git a/rathaxes/samples/e1000/CMakeLists.txt b/rathaxes/samples/e1000/CMakeLists.txt
--- a/rathaxes/samples/e1000/CMakeLists.txt
+++ b/rathaxes/samples/e1000/CMakeLists.txt
@@ -5,6 +5,7 @@
                      log.rti
                      lkm.rti
                      device.rti
+                     dma.rti
                      pci.rti
                      socket.rti
                      ethernet.rti
@@ -12,8 +13,9 @@
                      BLT
                      log.blt
                      lkm.blt
+                     device.blt
+                     dma.blt
                      pci.blt
-                     device.blt
                      socket.blt
                      e1000.blt
                      ethernet.blt)
diff --git a/rathaxes/samples/e1000/dma.blt b/rathaxes/samples/e1000/dma.blt
new file mode 100644
--- /dev/null
+++ b/rathaxes/samples/e1000/dma.blt
@@ -0,0 +1,89 @@
+with DMA, Builtin, LKM, Device
+{
+    template type   DMA::AbstractDMAHandle()
+    {
+        chunk   LKM::includes()
+        {
+            #include <linux/dma-mapping.h>
+        }
+
+        decl    data_types()
+        {
+            dma_addr_t  data;
+        }
+
+        map
+        {
+            k_dma_handle: ((dma_addr_t)${self});
+        }
+    }
+
+    template type   DMA::AbstractDMADirection()
+    {
+        decl    data_types()
+        {
+            enum dma_data_direction data;
+        }
+
+        map
+        {
+            k_dma_direction: ((enum dma_data_direction)${self});
+        }
+    }
+
+    template type   DMA::DMADirection()
+    {
+        decl    data_types()
+        {
+            RTX_DMA_BIDIRECTIONAL   = DMA_BIDIRECTIONAL,
+            RTX_DMA_TO_DEVICE       = DMA_TO_DEVICE,
+            RTX_DMA_FROM_DEVICE     = DMA_FROM_DEVICE
+        }
+
+        map
+        {
+            /* XXX: we should use ${DMA::AbstractDMADirection} here: */
+            dma_direction: ((enum dma_data_direction)${self});
+        }
+    }
+
+    template sequence   map(Device::AbstractDevice dev, Builtin::symbol buf, Builtin::number size, DMA::DMADirection dir)
+    {
+        chunk  ::CALL()
+        {
+            ((${DMA::DMA::AbstractDMAHandle})dma_map_single(${dev.k_device}, ${buf}, ${size}, ${dir.dma_direction}));
+        }
+    }
+
+    template sequence   unmap(Device::AbstractDevice dev, DMA::AbstractDMAHandle handle, Builtin::number size, DMA::DMADirection dir)
+    {
+        chunk  ::CALL()
+        {
+            dma_unmap_single(${dev.k_device}, ${handle.k_dma_handle}, ${size}, ${dir.dma_direction});
+        }
+    }
+
+    template sequence   mapping_error(Device::AbstractDevice dev, DMA::AbstractDMAHandle handle)
+    {
+        chunk ::CALL()
+        {
+            dma_mapping_error(${dev.k_device}, ${handle.k_dma_handle});
+        }
+    }
+
+    template sequence   alloc_coherent(Device::AbstractDevice dev, Builtin::number size, DMA::AbstractDMAHandle handle)
+    {
+        chunk  ::CALL()
+        {
+            dma_alloc_coherent(${dev.k_device}, ${size}, &${handle.k_dma_handle}, GFP_KERNEL);
+        }
+    }
+
+    template sequence   free_coherent(Device::AbstractDevice dev, Builtin::number size, Builtin::symbol addr, DMA::AbstractDMAHandle handle)
+    {
+        chunk  ::CALL()
+        {
+            dma_free_coherent(${dev.k_device}, ${size}, ${addr}, ${handle.k_dma_handle});
+        }
+    }
+}
diff --git a/rathaxes/samples/e1000/dma.rti b/rathaxes/samples/e1000/dma.rti
new file mode 100644
--- /dev/null
+++ b/rathaxes/samples/e1000/dma.rti
@@ -0,0 +1,48 @@
+interface DMA : Builtin, LKM, Device
+{
+    provided type   AbstractDMAHandle
+    {
+        chunk       LKM::includes();
+        decl        data_types();
+        attribute   Builtin::symbol.scalar  k_dma_handle;
+    }
+
+    provided type   AbstractDMADirection
+    {
+        decl        data_types();
+        attribute   Builtin::symbol.scalar  k_dma_direction;
+    }
+
+    provided type   DMADirection
+    {
+        decl        data_types();
+        attribute   AbstractDMADirection.scalar dma_direction;
+    }
+
+    provided sequence   map(Device::AbstractDevice, Builtin::symbol, Builtin::number, DMADirection)
+    {
+        provided chunk  ::CALL(); /* -> DMAHandle */
+    }
+
+    provided sequence   unmap(Device::AbstractDevice, AbstractDMAHandle, Builtin::number, DMADirection)
+    {
+        provided chunk  ::CALL();
+    }
+
+    /* XXX: Until we have a real error handling mechanism: */
+    provided sequence   mapping_error(Device::AbstractDevice, AbstractDMAHandle)
+    {
+        provided chunk  ::CALL(); /* -> != 0 if the mapping failed */
+    }
+
+    provided sequence   alloc_coherent(Device::AbstractDevice, Builtin::number, AbstractDMAHandle)
+    {
+        /* return the addr and the handle via the AbstractDMAHandle ptr: */
+        provided chunk  ::CALL();
+    }
+
+    provided sequence   free_coherent(Device::AbstractDevice, Builtin::number, Builtin::symbol, AbstractDMAHandle)
+    {
+        provided chunk  ::CALL();
+    }
+}