All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v8 0/3] tests: add RTAS protocol
@ 2016-09-13 12:52 Laurent Vivier
  2016-09-13 12:52 ` [Qemu-devel] [PATCH v8 1/3] qtest: replace strtoXX() by qemu_strtoXX() Laurent Vivier
                   ` (3 more replies)
  0 siblings, 4 replies; 10+ messages in thread
From: Laurent Vivier @ 2016-09-13 12:52 UTC (permalink / raw)
  To: david; +Cc: thuth, lvivier, qemu-ppc, qemu-devel, groug

This series allows to call RTAS commands from the qtest framework,
and defines a first test to call RTAS command "get-time-of-day"
to validate the protocol and test RTAS.

RTAS command parameters are passed to the guest via the
guest memory, so we also need to implement the guest memory
management functions for SPAPR target.

RTAS commands will be needed later to test PCI from the qtest framework
with SPAPR virtual machines: PCI configuration is read/written with
RTAS commands "ibm,read-pci-config", "ibm,write-pci-config".

v8:
- exit if RTAS is not started with qemu-system-ppc64

v7:
- don't allocate twice the memory for the RTAS call
- add "-machine pseries" in rtas-test to be sure to use 
  the good machine type (with RTAS support).

v6:
- rebase
- remove useless include

v5:
- replace "ppc64" by "spapr"
- define and use qtest_spapr_vboot()/qtest_spapr_boot()/qtest_spapr_shutdown()

v4:
- use qemu_strtoXXX() instead strtoXX(),
  add a patch in the series to change all strtoXX() in qtest.c

v3:
- use mktimegm() instead of timegm()

v2:
- remove useless parenthesis, inline
- add a missing space in qrtas_call() prototype

Laurent Vivier (3):
  qtest: replace strtoXX() by qemu_strtoXX()
  libqos: define SPAPR libqos functions
  tests: add RTAS command in the protocol

 hw/ppc/spapr_rtas.c         | 19 ++++++++++++
 include/hw/ppc/spapr_rtas.h | 10 +++++++
 qtest.c                     | 66 ++++++++++++++++++++++++++---------------
 tests/Makefile.include      |  5 ++++
 tests/libqos/libqos-pc.c    |  2 ++
 tests/libqos/libqos-spapr.c | 30 +++++++++++++++++++
 tests/libqos/libqos-spapr.h | 10 +++++++
 tests/libqos/libqos.c       |  1 -
 tests/libqos/malloc-spapr.c | 38 ++++++++++++++++++++++++
 tests/libqos/malloc-spapr.h | 17 +++++++++++
 tests/libqos/rtas.c         | 71 +++++++++++++++++++++++++++++++++++++++++++++
 tests/libqos/rtas.h         | 11 +++++++
 tests/libqtest.c            | 10 +++++++
 tests/libqtest.h            | 15 ++++++++++
 tests/rtas-test.c           | 41 ++++++++++++++++++++++++++
 15 files changed, 322 insertions(+), 24 deletions(-)
 create mode 100644 include/hw/ppc/spapr_rtas.h
 create mode 100644 tests/libqos/libqos-spapr.c
 create mode 100644 tests/libqos/libqos-spapr.h
 create mode 100644 tests/libqos/malloc-spapr.c
 create mode 100644 tests/libqos/malloc-spapr.h
 create mode 100644 tests/libqos/rtas.c
 create mode 100644 tests/libqos/rtas.h
 create mode 100644 tests/rtas-test.c

-- 
2.5.5

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

* [Qemu-devel] [PATCH v8 1/3] qtest: replace strtoXX() by qemu_strtoXX()
  2016-09-13 12:52 [Qemu-devel] [PATCH v8 0/3] tests: add RTAS protocol Laurent Vivier
@ 2016-09-13 12:52 ` Laurent Vivier
  2016-09-13 12:52 ` [Qemu-devel] [PATCH v8 2/3] libqos: define SPAPR libqos functions Laurent Vivier
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 10+ messages in thread
From: Laurent Vivier @ 2016-09-13 12:52 UTC (permalink / raw)
  To: david; +Cc: thuth, lvivier, qemu-ppc, qemu-devel, groug

Check the result of qemu_strtoXX() and assert
if the string cannot be converted.

Signed-off-by: Laurent Vivier <lvivier@redhat.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Greg Kurz <groug@kaod.org>
---
v6:
- rebase and add Greg's Rb

v5:
- update log message about result checking
- add David's Rb

v4:
- add this patch in the series to change all strtoXX() in qtest.c

 qtest.c | 49 ++++++++++++++++++++++++++-----------------------
 1 file changed, 26 insertions(+), 23 deletions(-)

diff --git a/qtest.c b/qtest.c
index ce4c6db..649f7b2 100644
--- a/qtest.c
+++ b/qtest.c
@@ -27,6 +27,7 @@
 #include "qemu/config-file.h"
 #include "qemu/option.h"
 #include "qemu/error-report.h"
+#include "qemu/cutils.h"
 
 #define MAX_IRQ 256
 
@@ -325,12 +326,13 @@ static void qtest_process_command(CharDriverState *chr, gchar **words)
     } else if (strcmp(words[0], "outb") == 0 ||
                strcmp(words[0], "outw") == 0 ||
                strcmp(words[0], "outl") == 0) {
-        uint16_t addr;
-        uint32_t value;
+        unsigned long addr;
+        unsigned long value;
 
         g_assert(words[1] && words[2]);
-        addr = strtoul(words[1], NULL, 0);
-        value = strtoul(words[2], NULL, 0);
+        g_assert(qemu_strtoul(words[1], NULL, 0, &addr) == 0);
+        g_assert(qemu_strtoul(words[2], NULL, 0, &value) == 0);
+        g_assert(addr <= 0xffff);
 
         if (words[0][3] == 'b') {
             cpu_outb(addr, value);
@@ -344,11 +346,12 @@ static void qtest_process_command(CharDriverState *chr, gchar **words)
     } else if (strcmp(words[0], "inb") == 0 ||
         strcmp(words[0], "inw") == 0 ||
         strcmp(words[0], "inl") == 0) {
-        uint16_t addr;
+        unsigned long addr;
         uint32_t value = -1U;
 
         g_assert(words[1]);
-        addr = strtoul(words[1], NULL, 0);
+        g_assert(qemu_strtoul(words[1], NULL, 0, &addr) == 0);
+        g_assert(addr <= 0xffff);
 
         if (words[0][2] == 'b') {
             value = cpu_inb(addr);
@@ -367,8 +370,8 @@ static void qtest_process_command(CharDriverState *chr, gchar **words)
         uint64_t value;
 
         g_assert(words[1] && words[2]);
-        addr = strtoull(words[1], NULL, 0);
-        value = strtoull(words[2], NULL, 0);
+        g_assert(qemu_strtoull(words[1], NULL, 0, &addr) == 0);
+        g_assert(qemu_strtoull(words[2], NULL, 0, &value) == 0);
 
         if (words[0][5] == 'b') {
             uint8_t data = value;
@@ -396,7 +399,7 @@ static void qtest_process_command(CharDriverState *chr, gchar **words)
         uint64_t value = UINT64_C(-1);
 
         g_assert(words[1]);
-        addr = strtoull(words[1], NULL, 0);
+        g_assert(qemu_strtoull(words[1], NULL, 0, &addr) == 0);
 
         if (words[0][4] == 'b') {
             uint8_t data;
@@ -422,8 +425,8 @@ static void qtest_process_command(CharDriverState *chr, gchar **words)
         char *enc;
 
         g_assert(words[1] && words[2]);
-        addr = strtoull(words[1], NULL, 0);
-        len = strtoull(words[2], NULL, 0);
+        g_assert(qemu_strtoull(words[1], NULL, 0, &addr) == 0);
+        g_assert(qemu_strtoull(words[2], NULL, 0, &len) == 0);
 
         data = g_malloc(len);
         cpu_physical_memory_read(addr, data, len);
@@ -444,8 +447,8 @@ static void qtest_process_command(CharDriverState *chr, gchar **words)
         gchar *b64_data;
 
         g_assert(words[1] && words[2]);
-        addr = strtoull(words[1], NULL, 0);
-        len = strtoull(words[2], NULL, 0);
+        g_assert(qemu_strtoull(words[1], NULL, 0, &addr) == 0);
+        g_assert(qemu_strtoull(words[2], NULL, 0, &len) == 0);
 
         data = g_malloc(len);
         cpu_physical_memory_read(addr, data, len);
@@ -461,8 +464,8 @@ static void qtest_process_command(CharDriverState *chr, gchar **words)
         size_t data_len;
 
         g_assert(words[1] && words[2] && words[3]);
-        addr = strtoull(words[1], NULL, 0);
-        len = strtoull(words[2], NULL, 0);
+        g_assert(qemu_strtoull(words[1], NULL, 0, &addr) == 0);
+        g_assert(qemu_strtoull(words[2], NULL, 0, &len) == 0);
 
         data_len = strlen(words[3]);
         if (data_len < 3) {
@@ -487,12 +490,12 @@ static void qtest_process_command(CharDriverState *chr, gchar **words)
     } else if (strcmp(words[0], "memset") == 0) {
         uint64_t addr, len;
         uint8_t *data;
-        uint8_t pattern;
+        unsigned long pattern;
 
         g_assert(words[1] && words[2] && words[3]);
-        addr = strtoull(words[1], NULL, 0);
-        len = strtoull(words[2], NULL, 0);
-        pattern = strtoull(words[3], NULL, 0);
+        g_assert(qemu_strtoull(words[1], NULL, 0, &addr) == 0);
+        g_assert(qemu_strtoull(words[2], NULL, 0, &len) == 0);
+        g_assert(qemu_strtoul(words[3], NULL, 0, &pattern) == 0);
 
         if (len) {
             data = g_malloc(len);
@@ -510,8 +513,8 @@ static void qtest_process_command(CharDriverState *chr, gchar **words)
         gsize out_len;
 
         g_assert(words[1] && words[2] && words[3]);
-        addr = strtoull(words[1], NULL, 0);
-        len = strtoull(words[2], NULL, 0);
+        g_assert(qemu_strtoull(words[1], NULL, 0, &addr) == 0);
+        g_assert(qemu_strtoull(words[2], NULL, 0, &len) == 0);
 
         data_len = strlen(words[3]);
         if (data_len < 3) {
@@ -535,7 +538,7 @@ static void qtest_process_command(CharDriverState *chr, gchar **words)
         int64_t ns;
 
         if (words[1]) {
-            ns = strtoll(words[1], NULL, 0);
+            g_assert(qemu_strtoll(words[1], NULL, 0, &ns) == 0);
         } else {
             ns = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
         }
@@ -547,7 +550,7 @@ static void qtest_process_command(CharDriverState *chr, gchar **words)
         int64_t ns;
 
         g_assert(words[1]);
-        ns = strtoll(words[1], NULL, 0);
+        g_assert(qemu_strtoll(words[1], NULL, 0, &ns) == 0);
         qtest_clock_warp(ns);
         qtest_send_prefix(chr);
         qtest_sendf(chr, "OK %"PRIi64"\n",
-- 
2.5.5

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

* [Qemu-devel] [PATCH v8 2/3] libqos: define SPAPR libqos functions
  2016-09-13 12:52 [Qemu-devel] [PATCH v8 0/3] tests: add RTAS protocol Laurent Vivier
  2016-09-13 12:52 ` [Qemu-devel] [PATCH v8 1/3] qtest: replace strtoXX() by qemu_strtoXX() Laurent Vivier
@ 2016-09-13 12:52 ` Laurent Vivier
  2016-09-13 12:52 ` [Qemu-devel] [PATCH v8 3/3] tests: add RTAS command in the protocol Laurent Vivier
  2016-09-14  3:23 ` [Qemu-devel] [PATCH v8 0/3] tests: add RTAS protocol David Gibson
  3 siblings, 0 replies; 10+ messages in thread
From: Laurent Vivier @ 2016-09-13 12:52 UTC (permalink / raw)
  To: david; +Cc: thuth, lvivier, qemu-ppc, qemu-devel, groug

Define spapr_alloc_init()/spapr_alloc_init_flags()/spapr_alloc_uninit()

  to allocate and use SPAPR guest memory

Define qtest_spapr_vboot()/qtest_spapr_boot()/qtest_spapr_shutdown()

  to start SPAPR guest with QOSState initialized for it (memory management)

Move qtest_irq_intercept_in() from generic part to PC part.

Signed-off-by: Laurent Vivier <lvivier@redhat.com>
Reviewed-by: Greg Kurz <groug@kaod.org>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
---
v7:
- Add David's Rb

v6:
- rebase
- remove added include in tests/libqos/libqos.h
- add Greg's Rb
 
v5:
- replace "ppc64" by "spapr"
- Add test_spapr_vboot()/qtest_spapr_boot()/qtest_spapr_shutdown()
  and remove machine_alloc_XXX() fuctions

 tests/Makefile.include      |  2 ++
 tests/libqos/libqos-pc.c    |  2 ++
 tests/libqos/libqos-spapr.c | 30 ++++++++++++++++++++++++++++++
 tests/libqos/libqos-spapr.h | 10 ++++++++++
 tests/libqos/libqos.c       |  1 -
 tests/libqos/malloc-spapr.c | 38 ++++++++++++++++++++++++++++++++++++++
 tests/libqos/malloc-spapr.h | 17 +++++++++++++++++
 7 files changed, 99 insertions(+), 1 deletion(-)
 create mode 100644 tests/libqos/libqos-spapr.c
 create mode 100644 tests/libqos/libqos-spapr.h
 create mode 100644 tests/libqos/malloc-spapr.c
 create mode 100644 tests/libqos/malloc-spapr.h

diff --git a/tests/Makefile.include b/tests/Makefile.include
index e3a3266..91df9f2 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -576,6 +576,8 @@ tests/test-crypto-block$(EXESUF): tests/test-crypto-block.o $(test-crypto-obj-y)
 
 libqos-obj-y = tests/libqos/pci.o tests/libqos/fw_cfg.o tests/libqos/malloc.o
 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-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/libqos-pc.c b/tests/libqos/libqos-pc.c
index 72b5e3b..df34092 100644
--- a/tests/libqos/libqos-pc.c
+++ b/tests/libqos/libqos-pc.c
@@ -21,6 +21,8 @@ QOSState *qtest_pc_boot(const char *cmdline_fmt, ...)
     qs = qtest_vboot(&qos_ops, cmdline_fmt, ap);
     va_end(ap);
 
+    qtest_irq_intercept_in(global_qtest, "ioapic");
+
     return qs;
 }
 
diff --git a/tests/libqos/libqos-spapr.c b/tests/libqos/libqos-spapr.c
new file mode 100644
index 0000000..f19408b
--- /dev/null
+++ b/tests/libqos/libqos-spapr.c
@@ -0,0 +1,30 @@
+#include "qemu/osdep.h"
+#include "libqos/libqos-spapr.h"
+#include "libqos/malloc-spapr.h"
+
+static QOSOps qos_ops = {
+    .init_allocator = spapr_alloc_init_flags,
+    .uninit_allocator = spapr_alloc_uninit
+};
+
+QOSState *qtest_spapr_vboot(const char *cmdline_fmt, va_list ap)
+{
+    return qtest_vboot(&qos_ops, cmdline_fmt, ap);
+}
+
+QOSState *qtest_spapr_boot(const char *cmdline_fmt, ...)
+{
+    QOSState *qs;
+    va_list ap;
+
+    va_start(ap, cmdline_fmt);
+    qs = qtest_vboot(&qos_ops, cmdline_fmt, ap);
+    va_end(ap);
+
+    return qs;
+}
+
+void qtest_spapr_shutdown(QOSState *qs)
+{
+    return qtest_shutdown(qs);
+}
diff --git a/tests/libqos/libqos-spapr.h b/tests/libqos/libqos-spapr.h
new file mode 100644
index 0000000..dcb5c43
--- /dev/null
+++ b/tests/libqos/libqos-spapr.h
@@ -0,0 +1,10 @@
+#ifndef LIBQOS_SPAPR_H
+#define LIBQOS_SPAPR_H
+
+#include "libqos/libqos.h"
+
+QOSState *qtest_spapr_vboot(const char *cmdline_fmt, va_list ap);
+QOSState *qtest_spapr_boot(const char *cmdline_fmt, ...);
+void qtest_spapr_shutdown(QOSState *qs);
+
+#endif
diff --git a/tests/libqos/libqos.c b/tests/libqos/libqos.c
index c7ba441..a852dc5 100644
--- a/tests/libqos/libqos.c
+++ b/tests/libqos/libqos.c
@@ -20,7 +20,6 @@ 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;
-    qtest_irq_intercept_in(global_qtest, "ioapic");
     if (ops && ops->init_allocator) {
         qs->alloc = ops->init_allocator(ALLOC_NO_FLAGS);
     }
diff --git a/tests/libqos/malloc-spapr.c b/tests/libqos/malloc-spapr.c
new file mode 100644
index 0000000..006404a
--- /dev/null
+++ b/tests/libqos/malloc-spapr.c
@@ -0,0 +1,38 @@
+/*
+ * libqos malloc support 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 "libqos/malloc-spapr.h"
+
+#include "qemu-common.h"
+
+#define PAGE_SIZE 4096
+
+/* Memory must be a multiple of 256 MB,
+ * so we have at least 256MB
+ */
+#define SPAPR_MIN_SIZE 0x10000000
+
+void spapr_alloc_uninit(QGuestAllocator *allocator)
+{
+    alloc_uninit(allocator);
+}
+
+QGuestAllocator *spapr_alloc_init_flags(QAllocOpts flags)
+{
+    QGuestAllocator *s;
+
+    s = alloc_init_flags(flags, 1 << 20, SPAPR_MIN_SIZE);
+    alloc_set_page_size(s, PAGE_SIZE);
+
+    return s;
+}
+
+QGuestAllocator *spapr_alloc_init(void)
+{
+    return spapr_alloc_init_flags(ALLOC_NO_FLAGS);
+}
diff --git a/tests/libqos/malloc-spapr.h b/tests/libqos/malloc-spapr.h
new file mode 100644
index 0000000..64d0e77
--- /dev/null
+++ b/tests/libqos/malloc-spapr.h
@@ -0,0 +1,17 @@
+/*
+ * libqos malloc support 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_MALLOC_SPAPR_H
+#define LIBQOS_MALLOC_SPAPR_H
+
+#include "libqos/malloc.h"
+
+QGuestAllocator *spapr_alloc_init(void);
+QGuestAllocator *spapr_alloc_init_flags(QAllocOpts flags);
+void spapr_alloc_uninit(QGuestAllocator *allocator);
+
+#endif
-- 
2.5.5

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

* [Qemu-devel] [PATCH v8 3/3] tests: add RTAS command in the protocol
  2016-09-13 12:52 [Qemu-devel] [PATCH v8 0/3] tests: add RTAS protocol Laurent Vivier
  2016-09-13 12:52 ` [Qemu-devel] [PATCH v8 1/3] qtest: replace strtoXX() by qemu_strtoXX() Laurent Vivier
  2016-09-13 12:52 ` [Qemu-devel] [PATCH v8 2/3] libqos: define SPAPR libqos functions Laurent Vivier
@ 2016-09-13 12:52 ` Laurent Vivier
  2016-09-14  3:22   ` David Gibson
  2016-09-14  3:23 ` [Qemu-devel] [PATCH v8 0/3] tests: add RTAS protocol David Gibson
  3 siblings, 1 reply; 10+ messages in thread
From: Laurent Vivier @ 2016-09-13 12:52 UTC (permalink / raw)
  To: david; +Cc: thuth, lvivier, qemu-ppc, qemu-devel, groug

Add a first test to validate the protocol:

- rtas/get-time-of-day compares the time
  from the guest with the time from the host.

Signed-off-by: Laurent Vivier <lvivier@redhat.com>
Reviewed-by: Greg Kurz <groug@kaod.org>
---
v8:
- add Greg's Rb
- exit if RTAS is not started with qemu-system-ppc64

v7:
- don't allocate twice the memory for the RTAS call
- add "-machine pseries" in rtas-test

v6:
- rebase

v5:
- use qtest_spapr_boot() instead of machine_alloc_init()

v4:
- use qemu_strtoXXX() instead strtoXX()

v3:
- use mktimegm() instead of timegm()

v2:
- add a missing space in qrtas_call() prototype

 hw/ppc/spapr_rtas.c         | 19 ++++++++++++
 include/hw/ppc/spapr_rtas.h | 10 +++++++
 qtest.c                     | 17 +++++++++++
 tests/Makefile.include      |  3 ++
 tests/libqos/rtas.c         | 71 +++++++++++++++++++++++++++++++++++++++++++++
 tests/libqos/rtas.h         | 11 +++++++
 tests/libqtest.c            | 10 +++++++
 tests/libqtest.h            | 15 ++++++++++
 tests/rtas-test.c           | 41 ++++++++++++++++++++++++++
 9 files changed, 197 insertions(+)
 create mode 100644 include/hw/ppc/spapr_rtas.h
 create mode 100644 tests/libqos/rtas.c
 create mode 100644 tests/libqos/rtas.h
 create mode 100644 tests/rtas-test.c

diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
index 27b5ad4..b80c1db 100644
--- a/hw/ppc/spapr_rtas.c
+++ b/hw/ppc/spapr_rtas.c
@@ -37,6 +37,7 @@
 
 #include "hw/ppc/spapr.h"
 #include "hw/ppc/spapr_vio.h"
+#include "hw/ppc/spapr_rtas.h"
 #include "hw/ppc/ppc.h"
 #include "qapi-event.h"
 #include "hw/boards.h"
@@ -692,6 +693,24 @@ target_ulong spapr_rtas_call(PowerPCCPU *cpu, sPAPRMachineState *spapr,
     return H_PARAMETER;
 }
 
+uint64_t qtest_rtas_call(char *cmd, uint32_t nargs, uint64_t args,
+                         uint32_t nret, uint64_t rets)
+{
+    int token;
+
+    for (token = 0; token < RTAS_TOKEN_MAX - RTAS_TOKEN_BASE; token++) {
+        if (strcmp(cmd, rtas_table[token].name) == 0) {
+            sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
+            PowerPCCPU *cpu = POWERPC_CPU(first_cpu);
+
+            rtas_table[token].fn(cpu, spapr, token + RTAS_TOKEN_BASE,
+                                 nargs, args, nret, rets);
+            return H_SUCCESS;
+        }
+    }
+    return H_PARAMETER;
+}
+
 void spapr_rtas_register(int token, const char *name, spapr_rtas_fn fn)
 {
     assert((token >= RTAS_TOKEN_BASE) && (token < RTAS_TOKEN_MAX));
diff --git a/include/hw/ppc/spapr_rtas.h b/include/hw/ppc/spapr_rtas.h
new file mode 100644
index 0000000..383611f
--- /dev/null
+++ b/include/hw/ppc/spapr_rtas.h
@@ -0,0 +1,10 @@
+#ifndef HW_SPAPR_RTAS_H
+#define HW_SPAPR_RTAS_H
+/*
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+uint64_t qtest_rtas_call(char *cmd, uint32_t nargs, uint64_t args,
+                         uint32_t nret, uint64_t rets);
+#endif /* HW_SPAPR_RTAS_H */
diff --git a/qtest.c b/qtest.c
index 649f7b2..22482cc 100644
--- a/qtest.c
+++ b/qtest.c
@@ -28,6 +28,9 @@
 #include "qemu/option.h"
 #include "qemu/error-report.h"
 #include "qemu/cutils.h"
+#ifdef TARGET_PPC64
+#include "hw/ppc/spapr_rtas.h"
+#endif
 
 #define MAX_IRQ 256
 
@@ -534,6 +537,20 @@ static void qtest_process_command(CharDriverState *chr, gchar **words)
 
         qtest_send_prefix(chr);
         qtest_send(chr, "OK\n");
+#ifdef TARGET_PPC64
+    } else if (strcmp(words[0], "rtas") == 0) {
+        uint64_t res, args, ret;
+        unsigned long nargs, nret;
+
+        g_assert(qemu_strtoul(words[2], NULL, 0, &nargs) == 0);
+        g_assert(qemu_strtoull(words[3], NULL, 0, &args) == 0);
+        g_assert(qemu_strtoul(words[4], NULL, 0, &nret) == 0);
+        g_assert(qemu_strtoull(words[5], NULL, 0, &ret) == 0);
+        res = qtest_rtas_call(words[1], nargs, args, nret, ret);
+
+        qtest_send_prefix(chr);
+        qtest_sendf(chr, "OK %"PRIu64"\n", res);
+#endif
     } else if (qtest_enabled() && strcmp(words[0], "clock_step") == 0) {
         int64_t ns;
 
diff --git a/tests/Makefile.include b/tests/Makefile.include
index 91df9f2..fd61f97 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -265,6 +265,7 @@ check-qtest-ppc64-y += tests/prom-env-test$(EXESUF)
 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-sh4-y = tests/endianness-test$(EXESUF)
 
@@ -578,6 +579,7 @@ libqos-obj-y = tests/libqos/pci.o tests/libqos/fw_cfg.o tests/libqos/malloc.o
 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-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
@@ -592,6 +594,7 @@ tests/m48t59-test$(EXESUF): tests/m48t59-test.o
 tests/endianness-test$(EXESUF): tests/endianness-test.o
 tests/spapr-phb-test$(EXESUF): tests/spapr-phb-test.o $(libqos-obj-y)
 tests/prom-env-test$(EXESUF): tests/prom-env-test.o $(libqos-obj-y)
+tests/rtas-test$(EXESUF): tests/rtas-test.o $(libqos-spapr-obj-y)
 tests/fdc-test$(EXESUF): tests/fdc-test.o
 tests/ide-test$(EXESUF): tests/ide-test.o $(libqos-pc-obj-y)
 tests/ahci-test$(EXESUF): tests/ahci-test.o $(libqos-pc-obj-y)
diff --git a/tests/libqos/rtas.c b/tests/libqos/rtas.c
new file mode 100644
index 0000000..820321a
--- /dev/null
+++ b/tests/libqos/rtas.c
@@ -0,0 +1,71 @@
+/*
+ * 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/rtas.h"
+
+static void qrtas_copy_args(uint64_t target_args, uint32_t nargs,
+                            uint32_t *args)
+{
+    int i;
+
+    for (i = 0; i < nargs; i++) {
+        writel(target_args + i * sizeof(uint32_t), args[i]);
+    }
+}
+
+static void qrtas_copy_ret(uint64_t target_ret, uint32_t nret, uint32_t *ret)
+{
+    int i;
+
+    for (i = 0; i < nret; i++) {
+        ret[i] = readl(target_ret + i * sizeof(uint32_t));
+    }
+}
+
+static uint64_t qrtas_call(QGuestAllocator *alloc, const char *name,
+                           uint32_t nargs, uint32_t *args,
+                           uint32_t nret, uint32_t *ret)
+{
+    uint64_t res;
+    uint64_t target_args, target_ret;
+
+    target_args = guest_alloc(alloc, nargs * sizeof(uint32_t));
+    target_ret = guest_alloc(alloc, nret * sizeof(uint32_t));
+
+    qrtas_copy_args(target_args, nargs, args);
+    res = qtest_rtas_call(global_qtest, name,
+                          nargs, target_args, nret, target_ret);
+    qrtas_copy_ret(target_ret, nret, ret);
+
+    guest_free(alloc, target_ret);
+    guest_free(alloc, target_args);
+
+    return res;
+}
+
+int qrtas_get_time_of_day(QGuestAllocator *alloc, struct tm *tm, uint32_t *ns)
+{
+    int res;
+    uint32_t ret[8];
+
+    res = qrtas_call(alloc, "get-time-of-day", 0, NULL, 8, ret);
+    if (res != 0) {
+        return res;
+    }
+
+    res = ret[0];
+    memset(tm, 0, sizeof(*tm));
+    tm->tm_year = ret[1] - 1900;
+    tm->tm_mon = ret[2] - 1;
+    tm->tm_mday = ret[3];
+    tm->tm_hour = ret[4];
+    tm->tm_min = ret[5];
+    tm->tm_sec = ret[6];
+    *ns = ret[7];
+
+    return res;
+}
diff --git a/tests/libqos/rtas.h b/tests/libqos/rtas.h
new file mode 100644
index 0000000..a1b60a8
--- /dev/null
+++ b/tests/libqos/rtas.h
@@ -0,0 +1,11 @@
+/*
+ * 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_RTAS_H
+#define LIBQOS_RTAS_H
+#include "libqos/malloc.h"
+
+int qrtas_get_time_of_day(QGuestAllocator *alloc, struct tm *tm, uint32_t *ns);
+#endif /* LIBQOS_RTAS_H */
diff --git a/tests/libqtest.c b/tests/libqtest.c
index 42ccb62..6f6bdf1 100644
--- a/tests/libqtest.c
+++ b/tests/libqtest.c
@@ -751,6 +751,16 @@ void qtest_memread(QTestState *s, uint64_t addr, void *data, size_t size)
     g_strfreev(args);
 }
 
+uint64_t qtest_rtas_call(QTestState *s, const char *name,
+                         uint32_t nargs, uint64_t args,
+                         uint32_t nret, uint64_t ret)
+{
+    qtest_sendf(s, "rtas %s %u 0x%"PRIx64" %u 0x%"PRIx64"\n",
+                name, nargs, args, nret, ret);
+    qtest_rsp(s, 0);
+    return 0;
+}
+
 void qtest_add_func(const char *str, void (*fn)(void))
 {
     gchar *path = g_strdup_printf("/%s/%s", qtest_get_arch(), str);
diff --git a/tests/libqtest.h b/tests/libqtest.h
index d2b4853..f7402e0 100644
--- a/tests/libqtest.h
+++ b/tests/libqtest.h
@@ -318,6 +318,21 @@ uint64_t qtest_readq(QTestState *s, uint64_t addr);
 void qtest_memread(QTestState *s, uint64_t addr, void *data, size_t size);
 
 /**
+ * qtest_rtas_call:
+ * @s: #QTestState instance to operate on.
+ * @name: name of the command to call.
+ * @nargs: Number of args.
+ * @args: Guest address to read args from.
+ * @nret: Number of return value.
+ * @ret: Guest address to write return values to.
+ *
+ * Call an RTAS function
+ */
+uint64_t qtest_rtas_call(QTestState *s, const char *name,
+                         uint32_t nargs, uint64_t args,
+                         uint32_t nret, uint64_t ret);
+
+/**
  * qtest_bufread:
  * @s: #QTestState instance to operate on.
  * @addr: Guest address to read from.
diff --git a/tests/rtas-test.c b/tests/rtas-test.c
new file mode 100644
index 0000000..73c7803
--- /dev/null
+++ b/tests/rtas-test.c
@@ -0,0 +1,41 @@
+#include "qemu/osdep.h"
+#include "qemu/cutils.h"
+#include "libqtest.h"
+
+#include "libqos/libqos-spapr.h"
+#include "libqos/rtas.h"
+
+static void test_rtas_get_time_of_day(void)
+{
+    QOSState *qs;
+    struct tm tm;
+    uint32_t ns;
+    uint64_t ret;
+    time_t t1, t2;
+
+    qs = qtest_spapr_boot("-machine pseries");
+    g_assert(qs != NULL);
+
+    t1 = time(NULL);
+    ret = qrtas_get_time_of_day(qs->alloc, &tm, &ns);
+    g_assert_cmpint(ret, ==, 0);
+    t2 = mktimegm(&tm);
+    g_assert(t2 - t1 < 5); /* 5 sec max to run the test */
+
+    qtest_spapr_shutdown(qs);
+}
+
+int main(int argc, char *argv[])
+{
+    const char *arch = qtest_get_arch();
+
+    g_test_init(&argc, &argv, NULL);
+
+    if (strcmp(arch, "ppc64")) {
+        g_printerr("RTAS requires ppc64-softmmu/qemu-system-ppc64\n");
+        exit(EXIT_FAILURE);
+    }
+    qtest_add_func("rtas/get-time-of-day", test_rtas_get_time_of_day);
+
+    return g_test_run();
+}
-- 
2.5.5

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

* Re: [Qemu-devel] [PATCH v8 3/3] tests: add RTAS command in the protocol
  2016-09-13 12:52 ` [Qemu-devel] [PATCH v8 3/3] tests: add RTAS command in the protocol Laurent Vivier
@ 2016-09-14  3:22   ` David Gibson
  2016-09-14  9:05     ` [Qemu-devel] [Qemu-ppc] " Greg Kurz
  0 siblings, 1 reply; 10+ messages in thread
From: David Gibson @ 2016-09-14  3:22 UTC (permalink / raw)
  To: Laurent Vivier; +Cc: thuth, qemu-ppc, qemu-devel, groug

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

On Tue, Sep 13, 2016 at 02:52:45PM +0200, Laurent Vivier wrote:
> Add a first test to validate the protocol:
> 
> - rtas/get-time-of-day compares the time
>   from the guest with the time from the host.
> 
> Signed-off-by: Laurent Vivier <lvivier@redhat.com>
> Reviewed-by: Greg Kurz <groug@kaod.org>

Reviewed-by: David Gibson <david@gibson.dropbear.id.au>

> ---
> v8:
> - add Greg's Rb
> - exit if RTAS is not started with qemu-system-ppc64
> 
> v7:
> - don't allocate twice the memory for the RTAS call
> - add "-machine pseries" in rtas-test
> 
> v6:
> - rebase
> 
> v5:
> - use qtest_spapr_boot() instead of machine_alloc_init()
> 
> v4:
> - use qemu_strtoXXX() instead strtoXX()
> 
> v3:
> - use mktimegm() instead of timegm()
> 
> v2:
> - add a missing space in qrtas_call() prototype
> 
>  hw/ppc/spapr_rtas.c         | 19 ++++++++++++
>  include/hw/ppc/spapr_rtas.h | 10 +++++++
>  qtest.c                     | 17 +++++++++++
>  tests/Makefile.include      |  3 ++
>  tests/libqos/rtas.c         | 71 +++++++++++++++++++++++++++++++++++++++++++++
>  tests/libqos/rtas.h         | 11 +++++++
>  tests/libqtest.c            | 10 +++++++
>  tests/libqtest.h            | 15 ++++++++++
>  tests/rtas-test.c           | 41 ++++++++++++++++++++++++++
>  9 files changed, 197 insertions(+)
>  create mode 100644 include/hw/ppc/spapr_rtas.h
>  create mode 100644 tests/libqos/rtas.c
>  create mode 100644 tests/libqos/rtas.h
>  create mode 100644 tests/rtas-test.c
> 
> diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
> index 27b5ad4..b80c1db 100644
> --- a/hw/ppc/spapr_rtas.c
> +++ b/hw/ppc/spapr_rtas.c
> @@ -37,6 +37,7 @@
>  
>  #include "hw/ppc/spapr.h"
>  #include "hw/ppc/spapr_vio.h"
> +#include "hw/ppc/spapr_rtas.h"
>  #include "hw/ppc/ppc.h"
>  #include "qapi-event.h"
>  #include "hw/boards.h"
> @@ -692,6 +693,24 @@ target_ulong spapr_rtas_call(PowerPCCPU *cpu, sPAPRMachineState *spapr,
>      return H_PARAMETER;
>  }
>  
> +uint64_t qtest_rtas_call(char *cmd, uint32_t nargs, uint64_t args,
> +                         uint32_t nret, uint64_t rets)
> +{
> +    int token;
> +
> +    for (token = 0; token < RTAS_TOKEN_MAX - RTAS_TOKEN_BASE; token++) {
> +        if (strcmp(cmd, rtas_table[token].name) == 0) {
> +            sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());

As a sanity check you could return an error if you're unable to
resolve the machine as an sPAPR here.  Since that should only happen
on a broken testcase, it can be done as a later enhancement, though.

> +            PowerPCCPU *cpu = POWERPC_CPU(first_cpu);
> +
> +            rtas_table[token].fn(cpu, spapr, token + RTAS_TOKEN_BASE,
> +                                 nargs, args, nret, rets);
> +            return H_SUCCESS;
> +        }
> +    }
> +    return H_PARAMETER;
> +}
> +
>  void spapr_rtas_register(int token, const char *name, spapr_rtas_fn fn)
>  {
>      assert((token >= RTAS_TOKEN_BASE) && (token < RTAS_TOKEN_MAX));
> diff --git a/include/hw/ppc/spapr_rtas.h b/include/hw/ppc/spapr_rtas.h
> new file mode 100644
> index 0000000..383611f
> --- /dev/null
> +++ b/include/hw/ppc/spapr_rtas.h
> @@ -0,0 +1,10 @@
> +#ifndef HW_SPAPR_RTAS_H
> +#define HW_SPAPR_RTAS_H
> +/*
> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> + * See the COPYING file in the top-level directory.
> + */
> +
> +uint64_t qtest_rtas_call(char *cmd, uint32_t nargs, uint64_t args,
> +                         uint32_t nret, uint64_t rets);
> +#endif /* HW_SPAPR_RTAS_H */
> diff --git a/qtest.c b/qtest.c
> index 649f7b2..22482cc 100644
> --- a/qtest.c
> +++ b/qtest.c
> @@ -28,6 +28,9 @@
>  #include "qemu/option.h"
>  #include "qemu/error-report.h"
>  #include "qemu/cutils.h"
> +#ifdef TARGET_PPC64
> +#include "hw/ppc/spapr_rtas.h"
> +#endif
>  
>  #define MAX_IRQ 256
>  
> @@ -534,6 +537,20 @@ static void qtest_process_command(CharDriverState *chr, gchar **words)
>  
>          qtest_send_prefix(chr);
>          qtest_send(chr, "OK\n");
> +#ifdef TARGET_PPC64
> +    } else if (strcmp(words[0], "rtas") == 0) {
> +        uint64_t res, args, ret;
> +        unsigned long nargs, nret;
> +
> +        g_assert(qemu_strtoul(words[2], NULL, 0, &nargs) == 0);
> +        g_assert(qemu_strtoull(words[3], NULL, 0, &args) == 0);
> +        g_assert(qemu_strtoul(words[4], NULL, 0, &nret) == 0);
> +        g_assert(qemu_strtoull(words[5], NULL, 0, &ret) == 0);
> +        res = qtest_rtas_call(words[1], nargs, args, nret, ret);
> +
> +        qtest_send_prefix(chr);
> +        qtest_sendf(chr, "OK %"PRIu64"\n", res);
> +#endif
>      } else if (qtest_enabled() && strcmp(words[0], "clock_step") == 0) {
>          int64_t ns;
>  
> diff --git a/tests/Makefile.include b/tests/Makefile.include
> index 91df9f2..fd61f97 100644
> --- a/tests/Makefile.include
> +++ b/tests/Makefile.include
> @@ -265,6 +265,7 @@ check-qtest-ppc64-y += tests/prom-env-test$(EXESUF)
>  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-sh4-y = tests/endianness-test$(EXESUF)
>  
> @@ -578,6 +579,7 @@ libqos-obj-y = tests/libqos/pci.o tests/libqos/fw_cfg.o tests/libqos/malloc.o
>  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-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
> @@ -592,6 +594,7 @@ tests/m48t59-test$(EXESUF): tests/m48t59-test.o
>  tests/endianness-test$(EXESUF): tests/endianness-test.o
>  tests/spapr-phb-test$(EXESUF): tests/spapr-phb-test.o $(libqos-obj-y)
>  tests/prom-env-test$(EXESUF): tests/prom-env-test.o $(libqos-obj-y)
> +tests/rtas-test$(EXESUF): tests/rtas-test.o $(libqos-spapr-obj-y)
>  tests/fdc-test$(EXESUF): tests/fdc-test.o
>  tests/ide-test$(EXESUF): tests/ide-test.o $(libqos-pc-obj-y)
>  tests/ahci-test$(EXESUF): tests/ahci-test.o $(libqos-pc-obj-y)
> diff --git a/tests/libqos/rtas.c b/tests/libqos/rtas.c
> new file mode 100644
> index 0000000..820321a
> --- /dev/null
> +++ b/tests/libqos/rtas.c
> @@ -0,0 +1,71 @@
> +/*
> + * 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/rtas.h"
> +
> +static void qrtas_copy_args(uint64_t target_args, uint32_t nargs,
> +                            uint32_t *args)
> +{
> +    int i;
> +
> +    for (i = 0; i < nargs; i++) {
> +        writel(target_args + i * sizeof(uint32_t), args[i]);
> +    }
> +}
> +
> +static void qrtas_copy_ret(uint64_t target_ret, uint32_t nret, uint32_t *ret)
> +{
> +    int i;
> +
> +    for (i = 0; i < nret; i++) {
> +        ret[i] = readl(target_ret + i * sizeof(uint32_t));
> +    }
> +}
> +
> +static uint64_t qrtas_call(QGuestAllocator *alloc, const char *name,
> +                           uint32_t nargs, uint32_t *args,
> +                           uint32_t nret, uint32_t *ret)
> +{
> +    uint64_t res;
> +    uint64_t target_args, target_ret;
> +
> +    target_args = guest_alloc(alloc, nargs * sizeof(uint32_t));
> +    target_ret = guest_alloc(alloc, nret * sizeof(uint32_t));
> +
> +    qrtas_copy_args(target_args, nargs, args);
> +    res = qtest_rtas_call(global_qtest, name,
> +                          nargs, target_args, nret, target_ret);
> +    qrtas_copy_ret(target_ret, nret, ret);
> +
> +    guest_free(alloc, target_ret);
> +    guest_free(alloc, target_args);
> +
> +    return res;
> +}

This might be slightly more robust if the args were put into an actual
rtas args buffer (with the token not populated), rather than separate
args and rets array.  Again, that can be a later improvement though.

> +
> +int qrtas_get_time_of_day(QGuestAllocator *alloc, struct tm *tm, uint32_t *ns)
> +{
> +    int res;
> +    uint32_t ret[8];
> +
> +    res = qrtas_call(alloc, "get-time-of-day", 0, NULL, 8, ret);
> +    if (res != 0) {
> +        return res;
> +    }
> +
> +    res = ret[0];
> +    memset(tm, 0, sizeof(*tm));
> +    tm->tm_year = ret[1] - 1900;
> +    tm->tm_mon = ret[2] - 1;
> +    tm->tm_mday = ret[3];
> +    tm->tm_hour = ret[4];
> +    tm->tm_min = ret[5];
> +    tm->tm_sec = ret[6];
> +    *ns = ret[7];
> +
> +    return res;
> +}
> diff --git a/tests/libqos/rtas.h b/tests/libqos/rtas.h
> new file mode 100644
> index 0000000..a1b60a8
> --- /dev/null
> +++ b/tests/libqos/rtas.h
> @@ -0,0 +1,11 @@
> +/*
> + * 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_RTAS_H
> +#define LIBQOS_RTAS_H
> +#include "libqos/malloc.h"
> +
> +int qrtas_get_time_of_day(QGuestAllocator *alloc, struct tm *tm, uint32_t *ns);
> +#endif /* LIBQOS_RTAS_H */
> diff --git a/tests/libqtest.c b/tests/libqtest.c
> index 42ccb62..6f6bdf1 100644
> --- a/tests/libqtest.c
> +++ b/tests/libqtest.c
> @@ -751,6 +751,16 @@ void qtest_memread(QTestState *s, uint64_t addr, void *data, size_t size)
>      g_strfreev(args);
>  }
>  
> +uint64_t qtest_rtas_call(QTestState *s, const char *name,
> +                         uint32_t nargs, uint64_t args,
> +                         uint32_t nret, uint64_t ret)
> +{
> +    qtest_sendf(s, "rtas %s %u 0x%"PRIx64" %u 0x%"PRIx64"\n",
> +                name, nargs, args, nret, ret);
> +    qtest_rsp(s, 0);
> +    return 0;
> +}
> +
>  void qtest_add_func(const char *str, void (*fn)(void))
>  {
>      gchar *path = g_strdup_printf("/%s/%s", qtest_get_arch(), str);
> diff --git a/tests/libqtest.h b/tests/libqtest.h
> index d2b4853..f7402e0 100644
> --- a/tests/libqtest.h
> +++ b/tests/libqtest.h
> @@ -318,6 +318,21 @@ uint64_t qtest_readq(QTestState *s, uint64_t addr);
>  void qtest_memread(QTestState *s, uint64_t addr, void *data, size_t size);
>  
>  /**
> + * qtest_rtas_call:
> + * @s: #QTestState instance to operate on.
> + * @name: name of the command to call.
> + * @nargs: Number of args.
> + * @args: Guest address to read args from.
> + * @nret: Number of return value.
> + * @ret: Guest address to write return values to.
> + *
> + * Call an RTAS function
> + */
> +uint64_t qtest_rtas_call(QTestState *s, const char *name,
> +                         uint32_t nargs, uint64_t args,
> +                         uint32_t nret, uint64_t ret);
> +
> +/**
>   * qtest_bufread:
>   * @s: #QTestState instance to operate on.
>   * @addr: Guest address to read from.
> diff --git a/tests/rtas-test.c b/tests/rtas-test.c
> new file mode 100644
> index 0000000..73c7803
> --- /dev/null
> +++ b/tests/rtas-test.c
> @@ -0,0 +1,41 @@
> +#include "qemu/osdep.h"
> +#include "qemu/cutils.h"
> +#include "libqtest.h"
> +
> +#include "libqos/libqos-spapr.h"
> +#include "libqos/rtas.h"
> +
> +static void test_rtas_get_time_of_day(void)
> +{
> +    QOSState *qs;
> +    struct tm tm;
> +    uint32_t ns;
> +    uint64_t ret;
> +    time_t t1, t2;
> +
> +    qs = qtest_spapr_boot("-machine pseries");
> +    g_assert(qs != NULL);
> +
> +    t1 = time(NULL);
> +    ret = qrtas_get_time_of_day(qs->alloc, &tm, &ns);
> +    g_assert_cmpint(ret, ==, 0);
> +    t2 = mktimegm(&tm);
> +    g_assert(t2 - t1 < 5); /* 5 sec max to run the test */
> +
> +    qtest_spapr_shutdown(qs);
> +}
> +
> +int main(int argc, char *argv[])
> +{
> +    const char *arch = qtest_get_arch();
> +
> +    g_test_init(&argc, &argv, NULL);
> +
> +    if (strcmp(arch, "ppc64")) {
> +        g_printerr("RTAS requires ppc64-softmmu/qemu-system-ppc64\n");
> +        exit(EXIT_FAILURE);
> +    }
> +    qtest_add_func("rtas/get-time-of-day", test_rtas_get_time_of_day);
> +
> +    return g_test_run();
> +}

-- 
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: 801 bytes --]

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

* Re: [Qemu-devel] [PATCH v8 0/3] tests: add RTAS protocol
  2016-09-13 12:52 [Qemu-devel] [PATCH v8 0/3] tests: add RTAS protocol Laurent Vivier
                   ` (2 preceding siblings ...)
  2016-09-13 12:52 ` [Qemu-devel] [PATCH v8 3/3] tests: add RTAS command in the protocol Laurent Vivier
@ 2016-09-14  3:23 ` David Gibson
  2016-09-14  9:07   ` [Qemu-devel] [Qemu-ppc] " Greg Kurz
  3 siblings, 1 reply; 10+ messages in thread
From: David Gibson @ 2016-09-14  3:23 UTC (permalink / raw)
  To: Laurent Vivier; +Cc: thuth, qemu-ppc, qemu-devel, groug

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

On Tue, Sep 13, 2016 at 02:52:42PM +0200, Laurent Vivier wrote:
> This series allows to call RTAS commands from the qtest framework,
> and defines a first test to call RTAS command "get-time-of-day"
> to validate the protocol and test RTAS.
> 
> RTAS command parameters are passed to the guest via the
> guest memory, so we also need to implement the guest memory
> management functions for SPAPR target.
> 
> RTAS commands will be needed later to test PCI from the qtest framework
> with SPAPR virtual machines: PCI configuration is read/written with
> RTAS commands "ibm,read-pci-config", "ibm,write-pci-config".

I've applied the series to ppc-for-2.8, at least assuming no-one has
any objections to this coming through my tree.

> 
> v8:
> - exit if RTAS is not started with qemu-system-ppc64
> 
> v7:
> - don't allocate twice the memory for the RTAS call
> - add "-machine pseries" in rtas-test to be sure to use 
>   the good machine type (with RTAS support).
> 
> v6:
> - rebase
> - remove useless include
> 
> v5:
> - replace "ppc64" by "spapr"
> - define and use qtest_spapr_vboot()/qtest_spapr_boot()/qtest_spapr_shutdown()
> 
> v4:
> - use qemu_strtoXXX() instead strtoXX(),
>   add a patch in the series to change all strtoXX() in qtest.c
> 
> v3:
> - use mktimegm() instead of timegm()
> 
> v2:
> - remove useless parenthesis, inline
> - add a missing space in qrtas_call() prototype
> 
> Laurent Vivier (3):
>   qtest: replace strtoXX() by qemu_strtoXX()
>   libqos: define SPAPR libqos functions
>   tests: add RTAS command in the protocol
> 
>  hw/ppc/spapr_rtas.c         | 19 ++++++++++++
>  include/hw/ppc/spapr_rtas.h | 10 +++++++
>  qtest.c                     | 66 ++++++++++++++++++++++++++---------------
>  tests/Makefile.include      |  5 ++++
>  tests/libqos/libqos-pc.c    |  2 ++
>  tests/libqos/libqos-spapr.c | 30 +++++++++++++++++++
>  tests/libqos/libqos-spapr.h | 10 +++++++
>  tests/libqos/libqos.c       |  1 -
>  tests/libqos/malloc-spapr.c | 38 ++++++++++++++++++++++++
>  tests/libqos/malloc-spapr.h | 17 +++++++++++
>  tests/libqos/rtas.c         | 71 +++++++++++++++++++++++++++++++++++++++++++++
>  tests/libqos/rtas.h         | 11 +++++++
>  tests/libqtest.c            | 10 +++++++
>  tests/libqtest.h            | 15 ++++++++++
>  tests/rtas-test.c           | 41 ++++++++++++++++++++++++++
>  15 files changed, 322 insertions(+), 24 deletions(-)
>  create mode 100644 include/hw/ppc/spapr_rtas.h
>  create mode 100644 tests/libqos/libqos-spapr.c
>  create mode 100644 tests/libqos/libqos-spapr.h
>  create mode 100644 tests/libqos/malloc-spapr.c
>  create mode 100644 tests/libqos/malloc-spapr.h
>  create mode 100644 tests/libqos/rtas.c
>  create mode 100644 tests/libqos/rtas.h
>  create mode 100644 tests/rtas-test.c
> 

-- 
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: 801 bytes --]

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

* Re: [Qemu-devel] [Qemu-ppc] [PATCH v8 3/3] tests: add RTAS command in the protocol
  2016-09-14  3:22   ` David Gibson
@ 2016-09-14  9:05     ` Greg Kurz
  2016-09-14 10:51       ` David Gibson
  0 siblings, 1 reply; 10+ messages in thread
From: Greg Kurz @ 2016-09-14  9:05 UTC (permalink / raw)
  To: David Gibson; +Cc: Laurent Vivier, thuth, qemu-ppc, qemu-devel

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

On Wed, 14 Sep 2016 13:22:40 +1000
David Gibson <david@gibson.dropbear.id.au> wrote:

> On Tue, Sep 13, 2016 at 02:52:45PM +0200, Laurent Vivier wrote:
> > Add a first test to validate the protocol:
> > 
> > - rtas/get-time-of-day compares the time
> >   from the guest with the time from the host.
> > 
> > Signed-off-by: Laurent Vivier <lvivier@redhat.com>
> > Reviewed-by: Greg Kurz <groug@kaod.org>  
> 
> Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
> 
> > ---
> > v8:
> > - add Greg's Rb
> > - exit if RTAS is not started with qemu-system-ppc64
> > 
> > v7:
> > - don't allocate twice the memory for the RTAS call
> > - add "-machine pseries" in rtas-test
> > 
> > v6:
> > - rebase
> > 
> > v5:
> > - use qtest_spapr_boot() instead of machine_alloc_init()
> > 
> > v4:
> > - use qemu_strtoXXX() instead strtoXX()
> > 
> > v3:
> > - use mktimegm() instead of timegm()
> > 
> > v2:
> > - add a missing space in qrtas_call() prototype
> > 
> >  hw/ppc/spapr_rtas.c         | 19 ++++++++++++
> >  include/hw/ppc/spapr_rtas.h | 10 +++++++
> >  qtest.c                     | 17 +++++++++++
> >  tests/Makefile.include      |  3 ++
> >  tests/libqos/rtas.c         | 71 +++++++++++++++++++++++++++++++++++++++++++++
> >  tests/libqos/rtas.h         | 11 +++++++
> >  tests/libqtest.c            | 10 +++++++
> >  tests/libqtest.h            | 15 ++++++++++
> >  tests/rtas-test.c           | 41 ++++++++++++++++++++++++++
> >  9 files changed, 197 insertions(+)
> >  create mode 100644 include/hw/ppc/spapr_rtas.h
> >  create mode 100644 tests/libqos/rtas.c
> >  create mode 100644 tests/libqos/rtas.h
> >  create mode 100644 tests/rtas-test.c
> > 
> > diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
> > index 27b5ad4..b80c1db 100644
> > --- a/hw/ppc/spapr_rtas.c
> > +++ b/hw/ppc/spapr_rtas.c
> > @@ -37,6 +37,7 @@
> >  
> >  #include "hw/ppc/spapr.h"
> >  #include "hw/ppc/spapr_vio.h"
> > +#include "hw/ppc/spapr_rtas.h"
> >  #include "hw/ppc/ppc.h"
> >  #include "qapi-event.h"
> >  #include "hw/boards.h"
> > @@ -692,6 +693,24 @@ target_ulong spapr_rtas_call(PowerPCCPU *cpu, sPAPRMachineState *spapr,
> >      return H_PARAMETER;
> >  }
> >  
> > +uint64_t qtest_rtas_call(char *cmd, uint32_t nargs, uint64_t args,
> > +                         uint32_t nret, uint64_t rets)
> > +{
> > +    int token;
> > +
> > +    for (token = 0; token < RTAS_TOKEN_MAX - RTAS_TOKEN_BASE; token++) {
> > +        if (strcmp(cmd, rtas_table[token].name) == 0) {
> > +            sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());  
> 
> As a sanity check you could return an error if you're unable to
> resolve the machine as an sPAPR here.  Since that should only happen
> on a broken testcase, it can be done as a later enhancement, though.
> 

Hmm... if the machine isn't sPAPR, SPAPR_MACHINE() will abort, which makes
sense in the case of a broken testcase.

hw/ppc/spapr_rtas.c:703:qtest_rtas_call: Object 0x558f5de65590 is not an instance of type spapr-machine

> > +            PowerPCCPU *cpu = POWERPC_CPU(first_cpu);
> > +
> > +            rtas_table[token].fn(cpu, spapr, token + RTAS_TOKEN_BASE,
> > +                                 nargs, args, nret, rets);
> > +            return H_SUCCESS;
> > +        }
> > +    }
> > +    return H_PARAMETER;
> > +}
> > +
> >  void spapr_rtas_register(int token, const char *name, spapr_rtas_fn fn)
> >  {
> >      assert((token >= RTAS_TOKEN_BASE) && (token < RTAS_TOKEN_MAX));
> > diff --git a/include/hw/ppc/spapr_rtas.h b/include/hw/ppc/spapr_rtas.h
> > new file mode 100644
> > index 0000000..383611f
> > --- /dev/null
> > +++ b/include/hw/ppc/spapr_rtas.h
> > @@ -0,0 +1,10 @@
> > +#ifndef HW_SPAPR_RTAS_H
> > +#define HW_SPAPR_RTAS_H
> > +/*
> > + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> > + * See the COPYING file in the top-level directory.
> > + */
> > +
> > +uint64_t qtest_rtas_call(char *cmd, uint32_t nargs, uint64_t args,
> > +                         uint32_t nret, uint64_t rets);
> > +#endif /* HW_SPAPR_RTAS_H */
> > diff --git a/qtest.c b/qtest.c
> > index 649f7b2..22482cc 100644
> > --- a/qtest.c
> > +++ b/qtest.c
> > @@ -28,6 +28,9 @@
> >  #include "qemu/option.h"
> >  #include "qemu/error-report.h"
> >  #include "qemu/cutils.h"
> > +#ifdef TARGET_PPC64
> > +#include "hw/ppc/spapr_rtas.h"
> > +#endif
> >  
> >  #define MAX_IRQ 256
> >  
> > @@ -534,6 +537,20 @@ static void qtest_process_command(CharDriverState *chr, gchar **words)
> >  
> >          qtest_send_prefix(chr);
> >          qtest_send(chr, "OK\n");
> > +#ifdef TARGET_PPC64
> > +    } else if (strcmp(words[0], "rtas") == 0) {
> > +        uint64_t res, args, ret;
> > +        unsigned long nargs, nret;
> > +
> > +        g_assert(qemu_strtoul(words[2], NULL, 0, &nargs) == 0);
> > +        g_assert(qemu_strtoull(words[3], NULL, 0, &args) == 0);
> > +        g_assert(qemu_strtoul(words[4], NULL, 0, &nret) == 0);
> > +        g_assert(qemu_strtoull(words[5], NULL, 0, &ret) == 0);
> > +        res = qtest_rtas_call(words[1], nargs, args, nret, ret);
> > +
> > +        qtest_send_prefix(chr);
> > +        qtest_sendf(chr, "OK %"PRIu64"\n", res);
> > +#endif
> >      } else if (qtest_enabled() && strcmp(words[0], "clock_step") == 0) {
> >          int64_t ns;
> >  
> > diff --git a/tests/Makefile.include b/tests/Makefile.include
> > index 91df9f2..fd61f97 100644
> > --- a/tests/Makefile.include
> > +++ b/tests/Makefile.include
> > @@ -265,6 +265,7 @@ check-qtest-ppc64-y += tests/prom-env-test$(EXESUF)
> >  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-sh4-y = tests/endianness-test$(EXESUF)
> >  
> > @@ -578,6 +579,7 @@ libqos-obj-y = tests/libqos/pci.o tests/libqos/fw_cfg.o tests/libqos/malloc.o
> >  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-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
> > @@ -592,6 +594,7 @@ tests/m48t59-test$(EXESUF): tests/m48t59-test.o
> >  tests/endianness-test$(EXESUF): tests/endianness-test.o
> >  tests/spapr-phb-test$(EXESUF): tests/spapr-phb-test.o $(libqos-obj-y)
> >  tests/prom-env-test$(EXESUF): tests/prom-env-test.o $(libqos-obj-y)
> > +tests/rtas-test$(EXESUF): tests/rtas-test.o $(libqos-spapr-obj-y)
> >  tests/fdc-test$(EXESUF): tests/fdc-test.o
> >  tests/ide-test$(EXESUF): tests/ide-test.o $(libqos-pc-obj-y)
> >  tests/ahci-test$(EXESUF): tests/ahci-test.o $(libqos-pc-obj-y)
> > diff --git a/tests/libqos/rtas.c b/tests/libqos/rtas.c
> > new file mode 100644
> > index 0000000..820321a
> > --- /dev/null
> > +++ b/tests/libqos/rtas.c
> > @@ -0,0 +1,71 @@
> > +/*
> > + * 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/rtas.h"
> > +
> > +static void qrtas_copy_args(uint64_t target_args, uint32_t nargs,
> > +                            uint32_t *args)
> > +{
> > +    int i;
> > +
> > +    for (i = 0; i < nargs; i++) {
> > +        writel(target_args + i * sizeof(uint32_t), args[i]);
> > +    }
> > +}
> > +
> > +static void qrtas_copy_ret(uint64_t target_ret, uint32_t nret, uint32_t *ret)
> > +{
> > +    int i;
> > +
> > +    for (i = 0; i < nret; i++) {
> > +        ret[i] = readl(target_ret + i * sizeof(uint32_t));
> > +    }
> > +}
> > +
> > +static uint64_t qrtas_call(QGuestAllocator *alloc, const char *name,
> > +                           uint32_t nargs, uint32_t *args,
> > +                           uint32_t nret, uint32_t *ret)
> > +{
> > +    uint64_t res;
> > +    uint64_t target_args, target_ret;
> > +
> > +    target_args = guest_alloc(alloc, nargs * sizeof(uint32_t));
> > +    target_ret = guest_alloc(alloc, nret * sizeof(uint32_t));
> > +
> > +    qrtas_copy_args(target_args, nargs, args);
> > +    res = qtest_rtas_call(global_qtest, name,
> > +                          nargs, target_args, nret, target_ret);
> > +    qrtas_copy_ret(target_ret, nret, ret);
> > +
> > +    guest_free(alloc, target_ret);
> > +    guest_free(alloc, target_args);
> > +
> > +    return res;
> > +}  
> 
> This might be slightly more robust if the args were put into an actual
> rtas args buffer (with the token not populated), rather than separate
> args and rets array.  Again, that can be a later improvement though.
> 
> > +
> > +int qrtas_get_time_of_day(QGuestAllocator *alloc, struct tm *tm, uint32_t *ns)
> > +{
> > +    int res;
> > +    uint32_t ret[8];
> > +
> > +    res = qrtas_call(alloc, "get-time-of-day", 0, NULL, 8, ret);
> > +    if (res != 0) {
> > +        return res;
> > +    }
> > +
> > +    res = ret[0];
> > +    memset(tm, 0, sizeof(*tm));
> > +    tm->tm_year = ret[1] - 1900;
> > +    tm->tm_mon = ret[2] - 1;
> > +    tm->tm_mday = ret[3];
> > +    tm->tm_hour = ret[4];
> > +    tm->tm_min = ret[5];
> > +    tm->tm_sec = ret[6];
> > +    *ns = ret[7];
> > +
> > +    return res;
> > +}
> > diff --git a/tests/libqos/rtas.h b/tests/libqos/rtas.h
> > new file mode 100644
> > index 0000000..a1b60a8
> > --- /dev/null
> > +++ b/tests/libqos/rtas.h
> > @@ -0,0 +1,11 @@
> > +/*
> > + * 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_RTAS_H
> > +#define LIBQOS_RTAS_H
> > +#include "libqos/malloc.h"
> > +
> > +int qrtas_get_time_of_day(QGuestAllocator *alloc, struct tm *tm, uint32_t *ns);
> > +#endif /* LIBQOS_RTAS_H */
> > diff --git a/tests/libqtest.c b/tests/libqtest.c
> > index 42ccb62..6f6bdf1 100644
> > --- a/tests/libqtest.c
> > +++ b/tests/libqtest.c
> > @@ -751,6 +751,16 @@ void qtest_memread(QTestState *s, uint64_t addr, void *data, size_t size)
> >      g_strfreev(args);
> >  }
> >  
> > +uint64_t qtest_rtas_call(QTestState *s, const char *name,
> > +                         uint32_t nargs, uint64_t args,
> > +                         uint32_t nret, uint64_t ret)
> > +{
> > +    qtest_sendf(s, "rtas %s %u 0x%"PRIx64" %u 0x%"PRIx64"\n",
> > +                name, nargs, args, nret, ret);
> > +    qtest_rsp(s, 0);
> > +    return 0;
> > +}
> > +
> >  void qtest_add_func(const char *str, void (*fn)(void))
> >  {
> >      gchar *path = g_strdup_printf("/%s/%s", qtest_get_arch(), str);
> > diff --git a/tests/libqtest.h b/tests/libqtest.h
> > index d2b4853..f7402e0 100644
> > --- a/tests/libqtest.h
> > +++ b/tests/libqtest.h
> > @@ -318,6 +318,21 @@ uint64_t qtest_readq(QTestState *s, uint64_t addr);
> >  void qtest_memread(QTestState *s, uint64_t addr, void *data, size_t size);
> >  
> >  /**
> > + * qtest_rtas_call:
> > + * @s: #QTestState instance to operate on.
> > + * @name: name of the command to call.
> > + * @nargs: Number of args.
> > + * @args: Guest address to read args from.
> > + * @nret: Number of return value.
> > + * @ret: Guest address to write return values to.
> > + *
> > + * Call an RTAS function
> > + */
> > +uint64_t qtest_rtas_call(QTestState *s, const char *name,
> > +                         uint32_t nargs, uint64_t args,
> > +                         uint32_t nret, uint64_t ret);
> > +
> > +/**
> >   * qtest_bufread:
> >   * @s: #QTestState instance to operate on.
> >   * @addr: Guest address to read from.
> > diff --git a/tests/rtas-test.c b/tests/rtas-test.c
> > new file mode 100644
> > index 0000000..73c7803
> > --- /dev/null
> > +++ b/tests/rtas-test.c
> > @@ -0,0 +1,41 @@
> > +#include "qemu/osdep.h"
> > +#include "qemu/cutils.h"
> > +#include "libqtest.h"
> > +
> > +#include "libqos/libqos-spapr.h"
> > +#include "libqos/rtas.h"
> > +
> > +static void test_rtas_get_time_of_day(void)
> > +{
> > +    QOSState *qs;
> > +    struct tm tm;
> > +    uint32_t ns;
> > +    uint64_t ret;
> > +    time_t t1, t2;
> > +
> > +    qs = qtest_spapr_boot("-machine pseries");
> > +    g_assert(qs != NULL);
> > +
> > +    t1 = time(NULL);
> > +    ret = qrtas_get_time_of_day(qs->alloc, &tm, &ns);
> > +    g_assert_cmpint(ret, ==, 0);
> > +    t2 = mktimegm(&tm);
> > +    g_assert(t2 - t1 < 5); /* 5 sec max to run the test */
> > +
> > +    qtest_spapr_shutdown(qs);
> > +}
> > +
> > +int main(int argc, char *argv[])
> > +{
> > +    const char *arch = qtest_get_arch();
> > +
> > +    g_test_init(&argc, &argv, NULL);
> > +
> > +    if (strcmp(arch, "ppc64")) {
> > +        g_printerr("RTAS requires ppc64-softmmu/qemu-system-ppc64\n");
> > +        exit(EXIT_FAILURE);
> > +    }
> > +    qtest_add_func("rtas/get-time-of-day", test_rtas_get_time_of_day);
> > +
> > +    return g_test_run();
> > +}  
> 


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 181 bytes --]

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

* Re: [Qemu-devel] [Qemu-ppc] [PATCH v8 0/3] tests: add RTAS protocol
  2016-09-14  3:23 ` [Qemu-devel] [PATCH v8 0/3] tests: add RTAS protocol David Gibson
@ 2016-09-14  9:07   ` Greg Kurz
  2016-09-14 10:51     ` David Gibson
  0 siblings, 1 reply; 10+ messages in thread
From: Greg Kurz @ 2016-09-14  9:07 UTC (permalink / raw)
  To: David Gibson; +Cc: Laurent Vivier, thuth, qemu-ppc, qemu-devel

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

On Wed, 14 Sep 2016 13:23:37 +1000
David Gibson <david@gibson.dropbear.id.au> wrote:

> On Tue, Sep 13, 2016 at 02:52:42PM +0200, Laurent Vivier wrote:
> > This series allows to call RTAS commands from the qtest framework,
> > and defines a first test to call RTAS command "get-time-of-day"
> > to validate the protocol and test RTAS.
> > 
> > RTAS command parameters are passed to the guest via the
> > guest memory, so we also need to implement the guest memory
> > management functions for SPAPR target.
> > 
> > RTAS commands will be needed later to test PCI from the qtest framework
> > with SPAPR virtual machines: PCI configuration is read/written with
> > RTAS commands "ibm,read-pci-config", "ibm,write-pci-config".  
> 
> I've applied the series to ppc-for-2.8, at least assuming no-one has
> any objections to this coming through my tree.
> 

BTW, should the new files introduced by this patchset be added to
MAINTAINERS ?

> > 
> > v8:
> > - exit if RTAS is not started with qemu-system-ppc64
> > 
> > v7:
> > - don't allocate twice the memory for the RTAS call
> > - add "-machine pseries" in rtas-test to be sure to use 
> >   the good machine type (with RTAS support).
> > 
> > v6:
> > - rebase
> > - remove useless include
> > 
> > v5:
> > - replace "ppc64" by "spapr"
> > - define and use qtest_spapr_vboot()/qtest_spapr_boot()/qtest_spapr_shutdown()
> > 
> > v4:
> > - use qemu_strtoXXX() instead strtoXX(),
> >   add a patch in the series to change all strtoXX() in qtest.c
> > 
> > v3:
> > - use mktimegm() instead of timegm()
> > 
> > v2:
> > - remove useless parenthesis, inline
> > - add a missing space in qrtas_call() prototype
> > 
> > Laurent Vivier (3):
> >   qtest: replace strtoXX() by qemu_strtoXX()
> >   libqos: define SPAPR libqos functions
> >   tests: add RTAS command in the protocol
> > 
> >  hw/ppc/spapr_rtas.c         | 19 ++++++++++++
> >  include/hw/ppc/spapr_rtas.h | 10 +++++++
> >  qtest.c                     | 66 ++++++++++++++++++++++++++---------------
> >  tests/Makefile.include      |  5 ++++
> >  tests/libqos/libqos-pc.c    |  2 ++
> >  tests/libqos/libqos-spapr.c | 30 +++++++++++++++++++
> >  tests/libqos/libqos-spapr.h | 10 +++++++
> >  tests/libqos/libqos.c       |  1 -
> >  tests/libqos/malloc-spapr.c | 38 ++++++++++++++++++++++++
> >  tests/libqos/malloc-spapr.h | 17 +++++++++++
> >  tests/libqos/rtas.c         | 71 +++++++++++++++++++++++++++++++++++++++++++++
> >  tests/libqos/rtas.h         | 11 +++++++
> >  tests/libqtest.c            | 10 +++++++
> >  tests/libqtest.h            | 15 ++++++++++
> >  tests/rtas-test.c           | 41 ++++++++++++++++++++++++++
> >  15 files changed, 322 insertions(+), 24 deletions(-)
> >  create mode 100644 include/hw/ppc/spapr_rtas.h
> >  create mode 100644 tests/libqos/libqos-spapr.c
> >  create mode 100644 tests/libqos/libqos-spapr.h
> >  create mode 100644 tests/libqos/malloc-spapr.c
> >  create mode 100644 tests/libqos/malloc-spapr.h
> >  create mode 100644 tests/libqos/rtas.c
> >  create mode 100644 tests/libqos/rtas.h
> >  create mode 100644 tests/rtas-test.c
> >   
> 


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 181 bytes --]

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

* Re: [Qemu-devel] [Qemu-ppc] [PATCH v8 3/3] tests: add RTAS command in the protocol
  2016-09-14  9:05     ` [Qemu-devel] [Qemu-ppc] " Greg Kurz
@ 2016-09-14 10:51       ` David Gibson
  0 siblings, 0 replies; 10+ messages in thread
From: David Gibson @ 2016-09-14 10:51 UTC (permalink / raw)
  To: Greg Kurz; +Cc: Laurent Vivier, thuth, qemu-ppc, qemu-devel

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

On Wed, Sep 14, 2016 at 11:05:47AM +0200, Greg Kurz wrote:
> On Wed, 14 Sep 2016 13:22:40 +1000
> David Gibson <david@gibson.dropbear.id.au> wrote:
> 
> > On Tue, Sep 13, 2016 at 02:52:45PM +0200, Laurent Vivier wrote:
> > > Add a first test to validate the protocol:
> > > 
> > > - rtas/get-time-of-day compares the time
> > >   from the guest with the time from the host.
> > > 
> > > Signed-off-by: Laurent Vivier <lvivier@redhat.com>
> > > Reviewed-by: Greg Kurz <groug@kaod.org>  
> > 
> > Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
> > 
> > > ---
> > > v8:
> > > - add Greg's Rb
> > > - exit if RTAS is not started with qemu-system-ppc64
> > > 
> > > v7:
> > > - don't allocate twice the memory for the RTAS call
> > > - add "-machine pseries" in rtas-test
> > > 
> > > v6:
> > > - rebase
> > > 
> > > v5:
> > > - use qtest_spapr_boot() instead of machine_alloc_init()
> > > 
> > > v4:
> > > - use qemu_strtoXXX() instead strtoXX()
> > > 
> > > v3:
> > > - use mktimegm() instead of timegm()
> > > 
> > > v2:
> > > - add a missing space in qrtas_call() prototype
> > > 
> > >  hw/ppc/spapr_rtas.c         | 19 ++++++++++++
> > >  include/hw/ppc/spapr_rtas.h | 10 +++++++
> > >  qtest.c                     | 17 +++++++++++
> > >  tests/Makefile.include      |  3 ++
> > >  tests/libqos/rtas.c         | 71 +++++++++++++++++++++++++++++++++++++++++++++
> > >  tests/libqos/rtas.h         | 11 +++++++
> > >  tests/libqtest.c            | 10 +++++++
> > >  tests/libqtest.h            | 15 ++++++++++
> > >  tests/rtas-test.c           | 41 ++++++++++++++++++++++++++
> > >  9 files changed, 197 insertions(+)
> > >  create mode 100644 include/hw/ppc/spapr_rtas.h
> > >  create mode 100644 tests/libqos/rtas.c
> > >  create mode 100644 tests/libqos/rtas.h
> > >  create mode 100644 tests/rtas-test.c
> > > 
> > > diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
> > > index 27b5ad4..b80c1db 100644
> > > --- a/hw/ppc/spapr_rtas.c
> > > +++ b/hw/ppc/spapr_rtas.c
> > > @@ -37,6 +37,7 @@
> > >  
> > >  #include "hw/ppc/spapr.h"
> > >  #include "hw/ppc/spapr_vio.h"
> > > +#include "hw/ppc/spapr_rtas.h"
> > >  #include "hw/ppc/ppc.h"
> > >  #include "qapi-event.h"
> > >  #include "hw/boards.h"
> > > @@ -692,6 +693,24 @@ target_ulong spapr_rtas_call(PowerPCCPU *cpu, sPAPRMachineState *spapr,
> > >      return H_PARAMETER;
> > >  }
> > >  
> > > +uint64_t qtest_rtas_call(char *cmd, uint32_t nargs, uint64_t args,
> > > +                         uint32_t nret, uint64_t rets)
> > > +{
> > > +    int token;
> > > +
> > > +    for (token = 0; token < RTAS_TOKEN_MAX - RTAS_TOKEN_BASE; token++) {
> > > +        if (strcmp(cmd, rtas_table[token].name) == 0) {
> > > +            sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());  
> > 
> > As a sanity check you could return an error if you're unable to
> > resolve the machine as an sPAPR here.  Since that should only happen
> > on a broken testcase, it can be done as a later enhancement, though.
> > 
> 
> Hmm... if the machine isn't sPAPR, SPAPR_MACHINE() will abort, which makes
> sense in the case of a broken testcase.
> 
> hw/ppc/spapr_rtas.c:703:qtest_rtas_call: Object 0x558f5de65590 is
> not an instance of type spapr-machine

Ah, sorry, I'd forgotten.  I had mixed it up with
object_dynamic_cast() and was thinking it just returned NULL.  So we
implicitly have the check I was asking for.

-- 
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: 801 bytes --]

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

* Re: [Qemu-devel] [Qemu-ppc] [PATCH v8 0/3] tests: add RTAS protocol
  2016-09-14  9:07   ` [Qemu-devel] [Qemu-ppc] " Greg Kurz
@ 2016-09-14 10:51     ` David Gibson
  0 siblings, 0 replies; 10+ messages in thread
From: David Gibson @ 2016-09-14 10:51 UTC (permalink / raw)
  To: Greg Kurz; +Cc: Laurent Vivier, thuth, qemu-ppc, qemu-devel

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

On Wed, Sep 14, 2016 at 11:07:59AM +0200, Greg Kurz wrote:
> On Wed, 14 Sep 2016 13:23:37 +1000
> David Gibson <david@gibson.dropbear.id.au> wrote:
> 
> > On Tue, Sep 13, 2016 at 02:52:42PM +0200, Laurent Vivier wrote:
> > > This series allows to call RTAS commands from the qtest framework,
> > > and defines a first test to call RTAS command "get-time-of-day"
> > > to validate the protocol and test RTAS.
> > > 
> > > RTAS command parameters are passed to the guest via the
> > > guest memory, so we also need to implement the guest memory
> > > management functions for SPAPR target.
> > > 
> > > RTAS commands will be needed later to test PCI from the qtest framework
> > > with SPAPR virtual machines: PCI configuration is read/written with
> > > RTAS commands "ibm,read-pci-config", "ibm,write-pci-config".  
> > 
> > I've applied the series to ppc-for-2.8, at least assuming no-one has
> > any objections to this coming through my tree.
> > 
> 
> BTW, should the new files introduced by this patchset be added to
> MAINTAINERS ?

Yes, that would be a good idea.

-- 
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: 801 bytes --]

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

end of thread, other threads:[~2016-09-14 10:52 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-09-13 12:52 [Qemu-devel] [PATCH v8 0/3] tests: add RTAS protocol Laurent Vivier
2016-09-13 12:52 ` [Qemu-devel] [PATCH v8 1/3] qtest: replace strtoXX() by qemu_strtoXX() Laurent Vivier
2016-09-13 12:52 ` [Qemu-devel] [PATCH v8 2/3] libqos: define SPAPR libqos functions Laurent Vivier
2016-09-13 12:52 ` [Qemu-devel] [PATCH v8 3/3] tests: add RTAS command in the protocol Laurent Vivier
2016-09-14  3:22   ` David Gibson
2016-09-14  9:05     ` [Qemu-devel] [Qemu-ppc] " Greg Kurz
2016-09-14 10:51       ` David Gibson
2016-09-14  3:23 ` [Qemu-devel] [PATCH v8 0/3] tests: add RTAS protocol David Gibson
2016-09-14  9:07   ` [Qemu-devel] [Qemu-ppc] " Greg Kurz
2016-09-14 10:51     ` David Gibson

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.