122773d60SMichael S. Tsirkin /* 222773d60SMichael S. Tsirkin * QEMU PCI test device 322773d60SMichael S. Tsirkin * 422773d60SMichael S. Tsirkin * Copyright (c) 2012 Red Hat Inc. 522773d60SMichael S. Tsirkin * Author: Michael S. Tsirkin <mst@redhat.com> 622773d60SMichael S. Tsirkin * 722773d60SMichael S. Tsirkin * This program is free software; you can redistribute it and/or modify 822773d60SMichael S. Tsirkin * it under the terms of the GNU General Public License as published by 922773d60SMichael S. Tsirkin * the Free Software Foundation; either version 2 of the License, or 1022773d60SMichael S. Tsirkin * (at your option) any later version. 1122773d60SMichael S. Tsirkin * 1222773d60SMichael S. Tsirkin * This program is distributed in the hope that it will be useful, 1322773d60SMichael S. Tsirkin * but WITHOUT ANY WARRANTY; without even the implied warranty of 1422773d60SMichael S. Tsirkin * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1522773d60SMichael S. Tsirkin * GNU General Public License for more details. 1622773d60SMichael S. Tsirkin * 1722773d60SMichael S. Tsirkin * You should have received a copy of the GNU General Public License along 1822773d60SMichael S. Tsirkin * with this program; if not, see <http://www.gnu.org/licenses/>. 1922773d60SMichael S. Tsirkin */ 2097d5408fSPeter Maydell #include "qemu/osdep.h" 2122773d60SMichael S. Tsirkin #include "hw/hw.h" 2222773d60SMichael S. Tsirkin #include "hw/pci/pci.h" 2322773d60SMichael S. Tsirkin #include "qemu/event_notifier.h" 2477ac58ddSPaolo Bonzini #include "sysemu/kvm.h" 2522773d60SMichael S. Tsirkin 2622773d60SMichael S. Tsirkin typedef struct PCITestDevHdr { 2722773d60SMichael S. Tsirkin uint8_t test; 2822773d60SMichael S. Tsirkin uint8_t width; 2922773d60SMichael S. Tsirkin uint8_t pad0[2]; 3022773d60SMichael S. Tsirkin uint32_t offset; 3122773d60SMichael S. Tsirkin uint8_t data; 3222773d60SMichael S. Tsirkin uint8_t pad1[3]; 3322773d60SMichael S. Tsirkin uint32_t count; 3422773d60SMichael S. Tsirkin uint8_t name[]; 3522773d60SMichael S. Tsirkin } PCITestDevHdr; 3622773d60SMichael S. Tsirkin 3722773d60SMichael S. Tsirkin typedef struct IOTest { 3822773d60SMichael S. Tsirkin MemoryRegion *mr; 3922773d60SMichael S. Tsirkin EventNotifier notifier; 4022773d60SMichael S. Tsirkin bool hasnotifier; 4122773d60SMichael S. Tsirkin unsigned size; 4222773d60SMichael S. Tsirkin bool match_data; 4322773d60SMichael S. Tsirkin PCITestDevHdr *hdr; 4422773d60SMichael S. Tsirkin unsigned bufsize; 4522773d60SMichael S. Tsirkin } IOTest; 4622773d60SMichael S. Tsirkin 4722773d60SMichael S. Tsirkin #define IOTEST_DATAMATCH 0xFA 4822773d60SMichael S. Tsirkin #define IOTEST_NOMATCH 0xCE 4922773d60SMichael S. Tsirkin 5022773d60SMichael S. Tsirkin #define IOTEST_IOSIZE 128 5122773d60SMichael S. Tsirkin #define IOTEST_MEMSIZE 2048 5222773d60SMichael S. Tsirkin 5322773d60SMichael S. Tsirkin static const char *iotest_test[] = { 5422773d60SMichael S. Tsirkin "no-eventfd", 5522773d60SMichael S. Tsirkin "wildcard-eventfd", 5622773d60SMichael S. Tsirkin "datamatch-eventfd" 5722773d60SMichael S. Tsirkin }; 5822773d60SMichael S. Tsirkin 5922773d60SMichael S. Tsirkin static const char *iotest_type[] = { 6022773d60SMichael S. Tsirkin "mmio", 6122773d60SMichael S. Tsirkin "portio" 6222773d60SMichael S. Tsirkin }; 6322773d60SMichael S. Tsirkin 6422773d60SMichael S. Tsirkin #define IOTEST_TEST(i) (iotest_test[((i) % ARRAY_SIZE(iotest_test))]) 6522773d60SMichael S. Tsirkin #define IOTEST_TYPE(i) (iotest_type[((i) / ARRAY_SIZE(iotest_test))]) 6622773d60SMichael S. Tsirkin #define IOTEST_MAX_TEST (ARRAY_SIZE(iotest_test)) 6722773d60SMichael S. Tsirkin #define IOTEST_MAX_TYPE (ARRAY_SIZE(iotest_type)) 6822773d60SMichael S. Tsirkin #define IOTEST_MAX (IOTEST_MAX_TEST * IOTEST_MAX_TYPE) 6922773d60SMichael S. Tsirkin 7022773d60SMichael S. Tsirkin enum { 7122773d60SMichael S. Tsirkin IOTEST_ACCESS_NAME, 7222773d60SMichael S. Tsirkin IOTEST_ACCESS_DATA, 7322773d60SMichael S. Tsirkin IOTEST_ACCESS_MAX, 7422773d60SMichael S. Tsirkin }; 7522773d60SMichael S. Tsirkin 7622773d60SMichael S. Tsirkin #define IOTEST_ACCESS_TYPE uint8_t 7722773d60SMichael S. Tsirkin #define IOTEST_ACCESS_WIDTH (sizeof(uint8_t)) 7822773d60SMichael S. Tsirkin 7922773d60SMichael S. Tsirkin typedef struct PCITestDevState { 806d27a409SAndreas Färber /*< private >*/ 816d27a409SAndreas Färber PCIDevice parent_obj; 826d27a409SAndreas Färber /*< public >*/ 836d27a409SAndreas Färber 8422773d60SMichael S. Tsirkin MemoryRegion mmio; 8522773d60SMichael S. Tsirkin MemoryRegion portio; 8622773d60SMichael S. Tsirkin IOTest *tests; 8722773d60SMichael S. Tsirkin int current; 88*41746334SGerd Hoffmann 89*41746334SGerd Hoffmann uint64_t membar_size; 90*41746334SGerd Hoffmann MemoryRegion membar; 9122773d60SMichael S. Tsirkin } PCITestDevState; 9222773d60SMichael S. Tsirkin 9340108d0aSPeter Crosthwaite #define TYPE_PCI_TEST_DEV "pci-testdev" 9440108d0aSPeter Crosthwaite 9540108d0aSPeter Crosthwaite #define PCI_TEST_DEV(obj) \ 9640108d0aSPeter Crosthwaite OBJECT_CHECK(PCITestDevState, (obj), TYPE_PCI_TEST_DEV) 9740108d0aSPeter Crosthwaite 9822773d60SMichael S. Tsirkin #define IOTEST_IS_MEM(i) (strcmp(IOTEST_TYPE(i), "portio")) 9922773d60SMichael S. Tsirkin #define IOTEST_REGION(d, i) (IOTEST_IS_MEM(i) ? &(d)->mmio : &(d)->portio) 10022773d60SMichael S. Tsirkin #define IOTEST_SIZE(i) (IOTEST_IS_MEM(i) ? IOTEST_MEMSIZE : IOTEST_IOSIZE) 10122773d60SMichael S. Tsirkin #define IOTEST_PCI_BAR(i) (IOTEST_IS_MEM(i) ? PCI_BASE_ADDRESS_SPACE_MEMORY : \ 10222773d60SMichael S. Tsirkin PCI_BASE_ADDRESS_SPACE_IO) 10322773d60SMichael S. Tsirkin 10422773d60SMichael S. Tsirkin static int pci_testdev_start(IOTest *test) 10522773d60SMichael S. Tsirkin { 10622773d60SMichael S. Tsirkin test->hdr->count = 0; 10722773d60SMichael S. Tsirkin if (!test->hasnotifier) { 10822773d60SMichael S. Tsirkin return 0; 10922773d60SMichael S. Tsirkin } 11022773d60SMichael S. Tsirkin event_notifier_test_and_clear(&test->notifier); 11122773d60SMichael S. Tsirkin memory_region_add_eventfd(test->mr, 11222773d60SMichael S. Tsirkin le32_to_cpu(test->hdr->offset), 11322773d60SMichael S. Tsirkin test->size, 11422773d60SMichael S. Tsirkin test->match_data, 11522773d60SMichael S. Tsirkin test->hdr->data, 11622773d60SMichael S. Tsirkin &test->notifier); 11722773d60SMichael S. Tsirkin return 0; 11822773d60SMichael S. Tsirkin } 11922773d60SMichael S. Tsirkin 12022773d60SMichael S. Tsirkin static void pci_testdev_stop(IOTest *test) 12122773d60SMichael S. Tsirkin { 12222773d60SMichael S. Tsirkin if (!test->hasnotifier) { 12322773d60SMichael S. Tsirkin return; 12422773d60SMichael S. Tsirkin } 12522773d60SMichael S. Tsirkin memory_region_del_eventfd(test->mr, 12622773d60SMichael S. Tsirkin le32_to_cpu(test->hdr->offset), 12722773d60SMichael S. Tsirkin test->size, 12822773d60SMichael S. Tsirkin test->match_data, 12922773d60SMichael S. Tsirkin test->hdr->data, 13022773d60SMichael S. Tsirkin &test->notifier); 13122773d60SMichael S. Tsirkin } 13222773d60SMichael S. Tsirkin 13322773d60SMichael S. Tsirkin static void 13422773d60SMichael S. Tsirkin pci_testdev_reset(PCITestDevState *d) 13522773d60SMichael S. Tsirkin { 13622773d60SMichael S. Tsirkin if (d->current == -1) { 13722773d60SMichael S. Tsirkin return; 13822773d60SMichael S. Tsirkin } 13922773d60SMichael S. Tsirkin pci_testdev_stop(&d->tests[d->current]); 14022773d60SMichael S. Tsirkin d->current = -1; 14122773d60SMichael S. Tsirkin } 14222773d60SMichael S. Tsirkin 14322773d60SMichael S. Tsirkin static void pci_testdev_inc(IOTest *test, unsigned inc) 14422773d60SMichael S. Tsirkin { 14522773d60SMichael S. Tsirkin uint32_t c = le32_to_cpu(test->hdr->count); 14622773d60SMichael S. Tsirkin test->hdr->count = cpu_to_le32(c + inc); 14722773d60SMichael S. Tsirkin } 14822773d60SMichael S. Tsirkin 14922773d60SMichael S. Tsirkin static void 15022773d60SMichael S. Tsirkin pci_testdev_write(void *opaque, hwaddr addr, uint64_t val, 15122773d60SMichael S. Tsirkin unsigned size, int type) 15222773d60SMichael S. Tsirkin { 15322773d60SMichael S. Tsirkin PCITestDevState *d = opaque; 15422773d60SMichael S. Tsirkin IOTest *test; 15522773d60SMichael S. Tsirkin int t, r; 15622773d60SMichael S. Tsirkin 15722773d60SMichael S. Tsirkin if (addr == offsetof(PCITestDevHdr, test)) { 15822773d60SMichael S. Tsirkin pci_testdev_reset(d); 15922773d60SMichael S. Tsirkin if (val >= IOTEST_MAX_TEST) { 16022773d60SMichael S. Tsirkin return; 16122773d60SMichael S. Tsirkin } 16222773d60SMichael S. Tsirkin t = type * IOTEST_MAX_TEST + val; 16322773d60SMichael S. Tsirkin r = pci_testdev_start(&d->tests[t]); 16422773d60SMichael S. Tsirkin if (r < 0) { 16522773d60SMichael S. Tsirkin return; 16622773d60SMichael S. Tsirkin } 16722773d60SMichael S. Tsirkin d->current = t; 16822773d60SMichael S. Tsirkin return; 16922773d60SMichael S. Tsirkin } 17022773d60SMichael S. Tsirkin if (d->current < 0) { 17122773d60SMichael S. Tsirkin return; 17222773d60SMichael S. Tsirkin } 17322773d60SMichael S. Tsirkin test = &d->tests[d->current]; 17422773d60SMichael S. Tsirkin if (addr != le32_to_cpu(test->hdr->offset)) { 17522773d60SMichael S. Tsirkin return; 17622773d60SMichael S. Tsirkin } 17722773d60SMichael S. Tsirkin if (test->match_data && test->size != size) { 17822773d60SMichael S. Tsirkin return; 17922773d60SMichael S. Tsirkin } 18022773d60SMichael S. Tsirkin if (test->match_data && val != test->hdr->data) { 18122773d60SMichael S. Tsirkin return; 18222773d60SMichael S. Tsirkin } 18322773d60SMichael S. Tsirkin pci_testdev_inc(test, 1); 18422773d60SMichael S. Tsirkin } 18522773d60SMichael S. Tsirkin 18622773d60SMichael S. Tsirkin static uint64_t 18722773d60SMichael S. Tsirkin pci_testdev_read(void *opaque, hwaddr addr, unsigned size) 18822773d60SMichael S. Tsirkin { 18922773d60SMichael S. Tsirkin PCITestDevState *d = opaque; 19022773d60SMichael S. Tsirkin const char *buf; 19122773d60SMichael S. Tsirkin IOTest *test; 19222773d60SMichael S. Tsirkin if (d->current < 0) { 19322773d60SMichael S. Tsirkin return 0; 19422773d60SMichael S. Tsirkin } 19522773d60SMichael S. Tsirkin test = &d->tests[d->current]; 19622773d60SMichael S. Tsirkin buf = (const char *)test->hdr; 19722773d60SMichael S. Tsirkin if (addr + size >= test->bufsize) { 19822773d60SMichael S. Tsirkin return 0; 19922773d60SMichael S. Tsirkin } 20022773d60SMichael S. Tsirkin if (test->hasnotifier) { 20122773d60SMichael S. Tsirkin event_notifier_test_and_clear(&test->notifier); 20222773d60SMichael S. Tsirkin } 20322773d60SMichael S. Tsirkin return buf[addr]; 20422773d60SMichael S. Tsirkin } 20522773d60SMichael S. Tsirkin 20622773d60SMichael S. Tsirkin static void 20722773d60SMichael S. Tsirkin pci_testdev_mmio_write(void *opaque, hwaddr addr, uint64_t val, 20822773d60SMichael S. Tsirkin unsigned size) 20922773d60SMichael S. Tsirkin { 21022773d60SMichael S. Tsirkin pci_testdev_write(opaque, addr, val, size, 0); 21122773d60SMichael S. Tsirkin } 21222773d60SMichael S. Tsirkin 21322773d60SMichael S. Tsirkin static void 21422773d60SMichael S. Tsirkin pci_testdev_pio_write(void *opaque, hwaddr addr, uint64_t val, 21522773d60SMichael S. Tsirkin unsigned size) 21622773d60SMichael S. Tsirkin { 21722773d60SMichael S. Tsirkin pci_testdev_write(opaque, addr, val, size, 1); 21822773d60SMichael S. Tsirkin } 21922773d60SMichael S. Tsirkin 22022773d60SMichael S. Tsirkin static const MemoryRegionOps pci_testdev_mmio_ops = { 22122773d60SMichael S. Tsirkin .read = pci_testdev_read, 22222773d60SMichael S. Tsirkin .write = pci_testdev_mmio_write, 22322773d60SMichael S. Tsirkin .endianness = DEVICE_LITTLE_ENDIAN, 22422773d60SMichael S. Tsirkin .impl = { 22522773d60SMichael S. Tsirkin .min_access_size = 1, 22622773d60SMichael S. Tsirkin .max_access_size = 1, 22722773d60SMichael S. Tsirkin }, 22822773d60SMichael S. Tsirkin }; 22922773d60SMichael S. Tsirkin 23022773d60SMichael S. Tsirkin static const MemoryRegionOps pci_testdev_pio_ops = { 23122773d60SMichael S. Tsirkin .read = pci_testdev_read, 23222773d60SMichael S. Tsirkin .write = pci_testdev_pio_write, 23322773d60SMichael S. Tsirkin .endianness = DEVICE_LITTLE_ENDIAN, 23422773d60SMichael S. Tsirkin .impl = { 23522773d60SMichael S. Tsirkin .min_access_size = 1, 23622773d60SMichael S. Tsirkin .max_access_size = 1, 23722773d60SMichael S. Tsirkin }, 23822773d60SMichael S. Tsirkin }; 23922773d60SMichael S. Tsirkin 2409af21dbeSMarkus Armbruster static void pci_testdev_realize(PCIDevice *pci_dev, Error **errp) 24122773d60SMichael S. Tsirkin { 24240108d0aSPeter Crosthwaite PCITestDevState *d = PCI_TEST_DEV(pci_dev); 24322773d60SMichael S. Tsirkin uint8_t *pci_conf; 24422773d60SMichael S. Tsirkin char *name; 24522773d60SMichael S. Tsirkin int r, i; 24645aa4e8eSMichael S. Tsirkin bool fastmmio = kvm_ioeventfd_any_length_enabled(); 24722773d60SMichael S. Tsirkin 2486d27a409SAndreas Färber pci_conf = pci_dev->config; 24922773d60SMichael S. Tsirkin 25022773d60SMichael S. Tsirkin pci_conf[PCI_INTERRUPT_PIN] = 0; /* no interrupt pin */ 25122773d60SMichael S. Tsirkin 2523c161542SPaolo Bonzini memory_region_init_io(&d->mmio, OBJECT(d), &pci_testdev_mmio_ops, d, 25322773d60SMichael S. Tsirkin "pci-testdev-mmio", IOTEST_MEMSIZE * 2); 2543c161542SPaolo Bonzini memory_region_init_io(&d->portio, OBJECT(d), &pci_testdev_pio_ops, d, 25522773d60SMichael S. Tsirkin "pci-testdev-portio", IOTEST_IOSIZE * 2); 2566d27a409SAndreas Färber pci_register_bar(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &d->mmio); 2576d27a409SAndreas Färber pci_register_bar(pci_dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->portio); 25822773d60SMichael S. Tsirkin 259*41746334SGerd Hoffmann if (d->membar_size) { 260*41746334SGerd Hoffmann memory_region_init(&d->membar, OBJECT(d), "pci-testdev-membar", 261*41746334SGerd Hoffmann d->membar_size); 262*41746334SGerd Hoffmann pci_register_bar(pci_dev, 2, 263*41746334SGerd Hoffmann PCI_BASE_ADDRESS_SPACE_MEMORY | 264*41746334SGerd Hoffmann PCI_BASE_ADDRESS_MEM_PREFETCH | 265*41746334SGerd Hoffmann PCI_BASE_ADDRESS_MEM_TYPE_64, 266*41746334SGerd Hoffmann &d->membar); 267*41746334SGerd Hoffmann } 268*41746334SGerd Hoffmann 26922773d60SMichael S. Tsirkin d->current = -1; 27022773d60SMichael S. Tsirkin d->tests = g_malloc0(IOTEST_MAX * sizeof *d->tests); 27122773d60SMichael S. Tsirkin for (i = 0; i < IOTEST_MAX; ++i) { 27222773d60SMichael S. Tsirkin IOTest *test = &d->tests[i]; 27322773d60SMichael S. Tsirkin name = g_strdup_printf("%s-%s", IOTEST_TYPE(i), IOTEST_TEST(i)); 27422773d60SMichael S. Tsirkin test->bufsize = sizeof(PCITestDevHdr) + strlen(name) + 1; 27522773d60SMichael S. Tsirkin test->hdr = g_malloc0(test->bufsize); 27622773d60SMichael S. Tsirkin memcpy(test->hdr->name, name, strlen(name) + 1); 27722773d60SMichael S. Tsirkin g_free(name); 27822773d60SMichael S. Tsirkin test->hdr->offset = cpu_to_le32(IOTEST_SIZE(i) + i * IOTEST_ACCESS_WIDTH); 27922773d60SMichael S. Tsirkin test->match_data = strcmp(IOTEST_TEST(i), "wildcard-eventfd"); 28045aa4e8eSMichael S. Tsirkin if (fastmmio && IOTEST_IS_MEM(i) && !test->match_data) { 28145aa4e8eSMichael S. Tsirkin test->size = 0; 28245aa4e8eSMichael S. Tsirkin } else { 28345aa4e8eSMichael S. Tsirkin test->size = IOTEST_ACCESS_WIDTH; 28445aa4e8eSMichael S. Tsirkin } 28522773d60SMichael S. Tsirkin test->hdr->test = i; 28622773d60SMichael S. Tsirkin test->hdr->data = test->match_data ? IOTEST_DATAMATCH : IOTEST_NOMATCH; 28722773d60SMichael S. Tsirkin test->hdr->width = IOTEST_ACCESS_WIDTH; 28822773d60SMichael S. Tsirkin test->mr = IOTEST_REGION(d, i); 28922773d60SMichael S. Tsirkin if (!strcmp(IOTEST_TEST(i), "no-eventfd")) { 29022773d60SMichael S. Tsirkin test->hasnotifier = false; 29122773d60SMichael S. Tsirkin continue; 29222773d60SMichael S. Tsirkin } 29322773d60SMichael S. Tsirkin r = event_notifier_init(&test->notifier, 0); 29422773d60SMichael S. Tsirkin assert(r >= 0); 29522773d60SMichael S. Tsirkin test->hasnotifier = true; 29622773d60SMichael S. Tsirkin } 29722773d60SMichael S. Tsirkin } 29822773d60SMichael S. Tsirkin 29922773d60SMichael S. Tsirkin static void 30022773d60SMichael S. Tsirkin pci_testdev_uninit(PCIDevice *dev) 30122773d60SMichael S. Tsirkin { 30240108d0aSPeter Crosthwaite PCITestDevState *d = PCI_TEST_DEV(dev); 30322773d60SMichael S. Tsirkin int i; 30422773d60SMichael S. Tsirkin 30522773d60SMichael S. Tsirkin pci_testdev_reset(d); 30622773d60SMichael S. Tsirkin for (i = 0; i < IOTEST_MAX; ++i) { 30722773d60SMichael S. Tsirkin if (d->tests[i].hasnotifier) { 30822773d60SMichael S. Tsirkin event_notifier_cleanup(&d->tests[i].notifier); 30922773d60SMichael S. Tsirkin } 31022773d60SMichael S. Tsirkin g_free(d->tests[i].hdr); 31122773d60SMichael S. Tsirkin } 31222773d60SMichael S. Tsirkin g_free(d->tests); 31322773d60SMichael S. Tsirkin } 31422773d60SMichael S. Tsirkin 31522773d60SMichael S. Tsirkin static void qdev_pci_testdev_reset(DeviceState *dev) 31622773d60SMichael S. Tsirkin { 31740108d0aSPeter Crosthwaite PCITestDevState *d = PCI_TEST_DEV(dev); 31822773d60SMichael S. Tsirkin pci_testdev_reset(d); 31922773d60SMichael S. Tsirkin } 32022773d60SMichael S. Tsirkin 321*41746334SGerd Hoffmann static Property pci_testdev_properties[] = { 322*41746334SGerd Hoffmann DEFINE_PROP_SIZE("membar", PCITestDevState, membar_size, 0), 323*41746334SGerd Hoffmann DEFINE_PROP_END_OF_LIST(), 324*41746334SGerd Hoffmann }; 325*41746334SGerd Hoffmann 32622773d60SMichael S. Tsirkin static void pci_testdev_class_init(ObjectClass *klass, void *data) 32722773d60SMichael S. Tsirkin { 32822773d60SMichael S. Tsirkin DeviceClass *dc = DEVICE_CLASS(klass); 32922773d60SMichael S. Tsirkin PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); 33022773d60SMichael S. Tsirkin 3319af21dbeSMarkus Armbruster k->realize = pci_testdev_realize; 33222773d60SMichael S. Tsirkin k->exit = pci_testdev_uninit; 33322773d60SMichael S. Tsirkin k->vendor_id = PCI_VENDOR_ID_REDHAT; 33422773d60SMichael S. Tsirkin k->device_id = PCI_DEVICE_ID_REDHAT_TEST; 33522773d60SMichael S. Tsirkin k->revision = 0x00; 33622773d60SMichael S. Tsirkin k->class_id = PCI_CLASS_OTHERS; 33722773d60SMichael S. Tsirkin dc->desc = "PCI Test Device"; 338125ee0edSMarcel Apfelbaum set_bit(DEVICE_CATEGORY_MISC, dc->categories); 33922773d60SMichael S. Tsirkin dc->reset = qdev_pci_testdev_reset; 340*41746334SGerd Hoffmann dc->props = pci_testdev_properties; 34122773d60SMichael S. Tsirkin } 34222773d60SMichael S. Tsirkin 34322773d60SMichael S. Tsirkin static const TypeInfo pci_testdev_info = { 34440108d0aSPeter Crosthwaite .name = TYPE_PCI_TEST_DEV, 34522773d60SMichael S. Tsirkin .parent = TYPE_PCI_DEVICE, 34622773d60SMichael S. Tsirkin .instance_size = sizeof(PCITestDevState), 34722773d60SMichael S. Tsirkin .class_init = pci_testdev_class_init, 348fd3b02c8SEduardo Habkost .interfaces = (InterfaceInfo[]) { 349fd3b02c8SEduardo Habkost { INTERFACE_CONVENTIONAL_PCI_DEVICE }, 350fd3b02c8SEduardo Habkost { }, 351fd3b02c8SEduardo Habkost }, 35222773d60SMichael S. Tsirkin }; 35322773d60SMichael S. Tsirkin 35422773d60SMichael S. Tsirkin static void pci_testdev_register_types(void) 35522773d60SMichael S. Tsirkin { 35622773d60SMichael S. Tsirkin type_register_static(&pci_testdev_info); 35722773d60SMichael S. Tsirkin } 35822773d60SMichael S. Tsirkin 35922773d60SMichael S. Tsirkin type_init(pci_testdev_register_types) 360