added entries to gitignore
[barrelfish] / include / barrelfish / caddr.h
1 /**
2  * \file
3  * \brief Inline functions to allow manipulation of raw capability addresses
4  *
5  * This file is not part of the standard includes, because most user code should
6  * treat #capref as an opaque value.
7  */
8
9 /*
10  * Copyright (c) 2007, 2008, 2009, 2010, 2012, ETH Zurich.
11  * All rights reserved.
12  *
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.
16  */
17
18 #ifndef INCLUDEBARRELFISH_CADDR_H
19 #define INCLUDEBARRELFISH_CADDR_H
20
21 #include <stdbool.h>
22 #include <sys/cdefs.h>
23
24 #include <barrelfish_kpi/types.h>
25
26 __BEGIN_DECLS
27
28 #include <stdbool.h>
29
30 /**
31  * \brief User-level representation of a CNode, its CSpace address and size
32  */
33 struct cnoderef {
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));
39
40 #define NULL_CNODE (struct cnoderef){ /*address*/ 0, /*address_bits*/ 0, \
41                                       /*size_bits*/ 0, /*guard_size*/ 0 }
42
43 /**
44  * \brief User-level representation of a capability and its CSpace address
45  */
46
47 struct capref {
48     struct cnoderef cnode;    ///< CNode this cap resides in
49     capaddr_t slot;               ///< Slot number within CNode
50 };
51
52 #define NULL_CAP (struct capref){ /*cnode*/ NULL_CNODE, /*slot*/ 0 }
53
54 static inline bool capref_is_null(struct capref capref)
55 {
56     return capref.cnode.address == 0 && capref.cnode.address_bits == 0;
57 }
58
59 /* well-known cnodes */
60 extern struct cnoderef cnode_root, cnode_task, cnode_base,
61     cnode_super, cnode_page, cnode_module;
62
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;
66
67 /**
68  * \brief Returns the number of valid bits in the CSpace address of a cap
69  */
70 static inline uint8_t get_cap_valid_bits(struct capref cap)
71 {
72     uint8_t sum = cap.cnode.address_bits + cap.cnode.guard_size +
73         cap.cnode.size_bits;
74     if (sum > CPTR_BITS) {
75         return sum % CPTR_BITS;
76     } else {
77         return sum;
78     }
79 }
80
81 /**
82  * \brief Returns the CSpace address of a cap
83  */
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)
89 #else
90 static inline capaddr_t get_cap_addr(struct capref cap)
91 #endif
92 {
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);
96     } else {
97         return cap.cnode.address | (cap.slot << (CPTR_BITS - vbits));
98     }
99 }
100
101 /**
102  * \brief Returns the number of valid bits in the CSpace address of the CNode
103  *        containing the given cap
104  */
105 static inline uint8_t get_cnode_valid_bits(struct capref cap)
106 {
107     return cap.cnode.address_bits;
108 }
109
110 /**
111  * \brief Returns the CSpace address of the CNode containing the given cap
112  *
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.
115  */
116 static inline capaddr_t get_cnode_addr(struct capref cap)
117 {
118     return cap.cnode.address >> (CPTR_BITS - cap.cnode.address_bits);
119 }
120
121 /**
122  * \brief Compare two cnoderefs
123  *
124  * Two cnoderefs are equal if they have the same base address,
125  * same number of valid bits and the same guard_size.
126  */
127 static inline bool cnodecmp(struct cnoderef c1, struct cnoderef c2)
128 {
129     return ((c1.address == c2.address) &&
130             (c1.address_bits == c2.address_bits) &&
131             (c1.guard_size == c2.guard_size));
132 }
133
134 /**
135  * \brief Compare two caprefs
136  *
137  * Two caprefs are equal if they have the same cnoderef and the same
138  * slot.
139  */
140 static inline bool capcmp(struct capref c1, struct capref c2)
141 {
142     return (c1.slot == c2.slot) && cnodecmp(c1.cnode, c2.cnode);
143 }
144
145 /**
146  * \brief Creates a new #cnoderef struct, performing address calculations.
147  */
148 static inline struct cnoderef build_cnoderef(struct capref cap,
149                                              uint8_t size_bits)
150 {
151     struct cnoderef ret;
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
157     return ret;
158 }
159
160 __END_DECLS
161
162 #endif