All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v5 0/5] tests: enable ohci/uhci/xhci tests on PPC64
@ 2016-10-04 16:44 Laurent Vivier
  2016-10-04 16:44 ` [Qemu-devel] [PATCH v5 1/5] qtest: add read/write accessors with a specific endianness Laurent Vivier
                   ` (4 more replies)
  0 siblings, 5 replies; 7+ messages in thread
From: Laurent Vivier @ 2016-10-04 16:44 UTC (permalink / raw)
  To: qemu-devel
  Cc: thuth, qemu-ppc, Cédric Le Goater, dgibson, Gerd Hoffmann,
	Greg Kurz, Laurent Vivier

This series enables USB tests on PPC64, and for
that implements libqos SPAPR PCI support.

v5:
- Add Cédric's patch providing read/write accessors
  with a specific endianness, and use it
- don't duplicate usb-hcd-uhci-test machine parameters
  and exit gracefully for an unsupported machine

v4:
- rebase on ppc-for-2.8
- move endianness management in pci-spapr.c
  and remove the two useless patches managing that
- Add David's R-b

v3:
- rebase
- minor fixes (commas, comments)
- add Greg's R-b

v2:
- rebase
- revert order in qtest_common_shutdown() to release
  PCI and then memory allocator
- remove useless byte-swapping in qpci-spapr.c
- compute machine endianness on qtest_init()
- introduce target_cpu_to_leXX()/target_cpu_to_beXX()
            target_leXX_to_cpu()/target_beXX_to_cpu()

Cédric Le Goater (1):
  qtest: add read/write accessors with a specific endianness

Laurent Vivier (4):
  libqos: add PPC64 PCI support
  libqos: add PCI management in qtest_vboot()/qtest_shutdown()
  libqos: use generic qtest_shutdown()
  tests: enable ohci/uhci/xhci tests on PPC64

 tests/Makefile.include      |   9 +-
 tests/e1000e-test.c         |   2 +-
 tests/i440fx-test.c         |   2 +-
 tests/ide-test.c            |   2 +-
 tests/ivshmem-test.c        |   2 +-
 tests/libqos/ahci.c         |   2 +-
 tests/libqos/libqos-pc.c    |   8 +-
 tests/libqos/libqos-spapr.c |   8 +-
 tests/libqos/libqos.c       |  32 ++++-
 tests/libqos/libqos.h       |  11 +-
 tests/libqos/pci-pc.c       |  24 +---
 tests/libqos/pci-pc.h       |   3 +-
 tests/libqos/pci-spapr.c    | 282 ++++++++++++++++++++++++++++++++++++++++++++
 tests/libqos/pci-spapr.h    |  17 +++
 tests/libqos/pci.c          |  22 +++-
 tests/libqos/rtas.c         |  45 +++++++
 tests/libqos/rtas.h         |   4 +
 tests/libqtest.c            |  91 ++++++++++++++
 tests/libqtest.h            |  71 +++++++++++
 tests/q35-test.c            |   2 +-
 tests/rtas-test.c           |   2 +-
 tests/rtl8139-test.c        |   2 +-
 tests/tco-test.c            |   2 +-
 tests/usb-hcd-ehci-test.c   |   2 +-
 tests/usb-hcd-uhci-test.c   |  27 +++--
 tests/vhost-user-test.c     |   4 +-
 tests/virtio-9p-test.c      |   2 +-
 tests/virtio-blk-test.c     |   2 +-
 tests/virtio-net-test.c     |   2 +-
 tests/virtio-scsi-test.c    |   2 +-
 30 files changed, 624 insertions(+), 62 deletions(-)
 create mode 100644 tests/libqos/pci-spapr.c
 create mode 100644 tests/libqos/pci-spapr.h

-- 
2.7.4

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Qemu-devel] [PATCH v5 1/5] qtest: add read/write accessors with a specific endianness
  2016-10-04 16:44 [Qemu-devel] [PATCH v5 0/5] tests: enable ohci/uhci/xhci tests on PPC64 Laurent Vivier
@ 2016-10-04 16:44 ` Laurent Vivier
  2016-10-05  5:42   ` Cédric Le Goater
  2016-10-04 16:44 ` [Qemu-devel] [PATCH v5 2/5] libqos: add PPC64 PCI support Laurent Vivier
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 7+ messages in thread
From: Laurent Vivier @ 2016-10-04 16:44 UTC (permalink / raw)
  To: qemu-devel
  Cc: thuth, qemu-ppc, Cédric Le Goater, dgibson, Gerd Hoffmann,
	Greg Kurz, Laurent Vivier

From: Cédric Le Goater <clg@kaod.org>

Some test scenarios require to access memory regions using a specific
endianness, such as a device region, but the current qtest memory
accessors are done in native endian, which means that the values are
byteswapped in qtest if the endianness of the guest and the host are
different.

To maintain the endianness of a value, we need a new set of memory
accessor. This can be done in two ways:

- first, convert the value to the required endianness in libqtest and
  then use the memread/write routines so that qtest accesses the guest
  memory without doing any supplementary byteswapping

- an alternative method would be to handle the byte swapping on the
  qtest side. For that, we would need to extend the read/write
  protocol with an ending word : "native|le|be" and modify the tswap
  calls accordingly under the qtest_process_command() routine.

The result is the same and the first method is simpler.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: Laurent Vivier <lvivier@redhat.com>
---
 tests/libqtest.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 tests/libqtest.h | 71 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 162 insertions(+)

diff --git a/tests/libqtest.c b/tests/libqtest.c
index 6f6bdf1..611f2c3 100644
--- a/tests/libqtest.c
+++ b/tests/libqtest.c
@@ -15,6 +15,7 @@
  *
  */
 #include "qemu/osdep.h"
+#include "qemu/bswap.h"
 #include "libqtest.h"
 
 #include <sys/socket.h>
@@ -688,6 +689,42 @@ void qtest_writeq(QTestState *s, uint64_t addr, uint64_t value)
     qtest_write(s, "writeq", addr, value);
 }
 
+void qtest_writew_be(QTestState *s, uint64_t addr, uint16_t value)
+{
+    value = cpu_to_be16(value);
+    qtest_memread(s, addr, &value, sizeof(value));
+}
+
+void qtest_writel_be(QTestState *s, uint64_t addr, uint32_t value)
+{
+    value = cpu_to_be32(value);
+    qtest_memread(s, addr, &value, sizeof(value));
+}
+
+void qtest_writeq_be(QTestState *s, uint64_t addr, uint64_t value)
+{
+    value = cpu_to_be64(value);
+    qtest_memread(s, addr, &value, sizeof(value));
+}
+
+void qtest_writew_le(QTestState *s, uint64_t addr, uint16_t value)
+{
+    value = cpu_to_le16(value);
+    qtest_memread(s, addr, &value, sizeof(value));
+}
+
+void qtest_writel_le(QTestState *s, uint64_t addr, uint32_t value)
+{
+    value = cpu_to_le32(value);
+    qtest_memread(s, addr, &value, sizeof(value));
+}
+
+void qtest_writeq_le(QTestState *s, uint64_t addr, uint64_t value)
+{
+    value = cpu_to_le64(value);
+    qtest_memread(s, addr, &value, sizeof(value));
+}
+
 static uint64_t qtest_read(QTestState *s, const char *cmd, uint64_t addr)
 {
     gchar **args;
@@ -721,6 +758,60 @@ uint64_t qtest_readq(QTestState *s, uint64_t addr)
     return qtest_read(s, "readq", addr);
 }
 
+uint16_t qtest_readw_be(QTestState *s, uint64_t addr)
+{
+    uint16_t value;
+
+    qtest_memread(s, addr, &value, sizeof(value));
+
+    return be16_to_cpu(value);
+}
+
+uint32_t qtest_readl_be(QTestState *s, uint64_t addr)
+{
+    uint32_t value;
+
+    qtest_memread(s, addr, &value, sizeof(value));
+
+    return be32_to_cpu(value);
+}
+
+uint64_t qtest_readq_be(QTestState *s, uint64_t addr)
+{
+    uint64_t value;
+
+    qtest_memread(s, addr, &value, sizeof(value));
+
+    return be64_to_cpu(value);
+}
+
+uint16_t qtest_readw_le(QTestState *s, uint64_t addr)
+{
+    uint16_t value;
+
+    qtest_memread(s, addr, &value, sizeof(value));
+
+    return le16_to_cpu(value);
+}
+
+uint32_t qtest_readl_le(QTestState *s, uint64_t addr)
+{
+    uint32_t value;
+
+    qtest_memread(s, addr, &value, sizeof(value));
+
+    return le32_to_cpu(value);
+}
+
+uint64_t qtest_readq_le(QTestState *s, uint64_t addr)
+{
+    uint64_t value;
+
+    qtest_memread(s, addr, &value, sizeof(value));
+
+    return le64_to_cpu(value);
+}
+
 static int hex2nib(char ch)
 {
     if (ch >= '0' && ch <= '9') {
diff --git a/tests/libqtest.h b/tests/libqtest.h
index f7402e0..d5c25a9 100644
--- a/tests/libqtest.h
+++ b/tests/libqtest.h
@@ -887,4 +887,75 @@ void qmp_fd_send(int fd, const char *fmt, ...);
 QDict *qmp_fdv(int fd, const char *fmt, va_list ap);
 QDict *qmp_fd(int fd, const char *fmt, ...);
 
+/*
+ * BE/LE read/write accessors
+ */
+uint16_t qtest_readw_be(QTestState *s, uint64_t addr);
+uint32_t qtest_readl_be(QTestState *s, uint64_t addr);
+uint64_t qtest_readq_be(QTestState *s, uint64_t addr);
+
+static inline uint16_t readw_be(uint64_t addr)
+{
+    return qtest_readw_be(global_qtest, addr);
+}
+static inline uint32_t readl_be(uint64_t addr)
+{
+    return qtest_readl_be(global_qtest, addr);
+}
+static inline uint64_t readq_be(uint64_t addr)
+{
+    return qtest_readq_be(global_qtest, addr);
+}
+
+void qtest_writew_be(QTestState *s, uint64_t addr, uint16_t value);
+void qtest_writel_be(QTestState *s, uint64_t addr, uint32_t value);
+void qtest_writeq_be(QTestState *s, uint64_t addr, uint64_t value);
+
+static inline void writew_be(uint64_t addr, uint16_t value)
+{
+    qtest_writew_be(global_qtest, addr, value);
+}
+static inline void writel_be(uint64_t addr, uint32_t value)
+{
+    qtest_writel_be(global_qtest, addr, value);
+}
+static inline void writeq_be(uint64_t addr, uint64_t value)
+{
+    qtest_writeq_be(global_qtest, addr, value);
+}
+
+uint16_t qtest_readw_le(QTestState *s, uint64_t addr);
+uint32_t qtest_readl_le(QTestState *s, uint64_t addr);
+uint64_t qtest_readq_le(QTestState *s, uint64_t addr);
+
+static inline uint16_t readw_le(uint64_t addr)
+{
+    return qtest_readw_le(global_qtest, addr);
+}
+static inline uint32_t readl_le(uint64_t addr)
+{
+    return qtest_readl_le(global_qtest, addr);
+}
+static inline uint64_t readq_le(uint64_t addr)
+{
+    return qtest_readq_le(global_qtest, addr);
+}
+
+void qtest_writew_le(QTestState *s, uint64_t addr, uint16_t value);
+void qtest_writel_le(QTestState *s, uint64_t addr, uint32_t value);
+void qtest_writeq_le(QTestState *s, uint64_t addr, uint64_t value);
+
+static inline void writew_le(uint64_t addr, uint16_t value)
+{
+    qtest_writew_le(global_qtest, addr, value);
+}
+static inline void writel_le(uint64_t addr, uint32_t value)
+{
+    qtest_writel_le(global_qtest, addr, value);
+}
+static inline void writeq_le(uint64_t addr, uint64_t value)
+{
+    qtest_writeq_le(global_qtest, addr, value);
+}
+
 #endif
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [Qemu-devel] [PATCH v5 2/5] libqos: add PPC64 PCI support
  2016-10-04 16:44 [Qemu-devel] [PATCH v5 0/5] tests: enable ohci/uhci/xhci tests on PPC64 Laurent Vivier
  2016-10-04 16:44 ` [Qemu-devel] [PATCH v5 1/5] qtest: add read/write accessors with a specific endianness Laurent Vivier
@ 2016-10-04 16:44 ` Laurent Vivier
  2016-10-04 16:44 ` [Qemu-devel] [PATCH v5 3/5] libqos: add PCI management in qtest_vboot()/qtest_shutdown() Laurent Vivier
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Laurent Vivier @ 2016-10-04 16:44 UTC (permalink / raw)
  To: qemu-devel
  Cc: thuth, qemu-ppc, Cédric Le Goater, dgibson, Gerd Hoffmann,
	Greg Kurz, Laurent Vivier

Signed-off-by: Laurent Vivier <lvivier@redhat.com>
---
 tests/Makefile.include   |   1 +
 tests/libqos/pci-pc.c    |  22 ----
 tests/libqos/pci-spapr.c | 282 +++++++++++++++++++++++++++++++++++++++++++++++
 tests/libqos/pci-spapr.h |  17 +++
 tests/libqos/pci.c       |  22 +++-
 tests/libqos/rtas.c      |  45 ++++++++
 tests/libqos/rtas.h      |   4 +
 7 files changed, 370 insertions(+), 23 deletions(-)
 create mode 100644 tests/libqos/pci-spapr.c
 create mode 100644 tests/libqos/pci-spapr.h

diff --git a/tests/Makefile.include b/tests/Makefile.include
index 77d42d7..8b1c171 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -591,6 +591,7 @@ libqos-obj-y += tests/libqos/i2c.o tests/libqos/libqos.o
 libqos-spapr-obj-y = $(libqos-obj-y) tests/libqos/malloc-spapr.o
 libqos-spapr-obj-y += tests/libqos/libqos-spapr.o
 libqos-spapr-obj-y += tests/libqos/rtas.o
+libqos-spapr-obj-y += tests/libqos/pci-spapr.o
 libqos-pc-obj-y = $(libqos-obj-y) tests/libqos/pci-pc.o
 libqos-pc-obj-y += tests/libqos/malloc-pc.o tests/libqos/libqos-pc.o
 libqos-pc-obj-y += tests/libqos/ahci.o
diff --git a/tests/libqos/pci-pc.c b/tests/libqos/pci-pc.c
index 1ae2d37..82066b8 100644
--- a/tests/libqos/pci-pc.c
+++ b/tests/libqos/pci-pc.c
@@ -255,28 +255,6 @@ void qpci_free_pc(QPCIBus *bus)
     g_free(s);
 }
 
-void qpci_plug_device_test(const char *driver, const char *id,
-                           uint8_t slot, const char *opts)
-{
-    QDict *response;
-    char *cmd;
-
-    cmd = g_strdup_printf("{'execute': 'device_add',"
-                          " 'arguments': {"
-                          "   'driver': '%s',"
-                          "   'addr': '%d',"
-                          "   %s%s"
-                          "   'id': '%s'"
-                          "}}", driver, slot,
-                          opts ? opts : "", opts ? "," : "",
-                          id);
-    response = qmp(cmd);
-    g_free(cmd);
-    g_assert(response);
-    g_assert(!qdict_haskey(response, "error"));
-    QDECREF(response);
-}
-
 void qpci_unplug_acpi_device_test(const char *id, uint8_t slot)
 {
     QDict *response;
diff --git a/tests/libqos/pci-spapr.c b/tests/libqos/pci-spapr.c
new file mode 100644
index 0000000..19a0b22
--- /dev/null
+++ b/tests/libqos/pci-spapr.c
@@ -0,0 +1,282 @@
+/*
+ * libqos PCI bindings for SPAPR
+ *
+ * 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 "libqos/pci-spapr.h"
+#include "libqos/rtas.h"
+
+#include "hw/pci/pci_regs.h"
+
+#include "qemu-common.h"
+#include "qemu/host-utils.h"
+
+
+/* From include/hw/pci-host/spapr.h */
+
+#define SPAPR_PCI_BASE_BUID          0x800000020000000ULL
+
+#define SPAPR_PCI_MEM_WIN_BUS_OFFSET 0x80000000ULL
+
+#define SPAPR_PCI_WINDOW_BASE        0x10000000000ULL
+#define SPAPR_PCI_WINDOW_SPACING     0x1000000000ULL
+#define SPAPR_PCI_MMIO_WIN_OFF       0xA0000000
+#define SPAPR_PCI_MMIO_WIN_SIZE      (SPAPR_PCI_WINDOW_SPACING - \
+                                     SPAPR_PCI_MEM_WIN_BUS_OFFSET)
+#define SPAPR_PCI_IO_WIN_OFF         0x80000000
+#define SPAPR_PCI_IO_WIN_SIZE        0x10000
+
+/* index is the phb index */
+
+#define BUIDBASE(index)              (SPAPR_PCI_BASE_BUID + (index))
+#define PCIBASE(index)               (SPAPR_PCI_WINDOW_BASE + \
+                                      (index) * SPAPR_PCI_WINDOW_SPACING)
+#define IOBASE(index)                (PCIBASE(index) + SPAPR_PCI_IO_WIN_OFF)
+#define MMIOBASE(index)              (PCIBASE(index) + SPAPR_PCI_MMIO_WIN_OFF)
+
+typedef struct QPCIBusSPAPR {
+    QPCIBus bus;
+    QGuestAllocator *alloc;
+
+    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;
+
+/* PCI devices are always little-endian */
+
+static uint8_t qpci_spapr_io_readb(QPCIBus *bus, void *addr)
+{
+    uint64_t port = (uint64_t)addr;
+    uint8_t v;
+    if (port < SPAPR_PCI_IO_WIN_SIZE) {
+        v = readb(IOBASE(0) + port);
+    } else {
+        v = readb(MMIOBASE(0) + port);
+    }
+    return v;
+}
+
+static uint16_t qpci_spapr_io_readw(QPCIBus *bus, void *addr)
+{
+    uint64_t port = (uint64_t)addr;
+    uint16_t v;
+    if (port < SPAPR_PCI_IO_WIN_SIZE) {
+        v = readw_le(IOBASE(0) + port);
+    } else {
+        v = readw_le(MMIOBASE(0) + port);
+    }
+    return v;
+}
+
+static uint32_t qpci_spapr_io_readl(QPCIBus *bus, void *addr)
+{
+    uint64_t port = (uint64_t)addr;
+    uint32_t v;
+    if (port < SPAPR_PCI_IO_WIN_SIZE) {
+        v = readl_le(IOBASE(0) + port);
+    } else {
+        v = readl_le(MMIOBASE(0) + port);
+    }
+    return v;
+}
+
+static void qpci_spapr_io_writeb(QPCIBus *bus, void *addr, uint8_t value)
+{
+    uint64_t port = (uint64_t)addr;
+    if (port < SPAPR_PCI_IO_WIN_SIZE) {
+        writeb(IOBASE(0) + port, value);
+    } else {
+        writeb(MMIOBASE(0) + port, value);
+    }
+}
+
+static void qpci_spapr_io_writew(QPCIBus *bus, void *addr, uint16_t value)
+{
+    uint64_t port = (uint64_t)addr;
+    if (port < SPAPR_PCI_IO_WIN_SIZE) {
+        writew_le(IOBASE(0) + port, value);
+    } else {
+        writew_le(MMIOBASE(0) + port, value);
+    }
+}
+
+static void qpci_spapr_io_writel(QPCIBus *bus, void *addr, uint32_t value)
+{
+    uint64_t port = (uint64_t)addr;
+    if (port < SPAPR_PCI_IO_WIN_SIZE) {
+        writel_le(IOBASE(0) + port, value);
+    } else {
+        writel_le(MMIOBASE(0) + port, value);
+    }
+}
+
+static uint8_t qpci_spapr_config_readb(QPCIBus *bus, int devfn, uint8_t offset)
+{
+    QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
+    uint32_t config_addr = (devfn << 8) | offset;
+    return qrtas_ibm_read_pci_config(s->alloc, BUIDBASE(0),
+                                     config_addr, 1);
+}
+
+static uint16_t qpci_spapr_config_readw(QPCIBus *bus, int devfn, uint8_t offset)
+{
+    QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
+    uint32_t config_addr = (devfn << 8) | offset;
+    return qrtas_ibm_read_pci_config(s->alloc, BUIDBASE(0),
+                                     config_addr, 2);
+}
+
+static uint32_t qpci_spapr_config_readl(QPCIBus *bus, int devfn, uint8_t offset)
+{
+    QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
+    uint32_t config_addr = (devfn << 8) | offset;
+    return qrtas_ibm_read_pci_config(s->alloc, BUIDBASE(0),
+                                     config_addr, 4);
+}
+
+static void qpci_spapr_config_writeb(QPCIBus *bus, int devfn, uint8_t offset,
+                                     uint8_t value)
+{
+    QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
+    uint32_t config_addr = (devfn << 8) | offset;
+    qrtas_ibm_write_pci_config(s->alloc, BUIDBASE(0),
+                               config_addr, 1, value);
+}
+
+static void qpci_spapr_config_writew(QPCIBus *bus, int devfn, uint8_t offset,
+                                     uint16_t value)
+{
+    QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
+    uint32_t config_addr = (devfn << 8) | offset;
+    qrtas_ibm_write_pci_config(s->alloc, BUIDBASE(0),
+                               config_addr, 2, value);
+}
+
+static void qpci_spapr_config_writel(QPCIBus *bus, int devfn, uint8_t offset,
+                                     uint32_t value)
+{
+    QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
+    uint32_t config_addr = (devfn << 8) | offset;
+    qrtas_ibm_write_pci_config(s->alloc, BUIDBASE(0),
+                               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 */
+}
+
+QPCIBus *qpci_init_spapr(QGuestAllocator *alloc)
+{
+    QPCIBusSPAPR *ret;
+
+    ret = g_malloc(sizeof(*ret));
+
+    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.io_writeb = qpci_spapr_io_writeb;
+    ret->bus.io_writew = qpci_spapr_io_writew;
+    ret->bus.io_writel = qpci_spapr_io_writel;
+
+    ret->bus.config_readb = qpci_spapr_config_readb;
+    ret->bus.config_readw = qpci_spapr_config_readw;
+    ret->bus.config_readl = qpci_spapr_config_readl;
+
+    ret->bus.config_writeb = qpci_spapr_config_writeb;
+    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;
+
+    ret->pci_hole_start = 0xC0000000;
+    ret->pci_hole_size = SPAPR_PCI_MMIO_WIN_SIZE;
+    ret->pci_hole_alloc = 0;
+
+    ret->pci_iohole_start = 0xc000;
+    ret->pci_iohole_size = SPAPR_PCI_IO_WIN_SIZE;
+    ret->pci_iohole_alloc = 0;
+
+    return &ret->bus;
+}
+
+void qpci_free_spapr(QPCIBus *bus)
+{
+    QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
+
+    g_free(s);
+}
diff --git a/tests/libqos/pci-spapr.h b/tests/libqos/pci-spapr.h
new file mode 100644
index 0000000..4192126
--- /dev/null
+++ b/tests/libqos/pci-spapr.h
@@ -0,0 +1,17 @@
+/*
+ * libqos PCI bindings for SPAPR
+ *
+ * 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_PCI_SPAPR_H
+#define LIBQOS_PCI_SPAPR_H
+
+#include "libqos/malloc.h"
+#include "libqos/pci.h"
+
+QPCIBus *qpci_init_spapr(QGuestAllocator *alloc);
+void     qpci_free_spapr(QPCIBus *bus);
+
+#endif
diff --git a/tests/libqos/pci.c b/tests/libqos/pci.c
index ed78d91..c3f3382 100644
--- a/tests/libqos/pci.c
+++ b/tests/libqos/pci.c
@@ -263,4 +263,24 @@ void qpci_iounmap(QPCIDevice *dev, void *data)
     dev->bus->iounmap(dev->bus, data);
 }
 
-
+void qpci_plug_device_test(const char *driver, const char *id,
+                           uint8_t slot, const char *opts)
+{
+    QDict *response;
+    char *cmd;
+
+    cmd = g_strdup_printf("{'execute': 'device_add',"
+                          " 'arguments': {"
+                          "   'driver': '%s',"
+                          "   'addr': '%d',"
+                          "   %s%s"
+                          "   'id': '%s'"
+                          "}}", driver, slot,
+                          opts ? opts : "", opts ? "," : "",
+                          id);
+    response = qmp(cmd);
+    g_free(cmd);
+    g_assert(response);
+    g_assert(!qdict_haskey(response, "error"));
+    QDECREF(response);
+}
diff --git a/tests/libqos/rtas.c b/tests/libqos/rtas.c
index 820321a..0269803 100644
--- a/tests/libqos/rtas.c
+++ b/tests/libqos/rtas.c
@@ -69,3 +69,48 @@ int qrtas_get_time_of_day(QGuestAllocator *alloc, struct tm *tm, uint32_t *ns)
 
     return res;
 }
+
+uint32_t qrtas_ibm_read_pci_config(QGuestAllocator *alloc, uint64_t buid,
+                                   uint32_t addr, uint32_t size)
+{
+    int res;
+    uint32_t args[4], ret[2];
+
+    args[0] = addr;
+    args[1] = buid >> 32;
+    args[2] = buid & 0xffffffff;
+    args[3] = size;
+    res = qrtas_call(alloc, "ibm,read-pci-config", 4, args, 2, ret);
+    if (res != 0) {
+        return -1;
+    }
+
+    if (ret[0] != 0) {
+        return -1;
+    }
+
+    return ret[1];
+}
+
+int qrtas_ibm_write_pci_config(QGuestAllocator *alloc, uint64_t buid,
+                               uint32_t addr, uint32_t size, uint32_t val)
+{
+    int res;
+    uint32_t args[5], ret[1];
+
+    args[0] = addr;
+    args[1] = buid >> 32;
+    args[2] = buid & 0xffffffff;
+    args[3] = size;
+    args[4] = val;
+    res = qrtas_call(alloc, "ibm,write-pci-config", 5, args, 1, ret);
+    if (res != 0) {
+        return -1;
+    }
+
+    if (ret[0] != 0) {
+        return -1;
+    }
+
+    return 0;
+}
diff --git a/tests/libqos/rtas.h b/tests/libqos/rtas.h
index a1b60a8..498eb19 100644
--- a/tests/libqos/rtas.h
+++ b/tests/libqos/rtas.h
@@ -8,4 +8,8 @@
 #include "libqos/malloc.h"
 
 int qrtas_get_time_of_day(QGuestAllocator *alloc, struct tm *tm, uint32_t *ns);
+uint32_t qrtas_ibm_read_pci_config(QGuestAllocator *alloc, uint64_t buid,
+                                   uint32_t addr, uint32_t size);
+int qrtas_ibm_write_pci_config(QGuestAllocator *alloc, uint64_t buid,
+                               uint32_t addr, uint32_t size, uint32_t val);
 #endif /* LIBQOS_RTAS_H */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [Qemu-devel] [PATCH v5 3/5] libqos: add PCI management in qtest_vboot()/qtest_shutdown()
  2016-10-04 16:44 [Qemu-devel] [PATCH v5 0/5] tests: enable ohci/uhci/xhci tests on PPC64 Laurent Vivier
  2016-10-04 16:44 ` [Qemu-devel] [PATCH v5 1/5] qtest: add read/write accessors with a specific endianness Laurent Vivier
  2016-10-04 16:44 ` [Qemu-devel] [PATCH v5 2/5] libqos: add PPC64 PCI support Laurent Vivier
@ 2016-10-04 16:44 ` Laurent Vivier
  2016-10-04 16:44 ` [Qemu-devel] [PATCH v5 4/5] libqos: use generic qtest_shutdown() Laurent Vivier
  2016-10-04 16:44 ` [Qemu-devel] [PATCH v5 5/5] tests: enable ohci/uhci/xhci tests on PPC64 Laurent Vivier
  4 siblings, 0 replies; 7+ messages in thread
From: Laurent Vivier @ 2016-10-04 16:44 UTC (permalink / raw)
  To: qemu-devel
  Cc: thuth, qemu-ppc, Cédric Le Goater, dgibson, Gerd Hoffmann,
	Greg Kurz, Laurent Vivier

Signed-off-by: Laurent Vivier <lvivier@redhat.com>
Reviewed-by: Greg Kurz <groug@kaod.org>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
---
 tests/e1000e-test.c         |  2 +-
 tests/i440fx-test.c         |  2 +-
 tests/ide-test.c            |  2 +-
 tests/ivshmem-test.c        |  2 +-
 tests/libqos/ahci.c         |  2 +-
 tests/libqos/libqos-pc.c    |  5 ++++-
 tests/libqos/libqos-spapr.c |  5 ++++-
 tests/libqos/libqos.c       | 21 ++++++++++++++++-----
 tests/libqos/libqos.h       |  3 +++
 tests/libqos/pci-pc.c       |  2 +-
 tests/libqos/pci-pc.h       |  3 ++-
 tests/q35-test.c            |  2 +-
 tests/rtl8139-test.c        |  2 +-
 tests/tco-test.c            |  2 +-
 tests/usb-hcd-ehci-test.c   |  2 +-
 tests/usb-hcd-uhci-test.c   |  2 +-
 tests/vhost-user-test.c     |  4 ++--
 tests/virtio-9p-test.c      |  2 +-
 tests/virtio-blk-test.c     |  2 +-
 tests/virtio-net-test.c     |  2 +-
 tests/virtio-scsi-test.c    |  2 +-
 21 files changed, 46 insertions(+), 25 deletions(-)

diff --git a/tests/e1000e-test.c b/tests/e1000e-test.c
index d497b08..3979b20 100644
--- a/tests/e1000e-test.c
+++ b/tests/e1000e-test.c
@@ -390,7 +390,7 @@ static void data_test_init(e1000e_device *d)
     qtest_start(cmdline);
     g_free(cmdline);
 
-    test_bus = qpci_init_pc();
+    test_bus = qpci_init_pc(NULL);
     g_assert_nonnull(test_bus);
 
     test_alloc = pc_alloc_init();
diff --git a/tests/i440fx-test.c b/tests/i440fx-test.c
index 3542ad1..da2d5a5 100644
--- a/tests/i440fx-test.c
+++ b/tests/i440fx-test.c
@@ -38,7 +38,7 @@ static QPCIBus *test_start_get_bus(const TestData *s)
     cmdline = g_strdup_printf("-smp %d", s->num_cpus);
     qtest_start(cmdline);
     g_free(cmdline);
-    return qpci_init_pc();
+    return qpci_init_pc(NULL);
 }
 
 static void test_i440fx_defaults(gconstpointer opaque)
diff --git a/tests/ide-test.c b/tests/ide-test.c
index 1e51af2..a8a4081 100644
--- a/tests/ide-test.c
+++ b/tests/ide-test.c
@@ -143,7 +143,7 @@ static QPCIDevice *get_pci_device(uint16_t *bmdma_base)
     uint16_t vendor_id, device_id;
 
     if (!pcibus) {
-        pcibus = qpci_init_pc();
+        pcibus = qpci_init_pc(NULL);
     }
 
     /* Find PCI device and verify it's the right one */
diff --git a/tests/ivshmem-test.c b/tests/ivshmem-test.c
index 0957ee7..f36bfe7 100644
--- a/tests/ivshmem-test.c
+++ b/tests/ivshmem-test.c
@@ -105,7 +105,7 @@ static void setup_vm_cmd(IVState *s, const char *cmd, bool msix)
     uint64_t barsize;
 
     s->qtest = qtest_start(cmd);
-    s->pcibus = qpci_init_pc();
+    s->pcibus = qpci_init_pc(NULL);
     s->dev = get_device(s->pcibus);
 
     s->reg_base = qpci_iomap(s->dev, 0, &barsize);
diff --git a/tests/libqos/ahci.c b/tests/libqos/ahci.c
index f3be550..716ab79 100644
--- a/tests/libqos/ahci.c
+++ b/tests/libqos/ahci.c
@@ -128,7 +128,7 @@ QPCIDevice *get_ahci_device(uint32_t *fingerprint)
     uint32_t ahci_fingerprint;
     QPCIBus *pcibus;
 
-    pcibus = qpci_init_pc();
+    pcibus = qpci_init_pc(NULL);
 
     /* Find the AHCI PCI device and verify it's the right one. */
     ahci = qpci_device_find(pcibus, QPCI_DEVFN(0x1F, 0x02));
diff --git a/tests/libqos/libqos-pc.c b/tests/libqos/libqos-pc.c
index df34092..aa17c98 100644
--- a/tests/libqos/libqos-pc.c
+++ b/tests/libqos/libqos-pc.c
@@ -1,10 +1,13 @@
 #include "qemu/osdep.h"
 #include "libqos/libqos-pc.h"
 #include "libqos/malloc-pc.h"
+#include "libqos/pci-pc.h"
 
 static QOSOps qos_ops = {
     .init_allocator = pc_alloc_init_flags,
-    .uninit_allocator = pc_alloc_uninit
+    .uninit_allocator = pc_alloc_uninit,
+    .qpci_init = qpci_init_pc,
+    .qpci_free = qpci_free_pc,
 };
 
 QOSState *qtest_pc_vboot(const char *cmdline_fmt, va_list ap)
diff --git a/tests/libqos/libqos-spapr.c b/tests/libqos/libqos-spapr.c
index f19408b..333e6fb 100644
--- a/tests/libqos/libqos-spapr.c
+++ b/tests/libqos/libqos-spapr.c
@@ -1,10 +1,13 @@
 #include "qemu/osdep.h"
 #include "libqos/libqos-spapr.h"
 #include "libqos/malloc-spapr.h"
+#include "libqos/pci-spapr.h"
 
 static QOSOps qos_ops = {
     .init_allocator = spapr_alloc_init_flags,
-    .uninit_allocator = spapr_alloc_uninit
+    .uninit_allocator = spapr_alloc_uninit,
+    .qpci_init = qpci_init_spapr,
+    .qpci_free = qpci_free_spapr,
 };
 
 QOSState *qtest_spapr_vboot(const char *cmdline_fmt, va_list ap)
diff --git a/tests/libqos/libqos.c b/tests/libqos/libqos.c
index a852dc5..d842bf5 100644
--- a/tests/libqos/libqos.c
+++ b/tests/libqos/libqos.c
@@ -20,8 +20,13 @@ QOSState *qtest_vboot(QOSOps *ops, const char *cmdline_fmt, va_list ap)
     cmdline = g_strdup_vprintf(cmdline_fmt, ap);
     qs->qts = qtest_start(cmdline);
     qs->ops = ops;
-    if (ops && ops->init_allocator) {
-        qs->alloc = ops->init_allocator(ALLOC_NO_FLAGS);
+    if (ops) {
+        if (ops->init_allocator) {
+            qs->alloc = ops->init_allocator(ALLOC_NO_FLAGS);
+        }
+        if (ops->qpci_init && qs->alloc) {
+            qs->pcibus = ops->qpci_init(qs->alloc);
+        }
     }
 
     g_free(cmdline);
@@ -49,9 +54,15 @@ QOSState *qtest_boot(QOSOps *ops, const char *cmdline_fmt, ...)
  */
 void qtest_shutdown(QOSState *qs)
 {
-    if (qs->alloc && qs->ops && qs->ops->uninit_allocator) {
-        qs->ops->uninit_allocator(qs->alloc);
-        qs->alloc = NULL;
+    if (qs->ops) {
+        if (qs->pcibus && qs->ops->qpci_free) {
+            qs->ops->qpci_free(qs->pcibus);
+            qs->pcibus = NULL;
+        }
+        if (qs->alloc && qs->ops->uninit_allocator) {
+            qs->ops->uninit_allocator(qs->alloc);
+            qs->alloc = NULL;
+        }
     }
     qtest_quit(qs->qts);
     g_free(qs);
diff --git a/tests/libqos/libqos.h b/tests/libqos/libqos.h
index 604980d..a9f6990 100644
--- a/tests/libqos/libqos.h
+++ b/tests/libqos/libqos.h
@@ -8,11 +8,14 @@
 typedef struct QOSOps {
     QGuestAllocator *(*init_allocator)(QAllocOpts);
     void (*uninit_allocator)(QGuestAllocator *);
+    QPCIBus *(*qpci_init)(QGuestAllocator *alloc);
+    void (*qpci_free)(QPCIBus *bus);
 } QOSOps;
 
 typedef struct QOSState {
     QTestState *qts;
     QGuestAllocator *alloc;
+    QPCIBus *pcibus;
     QOSOps *ops;
 } QOSState;
 
diff --git a/tests/libqos/pci-pc.c b/tests/libqos/pci-pc.c
index 82066b8..9600ed6 100644
--- a/tests/libqos/pci-pc.c
+++ b/tests/libqos/pci-pc.c
@@ -212,7 +212,7 @@ static void qpci_pc_iounmap(QPCIBus *bus, void *data)
     /* FIXME */
 }
 
-QPCIBus *qpci_init_pc(void)
+QPCIBus *qpci_init_pc(QGuestAllocator *alloc)
 {
     QPCIBusPC *ret;
 
diff --git a/tests/libqos/pci-pc.h b/tests/libqos/pci-pc.h
index 2621179..9479b51 100644
--- a/tests/libqos/pci-pc.h
+++ b/tests/libqos/pci-pc.h
@@ -14,8 +14,9 @@
 #define LIBQOS_PCI_PC_H
 
 #include "libqos/pci.h"
+#include "libqos/malloc.h"
 
-QPCIBus *qpci_init_pc(void);
+QPCIBus *qpci_init_pc(QGuestAllocator *alloc);
 void     qpci_free_pc(QPCIBus *bus);
 
 #endif
diff --git a/tests/q35-test.c b/tests/q35-test.c
index 71538fc..763fe3d 100644
--- a/tests/q35-test.c
+++ b/tests/q35-test.c
@@ -42,7 +42,7 @@ static void test_smram_lock(void)
     QPCIDevice *pcidev;
     QDict *response;
 
-    pcibus = qpci_init_pc();
+    pcibus = qpci_init_pc(NULL);
     g_assert(pcibus != NULL);
 
     pcidev = qpci_device_find(pcibus, 0);
diff --git a/tests/rtl8139-test.c b/tests/rtl8139-test.c
index 13de7ee..c2f601a 100644
--- a/tests/rtl8139-test.c
+++ b/tests/rtl8139-test.c
@@ -35,7 +35,7 @@ static QPCIDevice *get_device(void)
 {
     QPCIDevice *dev;
 
-    pcibus = qpci_init_pc();
+    pcibus = qpci_init_pc(NULL);
     qpci_device_foreach(pcibus, 0x10ec, 0x8139, save_fn, &dev);
     g_assert(dev != NULL);
 
diff --git a/tests/tco-test.c b/tests/tco-test.c
index 0d13aa8..0d201b1 100644
--- a/tests/tco-test.c
+++ b/tests/tco-test.c
@@ -57,7 +57,7 @@ static void test_init(TestData *d)
     qtest_irq_intercept_in(qs, "ioapic");
     g_free(s);
 
-    bus = qpci_init_pc();
+    bus = qpci_init_pc(NULL);
     d->dev = qpci_device_find(bus, QPCI_DEVFN(0x1f, 0x00));
     g_assert(d->dev != NULL);
 
diff --git a/tests/usb-hcd-ehci-test.c b/tests/usb-hcd-ehci-test.c
index eb247ad..a4ceeaa 100644
--- a/tests/usb-hcd-ehci-test.c
+++ b/tests/usb-hcd-ehci-test.c
@@ -56,7 +56,7 @@ static void pci_init(void)
     if (pcibus) {
         return;
     }
-    pcibus = qpci_init_pc();
+    pcibus = qpci_init_pc(NULL);
     g_assert(pcibus != NULL);
 
     qusb_pci_init_one(pcibus, &uhci1, QPCI_DEVFN(0x1d, 0), 4);
diff --git a/tests/usb-hcd-uhci-test.c b/tests/usb-hcd-uhci-test.c
index 5cd59ad..c24063e 100644
--- a/tests/usb-hcd-uhci-test.c
+++ b/tests/usb-hcd-uhci-test.c
@@ -23,7 +23,7 @@ static void test_port(int port)
     struct qhc uhci;
 
     g_assert(port > 0);
-    pcibus = qpci_init_pc();
+    pcibus = qpci_init_pc(NULL);
     g_assert(pcibus != NULL);
     qusb_pci_init_one(pcibus, &uhci, QPCI_DEVFN(0x1d, 0), 4);
     uhci_port_test(&uhci, port - 1, UHCI_PORT_CCS);
diff --git a/tests/vhost-user-test.c b/tests/vhost-user-test.c
index a39846e..d7c48c5 100644
--- a/tests/vhost-user-test.c
+++ b/tests/vhost-user-test.c
@@ -163,7 +163,7 @@ static void init_virtio_dev(TestServer *s)
     QVirtioPCIDevice *dev;
     uint32_t features;
 
-    bus = qpci_init_pc();
+    bus = qpci_init_pc(NULL);
     g_assert_nonnull(bus);
 
     dev = qvirtio_pci_device_find(bus, VIRTIO_ID_NET);
@@ -884,7 +884,7 @@ static void test_multiqueue(void)
     qtest_start(cmd);
     g_free(cmd);
 
-    bus = qpci_init_pc();
+    bus = qpci_init_pc(NULL);
     dev = virtio_net_pci_init(bus, PCI_SLOT);
 
     alloc = pc_alloc_init();
diff --git a/tests/virtio-9p-test.c b/tests/virtio-9p-test.c
index b8fb6cd..e8b2196 100644
--- a/tests/virtio-9p-test.c
+++ b/tests/virtio-9p-test.c
@@ -63,7 +63,7 @@ static QVirtIO9P *qvirtio_9p_pci_init(void)
 
     v9p = g_new0(QVirtIO9P, 1);
     v9p->alloc = pc_alloc_init();
-    v9p->bus = qpci_init_pc();
+    v9p->bus = qpci_init_pc(NULL);
 
     dev = qvirtio_pci_device_find(v9p->bus, VIRTIO_ID_9P);
     g_assert_nonnull(dev);
diff --git a/tests/virtio-blk-test.c b/tests/virtio-blk-test.c
index 811cf75..3c4fecc 100644
--- a/tests/virtio-blk-test.c
+++ b/tests/virtio-blk-test.c
@@ -75,7 +75,7 @@ static QPCIBus *pci_test_start(void)
     g_free(tmp_path);
     g_free(cmdline);
 
-    return qpci_init_pc();
+    return qpci_init_pc(NULL);
 }
 
 static void arm_test_start(void)
diff --git a/tests/virtio-net-test.c b/tests/virtio-net-test.c
index 361506f..a343a6b 100644
--- a/tests/virtio-net-test.c
+++ b/tests/virtio-net-test.c
@@ -62,7 +62,7 @@ static QPCIBus *pci_test_start(int socket)
     qtest_start(cmdline);
     g_free(cmdline);
 
-    return qpci_init_pc();
+    return qpci_init_pc(NULL);
 }
 
 static void driver_init(const QVirtioBus *bus, QVirtioDevice *dev)
diff --git a/tests/virtio-scsi-test.c b/tests/virtio-scsi-test.c
index f1489e6..79088bb 100644
--- a/tests/virtio-scsi-test.c
+++ b/tests/virtio-scsi-test.c
@@ -146,7 +146,7 @@ static QVirtIOSCSI *qvirtio_scsi_pci_init(int slot)
 
     vs = g_new0(QVirtIOSCSI, 1);
     vs->alloc = pc_alloc_init();
-    vs->bus = qpci_init_pc();
+    vs->bus = qpci_init_pc(NULL);
 
     dev = qvirtio_pci_device_find(vs->bus, VIRTIO_ID_SCSI);
     vs->dev = (QVirtioDevice *)dev;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [Qemu-devel] [PATCH v5 4/5] libqos: use generic qtest_shutdown()
  2016-10-04 16:44 [Qemu-devel] [PATCH v5 0/5] tests: enable ohci/uhci/xhci tests on PPC64 Laurent Vivier
                   ` (2 preceding siblings ...)
  2016-10-04 16:44 ` [Qemu-devel] [PATCH v5 3/5] libqos: add PCI management in qtest_vboot()/qtest_shutdown() Laurent Vivier
@ 2016-10-04 16:44 ` Laurent Vivier
  2016-10-04 16:44 ` [Qemu-devel] [PATCH v5 5/5] tests: enable ohci/uhci/xhci tests on PPC64 Laurent Vivier
  4 siblings, 0 replies; 7+ messages in thread
From: Laurent Vivier @ 2016-10-04 16:44 UTC (permalink / raw)
  To: qemu-devel
  Cc: thuth, qemu-ppc, Cédric Le Goater, dgibson, Gerd Hoffmann,
	Greg Kurz, Laurent Vivier

Machine specific shutdown function can be registered by
the machine specific qtest_XXX_boot() if needed.

So we will not have to test twice the architecture (on boot and on
shutdown) if the test can be run on several architectures.

Signed-off-by: Laurent Vivier <lvivier@redhat.com>
Reviewed-by: Greg Kurz <groug@kaod.org>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
---
 tests/libqos/libqos-pc.c    |  3 ++-
 tests/libqos/libqos-spapr.c |  3 ++-
 tests/libqos/libqos.c       | 11 ++++++++++-
 tests/libqos/libqos.h       |  8 ++++++--
 tests/rtas-test.c           |  2 +-
 5 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/tests/libqos/libqos-pc.c b/tests/libqos/libqos-pc.c
index aa17c98..b554758 100644
--- a/tests/libqos/libqos-pc.c
+++ b/tests/libqos/libqos-pc.c
@@ -8,6 +8,7 @@ static QOSOps qos_ops = {
     .uninit_allocator = pc_alloc_uninit,
     .qpci_init = qpci_init_pc,
     .qpci_free = qpci_free_pc,
+    .shutdown = qtest_pc_shutdown,
 };
 
 QOSState *qtest_pc_vboot(const char *cmdline_fmt, va_list ap)
@@ -31,5 +32,5 @@ QOSState *qtest_pc_boot(const char *cmdline_fmt, ...)
 
 void qtest_pc_shutdown(QOSState *qs)
 {
-    return qtest_shutdown(qs);
+    return qtest_common_shutdown(qs);
 }
diff --git a/tests/libqos/libqos-spapr.c b/tests/libqos/libqos-spapr.c
index 333e6fb..a37791e 100644
--- a/tests/libqos/libqos-spapr.c
+++ b/tests/libqos/libqos-spapr.c
@@ -8,6 +8,7 @@ static QOSOps qos_ops = {
     .uninit_allocator = spapr_alloc_uninit,
     .qpci_init = qpci_init_spapr,
     .qpci_free = qpci_free_spapr,
+    .shutdown = qtest_spapr_shutdown,
 };
 
 QOSState *qtest_spapr_vboot(const char *cmdline_fmt, va_list ap)
@@ -29,5 +30,5 @@ QOSState *qtest_spapr_boot(const char *cmdline_fmt, ...)
 
 void qtest_spapr_shutdown(QOSState *qs)
 {
-    return qtest_shutdown(qs);
+    return qtest_common_shutdown(qs);
 }
diff --git a/tests/libqos/libqos.c b/tests/libqos/libqos.c
index d842bf5..7abb482 100644
--- a/tests/libqos/libqos.c
+++ b/tests/libqos/libqos.c
@@ -52,7 +52,7 @@ QOSState *qtest_boot(QOSOps *ops, const char *cmdline_fmt, ...)
 /**
  * Tear down the QEMU instance.
  */
-void qtest_shutdown(QOSState *qs)
+void qtest_common_shutdown(QOSState *qs)
 {
     if (qs->ops) {
         if (qs->pcibus && qs->ops->qpci_free) {
@@ -68,6 +68,15 @@ void qtest_shutdown(QOSState *qs)
     g_free(qs);
 }
 
+void qtest_shutdown(QOSState *qs)
+{
+    if (qs->ops && qs->ops->shutdown) {
+        qs->ops->shutdown(qs);
+    } else {
+        qtest_common_shutdown(qs);
+    }
+}
+
 void set_context(QOSState *s)
 {
     global_qtest = s->qts;
diff --git a/tests/libqos/libqos.h b/tests/libqos/libqos.h
index a9f6990..2319697 100644
--- a/tests/libqos/libqos.h
+++ b/tests/libqos/libqos.h
@@ -5,22 +5,26 @@
 #include "libqos/pci.h"
 #include "libqos/malloc-pc.h"
 
+typedef struct QOSState QOSState;
+
 typedef struct QOSOps {
     QGuestAllocator *(*init_allocator)(QAllocOpts);
     void (*uninit_allocator)(QGuestAllocator *);
     QPCIBus *(*qpci_init)(QGuestAllocator *alloc);
     void (*qpci_free)(QPCIBus *bus);
+    void (*shutdown)(QOSState *);
 } QOSOps;
 
-typedef struct QOSState {
+struct QOSState {
     QTestState *qts;
     QGuestAllocator *alloc;
     QPCIBus *pcibus;
     QOSOps *ops;
-} QOSState;
+};
 
 QOSState *qtest_vboot(QOSOps *ops, const char *cmdline_fmt, va_list ap);
 QOSState *qtest_boot(QOSOps *ops, const char *cmdline_fmt, ...);
+void qtest_common_shutdown(QOSState *qs);
 void qtest_shutdown(QOSState *qs);
 bool have_qemu_img(void);
 void mkimg(const char *file, const char *fmt, unsigned size_mb);
diff --git a/tests/rtas-test.c b/tests/rtas-test.c
index 73c7803..ba0867a 100644
--- a/tests/rtas-test.c
+++ b/tests/rtas-test.c
@@ -22,7 +22,7 @@ static void test_rtas_get_time_of_day(void)
     t2 = mktimegm(&tm);
     g_assert(t2 - t1 < 5); /* 5 sec max to run the test */
 
-    qtest_spapr_shutdown(qs);
+    qtest_shutdown(qs);
 }
 
 int main(int argc, char *argv[])
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [Qemu-devel] [PATCH v5 5/5] tests: enable ohci/uhci/xhci tests on PPC64
  2016-10-04 16:44 [Qemu-devel] [PATCH v5 0/5] tests: enable ohci/uhci/xhci tests on PPC64 Laurent Vivier
                   ` (3 preceding siblings ...)
  2016-10-04 16:44 ` [Qemu-devel] [PATCH v5 4/5] libqos: use generic qtest_shutdown() Laurent Vivier
@ 2016-10-04 16:44 ` Laurent Vivier
  4 siblings, 0 replies; 7+ messages in thread
From: Laurent Vivier @ 2016-10-04 16:44 UTC (permalink / raw)
  To: qemu-devel
  Cc: thuth, qemu-ppc, Cédric Le Goater, dgibson, Gerd Hoffmann,
	Greg Kurz, Laurent Vivier

Signed-off-by: Laurent Vivier <lvivier@redhat.com>
---
 tests/Makefile.include    |  8 +++++++-
 tests/usb-hcd-uhci-test.c | 27 +++++++++++++++++++--------
 2 files changed, 26 insertions(+), 9 deletions(-)

diff --git a/tests/Makefile.include b/tests/Makefile.include
index 8b1c171..c46a32d 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -272,6 +272,12 @@ check-qtest-ppc64-y += tests/postcopy-test$(EXESUF)
 check-qtest-ppc64-y += tests/boot-serial-test$(EXESUF)
 check-qtest-ppc64-y += tests/rtas-test$(EXESUF)
 check-qtest-ppc64-y += tests/pxe-test$(EXESUF)
+check-qtest-ppc64-y += tests/usb-hcd-ohci-test$(EXESUF)
+gcov-files-ppc64-y += hw/usb/hcd-ohci.c
+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-sh4-y = tests/endianness-test$(EXESUF)
 
@@ -597,7 +603,7 @@ libqos-pc-obj-y += tests/libqos/malloc-pc.o tests/libqos/libqos-pc.o
 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-pc-obj-y) tests/libqos/usb.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
 
 tests/device-introspect-test$(EXESUF): tests/device-introspect-test.o
diff --git a/tests/usb-hcd-uhci-test.c b/tests/usb-hcd-uhci-test.c
index c24063e..e956b9c 100644
--- a/tests/usb-hcd-uhci-test.c
+++ b/tests/usb-hcd-uhci-test.c
@@ -9,9 +9,13 @@
 
 #include "qemu/osdep.h"
 #include "libqtest.h"
+#include "libqos/libqos.h"
 #include "libqos/usb.h"
+#include "libqos/libqos-pc.h"
+#include "libqos/libqos-spapr.h"
 #include "hw/usb/uhci-regs.h"
 
+static QOSState *qs;
 
 static void test_uhci_init(void)
 {
@@ -19,13 +23,10 @@ static void test_uhci_init(void)
 
 static void test_port(int port)
 {
-    QPCIBus *pcibus;
     struct qhc uhci;
 
     g_assert(port > 0);
-    pcibus = qpci_init_pc(NULL);
-    g_assert(pcibus != NULL);
-    qusb_pci_init_one(pcibus, &uhci, QPCI_DEVFN(0x1d, 0), 4);
+    qusb_pci_init_one(qs->pcibus, &uhci, QPCI_DEVFN(0x1d, 0), 4);
     uhci_port_test(&uhci, port - 1, UHCI_PORT_CCS);
 }
 
@@ -75,6 +76,10 @@ static void test_usb_storage_hotplug(void)
 
 int main(int argc, char **argv)
 {
+    const char *arch = qtest_get_arch();
+    const char *cmd = "-device piix3-usb-uhci,id=uhci,addr=1d.0"
+                      " -drive id=drive0,if=none,file=/dev/null,format=raw"
+                      " -device usb-tablet,bus=uhci.0,port=1";
     int ret;
 
     g_test_init(&argc, &argv, NULL);
@@ -84,11 +89,17 @@ int main(int argc, char **argv)
     qtest_add_func("/uhci/pci/hotplug", test_uhci_hotplug);
     qtest_add_func("/uhci/pci/hotplug/usb-storage", test_usb_storage_hotplug);
 
-    qtest_start("-device piix3-usb-uhci,id=uhci,addr=1d.0"
-                " -drive id=drive0,if=none,file=/dev/null,format=raw"
-                " -device usb-tablet,bus=uhci.0,port=1");
+    if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
+        qs = qtest_pc_boot(cmd);
+    } else if (strcmp(arch, "ppc64") == 0) {
+        qs = qtest_spapr_boot(cmd);
+    } else {
+        g_printerr("usb-hcd-uhci-test tests are only "
+                   "available on x86 or ppc64\n");
+        exit(EXIT_FAILURE);
+    }
     ret = g_test_run();
-    qtest_end();
+    qtest_shutdown(qs);
 
     return ret;
 }
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [Qemu-devel] [PATCH v5 1/5] qtest: add read/write accessors with a specific endianness
  2016-10-04 16:44 ` [Qemu-devel] [PATCH v5 1/5] qtest: add read/write accessors with a specific endianness Laurent Vivier
@ 2016-10-05  5:42   ` Cédric Le Goater
  0 siblings, 0 replies; 7+ messages in thread
From: Cédric Le Goater @ 2016-10-05  5:42 UTC (permalink / raw)
  To: Laurent Vivier, qemu-devel
  Cc: thuth, qemu-ppc, dgibson, Gerd Hoffmann, Greg Kurz

On 10/04/2016 06:44 PM, Laurent Vivier wrote:
> From: Cédric Le Goater <clg@kaod.org>
> 
> Some test scenarios require to access memory regions using a specific
> endianness, such as a device region, but the current qtest memory
> accessors are done in native endian, which means that the values are
> byteswapped in qtest if the endianness of the guest and the host are
> different.
> 
> To maintain the endianness of a value, we need a new set of memory
> accessor. This can be done in two ways:
> 
> - first, convert the value to the required endianness in libqtest and
>   then use the memread/write routines so that qtest accesses the guest
>   memory without doing any supplementary byteswapping
> 
> - an alternative method would be to handle the byte swapping on the
>   qtest side. For that, we would need to extend the read/write
>   protocol with an ending word : "native|le|be" and modify the tswap
>   calls accordingly under the qtest_process_command() routine.
> 
> The result is the same and the first method is simpler.
> 
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> Signed-off-by: Laurent Vivier <lvivier@redhat.com>


Hello,

There is an issue in my patch in the write ops ... so a v2 is clearly 
needed. Let's see if there are more comments before doing so. 

Thanks,

C. 


> ---
>  tests/libqtest.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  tests/libqtest.h | 71 +++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 162 insertions(+)
> 
> diff --git a/tests/libqtest.c b/tests/libqtest.c
> index 6f6bdf1..611f2c3 100644
> --- a/tests/libqtest.c
> +++ b/tests/libqtest.c
> @@ -15,6 +15,7 @@
>   *
>   */
>  #include "qemu/osdep.h"
> +#include "qemu/bswap.h"
>  #include "libqtest.h"
>  
>  #include <sys/socket.h>
> @@ -688,6 +689,42 @@ void qtest_writeq(QTestState *s, uint64_t addr, uint64_t value)
>      qtest_write(s, "writeq", addr, value);
>  }
>  
> +void qtest_writew_be(QTestState *s, uint64_t addr, uint16_t value)
> +{
> +    value = cpu_to_be16(value);
> +    qtest_memread(s, addr, &value, sizeof(value));
> +}
> +
> +void qtest_writel_be(QTestState *s, uint64_t addr, uint32_t value)
> +{
> +    value = cpu_to_be32(value);
> +    qtest_memread(s, addr, &value, sizeof(value));
> +}
> +
> +void qtest_writeq_be(QTestState *s, uint64_t addr, uint64_t value)
> +{
> +    value = cpu_to_be64(value);
> +    qtest_memread(s, addr, &value, sizeof(value));
> +}
> +
> +void qtest_writew_le(QTestState *s, uint64_t addr, uint16_t value)
> +{
> +    value = cpu_to_le16(value);
> +    qtest_memread(s, addr, &value, sizeof(value));
> +}
> +
> +void qtest_writel_le(QTestState *s, uint64_t addr, uint32_t value)
> +{
> +    value = cpu_to_le32(value);
> +    qtest_memread(s, addr, &value, sizeof(value));
> +}
> +
> +void qtest_writeq_le(QTestState *s, uint64_t addr, uint64_t value)
> +{
> +    value = cpu_to_le64(value);
> +    qtest_memread(s, addr, &value, sizeof(value));
> +}
> +
>  static uint64_t qtest_read(QTestState *s, const char *cmd, uint64_t addr)
>  {
>      gchar **args;
> @@ -721,6 +758,60 @@ uint64_t qtest_readq(QTestState *s, uint64_t addr)
>      return qtest_read(s, "readq", addr);
>  }
>  
> +uint16_t qtest_readw_be(QTestState *s, uint64_t addr)
> +{
> +    uint16_t value;
> +
> +    qtest_memread(s, addr, &value, sizeof(value));
> +
> +    return be16_to_cpu(value);
> +}
> +
> +uint32_t qtest_readl_be(QTestState *s, uint64_t addr)
> +{
> +    uint32_t value;
> +
> +    qtest_memread(s, addr, &value, sizeof(value));
> +
> +    return be32_to_cpu(value);
> +}
> +
> +uint64_t qtest_readq_be(QTestState *s, uint64_t addr)
> +{
> +    uint64_t value;
> +
> +    qtest_memread(s, addr, &value, sizeof(value));
> +
> +    return be64_to_cpu(value);
> +}
> +
> +uint16_t qtest_readw_le(QTestState *s, uint64_t addr)
> +{
> +    uint16_t value;
> +
> +    qtest_memread(s, addr, &value, sizeof(value));
> +
> +    return le16_to_cpu(value);
> +}
> +
> +uint32_t qtest_readl_le(QTestState *s, uint64_t addr)
> +{
> +    uint32_t value;
> +
> +    qtest_memread(s, addr, &value, sizeof(value));
> +
> +    return le32_to_cpu(value);
> +}
> +
> +uint64_t qtest_readq_le(QTestState *s, uint64_t addr)
> +{
> +    uint64_t value;
> +
> +    qtest_memread(s, addr, &value, sizeof(value));
> +
> +    return le64_to_cpu(value);
> +}
> +
>  static int hex2nib(char ch)
>  {
>      if (ch >= '0' && ch <= '9') {
> diff --git a/tests/libqtest.h b/tests/libqtest.h
> index f7402e0..d5c25a9 100644
> --- a/tests/libqtest.h
> +++ b/tests/libqtest.h
> @@ -887,4 +887,75 @@ void qmp_fd_send(int fd, const char *fmt, ...);
>  QDict *qmp_fdv(int fd, const char *fmt, va_list ap);
>  QDict *qmp_fd(int fd, const char *fmt, ...);
>  
> +/*
> + * BE/LE read/write accessors
> + */
> +uint16_t qtest_readw_be(QTestState *s, uint64_t addr);
> +uint32_t qtest_readl_be(QTestState *s, uint64_t addr);
> +uint64_t qtest_readq_be(QTestState *s, uint64_t addr);
> +
> +static inline uint16_t readw_be(uint64_t addr)
> +{
> +    return qtest_readw_be(global_qtest, addr);
> +}
> +static inline uint32_t readl_be(uint64_t addr)
> +{
> +    return qtest_readl_be(global_qtest, addr);
> +}
> +static inline uint64_t readq_be(uint64_t addr)
> +{
> +    return qtest_readq_be(global_qtest, addr);
> +}
> +
> +void qtest_writew_be(QTestState *s, uint64_t addr, uint16_t value);
> +void qtest_writel_be(QTestState *s, uint64_t addr, uint32_t value);
> +void qtest_writeq_be(QTestState *s, uint64_t addr, uint64_t value);
> +
> +static inline void writew_be(uint64_t addr, uint16_t value)
> +{
> +    qtest_writew_be(global_qtest, addr, value);
> +}
> +static inline void writel_be(uint64_t addr, uint32_t value)
> +{
> +    qtest_writel_be(global_qtest, addr, value);
> +}
> +static inline void writeq_be(uint64_t addr, uint64_t value)
> +{
> +    qtest_writeq_be(global_qtest, addr, value);
> +}
> +
> +uint16_t qtest_readw_le(QTestState *s, uint64_t addr);
> +uint32_t qtest_readl_le(QTestState *s, uint64_t addr);
> +uint64_t qtest_readq_le(QTestState *s, uint64_t addr);
> +
> +static inline uint16_t readw_le(uint64_t addr)
> +{
> +    return qtest_readw_le(global_qtest, addr);
> +}
> +static inline uint32_t readl_le(uint64_t addr)
> +{
> +    return qtest_readl_le(global_qtest, addr);
> +}
> +static inline uint64_t readq_le(uint64_t addr)
> +{
> +    return qtest_readq_le(global_qtest, addr);
> +}
> +
> +void qtest_writew_le(QTestState *s, uint64_t addr, uint16_t value);
> +void qtest_writel_le(QTestState *s, uint64_t addr, uint32_t value);
> +void qtest_writeq_le(QTestState *s, uint64_t addr, uint64_t value);
> +
> +static inline void writew_le(uint64_t addr, uint16_t value)
> +{
> +    qtest_writew_le(global_qtest, addr, value);
> +}
> +static inline void writel_le(uint64_t addr, uint32_t value)
> +{
> +    qtest_writel_le(global_qtest, addr, value);
> +}
> +static inline void writeq_le(uint64_t addr, uint64_t value)
> +{
> +    qtest_writeq_le(global_qtest, addr, value);
> +}
> +
>  #endif
> 

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2016-10-05  5:42 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-10-04 16:44 [Qemu-devel] [PATCH v5 0/5] tests: enable ohci/uhci/xhci tests on PPC64 Laurent Vivier
2016-10-04 16:44 ` [Qemu-devel] [PATCH v5 1/5] qtest: add read/write accessors with a specific endianness Laurent Vivier
2016-10-05  5:42   ` Cédric Le Goater
2016-10-04 16:44 ` [Qemu-devel] [PATCH v5 2/5] libqos: add PPC64 PCI support Laurent Vivier
2016-10-04 16:44 ` [Qemu-devel] [PATCH v5 3/5] libqos: add PCI management in qtest_vboot()/qtest_shutdown() Laurent Vivier
2016-10-04 16:44 ` [Qemu-devel] [PATCH v5 4/5] libqos: use generic qtest_shutdown() Laurent Vivier
2016-10-04 16:44 ` [Qemu-devel] [PATCH v5 5/5] tests: enable ohci/uhci/xhci tests on PPC64 Laurent Vivier

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.