dc874972a40492b0aa44c95f1b4179f9943be066
[barrelfish] / include / virtio / virtqueue.h
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_H
11 #define VIRTIO_VIRTQUEUE_H
12
13 #include <barrelfish/barrelfish.h>
14
15 /*
16  * Extracted from the Virtio Specification 1.0
17  * http://docs.oasis-open.org/virtio/virtio/v1.0/virtio-v1.0.pdf
18  *
19  * VIRQUEUES:
20  *
21  * Size is determined by a 16bit integer.
22  * The queue consists of a descriptor table, available ring, used ring
23  * Each of the three parts are physically-contiguous in guest memory.
24  *
25  */
26
27 // forward definition
28 struct virtqueue;
29
30 /// interrupt handler for virtqueue interrupts
31 typedef void (*virtq_intr_hander_t)(struct virtqueue *, void *);
32
33 /// the maximum length of the name field
34 #define VIRTQUEUE_NAME_SIZE 32
35
36 /// the maximum number of elements in a vring
37 #define VIRTQUEUE_SIZE_MAX (1<<15)
38
39 /// this value marks the end of a descriptor chain
40 #define VIRTQUEUE_CHAIN_END VIRTQUEUE_SIZE_MAX
41
42 /// Feature flag indicating that the ring supports indirect descriptors
43 #define VIRTIO_RING_F_INDIRECT_DESC (1 << 28)
44
45 /// Feature flag indicating that the ring supports interrupt suppression
46 #define VIRTIO_RING_F_EVENT_IDX     (1 << 29)
47
48
49 /**
50  * this structure holds necessary data to allocate a new virtqueue
51  */
52 struct virtqueue_setup {
53     char name[VIRTQUEUE_NAME_SIZE];     ///< the name of the queue
54     struct virtio_device *device;       ///< device this queue belongs to
55     uint16_t queue_id;                  ///< queue id of this queue
56     uint16_t vring_ndesc;               ///< size of the vring
57     lvaddr_t vring_align;               ///< alignment of the vring
58     virtq_intr_hander_t intr_handler;   ///< interrupt handler function
59     void *intr_arg;                     ///< argument for the interrupt handler
60     uint16_t max_indirect;              ///< maximum indirect descriptors
61 };
62
63 /**
64  *
65  */
66 enum virtqueue_intr_postpone {
67    VIRTQUEUE_INTR_POSTPONE_SHORT,
68    VIRTQUEUE_INTR_POSTPONE_LONG,
69    VIRTQUEUE_INTR_POSTPONE_EMPTIED,
70 };
71
72
73 /**
74  * \brief allocates and initiates a new virtqueue structure
75  *
76  * \param setup  pointer to the setup information
77  * \param vq     pointer where to store the new virtqueue pointer
78  *
79  * \returns SYS_ERR_OK on success
80  */
81 errval_t virtio_virtqueue_alloc(struct virtqueue_setup *setup,
82                                 struct virtqueue **vq);
83
84 /**
85  * \brief allocates and initiates a new virtqueue structure
86  *
87  * \param setup     pointer to the setup information
88  * \param vring_cap capability to be used for the vring
89  * \param vq        pointer where to store the new virtqueue pointer
90  *
91  * \returns SYS_ERR_OK on success
92  */
93 errval_t virtio_virtqueue_alloc_with_caps(struct virtqueue_setup *setup,
94                                           struct capref vring_cap,
95                                           struct virtqueue **vq);
96
97 /**
98  * \brief frees the resources of previously allocated virtqueues
99  *
100  * \param vq pointer to the virtqueue memory to be freed
101  *
102  * \returns SYS_ERR_OK on success
103  */
104 errval_t virtio_virtqueue_free(struct virtqueue *vq);
105
106 /*
107 void    *virtqueue_drain(struct virtqueue *vq, int *last);
108 int  virtqueue_reinit(struct virtqueue *vq, uint16_t size);
109 */
110
111
112 /*
113  * ===========================================================================
114  * Getter functions for certain values of the virtqueue structure
115  */
116
117 /**
118  * \brief Returns the physical address of the vring.
119  *
120  * \param vq pointer to the virtqueue structure
121  *
122  * \returns the physical address of the vring
123  */
124 lpaddr_t virtio_virtqueue_get_vring_paddr(struct virtqueue *vq);
125
126
127 /**
128  * \brief Returns the frame capability of the vring
129  *
130  * \param vq        pointer to the virtqueue structure
131  * \param ret_cap   memory location where to store the capref
132  */
133 void virtio_virtqueue_get_vring_cap(struct virtqueue *vq,
134                                     struct capref *ret_cap);
135
136 /**
137  * \brief Returns the queue index of the virtqueue of the device
138  *
139  * \param vq pointer to the virtqueue structure
140  *
141  * \returns queue index
142  */
143 uint16_t virtio_virtqueue_get_queue_index(struct virtqueue *vq);
144
145 /**
146  * \brief returns the alignment of the vring
147  *
148  * \param the virtqueue to get the alignment from
149  *
150  * \returns vring alignment
151  */
152 lvaddr_t virtio_virtqueue_get_vring_align(struct virtqueue *vq);
153
154 /**
155  * \brief Returns the number of elements (number of descriptors)in the vring of
156  *        this virtqueue
157  *
158  * \param vq pointer to the virtqueue structure
159  *
160  * \returns number of elements in the vring
161  */
162 uint16_t virtio_virtqueue_get_num_desc(struct virtqueue *vq);
163
164 /**
165  * \brief Checks if the virtqueue is empty
166  *
167  * \param vq pointer to the virtqueue structure
168  *
169  * \returns 0 the queue is not empty
170  *          1 the queue is empty
171  */
172 bool virtio_virtqueue_is_empty(struct virtqueue *vq);
173
174 /**
175  * \brief Checks if the virtqueue is full
176  *
177  * \param vq pointer to the virtqueue structure
178  *
179  * \returns 0 the queue is not full
180  *          1 the queue is full
181  */
182 bool virtio_virtqueue_is_full(struct virtqueue *vq);
183
184 /**
185  * \brief Calculates the number of used descriptors in this queue
186  *
187  * \param vq pointer to the virtqueue structure
188  *
189  * \returns number of used descriptors
190  */
191 uint16_t virtio_virtqueue_get_num_used(struct virtqueue *vq);
192
193
194 /*
195  * ===========================================================================
196  * Interrupt handling
197  */
198
199 /**
200  * \brief enables the interrupts on the next descriptor processed
201  *
202  * \param vq the virtqueue to enable the interrupts
203  *
204  * \returns 1 if the interrupts have been enabled
205  *          0 if the interrupts have not been enabled
206  */
207 bool virtio_virtqueue_intr_enable(struct virtqueue *vq);
208
209 /**
210  * \brief postpones the interrupt to a later point of time
211  *
212  * \param vq the virtqueue to enable the interrupts
213  * \param
214  *
215  * \returns 1 if the interrupts have been enabled
216  *          0 if the interrupts have not been enabled
217  */
218 bool virtio_virtqueue_intr_postpone(struct virtqueue *vq,
219                                     enum virtqueue_intr_postpone hint);
220
221 /**
222  * \brief checks if the interrupts can be disabled
223  *
224  * \param vq virtual queue to check
225  *
226  * \returns 1 if the interrupts have been disabled
227  *          0 if the interrupts are not changed
228  *
229  */
230 bool virtio_virtqueue_intr_filter(struct virtqueue *vq);
231
232 /**
233  * \brief calls the interrupt handler for this virtqueue
234  *
235  * \param vq virtqueue to call the intr handler for
236  */
237 void virtio_virtqueue_intr_handle(struct virtqueue *vq);
238
239 /**
240  * \brief disables the interrupts for the given virtqueue by giving a hint
241  *        to the host
242  *
243  * \param vq        virtqueue to disable the interrupts
244  */
245 void virtio_virtqueue_intr_disable(struct virtqueue *vq);
246
247
248 /**
249  * \brief notifies the host about the new queued descriptors
250  *
251  * \param vq virtqueue to notify the host
252  */
253 void virtio_virtqueue_notify_host(struct virtqueue *vq);
254
255
256 /**
257  * \brief masks the ring features out of a features bit mask
258  *
259  * \param features  the features to mask
260  *
261  * \returns bitmask of masked features
262  */
263 static inline uint64_t virtio_virtqueue_mask_features(uint64_t features)
264 {
265     uint64_t mask;
266
267     mask = (1 << VIRTIO_TRANSPORT_F_START) - 1;
268     mask |= VIRTIO_RING_F_INDIRECT_DESC;
269     mask |= VIRTIO_RING_F_EVENT_IDX;
270
271     return (features & mask);
272 }
273
274 /*
275  * ===========================================================================
276  * Virtqueue Queue Management
277  */
278
279 errval_t virtio_virtqueue_desc_enqueue(struct virtqueue *vq,
280                                        struct virtio_buffer *buf,
281                                        void *vaddr,
282                                        uint16_t writeable,
283                                        uint16_t readable);
284
285 #if 0
286 int  virtqueue_enqueue(struct virtqueue *vq, void *cookie,
287          struct sglist *sg, int readable, int writable);
288 void    *virtqueue_dequeue(struct virtqueue *vq, uint32_t *len);
289 void    *virtqueue_poll(struct virtqueue *vq, uint32_t *len);
290
291
292
293 uint64_t virtqueue_filter_features(uint64_t features);
294
295 void     virtqueue_dump(struct virtqueue *vq);
296 #endif
297
298
299 #endif // VIRTIO_VIRTQUEUE_H