1
2
3
4
5#ifndef _VIRTIO_RING_H_
6#define _VIRTIO_RING_H_
7
8#include <stdint.h>
9
10#include <rte_common.h>
11
12
13#define VRING_DESC_F_NEXT 1
14
15#define VRING_DESC_F_WRITE 2
16
17#define VRING_DESC_F_INDIRECT 4
18
19
20#define VRING_PACKED_DESC_F_AVAIL (1 << 7)
21
22#define VRING_PACKED_DESC_F_USED (1 << 15)
23
24
25#define VRING_PACKED_DESC_F_AVAIL_USED (VRING_PACKED_DESC_F_AVAIL | \
26 VRING_PACKED_DESC_F_USED)
27
28
29
30
31#define VRING_USED_F_NO_NOTIFY 1
32
33
34
35#define VRING_AVAIL_F_NO_INTERRUPT 1
36
37
38
39struct vring_desc {
40 uint64_t addr;
41 uint32_t len;
42 uint16_t flags;
43 uint16_t next;
44};
45
46struct vring_avail {
47 uint16_t flags;
48 uint16_t idx;
49 uint16_t ring[0];
50};
51
52
53struct vring_used_elem {
54
55 uint32_t id;
56
57 uint32_t len;
58};
59
60struct vring_used {
61 uint16_t flags;
62 uint16_t idx;
63 struct vring_used_elem ring[0];
64};
65
66
67
68
69struct vring_packed_desc {
70 uint64_t addr;
71 uint32_t len;
72 uint16_t id;
73 uint16_t flags;
74};
75
76#define RING_EVENT_FLAGS_ENABLE 0x0
77#define RING_EVENT_FLAGS_DISABLE 0x1
78#define RING_EVENT_FLAGS_DESC 0x2
79struct vring_packed_desc_event {
80 uint16_t desc_event_off_wrap;
81 uint16_t desc_event_flags;
82};
83
84struct vring_packed {
85 unsigned int num;
86 struct vring_packed_desc *desc;
87 struct vring_packed_desc_event *driver;
88 struct vring_packed_desc_event *device;
89};
90
91struct vring {
92 unsigned int num;
93 struct vring_desc *desc;
94 struct vring_avail *avail;
95 struct vring_used *used;
96};
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128#define vring_used_event(vr) ((vr)->avail->ring[(vr)->num])
129#define vring_avail_event(vr) (*(uint16_t *)&(vr)->used->ring[(vr)->num])
130
131static inline size_t
132vring_size(struct virtio_hw *hw, unsigned int num, unsigned long align)
133{
134 size_t size;
135
136 if (virtio_with_packed_queue(hw)) {
137 size = num * sizeof(struct vring_packed_desc);
138 size += sizeof(struct vring_packed_desc_event);
139 size = RTE_ALIGN_CEIL(size, align);
140 size += sizeof(struct vring_packed_desc_event);
141 return size;
142 }
143
144 size = num * sizeof(struct vring_desc);
145 size += sizeof(struct vring_avail) + (num * sizeof(uint16_t));
146 size = RTE_ALIGN_CEIL(size, align);
147 size += sizeof(struct vring_used) +
148 (num * sizeof(struct vring_used_elem));
149 return size;
150}
151static inline void
152vring_init_split(struct vring *vr, uint8_t *p, unsigned long align,
153 unsigned int num)
154{
155 vr->num = num;
156 vr->desc = (struct vring_desc *) p;
157 vr->avail = (struct vring_avail *) (p +
158 num * sizeof(struct vring_desc));
159 vr->used = (void *)
160 RTE_ALIGN_CEIL((uintptr_t)(&vr->avail->ring[num]), align);
161}
162
163static inline void
164vring_init_packed(struct vring_packed *vr, uint8_t *p, unsigned long align,
165 unsigned int num)
166{
167 vr->num = num;
168 vr->desc = (struct vring_packed_desc *)p;
169 vr->driver = (struct vring_packed_desc_event *)(p +
170 vr->num * sizeof(struct vring_packed_desc));
171 vr->device = (struct vring_packed_desc_event *)
172 RTE_ALIGN_CEIL(((uintptr_t)vr->driver +
173 sizeof(struct vring_packed_desc_event)), align);
174}
175
176
177
178
179
180
181
182static inline int
183vring_need_event(uint16_t event_idx, uint16_t new_idx, uint16_t old)
184{
185 return (uint16_t)(new_idx - event_idx - 1) < (uint16_t)(new_idx - old);
186}
187
188#endif
189