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, Haldeneggsteig 4, 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 <devif/queue_interface.h>
17#include <devif/backends/descq.h>
18#include <devif/backends/debug.h>
19
20
21static uint16_t qid = 0;
22
23static struct ele* list = NULL;
24static struct ele* end = NULL;
25static struct devq* descq;
26static struct devq* debug;
27
28
29struct ele {
30    struct  descq* q;
31    uint16_t qid;
32    struct ele* next;
33};
34
35static errval_t create(struct descq* q, bool notifications, uint8_t role,
36                       uint64_t* queue_id)
37{
38    if (list == NULL) {
39        list = malloc(sizeof(struct ele));
40        list->q = q;
41        list->qid = qid;
42        list->next = NULL;
43        end = list;
44    } else {
45        struct ele* item = malloc(sizeof(struct ele));
46        item->q = q;
47        item->qid = qid;
48        item->next = NULL;
49        end->next = item;
50        end = item;
51    }
52
53    // stack debug queue on top
54    errval_t err;
55    err = debug_create((struct debug_q**) &debug, (struct devq*) q);
56    if (err_is_fail(err)) {
57        USER_PANIC("Allocating debug q failed \n");
58    }
59
60    qid++;
61    return SYS_ERR_OK;
62}
63
64static errval_t destroy(struct descq* q)
65{
66    return SYS_ERR_OK;
67}
68
69
70static errval_t notify(struct descq* q)
71{
72
73    //struct devq* queue = (struct devq*) q;
74    struct devq* queue = (struct devq*) debug;
75    errval_t err = SYS_ERR_OK;
76    //errval_t err2 = SYS_ERR_OK;
77    regionid_t rid;
78    genoffset_t offset;
79    genoffset_t length;
80    genoffset_t valid_data;
81    genoffset_t valid_length;
82    uint64_t flags;
83    bool exit = false;
84    uint16_t num_enq = 0;
85    while(!exit) {
86        err = devq_dequeue(queue, &rid, &offset, &length,
87                           &valid_data, &valid_length, &flags);
88        if (err_is_fail(err)) {
89            exit = true;
90        } else {
91           bool exit2 = false;
92            while(!exit2) {
93                err = devq_enqueue(queue, rid, offset, length, valid_data,
94                                   valid_length, flags);
95                if (err_is_ok(err)) {
96                    exit2 = true;
97                    num_enq++;
98                }
99            }
100        }
101    }
102
103    if (num_enq > 0) {
104        err = devq_notify(queue);
105    } else {
106        err = SYS_ERR_OK;
107    }
108
109    return err;
110}
111
112static errval_t reg(struct descq* q, struct capref cap,
113                    regionid_t rid)
114{
115    return debug_add_region((struct debug_q*) debug, cap, rid);
116}
117
118
119static errval_t dereg(struct descq* q, regionid_t rid)
120{
121    return debug_remove_region((struct debug_q*) debug, rid);
122}
123
124
125static errval_t control(struct descq* q, uint64_t cmd, uint64_t value, uint64_t* res)
126{
127    return SYS_ERR_OK;
128}
129
130int main(int argc, char *argv[])
131{
132    uint64_t id;
133    errval_t err;
134    struct descq_func_pointer* f = malloc(sizeof(struct descq_func_pointer));
135    assert(f != NULL);
136
137    f->notify = notify;
138    f->create = create;
139    f->destroy = destroy;
140    f->reg = reg;
141    f->dereg = dereg;
142    f->control = control;
143
144    err = descq_create((struct descq**)&descq, DESCQ_DEFAULT_SIZE, "test_queue",
145                       true, true, 0, &id, f);
146    if (err_is_fail(err)) {
147        USER_PANIC("Allocating debug q failed \n");
148    }
149
150    assert(err_is_ok(err));
151    while(true) {
152        event_dispatch(get_default_waitset());
153    }
154}
155
156