]>
Commit | Line | Data |
---|---|---|
eeddd59f LV |
1 | /* |
2 | * This work is licensed under the terms of the GNU GPL, version 2 or later. | |
3 | * See the COPYING file in the top-level directory. | |
4 | */ | |
5 | ||
6 | #include "qemu/osdep.h" | |
7 | #include "libqtest.h" | |
8 | #include "libqos/rtas.h" | |
9 | ||
9b67af76 EB |
10 | static void qrtas_copy_args(QTestState *qts, uint64_t target_args, |
11 | uint32_t nargs, uint32_t *args) | |
eeddd59f LV |
12 | { |
13 | int i; | |
14 | ||
15 | for (i = 0; i < nargs; i++) { | |
9b67af76 | 16 | qtest_writel(qts, target_args + i * sizeof(uint32_t), args[i]); |
eeddd59f LV |
17 | } |
18 | } | |
19 | ||
9b67af76 EB |
20 | static void qrtas_copy_ret(QTestState *qts, uint64_t target_ret, |
21 | uint32_t nret, uint32_t *ret) | |
eeddd59f LV |
22 | { |
23 | int i; | |
24 | ||
25 | for (i = 0; i < nret; i++) { | |
9b67af76 | 26 | ret[i] = qtest_readl(qts, target_ret + i * sizeof(uint32_t)); |
eeddd59f LV |
27 | } |
28 | } | |
29 | ||
9b67af76 EB |
30 | static uint64_t qrtas_call(QTestState *qts, QGuestAllocator *alloc, |
31 | const char *name, | |
eeddd59f LV |
32 | uint32_t nargs, uint32_t *args, |
33 | uint32_t nret, uint32_t *ret) | |
34 | { | |
35 | uint64_t res; | |
36 | uint64_t target_args, target_ret; | |
37 | ||
38 | target_args = guest_alloc(alloc, nargs * sizeof(uint32_t)); | |
39 | target_ret = guest_alloc(alloc, nret * sizeof(uint32_t)); | |
40 | ||
9b67af76 EB |
41 | qrtas_copy_args(qts, target_args, nargs, args); |
42 | res = qtest_rtas_call(qts, name, nargs, target_args, nret, target_ret); | |
43 | qrtas_copy_ret(qts, target_ret, nret, ret); | |
eeddd59f LV |
44 | |
45 | guest_free(alloc, target_ret); | |
46 | guest_free(alloc, target_args); | |
47 | ||
48 | return res; | |
49 | } | |
50 | ||
9b67af76 EB |
51 | int qrtas_get_time_of_day(QTestState *qts, QGuestAllocator *alloc, |
52 | struct tm *tm, uint32_t *ns) | |
eeddd59f LV |
53 | { |
54 | int res; | |
55 | uint32_t ret[8]; | |
56 | ||
9b67af76 | 57 | res = qrtas_call(qts, alloc, "get-time-of-day", 0, NULL, 8, ret); |
eeddd59f LV |
58 | if (res != 0) { |
59 | return res; | |
60 | } | |
61 | ||
62 | res = ret[0]; | |
63 | memset(tm, 0, sizeof(*tm)); | |
64 | tm->tm_year = ret[1] - 1900; | |
65 | tm->tm_mon = ret[2] - 1; | |
66 | tm->tm_mday = ret[3]; | |
67 | tm->tm_hour = ret[4]; | |
68 | tm->tm_min = ret[5]; | |
69 | tm->tm_sec = ret[6]; | |
70 | *ns = ret[7]; | |
71 | ||
72 | return res; | |
73 | } | |
cf716b31 | 74 | |
9b67af76 EB |
75 | uint32_t qrtas_ibm_read_pci_config(QTestState *qts, QGuestAllocator *alloc, |
76 | uint64_t buid, | |
cf716b31 LV |
77 | uint32_t addr, uint32_t size) |
78 | { | |
79 | int res; | |
80 | uint32_t args[4], ret[2]; | |
81 | ||
82 | args[0] = addr; | |
83 | args[1] = buid >> 32; | |
84 | args[2] = buid & 0xffffffff; | |
85 | args[3] = size; | |
9b67af76 | 86 | res = qrtas_call(qts, alloc, "ibm,read-pci-config", 4, args, 2, ret); |
cf716b31 LV |
87 | if (res != 0) { |
88 | return -1; | |
89 | } | |
90 | ||
91 | if (ret[0] != 0) { | |
92 | return -1; | |
93 | } | |
94 | ||
95 | return ret[1]; | |
96 | } | |
97 | ||
9b67af76 EB |
98 | int qrtas_ibm_write_pci_config(QTestState *qts, QGuestAllocator *alloc, |
99 | uint64_t buid, | |
cf716b31 LV |
100 | uint32_t addr, uint32_t size, uint32_t val) |
101 | { | |
102 | int res; | |
103 | uint32_t args[5], ret[1]; | |
104 | ||
105 | args[0] = addr; | |
106 | args[1] = buid >> 32; | |
107 | args[2] = buid & 0xffffffff; | |
108 | args[3] = size; | |
109 | args[4] = val; | |
9b67af76 | 110 | res = qrtas_call(qts, alloc, "ibm,write-pci-config", 5, args, 1, ret); |
cf716b31 LV |
111 | if (res != 0) { |
112 | return -1; | |
113 | } | |
114 | ||
115 | if (ret[0] != 0) { | |
116 | return -1; | |
117 | } | |
118 | ||
119 | return 0; | |
120 | } |