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