| 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 | #ifndef LIBQOS_PCI_H |
| 14 | #define LIBQOS_PCI_H |
| 15 | |
| 16 | #include "../libqtest.h" |
| 17 | #include "qgraph.h" |
| 18 | |
| 19 | #define QPCI_DEVFN(dev, fn) (((dev) << 3) | (fn)) |
| 20 | |
| 21 | typedef struct QPCIDevice QPCIDevice; |
| 22 | typedef struct QPCIBus QPCIBus; |
| 23 | typedef struct QPCIBar QPCIBar; |
| 24 | typedef struct QPCIAddress QPCIAddress; |
| 25 | |
| 26 | struct QPCIBus { |
| 27 | uint8_t (*pio_readb)(QPCIBus *bus, uint32_t addr); |
| 28 | uint16_t (*pio_readw)(QPCIBus *bus, uint32_t addr); |
| 29 | uint32_t (*pio_readl)(QPCIBus *bus, uint32_t addr); |
| 30 | uint64_t (*pio_readq)(QPCIBus *bus, uint32_t addr); |
| 31 | |
| 32 | void (*pio_writeb)(QPCIBus *bus, uint32_t addr, uint8_t value); |
| 33 | void (*pio_writew)(QPCIBus *bus, uint32_t addr, uint16_t value); |
| 34 | void (*pio_writel)(QPCIBus *bus, uint32_t addr, uint32_t value); |
| 35 | void (*pio_writeq)(QPCIBus *bus, uint32_t addr, uint64_t value); |
| 36 | |
| 37 | void (*memread)(QPCIBus *bus, uint32_t addr, void *buf, size_t len); |
| 38 | void (*memwrite)(QPCIBus *bus, uint32_t addr, const void *buf, size_t len); |
| 39 | |
| 40 | uint8_t (*config_readb)(QPCIBus *bus, int devfn, uint8_t offset); |
| 41 | uint16_t (*config_readw)(QPCIBus *bus, int devfn, uint8_t offset); |
| 42 | uint32_t (*config_readl)(QPCIBus *bus, int devfn, uint8_t offset); |
| 43 | |
| 44 | void (*config_writeb)(QPCIBus *bus, int devfn, |
| 45 | uint8_t offset, uint8_t value); |
| 46 | void (*config_writew)(QPCIBus *bus, int devfn, |
| 47 | uint8_t offset, uint16_t value); |
| 48 | void (*config_writel)(QPCIBus *bus, int devfn, |
| 49 | uint8_t offset, uint32_t value); |
| 50 | |
| 51 | QTestState *qts; |
| 52 | uint64_t pio_alloc_ptr, pio_limit; |
| 53 | uint64_t mmio_alloc_ptr, mmio_limit; |
| 54 | bool has_buggy_msi; /* TRUE for spapr, FALSE for pci */ |
| 55 | bool not_hotpluggable; /* TRUE if devices cannot be hotplugged */ |
| 56 | |
| 57 | }; |
| 58 | |
| 59 | struct QPCIBar { |
| 60 | uint64_t addr; |
| 61 | bool is_io; |
| 62 | }; |
| 63 | |
| 64 | struct QPCIDevice |
| 65 | { |
| 66 | QPCIBus *bus; |
| 67 | int devfn; |
| 68 | bool msix_enabled; |
| 69 | QPCIBar msix_table_bar, msix_pba_bar; |
| 70 | uint64_t msix_table_off, msix_pba_off; |
| 71 | }; |
| 72 | |
| 73 | struct QPCIAddress { |
| 74 | uint32_t devfn; |
| 75 | uint16_t vendor_id; |
| 76 | uint16_t device_id; |
| 77 | }; |
| 78 | |
| 79 | void qpci_device_foreach(QPCIBus *bus, int vendor_id, int device_id, |
| 80 | void (*func)(QPCIDevice *dev, int devfn, void *data), |
| 81 | void *data); |
| 82 | QPCIDevice *qpci_device_find(QPCIBus *bus, int devfn); |
| 83 | void qpci_device_init(QPCIDevice *dev, QPCIBus *bus, QPCIAddress *addr); |
| 84 | int qpci_secondary_buses_init(QPCIBus *bus); |
| 85 | |
| 86 | bool qpci_has_buggy_msi(QPCIDevice *dev); |
| 87 | bool qpci_check_buggy_msi(QPCIDevice *dev); |
| 88 | |
| 89 | void qpci_device_enable(QPCIDevice *dev); |
| 90 | uint8_t qpci_find_capability(QPCIDevice *dev, uint8_t id, uint8_t start_addr); |
| 91 | void qpci_msix_enable(QPCIDevice *dev); |
| 92 | void qpci_msix_disable(QPCIDevice *dev); |
| 93 | bool qpci_msix_pending(QPCIDevice *dev, uint16_t entry); |
| 94 | bool qpci_msix_masked(QPCIDevice *dev, uint16_t entry); |
| 95 | uint16_t qpci_msix_table_size(QPCIDevice *dev); |
| 96 | |
| 97 | uint8_t qpci_config_readb(QPCIDevice *dev, uint8_t offset); |
| 98 | uint16_t qpci_config_readw(QPCIDevice *dev, uint8_t offset); |
| 99 | uint32_t qpci_config_readl(QPCIDevice *dev, uint8_t offset); |
| 100 | |
| 101 | void qpci_config_writeb(QPCIDevice *dev, uint8_t offset, uint8_t value); |
| 102 | void qpci_config_writew(QPCIDevice *dev, uint8_t offset, uint16_t value); |
| 103 | void qpci_config_writel(QPCIDevice *dev, uint8_t offset, uint32_t value); |
| 104 | |
| 105 | uint8_t qpci_io_readb(QPCIDevice *dev, QPCIBar token, uint64_t off); |
| 106 | uint16_t qpci_io_readw(QPCIDevice *dev, QPCIBar token, uint64_t off); |
| 107 | uint32_t qpci_io_readl(QPCIDevice *dev, QPCIBar token, uint64_t off); |
| 108 | uint64_t qpci_io_readq(QPCIDevice *dev, QPCIBar token, uint64_t off); |
| 109 | |
| 110 | void qpci_io_writeb(QPCIDevice *dev, QPCIBar token, uint64_t off, |
| 111 | uint8_t value); |
| 112 | void qpci_io_writew(QPCIDevice *dev, QPCIBar token, uint64_t off, |
| 113 | uint16_t value); |
| 114 | void qpci_io_writel(QPCIDevice *dev, QPCIBar token, uint64_t off, |
| 115 | uint32_t value); |
| 116 | void qpci_io_writeq(QPCIDevice *dev, QPCIBar token, uint64_t off, |
| 117 | uint64_t value); |
| 118 | |
| 119 | void qpci_memread(QPCIDevice *bus, QPCIBar token, uint64_t off, |
| 120 | void *buf, size_t len); |
| 121 | void qpci_memwrite(QPCIDevice *bus, QPCIBar token, uint64_t off, |
| 122 | const void *buf, size_t len); |
| 123 | QPCIBar qpci_iomap(QPCIDevice *dev, int barno, uint64_t *sizeptr); |
| 124 | void qpci_iounmap(QPCIDevice *dev, QPCIBar addr); |
| 125 | QPCIBar qpci_legacy_iomap(QPCIDevice *dev, uint16_t addr); |
| 126 | |
| 127 | void qpci_unplug_acpi_device_test(QTestState *qs, const char *id, uint8_t slot); |
| 128 | |
| 129 | void add_qpci_address(QOSGraphEdgeOptions *opts, QPCIAddress *addr); |
| 130 | #endif |