1/*
2 * Copyright (c) 2012, ETH Zurich.
3 * All rights reserved.
4 *
5 * This file is distributed under the terms in the attached LICENSE file.
6 * If you do not find this file, copies can be found by writing to:
7 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
8 */
9
10#include <send_cap.h>
11#include <capops.h>
12#include <barrelfish/debug.h>
13#include <monitor_invocations.h>
14#include <string.h>
15#include "monitor_debug.h"
16
17static void
18captx_prepare_copy_result_cont(errval_t status, capaddr_t cnaddr,
19                               uint8_t cnlevel, cslot_t slot, void *st_)
20{
21    struct captx_prepare_state *st = (struct captx_prepare_state*)st_;
22    if (err_is_ok(status)) {
23        st->captx.cnptr = cnaddr;
24        st->captx.cnlevel = cnlevel;
25        st->captx.slot = slot;
26    }
27    intermon_captx_t *tx = err_is_ok(status) ? &st->captx : NULL;
28    DEBUG_CAPOPS("%s: st->send_cont = %p\n", __FUNCTION__, st->send_cont);
29    st->send_cont(status, st, tx, st->st);
30}
31
32void
33captx_prepare_send(struct capref cap, coreid_t dest, bool give_away,
34                   struct captx_prepare_state *state, captx_send_cont send_cont,
35                   void *st)
36{
37    assert(state);
38    assert(send_cont);
39    memset(state, 0, sizeof(*state));
40    state->send_cont = send_cont;
41    state->st = st;
42    capops_copy(cap, dest, give_away, captx_prepare_copy_result_cont, state);
43}
44
45static errval_t
46captx_get_capref(capaddr_t cnaddr, uint8_t cnlevel, cslot_t slot,
47                 struct capref *ret)
48{
49    errval_t err;
50
51    if (cnaddr == 0 && cnlevel == 0 && slot == 0) {
52        // got a null cap, return null capref
53        *ret = NULL_CAP;
54        return SYS_ERR_OK;
55    }
56
57    struct capability cnode_cap;
58    err = invoke_monitor_identify_cap(cnaddr, cnlevel, &cnode_cap);
59    if (err_is_fail(err)) {
60        return err;
61    }
62    if (cnode_cap.type != ObjType_L1CNode &&
63        cnode_cap.type != ObjType_L2CNode) {
64        return SYS_ERR_CNODE_TYPE;
65    }
66
67    *ret = (struct capref) {
68        .cnode = {
69            .cnode = cnaddr,
70            .level = cnlevel,
71            .croot = CPTR_ROOTCN,
72        },
73        .slot = slot,
74    };
75
76    return SYS_ERR_OK;
77}
78
79void
80captx_handle_recv(intermon_captx_t *captx, struct captx_recv_state *state,
81                  captx_recv_cont recv_cont, void *st)
82{
83    DEBUG_CAPOPS("%s\n", __FUNCTION__);
84    assert(state);
85    assert(recv_cont);
86    errval_t err;
87
88    struct capref cap;
89    err = captx_get_capref(captx->cnptr, captx->cnlevel, captx->slot, &cap);
90
91    recv_cont(err, state, cap, st);
92}
93