T258: refactor creation of new cspaces to make it cleaner
[barrelfish] / include / barrelfish / capabilities.h
1 /**
2  * \file
3  * \brief Base capability/cnode handling functions.
4  */
5
6 /*
7  * Copyright (c) 2007, 2008, 2009, 2010, 2012, ETH Zurich.
8  * All rights reserved.
9  *
10  * This file is distributed under the terms in the attached LICENSE file.
11  * If you do not find this file, copies can be found by writing to:
12  * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
13  */
14
15 #ifndef INCLUDEBARRELFISH_CAPABILITIES_H
16 #define INCLUDEBARRELFISH_CAPABILITIES_H
17
18 #include <stdint.h>
19 #include <sys/cdefs.h>
20
21 #include <barrelfish_kpi/types.h>
22 #include <barrelfish_kpi/capabilities.h>
23 #include <barrelfish_kpi/dispatcher_shared.h>
24 #include <barrelfish_kpi/distcaps.h>
25 #include <barrelfish/invocations.h>
26 #include <barrelfish/slot_alloc.h>
27
28 __BEGIN_DECLS
29
30 errval_t cnode_create(struct capref *ret_dest, struct cnoderef *cnoderef,
31                  cslot_t slots, cslot_t *retslots);
32 errval_t cnode_create_foreign_l2(struct capref dest_l1, cslot_t dest_slot, struct cnoderef *cnoderef);
33 errval_t cnode_create_l2(struct capref *ret_dest, struct cnoderef *cnoderef);
34 errval_t cnode_create_l1(struct capref *ret_dest, struct cnoderef *cnoderef);
35 errval_t cnode_create_raw(struct capref dest, struct cnoderef *cnoderef,
36                           enum objtype cntype, cslot_t slots, cslot_t *retslots);
37 errval_t cnode_create_with_guard(struct capref dest, struct cnoderef *cnoderef,
38                             cslot_t slots, cslot_t *retslots,
39                             uint64_t guard, uint8_t guard_size);
40 errval_t cnode_create_from_mem(struct capref dest, struct capref src,
41                                enum objtype cntype, struct cnoderef *cnoderef,
42                                size_t slots);
43
44 errval_t root_cnode_resize(struct capref new, struct capref ret);
45
46 errval_t cap_retype(struct capref dest_start, struct capref src, gensize_t offset,
47                     enum objtype new_type, gensize_t objsize, size_t count);
48 errval_t cap_create(struct capref dest, enum objtype type, size_t bytes);
49 errval_t cap_delete(struct capref cap);
50 errval_t cap_revoke(struct capref cap);
51 struct cspace_allocator;
52 errval_t cap_destroy(struct capref cap);
53
54 errval_t vnode_create(struct capref dest, enum objtype type);
55 errval_t frame_create(struct capref dest, size_t bytes, size_t *retbytes);
56 errval_t frame_alloc(struct capref *dest, size_t bytes, size_t *retbytes);
57 errval_t devframe_type(struct capref *dest, struct capref src, uint8_t bits);
58 errval_t dispatcher_create(struct capref dest);
59
60 typedef void (*handler_func_t)(void *);
61 struct lmp_endpoint;
62
63 errval_t endpoint_create(size_t buflen, struct capref *retcap,
64                          struct lmp_endpoint **retep);
65
66 errval_t idcap_alloc(struct capref *dest);
67 errval_t idcap_create(struct capref dest);
68
69 errval_t cnode_build_cnoderef(struct cnoderef *cnoder, struct capref capr);
70 errval_t cnode_build_l1cnoderef(struct cnoderef *cnoder, struct capref capr);
71
72 /**
73  * \brief Mint (Copy changing type-specific parameters) a capability
74  *
75  * \param dest    Location of destination slot, which must be empty
76  * \param src     Location of source slot
77  * \param param1  Type-specific parameter 1
78  * \param param2  Type-specific parameter 2
79  *
80  * Consult the Barrelfish Kernel API Specification for the meaning of the
81  * type-specific parameters.
82  */
83 static inline errval_t
84 cap_mint(struct capref dest, struct capref src, uint64_t param1, uint64_t param2)
85 {
86     capaddr_t dcs_addr = get_croot_addr(dest);
87     capaddr_t dcn_addr = get_cnode_addr(dest);
88     uint8_t dcn_level  = get_cnode_level(dest);
89     capaddr_t scp_root = get_croot_addr(src);
90     capaddr_t scp_addr = get_cap_addr(src);
91     uint8_t scp_level  = get_cap_level(src);
92
93     return invoke_cnode_mint(cap_root, dcs_addr, dcn_addr, dest.slot,
94                              scp_root, scp_addr, dcn_level, scp_level,
95                              param1, param2);
96 }
97
98 /**
99  * \brief Perform mapping operation in kernel by minting a cap to a VNode
100  *
101  * \param dest destination VNode cap
102  * \param src  source Frame cap
103  * \param slot slot in destination VNode
104  * \param attr Architecture-specific page (table) attributes
105  * \param off Offset from source frame to map (must be page-aligned)
106  */
107 static inline errval_t
108 vnode_map(struct capref dest, struct capref src, capaddr_t slot,
109           uint64_t attr, uint64_t off, uint64_t pte_count,
110           struct capref mapping)
111 {
112     assert(get_croot_addr(dest) == CPTR_ROOTCN);
113
114     capaddr_t sroot = get_croot_addr(src);
115     capaddr_t saddr = get_cap_addr(src);
116     uint8_t slevel  = get_cap_level(src);
117
118     uint8_t mcn_level = get_cnode_level(mapping);
119     capaddr_t mcn_addr = get_cnode_addr(mapping);
120     capaddr_t mcn_root = get_croot_addr(mapping);
121
122     return invoke_vnode_map(dest, slot, sroot, saddr, slevel, attr, off, pte_count,
123                             mcn_root, mcn_addr, mcn_level, mapping.slot);
124 }
125
126 static inline errval_t vnode_unmap(struct capref pgtl, struct capref mapping)
127 {
128     capaddr_t mapping_addr = get_cap_addr(mapping);
129     uint8_t level = get_cap_level(mapping);
130
131     return invoke_vnode_unmap(pgtl, mapping_addr, level);
132 }
133
134 /**
135  * \brief Copy a capability between slots in CSpace
136  *
137  * \param dest    Location of destination slot, which must be empty
138  * \param src     Location of source capability
139  */
140 static inline errval_t cap_copy(struct capref dest, struct capref src)
141 {
142     errval_t err;
143     capaddr_t dcs_addr = get_croot_addr(dest);
144     capaddr_t dcn_addr = get_cnode_addr(dest);
145     capaddr_t scp_root = get_croot_addr(src);
146     capaddr_t scp_addr = get_cap_addr(src);
147     uint8_t dcn_level  = get_cnode_level(dest);
148     uint8_t scp_level  = get_cap_level(src);
149
150     err = invoke_cnode_copy(cap_root, dcs_addr, dcn_addr, dest.slot, scp_root,
151                             scp_addr, dcn_level, scp_level);
152     return err;
153 }
154
155 static inline errval_t cap_get_state(struct capref cap, distcap_state_t *state)
156 {
157     capaddr_t caddr = get_cap_addr(cap);
158     uint8_t level = get_cap_level(cap);
159
160     return invoke_cnode_get_state(cap_root, caddr, level, state);
161 }
162
163 __END_DECLS
164
165 /**
166  * \brief Identify a frame. This wraps the invocation so we can handle the
167  *        case where the Frame cap is not invokable.
168  * \param cap the capability to identify
169  * \param ret A pointer to a `struct frame_identify` to fill in
170  */
171 static inline errval_t frame_identify(struct capref frame, struct frame_identity *ret)
172 {
173     errval_t err, err2;
174     struct capref invokable = frame;
175
176     if (get_croot_addr(invokable) != CPTR_ROOTCN) {
177         err = slot_alloc(&invokable);
178         if (err_is_fail(err)) {
179             return err_push(err, LIB_ERR_SLOT_ALLOC);
180         }
181         err = cap_copy(invokable, frame);
182     }
183
184     err = invoke_frame_identify(invokable, ret);
185
186     if (!capcmp(invokable, frame)) {
187         // made copy earlier, cleanup
188         err2 = cap_destroy(invokable);
189         assert(err_is_ok(err2));
190     }
191
192     return err;
193 }
194
195 #endif //INCLUDEBARRELFISH_CAPABILITIES_H