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