mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-15 15:07:16 +00:00
parent
c888ff0d76
commit
7876dfcb5e
@ -21,6 +21,9 @@ class Backend_memory {
|
||||
static Genode::Ram_dataspace_capability alloc(Genode::addr_t size,
|
||||
bool cached) {
|
||||
return Genode::env()->ram_session()->alloc(size, cached); }
|
||||
|
||||
static void free(Genode::Ram_dataspace_capability cap) {
|
||||
return Genode::env()->ram_session()->free(cap); }
|
||||
};
|
||||
|
||||
#endif /* _ARM__PLATFORM__LX_MEM_ */
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* \brief Platform specific part of memory allocation
|
||||
* \author Alexander Boettcher
|
||||
* \author Alexander Boettcher
|
||||
* \date 2013-03-18
|
||||
*/
|
||||
|
||||
@ -20,6 +20,8 @@ class Backend_memory {
|
||||
|
||||
static Genode::Ram_dataspace_capability alloc(Genode::addr_t size,
|
||||
bool cached);
|
||||
|
||||
static void free(Genode::Ram_dataspace_capability cap);
|
||||
};
|
||||
|
||||
#endif /* _X86__PLATFORM__LX_MEM_ */
|
||||
|
@ -12,6 +12,8 @@
|
||||
*/
|
||||
|
||||
/* Genode inludes */
|
||||
#include <ram_session/client.h>
|
||||
#include <base/object_pool.h>
|
||||
#include <pci_session/connection.h>
|
||||
#include <pci_device/client.h>
|
||||
|
||||
@ -175,12 +177,51 @@ class Pci_driver
|
||||
};
|
||||
|
||||
|
||||
/********************************
|
||||
** Backend memory definitions **
|
||||
********************************/
|
||||
|
||||
struct Memory_object_base : Genode::Object_pool<Memory_object_base>::Entry
|
||||
{
|
||||
Memory_object_base(Genode::Ram_dataspace_capability cap)
|
||||
: Genode::Object_pool<Memory_object_base>::Entry(cap) {}
|
||||
virtual ~Memory_object_base() {};
|
||||
|
||||
virtual void free() = 0;
|
||||
|
||||
Genode::Ram_dataspace_capability ram_cap()
|
||||
{
|
||||
using namespace Genode;
|
||||
return reinterpret_cap_cast<Ram_dataspace>(cap());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct Ram_object : Memory_object_base
|
||||
{
|
||||
Ram_object(Genode::Ram_dataspace_capability cap)
|
||||
: Memory_object_base(cap) {}
|
||||
|
||||
void free();
|
||||
};
|
||||
|
||||
|
||||
struct Dma_object : Memory_object_base
|
||||
{
|
||||
Dma_object(Genode::Ram_dataspace_capability cap)
|
||||
: Memory_object_base(cap) {}
|
||||
|
||||
void free();
|
||||
};
|
||||
|
||||
|
||||
/*********************
|
||||
** Linux interface **
|
||||
*********************/
|
||||
|
||||
static Pci::Device_capability pci_device_cap;
|
||||
static Pci::Connection pci;
|
||||
static Genode::Object_pool<Memory_object_base> memory_pool;
|
||||
|
||||
int pci_register_driver(struct pci_driver *drv)
|
||||
{
|
||||
@ -319,13 +360,42 @@ const char *pci_name(const struct pci_dev *pdev)
|
||||
return "dummy";
|
||||
}
|
||||
|
||||
|
||||
void Ram_object::free() { Genode::env()->ram_session()->free(ram_cap()); }
|
||||
|
||||
|
||||
void Dma_object::free() { pci.free_dma_buffer(pci_device_cap, ram_cap()); }
|
||||
|
||||
|
||||
Genode::Ram_dataspace_capability Backend_memory::alloc(Genode::addr_t size,
|
||||
bool cached)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
if (cached)
|
||||
return env()->ram_session()->alloc(size, cached);
|
||||
else
|
||||
return pci.alloc_dma_buffer(pci_device_cap, size);
|
||||
Memory_object_base *o;
|
||||
Genode::Ram_dataspace_capability cap;
|
||||
if (cached) {
|
||||
cap = env()->ram_session()->alloc(size, cached);
|
||||
o = new (env()->heap()) Ram_object(cap);
|
||||
} else {
|
||||
cap = pci.alloc_dma_buffer(pci_device_cap, size);
|
||||
o = new (env()->heap()) Dma_object(cap);
|
||||
}
|
||||
|
||||
memory_pool.insert(o);
|
||||
return cap;
|
||||
}
|
||||
|
||||
|
||||
void Backend_memory::free(Genode::Ram_dataspace_capability cap)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
Memory_object_base *o = memory_pool.lookup_and_lock(cap);
|
||||
if (!o)
|
||||
return;
|
||||
|
||||
o->free();
|
||||
memory_pool.remove_locked(o);
|
||||
destroy(env()->heap(), o);
|
||||
}
|
||||
|
@ -177,6 +177,9 @@ class Storage_device : public Genode::List<Storage_device>::Element,
|
||||
|
||||
Genode::Ram_dataspace_capability alloc_dma_buffer(Genode::size_t size) {
|
||||
return Backend_memory::alloc(size, false); }
|
||||
|
||||
void free_dma_buffer(Genode::Ram_dataspace_capability cap) {
|
||||
return Backend_memory::free(cap); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -25,18 +25,49 @@ namespace Block {
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
class Session_component_base;
|
||||
class Session_component;
|
||||
class Root;
|
||||
};
|
||||
|
||||
|
||||
class Block::Session_component : public Block::Session_rpc_object
|
||||
/**
|
||||
* We have a hen and egg situation that makes this base class necessary.
|
||||
* The Block::Session_rpc_object construction depends on a dataspace for
|
||||
* the packet stream. The dataspace on the other hand is constructed by
|
||||
* the driver, which is created on demand when creating a session.
|
||||
* When creating the driver, and dataspace outside the Session_component
|
||||
* constructor within _create_session of the root component, we would have
|
||||
* to destroy the driver and dataspace within the destructor body of
|
||||
* Session_component, which will lead to problems, because the packet stream
|
||||
* destructors will be called after the shared memory already vanished.
|
||||
*/
|
||||
class Block::Session_component_base
|
||||
{
|
||||
protected:
|
||||
|
||||
Driver_factory &_driver_factory;
|
||||
Driver &_driver;
|
||||
Ram_dataspace_capability _rq_ds;
|
||||
|
||||
Session_component_base(Driver_factory &factory, size_t tx_buf_size)
|
||||
: _driver_factory(factory),
|
||||
_driver(*factory.create()),
|
||||
_rq_ds(_driver.alloc_dma_buffer(tx_buf_size)) {}
|
||||
|
||||
~Session_component_base()
|
||||
{
|
||||
_driver.free_dma_buffer(_rq_ds);
|
||||
_driver_factory.destroy(&_driver);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class Block::Session_component : public Block::Session_component_base,
|
||||
public Block::Session_rpc_object
|
||||
{
|
||||
private:
|
||||
|
||||
Driver_factory &_driver_factory;
|
||||
Driver &_driver;
|
||||
Ram_dataspace_capability _rq_ds;
|
||||
addr_t _rq_phys;
|
||||
Signal_rpc_member<Session_component> _sink_ack;
|
||||
Signal_rpc_member<Session_component> _sink_submit;
|
||||
@ -149,14 +180,10 @@ class Block::Session_component : public Block::Session_rpc_object
|
||||
* \param driver_factory factory to create and destroy driver objects
|
||||
* \param ep entrypoint handling this session component
|
||||
*/
|
||||
Session_component(Ram_dataspace_capability rq_ds,
|
||||
Driver &driver,
|
||||
Driver_factory &driver_factory,
|
||||
Server::Entrypoint &ep)
|
||||
: Session_rpc_object(rq_ds, ep.rpc_ep()),
|
||||
_driver_factory(driver_factory),
|
||||
_driver(driver),
|
||||
_rq_ds(rq_ds),
|
||||
Session_component(Driver_factory &driver_factory,
|
||||
Server::Entrypoint &ep, size_t buf_size)
|
||||
: Session_component_base(driver_factory, buf_size),
|
||||
Session_rpc_object(_rq_ds, ep.rpc_ep()),
|
||||
_rq_phys(Dataspace_client(_rq_ds).phys_addr()),
|
||||
_sink_ack(ep, *this, &Session_component::_ready_to_ack),
|
||||
_sink_submit(ep, *this, &Session_component::_packet_avail),
|
||||
@ -166,7 +193,7 @@ class Block::Session_component : public Block::Session_rpc_object
|
||||
_tx.sigh_ready_to_ack(_sink_ack);
|
||||
_tx.sigh_packet_avail(_sink_submit);
|
||||
|
||||
driver.session = this;
|
||||
_driver.session = this;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -198,12 +225,6 @@ class Block::Session_component : public Block::Session_rpc_object
|
||||
_packet_avail(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~Session_component() {
|
||||
_driver_factory.destroy(&_driver); }
|
||||
|
||||
|
||||
/*******************************
|
||||
** Block session interface **
|
||||
@ -262,11 +283,8 @@ class Block::Root : public Genode::Root_component<Block::Session_component,
|
||||
throw Root::Quota_exceeded();
|
||||
}
|
||||
|
||||
Driver * driver = _driver_factory.create();
|
||||
Ram_dataspace_capability ds_cap;
|
||||
ds_cap = driver->alloc_dma_buffer(tx_buf_size);
|
||||
return new (md_alloc())
|
||||
Session_component(ds_cap, *driver, _driver_factory, _ep);
|
||||
return new (md_alloc()) Session_component(_driver_factory,
|
||||
_ep, tx_buf_size);
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -147,6 +147,12 @@ struct Block::Driver
|
||||
alloc_dma_buffer(Genode::size_t size) {
|
||||
return Genode::env()->ram_session()->alloc(size, false); }
|
||||
|
||||
/**
|
||||
* Free buffer which is suitable for DMA.
|
||||
*/
|
||||
virtual void free_dma_buffer(Genode::Ram_dataspace_capability c) {
|
||||
return Genode::env()->ram_session()->free(c); }
|
||||
|
||||
/**
|
||||
* Synchronize with device.
|
||||
*
|
||||
|
@ -563,6 +563,7 @@ class Ahci_device_base
|
||||
}
|
||||
|
||||
virtual Ram_dataspace_capability alloc_dma_buffer(size_t size) = 0;
|
||||
virtual void free_dma_buffer(Ram_dataspace_capability cap) = 0;
|
||||
};
|
||||
|
||||
#endif /* _AHCI_DEVICE_BASE_H_ */
|
||||
|
@ -81,6 +81,9 @@ class Ahci_driver_base : public Block::Driver
|
||||
|
||||
Ram_dataspace_capability alloc_dma_buffer(size_t size) {
|
||||
return _device->alloc_dma_buffer(size); }
|
||||
|
||||
void free_dma_buffer(Ram_dataspace_capability cap) {
|
||||
return _device->free_dma_buffer(cap); }
|
||||
};
|
||||
|
||||
#endif /* _AHCI_DRIVER_BASE_H_ */
|
||||
|
@ -205,6 +205,9 @@ class Ahci_device : public Ahci_device_base
|
||||
|
||||
Ram_dataspace_capability alloc_dma_buffer(size_t size) {
|
||||
return _pci.alloc_dma_buffer(_pci_device_cap, size); }
|
||||
|
||||
void free_dma_buffer(Ram_dataspace_capability cap) {
|
||||
return _pci.free_dma_buffer(_pci_device_cap, cap); }
|
||||
};
|
||||
|
||||
#endif /* _AHCI_DEVICE_H_ */
|
||||
|
Loading…
x
Reference in New Issue
Block a user