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