1 /**
2  * \file
3  * Common constants.
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 __L4_SYS__INCLUDE__CONSTS_H__
27 #define __L4_SYS__INCLUDE__CONSTS_H__
28 
29 #include <l4/sys/compiler.h>
30 #include <l4/sys/l4int.h>
31 
32 /**
33  * Capability selector flags.
34  * \ingroup l4_ipc_api
35  *
36  * These flags determine the concrete operation when a kernel object
37  * is invoked.
38  */
39 enum l4_syscall_flags_t
40 {
41   /**
42    * Default flags (call to a kernel object).
43    * \hideinitializer
44    *
45    * Using this value as flags in the capability selector for an
46    * invocation indicates a call (send and wait for a reply).
47    */
48   L4_SYSF_NONE      = 0x00,
49 
50   /**
51    * Send-phase flag.
52    * \hideinitializer
53    *
54    * Setting this flag in a capability selector induces a send phase,
55    * this means a message is sent to the object denoted by the capability.
56    * For receive phase see #L4_SYSF_RECV.
57    */
58   L4_SYSF_SEND      = 0x01,
59 
60   /**
61    * Receive-phase flag.
62    * \hideinitializer
63    *
64    * Setting this flag in a capability selector induces a receive phase,
65    * this means the invoking thread waits for a message from the object
66    * denoted by the capability.
67    * For a send phase see #L4_SYSF_SEND.
68    */
69   L4_SYSF_RECV      = 0x02,
70 
71   /**
72    * Open-wait flag.
73    * \hideinitializer
74    *
75    * This flag indicates that the receive operation (see #L4_SYSF_RECV)
76    * shall be an \em open \em wait. \em Open \em wait means that the invoking
77    * thread shall wait for a message from any possible sender and \em not from
78    * the sender denoted by the capability.
79    */
80   L4_SYSF_OPEN_WAIT = 0x04,
81 
82   /**
83    * Reply flag.
84    * \hideinitializer
85    *
86    * This flag indicates that the send phase shall use the in-kernel reply
87    * capability instead of the capability denoted by the selector index.
88    */
89   L4_SYSF_REPLY     = 0x08,
90 
91   /**
92    * Call flags (combines send and receive).
93    * \hideinitializer
94    *
95    * Combines #L4_SYSF_SEND and L4_SYSF_RECV.
96    */
97   L4_SYSF_CALL           = L4_SYSF_SEND | L4_SYSF_RECV,
98 
99   /**
100    * Wait flags (combines receive and open wait).
101    * \hideinitializer
102    *
103    * Combines #L4_SYSF_RECV and #L4_SYSF_OPEN_WAIT.
104    */
105   L4_SYSF_WAIT           = L4_SYSF_OPEN_WAIT | L4_SYSF_RECV,
106 
107   /**
108    * Send-and-wait flags.
109    * \hideinitializer
110    *
111    * Combines #L4_SYSF_SEND and #L4_SYSF_WAIT.
112    */
113   L4_SYSF_SEND_AND_WAIT  = L4_SYSF_OPEN_WAIT | L4_SYSF_CALL,
114 
115   /**
116    * Reply-and-wait flags.
117    * \hideinitializer
118    *
119    * Combines #L4_SYSF_SEND, #L4_SYSF_REPLY, and #L4_SYSF_WAIT.
120    */
121   L4_SYSF_REPLY_AND_WAIT = L4_SYSF_WAIT | L4_SYSF_SEND | L4_SYSF_REPLY
122 };
123 
124 /**
125  * Constants related to capability selectors.
126  * \ingroup l4_cap_api
127  */
128 enum l4_cap_consts_t
129 {
130   /** Capability index shift. \hideinitializer */
131   L4_CAP_SHIFT   = 12UL,
132   /** Offset of two consecutive capability selectors. \hideinitializer */
133   L4_CAP_SIZE    = 1UL << L4_CAP_SHIFT,
134   L4_CAP_OFFSET  = 1UL << L4_CAP_SHIFT,
135   /**
136    * Mask to get only the relevant bits of an l4_cap_idx_t.
137    * \hideinitializer
138    */
139   L4_CAP_MASK    = ~0UL << (L4_CAP_SHIFT - 1),
140   /** Invalid capability selector. \hideinitializer */
141   L4_INVALID_CAP = ~0UL << (L4_CAP_SHIFT - 1),
142 
143   L4_INVALID_CAP_BIT = 1UL << (L4_CAP_SHIFT - 1),
144 };
145 
146 enum l4_sched_consts_t
147 {
148   L4_SCHED_MIN_PRIO = 0,
149   L4_SCHED_MAX_PRIO = 255,
150 };
151 
152 /**
153  * Flags for the unmap operation.
154  * \ingroup l4_task_api
155  * \see L4::Task::unmap() and l4_task_unmap()
156  */
157 enum l4_unmap_flags_t
158 {
159   /**
160    * Flag to tell the unmap operation to unmap all child mappings including the
161    * mapping in the invoked task.
162    *
163    * \note Object capabilities are not hierarchical -- they have no children.
164    *       The result of the map operation on an object capability is a copy of
165    *       that capability in the object space of the destination task. An
166    *       unmap operation on object capabilities is a no-op if this flag is
167    *       not specified.
168    * \hideinitializer
169    * \see L4::Task::unmap() l4_task_unmap()
170    */
171   L4_FP_ALL_SPACES   = 0x80000000UL,
172 
173   /**
174    * Flag that indicates that an unmap operation on object capabilities shall
175    * try to delete the corresponding objects.
176    * \hideinitializer
177    * \see L4::Task::unmap() l4_task_unmap()
178    */
179   L4_FP_DELETE_OBJ   = 0xc0000000UL,
180 
181   /**
182    * Counterpart to #L4_FP_ALL_SPACES, unmap only child mappings.
183    * \hideinitializer
184    * \see L4::Task::unmap() l4_task_unmap()
185    */
186   L4_FP_OTHER_SPACES = 0x0UL
187 };
188 
189 /**
190  * Constants for message items.
191  * \ingroup l4_msgitem_api
192  */
193 enum l4_msg_item_consts_t
194 {
195   L4_ITEM_MAP       = 8, ///< Identify a message item as \em map \em item.
196 
197   /**
198    * Denote that the following item shall be put into the same receive item as
199    * this one.
200    */
201   L4_ITEM_CONT      = 1,
202 
203   // send
204   L4_MAP_ITEM_GRANT = 2, ///< Flag as \em grant instead of \em map operation.
205   L4_MAP_ITEM_MAP   = 0, ///< Flag as usual \em map operation.
206 
207   // receive
208   /**
209    * Mark the receive buffer to be a small receive item that describes a buffer
210    * for a single capability.
211    */
212   L4_RCV_ITEM_SINGLE_CAP = L4_ITEM_MAP | 2,
213 
214   /**
215    * The receiver requests to receive a local ID instead of a mapping whenever
216    * possible.
217    */
218   L4_RCV_ITEM_LOCAL_ID   = 4,
219 };
220 
221 /**
222  * Constants for buffer descriptors.
223  * \ingroup l4_utcb_br_api
224  */
225 enum l4_buffer_desc_consts_t
226 {
227   L4_BDR_MEM_SHIFT   = 0,  ///< Bit offset for the memory-buffer index
228   L4_BDR_IO_SHIFT    = 5,  ///< Bit offset for the IO-buffer index
229   L4_BDR_OBJ_SHIFT   = 10, ///< Bit offset for the capability-buffer index
230   L4_BDR_OFFSET_MASK = (1UL << 20) - 1,
231 };
232 
233 /**
234  * \ingroup l4_cap_api
235  * Default capabilities setup for the initial tasks.
236  *
237  * These capability selectors are setup per default by the micro kernel
238  * for the two initial tasks, the Root-Pager (Sigma0) and the Root-Task
239  * (Moe).
240  *
241  * \attention These constants do not have any particular meaning for
242  *            applications started by Moe, see \ref api_l4re_env for
243  *            this kind of information.
244  * \see \ref api_l4re_env for information useful for normal user applications.
245  */
246 enum l4_default_caps_t
247 {
248   /// Capability selector for the current task. \hideinitializer
249   L4_BASE_TASK_CAP      = 1UL << L4_CAP_SHIFT,
250   /// Capability selector for the factory.      \hideinitializer
251   L4_BASE_FACTORY_CAP   = 2UL << L4_CAP_SHIFT,
252   /// Capability selector for the first thread. \hideinitializer
253   L4_BASE_THREAD_CAP    = 3UL << L4_CAP_SHIFT,
254   /**
255    * Capability selector for the pager gate.
256    *
257    * \hideinitializer
258    * For Sigma0, the pager is not present since it never raises page faults.
259    * For Moe, the pager is set to Sigma0.
260    */
261   L4_BASE_PAGER_CAP     = 4UL << L4_CAP_SHIFT,
262   /**
263    * Capability selector for the log object.
264    *
265    * \hideinitializer
266    * Present if the corresponding feature is turned on in the microkernel
267    * configuration.
268    */
269   L4_BASE_LOG_CAP       = 5UL << L4_CAP_SHIFT,
270   /// Capability selector for the base icu object.   \hideinitializer
271   L4_BASE_ICU_CAP       = 6UL << L4_CAP_SHIFT,
272   /// Capability selector for the scheduler cap.   \hideinitializer
273   L4_BASE_SCHEDULER_CAP = 7UL << L4_CAP_SHIFT,
274   /**
275    * Capability selector for the IO-MMU cap.
276    *
277    * \hideinitializer
278    * Present if the microkernel detected an IO-MMU.
279    */
280   L4_BASE_IOMMU_CAP     = 8UL << L4_CAP_SHIFT,
281   /**
282    * Capability selector for the debugger cap.
283    *
284    * \hideinitializer
285    * Present if the corresponding feature is turned on in the microkernel
286    * configuration.
287    */
288   L4_BASE_DEBUGGER_CAP  = 10UL << L4_CAP_SHIFT,
289   /** Capability selector for the ARM SMCCC cap.
290    *
291    * \hideinitializer
292    * Present if the microkernel detected an ARM SMC capable trusted execution
293    * environment.
294    */
295   L4_BASE_ARM_SMCCC_CAP = 11UL << L4_CAP_SHIFT,
296 
297   /// \internal helper must be last before L4_BASE_CAPS_LAST
298   L4_BASE_CAPS_LAST_P1,
299   /// Last capability index used for base capabilities
300   L4_BASE_CAPS_LAST = L4_BASE_CAPS_LAST_P1 - 1
301 };
302 
303 /**
304  * \defgroup l4_memory_api Memory related
305  * Memory related constants, data types and functions.
306  * \ingroup l4_api
307  */
308 /**
309  * Minimal page size (in bytes).
310  * \ingroup l4_memory_api
311  * \hideinitializer
312  */
313 #define L4_PAGESIZE		(1UL << L4_PAGESHIFT)
314 
315 /**
316  * Mask for the page number.
317  * \ingroup l4_memory_api
318  * \hideinitializer
319  *
320  * \note The most significant bits are set.
321  */
322 #define L4_PAGEMASK		(~(L4_PAGESIZE - 1))
323 
324 /**
325  * Number of bits used for page offset.
326  * \ingroup l4_memory_api
327  * \hideinitializer
328  *
329  * Size of page in log2.
330  */
331 #define L4_LOG2_PAGESIZE	L4_PAGESHIFT
332 
333 /**
334  * Size of a large page.
335  * \ingroup l4_memory_api
336  * \hideinitializer
337  *
338  * A large page is a \em super \em page on IA32 or a \em section on ARM.
339  */
340 #define L4_SUPERPAGESIZE	(1UL << L4_SUPERPAGESHIFT)
341 
342 /**
343  * Mask for the number of a large page.
344  * \ingroup l4_memory_api
345  * \hideinitializer
346  *
347  * \note The most significant bits are set.
348  */
349 #define L4_SUPERPAGEMASK	(~(L4_SUPERPAGESIZE - 1))
350 
351 /**
352  * Number of bits used as offset for a large page.
353  * \ingroup l4_memory_api
354  * \hideinitializer
355  * Size of large page in log2
356  */
357 #define L4_LOG2_SUPERPAGESIZE	L4_SUPERPAGESHIFT
358 
359 /**
360  * Round an address down to the next lower page boundary.
361  * \ingroup l4_memory_api
362  *
363  * The address is rounded down to the next lower minimal page boundary. On
364  * most architectures this is a 4k page. Check #L4_PAGESIZE for the minimal
365  * page size.
366  *
367  * \param address  The address to round.
368  */
369 L4_INLINE l4_addr_t l4_trunc_page(l4_addr_t address) L4_NOTHROW;
l4_trunc_page(l4_addr_t address)370 L4_INLINE l4_addr_t l4_trunc_page(l4_addr_t address) L4_NOTHROW
371 { return address & L4_PAGEMASK; }
372 
373 /**
374  * Round an address down to the next lower flex page with size \a bits.
375  * \ingroup l4_memory_api
376  *
377  * \param address  The address to round.
378  * \param bits     The size of the flex page (log2).
379  */
380 L4_INLINE l4_addr_t l4_trunc_size(l4_addr_t address, unsigned char bits) L4_NOTHROW;
l4_trunc_size(l4_addr_t address,unsigned char bits)381 L4_INLINE l4_addr_t l4_trunc_size(l4_addr_t address, unsigned char bits) L4_NOTHROW
382 { return address & (~0UL << bits); }
383 
384 /**
385  * Round address up to the next page.
386  * \ingroup l4_memory_api
387  *
388  * The address is rounded up to the next minimal page boundary. On most
389  * architectures this is a 4k page. Check #L4_PAGESIZE for the minimal page
390  * size.
391  *
392  * \param address  The address to round up.
393  */
394 L4_INLINE l4_addr_t l4_round_page(l4_addr_t address) L4_NOTHROW;
l4_round_page(l4_addr_t address)395 L4_INLINE l4_addr_t l4_round_page(l4_addr_t address) L4_NOTHROW
396 { return (address + L4_PAGESIZE - 1) & L4_PAGEMASK; }
397 
398 /**
399  * Round value up to the next alignment with \a bits size.
400  * \ingroup l4_memory_api
401  *
402  * \param value   The value to round up to the next size-alignment.
403  * \param bits    The size of the alignment (log2).
404  */
405 L4_INLINE l4_addr_t l4_round_size(l4_addr_t value, unsigned char bits) L4_NOTHROW;
l4_round_size(l4_addr_t value,unsigned char bits)406 L4_INLINE l4_addr_t l4_round_size(l4_addr_t value, unsigned char bits) L4_NOTHROW
407 { return (value + (1UL << bits) - 1) & (~0UL << bits); }
408 
409 /**
410  * Determine how many machine words (l4_umword_t) are required to store a
411  * buffer of 'size' bytes.
412  *
413  * \ingroup l4_memory_api
414  *
415  * \param bytes   The number of bytes to be translated into machine words.
416  */
417 L4_INLINE unsigned l4_bytes_to_mwords(unsigned size) L4_NOTHROW;
l4_bytes_to_mwords(unsigned size)418 L4_INLINE unsigned l4_bytes_to_mwords(unsigned size) L4_NOTHROW
419 { return (size + sizeof(l4_umword_t) - 1) / sizeof(l4_umword_t); }
420 
421 /**
422  * Address related constants.
423  * \ingroup l4_memory_api
424  */
425 enum l4_addr_consts_t {
426   /// Invalid address.
427   L4_INVALID_ADDR = ~0UL
428 };
429 
430 /**
431  * Invalid address as pointer type.
432  * \ingroup l4_memory_api
433  */
434 #define L4_INVALID_PTR ((void *)L4_INVALID_ADDR)
435 
436 #ifndef NULL
437 #ifndef __cplusplus
438 # define NULL ((void *)0)  /**< \ingroup l4sys_defines
439                             **  \hideinitializer
440                             ** NULL
441                             **/
442 #else
443 # define NULL 0
444 #endif
445 #endif
446 
447 #endif /* ! __L4_SYS__INCLUDE__CONSTS_H__ */
448