Use size_t cast instead of fixed-length integer cast
[ipc/ipcdev.git] / packages / ti / ipc / rpmsg / virtio_ring.h
1 #ifndef _LINUX_VIRTIO_RING_H
2 #define _LINUX_VIRTIO_RING_H
3 /* An interface for efficient virtio implementation, currently for use by KVM
4  * and lguest, but hopefully others soon.  Do NOT change this since it will
5  * break existing servers and clients.
6  *
7  * This header is BSD licensed so anyone can use the definitions to implement
8  * compatible drivers/servers.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. Neither the name of IBM nor the names of its contributors
19  *    may be used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  * Copyright Rusty Russell IBM Corporation 2007. */
34 #include <xdc/std.h>
36 /* This marks a buffer as continuing via the next field. */
37 #define VRING_DESC_F_NEXT   1
38 /* This marks a buffer as write-only (otherwise read-only). */
39 #define VRING_DESC_F_WRITE  2
41 /* The Host uses this in used->flags to advise the Guest: don't kick me when
42  * you add a buffer.  It's unreliable, so it's simply an optimization.  Guest
43  * will still kick if it's out of buffers. */
44 #define VRING_USED_F_NO_NOTIFY  1
45 /* The Guest uses this in avail->flags to advise the Host: don't interrupt me
46  * when you consume a buffer.  It's unreliable, so it's simply an
47  * optimization.  */
48 #define VRING_AVAIL_F_NO_INTERRUPT  1
50 /* Virtio ring descriptors: 16 bytes.  These can chain together via "next". */
51 struct vring_desc
52 {
53     /* Address (guest-physical). */
54     UInt32 addr;
56     UInt32 padding; /* Because 64 bits is originally used for addr */
58     /* Length. */
59     UInt32 len;
60     /* The flags as indicated above. */  /* Optional for now! */
61     UInt16 flags;
62     /* We chain unused descriptors via this, too */
63     UInt16 next;
64 };
66 struct vring_avail
67 {
68     UInt16 flags;
69     UInt16 idx;
70     UInt16 ring[256];
71 };
73 /* u32 is used here for ids for padding reasons. */
74 struct vring_used_elem
75 {
76     /* Index of start of used descriptor chain. */
77     UInt32 id;
78     /* Total length of the descriptor chain which was used (written to) */
79     UInt32 len;
80 };
82 struct vring_used
83 {
84     UInt16 flags;
85     UInt16 idx;
86     struct vring_used_elem ring[256];
87 };
89 struct vring {
90     unsigned int num;
92     struct vring_desc *desc;
94     struct vring_avail *avail;
96     struct vring_used *used;
97 };
99 /*
100  * When you boot you have to add all the buffers to your own A8
101  * - Call add buf repeatedly
102  * - When we take the buffer from the available list, you should have the pointer in the descriptor address
103  *
104  */
106 /* The standard layout for the ring is a continuous chunk of memory which looks
107  * like this.  We assume num is a power of 2.
108  *
109  * struct vring
110  * {
111  *    // The actual descriptors (16 bytes each)
112  *    struct vring_desc desc[num];
113  *
114  *    // A ring of available descriptor heads with free-running index.
115  *    UInt16 avail_flags;
116  *    UInt16 avail_idx;
117  *    UInt16 available[num];
118  *
119  *    // Padding to the next page boundary.
120  *    char pad[];
121  *
122  *    // A ring of used descriptor heads with free-running index.
123  *    UInt16 used_flags;
124  *    UInt16 used_idx;
125  *    struct vring_used_elem used[num];
126  * };
127  */
128 static inline void vring_init(struct vring *vr, unsigned int num, void *p,
129                               unsigned long pagesize)
131     vr->num = num;
132     vr->desc = p;
133     vr->avail = (struct vring_avail *)(size_t)
134                     ((size_t)p + (num * sizeof(struct vring_desc)));
135     /*
136      * Suppress Coverity Error: Indexing "vr->avail->ring" with "num".
137      * This should be OK, because this is just address calculation:
138      */
139     /* coverity[index_parm] */
140     vr->used = (struct vring_used *)(size_t)
141                    (((size_t)&vr->avail->ring[num] + pagesize-1) &
142                    ~(pagesize - 1));
145 static inline unsigned vring_size(unsigned int num, unsigned long pagesize)
147     return ((sizeof(struct vring_desc) * num + sizeof(UInt16) * (2 + num)
148                 + pagesize - 1) & ~(pagesize - 1))
149                 + sizeof(UInt16) * 2 + sizeof(struct vring_used_elem) * num;
152 #ifdef __KERNEL__
153 #include <linux/interrupt.h>
154 struct virtio_device;
155 struct virtqueue;
157 struct virtqueue *vring_new_virtqueue(unsigned int num,
158                                       struct virtio_device *vdev,
159                                       void *pages,
160                                       void (*notify)(struct virtqueue *vq),
161                                       void (*callback)(struct virtqueue *vq));
163 void vring_del_virtqueue(struct virtqueue *vq);
164 /* Filter out transport-specific feature bits. */
165 void vring_transport_features(struct virtio_device *vdev);
167 irqreturn_t vring_interrupt(int irq, void *_vq);
168 #endif /* __KERNEL__ */
169 #endif /* _LINUX_VIRTIO_RING_H */