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