1/* 2 * Copyright (c) 2014 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, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group. 8 */ 9 10#ifndef VIRTIO_VIRTQUEUE_HOST_H 11#define VIRTIO_VIRTQUEUE_HOST_H 12 13 14#include <virtio/virtio_host.h> 15#include <virtio/virtqueue.h> 16 17// forward definition 18struct virtqueue_host; 19 20 21 22/* 23 * Extracted from the Virtio Specification 1.0 24 * http://docs.oasis-open.org/virtio/virtio/v1.0/virtio-v1.0.pdf 25 * 26 * VIRQUEUES: 27 * 28 * Size is determined by a 16bit integer. 29 * The queue consists of a descriptor table, available ring, used ring 30 * Each of the three parts are physically-contiguous in guest memory. 31 * 32 */ 33 34 35 36 37/** 38 * \brief allocates and initiates a new virtqueue structure with no vring mem 39 * 40 * \param dev the VirtIO device of to allocate the virtqueues for 41 * \param setup pointer to the setup information 42 * \param vq_num the number of virtqueues structures to allocate 43 * 44 * \returns SYS_ERR_OK on success 45 */ 46errval_t virtio_vq_host_alloc(struct virtqueue_host ***vq, 47 struct virtqueue_setup *setup, 48 uint16_t vq_num); 49 50/** 51 * \brief allocates and initiates a new virtqueue structure 52 * 53 * \param vdev the VirtIO device 54 * \param vring_cap capability to be used for the vring 55 * \param vq_id id of the queue to initialize 56 * \param ndesc the number of descriptors in this queue 57 * \param has_buf indicates if there are buffers 58 * 59 * \returns SYS_ERR_OK on success 60 */ 61errval_t virtio_vq_host_init_vring(struct virtio_device *vdev, 62 struct capref vring_cap, 63 uint16_t vq_id, 64 uint16_t ndesc, 65 uint8_t has_buf); 66 67/** 68 * \brief frees the resources of previously allocated virtqueues 69 * 70 * \param vq pointer to the virtqueue memory to be freed 71 * 72 * \returns SYS_ERR_OK on success 73 */ 74errval_t virtio_vq_host_free(struct virtqueue_host *vq); 75 76/* 77void *virtqueue_drain(struct virtqueue_host *vq, int *last); 78int virtqueue_reinit(struct virtqueue_host *vq, uint16_t size); 79*/ 80 81 82/* 83 * =========================================================================== 84 * Getter functions for certain values of the virtqueue structure 85 */ 86 87/** 88 * \brief Returns the physical address of the vring. 89 * 90 * \param vq pointer to the virtqueue structure 91 * 92 * \returns the physical address of the vring 93 */ 94lpaddr_t virtio_vq_host_get_vring_paddr(struct virtqueue_host *vq); 95 96 97/** 98 * \brief Returns the frame capability of the vring 99 * 100 * \param vq pointer to the virtqueue structure 101 * \param ret_cap memory location where to store the capref 102 */ 103void virtio_vq_host_get_vring_cap(struct virtqueue_host *vq, 104 struct capref *ret_cap); 105 106/** 107 * \brief Returns the queue index of the virtqueue of the device 108 * 109 * \param vq pointer to the virtqueue structure 110 * 111 * \returns queue index 112 */ 113uint16_t virtio_vq_host_get_queue_index(struct virtqueue_host *vq); 114 115/** 116 * \brief returns the alignment of the vring 117 * 118 * \param the virtqueue to get the alignment from 119 * 120 * \returns vring alignment 121 */ 122lvaddr_t virtio_vq_host_get_vring_align(struct virtqueue_host *vq); 123 124/** 125 * \brief Returns the number of elements (number of descriptors)in the vring of 126 * this virtqueue 127 * 128 * \param vq pointer to the virtqueue structure 129 * 130 * \returns number of elements in the vring 131 */ 132uint16_t virtio_vq_host_get_num_desc(struct virtqueue_host *vq); 133 134/** 135 * \brief Checks if the virtqueue is empty 136 * 137 * \param vq pointer to the virtqueue structure 138 * 139 * \returns 0 the queue is not empty 140 * 1 the queue is empty 141 */ 142bool virtio_vq_host_is_empty(struct virtqueue_host *vq); 143 144 145/** 146 * \brief Calculates the number of used descriptors in this queue 147 * 148 * \param vq pointer to the virtqueue structure 149 * 150 * \returns number of used descriptors 151 */ 152uint16_t virtio_vq_host_get_num_avail(struct virtqueue_host *vq); 153 154 155/* 156 * =========================================================================== 157 * Interrupt handling 158 */ 159 160/** 161 * \brief sends an interrupt to the guest that an event has happened on the 162 * queue 163 * 164 * \param vq virtqueue to send the interrupt on 165 * 166 * \returns SYS_ERR_OK on success 167 */ 168errval_t virtio_vq_host_intr_send(struct virtqueue_host *vq); 169 170 171/** 172 * \brief masks the ring features out of a features bit mask 173 * 174 * \param features the features to mask 175 * 176 * \returns bitmask of masked features 177 */ 178static inline uint64_t virtio_vq_host_mask_features(uint64_t features) 179{ 180 uint64_t mask; 181 182 mask = (1 << VIRTIO_TRANSPORT_F_START) - 1; 183 mask |= (1 << VIRTIO_RING_F_INDIRECT_DESC); 184 mask |= (1 <<VIRTIO_RING_F_EVENT_IDX); 185 186 return (features & mask); 187} 188 189/* 190 * =========================================================================== 191 * Virtqueue Queue Management 192 */ 193 194/** 195 * \brief Enqueues a new descriptor chain into the virtqueue 196 * 197 * \param vq the virtqueue the descriptor chain gets enqueued in 198 * \param bl list of buffers to enqueue into the virtqueue 199 * \param st state associated with this descriptor chain 200 * \param num_wr number of writable descriptors 201 * \param num_rd number of readable descriptors 202 * 203 * \returns SYS_ERR_OK on success 204 * VIRTIO_ERR_* on failure 205 */ 206errval_t virtio_vq_host_desc_enqueue(struct virtqueue_host *vq, 207 struct virtio_host_buf *buf, 208 uint16_t idx); 209 210/** 211 * \brief dequeues a descriptor chain form the virtqueue 212 * 213 * \param vq the virtqueue to dequeue descriptors from 214 * 215 * \returns SYS_ERR_OK when the dequeue is successful 216 * VIRTIO_ERR_NO_DESC_AVAIL when there was no descriptor to dequeue 217 * VIRTIO_ERR_* if there was an error 218 */ 219errval_t virtio_vq_host_desc_dequeue(struct virtqueue_host *vq); 220 221 222/** 223 * \brief polls the virtqueue 224 * 225 * \param vq the virtqueue array to dequeue descriptors from 226 * \param vq_num the number of entries in the vq array 227 * 228 * \returns SYS_ERR_OK when the dequeue is successful 229 * VIRTIO_ERR_* if there was an error 230 */ 231errval_t virtio_vq_host_poll(struct virtqueue_host **vq, 232 uint16_t vq_num); 233 234 235#endif // VIRTIO_VIRTQUEUE_H 236