qemu-devel
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]