Integrate SIGNAL session into PD session

This patch removes the SIGNAL service from core and moves its
functionality to the PD session. Furthermore, it unifies the PD service
implementation and terminology across the various base platforms.

Issue #1841
This commit is contained in:
Norman Feske 2016-01-14 13:22:00 +01:00 committed by Christian Helmuth
parent 705ac74498
commit b1910cdd54
83 changed files with 1711 additions and 2234 deletions

View File

@ -19,6 +19,8 @@ SRC_CC += cap_session_component.cc \
pager_ep.cc \
pager_object.cc \
pd_session_component.cc \
pd_assign_pci.cc \
pd_upgrade_ram_quota.cc \
platform.cc \
platform_pd.cc \
platform_services.cc \
@ -28,7 +30,6 @@ SRC_CC += cap_session_component.cc \
rm_session_component.cc \
rm_session_support.cc \
rom_session_component.cc \
signal_session_component.cc \
signal_source_component.cc \
thread_start.cc \
trace_session_component.cc
@ -49,10 +50,11 @@ vpath rom_session_component.cc $(GEN_CORE_DIR)
vpath cap_session_component.cc $(GEN_CORE_DIR)
vpath cpu_session_component.cc $(GEN_CORE_DIR)
vpath pd_session_component.cc $(GEN_CORE_DIR)
vpath pd_assign_pci.cc $(GEN_CORE_DIR)
vpath pd_upgrade_ram_quota.cc $(GEN_CORE_DIR)
vpath rm_session_component.cc $(GEN_CORE_DIR)
vpath io_mem_session_component.cc $(GEN_CORE_DIR)
vpath io_mem_session_support.cc $(GEN_CORE_DIR)
vpath signal_session_component.cc $(GEN_CORE_DIR)
vpath signal_source_component.cc $(GEN_CORE_DIR)
vpath trace_session_component.cc $(GEN_CORE_DIR)
vpath dataspace_component.cc $(GEN_CORE_DIR)

View File

@ -1,35 +0,0 @@
/*
* \brief Fiasco.OC-specific signal source RPC interface
* \author Norman Feske
* \author Stefan Kalkowski
* \date 2011-04-12
*/
/*
* Copyright (C) 2011-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__SIGNAL_SESSION__FOC_SOURCE_H_
#define _INCLUDE__SIGNAL_SESSION__FOC_SOURCE_H_
#include <base/rpc.h>
#include <signal_session/source.h>
namespace Genode {
struct Foc_signal_source : Signal_source
{
/*********************
** RPC declaration **
*********************/
GENODE_RPC(Rpc_request_semaphore, Native_capability, _request_semaphore);
GENODE_RPC_INTERFACE_INHERIT(Signal_source, Rpc_request_semaphore);
};
}
#endif /* _INCLUDE__SIGNAL_SESSION__FOC_SOURCE_H_ */

View File

@ -1,37 +0,0 @@
/*
* \brief Signal-source server interface
* \author Norman Feske
* \date 2010-02-03
*/
/*
* Copyright (C) 2010-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__SIGNAL_SESSION__SOURCE_RPC_OBJECT_H_
#define _INCLUDE__SIGNAL_SESSION__SOURCE_RPC_OBJECT_H_
#include <base/rpc_server.h>
#include <signal_session/foc_source.h>
namespace Genode {
struct Signal_source_rpc_object : Rpc_object<Foc_signal_source, Signal_source_rpc_object>
{
protected:
Native_capability _blocking_semaphore;
public:
Signal_source_rpc_object(Native_capability cap)
: _blocking_semaphore(cap) {}
Native_capability _request_semaphore() { return _blocking_semaphore; }
};
}
#endif /* _INCLUDE__SIGNAL_SESSION__SOURCE_RPC_OBJECT_H_ */

View File

@ -20,12 +20,12 @@
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__SIGNAL_SESSION__SOURCE_CLIENT_H_
#define _INCLUDE__SIGNAL_SESSION__SOURCE_CLIENT_H_
#ifndef _INCLUDE__SIGNAL_SOURCE__CLIENT_H_
#define _INCLUDE__SIGNAL_SOURCE__CLIENT_H_
#include <base/rpc_client.h>
#include <base/thread.h>
#include <signal_session/foc_source.h>
#include <signal_source/foc_signal_source.h>
namespace Fiasco {
#include <l4/sys/irq.h>
@ -63,7 +63,7 @@ namespace Genode {
/**
* Constructor
*/
Signal_source_client(Signal_source_capability cap)
Signal_source_client(Capability<Signal_source> cap)
: Rpc_client<Foc_signal_source>(static_cap_cast<Foc_signal_source>(cap))
{ _init_sem(); }
@ -92,4 +92,4 @@ namespace Genode {
};
}
#endif /* _INCLUDE__SIGNAL_SESSION__SOURCE_CLIENT_H_ */
#endif /* _INCLUDE__SIGNAL_SOURCE__CLIENT_H_ */

View File

@ -0,0 +1,30 @@
/*
* \brief Fiasco.OC-specific signal source RPC interface
* \author Norman Feske
* \author Stefan Kalkowski
* \date 2011-04-12
*/
/*
* Copyright (C) 2011-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__SIGNAL_SOURCE__FOC_SIGNAL_SOURCE_H_
#define _INCLUDE__SIGNAL_SOURCE__FOC_SIGNAL_SOURCE_H_
#include <signal_source/signal_source.h>
#include <base/rpc_server.h>
namespace Genode { struct Foc_signal_source; }
struct Genode::Foc_signal_source : Signal_source
{
GENODE_RPC(Rpc_request_semaphore, Native_capability, _request_semaphore);
GENODE_RPC_INTERFACE_INHERIT(Signal_source, Rpc_request_semaphore);
};
#endif /* _INCLUDE__SIGNAL_SOURCE__SIGNAL_SOURCE_H_ */

View File

@ -0,0 +1,38 @@
/*
* \brief Signal-source server interface
* \author Norman Feske
* \date 2010-02-03
*/
/*
* Copyright (C) 2010-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__SIGNAL_SOURCE__RPC_OBJECT_H_
#define _INCLUDE__SIGNAL_SOURCE__RPC_OBJECT_H_
#include <base/rpc_server.h>
#include <signal_source/foc_signal_source.h>
namespace Genode { struct Signal_source_rpc_object; }
struct Genode::Signal_source_rpc_object : Rpc_object<Foc_signal_source,
Signal_source_rpc_object>
{
protected:
Native_capability _blocking_semaphore;
public:
Signal_source_rpc_object(Native_capability cap)
: _blocking_semaphore(cap) {}
Native_capability _request_semaphore() { return _blocking_semaphore; }
};
#endif /* _INCLUDE__SIGNAL_SOURCE__RPC_OBJECT_H_ */

View File

@ -16,48 +16,90 @@
#define _CORE__INCLUDE__PD_SESSION_COMPONENT_H_
/* Genode includes */
#include <util/arg_string.h>
#include <foc_pd_session/foc_pd_session.h>
#include <base/rpc_server.h>
/* core includes */
#include <platform_pd.h>
#include <signal_broker.h>
namespace Genode {
class Pd_session_component : public Rpc_object<Foc_pd_session>
{
private:
Platform_pd _pd;
Parent_capability _parent;
Rpc_entrypoint *_thread_ep;
public:
Pd_session_component(Rpc_entrypoint *thread_ep,
Allocator *md_alloc, const char *args)
: _thread_ep(thread_ep) { }
/**
* Register quota donation at allocator guard
*/
void upgrade_ram_quota(size_t ram_quota) { }
namespace Genode { class Pd_session_component; }
/**************************
** PD session interface **
**************************/
class Genode::Pd_session_component : public Rpc_object<Foc_pd_session>
{
private:
int bind_thread(Thread_capability);
int assign_parent(Parent_capability);
Allocator_guard _md_alloc; /* guarded meta-data allocator */
Platform_pd _pd;
Capability<Parent> _parent;
Rpc_entrypoint &_thread_ep;
Signal_broker _signal_broker;
size_t _ram_quota(char const * args) {
return Arg_string::find_arg(args, "ram_quota").long_value(0); }
public:
Pd_session_component(Rpc_entrypoint &thread_ep,
Rpc_entrypoint &receiver_ep,
Rpc_entrypoint &context_ep,
Allocator &md_alloc,
char const *args)
:
_md_alloc(&md_alloc, _ram_quota(args)),
_thread_ep(thread_ep),
_signal_broker(_md_alloc, receiver_ep, context_ep)
{ }
/**
* Register quota donation at allocator guard
*/
void upgrade_ram_quota(size_t ram_quota) {
_md_alloc.upgrade(ram_quota); }
/**********************************
** Fiasco.OC specific functions **
**********************************/
/**************************
** PD session interface **
**************************/
Native_capability task_cap();
};
}
int bind_thread(Thread_capability) override;
int assign_parent(Capability<Parent>) override;
bool assign_pci(addr_t, uint16_t) override
{
PWRN("not implemented"); return false;
};
Signal_source_capability alloc_signal_source() override {
return _signal_broker.alloc_signal_source(); }
void free_signal_source(Signal_source_capability sig_rec_cap) override {
_signal_broker.free_signal_source(sig_rec_cap); }
Signal_context_capability
alloc_context(Signal_source_capability sig_rec_cap, unsigned long imprint) override
{
try {
return _signal_broker.alloc_context(sig_rec_cap, imprint); }
catch (Genode::Allocator::Out_of_memory) {
throw Pd_session::Out_of_metadata(); }
}
void free_context(Signal_context_capability cap) override {
_signal_broker.free_context(cap); }
void submit(Signal_context_capability cap, unsigned n) override {
_signal_broker.submit(cap, n); }
/**********************************
** Fiasco.OC specific functions **
**********************************/
Native_capability task_cap();
};
#endif /* _CORE__INCLUDE__PD_SESSION_COMPONENT_H_ */

View File

@ -17,8 +17,8 @@
#include <base/native_types.h>
/* core includes */
#include <signal_session_component.h>
#include <platform.h>
#include <signal_source_component.h>
namespace Fiasco {
#include <l4/sys/factory.h>
@ -39,8 +39,7 @@ void Signal_source_component::release(Signal_context_component *context)
}
void Signal_source_component::submit(Signal_context_component *context,
Ipc_ostream *ostream,
int cnt)
unsigned long cnt)
{
/* enqueue signal to context */
context->increment_signal_cnt(cnt);

View File

@ -31,7 +31,6 @@ SRC_CC += cap_session_component.cc \
rm_session_component.cc \
rm_session_support.cc \
rom_session_component.cc \
signal_session_component.cc \
signal_source_component.cc \
thread_start.cc \
trace_session_component.cc
@ -57,7 +56,6 @@ vpath pd_session_component.cc $(GEN_CORE_DIR)
vpath ram_session_component.cc $(GEN_CORE_DIR)
vpath rm_session_component.cc $(GEN_CORE_DIR)
vpath rom_session_component.cc $(GEN_CORE_DIR)
vpath signal_session_component.cc $(GEN_CORE_DIR)
vpath trace_session_component.cc $(GEN_CORE_DIR)
vpath pager_object.cc $(GEN_CORE_DIR)
vpath core_printf.cc $(BASE_DIR)/src/base/console

View File

@ -26,7 +26,7 @@ namespace Genode { struct Pd_connection; }
struct Genode::Pd_connection : Connection<Pd_session>, Pd_session_client
{
enum { RAM_QUOTA = 20*1024 };
enum { RAM_QUOTA = 28*1024 };
/**
* Constructor

View File

@ -1,57 +0,0 @@
/*
* \brief Client-side implementation of the signal session interface
* \author Martin Stein
* \date 2012-05-05
*/
/*
* Copyright (C) 2012-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__SIGNAL_SESSION__CLIENT_H_
#define _INCLUDE__SIGNAL_SESSION__CLIENT_H_
/* Genode includes */
#include <signal_session/capability.h>
#include <signal_session/signal_session.h>
#include <base/rpc_client.h>
namespace Genode
{
/**
* Client-side implementation of the signal session interface
*/
struct Signal_session_client : Rpc_client<Signal_session>
{
/**
* Constructor
*
* \param s targeted signal session
*/
explicit Signal_session_client(Signal_session_capability const s)
: Rpc_client<Signal_session>(s) { }
/******************************
** Signal_session interface **
******************************/
Signal_receiver_capability alloc_receiver()
{ return call<Rpc_alloc_receiver>(); }
Signal_context_capability
alloc_context(Signal_receiver_capability const r,
unsigned const imprint) {
return call<Rpc_alloc_context>(r, imprint); }
void free_receiver(Signal_receiver_capability cap) {
call<Rpc_free_receiver>(cap); }
void free_context(Signal_context_capability cap) {
call<Rpc_free_context>(cap); }
};
}
#endif /* _INCLUDE__SIGNAL_SESSION__CLIENT_H_ */

View File

@ -1,35 +0,0 @@
/*
* \brief Connection to signal service
* \author Stefan Kalkowski
* \author Norman Feske
* \date 2015-05-20
*
* This is a shadow copy of the generic header in base,
* due to higher memory donation requirements in base-hw
*/
/*
* Copyright (C) 2015 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__SIGNAL_SESSION__CONNECTION_H_
#define _INCLUDE__SIGNAL_SESSION__CONNECTION_H_
#include <signal_session/client.h>
#include <base/connection.h>
namespace Genode { struct Signal_connection; }
struct Genode::Signal_connection : Connection<Signal_session>,
Signal_session_client
{
Signal_connection()
: Connection<Signal_session>(session("ram_quota=32K")),
Signal_session_client(cap()) { }
};
#endif /* _INCLUDE__CAP_SESSION__CONNECTION_H_ */

View File

@ -1,136 +0,0 @@
/*
* \brief Signal session interface
* \author Martin Stein
* \date 2012-05-05
*/
/*
* Copyright (C) 2012-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__SIGNAL_SESSION__SIGNAL_SESSION_H_
#define _INCLUDE__SIGNAL_SESSION__SIGNAL_SESSION_H_
/* Genode includes */
#include <base/capability.h>
#include <base/exception.h>
#include <session/session.h>
namespace Genode
{
class Signal_receiver;
class Signal_context;
/*
* The 'dst' of this cap is used to communicate the ID of the
* corresponding signal-receiver kernel-object or 0 if the cap is invalid.
*/
typedef Capability<Signal_receiver> Signal_receiver_capability;
/*
* The 'dst' of this cap is used to communicate the ID of the
* corresponding signal-context kernel-object or 0 if the cap is invalid.
*/
typedef Capability<Signal_context> Signal_context_capability;
/**
* Signal session interface
*/
struct Signal_session : Session
{
class Out_of_metadata : public Exception { };
class Create_receiver_failed : public Exception { };
class Create_context_failed : public Exception { };
class Kill_receiver_failed : public Exception { };
class Kill_context_failed : public Exception { };
/**
* String that can be used to refer to this service
*/
static const char * service_name() { return "SIGNAL"; }
/**
* Destructor
*
* \throw Kill_context_failed
* \throw Kill_receiver_failed
*/
virtual ~Signal_session() { }
/**
* Create and manage a new signal receiver
*
* \return a cap that acts as reference to the created object
*
* \throw Out_of_metadata
* \throw Create_receiver_failed
*/
virtual Signal_receiver_capability alloc_receiver() = 0;
/**
* Create and manage a new signal context
*
* \param r names the signal receiver that shall provide
* the new context
* \param imprint every signal that occures on the new context gets
* signed with this value
*
* \return a cap that acts as reference to the created object
*
* \throw Out_of_metadata
* \throw Create_context_failed
*/
virtual Signal_context_capability
alloc_context(Signal_receiver_capability r,
unsigned const imprint) = 0;
/**
* Free a signal receiver
*
* \param cap capability of targeted signal receiver
*
* \throw Kill_receiver_failed
*/
virtual void free_receiver(Signal_receiver_capability cap) = 0;
/**
* Free a signal context
*
* \param cap capability of targeted signal context
*
* \throw Kill_context_failed
*/
virtual void free_context(Signal_context_capability cap) = 0;
/*********************
** RPC declaration **
*********************/
GENODE_RPC_THROW(Rpc_alloc_receiver, Signal_receiver_capability,
alloc_receiver, GENODE_TYPE_LIST(Out_of_metadata,
Create_receiver_failed));
GENODE_RPC_THROW(Rpc_alloc_context, Signal_context_capability,
alloc_context, GENODE_TYPE_LIST(Out_of_metadata,
Create_context_failed), Signal_receiver_capability,
unsigned);
GENODE_RPC_THROW(Rpc_free_receiver, void, free_receiver,
GENODE_TYPE_LIST(Kill_receiver_failed),
Signal_receiver_capability);
GENODE_RPC_THROW(Rpc_free_context, void, free_context,
GENODE_TYPE_LIST(Kill_context_failed),
Signal_context_capability);
GENODE_RPC_INTERFACE(Rpc_alloc_receiver, Rpc_alloc_context,
Rpc_free_receiver, Rpc_free_context);
};
}
#endif /* _INCLUDE__SIGNAL_SESSION__SIGNAL_SESSION_H_ */

View File

@ -30,6 +30,8 @@ SRC_CC += io_mem_session_support.cc
SRC_CC += irq_session_component.cc
SRC_CC += main.cc
SRC_CC += pd_session_component.cc
SRC_CC += pd_upgrade_ram_quota.cc
SRC_CC += pd_assign_pci.cc
SRC_CC += platform.cc
SRC_CC += platform_pd.cc
SRC_CC += platform_thread.cc
@ -38,7 +40,6 @@ SRC_CC += ram_session_component.cc
SRC_CC += ram_session_support.cc
SRC_CC += rm_session_component.cc
SRC_CC += rom_session_component.cc
SRC_CC += signal_session_component.cc
SRC_CC += trace_session_component.cc
SRC_CC += thread_start.cc
SRC_CC += env.cc

View File

@ -12,9 +12,11 @@
*/
/* Genode includes */
#include <util/retry.h>
#include <base/thread.h>
#include <base/signal.h>
#include <signal_session/connection.h>
#include <base/env.h>
#include <base/trace/events.h>
/* base-hw includes */
#include <kernel/interface.h>
@ -46,33 +48,22 @@ void Signal_transmitter::submit(unsigned cnt)
Signal_receiver::Signal_receiver()
{
/* create a kernel object that corresponds to the receiver */
bool session_upgraded = 0;
Signal_connection * const s = signal_connection();
while (1) {
try {
_cap = s->alloc_receiver();
return;
} catch (Signal_session::Out_of_metadata)
{
/* upgrade session quota and try again, but only once */
if (session_upgraded) {
PERR("failed to alloc signal receiver");
_cap = Signal_receiver_capability();
return;
}
PINF("upgrading quota donation for SIGNAL session");
env()->parent()->upgrade(s->cap(), "ram_quota=8K");
session_upgraded = 1;
retry<Pd_session::Out_of_metadata>(
[&] () {
_cap = env()->pd_session()->alloc_signal_source();
},
[&] () {
PINF("upgrading quota donation for PD session");
env()->parent()->upgrade(env()->pd_session_cap(), "ram_quota=8K");
}
}
);
}
void Signal_receiver::_platform_destructor()
{
/* release server resources of receiver */
signal_connection()->free_receiver(_cap);
env()->pd_session()->free_signal_source(_cap);
}
@ -91,27 +82,21 @@ Signal_context_capability Signal_receiver::manage(Signal_context * const c)
Lock::Guard context_guard(c->_lock);
if (c->_receiver) { throw Context_already_in_use(); }
/* create a context kernel-object at the receiver kernel-object */
bool session_upgraded = 0;
Signal_connection * const s = signal_connection();
while (1) {
try {
c->_cap = s->alloc_context(_cap, (unsigned long)c);
retry<Pd_session::Out_of_metadata>(
[&] () {
/* use signal context as imprint */
c->_cap = env()->pd_session()->alloc_context(_cap, (unsigned long)c);
c->_receiver = this;
_contexts.insert(&c->_receiver_le);
return c->_cap;
} catch (Signal_session::Out_of_metadata)
{
/* upgrade session quota and try again, but only once */
if (session_upgraded) {
PERR("failed to alloc signal context");
return Signal_context_capability();
}
PINF("upgrading quota donation for signal session");
env()->parent()->upgrade(s->cap(), "ram_quota=8K");
session_upgraded = 1;
},
[&] () {
PINF("upgrading quota donation for PD session");
env()->parent()->upgrade(env()->pd_session_cap(), "ram_quota=8K");
}
}
);
return c->_cap;
}

View File

@ -1,85 +0,0 @@
/*
* \brief Core-specific instance of the PD session interface
* \author Christian Helmuth
* \author Stefan Kalkowski
* \date 2006-07-17
*/
/*
* Copyright (C) 2006-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _CORE__INCLUDE__PD_SESSION_COMPONENT_H_
#define _CORE__INCLUDE__PD_SESSION_COMPONENT_H_
/* Genode includes */
#include <base/allocator_guard.h>
#include <base/rpc_server.h>
#include <pd_session/pd_session.h>
#include <util/arg_string.h>
/* core includes */
#include <platform_pd.h>
namespace Genode { class Pd_session_component; }
class Genode::Pd_session_component : public Rpc_object<Pd_session>
{
private:
/**
* Read and store the PD label
*/
struct Label {
enum { MAX_LEN = 64 };
char string[MAX_LEN];
Label(char const *args)
{
Arg_string::find_arg(args, "label").string(string,
sizeof(string), "");
}
} const _label;
Allocator_guard _md_alloc; /* guarded meta-data allocator */
Platform_pd _pd;
Parent_capability _parent;
Rpc_entrypoint *_thread_ep;
size_t _ram_quota(char const * args) {
return Arg_string::find_arg(args, "ram_quota").long_value(0); }
public:
Pd_session_component(Rpc_entrypoint * thread_ep,
Allocator * md_alloc,
char const * args)
: _label(args),
_md_alloc(md_alloc, _ram_quota(args)),
_pd(&_md_alloc, _label.string),
_thread_ep(thread_ep) { }
/**
* Register quota donation at allocator guard
*/
void upgrade_ram_quota(size_t ram_quota)
{
_md_alloc.upgrade(ram_quota);
_pd.upgrade_slab(_md_alloc);
}
/**************************/
/** PD session interface **/
/**************************/
int bind_thread(Thread_capability);
int assign_parent(Parent_capability);
};
#endif /* _CORE__INCLUDE__PD_SESSION_COMPONENT_H_ */

View File

@ -0,0 +1,152 @@
/*
* \brief Base-hw-specific signal-delivery mechanism
* \author Norman Feske
* \date 2016-01-04
*/
/*
* Copyright (C) 2016 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _CORE__INCLUDE__SIGNAL_BROKER_H_
#define _CORE__INCLUDE__SIGNAL_BROKER_H_
/* Genode includes */
#include <base/tslab.h>
/* core-local includes */
#include <assertion.h>
#include <signal_source_component.h>
namespace Genode { class Signal_broker; }
class Genode::Signal_broker
{
private:
template <typename T, size_t BLOCK_SIZE = get_page_size()>
class Slab : public Tslab<T, BLOCK_SIZE>
{
private:
uint8_t _first_block[BLOCK_SIZE];
public:
Slab(Allocator * const allocator)
: Tslab<T, BLOCK_SIZE>(allocator,
(Slab_block*)&_first_block) { }
};
Allocator &_md_alloc;
Slab<Signal_source_component> _sources_slab { &_md_alloc };
Signal_source_pool _sources;
Slab<Signal_context_component> _contexts_slab { &_md_alloc };
Signal_context_pool _contexts;
public:
class Invalid_signal_source : public Exception { };
Signal_broker(Allocator &md_alloc, Rpc_entrypoint &, Rpc_entrypoint &)
:
_md_alloc(md_alloc)
{ }
~Signal_broker()
{
_contexts.remove_all([this] (Signal_context_component *c) {
destroy(&_contexts_slab, c);});
_sources.remove_all([this] (Signal_source_component *s) {
destroy(&_sources_slab, s);});
}
/*
* \throw Allocator::Out_of_memory
*/
Capability<Signal_source> alloc_signal_source()
{
/* the _sources_slab may throw Allocator::Out_of_memory */
Signal_source_component *s = new (_sources_slab) Signal_source_component();
_sources.insert(s);
return reinterpret_cap_cast<Signal_source>(s->cap());
}
void free_signal_source(Capability<Signal_source> cap)
{
Signal_source_component *source = nullptr;
auto lambda = [&] (Signal_source_component *s) {
if (!s) {
PERR("unknown signal source");
return;
}
source = s;
_sources.remove(source);
};
_sources.apply(cap, lambda);
/* destruct signal source outside the lambda to prevent deadlock */
if (source)
destroy(&_sources_slab, source);
}
/*
* \throw Allocator::Out_of_memory
* \throw Invalid_signal_source
*/
Signal_context_capability
alloc_context(Capability<Signal_source> source, unsigned long imprint)
{
auto lambda = [&] (Signal_source_component *s) {
if (!s) {
PERR("unknown signal source");
throw Invalid_signal_source();
}
/* the _contexts_slab may throw Allocator::Out_of_memory */
Signal_context_component *c = new (_contexts_slab)
Signal_context_component(*s, imprint);
_contexts.insert(c);
return reinterpret_cap_cast<Signal_context>(c->cap());
};
return _sources.apply(source, lambda);
}
void free_context(Signal_context_capability context_cap)
{
Signal_context_component *context = nullptr;
auto lambda = [&] (Signal_context_component *c) {
if (!c) {
PERR("unknown signal context");
return;
}
context = c;
_contexts.remove(context);
};
_contexts.apply(context_cap, lambda);
/* destruct context outside the lambda to prevent deadlock */
if (context)
destroy(&_contexts_slab, context);
}
void submit(Signal_context_capability cap, unsigned cnt)
{
/*
* This function is never called as base-hw delivers signals
* directly via the kernel.
*/
}
};
#endif /* _CORE__INCLUDE__SIGNAL_BROKER_H_ */

View File

@ -1,96 +0,0 @@
/*
* \brief Signal root interface on HW-core
* \author Martin Stein
* \date 2012-05-06
*/
/*
* Copyright (C) 2012-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _CORE__INCLUDE__SIGNAL_ROOT_H_
#define _CORE__INCLUDE__SIGNAL_ROOT_H_
/* Genode includes */
#include <root/component.h>
/* base-hw includes */
#include <kernel/core_interface.h>
/* core includes */
#include <signal_session_component.h>
namespace Genode
{
/**
* Provide EP to signal root before it initialises root component
*/
class Signal_handler
{
enum { STACK_SIZE = 1024 * sizeof(addr_t) };
Rpc_entrypoint _entrypoint;
public:
/**
* Constructor
*/
Signal_handler(Cap_session * const c)
: _entrypoint(c, STACK_SIZE, "signal") { }
/***************
** Accessors **
***************/
Rpc_entrypoint * entrypoint() { return &_entrypoint; }
};
/**
* Provides signal service by managing appropriate sessions to the clients
*/
class Signal_root : private Signal_handler,
public Root_component<Signal_session_component>
{
public:
/**
* Constructor
*
* \param md Meta-data allocator to be used by root component
* \param c CAP session to be used by the root entrypoint
*/
Signal_root(Allocator * const md, Cap_session * const c) :
Signal_handler(c),
Root_component<Signal_session_component>(entrypoint(), md)
{ }
protected:
/********************************
** 'Root_component' interface **
********************************/
Signal_session_component * _create_session(const char * args)
{
size_t ram_quota =
Arg_string::find_arg(args, "ram_quota").ulong_value(0);
return new (md_alloc())
Signal_session_component(md_alloc(), ram_quota);
}
void _upgrade_session(Signal_session_component *s,
const char * args)
{
size_t ram_quota =
Arg_string::find_arg(args, "ram_quota").ulong_value(0);
s->upgrade_ram_quota(ram_quota);
}
};
}
#endif /* _CORE__INCLUDE__SIGNAL_ROOT_H_ */

View File

@ -1,124 +0,0 @@
/*
* \brief Server-sided implementation of a signal session
* \author Martin stein
* \date 2012-05-05
*/
/*
* Copyright (C) 2012-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _CORE__INCLUDE__SIGNAL_SESSION_COMPONENT_H_
#define _CORE__INCLUDE__SIGNAL_SESSION_COMPONENT_H_
/* Genode includes */
#include <signal_session/signal_session.h>
#include <base/rpc_server.h>
#include <base/tslab.h>
#include <base/allocator_guard.h>
#include <base/object_pool.h>
/* core includes */
#include <object.h>
#include <kernel/signal_receiver.h>
#include <util.h>
namespace Genode
{
/**
* Server-side implementation of a signal session
*/
class Signal_session_component;
}
class Genode::Signal_session_component : public Rpc_object<Signal_session>
{
private:
struct Receiver : Kernel_object<Kernel::Signal_receiver>,
Object_pool<Receiver>::Entry
{
using Pool = Object_pool<Receiver>;
Receiver();
};
struct Context : Kernel_object<Kernel::Signal_context>,
Object_pool<Context>::Entry
{
using Pool = Object_pool<Context>;
Context(Receiver &rcv, unsigned const imprint);
};
template <typename T, size_t BLOCK_SIZE = get_page_size()>
class Slab : public Tslab<T, BLOCK_SIZE>
{
private:
uint8_t _first_block[BLOCK_SIZE];
public:
Slab(Allocator * const allocator)
: Tslab<T, BLOCK_SIZE>(allocator,
(Slab_block*)&_first_block) { }
};
Allocator_guard _allocator;
Slab<Receiver> _receivers_slab;
Receiver::Pool _receivers;
Slab<Context> _contexts_slab;
Context::Pool _contexts;
/**
* Destruct receiver 'r'
*/
void _destruct_receiver(Receiver * const r);
/**
* Destruct context 'c'
*/
void _destruct_context(Context * const c);
public:
/**
* Constructor
*
* \param allocator RAM allocator for meta data
* \param quota amount of RAM quota donated to this session
*/
Signal_session_component(Allocator * const allocator,
size_t const quota);
~Signal_session_component();
/**
* Raise the quota of this session by 'q'
*/
void upgrade_ram_quota(size_t const q) { _allocator.upgrade(q); }
/******************************
** Signal_session interface **
******************************/
Signal_receiver_capability alloc_receiver();
Signal_context_capability
alloc_context(Signal_receiver_capability, unsigned const);
void free_receiver(Signal_receiver_capability);
void free_context(Signal_context_capability);
};
#endif /* _CORE__INCLUDE__SIGNAL_SESSION_COMPONENT_H_ */

View File

@ -0,0 +1,65 @@
/*
* \brief Signal-delivery mechanism
* \author Norman Feske
* \date 2009-08-05
*/
/*
* Copyright (C) 2009-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _CORE__INCLUDE__SIGNAL_SOURCE_COMPONENT_H_
#define _CORE__INCLUDE__SIGNAL_SOURCE_COMPONENT_H_
/* Genode includes */
#include <base/object_pool.h>
/* core-local includes */
#include <object.h>
#include <kernel/signal_receiver.h>
#include <assertion.h>
namespace Genode {
class Signal_context_component;
class Signal_source_component;
typedef Object_pool<Signal_context_component> Signal_context_pool;
typedef Object_pool<Signal_source_component> Signal_source_pool;
}
struct Genode::Signal_context_component : Kernel_object<Kernel::Signal_context>,
Signal_context_pool::Entry
{
inline Signal_context_component(Signal_source_component &s,
unsigned long const imprint);
Signal_source_component *source() { ASSERT_NEVER_CALLED; }
};
struct Genode::Signal_source_component : Kernel_object<Kernel::Signal_receiver>,
Signal_source_pool::Entry
{
Signal_source_component()
:
Kernel_object<Kernel::Signal_receiver>(true),
Signal_source_pool::Entry(Kernel_object<Kernel::Signal_receiver>::_cap)
{ }
void submit(Signal_context_component *, unsigned long) { ASSERT_NEVER_CALLED; }
};
Genode::Signal_context_component::Signal_context_component(Signal_source_component &s,
unsigned long const imprint)
:
Kernel_object<Kernel::Signal_context>(true, s.kernel_object(), imprint),
Signal_context_pool::Entry(Kernel_object<Kernel::Signal_context>::_cap)
{ }
#endif /* _CORE__INCLUDE__SIGNAL_SOURCE_COMPONENT_H_ */

View File

@ -0,0 +1,25 @@
/*
* \brief Core implementation of the PD session interface
* \author Norman Feske
* \date 2016-01-13
*/
/*
* Copyright (C) 2016 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* core-local includes */
#include <pd_session_component.h>
using namespace Genode;
void Pd_session_component::upgrade_ram_quota(size_t ram_quota)
{
_md_alloc.upgrade(ram_quota);
_pd.upgrade_slab(_md_alloc);
}

View File

@ -1,125 +0,0 @@
/*
* \brief Implementation of the SIGNAL service on the HW-core
* \author Martin Stein
* \date 2012-05-05
*/
/*
* Copyright (C) 2012-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* Genode includes */
#include <base/printf.h>
#include <unmanaged_singleton.h>
/* base-hw includes */
#include <kernel/core_interface.h>
/* core includes */
#include <signal_session_component.h>
using namespace Genode;
Signal_session_component::Receiver::Receiver()
: Kernel_object<Kernel::Signal_receiver>(true),
Signal_session_component::Receiver::Pool::Entry(Kernel_object<Kernel::Signal_receiver>::_cap) { }
Signal_session_component::Context::Context(Signal_session_component::Receiver &r,
unsigned const imprint)
: Kernel_object<Kernel::Signal_context>(true, r.kernel_object(), imprint),
Signal_session_component::Context::Pool::Entry(Kernel_object<Kernel::Signal_context>::_cap) { }
Signal_receiver_capability Signal_session_component::alloc_receiver()
{
try {
Receiver * r = new (_receivers_slab) Receiver();
_receivers.insert(r);
return reinterpret_cap_cast<Signal_receiver>(r->cap());
} catch (Allocator::Out_of_memory&) {
PERR("failed to allocate signal-receiver resources");
throw Out_of_metadata();
}
return reinterpret_cap_cast<Signal_receiver>(Untyped_capability());
}
void Signal_session_component::free_receiver(Signal_receiver_capability cap)
{
/* look up ressource info */
Receiver * receiver;
auto lambda = [&] (Receiver *r) {
receiver = r;
if (!receiver) {
PERR("unknown signal receiver");
throw Kill_receiver_failed();
}
/* release resources */
_receivers.remove(receiver);
};
_receivers.apply(cap, lambda);
destroy(&_receivers_slab, receiver);
}
Signal_context_capability
Signal_session_component::alloc_context(Signal_receiver_capability src,
unsigned const imprint)
{
/* look up ressource info */
auto lambda = [&] (Receiver *r) {
if (!r) {
PERR("unknown signal receiver");
throw Create_context_failed();
}
try {
Context * c = new (_contexts_slab) Context(*r, imprint);
_contexts.insert(c);
return reinterpret_cap_cast<Signal_context>(c->cap());
} catch (Allocator::Out_of_memory&) {
PERR("failed to allocate signal-context resources");
throw Out_of_metadata();
}
return reinterpret_cap_cast<Signal_context>(Untyped_capability());
};
return _receivers.apply(src, lambda);
}
void Signal_session_component::free_context(Signal_context_capability cap)
{
/* look up ressource info */
Context * context;
auto lambda = [&] (Context *c) {
context = c;
if (!context) {
PERR("unknown signal context");
throw Kill_context_failed();
}
/* release resources */
_contexts.remove(context);
};
_contexts.apply(cap, lambda);
destroy(&_contexts_slab, context);
}
Signal_session_component::Signal_session_component(Allocator * const allocator,
size_t const quota)
: _allocator(allocator, quota), _receivers_slab(&_allocator),
_contexts_slab(&_allocator) { }
Signal_session_component::~Signal_session_component()
{
_contexts.remove_all([this] (Context * c) {
destroy(&_contexts_slab, c);});
_receivers.remove_all([this] (Receiver * r) {
destroy(&_receivers_slab, r);});
}

View File

@ -16,7 +16,7 @@
/* Genode includes */
#include <session/session.h>
#include <signal_session/signal_session.h>
#include <base/signal.h>
namespace Sync
{

View File

@ -17,27 +17,45 @@
#include <linux_pd_session/linux_pd_session.h>
#include <base/rpc_client.h>
namespace Genode {
namespace Genode { struct Linux_pd_session_client; }
struct Linux_pd_session_client : Rpc_client<Linux_pd_session>
{
explicit Linux_pd_session_client(Capability<Linux_pd_session> session)
: Rpc_client<Linux_pd_session>(session) { }
struct Genode::Linux_pd_session_client : Rpc_client<Linux_pd_session>
{
explicit Linux_pd_session_client(Capability<Linux_pd_session> session)
: Rpc_client<Linux_pd_session>(session) { }
int bind_thread(Thread_capability thread) {
return call<Rpc_bind_thread>(thread); }
int bind_thread(Thread_capability thread) override {
return call<Rpc_bind_thread>(thread); }
int assign_parent(Parent_capability parent) {
return call<Rpc_assign_parent>(parent); }
int assign_parent(Capability<Parent> parent) override {
return call<Rpc_assign_parent>(parent); }
bool assign_pci(addr_t pci_config_memory_address, uint16_t bdf) override {
return call<Rpc_assign_pci>(pci_config_memory_address, bdf); }
Signal_source_capability alloc_signal_source() override {
return call<Rpc_alloc_signal_source>(); }
void free_signal_source(Signal_source_capability cap) override {
call<Rpc_free_signal_source>(cap); }
Signal_context_capability alloc_context(Signal_source_capability source,
unsigned long imprint) override {
return call<Rpc_alloc_context>(source, imprint); }
void free_context(Signal_context_capability cap) override {
call<Rpc_free_context>(cap); }
void submit(Signal_context_capability receiver, unsigned cnt = 1) override {
call<Rpc_submit>(receiver, cnt); }
/*****************************
* Linux-specific extension **
*****************************/
/*****************************
* Linux-specific extension **
*****************************/
void start(Capability<Dataspace> binary) {
call<Rpc_start>(binary); }
};
}
void start(Capability<Dataspace> binary) {
call<Rpc_start>(binary); }
};
#endif /* _INCLUDE__LINUX_PD_SESSION__CLIENT_H_ */

View File

@ -323,6 +323,7 @@ namespace Genode {
Cpu_session_capability _cpu_session_cap;
Expanding_cpu_session_client _cpu_session_client;
Rm_session_mmap _rm_session_mmap;
Pd_session_capability _pd_session_cap;
Pd_session_client _pd_session_client;
public:
@ -339,7 +340,8 @@ namespace Genode {
_cpu_session_cap(cpu_cap),
_cpu_session_client(static_cap_cast<Linux_cpu_session>(cpu_cap)),
_rm_session_mmap(false),
_pd_session_client(pd_cap)
_pd_session_cap(pd_cap),
_pd_session_client(_pd_session_cap)
{ }
@ -347,12 +349,13 @@ namespace Genode {
** Env interface **
*******************/
Ram_session *ram_session() { return &_ram_session_client; }
Ram_session_capability ram_session_cap() { return _ram_session_cap; }
Rm_session *rm_session() { return &_rm_session_mmap; }
Linux_cpu_session *cpu_session() { return &_cpu_session_client; }
Cpu_session_capability cpu_session_cap() { return _cpu_session_cap; }
Pd_session *pd_session() { return &_pd_session_client; }
Ram_session *ram_session() override { return &_ram_session_client; }
Ram_session_capability ram_session_cap() override { return _ram_session_cap; }
Rm_session *rm_session() override { return &_rm_session_mmap; }
Linux_cpu_session *cpu_session() override { return &_cpu_session_client; }
Cpu_session_capability cpu_session_cap() override { return _cpu_session_cap; }
Pd_session *pd_session() override { return &_pd_session_client; }
Pd_session_capability pd_session_cap() override { return _pd_session_cap; }
/*
* Support functions for implementing fork on Noux.
@ -451,8 +454,8 @@ namespace Genode {
** Env interface **
*******************/
Parent *parent() { return &_parent(); }
Heap *heap() { return &_heap; }
Parent *parent() override { return &_parent(); }
Heap *heap() override { return &_heap; }
};
}

View File

@ -23,6 +23,7 @@
#include <core_parent.h>
#include <cap_session_component.h>
#include <ram_session_component.h>
#include <core_pd_session.h>
/* internal base includes */
#include <platform_env.h>
@ -140,6 +141,17 @@ namespace Genode {
Cap_session_component _cap_session;
Entrypoint _entrypoint;
Core_ram_session _ram_session;
/*
* The core-local PD session is provided by a real RPC object
* dispatched by the same entrypoint as the signal-source RPC
* objects. This is needed to allow the 'Pd_session::submit'
* method to issue out-of-order replies to
* 'Signal_source::wait_for_signal' calls.
*/
Core_pd_session_component _pd_session_component;
Pd_session_client _pd_session_client;
Heap _heap;
Ram_session_capability const _ram_session_cap;
@ -158,6 +170,8 @@ namespace Genode {
_ram_session(&_entrypoint, &_entrypoint,
platform()->ram_alloc(), platform()->core_mem_alloc(),
"ram_quota=4M", platform()->ram_alloc()->avail()),
_pd_session_component(_entrypoint /* XXX use a different entrypoint */),
_pd_session_client(_entrypoint.manage(&_pd_session_component)),
_heap(&_ram_session, Platform_env_base::rm_session()),
_ram_session_cap(_entrypoint.manage(&_ram_session))
{ }
@ -183,6 +197,7 @@ namespace Genode {
Parent *parent() { return &_core_parent; }
Ram_session *ram_session() { return &_ram_session; }
Ram_session_capability ram_session_cap() { return _ram_session_cap; }
Pd_session *pd_session() { return &_pd_session_client; }
Allocator *heap() { return &_heap; }
Cpu_session_capability cpu_session_cap() {
@ -190,12 +205,6 @@ namespace Genode {
return Cpu_session_capability();
}
Pd_session *pd_session()
{
PWRN("%s:%u not implemented", __FILE__, __LINE__);
return 0;
}
void reload_parent_cap(Capability<Parent>::Dst, long) { }
};

View File

@ -21,61 +21,92 @@
/* core includes */
#include <platform_pd.h>
#include <signal_broker.h>
namespace Genode {
class Dataspace_component;
class Pd_session_component : public Rpc_object<Linux_pd_session, Pd_session_component>
{
private:
enum { LABEL_MAX_LEN = 1024 };
enum { ROOT_PATH_MAX_LEN = 512 };
unsigned long _pid;
char _label[LABEL_MAX_LEN];
char _root[ROOT_PATH_MAX_LEN];
unsigned _uid;
unsigned _gid;
Parent_capability _parent;
Rpc_entrypoint *_ds_ep;
void _start(Dataspace_component *ds);
public:
/**
* Constructor
*
* \param ds_ep entrypoint where the dataspaces are managed
* \param md_alloc meta-data allocator
* \param args additional session arguments
*/
Pd_session_component(Rpc_entrypoint *ds_ep, Allocator * md_alloc,
const char *args);
~Pd_session_component();
/**
* Register quota donation at allocator guard
*/
void upgrade_ram_quota(size_t ram_quota) { }
/**************************
** PD session interface **
**************************/
int bind_thread(Thread_capability);
int assign_parent(Parent_capability parent);
/******************************
** Linux-specific extension **
******************************/
void start(Capability<Dataspace> binary);
};
class Pd_session_component;
class Parent;
}
class Genode::Pd_session_component : public Rpc_object<Linux_pd_session, Pd_session_component>
{
private:
enum { LABEL_MAX_LEN = 1024 };
enum { ROOT_PATH_MAX_LEN = 512 };
unsigned long _pid;
char _label[LABEL_MAX_LEN];
char _root[ROOT_PATH_MAX_LEN];
unsigned _uid;
unsigned _gid;
Capability<Parent> _parent;
Rpc_entrypoint &_ds_ep;
Signal_broker _signal_broker;
void _start(Dataspace_component *ds);
public:
/**
* Constructor
*
* \param ds_ep entrypoint where the dataspaces are managed
* \param receiver_ep entrypoint holding signal-receiver component
* objects
* \param context_ep global pool of all signal contexts
* \param md_alloc meta-data allocator
* \param args additional session arguments
*/
Pd_session_component(Rpc_entrypoint &ds_ep,
Rpc_entrypoint &receiver_ep,
Rpc_entrypoint &context_ep,
Allocator &md_alloc,
const char *args);
~Pd_session_component();
/**
* Register quota donation at allocator guard
*/
void upgrade_ram_quota(size_t ram_quota) { }
/**************************
** PD session interface **
**************************/
int bind_thread(Thread_capability);
int assign_parent(Capability<Parent>);
bool assign_pci(addr_t, uint16_t) { return false; }
Signal_source_capability alloc_signal_source() override {
return _signal_broker.alloc_signal_source(); }
void free_signal_source(Signal_source_capability cap) override {
_signal_broker.free_signal_source(cap); }
Signal_context_capability
alloc_context(Signal_source_capability sig_rec_cap, unsigned long imprint) override
{
return _signal_broker.alloc_context(sig_rec_cap, imprint);
}
void free_context(Signal_context_capability cap) override {
_signal_broker.free_context(cap); }
void submit(Signal_context_capability cap, unsigned n) override {
_signal_broker.submit(cap, n); }
/******************************
** Linux-specific extension **
******************************/
void start(Capability<Dataspace> binary);
};
#endif /* _CORE__INCLUDE__PD_SESSION_COMPONENT_H_ */

View File

@ -397,11 +397,14 @@ void Pd_session_component::_start(Dataspace_component *ds)
}
Pd_session_component::Pd_session_component(Rpc_entrypoint * ep,
Allocator * md_alloc,
const char * args)
Pd_session_component::Pd_session_component(Rpc_entrypoint &ds_ep,
Rpc_entrypoint &receiver_ep,
Rpc_entrypoint &context_ep,
Allocator &md_alloc,
const char *args)
:
_pid(0), _uid(0), _gid(0), _ds_ep(ep)
_pid(0), _uid(0), _gid(0), _ds_ep(ds_ep),
_signal_broker(md_alloc, receiver_ep, context_ep)
{
Arg_string::find_arg(args, "label").string(_label, sizeof(_label),
"<unlabeled>");
@ -449,7 +452,7 @@ Pd_session_component::~Pd_session_component()
int Pd_session_component::bind_thread(Thread_capability) { return -1; }
int Pd_session_component::assign_parent(Parent_capability parent)
int Pd_session_component::assign_parent(Capability<Parent> parent)
{
_parent = parent;
return 0;
@ -459,6 +462,6 @@ int Pd_session_component::assign_parent(Parent_capability parent)
void Pd_session_component::start(Capability<Dataspace> binary)
{
/* lookup binary dataspace */
_ds_ep->apply(binary, [&] (Dataspace_component *ds) {
_ds_ep.apply(binary, [&] (Dataspace_component *ds) {
_start(ds); });
};

View File

@ -18,7 +18,6 @@ SRC_CC = main.cc \
dataspace_component.cc \
pd_session_component.cc \
io_mem_session_component.cc \
signal_session_component.cc \
signal_source_component.cc \
trace_session_component.cc \
thread_linux.cc \
@ -44,7 +43,6 @@ vpath ram_session_component.cc $(GEN_CORE_DIR)
vpath cap_session_component.cc $(GEN_CORE_DIR)
vpath cpu_session_component.cc $(GEN_CORE_DIR)
vpath platform_services.cc $(GEN_CORE_DIR)
vpath signal_session_component.cc $(GEN_CORE_DIR)
vpath signal_source_component.cc $(GEN_CORE_DIR)
vpath trace_session_component.cc $(GEN_CORE_DIR)
vpath core_printf.cc $(BASE_DIR)/src/base/console

View File

@ -17,25 +17,52 @@
#include <pd_session/capability.h>
#include <base/rpc_client.h>
namespace Genode {
namespace Genode { struct Pd_session_client; }
struct Pd_session_client : Rpc_client<Pd_session>
/*
* This implementation overrides the corresponding header in base/include
* to tweak the way the parent capability is passed to core.
*/
struct Genode::Pd_session_client : Rpc_client<Pd_session>
{
explicit Pd_session_client(Pd_session_capability session)
: Rpc_client<Pd_session>(session) { }
int bind_thread(Thread_capability thread) override {
return call<Rpc_bind_thread>(thread); }
int assign_parent(Capability<Parent> parent) override
{
explicit Pd_session_client(Pd_session_capability session)
: Rpc_client<Pd_session>(session) { }
/*
* NOVA-specific implementation
*
* We need to prevent NOVA from creating a new branch in the mapping
* tree. Instead, we need core to re-associate the supplied PD cap with
* the core-known PD session component of the parent.
*/
parent.solely_map();
return call<Rpc_assign_parent>(parent);
}
int bind_thread(Thread_capability thread) {
return call<Rpc_bind_thread>(thread); }
bool assign_pci(addr_t pci_config_memory_address, uint16_t bdf) override {
return call<Rpc_assign_pci>(pci_config_memory_address, bdf); }
int assign_parent(Parent_capability parent)
{
parent.solely_map();
return call<Rpc_assign_parent>(parent);
}
Signal_source_capability alloc_signal_source() override {
return call<Rpc_alloc_signal_source>(); }
bool assign_pci(addr_t pci_config_memory_address, uint16_t bdf) {
return call<Rpc_assign_pci>(pci_config_memory_address, bdf); }
};
}
void free_signal_source(Signal_source_capability cap) override {
call<Rpc_free_signal_source>(cap); }
Signal_context_capability alloc_context(Signal_source_capability source,
unsigned long imprint) override {
return call<Rpc_alloc_context>(source, imprint); }
void free_context(Signal_context_capability cap) override {
call<Rpc_free_context>(cap); }
void submit(Signal_context_capability receiver, unsigned cnt = 1) override {
call<Rpc_submit>(receiver, cnt); }
};
#endif /* _INCLUDE__PD_SESSION__CLIENT_H_ */

View File

@ -1,75 +0,0 @@
/*
* \brief Protection domain (PD) session interface
* \author Christian Helmuth
* \date 2006-06-27
*
* A pd session represents the protection domain of a program.
*/
/*
* Copyright (C) 2006-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__PD_SESSION__PD_SESSION_H_
#define _INCLUDE__PD_SESSION__PD_SESSION_H_
#include <thread/capability.h>
#include <parent/capability.h>
#include <session/session.h>
namespace Genode {
struct Pd_session : Session
{
static const char *service_name() { return "PD"; }
virtual ~Pd_session() { }
/**
* Bind thread to protection domain
*
* \param thread capability of thread to bind
*
* \return 0 on success or negative error code
*
* After successful bind, the thread will execute inside this
* protection domain when started.
*/
virtual int bind_thread(Thread_capability thread) = 0;
/**
* Assign parent to protection domain
*
* \param parent capability of parent interface
* \return 0 on success, or negative error code
*/
virtual int assign_parent(Parent_capability parent) = 0;
/**
* Assign PCI device to a protection domain.
*
* \param pci_config_space virtual address of the 4K PCI config
* space extended memory of the device
* \param bdf bus/device/function of the PCI device
* \return true on success, or false in case of an error
*/
virtual bool assign_pci(addr_t pci_config_space, uint16_t bdf) = 0;
/*********************
** RPC declaration **
*********************/
GENODE_RPC(Rpc_bind_thread, int, bind_thread, Thread_capability);
GENODE_RPC(Rpc_assign_parent, int, assign_parent, Parent_capability);
GENODE_RPC(Rpc_assign_pci, bool, assign_pci, addr_t, uint16_t);
GENODE_RPC_INTERFACE(Rpc_bind_thread, Rpc_assign_parent,
Rpc_assign_pci);
};
}
#endif /* _INCLUDE__PD_SESSION__PD_SESSION_H_ */

View File

@ -1,35 +0,0 @@
/*
* \brief NOVA-specific signal source RPC interface
* \author Norman Feske
* \date 2011-04-12
*/
/*
* Copyright (C) 2011-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__SIGNAL_SESSION__NOVA_SOURCE_H_
#define _INCLUDE__SIGNAL_SESSION__NOVA_SOURCE_H_
#include <base/rpc.h>
#include <signal_session/source.h>
namespace Genode {
struct Nova_signal_source : Signal_source
{
/*********************
** RPC declaration **
*********************/
GENODE_RPC(Rpc_register_semaphore, void, _register_semaphore,
Native_capability const &);
GENODE_RPC_INTERFACE_INHERIT(Signal_source, Rpc_register_semaphore);
};
}
#endif /* _INCLUDE__SIGNAL_SESSION__NOVA_SOURCE_H_ */

View File

@ -1,47 +0,0 @@
/*
* \brief Signal-source server interface
* \author Norman Feske
* \date 2010-02-03
*
* This file is only included by 'signal_session/server.h' and relies on the
* headers included there. No include guards are needed. It is a separate
* header file to make it easily replaceable by a platform-specific
* implementation.
*/
/*
* Copyright (C) 2010-2015 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__SIGNAL_SESSION__SOURCE_SERVER_H_
#define _INCLUDE__SIGNAL_SESSION__SOURCE_SERVER_H_
#include <base/rpc_server.h>
#include <signal_session/nova_source.h>
namespace Genode { struct Signal_source_rpc_object; }
struct Genode::Signal_source_rpc_object : Rpc_object<Nova_signal_source,
Signal_source_rpc_object>
{
public:
Native_capability _blocking_semaphore;
public:
void _register_semaphore(Native_capability const &cap)
{
if (_blocking_semaphore.valid())
PWRN("overwritting blocking signal semaphore !!!");
_blocking_semaphore = cap;
}
Signal_source_rpc_object() {}
};
#endif /* _INCLUDE__SIGNAL_SESSION__SOURCE_SERVER_H_ */

View File

@ -18,11 +18,11 @@
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__SIGNAL_SESSION__SOURCE_CLIENT_H_
#define _INCLUDE__SIGNAL_SESSION__SOURCE_CLIENT_H_
#ifndef _INCLUDE__SIGNAL_SOURCE__CLIENT_H_
#define _INCLUDE__SIGNAL_SOURCE__CLIENT_H_
#include <base/rpc_client.h>
#include <signal_session/nova_source.h>
#include <signal_source/nova_signal_source.h>
/* NOVA includes */
#include <nova/syscalls.h>
@ -60,9 +60,8 @@ namespace Genode {
/**
* Constructor
*/
Signal_source_client(Signal_source_capability cap)
: Rpc_client<Nova_signal_source>(
static_cap_cast<Nova_signal_source>(cap))
Signal_source_client(Capability<Signal_source> cap)
: Rpc_client<Nova_signal_source>(static_cap_cast<Nova_signal_source>(cap))
{
/*
* Make sure that we have acquired the
@ -76,9 +75,9 @@ namespace Genode {
** Signal source interface **
*****************************/
Signal wait_for_signal()
Signal wait_for_signal() override
{
/*
/*
* Block on semaphore, will be unblocked if
* signal is available
*/
@ -94,4 +93,4 @@ namespace Genode {
};
}
#endif /* _INCLUDE__SIGNAL_SESSION__SOURCE_CLIENT_H_ */
#endif /* _INCLUDE__SIGNAL_SOURCE__CLIENT_H_ */

View File

@ -0,0 +1,30 @@
/*
* \brief NOVA-specific signal source RPC interface
* \author Norman Feske
* \date 2011-04-12
*/
/*
* Copyright (C) 2011-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__SIGNAL_SOURCE__NOVA_SIGNAL_SOURCE_H_
#define _INCLUDE__SIGNAL_SOURCE__NOVA_SIGNAL_SOURCE_H_
#include <base/rpc.h>
#include <signal_source/signal_source.h>
namespace Genode { struct Nova_signal_source; }
struct Genode::Nova_signal_source : Signal_source
{
GENODE_RPC(Rpc_register_semaphore, void, register_semaphore,
Native_capability const &);
GENODE_RPC_INTERFACE_INHERIT(Signal_source, Rpc_register_semaphore);
};
#endif /* _INCLUDE__SIGNAL_SOURCE__NOVA_SIGNAL_SOURCE_H_ */

View File

@ -13,13 +13,12 @@
/* Genode includes */
#include <signal_session/connection.h>
#include <base/signal.h>
#include <base/trace/events.h>
using namespace Genode;
/************************
** Signal transmitter **
************************/
void Signal_transmitter::submit(unsigned cnt)
{
{

View File

@ -1,77 +0,0 @@
/*
* \brief Core-specific instance of the PD session interface
* \author Christian Helmuth
* \date 2006-07-17
*/
/*
* Copyright (C) 2006-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _CORE__INCLUDE__PD_SESSION_COMPONENT_H_
#define _CORE__INCLUDE__PD_SESSION_COMPONENT_H_
/* Genode includes */
#include <base/rpc_server.h>
#include <util/arg_string.h>
#include <pd_session/pd_session.h>
/* core includes */
#include <platform_pd.h>
namespace Genode {
class Pd_session_component : public Rpc_object<Pd_session>
{
private:
/**
* Read and store the PD label
*/
struct Label {
enum { MAX_LEN = 64 };
char string[MAX_LEN];
/**
* Constructor
*/
Label(char const *args)
{
Arg_string::find_arg(args, "label").string(string, sizeof(string), "");
}
} const _label;
Platform_pd _pd;
Parent_capability _parent;
Rpc_entrypoint *_thread_ep;
public:
Pd_session_component(Rpc_entrypoint *thread_ep,
Allocator * md_alloc, char const *args)
: _label(args),
_pd(md_alloc, _label.string),
_thread_ep(thread_ep) { }
/**
* Register quota donation at allocator guard
*/
void upgrade_ram_quota(size_t ram_quota) { }
/**************************/
/** PD session interface **/
/**************************/
int bind_thread(Thread_capability);
int assign_parent(Parent_capability);
bool assign_pci(addr_t, uint16_t);
};
}
#endif /* _CORE__INCLUDE__PD_SESSION_COMPONENT_H_ */

View File

@ -0,0 +1,135 @@
/*
* \brief NOVA-specific signal-delivery mechanism
* \author Norman Feske
* \date 2016-01-04
*/
/*
* Copyright (C) 2016 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _CORE__INCLUDE__SIGNAL_BROKER_H_
#define _CORE__INCLUDE__SIGNAL_BROKER_H_
/* Genode includes */
#include <base/tslab.h>
/* core-local includes */
#include <signal_source_component.h>
#include <signal_source/capability.h>
namespace Genode { class Signal_broker; }
class Genode::Signal_broker
{
private:
Allocator &_md_alloc;
Rpc_entrypoint &_source_ep;
Object_pool<Signal_context_component> _obj_pool;
Rpc_entrypoint &_context_ep;
Signal_source_component _source;
Signal_source_capability _source_cap;
Tslab<Signal_context_component,
960*sizeof(long)> _contexts_slab { &_md_alloc };
public:
class Invalid_signal_source : public Exception { };
Signal_broker(Allocator &md_alloc,
Rpc_entrypoint &source_ep,
Rpc_entrypoint &context_ep)
:
_md_alloc(md_alloc),
_source_ep(source_ep),
_context_ep(context_ep),
_source(&_context_ep),
_source_cap(_source_ep.manage(&_source))
{ }
~Signal_broker()
{
/* remove source from entrypoint */
_source_ep.dissolve(&_source);
/* free all signal contexts */
while (Signal_context_component *r = _contexts_slab.first_object())
free_context(reinterpret_cap_cast<Signal_context>(r->cap()));
}
Signal_source_capability alloc_signal_source() { return _source_cap; }
void free_signal_source(Signal_source_capability) { }
/*
* \throw Allocator::Out_of_memory
*/
Signal_context_capability
alloc_context(Signal_source_capability, unsigned long imprint)
{
/*
* XXX For now, we ignore the signal-source argument as we
* create only a single receiver for each PD.
*/
Native_capability sm = _source.blocking_semaphore();
if (!sm.valid()) {
PWRN("signal receiver sm is not valid");
for (;;);
return Signal_context_capability();
}
Native_capability si(cap_map()->insert());
Signal_context_capability cap = reinterpret_cap_cast<Signal_context>(si);
uint8_t res = Nova::create_si(cap.local_name(), __core_pd_sel, imprint,
sm.local_name());
if (res != Nova::NOVA_OK) {
PWRN("creating signal failed - error %u", res);
return Signal_context_capability();
}
/* the _contexts_slab may throw Allocator::Out_of_memory */
_obj_pool.insert(new (&_contexts_slab) Signal_context_component(cap));
/* return unique capability for the signal context */
return cap;
}
void free_context(Signal_context_capability context_cap)
{
Signal_context_component *context;
auto lambda = [&] (Signal_context_component *c) {
context = c;
if (context) _obj_pool.remove(context);
};
_obj_pool.apply(context_cap, lambda);
if (!context) {
PWRN("%p - specified signal-context capability has wrong type %lx",
this, context_cap.local_name());
return;
}
destroy(&_contexts_slab, context);
Nova::revoke(Nova::Obj_crd(context_cap.local_name(), 0));
cap_map()->remove(context_cap.local_name(), 0);
}
void submit(Signal_context_capability cap, unsigned cnt)
{
/*
* On NOVA, signals are submitted directly to the kernel, not
* by using core as a proxy.
*/
ASSERT_NEVER_CALLED;
}
};
#endif /* _CORE__INCLUDE__SIGNAL_BROKER_H_ */

View File

@ -1,135 +0,0 @@
/*
* \brief Signal service
* \author Norman Feske
* \date 2009-08-05
*/
/*
* Copyright (C) 2009-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _CORE__INCLUDE__SIGNAL_SESSION_COMPONENT_H_
#define _CORE__INCLUDE__SIGNAL_SESSION_COMPONENT_H_
#include <signal_session/signal_session.h>
#include <signal_session/source_rpc_object.h>
#include <base/allocator_guard.h>
#include <base/tslab.h>
#include <base/lock.h>
#include <base/rpc_client.h>
#include <base/rpc_server.h>
#include <util/fifo.h>
#include <base/signal.h>
namespace Genode {
class Signal_source_component;
class Signal_context_component;
typedef Fifo<Signal_context_component> Signal_queue;
class Signal_context_component : public Object_pool<Signal_context_component>::Entry
{
public:
/**
* Constructor
*/
Signal_context_component(Signal_context_capability cap)
: Object_pool<Signal_context_component>::Entry(cap) { }
};
class Signal_source_component : public Signal_source_rpc_object
{
public:
/**
* Constructor
*/
Signal_source_component(Rpc_entrypoint *) { }
/*****************************
** Signal-source interface **
*****************************/
Signal wait_for_signal() { return Signal(0, 0); }
};
class Signal_session_component : public Rpc_object<Signal_session>
{
private:
Rpc_entrypoint *_source_ep;
Object_pool<Signal_context_component> _signal_queue;
Signal_source_component _source;
Signal_source_capability _source_cap;
Allocator_guard _md_alloc;
Tslab<Signal_context_component,
960*sizeof(long)> _contexts_slab;
Ipc_ostream *_ipc_ostream;
public:
/**
* Constructor
*
* \param source_ep entrypoint holding signal-source component
* objects
* \param context_ep global pool of all signal contexts
* \param md_alloc backing-store allocator for
* signal-context component objects
*
* To maintain proper synchronization, 'signal_source_ep' must be
* the same entrypoint as used for the signal-session component.
* The 'signal_context_ep' is only used for associative array
* to map signal-context capabilities to 'Signal_context_component'
* objects and as capability allocator for such objects.
*/
Signal_session_component(Rpc_entrypoint *source_ep,
Rpc_entrypoint *context_ep,
Allocator *context_md_alloc,
size_t ram_quota);
~Signal_session_component();
/**
* Register quota donation at allocator guard
*/
void upgrade_ram_quota(size_t ram_quota) { _md_alloc.upgrade(ram_quota); }
/******************************
** Signal-session interface **
******************************/
Signal_source_capability signal_source();
Signal_context_capability alloc_context(long imprint);
void free_context(Signal_context_capability context_cap);
void submit(Signal_context_capability context_cap, unsigned cnt);
/**************************
** Rpc_object interface **
**************************/
Rpc_exception_code dispatch(int opcode, Ipc_istream &is, Ipc_ostream &os)
{
/*
* Make IPC output stream available to the submit function. The
* stream is used to carry signal payload for the out-of-order
* handling of 'wait_for_signal' replies.
*/
_ipc_ostream = &os;
/* dispatch RPC */
return Rpc_object<Signal_session>::dispatch(opcode, is, os);
}
};
}
#endif /* _CORE__INCLUDE__CAP_SESSION_COMPONENT_H_ */

View File

@ -0,0 +1,63 @@
/*
* \brief Signal-delivery mechanism
* \author Norman Feske
* \date 2009-08-05
*/
/*
* Copyright (C) 2009-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _CORE__INCLUDE__SIGNAL_SOURCE_COMPONENT_H_
#define _CORE__INCLUDE__SIGNAL_SOURCE_COMPONENT_H_
#include <base/object_pool.h>
#include <signal_source/nova_signal_source.h>
#include <assertion.h>
namespace Genode {
class Signal_context_component;
class Signal_source_component;
}
struct Genode::Signal_context_component : Object_pool<Signal_context_component>::Entry
{
Signal_context_component(Signal_context_capability cap)
: Object_pool<Signal_context_component>::Entry(cap) { }
Signal_source_component *source() { ASSERT_NEVER_CALLED; }
};
class Genode::Signal_source_component : public Rpc_object<Nova_signal_source,
Signal_source_component>
{
private:
Native_capability _blocking_semaphore;
public:
Signal_source_component(Rpc_entrypoint *) { }
void register_semaphore(Native_capability const &cap)
{
if (_blocking_semaphore.valid())
PWRN("overwritting blocking signal semaphore !!!");
_blocking_semaphore = cap;
}
Native_capability blocking_semaphore() const { return _blocking_semaphore; }
Signal wait_for_signal() { /* unused on NOVA */ return Signal(0, 0); }
void submit(Signal_context_component *, unsigned long) { /* unused on NOVA */ }
};
#endif /* _CORE__INCLUDE__SIGNAL_SOURCE_COMPONENT_H_ */

View File

@ -1,113 +0,0 @@
/*
* \brief Implementation of the SIGNAL interface
* \author Alexander Boettcher
* \date 2015-03-04
*/
/*
* Copyright (C) 2015 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* Genode includes */
#include <base/printf.h>
/* core includes */
#include <signal_session_component.h>
using namespace Genode;
/******************************
** Signal-session component **
******************************/
Signal_session_component::Signal_session_component(Rpc_entrypoint *source_ep,
Rpc_entrypoint *context_ep,
Allocator *context_md_alloc,
size_t ram_quota)
:
_source_ep(source_ep),
_source(source_ep),
_source_cap(_source_ep->manage(&_source)),
_md_alloc(context_md_alloc, ram_quota),
_contexts_slab(&_md_alloc)
{ }
Signal_session_component::~Signal_session_component()
{
/* remove _signal_source from entrypoint */
_source_ep->dissolve(&_source);
/* free all signal contexts */
while (Signal_context_component *r = _contexts_slab.first_object())
free_context(reinterpret_cap_cast<Signal_context>(Native_capability(r->cap())));
}
Signal_source_capability Signal_session_component::signal_source()
{
return _source_cap;
}
extern "C" Genode::addr_t __core_pd_sel;
Signal_context_capability Signal_session_component::alloc_context(long imprint)
{
Native_capability sm = _source._blocking_semaphore;
if (!sm.valid()) {
PWRN("signal receiver sm is not valid");
return Signal_context_capability();
}
Native_capability si(cap_map()->insert());
Signal_context_capability cap = reinterpret_cap_cast<Signal_context>(si);
uint8_t res = Nova::create_si(cap.local_name(), __core_pd_sel, imprint,
sm.local_name());
if (res != Nova::NOVA_OK) {
PWRN("creating signal failed - error %u", res);
return Signal_context_capability();
}
try {
_signal_queue.insert(new (&_contexts_slab) Signal_context_component(cap));
} catch (Allocator::Out_of_memory) {
throw Out_of_metadata();
}
/* return unique capability for the signal context */
return cap;
}
void Signal_session_component::free_context(Signal_context_capability context_cap)
{
Signal_context_component *context;
auto lambda = [&] (Signal_context_component *c) {
context = c;
if (context) _signal_queue.remove(context);
};
_signal_queue.apply(context_cap, lambda);
if (!context) {
PWRN("%p - specified signal-context capability has wrong type %lx",
this, context_cap.local_name());
return;
}
destroy(&_contexts_slab, context);
Nova::revoke(Nova::Obj_crd(context_cap.local_name(), 0));
cap_map()->remove(context_cap.local_name(), 0);
}
void Signal_session_component::submit(Signal_context_capability context_cap,
unsigned cnt)
{
PDBG("should not be called");
}

View File

@ -21,7 +21,8 @@ SRC_CC = context_area.cc \
main.cc \
pager.cc \
pd_session_component.cc \
pd_session_extension.cc \
pd_upgrade_ram_quota.cc \
pd_assign_pci.cc \
platform.cc \
platform_pd.cc \
platform_services.cc \
@ -31,7 +32,6 @@ SRC_CC = context_area.cc \
rm_session_component.cc \
rm_session_support.cc \
rom_session_component.cc \
signal_session_component.cc \
thread_start.cc \
bios_data_area.cc \
trace_session_component.cc
@ -49,6 +49,7 @@ vpath ram_session_component.cc $(GEN_CORE_DIR)
vpath rom_session_component.cc $(GEN_CORE_DIR)
vpath cpu_session_component.cc $(GEN_CORE_DIR)
vpath pd_session_component.cc $(GEN_CORE_DIR)
vpath pd_upgrade_ram_quota.cc $(GEN_CORE_DIR)
vpath rm_session_component.cc $(GEN_CORE_DIR)
vpath trace_session_component.cc $(GEN_CORE_DIR)
vpath io_port_session_component.cc $(GEN_CORE_DIR)/spec/x86

View File

@ -21,45 +21,71 @@
/* core includes */
#include <platform.h>
#include <signal_broker.h>
namespace Genode {
class Pd_session_component : public Rpc_object<Okl4_pd_session>
{
private:
Platform_pd _pd;
Rpc_entrypoint *_thread_ep;
public:
Pd_session_component(Rpc_entrypoint *thread_ep,
Allocator *md_alloc, const char *args)
: _thread_ep(thread_ep) { }
/**
* Register quota donation at allocator guard
*/
void upgrade_ram_quota(size_t ram_quota) { }
namespace Genode { class Pd_session_component; }
/**************************
** Pd session interface **
**************************/
class Genode::Pd_session_component : public Rpc_object<Okl4_pd_session>
{
private:
int bind_thread(Thread_capability);
int assign_parent(Parent_capability);
Platform_pd _pd;
Rpc_entrypoint &_thread_ep;
Signal_broker _signal_broker;
public:
Pd_session_component(Rpc_entrypoint &thread_ep,
Rpc_entrypoint &receiver_ep,
Rpc_entrypoint &context_ep,
Allocator &md_alloc, const char *args)
:
_thread_ep(thread_ep),
_signal_broker(md_alloc, receiver_ep, context_ep)
{ }
/**
* Register quota donation at allocator guard
*/
void upgrade_ram_quota(size_t ram_quota) { }
/*****************************
** OKL4-specific additions **
*****************************/
/**************************
** Pd session interface **
**************************/
void space_pager(Thread_capability thread);
int bind_thread(Thread_capability);
int assign_parent(Capability<Parent>);
bool assign_pci(addr_t, uint16_t) { return false; }
Okl4::L4_SpaceId_t space_id() {
return Okl4::L4_SpaceId(_pd.pd_id()); }
};
}
Signal_source_capability alloc_signal_source() override {
return _signal_broker.alloc_signal_source(); }
void free_signal_source(Signal_source_capability cap) override {
_signal_broker.free_signal_source(cap); }
Signal_context_capability
alloc_context(Signal_source_capability sig_rec_cap, unsigned long imprint) override
{
return _signal_broker.alloc_context(sig_rec_cap, imprint);
}
void free_context(Signal_context_capability cap) override {
_signal_broker.free_context(cap); }
void submit(Signal_context_capability cap, unsigned n) override {
_signal_broker.submit(cap, n); }
/*****************************
** OKL4-specific additions **
*****************************/
void space_pager(Thread_capability thread);
Okl4::L4_SpaceId_t space_id() {
return Okl4::L4_SpaceId(_pd.pd_id()); }
};
#endif /* _CORE__INCLUDE__OKL4__PD_SESSION_COMPONENT_H_ */

View File

@ -21,7 +21,7 @@ using namespace Genode;
void Pd_session_component::space_pager(Thread_capability thread)
{
_thread_ep->apply(thread, [this] (Cpu_thread_component *cpu_thread)
_thread_ep.apply(thread, [this] (Cpu_thread_component *cpu_thread)
{
if (!cpu_thread) return;
_pd.space_pager(cpu_thread->platform_thread());

View File

@ -31,7 +31,6 @@ SRC_CC += cap_session_component.cc \
rm_session_component.cc \
rm_session_support.cc \
rom_session_component.cc \
signal_session_component.cc \
signal_source_component.cc \
thread_start.cc \
trace_session_component.cc
@ -53,7 +52,6 @@ vpath pd_session_component.cc $(GEN_CORE_DIR)
vpath rm_session_component.cc $(GEN_CORE_DIR)
vpath io_mem_session_component.cc $(GEN_CORE_DIR)
vpath io_mem_session_support.cc $(GEN_CORE_DIR)
vpath signal_session_component.cc $(GEN_CORE_DIR)
vpath signal_source_component.cc $(GEN_CORE_DIR)
vpath trace_session_component.cc $(GEN_CORE_DIR)
vpath dataspace_component.cc $(GEN_CORE_DIR)

View File

@ -18,6 +18,8 @@ SRC_CC = cap_session_component.cc \
main.cc \
multiboot_info.cc \
pd_session_component.cc \
pd_assign_pci.cc \
pd_upgrade_ram_quota.cc \
pager.cc \
pager_ep.cc \
pager_object.cc \
@ -30,7 +32,6 @@ SRC_CC = cap_session_component.cc \
rm_session_component.cc \
rm_session_support.cc \
rom_session_component.cc \
signal_session_component.cc \
signal_source_component.cc \
thread_start.cc \
trace_session_component.cc
@ -48,10 +49,11 @@ vpath rom_session_component.cc $(GEN_CORE_DIR)
vpath cap_session_component.cc $(GEN_CORE_DIR)
vpath cpu_session_component.cc $(GEN_CORE_DIR)
vpath pd_session_component.cc $(GEN_CORE_DIR)
vpath pd_assign_pci.cc $(GEN_CORE_DIR)
vpath pd_upgrade_ram_quota.cc $(GEN_CORE_DIR)
vpath rm_session_component.cc $(GEN_CORE_DIR)
vpath io_mem_session_component.cc $(GEN_CORE_DIR)
vpath io_mem_session_support.cc $(GEN_CORE_DIR)
vpath signal_session_component.cc $(GEN_CORE_DIR)
vpath signal_source_component.cc $(GEN_CORE_DIR)
vpath trace_session_component.cc $(GEN_CORE_DIR)
vpath dataspace_component.cc $(GEN_CORE_DIR)

View File

@ -11,6 +11,8 @@ SRC_CC += \
cpu_session_component.cc \
cpu_session_support.cc \
pd_session_component.cc \
pd_assign_pci.cc \
pd_upgrade_ram_quota.cc \
io_mem_session_component.cc \
io_mem_session_support.cc \
thread_start.cc \
@ -22,7 +24,6 @@ SRC_CC += \
rm_session_component.cc \
rm_session_support.cc \
irq_session_component.cc \
signal_session_component.cc \
signal_source_component.cc \
trace_session_component.cc \
core_rm_session.cc \
@ -47,11 +48,12 @@ vpath ram_session_component.cc $(GEN_CORE_DIR)
vpath rom_session_component.cc $(GEN_CORE_DIR)
vpath cpu_session_component.cc $(GEN_CORE_DIR)
vpath pd_session_component.cc $(GEN_CORE_DIR)
vpath pd_assign_pci.cc $(GEN_CORE_DIR)
vpath pd_upgrade_ram_quota.cc $(GEN_CORE_DIR)
vpath rm_session_component.cc $(GEN_CORE_DIR)
vpath io_mem_session_component.cc $(GEN_CORE_DIR)
vpath io_mem_session_support.cc $(GEN_CORE_DIR)
vpath platform_services.cc $(GEN_CORE_DIR)
vpath signal_session_component.cc $(GEN_CORE_DIR)
vpath signal_source_component.cc $(GEN_CORE_DIR)
vpath trace_session_component.cc $(GEN_CORE_DIR)
vpath dataspace_component.cc $(GEN_CORE_DIR)

View File

@ -21,7 +21,8 @@
#include <ram_session/ram_session.h>
#include <cpu_session/cpu_session.h>
#include <cpu_session/capability.h>
#include <pd_session/pd_session.h>
#include <pd_session/capability.h>
#include <cap_session/cap_session.h>
#include <base/allocator.h>
#include <base/snprintf.h>
#include <base/lock.h>
@ -80,6 +81,7 @@ struct Genode::Env
* PD session of the component as created by the parent
*/
virtual Pd_session *pd_session() = 0;
virtual Pd_session_capability pd_session_cap() = 0;
/**
* Heap backed by the RAM session of the environment
@ -116,6 +118,4 @@ struct Genode::Env
};
#endif /* _INCLUDE__BASE__ENV_H_ */

View File

@ -385,16 +385,15 @@ class Genode::Rpc_entrypoint : Thread_base, public Object_pool<Rpc_object_base>
*
* \noapi
*
* Note: This is a temporary API method, which is going to be
* removed. Please do not use this method.
*
* In combination with the 'reply_dst' accessor method, this
* method can be used to implement services that dispatch client
* requests out of order. In such cases, the server activation may
* send reply messages to multiple blocking clients before
* answering the original call.
* In combination with the 'reply_dst' accessor method, this method
* allows for the dispatching of client requests out of order. The only
* designated user of this method is core's PD service. The
* 'Pd_session::submit' RPC function uses it to send a reply to a
* caller of the 'Signal_source::wait_for_signal' RPC function before
* returning from the 'submit' call.
*/
void explicit_reply(Untyped_capability reply_cap, int return_value);
void reply_signal_info(Untyped_capability reply_cap,
unsigned long imprint, unsigned long cnt);
/**
* Return true if the caller corresponds to the entrypoint called

View File

@ -20,7 +20,7 @@
#include <util/noncopyable.h>
#include <util/list.h>
#include <base/semaphore.h>
#include <signal_session/signal_session.h>
#include <base/capability.h>
/* only needed for base-hw */
namespace Kernel { struct Signal_receiver; }
@ -28,15 +28,18 @@ namespace Kernel { struct Signal_receiver; }
namespace Genode {
class Signal_source;
class Signal_receiver;
class Signal_context;
class Signal_context_registry;
class Signal_transmitter;
class Signal;
class Signal_dispatcher_base;
class Signal_connection;
template <typename> class Signal_dispatcher;
Signal_connection * signal_connection();
template <typename> class Signal_dispatcher;
template <typename, typename> class Signal_handler;
typedef Capability<Signal_context> Signal_context_capability;
}
@ -129,8 +132,6 @@ class Genode::Signal_transmitter
Signal_context_capability _context; /* destination */
Signal_connection * connection();
public:
/**
@ -179,7 +180,7 @@ class Genode::Signal_receiver : Noncopyable
* Provides the kernel-object name via the 'dst' method. This is
* needed for 'base-hw' only.
*/
Signal_receiver_capability _cap;
Capability<Signal_source> _cap;
/**
* List of associated contexts
@ -286,7 +287,7 @@ class Genode::Signal_receiver : Noncopyable
* source associated with the process. It must not be used for other
* purposes.
*/
static void dispatch_signals(Signal_source *signal_source);
static void dispatch_signals(Signal_source *);
};

View File

@ -28,18 +28,27 @@ struct Genode::Pd_session_client : Rpc_client<Pd_session>
int bind_thread(Thread_capability thread) override {
return call<Rpc_bind_thread>(thread); }
int assign_parent(Parent_capability parent) override {
int assign_parent(Capability<Parent> parent) override {
return call<Rpc_assign_parent>(parent); }
/**
* Dummy stub for PCI-device assignment operation
*
* The assign_pci function exists only in the NOVA-specific version of the
* PD-session interface. This empty dummy stub merely exists to maintain
* API compatibility accross all base platforms so that drivers don't need
* to distinguish NOVA from non-NOVA.
*/
bool assign_pci(addr_t) { return false; }
bool assign_pci(addr_t pci_config_memory_address, uint16_t bdf) override {
return call<Rpc_assign_pci>(pci_config_memory_address, bdf); }
Signal_source_capability alloc_signal_source() override {
return call<Rpc_alloc_signal_source>(); }
void free_signal_source(Signal_source_capability cap) override {
call<Rpc_free_signal_source>(cap); }
Signal_context_capability alloc_context(Signal_source_capability source,
unsigned long imprint) override {
return call<Rpc_alloc_context>(source, imprint); }
void free_context(Signal_context_capability cap) override {
call<Rpc_free_context>(cap); }
void submit(Signal_context_capability receiver, unsigned cnt = 1) override {
call<Rpc_submit>(receiver, cnt); }
};
#endif /* _INCLUDE__PD_SESSION__CLIENT_H_ */

View File

@ -22,7 +22,7 @@ namespace Genode { struct Pd_connection; }
struct Genode::Pd_connection : Connection<Pd_session>, Pd_session_client
{
enum { RAM_QUOTA = 4*1024 };
enum { RAM_QUOTA = 4*1024*sizeof(long) };
/**
* Constructor

View File

@ -1,6 +1,7 @@
/*
* \brief Protection domain (PD) session interface
* \author Christian Helmuth
* \author Norman Feske
* \date 2006-06-27
*
* A pd session represents the protection domain of a program.
@ -16,11 +17,17 @@
#ifndef _INCLUDE__PD_SESSION__PD_SESSION_H_
#define _INCLUDE__PD_SESSION__PD_SESSION_H_
#include <base/exception.h>
#include <thread/capability.h>
#include <parent/capability.h>
#include <session/session.h>
#include <signal_source/signal_source.h>
namespace Genode { struct Pd_session; }
namespace Genode {
struct Pd_session;
struct Parent;
struct Signal_context;
}
struct Genode::Pd_session : Session
@ -47,17 +54,117 @@ struct Genode::Pd_session : Session
* \param parent capability of parent interface
* \return 0 on success, or negative error code
*/
virtual int assign_parent(Parent_capability parent) = 0;
virtual int assign_parent(Capability<Parent> parent) = 0;
/**
* Assign PCI device to PD
*
* The specified address has to refer to the locally mapped PCI
* configuration space of the device.
*
* This function is solely used on the NOVA kernel.
*/
virtual bool assign_pci(addr_t pci_config_memory_address, uint16_t bdf) = 0;
/********************************
** Support for the signal API **
********************************/
typedef Capability<Signal_source> Signal_source_capability;
class Out_of_metadata : public Exception { };
class Invalid_signal_source : public Exception { };
/**
* Create a new signal source
*
* \return a cap that acts as reference to the created source
*
* The signal source provides an interface to wait for incoming signals.
*
* \throw Out_of_metadata
*/
virtual Signal_source_capability alloc_signal_source() = 0;
/**
* Free a signal source
*
* \param cap capability of the signal source to destroy
*/
virtual void free_signal_source(Signal_source_capability cap) = 0;
/**
* Allocate signal context
*
* \param source signal source that shall provide the new context
*
*
* \param imprint opaque value that gets delivered with signals
* originating from the allocated signal-context capability
* \return new signal-context capability
*
* \throw Out_of_metadata
* \throw Invalid_signal_source
*/
virtual Capability<Signal_context>
alloc_context(Signal_source_capability source, unsigned long imprint) = 0;
/**
* Free signal-context
*
* \param cap capability of signal-context to release
*/
virtual void free_context(Capability<Signal_context> cap) = 0;
/**
* Submit signals to the specified signal context
*
* \param context signal destination
* \param cnt number of signals to submit at once
*
* The 'context' argument does not necessarily belong to this PD session.
* Normally, it is a capability obtained from a potentially untrusted
* component. Because we cannot trust this capability, signals are not
* submitted by invoking 'cap' directly but by using it as argument to our
* trusted PD-session interface. Otherwise, a potential signal receiver
* could supply a capability with a blocking interface to compromise the
* nonblocking behaviour of the signal submission.
*/
virtual void submit(Capability<Signal_context> context, unsigned cnt = 1) = 0;
/***********************************
** Support for the RPC framework **
***********************************/
/*********************
** RPC declaration **
*********************/
GENODE_RPC(Rpc_bind_thread, int, bind_thread, Thread_capability);
GENODE_RPC(Rpc_assign_parent, int, assign_parent, Parent_capability);
GENODE_RPC(Rpc_bind_thread, int, bind_thread, Thread_capability);
GENODE_RPC(Rpc_assign_parent, int, assign_parent, Capability<Parent>);
GENODE_RPC(Rpc_assign_pci, bool, assign_pci, addr_t, uint16_t);
GENODE_RPC_INTERFACE(Rpc_bind_thread, Rpc_assign_parent);
GENODE_RPC_THROW(Rpc_alloc_signal_source, Signal_source_capability,
alloc_signal_source, GENODE_TYPE_LIST(Out_of_metadata));
GENODE_RPC(Rpc_free_signal_source, void, free_signal_source, Signal_source_capability);
GENODE_RPC_THROW(Rpc_alloc_context, Capability<Signal_context>, alloc_context,
GENODE_TYPE_LIST(Out_of_metadata, Invalid_signal_source),
Signal_source_capability, unsigned long);
GENODE_RPC(Rpc_free_context, void, free_context,
Capability<Signal_context>);
GENODE_RPC(Rpc_submit, void, submit, Capability<Signal_context>, unsigned);
GENODE_RPC_INTERFACE(Rpc_bind_thread, Rpc_assign_parent, Rpc_assign_pci,
Rpc_alloc_signal_source, Rpc_free_signal_source,
Rpc_alloc_context, Rpc_free_context, Rpc_submit);
};
#endif /* _INCLUDE__PD_SESSION__PD_SESSION_H_ */

View File

@ -1,25 +0,0 @@
/*
* \brief Signal-session capability type
* \author Norman Feske
* \date 2009-08-05
*/
/*
* Copyright (C) 2009-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__SIGNAL_SESSION__CAPABILITY_H_
#define _INCLUDE__SIGNAL_SESSION__CAPABILITY_H_
#include <base/capability.h>
#include <signal_session/signal_session.h>
namespace Genode {
typedef Capability<Signal_session> Signal_session_capability;
}
#endif /* _INCLUDE__SIGNAL_SESSION__CAPABILITY_H_ */

View File

@ -1,43 +0,0 @@
/*
* \brief Client-side signal session interface
* \author Norman Feske
* \date 2009-08-05
*/
/*
* Copyright (C) 2009-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__SIGNAL_SESSION__CLIENT_H_
#define _INCLUDE__SIGNAL_SESSION__CLIENT_H_
#include <signal_session/capability.h>
#include <signal_session/signal_session.h>
#include <base/rpc_client.h>
#include <signal_session/source_client.h>
namespace Genode { struct Signal_session_client; }
struct Genode::Signal_session_client : Rpc_client<Signal_session>
{
explicit Signal_session_client(Signal_session_capability session)
: Rpc_client<Signal_session>(session) { }
Signal_source_capability signal_source() override {
return call<Rpc_signal_source>(); }
Signal_context_capability alloc_context(long imprint) override {
return call<Rpc_alloc_context>(imprint); }
void free_context(Signal_context_capability cap) override {
call<Rpc_free_context>(cap); }
void submit(Signal_context_capability receiver, unsigned cnt = 1) override {
call<Rpc_submit>(receiver, cnt); }
};
#endif /* _INCLUDE__CAP_SESSION__CLIENT_H_ */

View File

@ -1,32 +0,0 @@
/*
* \brief Connection to signal service
* \author Norman Feske
* \date 2009-08-05
*/
/*
* Copyright (C) 2009-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__SIGNAL_SESSION__CONNECTION_H_
#define _INCLUDE__SIGNAL_SESSION__CONNECTION_H_
#include <signal_session/client.h>
#include <base/connection.h>
namespace Genode { struct Signal_connection; }
struct Genode::Signal_connection : Connection<Signal_session>, Signal_session_client
{
Signal_connection()
:
Connection<Signal_session>(session("ram_quota=16K")),
Signal_session_client(cap())
{ }
};
#endif /* _INCLUDE__CAP_SESSION__CONNECTION_H_ */

View File

@ -1,99 +0,0 @@
/*
* \brief Signal session interface
* \author Norman Feske
* \date 2009-08-05
*/
/*
* Copyright (C) 2009-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__SIGNAL_SESSION__SIGNAL_SESSION_H_
#define _INCLUDE__SIGNAL_SESSION__SIGNAL_SESSION_H_
#include <base/capability.h>
#include <base/exception.h>
#include <signal_session/source.h>
#include <session/session.h>
namespace Genode {
class Signal_context;
class Signal_receiver;
typedef Capability<Signal_receiver> Signal_receiver_capability;
typedef Capability<Signal_context> Signal_context_capability;
typedef Capability<Signal_source> Signal_source_capability;
struct Signal_session;
}
struct Genode::Signal_session : Session
{
static const char *service_name() { return "SIGNAL"; }
virtual ~Signal_session() { }
class Out_of_metadata : public Exception { };
/**
* Request capability for the signal-source interface
*/
virtual Signal_source_capability signal_source() = 0;
/**
* Allocate signal context
*
* \param imprint opaque value that gets delivered with signals
* originating from the allocated signal-context
* capability
* \return new signal-context capability
* \throw Out_of_metadata
*/
virtual Signal_context_capability alloc_context(long imprint) = 0;
/**
* Free signal-context
*
* \param cap capability of signal-context to release
*/
virtual void free_context(Signal_context_capability cap) = 0;
/**
* Submit signals to the specified signal context
*
* \param context signal destination
* \param cnt number of signals to submit at once
*
* Note that the 'context' argument does not necessarily belong to
* the signal session. Normally, it is a capability obtained from
* a potentially untrusted source. Because we cannot trust this
* capability, signals are not submitted by invoking 'cap' directly
* but by using it as argument to our trusted signal-session
* interface. Otherwise, a potential signal receiver could supply
* a capability with a blocking interface to compromise the
* nonblocking behaviour of the signal submission.
*/
virtual void submit(Signal_context_capability context,
unsigned cnt = 1) = 0;
/*********************
** RPC declaration **
*********************/
GENODE_RPC(Rpc_signal_source, Signal_source_capability, signal_source);
GENODE_RPC_THROW(Rpc_alloc_context, Signal_context_capability, alloc_context,
GENODE_TYPE_LIST(Out_of_metadata), long);
GENODE_RPC(Rpc_free_context, void, free_context, Signal_context_capability);
GENODE_RPC(Rpc_submit, void, submit, Signal_context_capability, unsigned);
GENODE_RPC_INTERFACE(Rpc_submit, Rpc_signal_source, Rpc_alloc_context,
Rpc_free_context);
};
#endif /* _INCLUDE__CAP_SESSION__CAP_SESSION_H_ */

View File

@ -1,33 +0,0 @@
/*
* \brief Signal-source client interface
* \author Norman Feske
* \date 2010-02-03
*
* See documentation in 'signal_session/source.h'.
*/
/*
* Copyright (C) 2010-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__SIGNAL_SESSION__SOURCE_CLIENT_H_
#define _INCLUDE__SIGNAL_SESSION__SOURCE_CLIENT_H_
#include <signal_session/source.h>
#include <base/rpc_client.h>
namespace Genode { struct Signal_source_client; }
struct Genode::Signal_source_client : Rpc_client<Signal_source>
{
Signal_source_client(Signal_source_capability signal_source)
: Rpc_client<Signal_source>(signal_source) { }
Signal wait_for_signal() override { return call<Rpc_wait_for_signal>(); }
};
#endif /* _INCLUDE__SIGNAL_SESSION__SOURCE_CLIENT_H_ */

View File

@ -0,0 +1,22 @@
/*
* \brief Signal-source capability type
* \author Norman Feske
* \date 2016-01-04
*/
/*
* Copyright (C) 2016 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__SIGNAL_SOURCE__CAPABILITY_H_
#define _INCLUDE__SIGNAL_SOURCE__CAPABILITY_H_
#include <base/capability.h>
#include <signal_source/signal_source.h>
namespace Genode { typedef Capability<Signal_source> Signal_source_capability; }
#endif /* _INCLUDE__SIGNAL_SOURCE__CAPABILITY_H_ */

View File

@ -0,0 +1,30 @@
/*
* \brief Client-side signal-source interface
* \author Norman Feske
* \date 2016-01-04
*/
/*
* Copyright (C) 2016 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__SIGNAL_SOURCE__CLIENT_H_
#define _INCLUDE__SIGNAL_SOURCE__CLIENT_H_
#include <base/rpc_client.h>
#include <pd_session/pd_session.h>
namespace Genode { class Signal_source_client; }
struct Genode::Signal_source_client : Rpc_client<Signal_source>
{
Signal_source_client(Capability<Signal_source> signal_source)
: Rpc_client<Signal_source>(signal_source) { }
Signal wait_for_signal() override { return call<Rpc_wait_for_signal>(); }
};
#endif /* _INCLUDE__SIGNAL_SOURCE__CLIENT_H_ */

View File

@ -15,14 +15,14 @@
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__SIGNAL_SESSION__SOURCE_RPC_OBJECT_H_
#define _INCLUDE__SIGNAL_SESSION__SOURCE_RPC_OBJECT_H_
#ifndef _INCLUDE__SIGNAL_SOURCE__RPC_OBJECT_H_
#define _INCLUDE__SIGNAL_SOURCE__RPC_OBJECT_H_
#include <signal_session/source.h>
#include <base/rpc_server.h>
#include <signal_source/signal_source.h>
namespace Genode { struct Signal_source_rpc_object; }
struct Genode::Signal_source_rpc_object : Rpc_object<Signal_source> { };
#endif /* _INCLUDE__SIGNAL_SESSION__SOURCE_RPC_OBJECT_H_ */
#endif /* _INCLUDE__SIGNAL_SOURCE__RPC_OBJECT_H_ */

View File

@ -3,10 +3,9 @@
* \author Norman Feske
* \date 2010-02-03
*
* This file is only included by 'signal_session/signal_session.h' and relies
* on the headers included there. No include guards are needed. It is a
* separate header file to make it easily replaceable by a platform-specific
* implementation.
* This file is only included by 'pd_session/pd_session.h' and relies
* on the headers included there. It is a separate header file to make it
* easily replaceable by a platform-specific implementation.
*/
/*
@ -16,22 +15,19 @@
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__SIGNAL_SESSION__SOURCE_H_
#define _INCLUDE__SIGNAL_SESSION__SOURCE_H_
#include <base/rpc.h>
namespace Genode { struct Signal_source; }
#ifndef _INCLUDE__SIGNAL_SOURCE__SIGNAL_SOURCE_H_
#define _INCLUDE__SIGNAL_SOURCE__SIGNAL_SOURCE_H_
namespace Genode { class Signal_source; }
/**
* Blocking part of the signal-session interface
* Blocking part of the PD-session interface
*
* The blocking 'wait_for_signal()' operation cannot be part of the
* signal-session interface because otherwise, context allocations or
* PD-session interface because otherwise, context allocations or
* signal submissions would not be possible while blocking for signals.
* Therefore, the blocking part is implemented a separate interface,
* which can be used by an independent thread.
* Therefore, the blocking part is implemented as a kernel-specific
* special case.
*/
struct Genode::Signal_source
{
@ -44,10 +40,7 @@ struct Genode::Signal_source
public:
Signal(long imprint, int num) :
_imprint(imprint),
_num(num)
{ }
Signal(long imprint, int num) : _imprint(imprint), _num(num) { }
Signal() : _imprint(0), _num(0) { }
@ -72,4 +65,4 @@ struct Genode::Signal_source
GENODE_RPC_INTERFACE(Rpc_wait_for_signal);
};
#endif /* _INCLUDE__SIGNAL_SESSION__SOURCE_H_ */
#endif /* _INCLUDE__SIGNAL_SOURCE__SIGNAL_SOURCE_H_ */

View File

@ -144,6 +144,7 @@ class Genode::Platform_env : public Genode::Env, public Emergency_ram_reserve
Cpu_session_capability cpu_session_cap() { return _resources.cpu; }
Rm_session *rm_session() { return &_resources.rm; }
Pd_session *pd_session() { return &_resources.pd; }
Pd_session_capability pd_session_cap() { return _resources.pd; }
Allocator *heap() { return &_heap; }
};

View File

@ -49,7 +49,8 @@ void Rpc_entrypoint::omit_reply()
}
void Rpc_entrypoint::explicit_reply(Untyped_capability reply_cap, int return_value)
void Rpc_entrypoint::reply_signal_info(Untyped_capability reply_cap,
unsigned long imprint, unsigned long cnt)
{
if (!_ipc_server) return;
@ -57,9 +58,9 @@ void Rpc_entrypoint::explicit_reply(Untyped_capability reply_cap, int return_val
Untyped_capability last_reply_cap = _ipc_server->dst();
/* direct ipc server to the specified reply destination */
_ipc_server->ret(return_value);
_ipc_server->ret(0);
_ipc_server->dst(reply_cap);
*_ipc_server << IPC_REPLY;
*_ipc_server << Signal_source::Signal(imprint, cnt) << IPC_REPLY;
/* restore reply capability of the original request */
_ipc_server->dst(last_reply_cap);

View File

@ -14,20 +14,12 @@
*/
/* Genode includes */
#include <base/env.h>
#include <base/signal.h>
#include <signal_session/connection.h>
#include <base/trace/events.h>
using namespace Genode;
/**
* Return process-wide signal session
*/
Signal_connection * Genode::signal_connection()
{
static Signal_connection sc;
return &sc;
}
/************
** Signal **
@ -110,9 +102,6 @@ Signal_context::~Signal_context()
** Signal_transmitter **
************************/
Signal_connection * Signal_transmitter::connection() { return signal_connection(); }
Signal_transmitter::Signal_transmitter(Signal_context_capability context)
: _context(context) { }
@ -201,7 +190,7 @@ void Signal_receiver::_unsynchronized_dissolve(Signal_context * const context)
_platform_begin_dissolve(context);
/* tell core to stop sending signals referring to the context */
signal_connection()->free_context(context->_cap);
env()->pd_session()->free_context(context->_cap);
/* restore default initialization of signal context */
context->_receiver = 0;

View File

@ -13,17 +13,20 @@
*/
#include <signal_session/connection.h>
#include <base/env.h>
#include <base/trace/events.h>
using namespace Genode;
/************************
** Signal transmitter **
************************/
void Signal_transmitter::submit(unsigned cnt)
{
{
Trace::Signal_submit trace_event(cnt);
}
connection()->submit(_context, cnt);
env()->pd_session()->submit(_context, cnt);
}

View File

@ -11,10 +11,12 @@
* under the terms of the GNU General Public License version 2.
*/
#include <util/retry.h>
#include <base/env.h>
#include <base/signal.h>
#include <base/thread.h>
#include <base/trace/events.h>
#include <signal_session/connection.h>
#include <signal_source/client.h>
using namespace Genode;
@ -63,7 +65,7 @@ class Signal_handler_thread : Thread<STACK_SIZE>, Lock
Signal_source *Signal_handler_thread::signal_source()
{
static Signal_source_client sigsrc(signal_connection()->signal_source());
static Signal_source_client sigsrc(env()->pd_session()->alloc_signal_source());
return &sigsrc;
}
@ -203,30 +205,23 @@ Signal_context_capability Signal_receiver::manage(Signal_context *context)
/* register context at process-wide registry */
signal_context_registry()->insert(&context->_registry_le);
bool try_again = true;
for (;;) {
try {
retry<Pd_session::Out_of_metadata>(
[&] () {
/* use signal context as imprint */
context->_cap = signal_connection()->alloc_context((long)context);
return context->_cap;
} catch (Signal_session::Out_of_metadata) {
/* give up if the error occurred a second time */
if (try_again) { try_again = false; }
else { break; }
context->_cap = env()->pd_session()->alloc_context(_cap, (long)context);
},
[&] () {
size_t const quota = 1024*sizeof(long);
char buf[64];
snprintf(buf, sizeof(buf), "ram_quota=%zu", quota);
PINF("upgrading quota donation for SIGNAL session (%zu bytes)", quota);
PINF("upgrading quota donation for PD session (%zu bytes)", quota);
env()->parent()->upgrade(signal_connection()->cap(), buf);
env()->parent()->upgrade(env()->pd_session_cap(), buf);
}
};
return Signal_context_capability();
);
return context->_cap;
}

View File

@ -0,0 +1,24 @@
/*
* \brief Assertion macros
* \author Norman Feske
* \date 2016-01-13
*/
/*
* Copyright (C) 2015 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _CORE__INCLUDE__ASSERTION_H_
#define _CORE__INCLUDE__ASSERTION_H_
/* Genode includes */
#include <base/printf.h>
#define ASSERT_NEVER_CALLED \
PERR("Unexpected call of '%s' (%s:%u)", __FUNCTION__, __FILE__, __LINE__); \
for (;;); throw 0UL;
#endif /* _CORE__INCLUDE__ASSERTION_H_ */

View File

@ -22,12 +22,14 @@
#include <base/env.h>
#include <base/heap.h>
#include <ram_session/client.h>
#include <pd_session/client.h>
#include <rm_session/capability.h>
/* core includes */
#include <platform.h>
#include <core_parent.h>
#include <core_rm_session.h>
#include <core_pd_session.h>
#include <cap_session_component.h>
#include <ram_session_component.h>
@ -113,30 +115,45 @@ namespace Genode {
typedef Synchronized_ram_session<Ram_session_component> Core_ram_session;
Core_parent _core_parent;
Cap_session_component _cap_session;
enum { ENTRYPOINT_STACK_SIZE = 2048 * sizeof(Genode::addr_t) };
Core_parent _core_parent;
Cap_session_component _cap_session;
Rpc_entrypoint _entrypoint;
Core_rm_session _rm_session;
Core_ram_session _ram_session;
Heap _heap;
Ram_session_capability const _ram_session_cap;
/*
* The core-local PD session is provided by a real RPC object
* dispatched by the same entrypoint as the signal-source RPC
* objects. This is needed to allow the 'Pd_session::submit'
* method to issue out-of-order replies to
* 'Signal_source::wait_for_signal' calls.
*/
Core_pd_session_component _pd_session_component;
Pd_session_client _pd_session_client;
Heap _heap;
public:
/**
* Constructor
*/
Core_env() :
Core_env()
:
_cap_session(platform()->core_mem_alloc(), "ram_quota=4K"),
_entrypoint(&_cap_session, ENTRYPOINT_STACK_SIZE, "entrypoint"),
_rm_session(&_entrypoint),
_ram_session(&_entrypoint, &_entrypoint,
platform()->ram_alloc(), platform()->core_mem_alloc(),
"ram_quota=4M", platform()->ram_alloc()->avail()),
_heap(&_ram_session, &_rm_session),
_ram_session_cap(_entrypoint.manage(&_ram_session))
_ram_session_cap(_entrypoint.manage(&_ram_session)),
_pd_session_component(_entrypoint /* XXX use a different entrypoint */),
_pd_session_client(_entrypoint.manage(&_pd_session_component)),
_heap(&_ram_session, &_rm_session)
{ }
/**
@ -144,19 +161,20 @@ namespace Genode {
*/
~Core_env() { parent()->exit(0); }
Cap_session *cap_session() { return &_cap_session; }
Rpc_entrypoint *entrypoint() { return &_entrypoint; }
Cap_session *cap_session() { return &_cap_session; }
/*******************
** Env interface **
*******************/
Parent *parent() { return &_core_parent; }
Ram_session *ram_session() { return &_ram_session; }
Ram_session_capability ram_session_cap() { return _ram_session_cap; }
Rm_session *rm_session() { return &_rm_session; }
Allocator *heap() { return &_heap; }
Parent *parent() override { return &_core_parent; }
Ram_session *ram_session() override { return &_ram_session; }
Ram_session_capability ram_session_cap() override { return _ram_session_cap; }
Rm_session *rm_session() override { return &_rm_session; }
Pd_session *pd_session() override { return &_pd_session_client; }
Allocator *heap() override { return &_heap; }
Cpu_session *cpu_session()
{
@ -169,10 +187,10 @@ namespace Genode {
return Cpu_session_capability();
}
Pd_session *pd_session()
Pd_session_capability pd_session_cap() override
{
PWRN("%s:%u not implemented", __FILE__, __LINE__);
return 0;
return Pd_session_capability();
}
void reinit(Capability<Parent>::Dst, long) { }

View File

@ -0,0 +1,102 @@
/*
* \brief Core-specific pseudo PD session
* \author Norman Feske
* \date 2016-01-13
*/
/*
* Copyright (C) 2015 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _CORE__INCLUDE__CORE_PD_SESSION_H_
#define _CORE__INCLUDE__CORE_PD_SESSION_H_
/* Genode includes */
#include <base/rpc_server.h>
#include <base/allocator.h>
#include <pd_session/pd_session.h>
/* core includes */
#include <assertion.h>
#include <signal_source_component.h>
namespace Genode { class Core_pd_session_component; }
class Genode::Core_pd_session_component : public Rpc_object<Pd_session>
{
private:
Rpc_entrypoint &_signal_source_ep;
public:
/**
* Constructor
*
* \param context_ep entrypoint that serves the signal-source
* components
*/
Core_pd_session_component(Rpc_entrypoint &signal_source_ep)
:
_signal_source_ep(signal_source_ep)
{ }
int bind_thread(Thread_capability thread) override
{
ASSERT_NEVER_CALLED;
}
int assign_parent(Capability<Parent> parent) override
{
ASSERT_NEVER_CALLED;
}
bool assign_pci(addr_t pci_config_memory_address, uint16_t) override
{
ASSERT_NEVER_CALLED;
}
Signal_source_capability alloc_signal_source() override
{
/*
* Even though core does not receive any signals, this function is
* called by the base-common initialization code on base-hw. We
* can savely return an invalid capability as it is never used.
*/
return Signal_source_capability();
}
void free_signal_source(Signal_source_capability cap) override
{
ASSERT_NEVER_CALLED;
}
Capability<Signal_context>
alloc_context(Signal_source_capability source, unsigned long imprint) override
{
ASSERT_NEVER_CALLED;
}
void free_context(Capability<Signal_context> cap) override
{
ASSERT_NEVER_CALLED;
}
void submit(Capability<Signal_context> cap, unsigned cnt = 1) override
{
_signal_source_ep.apply(cap, [&] (Signal_context_component *context) {
if (!context) {
PDBG("invalid signal-context capability");
return;
}
context->source()->submit(context, cnt);
});
}
};
#endif /* _CORE__INCLUDE__CORE_PD_SESSION_H_ */

View File

@ -25,19 +25,21 @@ namespace Genode {
}
class Genode::Pd_root
: public Genode::Root_component<Genode::Pd_session_component>
class Genode::Pd_root : public Genode::Root_component<Genode::Pd_session_component>
{
private:
Rpc_entrypoint *_thread_ep;
Allocator *_md_alloc;
Rpc_entrypoint &_thread_ep;
Allocator &_md_alloc;
protected:
Pd_session_component *_create_session(const char *args)
{
/* XXX use separate entrypoint for PD sessions */
return new (md_alloc()) Pd_session_component(_thread_ep,
_thread_ep,
_thread_ep,
_md_alloc, args);
}
@ -61,7 +63,7 @@ class Genode::Pd_root
Rpc_entrypoint *thread_ep,
Allocator *md_alloc)
: Root_component<Pd_session_component>(session_ep, md_alloc),
_thread_ep(thread_ep), _md_alloc(md_alloc) { }
_thread_ep(*thread_ep), _md_alloc(*md_alloc) { }
};
#endif /* _CORE__INCLUDE__PD_ROOT_H_ */

View File

@ -2,11 +2,12 @@
* \brief Core-specific instance of the PD session interface
* \author Christian Helmuth
* \author Stefan Kalkowski
* \author Norman Feske
* \date 2006-07-17
*/
/*
* Copyright (C) 2006-2013 Genode Labs GmbH
* Copyright (C) 2006-2016 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
@ -23,6 +24,7 @@
/* core includes */
#include <platform_pd.h>
#include <signal_broker.h>
namespace Genode { class Pd_session_component; }
@ -48,35 +50,86 @@ class Genode::Pd_session_component : public Rpc_object<Pd_session>
Allocator_guard _md_alloc; /* guarded meta-data allocator */
Platform_pd _pd;
Parent_capability _parent;
Rpc_entrypoint *_thread_ep;
Capability<Parent> _parent;
Rpc_entrypoint &_thread_ep;
Signal_broker _signal_broker;
size_t _ram_quota(char const * args) {
return Arg_string::find_arg(args, "ram_quota").long_value(0); }
public:
Pd_session_component(Rpc_entrypoint * thread_ep,
Allocator * md_alloc,
char const * args)
: _label(args),
_md_alloc(md_alloc, _ram_quota(args)),
_pd(&_md_alloc, _label.string),
_thread_ep(thread_ep) { }
/**
* Constructor
*
* \param receiver_ep entrypoint holding signal-receiver component
* objects
* \param context_ep global pool of all signal contexts
* \param md_alloc backing-store allocator for
* signal-context component objects
*
* To maintain proper synchronization, 'receiver_ep' must be
* the same entrypoint as used for the signal-session component.
* The 'signal_context_ep' is only used for associative array
* to map signal-context capabilities to 'Signal_context_component'
* objects and as capability allocator for such objects.
*/
Pd_session_component(Rpc_entrypoint &thread_ep,
Rpc_entrypoint &receiver_ep,
Rpc_entrypoint &context_ep,
Allocator &md_alloc,
char const *args)
:
_label(args),
_md_alloc(&md_alloc, _ram_quota(args)),
_pd(&_md_alloc, _label.string),
_thread_ep(thread_ep),
_signal_broker(_md_alloc, receiver_ep, context_ep)
{ }
/**
* Register quota donation at allocator guard
*/
void upgrade_ram_quota(size_t ram_quota) {
_md_alloc.upgrade(ram_quota); }
void upgrade_ram_quota(size_t ram_quota);
/**************************/
/** PD session interface **/
/**************************/
/**************************
** PD session interface **
**************************/
int bind_thread(Thread_capability);
int assign_parent(Parent_capability);
int bind_thread(Thread_capability) override;
int assign_parent(Capability<Parent>) override;
bool assign_pci(addr_t, uint16_t) override;
Signal_source_capability alloc_signal_source() override
{
try {
return _signal_broker.alloc_signal_source(); }
catch (Genode::Allocator::Out_of_memory) {
throw Pd_session::Out_of_metadata(); }
}
void free_signal_source(Signal_source_capability sig_rec_cap) override {
_signal_broker.free_signal_source(sig_rec_cap); }
Signal_context_capability
alloc_context(Signal_source_capability sig_rec_cap, unsigned long imprint) override
{
try {
return _signal_broker.alloc_context(sig_rec_cap, imprint); }
catch (Genode::Allocator::Out_of_memory) {
throw Pd_session::Out_of_metadata(); }
catch (Signal_broker::Invalid_signal_source) {
throw Pd_session::Invalid_signal_source(); }
}
void free_context(Signal_context_capability cap) override {
_signal_broker.free_context(cap); }
void submit(Signal_context_capability cap, unsigned n) override {
_signal_broker.submit(cap, n); }
};
#endif /* _CORE__INCLUDE__PD_SESSION_COMPONENT_H_ */

View File

@ -0,0 +1,110 @@
/*
* \brief Mechanism to deliver signals via core
* \author Norman Feske
* \date 2016-01-04
*/
/*
* Copyright (C) 2016 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _CORE__INCLUDE__SIGNAL_BROKER_H_
#define _CORE__INCLUDE__SIGNAL_BROKER_H_
#include <signal_source_component.h>
#include <signal_source/capability.h>
namespace Genode { class Signal_broker; }
class Genode::Signal_broker
{
private:
Allocator &_md_alloc;
Rpc_entrypoint &_source_ep;
Rpc_entrypoint &_context_ep;
Signal_source_component _source;
Signal_source_capability _source_cap;
Tslab<Signal_context_component,
960*sizeof(long)> _contexts_slab { &_md_alloc };
public:
class Invalid_signal_source : public Exception { };
Signal_broker(Allocator &md_alloc,
Rpc_entrypoint &source_ep,
Rpc_entrypoint &context_ep)
:
_md_alloc(md_alloc),
_source_ep(source_ep),
_context_ep(context_ep),
_source(&_context_ep),
_source_cap(_source_ep.manage(&_source))
{ }
~Signal_broker()
{
/* remove source from entrypoint */
_source_ep.dissolve(&_source);
/* free all signal contexts */
while (Signal_context_component *r = _contexts_slab.first_object())
free_context(r->cap());
}
Signal_source_capability alloc_signal_source() { return _source_cap; }
void free_signal_source(Signal_source_capability) { }
Signal_context_capability
alloc_context(Signal_source_capability, unsigned long imprint)
{
/*
* XXX For now, we ignore the signal-source argument as we
* create only a single receiver for each PD.
*/
Signal_context_component *context = new (&_contexts_slab)
Signal_context_component(imprint, &_source);
return _context_ep.manage(context);
}
void free_context(Signal_context_capability context_cap)
{
Signal_context_component *context;
_context_ep.apply(context_cap, [&] (Signal_context_component *c) {
context = c;
if (!context) {
PWRN("specified signal-context capability has wrong type");
return;
}
_context_ep.dissolve(context);
});
destroy(&_contexts_slab, context);
}
void submit(Signal_context_capability cap, unsigned cnt)
{
_source_ep.apply(cap, [&] (Signal_context_component *context) {
if (!context) {
/*
* We do not use PWRN() to enable the build system to
* suppress this warning in release mode (SPECS +=
* release).
*/
PDBG("invalid signal-context capability");
return;
}
context->source()->submit(context, cnt);
});
}
};
#endif /* _CORE__INCLUDE__SIGNAL_BROKER_H_ */

View File

@ -1,76 +0,0 @@
/*
* \brief Signal root interface
* \author Norman Feske
* \date 2009-08-05
*/
/*
* Copyright (C) 2009-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _CORE__INCLUDE__SIGNAL_ROOT_H_
#define _CORE__INCLUDE__SIGNAL_ROOT_H_
/* Genode includes */
#include <root/component.h>
/* core includes */
#include <signal_session_component.h>
namespace Genode {
class Signal_handler
{
private:
enum { STACK_SIZE = sizeof(addr_t)*1024 };
Rpc_entrypoint _ep;
public:
Signal_handler(Cap_session *cap_session) :
_ep(cap_session, STACK_SIZE, "signal")
{ }
Rpc_entrypoint *entrypoint() { return &_ep; }
};
class Signal_root : private Signal_handler,
public Root_component<Signal_session_component>
{
protected:
Signal_session_component *_create_session(const char *args)
{
size_t ram_quota = Arg_string::find_arg(args, "ram_quota").ulong_value(0);
return new (md_alloc())
Signal_session_component(entrypoint(), entrypoint(),
md_alloc(), ram_quota);
}
void _upgrade_session(Signal_session_component *s, const char *args)
{
size_t ram_quota = Arg_string::find_arg(args, "ram_quota").ulong_value(0);
s->upgrade_ram_quota(ram_quota);
}
public:
/**
* Constructor
*
* \param md_alloc meta-data allocator to be used by root component
*/
Signal_root(Allocator *md_alloc, Cap_session *cap_session)
:
Signal_handler(cap_session),
Root_component<Signal_session_component>(entrypoint(), md_alloc)
{ }
};
}
#endif /* _CORE__INCLUDE__SIGNAL_ROOT_H_ */

View File

@ -1,209 +0,0 @@
/*
* \brief Signal service
* \author Norman Feske
* \date 2009-08-05
*/
/*
* Copyright (C) 2009-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _CORE__INCLUDE__SIGNAL_SESSION_COMPONENT_H_
#define _CORE__INCLUDE__SIGNAL_SESSION_COMPONENT_H_
#include <signal_session/signal_session.h>
#include <signal_session/source_rpc_object.h>
#include <base/allocator_guard.h>
#include <base/tslab.h>
#include <base/lock.h>
#include <base/rpc_client.h>
#include <base/rpc_server.h>
#include <util/fifo.h>
#include <base/signal.h>
namespace Genode {
class Signal_source_component;
class Signal_context_component;
typedef Fifo<Signal_context_component> Signal_queue;
class Signal_context_component : public Rpc_object<Signal_context>,
public Signal_queue::Element
{
private:
long _imprint;
int _cnt;
Signal_source_component *_source;
public:
/**
* Constructor
*/
Signal_context_component(long imprint, Signal_source_component *source)
: _imprint(imprint), _cnt(0), _source(source) { }
/**
* De-constructor
*/
~Signal_context_component();
/**
* Increment number of signals to be delivered at once
*/
void increment_signal_cnt(int increment) { _cnt += increment; }
/**
* Reset number of pending signals
*/
void reset_signal_cnt() { _cnt = 0; }
long imprint() { return _imprint; }
int cnt() { return _cnt; }
Signal_source_component *source() { return _source; }
};
class Signal_source_component : public Signal_source_rpc_object
{
/**
* Helper for clean destruction of signal-source component
*
* Normally, reply capabilities are implicitly destroyed when answering
* an RPC call. But when destructing a signal session while a signal-
* source client is blocking on a 'wait_for_signal' call, this
* blocking call will never return via the normal control flow
* (signal submission). In this case, the reply capability would
* outlive the signal session. To avoid the leakage of such reply
* capabilities, we let the signal-session destructor perform a
* core-local RPC call to the so-called 'Finalizer' object, which has
* the sole purpose of replying to the last outstanding
* 'wait_for_signal' call and thereby releasing the corresponding
* reply capability.
*/
struct Finalizer
{
GENODE_RPC(Rpc_exit, void, exit);
GENODE_RPC_INTERFACE(Rpc_exit);
};
struct Finalizer_component : Rpc_object<Finalizer, Finalizer_component>
{
Signal_source_component &source;
Finalizer_component(Signal_source_component &source)
: source(source) { }
void exit();
};
private:
Signal_queue _signal_queue;
Rpc_entrypoint *_entrypoint;
Native_capability _reply_cap;
Finalizer_component _finalizer;
Capability<Finalizer> _finalizer_cap;
public:
/**
* Constructor
*/
Signal_source_component(Rpc_entrypoint *rpc_entrypoint);
~Signal_source_component();
void release(Signal_context_component *context);
void submit(Signal_context_component *context,
Ipc_ostream *ostream,
int cnt);
/*****************************
** Signal-source interface **
*****************************/
Signal wait_for_signal();
};
class Signal_session_component : public Rpc_object<Signal_session>
{
private:
Rpc_entrypoint *_source_ep;
Rpc_entrypoint *_context_ep;
Signal_source_component _source;
Signal_source_capability _source_cap;
Allocator_guard _md_alloc;
Tslab<Signal_context_component,
960*sizeof(long)> _contexts_slab;
Ipc_ostream *_ipc_ostream;
public:
/**
* Constructor
*
* \param source_ep entrypoint holding signal-source component
* objects
* \param context_ep global pool of all signal contexts
* \param md_alloc backing-store allocator for
* signal-context component objects
*
* To maintain proper synchronization, 'signal_source_ep' must be
* the same entrypoint as used for the signal-session component.
* The 'signal_context_ep' is only used for associative array
* to map signal-context capabilities to 'Signal_context_component'
* objects and as capability allocator for such objects.
*/
Signal_session_component(Rpc_entrypoint *source_ep,
Rpc_entrypoint *context_ep,
Allocator *context_md_alloc,
size_t ram_quota);
~Signal_session_component();
/**
* Register quota donation at allocator guard
*/
void upgrade_ram_quota(size_t ram_quota) { _md_alloc.upgrade(ram_quota); }
/******************************
** Signal-session interface **
******************************/
Signal_source_capability signal_source();
Signal_context_capability alloc_context(long imprint);
void free_context(Signal_context_capability context_cap);
void submit(Signal_context_capability context_cap, unsigned cnt);
/**************************
** Rpc_object interface **
**************************/
Rpc_exception_code dispatch(int opcode, Ipc_istream &is, Ipc_ostream &os)
{
/*
* Make IPC output stream available to the submit function. The
* stream is used to carry signal payload for the out-of-order
* handling of 'wait_for_signal' replies.
*/
_ipc_ostream = &os;
/* dispatch RPC */
return Rpc_object<Signal_session>::dispatch(opcode, is, os);
}
};
}
#endif /* _CORE__INCLUDE__CAP_SESSION_COMPONENT_H_ */

View File

@ -0,0 +1,143 @@
/*
* \brief Signal-delivery mechanism
* \author Norman Feske
* \date 2009-08-05
*/
/*
* Copyright (C) 2009-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _CORE__INCLUDE__SIGNAL_SOURCE_COMPONENT_H_
#define _CORE__INCLUDE__SIGNAL_SOURCE_COMPONENT_H_
#include <signal_source/rpc_object.h>
#include <base/allocator_guard.h>
#include <base/tslab.h>
#include <base/lock.h>
#include <base/rpc_client.h>
#include <base/rpc_server.h>
#include <util/fifo.h>
#include <base/signal.h>
namespace Genode {
class Signal_context_component;
class Signal_source_component;
typedef Fifo<Signal_context_component> Signal_queue;
}
class Genode::Signal_context_component : public Rpc_object<Signal_context>,
public Signal_queue::Element
{
private:
long _imprint;
int _cnt;
Signal_source_component *_source;
public:
/**
* Constructor
*/
Signal_context_component(long imprint,
Signal_source_component *source)
: _imprint(imprint), _cnt(0), _source(source) { }
/**
* Destructor
*/
inline ~Signal_context_component();
/**
* Increment number of signals to be delivered at once
*/
void increment_signal_cnt(int increment) { _cnt += increment; }
/**
* Reset number of pending signals
*/
void reset_signal_cnt() { _cnt = 0; }
long imprint() { return _imprint; }
int cnt() { return _cnt; }
Signal_source_component *source() { return _source; }
};
class Genode::Signal_source_component : public Signal_source_rpc_object
{
/**
* Helper for clean destruction of signal-receiver component
*
* Normally, reply capabilities are implicitly destroyed when answering
* an RPC call. But when destructing a signal session while a signal-
* receiver client is blocking on a 'wait_for_signal' call, this
* blocking call will never return via the normal control flow
* (signal submission). In this case, the reply capability would
* outlive the signal session. To avoid the leakage of such reply
* capabilities, we let the signal-session destructor perform a
* core-local RPC call to the so-called 'Finalizer' object, which has
* the sole purpose of replying to the last outstanding
* 'wait_for_signal' call and thereby releasing the corresponding
* reply capability.
*/
struct Finalizer
{
GENODE_RPC(Rpc_exit, void, exit);
GENODE_RPC_INTERFACE(Rpc_exit);
};
struct Finalizer_component : Rpc_object<Finalizer, Finalizer_component>
{
Signal_source_component &source;
Finalizer_component(Signal_source_component &source)
: source(source) { }
void exit();
};
private:
Signal_queue _signal_queue;
Rpc_entrypoint *_entrypoint;
Native_capability _reply_cap;
Finalizer_component _finalizer;
Capability<Finalizer> _finalizer_cap;
public:
/**
* Constructor
*/
Signal_source_component(Rpc_entrypoint *rpc_entrypoint);
~Signal_source_component();
void release(Signal_context_component *context);
void submit(Signal_context_component *context,
unsigned long cnt);
/*****************************
** Signal-receiver interface **
*****************************/
Signal wait_for_signal() override;
};
Genode::Signal_context_component::~Signal_context_component()
{
if (is_enqueued() && _source)
_source->release(this);
}
#endif /* _CORE__INCLUDE__SIGNAL_SOURCE_COMPONENT_H_ */

View File

@ -33,7 +33,6 @@
#include <log_root.h>
#include <io_mem_root.h>
#include <irq_root.h>
#include <signal_root.h>
#include <trace/root.h>
#include <platform_services.h>
@ -213,16 +212,6 @@ int main()
*/
static Sliced_heap sliced_heap(env()->ram_session(), env()->rm_session());
/**
* Provide signal service before other services to enable the use of signal
* connection during service initialization. This has been introduced due
* to the use of the signal framework for paging (RM service) in base-hw.
*/
static Signal_root signal_root(&sliced_heap, core_env()->cap_session());
char const * const signal_name = Signal_session::service_name();
static Local_service signal_service(signal_name, &signal_root);
local_services.insert(&signal_service);
static Cap_root cap_root (e, &sliced_heap);
static Ram_root ram_root (e, e, platform()->ram_alloc(), &sliced_heap);
static Rom_root rom_root (e, e, platform()->rom_fs(), &sliced_heap);

View File

@ -0,0 +1,22 @@
/*
* \brief Core implementation of the PD session interface
* \author Norman Feske
* \date 2016-01-13
*
* This dummy is used on all kernels with no IOMMU support.
*/
/*
* Copyright (C) 2016 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* core-local includes */
#include <pd_session_component.h>
using namespace Genode;
bool Pd_session_component::assign_pci(addr_t, uint16_t) { return false; }

View File

@ -26,7 +26,7 @@ using namespace Genode;
int Pd_session_component::bind_thread(Thread_capability thread)
{
return _thread_ep->apply(thread, [&] (Cpu_thread_component *cpu_thread) {
return _thread_ep.apply(thread, [&] (Cpu_thread_component *cpu_thread) {
if (!cpu_thread) return -1;
if (cpu_thread->bound()) {

View File

@ -0,0 +1,24 @@
/*
* \brief Core implementation of the PD session interface
* \author Norman Feske
* \date 2016-01-13
*/
/*
* Copyright (C) 2016 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* core-local includes */
#include <pd_session_component.h>
using namespace Genode;
void Pd_session_component::upgrade_ram_quota(size_t ram_quota)
{
_md_alloc.upgrade(ram_quota);
}

View File

@ -1,110 +0,0 @@
/*
* \brief Implementation of the SIGNAL interface
* \author Norman Feske
* \date 2009-08-11
*/
/*
* Copyright (C) 2009-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* Genode includes */
#include <base/printf.h>
/* core includes */
#include <signal_session_component.h>
using namespace Genode;
/******************************
** Signal-session component **
******************************/
Signal_session_component::Signal_session_component(Rpc_entrypoint *source_ep,
Rpc_entrypoint *context_ep,
Allocator *context_md_alloc,
size_t ram_quota)
:
_source_ep(source_ep),
_context_ep(context_ep),
_source(source_ep),
_source_cap(_source_ep->manage(&_source)),
_md_alloc(context_md_alloc, ram_quota),
_contexts_slab(&_md_alloc)
{ }
Signal_session_component::~Signal_session_component()
{
/* remove _signal_source from entrypoint */
_source_ep->dissolve(&_source);
/* free all signal contexts */
while (Signal_context_component *r = _contexts_slab.first_object())
free_context(r->cap());
}
Signal_source_capability Signal_session_component::signal_source()
{
return _source_cap;
}
Signal_context_capability Signal_session_component::alloc_context(long imprint)
{
Signal_context_component *context;
try { context = new (&_contexts_slab)
Signal_context_component(imprint, &_source); }
catch (Allocator::Out_of_memory) { throw Out_of_metadata(); }
/* return unique capability for the signal context */
return _context_ep->manage(context);
}
void Signal_session_component::free_context(Signal_context_capability context_cap)
{
Signal_context_component *context;
_context_ep->apply(context_cap, [&] (Signal_context_component *c) {
context = c;
if (!context) {
PWRN("specified signal-context capability has wrong type");
return;
}
_context_ep->dissolve(context);
});
destroy(&_contexts_slab, context);
}
void Signal_session_component::submit(Signal_context_capability context_cap,
unsigned cnt)
{
_context_ep->apply(context_cap, [&] (Signal_context_component *context) {
if (!context) {
/*
* We do not use PWRN() to enable the build system to suppress this
* warning in release mode (SPECS += release).
*/
PDBG("invalid signal-context capability");
return;
}
context->source()->submit(context, _ipc_ostream, cnt);
});
}
Signal_context_component::~Signal_context_component()
{
if (is_enqueued() && _source)
_source->release(this);
}

View File

@ -16,7 +16,7 @@
#include <base/printf.h>
/* core includes */
#include <signal_session_component.h>
#include <signal_source_component.h>
using namespace Genode;
@ -33,8 +33,7 @@ void Signal_source_component::release(Signal_context_component *context)
void Signal_source_component::submit(Signal_context_component *context,
Ipc_ostream *ostream,
int cnt)
unsigned long cnt)
{
/*
* If the client does not block in 'wait_for_signal', the
@ -49,8 +48,7 @@ void Signal_source_component::submit(Signal_context_component *context,
*/
if (_reply_cap.valid()) {
*ostream << Signal(context->imprint(), context->cnt());
_entrypoint->explicit_reply(_reply_cap, 0);
_entrypoint->reply_signal_info(_reply_cap, context->imprint(), context->cnt());
/*
* We unblocked the client and, therefore, can invalidate
@ -108,6 +106,6 @@ void Signal_source_component::Finalizer_component::exit()
if (!source._reply_cap.valid())
return;
source._entrypoint->explicit_reply(source._reply_cap, 0);
source._entrypoint->reply_signal_info(source._reply_cap, 0, 0);
source._reply_cap = Untyped_capability();
}