* [Qemu-devel] [PATCH v5 0/3] tests: add RTAS protocol
@ 2016-09-08 8:30 Laurent Vivier
2016-09-08 8:30 ` [Qemu-devel] [PATCH v5 1/3] qtest: replace strtoXX() by qemu_strtoXX() Laurent Vivier
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Laurent Vivier @ 2016-09-08 8:30 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".
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/libqos.h | 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 | 40 +++++++++++++++++++++++++
16 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] 7+ messages in thread
* [Qemu-devel] [PATCH v5 1/3] qtest: replace strtoXX() by qemu_strtoXX()
2016-09-08 8:30 [Qemu-devel] [PATCH v5 0/3] tests: add RTAS protocol Laurent Vivier
@ 2016-09-08 8:30 ` Laurent Vivier
2016-09-08 9:53 ` Greg Kurz
2016-09-08 8:30 ` [Qemu-devel] [PATCH v5 2/3] libqos: define SPAPR libqos functions Laurent Vivier
2016-09-08 8:30 ` [Qemu-devel] [PATCH v5 3/3] tests: add RTAS command in the protocol Laurent Vivier
2 siblings, 1 reply; 7+ messages in thread
From: Laurent Vivier @ 2016-09-08 8:30 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>
---
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 da4826c..4c94708 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
@@ -324,12 +325,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);
@@ -343,11 +345,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);
@@ -366,8 +369,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;
@@ -395,7 +398,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;
@@ -421,8 +424,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);
@@ -443,8 +446,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);
@@ -460,8 +463,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) {
@@ -486,12 +489,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);
data = g_malloc(len);
memset(data, pattern, len);
@@ -507,8 +510,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) {
@@ -532,7 +535,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);
}
@@ -544,7 +547,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 related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH v5 2/3] libqos: define SPAPR libqos functions
2016-09-08 8:30 [Qemu-devel] [PATCH v5 0/3] tests: add RTAS protocol Laurent Vivier
2016-09-08 8:30 ` [Qemu-devel] [PATCH v5 1/3] qtest: replace strtoXX() by qemu_strtoXX() Laurent Vivier
@ 2016-09-08 8:30 ` Laurent Vivier
2016-09-08 17:47 ` Greg Kurz
2016-09-08 8:30 ` [Qemu-devel] [PATCH v5 3/3] tests: add RTAS command in the protocol Laurent Vivier
2 siblings, 1 reply; 7+ messages in thread
From: Laurent Vivier @ 2016-09-08 8:30 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>
---
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/libqos.h | 1 +
tests/libqos/malloc-spapr.c | 38 ++++++++++++++++++++++++++++++++++++++
tests/libqos/malloc-spapr.h | 17 +++++++++++++++++
8 files changed, 100 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 14be491..da17b9b 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -557,6 +557,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/libqos.h b/tests/libqos/libqos.h
index 604980d..5022ce3 100644
--- a/tests/libqos/libqos.h
+++ b/tests/libqos/libqos.h
@@ -4,6 +4,7 @@
#include "libqtest.h"
#include "libqos/pci.h"
#include "libqos/malloc-pc.h"
+#include "libqos/malloc-spapr.h"
typedef struct QOSOps {
QGuestAllocator *(*init_allocator)(QAllocOpts);
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 related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH v5 3/3] tests: add RTAS command in the protocol
2016-09-08 8:30 [Qemu-devel] [PATCH v5 0/3] tests: add RTAS protocol Laurent Vivier
2016-09-08 8:30 ` [Qemu-devel] [PATCH v5 1/3] qtest: replace strtoXX() by qemu_strtoXX() Laurent Vivier
2016-09-08 8:30 ` [Qemu-devel] [PATCH v5 2/3] libqos: define SPAPR libqos functions Laurent Vivier
@ 2016-09-08 8:30 ` Laurent Vivier
2016-09-08 17:53 ` [Qemu-devel] [Qemu-ppc] " Greg Kurz
2 siblings, 1 reply; 7+ messages in thread
From: Laurent Vivier @ 2016-09-08 8:30 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>
---
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 | 40 +++++++++++++++++++++++++
9 files changed, 196 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 dc058e5..8aed56f 100644
--- a/hw/ppc/spapr_rtas.c
+++ b/hw/ppc/spapr_rtas.c
@@ -36,6 +36,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"
@@ -691,6 +692,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 4c94708..beb62b4 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
@@ -531,6 +534,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 da17b9b..a2cd446 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -272,6 +272,7 @@ check-qtest-sparc-y += tests/prom-env-test$(EXESUF)
check-qtest-microblazeel-y = $(check-qtest-microblaze-y)
check-qtest-xtensaeb-y = $(check-qtest-xtensa-y)
check-qtest-ppc64-y += tests/postcopy-test$(EXESUF)
+check-qtest-ppc64-y += tests/rtas-test$(EXESUF)
check-qtest-generic-y += tests/qom-test$(EXESUF)
@@ -559,6 +560,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
@@ -573,6 +575,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..d5f4ced
--- /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 + nret) * 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 eb00f13..c9dd57b 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 37f37ad..1badb76 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..3bca36b
--- /dev/null
+++ b/tests/rtas-test.c
@@ -0,0 +1,40 @@
+#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("");
+
+ 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") == 0) {
+ qtest_add_func("rtas/get-time-of-day", test_rtas_get_time_of_day);
+ } else {
+ g_assert_not_reached();
+ }
+
+ return g_test_run();
+}
--
2.5.5
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [Qemu-devel] [PATCH v5 1/3] qtest: replace strtoXX() by qemu_strtoXX()
2016-09-08 8:30 ` [Qemu-devel] [PATCH v5 1/3] qtest: replace strtoXX() by qemu_strtoXX() Laurent Vivier
@ 2016-09-08 9:53 ` Greg Kurz
0 siblings, 0 replies; 7+ messages in thread
From: Greg Kurz @ 2016-09-08 9:53 UTC (permalink / raw)
To: Laurent Vivier; +Cc: david, thuth, qemu-ppc, qemu-devel
On Thu, 8 Sep 2016 10:30:32 +0200
Laurent Vivier <lvivier@redhat.com> wrote:
> 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>
> 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 da4826c..4c94708 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
>
> @@ -324,12 +325,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);
> @@ -343,11 +345,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);
> @@ -366,8 +369,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;
> @@ -395,7 +398,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;
> @@ -421,8 +424,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);
> @@ -443,8 +446,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);
> @@ -460,8 +463,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) {
> @@ -486,12 +489,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);
>
> data = g_malloc(len);
> memset(data, pattern, len);
> @@ -507,8 +510,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) {
> @@ -532,7 +535,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);
> }
> @@ -544,7 +547,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",
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Qemu-devel] [PATCH v5 2/3] libqos: define SPAPR libqos functions
2016-09-08 8:30 ` [Qemu-devel] [PATCH v5 2/3] libqos: define SPAPR libqos functions Laurent Vivier
@ 2016-09-08 17:47 ` Greg Kurz
0 siblings, 0 replies; 7+ messages in thread
From: Greg Kurz @ 2016-09-08 17:47 UTC (permalink / raw)
To: Laurent Vivier; +Cc: david, thuth, qemu-ppc, qemu-devel
On Thu, 8 Sep 2016 10:30:33 +0200
Laurent Vivier <lvivier@redhat.com> wrote:
> 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>
> ---
Nice work ! Just a minor remark, see below.
> 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/libqos.h | 1 +
> tests/libqos/malloc-spapr.c | 38 ++++++++++++++++++++++++++++++++++++++
> tests/libqos/malloc-spapr.h | 17 +++++++++++++++++
> 8 files changed, 100 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 14be491..da17b9b 100644
> --- a/tests/Makefile.include
> +++ b/tests/Makefile.include
> @@ -557,6 +557,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/libqos.h b/tests/libqos/libqos.h
> index 604980d..5022ce3 100644
> --- a/tests/libqos/libqos.h
> +++ b/tests/libqos/libqos.h
> @@ -4,6 +4,7 @@
> #include "libqtest.h"
> #include "libqos/pci.h"
> #include "libqos/malloc-pc.h"
> +#include "libqos/malloc-spapr.h"
>
Not sure this is actually needed, but it doesn't hurt and can be addressed in
a followup include cleaning patch.
Reviewed-by: Greg Kurz <groug@kaod.org>
> typedef struct QOSOps {
> QGuestAllocator *(*init_allocator)(QAllocOpts);
> 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
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Qemu-devel] [Qemu-ppc] [PATCH v5 3/3] tests: add RTAS command in the protocol
2016-09-08 8:30 ` [Qemu-devel] [PATCH v5 3/3] tests: add RTAS command in the protocol Laurent Vivier
@ 2016-09-08 17:53 ` Greg Kurz
0 siblings, 0 replies; 7+ messages in thread
From: Greg Kurz @ 2016-09-08 17:53 UTC (permalink / raw)
To: Laurent Vivier; +Cc: david, thuth, qemu-ppc, qemu-devel
On Thu, 8 Sep 2016 10:30:34 +0200
Laurent Vivier <lvivier@redhat.com> 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>
> ---
This patch has a conflict in tests/Makefile.include, with both master and David's
ppc-for-2.8 branch. It looks like you're missing the following commits:
commit 29531542bc92603a198d50412e1142b9f0fb0a73
Author: Thomas Huth <thuth@redhat.com>
Date: Sat Sep 3 11:57:50 2016 +0200
tests: Resort check-qtest entries in Makefile.include
and
commit d2ab58ffc927c00e88f53f9b853b015a76fa1bd2
Author: Thomas Huth <thuth@redhat.com>
Date: Sat Sep 3 11:57:51 2016 +0200
tests: Check serial output of firmware boot of some machines
Appart from that, it looks fine.
Cheers.
--
Greg
> 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 | 40 +++++++++++++++++++++++++
> 9 files changed, 196 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 dc058e5..8aed56f 100644
> --- a/hw/ppc/spapr_rtas.c
> +++ b/hw/ppc/spapr_rtas.c
> @@ -36,6 +36,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"
> @@ -691,6 +692,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 4c94708..beb62b4 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
>
> @@ -531,6 +534,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 da17b9b..a2cd446 100644
> --- a/tests/Makefile.include
> +++ b/tests/Makefile.include
> @@ -272,6 +272,7 @@ check-qtest-sparc-y += tests/prom-env-test$(EXESUF)
> check-qtest-microblazeel-y = $(check-qtest-microblaze-y)
> check-qtest-xtensaeb-y = $(check-qtest-xtensa-y)
> check-qtest-ppc64-y += tests/postcopy-test$(EXESUF)
> +check-qtest-ppc64-y += tests/rtas-test$(EXESUF)
>
> check-qtest-generic-y += tests/qom-test$(EXESUF)
>
> @@ -559,6 +560,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
> @@ -573,6 +575,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..d5f4ced
> --- /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 + nret) * 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 eb00f13..c9dd57b 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 37f37ad..1badb76 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..3bca36b
> --- /dev/null
> +++ b/tests/rtas-test.c
> @@ -0,0 +1,40 @@
> +#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("");
> +
> + 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") == 0) {
> + qtest_add_func("rtas/get-time-of-day", test_rtas_get_time_of_day);
> + } else {
> + g_assert_not_reached();
> + }
> +
> + return g_test_run();
> +}
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2016-09-08 17:53 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-09-08 8:30 [Qemu-devel] [PATCH v5 0/3] tests: add RTAS protocol Laurent Vivier
2016-09-08 8:30 ` [Qemu-devel] [PATCH v5 1/3] qtest: replace strtoXX() by qemu_strtoXX() Laurent Vivier
2016-09-08 9:53 ` Greg Kurz
2016-09-08 8:30 ` [Qemu-devel] [PATCH v5 2/3] libqos: define SPAPR libqos functions Laurent Vivier
2016-09-08 17:47 ` Greg Kurz
2016-09-08 8:30 ` [Qemu-devel] [PATCH v5 3/3] tests: add RTAS command in the protocol Laurent Vivier
2016-09-08 17:53 ` [Qemu-devel] [Qemu-ppc] " Greg Kurz
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).