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