Fix virtio compile errors on various gcc versions.
[seabios.git] / src / virtio-ring.h
1 #ifndef _VIRTIO_RING_H
2 #define _VIRTIO_RING_H
3
4 #include "types.h" // u64
5 #include "memmap.h" // PAGE_SIZE
6
7 #define PAGE_SHIFT 12
8 #define PAGE_MASK  (PAGE_SIZE-1)
9
10 #define virt_to_phys(v) (unsigned long)(v)
11 #define phys_to_virt(p) (void*)(p)
12 #define wmb() barrier()
13 #define mb() barrier()
14
15 /* Status byte for guest to report progress, and synchronize features. */
16 /* We have seen device and processed generic fields (VIRTIO_CONFIG_F_VIRTIO) */
17 #define VIRTIO_CONFIG_S_ACKNOWLEDGE     1
18 /* We have found a driver for the device. */
19 #define VIRTIO_CONFIG_S_DRIVER          2
20 /* Driver has used its parts of the config, and is happy */
21 #define VIRTIO_CONFIG_S_DRIVER_OK       4
22 /* We've given up on this device. */
23 #define VIRTIO_CONFIG_S_FAILED          0x80
24
25 #define MAX_QUEUE_NUM      (128)
26
27 #define VRING_DESC_F_NEXT  1
28 #define VRING_DESC_F_WRITE 2
29
30 #define VRING_AVAIL_F_NO_INTERRUPT 1
31
32 #define VRING_USED_F_NO_NOTIFY     1
33
34 struct vring_desc
35 {
36    u64 addr;
37    u32 len;
38    u16 flags;
39    u16 next;
40 };
41
42 struct vring_avail
43 {
44    u16 flags;
45    u16 idx;
46    u16 ring[0];
47 };
48
49 struct vring_used_elem
50 {
51    u32 id;
52    u32 len;
53 };
54
55 struct vring_used
56 {
57    u16 flags;
58    u16 idx;
59    struct vring_used_elem ring[];
60 };
61
62 struct vring {
63    unsigned int num;
64    struct vring_desc *desc;
65    struct vring_avail *avail;
66    struct vring_used *used;
67 };
68
69 #define vring_size(num) \
70    (((((sizeof(struct vring_desc) * num) + \
71       (sizeof(struct vring_avail) + sizeof(u16) * num)) \
72          + PAGE_MASK) & ~PAGE_MASK) + \
73          (sizeof(struct vring_used) + sizeof(struct vring_used_elem) * num))
74
75 typedef unsigned char virtio_queue_t[PAGE_MASK + vring_size(MAX_QUEUE_NUM)];
76
77 struct vring_virtqueue {
78    virtio_queue_t queue;
79    struct vring vring;
80    u16 free_head;
81    u16 last_used_idx;
82    u16 vdata[MAX_QUEUE_NUM];
83    /* PCI */
84    int queue_index;
85 };
86
87 struct vring_list {
88   char *addr;
89   unsigned int length;
90 };
91
92 static inline void vring_init(struct vring *vr,
93                          unsigned int num, unsigned char *queue)
94 {
95    unsigned int i;
96    unsigned long pa;
97
98    ASSERT32FLAT();
99    vr->num = num;
100
101    /* physical address of desc must be page aligned */
102
103    pa = virt_to_phys(queue);
104    pa = (pa + PAGE_MASK) & ~PAGE_MASK;
105    vr->desc = phys_to_virt(pa);
106
107    vr->avail = (struct vring_avail *)&vr->desc[num];
108
109    /* physical address of used must be page aligned */
110
111    pa = virt_to_phys(&vr->avail->ring[num]);
112    pa = (pa + PAGE_MASK) & ~PAGE_MASK;
113    vr->used = phys_to_virt(pa);
114
115    for (i = 0; i < num - 1; i++)
116            vr->desc[i].next = i + 1;
117    vr->desc[i].next = 0;
118 }
119
120 int vring_more_used(struct vring_virtqueue *vq);
121 void vring_detach(struct vring_virtqueue *vq, unsigned int head);
122 int vring_get_buf(struct vring_virtqueue *vq, unsigned int *len);
123 void vring_add_buf(struct vring_virtqueue *vq, struct vring_list list[],
124                    unsigned int out, unsigned int in,
125                    int index, int num_added);
126 void vring_kick(unsigned int ioaddr, struct vring_virtqueue *vq, int num_added);
127
128 #endif /* _VIRTIO_RING_H_ */