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 "rtas.h" 9 10 static void qrtas_copy_args(QTestState *qts, uint64_t target_args, 11 uint32_t nargs, uint32_t *args) 12 { 13 int i; 14 15 for (i = 0; i < nargs; i++) { 16 qtest_writel(qts, target_args + i * sizeof(uint32_t), args[i]); 17 } 18 } 19 20 static void qrtas_copy_ret(QTestState *qts, uint64_t target_ret, 21 uint32_t nret, uint32_t *ret) 22 { 23 int i; 24 25 for (i = 0; i < nret; i++) { 26 ret[i] = qtest_readl(qts, target_ret + i * sizeof(uint32_t)); 27 } 28 } 29 30 static uint64_t qrtas_call(QTestState *qts, QGuestAllocator *alloc, 31 const char *name, 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 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); 44 45 guest_free(alloc, target_ret); 46 guest_free(alloc, target_args); 47 48 return res; 49 } 50 51 int qrtas_get_time_of_day(QTestState *qts, QGuestAllocator *alloc, 52 struct tm *tm, uint32_t *ns) 53 { 54 int res; 55 uint32_t ret[8]; 56 57 res = qrtas_call(qts, alloc, "get-time-of-day", 0, NULL, 8, ret); 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 } 74 75 uint32_t qrtas_ibm_read_pci_config(QTestState *qts, QGuestAllocator *alloc, 76 uint64_t buid, 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; 86 res = qrtas_call(qts, alloc, "ibm,read-pci-config", 4, args, 2, ret); 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 98 int qrtas_ibm_write_pci_config(QTestState *qts, QGuestAllocator *alloc, 99 uint64_t buid, 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; 110 res = qrtas_call(qts, alloc, "ibm,write-pci-config", 5, args, 1, ret); 111 if (res != 0) { 112 return -1; 113 } 114 115 if (ret[0] != 0) { 116 return -1; 117 } 118 119 return 0; 120 } 121