2014-03-15 01:26:53 +01:00
|
|
|
/*
|
|
|
|
* \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
|
|
|
|
{
|
2014-03-15 16:12:09 +01:00
|
|
|
addr_t mode_transition_base();
|
2014-03-15 01:26:53 +01:00
|
|
|
size_t mode_transition_size();
|
|
|
|
size_t thread_size();
|
|
|
|
size_t pd_size();
|
2014-03-15 16:07:30 +01:00
|
|
|
unsigned pd_alignment_log2();
|
2014-03-15 01:26:53 +01:00
|
|
|
size_t signal_context_size();
|
|
|
|
size_t signal_receiver_size();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Kernel names of the kernel calls
|
|
|
|
*/
|
2014-04-07 16:18:43 +02:00
|
|
|
constexpr Call_arg call_id_new_thread() { return 14; }
|
|
|
|
constexpr Call_arg call_id_bin_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_bin_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_bin_signal_context() { return 25; }
|
|
|
|
constexpr Call_arg call_id_bin_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; }
|
2015-02-19 14:50:27 +01:00
|
|
|
constexpr Call_arg call_id_bin_vm() { return 31; }
|
2014-03-15 01:26:53 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Create a domain
|
|
|
|
*
|
|
|
|
* \param dst appropriate memory donation for the kernel object
|
|
|
|
* \param pd core local Platform_pd object
|
|
|
|
*
|
|
|
|
* \retval >0 kernel name of the new domain
|
|
|
|
* \retval 0 failed
|
|
|
|
*/
|
2015-02-06 17:23:41 +01:00
|
|
|
inline unsigned long new_pd(void * const dst, Platform_pd * const pd)
|
2014-03-15 01:26:53 +01:00
|
|
|
{
|
|
|
|
return call(call_id_new_pd(), (Call_arg)dst, (Call_arg)pd);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Destruct a domain
|
|
|
|
*
|
|
|
|
* \param pd_id kernel name of the targeted domain
|
|
|
|
*
|
|
|
|
* \retval 0 succeeded
|
|
|
|
* \retval -1 failed
|
|
|
|
*/
|
|
|
|
inline int bin_pd(unsigned const pd_id)
|
|
|
|
{
|
|
|
|
return call(call_id_bin_pd(), pd_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Update locally effective domain configuration to in-memory state
|
|
|
|
*
|
|
|
|
* \param pd_id kernel name of the targeted domain
|
|
|
|
*
|
|
|
|
* Kernel and/or hardware may cache parts of a domain configuration. This
|
|
|
|
* function ensures that the in-memory state of the targeted domain gets
|
2014-10-10 16:13:52 +02:00
|
|
|
* CPU-locally effective.
|
2014-03-15 01:26:53 +01:00
|
|
|
*/
|
|
|
|
inline void update_pd(unsigned const pd_id)
|
|
|
|
{
|
|
|
|
call(call_id_update_pd(), pd_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create a thread
|
|
|
|
*
|
|
|
|
* \param p memory donation for the new kernel thread object
|
|
|
|
* \param priority scheduling priority of the new thread
|
2014-10-16 11:15:46 +02:00
|
|
|
* \param quota CPU-time quota of the new thread in milliseconds
|
2014-03-15 01:26:53 +01:00
|
|
|
* \param label debugging label of the new thread
|
|
|
|
*
|
|
|
|
* \retval >0 kernel name of the new thread
|
|
|
|
* \retval 0 failed
|
|
|
|
*/
|
2014-03-15 21:21:14 +01:00
|
|
|
inline unsigned new_thread(void * const p, unsigned const priority,
|
2014-10-16 11:15:46 +02:00
|
|
|
size_t const quota, char const * const label)
|
2014-03-15 01:26:53 +01:00
|
|
|
{
|
|
|
|
return call(call_id_new_thread(), (Call_arg)p, (Call_arg)priority,
|
2014-10-16 11:15:46 +02:00
|
|
|
(Call_arg)quota, (Call_arg)label);
|
2014-03-15 01:26:53 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-03-16 16:00:55 +01:00
|
|
|
/**
|
|
|
|
* Pause execution of a specific thread
|
|
|
|
*
|
|
|
|
* \param thread_id kernel name of the targeted thread
|
|
|
|
*/
|
|
|
|
inline void pause_thread(unsigned const thread_id)
|
|
|
|
{
|
|
|
|
call(call_id_pause_thread(), thread_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-03-15 01:26:53 +01:00
|
|
|
/**
|
|
|
|
* Destruct a thread
|
|
|
|
*
|
|
|
|
* \param thread_id kernel name of the targeted thread
|
|
|
|
*/
|
|
|
|
inline void bin_thread(unsigned const thread_id)
|
|
|
|
{
|
|
|
|
call(call_id_bin_thread(), thread_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Start execution of a thread
|
|
|
|
*
|
|
|
|
* \param thread_id kernel name of the targeted thread
|
2014-10-10 16:13:52 +02:00
|
|
|
* \param cpu_id kernel name of the targeted CPU
|
2014-03-15 01:26:53 +01:00
|
|
|
* \param pd_id kernel name of the targeted domain
|
|
|
|
* \param utcb core local pointer to userland thread-context
|
2014-12-11 16:09:00 +01:00
|
|
|
*
|
|
|
|
* \retval 0 suceeded
|
|
|
|
* \retval !=0 failed
|
2014-03-15 01:26:53 +01:00
|
|
|
*/
|
2014-12-11 16:09:00 +01:00
|
|
|
inline int start_thread(unsigned const thread_id, unsigned const cpu_id,
|
|
|
|
unsigned const pd_id, Native_utcb * const utcb)
|
2014-03-15 01:26:53 +01:00
|
|
|
{
|
2014-12-11 16:09:00 +01:00
|
|
|
return call(call_id_start_thread(), thread_id, cpu_id, pd_id,
|
|
|
|
(Call_arg)utcb);
|
2014-03-15 01:26:53 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-03-25 16:34:20 +01:00
|
|
|
/**
|
|
|
|
* Cancel blocking of a thread if possible
|
|
|
|
*
|
|
|
|
* \param thread_id kernel name of the targeted thread
|
|
|
|
*
|
|
|
|
* \return wether thread was in a cancelable blocking beforehand
|
|
|
|
*/
|
|
|
|
inline bool resume_thread(unsigned const thread_id)
|
|
|
|
{
|
|
|
|
return call(call_id_resume_thread(), thread_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-03-15 01:26:53 +01:00
|
|
|
/**
|
|
|
|
* Set or unset the handler of an event that can be triggered by a thread
|
|
|
|
*
|
|
|
|
* \param thread_id kernel name of the targeted thread
|
|
|
|
* \param event_id kernel name of the targeted thread event
|
|
|
|
* \param signal_context_id kernel name of the handlers signal context
|
2014-03-15 21:22:30 +01:00
|
|
|
*
|
|
|
|
* \retval 0 succeeded
|
|
|
|
* \retval -1 failed
|
2014-03-15 01:26:53 +01:00
|
|
|
*/
|
|
|
|
inline int route_thread_event(unsigned const thread_id,
|
|
|
|
unsigned const event_id,
|
|
|
|
unsigned const signal_context_id)
|
|
|
|
{
|
|
|
|
return call(call_id_route_thread_event(), thread_id,
|
|
|
|
event_id, signal_context_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Access plain member variables of a kernel thread-object
|
|
|
|
*
|
2014-03-16 11:57:01 +01:00
|
|
|
* \param thread_id kernel name of the targeted thread
|
|
|
|
* \param reads amount of read operations
|
|
|
|
* \param writes amount of write operations
|
|
|
|
* \param values base of the value buffer for all operations
|
2014-03-15 01:26:53 +01:00
|
|
|
*
|
2014-03-16 11:41:51 +01:00
|
|
|
* \return amount of undone operations according to the execution order
|
2014-03-15 01:26:53 +01:00
|
|
|
*
|
2014-03-16 11:41:51 +01:00
|
|
|
* 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.
|
2014-03-15 01:26:53 +01:00
|
|
|
*
|
|
|
|
* 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
|
|
|
|
*
|
2014-03-16 11:57:01 +01:00
|
|
|
* Expected structure at values:
|
2014-03-15 01:26:53 +01:00
|
|
|
*
|
2014-03-16 11:57:01 +01:00
|
|
|
* 0 * sizeof(addr_t): read destination #1
|
|
|
|
* ... ...
|
|
|
|
* (reads - 1) * sizeof(addr_t): read destination #reads
|
|
|
|
* (reads - 0) * sizeof(addr_t): write value #1
|
2014-03-15 01:26:53 +01:00
|
|
|
* ... ...
|
2014-03-16 11:57:01 +01:00
|
|
|
* (reads + writes - 1) * sizeof(addr_t): write value #writes
|
2014-03-15 01:26:53 +01:00
|
|
|
*/
|
2014-03-16 11:41:51 +01:00
|
|
|
inline unsigned access_thread_regs(unsigned const thread_id,
|
|
|
|
unsigned const reads,
|
|
|
|
unsigned const writes,
|
2014-03-16 11:57:01 +01:00
|
|
|
addr_t * const values)
|
2014-03-15 01:26:53 +01:00
|
|
|
{
|
|
|
|
return call(call_id_access_thread_regs(), thread_id, reads, writes,
|
2014-03-16 11:57:01 +01:00
|
|
|
(Call_arg)values);
|
2014-03-15 01:26:53 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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 kernel name of targeted signal receiver
|
|
|
|
* \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,
|
|
|
|
unsigned const receiver,
|
|
|
|
unsigned const imprint)
|
|
|
|
{
|
|
|
|
return call(call_id_new_signal_context(), p, receiver, imprint);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Destruct a signal context
|
|
|
|
*
|
|
|
|
* \param context kernel name of the targeted signal context
|
|
|
|
*
|
|
|
|
* \retval 0 suceeded
|
|
|
|
* \retval -1 failed
|
|
|
|
*/
|
|
|
|
inline int bin_signal_context(unsigned const context)
|
|
|
|
{
|
|
|
|
return call(call_id_bin_signal_context(), context);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Destruct a signal receiver
|
|
|
|
*
|
|
|
|
* \param receiver kernel name of the targeted signal receiver
|
|
|
|
*
|
|
|
|
* \retval 0 suceeded
|
|
|
|
* \retval -1 failed
|
|
|
|
*/
|
|
|
|
inline int bin_signal_receiver(unsigned const receiver)
|
|
|
|
{
|
|
|
|
return call(call_id_bin_signal_receiver(), receiver);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create a virtual machine that is stopped initially
|
|
|
|
*
|
|
|
|
* \param dst memory donation for the VM object
|
2014-10-10 16:13:52 +02:00
|
|
|
* \param state location of the CPU state of the VM
|
2014-03-15 01:26:53 +01:00
|
|
|
* \param signal_context_id kernel name of the signal context for VM events
|
2015-02-19 14:50:27 +01:00
|
|
|
* \param table guest-physical to host-physical translation
|
|
|
|
* table pointer
|
2014-03-15 01:26:53 +01:00
|
|
|
*
|
|
|
|
* \retval >0 kernel name of the new VM
|
|
|
|
* \retval 0 failed
|
|
|
|
*
|
|
|
|
* Regaining of the supplied memory is not supported by now.
|
|
|
|
*/
|
2014-03-16 12:39:32 +01:00
|
|
|
inline unsigned new_vm(void * const dst, void * const state,
|
2015-02-19 14:50:27 +01:00
|
|
|
unsigned const signal_context_id,
|
|
|
|
void * const table)
|
2014-03-15 01:26:53 +01:00
|
|
|
{
|
|
|
|
return call(call_id_new_vm(), (Call_arg)dst, (Call_arg)state,
|
2015-02-19 14:50:27 +01:00
|
|
|
(Call_arg)table, signal_context_id);
|
2014-03-15 01:26:53 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Execute a virtual-machine (again)
|
|
|
|
*
|
|
|
|
* \param vm_id kernel name of the targeted VM
|
2015-02-19 14:50:27 +01:00
|
|
|
*
|
|
|
|
* \retval 0 suceeded
|
|
|
|
* \retval -1 failed
|
2014-03-15 01:26:53 +01:00
|
|
|
*/
|
2015-02-19 14:50:27 +01:00
|
|
|
inline int run_vm(unsigned const vm_id)
|
2014-03-15 01:26:53 +01:00
|
|
|
{
|
2015-02-19 14:50:27 +01:00
|
|
|
return call(call_id_run_vm(), vm_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Destruct a virtual-machine
|
|
|
|
*
|
|
|
|
* \param vm_id kernel name of the targeted VM
|
|
|
|
*
|
|
|
|
* \retval 0 suceeded
|
|
|
|
* \retval -1 failed
|
|
|
|
*/
|
|
|
|
inline int bin_vm(unsigned const vm_id)
|
|
|
|
{
|
|
|
|
return call(call_id_bin_vm(), vm_id);
|
2014-03-15 01:26:53 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Stop execution of a virtual-machine
|
|
|
|
*
|
|
|
|
* \param vm_id kernel name of the targeted VM
|
2015-02-19 14:50:27 +01:00
|
|
|
*
|
|
|
|
* \retval 0 suceeded
|
|
|
|
* \retval -1 failed
|
2014-03-15 01:26:53 +01:00
|
|
|
*/
|
2015-02-19 14:50:27 +01:00
|
|
|
inline int pause_vm(unsigned const vm_id)
|
2014-03-15 01:26:53 +01:00
|
|
|
{
|
2015-02-19 14:50:27 +01:00
|
|
|
return call(call_id_pause_vm(), vm_id);
|
2014-03-15 01:26:53 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* _KERNEL__CORE_INTERFACE_H_ */
|