1 /*
2  * Unit tests for the generic vPCI handler code.
3  *
4  * Copyright (C) 2017 Citrix Systems R&D
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms and conditions of the GNU General Public
8  * License, version 2, as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public
16  * License along with this program; If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #include "emul.h"
20 
21 /* Single vcpu (current), and single domain with a single PCI device. */
22 static struct vpci vpci;
23 
24 static struct domain d;
25 
26 const struct pci_dev test_pdev = {
27     .vpci = &vpci,
28 };
29 
30 const static struct vcpu v = {
31     .domain = &d
32 };
33 
34 const struct vcpu *current = &v;
35 
36 /* Dummy hooks, write stores data, read fetches it. */
vpci_read8(const struct pci_dev * pdev,unsigned int reg,void * data)37 static uint32_t vpci_read8(const struct pci_dev *pdev, unsigned int reg,
38                            void *data)
39 {
40     return *(uint8_t *)data;
41 }
42 
vpci_write8(const struct pci_dev * pdev,unsigned int reg,uint32_t val,void * data)43 static void vpci_write8(const struct pci_dev *pdev, unsigned int reg,
44                         uint32_t val, void *data)
45 {
46     *(uint8_t *)data = val;
47 }
48 
vpci_read16(const struct pci_dev * pdev,unsigned int reg,void * data)49 static uint32_t vpci_read16(const struct pci_dev *pdev, unsigned int reg,
50                             void *data)
51 {
52     return *(uint16_t *)data;
53 }
54 
vpci_write16(const struct pci_dev * pdev,unsigned int reg,uint32_t val,void * data)55 static void vpci_write16(const struct pci_dev *pdev, unsigned int reg,
56                          uint32_t val, void *data)
57 {
58     *(uint16_t *)data = val;
59 }
60 
vpci_read32(const struct pci_dev * pdev,unsigned int reg,void * data)61 static uint32_t vpci_read32(const struct pci_dev *pdev, unsigned int reg,
62                             void *data)
63 {
64     return *(uint32_t *)data;
65 }
66 
vpci_write32(const struct pci_dev * pdev,unsigned int reg,uint32_t val,void * data)67 static void vpci_write32(const struct pci_dev *pdev, unsigned int reg,
68                          uint32_t val, void *data)
69 {
70     *(uint32_t *)data = val;
71 }
72 
73 struct mask_data {
74     uint32_t val;
75     uint32_t rw1c_mask;
76 };
77 
vpci_read32_mask(const struct pci_dev * pdev,unsigned int reg,void * data)78 static uint32_t vpci_read32_mask(const struct pci_dev *pdev, unsigned int reg,
79                                  void *data)
80 {
81     const struct mask_data *md = data;
82 
83     return md->val;
84 }
85 
vpci_write32_mask(const struct pci_dev * pdev,unsigned int reg,uint32_t val,void * data)86 static void vpci_write32_mask(const struct pci_dev *pdev, unsigned int reg,
87                               uint32_t val, void *data)
88 {
89     struct mask_data *md = data;
90 
91     md->val  = val | (md->val & md->rw1c_mask);
92     md->val &= ~(val & md->rw1c_mask);
93 }
94 
95 #define VPCI_READ(reg, size, data) ({                           \
96     data = vpci_read((pci_sbdf_t){ .sbdf = 0 }, reg, size);     \
97 })
98 
99 #define VPCI_READ_CHECK(reg, size, expected) ({                 \
100     uint32_t rd;                                                \
101                                                                 \
102     VPCI_READ(reg, size, rd);                                   \
103     assert(rd == (expected));                                   \
104 })
105 
106 #define VPCI_WRITE(reg, size, data) ({                          \
107     vpci_write((pci_sbdf_t){ .sbdf = 0 }, reg, size, data);     \
108 })
109 
110 #define VPCI_WRITE_CHECK(reg, size, data) ({                    \
111     VPCI_WRITE(reg, size, data);                                \
112     VPCI_READ_CHECK(reg, size, data);                           \
113 })
114 
115 #define VPCI_ADD_REG(fread, fwrite, off, size, store)                       \
116     assert(!vpci_add_register(test_pdev.vpci, fread, fwrite, off, size,     \
117                               &store))
118 
119 #define VPCI_ADD_REG_MASK(fread, fwrite, off, size, store,                     \
120                           ro_mask, rw1c_mask, rsvdp_mask, rsvdz_mask)          \
121     assert(!vpci_add_register_mask(test_pdev.vpci, fread, fwrite, off, size,   \
122                                    &store,                                     \
123                                    ro_mask, rw1c_mask, rsvdp_mask, rsvdz_mask))
124 
125 #define VPCI_ADD_INVALID_REG(fread, fwrite, off, size)                      \
126     assert(vpci_add_register(test_pdev.vpci, fread, fwrite, off, size, NULL))
127 
128 #define VPCI_ADD_INVALID_REG_MASK(fread, fwrite, off, size,                   \
129                                   ro_mask, rw1c_mask, rsvdp_mask, rsvdz_mask) \
130     assert(vpci_add_register_mask(test_pdev.vpci, fread, fwrite, off, size,   \
131                                   NULL, ro_mask, rw1c_mask, rsvdp_mask,       \
132                                   rsvdz_mask))
133 
134 #define VPCI_REMOVE_REG(off, size)                                          \
135     assert(!vpci_remove_register(test_pdev.vpci, off, size))
136 
137 #define VPCI_REMOVE_INVALID_REG(off, size)                                  \
138     assert(vpci_remove_register(test_pdev.vpci, off, size))
139 
140 /* Read a 32b register using all possible sizes. */
multiread4_check(unsigned int reg,uint32_t val)141 void multiread4_check(unsigned int reg, uint32_t val)
142 {
143     unsigned int i;
144 
145     /* Read using bytes. */
146     for ( i = 0; i < 4; i++ )
147         VPCI_READ_CHECK(reg + i, 1, (val >> (i * 8)) & UINT8_MAX);
148 
149     /* Read using 2bytes. */
150     for ( i = 0; i < 2; i++ )
151         VPCI_READ_CHECK(reg + i * 2, 2, (val >> (i * 2 * 8)) & UINT16_MAX);
152 
153     VPCI_READ_CHECK(reg, 4, val);
154 }
155 
multiwrite4_check(unsigned int reg)156 void multiwrite4_check(unsigned int reg)
157 {
158     unsigned int i;
159     uint32_t val = 0xa2f51732;
160 
161     /* Write using bytes. */
162     for ( i = 0; i < 4; i++ )
163         VPCI_WRITE_CHECK(reg + i, 1, (val >> (i * 8)) & UINT8_MAX);
164     multiread4_check(reg, val);
165 
166     /* Change the value each time to be sure writes work fine. */
167     val = 0x2b836fda;
168     /* Write using 2bytes. */
169     for ( i = 0; i < 2; i++ )
170         VPCI_WRITE_CHECK(reg + i * 2, 2, (val >> (i * 2 * 8)) & UINT16_MAX);
171     multiread4_check(reg, val);
172 
173     val = 0xc4693beb;
174     VPCI_WRITE_CHECK(reg, 4, val);
175     multiread4_check(reg, val);
176 }
177 
178 int
main(int argc,char ** argv)179 main(int argc, char **argv)
180 {
181     /* Index storage by offset. */
182     uint32_t r0 = 0xdeadbeef;
183     uint8_t r5 = 0xef;
184     uint8_t r6 = 0xbe;
185     uint8_t r7 = 0xef;
186     uint16_t r12 = 0x8696;
187     uint8_t r16[4] = { };
188     uint16_t r20[2] = { };
189     uint32_t r24 = 0;
190     uint8_t r28, r30;
191     struct mask_data r32;
192     unsigned int i;
193     int rc;
194 
195     INIT_LIST_HEAD(&vpci.handlers);
196     spin_lock_init(&vpci.lock);
197 
198     VPCI_ADD_REG(vpci_read32, vpci_write32, 0, 4, r0);
199     VPCI_READ_CHECK(0, 4, r0);
200     VPCI_WRITE_CHECK(0, 4, 0xbcbcbcbc);
201 
202     VPCI_ADD_REG(vpci_read8, vpci_write8, 5, 1, r5);
203     VPCI_READ_CHECK(5, 1, r5);
204     VPCI_WRITE_CHECK(5, 1, 0xba);
205 
206     VPCI_ADD_REG(vpci_read8, vpci_write8, 6, 1, r6);
207     VPCI_READ_CHECK(6, 1, r6);
208     VPCI_WRITE_CHECK(6, 1, 0xba);
209 
210     VPCI_ADD_REG(vpci_read8, vpci_write8, 7, 1, r7);
211     VPCI_READ_CHECK(7, 1, r7);
212     VPCI_WRITE_CHECK(7, 1, 0xbd);
213 
214     VPCI_ADD_REG(vpci_read16, vpci_write16, 12, 2, r12);
215     VPCI_READ_CHECK(12, 2, r12);
216     VPCI_READ_CHECK(12, 4, 0xffff8696);
217 
218     /*
219      * At this point we have the following layout:
220      *
221      * Note that this refers to the position of the variables,
222      * but the value has already changed from the one given at
223      * initialization time because write tests have been performed.
224      *
225      * 32    24    16     8     0
226      *  +-----+-----+-----+-----+
227      *  |          r0           | 0
228      *  +-----+-----+-----+-----+
229      *  | r7  |  r6 |  r5 |/////| 32
230      *  +-----+-----+-----+-----|
231      *  |///////////////////////| 64
232      *  +-----------+-----------+
233      *  |///////////|    r12    | 96
234      *  +-----------+-----------+
235      *             ...
236      *  / = unhandled.
237      */
238 
239     /* Try to add an overlapping register handler. */
240     VPCI_ADD_INVALID_REG(vpci_read32, vpci_write32, 4, 4);
241 
242     /* Try to add a non-aligned register. */
243     VPCI_ADD_INVALID_REG(vpci_read16, vpci_write16, 15, 2);
244 
245     /* Try to add a register with wrong size. */
246     VPCI_ADD_INVALID_REG(vpci_read16, vpci_write16, 8, 3);
247 
248     /* Try to add a register with missing handlers. */
249     VPCI_ADD_INVALID_REG(NULL, NULL, 8, 2);
250 
251     /* Try to add registers with the same bits set in multiple masks. */
252     VPCI_ADD_INVALID_REG_MASK(vpci_read32, vpci_write32, 8, 4, 1, 1, 0, 0);
253     VPCI_ADD_INVALID_REG_MASK(vpci_read32, vpci_write32, 8, 4, 1, 0, 1, 0);
254     VPCI_ADD_INVALID_REG_MASK(vpci_read32, vpci_write32, 8, 4, 1, 0, 0, 1);
255     VPCI_ADD_INVALID_REG_MASK(vpci_read32, vpci_write32, 8, 4, 0, 1, 1, 0);
256     VPCI_ADD_INVALID_REG_MASK(vpci_read32, vpci_write32, 8, 4, 0, 1, 0, 1);
257     VPCI_ADD_INVALID_REG_MASK(vpci_read32, vpci_write32, 8, 4, 0, 0, 1, 1);
258 
259     /* Try to add registers with mask bits set beyond the register size */
260     VPCI_ADD_INVALID_REG_MASK(vpci_read8, vpci_write8, 8, 1, 0x100U, 0, 0, 0);
261     VPCI_ADD_INVALID_REG_MASK(vpci_read8, vpci_write8, 8, 1, 0, 0x100U, 0, 0);
262     VPCI_ADD_INVALID_REG_MASK(vpci_read8, vpci_write8, 8, 1, 0, 0, 0x100U, 0);
263     VPCI_ADD_INVALID_REG_MASK(vpci_read8, vpci_write8, 8, 1, 0, 0, 0, 0x100U);
264     VPCI_ADD_INVALID_REG_MASK(vpci_read16, vpci_write16, 8, 2, 0x10000U,0,0,0);
265     VPCI_ADD_INVALID_REG_MASK(vpci_read16, vpci_write16, 8, 2, 0,0x10000U,0,0);
266     VPCI_ADD_INVALID_REG_MASK(vpci_read16, vpci_write16, 8, 2, 0,0,0x10000U,0);
267     VPCI_ADD_INVALID_REG_MASK(vpci_read16, vpci_write16, 8, 2, 0,0,0,0x10000U);
268 
269     /* Read/write of unset register. */
270     VPCI_READ_CHECK(8, 4, 0xffffffff);
271     VPCI_READ_CHECK(8, 2, 0xffff);
272     VPCI_READ_CHECK(8, 1, 0xff);
273     VPCI_WRITE(10, 2, 0xbeef);
274     VPCI_READ_CHECK(10, 2, 0xffff);
275 
276     /* Read of multiple registers */
277     VPCI_WRITE_CHECK(7, 1, 0xbd);
278     VPCI_READ_CHECK(4, 4, 0xbdbabaff);
279 
280     /* Partial read of a register. */
281     VPCI_WRITE_CHECK(0, 4, 0x1a1b1c1d);
282     VPCI_READ_CHECK(2, 1, 0x1b);
283     VPCI_READ_CHECK(6, 2, 0xbdba);
284 
285     /* Write of multiple registers. */
286     VPCI_WRITE_CHECK(4, 4, 0xaabbccff);
287 
288     /* Partial write of a register. */
289     VPCI_WRITE_CHECK(2, 1, 0xfe);
290     VPCI_WRITE_CHECK(6, 2, 0xfebc);
291 
292     /*
293      * Test all possible read/write size combinations.
294      *
295      * Place 4 1B registers at 128bits (16B), 2 2B registers at 160bits
296      * (20B) and finally 1 4B register at 192bits (24B).
297      *
298      * Then perform all possible write and read sizes on each of them.
299      *
300      *               ...
301      * 32     24     16      8      0
302      *  +------+------+------+------+
303      *  |r16[3]|r16[2]|r16[1]|r16[0]| 16
304      *  +------+------+------+------+
305      *  |    r20[1]   |    r20[0]   | 20
306      *  +-------------+-------------|
307      *  |            r24            | 24
308      *  +-------------+-------------+
309      *
310      */
311     VPCI_ADD_REG(vpci_read8, vpci_write8, 16, 1, r16[0]);
312     VPCI_ADD_REG(vpci_read8, vpci_write8, 17, 1, r16[1]);
313     VPCI_ADD_REG(vpci_read8, vpci_write8, 18, 1, r16[2]);
314     VPCI_ADD_REG(vpci_read8, vpci_write8, 19, 1, r16[3]);
315 
316     VPCI_ADD_REG(vpci_read16, vpci_write16, 20, 2, r20[0]);
317     VPCI_ADD_REG(vpci_read16, vpci_write16, 22, 2, r20[1]);
318 
319     VPCI_ADD_REG(vpci_read32, vpci_write32, 24, 4, r24);
320 
321     /* Check the initial value is 0. */
322     multiread4_check(16, 0);
323     multiread4_check(20, 0);
324     multiread4_check(24, 0);
325 
326     multiwrite4_check(16);
327     multiwrite4_check(20);
328     multiwrite4_check(24);
329 
330     /*
331      * Check multiple non-consecutive gaps on the same read/write:
332      *
333      * 32     24     16      8      0
334      *  +------+------+------+------+
335      *  |//////|  r30 |//////|  r28 | 28
336      *  +------+------+------+------+
337      *
338      */
339     VPCI_ADD_REG(vpci_read8, vpci_write8, 28, 1, r28);
340     VPCI_ADD_REG(vpci_read8, vpci_write8, 30, 1, r30);
341     VPCI_WRITE_CHECK(28, 4, 0xffacffdc);
342 
343     /*
344      * Test ro/rw1c/rsvdp/rsvdz masks.
345      *
346      * 32     24     16      8      0
347      *  +------+------+------+------+
348      *  |rsvdz |rsvdp | rw1c |  ro  | 32
349      *  +------+------+------+------+
350      *
351      */
352     r32.rw1c_mask = 0x0000ff00U;
353     VPCI_ADD_REG_MASK(vpci_read32_mask, vpci_write32_mask, 32, 4, r32,
354                       0x000000ffU   /* RO    */,
355                       r32.rw1c_mask /* RW1C  */,
356                       0x00ff0000U   /* RsvdP */,
357                       0xff000000U   /* RsvdZ */);
358 
359     /* ro */
360     r32.val = 0x0f0f0f0fU;
361     VPCI_READ_CHECK(32, 1, 0x0f);
362     VPCI_WRITE(32, 1, 0x5a);
363     VPCI_READ_CHECK(32, 1, 0x0f);
364     assert(r32.val == 0x000f0f0fU);
365 
366     /* rw1c */
367     r32.val = 0x0f0f0f0fU;
368     VPCI_READ_CHECK(33, 1, 0x0f);
369     VPCI_WRITE(33, 1, 0x5a);
370     VPCI_READ_CHECK(33, 1, 0x05);
371     assert(r32.val == 0x000f050fU);
372 
373     /* rsvdp */
374     r32.val = 0x0f0f0f0fU;
375     VPCI_READ_CHECK(34, 1, 0);
376     VPCI_WRITE(34, 1, 0x5a);
377     VPCI_READ_CHECK(34, 1, 0);
378     assert(r32.val == 0x000f0f0fU);
379 
380     /* rsvdz */
381     r32.val = 0x0f0f0f0fU;
382     VPCI_READ_CHECK(35, 1, 0);
383     VPCI_WRITE(35, 1, 0x5a);
384     VPCI_READ_CHECK(35, 1, 0);
385     assert(r32.val == 0x000f0f0fU);
386 
387     /* write all 0's */
388     r32.val = 0x0f0f0f0fU;
389     VPCI_READ_CHECK(32, 4, 0x00000f0fU);
390     VPCI_WRITE(32, 4, 0);
391     VPCI_READ_CHECK(32, 4, 0x00000f0fU);
392     assert(r32.val == 0x000f0f0fU);
393 
394     /* write all 1's */
395     r32.val = 0x0f0f0f0fU;
396     VPCI_READ_CHECK(32, 4, 0x00000f0fU);
397     VPCI_WRITE(32, 4, 0xffffffffU);
398     VPCI_READ_CHECK(32, 4, 0x0000000fU);
399     assert(r32.val == 0x000f000fU);
400 
401     /* Finally try to remove a couple of registers. */
402     VPCI_REMOVE_REG(28, 1);
403     VPCI_REMOVE_REG(24, 4);
404     VPCI_REMOVE_REG(12, 2);
405 
406     VPCI_REMOVE_INVALID_REG(20, 1);
407     VPCI_REMOVE_INVALID_REG(16, 2);
408     VPCI_REMOVE_INVALID_REG(30, 2);
409 
410     return 0;
411 }
412 
413 /*
414  * Local variables:
415  * mode: C
416  * c-file-style: "BSD"
417  * c-basic-offset: 4
418  * indent-tabs-mode: nil
419  * End:
420  */
421