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