Asynchronous reads added
[qemu/ovp.git] / qemu-vio-virtio.h
blobab4993e7ffc0eb1e5ff5c15bbbe3dd2c7f666f8f
1 #ifndef QUEMU_VIO_VIRTIO_H
2 #define QUEMU_VIO_VIRTIO_H
4 #include <stdint.h>
6 #include "targphys.h"
7 #include "block.h"
8 #include "sysemu.h"
9 #include "targphys.h"
11 #include <linux/virtio_blk.h>
13 #define VIRTQUEUE_MAX_SIZE 1024
14 #define BLOCK_SERIAL_STRLEN 20
16 #define VIRTIO_BLK_S_OK 0
17 #define VIRTIO_BLK_S_IOERR 1
18 #define VIRTIO_BLK_S_UNSUPP 2
20 #define VIRTQUEUE_MAX_SIZE 1024
21 #define VIRTIO_PCI_VRING_ALIGN 4096
24 #define VIRTIO_CONFIG_S_ACKNOWLEDGE 1
25 /* We have found a driver for the device. */
26 #define VIRTIO_CONFIG_S_DRIVER 2
27 /* Driver has used its parts of the config, and is happy */
28 #define VIRTIO_CONFIG_S_DRIVER_OK 4
29 /* We've given up on this device. */
30 #define VIRTIO_CONFIG_S_FAILED 0x80
32 /* Some virtio feature bits (currently bits 28 through 31) are reserved for the
33 * transport being used (eg. virtio_ring), the rest are per-device feature bits. */
34 #define VIRTIO_TRANSPORT_F_START 28
35 #define VIRTIO_TRANSPORT_F_END 32
37 /* We notify when the ring is completely used, even if the guest is suppressing
38 * callbacks */
39 #define VIRTIO_F_NOTIFY_ON_EMPTY 24
40 /* We support indirect buffer descriptors */
41 #define VIRTIO_RING_F_INDIRECT_DESC 28
42 /* A guest should never accept this. It implies negotiation is broken. */
43 #define VIRTIO_F_BAD_FEATURE 30
45 /* from Linux's linux/virtio_ring.h */
47 /* This marks a buffer as continuing via the next field. */
48 #define VRING_DESC_F_NEXT 1
49 /* This marks a buffer as write-only (otherwise read-only). */
50 #define VRING_DESC_F_WRITE 2
51 /* This means the buffer contains a list of buffer descriptors. */
52 #define VRING_DESC_F_INDIRECT 4
54 /* This means don't notify other side when buffer added. */
55 #define VRING_USED_F_NO_NOTIFY 1
56 /* This means don't interrupt guest when buffer consumed. */
57 #define VRING_AVAIL_F_NO_INTERRUPT 1
59 #ifndef offsetof
60 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *) 0)->MEMBER)
61 #endif
62 #ifndef container_of
63 #define container_of(ptr, type, member) ({ \
64 const typeof(((type *) 0)->member) *__mptr = (ptr); \
65 (type *) ((char *) __mptr - offsetof(type, member));})
66 #endif
68 #ifndef MIN
69 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
70 #endif
71 #ifndef MAX
72 #define MAX(a, b) (((a) > (b)) ? (a) : (b))
73 #endif
75 /* This is the last element of the write scatter-gather list */
76 struct virtio_blk_inhdr
78 unsigned char status;
81 /* SCSI pass-through header */
83 struct virtio_scsi_inhdr
85 uint32_t errors;
86 uint32_t data_len;
87 uint32_t sense_len;
88 uint32_t residual;
92 typedef struct {
93 void (*notify)(void * opaque, uint16_t vector);
94 void (*save_config)(void * opaque, QEMUFile *f);
95 void (*save_queue)(void * opaque, int n, QEMUFile *f);
96 int (*load_config)(void * opaque, QEMUFile *f);
97 int (*load_queue)(void * opaque, int n, QEMUFile *f);
98 unsigned (*get_features)(void * opaque);
99 } VirtIOBindings;
101 struct myiovec {
102 void *iov_base;
103 size_t iov_len;
106 typedef struct VRingDesc
108 uint64_t addr;
109 uint32_t len;
110 uint16_t flags;
111 uint16_t next;
112 } VRingDesc;
114 typedef struct VRingAvail
116 uint16_t flags;
117 uint16_t idx;
118 uint16_t ring[0];
119 } VRingAvail;
121 typedef struct VRingUsedElem
123 uint32_t id;
124 uint32_t len;
125 } VRingUsedElem;
127 typedef struct VRingUsed
129 uint16_t flags;
130 uint16_t idx;
131 VRingUsedElem ring[0];
132 } VRingUsed;
134 typedef struct VRing
136 unsigned int num;
137 target_phys_addr_t desc;
138 target_phys_addr_t avail;
139 target_phys_addr_t used;
140 } VRing;
142 typedef struct VirtQueue
144 VRing vring;
145 target_phys_addr_t pa;
146 uint16_t last_avail_idx;
147 int inuse;
148 uint16_t vector;
149 // void (*handle_output)(VirtIODevice *vdev, VirtQueue *vq);
150 } VirtQueue;
152 typedef struct VirtQueueElement
154 unsigned int index;
155 unsigned int out_num;
156 unsigned int in_num;
157 target_phys_addr_t in_addr[VIRTQUEUE_MAX_SIZE];
158 struct iovec in_sg[VIRTQUEUE_MAX_SIZE];
159 struct iovec out_sg[VIRTQUEUE_MAX_SIZE];
160 } VirtQueueElement;
162 struct VirtIODevice
164 const char *name;
165 uint8_t status;
166 uint8_t isr;
167 uint16_t queue_sel;
168 uint32_t features;
169 size_t config_len;
170 void *config;
171 uint16_t config_vector;
172 int nvectors;
173 uint32_t (*get_features)(VirtIODevice *vdev);
174 uint32_t (*bad_features)(VirtIODevice *vdev);
175 void (*set_features)(VirtIODevice *vdev, uint32_t val);
176 void (*get_config)(VirtIODevice *vdev, uint8_t *config);
177 void (*set_config)(VirtIODevice *vdev, const uint8_t *config);
178 void (*reset)(VirtIODevice *vdev);
179 VirtQueue *vq;
180 const VirtIOBindings *binding;
181 void *binding_opaque;
182 uint16_t device_id;
185 typedef struct VirtIOBlock
187 VirtIODevice vdev;
188 BlockDriverState *bs;
189 VirtQueue *vq;
190 void *rq;
191 char serial_str[BLOCK_SERIAL_STRLEN + 1];
192 QEMUBH *bh;
193 size_t config_size;
194 } VirtIOBlock;
196 typedef struct VirtIOBlockReq
198 VirtIOBlock *dev;
199 VirtQueueElement elem;
200 struct virtio_blk_inhdr *in;
201 struct virtio_blk_outhdr *out;
202 struct virtio_scsi_inhdr *scsi;
203 QEMUIOVector qiov;
204 struct VirtIOBlockReq *next;
205 } VirtIOBlockReq;
207 typedef struct MultiReqBuffer {
208 BlockRequest blkreq[32];
209 int num_writes;
210 BlockDriverState *old_bs;
211 } MultiReqBuffer;
213 void *cpu_physical_memory_map(target_phys_addr_t addr,
214 target_phys_addr_t *plen,
215 int is_write);
216 void cpu_physical_memory_unmap(void *buffer, target_phys_addr_t len,
217 int is_write, target_phys_addr_t access_len);
220 static inline __u64 ldq_phys(target_phys_addr_t pa) {
221 __u64 ret;
222 memcpy(&ret,(void *)pa,8);
223 return ret;
226 static inline __u32 ldl_phys(target_phys_addr_t pa) {
227 __u32 ret;
228 memcpy(&ret,(void *)pa,4);
229 return ret;
232 static inline __u16 lduw_phys(target_phys_addr_t pa) {
233 __u16 ret;
234 memcpy(&ret,(void *)pa,2);
235 return ret;
238 static inline void stl_phys(target_phys_addr_t pa, uint32_t val) {
239 memcpy((void *)pa,&val,4);
242 static inline void stw_phys(target_phys_addr_t pa, uint16_t val) {
243 memcpy((void *)pa,&val,2);
246 void virtqueue_init(VirtQueue *vq);
247 void virtqueue_push(VirtQueue *vq, const VirtQueueElement *elem,unsigned int len);
248 int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem);
249 void virtio_notify(VirtQueue *vq);
251 #endif