1 /* 2 * QTest testcase for PowerNV 10 interrupt controller (xive2) 3 * - Test cache flush/queue sync injection 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 #include "hw/intc/pnv_xive2_regs.h" 14 #include "hw/ppc/xive_regs.h" 15 #include "hw/ppc/xive2_regs.h" 16 17 #define PNV_XIVE2_QUEUE_IPI 0x00 18 #define PNV_XIVE2_QUEUE_HW 0x01 19 #define PNV_XIVE2_QUEUE_NXC 0x02 20 #define PNV_XIVE2_QUEUE_INT 0x03 21 #define PNV_XIVE2_QUEUE_OS 0x04 22 #define PNV_XIVE2_QUEUE_POOL 0x05 23 #define PNV_XIVE2_QUEUE_HARD 0x06 24 #define PNV_XIVE2_CACHE_ENDC 0x08 25 #define PNV_XIVE2_CACHE_ESBC 0x09 26 #define PNV_XIVE2_CACHE_EASC 0x0a 27 #define PNV_XIVE2_QUEUE_NXC_LD_LCL_NCO 0x10 28 #define PNV_XIVE2_QUEUE_NXC_LD_LCL_CO 0x11 29 #define PNV_XIVE2_QUEUE_NXC_ST_LCL_NCI 0x12 30 #define PNV_XIVE2_QUEUE_NXC_ST_LCL_CI 0x13 31 #define PNV_XIVE2_QUEUE_NXC_ST_RMT_NCI 0x14 32 #define PNV_XIVE2_QUEUE_NXC_ST_RMT_CI 0x15 33 #define PNV_XIVE2_CACHE_NXC 0x18 34 35 #define PNV_XIVE2_SYNC_IPI 0x000 36 #define PNV_XIVE2_SYNC_HW 0x080 37 #define PNV_XIVE2_SYNC_NxC 0x100 38 #define PNV_XIVE2_SYNC_INT 0x180 39 #define PNV_XIVE2_SYNC_OS_ESC 0x200 40 #define PNV_XIVE2_SYNC_POOL_ESC 0x280 41 #define PNV_XIVE2_SYNC_HARD_ESC 0x300 42 #define PNV_XIVE2_SYNC_NXC_LD_LCL_NCO 0x800 43 #define PNV_XIVE2_SYNC_NXC_LD_LCL_CO 0x880 44 #define PNV_XIVE2_SYNC_NXC_ST_LCL_NCI 0x900 45 #define PNV_XIVE2_SYNC_NXC_ST_LCL_CI 0x980 46 #define PNV_XIVE2_SYNC_NXC_ST_RMT_NCI 0xA00 47 #define PNV_XIVE2_SYNC_NXC_ST_RMT_CI 0xA80 48 49 50 static uint64_t get_sync_addr(uint32_t src_pir, int ic_topo_id, int type) 51 { 52 int thread_nr = src_pir & 0x7f; 53 uint64_t addr = XIVE_SYNC_MEM + thread_nr * 512 + ic_topo_id * 32 + type; 54 return addr; 55 } 56 57 static uint8_t get_sync(QTestState *qts, uint32_t src_pir, int ic_topo_id, 58 int type) 59 { 60 uint64_t addr = get_sync_addr(src_pir, ic_topo_id, type); 61 return qtest_readb(qts, addr); 62 } 63 64 static void clr_sync(QTestState *qts, uint32_t src_pir, int ic_topo_id, 65 int type) 66 { 67 uint64_t addr = get_sync_addr(src_pir, ic_topo_id, type); 68 qtest_writeb(qts, addr, 0x0); 69 } 70 71 static void inject_cache_flush(QTestState *qts, int ic_topo_id, 72 uint64_t scom_addr) 73 { 74 (void)ic_topo_id; 75 pnv_xive_xscom_write(qts, scom_addr, 0); 76 } 77 78 static void inject_queue_sync(QTestState *qts, int ic_topo_id, uint64_t offset) 79 { 80 (void)ic_topo_id; 81 uint64_t addr = XIVE_IC_ADDR + (VST_SYNC << XIVE_PAGE_SHIFT) + offset; 82 qtest_writeq(qts, addr, 0); 83 } 84 85 static void inject_op(QTestState *qts, int ic_topo_id, int type) 86 { 87 switch (type) { 88 case PNV_XIVE2_QUEUE_IPI: 89 inject_queue_sync(qts, ic_topo_id, PNV_XIVE2_SYNC_IPI); 90 break; 91 case PNV_XIVE2_QUEUE_HW: 92 inject_queue_sync(qts, ic_topo_id, PNV_XIVE2_SYNC_HW); 93 break; 94 case PNV_XIVE2_QUEUE_NXC: 95 inject_queue_sync(qts, ic_topo_id, PNV_XIVE2_SYNC_NxC); 96 break; 97 case PNV_XIVE2_QUEUE_INT: 98 inject_queue_sync(qts, ic_topo_id, PNV_XIVE2_SYNC_INT); 99 break; 100 case PNV_XIVE2_QUEUE_OS: 101 inject_queue_sync(qts, ic_topo_id, PNV_XIVE2_SYNC_OS_ESC); 102 break; 103 case PNV_XIVE2_QUEUE_POOL: 104 inject_queue_sync(qts, ic_topo_id, PNV_XIVE2_SYNC_POOL_ESC); 105 break; 106 case PNV_XIVE2_QUEUE_HARD: 107 inject_queue_sync(qts, ic_topo_id, PNV_XIVE2_SYNC_HARD_ESC); 108 break; 109 case PNV_XIVE2_CACHE_ENDC: 110 inject_cache_flush(qts, ic_topo_id, X_VC_ENDC_FLUSH_INJECT); 111 break; 112 case PNV_XIVE2_CACHE_ESBC: 113 inject_cache_flush(qts, ic_topo_id, X_VC_ESBC_FLUSH_INJECT); 114 break; 115 case PNV_XIVE2_CACHE_EASC: 116 inject_cache_flush(qts, ic_topo_id, X_VC_EASC_FLUSH_INJECT); 117 break; 118 case PNV_XIVE2_QUEUE_NXC_LD_LCL_NCO: 119 inject_queue_sync(qts, ic_topo_id, PNV_XIVE2_SYNC_NXC_LD_LCL_NCO); 120 break; 121 case PNV_XIVE2_QUEUE_NXC_LD_LCL_CO: 122 inject_queue_sync(qts, ic_topo_id, PNV_XIVE2_SYNC_NXC_LD_LCL_CO); 123 break; 124 case PNV_XIVE2_QUEUE_NXC_ST_LCL_NCI: 125 inject_queue_sync(qts, ic_topo_id, PNV_XIVE2_SYNC_NXC_ST_LCL_NCI); 126 break; 127 case PNV_XIVE2_QUEUE_NXC_ST_LCL_CI: 128 inject_queue_sync(qts, ic_topo_id, PNV_XIVE2_SYNC_NXC_ST_LCL_CI); 129 break; 130 case PNV_XIVE2_QUEUE_NXC_ST_RMT_NCI: 131 inject_queue_sync(qts, ic_topo_id, PNV_XIVE2_SYNC_NXC_ST_RMT_NCI); 132 break; 133 case PNV_XIVE2_QUEUE_NXC_ST_RMT_CI: 134 inject_queue_sync(qts, ic_topo_id, PNV_XIVE2_SYNC_NXC_ST_RMT_CI); 135 break; 136 case PNV_XIVE2_CACHE_NXC: 137 inject_cache_flush(qts, ic_topo_id, X_PC_NXC_FLUSH_INJECT); 138 break; 139 default: 140 g_assert_not_reached(); 141 break; 142 } 143 } 144 145 const uint8_t xive_inject_tests[] = { 146 PNV_XIVE2_QUEUE_IPI, 147 PNV_XIVE2_QUEUE_HW, 148 PNV_XIVE2_QUEUE_NXC, 149 PNV_XIVE2_QUEUE_INT, 150 PNV_XIVE2_QUEUE_OS, 151 PNV_XIVE2_QUEUE_POOL, 152 PNV_XIVE2_QUEUE_HARD, 153 PNV_XIVE2_CACHE_ENDC, 154 PNV_XIVE2_CACHE_ESBC, 155 PNV_XIVE2_CACHE_EASC, 156 PNV_XIVE2_QUEUE_NXC_LD_LCL_NCO, 157 PNV_XIVE2_QUEUE_NXC_LD_LCL_CO, 158 PNV_XIVE2_QUEUE_NXC_ST_LCL_NCI, 159 PNV_XIVE2_QUEUE_NXC_ST_LCL_CI, 160 PNV_XIVE2_QUEUE_NXC_ST_RMT_NCI, 161 PNV_XIVE2_QUEUE_NXC_ST_RMT_CI, 162 PNV_XIVE2_CACHE_NXC, 163 }; 164 165 void test_flush_sync_inject(QTestState *qts) 166 { 167 int ic_topo_id = 0; 168 169 /* 170 * Writes performed by qtest are not done in the context of a thread. 171 * This means that QEMU XIVE code doesn't have a way to determine what 172 * thread is originating the write. In order to allow for some testing, 173 * QEMU XIVE code will assume a PIR of 0 when unable to determine the 174 * source thread for cache flush and queue sync inject operations. 175 * See hw/intc/pnv_xive2.c: pnv_xive2_inject_notify() for details. 176 */ 177 int src_pir = 0; 178 int test_nr; 179 uint8_t byte; 180 181 printf("# ============================================================\n"); 182 printf("# Starting cache flush/queue sync injection tests...\n"); 183 184 for (test_nr = 0; test_nr < sizeof(xive_inject_tests); 185 test_nr++) { 186 int op_type = xive_inject_tests[test_nr]; 187 188 printf("# Running test %d\n", test_nr); 189 190 /* start with status byte set to 0 */ 191 clr_sync(qts, src_pir, ic_topo_id, op_type); 192 byte = get_sync(qts, src_pir, ic_topo_id, op_type); 193 g_assert_cmphex(byte, ==, 0); 194 195 /* request cache flush or queue sync operation */ 196 inject_op(qts, ic_topo_id, op_type); 197 198 /* verify that status byte was written to 0xff */ 199 byte = get_sync(qts, src_pir, ic_topo_id, op_type); 200 g_assert_cmphex(byte, ==, 0xff); 201 202 clr_sync(qts, src_pir, ic_topo_id, op_type); 203 } 204 } 205 206