genode/repos/base-hw/src/core/include/kernel/core_interface.h

402 lines
11 KiB
C++

/*
* \brief Parts of the kernel interface that are restricted to core
* \author Martin stein
* \date 2014-03-15
*/
/*
* Copyright (C) 2014 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _KERNEL__CORE_INTERFACE_H_
#define _KERNEL__CORE_INTERFACE_H_
/* base-hw includes */
#include <kernel/interface.h>
namespace Kernel
{
class Pd;
class Thread;
class Signal_receiver;
class Signal_context;
class Vm;
class User_irq;
addr_t mode_transition_base();
size_t mode_transition_size();
size_t thread_size();
size_t pd_size();
unsigned pd_alignment_log2();
size_t signal_context_size();
size_t signal_receiver_size();
/**
* Kernel names of the kernel calls
*/
constexpr Call_arg call_id_new_thread() { return 14; }
constexpr Call_arg call_id_delete_thread() { return 15; }
constexpr Call_arg call_id_start_thread() { return 16; }
constexpr Call_arg call_id_resume_thread() { return 17; }
constexpr Call_arg call_id_access_thread_regs() { return 18; }
constexpr Call_arg call_id_route_thread_event() { return 19; }
constexpr Call_arg call_id_update_pd() { return 20; }
constexpr Call_arg call_id_new_pd() { return 21; }
constexpr Call_arg call_id_delete_pd() { return 22; }
constexpr Call_arg call_id_new_signal_receiver() { return 23; }
constexpr Call_arg call_id_new_signal_context() { return 24; }
constexpr Call_arg call_id_delete_signal_context() { return 25; }
constexpr Call_arg call_id_delete_signal_receiver() { return 26; }
constexpr Call_arg call_id_new_vm() { return 27; }
constexpr Call_arg call_id_run_vm() { return 28; }
constexpr Call_arg call_id_pause_vm() { return 29; }
constexpr Call_arg call_id_pause_thread() { return 30; }
constexpr Call_arg call_id_delete_vm() { return 31; }
constexpr Call_arg call_id_new_irq() { return 32; }
constexpr Call_arg call_id_delete_irq() { return 33; }
constexpr Call_arg call_id_thread_quota() { return 34; }
constexpr Call_arg call_id_ack_irq() { return 35; }
/**
* Create a domain
*
* \param dst appropriate memory donation for the kernel object
* \param pd core local Platform_pd object
*
* \retval 0 when successful, otherwise !=0
*/
inline int long new_pd(void * const dst, Platform_pd * const pd)
{
return call(call_id_new_pd(), (Call_arg)dst, (Call_arg)pd);
}
/**
* Destruct a domain
*
* \param pd pointer to pd kernel object
*/
inline void delete_pd(Pd * const pd)
{
call(call_id_delete_pd(), (Call_arg)pd);
}
/**
* Update locally effective domain configuration to in-memory state
*
* \param pd pointer to pd kernel object
*
* Kernel and/or hardware may cache parts of a domain configuration. This
* function ensures that the in-memory state of the targeted domain gets
* CPU-locally effective.
*/
inline void update_pd(Pd * const pd)
{
call(call_id_update_pd(), (Call_arg)pd);
}
/**
* Create a thread
*
* \param p memory donation for the new kernel thread object
* \param priority scheduling priority of the new thread
* \param quota CPU quota of the new thread
* \param label debugging label of the new thread
*
* \retval >0 kernel name of the new thread
* \retval 0 failed
*/
inline unsigned new_thread(void * const p, unsigned const priority,
size_t const quota, char const * const label)
{
return call(call_id_new_thread(), (Call_arg)p, (Call_arg)priority,
(Call_arg)quota, (Call_arg)label);
}
/**
* Configure the CPU quota of a thread
*
* \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)
{
call(call_id_thread_quota(), (Call_arg)thread, (Call_arg)quota);
}
/**
* Pause execution of a specific thread
*
* \param thread pointer to thread kernel object
*/
inline void pause_thread(Thread * const thread)
{
call(call_id_pause_thread(), (Call_arg)thread);
}
/**
* Destruct a thread
*
* \param thread pointer to thread kernel object
*/
inline void delete_thread(Thread * const thread)
{
call(call_id_delete_thread(), (Call_arg)thread);
}
/**
* Start execution of a thread
*
* \param thread pointer to thread kernel object
* \param cpu_id kernel name of the targeted CPU
* \param pd pointer to pd kernel object
* \param utcb core local pointer to userland thread-context
*
* \retval 0 suceeded
* \retval !=0 failed
*/
inline int start_thread(Thread * const thread, unsigned const cpu_id,
Pd * const pd, Native_utcb * const utcb)
{
return call(call_id_start_thread(), (Call_arg)thread, cpu_id,
(Call_arg)pd, (Call_arg)utcb);
}
/**
* Cancel blocking of a thread if possible
*
* \param thread pointer to thread kernel object
*
* \return wether thread was in a cancelable blocking beforehand
*/
inline bool resume_thread(Thread * const thread)
{
return call(call_id_resume_thread(), (Call_arg)thread);
}
/**
* Set or unset the handler of an event that can be triggered by a thread
*
* \param thread pointer to thread kernel object
* \param event_id kernel name of the targeted thread event
* \param signal_context_id kernel name of the handlers signal context
*
* \retval 0 succeeded
* \retval -1 failed
*/
inline int route_thread_event(Thread * const thread,
unsigned const event_id,
unsigned const signal_context_id)
{
return call(call_id_route_thread_event(), (Call_arg)thread,
event_id, signal_context_id);
}
/**
* Access plain member variables of a kernel thread-object
*
* \param thread pointer to thread kernel object
* \param reads amount of read operations
* \param writes amount of write operations
* \param values base of the value buffer for all operations
*
* \return amount of undone operations according to the execution order
*
* Operations are executed in order of the appearance of the register names
* in the callers UTCB. If reads = 0, read_values is of no relevance. If
* writes = 0, write_values is of no relevance.
*
* Expected structure at the callers UTCB base:
*
* 0 * sizeof(addr_t): read register name #1
* ... ...
* (reads - 1) * sizeof(addr_t): read register name #reads
* (reads - 0) * sizeof(addr_t): write register name #1
* ... ...
* (reads + writes - 1) * sizeof(addr_t): write register name #writes
*
* Expected structure at values:
*
* 0 * sizeof(addr_t): read destination #1
* ... ...
* (reads - 1) * sizeof(addr_t): read destination #reads
* (reads - 0) * sizeof(addr_t): write value #1
* ... ...
* (reads + writes - 1) * sizeof(addr_t): write value #writes
*/
inline unsigned access_thread_regs(Thread * const thread,
unsigned const reads,
unsigned const writes,
addr_t * const values)
{
return call(call_id_access_thread_regs(), (Call_arg)thread,
reads, writes, (Call_arg)values);
}
/**
* Create a signal receiver
*
* \param p memory donation for the kernel signal-receiver object
*
* \retval >0 kernel name of the new signal receiver
* \retval 0 failed
*/
inline unsigned new_signal_receiver(addr_t const p)
{
return call(call_id_new_signal_receiver(), p);
}
/**
* Create a signal context and assign it to a signal receiver
*
* \param p memory donation for the kernel signal-context object
* \param receiver pointer to signal receiver kernel object
* \param imprint user label of the signal context
*
* \retval >0 kernel name of the new signal context
* \retval 0 failed
*/
inline unsigned new_signal_context(addr_t const p,
Signal_receiver * const receiver,
unsigned const imprint)
{
return call(call_id_new_signal_context(), p,
(Call_arg)receiver, imprint);
}
/**
* Destruct a signal context
*
* \param context pointer to signal context kernel object
*/
inline void delete_signal_context(Signal_context * const context)
{
call(call_id_delete_signal_context(), (Call_arg)context);
}
/**
* Destruct a signal receiver
*
* \param receiver pointer to signal receiver kernel object
*
* \retval 0 suceeded
* \retval -1 failed
*/
inline void delete_signal_receiver(Signal_receiver * const receiver)
{
call(call_id_delete_signal_receiver(), (Call_arg)receiver);
}
/**
* Create a virtual machine that is stopped initially
*
* \param dst memory donation for the VM object
* \param state location of the CPU state of the VM
* \param signal_context_id kernel name of the signal context for VM events
* \param table guest-physical to host-physical translation
* table pointer
*
* \retval 0 when successful, otherwise !=0
*
* Regaining of the supplied memory is not supported by now.
*/
inline int new_vm(void * const dst, void * const state,
unsigned const signal_context_id,
void * const table)
{
return call(call_id_new_vm(), (Call_arg)dst, (Call_arg)state,
(Call_arg)table, signal_context_id);
}
/**
* Execute a virtual-machine (again)
*
* \param vm pointer to vm kernel object
*
* \retval 0 when successful, otherwise !=0
*/
inline int run_vm(Vm * const vm)
{
return call(call_id_run_vm(), (Call_arg) vm);
}
/**
* Destruct a virtual-machine
*
* \param vm pointer to vm kernel object
*
* \retval 0 when successful, otherwise !=0
*/
inline int delete_vm(Vm * const vm)
{
return call(call_id_delete_vm(), (Call_arg) vm);
}
/**
* Stop execution of a virtual-machine
*
* \param vm pointer to vm kernel object
*
* \retval 0 when successful, otherwise !=0
*/
inline int pause_vm(Vm * const vm)
{
return 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 kernel name of the signal context
*/
inline int new_irq(addr_t const p, unsigned irq_nr,
unsigned signal_context_id)
{
return call(call_id_new_irq(), (Call_arg) p, irq_nr, signal_context_id);
}
/**
* Acknowledge interrupt
*
* \param irq pointer to interrupt kernel object
*/
inline void ack_irq(User_irq * const 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);
}
}
#endif /* _KERNEL__CORE_INTERFACE_H_ */