Merge remote-tracking branch 'remotes/amarkovic/tags/mips-queue-january-17-2019-v2...
[qemu.git] / tests / libqos / virtio.h
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
13 #include "libqos/malloc.h"
14 #include "standard-headers/linux/virtio_ring.h"
15
16 #define QVIRTIO_F_BAD_FEATURE 0x40000000
17
18 typedef struct QVirtioDevice {
19 /* Device type */
20 uint16_t device_type;
21 } QVirtioDevice;
22
23 typedef struct QVirtQueue {
24 uint64_t desc; /* This points to an array of struct vring_desc */
25 uint64_t avail; /* This points to a struct vring_avail */
26 uint64_t used; /* This points to a struct vring_desc */
27 uint16_t index;
28 uint32_t size;
29 uint32_t free_head;
30 uint32_t num_free;
31 uint32_t align;
32 bool indirect;
33 bool event;
34 } QVirtQueue;
35
36 typedef struct QVRingIndirectDesc {
37 uint64_t desc; /* This points to an array fo struct vring_desc */
38 uint16_t index;
39 uint16_t elem;
40 } QVRingIndirectDesc;
41
42 typedef struct QVirtioBus {
43 uint8_t (*config_readb)(QVirtioDevice *d, uint64_t addr);
44 uint16_t (*config_readw)(QVirtioDevice *d, uint64_t addr);
45 uint32_t (*config_readl)(QVirtioDevice *d, uint64_t addr);
46 uint64_t (*config_readq)(QVirtioDevice *d, uint64_t addr);
47
48 /* Get features of the device */
49 uint32_t (*get_features)(QVirtioDevice *d);
50
51 /* Set features of the device */
52 void (*set_features)(QVirtioDevice *d, uint32_t features);
53
54 /* Get features of the guest */
55 uint32_t (*get_guest_features)(QVirtioDevice *d);
56
57 /* Get status of the device */
58 uint8_t (*get_status)(QVirtioDevice *d);
59
60 /* Set status of the device */
61 void (*set_status)(QVirtioDevice *d, uint8_t status);
62
63 /* Get the queue ISR status of the device */
64 bool (*get_queue_isr_status)(QVirtioDevice *d, QVirtQueue *vq);
65
66 /* Get the configuration ISR status of the device */
67 bool (*get_config_isr_status)(QVirtioDevice *d);
68
69 /* Select a queue to work on */
70 void (*queue_select)(QVirtioDevice *d, uint16_t index);
71
72 /* Get the size of the selected queue */
73 uint16_t (*get_queue_size)(QVirtioDevice *d);
74
75 /* Set the address of the selected queue */
76 void (*set_queue_address)(QVirtioDevice *d, uint32_t pfn);
77
78 /* Setup the virtqueue specified by index */
79 QVirtQueue *(*virtqueue_setup)(QVirtioDevice *d, QGuestAllocator *alloc,
80 uint16_t index);
81
82 /* Free virtqueue resources */
83 void (*virtqueue_cleanup)(QVirtQueue *vq, QGuestAllocator *alloc);
84
85 /* Notify changes in virtqueue */
86 void (*virtqueue_kick)(QVirtioDevice *d, QVirtQueue *vq);
87 } QVirtioBus;
88
89 static inline uint32_t qvring_size(uint32_t num, uint32_t align)
90 {
91 return ((sizeof(struct vring_desc) * num + sizeof(uint16_t) * (3 + num)
92 + align - 1) & ~(align - 1))
93 + sizeof(uint16_t) * 3 + sizeof(struct vring_used_elem) * num;
94 }
95
96 uint8_t qvirtio_config_readb(const QVirtioBus *bus, QVirtioDevice *d,
97 uint64_t addr);
98 uint16_t qvirtio_config_readw(const QVirtioBus *bus, QVirtioDevice *d,
99 uint64_t addr);
100 uint32_t qvirtio_config_readl(const QVirtioBus *bus, QVirtioDevice *d,
101 uint64_t addr);
102 uint64_t qvirtio_config_readq(const QVirtioBus *bus, QVirtioDevice *d,
103 uint64_t addr);
104 uint32_t qvirtio_get_features(const QVirtioBus *bus, QVirtioDevice *d);
105 void qvirtio_set_features(const QVirtioBus *bus, QVirtioDevice *d,
106 uint32_t features);
107
108 void qvirtio_reset(const QVirtioBus *bus, QVirtioDevice *d);
109 void qvirtio_set_acknowledge(const QVirtioBus *bus, QVirtioDevice *d);
110 void qvirtio_set_driver(const QVirtioBus *bus, QVirtioDevice *d);
111 void qvirtio_set_driver_ok(const QVirtioBus *bus, QVirtioDevice *d);
112
113 void qvirtio_wait_queue_isr(const QVirtioBus *bus, QVirtioDevice *d,
114 QVirtQueue *vq, gint64 timeout_us);
115 uint8_t qvirtio_wait_status_byte_no_isr(const QVirtioBus *bus,
116 QVirtioDevice *d,
117 QVirtQueue *vq,
118 uint64_t addr,
119 gint64 timeout_us);
120 void qvirtio_wait_config_isr(const QVirtioBus *bus, QVirtioDevice *d,
121 gint64 timeout_us);
122 QVirtQueue *qvirtqueue_setup(const QVirtioBus *bus, QVirtioDevice *d,
123 QGuestAllocator *alloc, uint16_t index);
124 void qvirtqueue_cleanup(const QVirtioBus *bus, QVirtQueue *vq,
125 QGuestAllocator *alloc);
126
127 void qvring_init(const QGuestAllocator *alloc, QVirtQueue *vq, uint64_t addr);
128 QVRingIndirectDesc *qvring_indirect_desc_setup(QVirtioDevice *d,
129 QGuestAllocator *alloc, uint16_t elem);
130 void qvring_indirect_desc_add(QVRingIndirectDesc *indirect, uint64_t data,
131 uint32_t len, bool write);
132 uint32_t qvirtqueue_add(QVirtQueue *vq, uint64_t data, uint32_t len, bool write,
133 bool next);
134 uint32_t qvirtqueue_add_indirect(QVirtQueue *vq, QVRingIndirectDesc *indirect);
135 void qvirtqueue_kick(const QVirtioBus *bus, QVirtioDevice *d, QVirtQueue *vq,
136 uint32_t free_head);
137
138 void qvirtqueue_set_used_event(QVirtQueue *vq, uint16_t idx);
139 #endif