mirror of
https://github.com/genodelabs/genode.git
synced 2025-05-25 19:54:26 +00:00
parent
784e728727
commit
02233b64fb
@ -11,13 +11,10 @@
|
|||||||
* under the terms of the GNU General Public License version 2.
|
* under the terms of the GNU General Public License version 2.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <base/component.h>
|
||||||
#include <os/static_root.h>
|
#include <os/static_root.h>
|
||||||
#include <base/log.h>
|
#include <base/log.h>
|
||||||
#include <base/sleep.h>
|
#include <base/sleep.h>
|
||||||
|
|
||||||
#include <os/server.h>
|
|
||||||
|
|
||||||
#include <cap_session/connection.h>
|
|
||||||
#include <dataspace/client.h>
|
#include <dataspace/client.h>
|
||||||
#include <region_map/client.h>
|
#include <region_map/client.h>
|
||||||
#include <pd_session/client.h>
|
#include <pd_session/client.h>
|
||||||
@ -30,10 +27,22 @@
|
|||||||
#include "../pci_device_pd_ipc.h"
|
#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
|
struct Expanding_region_map_client : Genode::Region_map_client
|
||||||
{
|
{
|
||||||
Expanding_region_map_client(Genode::Capability<Region_map> cap)
|
Genode::Env &_env;
|
||||||
: Region_map_client(cap) { }
|
|
||||||
|
Expanding_region_map_client(Genode::Env &env)
|
||||||
|
:
|
||||||
|
Region_map_client(env.pd().address_space()), _env(env)
|
||||||
|
{ }
|
||||||
|
|
||||||
Local_addr attach(Genode::Dataspace_capability ds,
|
Local_addr attach(Genode::Dataspace_capability ds,
|
||||||
Genode::size_t size, Genode::off_t offset,
|
Genode::size_t size, Genode::off_t offset,
|
||||||
@ -57,19 +66,13 @@ struct Expanding_region_map_client : Genode::Region_map_client
|
|||||||
Genode::snprintf(buf, sizeof(buf), "ram_quota=%u",
|
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)
|
static bool map_eager(Genode::addr_t const page, unsigned log2_order)
|
||||||
{
|
{
|
||||||
using Genode::addr_t;
|
using Genode::addr_t;
|
||||||
@ -104,7 +107,7 @@ void Platform::Device_pd_component::attach_dma_mem(Genode::Dataspace_capability
|
|||||||
addr_t page = ~0UL;
|
addr_t page = ~0UL;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
page = address_space().attach_at(ds_cap, phys);
|
page = _address_space.attach_at(ds_cap, phys);
|
||||||
} catch (Rm_session::Out_of_metadata) {
|
} catch (Rm_session::Out_of_metadata) {
|
||||||
throw;
|
throw;
|
||||||
} catch (Rm_session::Region_conflict) {
|
} catch (Rm_session::Region_conflict) {
|
||||||
@ -115,7 +118,7 @@ void Platform::Device_pd_component::attach_dma_mem(Genode::Dataspace_capability
|
|||||||
/* sanity check */
|
/* sanity check */
|
||||||
if ((page == ~0UL) || (page != phys)) {
|
if ((page == ~0UL) || (page != phys)) {
|
||||||
if (page != ~0UL)
|
if (page != ~0UL)
|
||||||
address_space().detach(page);
|
_address_space.detach(page);
|
||||||
|
|
||||||
Genode::error("attachment of DMA memory @ ",
|
Genode::error("attachment of DMA memory @ ",
|
||||||
Genode::Hex(phys), "+", Genode::Hex(size), " failed");
|
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;
|
using namespace Genode;
|
||||||
|
|
||||||
Dataspace_client ds_client(io_mem_cap);
|
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 */
|
/* sanity check */
|
||||||
if (!page)
|
if (!page)
|
||||||
throw Rm_session::Region_conflict();
|
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");
|
Genode::log("assignment of ", rid, " succeeded");
|
||||||
|
|
||||||
/* we don't need the mapping anymore */
|
/* we don't need the mapping anymore */
|
||||||
address_space().detach(page);
|
_address_space.detach(page);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
using namespace Genode;
|
|
||||||
|
|
||||||
|
|
||||||
struct Main
|
struct Main
|
||||||
{
|
{
|
||||||
Server::Entrypoint &ep;
|
Genode::Env &env;
|
||||||
|
|
||||||
Platform::Device_pd_component pd_component;
|
Expanding_region_map_client rm { env };
|
||||||
Static_root<Platform::Device_pd> root;
|
|
||||||
|
|
||||||
Main(Server::Entrypoint &ep)
|
Platform::Device_pd_component pd_component { rm };
|
||||||
: ep(ep), root(ep.manage(pd_component))
|
|
||||||
|
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
|
TARGET = device_pd
|
||||||
SRC_CC = main.cc
|
SRC_CC = main.cc
|
||||||
LIBS = base server
|
LIBS = base
|
||||||
|
|
||||||
REQUIRES = nova
|
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,
|
struct Platform::Device_pd_component : Genode::Rpc_object<Device_pd,
|
||||||
Device_pd_component>
|
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 attach_dma_mem(Genode::Dataspace_capability);
|
||||||
void assign_pci(Genode::Io_mem_dataspace_capability, Genode::uint16_t);
|
void assign_pci(Genode::Io_mem_dataspace_capability, Genode::uint16_t);
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user