dde_kit: support to allocate DMA buffer per device

This commit is contained in:
Alexander Boettcher 2013-02-21 13:43:43 +01:00 committed by Norman Feske
parent be0fa1f63a
commit 415b50032e
3 changed files with 58 additions and 3 deletions

View File

@ -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
*

View File

@ -21,9 +21,11 @@
*/
#include <base/printf.h>
#include <dataspace/client.h>
extern "C" {
#include <dde_kit/pci.h>
#include <dde_kit/pgtab.h>
}
#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 **

View File

@ -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);
}
};
}