1 /* 2 * QTest testcase for PowerNV 10 interrupt controller (xive2) 3 * - Common functions for XIVE2 tests 4 * 5 * Copyright (c) 2024, IBM Corporation. 6 * 7 * SPDX-License-Identifier: GPL-2.0-or-later 8 */ 9 #include "qemu/osdep.h" 10 #include "libqtest.h" 11 12 #include "pnv-xive2-common.h" 13 14 15 static uint64_t pnv_xscom_addr(uint32_t pcba) 16 { 17 return P10_XSCOM_BASE | ((uint64_t) pcba << 3); 18 } 19 20 static uint64_t pnv_xive_xscom_addr(uint32_t reg) 21 { 22 return pnv_xscom_addr(XIVE_XSCOM + reg); 23 } 24 25 uint64_t pnv_xive_xscom_read(QTestState *qts, uint32_t reg) 26 { 27 return qtest_readq(qts, pnv_xive_xscom_addr(reg)); 28 } 29 30 void pnv_xive_xscom_write(QTestState *qts, uint32_t reg, uint64_t val) 31 { 32 qtest_writeq(qts, pnv_xive_xscom_addr(reg), val); 33 } 34 35 static void xive_get_struct(QTestState *qts, uint64_t src, void *dest, 36 size_t size) 37 { 38 uint8_t *destination = (uint8_t *)dest; 39 size_t i; 40 41 for (i = 0; i < size; i++) { 42 *(destination + i) = qtest_readb(qts, src + i); 43 } 44 } 45 46 static void xive_copy_struct(QTestState *qts, void *src, uint64_t dest, 47 size_t size) 48 { 49 uint8_t *source = (uint8_t *)src; 50 size_t i; 51 52 for (i = 0; i < size; i++) { 53 qtest_writeb(qts, dest + i, *(source + i)); 54 } 55 } 56 57 uint64_t xive_get_queue_addr(uint32_t end_index) 58 { 59 return XIVE_QUEUE_MEM + (uint64_t)end_index * XIVE_QUEUE_SIZE; 60 } 61 62 uint8_t get_esb(QTestState *qts, uint32_t index, uint8_t page, 63 uint32_t offset) 64 { 65 uint64_t addr; 66 67 addr = XIVE_ESB_ADDR + ((uint64_t)index << (XIVE_PAGE_SHIFT + 1)); 68 if (page == 1) { 69 addr += 1 << XIVE_PAGE_SHIFT; 70 } 71 return qtest_readb(qts, addr + offset); 72 } 73 74 void set_esb(QTestState *qts, uint32_t index, uint8_t page, 75 uint32_t offset, uint32_t val) 76 { 77 uint64_t addr; 78 79 addr = XIVE_ESB_ADDR + ((uint64_t)index << (XIVE_PAGE_SHIFT + 1)); 80 if (page == 1) { 81 addr += 1 << XIVE_PAGE_SHIFT; 82 } 83 return qtest_writel(qts, addr + offset, cpu_to_be32(val)); 84 } 85 86 void get_nvp(QTestState *qts, uint32_t index, Xive2Nvp* nvp) 87 { 88 uint64_t addr = XIVE_NVP_MEM + (uint64_t)index * sizeof(Xive2Nvp); 89 xive_get_struct(qts, addr, nvp, sizeof(Xive2Nvp)); 90 } 91 92 void set_nvp(QTestState *qts, uint32_t index, uint8_t first) 93 { 94 uint64_t nvp_addr; 95 Xive2Nvp nvp; 96 uint64_t report_addr; 97 98 nvp_addr = XIVE_NVP_MEM + (uint64_t)index * sizeof(Xive2Nvp); 99 report_addr = (XIVE_REPORT_MEM + (uint64_t)index * XIVE_REPORT_SIZE) >> 8; 100 101 memset(&nvp, 0, sizeof(nvp)); 102 nvp.w0 = xive_set_field32(NVP2_W0_VALID, 0, 1); 103 nvp.w0 = xive_set_field32(NVP2_W0_PGOFIRST, nvp.w0, first); 104 nvp.w6 = xive_set_field32(NVP2_W6_REPORTING_LINE, nvp.w6, 105 (report_addr >> 24) & 0xfffffff); 106 nvp.w7 = xive_set_field32(NVP2_W7_REPORTING_LINE, nvp.w7, 107 report_addr & 0xffffff); 108 xive_copy_struct(qts, &nvp, nvp_addr, sizeof(nvp)); 109 } 110 111 static uint64_t get_cl_pair_addr(Xive2Nvp *nvp) 112 { 113 uint64_t upper = xive_get_field32(0x0fffffff, nvp->w6); 114 uint64_t lower = xive_get_field32(0xffffff00, nvp->w7); 115 return (upper << 32) | (lower << 8); 116 } 117 118 void get_cl_pair(QTestState *qts, Xive2Nvp *nvp, uint8_t *cl_pair) 119 { 120 uint64_t addr = get_cl_pair_addr(nvp); 121 xive_get_struct(qts, addr, cl_pair, XIVE_REPORT_SIZE); 122 } 123 124 void set_cl_pair(QTestState *qts, Xive2Nvp *nvp, uint8_t *cl_pair) 125 { 126 uint64_t addr = get_cl_pair_addr(nvp); 127 xive_copy_struct(qts, cl_pair, addr, XIVE_REPORT_SIZE); 128 } 129 130 void set_nvg(QTestState *qts, uint32_t index, uint8_t next) 131 { 132 uint64_t nvg_addr; 133 Xive2Nvgc nvg; 134 135 nvg_addr = XIVE_NVG_MEM + (uint64_t)index * sizeof(Xive2Nvgc); 136 137 memset(&nvg, 0, sizeof(nvg)); 138 nvg.w0 = xive_set_field32(NVGC2_W0_VALID, 0, 1); 139 nvg.w0 = xive_set_field32(NVGC2_W0_PGONEXT, nvg.w0, next); 140 xive_copy_struct(qts, &nvg, nvg_addr, sizeof(nvg)); 141 } 142 143 void set_eas(QTestState *qts, uint32_t index, uint32_t end_index, 144 uint32_t data) 145 { 146 uint64_t eas_addr; 147 Xive2Eas eas; 148 149 eas_addr = XIVE_EAS_MEM + (uint64_t)index * sizeof(Xive2Eas); 150 151 memset(&eas, 0, sizeof(eas)); 152 eas.w = xive_set_field64(EAS2_VALID, 0, 1); 153 eas.w = xive_set_field64(EAS2_END_INDEX, eas.w, end_index); 154 eas.w = xive_set_field64(EAS2_END_DATA, eas.w, data); 155 xive_copy_struct(qts, &eas, eas_addr, sizeof(eas)); 156 } 157 158 void set_end(QTestState *qts, uint32_t index, uint32_t nvp_index, 159 uint8_t priority, bool i) 160 { 161 uint64_t end_addr, queue_addr, queue_hi, queue_lo; 162 uint8_t queue_size; 163 Xive2End end; 164 165 end_addr = XIVE_END_MEM + (uint64_t)index * sizeof(Xive2End); 166 queue_addr = xive_get_queue_addr(index); 167 queue_hi = (queue_addr >> 32) & END2_W2_EQ_ADDR_HI; 168 queue_lo = queue_addr & END2_W3_EQ_ADDR_LO; 169 queue_size = ctz16(XIVE_QUEUE_SIZE) - 12; 170 171 memset(&end, 0, sizeof(end)); 172 end.w0 = xive_set_field32(END2_W0_VALID, 0, 1); 173 end.w0 = xive_set_field32(END2_W0_ENQUEUE, end.w0, 1); 174 end.w0 = xive_set_field32(END2_W0_UCOND_NOTIFY, end.w0, 1); 175 end.w0 = xive_set_field32(END2_W0_BACKLOG, end.w0, 1); 176 177 end.w1 = xive_set_field32(END2_W1_GENERATION, 0, 1); 178 179 end.w2 = cpu_to_be32(queue_hi); 180 181 end.w3 = cpu_to_be32(queue_lo); 182 end.w3 = xive_set_field32(END2_W3_QSIZE, end.w3, queue_size); 183 184 end.w6 = xive_set_field32(END2_W6_IGNORE, 0, i); 185 end.w6 = xive_set_field32(END2_W6_VP_OFFSET, end.w6, nvp_index); 186 187 end.w7 = xive_set_field32(END2_W7_F0_PRIORITY, 0, priority); 188 xive_copy_struct(qts, &end, end_addr, sizeof(end)); 189 } 190 191