提交 41746334 编写于 作者: G Gerd Hoffmann 提交者: Michael S. Tsirkin

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: NMarc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: NLaszlo Ersek <lersek@redhat.com>
Tested-by: NLaszlo Ersek <lersek@redhat.com>
Signed-off-by: NGerd Hoffmann <kraxel@redhat.com>
Reviewed-by: NMichael S. Tsirkin <mst@redhat.com>
Signed-off-by: NMichael S. Tsirkin <mst@redhat.com>
上级 7115dcf4
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. ...@@ -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.
...@@ -85,6 +85,9 @@ typedef struct PCITestDevState { ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 = {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册