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" 7eeddd59fSLaurent Vivier #include "libqtest.h" 8eeddd59fSLaurent Vivier #include "libqos/rtas.h" 9eeddd59fSLaurent Vivier 10*9b67af76SEric Blake static void qrtas_copy_args(QTestState *qts, uint64_t target_args, 11*9b67af76SEric Blake uint32_t nargs, uint32_t *args) 12eeddd59fSLaurent Vivier { 13eeddd59fSLaurent Vivier int i; 14eeddd59fSLaurent Vivier 15eeddd59fSLaurent Vivier for (i = 0; i < nargs; i++) { 16*9b67af76SEric Blake qtest_writel(qts, target_args + i * sizeof(uint32_t), args[i]); 17eeddd59fSLaurent Vivier } 18eeddd59fSLaurent Vivier } 19eeddd59fSLaurent Vivier 20*9b67af76SEric Blake static void qrtas_copy_ret(QTestState *qts, uint64_t target_ret, 21*9b67af76SEric Blake uint32_t nret, uint32_t *ret) 22eeddd59fSLaurent Vivier { 23eeddd59fSLaurent Vivier int i; 24eeddd59fSLaurent Vivier 25eeddd59fSLaurent Vivier for (i = 0; i < nret; i++) { 26*9b67af76SEric Blake ret[i] = qtest_readl(qts, target_ret + i * sizeof(uint32_t)); 27eeddd59fSLaurent Vivier } 28eeddd59fSLaurent Vivier } 29eeddd59fSLaurent Vivier 30*9b67af76SEric Blake static uint64_t qrtas_call(QTestState *qts, QGuestAllocator *alloc, 31*9b67af76SEric 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 41*9b67af76SEric Blake qrtas_copy_args(qts, target_args, nargs, args); 42*9b67af76SEric Blake res = qtest_rtas_call(qts, name, nargs, target_args, nret, target_ret); 43*9b67af76SEric 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 51*9b67af76SEric Blake int qrtas_get_time_of_day(QTestState *qts, QGuestAllocator *alloc, 52*9b67af76SEric Blake struct tm *tm, uint32_t *ns) 53eeddd59fSLaurent Vivier { 54eeddd59fSLaurent Vivier int res; 55eeddd59fSLaurent Vivier uint32_t ret[8]; 56eeddd59fSLaurent Vivier 57*9b67af76SEric 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 75*9b67af76SEric Blake uint32_t qrtas_ibm_read_pci_config(QTestState *qts, QGuestAllocator *alloc, 76*9b67af76SEric 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; 86*9b67af76SEric 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 98*9b67af76SEric Blake int qrtas_ibm_write_pci_config(QTestState *qts, QGuestAllocator *alloc, 99*9b67af76SEric 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; 110*9b67af76SEric 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