hw: turn Kernel_object into Genode::Constructible

Fix #3531
This commit is contained in:
Stefan Kalkowski 2019-10-16 15:07:11 +02:00 committed by Christian Helmuth
parent 3e3fb63863
commit f6435d91fc
30 changed files with 304 additions and 327 deletions

View File

@ -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,7 +47,7 @@ void Irq_session_component::sigh(Signal_context_capability cap)
_sig_cap = cap;
if (Kernel::new_irq((addr_t)&_kernel_object, _irq_number,
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());
}

View File

@ -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,12 +33,12 @@ class Genode::Irq_session_component : public Rpc_object<Irq_session>,
friend class List<Irq_session_component>;
Irq_args const _irq_args;
unsigned _irq_number;
Range_allocator &_irq_alloc;
Genode::uint8_t _kernel_object[sizeof(Kernel::User_irq)];
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);

View File

@ -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,
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);
}
}

View File

@ -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>

View File

@ -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);
}

View File

@ -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_ */

View File

@ -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); }
};

View File

@ -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_ */

View File

@ -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),
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();

View File

@ -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_ */

View File

@ -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;

View File

@ -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,
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;

View File

@ -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,
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); }
/****************

View File

@ -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();
}
};

View File

@ -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());
}

View File

@ -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:
/**

View File

@ -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();
}

View File

@ -77,7 +77,6 @@ class Hw::Address_space : public Genode::Address_space
Genode::addr_t _tt_phys; /* table phys addr */
Array * _tt_array = nullptr;
Table::Allocator & _tt_alloc; /* table allocator */
Kernel::Pd & _kernel_pd;
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,7 +133,7 @@ class Hw::Address_space : public Genode::Address_space
** Accessors **
***************/
Kernel::Pd & kernel_pd() { return _kernel_pd; }
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:

View File

@ -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);
}

View File

@ -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'

View File

@ -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();

View File

@ -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;

View File

@ -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)
{ }

View File

@ -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);

View File

@ -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?");
}

View File

@ -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),

View File

@ -28,7 +28,7 @@ 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),
if (!_kobj.create(_ds_addr, Capability_space::capid(handler),
cma().phys_addr(&_table)))
Genode::warning("Cannot instantiate vm kernel object, invalid signal context?");
}
@ -95,8 +95,7 @@ Vm_session_component::Vm_session_component(Rpc_entrypoint &ds_ep,
Region_map &region_map,
unsigned,
Trace::Source_registry &)
:
Ram_quota_guard(resources.ram_quota),
: 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()),

View File

@ -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),

View File

@ -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);
}

View File

@ -35,11 +35,11 @@ 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:
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 { }