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_H
11#define VIRTIO_H
12
13#include <barrelfish/barrelfish.h>
14
15
16/// defines how we map the memory frames
17#define VIRTIO_VREGION_FLAGS_DEVICE VREGION_FLAGS_READ_WRITE
18#define VIRTIO_VREGION_FLAGS_RING   VREGION_FLAGS_READ_WRITE
19
20
21/*
22 * Generic Feature Bits
23 */
24
25/// Generate interrupt if queue is completely used
26#define VIRTIO_F_NOTIFY_ON_EMPTY (1 << 24)
27
28/// guest should never set this feature. This indicates faulty drivers
29#define VIRTIO_F_BAD_FEATURE (1 << 30)
30
31/// range of the transport related feature bits
32#define VIRTIO_TRANSPORT_F_START    28
33#define VIRTIO_TRANSPORT_F_END      32
34
35/**
36 * represents the channel backend to be used for this VirtIO guest library
37 */
38enum virtio_host
39{
40    VIRTIO_HOST_CHAN_INVALID,  ///< the channel type is invalid
41    VIRTIO_HOST_CHAN_FLOUNDER, ///< the flounder RPC backend should be used
42    VIRTIO_HOST_CHAN_XEON_PHI, ///< the xeon phi messaging backend should be used
43};
44
45/**
46 * VirtIO Memory segment
47 */
48
49struct virtio_buffer_allocator;
50
51enum virtio_buffer_state {
52    VIRTIO_BUFFER_S_INVALID,
53    VIRTIO_BUFFER_S_FREE,
54    VIRTIO_BUFFER_S_ALLOCED,
55    VIRTIO_BUFFER_S_ALLOCED_WRITABLE,
56    VIRTIO_BUFFER_S_ALLOCED_READABLE,
57    VIRTIO_BUFFER_S_QUEUED
58};
59
60enum virtio_bl_state {
61    VIRTIO_BUFFER_LIST_S_INVALID,     ///< invalid state
62    VIRTIO_BUFFER_LIST_S_EMTPY,       ///< list is empty can be used to insert bufs
63    VIRTIO_BUFFER_LIST_S_FILLED,      ///< list contains buffers, more can be appended
64    VIRTIO_BUFFER_LIST_S_ENQUEUED     ///< buffer list is enqueued, appending not possible
65};
66
67/**
68 * represents a VirtIO buffer to be used
69 */
70struct virtio_buffer
71{
72    struct virtio_buffer_allocator *a;  ///< pointer to the allocator
73    enum virtio_buffer_state state;     ///< state of this buffer
74    lpaddr_t paddr;                     ///< physical address of the buffer
75    void *buf;                          ///< mapped virtual address of the buffer
76    size_t   length;                    ///< size of this buffer
77    size_t   data_length;
78    struct virtio_buffer_list *lhead;   ///< pointer to the buffer list head
79    struct virtio_buffer *next;         ///< pointer to the next buffer in the list
80    struct virtio_buffer *prev;   ///< pointer to the previous next field
81};
82
83/**
84 * represents a list of buffers
85 */
86struct virtio_buffer_list
87{
88    enum virtio_bl_state state;
89    struct virtio_buffer *head;
90    struct virtio_buffer *tail;
91    size_t length;
92};
93
94
95/**
96 * \brief   initializes the buffer allocator and allocates memory for the
97 *          buffers
98 *
99 * \param   alloc   the allocator struct to initialize
100 * \param   nbufs   number of buffers to allocate
101 * \param   bufsz   size of each buffer to allocate
102 *
103 * \return  SYS_ERR_OK on success
104 */
105errval_t virtio_buffer_alloc_init(struct virtio_buffer_allocator **alloc,
106                                  size_t nbufs,
107                                  size_t bufsz);
108
109/**
110 * \brief allocated and initializes a new buffer allocator based on the
111 *        capability with an already existing mapping
112 *
113 * \param bf        where to store the buffer allocator pointer
114 * \param cap       capability of the buffers
115 * \param vaddr     virtual address where they are mapped
116 * \param offset    offset where the buffers start
117 * \param bufsize   size of a single buffer
118 * \param bufcount  number of buffers
119 */
120errval_t virtio_buffer_alloc_init_vq(struct virtio_buffer_allocator **bf,
121                                     struct capref cap,
122                                     lvaddr_t vaddr,
123                                     lpaddr_t offset,
124                                     size_t bufsize,
125                                     size_t bufcount);
126
127/**
128 * \brief   destroys a buffer allocator by freeing up all the resources used
129 *          by the buffers
130 *
131 * \param   alloc   the allocator to destroy
132 *
133 * \returns SYS_ERR_OK on success
134 */
135errval_t virtio_buffer_alloc_destroy(struct virtio_buffer_allocator *alloc);
136
137/**
138 * \brief   allocated a new virti_buffer from the buffer allocator
139 */
140struct virtio_buffer *virtio_buffer_alloc(struct virtio_buffer_allocator *alloc);
141
142/**
143 * \brief   frees up a unused buffer by returning it to the allocator
144 *
145 * \param   buf     the buffer to be freed
146 */
147errval_t virtio_buffer_free(struct virtio_buffer *buf);
148
149/**
150 * \brief   returns the backing frame capability of a buffer allocator
151 */
152void virtio_buffer_alloc_get_cap(struct virtio_buffer_allocator *alloc,
153                                     struct capref *ret_cap,
154                                     lpaddr_t *offset);
155
156/**
157 * \brief returns the virtual range this buffer allocator spans
158 *
159 * \param alloc the virtio buffer allocator
160 * \param vaddr virtual address the region starts
161 * \param size  the size of the memory region
162 */
163void virtio_buffer_alloc_get_range(struct virtio_buffer_allocator *alloc,
164                                   lvaddr_t *vaddr,
165                                   size_t *size);
166
167/**
168 * \brief initializes a new VirtIO buffer list to be used for chaining buffers
169 *
170 * \param bl buffer list to initialize
171 *
172 * \return SYS_ERR_OK on success
173 */
174errval_t virtio_blist_init(struct virtio_buffer_list *bl);
175
176/**
177 * \brief frees up the buffer list by returning the buffers to the allocator
178 *
179 * \param bl buffer list to be freed
180 *
181 * \returns SYS_ERR_OK on success
182 */
183errval_t virtio_blist_free(struct virtio_buffer_list *bl);
184
185/**
186 * \brief appends a buffer to the tail of buffer list
187 *
188 * \param bl    the list to append the buffer to
189 * \param buf   the buffer to be appended
190 */
191errval_t virtio_blist_append(struct virtio_buffer_list *bl,
192                             struct virtio_buffer *buf);
193
194/**
195 * \brief prepend a buffer to the tail of buffer list
196 *
197 * \param bl    the list to prepend the buffer to
198 * \param buf   the buffer to be prepended
199 */
200errval_t virtio_blist_prepend(struct virtio_buffer_list *bl,
201                              struct virtio_buffer *buf);
202
203/**
204 * \brief returns and removes the head of the list
205 *
206 * \param bl buffer list
207 *
208 * \returns pointer to virtio_buffer on sucess
209 *          NULL on failuer
210 */
211struct virtio_buffer *virtio_blist_head(struct virtio_buffer_list *bl);
212
213/**
214 * \brief returns and removes the tail of the list
215 *
216 * \param bl buffer list
217 *
218 * \returns pointer to virtio_buffer on sucess
219 *          NULL on failuer
220 */
221struct virtio_buffer *virtio_blist_tail(struct virtio_buffer_list *bl);
222
223#endif // VIRTIO_H
224