1fd4ab1feSOlivier Matz /* SPDX-License-Identifier: BSD-3-Clause 2fd4ab1feSOlivier Matz * Copyright(c) 2017 6WIND S.A. 3c752998bSGaetan Rivet */ 4c752998bSGaetan Rivet 5c752998bSGaetan Rivet #ifndef _PCI_PRIVATE_H_ 6c752998bSGaetan Rivet #define _PCI_PRIVATE_H_ 7c752998bSGaetan Rivet 8c752998bSGaetan Rivet #include <stdbool.h> 9c752998bSGaetan Rivet #include <stdio.h> 1045d62067SDmitry Kozlyuk 11a04322f6SDavid Marchand #include <bus_driver.h> 121f37cb2bSDavid Marchand #include <bus_pci_driver.h> 13*849f773bSDavid Marchand #include <rte_log.h> 1445d62067SDmitry Kozlyuk #include <rte_os_shim.h> 1545d62067SDmitry Kozlyuk #include <rte_pci.h> 16c752998bSGaetan Rivet 17*849f773bSDavid Marchand extern int pci_bus_logtype; 18*849f773bSDavid Marchand #define RTE_LOGTYPE_PCI_BUS pci_bus_logtype 19*849f773bSDavid Marchand #define PCI_LOG(level, ...) \ 20*849f773bSDavid Marchand RTE_LOG_LINE(level, PCI_BUS, "" __VA_ARGS__) 21*849f773bSDavid Marchand 224b741542SChenbo Xia #define RTE_MAX_PCI_REGIONS 9 234b741542SChenbo Xia 2487a02023SChenbo Xia /* 2587a02023SChenbo Xia * Convert struct rte_pci_device to struct rte_pci_device_internal 2687a02023SChenbo Xia */ 2787a02023SChenbo Xia #define RTE_PCI_DEVICE_INTERNAL(ptr) \ 2887a02023SChenbo Xia container_of(ptr, struct rte_pci_device_internal, device) 2987a02023SChenbo Xia #define RTE_PCI_DEVICE_INTERNAL_CONST(ptr) \ 3087a02023SChenbo Xia container_of(ptr, const struct rte_pci_device_internal, device) 3187a02023SChenbo Xia 321f37cb2bSDavid Marchand /** 331f37cb2bSDavid Marchand * Structure describing the PCI bus 341f37cb2bSDavid Marchand */ 351f37cb2bSDavid Marchand struct rte_pci_bus { 361f37cb2bSDavid Marchand struct rte_bus bus; /**< Inherit the generic class */ 371f37cb2bSDavid Marchand RTE_TAILQ_HEAD(, rte_pci_device) device_list; /**< List of PCI devices */ 381f37cb2bSDavid Marchand RTE_TAILQ_HEAD(, rte_pci_driver) driver_list; /**< List of PCI drivers */ 391f37cb2bSDavid Marchand }; 401f37cb2bSDavid Marchand 4146521ca2SGaetan Rivet extern struct rte_pci_bus rte_pci_bus; 4246521ca2SGaetan Rivet 431f37cb2bSDavid Marchand /* PCI Bus iterators */ 441f37cb2bSDavid Marchand #define FOREACH_DEVICE_ON_PCIBUS(p) \ 451f37cb2bSDavid Marchand RTE_TAILQ_FOREACH(p, &(rte_pci_bus.device_list), next) 461f37cb2bSDavid Marchand 471f37cb2bSDavid Marchand #define FOREACH_DRIVER_ON_PCIBUS(p) \ 481f37cb2bSDavid Marchand RTE_TAILQ_FOREACH(p, &(rte_pci_bus.driver_list), next) 491f37cb2bSDavid Marchand 50c752998bSGaetan Rivet struct rte_pci_driver; 51c752998bSGaetan Rivet struct rte_pci_device; 52c752998bSGaetan Rivet 534b741542SChenbo Xia struct rte_pci_region { 544b741542SChenbo Xia uint64_t size; 554b741542SChenbo Xia uint64_t offset; 564b741542SChenbo Xia }; 574b741542SChenbo Xia 5887a02023SChenbo Xia struct rte_pci_device_internal { 5987a02023SChenbo Xia struct rte_pci_device device; 604b741542SChenbo Xia /* PCI regions provided by e.g. VFIO. */ 614b741542SChenbo Xia struct rte_pci_region region[RTE_MAX_PCI_REGIONS]; 6287a02023SChenbo Xia }; 6387a02023SChenbo Xia 64c752998bSGaetan Rivet /** 65c752998bSGaetan Rivet * Scan the content of the PCI bus, and the devices in the devices 66c752998bSGaetan Rivet * list 67c752998bSGaetan Rivet * 68c752998bSGaetan Rivet * @return 69c752998bSGaetan Rivet * 0 on success, negative on error 70c752998bSGaetan Rivet */ 71c752998bSGaetan Rivet int rte_pci_scan(void); 72c752998bSGaetan Rivet 73c752998bSGaetan Rivet /** 748f4de2dbSDavid Marchand * Set common internal information for a PCI device. 75c752998bSGaetan Rivet */ 76c752998bSGaetan Rivet void 778f4de2dbSDavid Marchand pci_common_set(struct rte_pci_device *dev); 788f4de2dbSDavid Marchand 798f4de2dbSDavid Marchand /** 808f4de2dbSDavid Marchand * Free a PCI device. 818f4de2dbSDavid Marchand */ 828f4de2dbSDavid Marchand void 8387a02023SChenbo Xia pci_free(struct rte_pci_device_internal *pdev); 84c752998bSGaetan Rivet 85c752998bSGaetan Rivet /** 86463a5245SSunil Kumar Kori * Validate whether a device with given PCI address should be ignored or not. 87463a5245SSunil Kumar Kori * 88463a5245SSunil Kumar Kori * @param pci_addr 89463a5245SSunil Kumar Kori * PCI address of device to be validated 90463a5245SSunil Kumar Kori * @return 91463a5245SSunil Kumar Kori * true: if device is to be ignored, 92463a5245SSunil Kumar Kori * false: if device is to be scanned, 93463a5245SSunil Kumar Kori */ 94463a5245SSunil Kumar Kori bool rte_pci_ignore_device(const struct rte_pci_addr *pci_addr); 95463a5245SSunil Kumar Kori 96463a5245SSunil Kumar Kori /** 97c752998bSGaetan Rivet * Add a PCI device to the PCI Bus (append to PCI Device list). This function 98c752998bSGaetan Rivet * also updates the bus references of the PCI Device (and the generic device 99c752998bSGaetan Rivet * object embedded within. 100c752998bSGaetan Rivet * 101c752998bSGaetan Rivet * @param pci_dev 102c752998bSGaetan Rivet * PCI device to add 103c752998bSGaetan Rivet * @return void 104c752998bSGaetan Rivet */ 105c752998bSGaetan Rivet void rte_pci_add_device(struct rte_pci_device *pci_dev); 106c752998bSGaetan Rivet 107c752998bSGaetan Rivet /** 108c752998bSGaetan Rivet * Insert a PCI device in the PCI Bus at a particular location in the device 109c752998bSGaetan Rivet * list. It also updates the PCI Bus reference of the new devices to be 110c752998bSGaetan Rivet * inserted. 111c752998bSGaetan Rivet * 112c752998bSGaetan Rivet * @param exist_pci_dev 113c752998bSGaetan Rivet * Existing PCI device in PCI Bus 114c752998bSGaetan Rivet * @param new_pci_dev 115c752998bSGaetan Rivet * PCI device to be added before exist_pci_dev 116c752998bSGaetan Rivet * @return void 117c752998bSGaetan Rivet */ 118c752998bSGaetan Rivet void rte_pci_insert_device(struct rte_pci_device *exist_pci_dev, 119c752998bSGaetan Rivet struct rte_pci_device *new_pci_dev); 120c752998bSGaetan Rivet 121c752998bSGaetan Rivet /** 122e1ece609SDavid Marchand * A structure describing a PCI mapping. 123e1ece609SDavid Marchand */ 124e1ece609SDavid Marchand struct pci_map { 125e1ece609SDavid Marchand void *addr; 126e1ece609SDavid Marchand char *path; 127e1ece609SDavid Marchand uint64_t offset; 128e1ece609SDavid Marchand uint64_t size; 129e1ece609SDavid Marchand uint64_t phaddr; 130f60abf97SMiao Li uint32_t nr_areas; 131f60abf97SMiao Li struct vfio_region_sparse_mmap_area *areas; 132e1ece609SDavid Marchand }; 133e1ece609SDavid Marchand 134e1ece609SDavid Marchand struct pci_msix_table { 135e1ece609SDavid Marchand int bar_index; 136e1ece609SDavid Marchand uint32_t offset; 137e1ece609SDavid Marchand uint32_t size; 138e1ece609SDavid Marchand }; 139e1ece609SDavid Marchand 140e1ece609SDavid Marchand /** 141e1ece609SDavid Marchand * A structure describing a mapped PCI resource. 142e1ece609SDavid Marchand * For multi-process we need to reproduce all PCI mappings in secondary 143e1ece609SDavid Marchand * processes, so save them in a tailq. 144e1ece609SDavid Marchand */ 145e1ece609SDavid Marchand struct mapped_pci_resource { 146e1ece609SDavid Marchand TAILQ_ENTRY(mapped_pci_resource) next; 147e1ece609SDavid Marchand 148e1ece609SDavid Marchand struct rte_pci_addr pci_addr; 149e1ece609SDavid Marchand char path[PATH_MAX]; 150e1ece609SDavid Marchand int nb_maps; 151e1ece609SDavid Marchand struct pci_map maps[PCI_MAX_RESOURCE]; 152e1ece609SDavid Marchand struct pci_msix_table msix_table; 153e1ece609SDavid Marchand }; 154e1ece609SDavid Marchand 155e1ece609SDavid Marchand /** mapped pci device list */ 156e1ece609SDavid Marchand TAILQ_HEAD(mapped_pci_res_list, mapped_pci_resource); 157e1ece609SDavid Marchand 158e1ece609SDavid Marchand /** 159e1ece609SDavid Marchand * Map a particular resource from a file. 160e1ece609SDavid Marchand * 161e1ece609SDavid Marchand * @param requested_addr 162e1ece609SDavid Marchand * The starting address for the new mapping range. 163e1ece609SDavid Marchand * @param fd 164e1ece609SDavid Marchand * The file descriptor. 165e1ece609SDavid Marchand * @param offset 166e1ece609SDavid Marchand * The offset for the mapping range. 167e1ece609SDavid Marchand * @param size 168e1ece609SDavid Marchand * The size for the mapping range. 169e1ece609SDavid Marchand * @param additional_flags 170e1ece609SDavid Marchand * The additional rte_mem_map() flags for the mapping range. 171e1ece609SDavid Marchand * @return 172e1ece609SDavid Marchand * - On success, the function returns a pointer to the mapped area. 173e200535cSDavid Marchand * - On error, NULL is returned. 174e1ece609SDavid Marchand */ 175e1ece609SDavid Marchand void *pci_map_resource(void *requested_addr, int fd, off_t offset, 176e1ece609SDavid Marchand size_t size, int additional_flags); 177e1ece609SDavid Marchand 178e1ece609SDavid Marchand /** 179e1ece609SDavid Marchand * Unmap a particular resource. 180e1ece609SDavid Marchand * 181e1ece609SDavid Marchand * @param requested_addr 182e1ece609SDavid Marchand * The address for the unmapping range. 183e1ece609SDavid Marchand * @param size 184e1ece609SDavid Marchand * The size for the unmapping range. 185e1ece609SDavid Marchand */ 186e1ece609SDavid Marchand void pci_unmap_resource(void *requested_addr, size_t size); 187e1ece609SDavid Marchand 188e1ece609SDavid Marchand /** 189c752998bSGaetan Rivet * Map the PCI resource of a PCI device in virtual memory 190c752998bSGaetan Rivet * 191c752998bSGaetan Rivet * This function is private to EAL. 192c752998bSGaetan Rivet * 193c752998bSGaetan Rivet * @return 194c752998bSGaetan Rivet * 0 on success, negative on error 195c752998bSGaetan Rivet */ 196c752998bSGaetan Rivet int pci_uio_map_resource(struct rte_pci_device *dev); 197c752998bSGaetan Rivet 198c752998bSGaetan Rivet /** 199c752998bSGaetan Rivet * Unmap the PCI resource of a PCI device 200c752998bSGaetan Rivet * 201c752998bSGaetan Rivet * This function is private to EAL. 202c752998bSGaetan Rivet */ 203c752998bSGaetan Rivet void pci_uio_unmap_resource(struct rte_pci_device *dev); 204c752998bSGaetan Rivet 205c752998bSGaetan Rivet /** 206c752998bSGaetan Rivet * Allocate uio resource for PCI device 207c752998bSGaetan Rivet * 208c752998bSGaetan Rivet * This function is private to EAL. 209c752998bSGaetan Rivet * 210c752998bSGaetan Rivet * @param dev 211c752998bSGaetan Rivet * PCI device to allocate uio resource 212c752998bSGaetan Rivet * @param uio_res 213c752998bSGaetan Rivet * Pointer to uio resource. 214c752998bSGaetan Rivet * If the function returns 0, the pointer will be filled. 215c752998bSGaetan Rivet * @return 216c752998bSGaetan Rivet * 0 on success, negative on error 217c752998bSGaetan Rivet */ 218c752998bSGaetan Rivet int pci_uio_alloc_resource(struct rte_pci_device *dev, 219c752998bSGaetan Rivet struct mapped_pci_resource **uio_res); 220c752998bSGaetan Rivet 221c752998bSGaetan Rivet /** 222c752998bSGaetan Rivet * Free uio resource for PCI device 223c752998bSGaetan Rivet * 224c752998bSGaetan Rivet * This function is private to EAL. 225c752998bSGaetan Rivet * 226c752998bSGaetan Rivet * @param dev 227c752998bSGaetan Rivet * PCI device to free uio resource 228c752998bSGaetan Rivet * @param uio_res 229c752998bSGaetan Rivet * Pointer to uio resource. 230c752998bSGaetan Rivet */ 231c752998bSGaetan Rivet void pci_uio_free_resource(struct rte_pci_device *dev, 232c752998bSGaetan Rivet struct mapped_pci_resource *uio_res); 233c752998bSGaetan Rivet 234c752998bSGaetan Rivet /** 235b01dc3daSJeff Guo * Remap the PCI resource of a PCI device in anonymous virtual memory. 236b01dc3daSJeff Guo * 237b01dc3daSJeff Guo * @param dev 238b01dc3daSJeff Guo * Point to the struct rte pci device. 239b01dc3daSJeff Guo * @return 240b01dc3daSJeff Guo * - On success, zero. 241b01dc3daSJeff Guo * - On failure, a negative value. 242b01dc3daSJeff Guo */ 243b01dc3daSJeff Guo int 244b01dc3daSJeff Guo pci_uio_remap_resource(struct rte_pci_device *dev); 245b01dc3daSJeff Guo 246b01dc3daSJeff Guo /** 247c752998bSGaetan Rivet * Map device memory to uio resource 248c752998bSGaetan Rivet * 249c752998bSGaetan Rivet * This function is private to EAL. 250c752998bSGaetan Rivet * 251c752998bSGaetan Rivet * @param dev 252c752998bSGaetan Rivet * PCI device that has memory information. 253c752998bSGaetan Rivet * @param res_idx 254c752998bSGaetan Rivet * Memory resource index of the PCI device. 255c752998bSGaetan Rivet * @param uio_res 256c752998bSGaetan Rivet * uio resource that will keep mapping information. 257c752998bSGaetan Rivet * @param map_idx 258c752998bSGaetan Rivet * Mapping information index of the uio resource. 259c752998bSGaetan Rivet * @return 260c752998bSGaetan Rivet * 0 on success, negative on error 261c752998bSGaetan Rivet */ 262c752998bSGaetan Rivet int pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx, 263c752998bSGaetan Rivet struct mapped_pci_resource *uio_res, int map_idx); 264c752998bSGaetan Rivet 265c752998bSGaetan Rivet /* 266c752998bSGaetan Rivet * Match the PCI Driver and Device using the ID Table 267c752998bSGaetan Rivet * 268c752998bSGaetan Rivet * @param pci_drv 269c752998bSGaetan Rivet * PCI driver from which ID table would be extracted 270c752998bSGaetan Rivet * @param pci_dev 271c752998bSGaetan Rivet * PCI device to match against the driver 272c752998bSGaetan Rivet * @return 273c752998bSGaetan Rivet * 1 for successful match 274c752998bSGaetan Rivet * 0 for unsuccessful match 275c752998bSGaetan Rivet */ 276c752998bSGaetan Rivet int 277c752998bSGaetan Rivet rte_pci_match(const struct rte_pci_driver *pci_drv, 278c752998bSGaetan Rivet const struct rte_pci_device *pci_dev); 279c752998bSGaetan Rivet 280c752998bSGaetan Rivet /** 28166d3724bSDavid Marchand * OS specific callbacks for rte_pci_get_iommu_class 282703458e1SBen Walker * 283703458e1SBen Walker */ 28466d3724bSDavid Marchand bool 28566d3724bSDavid Marchand pci_device_iommu_support_va(const struct rte_pci_device *dev); 28666d3724bSDavid Marchand 287703458e1SBen Walker enum rte_iova_mode 288703458e1SBen Walker pci_device_iova_mode(const struct rte_pci_driver *pci_drv, 289703458e1SBen Walker const struct rte_pci_device *pci_dev); 290703458e1SBen Walker 291703458e1SBen Walker /** 292c752998bSGaetan Rivet * Get iommu class of PCI devices on the bus. 293c752998bSGaetan Rivet * And return their preferred iova mapping mode. 294c752998bSGaetan Rivet * 295c752998bSGaetan Rivet * @return 296c752998bSGaetan Rivet * - enum rte_iova_mode. 297c752998bSGaetan Rivet */ 298c752998bSGaetan Rivet enum rte_iova_mode 299c752998bSGaetan Rivet rte_pci_get_iommu_class(void); 300c752998bSGaetan Rivet 30146521ca2SGaetan Rivet /* 30246521ca2SGaetan Rivet * Iterate over internal devices, 30346521ca2SGaetan Rivet * matching any device against the provided 30446521ca2SGaetan Rivet * string. 30546521ca2SGaetan Rivet * 30646521ca2SGaetan Rivet * @param start 30746521ca2SGaetan Rivet * Iteration starting point. 30846521ca2SGaetan Rivet * 30946521ca2SGaetan Rivet * @param str 31046521ca2SGaetan Rivet * Device string to match against. 31146521ca2SGaetan Rivet * 31246521ca2SGaetan Rivet * @param it 31346521ca2SGaetan Rivet * (unused) iterator structure. 31446521ca2SGaetan Rivet * 31546521ca2SGaetan Rivet * @return 31646521ca2SGaetan Rivet * A pointer to the next matching device if any. 31746521ca2SGaetan Rivet * NULL otherwise. 31846521ca2SGaetan Rivet */ 31946521ca2SGaetan Rivet void * 32046521ca2SGaetan Rivet rte_pci_dev_iterate(const void *start, 32146521ca2SGaetan Rivet const char *str, 32246521ca2SGaetan Rivet const struct rte_dev_iterator *it); 32346521ca2SGaetan Rivet 324d2a66ad7SXueming Li /* 325d2a66ad7SXueming Li * Parse device arguments and update name. 326d2a66ad7SXueming Li * 327d2a66ad7SXueming Li * @param da 328d2a66ad7SXueming Li * device arguments to parse. 329d2a66ad7SXueming Li * 330d2a66ad7SXueming Li * @return 331d2a66ad7SXueming Li * 0 on success. 332d2a66ad7SXueming Li * -EINVAL: kvargs string is invalid and cannot be parsed. 333d2a66ad7SXueming Li * -ENODEV: no key matching a device ID is found in the kv list. 334d2a66ad7SXueming Li */ 335d2a66ad7SXueming Li int 336d2a66ad7SXueming Li rte_pci_devargs_parse(struct rte_devargs *da); 337d2a66ad7SXueming Li 338c752998bSGaetan Rivet #endif /* _PCI_PRIVATE_H_ */ 339