Mercurial > archived > louis > epitech > mq > rathaxes
view rathaxes_samples_e1000_add_a_dma_abstraction.patch @ 138:6527e078252c
Wip
author | Louis Opter <kalessin@kalessin.fr> |
---|---|
date | Sun, 19 Jan 2014 13:45:30 -0800 |
parents | d84bc9a46771 |
children |
line wrap: on
line source
# HG changeset patch # Parent fb28afe4be73b2dc25945c07dcac93718b0f3e3e rathaxes: start a DMA allocation/mapping abstraction in the e1000 sample 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,103 @@ +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::DMAHandle() + { + decl data_types() + { + ${DMA::AbstractDMAHandle} data; + } + + map + { + /* XXX: we should use ${DMA::AbstractDMAHandle} here: */ + 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_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,54 @@ +interface DMA : Builtin, LKM, Device +{ + provided type AbstractDMAHandle + { + chunk LKM::includes(); + decl data_types(); + attribute Builtin::symbol.scalar k_dma_handle; + } + + provided type DMAHandle + { + decl data_types(); + attribute AbstractDMAHandle.scalar 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(); + } +}