mirror of
https://github.com/genodelabs/genode.git
synced 2025-03-23 12:35:41 +00:00
parent
784e728727
commit
02233b64fb
@ -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); }
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
TARGET = device_pd
|
||||
SRC_CC = main.cc
|
||||
LIBS = base server
|
||||
LIBS = base
|
||||
|
||||
REQUIRES = nova
|
||||
|
||||
|
@ -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);
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user