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