qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [RFC] Libqos virtio API
@ 2014-06-17  9:02 Marc Marí
  2014-06-18  9:02 ` Stefan Hajnoczi
  0 siblings, 1 reply; 2+ messages in thread
From: Marc Marí @ 2014-06-17  9:02 UTC (permalink / raw)
  To: qemu-devel; +Cc: Marc Marí, Paolo Bonzini, Paolo Bonzini, Stefan Hajnoczi

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í <marc.mari.barcelo@gmail.com>
---
 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

^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2014-06-18  9:02 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-06-17  9:02 [Qemu-devel] [RFC] Libqos virtio API Marc Marí
2014-06-18  9:02 ` Stefan Hajnoczi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).