Browse Source
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> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>pull/44/head
committed by
David Gibson
9 changed files with 197 additions and 0 deletions
@ -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 */ |
|||
@ -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; |
|||
} |
|||
@ -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 */ |
|||
@ -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(); |
|||
} |
|||
Loading…
Reference in new issue