3 * \brief Common IPC interface.
7 * (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
8 * Alexander Warg <warg@os.inf.tu-dresden.de>,
9 * Björn Döbel <doebel@os.inf.tu-dresden.de>,
10 * Torsten Frenzel <frenzel@os.inf.tu-dresden.de>
11 * economic rights: Technische Universität Dresden (Germany)
13 * This file is part of TUD:OS and distributed under the terms of the
14 * GNU General Public License 2.
15 * Please see the COPYING-GPL-2 file for details.
17 * As a special exception, you may use this file as part of a free software
18 * library without restriction. Specifically, if other files instantiate
19 * templates or use macros or inline functions from this file, or you compile
20 * this file and link it with other files to produce an executable, this
21 * file does not by itself cause the resulting executable to be covered by
22 * the GNU General Public License. This exception does not however
23 * invalidate any other reasons why the executable file might be covered by
24 * the GNU General Public License.
26 #ifndef __L4SYS__INCLUDE__L4API_FIASCO__IPC_H__
27 #define __L4SYS__INCLUDE__L4API_FIASCO__IPC_H__
29 #include <l4/sys/types.h>
30 #include <l4/sys/utcb.h>
31 #include <l4/sys/err.h>
34 * \defgroup l4_ipc_api Object Invocation
36 * \brief API for L4 object invocation.
38 * <c>\#include <l4/sys/ipc.h></c>
40 * General abstractions for L4 object invocation. The basic principle is that
41 * all objects are denoted by a capability that is accessed via a capability
42 * selector (see \link l4_cap_api Capabilities \endlink).
44 * This set of functions is common to all kinds of objects provided by the
45 * L4 micro kernel. The concrete semantics of an invocation depends on the
46 * object that shall be invoked.
48 * Objects may be invoked in various ways, the most common way is to use
49 * a \em call operation (l4_ipc_call()). However, there are a lot more
50 * flavours available that have a semantics depending on the object.
52 * \see \ref l4_kernel_object_gate_api
56 /*****************************************************************************
57 *** IPC result checking
58 *****************************************************************************/
61 * \defgroup l4_ipc_err_api Error Handling
63 * \brief Error handling for L4 object invocation.
65 * <c>\#include <l4/sys/ipc.h></c>
69 * \brief Error codes in the \em error TCR.
70 * \ingroup l4_ipc_err_api
72 * The error codes are accessible via the \em error TCR, see
73 * #l4_thread_regs_t.error.
75 enum l4_ipc_tcr_error_t
77 L4_IPC_ERROR_MASK = 0x1F, /**< Mask for error bits. */
78 L4_IPC_SND_ERR_MASK = 0x01, /**< Send error mask. */
80 L4_IPC_ENOT_EXISTENT = 0x04, /**< Non-existing destination or source.
81 ** \ingroup l4_ipc_api
83 L4_IPC_RETIMEOUT = 0x03, /**< Timeout during receive operation.
84 ** \ingroup l4_ipc_api
86 L4_IPC_SETIMEOUT = 0x02, /**< Timeout during send operation.
87 ** \ingroup l4_ipc_api
89 L4_IPC_RECANCELED = 0x07, /**< Receive operation canceled.
90 ** \ingroup l4_ipc_api
92 L4_IPC_SECANCELED = 0x06, /**< Send operation canceled.
93 ** \ingroup l4_ipc_api
95 L4_IPC_REMAPFAILED = 0x11, /**< Map flexpage failed in receive
97 ** \ingroup l4_ipc_api
99 L4_IPC_SEMAPFAILED = 0x10, /**< Map flexpage failed in send operation.
100 ** \ingroup l4_ipc_api
102 L4_IPC_RESNDPFTO = 0x0b, /**< Send-pagefault timeout in receive
104 ** \ingroup l4_ipc_api
106 L4_IPC_SESNDPFTO = 0x0a, /**< Send-pagefault timeout in send
108 ** \ingroup l4_ipc_api
110 L4_IPC_RERCVPFTO = 0x0d, /**< Receive-pagefault timeout in receive
112 ** \ingroup l4_ipc_api
114 L4_IPC_SERCVPFTO = 0x0c, /**< Receive-pagefault timeout in send
116 ** \ingroup l4_ipc_api
118 L4_IPC_REABORTED = 0x0f, /**< Receive operation aborted.
119 ** \ingroup l4_ipc_api
121 L4_IPC_SEABORTED = 0x0e, /**< Send operation aborted.
122 ** \ingroup l4_ipc_api
124 L4_IPC_REMSGCUT = 0x09, /**< Cut receive message. (due to
125 ** (a) message buffer is too small,
126 ** (b) not enough strings are accepted,
127 ** (c) at least one string buffer is too
129 ** \ingroup l4_ipc_api
131 L4_IPC_SEMSGCUT = 0x08, /**< Cut send message. (due to
132 ** (a) message buffer is too small,
133 ** (b) not enough strings are accepted,
134 ** (c) at least one string buffer is too
136 ** \ingroup l4_ipc_api
142 * \brief Get the error code for an object invocation.
143 * \ingroup l4_ipc_err_api
145 * \param tag Return value of the invocation.
146 * \param utcb UTCB that was used for the invocation.
148 * \return 0 if no error condition is set,
149 * error code otherwise (see #l4_ipc_tcr_error_t).
151 L4_INLINE l4_umword_t
152 l4_ipc_error(l4_msgtag_t tag, l4_utcb_t *utcb) L4_NOTHROW;
156 * \brief Return error code of a system call return message tag.
157 * \ingroup l4_ipc_err_api
158 * \param tag System call return message type
159 * \return 0 for no error, error number in case of error
162 l4_error(l4_msgtag_t tag) L4_NOTHROW;
165 l4_error_u(l4_msgtag_t tag, l4_utcb_t *utcb) L4_NOTHROW;
167 /*****************************************************************************
169 *****************************************************************************/
172 * \brief Returns whether an error occurred in send phase of an invocation.
173 * \ingroup l4_ipc_err_api
175 * \pre l4_msgtag_has_error(tag) == true
176 * \param utcb UTCB to check.
178 * \return Boolean value.
180 L4_INLINE int l4_ipc_is_snd_error(l4_utcb_t *utcb) L4_NOTHROW;
183 * \brief Returns whether an error occurred in receive phase of an invocation.
184 * \ingroup l4_ipc_err_api
186 * \pre l4_msgtag_has_error(tag) == true
187 * \param utcb UTCB to check.
189 * \return Boolean value.
191 L4_INLINE int l4_ipc_is_rcv_error(l4_utcb_t *utcb) L4_NOTHROW;
194 * \brief Get the error condition of the last invocation from the TCR.
195 * \ingroup l4_ipc_err_api
197 * \pre l4_msgtag_has_error(tag) == true
198 * \param utcb UTCB to check.
200 * \return Error condition of type l4_ipc_tcr_error_t.
202 L4_INLINE int l4_ipc_error_code(l4_utcb_t *utcb) L4_NOTHROW;
205 /*****************************************************************************
207 *****************************************************************************/
210 * \brief Send a message to an object (do \b not wait for a reply).
211 * \ingroup l4_ipc_api
213 * \param dest Capability selector for the destination object.
214 * \param utcb UTCB of the caller.
215 * \param tag Descriptor for the message to be sent.
216 * \param timeout Timeout pair (see #l4_timeout_t) only send part is relevant.
220 * A message is sent to the destination object. There is no receive phase
221 * included. The invoker continues working after sending the message.
223 * \attention This is a special-purpose message transfer, objects usually
224 * support only invocation via l4_ipc_call().
226 L4_INLINE l4_msgtag_t
227 l4_ipc_send(l4_cap_idx_t dest, l4_utcb_t *utcb, l4_msgtag_t tag,
228 l4_timeout_t timeout) L4_NOTHROW;
232 * \brief Wait for an incoming message from any possible sender.
233 * \ingroup l4_ipc_api
235 * \param utcb UTCB of the caller.
236 * \retval label Label assigned to the source object (IPC gate or IRQ).
237 * \param timeout Timeout pair (see #l4_timeout_t, only the receive part is
242 * This operation does an open wait, and therefore needs no capability to
243 * denote the possible source of a message. This means the calling thread
244 * waits for an incoming message from any possible source.
245 * There is no send phase included in this operation.
247 * The usual usage of this function is to call that function when entering a
248 * server loop in a user-level server that implements user-level objects,
249 * see also #l4_ipc_reply_and_wait().
251 L4_INLINE l4_msgtag_t
252 l4_ipc_wait(l4_utcb_t *utcb, l4_umword_t *label,
253 l4_timeout_t timeout) L4_NOTHROW;
257 * \brief Wait for a message from a specific source.
258 * \ingroup l4_ipc_api
260 * \param object Object to receive a message from.
261 * \param timeout Timeout pair (see #l4_timeout_t, only the receive part
263 * \param utcb UTCB of the caller.
265 * \return result tag.
267 * This operation waits for a message from the specified object. Messages from
268 * other sources are not accepted by this operation. The operation does not
269 * include a send phase, this means no message is sent to the object.
271 * \note This operation is usually used to receive messages from a specific IRQ
272 * or thread. However, it is not common to use this operation for normal
275 L4_INLINE l4_msgtag_t
276 l4_ipc_receive(l4_cap_idx_t object, l4_utcb_t *utcb,
277 l4_timeout_t timeout) L4_NOTHROW;
280 * \brief Object call (usual invocation).
281 * \ingroup l4_ipc_api
283 * \param object Capability selector for the object to call.
284 * \param utcb UTCB of the caller.
285 * \param tag Message tag to describe the message to be sent.
286 * \param timeout Timeout pair for send an receive phase (see #l4_timeout_t).
290 * A message is sent to the object and the invoker waits for a
291 * reply from the object. Messages from other sources are not accepted.
292 * \note The send-to-receive transition needs no time, the object can reply
293 * with a send timeout of zero.
295 L4_INLINE l4_msgtag_t
296 l4_ipc_call(l4_cap_idx_t object, l4_utcb_t *utcb, l4_msgtag_t tag,
297 l4_timeout_t timeout) L4_NOTHROW;
301 * \brief Reply and wait operation (uses the \em reply capability).
302 * \ingroup l4_ipc_api
304 * \param tag Describes the message to be sent as reply.
305 * \param utcb UTCB of the caller.
306 * \retval label Label assigned to the source object of the received message.
307 * \param timeout Timeout pair (see #l4_timeout_t).
310 * A message is sent to the previous caller using the implicit reply
311 * capability. Afterwards the invoking thread waits for a message from any
313 * \note This is the standard server operation: it sends a reply to the actual
314 * client and waits for the next incoming request, which may come from
317 L4_INLINE l4_msgtag_t
318 l4_ipc_reply_and_wait(l4_utcb_t *utcb, l4_msgtag_t tag,
319 l4_umword_t *label, l4_timeout_t timeout) L4_NOTHROW;
322 * \brief Send a message and do an open wait.
323 * \ingroup l4_ipc_api
325 * \param dest Object to send a message to.
326 * \param utcb UTCB of the caller.
327 * \param tag Describes the message that shall be sent.
328 * \retval label Label assigned to the source object of the receive phase.
329 * \param timeout Timeout pair (see #l4_timeout_t).
332 * A message is sent to the destination object and the invoking thread waits
333 * for a reply from any source.
335 * \note This is a special-purpose operation and shall not be used in general
338 L4_INLINE l4_msgtag_t
339 l4_ipc_send_and_wait(l4_cap_idx_t dest, l4_utcb_t *utcb, l4_msgtag_t tag,
340 l4_umword_t *label, l4_timeout_t timeout) L4_NOTHROW;
343 * \defgroup l4_ipc_rt_api Realtime API
344 * \ingroup l4_ipc_api
350 * Wait for next period.
351 * \ingroup l4_ipc_rt_api
353 * \param utcb UTCB of the caller.
355 * \param timeout IPC timeout (see #l4_ipc_timeout).
359 L4_INLINE l4_msgtag_t
360 l4_ipc_wait_next_period(l4_utcb_t *utcb,
362 l4_timeout_t timeout);
367 * \brief Generic L4 object invocation.
368 * \ingroup l4_ipc_api
370 * \param dest Destination object.
371 * \param utcb UTCB of the caller.
372 * \param flags Invocation flags (see #l4_syscall_flags_t).
373 * \param slabel Send label if applicable (may be seen by the receiver).
374 * \param tag Sending message tag.
375 * \retval rlabel Receiving label.
376 * \param timeout Timeout pair (see #l4_timeout_t).
380 L4_INLINE l4_msgtag_t
381 l4_ipc(l4_cap_idx_t dest,
387 l4_timeout_t timeout) L4_NOTHROW;
390 * \brief Sleep for an amount of time.
391 * \ingroup l4_ipc_api
393 * \param timeout Timeout pair (see #l4_timeout_t, the receive part matters).
395 * \return error code:
396 * - #L4_IPC_RETIMEOUT: success
397 * - #L4_IPC_RECANCELED woken up by a different thread
398 * (l4_thread_ex_regs()).
400 * The invoking thread waits until the timeout
401 * is expired or the wait was aborted by another thread by l4_thread_ex_regs().
403 L4_INLINE l4_msgtag_t
404 l4_ipc_sleep(l4_timeout_t timeout) L4_NOTHROW;
407 * \brief Add a flex-page to be sent to the UTCB
408 * \ingroup l4_ipc_api
410 * \param snd_fpage Flex-page.
411 * \param snd_base Send base.
412 * \param tag Tag to be modified.
413 * \retval tag Modified tag, the number of items will be increased,
414 * all other values in the tag will be retained.
416 * \return 0 on success, negative error code otherwise
419 l4_sndfpage_add(l4_fpage_t const snd_fpage, unsigned long snd_base,
420 l4_msgtag_t *tag) L4_NOTHROW;
424 * \ingroup l4_ipc_api
427 l4_sndfpage_add_u(l4_fpage_t const snd_fpage, unsigned long snd_base,
428 l4_msgtag_t *tag, l4_utcb_t *utcb) L4_NOTHROW;
431 /************************************************************************
433 **********************/
435 L4_INLINE l4_umword_t
436 l4_ipc_error(l4_msgtag_t tag, l4_utcb_t *utcb) L4_NOTHROW
438 if (!l4_msgtag_has_error(tag))
440 return l4_utcb_tcr_u(utcb)->error & L4_IPC_ERROR_MASK;
444 l4_error_u(l4_msgtag_t tag, l4_utcb_t *u) L4_NOTHROW
446 if (l4_msgtag_has_error(tag))
447 return -(L4_EIPC_LO + (l4_utcb_tcr_u(u)->error & L4_IPC_ERROR_MASK));
449 return l4_msgtag_label(tag);
453 l4_error(l4_msgtag_t tag) L4_NOTHROW
455 return l4_error_u(tag, l4_utcb());
459 L4_INLINE int l4_ipc_is_snd_error(l4_utcb_t *u) L4_NOTHROW
460 { return !(l4_utcb_tcr_u(u)->error & 1) == 0; }
462 L4_INLINE int l4_ipc_is_rcv_error(l4_utcb_t *u) L4_NOTHROW
463 { return l4_utcb_tcr_u(u)->error & 1; }
465 L4_INLINE int l4_ipc_error_code(l4_utcb_t *u) L4_NOTHROW
466 { return l4_utcb_tcr_u(u)->error & L4_IPC_ERROR_MASK; }
471 * \ingroup l4_ipc_api
474 l4_sndfpage_add_u(l4_fpage_t const snd_fpage, unsigned long snd_base,
475 l4_msgtag_t *tag, l4_utcb_t *utcb) L4_NOTHROW
477 l4_msg_regs_t *v = l4_utcb_mr_u(utcb);
478 int i = l4_msgtag_words(*tag) + 2 * l4_msgtag_items(*tag);
480 if (i >= L4_UTCB_GENERIC_DATA_SIZE - 1)
483 v->mr[i] = snd_base | L4_ITEM_MAP | L4_ITEM_CONT;
484 v->mr[i + 1] = snd_fpage.raw;
486 *tag = l4_msgtag(l4_msgtag_label(*tag), l4_msgtag_words(*tag),
487 l4_msgtag_items(*tag) + 1, l4_msgtag_flags(*tag));
492 l4_sndfpage_add(l4_fpage_t const snd_fpage, unsigned long snd_base,
493 l4_msgtag_t *tag) L4_NOTHROW
495 return l4_sndfpage_add_u(snd_fpage, snd_base, tag, l4_utcb());
499 #endif /* ! __L4SYS__INCLUDE__L4API_FIASCO__IPC_H__ */