Add virtio-mmio node in qgraph framework. virtio-mmio produces virtio, the interface consumed by all virtio-*-device nodes.
Being a memory-mapped device, it doesn't have to provide a constructor to qgraph, since it's always "contained" inside some other nodes. Also rename qvirtio_mmio_init_device in qvirtio_mmio_device_new, since the function actually allocates a new QVirtioMMIODevice and initialize it. Signed-off-by: Emanuele Giuseppe Esposito <e.emanuelegiuse...@gmail.com> Reviewed-by: Laurent Vivier <lviv...@redhat.com> --- tests/libqos/virtio-mmio.c | 66 ++++++++++++++++++++++++++------------ tests/libqos/virtio-mmio.h | 5 ++- tests/virtio-blk-test.c | 3 +- 3 files changed, 51 insertions(+), 23 deletions(-) diff --git a/tests/libqos/virtio-mmio.c b/tests/libqos/virtio-mmio.c index 7aa8383338..61ed0e549b 100644 --- a/tests/libqos/virtio-mmio.c +++ b/tests/libqos/virtio-mmio.c @@ -13,42 +13,43 @@ #include "libqos/virtio-mmio.h" #include "libqos/malloc.h" #include "libqos/malloc-generic.h" +#include "libqos/qgraph.h" #include "standard-headers/linux/virtio_ring.h" static uint8_t qvirtio_mmio_config_readb(QVirtioDevice *d, uint64_t off) { - QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d; + QVirtioMMIODevice *dev = container_of(d, QVirtioMMIODevice, vdev); return readb(dev->addr + QVIRTIO_MMIO_DEVICE_SPECIFIC + off); } static uint16_t qvirtio_mmio_config_readw(QVirtioDevice *d, uint64_t off) { - QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d; + QVirtioMMIODevice *dev = container_of(d, QVirtioMMIODevice, vdev); return readw(dev->addr + QVIRTIO_MMIO_DEVICE_SPECIFIC + off); } static uint32_t qvirtio_mmio_config_readl(QVirtioDevice *d, uint64_t off) { - QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d; + QVirtioMMIODevice *dev = container_of(d, QVirtioMMIODevice, vdev); return readl(dev->addr + QVIRTIO_MMIO_DEVICE_SPECIFIC + off); } static uint64_t qvirtio_mmio_config_readq(QVirtioDevice *d, uint64_t off) { - QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d; + QVirtioMMIODevice *dev = container_of(d, QVirtioMMIODevice, vdev); return readq(dev->addr + QVIRTIO_MMIO_DEVICE_SPECIFIC + off); } static uint32_t qvirtio_mmio_get_features(QVirtioDevice *d) { - QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d; + QVirtioMMIODevice *dev = container_of(d, QVirtioMMIODevice, vdev); writel(dev->addr + QVIRTIO_MMIO_HOST_FEATURES_SEL, 0); return readl(dev->addr + QVIRTIO_MMIO_HOST_FEATURES); } static void qvirtio_mmio_set_features(QVirtioDevice *d, uint32_t features) { - QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d; + QVirtioMMIODevice *dev = container_of(d, QVirtioMMIODevice, vdev); dev->features = features; writel(dev->addr + QVIRTIO_MMIO_GUEST_FEATURES_SEL, 0); writel(dev->addr + QVIRTIO_MMIO_GUEST_FEATURES, features); @@ -56,25 +57,25 @@ static void qvirtio_mmio_set_features(QVirtioDevice *d, uint32_t features) static uint32_t qvirtio_mmio_get_guest_features(QVirtioDevice *d) { - QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d; + QVirtioMMIODevice *dev = container_of(d, QVirtioMMIODevice, vdev); return dev->features; } static uint8_t qvirtio_mmio_get_status(QVirtioDevice *d) { - QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d; + QVirtioMMIODevice *dev = container_of(d, QVirtioMMIODevice, vdev); return (uint8_t)readl(dev->addr + QVIRTIO_MMIO_DEVICE_STATUS); } static void qvirtio_mmio_set_status(QVirtioDevice *d, uint8_t status) { - QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d; + QVirtioMMIODevice *dev = container_of(d, QVirtioMMIODevice, vdev); writel(dev->addr + QVIRTIO_MMIO_DEVICE_STATUS, (uint32_t)status); } static bool qvirtio_mmio_get_queue_isr_status(QVirtioDevice *d, QVirtQueue *vq) { - QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d; + QVirtioMMIODevice *dev = container_of(d, QVirtioMMIODevice, vdev); uint32_t isr; isr = readl(dev->addr + QVIRTIO_MMIO_INTERRUPT_STATUS) & 1; @@ -88,7 +89,7 @@ static bool qvirtio_mmio_get_queue_isr_status(QVirtioDevice *d, QVirtQueue *vq) static bool qvirtio_mmio_get_config_isr_status(QVirtioDevice *d) { - QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d; + QVirtioMMIODevice *dev = container_of(d, QVirtioMMIODevice, vdev); uint32_t isr; isr = readl(dev->addr + QVIRTIO_MMIO_INTERRUPT_STATUS) & 2; @@ -102,7 +103,7 @@ static bool qvirtio_mmio_get_config_isr_status(QVirtioDevice *d) static void qvirtio_mmio_queue_select(QVirtioDevice *d, uint16_t index) { - QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d; + QVirtioMMIODevice *dev = container_of(d, QVirtioMMIODevice, vdev); writel(dev->addr + QVIRTIO_MMIO_QUEUE_SEL, (uint32_t)index); g_assert_cmphex(readl(dev->addr + QVIRTIO_MMIO_QUEUE_PFN), ==, 0); @@ -110,20 +111,20 @@ static void qvirtio_mmio_queue_select(QVirtioDevice *d, uint16_t index) static uint16_t qvirtio_mmio_get_queue_size(QVirtioDevice *d) { - QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d; + QVirtioMMIODevice *dev = container_of(d, QVirtioMMIODevice, vdev); return (uint16_t)readl(dev->addr + QVIRTIO_MMIO_QUEUE_NUM_MAX); } static void qvirtio_mmio_set_queue_address(QVirtioDevice *d, uint32_t pfn) { - QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d; + QVirtioMMIODevice *dev = container_of(d, QVirtioMMIODevice, vdev); writel(dev->addr + QVIRTIO_MMIO_QUEUE_PFN, pfn); } static QVirtQueue *qvirtio_mmio_virtqueue_setup(QVirtioDevice *d, QGuestAllocator *alloc, uint16_t index) { - QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d; + QVirtioMMIODevice *dev = container_of(d, QVirtioMMIODevice, vdev); QVirtQueue *vq; uint64_t addr; @@ -163,7 +164,7 @@ static void qvirtio_mmio_virtqueue_cleanup(QVirtQueue *vq, static void qvirtio_mmio_virtqueue_kick(QVirtioDevice *d, QVirtQueue *vq) { - QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d; + QVirtioMMIODevice *dev = container_of(d, QVirtioMMIODevice, vdev); writel(dev->addr + QVIRTIO_MMIO_QUEUE_NOTIFY, vq->index); } @@ -187,12 +188,26 @@ const QVirtioBus qvirtio_mmio = { .virtqueue_kick = qvirtio_mmio_virtqueue_kick, }; -QVirtioMMIODevice *qvirtio_mmio_init_device(uint64_t addr, uint32_t page_size) +static void *qvirtio_mmio_get_driver(void *obj, const char *interface) { - QVirtioMMIODevice *dev; - uint32_t magic; - dev = g_malloc0(sizeof(*dev)); + QVirtioMMIODevice *virtio_mmio = obj; + if (!g_strcmp0(interface, "virtio")) { + return &virtio_mmio->vdev; + } + fprintf(stderr, "%s not present in virtio-mmio\n", interface); + g_assert_not_reached(); +} + +static void qvirtio_mmio_start_hw(QOSGraphObject *obj) +{ + QVirtioMMIODevice *dev = (QVirtioMMIODevice *) obj; + qvirtio_start_device(&dev->vdev); +} +void qvirtio_mmio_init_device(QVirtioMMIODevice *dev, uint64_t addr, + uint32_t page_size) +{ + uint32_t magic; magic = readl(addr + QVIRTIO_MMIO_MAGIC_VALUE); g_assert(magic == ('v' | 'i' << 8 | 'r' << 16 | 't' << 24)); @@ -203,5 +218,14 @@ QVirtioMMIODevice *qvirtio_mmio_init_device(uint64_t addr, uint32_t page_size) writel(addr + QVIRTIO_MMIO_GUEST_PAGE_SIZE, page_size); - return dev; + dev->obj.get_driver = qvirtio_mmio_get_driver; + dev->obj.start_hw = qvirtio_mmio_start_hw; +} + +static void virtio_mmio_register_nodes(void) +{ + qos_node_create_driver("virtio-mmio", NULL); + qos_node_produces("virtio-mmio", "virtio"); } + +libqos_init(virtio_mmio_register_nodes); diff --git a/tests/libqos/virtio-mmio.h b/tests/libqos/virtio-mmio.h index e3e52b9ce1..aadc60d6ed 100644 --- a/tests/libqos/virtio-mmio.h +++ b/tests/libqos/virtio-mmio.h @@ -11,6 +11,7 @@ #define LIBQOS_VIRTIO_MMIO_H #include "libqos/virtio.h" +#include "libqos/qgraph.h" #define QVIRTIO_MMIO_MAGIC_VALUE 0x000 #define QVIRTIO_MMIO_VERSION 0x004 @@ -33,6 +34,7 @@ #define QVIRTIO_MMIO_DEVICE_SPECIFIC 0x100 typedef struct QVirtioMMIODevice { + QOSGraphObject obj; QVirtioDevice vdev; uint64_t addr; uint32_t page_size; @@ -41,6 +43,7 @@ typedef struct QVirtioMMIODevice { extern const QVirtioBus qvirtio_mmio; -QVirtioMMIODevice *qvirtio_mmio_init_device(uint64_t addr, uint32_t page_size); +void qvirtio_mmio_init_device(QVirtioMMIODevice *dev, uint64_t addr, + uint32_t page_size); #endif diff --git a/tests/virtio-blk-test.c b/tests/virtio-blk-test.c index 66797d0348..e60b33c38a 100644 --- a/tests/virtio-blk-test.c +++ b/tests/virtio-blk-test.c @@ -709,7 +709,8 @@ static void mmio_basic(void) arm_test_start(); - dev = qvirtio_mmio_init_device(MMIO_DEV_BASE_ADDR, MMIO_PAGE_SIZE); + dev = g_malloc0(sizeof(QVirtioMMIODevice)); + qvirtio_mmio_init_device(dev, MMIO_DEV_BASE_ADDR, MMIO_PAGE_SIZE); g_assert(dev != NULL); g_assert_cmphex(dev->vdev.device_type, ==, VIRTIO_ID_BLOCK); -- 2.17.1