1 /*****************************************************************************/
2 /**
3  * \file
4  * Common L4 ABI Data Types.
5  * \ingroup l4_api
6  */
7 /*
8  * (c) 2008-2013 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
9  *               Alexander Warg <warg@os.inf.tu-dresden.de>,
10  *               Björn Döbel <doebel@os.inf.tu-dresden.de>,
11  *               Torsten Frenzel <frenzel@os.inf.tu-dresden.de>
12  *     economic rights: Technische Universität Dresden (Germany)
13  *
14  * This file is part of TUD:OS and distributed under the terms of the
15  * GNU General Public License 2.
16  * Please see the COPYING-GPL-2 file for details.
17  *
18  * As a special exception, you may use this file as part of a free software
19  * library without restriction.  Specifically, if other files instantiate
20  * templates or use macros or inline functions from this file, or you compile
21  * this file and link it with other files to produce an executable, this
22  * file does not by itself cause the resulting executable to be covered by
23  * the GNU General Public License.  This exception does not however
24  * invalidate any other reasons why the executable file might be covered by
25  * the GNU General Public License.
26  */
27 /*****************************************************************************/
28 #pragma once
29 
30 #include <l4/sys/l4int.h>
31 #include <l4/sys/compiler.h>
32 #include <l4/sys/consts.h>
33 
34 
35 /**
36  * \defgroup l4_msgtag_api Message Tag
37  * \ingroup l4_ipc_api
38  * API related to the message tag data type.
39  *
40  * \includefile{l4/sys/types.h}
41  */
42 
43 /**
44  * Message tag for IPC operations.
45  * \ingroup l4_msgtag_api
46  *
47  * All predefined protocols used by the kernel.
48  */
49 enum l4_msgtag_protocol
50 {
51   L4_PROTO_NONE          = 0,   ///< Default protocol tag to reply to kernel
52   L4_PROTO_ALLOW_SYSCALL = 1,   ///< Allow an alien the system call
53   L4_PROTO_PF_EXCEPTION  = 1,   ///< Make an exception out of a page fault
54 
55   L4_PROTO_IRQ           =  -1L, ///< IRQ message
56   L4_PROTO_PAGE_FAULT    =  -2L, ///< Page fault message
57   L4_PROTO_PREEMPTION    =  -3L, ///< Preemption message
58   L4_PROTO_SYS_EXCEPTION =  -4L, ///< System exception
59   L4_PROTO_EXCEPTION     =  -5L, ///< Exception
60   L4_PROTO_SIGMA0        =  -6L, ///< Sigma0 protocol
61   L4_PROTO_IO_PAGE_FAULT =  -8L, ///< I/O page fault message
62   L4_PROTO_KOBJECT       = -10L, ///< Protocol for messages to a generic kobject
63   L4_PROTO_TASK          = -11L, ///< Protocol for messages to a task object
64   L4_PROTO_THREAD        = -12L, ///< Protocol for messages to a thread object
65   L4_PROTO_LOG           = -13L, ///< Protocol for messages to a log object
66   L4_PROTO_SCHEDULER     = -14L, ///< Protocol for messages to a scheduler object
67   L4_PROTO_FACTORY       = -15L, ///< Protocol for messages to a factory object
68   L4_PROTO_VM            = -16L, ///< Protocol for messages to a virtual machine object
69   L4_PROTO_DMA_SPACE     = -17L, ///< Protocol for (creating) kernel DMA space objects
70   L4_PROTO_IRQ_SENDER    = -18L, ///< Protocol for IRQ senders (IRQ -> IPC)
71   L4_PROTO_IRQ_MUX       = -19L, ///< Protocol for IRQ mux (IRQ -> n x IRQ)
72   L4_PROTO_SEMAPHORE     = -20L, ///< Protocol for semaphore objects
73   L4_PROTO_META          = -21L, ///< Meta information protocol
74   L4_PROTO_IOMMU         = -22L, ///< Protocol ID for IO-MMUs
75   L4_PROTO_DEBUGGER      = -23L, ///< Protocol ID for the debugger
76   L4_PROTO_SMCCC         = -24L, ///< Protocol ID for ARM SMCCC calls
77 };
78 
79 enum L4_varg_type
80 {
81   L4_VARG_TYPE_NIL    = 0x00,
82   L4_VARG_TYPE_UMWORD = 0x01,
83   L4_VARG_TYPE_MWORD  = 0x81,
84   L4_VARG_TYPE_STRING = 0x02,
85   L4_VARG_TYPE_FPAGE  = 0x03,
86 
87   L4_VARG_TYPE_SIGN   = 0x80,
88 };
89 
90 
91 /**
92  * Flags for message tags.
93  * \ingroup l4_msgtag_api
94  */
95 enum l4_msgtag_flags
96 {
97   // flags for received IPC
98   /**
99    * Error indicator flag.
100    * \hideinitializer
101    */
102   L4_MSGTAG_ERROR        = 0x8000,
103 
104   // flags for sending IPC
105   /**
106    * Enable FPU transfer flag for IPC.
107    * \hideinitializer
108    *
109    * By enabling this flag when sending IPC, the sender indicates that the
110    * contents of the FPU shall be transferred to the receiving thread.
111    * However, the receiver has to indicate its willingness to receive
112    * FPU context in its buffer descriptor register (BDR).
113    */
114   L4_MSGTAG_TRANSFER_FPU = 0x1000,
115   /**
116    * Enable schedule in IPC flag.
117    * \hideinitializer
118    *
119    * Usually IPC operations donate the remaining time slice of a thread
120    * to the called thread. Enabling this flag when sending IPC does a real
121    * scheduling decision. However, this flag decreases IPC performance.
122    */
123   L4_MSGTAG_SCHEDULE     = 0x2000,
124   /**
125    * Enable IPC propagation.
126    * \hideinitializer
127    *
128    * This flag enables IPC propagation, which means an IPC reply-connection
129    * from the current caller will be propagated to the new IPC receiver.
130    * This makes it possible to propagate an IPC call to a third thread, which
131    * may then directly answer to the caller.
132    */
133   L4_MSGTAG_PROPAGATE    = 0x4000,
134 
135   /**
136    * Mask for all flags.
137    * \hideinitializer
138    */
139   L4_MSGTAG_FLAGS        = 0xf000,
140 };
141 
142 
143 /**
144  * Message tag data structure.
145  * \ingroup l4_msgtag_api
146  *
147  * \includefile{l4/sys/types.h}
148  *
149  * Describes the details of an IPC operation, in particular
150  * which parts of the UTCB have to be transmitted, and also flags
151  * to enable real-time and FPU extensions.
152  *
153  * The message tag also contains a user-defined label that could be used
154  * to specify a protocol ID. Some negative values are reserved for kernel
155  * protocols such as page faults and exceptions.
156  *
157  * The type must be treated completely opaque.
158  */
159 typedef struct l4_msgtag_t
160 {
161   l4_mword_t raw;   ///< raw value
162 #ifdef __cplusplus
163   /// Get the protocol value.
labell4_msgtag_t164   long label() const L4_NOTHROW { return raw >> 16; }
165   /// Set the protocol value.
labell4_msgtag_t166   void label(long v) L4_NOTHROW { raw = (raw & 0x0ffff) | ((l4_umword_t)v << 16); }
167   /// Get the number of untyped words.
wordsl4_msgtag_t168   unsigned words() const L4_NOTHROW { return raw & 0x3f; }
169   /// Get the number of typed items.
itemsl4_msgtag_t170   unsigned items() const L4_NOTHROW { return (raw >> 6) & 0x3f; }
171   /**
172    * Get the flags value.
173    *
174    * The flags are a combination of the flags defined by
175    * #l4_msgtag_flags.
176    */
flagsl4_msgtag_t177   unsigned flags() const L4_NOTHROW { return raw & 0xf000; }
178   /// Test if protocol indicates page-fault protocol.
is_page_faultl4_msgtag_t179   bool is_page_fault() const L4_NOTHROW { return label() == L4_PROTO_PAGE_FAULT; }
180   /// Test if protocol indicates preemption protocol.
is_preemptionl4_msgtag_t181   bool is_preemption() const L4_NOTHROW { return label() == L4_PROTO_PREEMPTION; }
182   /// Test if protocol indicates system-exception protocol.
is_sys_exceptionl4_msgtag_t183   bool is_sys_exception() const L4_NOTHROW { return label() == L4_PROTO_SYS_EXCEPTION; }
184   /// Test if protocol indicates exception protocol.
is_exceptionl4_msgtag_t185   bool is_exception() const L4_NOTHROW { return label() == L4_PROTO_EXCEPTION; }
186   /// Test if protocol indicates sigma0 protocol.
is_sigma0l4_msgtag_t187   bool is_sigma0() const L4_NOTHROW { return label() == L4_PROTO_SIGMA0; }
188   /// Test if protocol indicates IO-page-fault protocol.
is_io_page_faultl4_msgtag_t189   bool is_io_page_fault() const L4_NOTHROW { return label() == L4_PROTO_IO_PAGE_FAULT; }
190   /// Test if flags indicate an error.
has_errorl4_msgtag_t191   unsigned has_error() const L4_NOTHROW { return raw & L4_MSGTAG_ERROR; }
192 #endif
193 } l4_msgtag_t;
194 
195 
196 
197 /**
198  * Create a message tag from the specified values.
199  * \ingroup l4_msgtag_api
200  *
201  * \param label  The user-defined label
202  * \param words  The number of untyped words within the UTCB
203  * \param items  The number of typed items (e.g., flex pages) within the UTCB
204  * \param flags  The IPC flags for realtime and FPU extensions
205  *
206  * \return Message tag
207  */
208 L4_INLINE l4_msgtag_t l4_msgtag(long label, unsigned words, unsigned items,
209                                 unsigned flags) L4_NOTHROW;
210 
211 /**
212  * Get the protocol of tag.
213  * \ingroup l4_msgtag_api
214  *
215  * \param t  The tag
216  *
217  * \return Label
218  */
219 L4_INLINE long l4_msgtag_label(l4_msgtag_t t) L4_NOTHROW;
220 
221 /**
222  * Get the number of untyped words.
223  * \ingroup l4_msgtag_api
224  *
225  * \param t  The tag
226  *
227  * \return Number of words
228  */
229 L4_INLINE unsigned l4_msgtag_words(l4_msgtag_t t) L4_NOTHROW;
230 
231 /**
232  * Get the number of typed items.
233  * \ingroup l4_msgtag_api
234  *
235  * \param t  The tag
236  *
237  * \return Number of items.
238  */
239 L4_INLINE unsigned l4_msgtag_items(l4_msgtag_t t) L4_NOTHROW;
240 
241 /**
242  * Get the flags.
243  * \ingroup l4_msgtag_api
244  *
245  * The flag are defined by #l4_msgtag_flags.
246  *
247  * \param t  The tag
248  *
249  * \return Flags
250  */
251 L4_INLINE unsigned l4_msgtag_flags(l4_msgtag_t t) L4_NOTHROW;
252 
253 /**
254  * Test for error indicator flag.
255  * \ingroup l4_msgtag_api
256  *
257  * \param t  The tag
258  *
259  * \return >0 for yes, 0 for no
260  *
261  * Return whether the kernel operation caused a communication error, e.g.
262  * with IPC.
263  * if true: utcb->error is valid, otherwise utcb->error is not valid
264  */
265 L4_INLINE unsigned l4_msgtag_has_error(l4_msgtag_t t) L4_NOTHROW;
266 
267 /**
268  * Test for page-fault protocol.
269  * \ingroup l4_msgtag_api
270  *
271  * \param t  The tag
272  *
273  * \return Boolean value
274  */
275 L4_INLINE unsigned l4_msgtag_is_page_fault(l4_msgtag_t t) L4_NOTHROW;
276 
277 /**
278  * Test for preemption protocol.
279  * \ingroup l4_msgtag_api
280  *
281  * \param t  The tag
282  * \return Boolean value
283  */
284 L4_INLINE unsigned l4_msgtag_is_preemption(l4_msgtag_t t) L4_NOTHROW;
285 
286 /**
287  * Test for system-exception protocol.
288  * \ingroup l4_msgtag_api
289  *
290  * \param t  The tag
291  *
292  * \return Boolean value
293  */
294 L4_INLINE unsigned l4_msgtag_is_sys_exception(l4_msgtag_t t) L4_NOTHROW;
295 
296 /**
297  * Test for exception protocol.
298  * \ingroup l4_msgtag_api
299  *
300  * \param t  The tag
301  *
302  * \return Boolean value
303  */
304 L4_INLINE unsigned l4_msgtag_is_exception(l4_msgtag_t t) L4_NOTHROW;
305 
306 /**
307  * Test for sigma0 protocol.
308  * \ingroup l4_msgtag_api
309  *
310  * \param t  The tag
311  *
312  * \return Boolean value
313  */
314 L4_INLINE unsigned l4_msgtag_is_sigma0(l4_msgtag_t t) L4_NOTHROW;
315 
316 /**
317  * Test for IO-page-fault protocol.
318  * \ingroup l4_msgtag_api
319  *
320  * \param t  The tag
321  *
322  * \return Boolean value
323  */
324 L4_INLINE unsigned l4_msgtag_is_io_page_fault(l4_msgtag_t t) L4_NOTHROW;
325 
326 /**
327  * \defgroup l4_cap_api Capabilities
328  * \ingroup l4_api
329  * C interface for capabilities.
330  *
331  * Add
332  *
333  *     #include <l4/sys/types.h>
334  *     #include <l4/sys/consts.h>
335  *
336  * to your code to use the functions and definitions explained here.
337  */
338 /**
339  * L4 Capability selector Type.
340  * \ingroup l4_cap_api
341  */
342 typedef unsigned long l4_cap_idx_t;
343 
344 /**
345  * Test if a capability selector is the invalid capability.
346  * \ingroup l4_cap_api
347  *
348  * \param c  Capability selector
349  *
350  * \retval 0   The capability selector is not the invalid capability.
351  * \retval >0  The capability selector is the invalid capability.
352  */
353 L4_INLINE unsigned l4_is_invalid_cap(l4_cap_idx_t c) L4_NOTHROW;
354 
355 /**
356  * Test if a capability selector is a valid selector.
357  * \ingroup l4_cap_api
358  *
359  * \param c  Capability selector
360  *
361  * \retval 0   The capability selector is not valid.
362  * \retval >0  The capability selector is valid.
363  */
364 L4_INLINE unsigned l4_is_valid_cap(l4_cap_idx_t c) L4_NOTHROW;
365 
366 /**
367  * Test if two capability selectors are equal.
368  * \ingroup l4_cap_api
369  *
370  * \param c1  Capability
371  * \param c2  Capability
372  *
373  * \retval 0  The given capabilities are not in the same slot.
374  * \retval 1  The given capabilities are in the same slot.
375  */
376 L4_INLINE unsigned l4_capability_equal(l4_cap_idx_t c1, l4_cap_idx_t c2) L4_NOTHROW;
377 
378 /**
379  * Get the next capability selector after `c`.
380  *
381  * \param c  The capability selector for which the next selector shall be
382  *           computed.
383  *
384  * \returns The next capability selector after `c`.
385  */
386 L4_INLINE l4_cap_idx_t l4_capability_next(l4_cap_idx_t c) L4_NOTHROW;
387 
388 /* ************************************************************************* */
389 /* Implementation */
390 
391 L4_INLINE unsigned
l4_is_invalid_cap(l4_cap_idx_t c)392 l4_is_invalid_cap(l4_cap_idx_t c) L4_NOTHROW
393 { return c & L4_INVALID_CAP_BIT; }
394 
395 L4_INLINE unsigned
l4_is_valid_cap(l4_cap_idx_t c)396 l4_is_valid_cap(l4_cap_idx_t c) L4_NOTHROW
397 { return !(c & L4_INVALID_CAP_BIT); }
398 
399 L4_INLINE unsigned
l4_capability_equal(l4_cap_idx_t c1,l4_cap_idx_t c2)400 l4_capability_equal(l4_cap_idx_t c1, l4_cap_idx_t c2) L4_NOTHROW
401 { return (c1 >> L4_CAP_SHIFT) == (c2 >> L4_CAP_SHIFT); }
402 
403 
404 /**
405  * Message tag functions
406  */
407 L4_INLINE
l4_msgtag(long label,unsigned words,unsigned items,unsigned flags)408 l4_msgtag_t l4_msgtag(long label, unsigned words, unsigned items,
409                       unsigned flags) L4_NOTHROW
410 {
411   return (l4_msgtag_t){  (l4_mword_t)((l4_umword_t)label << 16)
412                        | (l4_mword_t)(words & 0x3f)
413                        | (l4_mword_t)((items & 0x3f) << 6)
414                        | (l4_mword_t)(flags & 0xf000)};
415 }
416 
417 
418 
419 L4_INLINE
l4_msgtag_label(l4_msgtag_t t)420 long l4_msgtag_label(l4_msgtag_t t) L4_NOTHROW
421 { return t.raw >> 16; }
422 
423 L4_INLINE
l4_msgtag_words(l4_msgtag_t t)424 unsigned l4_msgtag_words(l4_msgtag_t t) L4_NOTHROW
425 { return t.raw & 0x3f; }
426 
427 L4_INLINE
l4_msgtag_items(l4_msgtag_t t)428 unsigned l4_msgtag_items(l4_msgtag_t t) L4_NOTHROW
429 { return (t.raw >> 6) & 0x3f; }
430 
431 L4_INLINE
l4_msgtag_flags(l4_msgtag_t t)432 unsigned l4_msgtag_flags(l4_msgtag_t t) L4_NOTHROW
433 { return t.raw & 0xf000; }
434 
435 
436 L4_INLINE
l4_msgtag_has_error(l4_msgtag_t t)437 unsigned l4_msgtag_has_error(l4_msgtag_t t) L4_NOTHROW
438 { return t.raw & L4_MSGTAG_ERROR; }
439 
440 
441 
l4_msgtag_is_page_fault(l4_msgtag_t t)442 L4_INLINE unsigned l4_msgtag_is_page_fault(l4_msgtag_t t) L4_NOTHROW
443 { return l4_msgtag_label(t) == L4_PROTO_PAGE_FAULT; }
444 
l4_msgtag_is_preemption(l4_msgtag_t t)445 L4_INLINE unsigned l4_msgtag_is_preemption(l4_msgtag_t t) L4_NOTHROW
446 { return l4_msgtag_label(t) == L4_PROTO_PREEMPTION; }
447 
l4_msgtag_is_sys_exception(l4_msgtag_t t)448 L4_INLINE unsigned l4_msgtag_is_sys_exception(l4_msgtag_t t) L4_NOTHROW
449 { return l4_msgtag_label(t) == L4_PROTO_SYS_EXCEPTION; }
450 
l4_msgtag_is_exception(l4_msgtag_t t)451 L4_INLINE unsigned l4_msgtag_is_exception(l4_msgtag_t t) L4_NOTHROW
452 { return l4_msgtag_label(t) == L4_PROTO_EXCEPTION; }
453 
l4_msgtag_is_sigma0(l4_msgtag_t t)454 L4_INLINE unsigned l4_msgtag_is_sigma0(l4_msgtag_t t) L4_NOTHROW
455 { return l4_msgtag_label(t) == L4_PROTO_SIGMA0; }
456 
l4_msgtag_is_io_page_fault(l4_msgtag_t t)457 L4_INLINE unsigned l4_msgtag_is_io_page_fault(l4_msgtag_t t) L4_NOTHROW
458 { return l4_msgtag_label(t) == L4_PROTO_IO_PAGE_FAULT; }
459 
l4_capability_next(l4_cap_idx_t c)460 L4_INLINE l4_cap_idx_t l4_capability_next(l4_cap_idx_t c) L4_NOTHROW
461 { return c + L4_CAP_OFFSET; }
462 
463 #include <l4/sys/__l4_fpage.h>
464 #include <l4/sys/__timeout.h>
465