All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v2 0/6] tests: enable ohci/uhci/xhci tests on PPC64
@ 2016-09-27 18:55 Laurent Vivier
  2016-09-27 18:55 ` [Qemu-devel] [PATCH v2 1/6] libqos: add PPC64 PCI support Laurent Vivier
                   ` (6 more replies)
  0 siblings, 7 replies; 16+ messages in thread
From: Laurent Vivier @ 2016-09-27 18:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: dgibson, thuth, qemu-ppc, Gerd Hoffmann, Greg Kurz, Laurent Vivier

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

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()

Laurent Vivier (6):
  libqos: add PPC64 PCI support
  libqos: add PCI management in qtest_vboot()/qtest_shutdown()
  libqos: use generic qtest_shutdown()
  qtest: evaluate endianness of the target in qtest_init()
  qtest: define target cpu endianness conversion function
  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    | 280 ++++++++++++++++++++++++++++++++++++++++++++
 tests/libqos/pci-spapr.h    |  17 +++
 tests/libqos/pci.c          |  22 +++-
 tests/libqos/rtas.c         |  45 +++++++
 tests/libqos/rtas.h         |   4 +
 tests/libqos/usb.c          |   2 +-
 tests/libqos/virtio-pci.c   |   2 +-
 tests/libqtest.c            |  96 ++++++++-------
 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   |  24 ++--
 tests/vhost-user-test.c     |   4 +-
 tests/virtio-9p-test.c      |   2 +-
 tests/virtio-blk-test.c     |   4 +-
 tests/virtio-net-test.c     |   2 +-
 tests/virtio-scsi-test.c    |   2 +-
 32 files changed, 580 insertions(+), 112 deletions(-)
 create mode 100644 tests/libqos/pci-spapr.c
 create mode 100644 tests/libqos/pci-spapr.h

-- 
2.5.5

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

* [Qemu-devel] [PATCH v2 1/6] libqos: add PPC64 PCI support
  2016-09-27 18:55 [Qemu-devel] [PATCH v2 0/6] tests: enable ohci/uhci/xhci tests on PPC64 Laurent Vivier
@ 2016-09-27 18:55 ` Laurent Vivier
  2016-09-27 18:55 ` [Qemu-devel] [PATCH v2 2/6] libqos: add PCI management in qtest_vboot()/qtest_shutdown() Laurent Vivier
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 16+ messages in thread
From: Laurent Vivier @ 2016-09-27 18:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: dgibson, thuth, qemu-ppc, 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 | 280 +++++++++++++++++++++++++++++++++++++++++++++++
 tests/libqos/pci-spapr.h |  17 +++
 tests/libqos/pci.c       |  22 +++-
 tests/libqos/rtas.c      |  45 ++++++++
 tests/libqos/rtas.h      |   4 +
 7 files changed, 368 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 2aa78c1..bca2cbc 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -589,6 +589,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..78df823
--- /dev/null
+++ b/tests/libqos/pci-spapr.c
@@ -0,0 +1,280 @@
+/*
+ * 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;
+
+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(IOBASE(0) + port);
+    } else {
+        v = readw(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(IOBASE(0) + port);
+    } else {
+        v = readl(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(IOBASE(0) + port, value);
+    } else {
+        writew(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(IOBASE(0) + port, value);
+    } else {
+        writel(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.5.5

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

* [Qemu-devel] [PATCH v2 2/6] libqos: add PCI management in qtest_vboot()/qtest_shutdown()
  2016-09-27 18:55 [Qemu-devel] [PATCH v2 0/6] tests: enable ohci/uhci/xhci tests on PPC64 Laurent Vivier
  2016-09-27 18:55 ` [Qemu-devel] [PATCH v2 1/6] libqos: add PPC64 PCI support Laurent Vivier
@ 2016-09-27 18:55 ` Laurent Vivier
  2016-09-28  6:46   ` Greg Kurz
  2016-09-27 18:55 ` [Qemu-devel] [PATCH v2 3/6] libqos: use generic qtest_shutdown() Laurent Vivier
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 16+ messages in thread
From: Laurent Vivier @ 2016-09-27 18:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: dgibson, thuth, qemu-ppc, Gerd Hoffmann, Greg Kurz, Laurent Vivier

Signed-off-by: Laurent Vivier <lvivier@redhat.com>
---
 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..125c6b3 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.5.5

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

* [Qemu-devel] [PATCH v2 3/6] libqos: use generic qtest_shutdown()
  2016-09-27 18:55 [Qemu-devel] [PATCH v2 0/6] tests: enable ohci/uhci/xhci tests on PPC64 Laurent Vivier
  2016-09-27 18:55 ` [Qemu-devel] [PATCH v2 1/6] libqos: add PPC64 PCI support Laurent Vivier
  2016-09-27 18:55 ` [Qemu-devel] [PATCH v2 2/6] libqos: add PCI management in qtest_vboot()/qtest_shutdown() Laurent Vivier
@ 2016-09-27 18:55 ` Laurent Vivier
  2016-09-28  6:56   ` Greg Kurz
  2016-09-27 18:55 ` [Qemu-devel] [PATCH v2 4/6] qtest: evaluate endianness of the target in qtest_init() Laurent Vivier
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 16+ messages in thread
From: Laurent Vivier @ 2016-09-27 18:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: dgibson, thuth, qemu-ppc, 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>
---
 tests/libqos/libqos-pc.c    |  3 ++-
 tests/libqos/libqos-spapr.c |  5 +++--
 tests/libqos/libqos.c       | 11 ++++++++++-
 tests/libqos/libqos.h       |  8 ++++++--
 tests/rtas-test.c           |  2 +-
 5 files changed, 22 insertions(+), 7 deletions(-)

diff --git a/tests/libqos/libqos-pc.c b/tests/libqos/libqos-pc.c
index aa17c98..219824d 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 125c6b3..8f7fc14 100644
--- a/tests/libqos/libqos-spapr.c
+++ b/tests/libqos/libqos-spapr.c
@@ -7,7 +7,8 @@ static QOSOps qos_ops = {
     .init_allocator = spapr_alloc_init_flags,
     .uninit_allocator = spapr_alloc_uninit,
     .qpci_init = qpci_init_spapr,
-    .qpci_free = qpci_free_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.5.5

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

* [Qemu-devel] [PATCH v2 4/6] qtest: evaluate endianness of the target in qtest_init()
  2016-09-27 18:55 [Qemu-devel] [PATCH v2 0/6] tests: enable ohci/uhci/xhci tests on PPC64 Laurent Vivier
                   ` (2 preceding siblings ...)
  2016-09-27 18:55 ` [Qemu-devel] [PATCH v2 3/6] libqos: use generic qtest_shutdown() Laurent Vivier
@ 2016-09-27 18:55 ` Laurent Vivier
  2016-09-28  8:08   ` Greg Kurz
  2016-09-27 18:55 ` [Qemu-devel] [PATCH v2 5/6] qtest: define target cpu endianness conversion function Laurent Vivier
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 16+ messages in thread
From: Laurent Vivier @ 2016-09-27 18:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: dgibson, thuth, qemu-ppc, Gerd Hoffmann, Greg Kurz, Laurent Vivier

This allows to store it and not have to rescan the list
each time we need it.

Signed-off-by: Laurent Vivier <lvivier@redhat.com>
---
 tests/libqos/virtio-pci.c |  2 +-
 tests/libqtest.c          | 96 +++++++++++++++++++++++++----------------------
 tests/libqtest.h          | 16 ++++++--
 tests/virtio-blk-test.c   |  2 +-
 4 files changed, 66 insertions(+), 50 deletions(-)

diff --git a/tests/libqos/virtio-pci.c b/tests/libqos/virtio-pci.c
index 18b92b9..6e005c1 100644
--- a/tests/libqos/virtio-pci.c
+++ b/tests/libqos/virtio-pci.c
@@ -86,7 +86,7 @@ static uint64_t qvirtio_pci_config_readq(QVirtioDevice *d, uint64_t addr)
     int i;
     uint64_t u64 = 0;
 
-    if (qtest_big_endian()) {
+    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;
diff --git a/tests/libqtest.c b/tests/libqtest.c
index 6f6bdf1..aa4bc9e 100644
--- a/tests/libqtest.c
+++ b/tests/libqtest.c
@@ -37,6 +37,7 @@ struct QTestState
     bool irq_level[MAX_IRQ];
     GString *rx;
     pid_t qemu_pid;  /* our child QEMU process */
+    bool big_endian;
 };
 
 static GHookList abrt_hooks;
@@ -146,6 +147,52 @@ void qtest_add_abrt_handler(GHookFunc fn, const void *data)
     g_hook_prepend(&abrt_hooks, hook);
 }
 
+static bool arch_is_big_endian(const char *arch)
+{
+    int i;
+    static const struct {
+        const char *arch;
+        bool big_endian;
+    } endianness[] = {
+        { "aarch64", false },
+        { "alpha", false },
+        { "arm", false },
+        { "cris", false },
+        { "i386", false },
+        { "lm32", true },
+        { "m68k", true },
+        { "microblaze", true },
+        { "microblazeel", false },
+        { "mips", true },
+        { "mips64", true },
+        { "mips64el", false },
+        { "mipsel", false },
+        { "moxie", true },
+        { "or32", true },
+        { "ppc", true },
+        { "ppc64", true },
+        { "ppcemb", true },
+        { "s390x", true },
+        { "sh4", false },
+        { "sh4eb", true },
+        { "sparc", true },
+        { "sparc64", true },
+        { "unicore32", false },
+        { "x86_64", false },
+        { "xtensa", false },
+        { "xtensaeb", true },
+        { "tricore", false },
+        {},
+    };
+
+    for (i = 0; endianness[i].arch; i++) {
+        if (strcmp(endianness[i].arch, arch) == 0) {
+            return endianness[i].big_endian;
+        }
+    }
+    g_assert_not_reached();
+}
+
 QTestState *qtest_init(const char *extra_args)
 {
     QTestState *s;
@@ -209,6 +256,8 @@ QTestState *qtest_init(const char *extra_args)
         kill(s->qemu_pid, SIGSTOP);
     }
 
+    s->big_endian = arch_is_big_endian(qtest_get_arch());
+
     return s;
 }
 
@@ -886,50 +935,7 @@ char *hmp(const char *fmt, ...)
     return ret;
 }
 
-bool qtest_big_endian(void)
+bool qtest_big_endian(QTestState *s)
 {
-    const char *arch = qtest_get_arch();
-    int i;
-
-    static const struct {
-        const char *arch;
-        bool big_endian;
-    } endianness[] = {
-        { "aarch64", false },
-        { "alpha", false },
-        { "arm", false },
-        { "cris", false },
-        { "i386", false },
-        { "lm32", true },
-        { "m68k", true },
-        { "microblaze", true },
-        { "microblazeel", false },
-        { "mips", true },
-        { "mips64", true },
-        { "mips64el", false },
-        { "mipsel", false },
-        { "moxie", true },
-        { "or32", true },
-        { "ppc", true },
-        { "ppc64", true },
-        { "ppcemb", true },
-        { "s390x", true },
-        { "sh4", false },
-        { "sh4eb", true },
-        { "sparc", true },
-        { "sparc64", true },
-        { "unicore32", false },
-        { "x86_64", false },
-        { "xtensa", false },
-        { "xtensaeb", true },
-        {},
-    };
-
-    for (i = 0; endianness[i].arch; i++) {
-        if (strcmp(endianness[i].arch, arch) == 0) {
-            return endianness[i].big_endian;
-        }
-    }
-
-    return false;
+    return s->big_endian;
 }
diff --git a/tests/libqtest.h b/tests/libqtest.h
index f7402e0..4be1f77 100644
--- a/tests/libqtest.h
+++ b/tests/libqtest.h
@@ -410,6 +410,14 @@ int64_t qtest_clock_step(QTestState *s, int64_t step);
 int64_t qtest_clock_set(QTestState *s, int64_t val);
 
 /**
+ * qtest_big_endian:
+ * @s: QTestState instance to operate on.
+ *
+ * Returns: True if the architecture under test has a big endian configuration.
+ */
+bool qtest_big_endian(QTestState *s);
+
+/**
  * qtest_get_arch:
  *
  * Returns: The architecture for the QEMU executable under test.
@@ -874,12 +882,14 @@ static inline int64_t clock_set(int64_t val)
 }
 
 /**
- * qtest_big_endian:
+ * target_big_endian:
  *
  * Returns: True if the architecture under test has a big endian configuration.
  */
-bool qtest_big_endian(void);
-
+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);
diff --git a/tests/virtio-blk-test.c b/tests/virtio-blk-test.c
index 3c4fecc..0506917 100644
--- a/tests/virtio-blk-test.c
+++ b/tests/virtio-blk-test.c
@@ -125,7 +125,7 @@ static inline void virtio_blk_fix_request(QVirtioBlkReq *req)
     bool host_endian = false;
 #endif
 
-    if (qtest_big_endian() != host_endian) {
+    if (target_big_endian() != host_endian) {
         req->type = bswap32(req->type);
         req->ioprio = bswap32(req->ioprio);
         req->sector = bswap64(req->sector);
-- 
2.5.5

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

* [Qemu-devel] [PATCH v2 5/6] qtest: define target cpu endianness conversion function
  2016-09-27 18:55 [Qemu-devel] [PATCH v2 0/6] tests: enable ohci/uhci/xhci tests on PPC64 Laurent Vivier
                   ` (3 preceding siblings ...)
  2016-09-27 18:55 ` [Qemu-devel] [PATCH v2 4/6] qtest: evaluate endianness of the target in qtest_init() Laurent Vivier
@ 2016-09-27 18:55 ` Laurent Vivier
  2016-09-28  2:40   ` [Qemu-devel] [Qemu-ppc] " David Gibson
  2016-09-27 18:55 ` [Qemu-devel] [PATCH v2 6/6] tests: enable ohci/uhci/xhci tests on PPC64 Laurent Vivier
  2016-09-27 19:23 ` [Qemu-devel] [PATCH v2 0/6] " no-reply
  6 siblings, 1 reply; 16+ messages in thread
From: Laurent Vivier @ 2016-09-27 18:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: dgibson, thuth, qemu-ppc, Gerd Hoffmann, Greg Kurz, Laurent Vivier

Signed-off-by: Laurent Vivier <lvivier@redhat.com>
---
 tests/libqtest.h | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 57 insertions(+)

diff --git a/tests/libqtest.h b/tests/libqtest.h
index 4be1f77..4c47f2d 100644
--- a/tests/libqtest.h
+++ b/tests/libqtest.h
@@ -17,6 +17,7 @@
 #ifndef LIBQTEST_H
 #define LIBQTEST_H
 
+#include "qemu/bswap.h"
 #include "qapi/qmp/qdict.h"
 
 typedef struct QTestState QTestState;
@@ -891,6 +892,62 @@ static inline bool target_big_endian(void)
     return qtest_big_endian(global_qtest);
 }
 
+/* Endianness conversion function between target cpu and specified endianess
+ *
+ * uint16_t target_le16_to_cpu(uint16_t v);
+ * uint32_t target_le32_to_cpu(uint32_t v);
+ * uint64_t target_le64_to_cpu(uint64_t v);
+ * uint16_t target_be16_to_cpu(uint16_t v);
+ * uint32_t target_be32_to_cpu(uint32_t v);
+ * uint64_t target_be64_to_cpu(uint64_t v);
+ *
+ * Convert the value @v from the specified format to the native
+ * endianness of the host CPU by byteswapping if necessary, and
+ * return the converted value.
+ *
+ * uint16_t target_cpu_to_le16(uint16_t v);
+ * uint32_t target_cpu_to_le32(uint32_t v);
+ * uint64_t target_cpu_to_le64(uint64_t v);
+ * uint16_t target_cpu_to_be16(uint16_t v);
+ * uint32_t target_cpu_to_be32(uint32_t v);
+ * uint64_t target_cpu_to_be64(uint64_t v);
+ *
+ * Convert the value @v from the native endianness of the host CPU to
+ * the specified format by byteswapping if necessary, and return
+ * the converted value.
+ *
+ * Both target_X_to_cpu() and target_cpu_to_X() perform the same operation; you
+ * should use whichever one is better documenting of the function your
+ * code is performing.
+ *
+ */
+
+#define le_bswap(s, v, size) (qtest_big_endian(s) ? bswap ## size(v) : (v))
+#define be_bswap(s, v, size) (qtest_big_endian(s) ? (v) : bswap ## size(v))
+
+#define TARGET_CPU_CONVERT(endian, size, type)\
+static inline type target_ ## endian ## size ## _to_cpu(type v)\
+{\
+    return glue(endian, _bswap)(global_qtest, v, size);\
+} \
+\
+static inline type target_cpu_to_ ## endian ## size(type v)\
+{\
+    return glue(endian, _bswap)(global_qtest, v, size);\
+}
+
+TARGET_CPU_CONVERT(be, 16, uint16_t)
+TARGET_CPU_CONVERT(be, 32, uint32_t)
+TARGET_CPU_CONVERT(be, 64, uint64_t)
+
+TARGET_CPU_CONVERT(le, 16, uint16_t)
+TARGET_CPU_CONVERT(le, 32, uint32_t)
+TARGET_CPU_CONVERT(le, 64, uint64_t)
+
+#undef TARGET_CPU_CONVERT
+#undef be_bswap
+#undef le_bswap
+
 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, ...);
-- 
2.5.5

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

* [Qemu-devel] [PATCH v2 6/6] tests: enable ohci/uhci/xhci tests on PPC64
  2016-09-27 18:55 [Qemu-devel] [PATCH v2 0/6] tests: enable ohci/uhci/xhci tests on PPC64 Laurent Vivier
                   ` (4 preceding siblings ...)
  2016-09-27 18:55 ` [Qemu-devel] [PATCH v2 5/6] qtest: define target cpu endianness conversion function Laurent Vivier
@ 2016-09-27 18:55 ` Laurent Vivier
  2016-09-28  2:45   ` [Qemu-devel] [Qemu-ppc] " David Gibson
  2016-09-27 19:23 ` [Qemu-devel] [PATCH v2 0/6] " no-reply
  6 siblings, 1 reply; 16+ messages in thread
From: Laurent Vivier @ 2016-09-27 18:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: dgibson, thuth, qemu-ppc, Gerd Hoffmann, Greg Kurz, Laurent Vivier

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

diff --git a/tests/Makefile.include b/tests/Makefile.include
index bca2cbc..4136959 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -270,6 +270,12 @@ check-qtest-ppc64-y += tests/drive_del-test$(EXESUF)
 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/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)
 
@@ -595,7 +601,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/libqos/usb.c b/tests/libqos/usb.c
index f794d92..25e5f38 100644
--- a/tests/libqos/usb.c
+++ b/tests/libqos/usb.c
@@ -28,7 +28,7 @@ void qusb_pci_init_one(QPCIBus *pcibus, struct qhc *hc, uint32_t devfn, int bar)
 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 = target_le16_to_cpu(qpci_io_readw(hc->dev, addr));
     uint16_t mask = ~(UHCI_PORT_WRITE_CLEAR | UHCI_PORT_RSVD1);
 
     g_assert((value & mask) == (expect & mask));
diff --git a/tests/usb-hcd-uhci-test.c b/tests/usb-hcd-uhci-test.c
index c24063e..4b951ce 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,7 @@ static void test_usb_storage_hotplug(void)
 
 int main(int argc, char **argv)
 {
+    const char *arch = qtest_get_arch();
     int ret;
 
     g_test_init(&argc, &argv, NULL);
@@ -84,11 +86,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("-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");
+    } else if (strcmp(arch, "ppc64") == 0) {
+        qs = qtest_spapr_boot("-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");
+    }
     ret = g_test_run();
-    qtest_end();
+    qtest_shutdown(qs);
 
     return ret;
 }
-- 
2.5.5

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

* Re: [Qemu-devel] [PATCH v2 0/6] tests: enable ohci/uhci/xhci tests on PPC64
  2016-09-27 18:55 [Qemu-devel] [PATCH v2 0/6] tests: enable ohci/uhci/xhci tests on PPC64 Laurent Vivier
                   ` (5 preceding siblings ...)
  2016-09-27 18:55 ` [Qemu-devel] [PATCH v2 6/6] tests: enable ohci/uhci/xhci tests on PPC64 Laurent Vivier
@ 2016-09-27 19:23 ` no-reply
  6 siblings, 0 replies; 16+ messages in thread
From: no-reply @ 2016-09-27 19:23 UTC (permalink / raw)
  To: lvivier; +Cc: famz, qemu-devel, thuth, groug, qemu-ppc, kraxel, dgibson

Hi,

Your series seems to have some coding style problems. See output below for
more information:

Type: series
Message-id: 1475002559-392-1-git-send-email-lvivier@redhat.com
Subject: [Qemu-devel] [PATCH v2 0/6] tests: enable ohci/uhci/xhci tests on PPC64

=== TEST SCRIPT BEGIN ===
#!/bin/bash

BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0

# Useful git options
git config --local diff.renamelimit 0
git config --local diff.renames True

commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
    echo "Checking PATCH $n/$total: $(git show --no-patch --format=%s $c)..."
    if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
        failed=1
        echo
    fi
    n=$((n+1))
done

exit $failed
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 * [new tag]         patchew/1475002559-392-1-git-send-email-lvivier@redhat.com -> patchew/1475002559-392-1-git-send-email-lvivier@redhat.com
Switched to a new branch 'test'
0fd7274 tests: enable ohci/uhci/xhci tests on PPC64
0ee0891 qtest: define target cpu endianness conversion function
653d63f qtest: evaluate endianness of the target in qtest_init()
7c19b42 libqos: use generic qtest_shutdown()
8d4d411 libqos: add PCI management in qtest_vboot()/qtest_shutdown()
7f1933a libqos: add PPC64 PCI support

=== OUTPUT BEGIN ===
Checking PATCH 1/6: libqos: add PPC64 PCI support...
Checking PATCH 2/6: libqos: add PCI management in qtest_vboot()/qtest_shutdown()...
Checking PATCH 3/6: libqos: use generic qtest_shutdown()...
Checking PATCH 4/6: qtest: evaluate endianness of the target in qtest_init()...
Checking PATCH 5/6: qtest: define target cpu endianness conversion function...
ERROR: Macros with multiple statements should be enclosed in a do - while loop
#58: FILE: tests/libqtest.h:928:
+#define TARGET_CPU_CONVERT(endian, size, type)\
+static inline type target_ ## endian ## size ## _to_cpu(type v)\
+{\
+    return glue(endian, _bswap)(global_qtest, v, size);\
+} \
+\
+static inline type target_cpu_to_ ## endian ## size(type v)\
+{\
+    return glue(endian, _bswap)(global_qtest, v, size);\
+}

total: 1 errors, 0 warnings, 69 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 6/6: tests: enable ohci/uhci/xhci tests on PPC64...
=== OUTPUT END ===

Test command exited with code: 1


---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@freelists.org

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

* Re: [Qemu-devel] [Qemu-ppc] [PATCH v2 5/6] qtest: define target cpu endianness conversion function
  2016-09-27 18:55 ` [Qemu-devel] [PATCH v2 5/6] qtest: define target cpu endianness conversion function Laurent Vivier
@ 2016-09-28  2:40   ` David Gibson
  2016-09-28  7:41     ` Laurent Vivier
  0 siblings, 1 reply; 16+ messages in thread
From: David Gibson @ 2016-09-28  2:40 UTC (permalink / raw)
  To: Laurent Vivier
  Cc: qemu-devel, thuth, Greg Kurz, qemu-ppc, Gerd Hoffmann, dgibson

[-- Attachment #1: Type: text/plain, Size: 3571 bytes --]

On Tue, Sep 27, 2016 at 08:55:58PM +0200, Laurent Vivier wrote:
> Signed-off-by: Laurent Vivier <lvivier@redhat.com>
> ---
>  tests/libqtest.h | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 57 insertions(+)
> 
> diff --git a/tests/libqtest.h b/tests/libqtest.h
> index 4be1f77..4c47f2d 100644
> --- a/tests/libqtest.h
> +++ b/tests/libqtest.h
> @@ -17,6 +17,7 @@
>  #ifndef LIBQTEST_H
>  #define LIBQTEST_H
>  
> +#include "qemu/bswap.h"
>  #include "qapi/qmp/qdict.h"
>  
>  typedef struct QTestState QTestState;
> @@ -891,6 +892,62 @@ static inline bool target_big_endian(void)
>      return qtest_big_endian(global_qtest);
>  }
>  
> +/* Endianness conversion function between target cpu and specified endianess

Since the qtest accelerator essentially replaces the target cpu, it's
not really clear to me how the (default) endianness of the target cpu
comes into play.

IIUC for the purposes of the test code you'll eventually want things
converted to the *host* endianness - since that's the test code is
actually running on.

> + * uint16_t target_le16_to_cpu(uint16_t v);
> + * uint32_t target_le32_to_cpu(uint32_t v);
> + * uint64_t target_le64_to_cpu(uint64_t v);
> + * uint16_t target_be16_to_cpu(uint16_t v);
> + * uint32_t target_be32_to_cpu(uint32_t v);
> + * uint64_t target_be64_to_cpu(uint64_t v);
> + *
> + * Convert the value @v from the specified format to the native
> + * endianness of the host CPU by byteswapping if necessary, and
                        ^^^^^^^^
Should this be target CPU?

> + * return the converted value.
> + *
> + * uint16_t target_cpu_to_le16(uint16_t v);
> + * uint32_t target_cpu_to_le32(uint32_t v);
> + * uint64_t target_cpu_to_le64(uint64_t v);
> + * uint16_t target_cpu_to_be16(uint16_t v);
> + * uint32_t target_cpu_to_be32(uint32_t v);
> + * uint64_t target_cpu_to_be64(uint64_t v);
> + *
> + * Convert the value @v from the native endianness of the host CPU to
                                                    and here ^^^^^^^^
> + * the specified format by byteswapping if necessary, and return
> + * the converted value.
> + *
> + * Both target_X_to_cpu() and target_cpu_to_X() perform the same operation; you
> + * should use whichever one is better documenting of the function your
> + * code is performing.
> + *
> + */
> +
> +#define le_bswap(s, v, size) (qtest_big_endian(s) ? bswap ## size(v) : (v))
> +#define be_bswap(s, v, size) (qtest_big_endian(s) ? (v) : bswap ## size(v))
> +
> +#define TARGET_CPU_CONVERT(endian, size, type)\
> +static inline type target_ ## endian ## size ## _to_cpu(type v)\
> +{\
> +    return glue(endian, _bswap)(global_qtest, v, size);\
> +} \
> +\
> +static inline type target_cpu_to_ ## endian ## size(type v)\
> +{\
> +    return glue(endian, _bswap)(global_qtest, v, size);\
> +}
> +
> +TARGET_CPU_CONVERT(be, 16, uint16_t)
> +TARGET_CPU_CONVERT(be, 32, uint32_t)
> +TARGET_CPU_CONVERT(be, 64, uint64_t)
> +
> +TARGET_CPU_CONVERT(le, 16, uint16_t)
> +TARGET_CPU_CONVERT(le, 32, uint32_t)
> +TARGET_CPU_CONVERT(le, 64, uint64_t)
> +
> +#undef TARGET_CPU_CONVERT
> +#undef be_bswap
> +#undef le_bswap
> +
>  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, ...);

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [Qemu-devel] [Qemu-ppc] [PATCH v2 6/6] tests: enable ohci/uhci/xhci tests on PPC64
  2016-09-27 18:55 ` [Qemu-devel] [PATCH v2 6/6] tests: enable ohci/uhci/xhci tests on PPC64 Laurent Vivier
@ 2016-09-28  2:45   ` David Gibson
  2016-09-28  7:54     ` Laurent Vivier
  0 siblings, 1 reply; 16+ messages in thread
From: David Gibson @ 2016-09-28  2:45 UTC (permalink / raw)
  To: Laurent Vivier
  Cc: qemu-devel, thuth, Greg Kurz, qemu-ppc, Gerd Hoffmann, dgibson

[-- Attachment #1: Type: text/plain, Size: 5235 bytes --]

On Tue, Sep 27, 2016 at 08:55:59PM +0200, Laurent Vivier wrote:
> Signed-off-by: Laurent Vivier <lvivier@redhat.com>
> ---
>  tests/Makefile.include    |  8 +++++++-
>  tests/libqos/usb.c        |  2 +-
>  tests/usb-hcd-uhci-test.c | 24 ++++++++++++++++--------
>  3 files changed, 24 insertions(+), 10 deletions(-)
> 
> diff --git a/tests/Makefile.include b/tests/Makefile.include
> index bca2cbc..4136959 100644
> --- a/tests/Makefile.include
> +++ b/tests/Makefile.include
> @@ -270,6 +270,12 @@ check-qtest-ppc64-y += tests/drive_del-test$(EXESUF)
>  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/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)
>  
> @@ -595,7 +601,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/libqos/usb.c b/tests/libqos/usb.c
> index f794d92..25e5f38 100644
> --- a/tests/libqos/usb.c
> +++ b/tests/libqos/usb.c
> @@ -28,7 +28,7 @@ void qusb_pci_init_one(QPCIBus *pcibus, struct qhc *hc, uint32_t devfn, int bar)
>  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 = target_le16_to_cpu(qpci_io_readw(hc->dev, addr));

This doesn't look right.  Judging by the code using qpci_io_readw() in
qpci_device_foreach() and in other tests I'm looking at,
qpci_io_readw() (and the others) are expected to return results in
*host native* order - i.e. suitable for immediate comparisons and
masks within qtest code executing on the host.

>      uint16_t mask = ~(UHCI_PORT_WRITE_CLEAR | UHCI_PORT_RSVD1);
>  
>      g_assert((value & mask) == (expect & mask));
> diff --git a/tests/usb-hcd-uhci-test.c b/tests/usb-hcd-uhci-test.c
> index c24063e..4b951ce 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,7 @@ static void test_usb_storage_hotplug(void)
>  
>  int main(int argc, char **argv)
>  {
> +    const char *arch = qtest_get_arch();
>      int ret;
>  
>      g_test_init(&argc, &argv, NULL);
> @@ -84,11 +86,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("-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");
> +    } else if (strcmp(arch, "ppc64") == 0) {
> +        qs = qtest_spapr_boot("-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");

Why aren't there similar ifs needed for ohci, ehci and/or xhci?

> +    }
>      ret = g_test_run();
> -    qtest_end();
> +    qtest_shutdown(qs);
>  
>      return ret;
>  }

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [Qemu-devel] [PATCH v2 2/6] libqos: add PCI management in qtest_vboot()/qtest_shutdown()
  2016-09-27 18:55 ` [Qemu-devel] [PATCH v2 2/6] libqos: add PCI management in qtest_vboot()/qtest_shutdown() Laurent Vivier
@ 2016-09-28  6:46   ` Greg Kurz
  0 siblings, 0 replies; 16+ messages in thread
From: Greg Kurz @ 2016-09-28  6:46 UTC (permalink / raw)
  To: Laurent Vivier; +Cc: qemu-devel, dgibson, thuth, qemu-ppc, Gerd Hoffmann

On Tue, 27 Sep 2016 20:55:55 +0200
Laurent Vivier <lvivier@redhat.com> wrote:

> Signed-off-by: Laurent Vivier <lvivier@redhat.com>
> ---

Just a minor remark below, but anyway:

Reviewed-by: Greg Kurz <groug@kaod.org>

Cheers.

--
Greg

>  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..125c6b3 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

Maybe add a trailing comma like in libqos-pc.c ?

>  };
>  
>  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;

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

* Re: [Qemu-devel] [PATCH v2 3/6] libqos: use generic qtest_shutdown()
  2016-09-27 18:55 ` [Qemu-devel] [PATCH v2 3/6] libqos: use generic qtest_shutdown() Laurent Vivier
@ 2016-09-28  6:56   ` Greg Kurz
  0 siblings, 0 replies; 16+ messages in thread
From: Greg Kurz @ 2016-09-28  6:56 UTC (permalink / raw)
  To: Laurent Vivier; +Cc: qemu-devel, dgibson, thuth, qemu-ppc, Gerd Hoffmann

On Tue, 27 Sep 2016 20:55:56 +0200
Laurent Vivier <lvivier@redhat.com> wrote:

> 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>
> ---

Minor remarks below, but anyway:

Reviewed-by: Greg Kurz <groug@kaod.org>

Cheers.

--
Greg

>  tests/libqos/libqos-pc.c    |  3 ++-
>  tests/libqos/libqos-spapr.c |  5 +++--
>  tests/libqos/libqos.c       | 11 ++++++++++-
>  tests/libqos/libqos.h       |  8 ++++++--
>  tests/rtas-test.c           |  2 +-
>  5 files changed, 22 insertions(+), 7 deletions(-)
> 
> diff --git a/tests/libqos/libqos-pc.c b/tests/libqos/libqos-pc.c
> index aa17c98..219824d 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

Trailing comma ?

>  };
>  
>  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 125c6b3..8f7fc14 100644
> --- a/tests/libqos/libqos-spapr.c
> +++ b/tests/libqos/libqos-spapr.c
> @@ -7,7 +7,8 @@ static QOSOps qos_ops = {
>      .init_allocator = spapr_alloc_init_flags,
>      .uninit_allocator = spapr_alloc_uninit,
>      .qpci_init = qpci_init_spapr,
> -    .qpci_free = qpci_free_spapr
> +    .qpci_free = qpci_free_spapr,
> +    .shutdown = qtest_spapr_shutdown

Ditto.

>  };
>  
>  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[])

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

* Re: [Qemu-devel] [Qemu-ppc] [PATCH v2 5/6] qtest: define target cpu endianness conversion function
  2016-09-28  2:40   ` [Qemu-devel] [Qemu-ppc] " David Gibson
@ 2016-09-28  7:41     ` Laurent Vivier
  0 siblings, 0 replies; 16+ messages in thread
From: Laurent Vivier @ 2016-09-28  7:41 UTC (permalink / raw)
  To: David Gibson
  Cc: qemu-devel, thuth, Greg Kurz, qemu-ppc, Gerd Hoffmann, dgibson



On 28/09/2016 04:40, David Gibson wrote:
> On Tue, Sep 27, 2016 at 08:55:58PM +0200, Laurent Vivier wrote:
>> Signed-off-by: Laurent Vivier <lvivier@redhat.com>
>> ---
>>  tests/libqtest.h | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>  1 file changed, 57 insertions(+)
>>
>> diff --git a/tests/libqtest.h b/tests/libqtest.h
>> index 4be1f77..4c47f2d 100644
>> --- a/tests/libqtest.h
>> +++ b/tests/libqtest.h
>> @@ -17,6 +17,7 @@
>>  #ifndef LIBQTEST_H
>>  #define LIBQTEST_H
>>  
>> +#include "qemu/bswap.h"
>>  #include "qapi/qmp/qdict.h"
>>  
>>  typedef struct QTestState QTestState;
>> @@ -891,6 +892,62 @@ static inline bool target_big_endian(void)
>>      return qtest_big_endian(global_qtest);
>>  }
>>  
>> +/* Endianness conversion function between target cpu and specified endianess
> 
> Since the qtest accelerator essentially replaces the target cpu, it's
> not really clear to me how the (default) endianness of the target cpu
> comes into play.
> 
> IIUC for the purposes of the test code you'll eventually want things
> converted to the *host* endianness - since that's the test code is
> actually running on.

Values are read/written from/to memory by the qtest accelerator using
cpu_physical_memory_read()/cpu_physical_memory_write() (see qtest.c) and
then sent to the test program using ASCII protocol. So the values are
read/written using endianness of the guest.

So when we read a value from little-endian device on big endian guest
the value must be converted (like leXX_to_cpu() function on a host) but
in our case the involved endianness is the one from the guest (which is
reading the value from the memory) not the one from the host (which is
manipulating the value).

> 
>> + * uint16_t target_le16_to_cpu(uint16_t v);
>> + * uint32_t target_le32_to_cpu(uint32_t v);
>> + * uint64_t target_le64_to_cpu(uint64_t v);
>> + * uint16_t target_be16_to_cpu(uint16_t v);
>> + * uint32_t target_be32_to_cpu(uint32_t v);
>> + * uint64_t target_be64_to_cpu(uint64_t v);
>> + *
>> + * Convert the value @v from the specified format to the native
>> + * endianness of the host CPU by byteswapping if necessary, and
>                         ^^^^^^^^
> Should this be target CPU?

yes

>> + * return the converted value.
>> + *
>> + * uint16_t target_cpu_to_le16(uint16_t v);
>> + * uint32_t target_cpu_to_le32(uint32_t v);
>> + * uint64_t target_cpu_to_le64(uint64_t v);
>> + * uint16_t target_cpu_to_be16(uint16_t v);
>> + * uint32_t target_cpu_to_be32(uint32_t v);
>> + * uint64_t target_cpu_to_be64(uint64_t v);
>> + *
>> + * Convert the value @v from the native endianness of the host CPU to
>                                                     and here ^^^^^^^^
>> + * the specified format by byteswapping if necessary, and return
>> + * the converted value.
>> + *
>> + * Both target_X_to_cpu() and target_cpu_to_X() perform the same operation; you
>> + * should use whichever one is better documenting of the function your
>> + * code is performing.
>> + *
>> + */
>> +
>> +#define le_bswap(s, v, size) (qtest_big_endian(s) ? bswap ## size(v) : (v))
>> +#define be_bswap(s, v, size) (qtest_big_endian(s) ? (v) : bswap ## size(v))
>> +
>> +#define TARGET_CPU_CONVERT(endian, size, type)\
>> +static inline type target_ ## endian ## size ## _to_cpu(type v)\
>> +{\
>> +    return glue(endian, _bswap)(global_qtest, v, size);\
>> +} \
>> +\
>> +static inline type target_cpu_to_ ## endian ## size(type v)\
>> +{\
>> +    return glue(endian, _bswap)(global_qtest, v, size);\
>> +}
>> +
>> +TARGET_CPU_CONVERT(be, 16, uint16_t)
>> +TARGET_CPU_CONVERT(be, 32, uint32_t)
>> +TARGET_CPU_CONVERT(be, 64, uint64_t)
>> +
>> +TARGET_CPU_CONVERT(le, 16, uint16_t)
>> +TARGET_CPU_CONVERT(le, 32, uint32_t)
>> +TARGET_CPU_CONVERT(le, 64, uint64_t)
>> +
>> +#undef TARGET_CPU_CONVERT
>> +#undef be_bswap
>> +#undef le_bswap
>> +
>>  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, ...);
> 

Thanks,
Laurent

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

* Re: [Qemu-devel] [Qemu-ppc] [PATCH v2 6/6] tests: enable ohci/uhci/xhci tests on PPC64
  2016-09-28  2:45   ` [Qemu-devel] [Qemu-ppc] " David Gibson
@ 2016-09-28  7:54     ` Laurent Vivier
  2016-09-29  4:10       ` David Gibson
  0 siblings, 1 reply; 16+ messages in thread
From: Laurent Vivier @ 2016-09-28  7:54 UTC (permalink / raw)
  To: David Gibson
  Cc: qemu-devel, thuth, Greg Kurz, qemu-ppc, Gerd Hoffmann, dgibson



On 28/09/2016 04:45, David Gibson wrote:
> On Tue, Sep 27, 2016 at 08:55:59PM +0200, Laurent Vivier wrote:
>> Signed-off-by: Laurent Vivier <lvivier@redhat.com>
>> ---
>>  tests/Makefile.include    |  8 +++++++-
>>  tests/libqos/usb.c        |  2 +-
>>  tests/usb-hcd-uhci-test.c | 24 ++++++++++++++++--------
>>  3 files changed, 24 insertions(+), 10 deletions(-)
>>
>> diff --git a/tests/Makefile.include b/tests/Makefile.include
>> index bca2cbc..4136959 100644
>> --- a/tests/Makefile.include
>> +++ b/tests/Makefile.include
>> @@ -270,6 +270,12 @@ check-qtest-ppc64-y += tests/drive_del-test$(EXESUF)
>>  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/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)
>>  
>> @@ -595,7 +601,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/libqos/usb.c b/tests/libqos/usb.c
>> index f794d92..25e5f38 100644
>> --- a/tests/libqos/usb.c
>> +++ b/tests/libqos/usb.c
>> @@ -28,7 +28,7 @@ void qusb_pci_init_one(QPCIBus *pcibus, struct qhc *hc, uint32_t devfn, int bar)
>>  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 = target_le16_to_cpu(qpci_io_readw(hc->dev, addr));
> 
> This doesn't look right.  Judging by the code using qpci_io_readw() in
> qpci_device_foreach() and in other tests I'm looking at,
> qpci_io_readw() (and the others) are expected to return results in
> *host native* order - i.e. suitable for immediate comparisons and
> masks within qtest code executing on the host.

Its true when the endianness of the device is the same as the endianness
of the guest.

This case is particular because the endianness of the device is
little-endian (all USB controller are little-endian). On a little-endian
guest it is read correctly, on a big-endian guest it is not.

So either we add a command in the protocol to ask a big-endian guest to
read in a little-endian mode, or we can just convert it on the host
(knowing endianness of the guest).

> 
>>      uint16_t mask = ~(UHCI_PORT_WRITE_CLEAR | UHCI_PORT_RSVD1);
>>  
>>      g_assert((value & mask) == (expect & mask));
>> diff --git a/tests/usb-hcd-uhci-test.c b/tests/usb-hcd-uhci-test.c
>> index c24063e..4b951ce 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,7 @@ static void test_usb_storage_hotplug(void)
>>  
>>  int main(int argc, char **argv)
>>  {
>> +    const char *arch = qtest_get_arch();
>>      int ret;
>>  
>>      g_test_init(&argc, &argv, NULL);
>> @@ -84,11 +86,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("-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");
>> +    } else if (strcmp(arch, "ppc64") == 0) {
>> +        qs = qtest_spapr_boot("-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");
> 
> Why aren't there similar ifs needed for ohci, ehci and/or xhci?

ohci and xhci don't test the card is working correctly, they just test
we can plug it, so we don't need PCI framework and we don't have to
initialize it with qtest_XXX_boot(), and the machine are started in a
generic way using qtest_start().

I din't add ehci because I was not able to make it working for the moment.
My goal is to test virtio, so USB is just here to test new qtest SPAPR
PCI implementation. We can improve/add more PCI tests later.

> 
>> +    }
>>      ret = g_test_run();
>> -    qtest_end();
>> +    qtest_shutdown(qs);
>>  
>>      return ret;
>>  }
> 

thansk,
Laurent

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

* Re: [Qemu-devel] [PATCH v2 4/6] qtest: evaluate endianness of the target in qtest_init()
  2016-09-27 18:55 ` [Qemu-devel] [PATCH v2 4/6] qtest: evaluate endianness of the target in qtest_init() Laurent Vivier
@ 2016-09-28  8:08   ` Greg Kurz
  0 siblings, 0 replies; 16+ messages in thread
From: Greg Kurz @ 2016-09-28  8:08 UTC (permalink / raw)
  To: Laurent Vivier; +Cc: qemu-devel, dgibson, thuth, qemu-ppc, Gerd Hoffmann

On Tue, 27 Sep 2016 20:55:57 +0200
Laurent Vivier <lvivier@redhat.com> wrote:

> This allows to store it and not have to rescan the list
> each time we need it.
> 
> Signed-off-by: Laurent Vivier <lvivier@redhat.com>
> ---

Reviewed-by: Greg Kurz <groug@kaod.org>

>  tests/libqos/virtio-pci.c |  2 +-
>  tests/libqtest.c          | 96 +++++++++++++++++++++++++----------------------
>  tests/libqtest.h          | 16 ++++++--
>  tests/virtio-blk-test.c   |  2 +-
>  4 files changed, 66 insertions(+), 50 deletions(-)
> 
> diff --git a/tests/libqos/virtio-pci.c b/tests/libqos/virtio-pci.c
> index 18b92b9..6e005c1 100644
> --- a/tests/libqos/virtio-pci.c
> +++ b/tests/libqos/virtio-pci.c
> @@ -86,7 +86,7 @@ static uint64_t qvirtio_pci_config_readq(QVirtioDevice *d, uint64_t addr)
>      int i;
>      uint64_t u64 = 0;
>  
> -    if (qtest_big_endian()) {
> +    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;
> diff --git a/tests/libqtest.c b/tests/libqtest.c
> index 6f6bdf1..aa4bc9e 100644
> --- a/tests/libqtest.c
> +++ b/tests/libqtest.c
> @@ -37,6 +37,7 @@ struct QTestState
>      bool irq_level[MAX_IRQ];
>      GString *rx;
>      pid_t qemu_pid;  /* our child QEMU process */
> +    bool big_endian;
>  };
>  
>  static GHookList abrt_hooks;
> @@ -146,6 +147,52 @@ void qtest_add_abrt_handler(GHookFunc fn, const void *data)
>      g_hook_prepend(&abrt_hooks, hook);
>  }
>  
> +static bool arch_is_big_endian(const char *arch)
> +{
> +    int i;
> +    static const struct {
> +        const char *arch;
> +        bool big_endian;
> +    } endianness[] = {
> +        { "aarch64", false },
> +        { "alpha", false },
> +        { "arm", false },
> +        { "cris", false },
> +        { "i386", false },
> +        { "lm32", true },
> +        { "m68k", true },
> +        { "microblaze", true },
> +        { "microblazeel", false },
> +        { "mips", true },
> +        { "mips64", true },
> +        { "mips64el", false },
> +        { "mipsel", false },
> +        { "moxie", true },
> +        { "or32", true },
> +        { "ppc", true },
> +        { "ppc64", true },
> +        { "ppcemb", true },
> +        { "s390x", true },
> +        { "sh4", false },
> +        { "sh4eb", true },
> +        { "sparc", true },
> +        { "sparc64", true },
> +        { "unicore32", false },
> +        { "x86_64", false },
> +        { "xtensa", false },
> +        { "xtensaeb", true },
> +        { "tricore", false },
> +        {},
> +    };
> +
> +    for (i = 0; endianness[i].arch; i++) {
> +        if (strcmp(endianness[i].arch, arch) == 0) {
> +            return endianness[i].big_endian;
> +        }
> +    }
> +    g_assert_not_reached();
> +}
> +
>  QTestState *qtest_init(const char *extra_args)
>  {
>      QTestState *s;
> @@ -209,6 +256,8 @@ QTestState *qtest_init(const char *extra_args)
>          kill(s->qemu_pid, SIGSTOP);
>      }
>  
> +    s->big_endian = arch_is_big_endian(qtest_get_arch());
> +
>      return s;
>  }
>  
> @@ -886,50 +935,7 @@ char *hmp(const char *fmt, ...)
>      return ret;
>  }
>  
> -bool qtest_big_endian(void)
> +bool qtest_big_endian(QTestState *s)
>  {
> -    const char *arch = qtest_get_arch();
> -    int i;
> -
> -    static const struct {
> -        const char *arch;
> -        bool big_endian;
> -    } endianness[] = {
> -        { "aarch64", false },
> -        { "alpha", false },
> -        { "arm", false },
> -        { "cris", false },
> -        { "i386", false },
> -        { "lm32", true },
> -        { "m68k", true },
> -        { "microblaze", true },
> -        { "microblazeel", false },
> -        { "mips", true },
> -        { "mips64", true },
> -        { "mips64el", false },
> -        { "mipsel", false },
> -        { "moxie", true },
> -        { "or32", true },
> -        { "ppc", true },
> -        { "ppc64", true },
> -        { "ppcemb", true },
> -        { "s390x", true },
> -        { "sh4", false },
> -        { "sh4eb", true },
> -        { "sparc", true },
> -        { "sparc64", true },
> -        { "unicore32", false },
> -        { "x86_64", false },
> -        { "xtensa", false },
> -        { "xtensaeb", true },
> -        {},
> -    };
> -
> -    for (i = 0; endianness[i].arch; i++) {
> -        if (strcmp(endianness[i].arch, arch) == 0) {
> -            return endianness[i].big_endian;
> -        }
> -    }
> -
> -    return false;
> +    return s->big_endian;
>  }
> diff --git a/tests/libqtest.h b/tests/libqtest.h
> index f7402e0..4be1f77 100644
> --- a/tests/libqtest.h
> +++ b/tests/libqtest.h
> @@ -410,6 +410,14 @@ int64_t qtest_clock_step(QTestState *s, int64_t step);
>  int64_t qtest_clock_set(QTestState *s, int64_t val);
>  
>  /**
> + * qtest_big_endian:
> + * @s: QTestState instance to operate on.
> + *
> + * Returns: True if the architecture under test has a big endian configuration.
> + */
> +bool qtest_big_endian(QTestState *s);
> +
> +/**
>   * qtest_get_arch:
>   *
>   * Returns: The architecture for the QEMU executable under test.
> @@ -874,12 +882,14 @@ static inline int64_t clock_set(int64_t val)
>  }
>  
>  /**
> - * qtest_big_endian:
> + * target_big_endian:
>   *
>   * Returns: True if the architecture under test has a big endian configuration.
>   */
> -bool qtest_big_endian(void);
> -
> +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);
> diff --git a/tests/virtio-blk-test.c b/tests/virtio-blk-test.c
> index 3c4fecc..0506917 100644
> --- a/tests/virtio-blk-test.c
> +++ b/tests/virtio-blk-test.c
> @@ -125,7 +125,7 @@ static inline void virtio_blk_fix_request(QVirtioBlkReq *req)
>      bool host_endian = false;
>  #endif
>  
> -    if (qtest_big_endian() != host_endian) {
> +    if (target_big_endian() != host_endian) {
>          req->type = bswap32(req->type);
>          req->ioprio = bswap32(req->ioprio);
>          req->sector = bswap64(req->sector);

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

* Re: [Qemu-devel] [Qemu-ppc] [PATCH v2 6/6] tests: enable ohci/uhci/xhci tests on PPC64
  2016-09-28  7:54     ` Laurent Vivier
@ 2016-09-29  4:10       ` David Gibson
  0 siblings, 0 replies; 16+ messages in thread
From: David Gibson @ 2016-09-29  4:10 UTC (permalink / raw)
  To: Laurent Vivier
  Cc: qemu-devel, thuth, Greg Kurz, qemu-ppc, Gerd Hoffmann, dgibson

[-- Attachment #1: Type: text/plain, Size: 8007 bytes --]

On Wed, Sep 28, 2016 at 09:54:14AM +0200, Laurent Vivier wrote:
> 
> 
> On 28/09/2016 04:45, David Gibson wrote:
> > On Tue, Sep 27, 2016 at 08:55:59PM +0200, Laurent Vivier wrote:
> >> Signed-off-by: Laurent Vivier <lvivier@redhat.com>
> >> ---
> >>  tests/Makefile.include    |  8 +++++++-
> >>  tests/libqos/usb.c        |  2 +-
> >>  tests/usb-hcd-uhci-test.c | 24 ++++++++++++++++--------
> >>  3 files changed, 24 insertions(+), 10 deletions(-)
> >>
> >> diff --git a/tests/Makefile.include b/tests/Makefile.include
> >> index bca2cbc..4136959 100644
> >> --- a/tests/Makefile.include
> >> +++ b/tests/Makefile.include
> >> @@ -270,6 +270,12 @@ check-qtest-ppc64-y += tests/drive_del-test$(EXESUF)
> >>  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/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)
> >>  
> >> @@ -595,7 +601,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/libqos/usb.c b/tests/libqos/usb.c
> >> index f794d92..25e5f38 100644
> >> --- a/tests/libqos/usb.c
> >> +++ b/tests/libqos/usb.c
> >> @@ -28,7 +28,7 @@ void qusb_pci_init_one(QPCIBus *pcibus, struct qhc *hc, uint32_t devfn, int bar)
> >>  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 = target_le16_to_cpu(qpci_io_readw(hc->dev, addr));
> > 
> > This doesn't look right.  Judging by the code using qpci_io_readw() in
> > qpci_device_foreach() and in other tests I'm looking at,
> > qpci_io_readw() (and the others) are expected to return results in
> > *host native* order - i.e. suitable for immediate comparisons and
> > masks within qtest code executing on the host.
> 
> Its true when the endianness of the device is the same as the endianness
> of the guest.

Hmm.. so the existing code in qpci_device_foreach(), amongst others is
currently broken if host endian != guest endian?

Actually, though, regardless of what happens now, there's only one
sane approach here.  the pci_io_read*() functions know the length of
the value they're reading and return a word type.  Having it return
anything except native endianness is just bogus (host native that is,
because the code is executing on the host, although it's simulating
execution of a guest).

Endian conversions should *only* occur at the points we read or write
to guest memory or hardware (from either the framework or accel side).
That means if host and guest endian are different, we're likely to
swap the value as it's stored into guest memory, then swap it right
back as we pull it into the qtest accel, but that's fine.

> This case is particular because the endianness of the device is
> little-endian (all USB controller are little-endian). On a little-endian
> guest it is read correctly, on a big-endian guest it is not.

Basically all PCI devices (in fact, nearly vaguely modern all hardware
of any sort) are LE.  So I think it's correct for the PCI accessors to
assume the hardware is LE - the handful of BE devices out there can
jump through hoops to handle the exception.

Virtio pre-1.0 will require extra hacks because of the (stupid) "guest
native" behaviour.  But we should design the general interfaces around
the quirks of one device.

> So either we add a command in the protocol to ask a big-endian guest to
> read in a little-endian mode, or we can just convert it on the host
> (knowing endianness of the guest).
> 
> > 
> >>      uint16_t mask = ~(UHCI_PORT_WRITE_CLEAR | UHCI_PORT_RSVD1);
> >>  
> >>      g_assert((value & mask) == (expect & mask));
> >> diff --git a/tests/usb-hcd-uhci-test.c b/tests/usb-hcd-uhci-test.c
> >> index c24063e..4b951ce 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,7 @@ static void test_usb_storage_hotplug(void)
> >>  
> >>  int main(int argc, char **argv)
> >>  {
> >> +    const char *arch = qtest_get_arch();
> >>      int ret;
> >>  
> >>      g_test_init(&argc, &argv, NULL);
> >> @@ -84,11 +86,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("-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");
> >> +    } else if (strcmp(arch, "ppc64") == 0) {
> >> +        qs = qtest_spapr_boot("-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");
> > 
> > Why aren't there similar ifs needed for ohci, ehci and/or xhci?
> 
> ohci and xhci don't test the card is working correctly, they just test
> we can plug it, so we don't need PCI framework and we don't have to
> initialize it with qtest_XXX_boot(), and the machine are started in a
> generic way using qtest_start().
> 
> I din't add ehci because I was not able to make it working for the moment.
> My goal is to test virtio, so USB is just here to test new qtest SPAPR
> PCI implementation. We can improve/add more PCI tests later.
> 
> > 
> >> +    }
> >>      ret = g_test_run();
> >> -    qtest_end();
> >> +    qtest_shutdown(qs);
> >>  
> >>      return ret;
> >>  }
> > 
> 
> thansk,
> Laurent
> 

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

end of thread, other threads:[~2016-09-29  4:23 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-09-27 18:55 [Qemu-devel] [PATCH v2 0/6] tests: enable ohci/uhci/xhci tests on PPC64 Laurent Vivier
2016-09-27 18:55 ` [Qemu-devel] [PATCH v2 1/6] libqos: add PPC64 PCI support Laurent Vivier
2016-09-27 18:55 ` [Qemu-devel] [PATCH v2 2/6] libqos: add PCI management in qtest_vboot()/qtest_shutdown() Laurent Vivier
2016-09-28  6:46   ` Greg Kurz
2016-09-27 18:55 ` [Qemu-devel] [PATCH v2 3/6] libqos: use generic qtest_shutdown() Laurent Vivier
2016-09-28  6:56   ` Greg Kurz
2016-09-27 18:55 ` [Qemu-devel] [PATCH v2 4/6] qtest: evaluate endianness of the target in qtest_init() Laurent Vivier
2016-09-28  8:08   ` Greg Kurz
2016-09-27 18:55 ` [Qemu-devel] [PATCH v2 5/6] qtest: define target cpu endianness conversion function Laurent Vivier
2016-09-28  2:40   ` [Qemu-devel] [Qemu-ppc] " David Gibson
2016-09-28  7:41     ` Laurent Vivier
2016-09-27 18:55 ` [Qemu-devel] [PATCH v2 6/6] tests: enable ohci/uhci/xhci tests on PPC64 Laurent Vivier
2016-09-28  2:45   ` [Qemu-devel] [Qemu-ppc] " David Gibson
2016-09-28  7:54     ` Laurent Vivier
2016-09-29  4:10       ` David Gibson
2016-09-27 19:23 ` [Qemu-devel] [PATCH v2 0/6] " no-reply

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.