11cf4323eSThomas Huth /*
21cf4323eSThomas Huth * This work is licensed under the terms of the GNU GPL, version 2 or later.
31cf4323eSThomas Huth * See the COPYING file in the top-level directory.
41cf4323eSThomas Huth */
51cf4323eSThomas Huth
61cf4323eSThomas Huth #include "qemu/osdep.h"
7*907b5105SMarc-André Lureau #include "../libqtest.h"
8a2ce7dbdSPaolo Bonzini #include "rtas.h"
91cf4323eSThomas Huth
qrtas_copy_args(QTestState * qts,uint64_t target_args,uint32_t nargs,uint32_t * args)101cf4323eSThomas Huth static void qrtas_copy_args(QTestState *qts, uint64_t target_args,
111cf4323eSThomas Huth uint32_t nargs, uint32_t *args)
121cf4323eSThomas Huth {
131cf4323eSThomas Huth int i;
141cf4323eSThomas Huth
151cf4323eSThomas Huth for (i = 0; i < nargs; i++) {
161cf4323eSThomas Huth qtest_writel(qts, target_args + i * sizeof(uint32_t), args[i]);
171cf4323eSThomas Huth }
181cf4323eSThomas Huth }
191cf4323eSThomas Huth
qrtas_copy_ret(QTestState * qts,uint64_t target_ret,uint32_t nret,uint32_t * ret)201cf4323eSThomas Huth static void qrtas_copy_ret(QTestState *qts, uint64_t target_ret,
211cf4323eSThomas Huth uint32_t nret, uint32_t *ret)
221cf4323eSThomas Huth {
231cf4323eSThomas Huth int i;
241cf4323eSThomas Huth
251cf4323eSThomas Huth for (i = 0; i < nret; i++) {
261cf4323eSThomas Huth ret[i] = qtest_readl(qts, target_ret + i * sizeof(uint32_t));
271cf4323eSThomas Huth }
281cf4323eSThomas Huth }
291cf4323eSThomas Huth
qrtas_call(QTestState * qts,QGuestAllocator * alloc,const char * name,uint32_t nargs,uint32_t * args,uint32_t nret,uint32_t * ret)301cf4323eSThomas Huth static uint64_t qrtas_call(QTestState *qts, QGuestAllocator *alloc,
311cf4323eSThomas Huth const char *name,
321cf4323eSThomas Huth uint32_t nargs, uint32_t *args,
331cf4323eSThomas Huth uint32_t nret, uint32_t *ret)
341cf4323eSThomas Huth {
351cf4323eSThomas Huth uint64_t res;
361cf4323eSThomas Huth uint64_t target_args, target_ret;
371cf4323eSThomas Huth
381cf4323eSThomas Huth target_args = guest_alloc(alloc, nargs * sizeof(uint32_t));
391cf4323eSThomas Huth target_ret = guest_alloc(alloc, nret * sizeof(uint32_t));
401cf4323eSThomas Huth
411cf4323eSThomas Huth qrtas_copy_args(qts, target_args, nargs, args);
421cf4323eSThomas Huth res = qtest_rtas_call(qts, name, nargs, target_args, nret, target_ret);
431cf4323eSThomas Huth qrtas_copy_ret(qts, target_ret, nret, ret);
441cf4323eSThomas Huth
451cf4323eSThomas Huth guest_free(alloc, target_ret);
461cf4323eSThomas Huth guest_free(alloc, target_args);
471cf4323eSThomas Huth
481cf4323eSThomas Huth return res;
491cf4323eSThomas Huth }
501cf4323eSThomas Huth
qrtas_get_time_of_day(QTestState * qts,QGuestAllocator * alloc,struct tm * tm,uint32_t * ns)511cf4323eSThomas Huth int qrtas_get_time_of_day(QTestState *qts, QGuestAllocator *alloc,
521cf4323eSThomas Huth struct tm *tm, uint32_t *ns)
531cf4323eSThomas Huth {
541cf4323eSThomas Huth int res;
551cf4323eSThomas Huth uint32_t ret[8];
561cf4323eSThomas Huth
571cf4323eSThomas Huth res = qrtas_call(qts, alloc, "get-time-of-day", 0, NULL, 8, ret);
581cf4323eSThomas Huth if (res != 0) {
591cf4323eSThomas Huth return res;
601cf4323eSThomas Huth }
611cf4323eSThomas Huth
621cf4323eSThomas Huth res = ret[0];
631cf4323eSThomas Huth memset(tm, 0, sizeof(*tm));
641cf4323eSThomas Huth tm->tm_year = ret[1] - 1900;
651cf4323eSThomas Huth tm->tm_mon = ret[2] - 1;
661cf4323eSThomas Huth tm->tm_mday = ret[3];
671cf4323eSThomas Huth tm->tm_hour = ret[4];
681cf4323eSThomas Huth tm->tm_min = ret[5];
691cf4323eSThomas Huth tm->tm_sec = ret[6];
701cf4323eSThomas Huth *ns = ret[7];
711cf4323eSThomas Huth
721cf4323eSThomas Huth return res;
731cf4323eSThomas Huth }
741cf4323eSThomas Huth
qrtas_ibm_read_pci_config(QTestState * qts,QGuestAllocator * alloc,uint64_t buid,uint32_t addr,uint32_t size)751cf4323eSThomas Huth uint32_t qrtas_ibm_read_pci_config(QTestState *qts, QGuestAllocator *alloc,
761cf4323eSThomas Huth uint64_t buid,
771cf4323eSThomas Huth uint32_t addr, uint32_t size)
781cf4323eSThomas Huth {
791cf4323eSThomas Huth int res;
801cf4323eSThomas Huth uint32_t args[4], ret[2];
811cf4323eSThomas Huth
821cf4323eSThomas Huth args[0] = addr;
831cf4323eSThomas Huth args[1] = buid >> 32;
841cf4323eSThomas Huth args[2] = buid & 0xffffffff;
851cf4323eSThomas Huth args[3] = size;
861cf4323eSThomas Huth res = qrtas_call(qts, alloc, "ibm,read-pci-config", 4, args, 2, ret);
871cf4323eSThomas Huth if (res != 0) {
881cf4323eSThomas Huth return -1;
891cf4323eSThomas Huth }
901cf4323eSThomas Huth
911cf4323eSThomas Huth if (ret[0] != 0) {
921cf4323eSThomas Huth return -1;
931cf4323eSThomas Huth }
941cf4323eSThomas Huth
951cf4323eSThomas Huth return ret[1];
961cf4323eSThomas Huth }
971cf4323eSThomas Huth
qrtas_ibm_write_pci_config(QTestState * qts,QGuestAllocator * alloc,uint64_t buid,uint32_t addr,uint32_t size,uint32_t val)981cf4323eSThomas Huth int qrtas_ibm_write_pci_config(QTestState *qts, QGuestAllocator *alloc,
991cf4323eSThomas Huth uint64_t buid,
1001cf4323eSThomas Huth uint32_t addr, uint32_t size, uint32_t val)
1011cf4323eSThomas Huth {
1021cf4323eSThomas Huth int res;
1031cf4323eSThomas Huth uint32_t args[5], ret[1];
1041cf4323eSThomas Huth
1051cf4323eSThomas Huth args[0] = addr;
1061cf4323eSThomas Huth args[1] = buid >> 32;
1071cf4323eSThomas Huth args[2] = buid & 0xffffffff;
1081cf4323eSThomas Huth args[3] = size;
1091cf4323eSThomas Huth args[4] = val;
1101cf4323eSThomas Huth res = qrtas_call(qts, alloc, "ibm,write-pci-config", 5, args, 1, ret);
1111cf4323eSThomas Huth if (res != 0) {
1121cf4323eSThomas Huth return -1;
1131cf4323eSThomas Huth }
1141cf4323eSThomas Huth
1151cf4323eSThomas Huth if (ret[0] != 0) {
1161cf4323eSThomas Huth return -1;
1171cf4323eSThomas Huth }
1181cf4323eSThomas Huth
1191cf4323eSThomas Huth return 0;
1201cf4323eSThomas Huth }
121