1/* 2 * Copyright (c) 2017 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, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group. 8 */ 9 10#include <stdlib.h> 11#include <stdio.h> 12#include <time.h> 13#include <barrelfish/barrelfish.h> 14#include <barrelfish/waitset.h> 15#include <barrelfish/deferred.h> 16#include <barrelfish/nameservice_client.h> 17#include <devif/queue_interface.h> 18#include <devif/backends/descq.h> 19#include <devif/backends/debug.h> 20#include <if/devif_test_defs.h> 21 22 23static uint16_t qid = 0; 24 25static struct ele* list = NULL; 26static struct ele* end = NULL; 27static struct devq* descq; 28static struct devq* debug; 29 30 31struct ele { 32 struct descq* q; 33 uint16_t qid; 34 struct ele* next; 35}; 36 37static errval_t create(struct descq* q, uint64_t* queue_id) 38{ 39 if (list == NULL) { 40 list = malloc(sizeof(struct ele)); 41 list->q = q; 42 list->qid = qid; 43 list->next = NULL; 44 end = list; 45 } else { 46 struct ele* item = malloc(sizeof(struct ele)); 47 item->q = q; 48 item->qid = qid; 49 item->next = NULL; 50 end->next = item; 51 end = item; 52 } 53 54 // stack debug queue on top 55 errval_t err; 56 err = debug_create((struct debug_q**) &debug, (struct devq*) q); 57 if (err_is_fail(err)) { 58 USER_PANIC("Allocating debug q failed \n"); 59 } 60 61 qid++; 62 return SYS_ERR_OK; 63} 64 65static errval_t destroy(struct descq* q) 66{ 67 return SYS_ERR_OK; 68} 69 70static errval_t rpc_request_ep(struct devif_test_binding* b, coreid_t core, 71 errval_t* err, struct capref* cap) 72{ 73 *err = slot_alloc(cap); 74 if (err_is_fail(*err)) { 75 return *err; 76 } 77 78 *err = descq_create_ep((struct descq*) descq, core, cap); 79 if (err_is_fail(*err)) { 80 slot_free(*cap); 81 return *err; 82 } 83 84 return *err; 85} 86 87static void request_ep(struct devif_test_binding* b, coreid_t core) 88{ 89 errval_t err, err2; 90 struct capref ep; 91 err = rpc_request_ep(b, core, &err2, &ep); 92 err = b->tx_vtbl.request_ep_response(b, NOP_CONT, err, ep); 93 assert(err_is_ok(err)); 94} 95 96static errval_t notify(struct descq* q) 97{ 98 99 //struct devq* queue = (struct devq*) q; 100 struct devq* queue = (struct devq*) debug; 101 errval_t err = SYS_ERR_OK; 102 //errval_t err2 = SYS_ERR_OK; 103 regionid_t rid; 104 genoffset_t offset; 105 genoffset_t length; 106 genoffset_t valid_data; 107 genoffset_t valid_length; 108 uint64_t flags; 109 bool exit = false; 110 uint16_t num_enq = 0; 111 while(!exit) { 112 err = devq_dequeue(queue, &rid, &offset, &length, 113 &valid_data, &valid_length, &flags); 114 if (err_is_fail(err)) { 115 exit = true; 116 } else { 117 bool exit2 = false; 118 while(!exit2) { 119 err = devq_enqueue(queue, rid, offset, length, valid_data, 120 valid_length, flags); 121 if (err_is_ok(err)) { 122 exit2 = true; 123 num_enq++; 124 } 125 } 126 } 127 } 128 129 if (num_enq > 0) { 130 err = devq_notify(queue); 131 } else { 132 err = SYS_ERR_OK; 133 } 134 135 return err; 136} 137 138static errval_t reg(struct descq* q, struct capref cap, 139 regionid_t rid) 140{ 141 return debug_add_region((struct debug_q*) debug, cap, rid); 142} 143 144 145static errval_t dereg(struct descq* q, regionid_t rid) 146{ 147 return debug_remove_region((struct debug_q*) debug, rid); 148} 149 150 151static errval_t control(struct descq* q, uint64_t cmd, uint64_t value, uint64_t* res) 152{ 153 return SYS_ERR_OK; 154} 155 156static struct devif_test_rpc_rx_vtbl rpc_rx_vtbl = { 157 .request_ep_call = rpc_request_ep, 158}; 159 160static struct devif_test_rx_vtbl rx_vtbl = { 161 .request_ep_call = request_ep, 162}; 163 164 165static void export_cb(void *st, errval_t err, iref_t iref) 166{ 167 printf("exported devif_test_ep: interface\n"); 168 err = nameservice_register("devif_test_ep", iref); 169 assert(err_is_ok(err)); 170} 171 172 173static errval_t connect_cb(void *st, struct devif_test_binding *b) 174{ 175 printf("New connection on devif_test_ep interface\n"); 176 b->rx_vtbl = rx_vtbl; 177 b->rpc_rx_vtbl = rpc_rx_vtbl; 178 b->st = st; 179 return SYS_ERR_OK; 180} 181 182int main(int argc, char *argv[]) 183{ 184 uint64_t id; 185 errval_t err; 186 struct descq_func_pointer* f = malloc(sizeof(struct descq_func_pointer)); 187 assert(f != NULL); 188 189 f->notify = notify; 190 f->create = create; 191 f->destroy = destroy; 192 f->reg = reg; 193 f->dereg = dereg; 194 f->control = control; 195 196 err = descq_create((struct descq**)&descq, DESCQ_DEFAULT_SIZE, "test_queue", 197 true, &id, f); 198 if (err_is_fail(err)) { 199 USER_PANIC("Allocating debug q failed \n"); 200 } 201 202 err = devif_test_export(&descq, export_cb, connect_cb, get_default_waitset(), 203 IDC_BIND_FLAGS_DEFAULT); 204 if (err_is_fail(err)) { 205 USER_PANIC("Exporting devif_test failed\n"); 206 } 207 208 while(true) { 209 event_dispatch(get_default_waitset()); 210 } 211} 212 213