11cf4323eSThomas Huth /* 21cf4323eSThomas Huth * libqos PCI bindings 31cf4323eSThomas Huth * 41cf4323eSThomas Huth * Copyright IBM, Corp. 2012-2013 51cf4323eSThomas Huth * 61cf4323eSThomas Huth * Authors: 71cf4323eSThomas Huth * Anthony Liguori <aliguori@us.ibm.com> 81cf4323eSThomas Huth * 91cf4323eSThomas Huth * This work is licensed under the terms of the GNU GPL, version 2 or later. 101cf4323eSThomas Huth * See the COPYING file in the top-level directory. 111cf4323eSThomas Huth */ 121cf4323eSThomas Huth 131cf4323eSThomas Huth #ifndef LIBQOS_PCI_H 141cf4323eSThomas Huth #define LIBQOS_PCI_H 151cf4323eSThomas Huth 16907b5105SMarc-André Lureau #include "../libqtest.h" 17a2ce7dbdSPaolo Bonzini #include "qgraph.h" 181cf4323eSThomas Huth 191cf4323eSThomas Huth #define QPCI_DEVFN(dev, fn) (((dev) << 3) | (fn)) 201cf4323eSThomas Huth 211cf4323eSThomas Huth typedef struct QPCIDevice QPCIDevice; 221cf4323eSThomas Huth typedef struct QPCIBus QPCIBus; 231cf4323eSThomas Huth typedef struct QPCIBar QPCIBar; 241cf4323eSThomas Huth typedef struct QPCIAddress QPCIAddress; 251cf4323eSThomas Huth 261cf4323eSThomas Huth struct QPCIBus { 271cf4323eSThomas Huth uint8_t (*pio_readb)(QPCIBus *bus, uint32_t addr); 281cf4323eSThomas Huth uint16_t (*pio_readw)(QPCIBus *bus, uint32_t addr); 291cf4323eSThomas Huth uint32_t (*pio_readl)(QPCIBus *bus, uint32_t addr); 301cf4323eSThomas Huth uint64_t (*pio_readq)(QPCIBus *bus, uint32_t addr); 311cf4323eSThomas Huth 321cf4323eSThomas Huth void (*pio_writeb)(QPCIBus *bus, uint32_t addr, uint8_t value); 331cf4323eSThomas Huth void (*pio_writew)(QPCIBus *bus, uint32_t addr, uint16_t value); 341cf4323eSThomas Huth void (*pio_writel)(QPCIBus *bus, uint32_t addr, uint32_t value); 351cf4323eSThomas Huth void (*pio_writeq)(QPCIBus *bus, uint32_t addr, uint64_t value); 361cf4323eSThomas Huth 371cf4323eSThomas Huth void (*memread)(QPCIBus *bus, uint32_t addr, void *buf, size_t len); 381cf4323eSThomas Huth void (*memwrite)(QPCIBus *bus, uint32_t addr, const void *buf, size_t len); 391cf4323eSThomas Huth 401cf4323eSThomas Huth uint8_t (*config_readb)(QPCIBus *bus, int devfn, uint8_t offset); 411cf4323eSThomas Huth uint16_t (*config_readw)(QPCIBus *bus, int devfn, uint8_t offset); 421cf4323eSThomas Huth uint32_t (*config_readl)(QPCIBus *bus, int devfn, uint8_t offset); 431cf4323eSThomas Huth 441cf4323eSThomas Huth void (*config_writeb)(QPCIBus *bus, int devfn, 451cf4323eSThomas Huth uint8_t offset, uint8_t value); 461cf4323eSThomas Huth void (*config_writew)(QPCIBus *bus, int devfn, 471cf4323eSThomas Huth uint8_t offset, uint16_t value); 481cf4323eSThomas Huth void (*config_writel)(QPCIBus *bus, int devfn, 491cf4323eSThomas Huth uint8_t offset, uint32_t value); 501cf4323eSThomas Huth 511cf4323eSThomas Huth QTestState *qts; 523df72d1cSEric Auger uint64_t pio_alloc_ptr, pio_limit; 531cf4323eSThomas Huth uint64_t mmio_alloc_ptr, mmio_limit; 541cf4323eSThomas Huth bool has_buggy_msi; /* TRUE for spapr, FALSE for pci */ 55*02ee7a8aSEric Auger bool not_hotpluggable; /* TRUE if devices cannot be hotplugged */ 561cf4323eSThomas Huth 571cf4323eSThomas Huth }; 581cf4323eSThomas Huth 591cf4323eSThomas Huth struct QPCIBar { 601cf4323eSThomas Huth uint64_t addr; 613df72d1cSEric Auger bool is_io; 621cf4323eSThomas Huth }; 631cf4323eSThomas Huth 641cf4323eSThomas Huth struct QPCIDevice 651cf4323eSThomas Huth { 661cf4323eSThomas Huth QPCIBus *bus; 671cf4323eSThomas Huth int devfn; 681cf4323eSThomas Huth bool msix_enabled; 691cf4323eSThomas Huth QPCIBar msix_table_bar, msix_pba_bar; 701cf4323eSThomas Huth uint64_t msix_table_off, msix_pba_off; 711cf4323eSThomas Huth }; 721cf4323eSThomas Huth 731cf4323eSThomas Huth struct QPCIAddress { 741cf4323eSThomas Huth uint32_t devfn; 751cf4323eSThomas Huth uint16_t vendor_id; 761cf4323eSThomas Huth uint16_t device_id; 771cf4323eSThomas Huth }; 781cf4323eSThomas Huth 791cf4323eSThomas Huth void qpci_device_foreach(QPCIBus *bus, int vendor_id, int device_id, 801cf4323eSThomas Huth void (*func)(QPCIDevice *dev, int devfn, void *data), 811cf4323eSThomas Huth void *data); 821cf4323eSThomas Huth QPCIDevice *qpci_device_find(QPCIBus *bus, int devfn); 831cf4323eSThomas Huth void qpci_device_init(QPCIDevice *dev, QPCIBus *bus, QPCIAddress *addr); 84efe84f03SLaurent Vivier int qpci_secondary_buses_init(QPCIBus *bus); 851cf4323eSThomas Huth 861cf4323eSThomas Huth bool qpci_has_buggy_msi(QPCIDevice *dev); 871cf4323eSThomas Huth bool qpci_check_buggy_msi(QPCIDevice *dev); 881cf4323eSThomas Huth 891cf4323eSThomas Huth void qpci_device_enable(QPCIDevice *dev); 901cf4323eSThomas Huth uint8_t qpci_find_capability(QPCIDevice *dev, uint8_t id, uint8_t start_addr); 911cf4323eSThomas Huth void qpci_msix_enable(QPCIDevice *dev); 921cf4323eSThomas Huth void qpci_msix_disable(QPCIDevice *dev); 931cf4323eSThomas Huth bool qpci_msix_pending(QPCIDevice *dev, uint16_t entry); 941cf4323eSThomas Huth bool qpci_msix_masked(QPCIDevice *dev, uint16_t entry); 951cf4323eSThomas Huth uint16_t qpci_msix_table_size(QPCIDevice *dev); 961cf4323eSThomas Huth 971cf4323eSThomas Huth uint8_t qpci_config_readb(QPCIDevice *dev, uint8_t offset); 981cf4323eSThomas Huth uint16_t qpci_config_readw(QPCIDevice *dev, uint8_t offset); 991cf4323eSThomas Huth uint32_t qpci_config_readl(QPCIDevice *dev, uint8_t offset); 1001cf4323eSThomas Huth 1011cf4323eSThomas Huth void qpci_config_writeb(QPCIDevice *dev, uint8_t offset, uint8_t value); 1021cf4323eSThomas Huth void qpci_config_writew(QPCIDevice *dev, uint8_t offset, uint16_t value); 1031cf4323eSThomas Huth void qpci_config_writel(QPCIDevice *dev, uint8_t offset, uint32_t value); 1041cf4323eSThomas Huth 1051cf4323eSThomas Huth uint8_t qpci_io_readb(QPCIDevice *dev, QPCIBar token, uint64_t off); 1061cf4323eSThomas Huth uint16_t qpci_io_readw(QPCIDevice *dev, QPCIBar token, uint64_t off); 1071cf4323eSThomas Huth uint32_t qpci_io_readl(QPCIDevice *dev, QPCIBar token, uint64_t off); 1081cf4323eSThomas Huth uint64_t qpci_io_readq(QPCIDevice *dev, QPCIBar token, uint64_t off); 1091cf4323eSThomas Huth 1101cf4323eSThomas Huth void qpci_io_writeb(QPCIDevice *dev, QPCIBar token, uint64_t off, 1111cf4323eSThomas Huth uint8_t value); 1121cf4323eSThomas Huth void qpci_io_writew(QPCIDevice *dev, QPCIBar token, uint64_t off, 1131cf4323eSThomas Huth uint16_t value); 1141cf4323eSThomas Huth void qpci_io_writel(QPCIDevice *dev, QPCIBar token, uint64_t off, 1151cf4323eSThomas Huth uint32_t value); 1161cf4323eSThomas Huth void qpci_io_writeq(QPCIDevice *dev, QPCIBar token, uint64_t off, 1171cf4323eSThomas Huth uint64_t value); 1181cf4323eSThomas Huth 1191cf4323eSThomas Huth void qpci_memread(QPCIDevice *bus, QPCIBar token, uint64_t off, 1201cf4323eSThomas Huth void *buf, size_t len); 1211cf4323eSThomas Huth void qpci_memwrite(QPCIDevice *bus, QPCIBar token, uint64_t off, 1221cf4323eSThomas Huth const void *buf, size_t len); 1231cf4323eSThomas Huth QPCIBar qpci_iomap(QPCIDevice *dev, int barno, uint64_t *sizeptr); 1241cf4323eSThomas Huth void qpci_iounmap(QPCIDevice *dev, QPCIBar addr); 1251cf4323eSThomas Huth QPCIBar qpci_legacy_iomap(QPCIDevice *dev, uint16_t addr); 1261cf4323eSThomas Huth 1271cf4323eSThomas Huth void qpci_unplug_acpi_device_test(QTestState *qs, const char *id, uint8_t slot); 1281cf4323eSThomas Huth 1291cf4323eSThomas Huth void add_qpci_address(QOSGraphEdgeOptions *opts, QPCIAddress *addr); 1301cf4323eSThomas Huth #endif 131