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