[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC] Libqos virtio API
From: |
Marc Marí |
Subject: |
[Qemu-devel] [RFC] Libqos virtio API |
Date: |
Tue, 17 Jun 2014 11:02:48 +0200 |
This is the draft for the libqos virtio API to create test cases for virtio
devices. I'm looking forward to your comments.
Signed-off-by: Marc Marí <address@hidden>
---
tests/libqos/virtio.h | 148 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 148 insertions(+)
create mode 100644 tests/libqos/virtio.h
diff --git a/tests/libqos/virtio.h b/tests/libqos/virtio.h
new file mode 100644
index 0000000..03f28dc
--- /dev/null
+++ b/tests/libqos/virtio.h
@@ -0,0 +1,148 @@
+#define VIRTQUEUE_MAX_SIZE 1024
+
+struct QVirtioBus
+{
+ /* Send a notification IRQ to the device */
+ void (*notify)(QVirtioDevice *d, uint16_t vector);
+
+ /* Get configuration of the device */
+ void (*get_config)(QVirtioDevice *d, void *config);
+
+ /* Set configuration of the device */
+ void (*set_config)(QVirtioDevice *d, void *config);
+
+ /* Get features of the device */
+ uint32_t (*get_features)(QVirtioDevice *d);
+
+ /* Get status of the device */
+ uint8_t (*get_status)(QVirtioDevice *d);
+
+ /* Set status of the device */
+ void (*set_status)(QVirtioDevice *d, uint8_t val);
+
+ /* Reset the device */
+ void (*reset)(QVirtioDevice *d);
+
+ /* Check pending IRQs */
+ uint8_t (*query_isr)(QVirtioDevice *d);
+
+ /* Loop all devices, applying a function to all, or the one specified */
+ void (*device_foreach)(QVirtioBus *bus, uint16_t device_id,
+ void (*func)(QVirtioDevice *dev, void *data), void *data);
+
+ /* Find and return a device */
+ QVirtioDevice *(*device_find)(uint16_t device_id, int index);
+};
+
+QVirtioBus *qvirtio_pci_init();
+QVirtioBus *qvirtio_mmio_init();
+QVirtioBus *qvirtio_ccw_init();
+
+struct QVirtioDevice
+{
+ /* Index in all devices of the same type in the bus */
+ int index;
+
+ /* Device type */
+ uint16_t device_id;
+
+ /* VQs associated with the device */
+ QVirtQueue *vq;
+};
+
+/*
+I'm not sure what implementation of VirtQueue is better, QEMU's or Linux's. I
+think QEMU implementation is better, because it will be easier to connect the
+QEMU Virtqueue with the Libaos VirtQueue.
+
+The functions to use the VirtQueue are the ones I think necessary in Libqos,
but
+probably there are some missing and some others that are not necessary.
+*/
+struct QVirtQueue
+{
+ QVRing vring;
+ uint64_t pa;
+ uint16_t last_avail_idx;
+ uint16_t signalled_used;
+ bool signalled_used_valid;
+ bool notification;
+ uint16_t queue_index;
+ int inuse;
+ uint16_t vector;
+ void (*handle_output)(QVirtioDevice *d, VirtQueue *vq);
+ QVirtioDevice *dev;
+};
+
+typedef struct QVirtQueueElement
+{
+ unsigned int index;
+ unsigned int out_num;
+ unsigned int in_num;
+ uint64_t in_addr[VIRTQUEUE_MAX_SIZE];
+ uint64_t out_addr[VIRTQUEUE_MAX_SIZE];
+ struct iovec in_sg[VIRTQUEUE_MAX_SIZE];
+ struct iovec out_sg[VIRTQUEUE_MAX_SIZE];
+} QVirtQueueElement;
+
+typedef struct QVRingDesc
+{
+ uint64_t addr;
+ uint32_t len;
+ uint16_t flags;
+ uint16_t next;
+} QVRingDesc;
+
+typedef struct QVRingAvail
+{
+ uint16_t flags;
+ uint16_t idx;
+ uint16_t ring[0];
+} VRingAvail;
+
+typedef struct QVRingUsedElem
+{
+ uint32_t id;
+ uint32_t len;
+} QVRingUsedElem;
+
+typedef struct QVRingUsed
+{
+ uint16_t flags;
+ uint16_t idx;
+ VRingUsedElem ring[0];
+} QVRingUsed;
+
+typedef struct QVRing
+{
+ unsigned int num;
+ unsigned int align;
+ uint64_t desc;
+ uint64_t avail;
+ uint64_t used;
+} QVRing;
+
+uint64_t qvring_desc_addr(uint64_t desc_pa, int i);
+uint32_t qvring_desc_len(uint64_t desc_pa, int i);
+uint16_t qvring_desc_flags(uint64_t desc_pa, int i);
+uint16_t qvring_desc_next(uint64_t desc_pa, int i);
+uint16_t qvring_avail_flags(QVirtQueue *vq);
+uint16_t qvring_avail_idx(QVirtQueue *vq);
+uint16_t qvring_avail_ring(QVirtQueue *vq, int i);
+uint16_t qvring_used_event(QVirtQueue *vq);
+void qvring_used_ring_id(QVirtQueue *vq, int i, uint32_t val);
+void qvring_used_ring_len(QVirtQueue *vq, int i, uint32_t val);
+uint16_t qvring_used_idx(QVirtQueue *vq);
+void qvring_used_idx_set(QVirtQueue *vq, uint16_t val);
+void qvring_used_flags_set_bit(QVirtQueue *vq, int mask);
+void qvring_used_flags_unset_bit(QVirtQueue *vq, int mask);
+void qvring_avail_event(QVirtQueue *vq, uint16_t val);
+
+void qvirtqueue_push(QVirtQueue *vq, const QVirtQueueElement *elem, unsigned
int len);
+void qvirtqueue_flush(QVirtQueue *vq, unsigned int count);
+void qvirtqueue_fill(QVirtQueue *vq, const VirtQueueElement *elem, unsigned
int len, unsigned int idx);
+void qvirtqueue_pop(QVirtQueue *vq, VirtQueueElement *elem);
+void qvirtqueue_map_sg(struct iovec *sg, uint64_t *addr,
+ size_t num_sg, int is_write);
+void qvirtio_notify(QVirtioDevice *vdev, QVirtQueue *vq);
+int qvirtio_queue_ready(QVirtQueue *vq);
+int qvirtio_queue_empty(QVirtQueue *vq);
--
1.7.10.4
- [Qemu-devel] [RFC] Libqos virtio API,
Marc Marí <=