failure INVALID_REGION_ID "The region id is not valid",
failure REGION_DESTROY "The region has still buffers that are in use",
failure TX_FULL "Send queue full",
- failure RX_FULL "Receive queue full",
+ failure RX_EMPTY "Receive queue emtpy",
};
build library {
target = "devif",
cFiles = ["queue_interface.c", "region_pool.c",
- "region.c"],
- addCFlags = [ "-DLIBRARY" ]
+ "region.c", "desc_queue.c"],
+ addCFlags = [ "-DLIBRARY" ],
+ flounderBindings = ["devif"]
}
]
--- /dev/null
+/*
+ * Copyright (c) 2016 ETH Zurich.
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+#include <barrelfish/barrelfish.h>
+#include <devif/queue_interface.h>
+#include "desc_queue.h"
+#include "dqi_debug.h"
+
+
+struct __attribute__((aligned(DESCQ_ALIGNMENT))) desc {
+ regionid_t region_id; // 4
+ bufferid_t buffer_id; // 8
+ lpaddr_t base; // 16
+ size_t length; // 24
+ uint64_t misc_flags; // 32
+ uint8_t pad[32];
+};
+
+struct descq {
+ // Shared memory of the queue
+ struct capref shm;
+ size_t slots;
+
+ // Queue pointers
+ size_t head;
+ size_t tail;
+
+ // The queue itself
+ struct desc* descs;
+};
+
+
+/**
+ * @brief initialized a descriptor queue
+ *
+ * @param q Return pointer to the descriptor queue
+ * @param shm Cap of the shared memory of the queue
+ * @param slots Number of slots in the queue
+ *
+ * @returns error on failure or SYS_ERR_OK on success
+ */
+errval_t descq_init(struct descq** q,
+ struct capref shm,
+ size_t slots)
+{
+ USER_PANIC("NIY");
+ return SYS_ERR_OK;
+}
+
+/**
+ * @brief Destroys a descriptor queue and frees its resources
+ *
+ * @param q The descriptor queue
+ *
+ * @returns error on failure or SYS_ERR_OK on success
+ */
+errval_t descq_destroy(struct descq* q)
+{
+ USER_PANIC("NIY");
+ return SYS_ERR_OK;
+}
+
+/**
+ * @brief Enqueue a descriptor (as seperate fields)
+ * into the descriptor queue
+ *
+ * @param q The descriptor queue
+ * @param region_id Region id of the enqueued buffer
+ * @param buffer_id Buffer id of the buffer
+ * @param base Physical address of hte buffer
+ * @param len Lenght of the buffer
+ * @param misc_flags Miscellaneous flags
+ *
+ * @returns error if queue is full or SYS_ERR_OK on success
+ */
+errval_t descq_enqueue(struct descq* q,
+ regionid_t region_id,
+ bufferid_t buffer_id,
+ lpaddr_t base,
+ size_t len,
+ uint64_t misc_flags)
+{
+ USER_PANIC("NIY");
+ return SYS_ERR_OK;
+}
+/**
+ * @brief Dequeue a descriptor (as seperate fields)
+ * from the descriptor queue
+ *
+ * @param q The descriptor queue
+ * @param region_id Return pointer to the region id of
+ * the denqueued buffer
+ * @param buffer_id Return pointer to the buffer id of the buffer
+ * @param base Return pointer to the physical address
+ * of the buffer
+ * @param len Return pointer to the lenght of the buffer
+ * @param misc_flags Return pointer to miscellaneous flags
+ *
+ * @returns error if queue is empty or SYS_ERR_OK on success
+ */
+errval_t descq_dequeue(struct descq* q,
+ regionid_t* region_id,
+ bufferid_t* buffer_id,
+ lpaddr_t* base,
+ size_t* len,
+ uint64_t* misc_flags)
+{
+ USER_PANIC("NIY");
+ return SYS_ERR_OK;
+}
+/**
+ * @brief Check if the descriptor queue is full
+ *
+ * @param q The descriptor queue
+ *
+ * @returns true if the queue is full, otherwise false
+ */
+bool descq_full(struct descq* q)
+{
+ USER_PANIC("NIY");
+ return false;
+}
+/**
+ * @brief Check if the descriptor queue is empty
+ *
+ * @param q The descriptor queue
+ *
+ * @returns true if the queue is empty, otherwise false
+ */
+bool descq_empty(struct descq* q)
+{
+ USER_PANIC("NIY");
+ return false;
+}
+/**
+ * @brief Returns the number of occupied slots in the queue
+ *
+ * @param q The descriptor queue
+ *
+ * @returns the number of occupied slots
+ */
+size_t descq_full_slots(struct descq* q)
+{
+ USER_PANIC("NIY");
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 ETH Zurich.
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+#ifndef DESCQ_H_
+#define DESCQ_H_ 1
+
+
+#include <barrelfish/barrelfish.h>
+#include <devif/queue_interface.h>
+
+#define DESCQ_DEFAULT_SIZE 64
+#define DESCQ_ALIGNMENT 64
+
+struct descq;
+/**
+ * @brief initialized a descriptor queue
+ *
+ * @param q Return pointer to the descriptor queue
+ * @param shm Cap of the shared memory of the queue
+ * @param slots Number of slots in the queue
+ *
+ * @returns error on failure or SYS_ERR_OK on success
+ */
+errval_t descq_init(struct descq** q,
+ struct capref shm,
+ size_t slots);
+
+/**
+ * @brief Destroys a descriptor queue and frees its resources
+ *
+ * @param q The descriptor queue
+ *
+ * @returns error on failure or SYS_ERR_OK on success
+ */
+errval_t descq_destroy(struct descq* q);
+
+/**
+ * @brief Enqueue a descriptor (as seperate fields)
+ * into the descriptor queue
+ *
+ * @param q The descriptor queue
+ * @param region_id Region id of the enqueued buffer
+ * @param buffer_id Buffer id of the buffer
+ * @param base Physical address of hte buffer
+ * @param len Lenght of the buffer
+ * @param misc_flags Miscellaneous flags
+ *
+ * @returns error if queue is full or SYS_ERR_OK on success
+ */
+errval_t descq_enqueue(struct descq* q,
+ regionid_t region_id,
+ bufferid_t buffer_id,
+ lpaddr_t base,
+ size_t len,
+ uint64_t misc_flags);
+
+/**
+ * @brief Dequeue a descriptor (as seperate fields)
+ * from the descriptor queue
+ *
+ * @param q The descriptor queue
+ * @param region_id Return pointer to the region id of
+ * the denqueued buffer
+ * @param buffer_id Return pointer to the buffer id of the buffer
+ * @param base Return pointer to the physical address
+ * of the buffer
+ * @param len Return pointer to the lenght of the buffer
+ * @param misc_flags Return pointer to miscellaneous flags
+ *
+ * @returns error if queue is empty or SYS_ERR_OK on success
+ */
+errval_t descq_dequeue(struct descq* q,
+ regionid_t* region_id,
+ bufferid_t* buffer_id,
+ lpaddr_t* base,
+ size_t* len,
+ uint64_t* misc_flags);
+
+/**
+ * @brief Check if the descriptor queue is full
+ *
+ * @param q The descriptor queue
+ *
+ * @returns true if the queue is full, otherwise false
+ */
+bool descq_full(struct descq* q);
+
+/**
+ * @brief Check if the descriptor queue is empty
+ *
+ * @param q The descriptor queue
+ *
+ * @returns true if the queue is empty, otherwise false
+ */
+bool descq_empty(struct descq* q);
+
+/**
+ * @brief Returns the number of occupied slots in the queue
+ *
+ * @param q The descriptor queue
+ *
+ * @returns the number of occupied slots
+ */
+size_t descq_full_slots(struct descq* q);
+
+#endif /* DESCQ_H_ */
#include <barrelfish/barrelfish.h>
#include <devif/queue_interface.h>
#include "region_pool.h"
+#include "desc_queue.h"
#include "dqi_debug.h"
-#define DESCQ_SIZE 64
-#define DESCQ_ALIGNMENT 64
-
-struct __attribute__((aligned(DESCQ_ALIGNMENT))) descriptor {
- regionid_t region_id; // 4
- bufferid_t buffer_id; // 8
- lpaddr_t base; // 16
- size_t length; // 24
- uint64_t misc_flags; // 32
- uint8_t pad[32];
-};
struct devq_func_pointer {
devq_create_t create;
// Function pointers for backend
struct devq_func_pointer f;
- // queue state
- uint16_t tx_head;
- uint16_t tx_tail;
-
- uint16_t rx_head;
- uint16_t rx_tail;
-
- // Queues themselves
- struct descriptor rx[DESCQ_SIZE];
- struct descriptor tx[DESCQ_SIZE];
-
+ // queues
+ struct descq* rx;
+ struct descq* tx;
//TODO Other state needed ...
};
uint64_t flags)
{
errval_t err;
+ struct capref rx;
+ struct capref tx;
+
struct devq* tmp = malloc(sizeof(struct devq));
strncpy(tmp->device_name, device_name, MAX_DEVICE_NAME);
- tmp->rx_head = 0;
- tmp->tx_head = 0;
- tmp->rx_tail = 0;
- tmp->tx_tail = 0;
-
err = region_pool_init(&(tmp->pool));
if (err_is_fail(err)) {
free(tmp);
}
- *q = tmp;
+ // Allocate shared memory
+ err = frame_alloc(&rx, DESCQ_DEFAULT_SIZE*DESCQ_ALIGNMENT, NULL);
+ if (err_is_fail(err)) {
+ return err;
+ }
+
+ err = frame_alloc(&tx, DESCQ_DEFAULT_SIZE*DESCQ_ALIGNMENT, NULL);
+ if (err_is_fail(err)) {
+ return err;
+ }
+
+ // Initialize rx/tx queues
+ err = descq_init(&(tmp->rx), rx, DESCQ_DEFAULT_SIZE);
+ if (err_is_fail(err)){
+ return err;
+ }
+
+ err = descq_init(&(tmp->tx), tx, DESCQ_DEFAULT_SIZE);
+ if (err_is_fail(err)){
+ return err;
+ }
+
+ // TODO send queue caps to other endpoint
// TODO initalize device
// TODO initalize device state
+ *q = tmp;
return SYS_ERR_OK;
}
{
errval_t err;
+ err = descq_destroy(q->rx);
+ if (err_is_fail(err)) {
+ return err;
+ }
+
+ err = descq_destroy(q->tx);
+ if (err_is_fail(err)) {
+ return err;
+ }
+
err = region_pool_destroy(q->pool);
if (err_is_fail(err)) {
return err;
bufferid_t* buffer_id)
{
errval_t err;
- size_t num_free = 0;
-
- if (q->tx_head >= q->tx_tail) {
- num_free = DESCQ_SIZE - (q->tx_head - q->tx_tail);
- } else {
- num_free = DESCQ_SIZE - (q->tx_head + DESCQ_SIZE - q->tx_tail);
- }
-
- if (num_free == 0) {
- return DEVQ_ERR_TX_FULL;
- }
// Add buffer to used ones
err = region_pool_get_buffer_id_from_region(q->pool, region_id, base,
return DEVQ_ERR_BUFFER_ID;
}
- q->tx[q->tx_head].region_id = region_id;
- q->tx[q->tx_head].base = base;
- q->tx[q->tx_head].length = length;
- q->tx[q->tx_head].buffer_id = *buffer_id;
- q->tx[q->tx_head].misc_flags = misc_flags;
- q->tx_head = q->tx_head + 1 % DESCQ_SIZE;
+ // Enqueue into queue
+ err = descq_enqueue(q->tx, region_id, *buffer_id,
+ base, length, misc_flags);
+ if (err_is_fail(err)) {
+ return err;
+ }
return SYS_ERR_OK;
}
uint64_t* misc_flags)
{
errval_t err;
- size_t num_used = 0;
- if (q->rx_head >= q->rx_tail) {
- num_used = (q->rx_head - q->rx_tail);
- } else {
- num_used = (q->rx_head + DESCQ_SIZE - q->rx_tail);
- }
-
- if (num_used == 0) {
- return DEVQ_ERR_RX_FULL;
- }
- *region_id = q->rx[q->rx_head].region_id;
- *base = q->rx[q->rx_head].base;
- *length = q->rx[q->rx_head].length;
- *buffer_id = q->rx[q->rx_head].buffer_id;
- *misc_flags = q->rx[q->rx_head].misc_flags;
-
- q->rx_head = q->rx_head + 1 % DESCQ_SIZE;
-
-/*a
- // Only uncomment for testing
- if (q->tx_head >= q->tx_tail) {
- num_used = (q->tx_head - q->tx_tail);
- } else {
- num_used = (q->tx_head + DESCQ_SIZE - q->tx_tail);
- }
- if (num_used == 0) {
- return DEVQ_ERR_RX_FULL;
+ // Dequeue descriptor from descriptor queue
+ err = descq_dequeue(q->rx, region_id, buffer_id,
+ base, length, misc_flags);
+ if (err_is_fail(err)) {
+ return err;
}
- *region_id = q->tx[q->tx_tail].region_id;
- *base = q->tx[q->tx_tail].base;
- *length = q->tx[q->tx_tail].length;
- *buffer_id = q->tx[q->tx_tail].buffer_id;
- *misc_flags = q->tx[q->tx_tail].misc_flags;
- q->tx_tail = q->tx_tail + 1 % DESCQ_SIZE;
-*/
// Add buffer to free ones
err = region_pool_return_buffer_id_to_region(q->pool, *region_id,
*buffer_id);
if (err_is_fail(err)) {
- return DEVQ_ERR_BUFFER_ID;
+ return err;
}
return SYS_ERR_OK;