1 /****************************************************************************** 2 * pci.h 3 * 4 * PCI access functions. 5 */ 6 7 #ifndef __XEN_PCI_H__ 8 #define __XEN_PCI_H__ 9 10 #include <xen/types.h> 11 #include <xen/list.h> 12 #include <xen/spinlock.h> 13 #include <xen/irq.h> 14 #include <xen/pci_regs.h> 15 #include <xen/pfn.h> 16 #include <asm/device.h> 17 #include <asm/numa.h> 18 #include <asm/pci.h> 19 20 /* 21 * The PCI interface treats multi-function devices as independent 22 * devices. The slot/function address of each device is encoded 23 * in a single byte as follows: 24 * 25 * 15:8 = bus 26 * 7:3 = slot 27 * 2:0 = function 28 */ 29 #define PCI_SEG(sbdf) (((sbdf) >> 16) & 0xffff) 30 #define PCI_BUS(bdf) (((bdf) >> 8) & 0xff) 31 #define PCI_SLOT(bdf) (((bdf) >> 3) & 0x1f) 32 #define PCI_FUNC(bdf) ((bdf) & 0x07) 33 #define PCI_DEVFN(d,f) ((((d) & 0x1f) << 3) | ((f) & 0x07)) 34 #define PCI_DEVFN2(bdf) ((bdf) & 0xff) 35 #define PCI_BDF(b,d,f) ((((b) & 0xff) << 8) | PCI_DEVFN(d,f)) 36 #define PCI_BDF2(b,df) ((((b) & 0xff) << 8) | ((df) & 0xff)) 37 #define PCI_SBDF(s,b,d,f) ((((s) & 0xffff) << 16) | PCI_BDF(b,d,f)) 38 #define PCI_SBDF2(s,bdf) ((((s) & 0xffff) << 16) | ((bdf) & 0xffff)) 39 #define PCI_SBDF3(s,b,df) ((((s) & 0xffff) << 16) | PCI_BDF2(b, df)) 40 41 struct pci_dev_info { 42 /* 43 * VF's 'is_extfn' field is used to indicate whether its PF is an extended 44 * function. 45 */ 46 bool_t is_extfn; 47 bool_t is_virtfn; 48 struct { 49 u8 bus; 50 u8 devfn; 51 } physfn; 52 }; 53 54 struct pci_dev { 55 struct list_head alldevs_list; 56 struct list_head domain_list; 57 58 struct list_head msi_list; 59 60 struct arch_msix *msix; 61 62 struct domain *domain; 63 const u16 seg; 64 const u8 bus; 65 const u8 devfn; 66 67 u8 phantom_stride; 68 69 nodeid_t node; /* NUMA node */ 70 71 enum pdev_type { 72 DEV_TYPE_PCI_UNKNOWN, 73 DEV_TYPE_PCIe_ENDPOINT, 74 DEV_TYPE_PCIe_BRIDGE, // PCIe root port, switch 75 DEV_TYPE_PCIe2PCI_BRIDGE, // PCIe-to-PCI/PCIx bridge 76 DEV_TYPE_PCI2PCIe_BRIDGE, // PCI/PCIx-to-PCIe bridge 77 DEV_TYPE_LEGACY_PCI_BRIDGE, // Legacy PCI bridge 78 DEV_TYPE_PCI_HOST_BRIDGE, // PCI Host bridge 79 DEV_TYPE_PCI, 80 } type; 81 82 struct pci_dev_info info; 83 struct arch_pci_dev arch; 84 struct { 85 struct list_head list; 86 unsigned int cap_pos; 87 unsigned int queue_depth; 88 } ats; 89 struct { 90 s_time_t time; 91 unsigned int count; 92 #define PT_FAULT_THRESHOLD 10 93 } fault; 94 u64 vf_rlen[6]; 95 }; 96 97 #define for_each_pdev(domain, pdev) \ 98 list_for_each_entry(pdev, &(domain->arch.pdev_list), domain_list) 99 100 /* 101 * The pcidevs_lock protect alldevs_list, and the assignment for the 102 * devices, it also sync the access to the msi capability that is not 103 * interrupt handling related (the mask bit register). 104 */ 105 106 void pcidevs_lock(void); 107 void pcidevs_unlock(void); 108 bool_t __must_check pcidevs_locked(void); 109 bool_t __must_check pcidevs_trylock(void); 110 111 bool_t pci_known_segment(u16 seg); 112 bool_t pci_device_detect(u16 seg, u8 bus, u8 dev, u8 func); 113 int scan_pci_devices(void); 114 enum pdev_type pdev_type(u16 seg, u8 bus, u8 devfn); 115 int find_upstream_bridge(u16 seg, u8 *bus, u8 *devfn, u8 *secbus); 116 struct pci_dev *pci_lock_pdev(int seg, int bus, int devfn); 117 struct pci_dev *pci_lock_domain_pdev( 118 struct domain *, int seg, int bus, int devfn); 119 120 void setup_hwdom_pci_devices(struct domain *, 121 int (*)(u8 devfn, struct pci_dev *)); 122 int pci_release_devices(struct domain *d); 123 int pci_add_segment(u16 seg); 124 const unsigned long *pci_get_ro_map(u16 seg); 125 int pci_add_device(u16 seg, u8 bus, u8 devfn, 126 const struct pci_dev_info *, nodeid_t node); 127 int pci_remove_device(u16 seg, u8 bus, u8 devfn); 128 int pci_ro_device(int seg, int bus, int devfn); 129 int pci_hide_device(int bus, int devfn); 130 struct pci_dev *pci_get_pdev(int seg, int bus, int devfn); 131 struct pci_dev *pci_get_real_pdev(int seg, int bus, int devfn); 132 struct pci_dev *pci_get_pdev_by_domain(const struct domain *, int seg, 133 int bus, int devfn); 134 void pci_check_disable_device(u16 seg, u8 bus, u8 devfn); 135 136 uint8_t pci_conf_read8( 137 unsigned int seg, unsigned int bus, unsigned int dev, unsigned int func, 138 unsigned int reg); 139 uint16_t pci_conf_read16( 140 unsigned int seg, unsigned int bus, unsigned int dev, unsigned int func, 141 unsigned int reg); 142 uint32_t pci_conf_read32( 143 unsigned int seg, unsigned int bus, unsigned int dev, unsigned int func, 144 unsigned int reg); 145 void pci_conf_write8( 146 unsigned int seg, unsigned int bus, unsigned int dev, unsigned int func, 147 unsigned int reg, uint8_t data); 148 void pci_conf_write16( 149 unsigned int seg, unsigned int bus, unsigned int dev, unsigned int func, 150 unsigned int reg, uint16_t data); 151 void pci_conf_write32( 152 unsigned int seg, unsigned int bus, unsigned int dev, unsigned int func, 153 unsigned int reg, uint32_t data); 154 uint32_t pci_conf_read(uint32_t cf8, uint8_t offset, uint8_t bytes); 155 void pci_conf_write(uint32_t cf8, uint8_t offset, uint8_t bytes, uint32_t data); 156 int pci_mmcfg_read(unsigned int seg, unsigned int bus, 157 unsigned int devfn, int reg, int len, u32 *value); 158 int pci_mmcfg_write(unsigned int seg, unsigned int bus, 159 unsigned int devfn, int reg, int len, u32 value); 160 int pci_find_cap_offset(u16 seg, u8 bus, u8 dev, u8 func, u8 cap); 161 int pci_find_next_cap(u16 seg, u8 bus, unsigned int devfn, u8 pos, int cap); 162 int pci_find_ext_capability(int seg, int bus, int devfn, int cap); 163 int pci_find_next_ext_capability(int seg, int bus, int devfn, int pos, int cap); 164 const char *parse_pci(const char *, unsigned int *seg, unsigned int *bus, 165 unsigned int *dev, unsigned int *func); 166 const char *parse_pci_seg(const char *, unsigned int *seg, unsigned int *bus, 167 unsigned int *dev, unsigned int *func, bool *def_seg); 168 169 170 bool_t pcie_aer_get_firmware_first(const struct pci_dev *); 171 172 struct pirq; 173 int msixtbl_pt_register(struct domain *, struct pirq *, uint64_t gtable); 174 void msixtbl_pt_unregister(struct domain *, struct pirq *); 175 void msixtbl_pt_cleanup(struct domain *d); 176 177 #endif /* __XEN_PCI_H__ */ 178