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