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
30errval_t cnode_create(struct capref *ret_dest, struct cnoderef *cnoderef,
31                 cslot_t slots, cslot_t *retslots);
32errval_t cnode_create_foreign_l2(struct capref dest_l1, cslot_t dest_slot, struct cnoderef *cnoderef);
33errval_t cnode_create_l2(struct capref *ret_dest, struct cnoderef *cnoderef);
34errval_t cnode_create_l1(struct capref *ret_dest, struct cnoderef *cnoderef);
35errval_t cnode_create_raw(struct capref dest, struct cnoderef *cnoderef,
36                          enum objtype cntype, cslot_t slots, cslot_t *retslots);
37errval_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);
40errval_t cnode_create_from_mem(struct capref dest, struct capref src,
41                               enum objtype cntype, struct cnoderef *cnoderef,
42                               size_t slots);
43
44errval_t root_cnode_resize(struct capref new, struct capref ret);
45
46errval_t cap_retype(struct capref dest_start, struct capref src, gensize_t offset,
47                    enum objtype new_type, gensize_t objsize, size_t count);
48errval_t cap_create(struct capref dest, enum objtype type, size_t bytes);
49errval_t cap_delete(struct capref cap);
50errval_t cap_revoke(struct capref cap);
51struct cspace_allocator;
52errval_t cap_destroy(struct capref cap);
53
54errval_t vnode_create(struct capref dest, enum objtype type);
55errval_t frame_create(struct capref dest, size_t bytes, size_t *retbytes);
56errval_t frame_alloc(struct capref *dest, size_t bytes, size_t *retbytes);
57errval_t devframe_type(struct capref *dest, struct capref src, uint8_t bits);
58errval_t dispatcher_create(struct capref dest);
59
60typedef void (*handler_func_t)(void *);
61struct lmp_endpoint;
62
63errval_t endpoint_create(size_t buflen, struct capref *retcap,
64                         struct lmp_endpoint **retep);
65
66errval_t idcap_alloc(struct capref *dest);
67errval_t idcap_create(struct capref dest);
68
69errval_t cnode_build_cnoderef(struct cnoderef *cnoder, struct capref capr);
70errval_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 */
83static inline errval_t
84cap_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 */
107static inline errval_t
108vnode_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
126static 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
134static inline errval_t vnode_modify_flags(struct capref pgtl,
135        size_t entry, size_t num_pages, uint64_t attr)
136{
137    return invoke_vnode_modify_flags(pgtl, entry, num_pages, attr);
138}
139
140/**
141 * \brief Copy a capability between slots in CSpace
142 *
143 * \param dest    Location of destination slot, which must be empty
144 * \param src     Location of source capability
145 */
146static inline errval_t cap_copy(struct capref dest, struct capref src)
147{
148    errval_t err;
149    capaddr_t dcs_addr = get_croot_addr(dest);
150    capaddr_t dcn_addr = get_cnode_addr(dest);
151    capaddr_t scp_root = get_croot_addr(src);
152    capaddr_t scp_addr = get_cap_addr(src);
153    uint8_t dcn_level  = get_cnode_level(dest);
154    uint8_t scp_level  = get_cap_level(src);
155
156    err = invoke_cnode_copy(cap_root, dcs_addr, dcn_addr, dest.slot, scp_root,
157                            scp_addr, dcn_level, scp_level);
158    return err;
159}
160
161static inline errval_t cap_get_state(struct capref cap, distcap_state_t *state)
162{
163    capaddr_t caddr = get_cap_addr(cap);
164    uint8_t level = get_cap_level(cap);
165
166    return invoke_cnode_get_state(cap_root, caddr, level, state);
167}
168
169__END_DECLS
170
171/**
172 * \brief Identify a frame. This wraps the invocation so we can handle the
173 *        case where the Frame cap is not invokable.
174 * \param cap the capability to identify
175 * \param ret A pointer to a `struct frame_identify` to fill in
176 */
177static inline errval_t frame_identify(struct capref frame, struct frame_identity *ret)
178{
179    errval_t err, err2;
180    struct capref invokable = frame;
181
182    if (get_croot_addr(invokable) != CPTR_ROOTCN) {
183        err = slot_alloc(&invokable);
184        if (err_is_fail(err)) {
185            return err_push(err, LIB_ERR_SLOT_ALLOC);
186        }
187        err = cap_copy(invokable, frame);
188        if (err_is_fail(err)) {
189            return err_push(err, LIB_ERR_CAP_COPY);
190        }
191    }
192
193    err = invoke_frame_identify(invokable, ret);
194
195    if (!capcmp(invokable, frame)) {
196        // made copy earlier, cleanup
197        err2 = cap_destroy(invokable);
198        assert(err_is_ok(err2));
199    }
200
201    return err;
202}
203
204#endif //INCLUDEBARRELFISH_CAPABILITIES_H
205