pci-testdev: add optional memory bar

Add memory bar to pci-testdev.  Size is configurable using the membar
property.  Setting the size to zero (default) turns it off.  Can be used
to check whether guests handle large pci bars correctly.

Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
Gerd Hoffmann 2018-09-28 08:44:19 +02:00 committed by Michael S. Tsirkin
parent 7115dcf4f1
commit 417463341e
2 changed files with 29 additions and 5 deletions

View file

@ -1,11 +1,11 @@
pci-test is a device used for testing low level IO pci-test is a device used for testing low level IO
device implements up to two BARs: BAR0 and BAR1. device implements up to three BARs: BAR0, BAR1 and BAR2.
Each BAR can be memory or IO. Guests must detect Each of BAR 0+1 can be memory or IO. Guests must detect
BAR type and act accordingly. BAR types and act accordingly.
Each BAR size is up to 4K bytes. BAR 0+1 size is up to 4K bytes each.
Each BAR starts with the following header: BAR 0+1 starts with the following header:
typedef struct PCITestDevHdr { typedef struct PCITestDevHdr {
uint8_t test; <- write-only, starts a given test number uint8_t test; <- write-only, starts a given test number
@ -24,3 +24,8 @@ All registers are little endian.
device is expected to always implement tests 0 to N on each BAR, and to add new device is expected to always implement tests 0 to N on each BAR, and to add new
tests with higher numbers. In this way a guest can scan test numbers until it tests with higher numbers. In this way a guest can scan test numbers until it
detects an access type that it does not support on this BAR, then stop. detects an access type that it does not support on this BAR, then stop.
BAR2 is a 64bit memory bar, without backing storage. It is disabled
by default and can be enabled using the membar=<size> property. This
can be used to test whether guests handle pci bars of a specific
(possibly quite large) size correctly.

View file

@ -85,6 +85,9 @@ typedef struct PCITestDevState {
MemoryRegion portio; MemoryRegion portio;
IOTest *tests; IOTest *tests;
int current; int current;
uint64_t membar_size;
MemoryRegion membar;
} PCITestDevState; } PCITestDevState;
#define TYPE_PCI_TEST_DEV "pci-testdev" #define TYPE_PCI_TEST_DEV "pci-testdev"
@ -253,6 +256,16 @@ static void pci_testdev_realize(PCIDevice *pci_dev, Error **errp)
pci_register_bar(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &d->mmio); 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); pci_register_bar(pci_dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->portio);
if (d->membar_size) {
memory_region_init(&d->membar, OBJECT(d), "pci-testdev-membar",
d->membar_size);
pci_register_bar(pci_dev, 2,
PCI_BASE_ADDRESS_SPACE_MEMORY |
PCI_BASE_ADDRESS_MEM_PREFETCH |
PCI_BASE_ADDRESS_MEM_TYPE_64,
&d->membar);
}
d->current = -1; d->current = -1;
d->tests = g_malloc0(IOTEST_MAX * sizeof *d->tests); d->tests = g_malloc0(IOTEST_MAX * sizeof *d->tests);
for (i = 0; i < IOTEST_MAX; ++i) { for (i = 0; i < IOTEST_MAX; ++i) {
@ -305,6 +318,11 @@ static void qdev_pci_testdev_reset(DeviceState *dev)
pci_testdev_reset(d); pci_testdev_reset(d);
} }
static Property pci_testdev_properties[] = {
DEFINE_PROP_SIZE("membar", PCITestDevState, membar_size, 0),
DEFINE_PROP_END_OF_LIST(),
};
static void pci_testdev_class_init(ObjectClass *klass, void *data) static void pci_testdev_class_init(ObjectClass *klass, void *data)
{ {
DeviceClass *dc = DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass);
@ -319,6 +337,7 @@ static void pci_testdev_class_init(ObjectClass *klass, void *data)
dc->desc = "PCI Test Device"; dc->desc = "PCI Test Device";
set_bit(DEVICE_CATEGORY_MISC, dc->categories); set_bit(DEVICE_CATEGORY_MISC, dc->categories);
dc->reset = qdev_pci_testdev_reset; dc->reset = qdev_pci_testdev_reset;
dc->props = pci_testdev_properties;
} }
static const TypeInfo pci_testdev_info = { static const TypeInfo pci_testdev_info = {