]> git.proxmox.com Git - mirror_qemu.git/blame - tests/libqos/virtio.h
libqos: Added basic virtqueue support to virtio implementation
[mirror_qemu.git] / tests / libqos / virtio.h
CommitLineData
311e666a
MM
1/*
2 * libqos virtio definitions
3 *
4 * Copyright (c) 2014 Marc Marí
5 *
6 * This work is licensed under the terms of the GNU GPL, version 2 or later.
7 * See the COPYING file in the top-level directory.
8 */
9
10#ifndef LIBQOS_VIRTIO_H
11#define LIBQOS_VIRTIO_H
12
bf3c63d2
MM
13#include "libqos/malloc.h"
14
311e666a
MM
15#define QVIRTIO_VENDOR_ID 0x1AF4
16
46e0cf76
MM
17#define QVIRTIO_RESET 0x0
18#define QVIRTIO_ACKNOWLEDGE 0x1
19#define QVIRTIO_DRIVER 0x2
bf3c63d2 20#define QVIRTIO_DRIVER_OK 0x4
46e0cf76 21
311e666a
MM
22#define QVIRTIO_NET_DEVICE_ID 0x1
23#define QVIRTIO_BLK_DEVICE_ID 0x2
24
bf3c63d2
MM
25#define QVRING_DESC_F_NEXT 0x1
26#define QVRING_DESC_F_WRITE 0x2
27#define QVRING_DESC_F_INDIRECT 0x4
28
29#define QVIRTIO_F_NOTIFY_ON_EMPTY 0x01000000
30#define QVIRTIO_F_ANY_LAYOUT 0x08000000
31#define QVIRTIO_F_RING_INDIRECT_DESC 0x10000000
32#define QVIRTIO_F_RING_EVENT_IDX 0x20000000
33#define QVIRTIO_F_BAD_FEATURE 0x40000000
34
35#define QVRING_AVAIL_F_NO_INTERRUPT 1
36
37#define QVRING_USED_F_NO_NOTIFY 1
38
311e666a
MM
39typedef struct QVirtioDevice {
40 /* Device type */
41 uint16_t device_type;
42} QVirtioDevice;
43
bf3c63d2
MM
44typedef struct QVRingDesc {
45 uint64_t addr;
46 uint32_t len;
47 uint16_t flags;
48 uint16_t next;
49} QVRingDesc;
50
51typedef struct QVRingAvail {
52 uint16_t flags;
53 uint16_t idx;
54 uint16_t ring[0]; /* This is an array of uint16_t */
55} QVRingAvail;
56
57typedef struct QVRingUsedElem {
58 uint32_t id;
59 uint32_t len;
60} QVRingUsedElem;
61
62typedef struct QVRingUsed {
63 uint16_t flags;
64 uint16_t idx;
65 QVRingUsedElem ring[0]; /* This is an array of QVRingUsedElem structs */
66} QVRingUsed;
67
68typedef struct QVirtQueue {
69 uint64_t desc; /* This points to an array of QVRingDesc */
70 uint64_t avail; /* This points to a QVRingAvail */
71 uint64_t used; /* This points to a QVRingDesc */
72 uint16_t index;
73 uint32_t size;
74 uint32_t free_head;
75 uint32_t num_free;
76 uint32_t align;
77} QVirtQueue;
78
46e0cf76
MM
79typedef struct QVirtioBus {
80 uint8_t (*config_readb)(QVirtioDevice *d, void *addr);
81 uint16_t (*config_readw)(QVirtioDevice *d, void *addr);
82 uint32_t (*config_readl)(QVirtioDevice *d, void *addr);
83 uint64_t (*config_readq)(QVirtioDevice *d, void *addr);
84
bf3c63d2
MM
85 /* Get features of the device */
86 uint32_t (*get_features)(QVirtioDevice *d);
87
88 /* Get features of the device */
89 void (*set_features)(QVirtioDevice *d, uint32_t features);
90
46e0cf76
MM
91 /* Get status of the device */
92 uint8_t (*get_status)(QVirtioDevice *d);
93
94 /* Set status of the device */
95 void (*set_status)(QVirtioDevice *d, uint8_t status);
bf3c63d2
MM
96
97 /* Get the ISR status of the device */
98 uint8_t (*get_isr_status)(QVirtioDevice *d);
99
100 /* Select a queue to work on */
101 void (*queue_select)(QVirtioDevice *d, uint16_t index);
102
103 /* Get the size of the selected queue */
104 uint16_t (*get_queue_size)(QVirtioDevice *d);
105
106 /* Set the address of the selected queue */
107 void (*set_queue_address)(QVirtioDevice *d, uint32_t pfn);
108
109 /* Setup the virtqueue specified by index */
110 QVirtQueue *(*virtqueue_setup)(QVirtioDevice *d, QGuestAllocator *alloc,
111 uint16_t index);
112
113 /* Notify changes in virtqueue */
114 void (*virtqueue_kick)(QVirtioDevice *d, QVirtQueue *vq);
46e0cf76
MM
115} QVirtioBus;
116
bf3c63d2
MM
117static inline uint32_t qvring_size(uint32_t num, uint32_t align)
118{
119 return ((sizeof(struct QVRingDesc) * num + sizeof(uint16_t) * (3 + num)
120 + align - 1) & ~(align - 1))
121 + sizeof(uint16_t) * 3 + sizeof(struct QVRingUsedElem) * num;
122}
123
46e0cf76
MM
124uint8_t qvirtio_config_readb(const QVirtioBus *bus, QVirtioDevice *d,
125 void *addr);
126uint16_t qvirtio_config_readw(const QVirtioBus *bus, QVirtioDevice *d,
127 void *addr);
128uint32_t qvirtio_config_readl(const QVirtioBus *bus, QVirtioDevice *d,
129 void *addr);
130uint64_t qvirtio_config_readq(const QVirtioBus *bus, QVirtioDevice *d,
131 void *addr);
bf3c63d2
MM
132uint32_t qvirtio_get_features(const QVirtioBus *bus, QVirtioDevice *d);
133void qvirtio_set_features(const QVirtioBus *bus, QVirtioDevice *d,
134 uint32_t features);
46e0cf76
MM
135
136void qvirtio_reset(const QVirtioBus *bus, QVirtioDevice *d);
137void qvirtio_set_acknowledge(const QVirtioBus *bus, QVirtioDevice *d);
138void qvirtio_set_driver(const QVirtioBus *bus, QVirtioDevice *d);
bf3c63d2
MM
139void qvirtio_set_driver_ok(const QVirtioBus *bus, QVirtioDevice *d);
140
141bool qvirtio_wait_isr(const QVirtioBus *bus, QVirtioDevice *d, uint8_t mask,
142 uint64_t timeout);
143QVirtQueue *qvirtqueue_setup(const QVirtioBus *bus, QVirtioDevice *d,
144 QGuestAllocator *alloc, uint16_t index);
145
146void qvring_init(const QGuestAllocator *alloc, QVirtQueue *vq, uint64_t addr);
147uint32_t qvirtqueue_add(QVirtQueue *vq, uint64_t data, uint32_t len, bool write,
148 bool next);
149void qvirtqueue_kick(const QVirtioBus *bus, QVirtioDevice *d, QVirtQueue *vq,
150 uint32_t free_head);
46e0cf76 151
311e666a 152#endif