virtio_ring.h revision 227652
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: head/sys/dev/virtio/virtio_ring.h 227652 2011-11-18 05:43:43Z grehan $ */
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". */
32struct 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
43struct 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. */
50struct 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
57struct vring_used {
58        uint16_t flags;
59        uint16_t idx;
60        struct vring_used_elem ring[0];
61};
62
63struct 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
95static inline int
96vring_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
108static inline void
109vring_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