pci: allocate below 3G physical for 32bit & iommu

Related to #696.

Issue #1045
This commit is contained in:
Alexander Boettcher 2015-02-08 13:02:11 +01:00 committed by Christian Helmuth
parent 8c66a4b1be
commit 34719c4589
1 changed files with 32 additions and 14 deletions

View File

@ -82,6 +82,7 @@ namespace Pci {
Genode::Allocator *_md_alloc; Genode::Allocator *_md_alloc;
Genode::List<Device_component> _device_list; Genode::List<Device_component> _device_list;
Device_pd_client *_child; Device_pd_client *_child;
Genode::Ram_connection *_ram;
/** /**
* Scan PCI buses for a device * Scan PCI buses for a device
@ -160,9 +161,10 @@ namespace Pci {
*/ */
Session_component(Genode::Rpc_entrypoint *ep, Session_component(Genode::Rpc_entrypoint *ep,
Genode::Allocator *md_alloc, Genode::Allocator *md_alloc,
Device_pd_client *child) Device_pd_client *child,
Genode::Ram_connection *ram)
: :
_ep(ep), _md_alloc(md_alloc), _child(child) { } _ep(ep), _md_alloc(md_alloc), _child(child), _ram(ram) { }
/** /**
* Destructor * Destructor
@ -308,12 +310,19 @@ namespace Pci {
return io_mem->dataspace(); return io_mem->dataspace();
} }
Genode::Ram_dataspace_capability alloc_dma_buffer(Device_capability device_cap, /**
Genode::size_t size) * De-/Allocation of dma capable dataspaces
{ */
Genode::Ram_dataspace_capability ram = typedef Genode::Ram_dataspace_capability Ram_capability;
Genode::env()->ram_session()->alloc(size, Genode::UNCACHED);
Ram_capability alloc_dma_buffer(Device_capability device_cap,
Genode::size_t size)
{
if (Genode::env()->ram_session()->transfer_quota(_ram->cap(),
size))
return Ram_capability();
Ram_capability ram = _ram->alloc(size, Genode::UNCACHED);
if (!ram.valid() || !_child) if (!ram.valid() || !_child)
return ram; return ram;
@ -322,11 +331,10 @@ namespace Pci {
return ram; return ram;
} }
void free_dma_buffer(Device_capability device_cap, void free_dma_buffer(Device_capability, Ram_capability ram)
Genode::Ram_dataspace_capability cap)
{ {
if (cap.valid()) if (ram.valid())
Genode::env()->ram_session()->free(cap); _ram->free(ram);
} }
}; };
@ -337,7 +345,8 @@ namespace Pci {
/* for now we have only one device pd for all pci devices */ /* for now we have only one device pd for all pci devices */
Device_pd_client *_pd_device_client; Device_pd_client *_pd_device_client;
/* Ram_session for allocation of dma capable dataspaces */
Genode::Ram_connection _ram;
void _parse_config() void _parse_config()
{ {
@ -378,7 +387,8 @@ namespace Pci {
/* FIXME: pass quota to session-component constructor */ /* FIXME: pass quota to session-component constructor */
return new (md_alloc()) Session_component(ep(), md_alloc(), return new (md_alloc()) Session_component(ep(), md_alloc(),
_pd_device_client); _pd_device_client,
&_ram);
} }
public: public:
@ -396,13 +406,21 @@ namespace Pci {
Genode::Capability <Device_pd> pci_device_pd) Genode::Capability <Device_pd> pci_device_pd)
: :
Genode::Root_component<Session_component>(ep, md_alloc), Genode::Root_component<Session_component>(ep, md_alloc),
_pd_device_client(0) _pd_device_client(0),
/* restrict physical address to 4G on 32/64bit in general XXX */
/* restrict physical address to 3G on 32bit with device_pd */
_ram("dma", 0, (pci_device_pd.valid() && sizeof(void *) == 4) ?
0xc0000000UL : 0x100000000ULL)
{ {
_parse_config(); _parse_config();
if (pci_device_pd.valid()) if (pci_device_pd.valid())
_pd_device_client = new (md_alloc) Device_pd_client(pci_device_pd); _pd_device_client = new (md_alloc) Device_pd_client(pci_device_pd);
/* associate _ram session with ram_session of process */
_ram.ref_account(Genode::env()->ram_session_cap());
Genode::env()->ram_session()->transfer_quota(_ram.cap(), 0x1000);
/* enforce initial bus scan */ /* enforce initial bus scan */
bus_valid(); bus_valid();
} }