OpenAMP Library  353
virtio_ring.h
Go to the documentation of this file.
1 /*
2  * Copyright Rusty Russell IBM Corporation 2007.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  * $FreeBSD$
7  */
8 
9 #ifndef VIRTIO_RING_H
10 #define VIRTIO_RING_H
11 
12 #include <metal/compiler.h>
13 
14 #if defined __cplusplus
15 extern "C" {
16 #endif
17 
18 /* This marks a buffer as continuing via the next field. */
19 #define VRING_DESC_F_NEXT 1
20 /* This marks a buffer as write-only (otherwise read-only). */
21 #define VRING_DESC_F_WRITE 2
22 /* This means the buffer contains a list of buffer descriptors. */
23 #define VRING_DESC_F_INDIRECT 4
24 
25 /* The Host uses this in used->flags to advise the Guest: don't kick me
26  * when you add a buffer. It's unreliable, so it's simply an
27  * optimization. Guest will still kick if it's out of buffers.
28  */
29 #define VRING_USED_F_NO_NOTIFY 1
30 /* The Guest uses this in avail->flags to advise the Host: don't
31  * interrupt me when you consume a buffer. It's unreliable, so it's
32  * simply an optimization.
33  */
34 #define VRING_AVAIL_F_NO_INTERRUPT 1
35 
46 METAL_PACKED_BEGIN
47 struct vring_desc {
49  uint64_t addr;
50 
52  uint32_t len;
53 
55  uint16_t flags;
56 
58  uint16_t next;
60 
67 METAL_PACKED_BEGIN
68 struct vring_avail {
70  uint16_t flags;
71 
76  uint16_t idx;
77 
79  uint16_t ring[0];
81 
82 /* uint32_t is used here for ids for padding reasons. */
83 METAL_PACKED_BEGIN
85  union {
86  uint16_t event;
87  /* Index of start of used descriptor chain. */
88  uint32_t id;
89  };
90  /* Total length of the descriptor chain which was written to. */
91  uint32_t len;
93 
99 METAL_PACKED_BEGIN
100 struct vring_used {
102  uint16_t flags;
103 
108  uint16_t idx;
109 
111  struct vring_used_elem ring[0];
113 
157 struct vring {
162  unsigned int num;
163 
165  struct vring_desc *desc;
166 
169 
171  struct vring_used *used;
172 };
173 
174 /*
175  * We publish the used event index at the end of the available ring, and vice
176  * versa. They are at the end for backwards compatibility.
177  */
178 #define vring_used_event(vr) ((vr)->avail->ring[(vr)->num])
179 #define vring_avail_event(vr) ((vr)->used->ring[(vr)->num].event)
180 
181 static inline int vring_size(unsigned int num, unsigned long align)
182 {
183  int size;
184 
185  size = num * sizeof(struct vring_desc);
186  size += sizeof(struct vring_avail) + (num * sizeof(uint16_t)) +
187  sizeof(uint16_t);
188  size = (size + align - 1) & ~(align - 1);
189  size += sizeof(struct vring_used) +
190  (num * sizeof(struct vring_used_elem)) + sizeof(uint16_t);
191 
192  return size;
193 }
194 
195 static inline void
196 vring_init(struct vring *vr, unsigned int num, uint8_t *p, unsigned long align)
197 {
198  vr->num = num;
199  vr->desc = (struct vring_desc *)p;
200  vr->avail = (struct vring_avail *)(p + num * sizeof(struct vring_desc));
201  vr->used = (struct vring_used *)
202  (((unsigned long)&vr->avail->ring[num] + sizeof(uint16_t) +
203  align - 1) & ~(align - 1));
204 }
205 
206 /*
207  * The following is used with VIRTIO_RING_F_EVENT_IDX.
208  *
209  * Assuming a given event_idx value from the other size, if we have
210  * just incremented index from old to new_idx, should we trigger an
211  * event?
212  */
213 static inline int
214 vring_need_event(uint16_t event_idx, uint16_t new_idx, uint16_t old)
215 {
216  return (uint16_t)(new_idx - event_idx - 1) <
217  (uint16_t)(new_idx - old);
218 }
219 
220 #if defined __cplusplus
221 }
222 #endif
223 
224 #endif /* VIRTIO_RING_H */
Used to offer buffers to the device.
Definition: virtio_ring.h:68
uint16_t idx
Indicates where the driver puts the next descriptor entry in the ring (modulo the queue size)
Definition: virtio_ring.h:76
uint16_t flags
Flag which determines whether device notifications are required.
Definition: virtio_ring.h:70
uint16_t ring[0]
The ring of descriptors.
Definition: virtio_ring.h:79
VirtIO ring descriptors.
Definition: virtio_ring.h:47
uint64_t addr
Address (guest-physical)
Definition: virtio_ring.h:49
uint16_t next
We chain unused descriptors via this, too.
Definition: virtio_ring.h:58
uint16_t flags
Flags relevant to the descriptors.
Definition: virtio_ring.h:55
uint32_t len
Length.
Definition: virtio_ring.h:52
Definition: virtio_ring.h:84
uint16_t event
Definition: virtio_ring.h:86
uint32_t id
Definition: virtio_ring.h:88
uint32_t len
Definition: virtio_ring.h:91
The device returns buffers to this structure when done with them.
Definition: virtio_ring.h:100
struct vring_used_elem ring[0]
The ring of descriptors.
Definition: virtio_ring.h:111
uint16_t idx
Indicates where the driver puts the next descriptor entry in the ring (modulo the queue size)
Definition: virtio_ring.h:108
uint16_t flags
Flag which determines whether device notifications are required.
Definition: virtio_ring.h:102
The virtqueue layout structure.
Definition: virtio_ring.h:157
struct vring_desc * desc
The actual buffer descriptors, 16 bytes each.
Definition: virtio_ring.h:165
struct vring_avail * avail
A ring of available descriptor heads with free-running index.
Definition: virtio_ring.h:168
unsigned int num
The maximum number of buffer descriptors in the virtqueue.
Definition: virtio_ring.h:162
struct vring_used * used
A ring of used descriptor heads with free-running index.
Definition: virtio_ring.h:171
METAL_PACKED_BEGIN struct vring_desc METAL_PACKED_END
static int vring_size(unsigned int num, unsigned long align)
Definition: virtio_ring.h:181
static int vring_need_event(uint16_t event_idx, uint16_t new_idx, uint16_t old)
Definition: virtio_ring.h:214
static void vring_init(struct vring *vr, unsigned int num, uint8_t *p, unsigned long align)
Definition: virtio_ring.h:196