* [Qemu-devel] [PATCH v3] virtio: Introduce virtio-testdev
@ 2014-01-29 15:19 Andrew Jones
2014-01-30 12:44 ` Mike Day
0 siblings, 1 reply; 3+ messages in thread
From: Andrew Jones @ 2014-01-29 15:19 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, kvmarm, christoffer.dall
This is a virtio version of hw/misc/debugexit and should evolve into a
virtio version of pc-testdev. pc-testdev uses the PC's ISA bus, whereas
this testdev can be plugged into a virtio-mmio transport, which is
needed for kvm-unit-tests/arm. virtio-testdev uses the virtio device
config space as a communication channel, and implements an RTAS-like
protocol through it allowing guests to execute commands. Only three
commands are currently implemented;
1) VERSION: for version compatibility checks
2) CLEAR: set all the config space back to zero
3) EXIT: exit() from qemu with a status code
---
v3: Convert to QOM realize
v2:
- No real functional changes, just added some comments and changed
register bank accesses to use byte offsets, allowing the driver
implementation to better mirror this device's implementation.
Signed-off-by: Andrew Jones <drjones@redhat.com>
---
hw/virtio/Makefile.objs | 1 +
hw/virtio/virtio-testdev.c | 154 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 155 insertions(+)
create mode 100644 hw/virtio/virtio-testdev.c
diff --git a/hw/virtio/Makefile.objs b/hw/virtio/Makefile.objs
index 1ba53d9cc316c..b63fea4a175f0 100644
--- a/hw/virtio/Makefile.objs
+++ b/hw/virtio/Makefile.objs
@@ -3,6 +3,7 @@ common-obj-$(CONFIG_VIRTIO_PCI) += virtio-pci.o
common-obj-y += virtio-bus.o
common-obj-y += virtio-mmio.o
common-obj-$(CONFIG_VIRTIO_BLK_DATA_PLANE) += dataplane/
+common-obj-y += virtio-testdev.o
obj-y += virtio.o virtio-balloon.o
obj-$(CONFIG_LINUX) += vhost.o
diff --git a/hw/virtio/virtio-testdev.c b/hw/virtio/virtio-testdev.c
new file mode 100644
index 0000000000000..495639a66d3bc
--- /dev/null
+++ b/hw/virtio/virtio-testdev.c
@@ -0,0 +1,154 @@
+/*
+ * Virtio Test Device
+ *
+ * Copyright (C) 2013 Red Hat, Inc.
+ * Copyright (C) 2013 Andrew Jones <drjones@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ *
+ */
+#include "hw/virtio/virtio-bus.h"
+
+#define VIRTIO_ID_TESTDEV 0xffff
+
+#define TYPE_VIRTIO_TESTDEV "virtio-testdev"
+#define VIRTIO_TESTDEV(obj) \
+ OBJECT_CHECK(VirtIOTestdev, (obj), TYPE_VIRTIO_TESTDEV)
+
+#define TESTDEV_MAJOR_VER 1
+#define TESTDEV_MINOR_VER 1
+
+/*
+ * Size of the register bank in bytes. The max is determined
+ * by the device's config space. For virtio-mmio devices we
+ * only have 256 bytes, so that's our max, but we don't need
+ * that much anyway. 64 bytes gives us token, nargs, nrets,
+ * and an additional 13 4-byte registers for input/output.
+ * That'll do.
+ */
+#define CONFIG_SIZE 64
+
+enum {
+ VERSION = 1,
+ CLEAR,
+ EXIT,
+};
+
+#define TOKEN_OFFSET 0x0
+#define NARGS_OFFSET 0x4
+#define NRETS_OFFSET 0x8
+#define ARG_OFFSET(n) (0xc + (n) * 4)
+#define __RET_OFFSET(nargs, n) (ARG_OFFSET(nargs) + (n) * 4)
+#define RET_OFFSET(d, n) __RET_OFFSET(config_readl(d, NARGS_OFFSET), n)
+
+typedef struct VirtIOTestdev {
+ VirtIODevice parent_obj;
+ uint8_t config[CONFIG_SIZE];
+} VirtIOTestdev;
+
+static uint32_t config_readl(VirtIOTestdev *dev, unsigned offset)
+{
+ uint32_t *config = (uint32_t *)&dev->config[0];
+
+ if (offset > (CONFIG_SIZE - 4)) {
+ return 0;
+ }
+
+ return le32_to_cpu(config[offset / 4]);
+}
+
+static void config_writel(VirtIOTestdev *dev, unsigned offset, uint32_t val)
+{
+ uint32_t *config = (uint32_t *)&dev->config[0];
+
+ if (offset <= (CONFIG_SIZE - 4)) {
+ config[offset / 4] = cpu_to_le32(val);
+ }
+}
+
+static void virtio_testdev_get_config(VirtIODevice *vdev, uint8_t *config_data)
+{
+ VirtIOTestdev *dev = VIRTIO_TESTDEV(vdev);
+ memcpy(config_data, &dev->config[0], CONFIG_SIZE);
+}
+
+static void virtio_testdev_set_config(VirtIODevice *vdev,
+ const uint8_t *config_data)
+{
+ VirtIOTestdev *dev = VIRTIO_TESTDEV(vdev);
+ uint32_t token;
+
+ memcpy(&dev->config[0], config_data, CONFIG_SIZE);
+
+ token = config_readl(dev, TOKEN_OFFSET);
+
+ /*
+ * The token register must always remain zero in order to
+ * avoid re-executing operations while new operation
+ * arguments are being filled in.
+ */
+ config_writel(dev, TOKEN_OFFSET, 0);
+
+ switch (token) {
+ case 0:
+ /*
+ * No token yet, so we were just filling in arguments, and
+ * now there's nothing left to do.
+ */
+ return;
+ case VERSION:
+ config_writel(dev, RET_OFFSET(dev, 0),
+ (TESTDEV_MAJOR_VER << 16) | TESTDEV_MINOR_VER);
+ break;
+ case EXIT:
+ exit((config_readl(dev, ARG_OFFSET(0)) << 1) | 1);
+ case CLEAR:
+ default:
+ /* The CLEAR op and unknown ops reset all registers */
+ memset(&dev->config[0], 0, CONFIG_SIZE);
+ }
+}
+
+static uint32_t virtio_testdev_get_features(VirtIODevice *vdev, uint32_t f)
+{
+ return f;
+}
+
+static void virtio_testdev_realize(DeviceState *dev, Error **errp)
+{
+ VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+ virtio_init(vdev, "virtio-testdev", VIRTIO_ID_TESTDEV, CONFIG_SIZE);
+}
+
+static int virtio_testdev_exit(DeviceState *qdev)
+{
+ virtio_cleanup(VIRTIO_DEVICE(qdev));
+ return 0;
+}
+
+static void virtio_testdev_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
+ dc->exit = virtio_testdev_exit;
+ set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+ vdc->realize = virtio_testdev_realize;
+ vdc->get_config = virtio_testdev_get_config;
+ vdc->set_config = virtio_testdev_set_config;
+ vdc->get_features = virtio_testdev_get_features;
+}
+
+static const TypeInfo virtio_testdev_info = {
+ .name = TYPE_VIRTIO_TESTDEV,
+ .parent = TYPE_VIRTIO_DEVICE,
+ .instance_size = sizeof(VirtIOTestdev),
+ .class_init = virtio_testdev_class_init,
+};
+
+static void virtio_register_types(void)
+{
+ type_register_static(&virtio_testdev_info);
+}
+
+type_init(virtio_register_types)
--
1.8.1.4
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [Qemu-devel] [PATCH v3] virtio: Introduce virtio-testdev
2014-01-29 15:19 [Qemu-devel] [PATCH v3] virtio: Introduce virtio-testdev Andrew Jones
@ 2014-01-30 12:44 ` Mike Day
2014-01-30 12:56 ` Andrew Jones
0 siblings, 1 reply; 3+ messages in thread
From: Mike Day @ 2014-01-30 12:44 UTC (permalink / raw)
To: Andrew Jones, qemu-devel; +Cc: peter.maydell, kvmarm, christoffer.dall
Andrew Jones <drjones@redhat.com> writes:
> This is a virtio version of hw/misc/debugexit and should evolve into a
> virtio version of pc-testdev. pc-testdev uses the PC's ISA bus, whereas
> this testdev can be plugged into a virtio-mmio transport, which is
> needed for kvm-unit-tests/arm. virtio-testdev uses the virtio device
> config space as a communication channel, and implements an RTAS-like
> protocol through it allowing guests to execute commands. Only three
> commands are currently implemented;
> 1) VERSION: for version compatibility checks
> 2) CLEAR: set all the config space back to zero
> 3) EXIT: exit() from qemu with a status code
> +static uint32_t virtio_testdev_get_features(VirtIODevice *vdev, uint32_t f)
> +{
> + return f;
> +}
> +
Is this meant to be a stub currently?
Mike
--
Mike Day | "Endurance is a Virtue"
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [Qemu-devel] [PATCH v3] virtio: Introduce virtio-testdev
2014-01-30 12:44 ` Mike Day
@ 2014-01-30 12:56 ` Andrew Jones
0 siblings, 0 replies; 3+ messages in thread
From: Andrew Jones @ 2014-01-30 12:56 UTC (permalink / raw)
To: Mike Day; +Cc: peter.maydell, qemu-devel, christoffer.dall, kvmarm
On Thu, Jan 30, 2014 at 07:44:59AM -0500, Mike Day wrote:
>
> Andrew Jones <drjones@redhat.com> writes:
>
> > This is a virtio version of hw/misc/debugexit and should evolve into a
> > virtio version of pc-testdev. pc-testdev uses the PC's ISA bus, whereas
> > this testdev can be plugged into a virtio-mmio transport, which is
> > needed for kvm-unit-tests/arm. virtio-testdev uses the virtio device
> > config space as a communication channel, and implements an RTAS-like
> > protocol through it allowing guests to execute commands. Only three
> > commands are currently implemented;
> > 1) VERSION: for version compatibility checks
> > 2) CLEAR: set all the config space back to zero
> > 3) EXIT: exit() from qemu with a status code
>
> > +static uint32_t virtio_testdev_get_features(VirtIODevice *vdev, uint32_t f)
> > +{
> > + return f;
> > +}
> > +
>
> Is this meant to be a stub currently?
>
Something like that. *_get_features() must be supplied by all virtio
devices. Just returning the requested features, f, rather than zero,
is how virtio-rng does it. So I went that way too.
drew
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2014-01-30 12:57 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-01-29 15:19 [Qemu-devel] [PATCH v3] virtio: Introduce virtio-testdev Andrew Jones
2014-01-30 12:44 ` Mike Day
2014-01-30 12:56 ` Andrew Jones
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).