1/**
2 * Tests cross core cap management
3 *
4 *
5 * Copyright (c) 2010, ETH Zurich.
6 * All rights reserved.
7 *
8 * This file is distributed under the terms in the attached LICENSE file.
9 * If you do not find this file, copies can be found by writing to:
10 * ETH Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group.
11 */
12#include <barrelfish/barrelfish.h>
13#include <stdio.h>
14#include <barrelfish/nameservice_client.h>
15#include <if/xcorecap_defs.h>
16#include "xcorecap.h"
17/* --- Binding handlers --- */
18static void send_cap(struct xcorecap_binding *b, struct capref ram_cap);
19static void retype_cap(struct xcorecap_binding *b);
20static void delete_cap(struct xcorecap_binding *b);
21static void revoke_cap(struct xcorecap_binding *b);
22
23static struct xcorecap_rx_vtbl rx_vtbl = {
24    .send_cap = send_cap,
25    .retype_cap = retype_cap,
26    .delete_cap = delete_cap,
27    .revoke_cap = revoke_cap,
28};
29
30
31/* --- Globals used by message handlers --- */
32static struct capref sent_cap;
33
34
35/* --- Message handlers --- */
36static void send_cap(struct xcorecap_binding *b, struct capref ram_cap)
37{
38    sent_cap = ram_cap;
39
40    printf("xcorecapserv got cap\n");
41    fflush(stdout);
42
43    b->tx_vtbl.send_done(b, NOP_CONT);
44}
45
46static void retype_cap(struct xcorecap_binding *b)
47{
48    errval_t err;
49    struct capref vnode_cap;
50
51    // retype the ram vnode (should fail if retyped on another core)
52    err = slot_alloc(&vnode_cap);
53    if (err_is_fail(err)) {
54        DEBUG_ERR(err, "xcorecapserv: Vnode slot alloc failed\n");
55    }
56    err = cap_retype(vnode_cap, sent_cap, 0, ObjType_VNode_x86_64_ptable,
57                     1UL << ALLOC_BITS, 1);
58    if (err_is_fail(err)) {
59        DEBUG_ERR(err, "xcorecapserv: Retype to vnode failed\n");
60    }
61
62    printf("xcorecapserv retyped cap\n");
63    fflush(stdout);
64
65    b->tx_vtbl.send_done(b, NOP_CONT);
66}
67
68static void delete_cap(struct xcorecap_binding *b)
69{
70    errval_t err;
71    err = cap_delete(sent_cap);
72    if (err_is_fail(err)) {
73        DEBUG_ERR(err, "xcorecapserv: delete failed\n");
74    }
75
76    printf("xcorecapserv deleted cap\n");
77    fflush(stdout);
78
79    b->tx_vtbl.send_done(b, NOP_CONT);
80}
81
82
83static void revoke_cap(struct xcorecap_binding *b)
84{
85    errval_t err;
86    printf("xcorecapserv do revoke cap\n");
87    err = cap_revoke(sent_cap);
88    if (err_is_fail(err)) {
89        DEBUG_ERR(err, "xcorecapserv: revoke failed\n");
90    }
91
92    printf("xcorecapserv revoked cap\n");
93    fflush(stdout);
94
95    b->tx_vtbl.send_done(b, NOP_CONT);
96}
97
98static void export_cb(void *st, errval_t err, iref_t iref)
99{
100    if (err_is_fail(err)) {
101        DEBUG_ERR(err, "export failed");
102        abort();
103    }
104
105    printf("xcorecapserv: service exported at iref %"PRIuIREF"\n", iref);
106    fflush(stdout);
107    // register this iref with the name service
108    err = nameservice_register(my_service_name, iref);
109    if (err_is_fail(err)) {
110        DEBUG_ERR(err, "nameservice_register failed");
111        abort();
112    }
113}
114
115static errval_t connect_cb(void *st, struct xcorecap_binding *b)
116{
117    printf("xcorecapserv service got a connection!\n");
118    fflush(stdout);
119
120    // copy my message receive handler vtable to the binding
121    b->rx_vtbl = rx_vtbl;
122
123    // accept the connection (we could return an error to refuse it)
124    return SYS_ERR_OK;
125}
126
127
128/* --- Setup functions --- */
129static void init(void)
130{
131    errval_t err;
132
133    err = xcorecap_export(NULL, export_cb, connect_cb, get_default_waitset(),
134                          IDC_EXPORT_FLAGS_DEFAULT);
135
136    if (err_is_fail(err)) {
137        DEBUG_ERR(err, "xcorecapserv: Error exporting\n");
138        abort();
139    }
140}
141
142
143int main (int argc, char* argv[])
144{
145    errval_t err;
146
147    init();
148
149    struct waitset *ws = get_default_waitset();
150    while (1) {
151        err = event_dispatch(ws);
152        if (err_is_fail(err)) {
153            DEBUG_ERR(err, "in event_dispatch");
154            break;
155        }
156    }
157
158    return EXIT_FAILURE;
159
160}
161