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