xref: /freebsd/sys/dev/virtio/virtio_ring.h (revision 10b59a9b4add0320d52c15ce057dd697261e7dfc)
1 /*
2  * This header is BSD licensed so anyone can use the definitions
3  * to implement compatible drivers/servers.
4  *
5  * Copyright Rusty Russell IBM Corporation 2007.
6  */
7 /* $FreeBSD$ */
8 
9 #ifndef VIRTIO_RING_H
10 #define	VIRTIO_RING_H
11 
12 #include <sys/types.h>
13 
14 /* This marks a buffer as continuing via the next field. */
15 #define VRING_DESC_F_NEXT       1
16 /* This marks a buffer as write-only (otherwise read-only). */
17 #define VRING_DESC_F_WRITE      2
18 /* This means the buffer contains a list of buffer descriptors. */
19 #define VRING_DESC_F_INDIRECT	4
20 
21 /* The Host uses this in used->flags to advise the Guest: don't kick me
22  * when you add a buffer.  It's unreliable, so it's simply an
23  * optimization.  Guest will still kick if it's out of buffers. */
24 #define VRING_USED_F_NO_NOTIFY  1
25 /* The Guest uses this in avail->flags to advise the Host: don't
26  * interrupt me when you consume a buffer.  It's unreliable, so it's
27  * simply an optimization.  */
28 #define VRING_AVAIL_F_NO_INTERRUPT      1
29 
30 /* VirtIO ring descriptors: 16 bytes.
31  * These can chain together via "next". */
32 struct vring_desc {
33         /* Address (guest-physical). */
34         uint64_t addr;
35         /* Length. */
36         uint32_t len;
37         /* The flags as indicated above. */
38         uint16_t flags;
39         /* We chain unused descriptors via this, too. */
40         uint16_t next;
41 };
42 
43 struct vring_avail {
44         uint16_t flags;
45         uint16_t idx;
46         uint16_t ring[0];
47 };
48 
49 /* uint32_t is used here for ids for padding reasons. */
50 struct vring_used_elem {
51         /* Index of start of used descriptor chain. */
52         uint32_t id;
53         /* Total length of the descriptor chain which was written to. */
54         uint32_t len;
55 };
56 
57 struct vring_used {
58         uint16_t flags;
59         uint16_t idx;
60         struct vring_used_elem ring[0];
61 };
62 
63 struct vring {
64 	unsigned int num;
65 
66 	struct vring_desc *desc;
67 	struct vring_avail *avail;
68 	struct vring_used *used;
69 };
70 
71 /* The standard layout for the ring is a continuous chunk of memory which
72  * looks like this.  We assume num is a power of 2.
73  *
74  * struct vring {
75  *      // The actual descriptors (16 bytes each)
76  *      struct vring_desc desc[num];
77  *
78  *      // A ring of available descriptor heads with free-running index.
79  *      __u16 avail_flags;
80  *      __u16 avail_idx;
81  *      __u16 available[num];
82  *
83  *      // Padding to the next align boundary.
84  *      char pad[];
85  *
86  *      // A ring of used descriptor heads with free-running index.
87  *      __u16 used_flags;
88  *      __u16 used_idx;
89  *      struct vring_used_elem used[num];
90  * };
91  *
92  * NOTE: for VirtIO PCI, align is 4096.
93  */
94 
95 static inline int
96 vring_size(unsigned int num, unsigned long align)
97 {
98 	int size;
99 
100 	size = num * sizeof(struct vring_desc);
101 	size += sizeof(struct vring_avail) + (num * sizeof(uint16_t));
102 	size = (size + align - 1) & ~(align - 1);
103 	size += sizeof(struct vring_used) +
104 	    (num * sizeof(struct vring_used_elem));
105 	return (size);
106 }
107 
108 static inline void
109 vring_init(struct vring *vr, unsigned int num, uint8_t *p,
110     unsigned long align)
111 {
112         vr->num = num;
113         vr->desc = (struct vring_desc *) p;
114         vr->avail = (struct vring_avail *) (p +
115 	    num * sizeof(struct vring_desc));
116         vr->used = (void *)
117 	    (((unsigned long) &vr->avail->ring[num] + align-1) & ~(align-1));
118 }
119 #endif /* VIRTIO_RING_H */
120