]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/l4sys/include/ipc.h
update
[l4.git] / l4 / pkg / l4sys / include / ipc.h
1 /**
2  * \file
3  * \brief Common IPC interface.
4  * \ingroup l4_api
5  */
6 /*
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)
12  *
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.
16  *
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.
25  */
26 #ifndef __L4SYS__INCLUDE__L4API_FIASCO__IPC_H__
27 #define __L4SYS__INCLUDE__L4API_FIASCO__IPC_H__
28
29 #include <l4/sys/types.h>
30 #include <l4/sys/utcb.h>
31 #include <l4/sys/err.h>
32
33 /**
34  * \defgroup l4_ipc_api Object Invocation
35  * \ingroup l4_api
36  * \brief API for L4 object invocation.
37  *
38  * <c>\#include <l4/sys/ipc.h></c>
39  *
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).
43  *
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.
47  *
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.
51  *
52  * \see \ref l4_kernel_object_gate_api
53  *
54  */
55
56 /*****************************************************************************
57  *** IPC result checking
58  *****************************************************************************/
59
60 /**
61  * \defgroup l4_ipc_err_api Error Handling
62  * \ingroup l4_ipc_api
63  * \brief Error handling for L4 object invocation.
64  *
65  * <c>\#include <l4/sys/ipc.h></c>
66  */
67
68 /**
69  * \brief Error codes in the \em error TCR.
70  * \ingroup l4_ipc_err_api
71  *
72  * The error codes are accessible via the \em error TCR, see
73  * #l4_thread_regs_t.error.
74  */
75 enum l4_ipc_tcr_error_t
76 {
77   L4_IPC_ERROR_MASK       = 0x1F, /**< Mask for error bits. */
78   L4_IPC_SND_ERR_MASK     = 0x01, /**< Send error mask. */
79
80   L4_IPC_ENOT_EXISTENT    = 0x04, /**< Non-existing destination or source.
81                                    **  \ingroup l4_ipc_api
82                                    **/
83   L4_IPC_RETIMEOUT        = 0x03, /**< Timeout during receive operation.
84                                    **  \ingroup l4_ipc_api
85                                    **/
86   L4_IPC_SETIMEOUT        = 0x02, /**< Timeout during send operation.
87                                    **  \ingroup l4_ipc_api
88                                    **/
89   L4_IPC_RECANCELED       = 0x07, /**< Receive operation canceled.
90                                    **  \ingroup l4_ipc_api
91                                    **/
92   L4_IPC_SECANCELED       = 0x06, /**< Send operation canceled.
93                                    **  \ingroup l4_ipc_api
94                                    **/
95   L4_IPC_REMAPFAILED      = 0x11, /**< Map flexpage failed in receive
96                                    **  operation.
97                                    **  \ingroup l4_ipc_api
98                                    **/
99   L4_IPC_SEMAPFAILED      = 0x10, /**< Map flexpage failed in send operation.
100                                    **  \ingroup l4_ipc_api
101                                    **/
102   L4_IPC_RESNDPFTO        = 0x0b, /**< Send-pagefault timeout in receive
103                                    **  operation.
104                                    **  \ingroup l4_ipc_api
105                                    **/
106   L4_IPC_SESNDPFTO        = 0x0a, /**< Send-pagefault timeout in send
107                                    **  operation.
108                                    **  \ingroup l4_ipc_api
109                                    **/
110   L4_IPC_RERCVPFTO        = 0x0d, /**< Receive-pagefault timeout in receive
111                                    **  operation.
112                                    **  \ingroup l4_ipc_api
113                                    **/
114   L4_IPC_SERCVPFTO        = 0x0c, /**< Receive-pagefault timeout in send
115                                    **  operation.
116                                    **  \ingroup l4_ipc_api
117                                    **/
118   L4_IPC_REABORTED        = 0x0f, /**< Receive operation aborted.
119                                    **  \ingroup l4_ipc_api
120                                    **/
121   L4_IPC_SEABORTED        = 0x0e, /**< Send operation aborted.
122                                    **  \ingroup l4_ipc_api
123                                    **/
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
128                                    **      small)
129                                    **  \ingroup l4_ipc_api
130                                    **/
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
135                                    **      small)
136                                    **  \ingroup l4_ipc_api
137                                    **/
138 };
139
140
141 /**
142  * \brief Get the error code for an object invocation.
143  * \ingroup l4_ipc_err_api
144  *
145  * \param tag   Return value of the invocation.
146  * \param utcb  UTCB that was used for the invocation.
147  *
148  * \return 0 if no error condition is set,
149  *         error code otherwise (see #l4_ipc_tcr_error_t).
150  */
151 L4_INLINE l4_umword_t
152 l4_ipc_error(l4_msgtag_t tag, l4_utcb_t *utcb) L4_NOTHROW;
153
154
155 /**
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
160  */
161 L4_INLINE long
162 l4_error(l4_msgtag_t tag) L4_NOTHROW;
163
164 L4_INLINE long
165 l4_error_u(l4_msgtag_t tag, l4_utcb_t *utcb) L4_NOTHROW;
166
167 /*****************************************************************************
168  *** IPC results
169  *****************************************************************************/
170
171 /**
172  * \brief Returns whether an error occurred in send phase of an invocation.
173  * \ingroup l4_ipc_err_api
174  *
175  * \pre l4_msgtag_has_error(tag) == true
176  * \param utcb   UTCB to check.
177  *
178  * \return Boolean value.
179  */
180 L4_INLINE int l4_ipc_is_snd_error(l4_utcb_t *utcb) L4_NOTHROW;
181
182 /**
183  * \brief Returns whether an error occurred in receive phase of an invocation.
184  * \ingroup l4_ipc_err_api
185  *
186  * \pre l4_msgtag_has_error(tag) == true
187  * \param utcb   UTCB to check.
188  *
189  * \return Boolean value.
190  */
191 L4_INLINE int l4_ipc_is_rcv_error(l4_utcb_t *utcb) L4_NOTHROW;
192
193 /**
194  * \brief Get the error condition of the last invocation from the TCR.
195  * \ingroup l4_ipc_err_api
196  *
197  * \pre l4_msgtag_has_error(tag) == true
198  * \param utcb   UTCB to check.
199  *
200  * \return Error condition of type l4_ipc_tcr_error_t.
201  */
202 L4_INLINE int l4_ipc_error_code(l4_utcb_t *utcb) L4_NOTHROW;
203
204
205 /*****************************************************************************
206  *** IPC calls
207  *****************************************************************************/
208
209 /**
210  * \brief Send a message to an object (do \b not wait for a reply).
211  * \ingroup l4_ipc_api
212  *
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.
217  *
218  * \return  result tag
219  *
220  * A message is sent to the destination object. There is no receive phase
221  * included. The invoker continues working after sending the message.
222  *
223  * \attention This is a special-purpose message transfer, objects usually
224  *            support only invocation via l4_ipc_call().
225  */
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;
229
230
231 /**
232  * \brief Wait for an incoming message from any possible sender.
233  * \ingroup l4_ipc_api
234  *
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
238  *          used).
239  *
240  * \return  return tag
241  *
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.
246  *
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().
250  */
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;
254
255
256 /**
257  * \brief Wait for a message from a specific source.
258  * \ingroup l4_ipc_api
259  *
260  * \param   object  Object to receive a message from.
261  * \param   timeout Timeout pair (see #l4_timeout_t, only the receive part
262  *                  matters).
263  * \param   utcb    UTCB of the caller.
264  *
265  * \return  result tag.
266  *
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.
270  *
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
273  *       applications.
274  */
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;
278
279 /**
280  * \brief Object call (usual invocation).
281  * \ingroup l4_ipc_api
282  *
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).
287  *
288  * \return  result tag
289  *
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.
294  */
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;
298
299
300 /**
301  * \brief Reply and wait operation (uses the \em reply capability).
302  * \ingroup l4_ipc_api
303  *
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).
308  * \return  result tag
309  *
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
312  * source.
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
315  *       any other client.
316  */
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;
320
321 /**
322  * \brief Send a message and do an open wait.
323  * \ingroup l4_ipc_api
324  *
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).
330  * \return  result tag
331  *
332  * A message is sent to the destination object and the invoking thread waits
333  * for a reply from any source.
334  *
335  * \note This is a special-purpose operation and shall not be used in general
336  *       applications.
337  */
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;
341
342 /**
343  * \defgroup l4_ipc_rt_api Realtime API
344  * \ingroup l4_ipc_api
345  * \internal
346  */
347
348 #if 0
349 /**
350  * Wait for next period.
351  * \ingroup l4_ipc_rt_api
352  *
353  * \param utcb    UTCB of the caller.
354  * \param label   Label
355  * \param timeout IPC timeout (see #l4_ipc_timeout).
356  *
357  * \return result tag
358  */
359 L4_INLINE l4_msgtag_t
360 l4_ipc_wait_next_period(l4_utcb_t *utcb,
361                         l4_umword_t *label,
362                         l4_timeout_t timeout);
363
364 #endif
365
366 /**
367  * \brief Generic L4 object invocation.
368  * \ingroup l4_ipc_api
369  *
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).
377  *
378  * \return return tag
379  */
380 L4_INLINE l4_msgtag_t
381 l4_ipc(l4_cap_idx_t dest,
382        l4_utcb_t *utcb,
383        l4_umword_t flags,
384        l4_umword_t slabel,
385        l4_msgtag_t tag,
386        l4_umword_t *rlabel,
387        l4_timeout_t timeout) L4_NOTHROW;
388
389 /**
390  * \brief Sleep for an amount of time.
391  * \ingroup l4_ipc_api
392  *
393  * \param   timeout Timeout pair (see #l4_timeout_t, the receive part matters).
394  *
395  * \return  error code:
396  *          - #L4_IPC_RETIMEOUT: success
397  *          - #L4_IPC_RECANCELED woken up by a different thread
398  *            (l4_thread_ex_regs()).
399  *
400  * The invoking thread waits until the timeout
401  * is expired or the wait was aborted by another thread by l4_thread_ex_regs().
402  */
403 L4_INLINE l4_msgtag_t
404 l4_ipc_sleep(l4_timeout_t timeout) L4_NOTHROW;
405
406 /**
407  * \brief Add a flex-page to be sent to the UTCB
408  * \ingroup l4_ipc_api
409  *
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.
415  *
416  * \return 0 on success, negative error code otherwise
417  */
418 L4_INLINE int
419 l4_sndfpage_add(l4_fpage_t const snd_fpage, unsigned long snd_base,
420                 l4_msgtag_t *tag) L4_NOTHROW;
421
422 /*
423  * \internal
424  * \ingroup l4_ipc_api
425  */
426 L4_INLINE int
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;
429
430
431 /************************************************************************
432  * Implementations
433  **********************/
434
435 L4_INLINE l4_umword_t
436 l4_ipc_error(l4_msgtag_t tag, l4_utcb_t *utcb) L4_NOTHROW
437 {
438   if (!l4_msgtag_has_error(tag))
439     return 0;
440   return l4_utcb_tcr_u(utcb)->error & L4_IPC_ERROR_MASK;
441 }
442
443 L4_INLINE long
444 l4_error_u(l4_msgtag_t tag, l4_utcb_t *u) L4_NOTHROW
445 {
446   if (l4_msgtag_has_error(tag))
447     return -(L4_EIPC_LO + (l4_utcb_tcr_u(u)->error & L4_IPC_ERROR_MASK));
448
449   return l4_msgtag_label(tag);
450 }
451
452 L4_INLINE long
453 l4_error(l4_msgtag_t tag) L4_NOTHROW
454 {
455   return l4_error_u(tag, l4_utcb());
456 }
457
458
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; }
461
462 L4_INLINE int l4_ipc_is_rcv_error(l4_utcb_t *u) L4_NOTHROW
463 { return l4_utcb_tcr_u(u)->error & 1; }
464
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; }
467
468
469 /*
470  * \internal
471  * \ingroup l4_ipc_api
472  */
473 L4_INLINE int
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
476 {
477   l4_msg_regs_t *v = l4_utcb_mr_u(utcb);
478   int i = l4_msgtag_words(*tag) + 2 * l4_msgtag_items(*tag);
479
480   if (i >= L4_UTCB_GENERIC_DATA_SIZE - 1)
481     return -L4_ENOMEM;
482
483   v->mr[i]     = snd_base | L4_ITEM_MAP | L4_ITEM_CONT;
484   v->mr[i + 1] = snd_fpage.raw;
485
486   *tag = l4_msgtag(l4_msgtag_label(*tag), l4_msgtag_words(*tag),
487                    l4_msgtag_items(*tag) + 1, l4_msgtag_flags(*tag));
488   return 0;
489 }
490
491 L4_INLINE int
492 l4_sndfpage_add(l4_fpage_t const snd_fpage, unsigned long snd_base,
493                 l4_msgtag_t *tag) L4_NOTHROW
494 {
495   return l4_sndfpage_add_u(snd_fpage, snd_base, tag, l4_utcb());
496 }
497
498
499 #endif /* ! __L4SYS__INCLUDE__L4API_FIASCO__IPC_H__ */