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
get_sync_addr(uint32_t src_pir,int ic_topo_id,int type)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
get_sync(QTestState * qts,uint32_t src_pir,int ic_topo_id,int type)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
clr_sync(QTestState * qts,uint32_t src_pir,int ic_topo_id,int type)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
inject_cache_flush(QTestState * qts,int ic_topo_id,uint64_t scom_addr)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
inject_queue_sync(QTestState * qts,int ic_topo_id,uint64_t offset)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
inject_op(QTestState * qts,int ic_topo_id,int type)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
test_flush_sync_inject(QTestState * qts)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