1/* 2 * Copyright (c) 2016,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, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group. 8 */ 9 10#include <barrelfish/barrelfish.h> 11#include <barrelfish/deferred.h> 12#include <devif/queue_interface.h> 13#include <devif/backends/loopback_devif.h> 14#include <devif/queue_interface_backend.h> 15 16#define LOOPBACK_QUEUE_SIZE 256 17 18struct loopback_queue 19{ 20 struct devq q; 21 struct devq_buf queue[LOOPBACK_QUEUE_SIZE]; 22 size_t head; 23 size_t tail; 24 size_t num_ele; 25}; 26 27static errval_t loopback_enqueue(struct devq* q, regionid_t rid, genoffset_t offset, 28 genoffset_t length, genoffset_t valid_data, 29 genoffset_t valid_length, uint64_t flags) 30{ 31 struct loopback_queue *lq = (struct loopback_queue *)q; 32 33 34 if (lq->num_ele == LOOPBACK_QUEUE_SIZE) { 35 //debug_printf("enqueue: head=%lu tail=%lu full\n", lq->head, lq->tail); 36 return DEVQ_ERR_QUEUE_FULL; 37 } 38 39 //debug_printf("enqueue: head=%lu tail=%lu \n", lq->head, lq->tail); 40 lq->queue[lq->head].offset = offset; // 8 41 lq->queue[lq->head].length = length; // 16 42 lq->queue[lq->head].valid_data = valid_data; // 24 43 lq->queue[lq->head].valid_length = valid_length; // 32 44 lq->queue[lq->head].flags = flags; // 40 45 lq->queue[lq->head].rid = rid; // 44 46 47 lq->head = (lq->head + 1) % LOOPBACK_QUEUE_SIZE; 48 lq->num_ele++; 49 50 return SYS_ERR_OK; 51} 52 53static errval_t loopback_dequeue(struct devq* q, regionid_t* rid, 54 genoffset_t* offset, genoffset_t* length, 55 genoffset_t* valid_data, 56 genoffset_t* valid_length, uint64_t* flags) 57{ 58 struct loopback_queue *lq = (struct loopback_queue *)q; 59 60 if (lq->num_ele == 0) { 61 //debug_printf("dequeue: head=%lu tail=%lu emtpy\n", lq->head, lq->tail); 62 return DEVQ_ERR_QUEUE_EMPTY; 63 } 64 65 //debug_printf("dequeue: head=%lu tail=%lu \n", lq->head, lq->tail); 66 67 *offset = lq->queue[lq->tail].offset; // 8 68 *length = lq->queue[lq->tail].length; // 16 69 *valid_data = lq->queue[lq->tail].valid_data; // 24 70 *valid_length =lq->queue[lq->tail].valid_length; // 32 71 *flags = lq->queue[lq->tail].flags; // 40 72 *rid = lq->queue[lq->tail].rid; // 44 73 74 lq->tail = (lq->tail + 1) % LOOPBACK_QUEUE_SIZE; 75 lq->num_ele--; 76 return SYS_ERR_OK; 77} 78 79 80static errval_t loopback_notify(struct devq *q) 81{ 82 83#if 0 84 err = devq_dequeue(q, &(buf.rid), &(buf.addr), 85 &(buf.len), &(buf.bid), &(buf.flags)); 86 if (err_is_fail(err)) { 87 return err; 88 } 89 90 err = devq_enqueue(q, buf.rid, buf.addr, buf.len, 91 buf.flags, &buf.bid); 92 if (err_is_fail(err)) { 93 return err; 94 } 95#endif 96 97 98 return SYS_ERR_OK; 99} 100 101static errval_t loopback_register(struct devq *q, struct capref cap, 102 regionid_t region_id) 103{ 104 return SYS_ERR_OK; 105} 106 107static errval_t loopback_deregister(struct devq *q, regionid_t region_id) 108{ 109 return SYS_ERR_OK; 110} 111 112static errval_t loopback_control(struct devq *q, 113 uint64_t request, 114 uint64_t value, 115 uint64_t *result) 116{ 117 // TODO Might have some options for loopback device? 118 return SYS_ERR_OK; 119} 120 121 122static errval_t loopback_destroy(struct devq* q) 123{ 124 free((struct loopback_queue*)q); 125 return SYS_ERR_OK; 126} 127 128errval_t loopback_queue_create(struct loopback_queue** q) 129{ 130 errval_t err; 131 132 struct loopback_queue *lq = calloc(1, sizeof(struct loopback_queue)); 133 if (lq == NULL) { 134 return LIB_ERR_MALLOC_FAIL; 135 } 136 137 err = devq_init(&lq->q, false); 138 if (err_is_fail(err)) { 139 free(lq); 140 return err; 141 } 142 143 lq->head = 0; 144 lq->tail = 0; 145 lq->num_ele = 0; 146 147 lq->q.f.enq = loopback_enqueue; 148 lq->q.f.deq = loopback_dequeue; 149 lq->q.f.reg = loopback_register; 150 lq->q.f.dereg = loopback_deregister; 151 lq->q.f.ctrl = loopback_control; 152 lq->q.f.notify = loopback_notify; 153 lq->q.f.destroy = loopback_destroy; 154 155 *q = lq; 156 157 return SYS_ERR_OK; 158} 159