xref: /openbmc/qemu/tests/qtest/pnv-xive2-test.c (revision 6b829602e2f10f301ff8508f3a6850a0e913142c)
1*31bfbc00SFrederic Barrat /*
2*31bfbc00SFrederic Barrat  * QTest testcase for PowerNV 10 interrupt controller (xive2)
3*31bfbc00SFrederic Barrat  *  - Test irq to hardware thread
4*31bfbc00SFrederic Barrat  *  - Test 'Pull Thread Context to Odd Thread Reporting Line'
5*31bfbc00SFrederic Barrat  *
6*31bfbc00SFrederic Barrat  * Copyright (c) 2024, IBM Corporation.
7*31bfbc00SFrederic Barrat  *
8*31bfbc00SFrederic Barrat  * SPDX-License-Identifier: GPL-2.0-or-later
9*31bfbc00SFrederic Barrat  */
10*31bfbc00SFrederic Barrat #include "qemu/osdep.h"
11*31bfbc00SFrederic Barrat #include "libqtest.h"
12*31bfbc00SFrederic Barrat 
13*31bfbc00SFrederic Barrat #include "pnv-xive2-common.h"
14*31bfbc00SFrederic Barrat #include "hw/intc/pnv_xive2_regs.h"
15*31bfbc00SFrederic Barrat #include "hw/ppc/xive_regs.h"
16*31bfbc00SFrederic Barrat #include "hw/ppc/xive2_regs.h"
17*31bfbc00SFrederic Barrat 
18*31bfbc00SFrederic Barrat #define SMT                     4 /* some tests will break if less than 4 */
19*31bfbc00SFrederic Barrat 
20*31bfbc00SFrederic Barrat 
set_table(QTestState * qts,uint64_t type,uint64_t addr)21*31bfbc00SFrederic Barrat static void set_table(QTestState *qts, uint64_t type, uint64_t addr)
22*31bfbc00SFrederic Barrat {
23*31bfbc00SFrederic Barrat     uint64_t vsd, size, log_size;
24*31bfbc00SFrederic Barrat 
25*31bfbc00SFrederic Barrat     /*
26*31bfbc00SFrederic Barrat      * First, let's make sure that all the resources used fit in the
27*31bfbc00SFrederic Barrat      * given table.
28*31bfbc00SFrederic Barrat      */
29*31bfbc00SFrederic Barrat     switch (type) {
30*31bfbc00SFrederic Barrat     case VST_ESB:
31*31bfbc00SFrederic Barrat         size = MAX_IRQS / 4;
32*31bfbc00SFrederic Barrat         break;
33*31bfbc00SFrederic Barrat     case VST_EAS:
34*31bfbc00SFrederic Barrat         size = MAX_IRQS * 8;
35*31bfbc00SFrederic Barrat         break;
36*31bfbc00SFrederic Barrat     case VST_END:
37*31bfbc00SFrederic Barrat         size = MAX_ENDS * 32;
38*31bfbc00SFrederic Barrat         break;
39*31bfbc00SFrederic Barrat     case VST_NVP:
40*31bfbc00SFrederic Barrat     case VST_NVG:
41*31bfbc00SFrederic Barrat     case VST_NVC:
42*31bfbc00SFrederic Barrat         size = MAX_VPS * 32;
43*31bfbc00SFrederic Barrat         break;
44*31bfbc00SFrederic Barrat     case VST_SYNC:
45*31bfbc00SFrederic Barrat         size = 64 * 1024;
46*31bfbc00SFrederic Barrat         break;
47*31bfbc00SFrederic Barrat     default:
48*31bfbc00SFrederic Barrat         g_assert_not_reached();
49*31bfbc00SFrederic Barrat     }
50*31bfbc00SFrederic Barrat 
51*31bfbc00SFrederic Barrat     g_assert_cmpuint(size, <=, XIVE_VST_SIZE);
52*31bfbc00SFrederic Barrat     log_size = ctzl(XIVE_VST_SIZE) - 12;
53*31bfbc00SFrederic Barrat 
54*31bfbc00SFrederic Barrat     vsd = ((uint64_t) VSD_MODE_EXCLUSIVE) << 62 | addr | log_size;
55*31bfbc00SFrederic Barrat     pnv_xive_xscom_write(qts, X_VC_VSD_TABLE_ADDR, type << 48);
56*31bfbc00SFrederic Barrat     pnv_xive_xscom_write(qts, X_VC_VSD_TABLE_DATA, vsd);
57*31bfbc00SFrederic Barrat 
58*31bfbc00SFrederic Barrat     if (type != VST_EAS && type != VST_IC && type != VST_ERQ) {
59*31bfbc00SFrederic Barrat         pnv_xive_xscom_write(qts, X_PC_VSD_TABLE_ADDR, type << 48);
60*31bfbc00SFrederic Barrat         pnv_xive_xscom_write(qts, X_PC_VSD_TABLE_DATA, vsd);
61*31bfbc00SFrederic Barrat     }
62*31bfbc00SFrederic Barrat }
63*31bfbc00SFrederic Barrat 
set_tima8(QTestState * qts,uint32_t pir,uint32_t offset,uint8_t b)64*31bfbc00SFrederic Barrat static void set_tima8(QTestState *qts, uint32_t pir, uint32_t offset,
65*31bfbc00SFrederic Barrat                       uint8_t b)
66*31bfbc00SFrederic Barrat {
67*31bfbc00SFrederic Barrat     uint64_t ic_addr;
68*31bfbc00SFrederic Barrat 
69*31bfbc00SFrederic Barrat     ic_addr = XIVE_IC_TM_INDIRECT + (pir << XIVE_PAGE_SHIFT);
70*31bfbc00SFrederic Barrat     qtest_writeb(qts, ic_addr + offset, b);
71*31bfbc00SFrederic Barrat }
72*31bfbc00SFrederic Barrat 
set_tima32(QTestState * qts,uint32_t pir,uint32_t offset,uint32_t l)73*31bfbc00SFrederic Barrat static void set_tima32(QTestState *qts, uint32_t pir, uint32_t offset,
74*31bfbc00SFrederic Barrat                        uint32_t l)
75*31bfbc00SFrederic Barrat {
76*31bfbc00SFrederic Barrat     uint64_t ic_addr;
77*31bfbc00SFrederic Barrat 
78*31bfbc00SFrederic Barrat     ic_addr = XIVE_IC_TM_INDIRECT + (pir << XIVE_PAGE_SHIFT);
79*31bfbc00SFrederic Barrat     qtest_writel(qts, ic_addr + offset, l);
80*31bfbc00SFrederic Barrat }
81*31bfbc00SFrederic Barrat 
get_tima8(QTestState * qts,uint32_t pir,uint32_t offset)82*31bfbc00SFrederic Barrat static uint8_t get_tima8(QTestState *qts, uint32_t pir, uint32_t offset)
83*31bfbc00SFrederic Barrat {
84*31bfbc00SFrederic Barrat     uint64_t ic_addr;
85*31bfbc00SFrederic Barrat 
86*31bfbc00SFrederic Barrat     ic_addr = XIVE_IC_TM_INDIRECT + (pir << XIVE_PAGE_SHIFT);
87*31bfbc00SFrederic Barrat     return qtest_readb(qts, ic_addr + offset);
88*31bfbc00SFrederic Barrat }
89*31bfbc00SFrederic Barrat 
get_tima16(QTestState * qts,uint32_t pir,uint32_t offset)90*31bfbc00SFrederic Barrat static uint16_t get_tima16(QTestState *qts, uint32_t pir, uint32_t offset)
91*31bfbc00SFrederic Barrat {
92*31bfbc00SFrederic Barrat     uint64_t ic_addr;
93*31bfbc00SFrederic Barrat 
94*31bfbc00SFrederic Barrat     ic_addr = XIVE_IC_TM_INDIRECT + (pir << XIVE_PAGE_SHIFT);
95*31bfbc00SFrederic Barrat     return qtest_readw(qts, ic_addr + offset);
96*31bfbc00SFrederic Barrat }
97*31bfbc00SFrederic Barrat 
get_tima32(QTestState * qts,uint32_t pir,uint32_t offset)98*31bfbc00SFrederic Barrat static uint32_t get_tima32(QTestState *qts, uint32_t pir, uint32_t offset)
99*31bfbc00SFrederic Barrat {
100*31bfbc00SFrederic Barrat     uint64_t ic_addr;
101*31bfbc00SFrederic Barrat 
102*31bfbc00SFrederic Barrat     ic_addr = XIVE_IC_TM_INDIRECT + (pir << XIVE_PAGE_SHIFT);
103*31bfbc00SFrederic Barrat     return qtest_readl(qts, ic_addr + offset);
104*31bfbc00SFrederic Barrat }
105*31bfbc00SFrederic Barrat 
reset_pool_threads(QTestState * qts)106*31bfbc00SFrederic Barrat static void reset_pool_threads(QTestState *qts)
107*31bfbc00SFrederic Barrat {
108*31bfbc00SFrederic Barrat     uint8_t first_group = 0;
109*31bfbc00SFrederic Barrat     int i;
110*31bfbc00SFrederic Barrat 
111*31bfbc00SFrederic Barrat     for (i = 0; i < SMT; i++) {
112*31bfbc00SFrederic Barrat         uint32_t nvp_idx = 0x100 + i;
113*31bfbc00SFrederic Barrat         set_nvp(qts, nvp_idx, first_group);
114*31bfbc00SFrederic Barrat         set_tima32(qts, i, TM_QW2_HV_POOL + TM_WORD0, 0x000000ff);
115*31bfbc00SFrederic Barrat         set_tima32(qts, i, TM_QW2_HV_POOL + TM_WORD1, 0);
116*31bfbc00SFrederic Barrat         set_tima32(qts, i, TM_QW2_HV_POOL + TM_WORD2, TM_QW2W2_VP | nvp_idx);
117*31bfbc00SFrederic Barrat     }
118*31bfbc00SFrederic Barrat }
119*31bfbc00SFrederic Barrat 
reset_hw_threads(QTestState * qts)120*31bfbc00SFrederic Barrat static void reset_hw_threads(QTestState *qts)
121*31bfbc00SFrederic Barrat {
122*31bfbc00SFrederic Barrat     uint8_t first_group = 0;
123*31bfbc00SFrederic Barrat     uint32_t w1 = 0x000000ff;
124*31bfbc00SFrederic Barrat     int i;
125*31bfbc00SFrederic Barrat 
126*31bfbc00SFrederic Barrat     if (SMT >= 4) {
127*31bfbc00SFrederic Barrat         /* define 2 groups of 2, part of a bigger group of size 4 */
128*31bfbc00SFrederic Barrat         set_nvg(qts, 0x80, 0x02);
129*31bfbc00SFrederic Barrat         set_nvg(qts, 0x82, 0x02);
130*31bfbc00SFrederic Barrat         set_nvg(qts, 0x81, 0);
131*31bfbc00SFrederic Barrat         first_group = 0x01;
132*31bfbc00SFrederic Barrat         w1 = 0x000300ff;
133*31bfbc00SFrederic Barrat     }
134*31bfbc00SFrederic Barrat 
135*31bfbc00SFrederic Barrat     for (i = 0; i < SMT; i++) {
136*31bfbc00SFrederic Barrat         set_nvp(qts, 0x80 + i, first_group);
137*31bfbc00SFrederic Barrat         set_tima32(qts, i, TM_QW3_HV_PHYS + TM_WORD0, 0x00ff00ff);
138*31bfbc00SFrederic Barrat         set_tima32(qts, i, TM_QW3_HV_PHYS + TM_WORD1, w1);
139*31bfbc00SFrederic Barrat         set_tima32(qts, i, TM_QW3_HV_PHYS + TM_WORD2, 0x80000000);
140*31bfbc00SFrederic Barrat     }
141*31bfbc00SFrederic Barrat }
142*31bfbc00SFrederic Barrat 
reset_state(QTestState * qts)143*31bfbc00SFrederic Barrat static void reset_state(QTestState *qts)
144*31bfbc00SFrederic Barrat {
145*31bfbc00SFrederic Barrat     size_t mem_used = XIVE_MEM_END - XIVE_MEM_START;
146*31bfbc00SFrederic Barrat 
147*31bfbc00SFrederic Barrat     qtest_memset(qts, XIVE_MEM_START, 0, mem_used);
148*31bfbc00SFrederic Barrat     reset_hw_threads(qts);
149*31bfbc00SFrederic Barrat     reset_pool_threads(qts);
150*31bfbc00SFrederic Barrat }
151*31bfbc00SFrederic Barrat 
init_xive(QTestState * qts)152*31bfbc00SFrederic Barrat static void init_xive(QTestState *qts)
153*31bfbc00SFrederic Barrat {
154*31bfbc00SFrederic Barrat     uint64_t val1, val2, range;
155*31bfbc00SFrederic Barrat 
156*31bfbc00SFrederic Barrat     /*
157*31bfbc00SFrederic Barrat      * We can take a few shortcuts here, as we know the default values
158*31bfbc00SFrederic Barrat      * used for xive initialization
159*31bfbc00SFrederic Barrat      */
160*31bfbc00SFrederic Barrat 
161*31bfbc00SFrederic Barrat     /*
162*31bfbc00SFrederic Barrat      * Set the BARs.
163*31bfbc00SFrederic Barrat      * We reuse the same values used by firmware to ease debug.
164*31bfbc00SFrederic Barrat      */
165*31bfbc00SFrederic Barrat     pnv_xive_xscom_write(qts, X_CQ_IC_BAR, XIVE_IC_BAR);
166*31bfbc00SFrederic Barrat     pnv_xive_xscom_write(qts, X_CQ_TM_BAR, XIVE_TM_BAR);
167*31bfbc00SFrederic Barrat 
168*31bfbc00SFrederic Barrat     /* ESB and NVPG use 2 pages per resource. The others only one page */
169*31bfbc00SFrederic Barrat     range = (MAX_IRQS << 17) >> 25;
170*31bfbc00SFrederic Barrat     val1 = XIVE_ESB_BAR | range;
171*31bfbc00SFrederic Barrat     pnv_xive_xscom_write(qts, X_CQ_ESB_BAR, val1);
172*31bfbc00SFrederic Barrat 
173*31bfbc00SFrederic Barrat     range = (MAX_ENDS << 16) >> 25;
174*31bfbc00SFrederic Barrat     val1 = XIVE_END_BAR | range;
175*31bfbc00SFrederic Barrat     pnv_xive_xscom_write(qts, X_CQ_END_BAR, val1);
176*31bfbc00SFrederic Barrat 
177*31bfbc00SFrederic Barrat     range = (MAX_VPS << 17) >> 25;
178*31bfbc00SFrederic Barrat     val1 = XIVE_NVPG_BAR | range;
179*31bfbc00SFrederic Barrat     pnv_xive_xscom_write(qts, X_CQ_NVPG_BAR, val1);
180*31bfbc00SFrederic Barrat 
181*31bfbc00SFrederic Barrat     range = (MAX_VPS << 16) >> 25;
182*31bfbc00SFrederic Barrat     val1 = XIVE_NVC_BAR | range;
183*31bfbc00SFrederic Barrat     pnv_xive_xscom_write(qts, X_CQ_NVC_BAR, val1);
184*31bfbc00SFrederic Barrat 
185*31bfbc00SFrederic Barrat     /*
186*31bfbc00SFrederic Barrat      * Enable hw threads.
187*31bfbc00SFrederic Barrat      * We check the value written. Useless with current
188*31bfbc00SFrederic Barrat      * implementation, but it validates the xscom read path and it's
189*31bfbc00SFrederic Barrat      * what the hardware procedure says
190*31bfbc00SFrederic Barrat      */
191*31bfbc00SFrederic Barrat     val1 = 0xF000000000000000ull; /* core 0, 4 threads */
192*31bfbc00SFrederic Barrat     pnv_xive_xscom_write(qts, X_TCTXT_EN0, val1);
193*31bfbc00SFrederic Barrat     val2 = pnv_xive_xscom_read(qts, X_TCTXT_EN0);
194*31bfbc00SFrederic Barrat     g_assert_cmphex(val1, ==, val2);
195*31bfbc00SFrederic Barrat 
196*31bfbc00SFrederic Barrat     /* Memory tables */
197*31bfbc00SFrederic Barrat     set_table(qts, VST_ESB, XIVE_ESB_MEM);
198*31bfbc00SFrederic Barrat     set_table(qts, VST_EAS, XIVE_EAS_MEM);
199*31bfbc00SFrederic Barrat     set_table(qts, VST_END, XIVE_END_MEM);
200*31bfbc00SFrederic Barrat     set_table(qts, VST_NVP, XIVE_NVP_MEM);
201*31bfbc00SFrederic Barrat     set_table(qts, VST_NVG, XIVE_NVG_MEM);
202*31bfbc00SFrederic Barrat     set_table(qts, VST_NVC, XIVE_NVC_MEM);
203*31bfbc00SFrederic Barrat     set_table(qts, VST_SYNC, XIVE_SYNC_MEM);
204*31bfbc00SFrederic Barrat 
205*31bfbc00SFrederic Barrat     reset_hw_threads(qts);
206*31bfbc00SFrederic Barrat     reset_pool_threads(qts);
207*31bfbc00SFrederic Barrat }
208*31bfbc00SFrederic Barrat 
test_hw_irq(QTestState * qts)209*31bfbc00SFrederic Barrat static void test_hw_irq(QTestState *qts)
210*31bfbc00SFrederic Barrat {
211*31bfbc00SFrederic Barrat     uint32_t irq = 2;
212*31bfbc00SFrederic Barrat     uint32_t irq_data = 0x600df00d;
213*31bfbc00SFrederic Barrat     uint32_t end_index = 5;
214*31bfbc00SFrederic Barrat     uint32_t target_pir = 1;
215*31bfbc00SFrederic Barrat     uint32_t target_nvp = 0x80 + target_pir;
216*31bfbc00SFrederic Barrat     uint8_t priority = 5;
217*31bfbc00SFrederic Barrat     uint32_t reg32;
218*31bfbc00SFrederic Barrat     uint16_t reg16;
219*31bfbc00SFrederic Barrat     uint8_t pq, nsr, cppr;
220*31bfbc00SFrederic Barrat 
221*31bfbc00SFrederic Barrat     printf("# ============================================================\n");
222*31bfbc00SFrederic Barrat     printf("# Testing irq %d to hardware thread %d\n", irq, target_pir);
223*31bfbc00SFrederic Barrat 
224*31bfbc00SFrederic Barrat     /* irq config */
225*31bfbc00SFrederic Barrat     set_eas(qts, irq, end_index, irq_data);
226*31bfbc00SFrederic Barrat     set_end(qts, end_index, target_nvp, priority, false /* group */);
227*31bfbc00SFrederic Barrat 
228*31bfbc00SFrederic Barrat     /* enable and trigger irq */
229*31bfbc00SFrederic Barrat     get_esb(qts, irq, XIVE_EOI_PAGE, XIVE_ESB_SET_PQ_00);
230*31bfbc00SFrederic Barrat     set_esb(qts, irq, XIVE_TRIGGER_PAGE, 0, 0);
231*31bfbc00SFrederic Barrat 
232*31bfbc00SFrederic Barrat     /* check irq is raised on cpu */
233*31bfbc00SFrederic Barrat     pq = get_esb(qts, irq, XIVE_EOI_PAGE, XIVE_ESB_GET);
234*31bfbc00SFrederic Barrat     g_assert_cmpuint(pq, ==, XIVE_ESB_PENDING);
235*31bfbc00SFrederic Barrat 
236*31bfbc00SFrederic Barrat     reg32 = get_tima32(qts, target_pir, TM_QW3_HV_PHYS + TM_WORD0);
237*31bfbc00SFrederic Barrat     nsr = reg32 >> 24;
238*31bfbc00SFrederic Barrat     cppr = (reg32 >> 16) & 0xFF;
239*31bfbc00SFrederic Barrat     g_assert_cmphex(nsr, ==, 0x80);
240*31bfbc00SFrederic Barrat     g_assert_cmphex(cppr, ==, 0xFF);
241*31bfbc00SFrederic Barrat 
242*31bfbc00SFrederic Barrat     /* ack the irq */
243*31bfbc00SFrederic Barrat     reg16 = get_tima16(qts, target_pir, TM_SPC_ACK_HV_REG);
244*31bfbc00SFrederic Barrat     nsr = reg16 >> 8;
245*31bfbc00SFrederic Barrat     cppr = reg16 & 0xFF;
246*31bfbc00SFrederic Barrat     g_assert_cmphex(nsr, ==, 0x80);
247*31bfbc00SFrederic Barrat     g_assert_cmphex(cppr, ==, priority);
248*31bfbc00SFrederic Barrat 
249*31bfbc00SFrederic Barrat     /* check irq data is what was configured */
250*31bfbc00SFrederic Barrat     reg32 = qtest_readl(qts, xive_get_queue_addr(end_index));
251*31bfbc00SFrederic Barrat     g_assert_cmphex((reg32 & 0x7fffffff), ==, (irq_data & 0x7fffffff));
252*31bfbc00SFrederic Barrat 
253*31bfbc00SFrederic Barrat     /* End Of Interrupt */
254*31bfbc00SFrederic Barrat     set_esb(qts, irq, XIVE_EOI_PAGE, XIVE_ESB_STORE_EOI, 0);
255*31bfbc00SFrederic Barrat     pq = get_esb(qts, irq, XIVE_EOI_PAGE, XIVE_ESB_GET);
256*31bfbc00SFrederic Barrat     g_assert_cmpuint(pq, ==, XIVE_ESB_RESET);
257*31bfbc00SFrederic Barrat 
258*31bfbc00SFrederic Barrat     /* reset CPPR */
259*31bfbc00SFrederic Barrat     set_tima8(qts, target_pir, TM_QW3_HV_PHYS + TM_CPPR, 0xFF);
260*31bfbc00SFrederic Barrat     reg32 = get_tima32(qts, target_pir, TM_QW3_HV_PHYS + TM_WORD0);
261*31bfbc00SFrederic Barrat     nsr = reg32 >> 24;
262*31bfbc00SFrederic Barrat     cppr = (reg32 >> 16) & 0xFF;
263*31bfbc00SFrederic Barrat     g_assert_cmphex(nsr, ==, 0x00);
264*31bfbc00SFrederic Barrat     g_assert_cmphex(cppr, ==, 0xFF);
265*31bfbc00SFrederic Barrat }
266*31bfbc00SFrederic Barrat 
267*31bfbc00SFrederic Barrat #define XIVE_ODD_CL 0x80
test_pull_thread_ctx_to_odd_thread_cl(QTestState * qts)268*31bfbc00SFrederic Barrat static void test_pull_thread_ctx_to_odd_thread_cl(QTestState *qts)
269*31bfbc00SFrederic Barrat {
270*31bfbc00SFrederic Barrat     uint32_t target_pir = 1;
271*31bfbc00SFrederic Barrat     uint32_t target_nvp = 0x80 + target_pir;
272*31bfbc00SFrederic Barrat     Xive2Nvp nvp;
273*31bfbc00SFrederic Barrat     uint8_t cl_pair[XIVE_REPORT_SIZE];
274*31bfbc00SFrederic Barrat     uint32_t qw1w0, qw3w0, qw1w2, qw2w2;
275*31bfbc00SFrederic Barrat     uint8_t qw3b8;
276*31bfbc00SFrederic Barrat     uint32_t cl_word;
277*31bfbc00SFrederic Barrat     uint32_t word2;
278*31bfbc00SFrederic Barrat 
279*31bfbc00SFrederic Barrat     printf("# ============================================================\n");
280*31bfbc00SFrederic Barrat     printf("# Testing 'Pull Thread Context to Odd Thread Reporting Line'\n");
281*31bfbc00SFrederic Barrat 
282*31bfbc00SFrederic Barrat     /* clear odd cache line prior to pull operation */
283*31bfbc00SFrederic Barrat     memset(cl_pair, 0, sizeof(cl_pair));
284*31bfbc00SFrederic Barrat     get_nvp(qts, target_nvp, &nvp);
285*31bfbc00SFrederic Barrat     set_cl_pair(qts, &nvp, cl_pair);
286*31bfbc00SFrederic Barrat 
287*31bfbc00SFrederic Barrat     /* Read some values from TIMA that we expect to see in cacheline */
288*31bfbc00SFrederic Barrat     qw1w0 = get_tima32(qts, target_pir, TM_QW1_OS + TM_WORD0);
289*31bfbc00SFrederic Barrat     qw3w0 = get_tima32(qts, target_pir, TM_QW3_HV_PHYS + TM_WORD0);
290*31bfbc00SFrederic Barrat     qw1w2 = get_tima32(qts, target_pir, TM_QW1_OS + TM_WORD2);
291*31bfbc00SFrederic Barrat     qw2w2 = get_tima32(qts, target_pir, TM_QW2_HV_POOL + TM_WORD2);
292*31bfbc00SFrederic Barrat     qw3b8 = get_tima8(qts, target_pir, TM_QW3_HV_PHYS + TM_WORD2);
293*31bfbc00SFrederic Barrat 
294*31bfbc00SFrederic Barrat     /* Execute the pull operation */
295*31bfbc00SFrederic Barrat     set_tima8(qts, target_pir, TM_SPC_PULL_PHYS_CTX_OL, 0);
296*31bfbc00SFrederic Barrat 
297*31bfbc00SFrederic Barrat     /* Verify odd cache line values match TIMA after pull operation */
298*31bfbc00SFrederic Barrat     get_cl_pair(qts, &nvp, cl_pair);
299*31bfbc00SFrederic Barrat     memcpy(&cl_word, &cl_pair[XIVE_ODD_CL + TM_QW1_OS + TM_WORD0], 4);
300*31bfbc00SFrederic Barrat     g_assert_cmphex(qw1w0, ==, be32_to_cpu(cl_word));
301*31bfbc00SFrederic Barrat     memcpy(&cl_word, &cl_pair[XIVE_ODD_CL + TM_QW3_HV_PHYS + TM_WORD0], 4);
302*31bfbc00SFrederic Barrat     g_assert_cmphex(qw3w0, ==, be32_to_cpu(cl_word));
303*31bfbc00SFrederic Barrat     memcpy(&cl_word, &cl_pair[XIVE_ODD_CL + TM_QW1_OS + TM_WORD2], 4);
304*31bfbc00SFrederic Barrat     g_assert_cmphex(qw1w2, ==, be32_to_cpu(cl_word));
305*31bfbc00SFrederic Barrat     memcpy(&cl_word, &cl_pair[XIVE_ODD_CL + TM_QW2_HV_POOL + TM_WORD2], 4);
306*31bfbc00SFrederic Barrat     g_assert_cmphex(qw2w2, ==, be32_to_cpu(cl_word));
307*31bfbc00SFrederic Barrat     g_assert_cmphex(qw3b8, ==,
308*31bfbc00SFrederic Barrat                     cl_pair[XIVE_ODD_CL + TM_QW3_HV_PHYS + TM_WORD2]);
309*31bfbc00SFrederic Barrat 
310*31bfbc00SFrederic Barrat     /* Verify that all TIMA valid bits for target thread are cleared */
311*31bfbc00SFrederic Barrat     word2 = get_tima32(qts, target_pir, TM_QW1_OS + TM_WORD2);
312*31bfbc00SFrederic Barrat     g_assert_cmphex(xive_get_field32(TM_QW1W2_VO, word2), ==, 0);
313*31bfbc00SFrederic Barrat     word2 = get_tima32(qts, target_pir, TM_QW2_HV_POOL + TM_WORD2);
314*31bfbc00SFrederic Barrat     g_assert_cmphex(xive_get_field32(TM_QW2W2_VP, word2), ==, 0);
315*31bfbc00SFrederic Barrat     word2 = get_tima32(qts, target_pir, TM_QW3_HV_PHYS + TM_WORD2);
316*31bfbc00SFrederic Barrat     g_assert_cmphex(xive_get_field32(TM_QW3W2_VT, word2), ==, 0);
317*31bfbc00SFrederic Barrat }
test_xive(void)318*31bfbc00SFrederic Barrat static void test_xive(void)
319*31bfbc00SFrederic Barrat {
320*31bfbc00SFrederic Barrat     QTestState *qts;
321*31bfbc00SFrederic Barrat 
322*31bfbc00SFrederic Barrat     qts = qtest_initf("-M powernv10 -smp %d,cores=1,threads=%d -nographic "
323*31bfbc00SFrederic Barrat                       "-nodefaults -serial mon:stdio -S "
324*31bfbc00SFrederic Barrat                       "-d guest_errors -trace '*xive*'",
325*31bfbc00SFrederic Barrat                       SMT, SMT);
326*31bfbc00SFrederic Barrat     init_xive(qts);
327*31bfbc00SFrederic Barrat 
328*31bfbc00SFrederic Barrat     test_hw_irq(qts);
329*31bfbc00SFrederic Barrat 
330*31bfbc00SFrederic Barrat     /* omit reset_state here and use settings from test_hw_irq */
331*31bfbc00SFrederic Barrat     test_pull_thread_ctx_to_odd_thread_cl(qts);
332*31bfbc00SFrederic Barrat 
333*31bfbc00SFrederic Barrat     reset_state(qts);
334*31bfbc00SFrederic Barrat     test_flush_sync_inject(qts);
335*31bfbc00SFrederic Barrat 
336*31bfbc00SFrederic Barrat     qtest_quit(qts);
337*31bfbc00SFrederic Barrat }
338*31bfbc00SFrederic Barrat 
main(int argc,char ** argv)339*31bfbc00SFrederic Barrat int main(int argc, char **argv)
340*31bfbc00SFrederic Barrat {
341*31bfbc00SFrederic Barrat     g_test_init(&argc, &argv, NULL);
342*31bfbc00SFrederic Barrat     qtest_add_func("xive2", test_xive);
343*31bfbc00SFrederic Barrat     return g_test_run();
344*31bfbc00SFrederic Barrat }
345