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