From: Paolo Bonzini <pbonzini@redhat.com>
To: qemu-devel@nongnu.org
Cc: Eric Auger <eric.auger@redhat.com>
Subject: [PULL 10/27] tests/qtest/libqos: Add generic pci host bridge in arm-virt machine
Date: Thu, 12 May 2022 19:24:48 +0200 [thread overview]
Message-ID: <20220512172505.1065394-11-pbonzini@redhat.com> (raw)
In-Reply-To: <20220512172505.1065394-1-pbonzini@redhat.com>
From: Eric Auger <eric.auger@redhat.com>
Up to now the virt-machine node contains a virtio-mmio node.
However no driver produces any PCI interface node. Hence, PCI
tests cannot be run with aarch64 binary.
Add a GPEX driver node that produces a pci interface node. This latter
then can be consumed by all the pci tests. One of the first motivation
was to be able to run the virtio-iommu-pci tests.
We still face an issue with pci hotplug tests as hotplug cannot happen
on the pcie root bus and require a generic root port. This will be
addressed later on.
We force cpu=max along with aarch64/virt machine as some PCI tests
require high MMIO regions to be available.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Message-Id: <20220504152025.1785704-4-eric.auger@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
tests/qtest/libqos/arm-virt-machine.c | 19 ++-
tests/qtest/libqos/generic-pcihost.c | 231 ++++++++++++++++++++++++++
tests/qtest/libqos/generic-pcihost.h | 54 ++++++
tests/qtest/libqos/meson.build | 1 +
4 files changed, 301 insertions(+), 4 deletions(-)
create mode 100644 tests/qtest/libqos/generic-pcihost.c
create mode 100644 tests/qtest/libqos/generic-pcihost.h
diff --git a/tests/qtest/libqos/arm-virt-machine.c b/tests/qtest/libqos/arm-virt-machine.c
index 2e0beaefb8..139eaba142 100644
--- a/tests/qtest/libqos/arm-virt-machine.c
+++ b/tests/qtest/libqos/arm-virt-machine.c
@@ -22,6 +22,8 @@
#include "malloc.h"
#include "qgraph.h"
#include "virtio-mmio.h"
+#include "generic-pcihost.h"
+#include "hw/pci/pci_regs.h"
#define ARM_PAGE_SIZE 4096
#define VIRTIO_MMIO_BASE_ADDR 0x0A003E00
@@ -35,6 +37,7 @@ struct QVirtMachine {
QOSGraphObject obj;
QGuestAllocator alloc;
QVirtioMMIODevice virtio_mmio;
+ QGenericPCIHost bridge;
};
static void virt_destructor(QOSGraphObject *obj)
@@ -57,11 +60,13 @@ static void *virt_get_driver(void *object, const char *interface)
static QOSGraphObject *virt_get_device(void *obj, const char *device)
{
QVirtMachine *machine = obj;
- if (!g_strcmp0(device, "virtio-mmio")) {
+ if (!g_strcmp0(device, "generic-pcihost")) {
+ return &machine->bridge.obj;
+ } else if (!g_strcmp0(device, "virtio-mmio")) {
return &machine->virtio_mmio.obj;
}
- fprintf(stderr, "%s not present in arm/virtio\n", device);
+ fprintf(stderr, "%s not present in arm/virt\n", device);
g_assert_not_reached();
}
@@ -76,16 +81,22 @@ static void *qos_create_machine_arm_virt(QTestState *qts)
qvirtio_mmio_init_device(&machine->virtio_mmio, qts, VIRTIO_MMIO_BASE_ADDR,
VIRTIO_MMIO_SIZE);
+ qos_create_generic_pcihost(&machine->bridge, qts, &machine->alloc);
+
machine->obj.get_device = virt_get_device;
machine->obj.get_driver = virt_get_driver;
machine->obj.destructor = virt_destructor;
return machine;
}
-static void virtio_mmio_register_nodes(void)
+static void virt_machine_register_nodes(void)
{
qos_node_create_machine("arm/virt", qos_create_machine_arm_virt);
qos_node_contains("arm/virt", "virtio-mmio", NULL);
+
+ qos_node_create_machine_args("aarch64/virt", qos_create_machine_arm_virt,
+ " -cpu max");
+ qos_node_contains("aarch64/virt", "generic-pcihost", NULL);
}
-libqos_init(virtio_mmio_register_nodes);
+libqos_init(virt_machine_register_nodes);
diff --git a/tests/qtest/libqos/generic-pcihost.c b/tests/qtest/libqos/generic-pcihost.c
new file mode 100644
index 0000000000..3124b0e46b
--- /dev/null
+++ b/tests/qtest/libqos/generic-pcihost.c
@@ -0,0 +1,231 @@
+/*
+ * libqos PCI bindings for generic PCI
+ *
+ * Copyright Red Hat Inc., 2022
+ *
+ * Authors:
+ * Eric Auger <eric.auger@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "../libqtest.h"
+#include "generic-pcihost.h"
+#include "qapi/qmp/qdict.h"
+#include "hw/pci/pci_regs.h"
+#include "qemu/host-utils.h"
+
+#include "qemu/module.h"
+
+/* QGenericPCIHost */
+
+QOSGraphObject *generic_pcihost_get_device(void *obj, const char *device)
+{
+ QGenericPCIHost *host = obj;
+ if (!g_strcmp0(device, "pci-bus-generic")) {
+ return &host->pci.obj;
+ }
+ fprintf(stderr, "%s not present in generic-pcihost\n", device);
+ g_assert_not_reached();
+}
+
+void qos_create_generic_pcihost(QGenericPCIHost *host,
+ QTestState *qts,
+ QGuestAllocator *alloc)
+{
+ host->obj.get_device = generic_pcihost_get_device;
+ qpci_init_generic(&host->pci, qts, alloc, false);
+}
+
+static uint8_t qpci_generic_pio_readb(QPCIBus *bus, uint32_t addr)
+{
+ QGenericPCIBus *s = container_of(bus, QGenericPCIBus, bus);
+
+ return qtest_readb(bus->qts, s->gpex_pio_base + addr);
+}
+
+static void qpci_generic_pio_writeb(QPCIBus *bus, uint32_t addr, uint8_t val)
+{
+ QGenericPCIBus *s = container_of(bus, QGenericPCIBus, bus);
+
+ qtest_writeb(bus->qts, s->gpex_pio_base + addr, val);
+}
+
+static uint16_t qpci_generic_pio_readw(QPCIBus *bus, uint32_t addr)
+{
+ QGenericPCIBus *s = container_of(bus, QGenericPCIBus, bus);
+
+ return qtest_readw(bus->qts, s->gpex_pio_base + addr);
+}
+
+static void qpci_generic_pio_writew(QPCIBus *bus, uint32_t addr, uint16_t val)
+{
+ QGenericPCIBus *s = container_of(bus, QGenericPCIBus, bus);
+
+ qtest_writew(bus->qts, s->gpex_pio_base + addr, val);
+}
+
+static uint32_t qpci_generic_pio_readl(QPCIBus *bus, uint32_t addr)
+{
+ QGenericPCIBus *s = container_of(bus, QGenericPCIBus, bus);
+
+ return qtest_readl(bus->qts, s->gpex_pio_base + addr);
+}
+
+static void qpci_generic_pio_writel(QPCIBus *bus, uint32_t addr, uint32_t val)
+{
+ QGenericPCIBus *s = container_of(bus, QGenericPCIBus, bus);
+
+ qtest_writel(bus->qts, s->gpex_pio_base + addr, val);
+}
+
+static uint64_t qpci_generic_pio_readq(QPCIBus *bus, uint32_t addr)
+{
+ QGenericPCIBus *s = container_of(bus, QGenericPCIBus, bus);
+
+ return qtest_readq(bus->qts, s->gpex_pio_base + addr);
+}
+
+static void qpci_generic_pio_writeq(QPCIBus *bus, uint32_t addr, uint64_t val)
+{
+ QGenericPCIBus *s = container_of(bus, QGenericPCIBus, bus);
+
+ qtest_writeq(bus->qts, s->gpex_pio_base + addr, val);
+}
+
+static void qpci_generic_memread(QPCIBus *bus, uint32_t addr, void *buf, size_t len)
+{
+ qtest_memread(bus->qts, addr, buf, len);
+}
+
+static void qpci_generic_memwrite(QPCIBus *bus, uint32_t addr,
+ const void *buf, size_t len)
+{
+ qtest_memwrite(bus->qts, addr, buf, len);
+}
+
+static uint8_t qpci_generic_config_readb(QPCIBus *bus, int devfn, uint8_t offset)
+{
+ QGenericPCIBus *gbus = container_of(bus, QGenericPCIBus, bus);
+ uint64_t addr = gbus->ecam_alloc_ptr + ((0 << 20) | (devfn << 12) | offset);
+ uint8_t val;
+
+ qtest_memread(bus->qts, addr, &val, 1);
+ return val;
+}
+
+static uint16_t qpci_generic_config_readw(QPCIBus *bus, int devfn, uint8_t offset)
+{
+ QGenericPCIBus *gbus = container_of(bus, QGenericPCIBus, bus);
+ uint64_t addr = gbus->ecam_alloc_ptr + ((0 << 20) | (devfn << 12) | offset);
+ uint16_t val;
+
+ qtest_memread(bus->qts, addr, &val, 2);
+ return le16_to_cpu(val);
+}
+
+static uint32_t qpci_generic_config_readl(QPCIBus *bus, int devfn, uint8_t offset)
+{
+ QGenericPCIBus *gbus = container_of(bus, QGenericPCIBus, bus);
+ uint64_t addr = gbus->ecam_alloc_ptr + ((0 << 20) | (devfn << 12) | offset);
+ uint32_t val;
+
+ qtest_memread(bus->qts, addr, &val, 4);
+ return le32_to_cpu(val);
+}
+
+static void
+qpci_generic_config_writeb(QPCIBus *bus, int devfn, uint8_t offset, uint8_t value)
+{
+ QGenericPCIBus *gbus = container_of(bus, QGenericPCIBus, bus);
+ uint64_t addr = gbus->ecam_alloc_ptr + ((0 << 20) | (devfn << 12) | offset);
+
+ qtest_memwrite(bus->qts, addr, &value, 1);
+}
+
+static void
+qpci_generic_config_writew(QPCIBus *bus, int devfn, uint8_t offset, uint16_t value)
+{
+ QGenericPCIBus *gbus = container_of(bus, QGenericPCIBus, bus);
+ uint64_t addr = gbus->ecam_alloc_ptr + ((0 << 20) | (devfn << 12) | offset);
+ uint16_t val = cpu_to_le16(value);
+
+ qtest_memwrite(bus->qts, addr, &val, 2);
+}
+
+static void
+qpci_generic_config_writel(QPCIBus *bus, int devfn, uint8_t offset, uint32_t value)
+{
+ QGenericPCIBus *gbus = container_of(bus, QGenericPCIBus, bus);
+ uint64_t addr = gbus->ecam_alloc_ptr + ((0 << 20) | (devfn << 12) | offset);
+ uint32_t val = cpu_to_le32(value);
+
+ qtest_memwrite(bus->qts, addr, &val, 4);
+}
+
+static void *qpci_generic_get_driver(void *obj, const char *interface)
+{
+ QGenericPCIBus *qpci = obj;
+ if (!g_strcmp0(interface, "pci-bus")) {
+ return &qpci->bus;
+ }
+ fprintf(stderr, "%s not present in pci-bus-generic\n", interface);
+ g_assert_not_reached();
+}
+
+void qpci_init_generic(QGenericPCIBus *qpci, QTestState *qts,
+ QGuestAllocator *alloc, bool hotpluggable)
+{
+ assert(qts);
+
+ qpci->gpex_pio_base = 0x3eff0000;
+ qpci->bus.not_hotpluggable = !hotpluggable;
+ qpci->bus.has_buggy_msi = false;
+
+ qpci->bus.pio_readb = qpci_generic_pio_readb;
+ qpci->bus.pio_readw = qpci_generic_pio_readw;
+ qpci->bus.pio_readl = qpci_generic_pio_readl;
+ qpci->bus.pio_readq = qpci_generic_pio_readq;
+
+ qpci->bus.pio_writeb = qpci_generic_pio_writeb;
+ qpci->bus.pio_writew = qpci_generic_pio_writew;
+ qpci->bus.pio_writel = qpci_generic_pio_writel;
+ qpci->bus.pio_writeq = qpci_generic_pio_writeq;
+
+ qpci->bus.memread = qpci_generic_memread;
+ qpci->bus.memwrite = qpci_generic_memwrite;
+
+ qpci->bus.config_readb = qpci_generic_config_readb;
+ qpci->bus.config_readw = qpci_generic_config_readw;
+ qpci->bus.config_readl = qpci_generic_config_readl;
+
+ qpci->bus.config_writeb = qpci_generic_config_writeb;
+ qpci->bus.config_writew = qpci_generic_config_writew;
+ qpci->bus.config_writel = qpci_generic_config_writel;
+
+ qpci->bus.qts = qts;
+ qpci->bus.pio_alloc_ptr = 0x0000;
+ qpci->bus.pio_limit = 0x10000;
+ qpci->bus.mmio_alloc_ptr = 0x10000000;
+ qpci->bus.mmio_limit = 0x2eff0000;
+ qpci->ecam_alloc_ptr = 0x4010000000;
+
+ qpci->obj.get_driver = qpci_generic_get_driver;
+}
+
+static void qpci_generic_register_nodes(void)
+{
+ qos_node_create_driver("pci-bus-generic", NULL);
+ qos_node_produces("pci-bus-generic", "pci-bus");
+}
+
+static void qpci_generic_pci_register_nodes(void)
+{
+ qos_node_create_driver("generic-pcihost", NULL);
+ qos_node_contains("generic-pcihost", "pci-bus-generic", NULL);
+}
+
+libqos_init(qpci_generic_register_nodes);
+libqos_init(qpci_generic_pci_register_nodes);
diff --git a/tests/qtest/libqos/generic-pcihost.h b/tests/qtest/libqos/generic-pcihost.h
new file mode 100644
index 0000000000..c693c769df
--- /dev/null
+++ b/tests/qtest/libqos/generic-pcihost.h
@@ -0,0 +1,54 @@
+/*
+ * libqos Generic PCI bindings and generic pci host bridge
+ *
+ * Copyright Red Hat Inc., 2022
+ *
+ * Authors:
+ * Eric Auger <eric.auger@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef LIBQOS_GENERIC_PCIHOST_H
+#define LIBQOS_GENERIC_PCIHOST_H
+
+#include "pci.h"
+#include "malloc.h"
+#include "qgraph.h"
+
+typedef struct QGenericPCIBus {
+ QOSGraphObject obj;
+ QPCIBus bus;
+ uint64_t gpex_pio_base;
+ uint64_t ecam_alloc_ptr;
+} QGenericPCIBus;
+
+/*
+ * qpci_init_generic():
+ * @ret: A valid QGenericPCIBus * pointer
+ * @qts: The %QTestState
+ * @alloc: A previously initialized @alloc providing memory for @qts
+ * @bool: devices can be hotplugged on this bus
+ *
+ * This function initializes an already allocated
+ * QGenericPCIBus object.
+ */
+void qpci_init_generic(QGenericPCIBus *ret, QTestState *qts,
+ QGuestAllocator *alloc, bool hotpluggable);
+
+/* QGenericPCIHost */
+
+typedef struct QGenericPCIHost QGenericPCIHost;
+
+struct QGenericPCIHost {
+ QOSGraphObject obj;
+ QGenericPCIBus pci;
+};
+
+QOSGraphObject *generic_pcihost_get_device(void *obj, const char *device);
+void qos_create_generic_pcihost(QGenericPCIHost *host,
+ QTestState *qts,
+ QGuestAllocator *alloc);
+
+#endif
diff --git a/tests/qtest/libqos/meson.build b/tests/qtest/libqos/meson.build
index 9f292339f9..fd5d6e5ae1 100644
--- a/tests/qtest/libqos/meson.build
+++ b/tests/qtest/libqos/meson.build
@@ -45,6 +45,7 @@ libqos_srcs = files(
'virtio-scsi.c',
'virtio-serial.c',
'virtio-iommu.c',
+ 'generic-pcihost.c',
# qgraph machines:
'aarch64-xlnx-zcu102-machine.c',
--
2.36.0
next prev parent reply other threads:[~2022-05-12 17:40 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-05-12 17:24 [PULL 00/27] Misc patches for 2022-05-12 Paolo Bonzini
2022-05-12 17:24 ` [PULL 01/27] pc-bios/optionrom: detect -fno-pie Paolo Bonzini
2022-05-12 17:24 ` [PULL 02/27] pc-bios/optionrom: compile with -Wno-array-bounds Paolo Bonzini
2022-05-12 17:24 ` [PULL 03/27] target/i386: do not consult nonexistent host leaves Paolo Bonzini
2022-05-12 17:24 ` [PULL 04/27] checkpatch: fix g_malloc check Paolo Bonzini
2022-05-12 17:24 ` [PULL 05/27] meson: Make mremap() detecting works correctly Paolo Bonzini
2022-05-12 17:24 ` [PULL 06/27] hw/xen/xen_pt: Confine igd-passthrough-isa-bridge to XEN Paolo Bonzini
2022-05-12 17:24 ` [PULL 07/27] hw/xen/xen_pt: Resolve igd_passthrough_isa_bridge_create() indirection Paolo Bonzini
2022-05-12 17:24 ` [PULL 08/27] tests/qtest/libqos/pci: Introduce pio_limit Paolo Bonzini
2022-05-12 17:24 ` [PULL 09/27] tests/qtest/libqos: Skip hotplug tests if pci root bus is not hotpluggable Paolo Bonzini
2022-05-12 17:24 ` Paolo Bonzini [this message]
2022-05-12 17:24 ` [PULL 11/27] machine: use QAPI struct for boot configuration Paolo Bonzini
2022-05-12 17:24 ` [PULL 12/27] machine: add boot compound property Paolo Bonzini
2022-05-12 17:24 ` [PULL 13/27] machine: add mem " Paolo Bonzini
2022-06-13 13:42 ` Markus Armbruster
2022-08-05 9:30 ` Regression in -readconfig [memory] size (was: [PULL 13/27] machine: add mem compound property) Markus Armbruster
2022-08-05 9:42 ` Paolo Bonzini
2022-08-05 9:51 ` Daniel P. Berrangé
2022-05-12 17:24 ` [PULL 14/27] machine: make memory-backend a link property Paolo Bonzini
2022-05-12 17:24 ` [PULL 15/27] machine: move more memory validation to Machine object Paolo Bonzini
2022-05-12 17:24 ` [PULL 16/27] slirp: bump submodule past 4.7 release Paolo Bonzini
2022-05-12 17:24 ` [PULL 17/27] net: slirp: introduce a wrapper struct for QemuTimer Paolo Bonzini
2022-05-12 17:24 ` [PULL 18/27] net: slirp: switch to slirp_new Paolo Bonzini
2022-05-12 17:24 ` [PULL 19/27] net: slirp: add support for CFI-friendly timer API Paolo Bonzini
2022-05-12 17:24 ` [PULL 20/27] net: slirp: allow CFI with libslirp >= 4.7 Paolo Bonzini
2022-05-12 17:24 ` [PULL 21/27] coroutine-lock: qemu_co_queue_next is a coroutine-only qemu_co_enter_next Paolo Bonzini
2022-05-12 17:25 ` [PULL 22/27] coroutine-lock: introduce qemu_co_queue_enter_all Paolo Bonzini
2022-05-12 17:25 ` [PULL 23/27] coroutine-lock: qemu_co_queue_restart_all is a coroutine-only qemu_co_enter_all Paolo Bonzini
2022-05-12 17:25 ` [PULL 24/27] vhost-backend: do not depend on CONFIG_VHOST_VSOCK Paolo Bonzini
2022-05-12 17:25 ` [PULL 25/27] meson: link libpng independent of vnc Paolo Bonzini
2022-05-12 17:25 ` [PULL 26/27] vl: make machine type deprecation a warning Paolo Bonzini
2022-05-12 17:25 ` [PULL 27/27] vmxcap: add tertiary execution controls Paolo Bonzini
2022-05-12 21:14 ` [PULL 00/27] Misc patches for 2022-05-12 Richard Henderson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220512172505.1065394-11-pbonzini@redhat.com \
--to=pbonzini@redhat.com \
--cc=eric.auger@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).