1 #ifndef _PCI_H_ 2 #define _PCI_H_ 3 /* 4 * API for scanning a PCI bus for a given device, as well to access 5 * BAR registers. 6 * 7 * Copyright (C) 2013, Red Hat Inc, Michael S. Tsirkin <mst@redhat.com> 8 * 9 * This work is licensed under the terms of the GNU LGPL, version 2. 10 */ 11 #include "libcflat.h" 12 13 typedef uint16_t pcidevaddr_t; 14 enum { 15 PCIDEVADDR_INVALID = 0xffff, 16 }; 17 18 #define PCI_BAR_NUM 6 19 #define PCI_DEVFN_MAX 256 20 21 #define ASSERT_BAR_NUM(bar_num) \ 22 do { assert(bar_num >= 0 && bar_num < PCI_BAR_NUM); } while (0) 23 24 #define PCI_BDF_GET_DEVFN(x) ((x) & 0xff) 25 #define PCI_BDF_GET_BUS(x) (((x) >> 8) & 0xff) 26 27 struct pci_dev { 28 uint16_t bdf; 29 uint16_t msi_offset; 30 phys_addr_t resource[PCI_BAR_NUM]; 31 }; 32 33 extern void pci_dev_init(struct pci_dev *dev, pcidevaddr_t bdf); 34 extern void pci_cmd_set_clr(struct pci_dev *dev, uint16_t set, uint16_t clr); 35 typedef void (*pci_cap_handler_t)(struct pci_dev *dev, int cap_offset, int cap_id); 36 extern void pci_cap_walk(struct pci_dev *dev, pci_cap_handler_t handler); 37 extern void pci_enable_defaults(struct pci_dev *dev); 38 extern bool pci_setup_msi(struct pci_dev *dev, uint64_t msi_addr, 39 uint32_t msi_data); 40 41 typedef phys_addr_t iova_t; 42 43 extern bool pci_probe(void); 44 extern void pci_print(void); 45 extern bool pci_dev_exists(pcidevaddr_t dev); 46 extern pcidevaddr_t pci_find_dev(uint16_t vendor_id, uint16_t device_id); 47 48 /* 49 * @bar_num in all BAR access functions below is the index of the 32-bit 50 * register starting from the PCI_BASE_ADDRESS_0 offset. 51 * 52 * In cases where the BAR size is 64-bit, a caller should still provide 53 * @bar_num in terms of 32-bit words. For example, if a device has a 64-bit 54 * BAR#0 and a 32-bit BAR#1, then caller should provide 2 to address BAR#1, 55 * not 1. 56 * 57 * It is expected the caller is aware of the device BAR layout and never 58 * tries to address the middle of a 64-bit register. 59 */ 60 extern phys_addr_t pci_bar_get_addr(struct pci_dev *dev, int bar_num); 61 extern void pci_bar_set_addr(struct pci_dev *dev, int bar_num, phys_addr_t addr); 62 extern phys_addr_t pci_bar_size(struct pci_dev *dev, int bar_num); 63 extern uint32_t pci_bar_get(struct pci_dev *dev, int bar_num); 64 extern uint32_t pci_bar_mask(uint32_t bar); 65 extern bool pci_bar_is64(struct pci_dev *dev, int bar_num); 66 extern bool pci_bar_is_memory(struct pci_dev *dev, int bar_num); 67 extern bool pci_bar_is_valid(struct pci_dev *dev, int bar_num); 68 extern void pci_bar_print(struct pci_dev *dev, int bar_num); 69 extern void pci_dev_print_id(struct pci_dev *dev); 70 extern void pci_dev_print(struct pci_dev *dev); 71 extern uint8_t pci_intx_line(struct pci_dev *dev); 72 void pci_msi_set_enable(struct pci_dev *dev, bool enabled); 73 74 extern int pci_testdev(void); 75 76 /* 77 * pci-testdev is a driver for the pci-testdev qemu pci device. The 78 * device enables testing mmio and portio exits, and measuring their 79 * speed. 80 */ 81 #define PCI_VENDOR_ID_REDHAT 0x1b36 82 #define PCI_DEVICE_ID_REDHAT_TEST 0x0005 83 84 /* 85 * pci-testdev supports at least three types of tests (via mmio and 86 * portio BARs): no-eventfd, wildcard-eventfd and datamatch-eventfd 87 */ 88 #define PCI_TESTDEV_BAR_MEM 0 89 #define PCI_TESTDEV_BAR_IO 1 90 #define PCI_TESTDEV_NUM_BARS 2 91 #define PCI_TESTDEV_NUM_TESTS 3 92 93 struct pci_test_dev_hdr { 94 uint8_t test; 95 uint8_t width; 96 uint8_t pad0[2]; 97 uint32_t offset; 98 uint32_t data; 99 uint32_t count; 100 uint8_t name[]; 101 }; 102 103 #define PCI_HEADER_TYPE_MASK 0x7f 104 105 #endif /* _PCI_H_ */ 106