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
qpci_device_foreach(QPCIBus * bus,int vendor_id,int device_id,void (* func)(QPCIDevice * dev,int devfn,void * data),void * data)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
qpci_has_buggy_msi(QPCIDevice * dev)56 bool qpci_has_buggy_msi(QPCIDevice *dev)
57 {
58 return dev->bus->has_buggy_msi;
59 }
60
qpci_check_buggy_msi(QPCIDevice * dev)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
qpci_device_set(QPCIDevice * dev,QPCIBus * bus,int devfn)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
qpci_device_find(QPCIBus * bus,int devfn)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
qpci_device_init(QPCIDevice * dev,QPCIBus * bus,QPCIAddress * addr)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
qpci_find_resource_reserve_capability(QPCIDevice * dev)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
qpci_secondary_buses_rec(QPCIBus * qbus,int bus,int * pci_bus)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
qpci_secondary_buses_init(QPCIBus * bus)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
qpci_device_enable(QPCIDevice * dev)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 */
qpci_find_capability(QPCIDevice * dev,uint8_t id,uint8_t start_addr)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
qpci_msix_enable(QPCIDevice * dev)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
qpci_msix_disable(QPCIDevice * dev)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
qpci_msix_pending(QPCIDevice * dev,uint16_t entry)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 qpci_io_writel(dev, dev->msix_pba_bar, dev->msix_pba_off + off,
332 pba_entry & ~(1 << bit_n));
333 return (pba_entry & (1 << bit_n)) != 0;
334 }
335
qpci_msix_masked(QPCIDevice * dev,uint16_t entry)336 bool qpci_msix_masked(QPCIDevice *dev, uint16_t entry)
337 {
338 uint8_t addr;
339 uint16_t val;
340 uint64_t vector_off = dev->msix_table_off + entry * PCI_MSIX_ENTRY_SIZE;
341
342 g_assert(dev->msix_enabled);
343 addr = qpci_find_capability(dev, PCI_CAP_ID_MSIX, 0);
344 g_assert_cmphex(addr, !=, 0);
345 val = qpci_config_readw(dev, addr + PCI_MSIX_FLAGS);
346
347 if (val & PCI_MSIX_FLAGS_MASKALL) {
348 return true;
349 } else {
350 return (qpci_io_readl(dev, dev->msix_table_bar,
351 vector_off + PCI_MSIX_ENTRY_VECTOR_CTRL)
352 & PCI_MSIX_ENTRY_CTRL_MASKBIT) != 0;
353 }
354 }
355
qpci_msix_table_size(QPCIDevice * dev)356 uint16_t qpci_msix_table_size(QPCIDevice *dev)
357 {
358 uint8_t addr;
359 uint16_t control;
360
361 addr = qpci_find_capability(dev, PCI_CAP_ID_MSIX, 0);
362 g_assert_cmphex(addr, !=, 0);
363
364 control = qpci_config_readw(dev, addr + PCI_MSIX_FLAGS);
365 return (control & PCI_MSIX_FLAGS_QSIZE) + 1;
366 }
367
qpci_config_readb(QPCIDevice * dev,uint8_t offset)368 uint8_t qpci_config_readb(QPCIDevice *dev, uint8_t offset)
369 {
370 return dev->bus->config_readb(dev->bus, dev->devfn, offset);
371 }
372
qpci_config_readw(QPCIDevice * dev,uint8_t offset)373 uint16_t qpci_config_readw(QPCIDevice *dev, uint8_t offset)
374 {
375 return dev->bus->config_readw(dev->bus, dev->devfn, offset);
376 }
377
qpci_config_readl(QPCIDevice * dev,uint8_t offset)378 uint32_t qpci_config_readl(QPCIDevice *dev, uint8_t offset)
379 {
380 return dev->bus->config_readl(dev->bus, dev->devfn, offset);
381 }
382
383
qpci_config_writeb(QPCIDevice * dev,uint8_t offset,uint8_t value)384 void qpci_config_writeb(QPCIDevice *dev, uint8_t offset, uint8_t value)
385 {
386 dev->bus->config_writeb(dev->bus, dev->devfn, offset, value);
387 }
388
qpci_config_writew(QPCIDevice * dev,uint8_t offset,uint16_t value)389 void qpci_config_writew(QPCIDevice *dev, uint8_t offset, uint16_t value)
390 {
391 dev->bus->config_writew(dev->bus, dev->devfn, offset, value);
392 }
393
qpci_config_writel(QPCIDevice * dev,uint8_t offset,uint32_t value)394 void qpci_config_writel(QPCIDevice *dev, uint8_t offset, uint32_t value)
395 {
396 dev->bus->config_writel(dev->bus, dev->devfn, offset, value);
397 }
398
qpci_io_readb(QPCIDevice * dev,QPCIBar token,uint64_t off)399 uint8_t qpci_io_readb(QPCIDevice *dev, QPCIBar token, uint64_t off)
400 {
401 QPCIBus *bus = dev->bus;
402
403 if (token.is_io) {
404 return bus->pio_readb(bus, token.addr + off);
405 } else {
406 uint8_t val;
407
408 bus->memread(dev->bus, token.addr + off, &val, sizeof(val));
409 return val;
410 }
411 }
412
qpci_io_readw(QPCIDevice * dev,QPCIBar token,uint64_t off)413 uint16_t qpci_io_readw(QPCIDevice *dev, QPCIBar token, uint64_t off)
414 {
415 QPCIBus *bus = dev->bus;
416
417 if (token.is_io) {
418 return bus->pio_readw(bus, token.addr + off);
419 } else {
420 uint16_t val;
421
422 bus->memread(bus, token.addr + off, &val, sizeof(val));
423 return le16_to_cpu(val);
424 }
425 }
426
qpci_io_readl(QPCIDevice * dev,QPCIBar token,uint64_t off)427 uint32_t qpci_io_readl(QPCIDevice *dev, QPCIBar token, uint64_t off)
428 {
429 QPCIBus *bus = dev->bus;
430
431 if (token.is_io) {
432 return bus->pio_readl(bus, token.addr + off);
433 } else {
434 uint32_t val;
435
436 bus->memread(dev->bus, token.addr + off, &val, sizeof(val));
437 return le32_to_cpu(val);
438 }
439 }
440
qpci_io_readq(QPCIDevice * dev,QPCIBar token,uint64_t off)441 uint64_t qpci_io_readq(QPCIDevice *dev, QPCIBar token, uint64_t off)
442 {
443 QPCIBus *bus = dev->bus;
444
445 if (token.is_io) {
446 return bus->pio_readq(bus, token.addr + off);
447 } else {
448 uint64_t val;
449
450 bus->memread(bus, token.addr + off, &val, sizeof(val));
451 return le64_to_cpu(val);
452 }
453 }
454
qpci_io_writeb(QPCIDevice * dev,QPCIBar token,uint64_t off,uint8_t value)455 void qpci_io_writeb(QPCIDevice *dev, QPCIBar token, uint64_t off,
456 uint8_t value)
457 {
458 QPCIBus *bus = dev->bus;
459
460 if (token.is_io) {
461 bus->pio_writeb(bus, token.addr + off, value);
462 } else {
463 bus->memwrite(bus, token.addr + off, &value, sizeof(value));
464 }
465 }
466
qpci_io_writew(QPCIDevice * dev,QPCIBar token,uint64_t off,uint16_t value)467 void qpci_io_writew(QPCIDevice *dev, QPCIBar token, uint64_t off,
468 uint16_t value)
469 {
470 QPCIBus *bus = dev->bus;
471
472 if (token.is_io) {
473 bus->pio_writew(bus, token.addr + off, value);
474 } else {
475 value = cpu_to_le16(value);
476 bus->memwrite(bus, token.addr + off, &value, sizeof(value));
477 }
478 }
479
qpci_io_writel(QPCIDevice * dev,QPCIBar token,uint64_t off,uint32_t value)480 void qpci_io_writel(QPCIDevice *dev, QPCIBar token, uint64_t off,
481 uint32_t value)
482 {
483 QPCIBus *bus = dev->bus;
484
485 if (token.is_io) {
486 bus->pio_writel(bus, token.addr + off, value);
487 } else {
488 value = cpu_to_le32(value);
489 bus->memwrite(bus, token.addr + off, &value, sizeof(value));
490 }
491 }
492
qpci_io_writeq(QPCIDevice * dev,QPCIBar token,uint64_t off,uint64_t value)493 void qpci_io_writeq(QPCIDevice *dev, QPCIBar token, uint64_t off,
494 uint64_t value)
495 {
496 QPCIBus *bus = dev->bus;
497
498 if (token.is_io) {
499 bus->pio_writeq(bus, token.addr + off, value);
500 } else {
501 value = cpu_to_le64(value);
502 bus->memwrite(bus, token.addr + off, &value, sizeof(value));
503 }
504 }
505
qpci_memread(QPCIDevice * dev,QPCIBar token,uint64_t off,void * buf,size_t len)506 void qpci_memread(QPCIDevice *dev, QPCIBar token, uint64_t off,
507 void *buf, size_t len)
508 {
509 g_assert(!token.is_io);
510 dev->bus->memread(dev->bus, token.addr + off, buf, len);
511 }
512
qpci_memwrite(QPCIDevice * dev,QPCIBar token,uint64_t off,const void * buf,size_t len)513 void qpci_memwrite(QPCIDevice *dev, QPCIBar token, uint64_t off,
514 const void *buf, size_t len)
515 {
516 g_assert(!token.is_io);
517 dev->bus->memwrite(dev->bus, token.addr + off, buf, len);
518 }
519
qpci_iomap(QPCIDevice * dev,int barno,uint64_t * sizeptr)520 QPCIBar qpci_iomap(QPCIDevice *dev, int barno, uint64_t *sizeptr)
521 {
522 QPCIBus *bus = dev->bus;
523 static const int bar_reg_map[] = {
524 PCI_BASE_ADDRESS_0, PCI_BASE_ADDRESS_1, PCI_BASE_ADDRESS_2,
525 PCI_BASE_ADDRESS_3, PCI_BASE_ADDRESS_4, PCI_BASE_ADDRESS_5,
526 };
527 QPCIBar bar;
528 int bar_reg;
529 uint32_t addr, size;
530 uint32_t io_type;
531 uint64_t loc;
532
533 g_assert(barno >= 0 && barno <= 5);
534 bar_reg = bar_reg_map[barno];
535
536 qpci_config_writel(dev, bar_reg, 0xFFFFFFFF);
537 addr = qpci_config_readl(dev, bar_reg);
538
539 io_type = addr & PCI_BASE_ADDRESS_SPACE;
540 if (io_type == PCI_BASE_ADDRESS_SPACE_IO) {
541 addr &= PCI_BASE_ADDRESS_IO_MASK;
542 } else {
543 addr &= PCI_BASE_ADDRESS_MEM_MASK;
544 }
545
546 g_assert(addr); /* Must have *some* size bits */
547
548 size = 1U << ctz32(addr);
549 if (sizeptr) {
550 *sizeptr = size;
551 }
552
553 if (io_type == PCI_BASE_ADDRESS_SPACE_IO) {
554 loc = QEMU_ALIGN_UP(bus->pio_alloc_ptr, size);
555
556 g_assert(loc >= bus->pio_alloc_ptr);
557 g_assert(loc + size <= bus->pio_limit);
558
559 bus->pio_alloc_ptr = loc + size;
560 bar.is_io = true;
561
562 qpci_config_writel(dev, bar_reg, loc | PCI_BASE_ADDRESS_SPACE_IO);
563 } else {
564 loc = QEMU_ALIGN_UP(bus->mmio_alloc_ptr, size);
565
566 /* Check for space */
567 g_assert(loc >= bus->mmio_alloc_ptr);
568 g_assert(loc + size <= bus->mmio_limit);
569
570 bus->mmio_alloc_ptr = loc + size;
571 bar.is_io = false;
572
573 qpci_config_writel(dev, bar_reg, loc);
574 }
575
576 bar.addr = loc;
577 return bar;
578 }
579
qpci_iounmap(QPCIDevice * dev,QPCIBar bar)580 void qpci_iounmap(QPCIDevice *dev, QPCIBar bar)
581 {
582 /* FIXME */
583 }
584
qpci_legacy_iomap(QPCIDevice * dev,uint16_t addr)585 QPCIBar qpci_legacy_iomap(QPCIDevice *dev, uint16_t addr)
586 {
587 QPCIBar bar = { .addr = addr, .is_io = true };
588 return bar;
589 }
590
add_qpci_address(QOSGraphEdgeOptions * opts,QPCIAddress * addr)591 void add_qpci_address(QOSGraphEdgeOptions *opts, QPCIAddress *addr)
592 {
593 g_assert(addr);
594 g_assert(opts);
595
596 opts->arg = addr;
597 opts->size_arg = sizeof(QPCIAddress);
598 }
599