aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/Makefile.include3
-rw-r--r--tests/ahci-test.c13
-rw-r--r--tests/e1000e-test.c7
-rw-r--r--tests/ide-test.c177
-rw-r--r--tests/ivshmem-test.c47
-rw-r--r--tests/libqos/ahci.c4
-rw-r--r--tests/libqos/ahci.h7
-rw-r--r--tests/libqos/libqos.c2
-rw-r--r--tests/libqos/pci-pc.c187
-rw-r--r--tests/libqos/pci-spapr.c194
-rw-r--r--tests/libqos/pci.c194
-rw-r--r--tests/libqos/pci.h66
-rw-r--r--tests/libqos/usb.c6
-rw-r--r--tests/libqos/usb.h2
-rw-r--r--tests/libqos/virtio-mmio.c17
-rw-r--r--tests/libqos/virtio-pci.c146
-rw-r--r--tests/libqos/virtio-pci.h2
-rw-r--r--tests/libqos/virtio.c78
-rw-r--r--tests/libqos/virtio.h57
-rw-r--r--tests/libqtest.h10
-rw-r--r--tests/postcopy-test.c8
-rw-r--r--tests/prom-env-test.c20
-rw-r--r--tests/rtas-test.c1
-rw-r--r--tests/rtl8139-test.c10
-rw-r--r--tests/tco-test.c80
-rw-r--r--tests/usb-hcd-ehci-test.c5
-rw-r--r--tests/vhost-user-test.c33
-rw-r--r--tests/virtio-9p-test.c73
-rw-r--r--tests/virtio-blk-test.c342
-rw-r--r--tests/virtio-net-test.c106
-rw-r--r--tests/virtio-rng-test.c7
-rw-r--r--tests/virtio-scsi-test.c93
32 files changed, 999 insertions, 998 deletions
diff --git a/tests/Makefile.include b/tests/Makefile.include
index 22656eaf26..1a135d2340 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -282,6 +282,7 @@ check-qtest-ppc64-y += tests/usb-hcd-uhci-test$(EXESUF)
gcov-files-ppc64-y += hw/usb/hcd-uhci.c
check-qtest-ppc64-y += tests/usb-hcd-xhci-test$(EXESUF)
gcov-files-ppc64-y += hw/usb/hcd-xhci.c
+check-qtest-ppc64-y += $(check-qtest-virtio-y)
check-qtest-sh4-y = tests/endianness-test$(EXESUF)
@@ -615,7 +616,7 @@ libqos-pc-obj-y += tests/libqos/ahci.o
libqos-omap-obj-y = $(libqos-obj-y) tests/libqos/i2c-omap.o
libqos-imx-obj-y = $(libqos-obj-y) tests/libqos/i2c-imx.o
libqos-usb-obj-y = $(libqos-spapr-obj-y) $(libqos-pc-obj-y) tests/libqos/usb.o
-libqos-virtio-obj-y = $(libqos-pc-obj-y) tests/libqos/virtio.o tests/libqos/virtio-pci.o tests/libqos/virtio-mmio.o tests/libqos/malloc-generic.o
+libqos-virtio-obj-y = $(libqos-spapr-obj-y) $(libqos-pc-obj-y) tests/libqos/virtio.o tests/libqos/virtio-pci.o tests/libqos/virtio-mmio.o tests/libqos/malloc-generic.o
tests/device-introspect-test$(EXESUF): tests/device-introspect-test.o
tests/rtc-test$(EXESUF): tests/rtc-test.o
diff --git a/tests/ahci-test.c b/tests/ahci-test.c
index 9c0adce220..70bcafa9e4 100644
--- a/tests/ahci-test.c
+++ b/tests/ahci-test.c
@@ -78,25 +78,23 @@ static void string_bswap16(uint16_t *s, size_t bytes)
/**
* Verify that the transfer did not corrupt our state at all.
*/
-static void verify_state(AHCIQState *ahci)
+static void verify_state(AHCIQState *ahci, uint64_t hba_old)
{
int i, j;
uint32_t ahci_fingerprint;
uint64_t hba_base;
- uint64_t hba_stored;
AHCICommandHeader cmd;
ahci_fingerprint = qpci_config_readl(ahci->dev, PCI_VENDOR_ID);
g_assert_cmphex(ahci_fingerprint, ==, ahci->fingerprint);
/* If we haven't initialized, this is as much as can be validated. */
- if (!ahci->hba_base) {
+ if (!ahci->enabled) {
return;
}
hba_base = (uint64_t)qpci_config_readl(ahci->dev, PCI_BASE_ADDRESS_5);
- hba_stored = (uint64_t)(uintptr_t)ahci->hba_base;
- g_assert_cmphex(hba_base, ==, hba_stored);
+ g_assert_cmphex(hba_base, ==, hba_old);
g_assert_cmphex(ahci_rreg(ahci, AHCI_CAP), ==, ahci->cap);
g_assert_cmphex(ahci_rreg(ahci, AHCI_CAP2), ==, ahci->cap2);
@@ -119,12 +117,15 @@ static void ahci_migrate(AHCIQState *from, AHCIQState *to, const char *uri)
QOSState *tmp = to->parent;
QPCIDevice *dev = to->dev;
char *uri_local = NULL;
+ uint64_t hba_old;
if (uri == NULL) {
uri_local = g_strdup_printf("%s%s", "unix:", mig_socket);
uri = uri_local;
}
+ hba_old = (uint64_t)qpci_config_readl(from->dev, PCI_BASE_ADDRESS_5);
+
/* context will be 'to' after completion. */
migrate(from->parent, to->parent, uri);
@@ -141,7 +142,7 @@ static void ahci_migrate(AHCIQState *from, AHCIQState *to, const char *uri)
from->parent = tmp;
from->dev = dev;
- verify_state(to);
+ verify_state(to, hba_old);
g_free(uri_local);
}
diff --git a/tests/e1000e-test.c b/tests/e1000e-test.c
index 3979b20bb0..8c42ca919f 100644
--- a/tests/e1000e-test.c
+++ b/tests/e1000e-test.c
@@ -87,7 +87,7 @@
typedef struct e1000e_device {
QPCIDevice *pci_dev;
- void *mac_regs;
+ QPCIBar mac_regs;
uint64_t tx_ring;
uint64_t rx_ring;
@@ -119,12 +119,12 @@ static QPCIDevice *e1000e_device_find(QPCIBus *bus)
static void e1000e_macreg_write(e1000e_device *d, uint32_t reg, uint32_t val)
{
- qpci_io_writel(d->pci_dev, d->mac_regs + reg, val);
+ qpci_io_writel(d->pci_dev, d->mac_regs, reg, val);
}
static uint32_t e1000e_macreg_read(e1000e_device *d, uint32_t reg)
{
- return qpci_io_readl(d->pci_dev, d->mac_regs + reg);
+ return qpci_io_readl(d->pci_dev, d->mac_regs, reg);
}
static void e1000e_device_init(QPCIBus *bus, e1000e_device *d)
@@ -138,7 +138,6 @@ static void e1000e_device_init(QPCIBus *bus, e1000e_device *d)
/* Map BAR0 (mac registers) */
d->mac_regs = qpci_iomap(d->pci_dev, 0, NULL);
- g_assert_nonnull(d->mac_regs);
/* Reset the device */
val = e1000e_macreg_read(d, E1000E_CTRL);
diff --git a/tests/ide-test.c b/tests/ide-test.c
index a8a4081f78..67c7df0c8d 100644
--- a/tests/ide-test.c
+++ b/tests/ide-test.c
@@ -137,7 +137,7 @@ static void ide_test_quit(void)
qtest_end();
}
-static QPCIDevice *get_pci_device(uint16_t *bmdma_base)
+static QPCIDevice *get_pci_device(QPCIBar *bmdma_bar, QPCIBar *ide_bar)
{
QPCIDevice *dev;
uint16_t vendor_id, device_id;
@@ -156,7 +156,9 @@ static QPCIDevice *get_pci_device(uint16_t *bmdma_base)
g_assert(device_id == PCI_DEVICE_ID_INTEL_82371SB_1);
/* Map bmdma BAR */
- *bmdma_base = (uint16_t)(uintptr_t) qpci_iomap(dev, 4, NULL);
+ *bmdma_bar = qpci_iomap(dev, 4, NULL);
+
+ *ide_bar = qpci_legacy_iomap(dev, IDE_BASE);
qpci_device_enable(dev);
@@ -179,17 +181,18 @@ typedef struct PrdtEntry {
static int send_dma_request(int cmd, uint64_t sector, int nb_sectors,
PrdtEntry *prdt, int prdt_entries,
- void(*post_exec)(uint64_t sector, int nb_sectors))
+ void(*post_exec)(QPCIDevice *dev, QPCIBar ide_bar,
+ uint64_t sector, int nb_sectors))
{
QPCIDevice *dev;
- uint16_t bmdma_base;
+ QPCIBar bmdma_bar, ide_bar;
uintptr_t guest_prdt;
size_t len;
bool from_dev;
uint8_t status;
int flags;
- dev = get_pci_device(&bmdma_base);
+ dev = get_pci_device(&bmdma_bar, &ide_bar);
flags = cmd & ~0xff;
cmd &= 0xff;
@@ -214,59 +217,60 @@ static int send_dma_request(int cmd, uint64_t sector, int nb_sectors,
}
/* Select device 0 */
- outb(IDE_BASE + reg_device, 0 | LBA);
+ qpci_io_writeb(dev, ide_bar, reg_device, 0 | LBA);
/* Stop any running transfer, clear any pending interrupt */
- outb(bmdma_base + bmreg_cmd, 0);
- outb(bmdma_base + bmreg_status, BM_STS_INTR);
+ qpci_io_writeb(dev, bmdma_bar, bmreg_cmd, 0);
+ qpci_io_writeb(dev, bmdma_bar, bmreg_status, BM_STS_INTR);
/* Setup PRDT */
len = sizeof(*prdt) * prdt_entries;
guest_prdt = guest_alloc(guest_malloc, len);
memwrite(guest_prdt, prdt, len);
- outl(bmdma_base + bmreg_prdt, guest_prdt);
+ qpci_io_writel(dev, bmdma_bar, bmreg_prdt, guest_prdt);
/* ATA DMA command */
if (cmd == CMD_PACKET) {
/* Enables ATAPI DMA; otherwise PIO is attempted */
- outb(IDE_BASE + reg_feature, 0x01);
+ qpci_io_writeb(dev, ide_bar, reg_feature, 0x01);
} else {
- outb(IDE_BASE + reg_nsectors, nb_sectors);
- outb(IDE_BASE + reg_lba_low, sector & 0xff);
- outb(IDE_BASE + reg_lba_middle, (sector >> 8) & 0xff);
- outb(IDE_BASE + reg_lba_high, (sector >> 16) & 0xff);
+ qpci_io_writeb(dev, ide_bar, reg_nsectors, nb_sectors);
+ qpci_io_writeb(dev, ide_bar, reg_lba_low, sector & 0xff);
+ qpci_io_writeb(dev, ide_bar, reg_lba_middle, (sector >> 8) & 0xff);
+ qpci_io_writeb(dev, ide_bar, reg_lba_high, (sector >> 16) & 0xff);
}
- outb(IDE_BASE + reg_command, cmd);
+ qpci_io_writeb(dev, ide_bar, reg_command, cmd);
if (post_exec) {
- post_exec(sector, nb_sectors);
+ post_exec(dev, ide_bar, sector, nb_sectors);
}
/* Start DMA transfer */
- outb(bmdma_base + bmreg_cmd, BM_CMD_START | (from_dev ? BM_CMD_WRITE : 0));
+ qpci_io_writeb(dev, bmdma_bar, bmreg_cmd,
+ BM_CMD_START | (from_dev ? BM_CMD_WRITE : 0));
if (flags & CMDF_ABORT) {
- outb(bmdma_base + bmreg_cmd, 0);
+ qpci_io_writeb(dev, bmdma_bar, bmreg_cmd, 0);
}
/* Wait for the DMA transfer to complete */
do {
- status = inb(bmdma_base + bmreg_status);
+ status = qpci_io_readb(dev, bmdma_bar, bmreg_status);
} while ((status & (BM_STS_ACTIVE | BM_STS_INTR)) == BM_STS_ACTIVE);
g_assert_cmpint(get_irq(IDE_PRIMARY_IRQ), ==, !!(status & BM_STS_INTR));
/* Check IDE status code */
- assert_bit_set(inb(IDE_BASE + reg_status), DRDY);
- assert_bit_clear(inb(IDE_BASE + reg_status), BSY | DRQ);
+ assert_bit_set(qpci_io_readb(dev, ide_bar, reg_status), DRDY);
+ assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), BSY | DRQ);
/* Reading the status register clears the IRQ */
g_assert(!get_irq(IDE_PRIMARY_IRQ));
/* Stop DMA transfer if still active */
if (status & BM_STS_ACTIVE) {
- outb(bmdma_base + bmreg_cmd, 0);
+ qpci_io_writeb(dev, bmdma_bar, bmreg_cmd, 0);
}
free_pci_device(dev);
@@ -276,6 +280,8 @@ static int send_dma_request(int cmd, uint64_t sector, int nb_sectors,
static void test_bmdma_simple_rw(void)
{
+ QPCIDevice *dev;
+ QPCIBar bmdma_bar, ide_bar;
uint8_t status;
uint8_t *buf;
uint8_t *cmpbuf;
@@ -289,6 +295,8 @@ static void test_bmdma_simple_rw(void)
},
};
+ dev = get_pci_device(&bmdma_bar, &ide_bar);
+
buf = g_malloc(len);
cmpbuf = g_malloc(len);
@@ -299,7 +307,7 @@ static void test_bmdma_simple_rw(void)
status = send_dma_request(CMD_WRITE_DMA, 0, 1, prdt,
ARRAY_SIZE(prdt), NULL);
g_assert_cmphex(status, ==, BM_STS_INTR);
- assert_bit_clear(inb(IDE_BASE + reg_status), DF | ERR);
+ assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), DF | ERR);
/* Write 0xaa pattern to sector 1 */
memset(buf, 0xaa, len);
@@ -308,14 +316,14 @@ static void test_bmdma_simple_rw(void)
status = send_dma_request(CMD_WRITE_DMA, 1, 1, prdt,
ARRAY_SIZE(prdt), NULL);
g_assert_cmphex(status, ==, BM_STS_INTR);
- assert_bit_clear(inb(IDE_BASE + reg_status), DF | ERR);
+ assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), DF | ERR);
/* Read and verify 0x55 pattern in sector 0 */
memset(cmpbuf, 0x55, len);
status = send_dma_request(CMD_READ_DMA, 0, 1, prdt, ARRAY_SIZE(prdt), NULL);
g_assert_cmphex(status, ==, BM_STS_INTR);
- assert_bit_clear(inb(IDE_BASE + reg_status), DF | ERR);
+ assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), DF | ERR);
memread(guest_buf, buf, len);
g_assert(memcmp(buf, cmpbuf, len) == 0);
@@ -325,7 +333,7 @@ static void test_bmdma_simple_rw(void)
status = send_dma_request(CMD_READ_DMA, 1, 1, prdt, ARRAY_SIZE(prdt), NULL);
g_assert_cmphex(status, ==, BM_STS_INTR);
- assert_bit_clear(inb(IDE_BASE + reg_status), DF | ERR);
+ assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), DF | ERR);
memread(guest_buf, buf, len);
g_assert(memcmp(buf, cmpbuf, len) == 0);
@@ -337,6 +345,8 @@ static void test_bmdma_simple_rw(void)
static void test_bmdma_short_prdt(void)
{
+ QPCIDevice *dev;
+ QPCIBar bmdma_bar, ide_bar;
uint8_t status;
PrdtEntry prdt[] = {
@@ -346,21 +356,25 @@ static void test_bmdma_short_prdt(void)
},
};
+ dev = get_pci_device(&bmdma_bar, &ide_bar);
+
/* Normal request */
status = send_dma_request(CMD_READ_DMA, 0, 1,
prdt, ARRAY_SIZE(prdt), NULL);
g_assert_cmphex(status, ==, 0);
- assert_bit_clear(inb(IDE_BASE + reg_status), DF | ERR);
+ assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), DF | ERR);
/* Abort the request before it completes */
status = send_dma_request(CMD_READ_DMA | CMDF_ABORT, 0, 1,
prdt, ARRAY_SIZE(prdt), NULL);
g_assert_cmphex(status, ==, 0);
- assert_bit_clear(inb(IDE_BASE + reg_status), DF | ERR);
+ assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), DF | ERR);
}
static void test_bmdma_one_sector_short_prdt(void)
{
+ QPCIDevice *dev;
+ QPCIBar bmdma_bar, ide_bar;
uint8_t status;
/* Read 2 sectors but only give 1 sector in PRDT */
@@ -371,21 +385,25 @@ static void test_bmdma_one_sector_short_prdt(void)
},
};
+ dev = get_pci_device(&bmdma_bar, &ide_bar);
+
/* Normal request */
status = send_dma_request(CMD_READ_DMA, 0, 2,
prdt, ARRAY_SIZE(prdt), NULL);
g_assert_cmphex(status, ==, 0);
- assert_bit_clear(inb(IDE_BASE + reg_status), DF | ERR);
+ assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), DF | ERR);
/* Abort the request before it completes */
status = send_dma_request(CMD_READ_DMA | CMDF_ABORT, 0, 2,
prdt, ARRAY_SIZE(prdt), NULL);
g_assert_cmphex(status, ==, 0);
- assert_bit_clear(inb(IDE_BASE + reg_status), DF | ERR);
+ assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), DF | ERR);
}
static void test_bmdma_long_prdt(void)
{
+ QPCIDevice *dev;
+ QPCIBar bmdma_bar, ide_bar;
uint8_t status;
PrdtEntry prdt[] = {
@@ -395,23 +413,29 @@ static void test_bmdma_long_prdt(void)
},
};
+ dev = get_pci_device(&bmdma_bar, &ide_bar);
+
/* Normal request */
status = send_dma_request(CMD_READ_DMA, 0, 1,
prdt, ARRAY_SIZE(prdt), NULL);
g_assert_cmphex(status, ==, BM_STS_ACTIVE | BM_STS_INTR);
- assert_bit_clear(inb(IDE_BASE + reg_status), DF | ERR);
+ assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), DF | ERR);
/* Abort the request before it completes */
status = send_dma_request(CMD_READ_DMA | CMDF_ABORT, 0, 1,
prdt, ARRAY_SIZE(prdt), NULL);
g_assert_cmphex(status, ==, BM_STS_INTR);
- assert_bit_clear(inb(IDE_BASE + reg_status), DF | ERR);
+ assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), DF | ERR);
}
static void test_bmdma_no_busmaster(void)
{
+ QPCIDevice *dev;
+ QPCIBar bmdma_bar, ide_bar;
uint8_t status;
+ dev = get_pci_device(&bmdma_bar, &ide_bar);
+
/* No PRDT_EOT, each entry addr 0/size 64k, and in theory qemu shouldn't be
* able to access it anyway because the Bus Master bit in the PCI command
* register isn't set. This is complete nonsense, but it used to be pretty
@@ -424,7 +448,7 @@ static void test_bmdma_no_busmaster(void)
/* Not entirely clear what the expected result is, but this is what we get
* in practice. At least we want to be aware of any changes. */
g_assert_cmphex(status, ==, BM_STS_ACTIVE | BM_STS_INTR);
- assert_bit_clear(inb(IDE_BASE + reg_status), DF | ERR);
+ assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), DF | ERR);
}
static void test_bmdma_setup(void)
@@ -454,6 +478,8 @@ static void string_cpu_to_be16(uint16_t *s, size_t bytes)
static void test_identify(void)
{
+ QPCIDevice *dev;
+ QPCIBar bmdma_bar, ide_bar;
uint8_t data;
uint16_t buf[256];
int i;
@@ -464,23 +490,25 @@ static void test_identify(void)
"-global ide-hd.ver=%s",
tmp_path, "testdisk", "version");
+ dev = get_pci_device(&bmdma_bar, &ide_bar);
+
/* IDENTIFY command on device 0*/
- outb(IDE_BASE + reg_device, 0);
- outb(IDE_BASE + reg_command, CMD_IDENTIFY);
+ qpci_io_writeb(dev, ide_bar, reg_device, 0);
+ qpci_io_writeb(dev, ide_bar, reg_command, CMD_IDENTIFY);
/* Read in the IDENTIFY buffer and check registers */
- data = inb(IDE_BASE + reg_device);
+ data = qpci_io_readb(dev, ide_bar, reg_device);
g_assert_cmpint(data & DEV, ==, 0);
for (i = 0; i < 256; i++) {
- data = inb(IDE_BASE + reg_status);
+ data = qpci_io_readb(dev, ide_bar, reg_status);
assert_bit_set(data, DRDY | DRQ);
assert_bit_clear(data, BSY | DF | ERR);
- ((uint16_t*) buf)[i] = inw(IDE_BASE + reg_data);
+ buf[i] = qpci_io_readw(dev, ide_bar, reg_data);
}
- data = inb(IDE_BASE + reg_status);
+ data = qpci_io_readb(dev, ide_bar, reg_status);
assert_bit_set(data, DRDY);
assert_bit_clear(data, BSY | DF | ERR | DRQ);
@@ -505,11 +533,15 @@ static void test_identify(void)
*/
static void make_dirty(uint8_t device)
{
+ QPCIDevice *dev;
+ QPCIBar bmdma_bar, ide_bar;
uint8_t status;
size_t len = 512;
uintptr_t guest_buf;
void* buf;
+ dev = get_pci_device(&bmdma_bar, &ide_bar);
+
guest_buf = guest_alloc(guest_malloc, len);
buf = g_malloc(len);
g_assert(guest_buf);
@@ -527,19 +559,23 @@ static void make_dirty(uint8_t device)
status = send_dma_request(CMD_WRITE_DMA, 1, 1, prdt,
ARRAY_SIZE(prdt), NULL);
g_assert_cmphex(status, ==, BM_STS_INTR);
- assert_bit_clear(inb(IDE_BASE + reg_status), DF | ERR);
+ assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), DF | ERR);
g_free(buf);
}
static void test_flush(void)
{
+ QPCIDevice *dev;
+ QPCIBar bmdma_bar, ide_bar;
uint8_t data;
ide_test_start(
"-drive file=blkdebug::%s,if=ide,cache=writeback,format=raw",
tmp_path);
+ dev = get_pci_device(&bmdma_bar, &ide_bar);
+
qtest_irq_intercept_in(global_qtest, "ioapic");
/* Dirty media so that CMD_FLUSH_CACHE will actually go to disk */
@@ -549,11 +585,11 @@ static void test_flush(void)
g_free(hmp("qemu-io ide0-hd0 \"break flush_to_os A\""));
/* FLUSH CACHE command on device 0*/
- outb(IDE_BASE + reg_device, 0);
- outb(IDE_BASE + reg_command, CMD_FLUSH_CACHE);
+ qpci_io_writeb(dev, ide_bar, reg_device, 0);
+ qpci_io_writeb(dev, ide_bar, reg_command, CMD_FLUSH_CACHE);
/* Check status while request is in flight*/
- data = inb(IDE_BASE + reg_status);
+ data = qpci_io_readb(dev, ide_bar, reg_status);
assert_bit_set(data, BSY | DRDY);
assert_bit_clear(data, DF | ERR | DRQ);
@@ -561,11 +597,11 @@ static void test_flush(void)
g_free(hmp("qemu-io ide0-hd0 \"resume A\""));
/* Check registers */
- data = inb(IDE_BASE + reg_device);
+ data = qpci_io_readb(dev, ide_bar, reg_device);
g_assert_cmpint(data & DEV, ==, 0);
do {
- data = inb(IDE_BASE + reg_status);
+ data = qpci_io_readb(dev, ide_bar, reg_status);
} while (data & BSY);
assert_bit_set(data, DRDY);
@@ -576,6 +612,8 @@ static void test_flush(void)
static void test_retry_flush(const char *machine)
{
+ QPCIDevice *dev;
+ QPCIBar bmdma_bar, ide_bar;
uint8_t data;
const char *s;
@@ -587,17 +625,19 @@ static void test_retry_flush(const char *machine)
"rerror=stop,werror=stop",
debug_path, tmp_path);
+ dev = get_pci_device(&bmdma_bar, &ide_bar);
+
qtest_irq_intercept_in(global_qtest, "ioapic");
/* Dirty media so that CMD_FLUSH_CACHE will actually go to disk */
make_dirty(0);
/* FLUSH CACHE command on device 0*/
- outb(IDE_BASE + reg_device, 0);
- outb(IDE_BASE + reg_command, CMD_FLUSH_CACHE);
+ qpci_io_writeb(dev, ide_bar, reg_device, 0);
+ qpci_io_writeb(dev, ide_bar, reg_command, CMD_FLUSH_CACHE);
/* Check status while request is in flight*/
- data = inb(IDE_BASE + reg_status);
+ data = qpci_io_readb(dev, ide_bar, reg_status);
assert_bit_set(data, BSY | DRDY);
assert_bit_clear(data, DF | ERR | DRQ);
@@ -608,11 +648,11 @@ static void test_retry_flush(const char *machine)
qmp_discard_response(s);
/* Check registers */
- data = inb(IDE_BASE + reg_device);
+ data = qpci_io_readb(dev, ide_bar, reg_device);
g_assert_cmpint(data & DEV, ==, 0);
do {
- data = inb(IDE_BASE + reg_status);
+ data = qpci_io_readb(dev, ide_bar, reg_status);
} while (data & BSY);
assert_bit_set(data, DRDY);
@@ -623,11 +663,16 @@ static void test_retry_flush(const char *machine)
static void test_flush_nodev(void)
{
+ QPCIDevice *dev;
+ QPCIBar bmdma_bar, ide_bar;
+
ide_test_start("");
+ dev = get_pci_device(&bmdma_bar, &ide_bar);
+
/* FLUSH CACHE command on device 0*/
- outb(IDE_BASE + reg_device, 0);
- outb(IDE_BASE + reg_command, CMD_FLUSH_CACHE);
+ qpci_io_writeb(dev, ide_bar, reg_device, 0);
+ qpci_io_writeb(dev, ide_bar, reg_command, CMD_FLUSH_CACHE);
/* Just testing that qemu doesn't crash... */
@@ -654,7 +699,8 @@ typedef struct Read10CDB {
uint16_t padding;
} __attribute__((__packed__)) Read10CDB;
-static void send_scsi_cdb_read10(uint64_t lba, int nblocks)
+static void send_scsi_cdb_read10(QPCIDevice *dev, QPCIBar ide_bar,
+ uint64_t lba, int nblocks)
{
Read10CDB pkt = { .padding = 0 };
int i;
@@ -670,7 +716,8 @@ static void send_scsi_cdb_read10(uint64_t lba, int nblocks)
/* Send Packet */
for (i = 0; i < sizeof(Read10CDB)/2; i++) {
- outw(IDE_BASE + reg_data, cpu_to_le16(((uint16_t *)&pkt)[i]));
+ qpci_io_writew(dev, ide_bar, reg_data,
+ le16_to_cpu(((uint16_t *)&pkt)[i]));
}
}
@@ -683,13 +730,17 @@ static void nsleep(int64_t nsecs)
static uint8_t ide_wait_clear(uint8_t flag)
{
+ QPCIDevice *dev;
+ QPCIBar bmdma_bar, ide_bar;
uint8_t data;
time_t st;
+ dev = get_pci_device(&bmdma_bar, &ide_bar);
+
/* Wait with a 5 second timeout */
time(&st);
while (true) {
- data = inb(IDE_BASE + reg_status);
+ data = qpci_io_readb(dev, ide_bar, reg_status);
if (!(data & flag)) {
return data;
}
@@ -723,6 +774,8 @@ static void ide_wait_intr(int irq)
static void cdrom_pio_impl(int nblocks)
{
+ QPCIDevice *dev;
+ QPCIBar bmdma_bar, ide_bar;
FILE *fh;
int patt_blocks = MAX(16, nblocks);
size_t patt_len = ATAPI_BLOCK_SIZE * patt_blocks;
@@ -741,13 +794,14 @@ static void cdrom_pio_impl(int nblocks)
ide_test_start("-drive if=none,file=%s,media=cdrom,format=raw,id=sr0,index=0 "
"-device ide-cd,drive=sr0,bus=ide.0", tmp_path);
+ dev = get_pci_device(&bmdma_bar, &ide_bar);
qtest_irq_intercept_in(global_qtest, "ioapic");
/* PACKET command on device 0 */
- outb(IDE_BASE + reg_device, 0);
- outb(IDE_BASE + reg_lba_middle, BYTE_COUNT_LIMIT & 0xFF);
- outb(IDE_BASE + reg_lba_high, (BYTE_COUNT_LIMIT >> 8 & 0xFF));
- outb(IDE_BASE + reg_command, CMD_PACKET);
+ qpci_io_writeb(dev, ide_bar, reg_device, 0);
+ qpci_io_writeb(dev, ide_bar, reg_lba_middle, BYTE_COUNT_LIMIT & 0xFF);
+ qpci_io_writeb(dev, ide_bar, reg_lba_high, (BYTE_COUNT_LIMIT >> 8 & 0xFF));
+ qpci_io_writeb(dev, ide_bar, reg_command, CMD_PACKET);
/* HP0: Check_Status_A State */
nsleep(400);
data = ide_wait_clear(BSY);
@@ -756,7 +810,7 @@ static void cdrom_pio_impl(int nblocks)
assert_bit_clear(data, ERR | DF | BSY);
/* SCSI CDB (READ10) -- read n*2048 bytes from block 0 */
- send_scsi_cdb_read10(0, nblocks);
+ send_scsi_cdb_read10(dev, ide_bar, 0, nblocks);
/* Read data back: occurs in bursts of 'BYTE_COUNT_LIMIT' bytes.
* If BYTE_COUNT_LIMIT is odd, we transfer BYTE_COUNT_LIMIT - 1 bytes.
@@ -780,7 +834,8 @@ static void cdrom_pio_impl(int nblocks)
/* HP4: Transfer_Data */
for (j = 0; j < MIN((limit / 2), rem); j++) {
- rx[offset + j] = le16_to_cpu(inw(IDE_BASE + reg_data));
+ rx[offset + j] = cpu_to_le16(qpci_io_readw(dev, ide_bar,
+ reg_data));
}
}
diff --git a/tests/ivshmem-test.c b/tests/ivshmem-test.c
index f36bfe7d0a..04a5c5dc7d 100644
--- a/tests/ivshmem-test.c
+++ b/tests/ivshmem-test.c
@@ -41,7 +41,7 @@ static QPCIDevice *get_device(QPCIBus *pcibus)
typedef struct _IVState {
QTestState *qtest;
- void *reg_base, *mem_base;
+ QPCIBar reg_bar, mem_bar;
QPCIBus *pcibus;
QPCIDevice *dev;
} IVState;
@@ -75,7 +75,7 @@ static inline unsigned in_reg(IVState *s, enum Reg reg)
unsigned res;
global_qtest = s->qtest;
- res = qpci_io_readl(s->dev, s->reg_base + reg);
+ res = qpci_io_readl(s->dev, s->reg_bar, reg);
g_test_message("*%s -> %x\n", name, res);
global_qtest = qtest;
@@ -89,7 +89,26 @@ static inline void out_reg(IVState *s, enum Reg reg, unsigned v)
global_qtest = s->qtest;
g_test_message("%x -> *%s\n", v, name);
- qpci_io_writel(s->dev, s->reg_base + reg, v);
+ qpci_io_writel(s->dev, s->reg_bar, reg, v);
+ global_qtest = qtest;
+}
+
+static inline void read_mem(IVState *s, uint64_t off, void *buf, size_t len)
+{
+ QTestState *qtest = global_qtest;
+
+ global_qtest = s->qtest;
+ qpci_memread(s->dev, s->mem_bar, off, buf, len);
+ global_qtest = qtest;
+}
+
+static inline void write_mem(IVState *s, uint64_t off,
+ const void *buf, size_t len)
+{
+ QTestState *qtest = global_qtest;
+
+ global_qtest = s->qtest;
+ qpci_memwrite(s->dev, s->mem_bar, off, buf, len);
global_qtest = qtest;
}
@@ -108,16 +127,14 @@ static void setup_vm_cmd(IVState *s, const char *cmd, bool msix)
s->pcibus = qpci_init_pc(NULL);
s->dev = get_device(s->pcibus);
- s->reg_base = qpci_iomap(s->dev, 0, &barsize);
- g_assert_nonnull(s->reg_base);
+ s->reg_bar = qpci_iomap(s->dev, 0, &barsize);
g_assert_cmpuint(barsize, ==, 256);
if (msix) {
qpci_msix_enable(s->dev);
}
- s->mem_base = qpci_iomap(s->dev, 2, &barsize);
- g_assert_nonnull(s->mem_base);
+ s->mem_bar = qpci_iomap(s->dev, 2, &barsize);
g_assert_cmpuint(barsize, ==, TMPSHMSIZE);
qpci_device_enable(s->dev);
@@ -169,7 +186,7 @@ static void test_ivshmem_single(void)
for (i = 0; i < G_N_ELEMENTS(data); i++) {
data[i] = i;
}
- qtest_memwrite(s->qtest, (uintptr_t)s->mem_base, data, sizeof(data));
+ write_mem(s, 0, data, sizeof(data));
/* verify write */
for (i = 0; i < G_N_ELEMENTS(data); i++) {
@@ -178,7 +195,7 @@ static void test_ivshmem_single(void)
/* read it back and verify read */
memset(data, 0, sizeof(data));
- qtest_memread(s->qtest, (uintptr_t)s->mem_base, data, sizeof(data));
+ read_mem(s, 0, data, sizeof(data));
for (i = 0; i < G_N_ELEMENTS(data); i++) {
g_assert_cmpuint(data[i], ==, i);
}
@@ -201,29 +218,29 @@ static void test_ivshmem_pair(void)
/* host write, guest 1 & 2 read */
memset(tmpshmem, 0x42, TMPSHMSIZE);
- qtest_memread(s1->qtest, (uintptr_t)s1->mem_base, data, TMPSHMSIZE);
+ read_mem(s1, 0, data, TMPSHMSIZE);
for (i = 0; i < TMPSHMSIZE; i++) {
g_assert_cmpuint(data[i], ==, 0x42);
}
- qtest_memread(s2->qtest, (uintptr_t)s2->mem_base, data, TMPSHMSIZE);
+ read_mem(s2, 0, data, TMPSHMSIZE);
for (i = 0; i < TMPSHMSIZE; i++) {
g_assert_cmpuint(data[i], ==, 0x42);
}
/* guest 1 write, guest 2 read */
memset(data, 0x43, TMPSHMSIZE);
- qtest_memwrite(s1->qtest, (uintptr_t)s1->mem_base, data, TMPSHMSIZE);
+ write_mem(s1, 0, data, TMPSHMSIZE);
memset(data, 0, TMPSHMSIZE);
- qtest_memread(s2->qtest, (uintptr_t)s2->mem_base, data, TMPSHMSIZE);
+ read_mem(s2, 0, data, TMPSHMSIZE);
for (i = 0; i < TMPSHMSIZE; i++) {
g_assert_cmpuint(data[i], ==, 0x43);
}
/* guest 2 write, guest 1 read */
memset(data, 0x44, TMPSHMSIZE);
- qtest_memwrite(s2->qtest, (uintptr_t)s2->mem_base, data, TMPSHMSIZE);
+ write_mem(s2, 0, data, TMPSHMSIZE);
memset(data, 0, TMPSHMSIZE);
- qtest_memread(s1->qtest, (uintptr_t)s2->mem_base, data, TMPSHMSIZE);
+ read_mem(s1, 0, data, TMPSHMSIZE);
for (i = 0; i < TMPSHMSIZE; i++) {
g_assert_cmpuint(data[i], ==, 0x44);
}
diff --git a/tests/libqos/ahci.c b/tests/libqos/ahci.c
index 716ab7939e..5180d65279 100644
--- a/tests/libqos/ahci.c
+++ b/tests/libqos/ahci.c
@@ -210,8 +210,7 @@ void ahci_pci_enable(AHCIQState *ahci)
void start_ahci_device(AHCIQState *ahci)
{
/* Map AHCI's ABAR (BAR5) */
- ahci->hba_base = qpci_iomap(ahci->dev, 5, &ahci->barsize);
- g_assert(ahci->hba_base);
+ ahci->hba_bar = qpci_iomap(ahci->dev, 5, &ahci->barsize);
/* turns on pci.cmd.iose, pci.cmd.mse and pci.cmd.bme */
qpci_device_enable(ahci->dev);
@@ -351,6 +350,7 @@ void ahci_hba_enable(AHCIQState *ahci)
reg = ahci_rreg(ahci, AHCI_GHC);
ASSERT_BIT_SET(reg, AHCI_GHC_IE);
+ ahci->enabled = true;
/* TODO: The device should now be idling and waiting for commands.
* In the future, a small test-case to inspect the Register D2H FIS
* and clear the initial interrupts might be good. */
diff --git a/tests/libqos/ahci.h b/tests/libqos/ahci.h
index c69fb5ae90..caaafe3fdf 100644
--- a/tests/libqos/ahci.h
+++ b/tests/libqos/ahci.h
@@ -321,12 +321,13 @@ typedef struct AHCIPortQState {
typedef struct AHCIQState {
QOSState *parent;
QPCIDevice *dev;
- void *hba_base;
+ QPCIBar hba_bar;
uint64_t barsize;
uint32_t fingerprint;
uint32_t cap;
uint32_t cap2;
AHCIPortQState port[32];
+ bool enabled;
} AHCIQState;
/**
@@ -488,12 +489,12 @@ typedef struct AHCIOpts {
static inline uint32_t ahci_mread(AHCIQState *ahci, size_t offset)
{
- return qpci_io_readl(ahci->dev, ahci->hba_base + offset);
+ return qpci_io_readl(ahci->dev, ahci->hba_bar, offset);
}
static inline void ahci_mwrite(AHCIQState *ahci, size_t offset, uint32_t value)
{
- qpci_io_writel(ahci->dev, ahci->hba_base + offset, value);
+ qpci_io_writel(ahci->dev, ahci->hba_bar, offset, value);
}
static inline uint32_t ahci_rreg(AHCIQState *ahci, uint32_t reg_num)
diff --git a/tests/libqos/libqos.c b/tests/libqos/libqos.c
index 7abb48254e..6226546c28 100644
--- a/tests/libqos/libqos.c
+++ b/tests/libqos/libqos.c
@@ -10,6 +10,8 @@
/**
* Launch QEMU with the given command line,
* and then set up interrupts and our guest malloc interface.
+ * Never returns NULL:
+ * Terminates the application in case an error is encountered.
*/
QOSState *qtest_vboot(QOSOps *ops, const char *cmdline_fmt, va_list ap)
{
diff --git a/tests/libqos/pci-pc.c b/tests/libqos/pci-pc.c
index 9600ed6e41..ded1c54c06 100644
--- a/tests/libqos/pci-pc.c
+++ b/tests/libqos/pci-pc.c
@@ -17,7 +17,6 @@
#include "hw/pci/pci_regs.h"
#include "qemu-common.h"
-#include "qemu/host-utils.h"
#define ACPI_PCIHP_ADDR 0xae00
@@ -26,89 +25,58 @@
typedef struct QPCIBusPC
{
QPCIBus bus;
-
- uint32_t pci_hole_start;
- uint32_t pci_hole_size;
- uint32_t pci_hole_alloc;
-
- uint16_t pci_iohole_start;
- uint16_t pci_iohole_size;
- uint16_t pci_iohole_alloc;
} QPCIBusPC;
-static uint8_t qpci_pc_io_readb(QPCIBus *bus, void *addr)
+static uint8_t qpci_pc_pio_readb(QPCIBus *bus, uint32_t addr)
{
- uintptr_t port = (uintptr_t)addr;
- uint8_t value;
-
- if (port < 0x10000) {
- value = inb(port);
- } else {
- value = readb(port);
- }
-
- return value;
+ return inb(addr);
}
-static uint16_t qpci_pc_io_readw(QPCIBus *bus, void *addr)
+static void qpci_pc_pio_writeb(QPCIBus *bus, uint32_t addr, uint8_t val)
{
- uintptr_t port = (uintptr_t)addr;
- uint16_t value;
-
- if (port < 0x10000) {
- value = inw(port);
- } else {
- value = readw(port);
- }
-
- return value;
+ outb(addr, val);
}
-static uint32_t qpci_pc_io_readl(QPCIBus *bus, void *addr)
+static uint16_t qpci_pc_pio_readw(QPCIBus *bus, uint32_t addr)
{
- uintptr_t port = (uintptr_t)addr;
- uint32_t value;
-
- if (port < 0x10000) {
- value = inl(port);
- } else {
- value = readl(port);
- }
+ return inw(addr);
+}
- return value;
+static void qpci_pc_pio_writew(QPCIBus *bus, uint32_t addr, uint16_t val)
+{
+ outw(addr, val);
}
-static void qpci_pc_io_writeb(QPCIBus *bus, void *addr, uint8_t value)
+static uint32_t qpci_pc_pio_readl(QPCIBus *bus, uint32_t addr)
{
- uintptr_t port = (uintptr_t)addr;
+ return inl(addr);
+}
- if (port < 0x10000) {
- outb(port, value);
- } else {
- writeb(port, value);
- }
+static void qpci_pc_pio_writel(QPCIBus *bus, uint32_t addr, uint32_t val)
+{
+ outl(addr, val);
}
-static void qpci_pc_io_writew(QPCIBus *bus, void *addr, uint16_t value)
+static uint64_t qpci_pc_pio_readq(QPCIBus *bus, uint32_t addr)
{
- uintptr_t port = (uintptr_t)addr;
+ return (uint64_t)inl(addr) + ((uint64_t)inl(addr + 4) << 32);
+}
- if (port < 0x10000) {
- outw(port, value);
- } else {
- writew(port, value);
- }
+static void qpci_pc_pio_writeq(QPCIBus *bus, uint32_t addr, uint64_t val)
+{
+ outl(addr, val & 0xffffffff);
+ outl(addr + 4, val >> 32);
}
-static void qpci_pc_io_writel(QPCIBus *bus, void *addr, uint32_t value)
+static void qpci_pc_memread(QPCIBus *bus, uint32_t addr, void *buf, size_t len)
{
- uintptr_t port = (uintptr_t)addr;
+ memread(addr, buf, len);
+}
- if (port < 0x10000) {
- outl(port, value);
- } else {
- writel(port, value);
- }
+static void qpci_pc_memwrite(QPCIBus *bus, uint32_t addr,
+ const void *buf, size_t len)
+{
+ memwrite(addr, buf, len);
}
static uint8_t qpci_pc_config_readb(QPCIBus *bus, int devfn, uint8_t offset)
@@ -147,84 +115,24 @@ static void qpci_pc_config_writel(QPCIBus *bus, int devfn, uint8_t offset, uint3
outl(0xcfc, value);
}
-static void *qpci_pc_iomap(QPCIBus *bus, QPCIDevice *dev, int barno, uint64_t *sizeptr)
-{
- QPCIBusPC *s = container_of(bus, QPCIBusPC, bus);
- static const int bar_reg_map[] = {
- PCI_BASE_ADDRESS_0, PCI_BASE_ADDRESS_1, PCI_BASE_ADDRESS_2,
- PCI_BASE_ADDRESS_3, PCI_BASE_ADDRESS_4, PCI_BASE_ADDRESS_5,
- };
- int bar_reg;
- uint32_t addr;
- uint64_t size;
- uint32_t io_type;
-
- g_assert(barno >= 0 && barno <= 5);
- bar_reg = bar_reg_map[barno];
-
- qpci_config_writel(dev, bar_reg, 0xFFFFFFFF);
- addr = qpci_config_readl(dev, bar_reg);
-
- io_type = addr & PCI_BASE_ADDRESS_SPACE;
- if (io_type == PCI_BASE_ADDRESS_SPACE_IO) {
- addr &= PCI_BASE_ADDRESS_IO_MASK;
- } else {
- addr &= PCI_BASE_ADDRESS_MEM_MASK;
- }
-
- size = (1ULL << ctzl(addr));
- if (size == 0) {
- return NULL;
- }
- if (sizeptr) {
- *sizeptr = size;
- }
-
- if (io_type == PCI_BASE_ADDRESS_SPACE_IO) {
- uint16_t loc;
-
- g_assert(QEMU_ALIGN_UP(s->pci_iohole_alloc, size) + size
- <= s->pci_iohole_size);
- s->pci_iohole_alloc = QEMU_ALIGN_UP(s->pci_iohole_alloc, size);
- loc = s->pci_iohole_start + s->pci_iohole_alloc;
- s->pci_iohole_alloc += size;
-
- qpci_config_writel(dev, bar_reg, loc | PCI_BASE_ADDRESS_SPACE_IO);
-
- return (void *)(intptr_t)loc;
- } else {
- uint64_t loc;
-
- g_assert(QEMU_ALIGN_UP(s->pci_hole_alloc, size) + size
- <= s->pci_hole_size);
- s->pci_hole_alloc = QEMU_ALIGN_UP(s->pci_hole_alloc, size);
- loc = s->pci_hole_start + s->pci_hole_alloc;
- s->pci_hole_alloc += size;
-
- qpci_config_writel(dev, bar_reg, loc);
-
- return (void *)(intptr_t)loc;
- }
-}
-
-static void qpci_pc_iounmap(QPCIBus *bus, void *data)
-{
- /* FIXME */
-}
-
QPCIBus *qpci_init_pc(QGuestAllocator *alloc)
{
QPCIBusPC *ret;
ret = g_malloc(sizeof(*ret));
- ret->bus.io_readb = qpci_pc_io_readb;
- ret->bus.io_readw = qpci_pc_io_readw;
- ret->bus.io_readl = qpci_pc_io_readl;
+ ret->bus.pio_readb = qpci_pc_pio_readb;
+ ret->bus.pio_readw = qpci_pc_pio_readw;
+ ret->bus.pio_readl = qpci_pc_pio_readl;
+ ret->bus.pio_readq = qpci_pc_pio_readq;
- ret->bus.io_writeb = qpci_pc_io_writeb;
- ret->bus.io_writew = qpci_pc_io_writew;
- ret->bus.io_writel = qpci_pc_io_writel;
+ ret->bus.pio_writeb = qpci_pc_pio_writeb;
+ ret->bus.pio_writew = qpci_pc_pio_writew;
+ ret->bus.pio_writel = qpci_pc_pio_writel;
+ ret->bus.pio_writeq = qpci_pc_pio_writeq;
+
+ ret->bus.memread = qpci_pc_memread;
+ ret->bus.memwrite = qpci_pc_memwrite;
ret->bus.config_readb = qpci_pc_config_readb;
ret->bus.config_readw = qpci_pc_config_readw;
@@ -234,16 +142,9 @@ QPCIBus *qpci_init_pc(QGuestAllocator *alloc)
ret->bus.config_writew = qpci_pc_config_writew;
ret->bus.config_writel = qpci_pc_config_writel;
- ret->bus.iomap = qpci_pc_iomap;
- ret->bus.iounmap = qpci_pc_iounmap;
-
- ret->pci_hole_start = 0xE0000000;
- ret->pci_hole_size = 0x20000000;
- ret->pci_hole_alloc = 0;
-
- ret->pci_iohole_start = 0xc000;
- ret->pci_iohole_size = 0x4000;
- ret->pci_iohole_alloc = 0;
+ ret->bus.pio_alloc_ptr = 0xc000;
+ ret->bus.mmio_alloc_ptr = 0xE0000000;
+ ret->bus.mmio_limit = 0x100000000ULL;
return &ret->bus;
}
diff --git a/tests/libqos/pci-spapr.c b/tests/libqos/pci-spapr.c
index 2eaaf9159a..1e5d015bd4 100644
--- a/tests/libqos/pci-spapr.c
+++ b/tests/libqos/pci-spapr.c
@@ -34,14 +34,6 @@ typedef struct QPCIBusSPAPR {
uint64_t mmio32_cpu_base;
QPCIWindow mmio32;
-
- uint64_t pci_hole_start;
- uint64_t pci_hole_size;
- uint64_t pci_hole_alloc;
-
- uint32_t pci_iohole_start;
- uint32_t pci_iohole_size;
- uint32_t pci_iohole_alloc;
} QPCIBusSPAPR;
/*
@@ -50,78 +42,66 @@ typedef struct QPCIBusSPAPR {
* so PCI accessors need to swap data endianness
*/
-static uint8_t qpci_spapr_io_readb(QPCIBus *bus, void *addr)
+static uint8_t qpci_spapr_pio_readb(QPCIBus *bus, uint32_t addr)
+{
+ QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
+ return readb(s->pio_cpu_base + addr);
+}
+
+static void qpci_spapr_pio_writeb(QPCIBus *bus, uint32_t addr, uint8_t val)
+{
+ QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
+ writeb(s->pio_cpu_base + addr, val);
+}
+
+static uint16_t qpci_spapr_pio_readw(QPCIBus *bus, uint32_t addr)
+{
+ QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
+ return bswap16(readw(s->pio_cpu_base + addr));
+}
+
+static void qpci_spapr_pio_writew(QPCIBus *bus, uint32_t addr, uint16_t val)
{
QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
- uint64_t port = (uintptr_t)addr;
- uint8_t v;
- if (port < s->pio.size) {
- v = readb(s->pio_cpu_base + port);
- } else {
- v = readb(s->mmio32_cpu_base + port);
- }
- return v;
+ writew(s->pio_cpu_base + addr, bswap16(val));
}
-static uint16_t qpci_spapr_io_readw(QPCIBus *bus, void *addr)
+static uint32_t qpci_spapr_pio_readl(QPCIBus *bus, uint32_t addr)
{
QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
- uint64_t port = (uintptr_t)addr;
- uint16_t v;
- if (port < s->pio.size) {
- v = readw(s->pio_cpu_base + port);
- } else {
- v = readw(s->mmio32_cpu_base + port);
- }
- return bswap16(v);
+ return bswap32(readl(s->pio_cpu_base + addr));
}
-static uint32_t qpci_spapr_io_readl(QPCIBus *bus, void *addr)
+static void qpci_spapr_pio_writel(QPCIBus *bus, uint32_t addr, uint32_t val)
{
QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
- uint64_t port = (uintptr_t)addr;
- uint32_t v;
- if (port < s->pio.size) {
- v = readl(s->pio_cpu_base + port);
- } else {
- v = readl(s->mmio32_cpu_base + port);
- }
- return bswap32(v);
+ writel(s->pio_cpu_base + addr, bswap32(val));
}
-static void qpci_spapr_io_writeb(QPCIBus *bus, void *addr, uint8_t value)
+static uint64_t qpci_spapr_pio_readq(QPCIBus *bus, uint32_t addr)
{
QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
- uint64_t port = (uintptr_t)addr;
- if (port < s->pio.size) {
- writeb(s->pio_cpu_base + port, value);
- } else {
- writeb(s->mmio32_cpu_base + port, value);
- }
+ return bswap64(readq(s->pio_cpu_base + addr));
}
-static void qpci_spapr_io_writew(QPCIBus *bus, void *addr, uint16_t value)
+static void qpci_spapr_pio_writeq(QPCIBus *bus, uint32_t addr, uint64_t val)
{
QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
- uint64_t port = (uintptr_t)addr;
- value = bswap16(value);
- if (port < s->pio.size) {
- writew(s->pio_cpu_base + port, value);
- } else {
- writew(s->mmio32_cpu_base + port, value);
- }
+ writeq(s->pio_cpu_base + addr, bswap64(val));
}
-static void qpci_spapr_io_writel(QPCIBus *bus, void *addr, uint32_t value)
+static void qpci_spapr_memread(QPCIBus *bus, uint32_t addr,
+ void *buf, size_t len)
{
QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
- uint64_t port = (uintptr_t)addr;
- value = bswap32(value);
- if (port < s->pio.size) {
- writel(s->pio_cpu_base + port, value);
- } else {
- writel(s->mmio32_cpu_base + port, value);
- }
+ memread(s->mmio32_cpu_base + addr, buf, len);
+}
+
+static void qpci_spapr_memwrite(QPCIBus *bus, uint32_t addr,
+ const void *buf, size_t len)
+{
+ QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
+ memwrite(s->mmio32_cpu_base + addr, buf, len);
}
static uint8_t qpci_spapr_config_readb(QPCIBus *bus, int devfn, uint8_t offset)
@@ -169,72 +149,6 @@ static void qpci_spapr_config_writel(QPCIBus *bus, int devfn, uint8_t offset,
qrtas_ibm_write_pci_config(s->alloc, s->buid, config_addr, 4, value);
}
-static void *qpci_spapr_iomap(QPCIBus *bus, QPCIDevice *dev, int barno,
- uint64_t *sizeptr)
-{
- QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
- static const int bar_reg_map[] = {
- PCI_BASE_ADDRESS_0, PCI_BASE_ADDRESS_1, PCI_BASE_ADDRESS_2,
- PCI_BASE_ADDRESS_3, PCI_BASE_ADDRESS_4, PCI_BASE_ADDRESS_5,
- };
- int bar_reg;
- uint32_t addr;
- uint64_t size;
- uint32_t io_type;
-
- g_assert(barno >= 0 && barno <= 5);
- bar_reg = bar_reg_map[barno];
-
- qpci_config_writel(dev, bar_reg, 0xFFFFFFFF);
- addr = qpci_config_readl(dev, bar_reg);
-
- io_type = addr & PCI_BASE_ADDRESS_SPACE;
- if (io_type == PCI_BASE_ADDRESS_SPACE_IO) {
- addr &= PCI_BASE_ADDRESS_IO_MASK;
- } else {
- addr &= PCI_BASE_ADDRESS_MEM_MASK;
- }
-
- size = (1ULL << ctzl(addr));
- if (size == 0) {
- return NULL;
- }
- if (sizeptr) {
- *sizeptr = size;
- }
-
- if (io_type == PCI_BASE_ADDRESS_SPACE_IO) {
- uint16_t loc;
-
- g_assert(QEMU_ALIGN_UP(s->pci_iohole_alloc, size) + size
- <= s->pci_iohole_size);
- s->pci_iohole_alloc = QEMU_ALIGN_UP(s->pci_iohole_alloc, size);
- loc = s->pci_iohole_start + s->pci_iohole_alloc;
- s->pci_iohole_alloc += size;
-
- qpci_config_writel(dev, bar_reg, loc | PCI_BASE_ADDRESS_SPACE_IO);
-
- return (void *)(unsigned long)loc;
- } else {
- uint64_t loc;
-
- g_assert(QEMU_ALIGN_UP(s->pci_hole_alloc, size) + size
- <= s->pci_hole_size);
- s->pci_hole_alloc = QEMU_ALIGN_UP(s->pci_hole_alloc, size);
- loc = s->pci_hole_start + s->pci_hole_alloc;
- s->pci_hole_alloc += size;
-
- qpci_config_writel(dev, bar_reg, loc);
-
- return (void *)(unsigned long)loc;
- }
-}
-
-static void qpci_spapr_iounmap(QPCIBus *bus, void *data)
-{
- /* FIXME */
-}
-
#define SPAPR_PCI_BASE (1ULL << 45)
#define SPAPR_PCI_MMIO32_WIN_SIZE 0x80000000 /* 2 GiB */
@@ -248,13 +162,18 @@ QPCIBus *qpci_init_spapr(QGuestAllocator *alloc)
ret->alloc = alloc;
- ret->bus.io_readb = qpci_spapr_io_readb;
- ret->bus.io_readw = qpci_spapr_io_readw;
- ret->bus.io_readl = qpci_spapr_io_readl;
+ ret->bus.pio_readb = qpci_spapr_pio_readb;
+ ret->bus.pio_readw = qpci_spapr_pio_readw;
+ ret->bus.pio_readl = qpci_spapr_pio_readl;
+ ret->bus.pio_readq = qpci_spapr_pio_readq;
- ret->bus.io_writeb = qpci_spapr_io_writeb;
- ret->bus.io_writew = qpci_spapr_io_writew;
- ret->bus.io_writel = qpci_spapr_io_writel;
+ ret->bus.pio_writeb = qpci_spapr_pio_writeb;
+ ret->bus.pio_writew = qpci_spapr_pio_writew;
+ ret->bus.pio_writel = qpci_spapr_pio_writel;
+ ret->bus.pio_writeq = qpci_spapr_pio_writeq;
+
+ ret->bus.memread = qpci_spapr_memread;
+ ret->bus.memwrite = qpci_spapr_memwrite;
ret->bus.config_readb = qpci_spapr_config_readb;
ret->bus.config_readw = qpci_spapr_config_readw;
@@ -264,9 +183,6 @@ QPCIBus *qpci_init_spapr(QGuestAllocator *alloc)
ret->bus.config_writew = qpci_spapr_config_writew;
ret->bus.config_writel = qpci_spapr_config_writel;
- ret->bus.iomap = qpci_spapr_iomap;
- ret->bus.iounmap = qpci_spapr_iounmap;
-
/* FIXME: We assume the default location of the PHB for now.
* Ideally we'd parse the device tree deposited in the guest to
* get the window locations */
@@ -281,15 +197,9 @@ QPCIBus *qpci_init_spapr(QGuestAllocator *alloc)
ret->mmio32.pci_base = 0x80000000; /* 2 GiB */
ret->mmio32.size = SPAPR_PCI_MMIO32_WIN_SIZE;
- ret->pci_hole_start = 0xC0000000;
- ret->pci_hole_size =
- ret->mmio32.pci_base + ret->mmio32.size - ret->pci_hole_start;
- ret->pci_hole_alloc = 0;
-
- ret->pci_iohole_start = 0xc000;
- ret->pci_iohole_size =
- ret->pio.pci_base + ret->pio.size - ret->pci_iohole_start;
- ret->pci_iohole_alloc = 0;
+ ret->bus.pio_alloc_ptr = 0xc000;
+ ret->bus.mmio_alloc_ptr = ret->mmio32.pci_base;
+ ret->bus.mmio_limit = ret->mmio32.pci_base + ret->mmio32.size;
return &ret->bus;
}
diff --git a/tests/libqos/pci.c b/tests/libqos/pci.c
index c3f3382b7c..2dcdeade2a 100644
--- a/tests/libqos/pci.c
+++ b/tests/libqos/pci.c
@@ -14,6 +14,7 @@
#include "libqos/pci.h"
#include "hw/pci/pci_regs.h"
+#include "qemu/host-utils.h"
void qpci_device_foreach(QPCIBus *bus, int vendor_id, int device_id,
void (*func)(QPCIDevice *dev, int devfn, void *data),
@@ -103,7 +104,6 @@ void qpci_msix_enable(QPCIDevice *dev)
uint32_t table;
uint8_t bir_table;
uint8_t bir_pba;
- void *offset;
addr = qpci_find_capability(dev, PCI_CAP_ID_MSIX);
g_assert_cmphex(addr, !=, 0);
@@ -113,18 +113,16 @@ void qpci_msix_enable(QPCIDevice *dev)
table = qpci_config_readl(dev, addr + PCI_MSIX_TABLE);
bir_table = table & PCI_MSIX_FLAGS_BIRMASK;
- offset = qpci_iomap(dev, bir_table, NULL);
- dev->msix_table = offset + (table & ~PCI_MSIX_FLAGS_BIRMASK);
+ dev->msix_table_bar = qpci_iomap(dev, bir_table, NULL);
+ dev->msix_table_off = table & ~PCI_MSIX_FLAGS_BIRMASK;
table = qpci_config_readl(dev, addr + PCI_MSIX_PBA);
bir_pba = table & PCI_MSIX_FLAGS_BIRMASK;
if (bir_pba != bir_table) {
- offset = qpci_iomap(dev, bir_pba, NULL);
+ dev->msix_pba_bar = qpci_iomap(dev, bir_pba, NULL);
}
- dev->msix_pba = offset + (table & ~PCI_MSIX_FLAGS_BIRMASK);
+ dev->msix_pba_off = table & ~PCI_MSIX_FLAGS_BIRMASK;
- g_assert(dev->msix_table != NULL);
- g_assert(dev->msix_pba != NULL);
dev->msix_enabled = true;
}
@@ -140,22 +138,23 @@ void qpci_msix_disable(QPCIDevice *dev)
qpci_config_writew(dev, addr + PCI_MSIX_FLAGS,
val & ~PCI_MSIX_FLAGS_ENABLE);
- qpci_iounmap(dev, dev->msix_table);
- qpci_iounmap(dev, dev->msix_pba);
+ qpci_iounmap(dev, dev->msix_table_bar);
+ qpci_iounmap(dev, dev->msix_pba_bar);
dev->msix_enabled = 0;
- dev->msix_table = NULL;
- dev->msix_pba = NULL;
+ dev->msix_table_off = 0;
+ dev->msix_pba_off = 0;
}
bool qpci_msix_pending(QPCIDevice *dev, uint16_t entry)
{
uint32_t pba_entry;
uint8_t bit_n = entry % 32;
- void *addr = dev->msix_pba + (entry / 32) * PCI_MSIX_ENTRY_SIZE / 4;
+ uint64_t off = (entry / 32) * PCI_MSIX_ENTRY_SIZE / 4;
g_assert(dev->msix_enabled);
- pba_entry = qpci_io_readl(dev, addr);
- qpci_io_writel(dev, addr, pba_entry & ~(1 << bit_n));
+ pba_entry = qpci_io_readl(dev, dev->msix_pba_bar, dev->msix_pba_off + off);
+ qpci_io_writel(dev, dev->msix_pba_bar, dev->msix_pba_off + off,
+ pba_entry & ~(1 << bit_n));
return (pba_entry & (1 << bit_n)) != 0;
}
@@ -163,7 +162,7 @@ bool qpci_msix_masked(QPCIDevice *dev, uint16_t entry)
{
uint8_t addr;
uint16_t val;
- void *vector_addr = dev->msix_table + (entry * PCI_MSIX_ENTRY_SIZE);
+ uint64_t vector_off = dev->msix_table_off + entry * PCI_MSIX_ENTRY_SIZE;
g_assert(dev->msix_enabled);
addr = qpci_find_capability(dev, PCI_CAP_ID_MSIX);
@@ -173,8 +172,9 @@ bool qpci_msix_masked(QPCIDevice *dev, uint16_t entry)
if (val & PCI_MSIX_FLAGS_MASKALL) {
return true;
} else {
- return (qpci_io_readl(dev, vector_addr + PCI_MSIX_ENTRY_VECTOR_CTRL)
- & PCI_MSIX_ENTRY_CTRL_MASKBIT) != 0;
+ return (qpci_io_readl(dev, dev->msix_table_bar,
+ vector_off + PCI_MSIX_ENTRY_VECTOR_CTRL)
+ & PCI_MSIX_ENTRY_CTRL_MASKBIT) != 0;
}
}
@@ -221,46 +221,174 @@ void qpci_config_writel(QPCIDevice *dev, uint8_t offset, uint32_t value)
dev->bus->config_writel(dev->bus, dev->devfn, offset, value);
}
+uint8_t qpci_io_readb(QPCIDevice *dev, QPCIBar token, uint64_t off)
+{
+ if (token.addr < QPCI_PIO_LIMIT) {
+ return dev->bus->pio_readb(dev->bus, token.addr + off);
+ } else {
+ uint8_t val;
+ dev->bus->memread(dev->bus, token.addr + off, &val, sizeof(val));
+ return val;
+ }
+}
+
+uint16_t qpci_io_readw(QPCIDevice *dev, QPCIBar token, uint64_t off)
+{
+ if (token.addr < QPCI_PIO_LIMIT) {
+ return dev->bus->pio_readw(dev->bus, token.addr + off);
+ } else {
+ uint16_t val;
+ dev->bus->memread(dev->bus, token.addr + off, &val, sizeof(val));
+ return le16_to_cpu(val);
+ }
+}
+
+uint32_t qpci_io_readl(QPCIDevice *dev, QPCIBar token, uint64_t off)
+{
+ if (token.addr < QPCI_PIO_LIMIT) {
+ return dev->bus->pio_readl(dev->bus, token.addr + off);
+ } else {
+ uint32_t val;
+ dev->bus->memread(dev->bus, token.addr + off, &val, sizeof(val));
+ return le32_to_cpu(val);
+ }
+}
-uint8_t qpci_io_readb(QPCIDevice *dev, void *data)
+uint64_t qpci_io_readq(QPCIDevice *dev, QPCIBar token, uint64_t off)
{
- return dev->bus->io_readb(dev->bus, data);
+ if (token.addr < QPCI_PIO_LIMIT) {
+ return dev->bus->pio_readq(dev->bus, token.addr + off);
+ } else {
+ uint64_t val;
+ dev->bus->memread(dev->bus, token.addr + off, &val, sizeof(val));
+ return le64_to_cpu(val);
+ }
}
-uint16_t qpci_io_readw(QPCIDevice *dev, void *data)
+void qpci_io_writeb(QPCIDevice *dev, QPCIBar token, uint64_t off,
+ uint8_t value)
{
- return dev->bus->io_readw(dev->bus, data);
+ if (token.addr < QPCI_PIO_LIMIT) {
+ dev->bus->pio_writeb(dev->bus, token.addr + off, value);
+ } else {
+ dev->bus->memwrite(dev->bus, token.addr + off, &value, sizeof(value));
+ }
+}
+
+void qpci_io_writew(QPCIDevice *dev, QPCIBar token, uint64_t off,
+ uint16_t value)
+{
+ if (token.addr < QPCI_PIO_LIMIT) {
+ dev->bus->pio_writew(dev->bus, token.addr + off, value);
+ } else {
+ value = cpu_to_le16(value);
+ dev->bus->memwrite(dev->bus, token.addr + off, &value, sizeof(value));
+ }
}
-uint32_t qpci_io_readl(QPCIDevice *dev, void *data)
+void qpci_io_writel(QPCIDevice *dev, QPCIBar token, uint64_t off,
+ uint32_t value)
{
- return dev->bus->io_readl(dev->bus, data);
+ if (token.addr < QPCI_PIO_LIMIT) {
+ dev->bus->pio_writel(dev->bus, token.addr + off, value);
+ } else {
+ value = cpu_to_le32(value);
+ dev->bus->memwrite(dev->bus, token.addr + off, &value, sizeof(value));
+ }
}
+void qpci_io_writeq(QPCIDevice *dev, QPCIBar token, uint64_t off,
+ uint64_t value)
+{
+ if (token.addr < QPCI_PIO_LIMIT) {
+ dev->bus->pio_writeq(dev->bus, token.addr + off, value);
+ } else {
+ value = cpu_to_le64(value);
+ dev->bus->memwrite(dev->bus, token.addr + off, &value, sizeof(value));
+ }
+}
-void qpci_io_writeb(QPCIDevice *dev, void *data, uint8_t value)
+void qpci_memread(QPCIDevice *dev, QPCIBar token, uint64_t off,
+ void *buf, size_t len)
{
- dev->bus->io_writeb(dev->bus, data, value);
+ g_assert(token.addr >= QPCI_PIO_LIMIT);
+ dev->bus->memread(dev->bus, token.addr + off, buf, len);
}
-void qpci_io_writew(QPCIDevice *dev, void *data, uint16_t value)
+void qpci_memwrite(QPCIDevice *dev, QPCIBar token, uint64_t off,
+ const void *buf, size_t len)
{
- dev->bus->io_writew(dev->bus, data, value);
+ g_assert(token.addr >= QPCI_PIO_LIMIT);
+ dev->bus->memwrite(dev->bus, token.addr + off, buf, len);
}
-void qpci_io_writel(QPCIDevice *dev, void *data, uint32_t value)
+QPCIBar qpci_iomap(QPCIDevice *dev, int barno, uint64_t *sizeptr)
{
- dev->bus->io_writel(dev->bus, data, value);
+ QPCIBus *bus = dev->bus;
+ static const int bar_reg_map[] = {
+ PCI_BASE_ADDRESS_0, PCI_BASE_ADDRESS_1, PCI_BASE_ADDRESS_2,
+ PCI_BASE_ADDRESS_3, PCI_BASE_ADDRESS_4, PCI_BASE_ADDRESS_5,
+ };
+ QPCIBar bar;
+ int bar_reg;
+ uint32_t addr, size;
+ uint32_t io_type;
+ uint64_t loc;
+
+ g_assert(barno >= 0 && barno <= 5);
+ bar_reg = bar_reg_map[barno];
+
+ qpci_config_writel(dev, bar_reg, 0xFFFFFFFF);
+ addr = qpci_config_readl(dev, bar_reg);
+
+ io_type = addr & PCI_BASE_ADDRESS_SPACE;
+ if (io_type == PCI_BASE_ADDRESS_SPACE_IO) {
+ addr &= PCI_BASE_ADDRESS_IO_MASK;
+ } else {
+ addr &= PCI_BASE_ADDRESS_MEM_MASK;
+ }
+
+ g_assert(addr); /* Must have *some* size bits */
+
+ size = 1U << ctz32(addr);
+ if (sizeptr) {
+ *sizeptr = size;
+ }
+
+ if (io_type == PCI_BASE_ADDRESS_SPACE_IO) {
+ loc = QEMU_ALIGN_UP(bus->pio_alloc_ptr, size);
+
+ g_assert(loc >= bus->pio_alloc_ptr);
+ g_assert(loc + size <= QPCI_PIO_LIMIT); /* Keep PIO below 64kiB */
+
+ bus->pio_alloc_ptr = loc + size;
+
+ qpci_config_writel(dev, bar_reg, loc | PCI_BASE_ADDRESS_SPACE_IO);
+ } else {
+ loc = QEMU_ALIGN_UP(bus->mmio_alloc_ptr, size);
+
+ /* Check for space */
+ g_assert(loc >= bus->mmio_alloc_ptr);
+ g_assert(loc + size <= bus->mmio_limit);
+
+ bus->mmio_alloc_ptr = loc + size;
+
+ qpci_config_writel(dev, bar_reg, loc);
+ }
+
+ bar.addr = loc;
+ return bar;
}
-void *qpci_iomap(QPCIDevice *dev, int barno, uint64_t *sizeptr)
+void qpci_iounmap(QPCIDevice *dev, QPCIBar bar)
{
- return dev->bus->iomap(dev->bus, dev, barno, sizeptr);
+ /* FIXME */
}
-void qpci_iounmap(QPCIDevice *dev, void *data)
+QPCIBar qpci_legacy_iomap(QPCIDevice *dev, uint16_t addr)
{
- dev->bus->iounmap(dev->bus, data);
+ QPCIBar bar = { .addr = addr };
+ return bar;
}
void qpci_plug_device_test(const char *driver, const char *id,
diff --git a/tests/libqos/pci.h b/tests/libqos/pci.h
index c06add8dbf..ed480614ff 100644
--- a/tests/libqos/pci.h
+++ b/tests/libqos/pci.h
@@ -15,20 +15,27 @@
#include "libqtest.h"
+#define QPCI_PIO_LIMIT 0x10000
+
#define QPCI_DEVFN(dev, fn) (((dev) << 3) | (fn))
typedef struct QPCIDevice QPCIDevice;
typedef struct QPCIBus QPCIBus;
+typedef struct QPCIBar QPCIBar;
-struct QPCIBus
-{
- uint8_t (*io_readb)(QPCIBus *bus, void *addr);
- uint16_t (*io_readw)(QPCIBus *bus, void *addr);
- uint32_t (*io_readl)(QPCIBus *bus, void *addr);
+struct QPCIBus {
+ uint8_t (*pio_readb)(QPCIBus *bus, uint32_t addr);
+ uint16_t (*pio_readw)(QPCIBus *bus, uint32_t addr);
+ uint32_t (*pio_readl)(QPCIBus *bus, uint32_t addr);
+ uint64_t (*pio_readq)(QPCIBus *bus, uint32_t addr);
- void (*io_writeb)(QPCIBus *bus, void *addr, uint8_t value);
- void (*io_writew)(QPCIBus *bus, void *addr, uint16_t value);
- void (*io_writel)(QPCIBus *bus, void *addr, uint32_t value);
+ void (*pio_writeb)(QPCIBus *bus, uint32_t addr, uint8_t value);
+ void (*pio_writew)(QPCIBus *bus, uint32_t addr, uint16_t value);
+ void (*pio_writel)(QPCIBus *bus, uint32_t addr, uint32_t value);
+ void (*pio_writeq)(QPCIBus *bus, uint32_t addr, uint64_t value);
+
+ void (*memread)(QPCIBus *bus, uint32_t addr, void *buf, size_t len);
+ void (*memwrite)(QPCIBus *bus, uint32_t addr, const void *buf, size_t len);
uint8_t (*config_readb)(QPCIBus *bus, int devfn, uint8_t offset);
uint16_t (*config_readw)(QPCIBus *bus, int devfn, uint8_t offset);
@@ -41,8 +48,12 @@ struct QPCIBus
void (*config_writel)(QPCIBus *bus, int devfn,
uint8_t offset, uint32_t value);
- void *(*iomap)(QPCIBus *bus, QPCIDevice *dev, int barno, uint64_t *sizeptr);
- void (*iounmap)(QPCIBus *bus, void *data);
+ uint16_t pio_alloc_ptr;
+ uint64_t mmio_alloc_ptr, mmio_limit;
+};
+
+struct QPCIBar {
+ uint64_t addr;
};
struct QPCIDevice
@@ -50,8 +61,8 @@ struct QPCIDevice
QPCIBus *bus;
int devfn;
bool msix_enabled;
- void *msix_table;
- void *msix_pba;
+ QPCIBar msix_table_bar, msix_pba_bar;
+ uint64_t msix_table_off, msix_pba_off;
};
void qpci_device_foreach(QPCIBus *bus, int vendor_id, int device_id,
@@ -75,16 +86,27 @@ void qpci_config_writeb(QPCIDevice *dev, uint8_t offset, uint8_t value);
void qpci_config_writew(QPCIDevice *dev, uint8_t offset, uint16_t value);
void qpci_config_writel(QPCIDevice *dev, uint8_t offset, uint32_t value);
-uint8_t qpci_io_readb(QPCIDevice *dev, void *data);
-uint16_t qpci_io_readw(QPCIDevice *dev, void *data);
-uint32_t qpci_io_readl(QPCIDevice *dev, void *data);
-
-void qpci_io_writeb(QPCIDevice *dev, void *data, uint8_t value);
-void qpci_io_writew(QPCIDevice *dev, void *data, uint16_t value);
-void qpci_io_writel(QPCIDevice *dev, void *data, uint32_t value);
-
-void *qpci_iomap(QPCIDevice *dev, int barno, uint64_t *sizeptr);
-void qpci_iounmap(QPCIDevice *dev, void *data);
+uint8_t qpci_io_readb(QPCIDevice *dev, QPCIBar token, uint64_t off);
+uint16_t qpci_io_readw(QPCIDevice *dev, QPCIBar token, uint64_t off);
+uint32_t qpci_io_readl(QPCIDevice *dev, QPCIBar token, uint64_t off);
+uint64_t qpci_io_readq(QPCIDevice *dev, QPCIBar token, uint64_t off);
+
+void qpci_io_writeb(QPCIDevice *dev, QPCIBar token, uint64_t off,
+ uint8_t value);
+void qpci_io_writew(QPCIDevice *dev, QPCIBar token, uint64_t off,
+ uint16_t value);
+void qpci_io_writel(QPCIDevice *dev, QPCIBar token, uint64_t off,
+ uint32_t value);
+void qpci_io_writeq(QPCIDevice *dev, QPCIBar token, uint64_t off,
+ uint64_t value);
+
+void qpci_memread(QPCIDevice *bus, QPCIBar token, uint64_t off,
+ void *buf, size_t len);
+void qpci_memwrite(QPCIDevice *bus, QPCIBar token, uint64_t off,
+ const void *buf, size_t len);
+QPCIBar qpci_iomap(QPCIDevice *dev, int barno, uint64_t *sizeptr);
+void qpci_iounmap(QPCIDevice *dev, QPCIBar addr);
+QPCIBar qpci_legacy_iomap(QPCIDevice *dev, uint16_t addr);
void qpci_plug_device_test(const char *driver, const char *id,
uint8_t slot, const char *opts);
diff --git a/tests/libqos/usb.c b/tests/libqos/usb.c
index f794d92da5..72d7a961fe 100644
--- a/tests/libqos/usb.c
+++ b/tests/libqos/usb.c
@@ -21,14 +21,12 @@ void qusb_pci_init_one(QPCIBus *pcibus, struct qhc *hc, uint32_t devfn, int bar)
hc->dev = qpci_device_find(pcibus, devfn);
g_assert(hc->dev != NULL);
qpci_device_enable(hc->dev);
- hc->base = qpci_iomap(hc->dev, bar, NULL);
- g_assert(hc->base != NULL);
+ hc->bar = qpci_iomap(hc->dev, bar, NULL);
}
void uhci_port_test(struct qhc *hc, int port, uint16_t expect)
{
- void *addr = hc->base + 0x10 + 2 * port;
- uint16_t value = qpci_io_readw(hc->dev, addr);
+ uint16_t value = qpci_io_readw(hc->dev, hc->bar, 0x10 + 2 * port);
uint16_t mask = ~(UHCI_PORT_WRITE_CLEAR | UHCI_PORT_RSVD1);
g_assert((value & mask) == (expect & mask));
diff --git a/tests/libqos/usb.h b/tests/libqos/usb.h
index 8fe56872b7..423dcfd82f 100644
--- a/tests/libqos/usb.h
+++ b/tests/libqos/usb.h
@@ -5,7 +5,7 @@
struct qhc {
QPCIDevice *dev;
- void *base;
+ QPCIBar bar;
};
void qusb_pci_init_one(QPCIBus *pcibus, struct qhc *hc,
diff --git a/tests/libqos/virtio-mmio.c b/tests/libqos/virtio-mmio.c
index 0cab38f296..7aa8383338 100644
--- a/tests/libqos/virtio-mmio.c
+++ b/tests/libqos/virtio-mmio.c
@@ -15,28 +15,28 @@
#include "libqos/malloc-generic.h"
#include "standard-headers/linux/virtio_ring.h"
-static uint8_t qvirtio_mmio_config_readb(QVirtioDevice *d, uint64_t addr)
+static uint8_t qvirtio_mmio_config_readb(QVirtioDevice *d, uint64_t off)
{
QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d;
- return readb(dev->addr + addr);
+ return readb(dev->addr + QVIRTIO_MMIO_DEVICE_SPECIFIC + off);
}
-static uint16_t qvirtio_mmio_config_readw(QVirtioDevice *d, uint64_t addr)
+static uint16_t qvirtio_mmio_config_readw(QVirtioDevice *d, uint64_t off)
{
QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d;
- return readw(dev->addr + addr);
+ return readw(dev->addr + QVIRTIO_MMIO_DEVICE_SPECIFIC + off);
}
-static uint32_t qvirtio_mmio_config_readl(QVirtioDevice *d, uint64_t addr)
+static uint32_t qvirtio_mmio_config_readl(QVirtioDevice *d, uint64_t off)
{
QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d;
- return readl(dev->addr + addr);
+ return readl(dev->addr + QVIRTIO_MMIO_DEVICE_SPECIFIC + off);
}
-static uint64_t qvirtio_mmio_config_readq(QVirtioDevice *d, uint64_t addr)
+static uint64_t qvirtio_mmio_config_readq(QVirtioDevice *d, uint64_t off)
{
QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d;
- return readq(dev->addr + addr);
+ return readq(dev->addr + QVIRTIO_MMIO_DEVICE_SPECIFIC + off);
}
static uint32_t qvirtio_mmio_get_features(QVirtioDevice *d)
@@ -199,6 +199,7 @@ QVirtioMMIODevice *qvirtio_mmio_init_device(uint64_t addr, uint32_t page_size)
dev->addr = addr;
dev->page_size = page_size;
dev->vdev.device_type = readl(addr + QVIRTIO_MMIO_DEVICE_ID);
+ dev->vdev.bus = &qvirtio_mmio;
writel(addr + QVIRTIO_MMIO_GUEST_PAGE_SIZE, page_size);
diff --git a/tests/libqos/virtio-pci.c b/tests/libqos/virtio-pci.c
index 6e005c1835..d4bf841f23 100644
--- a/tests/libqos/virtio-pci.c
+++ b/tests/libqos/virtio-pci.c
@@ -62,73 +62,87 @@ static void qvirtio_pci_assign_device(QVirtioDevice *d, void *data)
*vpcidev = (QVirtioPCIDevice *)d;
}
-static uint8_t qvirtio_pci_config_readb(QVirtioDevice *d, uint64_t addr)
+#define CONFIG_BASE(dev) (VIRTIO_PCI_CONFIG_OFF((dev)->pdev->msix_enabled))
+
+static uint8_t qvirtio_pci_config_readb(QVirtioDevice *d, uint64_t off)
{
QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
- return qpci_io_readb(dev->pdev, (void *)(uintptr_t)addr);
+ return qpci_io_readb(dev->pdev, dev->bar, CONFIG_BASE(dev) + off);
}
-static uint16_t qvirtio_pci_config_readw(QVirtioDevice *d, uint64_t addr)
+/* PCI is always read in little-endian order
+ * but virtio ( < 1.0) is in guest order
+ * so with a big-endian guest the order has been reversed,
+ * reverse it again
+ * virtio-1.0 is always little-endian, like PCI, but this
+ * case will be managed inside qvirtio_is_big_endian()
+ */
+
+static uint16_t qvirtio_pci_config_readw(QVirtioDevice *d, uint64_t off)
{
QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
- return qpci_io_readw(dev->pdev, (void *)(uintptr_t)addr);
+ uint16_t value;
+
+ value = qpci_io_readw(dev->pdev, dev->bar, CONFIG_BASE(dev) + off);
+ if (qvirtio_is_big_endian(d)) {
+ value = bswap16(value);
+ }
+ return value;
}
-static uint32_t qvirtio_pci_config_readl(QVirtioDevice *d, uint64_t addr)
+static uint32_t qvirtio_pci_config_readl(QVirtioDevice *d, uint64_t off)
{
QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
- return qpci_io_readl(dev->pdev, (void *)(uintptr_t)addr);
+ uint32_t value;
+
+ value = qpci_io_readl(dev->pdev, dev->bar, CONFIG_BASE(dev) + off);
+ if (qvirtio_is_big_endian(d)) {
+ value = bswap32(value);
+ }
+ return value;
}
-static uint64_t qvirtio_pci_config_readq(QVirtioDevice *d, uint64_t addr)
+static uint64_t qvirtio_pci_config_readq(QVirtioDevice *d, uint64_t off)
{
QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
- int i;
- uint64_t u64 = 0;
+ uint64_t val;
- if (target_big_endian()) {
- for (i = 0; i < 8; ++i) {
- u64 |= (uint64_t)qpci_io_readb(dev->pdev,
- (void *)(uintptr_t)addr + i) << (7 - i) * 8;
- }
- } else {
- for (i = 0; i < 8; ++i) {
- u64 |= (uint64_t)qpci_io_readb(dev->pdev,
- (void *)(uintptr_t)addr + i) << i * 8;
- }
+ val = qpci_io_readq(dev->pdev, dev->bar, CONFIG_BASE(dev) + off);
+ if (qvirtio_is_big_endian(d)) {
+ val = bswap64(val);
}
- return u64;
+ return val;
}
static uint32_t qvirtio_pci_get_features(QVirtioDevice *d)
{
QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
- return qpci_io_readl(dev->pdev, dev->addr + VIRTIO_PCI_HOST_FEATURES);
+ return qpci_io_readl(dev->pdev, dev->bar, VIRTIO_PCI_HOST_FEATURES);
}
static void qvirtio_pci_set_features(QVirtioDevice *d, uint32_t features)
{
QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
- qpci_io_writel(dev->pdev, dev->addr + VIRTIO_PCI_GUEST_FEATURES, features);
+ qpci_io_writel(dev->pdev, dev->bar, VIRTIO_PCI_GUEST_FEATURES, features);
}
static uint32_t qvirtio_pci_get_guest_features(QVirtioDevice *d)
{
QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
- return qpci_io_readl(dev->pdev, dev->addr + VIRTIO_PCI_GUEST_FEATURES);
+ return qpci_io_readl(dev->pdev, dev->bar, VIRTIO_PCI_GUEST_FEATURES);
}
static uint8_t qvirtio_pci_get_status(QVirtioDevice *d)
{
QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
- return qpci_io_readb(dev->pdev, dev->addr + VIRTIO_PCI_STATUS);
+ return qpci_io_readb(dev->pdev, dev->bar, VIRTIO_PCI_STATUS);
}
static void qvirtio_pci_set_status(QVirtioDevice *d, uint8_t status)
{
QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
- qpci_io_writeb(dev->pdev, dev->addr + VIRTIO_PCI_STATUS, status);
+ qpci_io_writeb(dev->pdev, dev->bar, VIRTIO_PCI_STATUS, status);
}
static bool qvirtio_pci_get_queue_isr_status(QVirtioDevice *d, QVirtQueue *vq)
@@ -152,7 +166,7 @@ static bool qvirtio_pci_get_queue_isr_status(QVirtioDevice *d, QVirtQueue *vq)
}
}
} else {
- return qpci_io_readb(dev->pdev, dev->addr + VIRTIO_PCI_ISR) & 1;
+ return qpci_io_readb(dev->pdev, dev->bar, VIRTIO_PCI_ISR) & 1;
}
}
@@ -176,26 +190,26 @@ static bool qvirtio_pci_get_config_isr_status(QVirtioDevice *d)
}
}
} else {
- return qpci_io_readb(dev->pdev, dev->addr + VIRTIO_PCI_ISR) & 2;
+ return qpci_io_readb(dev->pdev, dev->bar, VIRTIO_PCI_ISR) & 2;
}
}
static void qvirtio_pci_queue_select(QVirtioDevice *d, uint16_t index)
{
QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
- qpci_io_writeb(dev->pdev, dev->addr + VIRTIO_PCI_QUEUE_SEL, index);
+ qpci_io_writeb(dev->pdev, dev->bar, VIRTIO_PCI_QUEUE_SEL, index);
}
static uint16_t qvirtio_pci_get_queue_size(QVirtioDevice *d)
{
QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
- return qpci_io_readw(dev->pdev, dev->addr + VIRTIO_PCI_QUEUE_NUM);
+ return qpci_io_readw(dev->pdev, dev->bar, VIRTIO_PCI_QUEUE_NUM);
}
static void qvirtio_pci_set_queue_address(QVirtioDevice *d, uint32_t pfn)
{
QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
- qpci_io_writel(dev->pdev, dev->addr + VIRTIO_PCI_QUEUE_PFN, pfn);
+ qpci_io_writel(dev->pdev, dev->bar, VIRTIO_PCI_QUEUE_PFN, pfn);
}
static QVirtQueue *qvirtio_pci_virtqueue_setup(QVirtioDevice *d,
@@ -247,7 +261,7 @@ static void qvirtio_pci_virtqueue_cleanup(QVirtQueue *vq,
static void qvirtio_pci_virtqueue_kick(QVirtioDevice *d, QVirtQueue *vq)
{
QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
- qpci_io_writew(dev->pdev, dev->addr + VIRTIO_PCI_QUEUE_NOTIFY, vq->index);
+ qpci_io_writew(dev->pdev, dev->bar, VIRTIO_PCI_QUEUE_NOTIFY, vq->index);
}
const QVirtioBus qvirtio_pci = {
@@ -286,20 +300,20 @@ QVirtioPCIDevice *qvirtio_pci_device_find(QPCIBus *bus, uint16_t device_type)
QVirtioPCIDevice *dev = NULL;
qvirtio_pci_foreach(bus, device_type, qvirtio_pci_assign_device, &dev);
+ dev->vdev.bus = &qvirtio_pci;
+
return dev;
}
void qvirtio_pci_device_enable(QVirtioPCIDevice *d)
{
qpci_device_enable(d->pdev);
- d->addr = qpci_iomap(d->pdev, 0, NULL);
- g_assert(d->addr != NULL);
+ d->bar = qpci_iomap(d->pdev, 0, NULL);
}
void qvirtio_pci_device_disable(QVirtioPCIDevice *d)
{
- qpci_iounmap(d->pdev, d->addr);
- d->addr = NULL;
+ qpci_iounmap(d->pdev, d->bar);
}
void qvirtqueue_pci_msix_setup(QVirtioPCIDevice *d, QVirtQueuePCI *vqpci,
@@ -307,29 +321,33 @@ void qvirtqueue_pci_msix_setup(QVirtioPCIDevice *d, QVirtQueuePCI *vqpci,
{
uint16_t vector;
uint32_t control;
- void *addr;
+ uint64_t off;
g_assert(d->pdev->msix_enabled);
- addr = d->pdev->msix_table + (entry * 16);
+ off = d->pdev->msix_table_off + (entry * 16);
g_assert_cmpint(entry, >=, 0);
g_assert_cmpint(entry, <, qpci_msix_table_size(d->pdev));
vqpci->msix_entry = entry;
vqpci->msix_addr = guest_alloc(alloc, 4);
- qpci_io_writel(d->pdev, addr + PCI_MSIX_ENTRY_LOWER_ADDR,
- vqpci->msix_addr & ~0UL);
- qpci_io_writel(d->pdev, addr + PCI_MSIX_ENTRY_UPPER_ADDR,
- (vqpci->msix_addr >> 32) & ~0UL);
- qpci_io_writel(d->pdev, addr + PCI_MSIX_ENTRY_DATA, vqpci->msix_data);
-
- control = qpci_io_readl(d->pdev, addr + PCI_MSIX_ENTRY_VECTOR_CTRL);
- qpci_io_writel(d->pdev, addr + PCI_MSIX_ENTRY_VECTOR_CTRL,
- control & ~PCI_MSIX_ENTRY_CTRL_MASKBIT);
+ qpci_io_writel(d->pdev, d->pdev->msix_table_bar,
+ off + PCI_MSIX_ENTRY_LOWER_ADDR, vqpci->msix_addr & ~0UL);
+ qpci_io_writel(d->pdev, d->pdev->msix_table_bar,
+ off + PCI_MSIX_ENTRY_UPPER_ADDR,
+ (vqpci->msix_addr >> 32) & ~0UL);
+ qpci_io_writel(d->pdev, d->pdev->msix_table_bar,
+ off + PCI_MSIX_ENTRY_DATA, vqpci->msix_data);
+
+ control = qpci_io_readl(d->pdev, d->pdev->msix_table_bar,
+ off + PCI_MSIX_ENTRY_VECTOR_CTRL);
+ qpci_io_writel(d->pdev, d->pdev->msix_table_bar,
+ off + PCI_MSIX_ENTRY_VECTOR_CTRL,
+ control & ~PCI_MSIX_ENTRY_CTRL_MASKBIT);
qvirtio_pci_queue_select(&d->vdev, vqpci->vq.index);
- qpci_io_writew(d->pdev, d->addr + VIRTIO_MSI_QUEUE_VECTOR, entry);
- vector = qpci_io_readw(d->pdev, d->addr + VIRTIO_MSI_QUEUE_VECTOR);
+ qpci_io_writew(d->pdev, d->bar, VIRTIO_MSI_QUEUE_VECTOR, entry);
+ vector = qpci_io_readw(d->pdev, d->bar, VIRTIO_MSI_QUEUE_VECTOR);
g_assert_cmphex(vector, !=, VIRTIO_MSI_NO_VECTOR);
}
@@ -338,10 +356,10 @@ void qvirtio_pci_set_msix_configuration_vector(QVirtioPCIDevice *d,
{
uint16_t vector;
uint32_t control;
- void *addr;
+ uint64_t off;
g_assert(d->pdev->msix_enabled);
- addr = d->pdev->msix_table + (entry * 16);
+ off = d->pdev->msix_table_off + (entry * 16);
g_assert_cmpint(entry, >=, 0);
g_assert_cmpint(entry, <, qpci_msix_table_size(d->pdev));
@@ -350,17 +368,21 @@ void qvirtio_pci_set_msix_configuration_vector(QVirtioPCIDevice *d,
d->config_msix_data = 0x12345678;
d->config_msix_addr = guest_alloc(alloc, 4);
- qpci_io_writel(d->pdev, addr + PCI_MSIX_ENTRY_LOWER_ADDR,
- d->config_msix_addr & ~0UL);
- qpci_io_writel(d->pdev, addr + PCI_MSIX_ENTRY_UPPER_ADDR,
- (d->config_msix_addr >> 32) & ~0UL);
- qpci_io_writel(d->pdev, addr + PCI_MSIX_ENTRY_DATA, d->config_msix_data);
-
- control = qpci_io_readl(d->pdev, addr + PCI_MSIX_ENTRY_VECTOR_CTRL);
- qpci_io_writel(d->pdev, addr + PCI_MSIX_ENTRY_VECTOR_CTRL,
- control & ~PCI_MSIX_ENTRY_CTRL_MASKBIT);
-
- qpci_io_writew(d->pdev, d->addr + VIRTIO_MSI_CONFIG_VECTOR, entry);
- vector = qpci_io_readw(d->pdev, d->addr + VIRTIO_MSI_CONFIG_VECTOR);
+ qpci_io_writel(d->pdev, d->pdev->msix_table_bar,
+ off + PCI_MSIX_ENTRY_LOWER_ADDR, d->config_msix_addr & ~0UL);
+ qpci_io_writel(d->pdev, d->pdev->msix_table_bar,
+ off + PCI_MSIX_ENTRY_UPPER_ADDR,
+ (d->config_msix_addr >> 32) & ~0UL);
+ qpci_io_writel(d->pdev, d->pdev->msix_table_bar,
+ off + PCI_MSIX_ENTRY_DATA, d->config_msix_data);
+
+ control = qpci_io_readl(d->pdev, d->pdev->msix_table_bar,
+ off + PCI_MSIX_ENTRY_VECTOR_CTRL);
+ qpci_io_writel(d->pdev, d->pdev->msix_table_bar,
+ off + PCI_MSIX_ENTRY_VECTOR_CTRL,
+ control & ~PCI_MSIX_ENTRY_CTRL_MASKBIT);
+
+ qpci_io_writew(d->pdev, d->bar, VIRTIO_MSI_CONFIG_VECTOR, entry);
+ vector = qpci_io_readw(d->pdev, d->bar, VIRTIO_MSI_CONFIG_VECTOR);
g_assert_cmphex(vector, !=, VIRTIO_MSI_NO_VECTOR);
}
diff --git a/tests/libqos/virtio-pci.h b/tests/libqos/virtio-pci.h
index efcac2d3de..38c54c63ea 100644
--- a/tests/libqos/virtio-pci.h
+++ b/tests/libqos/virtio-pci.h
@@ -16,7 +16,7 @@
typedef struct QVirtioPCIDevice {
QVirtioDevice vdev;
QPCIDevice *pdev;
- void *addr;
+ QPCIBar bar;
uint16_t config_msix_entry;
uint64_t config_msix_addr;
uint32_t config_msix_data;
diff --git a/tests/libqos/virtio.c b/tests/libqos/virtio.c
index 105bccecaa..ec30cb99b2 100644
--- a/tests/libqos/virtio.c
+++ b/tests/libqos/virtio.c
@@ -13,45 +13,40 @@
#include "standard-headers/linux/virtio_config.h"
#include "standard-headers/linux/virtio_ring.h"
-uint8_t qvirtio_config_readb(const QVirtioBus *bus, QVirtioDevice *d,
- uint64_t addr)
+uint8_t qvirtio_config_readb(QVirtioDevice *d, uint64_t addr)
{
- return bus->config_readb(d, addr);
+ return d->bus->config_readb(d, addr);
}
-uint16_t qvirtio_config_readw(const QVirtioBus *bus, QVirtioDevice *d,
- uint64_t addr)
+uint16_t qvirtio_config_readw(QVirtioDevice *d, uint64_t addr)
{
- return bus->config_readw(d, addr);
+ return d->bus->config_readw(d, addr);
}
-uint32_t qvirtio_config_readl(const QVirtioBus *bus, QVirtioDevice *d,
- uint64_t addr)
+uint32_t qvirtio_config_readl(QVirtioDevice *d, uint64_t addr)
{
- return bus->config_readl(d, addr);
+ return d->bus->config_readl(d, addr);
}
-uint64_t qvirtio_config_readq(const QVirtioBus *bus, QVirtioDevice *d,
- uint64_t addr)
+uint64_t qvirtio_config_readq(QVirtioDevice *d, uint64_t addr)
{
- return bus->config_readq(d, addr);
+ return d->bus->config_readq(d, addr);
}
-uint32_t qvirtio_get_features(const QVirtioBus *bus, QVirtioDevice *d)
+uint32_t qvirtio_get_features(QVirtioDevice *d)
{
- return bus->get_features(d);
+ return d->bus->get_features(d);
}
-void qvirtio_set_features(const QVirtioBus *bus, QVirtioDevice *d,
- uint32_t features)
+void qvirtio_set_features(QVirtioDevice *d, uint32_t features)
{
- bus->set_features(d, features);
+ d->bus->set_features(d, features);
}
-QVirtQueue *qvirtqueue_setup(const QVirtioBus *bus, QVirtioDevice *d,
- QGuestAllocator *alloc, uint16_t index)
+QVirtQueue *qvirtqueue_setup(QVirtioDevice *d,
+ QGuestAllocator *alloc, uint16_t index)
{
- return bus->virtqueue_setup(d, alloc, index);
+ return d->bus->virtqueue_setup(d, alloc, index);
}
void qvirtqueue_cleanup(const QVirtioBus *bus, QVirtQueue *vq,
@@ -60,40 +55,40 @@ void qvirtqueue_cleanup(const QVirtioBus *bus, QVirtQueue *vq,
return bus->virtqueue_cleanup(vq, alloc);
}
-void qvirtio_reset(const QVirtioBus *bus, QVirtioDevice *d)
+void qvirtio_reset(QVirtioDevice *d)
{
- bus->set_status(d, 0);
- g_assert_cmphex(bus->get_status(d), ==, 0);
+ d->bus->set_status(d, 0);
+ g_assert_cmphex(d->bus->get_status(d), ==, 0);
}
-void qvirtio_set_acknowledge(const QVirtioBus *bus, QVirtioDevice *d)
+void qvirtio_set_acknowledge(QVirtioDevice *d)
{
- bus->set_status(d, bus->get_status(d) | VIRTIO_CONFIG_S_ACKNOWLEDGE);
- g_assert_cmphex(bus->get_status(d), ==, VIRTIO_CONFIG_S_ACKNOWLEDGE);
+ d->bus->set_status(d, d->bus->get_status(d) | VIRTIO_CONFIG_S_ACKNOWLEDGE);
+ g_assert_cmphex(d->bus->get_status(d), ==, VIRTIO_CONFIG_S_ACKNOWLEDGE);
}
-void qvirtio_set_driver(const QVirtioBus *bus, QVirtioDevice *d)
+void qvirtio_set_driver(QVirtioDevice *d)
{
- bus->set_status(d, bus->get_status(d) | VIRTIO_CONFIG_S_DRIVER);
- g_assert_cmphex(bus->get_status(d), ==,
+ d->bus->set_status(d, d->bus->get_status(d) | VIRTIO_CONFIG_S_DRIVER);
+ g_assert_cmphex(d->bus->get_status(d), ==,
VIRTIO_CONFIG_S_DRIVER | VIRTIO_CONFIG_S_ACKNOWLEDGE);
}
-void qvirtio_set_driver_ok(const QVirtioBus *bus, QVirtioDevice *d)
+void qvirtio_set_driver_ok(QVirtioDevice *d)
{
- bus->set_status(d, bus->get_status(d) | VIRTIO_CONFIG_S_DRIVER_OK);
- g_assert_cmphex(bus->get_status(d), ==, VIRTIO_CONFIG_S_DRIVER_OK |
+ d->bus->set_status(d, d->bus->get_status(d) | VIRTIO_CONFIG_S_DRIVER_OK);
+ g_assert_cmphex(d->bus->get_status(d), ==, VIRTIO_CONFIG_S_DRIVER_OK |
VIRTIO_CONFIG_S_DRIVER | VIRTIO_CONFIG_S_ACKNOWLEDGE);
}
-void qvirtio_wait_queue_isr(const QVirtioBus *bus, QVirtioDevice *d,
+void qvirtio_wait_queue_isr(QVirtioDevice *d,
QVirtQueue *vq, gint64 timeout_us)
{
gint64 start_time = g_get_monotonic_time();
for (;;) {
clock_step(100);
- if (bus->get_queue_isr_status(d, vq)) {
+ if (d->bus->get_queue_isr_status(d, vq)) {
return;
}
g_assert(g_get_monotonic_time() - start_time <= timeout_us);
@@ -105,8 +100,7 @@ void qvirtio_wait_queue_isr(const QVirtioBus *bus, QVirtioDevice *d,
* The virtqueue interrupt must not be raised, making this useful for testing
* event_index functionality.
*/
-uint8_t qvirtio_wait_status_byte_no_isr(const QVirtioBus *bus,
- QVirtioDevice *d,
+uint8_t qvirtio_wait_status_byte_no_isr(QVirtioDevice *d,
QVirtQueue *vq,
uint64_t addr,
gint64 timeout_us)
@@ -116,20 +110,19 @@ uint8_t qvirtio_wait_status_byte_no_isr(const QVirtioBus *bus,
while ((val = readb(addr)) == 0xff) {
clock_step(100);
- g_assert(!bus->get_queue_isr_status(d, vq));
+ g_assert(!d->bus->get_queue_isr_status(d, vq));
g_assert(g_get_monotonic_time() - start_time <= timeout_us);
}
return val;
}
-void qvirtio_wait_config_isr(const QVirtioBus *bus, QVirtioDevice *d,
- gint64 timeout_us)
+void qvirtio_wait_config_isr(QVirtioDevice *d, gint64 timeout_us)
{
gint64 start_time = g_get_monotonic_time();
for (;;) {
clock_step(100);
- if (bus->get_config_isr_status(d)) {
+ if (d->bus->get_config_isr_status(d)) {
return;
}
g_assert(g_get_monotonic_time() - start_time <= timeout_us);
@@ -253,8 +246,7 @@ uint32_t qvirtqueue_add_indirect(QVirtQueue *vq, QVRingIndirectDesc *indirect)
return vq->free_head++; /* Return and increase, in this order */
}
-void qvirtqueue_kick(const QVirtioBus *bus, QVirtioDevice *d, QVirtQueue *vq,
- uint32_t free_head)
+void qvirtqueue_kick(QVirtioDevice *d, QVirtQueue *vq, uint32_t free_head)
{
/* vq->avail->idx */
uint16_t idx = readw(vq->avail + 2);
@@ -276,7 +268,7 @@ void qvirtqueue_kick(const QVirtioBus *bus, QVirtioDevice *d, QVirtQueue *vq,
/* < 1 because we add elements to avail queue one by one */
if ((flags & VRING_USED_F_NO_NOTIFY) == 0 &&
(!vq->event || (uint16_t)(idx-avail_event) < 1)) {
- bus->virtqueue_kick(d, vq);
+ d->bus->virtqueue_kick(d, vq);
}
}
diff --git a/tests/libqos/virtio.h b/tests/libqos/virtio.h
index 0250842bf2..3397a080e9 100644
--- a/tests/libqos/virtio.h
+++ b/tests/libqos/virtio.h
@@ -15,7 +15,10 @@
#define QVIRTIO_F_BAD_FEATURE 0x40000000
+typedef struct QVirtioBus QVirtioBus;
+
typedef struct QVirtioDevice {
+ const QVirtioBus *bus;
/* Device type */
uint16_t device_type;
} QVirtioDevice;
@@ -39,7 +42,7 @@ typedef struct QVRingIndirectDesc {
uint16_t elem;
} QVRingIndirectDesc;
-typedef struct QVirtioBus {
+struct QVirtioBus {
uint8_t (*config_readb)(QVirtioDevice *d, uint64_t addr);
uint16_t (*config_readw)(QVirtioDevice *d, uint64_t addr);
uint32_t (*config_readl)(QVirtioDevice *d, uint64_t addr);
@@ -84,7 +87,13 @@ typedef struct QVirtioBus {
/* Notify changes in virtqueue */
void (*virtqueue_kick)(QVirtioDevice *d, QVirtQueue *vq);
-} QVirtioBus;
+};
+
+static inline bool qvirtio_is_big_endian(QVirtioDevice *d)
+{
+ /* FIXME: virtio 1.0 is always little-endian */
+ return qtest_big_endian(global_qtest);
+}
static inline uint32_t qvring_size(uint32_t num, uint32_t align)
{
@@ -93,34 +102,27 @@ static inline uint32_t qvring_size(uint32_t num, uint32_t align)
+ sizeof(uint16_t) * 3 + sizeof(struct vring_used_elem) * num;
}
-uint8_t qvirtio_config_readb(const QVirtioBus *bus, QVirtioDevice *d,
- uint64_t addr);
-uint16_t qvirtio_config_readw(const QVirtioBus *bus, QVirtioDevice *d,
- uint64_t addr);
-uint32_t qvirtio_config_readl(const QVirtioBus *bus, QVirtioDevice *d,
- uint64_t addr);
-uint64_t qvirtio_config_readq(const QVirtioBus *bus, QVirtioDevice *d,
- uint64_t addr);
-uint32_t qvirtio_get_features(const QVirtioBus *bus, QVirtioDevice *d);
-void qvirtio_set_features(const QVirtioBus *bus, QVirtioDevice *d,
- uint32_t features);
-
-void qvirtio_reset(const QVirtioBus *bus, QVirtioDevice *d);
-void qvirtio_set_acknowledge(const QVirtioBus *bus, QVirtioDevice *d);
-void qvirtio_set_driver(const QVirtioBus *bus, QVirtioDevice *d);
-void qvirtio_set_driver_ok(const QVirtioBus *bus, QVirtioDevice *d);
-
-void qvirtio_wait_queue_isr(const QVirtioBus *bus, QVirtioDevice *d,
+uint8_t qvirtio_config_readb(QVirtioDevice *d, uint64_t addr);
+uint16_t qvirtio_config_readw(QVirtioDevice *d, uint64_t addr);
+uint32_t qvirtio_config_readl(QVirtioDevice *d, uint64_t addr);
+uint64_t qvirtio_config_readq(QVirtioDevice *d, uint64_t addr);
+uint32_t qvirtio_get_features(QVirtioDevice *d);
+void qvirtio_set_features(QVirtioDevice *d, uint32_t features);
+
+void qvirtio_reset(QVirtioDevice *d);
+void qvirtio_set_acknowledge(QVirtioDevice *d);
+void qvirtio_set_driver(QVirtioDevice *d);
+void qvirtio_set_driver_ok(QVirtioDevice *d);
+
+void qvirtio_wait_queue_isr(QVirtioDevice *d,
QVirtQueue *vq, gint64 timeout_us);
-uint8_t qvirtio_wait_status_byte_no_isr(const QVirtioBus *bus,
- QVirtioDevice *d,
+uint8_t qvirtio_wait_status_byte_no_isr(QVirtioDevice *d,
QVirtQueue *vq,
uint64_t addr,
gint64 timeout_us);
-void qvirtio_wait_config_isr(const QVirtioBus *bus, QVirtioDevice *d,
- gint64 timeout_us);
-QVirtQueue *qvirtqueue_setup(const QVirtioBus *bus, QVirtioDevice *d,
- QGuestAllocator *alloc, uint16_t index);
+void qvirtio_wait_config_isr(QVirtioDevice *d, gint64 timeout_us);
+QVirtQueue *qvirtqueue_setup(QVirtioDevice *d,
+ QGuestAllocator *alloc, uint16_t index);
void qvirtqueue_cleanup(const QVirtioBus *bus, QVirtQueue *vq,
QGuestAllocator *alloc);
@@ -132,8 +134,7 @@ void qvring_indirect_desc_add(QVRingIndirectDesc *indirect, uint64_t data,
uint32_t qvirtqueue_add(QVirtQueue *vq, uint64_t data, uint32_t len, bool write,
bool next);
uint32_t qvirtqueue_add_indirect(QVirtQueue *vq, QVRingIndirectDesc *indirect);
-void qvirtqueue_kick(const QVirtioBus *bus, QVirtioDevice *d, QVirtQueue *vq,
- uint32_t free_head);
+void qvirtqueue_kick(QVirtioDevice *d, QVirtQueue *vq, uint32_t free_head);
void qvirtqueue_set_used_event(QVirtQueue *vq, uint16_t idx);
#endif
diff --git a/tests/libqtest.h b/tests/libqtest.h
index 4be1f77877..0224f06d65 100644
--- a/tests/libqtest.h
+++ b/tests/libqtest.h
@@ -881,16 +881,6 @@ static inline int64_t clock_set(int64_t val)
return qtest_clock_set(global_qtest, val);
}
-/**
- * target_big_endian:
- *
- * Returns: True if the architecture under test has a big endian configuration.
- */
-static inline bool target_big_endian(void)
-{
- return qtest_big_endian(global_qtest);
-}
-
QDict *qmp_fd_receive(int fd);
void qmp_fd_sendv(int fd, const char *fmt, va_list ap);
void qmp_fd_send(int fd, const char *fmt, ...);
diff --git a/tests/postcopy-test.c b/tests/postcopy-test.c
index 41ed1a976f..d6613c5fa4 100644
--- a/tests/postcopy-test.c
+++ b/tests/postcopy-test.c
@@ -18,7 +18,7 @@
#include "qemu/sockets.h"
#include "sysemu/char.h"
#include "sysemu/sysemu.h"
-#include "hw/nvram/openbios_firmware_abi.h"
+#include "hw/nvram/chrp_nvram.h"
#define MIN_NVRAM_SIZE 8192 /* from spapr_nvram.c */
@@ -137,15 +137,15 @@ static void init_bootfile_ppc(const char *bootpath)
{
FILE *bootfile;
char buf[MIN_NVRAM_SIZE];
- struct OpenBIOS_nvpart_v1 *header = (struct OpenBIOS_nvpart_v1 *)buf;
+ ChrpNvramPartHdr *header = (ChrpNvramPartHdr *)buf;
memset(buf, 0, MIN_NVRAM_SIZE);
/* Create a "common" partition in nvram to store boot-command property */
- header->signature = OPENBIOS_PART_SYSTEM;
+ header->signature = CHRP_NVPART_SYSTEM;
memcpy(header->name, "common", 6);
- OpenBIOS_finish_partition(header, MIN_NVRAM_SIZE);
+ chrp_nvram_finish_partition(header, MIN_NVRAM_SIZE);
/* FW_MAX_SIZE is 4MB, but slof.bin is only 900KB,
* so let's modify memory between 1MB and 100MB
diff --git a/tests/prom-env-test.c b/tests/prom-env-test.c
index 7a628574c3..0ba6f48607 100644
--- a/tests/prom-env-test.c
+++ b/tests/prom-env-test.c
@@ -9,11 +9,12 @@
* This work is licensed under the terms of the GNU GPL, version 2
* or later. See the COPYING file in the top-level directory.
*
- * This test is used to check that some OpenBIOS machines can be started
- * successfully in TCG mode. To do this, we first put some Forth code into
- * the "boot-command" Open Firmware environment variable. This Forth code
- * writes a well-known magic value to a known location in memory. Then we
- * start the guest so that OpenBIOS can boot and finally run the Forth code.
+ * This test is used to check that some Open Firmware based machines (i.e.
+ * OpenBIOS or SLOF) can be started successfully in TCG mode. To do this, we
+ * first put some Forth code into the "boot-command" Open Firmware environment
+ * variable. This Forth code writes a well-known magic value to a known location
+ * in memory. Then we start the guest so that the firmware can boot and finally
+ * run the Forth code.
* The testing code here then can finally check whether the value has been
* successfully written into the guest memory.
*/
@@ -71,13 +72,16 @@ int main(int argc, char *argv[])
{
const char *sparc_machines[] = { "SPARCbook", "Voyager", "SS-20", NULL };
const char *sparc64_machines[] = { "sun4u", "sun4v", NULL };
- const char *mac_machines[] = { "mac99", "g3beige", NULL };
+ const char *ppc_machines[] = { "mac99", "g3beige", NULL };
+ const char *ppc64_machines[] = { "mac99", "g3beige", "pseries", NULL };
const char *arch = qtest_get_arch();
g_test_init(&argc, &argv, NULL);
- if (!strcmp(arch, "ppc") || !strcmp(arch, "ppc64")) {
- add_tests(mac_machines);
+ if (!strcmp(arch, "ppc")) {
+ add_tests(ppc_machines);
+ } else if (!strcmp(arch, "ppc64")) {
+ add_tests(ppc64_machines);
} else if (!strcmp(arch, "sparc")) {
add_tests(sparc_machines);
} else if (!strcmp(arch, "sparc64")) {
diff --git a/tests/rtas-test.c b/tests/rtas-test.c
index ba0867afbd..276c87ef84 100644
--- a/tests/rtas-test.c
+++ b/tests/rtas-test.c
@@ -14,7 +14,6 @@ static void test_rtas_get_time_of_day(void)
time_t t1, t2;
qs = qtest_spapr_boot("-machine pseries");
- g_assert(qs != NULL);
t1 = time(NULL);
ret = qrtas_get_time_of_day(qs->alloc, &tm, &ns);
diff --git a/tests/rtl8139-test.c b/tests/rtl8139-test.c
index c2f601a380..7de7dc45ae 100644
--- a/tests/rtl8139-test.c
+++ b/tests/rtl8139-test.c
@@ -22,7 +22,7 @@ static void nop(void)
static QPCIBus *pcibus;
static QPCIDevice *dev;
-static void *dev_base;
+static QPCIBar dev_bar;
static void save_fn(QPCIDevice *dev, int devfn, void *data)
{
@@ -45,14 +45,14 @@ static QPCIDevice *get_device(void)
#define PORT(name, len, val) \
static unsigned __attribute__((unused)) in_##name(void) \
{ \
- unsigned res = qpci_io_read##len(dev, dev_base+(val)); \
+ unsigned res = qpci_io_read##len(dev, dev_bar, (val)); \
g_test_message("*%s -> %x\n", #name, res); \
return res; \
} \
static void out_##name(unsigned v) \
{ \
g_test_message("%x -> *%s\n", v, #name); \
- qpci_io_write##len(dev, dev_base+(val), v); \
+ qpci_io_write##len(dev, dev_bar, (val), v); \
}
PORT(Timer, l, 0x48)
@@ -186,9 +186,7 @@ static void test_init(void)
dev = get_device();
- dev_base = qpci_iomap(dev, 0, &barsize);
-
- g_assert(dev_base != NULL);
+ dev_bar = qpci_iomap(dev, 0, &barsize);
qpci_device_enable(dev);
diff --git a/tests/tco-test.c b/tests/tco-test.c
index 0d201b1fcb..ef02ec5903 100644
--- a/tests/tco-test.c
+++ b/tests/tco-test.c
@@ -41,7 +41,7 @@ typedef struct {
const char *args;
bool noreboot;
QPCIDevice *dev;
- void *tco_io_base;
+ QPCIBar tco_io_bar;
} TestData;
static void test_init(TestData *d)
@@ -70,42 +70,42 @@ static void test_init(TestData *d)
/* set Root Complex BAR */
qpci_config_writel(d->dev, ICH9_LPC_RCBA, RCBA_BASE_ADDR | 0x1);
- d->tco_io_base = (void *)((uintptr_t)PM_IO_BASE_ADDR + 0x60);
+ d->tco_io_bar = qpci_legacy_iomap(d->dev, PM_IO_BASE_ADDR + 0x60);
}
static void stop_tco(const TestData *d)
{
uint32_t val;
- val = qpci_io_readw(d->dev, d->tco_io_base + TCO1_CNT);
+ val = qpci_io_readw(d->dev, d->tco_io_bar, TCO1_CNT);
val |= TCO_TMR_HLT;
- qpci_io_writew(d->dev, d->tco_io_base + TCO1_CNT, val);
+ qpci_io_writew(d->dev, d->tco_io_bar, TCO1_CNT, val);
}
static void start_tco(const TestData *d)
{
uint32_t val;
- val = qpci_io_readw(d->dev, d->tco_io_base + TCO1_CNT);
+ val = qpci_io_readw(d->dev, d->tco_io_bar, TCO1_CNT);
val &= ~TCO_TMR_HLT;
- qpci_io_writew(d->dev, d->tco_io_base + TCO1_CNT, val);
+ qpci_io_writew(d->dev, d->tco_io_bar, TCO1_CNT, val);
}
static void load_tco(const TestData *d)
{
- qpci_io_writew(d->dev, d->tco_io_base + TCO_RLD, 4);
+ qpci_io_writew(d->dev, d->tco_io_bar, TCO_RLD, 4);
}
static void set_tco_timeout(const TestData *d, uint16_t ticks)
{
- qpci_io_writew(d->dev, d->tco_io_base + TCO_TMR, ticks);
+ qpci_io_writew(d->dev, d->tco_io_bar, TCO_TMR, ticks);
}
static void clear_tco_status(const TestData *d)
{
- qpci_io_writew(d->dev, d->tco_io_base + TCO1_STS, 0x0008);
- qpci_io_writew(d->dev, d->tco_io_base + TCO2_STS, 0x0002);
- qpci_io_writew(d->dev, d->tco_io_base + TCO2_STS, 0x0004);
+ qpci_io_writew(d->dev, d->tco_io_bar, TCO1_STS, 0x0008);
+ qpci_io_writew(d->dev, d->tco_io_bar, TCO2_STS, 0x0002);
+ qpci_io_writew(d->dev, d->tco_io_bar, TCO2_STS, 0x0004);
}
static void reset_on_second_timeout(bool enable)
@@ -128,25 +128,25 @@ static void test_tco_defaults(void)
d.args = NULL;
d.noreboot = true;
test_init(&d);
- g_assert_cmpint(qpci_io_readw(d.dev, d.tco_io_base + TCO_RLD), ==,
+ g_assert_cmpint(qpci_io_readw(d.dev, d.tco_io_bar, TCO_RLD), ==,
TCO_RLD_DEFAULT);
/* TCO_DAT_IN & TCO_DAT_OUT */
- g_assert_cmpint(qpci_io_readw(d.dev, d.tco_io_base + TCO_DAT_IN), ==,
+ g_assert_cmpint(qpci_io_readw(d.dev, d.tco_io_bar, TCO_DAT_IN), ==,
(TCO_DAT_OUT_DEFAULT << 8) | TCO_DAT_IN_DEFAULT);
/* TCO1_STS & TCO2_STS */
- g_assert_cmpint(qpci_io_readl(d.dev, d.tco_io_base + TCO1_STS), ==,
+ g_assert_cmpint(qpci_io_readl(d.dev, d.tco_io_bar, TCO1_STS), ==,
(TCO2_STS_DEFAULT << 16) | TCO1_STS_DEFAULT);
/* TCO1_CNT & TCO2_CNT */
- g_assert_cmpint(qpci_io_readl(d.dev, d.tco_io_base + TCO1_CNT), ==,
+ g_assert_cmpint(qpci_io_readl(d.dev, d.tco_io_bar, TCO1_CNT), ==,
(TCO2_CNT_DEFAULT << 16) | TCO1_CNT_DEFAULT);
/* TCO_MESSAGE1 & TCO_MESSAGE2 */
- g_assert_cmpint(qpci_io_readw(d.dev, d.tco_io_base + TCO_MESSAGE1), ==,
+ g_assert_cmpint(qpci_io_readw(d.dev, d.tco_io_bar, TCO_MESSAGE1), ==,
(TCO_MESSAGE2_DEFAULT << 8) | TCO_MESSAGE1_DEFAULT);
- g_assert_cmpint(qpci_io_readb(d.dev, d.tco_io_base + TCO_WDCNT), ==,
+ g_assert_cmpint(qpci_io_readb(d.dev, d.tco_io_bar, TCO_WDCNT), ==,
TCO_WDCNT_DEFAULT);
- g_assert_cmpint(qpci_io_readb(d.dev, d.tco_io_base + SW_IRQ_GEN), ==,
+ g_assert_cmpint(qpci_io_readb(d.dev, d.tco_io_bar, SW_IRQ_GEN), ==,
SW_IRQ_GEN_DEFAULT);
- g_assert_cmpint(qpci_io_readw(d.dev, d.tco_io_base + TCO_TMR), ==,
+ g_assert_cmpint(qpci_io_readw(d.dev, d.tco_io_bar, TCO_TMR), ==,
TCO_TMR_DEFAULT);
qtest_end();
}
@@ -171,23 +171,23 @@ static void test_tco_timeout(void)
clock_step(ticks * TCO_TICK_NSEC);
/* test first timeout */
- val = qpci_io_readw(d.dev, d.tco_io_base + TCO1_STS);
+ val = qpci_io_readw(d.dev, d.tco_io_bar, TCO1_STS);
ret = val & TCO_TIMEOUT ? 1 : 0;
g_assert(ret == 1);
/* test clearing timeout bit */
val |= TCO_TIMEOUT;
- qpci_io_writew(d.dev, d.tco_io_base + TCO1_STS, val);
- val = qpci_io_readw(d.dev, d.tco_io_base + TCO1_STS);
+ qpci_io_writew(d.dev, d.tco_io_bar, TCO1_STS, val);
+ val = qpci_io_readw(d.dev, d.tco_io_bar, TCO1_STS);
ret = val & TCO_TIMEOUT ? 1 : 0;
g_assert(ret == 0);
/* test second timeout */
clock_step(ticks * TCO_TICK_NSEC);
- val = qpci_io_readw(d.dev, d.tco_io_base + TCO1_STS);
+ val = qpci_io_readw(d.dev, d.tco_io_bar, TCO1_STS);
ret = val & TCO_TIMEOUT ? 1 : 0;
g_assert(ret == 1);
- val = qpci_io_readw(d.dev, d.tco_io_base + TCO2_STS);
+ val = qpci_io_readw(d.dev, d.tco_io_bar, TCO2_STS);
ret = val & TCO_SECOND_TO_STS ? 1 : 0;
g_assert(ret == 1);
@@ -214,13 +214,13 @@ static void test_tco_max_timeout(void)
start_tco(&d);
clock_step(((ticks & TCO_TMR_MASK) - 1) * TCO_TICK_NSEC);
- val = qpci_io_readw(d.dev, d.tco_io_base + TCO_RLD);
+ val = qpci_io_readw(d.dev, d.tco_io_bar, TCO_RLD);
g_assert_cmpint(val & TCO_RLD_MASK, ==, 1);
- val = qpci_io_readw(d.dev, d.tco_io_base + TCO1_STS);
+ val = qpci_io_readw(d.dev, d.tco_io_bar, TCO1_STS);
ret = val & TCO_TIMEOUT ? 1 : 0;
g_assert(ret == 0);
clock_step(TCO_TICK_NSEC);
- val = qpci_io_readw(d.dev, d.tco_io_base + TCO1_STS);
+ val = qpci_io_readw(d.dev, d.tco_io_bar, TCO1_STS);
ret = val & TCO_TIMEOUT ? 1 : 0;
g_assert(ret == 1);
@@ -358,11 +358,11 @@ static void test_tco_ticks_counter(void)
start_tco(&d);
do {
- rld = qpci_io_readw(d.dev, d.tco_io_base + TCO_RLD) & TCO_RLD_MASK;
+ rld = qpci_io_readw(d.dev, d.tco_io_bar, TCO_RLD) & TCO_RLD_MASK;
g_assert_cmpint(rld, ==, ticks);
clock_step(TCO_TICK_NSEC);
ticks--;
- } while (!(qpci_io_readw(d.dev, d.tco_io_base + TCO1_STS) & TCO_TIMEOUT));
+ } while (!(qpci_io_readw(d.dev, d.tco_io_bar, TCO1_STS) & TCO_TIMEOUT));
stop_tco(&d);
qtest_end();
@@ -378,10 +378,10 @@ static void test_tco1_control_bits(void)
test_init(&d);
val = TCO_LOCK;
- qpci_io_writew(d.dev, d.tco_io_base + TCO1_CNT, val);
+ qpci_io_writew(d.dev, d.tco_io_bar, TCO1_CNT, val);
val &= ~TCO_LOCK;
- qpci_io_writew(d.dev, d.tco_io_base + TCO1_CNT, val);
- g_assert_cmpint(qpci_io_readw(d.dev, d.tco_io_base + TCO1_CNT), ==,
+ qpci_io_writew(d.dev, d.tco_io_bar, TCO1_CNT, val);
+ g_assert_cmpint(qpci_io_readw(d.dev, d.tco_io_bar, TCO1_CNT), ==,
TCO_LOCK);
qtest_end();
}
@@ -405,13 +405,13 @@ static void test_tco1_status_bits(void)
start_tco(&d);
clock_step(ticks * TCO_TICK_NSEC);
- qpci_io_writeb(d.dev, d.tco_io_base + TCO_DAT_IN, 0);
- qpci_io_writeb(d.dev, d.tco_io_base + TCO_DAT_OUT, 0);
- val = qpci_io_readw(d.dev, d.tco_io_base + TCO1_STS);
+ qpci_io_writeb(d.dev, d.tco_io_bar, TCO_DAT_IN, 0);
+ qpci_io_writeb(d.dev, d.tco_io_bar, TCO_DAT_OUT, 0);
+ val = qpci_io_readw(d.dev, d.tco_io_bar, TCO1_STS);
ret = val & (TCO_TIMEOUT | SW_TCO_SMI | TCO_INT_STS) ? 1 : 0;
g_assert(ret == 1);
- qpci_io_writew(d.dev, d.tco_io_base + TCO1_STS, val);
- g_assert_cmpint(qpci_io_readw(d.dev, d.tco_io_base + TCO1_STS), ==, 0);
+ qpci_io_writew(d.dev, d.tco_io_bar, TCO1_STS, val);
+ g_assert_cmpint(qpci_io_readw(d.dev, d.tco_io_bar, TCO1_STS), ==, 0);
qtest_end();
}
@@ -434,11 +434,11 @@ static void test_tco2_status_bits(void)
start_tco(&d);
clock_step(ticks * TCO_TICK_NSEC * 2);
- val = qpci_io_readw(d.dev, d.tco_io_base + TCO2_STS);
+ val = qpci_io_readw(d.dev, d.tco_io_bar, TCO2_STS);
ret = val & (TCO_SECOND_TO_STS | TCO_BOOT_STS) ? 1 : 0;
g_assert(ret == 1);
- qpci_io_writew(d.dev, d.tco_io_base + TCO2_STS, val);
- g_assert_cmpint(qpci_io_readw(d.dev, d.tco_io_base + TCO2_STS), ==, 0);
+ qpci_io_writew(d.dev, d.tco_io_bar, TCO2_STS, val);
+ g_assert_cmpint(qpci_io_readw(d.dev, d.tco_io_bar, TCO2_STS), ==, 0);
qtest_end();
}
diff --git a/tests/usb-hcd-ehci-test.c b/tests/usb-hcd-ehci-test.c
index a4ceeaaa43..57af8a034e 100644
--- a/tests/usb-hcd-ehci-test.c
+++ b/tests/usb-hcd-ehci-test.c
@@ -38,8 +38,7 @@ static void uhci_port_update(struct qhc *hc, int port,
static void ehci_port_test(struct qhc *hc, int port, uint32_t expect)
{
- void *addr = hc->base + 0x64 + 4 * port;
- uint32_t value = qpci_io_readl(hc->dev, addr);
+ uint32_t value = qpci_io_readl(hc->dev, hc->bar, 0x64 + 4 * port);
uint16_t mask = ~(PORTSC_CSC | PORTSC_PEDC | PORTSC_OCC);
#if 0
@@ -91,7 +90,7 @@ static void pci_ehci_port_1(void)
static void pci_ehci_config(void)
{
/* hands over all ports from companion uhci to ehci */
- qpci_io_writew(ehci1.dev, ehci1.base + 0x60, 1);
+ qpci_io_writew(ehci1.dev, ehci1.bar, 0x60, 1);
}
static void pci_uhci_port_2(void)
diff --git a/tests/vhost-user-test.c b/tests/vhost-user-test.c
index a7f06291cb..e4b2900898 100644
--- a/tests/vhost-user-test.c
+++ b/tests/vhost-user-test.c
@@ -172,15 +172,15 @@ static void init_virtio_dev(TestServer *s)
g_assert_nonnull(dev);
qvirtio_pci_device_enable(dev);
- qvirtio_reset(&qvirtio_pci, &dev->vdev);
- qvirtio_set_acknowledge(&qvirtio_pci, &dev->vdev);
- qvirtio_set_driver(&qvirtio_pci, &dev->vdev);
+ qvirtio_reset(&dev->vdev);
+ qvirtio_set_acknowledge(&dev->vdev);
+ qvirtio_set_driver(&dev->vdev);
- features = qvirtio_get_features(&qvirtio_pci, &dev->vdev);
+ features = qvirtio_get_features(&dev->vdev);
features = features & VIRTIO_NET_F_MAC;
- qvirtio_set_features(&qvirtio_pci, &dev->vdev, features);
+ qvirtio_set_features(&dev->vdev, features);
- qvirtio_set_driver_ok(&qvirtio_pci, &dev->vdev);
+ qvirtio_set_driver_ok(&dev->vdev);
}
static void wait_for_fds(TestServer *s)
@@ -847,24 +847,24 @@ static QVirtioPCIDevice *virtio_net_pci_init(QPCIBus *bus, int slot)
g_assert_cmphex(dev->vdev.device_type, ==, VIRTIO_ID_NET);
qvirtio_pci_device_enable(dev);
- qvirtio_reset(&qvirtio_pci, &dev->vdev);
- qvirtio_set_acknowledge(&qvirtio_pci, &dev->vdev);
- qvirtio_set_driver(&qvirtio_pci, &dev->vdev);
+ qvirtio_reset(&dev->vdev);
+ qvirtio_set_acknowledge(&dev->vdev);
+ qvirtio_set_driver(&dev->vdev);
return dev;
}
-static void driver_init(const QVirtioBus *bus, QVirtioDevice *dev)
+static void driver_init(QVirtioDevice *dev)
{
uint32_t features;
- features = qvirtio_get_features(bus, dev);
+ features = qvirtio_get_features(dev);
features = features & ~(QVIRTIO_F_BAD_FEATURE |
(1u << VIRTIO_RING_F_INDIRECT_DESC) |
(1u << VIRTIO_RING_F_EVENT_IDX));
- qvirtio_set_features(bus, dev, features);
+ qvirtio_set_features(dev, features);
- qvirtio_set_driver_ok(bus, dev);
+ qvirtio_set_driver_ok(dev);
}
#define PCI_SLOT 0x04
@@ -896,16 +896,15 @@ static void test_multiqueue(void)
alloc = pc_alloc_init();
for (i = 0; i < queues * 2; i++) {
- vq[i] = (QVirtQueuePCI *)qvirtqueue_setup(&qvirtio_pci, &dev->vdev,
- alloc, i);
+ vq[i] = (QVirtQueuePCI *)qvirtqueue_setup(&dev->vdev, alloc, i);
}
- driver_init(&qvirtio_pci, &dev->vdev);
+ driver_init(&dev->vdev);
wait_for_rings_started(s, queues * 2);
/* End test */
for (i = 0; i < queues * 2; i++) {
- qvirtqueue_cleanup(&qvirtio_pci, &vq[i]->vq, alloc);
+ qvirtqueue_cleanup(dev->vdev.bus, &vq[i]->vq, alloc);
}
pc_alloc_uninit(alloc);
qvirtio_pci_device_disable(dev);
diff --git a/tests/virtio-9p-test.c b/tests/virtio-9p-test.c
index e8b21967d8..9c4f6cb406 100644
--- a/tests/virtio-9p-test.c
+++ b/tests/virtio-9p-test.c
@@ -10,112 +10,111 @@
#include "qemu/osdep.h"
#include "libqtest.h"
#include "qemu-common.h"
-#include "libqos/pci-pc.h"
+#include "libqos/libqos-pc.h"
+#include "libqos/libqos-spapr.h"
#include "libqos/virtio.h"
#include "libqos/virtio-pci.h"
-#include "libqos/malloc.h"
-#include "libqos/malloc-pc.h"
#include "standard-headers/linux/virtio_ids.h"
#include "standard-headers/linux/virtio_pci.h"
static const char mount_tag[] = "qtest";
static char *test_share;
-static void qvirtio_9p_start(void)
+
+static QOSState *qvirtio_9p_start(void)
{
- char *args;
+ const char *arch = qtest_get_arch();
+ const char *cmd = "-fsdev local,id=fsdev0,security_model=none,path=%s "
+ "-device virtio-9p-pci,fsdev=fsdev0,mount_tag=%s";
test_share = g_strdup("/tmp/qtest.XXXXXX");
g_assert_nonnull(mkdtemp(test_share));
- args = g_strdup_printf("-fsdev local,id=fsdev0,security_model=none,path=%s "
- "-device virtio-9p-pci,fsdev=fsdev0,mount_tag=%s",
- test_share, mount_tag);
+ if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
+ return qtest_pc_boot(cmd, test_share, mount_tag);
+ }
+ if (strcmp(arch, "ppc64") == 0) {
+ return qtest_spapr_boot(cmd, test_share, mount_tag);
+ }
- qtest_start(args);
- g_free(args);
+ g_printerr("virtio-9p tests are only available on x86 or ppc64\n");
+ exit(EXIT_FAILURE);
}
-static void qvirtio_9p_stop(void)
+static void qvirtio_9p_stop(QOSState *qs)
{
- qtest_end();
+ qtest_shutdown(qs);
rmdir(test_share);
g_free(test_share);
}
static void pci_nop(void)
{
- qvirtio_9p_start();
- qvirtio_9p_stop();
+ QOSState *qs;
+
+ qs = qvirtio_9p_start();
+ qvirtio_9p_stop(qs);
}
typedef struct {
QVirtioDevice *dev;
- QGuestAllocator *alloc;
- QPCIBus *bus;
+ QOSState *qs;
QVirtQueue *vq;
} QVirtIO9P;
-static QVirtIO9P *qvirtio_9p_pci_init(void)
+static QVirtIO9P *qvirtio_9p_pci_init(QOSState *qs)
{
QVirtIO9P *v9p;
QVirtioPCIDevice *dev;
v9p = g_new0(QVirtIO9P, 1);
- v9p->alloc = pc_alloc_init();
- v9p->bus = qpci_init_pc(NULL);
- dev = qvirtio_pci_device_find(v9p->bus, VIRTIO_ID_9P);
+ v9p->qs = qs;
+ dev = qvirtio_pci_device_find(v9p->qs->pcibus, VIRTIO_ID_9P);
g_assert_nonnull(dev);
g_assert_cmphex(dev->vdev.device_type, ==, VIRTIO_ID_9P);
v9p->dev = (QVirtioDevice *) dev;
qvirtio_pci_device_enable(dev);
- qvirtio_reset(&qvirtio_pci, v9p->dev);
- qvirtio_set_acknowledge(&qvirtio_pci, v9p->dev);
- qvirtio_set_driver(&qvirtio_pci, v9p->dev);
+ qvirtio_reset(v9p->dev);
+ qvirtio_set_acknowledge(v9p->dev);
+ qvirtio_set_driver(v9p->dev);
- v9p->vq = qvirtqueue_setup(&qvirtio_pci, v9p->dev, v9p->alloc, 0);
+ v9p->vq = qvirtqueue_setup(v9p->dev, v9p->qs->alloc, 0);
return v9p;
}
static void qvirtio_9p_pci_free(QVirtIO9P *v9p)
{
- qvirtqueue_cleanup(&qvirtio_pci, v9p->vq, v9p->alloc);
- pc_alloc_uninit(v9p->alloc);
+ qvirtqueue_cleanup(v9p->dev->bus, v9p->vq, v9p->qs->alloc);
qvirtio_pci_device_disable(container_of(v9p->dev, QVirtioPCIDevice, vdev));
g_free(v9p->dev);
- qpci_free_pc(v9p->bus);
g_free(v9p);
}
static void pci_basic_config(void)
{
QVirtIO9P *v9p;
- void *addr;
size_t tag_len;
char *tag;
int i;
+ QOSState *qs;
- qvirtio_9p_start();
- v9p = qvirtio_9p_pci_init();
+ qs = qvirtio_9p_start();
+ v9p = qvirtio_9p_pci_init(qs);
- addr = ((QVirtioPCIDevice *) v9p->dev)->addr + VIRTIO_PCI_CONFIG_OFF(false);
- tag_len = qvirtio_config_readw(&qvirtio_pci, v9p->dev,
- (uint64_t)(uintptr_t)addr);
+ tag_len = qvirtio_config_readw(v9p->dev, 0);
g_assert_cmpint(tag_len, ==, strlen(mount_tag));
- addr += sizeof(uint16_t);
tag = g_malloc(tag_len);
for (i = 0; i < tag_len; i++) {
- tag[i] = qvirtio_config_readb(&qvirtio_pci, v9p->dev,
- (uint64_t)(uintptr_t)addr + i);
+ tag[i] = qvirtio_config_readb(v9p->dev, i + 2);
}
g_assert_cmpmem(tag, tag_len, mount_tag, tag_len);
g_free(tag);
qvirtio_9p_pci_free(v9p);
- qvirtio_9p_stop();
+ qvirtio_9p_stop(qs);
}
int main(int argc, char **argv)
diff --git a/tests/virtio-blk-test.c b/tests/virtio-blk-test.c
index 0506917341..0e32e416dd 100644
--- a/tests/virtio-blk-test.c
+++ b/tests/virtio-blk-test.c
@@ -10,12 +10,11 @@
#include "qemu/osdep.h"
#include "libqtest.h"
+#include "libqos/libqos-pc.h"
+#include "libqos/libqos-spapr.h"
#include "libqos/virtio.h"
#include "libqos/virtio-pci.h"
#include "libqos/virtio-mmio.h"
-#include "libqos/pci-pc.h"
-#include "libqos/malloc.h"
-#include "libqos/malloc-pc.h"
#include "libqos/malloc-generic.h"
#include "qemu/bswap.h"
#include "standard-headers/linux/virtio_ids.h"
@@ -58,24 +57,29 @@ static char *drive_create(void)
return tmp_path;
}
-static QPCIBus *pci_test_start(void)
+static QOSState *pci_test_start(void)
{
- char *cmdline;
+ QOSState *qs;
+ const char *arch = qtest_get_arch();
char *tmp_path;
+ const char *cmd = "-drive if=none,id=drive0,file=%s,format=raw "
+ "-drive if=none,id=drive1,file=/dev/null,format=raw "
+ "-device virtio-blk-pci,id=drv0,drive=drive0,"
+ "addr=%x.%x";
tmp_path = drive_create();
- cmdline = g_strdup_printf("-drive if=none,id=drive0,file=%s,format=raw "
- "-drive if=none,id=drive1,file=/dev/null,format=raw "
- "-device virtio-blk-pci,id=drv0,drive=drive0,"
- "addr=%x.%x",
- tmp_path, PCI_SLOT, PCI_FN);
- qtest_start(cmdline);
+ if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
+ qs = qtest_pc_boot(cmd, tmp_path, PCI_SLOT, PCI_FN);
+ } else if (strcmp(arch, "ppc64") == 0) {
+ qs = qtest_spapr_boot(cmd, tmp_path, PCI_SLOT, PCI_FN);
+ } else {
+ g_printerr("virtio-blk tests are only available on x86 or ppc64\n");
+ exit(EXIT_FAILURE);
+ }
unlink(tmp_path);
g_free(tmp_path);
- g_free(cmdline);
-
- return qpci_init_pc(NULL);
+ return qs;
}
static void arm_test_start(void)
@@ -110,30 +114,30 @@ static QVirtioPCIDevice *virtio_blk_pci_init(QPCIBus *bus, int slot)
g_assert_cmphex(dev->pdev->devfn, ==, ((slot << 3) | PCI_FN));
qvirtio_pci_device_enable(dev);
- qvirtio_reset(&qvirtio_pci, &dev->vdev);
- qvirtio_set_acknowledge(&qvirtio_pci, &dev->vdev);
- qvirtio_set_driver(&qvirtio_pci, &dev->vdev);
+ qvirtio_reset(&dev->vdev);
+ qvirtio_set_acknowledge(&dev->vdev);
+ qvirtio_set_driver(&dev->vdev);
return dev;
}
-static inline void virtio_blk_fix_request(QVirtioBlkReq *req)
+static inline void virtio_blk_fix_request(QVirtioDevice *d, QVirtioBlkReq *req)
{
#ifdef HOST_WORDS_BIGENDIAN
- bool host_endian = true;
+ const bool host_is_big_endian = true;
#else
- bool host_endian = false;
+ const bool host_is_big_endian = false;
#endif
- if (target_big_endian() != host_endian) {
+ if (qvirtio_is_big_endian(d) != host_is_big_endian) {
req->type = bswap32(req->type);
req->ioprio = bswap32(req->ioprio);
req->sector = bswap64(req->sector);
}
}
-static uint64_t virtio_blk_request(QGuestAllocator *alloc, QVirtioBlkReq *req,
- uint64_t data_size)
+static uint64_t virtio_blk_request(QGuestAllocator *alloc, QVirtioDevice *d,
+ QVirtioBlkReq *req, uint64_t data_size)
{
uint64_t addr;
uint8_t status = 0xFF;
@@ -141,7 +145,7 @@ static uint64_t virtio_blk_request(QGuestAllocator *alloc, QVirtioBlkReq *req,
g_assert_cmpuint(data_size % 512, ==, 0);
addr = guest_alloc(alloc, sizeof(*req) + data_size);
- virtio_blk_fix_request(req);
+ virtio_blk_fix_request(d, req);
memwrite(addr, req, 16);
memwrite(addr + 16, req->data, data_size);
@@ -150,8 +154,8 @@ static uint64_t virtio_blk_request(QGuestAllocator *alloc, QVirtioBlkReq *req,
return addr;
}
-static void test_basic(const QVirtioBus *bus, QVirtioDevice *dev,
- QGuestAllocator *alloc, QVirtQueue *vq, uint64_t device_specific)
+static void test_basic(QVirtioDevice *dev, QGuestAllocator *alloc,
+ QVirtQueue *vq)
{
QVirtioBlkReq req;
uint64_t req_addr;
@@ -161,18 +165,18 @@ static void test_basic(const QVirtioBus *bus, QVirtioDevice *dev,
uint8_t status;
char *data;
- capacity = qvirtio_config_readq(bus, dev, device_specific);
+ capacity = qvirtio_config_readq(dev, 0);
g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
- features = qvirtio_get_features(bus, dev);
+ features = qvirtio_get_features(dev);
features = features & ~(QVIRTIO_F_BAD_FEATURE |
(1u << VIRTIO_RING_F_INDIRECT_DESC) |
(1u << VIRTIO_RING_F_EVENT_IDX) |
(1u << VIRTIO_BLK_F_SCSI));
- qvirtio_set_features(bus, dev, features);
+ qvirtio_set_features(dev, features);
- qvirtio_set_driver_ok(bus, dev);
+ qvirtio_set_driver_ok(dev);
/* Write and read with 3 descriptor layout */
/* Write request */
@@ -182,7 +186,7 @@ static void test_basic(const QVirtioBus *bus, QVirtioDevice *dev,
req.data = g_malloc0(512);
strcpy(req.data, "TEST");
- req_addr = virtio_blk_request(alloc, &req, 512);
+ req_addr = virtio_blk_request(alloc, dev, &req, 512);
g_free(req.data);
@@ -190,9 +194,9 @@ static void test_basic(const QVirtioBus *bus, QVirtioDevice *dev,
qvirtqueue_add(vq, req_addr + 16, 512, false, true);
qvirtqueue_add(vq, req_addr + 528, 1, true, false);
- qvirtqueue_kick(bus, dev, vq, free_head);
+ qvirtqueue_kick(dev, vq, free_head);
- qvirtio_wait_queue_isr(bus, dev, vq, QVIRTIO_BLK_TIMEOUT_US);
+ qvirtio_wait_queue_isr(dev, vq, QVIRTIO_BLK_TIMEOUT_US);
status = readb(req_addr + 528);
g_assert_cmpint(status, ==, 0);
@@ -204,7 +208,7 @@ static void test_basic(const QVirtioBus *bus, QVirtioDevice *dev,
req.sector = 0;
req.data = g_malloc0(512);
- req_addr = virtio_blk_request(alloc, &req, 512);
+ req_addr = virtio_blk_request(alloc, dev, &req, 512);
g_free(req.data);
@@ -212,9 +216,9 @@ static void test_basic(const QVirtioBus *bus, QVirtioDevice *dev,
qvirtqueue_add(vq, req_addr + 16, 512, true, true);
qvirtqueue_add(vq, req_addr + 528, 1, true, false);
- qvirtqueue_kick(bus, dev, vq, free_head);
+ qvirtqueue_kick(dev, vq, free_head);
- qvirtio_wait_queue_isr(bus, dev, vq, QVIRTIO_BLK_TIMEOUT_US);
+ qvirtio_wait_queue_isr(dev, vq, QVIRTIO_BLK_TIMEOUT_US);
status = readb(req_addr + 528);
g_assert_cmpint(status, ==, 0);
@@ -234,15 +238,15 @@ static void test_basic(const QVirtioBus *bus, QVirtioDevice *dev,
req.data = g_malloc0(512);
strcpy(req.data, "TEST");
- req_addr = virtio_blk_request(alloc, &req, 512);
+ req_addr = virtio_blk_request(alloc, dev, &req, 512);
g_free(req.data);
free_head = qvirtqueue_add(vq, req_addr, 528, false, true);
qvirtqueue_add(vq, req_addr + 528, 1, true, false);
- qvirtqueue_kick(bus, dev, vq, free_head);
+ qvirtqueue_kick(dev, vq, free_head);
- qvirtio_wait_queue_isr(bus, dev, vq, QVIRTIO_BLK_TIMEOUT_US);
+ qvirtio_wait_queue_isr(dev, vq, QVIRTIO_BLK_TIMEOUT_US);
status = readb(req_addr + 528);
g_assert_cmpint(status, ==, 0);
@@ -254,16 +258,16 @@ static void test_basic(const QVirtioBus *bus, QVirtioDevice *dev,
req.sector = 1;
req.data = g_malloc0(512);
- req_addr = virtio_blk_request(alloc, &req, 512);
+ req_addr = virtio_blk_request(alloc, dev, &req, 512);
g_free(req.data);
free_head = qvirtqueue_add(vq, req_addr, 16, false, true);
qvirtqueue_add(vq, req_addr + 16, 513, true, false);
- qvirtqueue_kick(bus, dev, vq, free_head);
+ qvirtqueue_kick(dev, vq, free_head);
- qvirtio_wait_queue_isr(bus, dev, vq, QVIRTIO_BLK_TIMEOUT_US);
+ qvirtio_wait_queue_isr(dev, vq, QVIRTIO_BLK_TIMEOUT_US);
status = readb(req_addr + 528);
g_assert_cmpint(status, ==, 0);
@@ -279,42 +283,30 @@ static void test_basic(const QVirtioBus *bus, QVirtioDevice *dev,
static void pci_basic(void)
{
QVirtioPCIDevice *dev;
- QPCIBus *bus;
+ QOSState *qs;
QVirtQueuePCI *vqpci;
- QGuestAllocator *alloc;
- void *addr;
- bus = pci_test_start();
- dev = virtio_blk_pci_init(bus, PCI_SLOT);
+ qs = pci_test_start();
+ dev = virtio_blk_pci_init(qs->pcibus, PCI_SLOT);
- alloc = pc_alloc_init();
- vqpci = (QVirtQueuePCI *)qvirtqueue_setup(&qvirtio_pci, &dev->vdev,
- alloc, 0);
+ vqpci = (QVirtQueuePCI *)qvirtqueue_setup(&dev->vdev, qs->alloc, 0);
- /* MSI-X is not enabled */
- addr = dev->addr + VIRTIO_PCI_CONFIG_OFF(false);
-
- test_basic(&qvirtio_pci, &dev->vdev, alloc, &vqpci->vq,
- (uint64_t)(uintptr_t)addr);
+ test_basic(&dev->vdev, qs->alloc, &vqpci->vq);
/* End test */
- qvirtqueue_cleanup(&qvirtio_pci, &vqpci->vq, alloc);
- pc_alloc_uninit(alloc);
+ qvirtqueue_cleanup(dev->vdev.bus, &vqpci->vq, qs->alloc);
qvirtio_pci_device_disable(dev);
g_free(dev);
- qpci_free_pc(bus);
- test_end();
+ qtest_shutdown(qs);
}
static void pci_indirect(void)
{
QVirtioPCIDevice *dev;
- QPCIBus *bus;
QVirtQueuePCI *vqpci;
- QGuestAllocator *alloc;
+ QOSState *qs;
QVirtioBlkReq req;
QVRingIndirectDesc *indirect;
- void *addr;
uint64_t req_addr;
uint64_t capacity;
uint32_t features;
@@ -322,28 +314,22 @@ static void pci_indirect(void)
uint8_t status;
char *data;
- bus = pci_test_start();
-
- dev = virtio_blk_pci_init(bus, PCI_SLOT);
+ qs = pci_test_start();
- /* MSI-X is not enabled */
- addr = dev->addr + VIRTIO_PCI_CONFIG_OFF(false);
+ dev = virtio_blk_pci_init(qs->pcibus, PCI_SLOT);
- capacity = qvirtio_config_readq(&qvirtio_pci, &dev->vdev,
- (uint64_t)(uintptr_t)addr);
+ capacity = qvirtio_config_readq(&dev->vdev, 0);
g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
- features = qvirtio_get_features(&qvirtio_pci, &dev->vdev);
+ features = qvirtio_get_features(&dev->vdev);
g_assert_cmphex(features & (1u << VIRTIO_RING_F_INDIRECT_DESC), !=, 0);
features = features & ~(QVIRTIO_F_BAD_FEATURE |
(1u << VIRTIO_RING_F_EVENT_IDX) |
(1u << VIRTIO_BLK_F_SCSI));
- qvirtio_set_features(&qvirtio_pci, &dev->vdev, features);
+ qvirtio_set_features(&dev->vdev, features);
- alloc = pc_alloc_init();
- vqpci = (QVirtQueuePCI *)qvirtqueue_setup(&qvirtio_pci, &dev->vdev,
- alloc, 0);
- qvirtio_set_driver_ok(&qvirtio_pci, &dev->vdev);
+ vqpci = (QVirtQueuePCI *)qvirtqueue_setup(&dev->vdev, qs->alloc, 0);
+ qvirtio_set_driver_ok(&dev->vdev);
/* Write request */
req.type = VIRTIO_BLK_T_OUT;
@@ -352,23 +338,23 @@ static void pci_indirect(void)
req.data = g_malloc0(512);
strcpy(req.data, "TEST");
- req_addr = virtio_blk_request(alloc, &req, 512);
+ req_addr = virtio_blk_request(qs->alloc, &dev->vdev, &req, 512);
g_free(req.data);
- indirect = qvring_indirect_desc_setup(&dev->vdev, alloc, 2);
+ indirect = qvring_indirect_desc_setup(&dev->vdev, qs->alloc, 2);
qvring_indirect_desc_add(indirect, req_addr, 528, false);
qvring_indirect_desc_add(indirect, req_addr + 528, 1, true);
free_head = qvirtqueue_add_indirect(&vqpci->vq, indirect);
- qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head);
+ qvirtqueue_kick(&dev->vdev, &vqpci->vq, free_head);
- qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
+ qvirtio_wait_queue_isr(&dev->vdev, &vqpci->vq,
QVIRTIO_BLK_TIMEOUT_US);
status = readb(req_addr + 528);
g_assert_cmpint(status, ==, 0);
g_free(indirect);
- guest_free(alloc, req_addr);
+ guest_free(qs->alloc, req_addr);
/* Read request */
req.type = VIRTIO_BLK_T_IN;
@@ -377,17 +363,17 @@ static void pci_indirect(void)
req.data = g_malloc0(512);
strcpy(req.data, "TEST");
- req_addr = virtio_blk_request(alloc, &req, 512);
+ req_addr = virtio_blk_request(qs->alloc, &dev->vdev, &req, 512);
g_free(req.data);
- indirect = qvring_indirect_desc_setup(&dev->vdev, alloc, 2);
+ indirect = qvring_indirect_desc_setup(&dev->vdev, qs->alloc, 2);
qvring_indirect_desc_add(indirect, req_addr, 16, false);
qvring_indirect_desc_add(indirect, req_addr + 16, 513, true);
free_head = qvirtqueue_add_indirect(&vqpci->vq, indirect);
- qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head);
+ qvirtqueue_kick(&dev->vdev, &vqpci->vq, free_head);
- qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
+ qvirtio_wait_queue_isr(&dev->vdev, &vqpci->vq,
QVIRTIO_BLK_TIMEOUT_US);
status = readb(req_addr + 528);
g_assert_cmpint(status, ==, 0);
@@ -398,61 +384,51 @@ static void pci_indirect(void)
g_free(data);
g_free(indirect);
- guest_free(alloc, req_addr);
+ guest_free(qs->alloc, req_addr);
/* End test */
- qvirtqueue_cleanup(&qvirtio_pci, &vqpci->vq, alloc);
- pc_alloc_uninit(alloc);
+ qvirtqueue_cleanup(dev->vdev.bus, &vqpci->vq, qs->alloc);
qvirtio_pci_device_disable(dev);
g_free(dev);
- qpci_free_pc(bus);
- test_end();
+ qtest_shutdown(qs);
}
static void pci_config(void)
{
QVirtioPCIDevice *dev;
- QPCIBus *bus;
+ QOSState *qs;
int n_size = TEST_IMAGE_SIZE / 2;
- void *addr;
uint64_t capacity;
- bus = pci_test_start();
+ qs = pci_test_start();
- dev = virtio_blk_pci_init(bus, PCI_SLOT);
+ dev = virtio_blk_pci_init(qs->pcibus, PCI_SLOT);
- /* MSI-X is not enabled */
- addr = dev->addr + VIRTIO_PCI_CONFIG_OFF(false);
-
- capacity = qvirtio_config_readq(&qvirtio_pci, &dev->vdev,
- (uint64_t)(uintptr_t)addr);
+ capacity = qvirtio_config_readq(&dev->vdev, 0);
g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
- qvirtio_set_driver_ok(&qvirtio_pci, &dev->vdev);
+ qvirtio_set_driver_ok(&dev->vdev);
qmp("{ 'execute': 'block_resize', 'arguments': { 'device': 'drive0', "
" 'size': %d } }", n_size);
- qvirtio_wait_config_isr(&qvirtio_pci, &dev->vdev, QVIRTIO_BLK_TIMEOUT_US);
+ qvirtio_wait_config_isr(&dev->vdev, QVIRTIO_BLK_TIMEOUT_US);
- capacity = qvirtio_config_readq(&qvirtio_pci, &dev->vdev,
- (uint64_t)(uintptr_t)addr);
+ capacity = qvirtio_config_readq(&dev->vdev, 0);
g_assert_cmpint(capacity, ==, n_size / 512);
qvirtio_pci_device_disable(dev);
g_free(dev);
- qpci_free_pc(bus);
- test_end();
+
+ qtest_shutdown(qs);
}
static void pci_msix(void)
{
QVirtioPCIDevice *dev;
- QPCIBus *bus;
+ QOSState *qs;
QVirtQueuePCI *vqpci;
- QGuestAllocator *alloc;
QVirtioBlkReq req;
int n_size = TEST_IMAGE_SIZE / 2;
- void *addr;
uint64_t req_addr;
uint64_t capacity;
uint32_t features;
@@ -460,41 +436,34 @@ static void pci_msix(void)
uint8_t status;
char *data;
- bus = pci_test_start();
- alloc = pc_alloc_init();
+ qs = pci_test_start();
- dev = virtio_blk_pci_init(bus, PCI_SLOT);
+ dev = virtio_blk_pci_init(qs->pcibus, PCI_SLOT);
qpci_msix_enable(dev->pdev);
- qvirtio_pci_set_msix_configuration_vector(dev, alloc, 0);
+ qvirtio_pci_set_msix_configuration_vector(dev, qs->alloc, 0);
- /* MSI-X is enabled */
- addr = dev->addr + VIRTIO_PCI_CONFIG_OFF(true);
-
- capacity = qvirtio_config_readq(&qvirtio_pci, &dev->vdev,
- (uint64_t)(uintptr_t)addr);
+ capacity = qvirtio_config_readq(&dev->vdev, 0);
g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
- features = qvirtio_get_features(&qvirtio_pci, &dev->vdev);
+ features = qvirtio_get_features(&dev->vdev);
features = features & ~(QVIRTIO_F_BAD_FEATURE |
(1u << VIRTIO_RING_F_INDIRECT_DESC) |
(1u << VIRTIO_RING_F_EVENT_IDX) |
(1u << VIRTIO_BLK_F_SCSI));
- qvirtio_set_features(&qvirtio_pci, &dev->vdev, features);
+ qvirtio_set_features(&dev->vdev, features);
- vqpci = (QVirtQueuePCI *)qvirtqueue_setup(&qvirtio_pci, &dev->vdev,
- alloc, 0);
- qvirtqueue_pci_msix_setup(dev, vqpci, alloc, 1);
+ vqpci = (QVirtQueuePCI *)qvirtqueue_setup(&dev->vdev, qs->alloc, 0);
+ qvirtqueue_pci_msix_setup(dev, vqpci, qs->alloc, 1);
- qvirtio_set_driver_ok(&qvirtio_pci, &dev->vdev);
+ qvirtio_set_driver_ok(&dev->vdev);
qmp("{ 'execute': 'block_resize', 'arguments': { 'device': 'drive0', "
" 'size': %d } }", n_size);
- qvirtio_wait_config_isr(&qvirtio_pci, &dev->vdev, QVIRTIO_BLK_TIMEOUT_US);
+ qvirtio_wait_config_isr(&dev->vdev, QVIRTIO_BLK_TIMEOUT_US);
- capacity = qvirtio_config_readq(&qvirtio_pci, &dev->vdev,
- (uint64_t)(uintptr_t)addr);
+ capacity = qvirtio_config_readq(&dev->vdev, 0);
g_assert_cmpint(capacity, ==, n_size / 512);
/* Write request */
@@ -504,22 +473,22 @@ static void pci_msix(void)
req.data = g_malloc0(512);
strcpy(req.data, "TEST");
- req_addr = virtio_blk_request(alloc, &req, 512);
+ req_addr = virtio_blk_request(qs->alloc, &dev->vdev, &req, 512);
g_free(req.data);
free_head = qvirtqueue_add(&vqpci->vq, req_addr, 16, false, true);
qvirtqueue_add(&vqpci->vq, req_addr + 16, 512, false, true);
qvirtqueue_add(&vqpci->vq, req_addr + 528, 1, true, false);
- qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head);
+ qvirtqueue_kick(&dev->vdev, &vqpci->vq, free_head);
- qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
+ qvirtio_wait_queue_isr(&dev->vdev, &vqpci->vq,
QVIRTIO_BLK_TIMEOUT_US);
status = readb(req_addr + 528);
g_assert_cmpint(status, ==, 0);
- guest_free(alloc, req_addr);
+ guest_free(qs->alloc, req_addr);
/* Read request */
req.type = VIRTIO_BLK_T_IN;
@@ -527,7 +496,7 @@ static void pci_msix(void)
req.sector = 0;
req.data = g_malloc0(512);
- req_addr = virtio_blk_request(alloc, &req, 512);
+ req_addr = virtio_blk_request(qs->alloc, &dev->vdev, &req, 512);
g_free(req.data);
@@ -535,10 +504,10 @@ static void pci_msix(void)
qvirtqueue_add(&vqpci->vq, req_addr + 16, 512, true, true);
qvirtqueue_add(&vqpci->vq, req_addr + 528, 1, true, false);
- qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head);
+ qvirtqueue_kick(&dev->vdev, &vqpci->vq, free_head);
- qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
+ qvirtio_wait_queue_isr(&dev->vdev, &vqpci->vq,
QVIRTIO_BLK_TIMEOUT_US);
status = readb(req_addr + 528);
@@ -549,26 +518,22 @@ static void pci_msix(void)
g_assert_cmpstr(data, ==, "TEST");
g_free(data);
- guest_free(alloc, req_addr);
+ guest_free(qs->alloc, req_addr);
/* End test */
- qvirtqueue_cleanup(&qvirtio_pci, &vqpci->vq, alloc);
- pc_alloc_uninit(alloc);
+ qvirtqueue_cleanup(dev->vdev.bus, &vqpci->vq, qs->alloc);
qpci_msix_disable(dev->pdev);
qvirtio_pci_device_disable(dev);
g_free(dev);
- qpci_free_pc(bus);
- test_end();
+ qtest_shutdown(qs);
}
static void pci_idx(void)
{
QVirtioPCIDevice *dev;
- QPCIBus *bus;
+ QOSState *qs;
QVirtQueuePCI *vqpci;
- QGuestAllocator *alloc;
QVirtioBlkReq req;
- void *addr;
uint64_t req_addr;
uint64_t capacity;
uint32_t features;
@@ -576,33 +541,27 @@ static void pci_idx(void)
uint8_t status;
char *data;
- bus = pci_test_start();
- alloc = pc_alloc_init();
+ qs = pci_test_start();
- dev = virtio_blk_pci_init(bus, PCI_SLOT);
+ dev = virtio_blk_pci_init(qs->pcibus, PCI_SLOT);
qpci_msix_enable(dev->pdev);
- qvirtio_pci_set_msix_configuration_vector(dev, alloc, 0);
+ qvirtio_pci_set_msix_configuration_vector(dev, qs->alloc, 0);
- /* MSI-X is enabled */
- addr = dev->addr + VIRTIO_PCI_CONFIG_OFF(true);
-
- capacity = qvirtio_config_readq(&qvirtio_pci, &dev->vdev,
- (uint64_t)(uintptr_t)addr);
+ capacity = qvirtio_config_readq(&dev->vdev, 0);
g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
- features = qvirtio_get_features(&qvirtio_pci, &dev->vdev);
+ features = qvirtio_get_features(&dev->vdev);
features = features & ~(QVIRTIO_F_BAD_FEATURE |
(1u << VIRTIO_RING_F_INDIRECT_DESC) |
(1u << VIRTIO_F_NOTIFY_ON_EMPTY) |
(1u << VIRTIO_BLK_F_SCSI));
- qvirtio_set_features(&qvirtio_pci, &dev->vdev, features);
+ qvirtio_set_features(&dev->vdev, features);
- vqpci = (QVirtQueuePCI *)qvirtqueue_setup(&qvirtio_pci, &dev->vdev,
- alloc, 0);
- qvirtqueue_pci_msix_setup(dev, vqpci, alloc, 1);
+ vqpci = (QVirtQueuePCI *)qvirtqueue_setup(&dev->vdev, qs->alloc, 0);
+ qvirtqueue_pci_msix_setup(dev, vqpci, qs->alloc, 1);
- qvirtio_set_driver_ok(&qvirtio_pci, &dev->vdev);
+ qvirtio_set_driver_ok(&dev->vdev);
/* Write request */
req.type = VIRTIO_BLK_T_OUT;
@@ -611,17 +570,16 @@ static void pci_idx(void)
req.data = g_malloc0(512);
strcpy(req.data, "TEST");
- req_addr = virtio_blk_request(alloc, &req, 512);
+ req_addr = virtio_blk_request(qs->alloc, &dev->vdev, &req, 512);
g_free(req.data);
free_head = qvirtqueue_add(&vqpci->vq, req_addr, 16, false, true);
qvirtqueue_add(&vqpci->vq, req_addr + 16, 512, false, true);
qvirtqueue_add(&vqpci->vq, req_addr + 528, 1, true, false);
- qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head);
+ qvirtqueue_kick(&dev->vdev, &vqpci->vq, free_head);
- qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
- QVIRTIO_BLK_TIMEOUT_US);
+ qvirtio_wait_queue_isr(&dev->vdev, &vqpci->vq, QVIRTIO_BLK_TIMEOUT_US);
/* Write request */
req.type = VIRTIO_BLK_T_OUT;
@@ -630,7 +588,7 @@ static void pci_idx(void)
req.data = g_malloc0(512);
strcpy(req.data, "TEST");
- req_addr = virtio_blk_request(alloc, &req, 512);
+ req_addr = virtio_blk_request(qs->alloc, &dev->vdev, &req, 512);
g_free(req.data);
@@ -639,15 +597,15 @@ static void pci_idx(void)
free_head = qvirtqueue_add(&vqpci->vq, req_addr, 16, false, true);
qvirtqueue_add(&vqpci->vq, req_addr + 16, 512, false, true);
qvirtqueue_add(&vqpci->vq, req_addr + 528, 1, true, false);
- qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head);
+ qvirtqueue_kick(&dev->vdev, &vqpci->vq, free_head);
/* No notification expected */
- status = qvirtio_wait_status_byte_no_isr(&qvirtio_pci, &dev->vdev,
+ status = qvirtio_wait_status_byte_no_isr(&dev->vdev,
&vqpci->vq, req_addr + 528,
QVIRTIO_BLK_TIMEOUT_US);
g_assert_cmpint(status, ==, 0);
- guest_free(alloc, req_addr);
+ guest_free(qs->alloc, req_addr);
/* Read request */
req.type = VIRTIO_BLK_T_IN;
@@ -655,7 +613,7 @@ static void pci_idx(void)
req.sector = 1;
req.data = g_malloc0(512);
- req_addr = virtio_blk_request(alloc, &req, 512);
+ req_addr = virtio_blk_request(qs->alloc, &dev->vdev, &req, 512);
g_free(req.data);
@@ -663,9 +621,9 @@ static void pci_idx(void)
qvirtqueue_add(&vqpci->vq, req_addr + 16, 512, true, true);
qvirtqueue_add(&vqpci->vq, req_addr + 528, 1, true, false);
- qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head);
+ qvirtqueue_kick(&dev->vdev, &vqpci->vq, free_head);
- qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
+ qvirtio_wait_queue_isr(&dev->vdev, &vqpci->vq,
QVIRTIO_BLK_TIMEOUT_US);
status = readb(req_addr + 528);
@@ -676,38 +634,38 @@ static void pci_idx(void)
g_assert_cmpstr(data, ==, "TEST");
g_free(data);
- guest_free(alloc, req_addr);
+ guest_free(qs->alloc, req_addr);
/* End test */
- qvirtqueue_cleanup(&qvirtio_pci, &vqpci->vq, alloc);
- pc_alloc_uninit(alloc);
+ qvirtqueue_cleanup(dev->vdev.bus, &vqpci->vq, qs->alloc);
qpci_msix_disable(dev->pdev);
qvirtio_pci_device_disable(dev);
g_free(dev);
- qpci_free_pc(bus);
- test_end();
+ qtest_shutdown(qs);
}
static void pci_hotplug(void)
{
- QPCIBus *bus;
QVirtioPCIDevice *dev;
+ QOSState *qs;
+ const char *arch = qtest_get_arch();
- bus = pci_test_start();
+ qs = pci_test_start();
/* plug secondary disk */
qpci_plug_device_test("virtio-blk-pci", "drv1", PCI_SLOT_HP,
"'drive': 'drive1'");
- dev = virtio_blk_pci_init(bus, PCI_SLOT_HP);
+ dev = virtio_blk_pci_init(qs->pcibus, PCI_SLOT_HP);
g_assert(dev);
qvirtio_pci_device_disable(dev);
g_free(dev);
/* unplug secondary disk */
- qpci_unplug_acpi_device_test("drv1", PCI_SLOT_HP);
- qpci_free_pc(bus);
- test_end();
+ if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
+ qpci_unplug_acpi_device_test("drv1", PCI_SLOT_HP);
+ }
+ qtest_shutdown(qs);
}
static void mmio_basic(void)
@@ -724,30 +682,27 @@ static void mmio_basic(void)
g_assert(dev != NULL);
g_assert_cmphex(dev->vdev.device_type, ==, VIRTIO_ID_BLOCK);
- qvirtio_reset(&qvirtio_mmio, &dev->vdev);
- qvirtio_set_acknowledge(&qvirtio_mmio, &dev->vdev);
- qvirtio_set_driver(&qvirtio_mmio, &dev->vdev);
+ qvirtio_reset(&dev->vdev);
+ qvirtio_set_acknowledge(&dev->vdev);
+ qvirtio_set_driver(&dev->vdev);
alloc = generic_alloc_init(MMIO_RAM_ADDR, MMIO_RAM_SIZE, MMIO_PAGE_SIZE);
- vq = qvirtqueue_setup(&qvirtio_mmio, &dev->vdev, alloc, 0);
+ vq = qvirtqueue_setup(&dev->vdev, alloc, 0);
- test_basic(&qvirtio_mmio, &dev->vdev, alloc, vq,
- QVIRTIO_MMIO_DEVICE_SPECIFIC);
+ test_basic(&dev->vdev, alloc, vq);
qmp("{ 'execute': 'block_resize', 'arguments': { 'device': 'drive0', "
" 'size': %d } }", n_size);
- qvirtio_wait_queue_isr(&qvirtio_mmio, &dev->vdev, vq,
- QVIRTIO_BLK_TIMEOUT_US);
+ qvirtio_wait_queue_isr(&dev->vdev, vq, QVIRTIO_BLK_TIMEOUT_US);
- capacity = qvirtio_config_readq(&qvirtio_mmio, &dev->vdev,
- QVIRTIO_MMIO_DEVICE_SPECIFIC);
+ capacity = qvirtio_config_readq(&dev->vdev, 0);
g_assert_cmpint(capacity, ==, n_size / 512);
/* End test */
- qvirtqueue_cleanup(&qvirtio_mmio, vq, alloc);
- generic_alloc_uninit(alloc);
+ qvirtqueue_cleanup(dev->vdev.bus, vq, alloc);
g_free(dev);
+ generic_alloc_uninit(alloc);
test_end();
}
@@ -757,12 +712,15 @@ int main(int argc, char **argv)
g_test_init(&argc, &argv, NULL);
- if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
+ if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0 ||
+ strcmp(arch, "ppc64") == 0) {
qtest_add_func("/virtio/blk/pci/basic", pci_basic);
qtest_add_func("/virtio/blk/pci/indirect", pci_indirect);
qtest_add_func("/virtio/blk/pci/config", pci_config);
- qtest_add_func("/virtio/blk/pci/msix", pci_msix);
- qtest_add_func("/virtio/blk/pci/idx", pci_idx);
+ if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
+ qtest_add_func("/virtio/blk/pci/msix", pci_msix);
+ qtest_add_func("/virtio/blk/pci/idx", pci_idx);
+ }
qtest_add_func("/virtio/blk/pci/hotplug", pci_hotplug);
} else if (strcmp(arch, "arm") == 0) {
qtest_add_func("/virtio/blk/mmio/basic", mmio_basic);
diff --git a/tests/virtio-net-test.c b/tests/virtio-net-test.c
index a343a6b048..8f94360480 100644
--- a/tests/virtio-net-test.c
+++ b/tests/virtio-net-test.c
@@ -12,12 +12,10 @@
#include "qemu-common.h"
#include "qemu/sockets.h"
#include "qemu/iov.h"
-#include "libqos/pci-pc.h"
+#include "libqos/libqos-pc.h"
+#include "libqos/libqos-spapr.h"
#include "libqos/virtio.h"
#include "libqos/virtio-pci.h"
-#include "libqos/malloc.h"
-#include "libqos/malloc-pc.h"
-#include "libqos/malloc-generic.h"
#include "qemu/bswap.h"
#include "hw/virtio/virtio-net.h"
#include "standard-headers/linux/virtio_ids.h"
@@ -46,39 +44,43 @@ static QVirtioPCIDevice *virtio_net_pci_init(QPCIBus *bus, int slot)
g_assert_cmphex(dev->vdev.device_type, ==, VIRTIO_ID_NET);
qvirtio_pci_device_enable(dev);
- qvirtio_reset(&qvirtio_pci, &dev->vdev);
- qvirtio_set_acknowledge(&qvirtio_pci, &dev->vdev);
- qvirtio_set_driver(&qvirtio_pci, &dev->vdev);
+ qvirtio_reset(&dev->vdev);
+ qvirtio_set_acknowledge(&dev->vdev);
+ qvirtio_set_driver(&dev->vdev);
return dev;
}
-static QPCIBus *pci_test_start(int socket)
+static QOSState *pci_test_start(int socket)
{
- char *cmdline;
-
- cmdline = g_strdup_printf("-netdev socket,fd=%d,id=hs0 -device "
- "virtio-net-pci,netdev=hs0", socket);
- qtest_start(cmdline);
- g_free(cmdline);
-
- return qpci_init_pc(NULL);
+ const char *arch = qtest_get_arch();
+ const char *cmd = "-netdev socket,fd=%d,id=hs0 -device "
+ "virtio-net-pci,netdev=hs0";
+
+ if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
+ return qtest_pc_boot(cmd, socket);
+ }
+ if (strcmp(arch, "ppc64") == 0) {
+ return qtest_spapr_boot(cmd, socket);
+ }
+ g_printerr("virtio-net tests are only available on x86 or ppc64\n");
+ exit(EXIT_FAILURE);
}
-static void driver_init(const QVirtioBus *bus, QVirtioDevice *dev)
+static void driver_init(QVirtioDevice *dev)
{
uint32_t features;
- features = qvirtio_get_features(bus, dev);
+ features = qvirtio_get_features(dev);
features = features & ~(QVIRTIO_F_BAD_FEATURE |
(1u << VIRTIO_RING_F_INDIRECT_DESC) |
(1u << VIRTIO_RING_F_EVENT_IDX));
- qvirtio_set_features(bus, dev, features);
+ qvirtio_set_features(dev, features);
- qvirtio_set_driver_ok(bus, dev);
+ qvirtio_set_driver_ok(dev);
}
-static void rx_test(const QVirtioBus *bus, QVirtioDevice *dev,
+static void rx_test(QVirtioDevice *dev,
QGuestAllocator *alloc, QVirtQueue *vq,
int socket)
{
@@ -101,19 +103,19 @@ static void rx_test(const QVirtioBus *bus, QVirtioDevice *dev,
req_addr = guest_alloc(alloc, 64);
free_head = qvirtqueue_add(vq, req_addr, 64, true, false);
- qvirtqueue_kick(bus, dev, vq, free_head);
+ qvirtqueue_kick(dev, vq, free_head);
ret = iov_send(socket, iov, 2, 0, sizeof(len) + sizeof(test));
g_assert_cmpint(ret, ==, sizeof(test) + sizeof(len));
- qvirtio_wait_queue_isr(bus, dev, vq, QVIRTIO_NET_TIMEOUT_US);
+ qvirtio_wait_queue_isr(dev, vq, QVIRTIO_NET_TIMEOUT_US);
memread(req_addr + VNET_HDR_SIZE, buffer, sizeof(test));
g_assert_cmpstr(buffer, ==, "TEST");
guest_free(alloc, req_addr);
}
-static void tx_test(const QVirtioBus *bus, QVirtioDevice *dev,
+static void tx_test(QVirtioDevice *dev,
QGuestAllocator *alloc, QVirtQueue *vq,
int socket)
{
@@ -127,9 +129,9 @@ static void tx_test(const QVirtioBus *bus, QVirtioDevice *dev,
memwrite(req_addr + VNET_HDR_SIZE, "TEST", 4);
free_head = qvirtqueue_add(vq, req_addr, 64, false, false);
- qvirtqueue_kick(bus, dev, vq, free_head);
+ qvirtqueue_kick(dev, vq, free_head);
- qvirtio_wait_queue_isr(bus, dev, vq, QVIRTIO_NET_TIMEOUT_US);
+ qvirtio_wait_queue_isr(dev, vq, QVIRTIO_NET_TIMEOUT_US);
guest_free(alloc, req_addr);
ret = qemu_recv(socket, &len, sizeof(len), 0);
@@ -140,7 +142,7 @@ static void tx_test(const QVirtioBus *bus, QVirtioDevice *dev,
g_assert_cmpstr(buffer, ==, "TEST");
}
-static void rx_stop_cont_test(const QVirtioBus *bus, QVirtioDevice *dev,
+static void rx_stop_cont_test(QVirtioDevice *dev,
QGuestAllocator *alloc, QVirtQueue *vq,
int socket)
{
@@ -164,7 +166,7 @@ static void rx_stop_cont_test(const QVirtioBus *bus, QVirtioDevice *dev,
req_addr = guest_alloc(alloc, 64);
free_head = qvirtqueue_add(vq, req_addr, 64, true, false);
- qvirtqueue_kick(bus, dev, vq, free_head);
+ qvirtqueue_kick(dev, vq, free_head);
rsp = qmp("{ 'execute' : 'stop'}");
QDECREF(rsp);
@@ -180,36 +182,34 @@ static void rx_stop_cont_test(const QVirtioBus *bus, QVirtioDevice *dev,
rsp = qmp("{ 'execute' : 'cont'}");
QDECREF(rsp);
- qvirtio_wait_queue_isr(bus, dev, vq, QVIRTIO_NET_TIMEOUT_US);
+ qvirtio_wait_queue_isr(dev, vq, QVIRTIO_NET_TIMEOUT_US);
memread(req_addr + VNET_HDR_SIZE, buffer, sizeof(test));
g_assert_cmpstr(buffer, ==, "TEST");
guest_free(alloc, req_addr);
}
-static void send_recv_test(const QVirtioBus *bus, QVirtioDevice *dev,
+static void send_recv_test(QVirtioDevice *dev,
QGuestAllocator *alloc, QVirtQueue *rvq,
QVirtQueue *tvq, int socket)
{
- rx_test(bus, dev, alloc, rvq, socket);
- tx_test(bus, dev, alloc, tvq, socket);
+ rx_test(dev, alloc, rvq, socket);
+ tx_test(dev, alloc, tvq, socket);
}
-static void stop_cont_test(const QVirtioBus *bus, QVirtioDevice *dev,
+static void stop_cont_test(QVirtioDevice *dev,
QGuestAllocator *alloc, QVirtQueue *rvq,
QVirtQueue *tvq, int socket)
{
- rx_stop_cont_test(bus, dev, alloc, rvq, socket);
+ rx_stop_cont_test(dev, alloc, rvq, socket);
}
static void pci_basic(gconstpointer data)
{
QVirtioPCIDevice *dev;
- QPCIBus *bus;
+ QOSState *qs;
QVirtQueuePCI *tx, *rx;
- QGuestAllocator *alloc;
- void (*func) (const QVirtioBus *bus,
- QVirtioDevice *dev,
+ void (*func) (QVirtioDevice *dev,
QGuestAllocator *alloc,
QVirtQueue *rvq,
QVirtQueue *tvq,
@@ -219,37 +219,37 @@ static void pci_basic(gconstpointer data)
ret = socketpair(PF_UNIX, SOCK_STREAM, 0, sv);
g_assert_cmpint(ret, !=, -1);
- bus = pci_test_start(sv[1]);
- dev = virtio_net_pci_init(bus, PCI_SLOT);
+ qs = pci_test_start(sv[1]);
+ dev = virtio_net_pci_init(qs->pcibus, PCI_SLOT);
- alloc = pc_alloc_init();
- rx = (QVirtQueuePCI *)qvirtqueue_setup(&qvirtio_pci, &dev->vdev,
- alloc, 0);
- tx = (QVirtQueuePCI *)qvirtqueue_setup(&qvirtio_pci, &dev->vdev,
- alloc, 1);
+ rx = (QVirtQueuePCI *)qvirtqueue_setup(&dev->vdev, qs->alloc, 0);
+ tx = (QVirtQueuePCI *)qvirtqueue_setup(&dev->vdev, qs->alloc, 1);
- driver_init(&qvirtio_pci, &dev->vdev);
- func(&qvirtio_pci, &dev->vdev, alloc, &rx->vq, &tx->vq, sv[0]);
+ driver_init(&dev->vdev);
+ func(&dev->vdev, qs->alloc, &rx->vq, &tx->vq, sv[0]);
/* End test */
close(sv[0]);
- qvirtqueue_cleanup(&qvirtio_pci, &tx->vq, alloc);
- qvirtqueue_cleanup(&qvirtio_pci, &rx->vq, alloc);
- pc_alloc_uninit(alloc);
+ qvirtqueue_cleanup(dev->vdev.bus, &tx->vq, qs->alloc);
+ qvirtqueue_cleanup(dev->vdev.bus, &rx->vq, qs->alloc);
qvirtio_pci_device_disable(dev);
g_free(dev->pdev);
g_free(dev);
- qpci_free_pc(bus);
- test_end();
+ qtest_shutdown(qs);
}
#endif
static void hotplug(void)
{
+ const char *arch = qtest_get_arch();
+
qtest_start("-device virtio-net-pci");
qpci_plug_device_test("virtio-net-pci", "net1", PCI_SLOT_HP, NULL);
- qpci_unplug_acpi_device_test("net1", PCI_SLOT_HP);
+
+ if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
+ qpci_unplug_acpi_device_test("net1", PCI_SLOT_HP);
+ }
test_end();
}
diff --git a/tests/virtio-rng-test.c b/tests/virtio-rng-test.c
index e1b26401f9..dcecf77463 100644
--- a/tests/virtio-rng-test.c
+++ b/tests/virtio-rng-test.c
@@ -20,8 +20,13 @@ static void pci_nop(void)
static void hotplug(void)
{
+ const char *arch = qtest_get_arch();
+
qpci_plug_device_test("virtio-rng-pci", "rng1", PCI_SLOT_HP, NULL);
- qpci_unplug_acpi_device_test("rng1", PCI_SLOT_HP);
+
+ if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
+ qpci_unplug_acpi_device_test("rng1", PCI_SLOT_HP);
+ }
}
int main(int argc, char **argv)
diff --git a/tests/virtio-scsi-test.c b/tests/virtio-scsi-test.c
index 79088bb249..69220ef07b 100644
--- a/tests/virtio-scsi-test.c
+++ b/tests/virtio-scsi-test.c
@@ -11,12 +11,10 @@
#include "qemu/osdep.h"
#include "libqtest.h"
#include "block/scsi.h"
+#include "libqos/libqos-pc.h"
+#include "libqos/libqos-spapr.h"
#include "libqos/virtio.h"
#include "libqos/virtio-pci.h"
-#include "libqos/pci-pc.h"
-#include "libqos/malloc.h"
-#include "libqos/malloc-pc.h"
-#include "libqos/malloc-generic.h"
#include "standard-headers/linux/virtio_ids.h"
#include "standard-headers/linux/virtio_pci.h"
#include "standard-headers/linux/virtio_scsi.h"
@@ -29,28 +27,32 @@
typedef struct {
QVirtioDevice *dev;
- QGuestAllocator *alloc;
- QPCIBus *bus;
+ QOSState *qs;
int num_queues;
QVirtQueue *vq[MAX_NUM_QUEUES + 2];
} QVirtIOSCSI;
-static void qvirtio_scsi_start(const char *extra_opts)
+static QOSState *qvirtio_scsi_start(const char *extra_opts)
{
- char *cmdline;
-
- cmdline = g_strdup_printf(
- "-drive id=drv0,if=none,file=/dev/null,format=raw "
- "-device virtio-scsi-pci,id=vs0 "
- "-device scsi-hd,bus=vs0.0,drive=drv0 %s",
- extra_opts ? : "");
- qtest_start(cmdline);
- g_free(cmdline);
+ const char *arch = qtest_get_arch();
+ const char *cmd = "-drive id=drv0,if=none,file=/dev/null,format=raw "
+ "-device virtio-scsi-pci,id=vs0 "
+ "-device scsi-hd,bus=vs0.0,drive=drv0 %s";
+
+ if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
+ return qtest_pc_boot(cmd, extra_opts ? : "");
+ }
+ if (strcmp(arch, "ppc64") == 0) {
+ return qtest_spapr_boot(cmd, extra_opts ? : "");
+ }
+
+ g_printerr("virtio-scsi tests are only available on x86 or ppc64\n");
+ exit(EXIT_FAILURE);
}
-static void qvirtio_scsi_stop(void)
+static void qvirtio_scsi_stop(QOSState *qs)
{
- qtest_end();
+ qtest_shutdown(qs);
}
static void qvirtio_scsi_pci_free(QVirtIOSCSI *vs)
@@ -58,12 +60,12 @@ static void qvirtio_scsi_pci_free(QVirtIOSCSI *vs)
int i;
for (i = 0; i < vs->num_queues + 2; i++) {
- qvirtqueue_cleanup(&qvirtio_pci, vs->vq[i], vs->alloc);
+ qvirtqueue_cleanup(vs->dev->bus, vs->vq[i], vs->qs->alloc);
}
- pc_alloc_uninit(vs->alloc);
qvirtio_pci_device_disable(container_of(vs->dev, QVirtioPCIDevice, vdev));
g_free(vs->dev);
- qpci_free_pc(vs->bus);
+ qvirtio_scsi_stop(vs->qs);
+ g_free(vs);
}
static uint64_t qvirtio_scsi_alloc(QVirtIOSCSI *vs, size_t alloc_size,
@@ -71,7 +73,7 @@ static uint64_t qvirtio_scsi_alloc(QVirtIOSCSI *vs, size_t alloc_size,
{
uint64_t addr;
- addr = guest_alloc(vs->alloc, alloc_size);
+ addr = guest_alloc(vs->qs->alloc, alloc_size);
if (data) {
memwrite(addr, data, alloc_size);
}
@@ -118,8 +120,8 @@ static uint8_t virtio_scsi_do_command(QVirtIOSCSI *vs, const uint8_t *cdb,
qvirtqueue_add(vq, data_in_addr, data_in_len, true, false);
}
- qvirtqueue_kick(&qvirtio_pci, vs->dev, vq, free_head);
- qvirtio_wait_queue_isr(&qvirtio_pci, vs->dev, vq, QVIRTIO_SCSI_TIMEOUT_US);
+ qvirtqueue_kick(vs->dev, vq, free_head);
+ qvirtio_wait_queue_isr(vs->dev, vq, QVIRTIO_SCSI_TIMEOUT_US);
response = readb(resp_addr +
offsetof(struct virtio_scsi_cmd_resp, response));
@@ -128,10 +130,10 @@ static uint8_t virtio_scsi_do_command(QVirtIOSCSI *vs, const uint8_t *cdb,
memread(resp_addr, resp_out, sizeof(*resp_out));
}
- guest_free(vs->alloc, req_addr);
- guest_free(vs->alloc, resp_addr);
- guest_free(vs->alloc, data_in_addr);
- guest_free(vs->alloc, data_out_addr);
+ guest_free(vs->qs->alloc, req_addr);
+ guest_free(vs->qs->alloc, resp_addr);
+ guest_free(vs->qs->alloc, data_in_addr);
+ guest_free(vs->qs->alloc, data_out_addr);
return response;
}
@@ -141,31 +143,29 @@ static QVirtIOSCSI *qvirtio_scsi_pci_init(int slot)
QVirtIOSCSI *vs;
QVirtioPCIDevice *dev;
struct virtio_scsi_cmd_resp resp;
- void *addr;
int i;
vs = g_new0(QVirtIOSCSI, 1);
- vs->alloc = pc_alloc_init();
- vs->bus = qpci_init_pc(NULL);
- dev = qvirtio_pci_device_find(vs->bus, VIRTIO_ID_SCSI);
+ vs->qs = qvirtio_scsi_start("-drive file=blkdebug::null-co://,"
+ "if=none,id=dr1,format=raw,file.align=4k "
+ "-device scsi-disk,drive=dr1,lun=0,scsi-id=1");
+ dev = qvirtio_pci_device_find(vs->qs->pcibus, VIRTIO_ID_SCSI);
vs->dev = (QVirtioDevice *)dev;
g_assert(dev != NULL);
g_assert_cmphex(vs->dev->device_type, ==, VIRTIO_ID_SCSI);
qvirtio_pci_device_enable(dev);
- qvirtio_reset(&qvirtio_pci, vs->dev);
- qvirtio_set_acknowledge(&qvirtio_pci, vs->dev);
- qvirtio_set_driver(&qvirtio_pci, vs->dev);
+ qvirtio_reset(vs->dev);
+ qvirtio_set_acknowledge(vs->dev);
+ qvirtio_set_driver(vs->dev);
- addr = dev->addr + VIRTIO_PCI_CONFIG_OFF(false);
- vs->num_queues = qvirtio_config_readl(&qvirtio_pci, vs->dev,
- (uint64_t)(uintptr_t)addr);
+ vs->num_queues = qvirtio_config_readl(vs->dev, 0);
g_assert_cmpint(vs->num_queues, <, MAX_NUM_QUEUES);
for (i = 0; i < vs->num_queues + 2; i++) {
- vs->vq[i] = qvirtqueue_setup(&qvirtio_pci, vs->dev, vs->alloc, i);
+ vs->vq[i] = qvirtqueue_setup(vs->dev, vs->qs->alloc, i);
}
/* Clear the POWER ON OCCURRED unit attention */
@@ -184,15 +184,18 @@ static QVirtIOSCSI *qvirtio_scsi_pci_init(int slot)
/* Tests only initialization so far. TODO: Replace with functional tests */
static void pci_nop(void)
{
- qvirtio_scsi_start(NULL);
- qvirtio_scsi_stop();
+ QOSState *qs;
+
+ qs = qvirtio_scsi_start(NULL);
+ qvirtio_scsi_stop(qs);
}
static void hotplug(void)
{
QDict *response;
+ QOSState *qs;
- qvirtio_scsi_start("-drive id=drv1,if=none,file=/dev/null,format=raw");
+ qs = qvirtio_scsi_start("-drive id=drv1,if=none,file=/dev/null,format=raw");
response = qmp("{\"execute\": \"device_add\","
" \"arguments\": {"
" \"driver\": \"scsi-hd\","
@@ -214,7 +217,7 @@ static void hotplug(void)
g_assert(qdict_haskey(response, "event"));
g_assert(!strcmp(qdict_get_str(response, "event"), "DEVICE_DELETED"));
QDECREF(response);
- qvirtio_scsi_stop();
+ qvirtio_scsi_stop(qs);
}
/* Test WRITE SAME with the lba not aligned */
@@ -230,9 +233,6 @@ static void test_unaligned_write_same(void)
0x41, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x33, 0x00, 0x00
};
- qvirtio_scsi_start("-drive file=blkdebug::null-co://,if=none,id=dr1"
- ",format=raw,file.align=4k "
- "-device scsi-disk,drive=dr1,lun=0,scsi-id=1");
vs = qvirtio_scsi_pci_init(PCI_SLOT);
g_assert_cmphex(0, ==,
@@ -242,7 +242,6 @@ static void test_unaligned_write_same(void)
virtio_scsi_do_command(vs, write_same_cdb_2, NULL, 0, buf2, 512, NULL));
qvirtio_scsi_pci_free(vs);
- qvirtio_scsi_stop();
}
int main(int argc, char **argv)