1 /*
2 * QTest testcase for PowerNV 10 interrupt controller (xive2)
3 * - Common functions for XIVE2 tests
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
14
pnv_xscom_addr(uint32_t pcba)15 static uint64_t pnv_xscom_addr(uint32_t pcba)
16 {
17 return P10_XSCOM_BASE | ((uint64_t) pcba << 3);
18 }
19
pnv_xive_xscom_addr(uint32_t reg)20 static uint64_t pnv_xive_xscom_addr(uint32_t reg)
21 {
22 return pnv_xscom_addr(XIVE_XSCOM + reg);
23 }
24
pnv_xive_xscom_read(QTestState * qts,uint32_t reg)25 uint64_t pnv_xive_xscom_read(QTestState *qts, uint32_t reg)
26 {
27 return qtest_readq(qts, pnv_xive_xscom_addr(reg));
28 }
29
pnv_xive_xscom_write(QTestState * qts,uint32_t reg,uint64_t val)30 void pnv_xive_xscom_write(QTestState *qts, uint32_t reg, uint64_t val)
31 {
32 qtest_writeq(qts, pnv_xive_xscom_addr(reg), val);
33 }
34
xive_get_struct(QTestState * qts,uint64_t src,void * dest,size_t size)35 static void xive_get_struct(QTestState *qts, uint64_t src, void *dest,
36 size_t size)
37 {
38 uint8_t *destination = (uint8_t *)dest;
39 size_t i;
40
41 for (i = 0; i < size; i++) {
42 *(destination + i) = qtest_readb(qts, src + i);
43 }
44 }
45
xive_copy_struct(QTestState * qts,void * src,uint64_t dest,size_t size)46 static void xive_copy_struct(QTestState *qts, void *src, uint64_t dest,
47 size_t size)
48 {
49 uint8_t *source = (uint8_t *)src;
50 size_t i;
51
52 for (i = 0; i < size; i++) {
53 qtest_writeb(qts, dest + i, *(source + i));
54 }
55 }
56
xive_get_queue_addr(uint32_t end_index)57 uint64_t xive_get_queue_addr(uint32_t end_index)
58 {
59 return XIVE_QUEUE_MEM + (uint64_t)end_index * XIVE_QUEUE_SIZE;
60 }
61
get_esb(QTestState * qts,uint32_t index,uint8_t page,uint32_t offset)62 uint8_t get_esb(QTestState *qts, uint32_t index, uint8_t page,
63 uint32_t offset)
64 {
65 uint64_t addr;
66
67 addr = XIVE_ESB_ADDR + ((uint64_t)index << (XIVE_PAGE_SHIFT + 1));
68 if (page == 1) {
69 addr += 1 << XIVE_PAGE_SHIFT;
70 }
71 return qtest_readb(qts, addr + offset);
72 }
73
set_esb(QTestState * qts,uint32_t index,uint8_t page,uint32_t offset,uint32_t val)74 void set_esb(QTestState *qts, uint32_t index, uint8_t page,
75 uint32_t offset, uint32_t val)
76 {
77 uint64_t addr;
78
79 addr = XIVE_ESB_ADDR + ((uint64_t)index << (XIVE_PAGE_SHIFT + 1));
80 if (page == 1) {
81 addr += 1 << XIVE_PAGE_SHIFT;
82 }
83 return qtest_writel(qts, addr + offset, cpu_to_be32(val));
84 }
85
get_nvp(QTestState * qts,uint32_t index,Xive2Nvp * nvp)86 void get_nvp(QTestState *qts, uint32_t index, Xive2Nvp* nvp)
87 {
88 uint64_t addr = XIVE_NVP_MEM + (uint64_t)index * sizeof(Xive2Nvp);
89 xive_get_struct(qts, addr, nvp, sizeof(Xive2Nvp));
90 }
91
set_nvp(QTestState * qts,uint32_t index,uint8_t first)92 void set_nvp(QTestState *qts, uint32_t index, uint8_t first)
93 {
94 uint64_t nvp_addr;
95 Xive2Nvp nvp;
96 uint64_t report_addr;
97
98 nvp_addr = XIVE_NVP_MEM + (uint64_t)index * sizeof(Xive2Nvp);
99 report_addr = (XIVE_REPORT_MEM + (uint64_t)index * XIVE_REPORT_SIZE) >> 8;
100
101 memset(&nvp, 0, sizeof(nvp));
102 nvp.w0 = xive_set_field32(NVP2_W0_VALID, 0, 1);
103 nvp.w0 = xive_set_field32(NVP2_W0_PGOFIRST, nvp.w0, first);
104 nvp.w6 = xive_set_field32(NVP2_W6_REPORTING_LINE, nvp.w6,
105 (report_addr >> 24) & 0xfffffff);
106 nvp.w7 = xive_set_field32(NVP2_W7_REPORTING_LINE, nvp.w7,
107 report_addr & 0xffffff);
108 xive_copy_struct(qts, &nvp, nvp_addr, sizeof(nvp));
109 }
110
get_cl_pair_addr(Xive2Nvp * nvp)111 static uint64_t get_cl_pair_addr(Xive2Nvp *nvp)
112 {
113 uint64_t upper = xive_get_field32(0x0fffffff, nvp->w6);
114 uint64_t lower = xive_get_field32(0xffffff00, nvp->w7);
115 return (upper << 32) | (lower << 8);
116 }
117
get_cl_pair(QTestState * qts,Xive2Nvp * nvp,uint8_t * cl_pair)118 void get_cl_pair(QTestState *qts, Xive2Nvp *nvp, uint8_t *cl_pair)
119 {
120 uint64_t addr = get_cl_pair_addr(nvp);
121 xive_get_struct(qts, addr, cl_pair, XIVE_REPORT_SIZE);
122 }
123
set_cl_pair(QTestState * qts,Xive2Nvp * nvp,uint8_t * cl_pair)124 void set_cl_pair(QTestState *qts, Xive2Nvp *nvp, uint8_t *cl_pair)
125 {
126 uint64_t addr = get_cl_pair_addr(nvp);
127 xive_copy_struct(qts, cl_pair, addr, XIVE_REPORT_SIZE);
128 }
129
set_nvg(QTestState * qts,uint32_t index,uint8_t next)130 void set_nvg(QTestState *qts, uint32_t index, uint8_t next)
131 {
132 uint64_t nvg_addr;
133 Xive2Nvgc nvg;
134
135 nvg_addr = XIVE_NVG_MEM + (uint64_t)index * sizeof(Xive2Nvgc);
136
137 memset(&nvg, 0, sizeof(nvg));
138 nvg.w0 = xive_set_field32(NVGC2_W0_VALID, 0, 1);
139 nvg.w0 = xive_set_field32(NVGC2_W0_PGONEXT, nvg.w0, next);
140 xive_copy_struct(qts, &nvg, nvg_addr, sizeof(nvg));
141 }
142
set_eas(QTestState * qts,uint32_t index,uint32_t end_index,uint32_t data)143 void set_eas(QTestState *qts, uint32_t index, uint32_t end_index,
144 uint32_t data)
145 {
146 uint64_t eas_addr;
147 Xive2Eas eas;
148
149 eas_addr = XIVE_EAS_MEM + (uint64_t)index * sizeof(Xive2Eas);
150
151 memset(&eas, 0, sizeof(eas));
152 eas.w = xive_set_field64(EAS2_VALID, 0, 1);
153 eas.w = xive_set_field64(EAS2_END_INDEX, eas.w, end_index);
154 eas.w = xive_set_field64(EAS2_END_DATA, eas.w, data);
155 xive_copy_struct(qts, &eas, eas_addr, sizeof(eas));
156 }
157
set_end(QTestState * qts,uint32_t index,uint32_t nvp_index,uint8_t priority,bool i)158 void set_end(QTestState *qts, uint32_t index, uint32_t nvp_index,
159 uint8_t priority, bool i)
160 {
161 uint64_t end_addr, queue_addr, queue_hi, queue_lo;
162 uint8_t queue_size;
163 Xive2End end;
164
165 end_addr = XIVE_END_MEM + (uint64_t)index * sizeof(Xive2End);
166 queue_addr = xive_get_queue_addr(index);
167 queue_hi = (queue_addr >> 32) & END2_W2_EQ_ADDR_HI;
168 queue_lo = queue_addr & END2_W3_EQ_ADDR_LO;
169 queue_size = ctz16(XIVE_QUEUE_SIZE) - 12;
170
171 memset(&end, 0, sizeof(end));
172 end.w0 = xive_set_field32(END2_W0_VALID, 0, 1);
173 end.w0 = xive_set_field32(END2_W0_ENQUEUE, end.w0, 1);
174 end.w0 = xive_set_field32(END2_W0_UCOND_NOTIFY, end.w0, 1);
175 end.w0 = xive_set_field32(END2_W0_BACKLOG, end.w0, 1);
176
177 end.w1 = xive_set_field32(END2_W1_GENERATION, 0, 1);
178
179 end.w2 = cpu_to_be32(queue_hi);
180
181 end.w3 = cpu_to_be32(queue_lo);
182 end.w3 = xive_set_field32(END2_W3_QSIZE, end.w3, queue_size);
183
184 end.w6 = xive_set_field32(END2_W6_IGNORE, 0, i);
185 end.w6 = xive_set_field32(END2_W6_VP_OFFSET, end.w6, nvp_index);
186
187 end.w7 = xive_set_field32(END2_W7_F0_PRIORITY, 0, priority);
188 xive_copy_struct(qts, &end, end_addr, sizeof(end));
189 }
190
191