Begin work on true virtio mmio Kill tests/vmrunkernel.c Our makefiles, plus emacs...
[akaros.git] / user / vmm / include / virtio.h
1 #ifndef VIRTIO_VIRTIO_H
2 #define VIRTIO_VIRTIO_H
3
4 #include <ros/arch/membar.h>
5 #include <ros/arch/mmu.h>
6 #include <ros/virtio_ring.h>
7 #include <ros/common.h>
8
9 #include <stddef.h>
10 #include <stdbool.h>
11
12 /* this is just an iov but we're going to keep the type for now, in case
13  * we want it at some point.
14  */
15 struct scatterlist {
16         void *v;
17         int length;
18 };
19
20 #define unlikely(x) (x)
21 #define virtio_rmb(x) rmb()
22 #define virtio_wmb(x) wmb()
23 #define virtio_mb(x) mb()
24
25 #define sg_phys(x) ((uintptr_t)x)
26 #define virt_to_phys(x) ((uintptr_t)x)
27
28 struct virtqueue *vring_new_virtqueue(unsigned int index,
29                                       unsigned int num,
30                                       unsigned int vring_align,
31                                       bool weak_barriers,
32                                       void *pages,
33                                       bool (*notify)(struct virtqueue *),
34                                       void (*callback)(struct virtqueue *),
35                                       const char *name);
36
37 int virtqueue_add_outbuf_avail(struct virtqueue *vq,
38                          struct scatterlist sg[], unsigned int num,
39                          void *data,
40                                int opts); // Opts only used in kernel functions.
41 unsigned int virtqueue_get_vring_size(struct virtqueue *_vq);
42 void *virtqueue_get_buf_used(struct virtqueue *_vq, unsigned int *len);
43 int virtqueue_add_inbuf_avail(struct virtqueue *vq,
44                         struct scatterlist sg[], unsigned int num,
45                               void *data, int opts);
46
47 /* linux-isms we may or may not ever care about. */
48 #define __user
49 #define __force
50 #define __cold
51
52 int avail(struct virtqueue *_vq);
53 void showvq(struct virtqueue *_vq);
54 void showdesc(struct virtqueue *_vq, uint16_t head);
55 int virtio_get_buf_avail_start(struct virtqueue *_vq, uint16_t *last_avail_idx, struct scatterlist **sgp, int *sgplen);
56 void virtio_get_buf_avail_done(struct virtqueue *_vq, uint16_t last_avail_idx, int id, int len);
57 void showscatterlist(struct scatterlist *sg, int num);
58
59 unsigned int wait_for_vq_desc(struct virtqueue *vq,
60                                  struct scatterlist iov[],
61                                  unsigned int *out_num, unsigned int *in_num);
62 void add_used(struct virtqueue *vq, unsigned int head, int len);
63
64 /**
65  * virtqueue - a queue to register buffers for sending or receiving.
66  * @list: the chain of virtqueues for this device
67  * @callback: the function to call when buffers are consumed (can be NULL).
68  * @name: the name of this virtqueue (mainly for debugging)
69  * @vdev: the virtio device this queue was created for.
70  * @priv: a pointer for the virtqueue implementation to use.
71  * @index: the zero-based ordinal number for this queue.
72  * @num_free: number of elements we expect to be able to fit.
73  *
74  * A note on @num_free: with indirect buffers, each buffer needs one
75  * element in the queue, otherwise a buffer will need one element per
76  * sg element.
77  */
78 struct virtqueue {
79         void (*callback)(struct virtqueue *vq);
80         const char *name;
81         unsigned int index;
82         unsigned int num_free;
83         void *priv;
84 };
85
86 int virtqueue_add_outbuf(struct virtqueue *vq,
87                          struct scatterlist sg[], unsigned int num,
88                          void *data,
89                          int flags);
90
91 int virtqueue_add_inbuf(struct virtqueue *vq,
92                         struct scatterlist sg[], unsigned int num,
93                         void *data,
94                         int flags);
95
96 int virtqueue_add_sgs(struct virtqueue *vq,
97                       struct scatterlist *sgs[],
98                       unsigned int out_sgs,
99                       unsigned int in_sgs,
100                       void *data,
101                       int flags);
102
103 bool virtqueue_kick(struct virtqueue *vq);
104
105 bool virtqueue_kick_prepare(struct virtqueue *vq);
106
107 bool virtqueue_notify(struct virtqueue *vq);
108
109 void *virtqueue_get_buf(struct virtqueue *vq, unsigned int *len);
110
111 void virtqueue_disable_cb(struct virtqueue *vq);
112
113 bool virtqueue_enable_cb(struct virtqueue *vq);
114
115 unsigned virtqueue_enable_cb_prepare(struct virtqueue *vq);
116
117 bool virtqueue_poll(struct virtqueue *vq, unsigned);
118
119 bool virtqueue_enable_cb_delayed(struct virtqueue *vq);
120
121 void *virtqueue_detach_unused_buf(struct virtqueue *vq);
122
123 unsigned int virtqueue_get_vring_size(struct virtqueue *vq);
124
125 bool virtqueue_is_broken(struct virtqueue *vq);
126 void virtqueue_close(struct virtqueue *vq);
127
128 static inline uint32_t read32(const volatile void *addr)
129 {
130         return *(const volatile uint32_t *)addr;
131 }
132
133 static inline void write32(volatile void *addr, uint32_t value)
134 {
135         *(volatile uint32_t *)addr = value;
136 }
137
138 #endif /* VIRTIO_VIRTIO_H */