]> git.proxmox.com Git - mirror_qemu.git/blobdiff - hw/misc/pci-testdev.c
Merge remote-tracking branch 'remotes/stsquad/tags/pull-mttcg-240217-1' into staging
[mirror_qemu.git] / hw / misc / pci-testdev.c
index 71ce5a3e0836d8b7343ee432c20b72c22b29e800..7d5990213ec08c485617c9b9fdbbf9aad635c678 100644 (file)
  * You should have received a copy of the GNU General Public License along
  * with this program; if not, see <http://www.gnu.org/licenses/>.
  */
+#include "qemu/osdep.h"
 #include "hw/hw.h"
 #include "hw/pci/pci.h"
 #include "qemu/event_notifier.h"
-#include "qemu/osdep.h"
+#include "sysemu/kvm.h"
 
 typedef struct PCITestDevHdr {
     uint8_t test;
@@ -76,13 +77,21 @@ enum {
 #define IOTEST_ACCESS_WIDTH (sizeof(uint8_t))
 
 typedef struct PCITestDevState {
-    PCIDevice dev;
+    /*< private >*/
+    PCIDevice parent_obj;
+    /*< public >*/
+
     MemoryRegion mmio;
     MemoryRegion portio;
     IOTest *tests;
     int current;
 } PCITestDevState;
 
+#define TYPE_PCI_TEST_DEV "pci-testdev"
+
+#define PCI_TEST_DEV(obj) \
+    OBJECT_CHECK(PCITestDevState, (obj), TYPE_PCI_TEST_DEV)
+
 #define IOTEST_IS_MEM(i) (strcmp(IOTEST_TYPE(i), "portio"))
 #define IOTEST_REGION(d, i) (IOTEST_IS_MEM(i) ?  &(d)->mmio : &(d)->portio)
 #define IOTEST_SIZE(i) (IOTEST_IS_MEM(i) ? IOTEST_MEMSIZE : IOTEST_IOSIZE)
@@ -225,23 +234,24 @@ static const MemoryRegionOps pci_testdev_pio_ops = {
     },
 };
 
-static int pci_testdev_init(PCIDevice *pci_dev)
+static void pci_testdev_realize(PCIDevice *pci_dev, Error **errp)
 {
-    PCITestDevState *d = DO_UPCAST(PCITestDevState, dev, pci_dev);
+    PCITestDevState *d = PCI_TEST_DEV(pci_dev);
     uint8_t *pci_conf;
     char *name;
     int r, i;
+    bool fastmmio = kvm_ioeventfd_any_length_enabled();
 
-    pci_conf = d->dev.config;
+    pci_conf = pci_dev->config;
 
     pci_conf[PCI_INTERRUPT_PIN] = 0; /* no interrupt pin */
 
-    memory_region_init_io(&d->mmio, &pci_testdev_mmio_ops, d,
+    memory_region_init_io(&d->mmio, OBJECT(d), &pci_testdev_mmio_ops, d,
                           "pci-testdev-mmio", IOTEST_MEMSIZE * 2);
-    memory_region_init_io(&d->portio, &pci_testdev_pio_ops, d,
+    memory_region_init_io(&d->portio, OBJECT(d), &pci_testdev_pio_ops, d,
                           "pci-testdev-portio", IOTEST_IOSIZE * 2);
-    pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &d->mmio);
-    pci_register_bar(&d->dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->portio);
+    pci_register_bar(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &d->mmio);
+    pci_register_bar(pci_dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->portio);
 
     d->current = -1;
     d->tests = g_malloc0(IOTEST_MAX * sizeof *d->tests);
@@ -253,8 +263,12 @@ static int pci_testdev_init(PCIDevice *pci_dev)
         memcpy(test->hdr->name, name, strlen(name) + 1);
         g_free(name);
         test->hdr->offset = cpu_to_le32(IOTEST_SIZE(i) + i * IOTEST_ACCESS_WIDTH);
-        test->size = IOTEST_ACCESS_WIDTH;
         test->match_data = strcmp(IOTEST_TEST(i), "wildcard-eventfd");
+        if (fastmmio && IOTEST_IS_MEM(i) && !test->match_data) {
+            test->size = 0;
+        } else {
+            test->size = IOTEST_ACCESS_WIDTH;
+        }
         test->hdr->test = i;
         test->hdr->data = test->match_data ? IOTEST_DATAMATCH : IOTEST_NOMATCH;
         test->hdr->width = IOTEST_ACCESS_WIDTH;
@@ -267,14 +281,12 @@ static int pci_testdev_init(PCIDevice *pci_dev)
         assert(r >= 0);
         test->hasnotifier = true;
     }
-
-    return 0;
 }
 
 static void
 pci_testdev_uninit(PCIDevice *dev)
 {
-    PCITestDevState *d = DO_UPCAST(PCITestDevState, dev, dev);
+    PCITestDevState *d = PCI_TEST_DEV(dev);
     int i;
 
     pci_testdev_reset(d);
@@ -285,13 +297,11 @@ pci_testdev_uninit(PCIDevice *dev)
         g_free(d->tests[i].hdr);
     }
     g_free(d->tests);
-    memory_region_destroy(&d->mmio);
-    memory_region_destroy(&d->portio);
 }
 
 static void qdev_pci_testdev_reset(DeviceState *dev)
 {
-    PCITestDevState *d = DO_UPCAST(PCITestDevState, dev.qdev, dev);
+    PCITestDevState *d = PCI_TEST_DEV(dev);
     pci_testdev_reset(d);
 }
 
@@ -300,18 +310,19 @@ static void pci_testdev_class_init(ObjectClass *klass, void *data)
     DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
-    k->init = pci_testdev_init;
+    k->realize = pci_testdev_realize;
     k->exit = pci_testdev_uninit;
     k->vendor_id = PCI_VENDOR_ID_REDHAT;
     k->device_id = PCI_DEVICE_ID_REDHAT_TEST;
     k->revision = 0x00;
     k->class_id = PCI_CLASS_OTHERS;
     dc->desc = "PCI Test Device";
+    set_bit(DEVICE_CATEGORY_MISC, dc->categories);
     dc->reset = qdev_pci_testdev_reset;
 }
 
 static const TypeInfo pci_testdev_info = {
-    .name          = "pci-testdev",
+    .name          = TYPE_PCI_TEST_DEV,
     .parent        = TYPE_PCI_DEVICE,
     .instance_size = sizeof(PCITestDevState),
     .class_init    = pci_testdev_class_init,