2012-05-30 18:13:09 +00:00
|
|
|
/*
|
2013-11-14 16:29:34 +00:00
|
|
|
* \brief Interface between kernel and userland
|
2012-05-30 18:13:09 +00:00
|
|
|
* \author Martin stein
|
|
|
|
* \date 2011-11-30
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2013-01-10 20:44:47 +00:00
|
|
|
* Copyright (C) 2011-2013 Genode Labs GmbH
|
2012-05-30 18:13:09 +00:00
|
|
|
*
|
|
|
|
* This file is part of the Genode OS framework, which is distributed
|
|
|
|
* under the terms of the GNU General Public License version 2.
|
|
|
|
*/
|
|
|
|
|
2013-11-14 16:29:34 +00:00
|
|
|
#ifndef _KERNEL__INTERFACE_H_
|
|
|
|
#define _KERNEL__INTERFACE_H_
|
2012-05-30 18:13:09 +00:00
|
|
|
|
2014-03-15 00:26:53 +00:00
|
|
|
/* base-hw includes */
|
2013-11-14 16:29:34 +00:00
|
|
|
#include <kernel/interface_support.h>
|
2012-05-30 18:13:09 +00:00
|
|
|
|
|
|
|
namespace Kernel
|
|
|
|
{
|
2015-05-19 12:18:40 +00:00
|
|
|
using addr_t = Genode::addr_t;
|
|
|
|
using size_t = Genode::size_t;
|
|
|
|
using capid_t = Genode::uint16_t;
|
|
|
|
|
|
|
|
constexpr capid_t cap_id_invalid() { return 0; }
|
2012-12-19 13:46:48 +00:00
|
|
|
|
2012-05-30 18:13:09 +00:00
|
|
|
/**
|
2014-03-15 00:26:53 +00:00
|
|
|
* Kernel names of the kernel calls
|
2012-05-30 18:13:09 +00:00
|
|
|
*/
|
2014-03-16 15:00:55 +00:00
|
|
|
constexpr Call_arg call_id_pause_current_thread() { return 0; }
|
2014-03-25 15:34:20 +00:00
|
|
|
constexpr Call_arg call_id_resume_local_thread() { return 1; }
|
2014-03-16 15:00:55 +00:00
|
|
|
constexpr Call_arg call_id_yield_thread() { return 2; }
|
|
|
|
constexpr Call_arg call_id_send_request_msg() { return 3; }
|
|
|
|
constexpr Call_arg call_id_send_reply_msg() { return 4; }
|
|
|
|
constexpr Call_arg call_id_await_request_msg() { return 5; }
|
|
|
|
constexpr Call_arg call_id_kill_signal_context() { return 6; }
|
|
|
|
constexpr Call_arg call_id_submit_signal() { return 7; }
|
|
|
|
constexpr Call_arg call_id_await_signal() { return 8; }
|
2015-11-13 14:49:11 +00:00
|
|
|
constexpr Call_arg call_id_ack_signal() { return 9; }
|
|
|
|
constexpr Call_arg call_id_print_char() { return 10; }
|
|
|
|
constexpr Call_arg call_id_update_data_region() { return 11; }
|
|
|
|
constexpr Call_arg call_id_update_instr_region() { return 12; }
|
2015-12-01 13:50:14 +00:00
|
|
|
constexpr Call_arg call_id_ack_cap() { return 13; }
|
|
|
|
constexpr Call_arg call_id_delete_cap() { return 14; }
|
2012-05-30 18:13:09 +00:00
|
|
|
|
2013-11-14 12:29:47 +00:00
|
|
|
|
2012-10-23 15:12:09 +00:00
|
|
|
/*****************************************************************
|
2013-11-14 16:29:34 +00:00
|
|
|
** Kernel call with 1 to 6 arguments **
|
2012-10-23 15:12:09 +00:00
|
|
|
** **
|
|
|
|
** These functions must not be inline to ensure that objects, **
|
|
|
|
** wich are referenced by arguments, are tagged as "used" even **
|
|
|
|
** though only the pointer gets handled in here. **
|
|
|
|
*****************************************************************/
|
|
|
|
|
2013-11-14 16:29:34 +00:00
|
|
|
Call_ret call(Call_arg arg_0);
|
2012-10-23 15:12:09 +00:00
|
|
|
|
2013-11-14 16:29:34 +00:00
|
|
|
Call_ret call(Call_arg arg_0,
|
|
|
|
Call_arg arg_1);
|
2012-10-23 15:12:09 +00:00
|
|
|
|
2013-11-14 16:29:34 +00:00
|
|
|
Call_ret call(Call_arg arg_0,
|
|
|
|
Call_arg arg_1,
|
|
|
|
Call_arg arg_2);
|
2012-10-23 15:12:09 +00:00
|
|
|
|
2013-11-14 16:29:34 +00:00
|
|
|
Call_ret call(Call_arg arg_0,
|
|
|
|
Call_arg arg_1,
|
|
|
|
Call_arg arg_2,
|
|
|
|
Call_arg arg_3);
|
2012-10-23 15:12:09 +00:00
|
|
|
|
2013-11-14 16:29:34 +00:00
|
|
|
Call_ret call(Call_arg arg_0,
|
|
|
|
Call_arg arg_1,
|
|
|
|
Call_arg arg_2,
|
|
|
|
Call_arg arg_3,
|
|
|
|
Call_arg arg_4);
|
2012-10-23 15:12:09 +00:00
|
|
|
|
2013-11-14 16:29:34 +00:00
|
|
|
Call_ret call(Call_arg arg_0,
|
|
|
|
Call_arg arg_1,
|
|
|
|
Call_arg arg_2,
|
|
|
|
Call_arg arg_3,
|
|
|
|
Call_arg arg_4,
|
|
|
|
Call_arg arg_5);
|
2012-10-23 15:12:09 +00:00
|
|
|
|
2012-05-30 18:13:09 +00:00
|
|
|
|
|
|
|
/**
|
2014-03-16 15:00:55 +00:00
|
|
|
* Pause execution of calling thread
|
2012-05-30 18:13:09 +00:00
|
|
|
*/
|
2014-03-16 15:00:55 +00:00
|
|
|
inline void pause_current_thread()
|
2013-11-14 12:29:47 +00:00
|
|
|
{
|
2014-03-16 15:00:55 +00:00
|
|
|
call(call_id_pause_current_thread());
|
2013-11-14 12:29:47 +00:00
|
|
|
}
|
2012-05-30 18:13:09 +00:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
2014-03-25 15:34:20 +00:00
|
|
|
* Cancel blocking of a thread of the current domain if possible
|
2012-05-30 18:13:09 +00:00
|
|
|
*
|
2015-05-19 12:18:40 +00:00
|
|
|
* \param thread_id capability id of the targeted thread
|
2012-05-30 18:13:09 +00:00
|
|
|
*
|
2014-03-17 11:12:04 +00:00
|
|
|
* \return wether thread was in a cancelable blocking beforehand
|
2012-05-30 18:13:09 +00:00
|
|
|
*/
|
2015-05-19 12:18:40 +00:00
|
|
|
inline bool resume_local_thread(capid_t const thread_id)
|
2013-11-14 12:29:47 +00:00
|
|
|
{
|
2014-03-25 15:34:20 +00:00
|
|
|
return call(call_id_resume_local_thread(), thread_id);
|
2013-11-14 12:29:47 +00:00
|
|
|
}
|
2012-11-09 16:10:38 +00:00
|
|
|
|
|
|
|
|
2012-05-30 18:13:09 +00:00
|
|
|
/**
|
|
|
|
* Let the current thread give up its remaining timeslice
|
|
|
|
*
|
2015-05-19 12:18:40 +00:00
|
|
|
* \param thread_id capability id of the benefited thread
|
2013-11-25 09:57:07 +00:00
|
|
|
*
|
|
|
|
* If thread_id is valid the call will resume the targeted thread
|
|
|
|
* additionally.
|
2012-05-30 18:13:09 +00:00
|
|
|
*/
|
2015-05-19 12:18:40 +00:00
|
|
|
inline void yield_thread(capid_t const thread_id)
|
2013-11-14 12:29:47 +00:00
|
|
|
{
|
2014-03-15 00:26:53 +00:00
|
|
|
call(call_id_yield_thread(), thread_id);
|
2013-09-18 20:33:56 +00:00
|
|
|
}
|
2012-05-30 18:13:09 +00:00
|
|
|
|
2014-04-07 13:52:21 +00:00
|
|
|
/**
|
|
|
|
* Globally apply writes to a data region in the current domain
|
|
|
|
*
|
|
|
|
* \param base base of the region within the current domain
|
|
|
|
* \param size size of the region
|
|
|
|
*/
|
|
|
|
inline void update_data_region(addr_t const base, size_t const size)
|
|
|
|
{
|
|
|
|
call(call_id_update_data_region(), (Call_arg)base, (Call_arg)size);
|
|
|
|
}
|
2012-05-30 18:13:09 +00:00
|
|
|
|
2014-04-07 14:18:43 +00:00
|
|
|
/**
|
|
|
|
* Globally apply writes to an instruction region in the current domain
|
|
|
|
*
|
|
|
|
* \param base base of the region within the current domain
|
|
|
|
* \param size size of the region
|
|
|
|
*/
|
|
|
|
inline void update_instr_region(addr_t const base, size_t const size)
|
|
|
|
{
|
|
|
|
call(call_id_update_instr_region(), (Call_arg)base, (Call_arg)size);
|
|
|
|
}
|
|
|
|
|
2012-05-30 18:13:09 +00:00
|
|
|
/**
|
2013-11-21 11:04:21 +00:00
|
|
|
* Send request message and await receipt of corresponding reply message
|
2012-05-30 18:13:09 +00:00
|
|
|
*
|
2015-05-19 12:18:40 +00:00
|
|
|
* \param thread_id capability id of targeted thread
|
2012-05-30 18:13:09 +00:00
|
|
|
*
|
2013-11-21 11:04:21 +00:00
|
|
|
* \retval 0 succeeded
|
|
|
|
* \retval -1 failed
|
2015-05-19 12:18:40 +00:00
|
|
|
* \retval -2 failed due to out-of-memory for capability reception
|
2013-11-21 11:04:21 +00:00
|
|
|
*
|
|
|
|
* If the call returns successful, the received message is located at the
|
|
|
|
* base of the callers userland thread-context.
|
2012-05-30 18:13:09 +00:00
|
|
|
*/
|
2015-05-19 12:18:40 +00:00
|
|
|
inline int send_request_msg(capid_t const thread_id, unsigned rcv_caps)
|
2013-10-07 14:01:03 +00:00
|
|
|
{
|
2015-05-19 12:18:40 +00:00
|
|
|
return call(call_id_send_request_msg(), thread_id, rcv_caps);
|
2013-10-07 14:01:03 +00:00
|
|
|
}
|
2012-05-30 18:13:09 +00:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
2013-11-21 11:04:21 +00:00
|
|
|
* Await receipt of request message
|
2012-05-30 18:13:09 +00:00
|
|
|
*
|
2015-05-19 12:18:40 +00:00
|
|
|
* \param rcv_caps number of capabilities willing to accept
|
|
|
|
*
|
2013-11-21 11:04:21 +00:00
|
|
|
* \retval 0 succeeded
|
2015-05-19 12:18:40 +00:00
|
|
|
* \retval -1 canceled
|
|
|
|
* \retval -2 failed due to out-of-memory for capability reception
|
2013-10-17 11:51:17 +00:00
|
|
|
*
|
2013-11-21 11:04:21 +00:00
|
|
|
* If the call returns successful, the received message is located at the
|
|
|
|
* base of the callers userland thread-context.
|
2012-05-30 18:13:09 +00:00
|
|
|
*/
|
2015-05-19 12:18:40 +00:00
|
|
|
inline int await_request_msg(unsigned rcv_caps)
|
2013-10-17 11:51:17 +00:00
|
|
|
{
|
2015-05-19 12:18:40 +00:00
|
|
|
return call(call_id_await_request_msg(), rcv_caps);
|
2013-10-17 11:51:17 +00:00
|
|
|
}
|
2012-05-30 18:13:09 +00:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
2013-11-21 11:04:21 +00:00
|
|
|
* Reply to lastly received request message
|
2012-05-30 18:13:09 +00:00
|
|
|
*
|
2015-05-19 12:18:40 +00:00
|
|
|
* \param rcv_caps number of capabilities to accept when awaiting again
|
2013-11-21 10:35:33 +00:00
|
|
|
* \param await_request_msg wether the call shall await a request message
|
2013-10-17 11:51:17 +00:00
|
|
|
*
|
2013-11-21 11:04:21 +00:00
|
|
|
* \retval 0 await_request_msg == 0 or request-message receipt succeeded
|
|
|
|
* \retval -1 await_request_msg == 1 and request-message receipt failed
|
|
|
|
*
|
|
|
|
* If the call returns successful and await_request_msg == 1, the received
|
|
|
|
* message is located at the base of the callers userland thread-context.
|
2012-05-30 18:13:09 +00:00
|
|
|
*/
|
2015-05-19 12:18:40 +00:00
|
|
|
inline int send_reply_msg(unsigned rcv_caps, bool const await_request_msg)
|
2013-10-17 11:51:17 +00:00
|
|
|
{
|
2015-05-19 12:18:40 +00:00
|
|
|
return call(call_id_send_reply_msg(), rcv_caps, await_request_msg);
|
2013-09-18 10:57:01 +00:00
|
|
|
}
|
|
|
|
|
2012-05-30 18:13:09 +00:00
|
|
|
|
|
|
|
/**
|
2013-11-27 23:45:48 +00:00
|
|
|
* Print a char c to the kernels serial ouput
|
|
|
|
*
|
|
|
|
* If c is set to 0 the kernel prints a table of all threads and their
|
|
|
|
* current activities to the serial output.
|
2012-05-30 18:13:09 +00:00
|
|
|
*/
|
|
|
|
inline void print_char(char const c)
|
2013-11-14 12:29:47 +00:00
|
|
|
{
|
2014-03-15 00:26:53 +00:00
|
|
|
call(call_id_print_char(), c);
|
2012-05-30 18:13:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2013-10-30 12:56:57 +00:00
|
|
|
* Await any context of a receiver and optionally ack a context before
|
2013-09-11 22:48:27 +00:00
|
|
|
*
|
2015-05-19 12:18:40 +00:00
|
|
|
* \param receiver_id capability id of the targeted signal receiver
|
2012-05-30 18:13:09 +00:00
|
|
|
*
|
2013-09-11 22:48:27 +00:00
|
|
|
* \retval 0 suceeded
|
|
|
|
* \retval -1 failed
|
2012-05-30 18:13:09 +00:00
|
|
|
*
|
2013-09-11 22:48:27 +00:00
|
|
|
* If this call returns 0, an instance of 'Signal::Data' is located at the
|
|
|
|
* base of the callers UTCB. Every occurence of a signal is provided
|
2013-10-30 12:56:57 +00:00
|
|
|
* through this function until it gets delivered through this function or
|
|
|
|
* context respectively receiver get destructed. If multiple threads
|
|
|
|
* listen at the same receiver, and/or multiple contexts of the receiver
|
|
|
|
* trigger simultanously, there is no assertion about wich thread
|
|
|
|
* receives, and from wich context. A context that delivered once doesn't
|
|
|
|
* deliver again unless its last delivery has been acknowledged via
|
|
|
|
* ack_signal.
|
|
|
|
*/
|
2015-05-19 12:18:40 +00:00
|
|
|
inline int await_signal(capid_t const receiver_id)
|
2013-09-11 22:48:27 +00:00
|
|
|
{
|
2015-03-17 14:41:47 +00:00
|
|
|
return call(call_id_await_signal(), receiver_id);
|
2013-09-11 22:48:27 +00:00
|
|
|
}
|
2012-05-30 18:13:09 +00:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Trigger a specific signal context
|
|
|
|
*
|
2015-05-19 12:18:40 +00:00
|
|
|
* \param context capability id of the targeted signal context
|
2013-09-11 22:48:27 +00:00
|
|
|
* \param num how often the context shall be triggered by this call
|
|
|
|
*
|
|
|
|
* \retval 0 suceeded
|
|
|
|
* \retval -1 failed
|
2012-05-30 18:13:09 +00:00
|
|
|
*/
|
2015-05-19 12:18:40 +00:00
|
|
|
inline int submit_signal(capid_t const context, unsigned const num)
|
2013-09-11 22:48:27 +00:00
|
|
|
{
|
2014-03-15 00:26:53 +00:00
|
|
|
return call(call_id_submit_signal(), context, num);
|
2013-09-11 22:48:27 +00:00
|
|
|
}
|
2012-10-02 12:27:32 +00:00
|
|
|
|
2013-11-14 12:29:47 +00:00
|
|
|
|
2013-02-18 12:58:09 +00:00
|
|
|
/**
|
2013-09-11 22:48:27 +00:00
|
|
|
* Acknowledge the processing of the last delivery of a signal context
|
2013-02-18 12:58:09 +00:00
|
|
|
*
|
2015-05-19 12:18:40 +00:00
|
|
|
* \param context capability id of the targeted signal context
|
2013-02-18 12:58:09 +00:00
|
|
|
*/
|
2015-05-19 12:18:40 +00:00
|
|
|
inline void ack_signal(capid_t const context)
|
2013-09-11 22:48:27 +00:00
|
|
|
{
|
2014-03-15 00:26:53 +00:00
|
|
|
call(call_id_ack_signal(), context);
|
2013-09-11 22:48:27 +00:00
|
|
|
}
|
2013-02-18 12:58:09 +00:00
|
|
|
|
2013-11-14 12:29:47 +00:00
|
|
|
|
2013-12-05 23:12:43 +00:00
|
|
|
/**
|
|
|
|
* Halt processing of a signal context synchronously
|
|
|
|
*
|
2015-05-19 12:18:40 +00:00
|
|
|
* \param context capability id of the targeted signal context
|
2013-12-05 23:12:43 +00:00
|
|
|
*
|
|
|
|
* \retval 0 suceeded
|
|
|
|
* \retval -1 failed
|
|
|
|
*/
|
2015-05-19 12:18:40 +00:00
|
|
|
inline int kill_signal_context(capid_t const context)
|
2013-12-05 23:12:43 +00:00
|
|
|
{
|
2014-03-15 00:26:53 +00:00
|
|
|
return call(call_id_kill_signal_context(), context);
|
2013-11-14 12:29:47 +00:00
|
|
|
}
|
2015-05-19 12:18:40 +00:00
|
|
|
|
2015-12-01 13:50:14 +00:00
|
|
|
/**
|
|
|
|
* Acknowledge reception of a capability
|
|
|
|
*
|
|
|
|
* \param cap capability id to acknowledge
|
|
|
|
*/
|
|
|
|
inline void ack_cap(capid_t const cap)
|
|
|
|
{
|
|
|
|
call(call_id_ack_cap(), cap);
|
|
|
|
}
|
|
|
|
|
2015-05-19 12:18:40 +00:00
|
|
|
/**
|
|
|
|
* Delete a capability id
|
|
|
|
*
|
|
|
|
* \param cap capability id to delete
|
|
|
|
*/
|
|
|
|
inline void delete_cap(capid_t const cap)
|
|
|
|
{
|
|
|
|
call(call_id_delete_cap(), cap);
|
|
|
|
}
|
2012-05-30 18:13:09 +00:00
|
|
|
}
|
|
|
|
|
2013-11-14 16:29:34 +00:00
|
|
|
#endif /* _KERNEL__INTERFACE_H_ */
|