3 * \brief Inline functions to allow manipulation of raw capability addresses
5 * This file is not part of the standard includes, because most user code should
6 * treat #capref as an opaque value.
10 * Copyright (c) 2007, 2008, 2009, 2010, 2012, ETH Zurich.
11 * All rights reserved.
13 * This file is distributed under the terms in the attached LICENSE file.
14 * If you do not find this file, copies can be found by writing to:
15 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
18 #ifndef INCLUDEBARRELFISH_CADDR_H
19 #define INCLUDEBARRELFISH_CADDR_H
22 #include <sys/cdefs.h>
24 #include <barrelfish_kpi/types.h>
31 * \brief User-level representation of a CNode, its CSpace address and size
34 capaddr_t address; ///< Base address of CNode in CSpace
35 uint8_t address_bits; ///< Number of valid bits in base address
36 uint8_t size_bits; ///< Number of slots in the CNode as a power of 2
37 uint8_t guard_size; ///< Guard size of the CNode
38 } __attribute__((packed));
40 #define NULL_CNODE (struct cnoderef){ /*address*/ 0, /*address_bits*/ 0, \
41 /*size_bits*/ 0, /*guard_size*/ 0 }
44 * \brief User-level representation of a capability and its CSpace address
48 struct cnoderef cnode; ///< CNode this cap resides in
49 capaddr_t slot; ///< Slot number within CNode
52 #define NULL_CAP (struct capref){ /*cnode*/ NULL_CNODE, /*slot*/ 0 }
54 static inline bool capref_is_null(struct capref capref)
56 return capref.cnode.address == 0 && capref.cnode.address_bits == 0;
59 /* well-known cnodes */
60 extern struct cnoderef cnode_root, cnode_task, cnode_base,
61 cnode_super0, cnode_super1, cnode_page, cnode_module;
63 /* well-known capabilities */
64 extern struct capref cap_root, cap_monitorep, cap_irq, cap_io, cap_dispatcher,
65 cap_selfep, cap_kernel, cap_initep, cap_perfmon, cap_dispframe, cap_sessionid;
68 * \brief Returns the number of valid bits in the CSpace address of a cap
70 static inline uint8_t get_cap_valid_bits(struct capref cap)
72 uint8_t sum = cap.cnode.address_bits + cap.cnode.guard_size +
74 if (sum > CPTR_BITS) {
75 return sum % CPTR_BITS;
82 * \brief Returns the CSpace address of a cap
84 // XXX: workaround for an inlining bug in gcc 4.4.1 as shipped with ubuntu 9.10
85 // XXX: bug still present in 4.4.3
86 #if defined(__GNUC__) \
87 && __GNUC__ == 4 && __GNUC_MINOR__ == 4 && __GNUC_PATCHLEVEL__ <= 3
88 static __attribute__((noinline)) capaddr_t get_cap_addr(struct capref cap)
90 static inline capaddr_t get_cap_addr(struct capref cap)
93 uint8_t vbits = get_cap_valid_bits(cap);
94 if (cap.cnode.address_bits == CPTR_BITS) { // special case for root
95 return cap.slot << (CPTR_BITS - vbits);
97 return cap.cnode.address | (cap.slot << (CPTR_BITS - vbits));
102 * \brief Returns the number of valid bits in the CSpace address of the CNode
103 * containing the given cap
105 static inline uint8_t get_cnode_valid_bits(struct capref cap)
107 return cap.cnode.address_bits;
111 * \brief Returns the CSpace address of the CNode containing the given cap
113 * Returns the valid bits of the address only, in the least significant bits
114 * of the result. This is the format needed for CNode invocation parameters.
116 static inline capaddr_t get_cnode_addr(struct capref cap)
118 return cap.cnode.address >> (CPTR_BITS - cap.cnode.address_bits);
122 * \brief Compare two cnoderefs
124 * Two cnoderefs are equal if they have the same base address,
125 * same number of valid bits and the same guard_size.
127 static inline bool cnodecmp(struct cnoderef c1, struct cnoderef c2)
129 return ((c1.address == c2.address) &&
130 (c1.address_bits == c2.address_bits) &&
131 (c1.guard_size == c2.guard_size));
135 * \brief Compare two caprefs
137 * Two caprefs are equal if they have the same cnoderef and the same
140 static inline bool capcmp(struct capref c1, struct capref c2)
142 return (c1.slot == c2.slot) && cnodecmp(c1.cnode, c2.cnode);
146 * \brief Creates a new #cnoderef struct, performing address calculations.
148 static inline struct cnoderef build_cnoderef(struct capref cap,
152 ret.address = get_cap_addr(cap);
153 ret.address_bits = (cap.cnode.address_bits + cap.cnode.guard_size +
154 cap.cnode.size_bits) % CPTR_BITS;
155 ret.size_bits = size_bits;
156 ret.guard_size = 0; // XXX