device_pd: use component API

Issue #1987
This commit is contained in:
Norman Feske 2016-10-31 19:19:27 +01:00 committed by Christian Helmuth
parent 784e728727
commit 02233b64fb
3 changed files with 48 additions and 43 deletions

View File

@ -11,13 +11,10 @@
* under the terms of the GNU General Public License version 2.
*/
#include <base/component.h>
#include <os/static_root.h>
#include <base/log.h>
#include <base/sleep.h>
#include <os/server.h>
#include <cap_session/connection.h>
#include <dataspace/client.h>
#include <region_map/client.h>
#include <pd_session/client.h>
@ -30,16 +27,28 @@
#include "../pci_device_pd_ipc.h"
/**
* Custom handling of PD-session depletion during attach operations
*
* The default implementation of 'env().rm()' automatically issues a resource
* request if the PD session quota gets exhausted. For the device PD, we don't
* want to issue resource requests but let the platform driver reflect this
* condition to its client.
*/
struct Expanding_region_map_client : Genode::Region_map_client
{
Expanding_region_map_client(Genode::Capability<Region_map> cap)
: Region_map_client(cap) { }
Genode::Env &_env;
Expanding_region_map_client(Genode::Env &env)
:
Region_map_client(env.pd().address_space()), _env(env)
{ }
Local_addr attach(Genode::Dataspace_capability ds,
Genode::size_t size, Genode::off_t offset,
bool use_local_addr,
Local_addr local_addr,
bool executable) override
Genode::size_t size, Genode::off_t offset,
bool use_local_addr,
Local_addr local_addr,
bool executable) override
{
return Genode::retry<Genode::Region_map::Out_of_metadata>(
[&] () {
@ -55,21 +64,15 @@ struct Expanding_region_map_client : Genode::Region_map_client
char buf[32];
Genode::snprintf(buf, sizeof(buf), "ram_quota=%u",
UPGRADE_QUOTA);
UPGRADE_QUOTA);
Genode::env()->parent()->upgrade(Genode::env()->pd_session_cap(), buf);
});
_env.parent().upgrade(_env.pd_session_cap(), buf);
}
);
}
};
static Genode::Region_map &address_space() {
using namespace Genode;
static Expanding_region_map_client rm(Genode::env()->pd_session()->address_space());
return rm;
}
static bool map_eager(Genode::addr_t const page, unsigned log2_order)
{
using Genode::addr_t;
@ -104,7 +107,7 @@ void Platform::Device_pd_component::attach_dma_mem(Genode::Dataspace_capability
addr_t page = ~0UL;
try {
page = address_space().attach_at(ds_cap, phys);
page = _address_space.attach_at(ds_cap, phys);
} catch (Rm_session::Out_of_metadata) {
throw;
} catch (Rm_session::Region_conflict) {
@ -115,7 +118,7 @@ void Platform::Device_pd_component::attach_dma_mem(Genode::Dataspace_capability
/* sanity check */
if ((page == ~0UL) || (page != phys)) {
if (page != ~0UL)
address_space().detach(page);
_address_space.detach(page);
Genode::error("attachment of DMA memory @ ",
Genode::Hex(phys), "+", Genode::Hex(size), " failed");
@ -134,13 +137,14 @@ void Platform::Device_pd_component::attach_dma_mem(Genode::Dataspace_capability
}
}
void Platform::Device_pd_component::assign_pci(Genode::Io_mem_dataspace_capability io_mem_cap, Genode::uint16_t rid)
void Platform::Device_pd_component::assign_pci(Genode::Io_mem_dataspace_capability io_mem_cap,
Genode::uint16_t rid)
{
using namespace Genode;
Dataspace_client ds_client(io_mem_cap);
addr_t page = address_space().attach(io_mem_cap);
addr_t page = _address_space.attach(io_mem_cap);
/* sanity check */
if (!page)
throw Rm_session::Region_conflict();
@ -173,34 +177,30 @@ void Platform::Device_pd_component::assign_pci(Genode::Io_mem_dataspace_capabili
Genode::log("assignment of ", rid, " succeeded");
/* we don't need the mapping anymore */
address_space().detach(page);
_address_space.detach(page);
}
using namespace Genode;
struct Main
{
Server::Entrypoint &ep;
Genode::Env &env;
Platform::Device_pd_component pd_component;
Static_root<Platform::Device_pd> root;
Expanding_region_map_client rm { env };
Main(Server::Entrypoint &ep)
: ep(ep), root(ep.manage(pd_component))
Platform::Device_pd_component pd_component { rm };
Genode::Static_root<Platform::Device_pd> root { env.ep().manage(pd_component) };
Main(Genode::Env &env) : env(env)
{
env()->parent()->announce(ep.manage(root));
env.parent().announce(env.ep().manage(root));
}
};
/************
** Server **
************/
/***************
** Component **
***************/
void Component::construct(Genode::Env &env) { static Main main(env); }
namespace Server {
char const *name() { return "device_pd_ep"; }
size_t stack_size() { return 1024*sizeof(long); }
void construct(Entrypoint &ep) { static Main server(ep); }
}

View File

@ -1,6 +1,6 @@
TARGET = device_pd
SRC_CC = main.cc
LIBS = base server
LIBS = base
REQUIRES = nova

View File

@ -57,6 +57,11 @@ struct Platform::Device_pd_client : Genode::Rpc_client<Device_pd>
struct Platform::Device_pd_component : Genode::Rpc_object<Device_pd,
Device_pd_component>
{
Genode::Region_map &_address_space;
Device_pd_component(Genode::Region_map &address_space)
: _address_space(address_space) { }
void attach_dma_mem(Genode::Dataspace_capability);
void assign_pci(Genode::Io_mem_dataspace_capability, Genode::uint16_t);
};