mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-23 15:32:25 +00:00
parent
3e3fb63863
commit
f6435d91fc
@ -18,7 +18,6 @@
|
||||
/* core includes */
|
||||
#include <kernel/irq.h>
|
||||
#include <irq_root.h>
|
||||
#include <irq_args.h>
|
||||
#include <core_env.h>
|
||||
|
||||
/* base-internal includes */
|
||||
@ -35,10 +34,7 @@ unsigned Irq_session_component::_find_irq_number(const char * const args)
|
||||
|
||||
void Irq_session_component::ack_irq()
|
||||
{
|
||||
using Kernel::User_irq;
|
||||
if (!_sig_cap.valid()) { return; }
|
||||
User_irq * const kirq = reinterpret_cast<User_irq*>(&_kernel_object);
|
||||
Kernel::ack_irq(kirq);
|
||||
if (_kobj.constructed()) Kernel::ack_irq(*_kobj);
|
||||
}
|
||||
|
||||
|
||||
@ -51,8 +47,8 @@ void Irq_session_component::sigh(Signal_context_capability cap)
|
||||
|
||||
_sig_cap = cap;
|
||||
|
||||
if (Kernel::new_irq((addr_t)&_kernel_object, _irq_number,
|
||||
Capability_space::capid(_sig_cap)))
|
||||
if (!_kobj.create(_irq_number, _irq_args.trigger(), _irq_args.polarity(),
|
||||
Capability_space::capid(_sig_cap)))
|
||||
warning("invalid signal handler for IRQ ", _irq_number);
|
||||
}
|
||||
|
||||
@ -61,18 +57,16 @@ Irq_session_component::~Irq_session_component()
|
||||
{
|
||||
using namespace Kernel;
|
||||
|
||||
User_irq * kirq = reinterpret_cast<User_irq*>(&_kernel_object);
|
||||
_irq_alloc.free((void *)(addr_t)_irq_number);
|
||||
if (_sig_cap.valid())
|
||||
Kernel::delete_irq(kirq);
|
||||
}
|
||||
|
||||
|
||||
Irq_session_component::Irq_session_component(Range_allocator &irq_alloc,
|
||||
const char * const args)
|
||||
:
|
||||
_irq_number(Platform::irq(_find_irq_number(args))), _irq_alloc(irq_alloc),
|
||||
_is_msi(false), _address(0), _value(0)
|
||||
: _irq_args(args),
|
||||
_irq_number(Platform::irq(_irq_args.irq_number())),
|
||||
_irq_alloc(irq_alloc),
|
||||
_kobj(), _is_msi(false), _address(0), _value(0)
|
||||
{
|
||||
const long mmconf =
|
||||
Arg_string::find_arg(args, "device_config_phys").long_value(0);
|
||||
@ -89,8 +83,4 @@ Irq_session_component::Irq_session_component(Range_allocator &irq_alloc,
|
||||
error("unavailable interrupt ", _irq_number, " requested");
|
||||
throw Service_denied();
|
||||
}
|
||||
|
||||
Irq_args const irq_args(args);
|
||||
|
||||
Kernel::irq_mode(_irq_number, irq_args.trigger(), irq_args.polarity());
|
||||
}
|
||||
|
@ -19,6 +19,8 @@
|
||||
#include <util/list.h>
|
||||
#include <irq_session/capability.h>
|
||||
|
||||
#include <irq_args.h>
|
||||
#include <object.h>
|
||||
#include <kernel/irq.h>
|
||||
|
||||
namespace Genode { class Irq_session_component; }
|
||||
@ -31,13 +33,13 @@ class Genode::Irq_session_component : public Rpc_object<Irq_session>,
|
||||
|
||||
friend class List<Irq_session_component>;
|
||||
|
||||
unsigned _irq_number;
|
||||
Range_allocator &_irq_alloc;
|
||||
Genode::uint8_t _kernel_object[sizeof(Kernel::User_irq)];
|
||||
bool _is_msi;
|
||||
addr_t _address, _value;
|
||||
|
||||
Signal_context_capability _sig_cap { };
|
||||
Irq_args const _irq_args;
|
||||
unsigned _irq_number;
|
||||
Range_allocator & _irq_alloc;
|
||||
Kernel_object<Kernel::User_irq> _kobj;
|
||||
bool _is_msi;
|
||||
addr_t _address, _value;
|
||||
Signal_context_capability _sig_cap { };
|
||||
|
||||
unsigned _find_irq_number(const char * const args);
|
||||
|
||||
|
@ -31,6 +31,7 @@ namespace Kernel
|
||||
class Vm;
|
||||
class User_irq;
|
||||
using Native_utcb = Genode::Native_utcb;
|
||||
template <typename T> class Core_object_identity;
|
||||
|
||||
/**
|
||||
* Kernel names of the kernel calls
|
||||
@ -60,15 +61,14 @@ namespace Kernel
|
||||
constexpr Call_arg call_id_delete_obj() { return 122; }
|
||||
constexpr Call_arg call_id_cancel_thread_blocking() { return 123; }
|
||||
constexpr Call_arg call_id_new_core_thread() { return 124; }
|
||||
constexpr Call_arg call_id_irq_mode() { return 125; }
|
||||
|
||||
/**
|
||||
* Invalidate TLB entries for the `pd` in region `addr`, `sz`
|
||||
*/
|
||||
inline void invalidate_tlb(Pd * const pd, addr_t const addr,
|
||||
inline void invalidate_tlb(Pd & pd, addr_t const addr,
|
||||
size_t const sz)
|
||||
{
|
||||
call(call_id_invalidate_tlb(), (Call_arg)pd, (Call_arg)addr,
|
||||
call(call_id_invalidate_tlb(), (Call_arg)&pd, (Call_arg)addr,
|
||||
(Call_arg)sz);
|
||||
}
|
||||
|
||||
@ -79,9 +79,9 @@ namespace Kernel
|
||||
* \param thread kernel object of the targeted thread
|
||||
* \param quota new CPU quota value
|
||||
*/
|
||||
inline void thread_quota(Kernel::Thread * const thread, size_t const quota)
|
||||
inline void thread_quota(Kernel::Thread & thread, size_t const quota)
|
||||
{
|
||||
call(call_id_thread_quota(), (Call_arg)thread, (Call_arg)quota);
|
||||
call(call_id_thread_quota(), (Call_arg)&thread, (Call_arg)quota);
|
||||
}
|
||||
|
||||
|
||||
@ -104,9 +104,9 @@ namespace Kernel
|
||||
* continue the execution of a thread no matter what state the thread is
|
||||
* in.
|
||||
*/
|
||||
inline void pause_thread(Thread * const thread)
|
||||
inline void pause_thread(Thread & thread)
|
||||
{
|
||||
call(call_id_pause_thread(), (Call_arg)thread);
|
||||
call(call_id_pause_thread(), (Call_arg)&thread);
|
||||
}
|
||||
|
||||
|
||||
@ -115,9 +115,9 @@ namespace Kernel
|
||||
*
|
||||
* \param thread pointer to thread kernel object
|
||||
*/
|
||||
inline void resume_thread(Thread * const thread)
|
||||
inline void resume_thread(Thread & thread)
|
||||
{
|
||||
call(call_id_resume_thread(), (Call_arg)thread);
|
||||
call(call_id_resume_thread(), (Call_arg)&thread);
|
||||
}
|
||||
|
||||
|
||||
@ -132,11 +132,11 @@ namespace Kernel
|
||||
* \retval 0 suceeded
|
||||
* \retval !=0 failed
|
||||
*/
|
||||
inline int start_thread(Thread * const thread, unsigned const cpu_id,
|
||||
Pd * const pd, Native_utcb * const utcb)
|
||||
inline int start_thread(Thread & thread, unsigned const cpu_id,
|
||||
Pd & pd, Native_utcb & utcb)
|
||||
{
|
||||
return call(call_id_start_thread(), (Call_arg)thread, cpu_id,
|
||||
(Call_arg)pd, (Call_arg)utcb);
|
||||
return call(call_id_start_thread(), (Call_arg)&thread, cpu_id,
|
||||
(Call_arg)&pd, (Call_arg)&utcb);
|
||||
}
|
||||
|
||||
|
||||
@ -155,9 +155,9 @@ namespace Kernel
|
||||
* limit the time a parent waits for a server when closing a session
|
||||
* of one of its children.
|
||||
*/
|
||||
inline void cancel_thread_blocking(Thread * const thread)
|
||||
inline void cancel_thread_blocking(Thread & thread)
|
||||
{
|
||||
call(call_id_cancel_thread_blocking(), (Call_arg)thread);
|
||||
call(call_id_cancel_thread_blocking(), (Call_arg)&thread);
|
||||
}
|
||||
|
||||
|
||||
@ -167,10 +167,10 @@ namespace Kernel
|
||||
* \param thread pointer to thread kernel object
|
||||
* \param signal_context_id capability id of the page-fault handler
|
||||
*/
|
||||
inline void thread_pager(Thread * const thread,
|
||||
capid_t const signal_context_id)
|
||||
inline void thread_pager(Thread & thread,
|
||||
capid_t const signal_context_id)
|
||||
{
|
||||
call(call_id_thread_pager(), (Call_arg)thread, signal_context_id);
|
||||
call(call_id_thread_pager(), (Call_arg)&thread, signal_context_id);
|
||||
}
|
||||
|
||||
|
||||
@ -179,9 +179,9 @@ namespace Kernel
|
||||
*
|
||||
* \param vm pointer to vm kernel object
|
||||
*/
|
||||
inline void run_vm(Vm * const vm)
|
||||
inline void run_vm(Vm & vm)
|
||||
{
|
||||
call(call_id_run_vm(), (Call_arg) vm);
|
||||
call(call_id_run_vm(), (Call_arg) &vm);
|
||||
}
|
||||
|
||||
|
||||
@ -190,33 +190,9 @@ namespace Kernel
|
||||
*
|
||||
* \param vm pointer to vm kernel object
|
||||
*/
|
||||
inline void pause_vm(Vm * const vm)
|
||||
inline void pause_vm(Vm & vm)
|
||||
{
|
||||
call(call_id_pause_vm(), (Call_arg) vm);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an interrupt object
|
||||
*
|
||||
* \param p memory donation for the irq object
|
||||
* \param irq_nr interrupt number
|
||||
* \param signal_context_id capability id of the signal context
|
||||
*/
|
||||
inline int new_irq(addr_t const p, unsigned irq_nr,
|
||||
capid_t signal_context_id)
|
||||
{
|
||||
return call(call_id_new_irq(), (Call_arg) p, irq_nr, signal_context_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set trigger/polaruty of IRQ
|
||||
* \param irq_nr interrupt number
|
||||
* \param trigger low or edge
|
||||
* \param polarity low or high
|
||||
*/
|
||||
inline void irq_mode(unsigned irq_nr, unsigned trigger, unsigned polarity)
|
||||
{
|
||||
call(call_id_irq_mode(), irq_nr, trigger, polarity);
|
||||
call(call_id_pause_vm(), (Call_arg) &vm);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -224,40 +200,9 @@ namespace Kernel
|
||||
*
|
||||
* \param irq pointer to interrupt kernel object
|
||||
*/
|
||||
inline void ack_irq(User_irq * const irq)
|
||||
inline void ack_irq(User_irq & irq)
|
||||
{
|
||||
call(call_id_ack_irq(), (Call_arg) irq);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destruct an interrupt object
|
||||
*
|
||||
* \param irq pointer to interrupt kernel object
|
||||
*/
|
||||
inline void delete_irq(User_irq * const irq)
|
||||
{
|
||||
call(call_id_delete_irq(), (Call_arg) irq);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new object identity for a thread
|
||||
*
|
||||
* \param dst memory donation for the new object
|
||||
* \param cap capability id of the targeted thread
|
||||
*/
|
||||
inline capid_t new_obj(void * const dst, capid_t const cap)
|
||||
{
|
||||
return call(call_id_new_obj(), (Call_arg)dst, (Call_arg)cap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy an object identity
|
||||
*
|
||||
* \param dst pointer to the object identity object
|
||||
*/
|
||||
inline void delete_obj(void * const dst)
|
||||
{
|
||||
call(call_id_delete_obj(), (Call_arg)dst);
|
||||
call(call_id_ack_irq(), (Call_arg) &irq);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,9 +15,6 @@
|
||||
#ifndef _CORE__KERNEL__IPC_NODE_H_
|
||||
#define _CORE__KERNEL__IPC_NODE_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <util/construct_at.h>
|
||||
|
||||
/* base-local includes */
|
||||
#include <base/internal/native_utcb.h>
|
||||
|
||||
|
@ -30,3 +30,14 @@ Kernel::Irq::Pool &Kernel::User_irq::_pool()
|
||||
static Irq::Pool p;
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
Kernel::User_irq::User_irq(unsigned const irq,
|
||||
Genode::Irq_session::Trigger trigger,
|
||||
Genode::Irq_session::Polarity polarity,
|
||||
Signal_context & context)
|
||||
: Irq(irq, _pool()), _context(context)
|
||||
{
|
||||
disable();
|
||||
cpu_pool().executing_cpu().pic().irq_mode(_irq_nr, trigger, polarity);
|
||||
}
|
||||
|
@ -135,8 +135,10 @@ class Kernel::User_irq : public Kernel::Irq, public Kernel::Object
|
||||
/**
|
||||
* Construct object that signals interrupt 'irq' via signal 'context'
|
||||
*/
|
||||
User_irq(unsigned const irq, Signal_context &context)
|
||||
: Irq(irq, _pool()), _context(context) { disable(); }
|
||||
User_irq(unsigned const irq,
|
||||
Genode::Irq_session::Trigger trigger,
|
||||
Genode::Irq_session::Polarity polarity,
|
||||
Signal_context & context);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
@ -157,6 +159,33 @@ class Kernel::User_irq : public Kernel::Irq, public Kernel::Object
|
||||
*/
|
||||
static User_irq * object(unsigned const irq) {
|
||||
return dynamic_cast<User_irq*>(_pool().object(irq)); }
|
||||
|
||||
/**
|
||||
* Syscall to create user irq object
|
||||
*
|
||||
* \param irq reference to constructible object
|
||||
* \param nr interrupt number
|
||||
* \param trigger level or edge
|
||||
* \param polarity low or high
|
||||
* \param sig capability of signal context
|
||||
*/
|
||||
static capid_t syscall_create(Genode::Kernel_object<User_irq> & irq,
|
||||
unsigned nr,
|
||||
Genode::Irq_session::Trigger trigger,
|
||||
Genode::Irq_session::Polarity polarity,
|
||||
capid_t sig)
|
||||
{
|
||||
return call(call_id_new_irq(), (Call_arg)&irq, nr,
|
||||
(trigger << 2) | polarity, sig);
|
||||
}
|
||||
|
||||
/**
|
||||
* Syscall to delete user irq object
|
||||
*
|
||||
* \param irq reference to constructible object
|
||||
*/
|
||||
static void syscall_destroy(Genode::Kernel_object<User_irq> &irq) {
|
||||
call(call_id_delete_irq(), (Call_arg) &irq); }
|
||||
};
|
||||
|
||||
#endif /* _CORE__KERNEL__IRQ_H_ */
|
||||
|
@ -18,8 +18,10 @@
|
||||
#include <util/avl_tree.h>
|
||||
#include <util/bit_allocator.h>
|
||||
#include <util/list.h>
|
||||
#include <util/reconstructible.h>
|
||||
|
||||
/* core includes */
|
||||
#include <kernel/core_interface.h>
|
||||
#include <kernel/interface.h>
|
||||
#include <kernel/kernel.h>
|
||||
|
||||
@ -192,6 +194,13 @@ class Kernel::Core_object_identity : public Object_identity,
|
||||
Object_identity_reference(this, core_pd()) { }
|
||||
|
||||
capid_t core_capid() { return capid(); }
|
||||
|
||||
static capid_t syscall_create(Genode::Constructible<Core_object_identity<T>> & t,
|
||||
capid_t const cap) {
|
||||
return call(call_id_new_obj(), (Call_arg)&t, (Call_arg)cap); }
|
||||
|
||||
static void syscall_destroy(Genode::Constructible<Core_object_identity<T>> & t) {
|
||||
call(call_id_delete_obj(), (Call_arg)&t); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -19,9 +19,11 @@
|
||||
#include <hw/assert.h>
|
||||
#include <cpu.h>
|
||||
#include <kernel/core_interface.h>
|
||||
#include <kernel/object.h>
|
||||
#include <object.h>
|
||||
#include <translation_table.h>
|
||||
|
||||
#include <util/reconstructible.h>
|
||||
|
||||
namespace Genode {
|
||||
class Platform_pd;
|
||||
}
|
||||
@ -51,6 +53,7 @@ class Kernel::Pd : public Kernel::Object
|
||||
Genode::Platform_pd &_platform_pd;
|
||||
Capid_allocator _capid_alloc { };
|
||||
Object_identity_reference_tree _cap_tree { };
|
||||
bool _core_pd { false };
|
||||
|
||||
public:
|
||||
|
||||
@ -69,6 +72,12 @@ class Kernel::Pd : public Kernel::Object
|
||||
{
|
||||
capid_t invalid = _capid_alloc.alloc();
|
||||
assert(invalid == cap_id_invalid());
|
||||
|
||||
static bool first_pd = true;
|
||||
if (first_pd) {
|
||||
_core_pd = true;
|
||||
first_pd = false;
|
||||
}
|
||||
}
|
||||
|
||||
~Pd()
|
||||
@ -77,16 +86,16 @@ class Kernel::Pd : public Kernel::Object
|
||||
oir->~Object_identity_reference();
|
||||
}
|
||||
|
||||
static capid_t syscall_create(void * const dst,
|
||||
Hw::Page_table &tt,
|
||||
Genode::Platform_pd &pd)
|
||||
static capid_t syscall_create(Genode::Kernel_object<Pd> & p,
|
||||
Hw::Page_table & tt,
|
||||
Genode::Platform_pd & pd)
|
||||
{
|
||||
return call(call_id_new_pd(), (Call_arg)dst,
|
||||
return call(call_id_new_pd(), (Call_arg)&p,
|
||||
(Call_arg)&tt, (Call_arg)&pd);
|
||||
}
|
||||
|
||||
static void syscall_destroy(Pd * const pd) {
|
||||
call(call_id_delete_pd(), (Call_arg)pd); }
|
||||
static void syscall_destroy(Genode::Kernel_object<Pd> & p) {
|
||||
call(call_id_delete_pd(), (Call_arg)&p); }
|
||||
|
||||
/**
|
||||
* Check whether the given 'cpu' needs to do some maintainance
|
||||
@ -103,6 +112,13 @@ class Kernel::Pd : public Kernel::Object
|
||||
Hw::Page_table &translation_table() { return _table; }
|
||||
Capid_allocator &capid_alloc() { return _capid_alloc; }
|
||||
Object_identity_reference_tree &cap_tree() { return _cap_tree; }
|
||||
bool core_pd() const { return _core_pd; }
|
||||
};
|
||||
|
||||
|
||||
template<>
|
||||
inline Kernel::Core_object_identity<Kernel::Pd>::Core_object_identity(Kernel::Pd & pd)
|
||||
: Object_identity(pd),
|
||||
Object_identity_reference(this, pd.core_pd() ? pd : core_pd()) { }
|
||||
|
||||
#endif /* _CORE__KERNEL__PD_H_ */
|
||||
|
@ -55,7 +55,7 @@ Signal_context_killer::~Signal_context_killer() { cancel_waiting(); }
|
||||
|
||||
void Signal_context::_deliverable()
|
||||
{
|
||||
if (_submits) { _receiver->_add_deliverable(this); }
|
||||
if (_submits) { _receiver._add_deliverable(this); }
|
||||
}
|
||||
|
||||
|
||||
@ -118,16 +118,15 @@ int Signal_context::kill(Signal_context_killer * const k)
|
||||
Signal_context::~Signal_context()
|
||||
{
|
||||
if (_killer) { _killer->_signal_context_kill_failed(); }
|
||||
_receiver->_context_destructed(this);
|
||||
_receiver._context_destructed(this);
|
||||
}
|
||||
|
||||
|
||||
Signal_context::Signal_context(Signal_receiver * const r, addr_t const imprint)
|
||||
:
|
||||
_receiver(r),
|
||||
_imprint(imprint)
|
||||
Signal_context::Signal_context(Signal_receiver & r, addr_t const imprint)
|
||||
: _receiver(r),
|
||||
_imprint(imprint)
|
||||
{
|
||||
r->_add_context(this);
|
||||
r._add_context(this);
|
||||
}
|
||||
|
||||
|
||||
@ -164,7 +163,7 @@ void Signal_receiver::_listen()
|
||||
/* communicate signal data to handler */
|
||||
_handlers.dequeue([&] (Signal_handler::Fifo_element &elem) {
|
||||
auto const handler = &elem.object();
|
||||
handler->_receiver = 0;
|
||||
handler->_receiver = nullptr;
|
||||
handler->_receive_signal(&data, sizeof(data));
|
||||
});
|
||||
context->_delivered();
|
||||
|
@ -16,9 +16,10 @@
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/signal.h>
|
||||
#include <util/reconstructible.h>
|
||||
|
||||
#include <kernel/core_interface.h>
|
||||
#include <kernel/object.h>
|
||||
#include <object.h>
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
@ -160,7 +161,7 @@ class Kernel::Signal_context : public Kernel::Object
|
||||
|
||||
Fifo_element _deliver_fe { *this };
|
||||
Fifo_element _contexts_fe { *this };
|
||||
Signal_receiver * const _receiver;
|
||||
Signal_receiver & _receiver;
|
||||
addr_t const _imprint;
|
||||
Signal_context_killer * _killer { nullptr };
|
||||
unsigned _submits { 0 };
|
||||
@ -197,7 +198,7 @@ class Kernel::Signal_context : public Kernel::Object
|
||||
*
|
||||
* \throw Assign_to_receiver_failed
|
||||
*/
|
||||
Signal_context(Signal_receiver * const r, addr_t const imprint);
|
||||
Signal_context(Signal_receiver & r, addr_t const imprint);
|
||||
|
||||
/**
|
||||
* Submit the signal
|
||||
@ -233,12 +234,12 @@ class Kernel::Signal_context : public Kernel::Object
|
||||
*
|
||||
* \retval capability id of the new kernel object
|
||||
*/
|
||||
static capid_t syscall_create(void * p,
|
||||
Signal_receiver * const receiver,
|
||||
static capid_t syscall_create(Genode::Kernel_object<Signal_context> &c,
|
||||
Signal_receiver & receiver,
|
||||
addr_t const imprint)
|
||||
{
|
||||
return call(call_id_new_signal_context(), (Call_arg)p,
|
||||
(Call_arg)receiver, (Call_arg)imprint);
|
||||
return call(call_id_new_signal_context(), (Call_arg)&c,
|
||||
(Call_arg)&receiver, (Call_arg)imprint);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -246,8 +247,8 @@ class Kernel::Signal_context : public Kernel::Object
|
||||
*
|
||||
* \param context pointer to signal context kernel object
|
||||
*/
|
||||
static void syscall_destroy(Signal_context * const context) {
|
||||
call(call_id_delete_signal_context(), (Call_arg)context); }
|
||||
static void syscall_destroy(Genode::Kernel_object<Signal_context> &c) {
|
||||
call(call_id_delete_signal_context(), (Call_arg)&c); }
|
||||
};
|
||||
|
||||
class Kernel::Signal_receiver : public Kernel::Object
|
||||
@ -311,16 +312,16 @@ class Kernel::Signal_receiver : public Kernel::Object
|
||||
*
|
||||
* \retval capability id of the new kernel object
|
||||
*/
|
||||
static capid_t syscall_create(void * p) {
|
||||
return call(call_id_new_signal_receiver(), (Call_arg)p); }
|
||||
static capid_t syscall_create(Genode::Kernel_object<Signal_receiver> &r) {
|
||||
return call(call_id_new_signal_receiver(), (Call_arg)&r); }
|
||||
|
||||
/**
|
||||
* Syscall to destruct a signal receiver
|
||||
*
|
||||
* \param receiver pointer to signal receiver kernel object
|
||||
*/
|
||||
static void syscall_destroy(Signal_receiver * const receiver) {
|
||||
call(call_id_delete_signal_receiver(), (Call_arg)receiver); }
|
||||
static void syscall_destroy(Genode::Kernel_object<Signal_receiver> &r) {
|
||||
call(call_id_delete_signal_receiver(), (Call_arg)&r); }
|
||||
};
|
||||
|
||||
#endif /* _CORE__KERNEL__SIGNAL_RECEIVER_H_ */
|
||||
|
@ -15,7 +15,6 @@
|
||||
/* Genode includes */
|
||||
#include <base/thread_state.h>
|
||||
#include <cpu_session/cpu_session.h>
|
||||
#include <util/construct_at.h>
|
||||
|
||||
/* base-internal includes */
|
||||
#include <base/internal/unmanaged_singleton.h>
|
||||
@ -47,17 +46,17 @@ Thread::Tlb_invalidation::Tlb_invalidation(Thread & caller, Pd & pd,
|
||||
}
|
||||
|
||||
|
||||
Thread::Destroy::Destroy(Thread & caller, Thread & to_delete)
|
||||
Thread::Destroy::Destroy(Thread & caller, Genode::Kernel_object<Thread> & to_delete)
|
||||
: caller(caller), thread_to_destroy(to_delete)
|
||||
{
|
||||
thread_to_destroy._cpu->work_list().insert(&_le);
|
||||
thread_to_destroy->_cpu->work_list().insert(&_le);
|
||||
caller._become_inactive(AWAITS_RESTART);
|
||||
}
|
||||
|
||||
|
||||
void Thread::Destroy::execute()
|
||||
{
|
||||
thread_to_destroy.~Thread();
|
||||
thread_to_destroy.destruct();
|
||||
cpu_pool().executing_cpu().work_list().remove(&_le);
|
||||
caller._restart();
|
||||
}
|
||||
@ -193,28 +192,6 @@ size_t Thread::_core_to_kernel_quota(size_t const quota) const
|
||||
}
|
||||
|
||||
|
||||
void Thread::_call_new_thread()
|
||||
{
|
||||
void * const p = (void *)user_arg_1();
|
||||
unsigned const priority = user_arg_2();
|
||||
unsigned const quota = _core_to_kernel_quota(user_arg_3());
|
||||
char const * const label = (char *)user_arg_4();
|
||||
Core_object<Thread> * co =
|
||||
Genode::construct_at<Core_object<Thread> >(p, priority, quota, label);
|
||||
user_arg_0(co->core_capid());
|
||||
}
|
||||
|
||||
|
||||
void Thread::_call_new_core_thread()
|
||||
{
|
||||
void * const p = (void *)user_arg_1();
|
||||
char const * const label = (char *)user_arg_2();
|
||||
Core_object<Thread> * co =
|
||||
Genode::construct_at<Core_object<Thread> >(p, label);
|
||||
user_arg_0(co->core_capid());
|
||||
}
|
||||
|
||||
|
||||
void Thread::_call_thread_quota()
|
||||
{
|
||||
Thread * const thread = (Thread *)user_arg_1();
|
||||
@ -227,7 +204,7 @@ void Thread::_call_start_thread()
|
||||
/* lookup CPU */
|
||||
Cpu & cpu = cpu_pool().cpu(user_arg_2());
|
||||
user_arg_0(0);
|
||||
Thread &thread = *(Thread *)user_arg_1();
|
||||
Thread &thread = *(Thread*)user_arg_1();
|
||||
|
||||
assert(thread._state == AWAITS_START);
|
||||
|
||||
@ -338,7 +315,8 @@ void Thread::_call_yield_thread()
|
||||
|
||||
void Thread::_call_delete_thread()
|
||||
{
|
||||
Thread * to_delete = reinterpret_cast<Thread*>(user_arg_1());
|
||||
Genode::Kernel_object<Thread> & to_delete =
|
||||
*(Genode::Kernel_object<Thread>*)user_arg_1();
|
||||
|
||||
/**
|
||||
* Delete a thread immediately if it has no cpu assigned yet,
|
||||
@ -346,7 +324,7 @@ void Thread::_call_delete_thread()
|
||||
*/
|
||||
if (!to_delete->_cpu ||
|
||||
(to_delete->_cpu->id() == Cpu::executing_id() ||
|
||||
&to_delete->_cpu->scheduled_job() != to_delete)) {
|
||||
&to_delete->_cpu->scheduled_job() != &*to_delete)) {
|
||||
_call_delete<Thread>();
|
||||
return;
|
||||
}
|
||||
@ -354,7 +332,7 @@ void Thread::_call_delete_thread()
|
||||
/**
|
||||
* Construct a cross-cpu work item and send an IPI
|
||||
*/
|
||||
_destroy.construct(*this, *to_delete);
|
||||
_destroy.construct(*this, to_delete);
|
||||
to_delete->_cpu->trigger_ip_interrupt();
|
||||
}
|
||||
|
||||
@ -566,21 +544,19 @@ void Thread::_call_kill_signal_context()
|
||||
|
||||
void Thread::_call_new_irq()
|
||||
{
|
||||
Signal_context * const c = pd().cap_tree().find<Signal_context>(user_arg_3());
|
||||
Signal_context * const c = pd().cap_tree().find<Signal_context>(user_arg_4());
|
||||
if (!c) {
|
||||
Genode::raw(*this, ": invalid signal context for interrupt");
|
||||
user_arg_0(-1);
|
||||
return;
|
||||
}
|
||||
|
||||
new ((void *)user_arg_1()) User_irq(user_arg_2(), *c);
|
||||
user_arg_0(0);
|
||||
}
|
||||
Genode::Irq_session::Trigger trigger =
|
||||
(Genode::Irq_session::Trigger) (user_arg_3() & 0b1100);
|
||||
Genode::Irq_session::Polarity polarity =
|
||||
(Genode::Irq_session::Polarity) (user_arg_3() & 0b11);
|
||||
|
||||
void Thread::_call_irq_mode()
|
||||
{
|
||||
cpu_pool().executing_cpu().pic().irq_mode(user_arg_1(), user_arg_2(),
|
||||
user_arg_3());
|
||||
_call_new<User_irq>((unsigned)user_arg_2(), trigger, polarity, *c);
|
||||
}
|
||||
|
||||
|
||||
@ -601,17 +577,18 @@ void Thread::_call_new_obj()
|
||||
return;
|
||||
}
|
||||
|
||||
using Thread_identity = Core_object_identity<Thread>;
|
||||
Thread_identity * coi =
|
||||
Genode::construct_at<Thread_identity>((void *)user_arg_1(), *thread);
|
||||
using Thread_identity = Genode::Constructible<Core_object_identity<Thread>>;
|
||||
Thread_identity & coi = *(Thread_identity*)user_arg_1();
|
||||
coi.construct(*thread);
|
||||
user_arg_0(coi->core_capid());
|
||||
}
|
||||
|
||||
|
||||
void Thread::_call_delete_obj()
|
||||
{
|
||||
using Object = Core_object_identity<Thread>;
|
||||
reinterpret_cast<Object*>(user_arg_1())->~Object();
|
||||
using Thread_identity = Genode::Constructible<Core_object_identity<Thread>>;
|
||||
Thread_identity & coi = *(Thread_identity*)user_arg_1();
|
||||
coi.destruct();
|
||||
}
|
||||
|
||||
|
||||
@ -686,8 +663,14 @@ void Thread::_call()
|
||||
}
|
||||
/* switch over kernel calls that are restricted to core */
|
||||
switch (call_id) {
|
||||
case call_id_new_thread(): _call_new_thread(); return;
|
||||
case call_id_new_core_thread(): _call_new_core_thread(); return;
|
||||
case call_id_new_thread():
|
||||
_call_new<Thread>((unsigned) user_arg_2(),
|
||||
(unsigned) _core_to_kernel_quota(user_arg_3()),
|
||||
(char const *) user_arg_4());
|
||||
return;
|
||||
case call_id_new_core_thread():
|
||||
_call_new<Thread>((char const *) user_arg_2());
|
||||
return;
|
||||
case call_id_thread_quota(): _call_thread_quota(); return;
|
||||
case call_id_delete_thread(): _call_delete_thread(); return;
|
||||
case call_id_start_thread(): _call_start_thread(); return;
|
||||
@ -702,7 +685,7 @@ void Thread::_call()
|
||||
case call_id_delete_pd(): _call_delete<Pd>(); return;
|
||||
case call_id_new_signal_receiver(): _call_new<Signal_receiver>(); return;
|
||||
case call_id_new_signal_context():
|
||||
_call_new<Signal_context>((Signal_receiver*) user_arg_2(), user_arg_3());
|
||||
_call_new<Signal_context>(*(Signal_receiver*) user_arg_2(), user_arg_3());
|
||||
return;
|
||||
case call_id_delete_signal_context(): _call_delete<Signal_context>(); return;
|
||||
case call_id_delete_signal_receiver(): _call_delete<Signal_receiver>(); return;
|
||||
@ -712,7 +695,6 @@ void Thread::_call()
|
||||
case call_id_pause_vm(): _call_pause_vm(); return;
|
||||
case call_id_pause_thread(): _call_pause_thread(); return;
|
||||
case call_id_new_irq(): _call_new_irq(); return;
|
||||
case call_id_irq_mode(): _call_irq_mode(); return;
|
||||
case call_id_delete_irq(): _call_delete<Irq>(); return;
|
||||
case call_id_ack_irq(): _call_ack_irq(); return;
|
||||
case call_id_new_obj(): _call_new_obj(); return;
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include <kernel/inter_processor_work.h>
|
||||
#include <kernel/signal_receiver.h>
|
||||
#include <kernel/ipc_node.h>
|
||||
#include <kernel/object.h>
|
||||
#include <object.h>
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
@ -89,10 +89,12 @@ class Kernel::Thread
|
||||
*/
|
||||
struct Destroy : Inter_processor_work
|
||||
{
|
||||
Thread & caller; /* the caller gets blocked till the end */
|
||||
Thread & thread_to_destroy; /* thread to be destroyed */
|
||||
using Kthread = Genode::Kernel_object<Thread>;
|
||||
|
||||
Destroy(Thread & caller, Thread & to_destroy);
|
||||
Thread & caller; /* the caller gets blocked till the end */
|
||||
Kthread & thread_to_destroy; /* thread to be destroyed */
|
||||
|
||||
Destroy(Thread & caller, Kthread & to_destroy);
|
||||
|
||||
/************************************
|
||||
** Inter_processor_work interface **
|
||||
@ -241,18 +243,19 @@ class Kernel::Thread
|
||||
template <typename T, typename... ARGS>
|
||||
void _call_new(ARGS &&... args)
|
||||
{
|
||||
using Object = Core_object<T>;
|
||||
void * dst = (void *)user_arg_1();
|
||||
Object * o = Genode::construct_at<Object>(dst, args...);
|
||||
user_arg_0(o->core_capid());
|
||||
Genode::Kernel_object<T> & kobj =
|
||||
*(Genode::Kernel_object<T>*)user_arg_1();
|
||||
kobj.construct(args...);
|
||||
user_arg_0(kobj->core_capid());
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void _call_delete()
|
||||
{
|
||||
using Object = Core_object<T>;
|
||||
reinterpret_cast<Object*>(user_arg_1())->~Object();
|
||||
Genode::Kernel_object<T> & kobj =
|
||||
*(Genode::Kernel_object<T>*)user_arg_1();
|
||||
kobj.destruct();
|
||||
}
|
||||
|
||||
|
||||
@ -334,11 +337,12 @@ class Kernel::Thread
|
||||
*
|
||||
* \retval capability id of the new kernel object
|
||||
*/
|
||||
static capid_t syscall_create(void * const p, unsigned const priority,
|
||||
size_t const quota,
|
||||
char const * const label)
|
||||
static capid_t syscall_create(Genode::Kernel_object<Thread> & t,
|
||||
unsigned const priority,
|
||||
size_t const quota,
|
||||
char const * const label)
|
||||
{
|
||||
return call(call_id_new_thread(), (Call_arg)p, (Call_arg)priority,
|
||||
return call(call_id_new_thread(), (Call_arg)&t, (Call_arg)priority,
|
||||
(Call_arg)quota, (Call_arg)label);
|
||||
}
|
||||
|
||||
@ -350,9 +354,10 @@ class Kernel::Thread
|
||||
*
|
||||
* \retval capability id of the new kernel object
|
||||
*/
|
||||
static capid_t syscall_create(void * const p, char const * const label)
|
||||
static capid_t syscall_create(Genode::Kernel_object<Thread> & t,
|
||||
char const * const label)
|
||||
{
|
||||
return call(call_id_new_core_thread(), (Call_arg)p,
|
||||
return call(call_id_new_core_thread(), (Call_arg)&t,
|
||||
(Call_arg)label);
|
||||
}
|
||||
|
||||
@ -361,8 +366,8 @@ class Kernel::Thread
|
||||
*
|
||||
* \param thread pointer to thread kernel object
|
||||
*/
|
||||
static void syscall_destroy(Thread * thread) {
|
||||
call(call_id_delete_thread(), (Call_arg)thread); }
|
||||
static void syscall_destroy(Genode::Kernel_object<Thread> & t) {
|
||||
call(call_id_delete_thread(), (Call_arg)&t); }
|
||||
|
||||
void print(Genode::Output &out) const;
|
||||
|
||||
|
@ -84,11 +84,12 @@ class Kernel::Vm : public Cpu_job,
|
||||
*
|
||||
* \retval cap id when successful, otherwise invalid cap id
|
||||
*/
|
||||
static capid_t syscall_create(void * const dst, void * const state,
|
||||
capid_t const signal_context_id,
|
||||
void * const table)
|
||||
static capid_t syscall_create(Genode::Kernel_object<Vm> & vm,
|
||||
void * const state,
|
||||
capid_t const signal_context_id,
|
||||
void * const table)
|
||||
{
|
||||
return call(call_id_new_vm(), (Call_arg)dst, (Call_arg)state,
|
||||
return call(call_id_new_vm(), (Call_arg)&vm, (Call_arg)state,
|
||||
(Call_arg)table, signal_context_id);
|
||||
}
|
||||
|
||||
@ -99,8 +100,8 @@ class Kernel::Vm : public Cpu_job,
|
||||
*
|
||||
* \retval 0 when successful, otherwise !=0
|
||||
*/
|
||||
static void syscall_destroy(Vm * const vm) {
|
||||
call(call_id_delete_vm(), (Call_arg) vm); }
|
||||
static void syscall_destroy(Genode::Kernel_object<Vm> & vm) {
|
||||
call(call_id_delete_vm(), (Call_arg) &vm); }
|
||||
|
||||
|
||||
/****************
|
||||
|
@ -15,7 +15,7 @@
|
||||
#define _CORE__OBJECT_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <util/construct_at.h>
|
||||
#include <util/reconstructible.h>
|
||||
|
||||
/* base-internal includes */
|
||||
#include <base/internal/capability_space.h>
|
||||
@ -35,13 +35,8 @@ namespace Genode {
|
||||
|
||||
|
||||
template <typename T>
|
||||
class Genode::Kernel_object
|
||||
class Genode::Kernel_object : public Genode::Constructible<Kernel::Core_object<T>>
|
||||
{
|
||||
private:
|
||||
|
||||
uint8_t _data[sizeof(Kernel::Core_object<T>)]
|
||||
__attribute__((aligned(sizeof(addr_t))));
|
||||
|
||||
protected:
|
||||
|
||||
Untyped_capability _cap { };
|
||||
@ -55,15 +50,17 @@ class Genode::Kernel_object
|
||||
*/
|
||||
template <typename... ARGS>
|
||||
Kernel_object(bool syscall, ARGS &&... args)
|
||||
: _cap(Capability_space::import(syscall ? T::syscall_create(&_data, args...)
|
||||
: _cap(Capability_space::import(syscall ? T::syscall_create(*this, args...)
|
||||
: Kernel::cap_id_invalid()))
|
||||
{
|
||||
if (!syscall) construct_at<T>(&_data, args...);
|
||||
if (!syscall) Genode::Constructible<Kernel::Core_object<T>>::construct(args...);
|
||||
}
|
||||
|
||||
~Kernel_object() { T::syscall_destroy(kernel_object()); }
|
||||
|
||||
T * kernel_object() { return reinterpret_cast<T*>(_data); }
|
||||
~Kernel_object()
|
||||
{
|
||||
if (Genode::Constructible<Kernel::Core_object<T>>::constructed())
|
||||
T::syscall_destroy(*this);
|
||||
}
|
||||
|
||||
Untyped_capability cap() { return _cap; }
|
||||
|
||||
@ -73,8 +70,10 @@ class Genode::Kernel_object
|
||||
template <typename... ARGS>
|
||||
bool create(ARGS &&... args)
|
||||
{
|
||||
if (_cap.valid()) return false;
|
||||
_cap = Capability_space::import(T::syscall_create(&_data, args...));
|
||||
if (Genode::Constructible<Kernel::Core_object<T>>::constructed())
|
||||
return false;
|
||||
|
||||
_cap = Capability_space::import(T::syscall_create(*this, args...));
|
||||
return _cap.valid();
|
||||
}
|
||||
};
|
||||
|
@ -53,12 +53,12 @@ void Pager_object::wake_up()
|
||||
if (pt) pt->restart();
|
||||
}
|
||||
|
||||
void Pager_object::start_paging(Kernel::Signal_receiver * receiver)
|
||||
void Pager_object::start_paging(Kernel_object<Kernel::Signal_receiver> & receiver)
|
||||
{
|
||||
using Object = Kernel_object<Kernel::Signal_context>;
|
||||
using Entry = Object_pool<Pager_object>::Entry;
|
||||
|
||||
create(receiver, (unsigned long)this);
|
||||
create(*receiver, (unsigned long)this);
|
||||
Entry::cap(Object::_cap);
|
||||
}
|
||||
|
||||
@ -103,13 +103,13 @@ void Pager_entrypoint::dissolve(Pager_object &o)
|
||||
|
||||
Pager_entrypoint::Pager_entrypoint(Rpc_cap_factory &)
|
||||
: Thread_deprecated<PAGER_EP_STACK_SIZE>("pager_ep"),
|
||||
Kernel_object<Kernel::Signal_receiver>(true)
|
||||
_kobj(true)
|
||||
{ start(); }
|
||||
|
||||
|
||||
Pager_capability Pager_entrypoint::manage(Pager_object &o)
|
||||
{
|
||||
o.start_paging(kernel_object());
|
||||
o.start_paging(_kobj);
|
||||
insert(&o);
|
||||
return reinterpret_cap_cast<Pager_object>(o.cap());
|
||||
}
|
||||
|
@ -157,7 +157,7 @@ class Genode::Pager_object : private Object_pool<Pager_object>::Entry,
|
||||
*
|
||||
* \param receiver signal receiver that receives the page faults
|
||||
*/
|
||||
void start_paging(Kernel::Signal_receiver * receiver);
|
||||
void start_paging(Kernel_object<Kernel::Signal_receiver> & receiver);
|
||||
|
||||
/**
|
||||
* Called when a page-fault finally could not be resolved
|
||||
@ -195,9 +195,12 @@ class Genode::Pager_object : private Object_pool<Pager_object>::Entry,
|
||||
|
||||
class Genode::Pager_entrypoint : public Object_pool<Pager_object>,
|
||||
public Thread_deprecated<PAGER_EP_STACK_SIZE>,
|
||||
private Kernel_object<Kernel::Signal_receiver>,
|
||||
private Ipc_pager
|
||||
{
|
||||
private:
|
||||
|
||||
Kernel_object<Kernel::Signal_receiver> _kobj;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
|
@ -69,26 +69,29 @@ void Hw::Address_space::flush(addr_t virt, size_t size, Core_local_addr)
|
||||
|
||||
try {
|
||||
_tt.remove_translation(virt, size, _tt_alloc);
|
||||
Kernel::invalidate_tlb(&_kernel_pd, virt, size);
|
||||
Kernel::invalidate_tlb(*_kobj, virt, size);
|
||||
} catch(...) {
|
||||
error("tried to remove invalid region!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Hw::Address_space::Address_space(Kernel::Pd & pd, Page_table & tt,
|
||||
Page_table::Allocator & tt_alloc)
|
||||
: _tt(tt), _tt_phys(Platform::core_page_table()),
|
||||
_tt_alloc(tt_alloc), _kernel_pd(pd) { }
|
||||
Hw::Address_space::Address_space(Page_table & tt,
|
||||
Page_table::Allocator & tt_alloc,
|
||||
Platform_pd & pd)
|
||||
: _tt(tt),
|
||||
_tt_phys(Platform::core_page_table()),
|
||||
_tt_alloc(tt_alloc),
|
||||
_kobj(false, *(Page_table*)translation_table_phys(), pd) {}
|
||||
|
||||
|
||||
Hw::Address_space::Address_space(Kernel::Pd & pd)
|
||||
Hw::Address_space::Address_space(Platform_pd & pd)
|
||||
: _tt(*construct_at<Page_table>(_table_alloc(), *((Page_table*)Hw::Mm::core_page_tables().base))),
|
||||
_tt_phys((addr_t)_cma().phys_addr(&_tt)),
|
||||
_tt_array(new (_cma()) Array([this] (void * virt) {
|
||||
return (addr_t)_cma().phys_addr(virt);})),
|
||||
_tt_alloc(_tt_array->alloc()),
|
||||
_kernel_pd(pd) { }
|
||||
_kobj(true, *(Page_table*)translation_table_phys(), pd) { }
|
||||
|
||||
|
||||
Hw::Address_space::~Address_space()
|
||||
@ -142,20 +145,13 @@ void Platform_pd::assign_parent(Native_capability parent)
|
||||
|
||||
Platform_pd::Platform_pd(Page_table & tt,
|
||||
Page_table::Allocator & alloc)
|
||||
:
|
||||
Hw::Address_space(*kernel_object(), tt, alloc),
|
||||
Kernel_object<Kernel::Pd>(false, *(Page_table*)translation_table_phys(), *this),
|
||||
_label("core")
|
||||
{ }
|
||||
: Hw::Address_space(tt, alloc, *this), _label("core") { }
|
||||
|
||||
|
||||
Platform_pd::Platform_pd(Allocator &, char const *label)
|
||||
:
|
||||
Hw::Address_space(*kernel_object()),
|
||||
Kernel_object<Kernel::Pd>(true, *(Page_table*)translation_table_phys(), *this),
|
||||
_label(label)
|
||||
: Hw::Address_space(*this), _label(label)
|
||||
{
|
||||
if (!_cap.valid()) {
|
||||
if (!_kobj.cap().valid()) {
|
||||
error("failed to create kernel object");
|
||||
throw Service_denied();
|
||||
}
|
||||
|
@ -72,12 +72,11 @@ class Hw::Address_space : public Genode::Address_space
|
||||
using Table = Hw::Page_table;
|
||||
using Array = Table::Allocator::Array<DEFAULT_TRANSLATION_TABLE_MAX>;
|
||||
|
||||
Genode::Lock _lock { }; /* table lock */
|
||||
Table & _tt; /* table virt addr */
|
||||
Genode::addr_t _tt_phys; /* table phys addr */
|
||||
Array * _tt_array = nullptr;
|
||||
Table::Allocator & _tt_alloc; /* table allocator */
|
||||
Kernel::Pd & _kernel_pd;
|
||||
Genode::Lock _lock { }; /* table lock */
|
||||
Table & _tt; /* table virt addr */
|
||||
Genode::addr_t _tt_phys; /* table phys addr */
|
||||
Array * _tt_array = nullptr;
|
||||
Table::Allocator & _tt_alloc; /* table allocator */
|
||||
|
||||
static inline Genode::Core_mem_allocator &_cma();
|
||||
|
||||
@ -85,25 +84,27 @@ class Hw::Address_space : public Genode::Address_space
|
||||
|
||||
protected:
|
||||
|
||||
Kernel_object<Kernel::Pd> _kobj;
|
||||
|
||||
/**
|
||||
* Core-specific constructor
|
||||
*
|
||||
* \param pd pointer to kernel's pd object
|
||||
* \param tt pointer to translation table
|
||||
* \param tt_alloc pointer to translation table allocator
|
||||
* \param tt reference to translation table
|
||||
* \param tt_alloc reference to translation table allocator
|
||||
* \param pd reference to platform pd object
|
||||
*/
|
||||
Address_space(Kernel::Pd & pd,
|
||||
Hw::Page_table & tt,
|
||||
Hw::Page_table::Allocator & tt_alloc);
|
||||
Address_space(Hw::Page_table & tt,
|
||||
Hw::Page_table::Allocator & tt_alloc,
|
||||
Platform_pd & pd);
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \param pd pointer to kernel's pd object
|
||||
* \param pd reference to platform pd object
|
||||
*/
|
||||
Address_space(Kernel::Pd & pd);
|
||||
Address_space(Platform_pd & pd);
|
||||
|
||||
~Address_space();
|
||||
|
||||
@ -132,9 +133,9 @@ class Hw::Address_space : public Genode::Address_space
|
||||
** Accessors **
|
||||
***************/
|
||||
|
||||
Kernel::Pd & kernel_pd() { return _kernel_pd; }
|
||||
Hw::Page_table & translation_table() { return _tt; }
|
||||
Genode::addr_t translation_table_phys() { return _tt_phys; }
|
||||
Kernel::Pd & kernel_pd() { return *_kobj; }
|
||||
Hw::Page_table & translation_table() { return _tt; }
|
||||
Genode::addr_t translation_table_phys() { return _tt_phys; }
|
||||
};
|
||||
|
||||
|
||||
@ -161,8 +162,7 @@ class Genode::Cap_space
|
||||
|
||||
|
||||
class Genode::Platform_pd : public Hw::Address_space,
|
||||
private Cap_space,
|
||||
private Kernel_object<Kernel::Pd>
|
||||
private Cap_space
|
||||
{
|
||||
private:
|
||||
|
||||
|
@ -54,7 +54,7 @@ Platform_thread::~Platform_thread()
|
||||
void Platform_thread::quota(size_t const quota)
|
||||
{
|
||||
_quota = quota;
|
||||
Kernel::thread_quota(_kobj.kernel_object(), quota);
|
||||
Kernel::thread_quota(*_kobj, quota);
|
||||
}
|
||||
|
||||
|
||||
@ -158,8 +158,8 @@ int Platform_thread::start(void * const ip, void * const sp)
|
||||
}
|
||||
|
||||
/* initialize thread registers */
|
||||
_kobj.kernel_object()->regs->ip = reinterpret_cast<addr_t>(ip);
|
||||
_kobj.kernel_object()->regs->sp = reinterpret_cast<addr_t>(sp);
|
||||
_kobj->regs->ip = reinterpret_cast<addr_t>(ip);
|
||||
_kobj->regs->sp = reinterpret_cast<addr_t>(sp);
|
||||
|
||||
/* start executing new thread */
|
||||
if (!_pd) {
|
||||
@ -179,8 +179,7 @@ int Platform_thread::start(void * const ip, void * const sp)
|
||||
utcb.cap_add(Capability_space::capid(_pd->parent()));
|
||||
utcb.cap_add(Capability_space::capid(_utcb));
|
||||
}
|
||||
Kernel::start_thread(_kobj.kernel_object(), cpu, &_pd->kernel_pd(),
|
||||
_utcb_core_addr);
|
||||
Kernel::start_thread(*_kobj, cpu, _pd->kernel_pd(), *_utcb_core_addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -189,7 +188,7 @@ void Platform_thread::pager(Pager_object &pager)
|
||||
{
|
||||
using namespace Kernel;
|
||||
|
||||
thread_pager(_kobj.kernel_object(), Capability_space::capid(pager.cap()));
|
||||
thread_pager(*_kobj, Capability_space::capid(pager.cap()));
|
||||
_pager = &pager;
|
||||
}
|
||||
|
||||
@ -205,14 +204,14 @@ Genode::Pager_object &Platform_thread::pager()
|
||||
|
||||
Thread_state Platform_thread::state()
|
||||
{
|
||||
Thread_state bstate(*_kobj.kernel_object()->regs);
|
||||
Thread_state bstate(*_kobj->regs);
|
||||
return Thread_state(bstate);
|
||||
}
|
||||
|
||||
|
||||
void Platform_thread::state(Thread_state thread_state)
|
||||
{
|
||||
Cpu_state * cstate = static_cast<Cpu_state *>(&*_kobj.kernel_object()->regs);
|
||||
Cpu_state * cstate = static_cast<Cpu_state *>(&*_kobj->regs);
|
||||
*cstate = static_cast<Cpu_state>(thread_state);
|
||||
}
|
||||
|
||||
|
@ -122,7 +122,7 @@ namespace Genode {
|
||||
/**
|
||||
* Return information about current fault
|
||||
*/
|
||||
Kernel::Thread_fault fault_info() { return _kobj.kernel_object()->fault(); }
|
||||
Kernel::Thread_fault fault_info() { return _kobj->fault(); }
|
||||
|
||||
/**
|
||||
* Join a protection domain
|
||||
@ -150,7 +150,7 @@ namespace Genode {
|
||||
/**
|
||||
* Pause this thread
|
||||
*/
|
||||
void pause() { Kernel::pause_thread(_kobj.kernel_object()); }
|
||||
void pause() { Kernel::pause_thread(*_kobj); }
|
||||
|
||||
/**
|
||||
* Enable/disable single stepping
|
||||
@ -160,13 +160,13 @@ namespace Genode {
|
||||
/**
|
||||
* Resume this thread
|
||||
*/
|
||||
void resume() { Kernel::resume_thread(_kobj.kernel_object()); }
|
||||
void resume() { Kernel::resume_thread(*_kobj); }
|
||||
|
||||
/**
|
||||
* Cancel currently blocking operation
|
||||
*/
|
||||
void cancel_blocking() {
|
||||
Kernel::cancel_thread_blocking(_kobj.kernel_object()); }
|
||||
Kernel::cancel_thread_blocking(*_kobj); }
|
||||
|
||||
/**
|
||||
* Set CPU quota of the thread to 'quota'
|
||||
|
@ -36,7 +36,7 @@ void Pager_entrypoint::entry()
|
||||
if (cap.valid()) Kernel::ack_signal(Capability_space::capid(cap));
|
||||
|
||||
/* receive fault */
|
||||
if (Kernel::await_signal(Capability_space::capid(_cap))) continue;
|
||||
if (Kernel::await_signal(Capability_space::capid(_kobj.cap()))) continue;
|
||||
|
||||
Pager_object *po = *(Pager_object**)Thread::myself()->utcb()->data();
|
||||
cap = po->cap();
|
||||
|
@ -39,14 +39,18 @@ class Genode::Rpc_cap_factory
|
||||
/**
|
||||
* Kernel object placeholder held in a list
|
||||
*/
|
||||
struct Kobject : List<Kobject>::Element
|
||||
struct Kobject
|
||||
: List<Kobject>::Element
|
||||
{
|
||||
using Identity = Kernel::Core_object_identity<Kernel::Thread>;
|
||||
using O = Kernel::Core_object_identity<Kernel::Thread>;
|
||||
|
||||
Native_capability cap { };
|
||||
Constructible<O> kobj {};
|
||||
Native_capability cap;
|
||||
|
||||
uint8_t data[sizeof(Identity)]
|
||||
__attribute__((aligned(sizeof(addr_t))));
|
||||
Kobject(Native_capability ep)
|
||||
: cap(Capability_space::import(O::syscall_create(kobj, Capability_space::capid(ep)))) {}
|
||||
|
||||
void destruct() { O::syscall_destroy(kobj); }
|
||||
};
|
||||
|
||||
using Slab = Tslab<Kobject, get_page_size()>;
|
||||
@ -68,7 +72,6 @@ class Genode::Rpc_cap_factory
|
||||
Lock::Guard guard(_lock);
|
||||
|
||||
while (Kobject * obj = _list.first()) {
|
||||
Kernel::delete_obj(obj->data);
|
||||
_list.remove(obj);
|
||||
destroy(&_slab, obj);
|
||||
}
|
||||
@ -87,11 +90,8 @@ class Genode::Rpc_cap_factory
|
||||
Kobject * obj;
|
||||
if (!_slab.alloc(sizeof(Kobject), (void**)&obj))
|
||||
throw Allocator::Out_of_memory();
|
||||
construct_at<Kobject>(obj);
|
||||
construct_at<Kobject>(obj, ep);
|
||||
|
||||
/* create kernel object via syscall */
|
||||
Kernel::capid_t capid = Kernel::new_obj(obj->data, Capability_space::capid(ep));
|
||||
obj->cap = Capability_space::import(capid);
|
||||
if (!obj->cap.valid()) {
|
||||
raw("Invalid entrypoint ", (addr_t)Capability_space::capid(ep),
|
||||
" for allocating a capability!");
|
||||
@ -110,7 +110,7 @@ class Genode::Rpc_cap_factory
|
||||
|
||||
for (Kobject * obj = _list.first(); obj; obj = obj->next()) {
|
||||
if (obj->cap.data() == cap.data()) {
|
||||
Kernel::delete_obj(obj->data);
|
||||
obj->destruct();
|
||||
_list.remove(obj);
|
||||
destroy(&_slab, obj);
|
||||
return;
|
||||
|
@ -55,19 +55,21 @@ struct Genode::Signal_source_component : private Kernel_object<Kernel::Signal_re
|
||||
using Signal_source_pool::Entry::cap;
|
||||
|
||||
Signal_source_component()
|
||||
:
|
||||
Kernel_object<Kernel::Signal_receiver>(true),
|
||||
Signal_source_pool::Entry(Kernel_object<Kernel::Signal_receiver>::_cap)
|
||||
: 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; }
|
||||
|
||||
Kernel::Signal_receiver & signal_receiver() {
|
||||
return **static_cast<Kernel_object<Kernel::Signal_receiver>*>(this); }
|
||||
};
|
||||
|
||||
|
||||
Genode::Signal_context_component::Signal_context_component(Signal_source_component &s,
|
||||
addr_t const imprint)
|
||||
:
|
||||
Kernel_object<Kernel::Signal_context>(true, s.kernel_object(), imprint),
|
||||
Kernel_object<Kernel::Signal_context>(true, s.signal_receiver(), imprint),
|
||||
Signal_context_pool::Entry(Kernel_object<Kernel::Signal_context>::_cap)
|
||||
{ }
|
||||
|
||||
|
@ -44,6 +44,7 @@ void Vm::exception(Cpu & cpu)
|
||||
return;
|
||||
case Genode::Cpu_state::DATA_ABORT:
|
||||
_state->dfar = Cpu::Dfar::read();
|
||||
[[fallthrough]];
|
||||
default:
|
||||
pause();
|
||||
_context->submit(1);
|
||||
|
@ -20,8 +20,7 @@ using namespace Genode;
|
||||
|
||||
void Vm_session_component::_exception_handler(Signal_context_capability handler, Vcpu_id)
|
||||
{
|
||||
if (!create(_ds_addr, Capability_space::capid(handler), nullptr))
|
||||
{
|
||||
if (!_kobj.create(_ds_addr, Capability_space::capid(handler), nullptr)) {
|
||||
warning("Cannot instantiate vm kernel object twice,"
|
||||
"or invalid signal context?");
|
||||
}
|
||||
|
@ -33,8 +33,7 @@ class Genode::Vm_session_component
|
||||
:
|
||||
private Ram_quota_guard,
|
||||
private Cap_quota_guard,
|
||||
public Rpc_object<Vm_session, Vm_session_component>,
|
||||
private Kernel_object<Kernel::Vm>
|
||||
public Rpc_object<Vm_session, Vm_session_component>
|
||||
{
|
||||
private:
|
||||
|
||||
@ -49,6 +48,7 @@ class Genode::Vm_session_component
|
||||
Region_map &_region_map;
|
||||
Ram_dataspace_capability _ds_cap { };
|
||||
Region_map::Local_addr _ds_addr { 0 };
|
||||
Kernel_object<Kernel::Vm> _kobj {};
|
||||
|
||||
static size_t _ds_size() {
|
||||
return align_addr(sizeof(Cpu_state_modes),
|
||||
|
@ -28,8 +28,8 @@ static Core_mem_allocator & cma() {
|
||||
|
||||
void Vm_session_component::_exception_handler(Signal_context_capability handler, Vcpu_id)
|
||||
{
|
||||
if (!create(_ds_addr, Capability_space::capid(handler),
|
||||
cma().phys_addr(&_table)))
|
||||
if (!_kobj.create(_ds_addr, Capability_space::capid(handler),
|
||||
cma().phys_addr(&_table)))
|
||||
Genode::warning("Cannot instantiate vm kernel object, invalid signal context?");
|
||||
}
|
||||
|
||||
@ -95,16 +95,15 @@ Vm_session_component::Vm_session_component(Rpc_entrypoint &ds_ep,
|
||||
Region_map ®ion_map,
|
||||
unsigned,
|
||||
Trace::Source_registry &)
|
||||
:
|
||||
Ram_quota_guard(resources.ram_quota),
|
||||
Cap_quota_guard(resources.cap_quota),
|
||||
_ep(ds_ep),
|
||||
_constrained_md_ram_alloc(ram_alloc, _ram_quota_guard(), _cap_quota_guard()),
|
||||
_sliced_heap(_constrained_md_ram_alloc, region_map),
|
||||
_region_map(region_map),
|
||||
_table(*construct_at<Table>(_alloc_table())),
|
||||
_table_array(*(new (cma()) Array([this] (void * virt) {
|
||||
return (addr_t)cma().phys_addr(virt);})))
|
||||
: Ram_quota_guard(resources.ram_quota),
|
||||
Cap_quota_guard(resources.cap_quota),
|
||||
_ep(ds_ep),
|
||||
_constrained_md_ram_alloc(ram_alloc, _ram_quota_guard(), _cap_quota_guard()),
|
||||
_sliced_heap(_constrained_md_ram_alloc, region_map),
|
||||
_region_map(region_map),
|
||||
_table(*construct_at<Table>(_alloc_table())),
|
||||
_table_array(*(new (cma()) Array([this] (void * virt) {
|
||||
return (addr_t)cma().phys_addr(virt);})))
|
||||
{
|
||||
_ds_cap = _constrained_md_ram_alloc.alloc(_ds_size(), Genode::Cache_attribute::UNCACHED);
|
||||
|
||||
|
@ -39,8 +39,7 @@ class Genode::Vm_session_component
|
||||
private Ram_quota_guard,
|
||||
private Cap_quota_guard,
|
||||
public Rpc_object<Vm_session, Vm_session_component>,
|
||||
public Region_map_detach,
|
||||
private Kernel_object<Kernel::Vm>
|
||||
public Region_map_detach
|
||||
{
|
||||
private:
|
||||
|
||||
@ -64,6 +63,7 @@ class Genode::Vm_session_component
|
||||
Region_map::Local_addr _ds_addr { 0 };
|
||||
Table &_table;
|
||||
Array &_table_array;
|
||||
Kernel_object<Kernel::Vm> _kobj {};
|
||||
|
||||
static size_t _ds_size() {
|
||||
return align_addr(sizeof(Cpu_state_modes),
|
||||
|
@ -30,13 +30,11 @@ addr_t Vm_session_component::_alloc_ds()
|
||||
|
||||
void Vm_session_component::_run(Vcpu_id)
|
||||
{
|
||||
if (Kernel_object<Kernel::Vm>::_cap.valid())
|
||||
Kernel::run_vm(kernel_object());
|
||||
if (_kobj.constructed()) Kernel::run_vm(*_kobj);
|
||||
}
|
||||
|
||||
|
||||
void Vm_session_component::_pause(Vcpu_id)
|
||||
{
|
||||
if (Kernel_object<Kernel::Vm>::_cap.valid())
|
||||
Kernel::pause_vm(kernel_object());
|
||||
if (_kobj.constructed()) Kernel::pause_vm(*_kobj);
|
||||
}
|
||||
|
@ -35,12 +35,12 @@ class Genode::Vm_session_component
|
||||
:
|
||||
private Ram_quota_guard,
|
||||
private Cap_quota_guard,
|
||||
public Rpc_object<Vm_session, Vm_session_component>,
|
||||
private Kernel_object<Kernel::Vm>
|
||||
public Rpc_object<Vm_session, Vm_session_component>
|
||||
{
|
||||
private:
|
||||
|
||||
Vm_state _state;
|
||||
Kernel_object<Kernel::Vm> _kobj {};
|
||||
Vm_state _state;
|
||||
|
||||
public:
|
||||
|
||||
@ -68,22 +68,16 @@ class Genode::Vm_session_component
|
||||
|
||||
void _exception_handler(Signal_context_capability handler, Vcpu_id)
|
||||
{
|
||||
if (!create(&_state, Capability_space::capid(handler), nullptr))
|
||||
if (!_kobj.create(&_state, Capability_space::capid(handler), nullptr))
|
||||
warning("Cannot instantiate vm kernel object, "
|
||||
"invalid signal context?");
|
||||
}
|
||||
|
||||
void _run(Vcpu_id)
|
||||
{
|
||||
if (Kernel_object<Kernel::Vm>::_cap.valid())
|
||||
Kernel::run_vm(kernel_object());
|
||||
}
|
||||
void _run(Vcpu_id) {
|
||||
if (_kobj.constructed()) Kernel::run_vm(*_kobj); }
|
||||
|
||||
void _pause(Vcpu_id)
|
||||
{
|
||||
if (Kernel_object<Kernel::Vm>::_cap.valid())
|
||||
Kernel::pause_vm(kernel_object());
|
||||
}
|
||||
void _pause(Vcpu_id) {
|
||||
if (_kobj.constructed()) Kernel::pause_vm(*_kobj); }
|
||||
|
||||
void attach(Dataspace_capability, addr_t, Attach_attr) override { }
|
||||
void attach_pic(addr_t) override { }
|
||||
|
Loading…
Reference in New Issue
Block a user