master
c 598 lines 18.7 KB
Raw
1 /*
2 * QTest testcase for PowerNV 10 interrupt controller (xive2)
3 * - Test irq to hardware thread
4 * - Test 'Pull Thread Context to Odd Thread Reporting Line'
5 * - Test irq to hardware group
6 * - Test irq to hardware group going through backlog
7 * - Test irq to pool thread
8 *
9 * Copyright (c) 2024, IBM Corporation.
10 *
11 * SPDX-License-Identifier: GPL-2.0-or-later
12 */
13 #include "qemu/osdep.h"
14 #include "libqtest.h"
15
16 #include "pnv-xive2-common.h"
17 #include "pnv-xscom.h"
18 #include "hw/intc/pnv_xive2_regs.h"
19 #include "hw/ppc/xive_regs.h"
20 #include "hw/ppc/xive2_regs.h"
21
22 #define SMT 4 /* some tests will break if less than 4 */
23
24
25 static void set_table(QTestState *qts, uint64_t type, uint64_t addr)
26 {
27 uint64_t vsd, size, log_size;
28
29 /*
30 * First, let's make sure that all the resources used fit in the
31 * given table.
32 */
33 switch (type) {
34 case VST_ESB:
35 size = MAX_IRQS / 4;
36 break;
37 case VST_EAS:
38 size = MAX_IRQS * 8;
39 break;
40 case VST_END:
41 size = MAX_ENDS * 32;
42 break;
43 case VST_NVP:
44 case VST_NVG:
45 case VST_NVC:
46 size = MAX_VPS * 32;
47 break;
48 case VST_SYNC:
49 size = 64 * 1024;
50 break;
51 default:
52 g_assert_not_reached();
53 }
54
55 g_assert_cmpuint(size, <=, XIVE_VST_SIZE);
56 log_size = ctzl(XIVE_VST_SIZE) - 12;
57
58 vsd = ((uint64_t) VSD_MODE_EXCLUSIVE) << 62 | addr | log_size;
59 pnv_xive_xscom_write(qts, X_VC_VSD_TABLE_ADDR, type << 48);
60 pnv_xive_xscom_write(qts, X_VC_VSD_TABLE_DATA, vsd);
61
62 if (type != VST_EAS && type != VST_IC && type != VST_ERQ) {
63 pnv_xive_xscom_write(qts, X_PC_VSD_TABLE_ADDR, type << 48);
64 pnv_xive_xscom_write(qts, X_PC_VSD_TABLE_DATA, vsd);
65 }
66 }
67
68 static void set_tima8(QTestState *qts, uint32_t pir, uint32_t offset,
69 uint8_t b)
70 {
71 uint64_t ic_addr;
72
73 ic_addr = XIVE_IC_TM_INDIRECT + (pir << XIVE_PAGE_SHIFT);
74 qtest_writeb(qts, ic_addr + offset, b);
75 }
76
77 static void set_tima32(QTestState *qts, uint32_t pir, uint32_t offset,
78 uint32_t l)
79 {
80 uint64_t ic_addr;
81
82 ic_addr = XIVE_IC_TM_INDIRECT + (pir << XIVE_PAGE_SHIFT);
83 qtest_writel(qts, ic_addr + offset, l);
84 }
85
86 static uint8_t get_tima8(QTestState *qts, uint32_t pir, uint32_t offset)
87 {
88 uint64_t ic_addr;
89
90 ic_addr = XIVE_IC_TM_INDIRECT + (pir << XIVE_PAGE_SHIFT);
91 return qtest_readb(qts, ic_addr + offset);
92 }
93
94 static uint16_t get_tima16(QTestState *qts, uint32_t pir, uint32_t offset)
95 {
96 uint64_t ic_addr;
97
98 ic_addr = XIVE_IC_TM_INDIRECT + (pir << XIVE_PAGE_SHIFT);
99 return qtest_readw(qts, ic_addr + offset);
100 }
101
102 static uint32_t get_tima32(QTestState *qts, uint32_t pir, uint32_t offset)
103 {
104 uint64_t ic_addr;
105
106 ic_addr = XIVE_IC_TM_INDIRECT + (pir << XIVE_PAGE_SHIFT);
107 return qtest_readl(qts, ic_addr + offset);
108 }
109
110 static void reset_pool_threads(QTestState *qts)
111 {
112 uint8_t first_group = 0;
113 int i;
114
115 for (i = 0; i < SMT; i++) {
116 uint32_t nvp_idx = 0x100 + i;
117 set_nvp(qts, nvp_idx, first_group);
118 set_tima32(qts, i, TM_QW2_HV_POOL + TM_WORD0, 0x000000ff);
119 set_tima32(qts, i, TM_QW2_HV_POOL + TM_WORD1, 0);
120 set_tima32(qts, i, TM_QW2_HV_POOL + TM_WORD2, TM_QW2W2_VP | nvp_idx);
121 }
122 }
123
124 static void reset_hw_threads(QTestState *qts)
125 {
126 uint8_t first_group = 0;
127 uint32_t w1 = 0x000000ff;
128 int i;
129
130 if (SMT >= 4) {
131 /* define 2 groups of 2, part of a bigger group of size 4 */
132 set_nvg(qts, 0x80, 0x02);
133 set_nvg(qts, 0x82, 0x02);
134 set_nvg(qts, 0x81, 0);
135 first_group = 0x01;
136 w1 = 0x000300ff;
137 }
138
139 for (i = 0; i < SMT; i++) {
140 set_nvp(qts, 0x80 + i, first_group);
141 set_tima32(qts, i, TM_QW3_HV_PHYS + TM_WORD0, 0x00ff00ff);
142 set_tima32(qts, i, TM_QW3_HV_PHYS + TM_WORD1, w1);
143 set_tima32(qts, i, TM_QW3_HV_PHYS + TM_WORD2, 0x80000000);
144 }
145 }
146
147 static void reset_state(QTestState *qts)
148 {
149 size_t mem_used = XIVE_MEM_END - XIVE_MEM_START;
150
151 qtest_memset(qts, XIVE_MEM_START, 0, mem_used);
152 reset_hw_threads(qts);
153 reset_pool_threads(qts);
154 }
155
156 static void init_xive(QTestState *qts)
157 {
158 uint64_t val1, val2, range;
159
160 /*
161 * We can take a few shortcuts here, as we know the default values
162 * used for xive initialization
163 */
164
165 /*
166 * Set the BARs.
167 * We reuse the same values used by firmware to ease debug.
168 */
169 pnv_xive_xscom_write(qts, X_CQ_IC_BAR, XIVE_IC_BAR);
170 pnv_xive_xscom_write(qts, X_CQ_TM_BAR, XIVE_TM_BAR);
171
172 /* ESB and NVPG use 2 pages per resource. The others only one page */
173 range = (MAX_IRQS << 17) >> 25;
174 val1 = XIVE_ESB_BAR | range;
175 pnv_xive_xscom_write(qts, X_CQ_ESB_BAR, val1);
176
177 range = (MAX_ENDS << 16) >> 25;
178 val1 = XIVE_END_BAR | range;
179 pnv_xive_xscom_write(qts, X_CQ_END_BAR, val1);
180
181 range = (MAX_VPS << 17) >> 25;
182 val1 = XIVE_NVPG_BAR | range;
183 pnv_xive_xscom_write(qts, X_CQ_NVPG_BAR, val1);
184
185 range = (MAX_VPS << 16) >> 25;
186 val1 = XIVE_NVC_BAR | range;
187 pnv_xive_xscom_write(qts, X_CQ_NVC_BAR, val1);
188
189 /*
190 * Enable hw threads.
191 * We check the value written. Useless with current
192 * implementation, but it validates the xscom read path and it's
193 * what the hardware procedure says
194 */
195 val1 = 0xF000000000000000ull; /* core 0, 4 threads */
196 pnv_xive_xscom_write(qts, X_TCTXT_EN0, val1);
197 val2 = pnv_xive_xscom_read(qts, X_TCTXT_EN0);
198 g_assert_cmphex(val1, ==, val2);
199
200 /* Memory tables */
201 set_table(qts, VST_ESB, XIVE_ESB_MEM);
202 set_table(qts, VST_EAS, XIVE_EAS_MEM);
203 set_table(qts, VST_END, XIVE_END_MEM);
204 set_table(qts, VST_NVP, XIVE_NVP_MEM);
205 set_table(qts, VST_NVG, XIVE_NVG_MEM);
206 set_table(qts, VST_NVC, XIVE_NVC_MEM);
207 set_table(qts, VST_SYNC, XIVE_SYNC_MEM);
208
209 reset_hw_threads(qts);
210 reset_pool_threads(qts);
211 }
212
213 static void test_hw_irq(QTestState *qts)
214 {
215 uint32_t irq = 2;
216 uint32_t irq_data = 0x600df00d;
217 uint32_t end_index = 5;
218 uint32_t target_pir = 1;
219 uint32_t target_nvp = 0x80 + target_pir;
220 uint8_t priority = 5;
221 uint32_t reg32;
222 uint16_t reg16;
223 uint8_t pq, nsr, cppr;
224
225 g_test_message("=========================================================");
226 g_test_message("Testing irq %d to hardware thread %d", irq, target_pir);
227
228 /* irq config */
229 set_eas(qts, irq, end_index, irq_data);
230 set_end(qts, end_index, target_nvp, priority, false /* group */);
231
232 /* enable and trigger irq */
233 get_esb(qts, irq, XIVE_EOI_PAGE, XIVE_ESB_SET_PQ_00);
234 set_esb(qts, irq, XIVE_TRIGGER_PAGE, 0, 0);
235
236 /* check irq is raised on cpu */
237 pq = get_esb(qts, irq, XIVE_EOI_PAGE, XIVE_ESB_GET);
238 g_assert_cmpuint(pq, ==, XIVE_ESB_PENDING);
239
240 reg32 = get_tima32(qts, target_pir, TM_QW3_HV_PHYS + TM_WORD0);
241 nsr = reg32 >> 24;
242 cppr = (reg32 >> 16) & 0xFF;
243 g_assert_cmphex(nsr, ==, 0x80);
244 g_assert_cmphex(cppr, ==, 0xFF);
245
246 /* ack the irq */
247 reg16 = get_tima16(qts, target_pir, TM_SPC_ACK_HV_REG);
248 nsr = reg16 >> 8;
249 cppr = reg16 & 0xFF;
250 g_assert_cmphex(nsr, ==, 0x80);
251 g_assert_cmphex(cppr, ==, priority);
252
253 /* check irq data is what was configured */
254 reg32 = qtest_readl(qts, xive_get_queue_addr(end_index));
255 g_assert_cmphex((reg32 & 0x7fffffff), ==, (irq_data & 0x7fffffff));
256
257 /* End Of Interrupt */
258 set_esb(qts, irq, XIVE_EOI_PAGE, XIVE_ESB_STORE_EOI, 0);
259 pq = get_esb(qts, irq, XIVE_EOI_PAGE, XIVE_ESB_GET);
260 g_assert_cmpuint(pq, ==, XIVE_ESB_RESET);
261
262 /* reset CPPR */
263 set_tima8(qts, target_pir, TM_QW3_HV_PHYS + TM_CPPR, 0xFF);
264 reg32 = get_tima32(qts, target_pir, TM_QW3_HV_PHYS + TM_WORD0);
265 nsr = reg32 >> 24;
266 cppr = (reg32 >> 16) & 0xFF;
267 g_assert_cmphex(nsr, ==, 0x00);
268 g_assert_cmphex(cppr, ==, 0xFF);
269 }
270
271 static void test_pool_irq(QTestState *qts)
272 {
273 uint32_t irq = 2;
274 uint32_t irq_data = 0x600d0d06;
275 uint32_t end_index = 5;
276 uint32_t target_pir = 1;
277 uint32_t target_nvp = 0x100 + target_pir;
278 uint8_t priority = 5;
279 uint32_t reg32;
280 uint16_t reg16;
281 uint8_t pq, nsr, cppr, ipb;
282
283 g_test_message("=========================================================");
284 g_test_message("Testing irq %d to pool thread %d", irq, target_pir);
285
286 /* irq config */
287 set_eas(qts, irq, end_index, irq_data);
288 set_end(qts, end_index, target_nvp, priority, false /* group */);
289
290 /* enable and trigger irq */
291 get_esb(qts, irq, XIVE_EOI_PAGE, XIVE_ESB_SET_PQ_00);
292 set_esb(qts, irq, XIVE_TRIGGER_PAGE, 0, 0);
293
294 /* check irq is raised on cpu */
295 pq = get_esb(qts, irq, XIVE_EOI_PAGE, XIVE_ESB_GET);
296 g_assert_cmpuint(pq, ==, XIVE_ESB_PENDING);
297
298 /* check TIMA values in the PHYS ring (shared by POOL ring) */
299 reg32 = get_tima32(qts, target_pir, TM_QW3_HV_PHYS + TM_WORD0);
300 nsr = reg32 >> 24;
301 cppr = (reg32 >> 16) & 0xFF;
302 g_assert_cmphex(nsr, ==, 0x40);
303 g_assert_cmphex(cppr, ==, 0xFF);
304
305 /* check TIMA values in the POOL ring */
306 reg32 = get_tima32(qts, target_pir, TM_QW2_HV_POOL + TM_WORD0);
307 nsr = reg32 >> 24;
308 cppr = (reg32 >> 16) & 0xFF;
309 ipb = (reg32 >> 8) & 0xFF;
310 g_assert_cmphex(nsr, ==, 0);
311 g_assert_cmphex(cppr, ==, 0);
312 g_assert_cmphex(ipb, ==, 0x80 >> priority);
313
314 /* ack the irq */
315 reg16 = get_tima16(qts, target_pir, TM_SPC_ACK_HV_REG);
316 nsr = reg16 >> 8;
317 cppr = reg16 & 0xFF;
318 g_assert_cmphex(nsr, ==, 0x40);
319 g_assert_cmphex(cppr, ==, priority);
320
321 /* check irq data is what was configured */
322 reg32 = qtest_readl(qts, xive_get_queue_addr(end_index));
323 g_assert_cmphex((reg32 & 0x7fffffff), ==, (irq_data & 0x7fffffff));
324
325 /* check IPB is cleared in the POOL ring */
326 reg32 = get_tima32(qts, target_pir, TM_QW2_HV_POOL + TM_WORD0);
327 ipb = (reg32 >> 8) & 0xFF;
328 g_assert_cmphex(ipb, ==, 0);
329
330 /* End Of Interrupt */
331 set_esb(qts, irq, XIVE_EOI_PAGE, XIVE_ESB_STORE_EOI, 0);
332 pq = get_esb(qts, irq, XIVE_EOI_PAGE, XIVE_ESB_GET);
333 g_assert_cmpuint(pq, ==, XIVE_ESB_RESET);
334
335 /* reset CPPR */
336 set_tima8(qts, target_pir, TM_QW3_HV_PHYS + TM_CPPR, 0xFF);
337 reg32 = get_tima32(qts, target_pir, TM_QW3_HV_PHYS + TM_WORD0);
338 nsr = reg32 >> 24;
339 cppr = (reg32 >> 16) & 0xFF;
340 g_assert_cmphex(nsr, ==, 0x00);
341 g_assert_cmphex(cppr, ==, 0xFF);
342 }
343
344 #define XIVE_ODD_CL 0x80
345 static void test_pull_thread_ctx_to_odd_thread_cl(QTestState *qts)
346 {
347 uint32_t target_pir = 1;
348 uint32_t target_nvp = 0x80 + target_pir;
349 Xive2Nvp nvp;
350 uint8_t cl_pair[XIVE_REPORT_SIZE];
351 uint32_t qw1w0, qw3w0, qw1w2, qw2w2;
352 uint8_t qw3b8;
353 uint32_t cl_word;
354 uint32_t word2;
355
356 g_test_message("=========================================================");
357 g_test_message("Testing 'Pull Thread Context to Odd Thread Reporting " \
358 "Line'");
359
360 /* clear odd cache line prior to pull operation */
361 memset(cl_pair, 0, sizeof(cl_pair));
362 get_nvp(qts, target_nvp, &nvp);
363 set_cl_pair(qts, &nvp, cl_pair);
364
365 /* Read some values from TIMA that we expect to see in cacheline */
366 qw1w0 = get_tima32(qts, target_pir, TM_QW1_OS + TM_WORD0);
367 qw3w0 = get_tima32(qts, target_pir, TM_QW3_HV_PHYS + TM_WORD0);
368 qw1w2 = get_tima32(qts, target_pir, TM_QW1_OS + TM_WORD2);
369 qw2w2 = get_tima32(qts, target_pir, TM_QW2_HV_POOL + TM_WORD2);
370 qw3b8 = get_tima8(qts, target_pir, TM_QW3_HV_PHYS + TM_WORD2);
371
372 /* Execute the pull operation */
373 set_tima8(qts, target_pir, TM_SPC_PULL_PHYS_CTX_OL, 0);
374
375 /* Verify odd cache line values match TIMA after pull operation */
376 get_cl_pair(qts, &nvp, cl_pair);
377 memcpy(&cl_word, &cl_pair[XIVE_ODD_CL + TM_QW1_OS + TM_WORD0], 4);
378 g_assert_cmphex(qw1w0, ==, be32_to_cpu(cl_word));
379 memcpy(&cl_word, &cl_pair[XIVE_ODD_CL + TM_QW3_HV_PHYS + TM_WORD0], 4);
380 g_assert_cmphex(qw3w0, ==, be32_to_cpu(cl_word));
381 memcpy(&cl_word, &cl_pair[XIVE_ODD_CL + TM_QW1_OS + TM_WORD2], 4);
382 g_assert_cmphex(qw1w2, ==, be32_to_cpu(cl_word));
383 memcpy(&cl_word, &cl_pair[XIVE_ODD_CL + TM_QW2_HV_POOL + TM_WORD2], 4);
384 g_assert_cmphex(qw2w2, ==, be32_to_cpu(cl_word));
385 g_assert_cmphex(qw3b8, ==,
386 cl_pair[XIVE_ODD_CL + TM_QW3_HV_PHYS + TM_WORD2]);
387
388 /* Verify that all TIMA valid bits for target thread are cleared */
389 word2 = get_tima32(qts, target_pir, TM_QW1_OS + TM_WORD2);
390 g_assert_cmphex(xive_get_field32(TM_QW1W2_VO, word2), ==, 0);
391 word2 = get_tima32(qts, target_pir, TM_QW2_HV_POOL + TM_WORD2);
392 g_assert_cmphex(xive_get_field32(TM_QW2W2_VP, word2), ==, 0);
393 word2 = get_tima32(qts, target_pir, TM_QW3_HV_PHYS + TM_WORD2);
394 g_assert_cmphex(xive_get_field32(TM_QW3W2_VT, word2), ==, 0);
395 }
396
397 static void test_hw_group_irq(QTestState *qts)
398 {
399 uint32_t irq = 100;
400 uint32_t irq_data = 0xdeadbeef;
401 uint32_t end_index = 23;
402 uint32_t chosen_one;
403 uint32_t target_nvp = 0x81; /* group size = 4 */
404 uint8_t priority = 6;
405 uint32_t reg32;
406 uint16_t reg16;
407 uint8_t pq, nsr, cppr;
408
409 g_test_message("=========================================================");
410 g_test_message("Testing irq %d to hardware group of size 4", irq);
411
412 /* irq config */
413 set_eas(qts, irq, end_index, irq_data);
414 set_end(qts, end_index, target_nvp, priority, true /* group */);
415
416 /* enable and trigger irq */
417 get_esb(qts, irq, XIVE_EOI_PAGE, XIVE_ESB_SET_PQ_00);
418 set_esb(qts, irq, XIVE_TRIGGER_PAGE, 0, 0);
419
420 /* check irq is raised on cpu */
421 pq = get_esb(qts, irq, XIVE_EOI_PAGE, XIVE_ESB_GET);
422 g_assert_cmpuint(pq, ==, XIVE_ESB_PENDING);
423
424 /* find the targeted vCPU */
425 for (chosen_one = 0; chosen_one < SMT; chosen_one++) {
426 reg32 = get_tima32(qts, chosen_one, TM_QW3_HV_PHYS + TM_WORD0);
427 nsr = reg32 >> 24;
428 if (nsr == 0x82) {
429 break;
430 }
431 }
432 g_assert_cmphex(chosen_one, <, SMT);
433 cppr = (reg32 >> 16) & 0xFF;
434 g_assert_cmphex(nsr, ==, 0x82);
435 g_assert_cmphex(cppr, ==, 0xFF);
436
437 /* ack the irq */
438 reg16 = get_tima16(qts, chosen_one, TM_SPC_ACK_HV_REG);
439 nsr = reg16 >> 8;
440 cppr = reg16 & 0xFF;
441 g_assert_cmphex(nsr, ==, 0x82);
442 g_assert_cmphex(cppr, ==, priority);
443
444 /* check irq data is what was configured */
445 reg32 = qtest_readl(qts, xive_get_queue_addr(end_index));
446 g_assert_cmphex((reg32 & 0x7fffffff), ==, (irq_data & 0x7fffffff));
447
448 /* End Of Interrupt */
449 set_esb(qts, irq, XIVE_EOI_PAGE, XIVE_ESB_STORE_EOI, 0);
450 pq = get_esb(qts, irq, XIVE_EOI_PAGE, XIVE_ESB_GET);
451 g_assert_cmpuint(pq, ==, XIVE_ESB_RESET);
452
453 /* reset CPPR */
454 set_tima8(qts, chosen_one, TM_QW3_HV_PHYS + TM_CPPR, 0xFF);
455 reg32 = get_tima32(qts, chosen_one, TM_QW3_HV_PHYS + TM_WORD0);
456 nsr = reg32 >> 24;
457 cppr = (reg32 >> 16) & 0xFF;
458 g_assert_cmphex(nsr, ==, 0x00);
459 g_assert_cmphex(cppr, ==, 0xFF);
460 }
461
462 static void test_hw_group_irq_backlog(QTestState *qts)
463 {
464 uint32_t irq = 31;
465 uint32_t irq_data = 0x01234567;
466 uint32_t end_index = 129;
467 uint32_t target_nvp = 0x81; /* group size = 4 */
468 uint32_t chosen_one = 3;
469 uint8_t blocking_priority, priority = 3;
470 uint32_t reg32;
471 uint16_t reg16;
472 uint8_t pq, nsr, cppr, lsmfb, i;
473
474 g_test_message("=========================================================");
475 g_test_message("Testing irq %d to hardware group of size 4 going " \
476 "through backlog",
477 irq);
478
479 /*
480 * set current priority of all threads in the group to something
481 * higher than what we're about to trigger
482 */
483 blocking_priority = priority - 1;
484 for (i = 0; i < SMT; i++) {
485 set_tima8(qts, i, TM_QW3_HV_PHYS + TM_CPPR, blocking_priority);
486 }
487
488 /* irq config */
489 set_eas(qts, irq, end_index, irq_data);
490 set_end(qts, end_index, target_nvp, priority, true /* group */);
491
492 /* enable and trigger irq */
493 get_esb(qts, irq, XIVE_EOI_PAGE, XIVE_ESB_SET_PQ_00);
494 set_esb(qts, irq, XIVE_TRIGGER_PAGE, 0, 0);
495
496 /* check irq is raised on cpu */
497 pq = get_esb(qts, irq, XIVE_EOI_PAGE, XIVE_ESB_GET);
498 g_assert_cmpuint(pq, ==, XIVE_ESB_PENDING);
499
500 /* check no interrupt is pending on the 2 possible targets */
501 for (i = 0; i < SMT; i++) {
502 reg32 = get_tima32(qts, i, TM_QW3_HV_PHYS + TM_WORD0);
503 nsr = reg32 >> 24;
504 cppr = (reg32 >> 16) & 0xFF;
505 lsmfb = reg32 & 0xFF;
506 g_assert_cmphex(nsr, ==, 0x0);
507 g_assert_cmphex(cppr, ==, blocking_priority);
508 g_assert_cmphex(lsmfb, ==, priority);
509 }
510
511 /* lower priority of one thread */
512 set_tima8(qts, chosen_one, TM_QW3_HV_PHYS + TM_CPPR, priority + 1);
513
514 /* check backlogged interrupt is presented */
515 reg32 = get_tima32(qts, chosen_one, TM_QW3_HV_PHYS + TM_WORD0);
516 nsr = reg32 >> 24;
517 cppr = (reg32 >> 16) & 0xFF;
518 g_assert_cmphex(nsr, ==, 0x82);
519 g_assert_cmphex(cppr, ==, priority + 1);
520
521 /* ack the irq */
522 reg16 = get_tima16(qts, chosen_one, TM_SPC_ACK_HV_REG);
523 nsr = reg16 >> 8;
524 cppr = reg16 & 0xFF;
525 g_assert_cmphex(nsr, ==, 0x82);
526 g_assert_cmphex(cppr, ==, priority);
527
528 /* check irq data is what was configured */
529 reg32 = qtest_readl(qts, xive_get_queue_addr(end_index));
530 g_assert_cmphex((reg32 & 0x7fffffff), ==, (irq_data & 0x7fffffff));
531
532 /* End Of Interrupt */
533 set_esb(qts, irq, XIVE_EOI_PAGE, XIVE_ESB_STORE_EOI, 0);
534 pq = get_esb(qts, irq, XIVE_EOI_PAGE, XIVE_ESB_GET);
535 g_assert_cmpuint(pq, ==, XIVE_ESB_RESET);
536
537 /* reset CPPR */
538 set_tima8(qts, chosen_one, TM_QW3_HV_PHYS + TM_CPPR, 0xFF);
539 reg32 = get_tima32(qts, chosen_one, TM_QW3_HV_PHYS + TM_WORD0);
540 nsr = reg32 >> 24;
541 cppr = (reg32 >> 16) & 0xFF;
542 lsmfb = reg32 & 0xFF;
543 g_assert_cmphex(nsr, ==, 0x00);
544 g_assert_cmphex(cppr, ==, 0xFF);
545 g_assert_cmphex(lsmfb, ==, 0xFF);
546 }
547
548 static void test_xive(const void *data)
549 {
550 const PnvChip *chip = data;
551 const char *machine = pnv_get_machine_type(chip->chip_type);
552 QTestState *qts;
553
554 qts = qtest_initf("-M %s -smp %d,cores=1,threads=%d -nographic "
555 "-nodefaults -S "
556 "-d guest_errors -trace '*xive*'",
557 machine, SMT, SMT);
558 init_xive(qts);
559
560 test_hw_irq(qts);
561
562 /* omit reset_state here and use settings from test_hw_irq */
563 test_pull_thread_ctx_to_odd_thread_cl(qts);
564
565 reset_state(qts);
566 test_pool_irq(qts);
567
568 reset_state(qts);
569 test_hw_group_irq(qts);
570
571 reset_state(qts);
572 test_hw_group_irq_backlog(qts);
573
574 reset_state(qts);
575 test_flush_sync_inject(qts);
576
577 reset_state(qts);
578 test_nvpg_bar(qts);
579
580 qtest_quit(qts);
581 }
582
583 int main(int argc, char **argv)
584 {
585 g_test_init(&argc, &argv, NULL);
586
587 for (int i = 0; i < ARRAY_SIZE(pnv_chips); i++) {
588 /* xive2 exists from Power10 onwards */
589 if (pnv_chips[i].chip_type < PNV_CHIP_POWER10) {
590 continue;
591 }
592
593 g_autofree char *tname = g_strdup_printf("pnv-xive2/%s",
594 pnv_chips[i].cpu_model);
595 qtest_add_data_func(tname, &pnv_chips[i], test_xive);
596 }
597 return g_test_run();
598 }