xref: /qemu/tests/qtest/libqos/pci.c (revision 1405d7e60d8c98a28b29885f70da4f2e4407fbc6)
1 /*
2  * libqos PCI bindings
3  *
4  * Copyright IBM, Corp. 2012-2013
5  *
6  * Authors:
7  *  Anthony Liguori   <aliguori@us.ibm.com>
8  *
9  * This work is licensed under the terms of the GNU GPL, version 2 or later.
10  * See the COPYING file in the top-level directory.
11  */
12 
13 #include "qemu/osdep.h"
14 #include "pci.h"
15 
16 #include "hw/pci/pci.h"
17 #include "hw/pci/pci_bridge.h"
18 #include "hw/pci/pci_regs.h"
19 #include "qemu/host-utils.h"
20 #include "qgraph.h"
21 
22 void qpci_device_foreach(QPCIBus *bus, int vendor_id, int device_id,
23                          void (*func)(QPCIDevice *dev, int devfn, void *data),
24                          void *data)
25 {
26     int slot;
27 
28     for (slot = 0; slot < 32; slot++) {
29         int fn;
30 
31         for (fn = 0; fn < 8; fn++) {
32             QPCIDevice *dev;
33 
34             dev = qpci_device_find(bus, QPCI_DEVFN(slot, fn));
35             if (!dev) {
36                 continue;
37             }
38 
39             if (vendor_id != -1 &&
40                 qpci_config_readw(dev, PCI_VENDOR_ID) != vendor_id) {
41                 g_free(dev);
42                 continue;
43             }
44 
45             if (device_id != -1 &&
46                 qpci_config_readw(dev, PCI_DEVICE_ID) != device_id) {
47                 g_free(dev);
48                 continue;
49             }
50 
51             func(dev, QPCI_DEVFN(slot, fn), data);
52         }
53     }
54 }
55 
56 bool qpci_has_buggy_msi(QPCIDevice *dev)
57 {
58     return dev->bus->has_buggy_msi;
59 }
60 
61 bool qpci_check_buggy_msi(QPCIDevice *dev)
62 {
63     if (qpci_has_buggy_msi(dev)) {
64         g_test_skip("Skipping due to incomplete support for MSI");
65         return true;
66     }
67     return false;
68 }
69 
70 static void qpci_device_set(QPCIDevice *dev, QPCIBus *bus, int devfn)
71 {
72     g_assert(dev);
73 
74     dev->bus = bus;
75     dev->devfn = devfn;
76 }
77 
78 QPCIDevice *qpci_device_find(QPCIBus *bus, int devfn)
79 {
80     QPCIDevice *dev;
81 
82     dev = g_malloc0(sizeof(*dev));
83     qpci_device_set(dev, bus, devfn);
84 
85     if (qpci_config_readw(dev, PCI_VENDOR_ID) == 0xFFFF) {
86         g_free(dev);
87         return NULL;
88     }
89 
90     return dev;
91 }
92 
93 void qpci_device_init(QPCIDevice *dev, QPCIBus *bus, QPCIAddress *addr)
94 {
95     uint16_t vendor_id, device_id;
96 
97     qpci_device_set(dev, bus, addr->devfn);
98     vendor_id = qpci_config_readw(dev, PCI_VENDOR_ID);
99     device_id = qpci_config_readw(dev, PCI_DEVICE_ID);
100     g_assert(!addr->vendor_id || vendor_id == addr->vendor_id);
101     g_assert(!addr->device_id || device_id == addr->device_id);
102 }
103 
104 static uint8_t qpci_find_resource_reserve_capability(QPCIDevice *dev)
105 {
106     uint16_t device_id;
107     uint8_t cap = 0;
108 
109     if (qpci_config_readw(dev, PCI_VENDOR_ID) != PCI_VENDOR_ID_REDHAT) {
110         return 0;
111     }
112 
113     device_id = qpci_config_readw(dev, PCI_DEVICE_ID);
114 
115     if (device_id != PCI_DEVICE_ID_REDHAT_PCIE_RP &&
116         device_id != PCI_DEVICE_ID_REDHAT_BRIDGE) {
117         return 0;
118     }
119 
120     do {
121         cap = qpci_find_capability(dev, PCI_CAP_ID_VNDR, cap);
122     } while (cap &&
123              qpci_config_readb(dev, cap + REDHAT_PCI_CAP_TYPE_OFFSET) !=
124              REDHAT_PCI_CAP_RESOURCE_RESERVE);
125     if (cap) {
126         uint8_t cap_len = qpci_config_readb(dev, cap + PCI_CAP_FLAGS);
127         if (cap_len < REDHAT_PCI_CAP_RES_RESERVE_CAP_SIZE) {
128             return 0;
129         }
130     }
131     return cap;
132 }
133 
134 static void qpci_secondary_buses_rec(QPCIBus *qbus, int bus, int *pci_bus)
135 {
136     QPCIDevice *dev;
137     uint16_t class;
138     uint8_t pribus, secbus, subbus;
139     int index;
140 
141     for (index = 0; index < 32; index++) {
142         dev = qpci_device_find(qbus, QPCI_DEVFN(bus + index, 0));
143         if (dev == NULL) {
144             continue;
145         }
146         class = qpci_config_readw(dev, PCI_CLASS_DEVICE);
147         if (class == PCI_CLASS_BRIDGE_PCI) {
148             qpci_config_writeb(dev, PCI_SECONDARY_BUS, 255);
149             qpci_config_writeb(dev, PCI_SUBORDINATE_BUS, 0);
150         }
151         g_free(dev);
152     }
153 
154     for (index = 0; index < 32; index++) {
155         dev = qpci_device_find(qbus, QPCI_DEVFN(bus + index, 0));
156         if (dev == NULL) {
157             continue;
158         }
159         class = qpci_config_readw(dev, PCI_CLASS_DEVICE);
160         if (class != PCI_CLASS_BRIDGE_PCI) {
161             g_free(dev);
162             continue;
163         }
164 
165         pribus = qpci_config_readb(dev, PCI_PRIMARY_BUS);
166         if (pribus != bus) {
167             qpci_config_writeb(dev, PCI_PRIMARY_BUS, bus);
168         }
169 
170         secbus = qpci_config_readb(dev, PCI_SECONDARY_BUS);
171         (*pci_bus)++;
172         if (*pci_bus != secbus) {
173             secbus = *pci_bus;
174             qpci_config_writeb(dev, PCI_SECONDARY_BUS, secbus);
175         }
176 
177         subbus = qpci_config_readb(dev, PCI_SUBORDINATE_BUS);
178         qpci_config_writeb(dev, PCI_SUBORDINATE_BUS, 255);
179 
180         qpci_secondary_buses_rec(qbus, secbus << 5, pci_bus);
181 
182         if (subbus != *pci_bus) {
183             uint8_t res_bus = *pci_bus;
184             uint8_t cap = qpci_find_resource_reserve_capability(dev);
185 
186             if (cap) {
187                 uint32_t tmp_res_bus;
188 
189                 tmp_res_bus = qpci_config_readl(dev, cap +
190                                             REDHAT_PCI_CAP_RES_RESERVE_BUS_RES);
191                 if (tmp_res_bus != (uint32_t)-1) {
192                     res_bus = tmp_res_bus & 0xFF;
193                     if ((uint8_t)(res_bus + secbus) < secbus ||
194                         (uint8_t)(res_bus + secbus) < res_bus) {
195                         res_bus = 0;
196                     }
197                     if (secbus + res_bus > *pci_bus) {
198                         res_bus = secbus + res_bus;
199                     }
200                 }
201             }
202             subbus = res_bus;
203             *pci_bus = res_bus;
204         }
205 
206         qpci_config_writeb(dev, PCI_SUBORDINATE_BUS, subbus);
207         g_free(dev);
208     }
209 }
210 
211 int qpci_secondary_buses_init(QPCIBus *bus)
212 {
213     int last_bus = 0;
214 
215     qpci_secondary_buses_rec(bus, 0, &last_bus);
216 
217     return last_bus;
218 }
219 
220 
221 void qpci_device_enable(QPCIDevice *dev)
222 {
223     uint16_t cmd;
224 
225     /* FIXME -- does this need to be a bus callout? */
226     cmd = qpci_config_readw(dev, PCI_COMMAND);
227     cmd |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
228     qpci_config_writew(dev, PCI_COMMAND, cmd);
229 
230     /* Verify the bits are now set. */
231     cmd = qpci_config_readw(dev, PCI_COMMAND);
232     g_assert_cmphex(cmd & PCI_COMMAND_IO, ==, PCI_COMMAND_IO);
233     g_assert_cmphex(cmd & PCI_COMMAND_MEMORY, ==, PCI_COMMAND_MEMORY);
234     g_assert_cmphex(cmd & PCI_COMMAND_MASTER, ==, PCI_COMMAND_MASTER);
235 }
236 
237 /**
238  * qpci_find_capability:
239  * @dev: the PCI device
240  * @id: the PCI Capability ID (PCI_CAP_ID_*)
241  * @start_addr: 0 to begin iteration or the last return value to continue
242  *              iteration
243  *
244  * Iterate over the PCI Capabilities List.
245  *
246  * Returns: PCI Configuration Space offset of the capabililty structure or
247  *          0 if no further matching capability is found
248  */
249 uint8_t qpci_find_capability(QPCIDevice *dev, uint8_t id, uint8_t start_addr)
250 {
251     uint8_t cap;
252     uint8_t addr;
253 
254     if (start_addr) {
255         addr = qpci_config_readb(dev, start_addr + PCI_CAP_LIST_NEXT);
256     } else {
257         addr = qpci_config_readb(dev, PCI_CAPABILITY_LIST);
258     }
259 
260     do {
261         cap = qpci_config_readb(dev, addr);
262         if (cap != id) {
263             addr = qpci_config_readb(dev, addr + PCI_CAP_LIST_NEXT);
264         }
265     } while (cap != id && addr != 0);
266 
267     return addr;
268 }
269 
270 void qpci_msix_enable(QPCIDevice *dev)
271 {
272     uint8_t addr;
273     uint16_t val;
274     uint32_t table;
275     uint8_t bir_table;
276     uint8_t bir_pba;
277 
278     addr = qpci_find_capability(dev, PCI_CAP_ID_MSIX, 0);
279     g_assert_cmphex(addr, !=, 0);
280 
281     val = qpci_config_readw(dev, addr + PCI_MSIX_FLAGS);
282     qpci_config_writew(dev, addr + PCI_MSIX_FLAGS, val | PCI_MSIX_FLAGS_ENABLE);
283 
284     table = qpci_config_readl(dev, addr + PCI_MSIX_TABLE);
285     bir_table = table & PCI_MSIX_FLAGS_BIRMASK;
286     dev->msix_table_bar = qpci_iomap(dev, bir_table, NULL);
287     dev->msix_table_off = table & ~PCI_MSIX_FLAGS_BIRMASK;
288 
289     table = qpci_config_readl(dev, addr + PCI_MSIX_PBA);
290     bir_pba = table & PCI_MSIX_FLAGS_BIRMASK;
291     if (bir_pba != bir_table) {
292         dev->msix_pba_bar = qpci_iomap(dev, bir_pba, NULL);
293     } else {
294         dev->msix_pba_bar = dev->msix_table_bar;
295     }
296     dev->msix_pba_off = table & ~PCI_MSIX_FLAGS_BIRMASK;
297 
298     dev->msix_enabled = true;
299 }
300 
301 void qpci_msix_disable(QPCIDevice *dev)
302 {
303     uint8_t addr;
304     uint16_t val;
305 
306     g_assert(dev->msix_enabled);
307     addr = qpci_find_capability(dev, PCI_CAP_ID_MSIX, 0);
308     g_assert_cmphex(addr, !=, 0);
309     val = qpci_config_readw(dev, addr + PCI_MSIX_FLAGS);
310     qpci_config_writew(dev, addr + PCI_MSIX_FLAGS,
311                                                 val & ~PCI_MSIX_FLAGS_ENABLE);
312 
313     if (dev->msix_pba_bar.addr != dev->msix_table_bar.addr) {
314         qpci_iounmap(dev, dev->msix_pba_bar);
315     }
316     qpci_iounmap(dev, dev->msix_table_bar);
317 
318     dev->msix_enabled = 0;
319     dev->msix_table_off = 0;
320     dev->msix_pba_off = 0;
321 }
322 
323 bool qpci_msix_pending(QPCIDevice *dev, uint16_t entry)
324 {
325     uint32_t pba_entry;
326     uint8_t bit_n = entry % 32;
327     uint64_t  off = (entry / 32) * PCI_MSIX_ENTRY_SIZE / 4;
328 
329     g_assert(dev->msix_enabled);
330     pba_entry = qpci_io_readl(dev, dev->msix_pba_bar, dev->msix_pba_off + off);
331     return (pba_entry & (1 << bit_n)) != 0;
332 }
333 
334 bool qpci_msix_masked(QPCIDevice *dev, uint16_t entry)
335 {
336     uint8_t addr;
337     uint16_t val;
338     uint64_t vector_off = dev->msix_table_off + entry * PCI_MSIX_ENTRY_SIZE;
339 
340     g_assert(dev->msix_enabled);
341     addr = qpci_find_capability(dev, PCI_CAP_ID_MSIX, 0);
342     g_assert_cmphex(addr, !=, 0);
343     val = qpci_config_readw(dev, addr + PCI_MSIX_FLAGS);
344 
345     if (val & PCI_MSIX_FLAGS_MASKALL) {
346         return true;
347     } else {
348         return (qpci_io_readl(dev, dev->msix_table_bar,
349                               vector_off + PCI_MSIX_ENTRY_VECTOR_CTRL)
350                 & PCI_MSIX_ENTRY_CTRL_MASKBIT) != 0;
351     }
352 }
353 
354 uint16_t qpci_msix_table_size(QPCIDevice *dev)
355 {
356     uint8_t addr;
357     uint16_t control;
358 
359     addr = qpci_find_capability(dev, PCI_CAP_ID_MSIX, 0);
360     g_assert_cmphex(addr, !=, 0);
361 
362     control = qpci_config_readw(dev, addr + PCI_MSIX_FLAGS);
363     return (control & PCI_MSIX_FLAGS_QSIZE) + 1;
364 }
365 
366 uint8_t qpci_config_readb(QPCIDevice *dev, uint8_t offset)
367 {
368     return dev->bus->config_readb(dev->bus, dev->devfn, offset);
369 }
370 
371 uint16_t qpci_config_readw(QPCIDevice *dev, uint8_t offset)
372 {
373     return dev->bus->config_readw(dev->bus, dev->devfn, offset);
374 }
375 
376 uint32_t qpci_config_readl(QPCIDevice *dev, uint8_t offset)
377 {
378     return dev->bus->config_readl(dev->bus, dev->devfn, offset);
379 }
380 
381 
382 void qpci_config_writeb(QPCIDevice *dev, uint8_t offset, uint8_t value)
383 {
384     dev->bus->config_writeb(dev->bus, dev->devfn, offset, value);
385 }
386 
387 void qpci_config_writew(QPCIDevice *dev, uint8_t offset, uint16_t value)
388 {
389     dev->bus->config_writew(dev->bus, dev->devfn, offset, value);
390 }
391 
392 void qpci_config_writel(QPCIDevice *dev, uint8_t offset, uint32_t value)
393 {
394     dev->bus->config_writel(dev->bus, dev->devfn, offset, value);
395 }
396 
397 uint8_t qpci_io_readb(QPCIDevice *dev, QPCIBar token, uint64_t off)
398 {
399     QPCIBus *bus = dev->bus;
400 
401     if (token.is_io) {
402         return bus->pio_readb(bus, token.addr + off);
403     } else {
404         uint8_t val;
405 
406         bus->memread(dev->bus, token.addr + off, &val, sizeof(val));
407         return val;
408     }
409 }
410 
411 uint16_t qpci_io_readw(QPCIDevice *dev, QPCIBar token, uint64_t off)
412 {
413     QPCIBus *bus = dev->bus;
414 
415     if (token.is_io) {
416         return bus->pio_readw(bus, token.addr + off);
417     } else {
418         uint16_t val;
419 
420         bus->memread(bus, token.addr + off, &val, sizeof(val));
421         return le16_to_cpu(val);
422     }
423 }
424 
425 uint32_t qpci_io_readl(QPCIDevice *dev, QPCIBar token, uint64_t off)
426 {
427     QPCIBus *bus = dev->bus;
428 
429     if (token.is_io) {
430         return bus->pio_readl(bus, token.addr + off);
431     } else {
432         uint32_t val;
433 
434         bus->memread(dev->bus, token.addr + off, &val, sizeof(val));
435         return le32_to_cpu(val);
436     }
437 }
438 
439 uint64_t qpci_io_readq(QPCIDevice *dev, QPCIBar token, uint64_t off)
440 {
441     QPCIBus *bus = dev->bus;
442 
443     if (token.is_io) {
444         return bus->pio_readq(bus, token.addr + off);
445     } else {
446         uint64_t val;
447 
448         bus->memread(bus, token.addr + off, &val, sizeof(val));
449         return le64_to_cpu(val);
450     }
451 }
452 
453 void qpci_io_writeb(QPCIDevice *dev, QPCIBar token, uint64_t off,
454                     uint8_t value)
455 {
456     QPCIBus *bus = dev->bus;
457 
458     if (token.is_io) {
459         bus->pio_writeb(bus, token.addr + off, value);
460     } else {
461         bus->memwrite(bus, token.addr + off, &value, sizeof(value));
462     }
463 }
464 
465 void qpci_io_writew(QPCIDevice *dev, QPCIBar token, uint64_t off,
466                     uint16_t value)
467 {
468     QPCIBus *bus = dev->bus;
469 
470     if (token.is_io) {
471         bus->pio_writew(bus, token.addr + off, value);
472     } else {
473         value = cpu_to_le16(value);
474         bus->memwrite(bus, token.addr + off, &value, sizeof(value));
475     }
476 }
477 
478 void qpci_io_writel(QPCIDevice *dev, QPCIBar token, uint64_t off,
479                     uint32_t value)
480 {
481     QPCIBus *bus = dev->bus;
482 
483     if (token.is_io) {
484         bus->pio_writel(bus, token.addr + off, value);
485     } else {
486         value = cpu_to_le32(value);
487         bus->memwrite(bus, token.addr + off, &value, sizeof(value));
488     }
489 }
490 
491 void qpci_io_writeq(QPCIDevice *dev, QPCIBar token, uint64_t off,
492                     uint64_t value)
493 {
494     QPCIBus *bus = dev->bus;
495 
496     if (token.is_io) {
497         bus->pio_writeq(bus, token.addr + off, value);
498     } else {
499         value = cpu_to_le64(value);
500         bus->memwrite(bus, token.addr + off, &value, sizeof(value));
501     }
502 }
503 
504 void qpci_memread(QPCIDevice *dev, QPCIBar token, uint64_t off,
505                   void *buf, size_t len)
506 {
507     g_assert(!token.is_io);
508     dev->bus->memread(dev->bus, token.addr + off, buf, len);
509 }
510 
511 void qpci_memwrite(QPCIDevice *dev, QPCIBar token, uint64_t off,
512                    const void *buf, size_t len)
513 {
514     g_assert(!token.is_io);
515     dev->bus->memwrite(dev->bus, token.addr + off, buf, len);
516 }
517 
518 QPCIBar qpci_iomap(QPCIDevice *dev, int barno, uint64_t *sizeptr)
519 {
520     QPCIBus *bus = dev->bus;
521     static const int bar_reg_map[] = {
522         PCI_BASE_ADDRESS_0, PCI_BASE_ADDRESS_1, PCI_BASE_ADDRESS_2,
523         PCI_BASE_ADDRESS_3, PCI_BASE_ADDRESS_4, PCI_BASE_ADDRESS_5,
524     };
525     QPCIBar bar;
526     int bar_reg;
527     uint32_t addr, size;
528     uint32_t io_type;
529     uint64_t loc;
530 
531     g_assert(barno >= 0 && barno <= 5);
532     bar_reg = bar_reg_map[barno];
533 
534     qpci_config_writel(dev, bar_reg, 0xFFFFFFFF);
535     addr = qpci_config_readl(dev, bar_reg);
536 
537     io_type = addr & PCI_BASE_ADDRESS_SPACE;
538     if (io_type == PCI_BASE_ADDRESS_SPACE_IO) {
539         addr &= PCI_BASE_ADDRESS_IO_MASK;
540     } else {
541         addr &= PCI_BASE_ADDRESS_MEM_MASK;
542     }
543 
544     g_assert(addr); /* Must have *some* size bits */
545 
546     size = 1U << ctz32(addr);
547     if (sizeptr) {
548         *sizeptr = size;
549     }
550 
551     if (io_type == PCI_BASE_ADDRESS_SPACE_IO) {
552         loc = QEMU_ALIGN_UP(bus->pio_alloc_ptr, size);
553 
554         g_assert(loc >= bus->pio_alloc_ptr);
555         g_assert(loc + size <= bus->pio_limit);
556 
557         bus->pio_alloc_ptr = loc + size;
558         bar.is_io = true;
559 
560         qpci_config_writel(dev, bar_reg, loc | PCI_BASE_ADDRESS_SPACE_IO);
561     } else {
562         loc = QEMU_ALIGN_UP(bus->mmio_alloc_ptr, size);
563 
564         /* Check for space */
565         g_assert(loc >= bus->mmio_alloc_ptr);
566         g_assert(loc + size <= bus->mmio_limit);
567 
568         bus->mmio_alloc_ptr = loc + size;
569         bar.is_io = false;
570 
571         qpci_config_writel(dev, bar_reg, loc);
572     }
573 
574     bar.addr = loc;
575     return bar;
576 }
577 
578 void qpci_iounmap(QPCIDevice *dev, QPCIBar bar)
579 {
580     /* FIXME */
581 }
582 
583 QPCIBar qpci_legacy_iomap(QPCIDevice *dev, uint16_t addr)
584 {
585     QPCIBar bar = { .addr = addr, .is_io = true };
586     return bar;
587 }
588 
589 void add_qpci_address(QOSGraphEdgeOptions *opts, QPCIAddress *addr)
590 {
591     g_assert(addr);
592     g_assert(opts);
593 
594     opts->arg = addr;
595     opts->size_arg = sizeof(QPCIAddress);
596 }
597