From 415b50032e849219b575df4ba6309631668f3fb2 Mon Sep 17 00:00:00 2001 From: Alexander Boettcher Date: Thu, 21 Feb 2013 13:43:43 +0100 Subject: [PATCH] dde_kit: support to allocate DMA buffer per device --- os/include/dde_kit/pci.h | 13 +++++++++++++ os/src/lib/dde_kit/pci.cc | 22 ++++++++++++++++++++++ os/src/lib/dde_kit/pci_tree.h | 26 +++++++++++++++++++++++--- 3 files changed, 58 insertions(+), 3 deletions(-) diff --git a/os/include/dde_kit/pci.h b/os/include/dde_kit/pci.h index d22a6db11..989e5d1e0 100644 --- a/os/include/dde_kit/pci.h +++ b/os/include/dde_kit/pci.h @@ -135,6 +135,19 @@ int dde_kit_pci_first_device(int *bus, int *dev, int *fun); */ int dde_kit_pci_next_device(int *bus, int *dev, int *fun); +/** + * Allocate a DMA buffer and map it. If an IOMMU is available this functions + * takes care that DMA to this buffer for the given PCI device is permitted. + * + * \retval bus bus number + * \retval dev device number + * \retval fun function number + * + * \return 0 in case of failure, otherwise the virtual address of the buffer. + */ +dde_kit_addr_t dde_kit_pci_alloc_dma_buffer(int bus, int dev, int fun, + dde_kit_size_t size); + /** * Initialize PCI subsystem * diff --git a/os/src/lib/dde_kit/pci.cc b/os/src/lib/dde_kit/pci.cc index 37f3970f7..17420cd56 100644 --- a/os/src/lib/dde_kit/pci.cc +++ b/os/src/lib/dde_kit/pci.cc @@ -21,9 +21,11 @@ */ #include +#include extern "C" { #include +#include } #include "pci_tree.h" @@ -137,6 +139,26 @@ extern "C" int dde_kit_pci_next_device(int *bus, int *dev, int *fun) } } +extern "C" dde_kit_addr_t dde_kit_pci_alloc_dma_buffer(int bus, int dev, + int fun, + dde_kit_size_t size) +{ + try { + using namespace Genode; + + Ram_dataspace_capability ram_cap; + ram_cap = pci_tree()->alloc_dma_buffer(bus, dev, fun, size); + addr_t base = (addr_t)env()->rm_session()->attach(ram_cap); + + /* add to DDE-kit page tables */ + addr_t phys = Dataspace_client(ram_cap).phys_addr(); + dde_kit_pgtab_set_region_with_size((void *)base, phys, size); + + return base; + } catch (...) { + return 0; + } +} /******************** ** Initialization ** diff --git a/os/src/lib/dde_kit/pci_tree.h b/os/src/lib/dde_kit/pci_tree.h index 809c06f2b..60da22726 100644 --- a/os/src/lib/dde_kit/pci_tree.h +++ b/os/src/lib/dde_kit/pci_tree.h @@ -40,12 +40,14 @@ namespace Dde_kit { private: - Pci::Device_client _device; - unsigned short _bdf; /* bus:device:function */ + Pci::Device_client _device; + unsigned short _bdf; /* bus:device:function */ public: - Pci_device(Pci::Device_capability device_cap) : _device(device_cap) + Pci_device(Pci::Device_capability device_cap) + : + _device(device_cap) { unsigned char bus = ~0, dev = ~0, fun = ~0; @@ -118,6 +120,14 @@ namespace Dde_kit { if (child(RIGHT)) child(RIGHT)->show(); } + + Ram_dataspace_capability alloc_dma_buffer(Pci::Connection &pci_drv, + size_t size) + { + /* trigger that the device gets assigned to this driver */ + pci_drv.config_extended(_device); + return pci_drv.alloc_dma_buffer(_device, size); + } }; class Pci_tree @@ -241,6 +251,16 @@ namespace Dde_kit { _next_bdf(d, bus, dev, fun); } + + Ram_dataspace_capability alloc_dma_buffer(int bus, int dev, + int fun, size_t size) + { + Lock::Guard lock_guard(_lock); + + unsigned short bdf = Pci_device::knit_bdf(bus, dev, fun); + + return _lookup(bdf)->alloc_dma_buffer(_pci_drv, size); + } }; }