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 <if/xcorecap_defs.h> 15#include <barrelfish/nameservice_client.h> 16#include <trace/trace.h> 17#include <trace_definitions/trace_defs.h> 18#include "xcorecap.h" 19 20/* --- Binding handlers --- */ 21static void state_machine(struct xcorecap_binding *b); 22 23struct xcorecap_rx_vtbl rx_vtbl = { 24 .send_done = state_machine, 25}; 26 27/* --- Client functions --- */ 28static void create_ram_cap(struct capref * ram_cap) { 29 errval_t err; 30 31 // allocate some ram 32 err = ram_alloc(ram_cap, ALLOC_BITS); 33 if (err_is_fail(err)) { 34 DEBUG_ERR(err, "xcorecap: RAM alloc failed\n"); 35 } 36} 37 38static errval_t retype_cap(struct capref * ram_cap, struct capref * frame_cap) 39{ 40 errval_t err; 41 42 // retype this to a frame 43 err = slot_alloc(frame_cap); 44 if (err_is_fail(err)) { 45 DEBUG_ERR(err, "xcorecap: Frame slot alloc failed\n"); 46 } 47 48 err = cap_retype(*frame_cap, *ram_cap, 0, ObjType_Frame, 1UL << ALLOC_BITS, 1); 49 if (err_is_fail(err)) { 50 DEBUG_ERR(err, "xcorecap: Retype to frame failed\n"); 51 } 52 53 return err; 54} 55 56/* --- Globals used by stack-ripped functions --- */ 57struct capref ram_cap, frame_cap; 58 59/* --- Stack-ripped message handlers --- */ 60static void send_cap(struct xcorecap_binding *b) 61{ 62 create_ram_cap(&ram_cap); 63 64 trace_event(TRACE_SUBSYS_BENCH, TRACE_EVENT_BENCH_PCBENCH, 1); 65 66 /* send cap */ 67 errval_t err = b->tx_vtbl.send_cap(b, NOP_CONT, ram_cap); 68 69 if (err_is_fail(err)) { 70 DEBUG_ERR(err, "sendcap failed"); 71 abort(); 72 } 73} 74 75static void trigger_remote_retype(void *arg) 76{ 77 struct xcorecap_binding *b = arg; 78 /* Trigger remote retype */ 79 errval_t err = b->tx_vtbl.retype_cap(b, NOP_CONT); 80 81 if (err_is_fail(err)) { 82 if (err_no(err) == FLOUNDER_ERR_TX_BUSY) { 83 struct waitset *ws = get_default_waitset(); 84 err = b->register_send(b, ws, MKCONT(trigger_remote_retype, b)); 85 if (err_is_fail(err)) { 86 // note that only one continuation may be registered at a time 87 DEBUG_ERR(err, "register_send on binding failed!"); 88 abort(); 89 } 90 } else { 91 DEBUG_ERR(err, "trigger retype failed"); 92 abort(); 93 } 94 } 95} 96 97static void trigger_remote_delete(void *arg) 98{ 99 struct xcorecap_binding *b = arg; 100 101 /* Trigger remote delete */ 102 errval_t err = b->tx_vtbl.delete_cap(b, NOP_CONT); 103 104 if (err_is_fail(err)) { 105 if (err_no(err) == FLOUNDER_ERR_TX_BUSY) { 106 struct waitset *ws = get_default_waitset(); 107 err = b->register_send(b, ws, MKCONT(trigger_remote_delete,b)); 108 if (err_is_fail(err)) { 109 // note that only one continuation may be registered at a time 110 DEBUG_ERR(err, "register_send on binding failed!"); 111 abort(); 112 } 113 } else { 114 DEBUG_ERR(err, "trigger retype failed"); 115 abort(); 116 } 117 } 118} 119 120static void trigger_remote_revoke(void *arg) 121{ 122 struct xcorecap_binding *b = arg; 123 124 /* Trigger remote revoke */ 125 errval_t err = b->tx_vtbl.revoke_cap(b, NOP_CONT); 126 127 if (err_is_fail(err)) { 128 if (err_no(err) == FLOUNDER_ERR_TX_BUSY) { 129 struct waitset *ws = get_default_waitset(); 130 err = b->register_send(b, ws, MKCONT(trigger_remote_revoke, b)); 131 if (err_is_fail(err)) { 132 // note that only one continuation may be registered at a time 133 DEBUG_ERR(err, "register_send on binding failed!"); 134 abort(); 135 } 136 } else { 137 DEBUG_ERR(err, "trigger retype failed"); 138 abort(); 139 } 140 } 141} 142 143 144static void state_machine(struct xcorecap_binding *b) 145{ 146 static int state = 0; 147 148 switch(state) { 149 case 0: 150 printf("xcorecap sending cap\n"); 151 send_cap(b); 152 state++; 153 break; 154 155 case 1: 156 printf("xcorecap performing local retype\n"); 157 errval_t err = retype_cap(&ram_cap, &frame_cap); 158 if (err_is_fail(err)) { 159 DEBUG_ERR(err, "retype failed"); 160 abort(); 161 } 162 printf("xcorecap trigger remote cap retype\n"); 163 trigger_remote_retype(b); 164 state++; 165 break; 166 167 case 2: 168 printf("xcorecap trigger remote cap revoke\n"); 169 trigger_remote_revoke(b); 170 state++; 171 break; 172 173 case 3: 174 printf("xcorecap sending another cap\n"); 175 send_cap(b); 176 state++; 177 break; 178 179 case 4: 180 printf("xcorecap delete remote cap\n"); 181 trigger_remote_delete(b); 182 state++; 183 break; 184 185 case 5: 186 printf("xcorecap on core %i done\n", disp_get_core_id()); 187 exit(0); 188 break; 189 190 default: 191 printf("got into incorrect state of %d\n", state); 192 break; 193 } 194} 195 196static void bind_cb(void *st, errval_t err, struct xcorecap_binding *b) 197{ 198 printf ("xcorecap: connected to server...\n"); 199 b->rx_vtbl = rx_vtbl; 200 201 // start test 202 state_machine(b); 203} 204 205/* --- Setup functions --- */ 206static void init(void) { 207 errval_t err; 208 iref_t iref; 209 210 err = nameservice_blocking_lookup(my_service_name, &iref); 211 if (err_is_fail(err)) { 212 fprintf(stderr, "xcorecap: could not connect to the xcorecap server.\n" 213 "Terminating.\n"); 214 abort(); 215 } 216 217 err = xcorecap_bind(iref, bind_cb, NULL, get_default_waitset(), 218 IDC_BIND_FLAGS_DEFAULT); 219 if (err_is_fail(err)) { 220 DEBUG_ERR(err, "bind failed"); 221 abort(); 222 } 223} 224 225 226int main (int argc, char* argv[]) 227{ 228 errval_t err; 229 230 printf("Starting xcorecap on core %i\n", disp_get_core_id()); 231 232 init(); 233 234 struct waitset *ws = get_default_waitset(); 235 while (1) { 236 err = event_dispatch(ws); 237 if (err_is_fail(err)) { 238 DEBUG_ERR(err, "in event_dispatch"); 239 break; 240 } 241 } 242 243 return EXIT_FAILURE; 244} 245