1eeddd59fSLaurent Vivier /*
2eeddd59fSLaurent Vivier * This work is licensed under the terms of the GNU GPL, version 2 or later.
3eeddd59fSLaurent Vivier * See the COPYING file in the top-level directory.
4eeddd59fSLaurent Vivier */
5eeddd59fSLaurent Vivier
6eeddd59fSLaurent Vivier #include "qemu/osdep.h"
7*907b5105SMarc-André Lureau #include "../libqtest.h"
8a2ce7dbdSPaolo Bonzini #include "rtas.h"
9eeddd59fSLaurent Vivier
qrtas_copy_args(QTestState * qts,uint64_t target_args,uint32_t nargs,uint32_t * args)109b67af76SEric Blake static void qrtas_copy_args(QTestState *qts, uint64_t target_args,
119b67af76SEric Blake uint32_t nargs, uint32_t *args)
12eeddd59fSLaurent Vivier {
13eeddd59fSLaurent Vivier int i;
14eeddd59fSLaurent Vivier
15eeddd59fSLaurent Vivier for (i = 0; i < nargs; i++) {
169b67af76SEric Blake qtest_writel(qts, target_args + i * sizeof(uint32_t), args[i]);
17eeddd59fSLaurent Vivier }
18eeddd59fSLaurent Vivier }
19eeddd59fSLaurent Vivier
qrtas_copy_ret(QTestState * qts,uint64_t target_ret,uint32_t nret,uint32_t * ret)209b67af76SEric Blake static void qrtas_copy_ret(QTestState *qts, uint64_t target_ret,
219b67af76SEric Blake uint32_t nret, uint32_t *ret)
22eeddd59fSLaurent Vivier {
23eeddd59fSLaurent Vivier int i;
24eeddd59fSLaurent Vivier
25eeddd59fSLaurent Vivier for (i = 0; i < nret; i++) {
269b67af76SEric Blake ret[i] = qtest_readl(qts, target_ret + i * sizeof(uint32_t));
27eeddd59fSLaurent Vivier }
28eeddd59fSLaurent Vivier }
29eeddd59fSLaurent Vivier
qrtas_call(QTestState * qts,QGuestAllocator * alloc,const char * name,uint32_t nargs,uint32_t * args,uint32_t nret,uint32_t * ret)309b67af76SEric Blake static uint64_t qrtas_call(QTestState *qts, QGuestAllocator *alloc,
319b67af76SEric Blake const char *name,
32eeddd59fSLaurent Vivier uint32_t nargs, uint32_t *args,
33eeddd59fSLaurent Vivier uint32_t nret, uint32_t *ret)
34eeddd59fSLaurent Vivier {
35eeddd59fSLaurent Vivier uint64_t res;
36eeddd59fSLaurent Vivier uint64_t target_args, target_ret;
37eeddd59fSLaurent Vivier
38eeddd59fSLaurent Vivier target_args = guest_alloc(alloc, nargs * sizeof(uint32_t));
39eeddd59fSLaurent Vivier target_ret = guest_alloc(alloc, nret * sizeof(uint32_t));
40eeddd59fSLaurent Vivier
419b67af76SEric Blake qrtas_copy_args(qts, target_args, nargs, args);
429b67af76SEric Blake res = qtest_rtas_call(qts, name, nargs, target_args, nret, target_ret);
439b67af76SEric Blake qrtas_copy_ret(qts, target_ret, nret, ret);
44eeddd59fSLaurent Vivier
45eeddd59fSLaurent Vivier guest_free(alloc, target_ret);
46eeddd59fSLaurent Vivier guest_free(alloc, target_args);
47eeddd59fSLaurent Vivier
48eeddd59fSLaurent Vivier return res;
49eeddd59fSLaurent Vivier }
50eeddd59fSLaurent Vivier
qrtas_get_time_of_day(QTestState * qts,QGuestAllocator * alloc,struct tm * tm,uint32_t * ns)519b67af76SEric Blake int qrtas_get_time_of_day(QTestState *qts, QGuestAllocator *alloc,
529b67af76SEric Blake struct tm *tm, uint32_t *ns)
53eeddd59fSLaurent Vivier {
54eeddd59fSLaurent Vivier int res;
55eeddd59fSLaurent Vivier uint32_t ret[8];
56eeddd59fSLaurent Vivier
579b67af76SEric Blake res = qrtas_call(qts, alloc, "get-time-of-day", 0, NULL, 8, ret);
58eeddd59fSLaurent Vivier if (res != 0) {
59eeddd59fSLaurent Vivier return res;
60eeddd59fSLaurent Vivier }
61eeddd59fSLaurent Vivier
62eeddd59fSLaurent Vivier res = ret[0];
63eeddd59fSLaurent Vivier memset(tm, 0, sizeof(*tm));
64eeddd59fSLaurent Vivier tm->tm_year = ret[1] - 1900;
65eeddd59fSLaurent Vivier tm->tm_mon = ret[2] - 1;
66eeddd59fSLaurent Vivier tm->tm_mday = ret[3];
67eeddd59fSLaurent Vivier tm->tm_hour = ret[4];
68eeddd59fSLaurent Vivier tm->tm_min = ret[5];
69eeddd59fSLaurent Vivier tm->tm_sec = ret[6];
70eeddd59fSLaurent Vivier *ns = ret[7];
71eeddd59fSLaurent Vivier
72eeddd59fSLaurent Vivier return res;
73eeddd59fSLaurent Vivier }
74cf716b31SLaurent Vivier
qrtas_ibm_read_pci_config(QTestState * qts,QGuestAllocator * alloc,uint64_t buid,uint32_t addr,uint32_t size)759b67af76SEric Blake uint32_t qrtas_ibm_read_pci_config(QTestState *qts, QGuestAllocator *alloc,
769b67af76SEric Blake uint64_t buid,
77cf716b31SLaurent Vivier uint32_t addr, uint32_t size)
78cf716b31SLaurent Vivier {
79cf716b31SLaurent Vivier int res;
80cf716b31SLaurent Vivier uint32_t args[4], ret[2];
81cf716b31SLaurent Vivier
82cf716b31SLaurent Vivier args[0] = addr;
83cf716b31SLaurent Vivier args[1] = buid >> 32;
84cf716b31SLaurent Vivier args[2] = buid & 0xffffffff;
85cf716b31SLaurent Vivier args[3] = size;
869b67af76SEric Blake res = qrtas_call(qts, alloc, "ibm,read-pci-config", 4, args, 2, ret);
87cf716b31SLaurent Vivier if (res != 0) {
88cf716b31SLaurent Vivier return -1;
89cf716b31SLaurent Vivier }
90cf716b31SLaurent Vivier
91cf716b31SLaurent Vivier if (ret[0] != 0) {
92cf716b31SLaurent Vivier return -1;
93cf716b31SLaurent Vivier }
94cf716b31SLaurent Vivier
95cf716b31SLaurent Vivier return ret[1];
96cf716b31SLaurent Vivier }
97cf716b31SLaurent Vivier
qrtas_ibm_write_pci_config(QTestState * qts,QGuestAllocator * alloc,uint64_t buid,uint32_t addr,uint32_t size,uint32_t val)989b67af76SEric Blake int qrtas_ibm_write_pci_config(QTestState *qts, QGuestAllocator *alloc,
999b67af76SEric Blake uint64_t buid,
100cf716b31SLaurent Vivier uint32_t addr, uint32_t size, uint32_t val)
101cf716b31SLaurent Vivier {
102cf716b31SLaurent Vivier int res;
103cf716b31SLaurent Vivier uint32_t args[5], ret[1];
104cf716b31SLaurent Vivier
105cf716b31SLaurent Vivier args[0] = addr;
106cf716b31SLaurent Vivier args[1] = buid >> 32;
107cf716b31SLaurent Vivier args[2] = buid & 0xffffffff;
108cf716b31SLaurent Vivier args[3] = size;
109cf716b31SLaurent Vivier args[4] = val;
1109b67af76SEric Blake res = qrtas_call(qts, alloc, "ibm,write-pci-config", 5, args, 1, ret);
111cf716b31SLaurent Vivier if (res != 0) {
112cf716b31SLaurent Vivier return -1;
113cf716b31SLaurent Vivier }
114cf716b31SLaurent Vivier
115cf716b31SLaurent Vivier if (ret[0] != 0) {
116cf716b31SLaurent Vivier return -1;
117cf716b31SLaurent Vivier }
118cf716b31SLaurent Vivier
119cf716b31SLaurent Vivier return 0;
120cf716b31SLaurent Vivier }
121