4 * \brief Common flex-page definitions.
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.
29 * \defgroup l4_fpage_api Flex pages
31 * \brief Flex-page related API.
33 * A flex page is a page with a variable size, that can describe memory,
34 * IO-Ports (IA32 only), and sets of kernel objects.
36 * A flex page describes an always size aligned region of an address space.
37 * The size is given in a log2 scale. This means the size in elements (bytes
38 * for memory, ports for IO-Ports, and capabilities for kernel objects) is
39 * always a power of two.
41 * A flex page also carries type and access right information for the
42 * described region. The type information selects the address space in which
43 * the flex page is valid. Access rights have a meaning depending on the
44 * specific address space (type).
46 * There exists a special type for defining \em receive \em windows or for
47 * the l4_task_unmap() method, that can be used to describe all address
48 * spaces (all types) with a single flex page.
52 * \brief L4 flexpage structure
53 * \ingroup l4_fpage_api
57 L4_FPAGE_RIGHTS_SHIFT = 0, ///< Access permissions shift
58 L4_FPAGE_TYPE_SHIFT = 4, ///< Flexpage type shift (memory, IO port, obj...)
59 L4_FPAGE_SIZE_SHIFT = 6, ///< Flexpage size shift (log2-based)
60 L4_FPAGE_ADDR_SHIFT = 12, ///< Page address shift
62 L4_FPAGE_RIGHTS_BITS = 4, ///< Access permissions size
63 L4_FPAGE_TYPE_BITS = 2, ///< Flexpage type size (memory, IO port, obj...)
64 L4_FPAGE_SIZE_BITS = 6, ///< Flexpage size size (log2-based)
65 L4_FPAGE_ADDR_BITS = L4_MWORD_BITS - L4_FPAGE_ADDR_SHIFT, ///< Page address size
68 L4_FPAGE_RIGHTS_MASK = ((1UL << L4_FPAGE_RIGHTS_BITS) - 1) << L4_FPAGE_RIGHTS_SHIFT,
69 L4_FPAGE_TYPE_MASK = ((1UL << L4_FPAGE_TYPE_BITS) - 1) << L4_FPAGE_TYPE_SHIFT,
70 L4_FPAGE_SIZE_MASK = ((1UL << L4_FPAGE_SIZE_BITS) - 1) << L4_FPAGE_SIZE_SHIFT,
71 L4_FPAGE_ADDR_MASK = ((1UL << L4_FPAGE_ADDR_BITS) - 1) << L4_FPAGE_ADDR_SHIFT,
75 * \brief L4 flexpage type
76 * \ingroup l4_fpage_api
79 l4_umword_t fpage; ///< Raw value
80 l4_umword_t raw; ///< Raw value
83 /** \brief Constants for flexpages
84 * \ingroup l4_fpage_api
88 L4_WHOLE_ADDRESS_SPACE = 63 /**< Whole address space size */
92 * \brief Send-flex-page types
93 * \ingroup l4_fpage_api
96 l4_umword_t snd_base; ///< Offset in receive window (send base)
97 l4_fpage_t fpage; ///< Source flex-page descriptor
101 /** \brief Flex-page rights
102 * \ingroup l4_fpage_api
106 L4_FPAGE_RO = 4, /**< Read-only flex page */
107 L4_FPAGE_RW = 6, /**< Read-write flex page */
114 /** \brief Cap-flex-page rights
115 * \ingroup l4_fpage_api
117 enum L4_cap_fpage_rights
119 L4_CAP_FPAGE_R = 0x4, /**< Read-only cap */
120 L4_CAP_FPAGE_RO = 0x4, /**< Read-only cap */
121 L4_CAP_FPAGE_RW = 0x5, /**< Read-write cap */
122 L4_CAP_FPAGE_RS = 0x6,
123 L4_CAP_FPAGE_RWS = 0x7,
124 L4_CAP_FPAGE_S = 0x2,
125 L4_CAP_FPAGE_W = 0x1,
126 L4_CAP_FPAGE_D = 0x8,
127 L4_CAP_FPAGE_RWSD = 0xf,
128 L4_CAP_FPAGE_RSD = 0xe,
131 /** \brief Flex-page type
132 * \ingroup l4_fpage_api
136 L4_FPAGE_SPECIAL = 0,
142 /** \brief Flex-page map control flags
143 * \ingroup l4_fpage_api
145 enum L4_fpage_control
147 L4_FPAGE_CONTROL_OFFSET_SHIFT = 10,
148 L4_FPAGE_CONTROL_MASK = ~0UL << L4_FPAGE_CONTROL_OFFSET_SHIFT,
151 /** \brief Flex-page map control for capabilities (snd_base)
152 * \ingroup l4_fpage_api
154 enum L4_obj_fpage_ctl
156 L4_FPAGE_C_NO_REF_CNT = 0x10,
157 L4_FPAGE_C_REF_CNT = 0x00,
161 /** \brief Flex-page cacheability option
162 * \ingroup l4_fpage_api
164 enum l4_fpage_cacheability_opt_t
166 /** Enable the cacheability option in a send flex page. */
167 L4_FPAGE_CACHE_OPT = 0x1,
169 /** Cacheability option to enable caches for the mapping. */
170 L4_FPAGE_CACHEABLE = 0x3,
172 /** Cacheability option to enable buffered writes for the mapping. */
173 L4_FPAGE_BUFFERABLE = 0x5,
175 /** Cacheability option to disable caching for the mapping. */
176 L4_FPAGE_UNCACHEABLE = 0x1
180 /** \brief Special constants for IO flex pages
181 * \ingroup l4_fpage_api
185 /** Whole I/O address space size */
186 L4_WHOLE_IOADDRESS_SPACE = 16,
188 /** Maximum I/O port address */
189 L4_IOPORT_MAX = (1L << L4_WHOLE_IOADDRESS_SPACE)
195 * \brief Create a memory flex page.
196 * \ingroup l4_fpage_api
198 * \param address Flex-page start address
199 * \param size Flex-page size (log2), #L4_WHOLE_ADDRESS_SPACE to
200 * specify the whole address space (with \a address 0)
201 * \param rights Access rights, see #l4_fpage_rights
202 * \return Memory flex page
205 l4_fpage(unsigned long address, unsigned int size, unsigned char rights) L4_NOTHROW;
208 * \brief Get a flex page, describing all address spaces at once.
209 * \ingroup l4_fpage_api
211 * \return Special \em all-spaces flex page.
214 l4_fpage_all(void) L4_NOTHROW;
217 * \brief Get an invalid flex page.
218 * \ingroup l4_fpage_api
220 * \return Special \em invalid flex page.
223 l4_fpage_invalid(void) L4_NOTHROW;
227 * \brief Create an IO-port flex page.
228 * \ingroup l4_fpage_api
230 * \param port I/O-flex-page port base
231 * \param size I/O-flex-page size, #L4_WHOLE_IOADDRESS_SPACE to
232 * specify the whole I/O address space (with \a port 0)
233 * \return I/O flex page
236 l4_iofpage(unsigned long port, unsigned int size) L4_NOTHROW;
240 * \brief Create a kernel-object flex page.
241 * \ingroup l4_fpage_api
243 * \param obj Base capability selector.
244 * \param order Log2 size (number of capabilities).
245 * \param rights Access rights
246 * \return Flex page for a set of kernel objects.
248 * \todo What are the possible values for the rights parameter?
251 l4_obj_fpage(l4_cap_idx_t obj, unsigned int order, unsigned char rights) L4_NOTHROW;
254 * \brief Test if the flex page is writable.
255 * \ingroup l4_fpage_api
257 * \param fp Flex page.
258 * \return != 0 if flex page is writable, 0 if not
261 l4_is_fpage_writable(l4_fpage_t fp) L4_NOTHROW;
265 * \defgroup l4_msgitem_api Message Items
266 * \ingroup l4_ipc_api
267 * \brief Message item related functions.
269 * Message items are typed items that can be transferred via IPC
270 * operations. Message items are also used to specify receive windows for
271 * typed items to be received.
272 * Message items are placed in the message registers (MRs) of the UTCB of
273 * the sending thread.
274 * Receive items are placed in the buffer registers (BRs) of the UTCB
275 * of the receiving thread.
277 * Message items are usually two-word data structures. The first
278 * word denotes the type of the message item (for example a memory flex-page,
279 * io flex-page or object flex-page) and the second word contains
280 * information depending on the type. There is actually one exception that is
281 * a small (one word) receive buffer item for a single capability.
285 * \brief Create the first word for a map item for the memory space.
286 * \ingroup l4_msgitem_api
288 * \param spot Hot spot address, used to determine what is actually mapped
289 * when send and receive flex page have differing sizes.
290 * \param cache Cacheability hints for memory flex pages. See
291 * \link l4_fpage_api::l4_fpage_cacheability_opt_t
292 * Cacheability options \endlink
293 * \param grant Indicates if it is a map or a grant item.
295 * \return The value to be used as first word in a map item for memory.
297 L4_INLINE l4_umword_t
298 l4_map_control(l4_umword_t spot, unsigned char cache, unsigned grant) L4_NOTHROW;
301 * \brief Create the first word for a map item for the object space.
302 * \ingroup l4_msgitem_api
304 * \param spot Hot spot address, used to determine what is actually mapped
305 * when send and receive flex pages have different size.
306 * \param grant Indicates if it is a map item or a grant item.
308 * \return The value to be used as first word in a map item for kernel objects
311 L4_INLINE l4_umword_t
312 l4_map_obj_control(l4_umword_t spot, unsigned grant) L4_NOTHROW;
315 * \brief Return rights from a flex page.
316 * \ingroup l4_fpage_api
319 * \return Size part of the given flex page.
322 l4_fpage_rights(l4_fpage_t f) L4_NOTHROW;
325 * \brief Return type from a flex page.
326 * \ingroup l4_fpage_api
329 * \return Type part of the given flex page.
332 l4_fpage_type(l4_fpage_t f) L4_NOTHROW;
335 * \brief Return size from a flex page.
336 * \ingroup l4_fpage_api
339 * \return Size part of the given flex page.
342 l4_fpage_size(l4_fpage_t f) L4_NOTHROW;
345 * \brief Return page from a flex page.
346 * \ingroup l4_fpage_api
349 * \return Page part of the given flex page.
351 L4_INLINE unsigned long
352 l4_fpage_page(l4_fpage_t f) L4_NOTHROW;
355 * \brief Set new right in a flex page.
356 * \ingroup l4_fpage_api
358 * \param src Flex page
359 * \param new_rights New rights
361 * \return Modified flex page with new rights.
364 l4_fpage_set_rights(l4_fpage_t src, unsigned char new_rights) L4_NOTHROW;
367 * \brief Test whether a given range is completely within an fpage.
368 * \ingroup l4_fpage_api
370 * \param fpage Flex page
371 * \param addr Address
372 * \param size Size of range in log2.
375 l4_fpage_contains(l4_fpage_t fpage, l4_addr_t addr, unsigned size) L4_NOTHROW;
378 * \brief Determine maximum flex page size of a region.
379 * \ingroup l4_fpage_api
381 * \param order Order value to start with (e.g. for memory
382 * L4_LOG2_PAGESIZE would be used)
383 * \param addr Address to be covered by the flex page.
384 * \param min_addr Start of region / minimal address (including).
385 * \param max_addr End of region / maximal address (excluding).
386 * \param hotspot (Optional) hot spot.
388 * \return Maximum order (log2-size) possible.
390 * \note The start address of the flex-page can be determined with
391 * l4_trunc_size(addr, returnvalue)
393 L4_INLINE unsigned char
394 l4_fpage_max_order(unsigned char order, l4_addr_t addr,
395 l4_addr_t min_addr, l4_addr_t max_addr,
396 l4_addr_t hotspot L4_DEFAULT_PARAM(0));
398 /*************************************************************************
400 *************************************************************************/
403 l4_fpage_rights(l4_fpage_t f) L4_NOTHROW
405 return (f.raw & L4_FPAGE_RIGHTS_MASK) >> L4_FPAGE_RIGHTS_SHIFT;
409 l4_fpage_type(l4_fpage_t f) L4_NOTHROW
411 return (f.raw & L4_FPAGE_TYPE_MASK) >> L4_FPAGE_TYPE_SHIFT;
415 l4_fpage_size(l4_fpage_t f) L4_NOTHROW
417 return (f.raw & L4_FPAGE_SIZE_MASK) >> L4_FPAGE_SIZE_SHIFT;
420 L4_INLINE unsigned long
421 l4_fpage_page(l4_fpage_t f) L4_NOTHROW
423 return (f.raw & L4_FPAGE_ADDR_MASK) >> L4_FPAGE_ADDR_SHIFT;
428 __l4_fpage_generic(unsigned long address, unsigned int type,
429 unsigned int size, unsigned char rights) L4_NOTHROW;
432 __l4_fpage_generic(unsigned long address, unsigned int type,
433 unsigned int size, unsigned char rights) L4_NOTHROW
436 t.raw = ((rights << L4_FPAGE_RIGHTS_SHIFT) & L4_FPAGE_RIGHTS_MASK)
437 | ((type << L4_FPAGE_TYPE_SHIFT) & L4_FPAGE_TYPE_MASK)
438 | ((size << L4_FPAGE_SIZE_SHIFT) & L4_FPAGE_SIZE_MASK)
439 | ((address ) & L4_FPAGE_ADDR_MASK);
444 l4_fpage_set_rights(l4_fpage_t src, unsigned char new_rights) L4_NOTHROW
447 f.raw = ((L4_FPAGE_TYPE_MASK | L4_FPAGE_SIZE_MASK | L4_FPAGE_ADDR_MASK) & src.raw)
448 | ((new_rights << L4_FPAGE_RIGHTS_SHIFT) & L4_FPAGE_RIGHTS_MASK);
453 l4_fpage(unsigned long address, unsigned int size, unsigned char rights) L4_NOTHROW
455 return __l4_fpage_generic(address, L4_FPAGE_MEMORY, size, rights);
459 l4_iofpage(unsigned long port, unsigned int size) L4_NOTHROW
461 return __l4_fpage_generic(port << L4_FPAGE_ADDR_SHIFT, L4_FPAGE_IO, size, L4_FPAGE_RW);
465 l4_obj_fpage(l4_cap_idx_t obj, unsigned int order, unsigned char rights) L4_NOTHROW
467 return __l4_fpage_generic(obj, L4_FPAGE_OBJ, order, rights);
471 l4_fpage_all(void) L4_NOTHROW
473 return __l4_fpage_generic(0, 0, L4_WHOLE_ADDRESS_SPACE, 0);
477 l4_fpage_invalid(void) L4_NOTHROW
479 return __l4_fpage_generic(0, 0, 0, 0);
484 l4_is_fpage_writable(l4_fpage_t fp) L4_NOTHROW
486 return l4_fpage_rights(fp) & L4_FPAGE_W;
489 L4_INLINE l4_umword_t
490 l4_map_control(l4_umword_t snd_base, unsigned char cache, unsigned grant) L4_NOTHROW
492 return (snd_base & L4_FPAGE_CONTROL_MASK)
493 | ((l4_umword_t)cache << 4) | L4_ITEM_MAP | grant;
496 L4_INLINE l4_umword_t
497 l4_map_obj_control(l4_umword_t snd_base, unsigned grant) L4_NOTHROW
499 return l4_map_control(snd_base, 0, grant);
503 l4_fpage_contains(l4_fpage_t fpage, l4_addr_t addr, unsigned log2size) L4_NOTHROW
505 l4_addr_t fa = l4_fpage_page(fpage) << L4_FPAGE_ADDR_SHIFT;
507 && (fa + (1UL << l4_fpage_size(fpage)) >= addr + (1UL << log2size));
510 L4_INLINE unsigned char
511 l4_fpage_max_order(unsigned char order, l4_addr_t addr,
512 l4_addr_t min_addr, l4_addr_t max_addr,
515 while (order < 30 /* limit to 1GB flexpages */)
518 l4_addr_t base = l4_trunc_size(addr, order + 1);
522 if (base + (1UL << (order + 1)) - 1 > max_addr - 1)
525 mask = ~(~0UL << (order + 1));
526 if (hotspot == ~0UL || ((addr ^ hotspot) & mask))