1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2010-2014 Intel Corporation 3 */ 4 5 #include <string.h> 6 #include <dirent.h> 7 8 #include <rte_log.h> 9 #include <rte_bus.h> 10 #include <rte_pci.h> 11 #include <rte_bus_pci.h> 12 #include <rte_eal_memconfig.h> 13 #include <rte_malloc.h> 14 #include <rte_devargs.h> 15 #include <rte_memcpy.h> 16 #include <rte_vfio.h> 17 18 #include "eal_filesystem.h" 19 20 #include "private.h" 21 #include "pci_init.h" 22 23 /** 24 * @file 25 * PCI probing under linux 26 * 27 * This code is used to simulate a PCI probe by parsing information in sysfs. 28 * When a registered device matches a driver, it is then initialized with 29 * IGB_UIO driver (or doesn't initialize, if the device wasn't bound to it). 30 */ 31 32 extern struct rte_pci_bus rte_pci_bus; 33 34 static int 35 pci_get_kernel_driver_by_path(const char *filename, char *dri_name, 36 size_t len) 37 { 38 int count; 39 char path[PATH_MAX]; 40 char *name; 41 42 if (!filename || !dri_name) 43 return -1; 44 45 count = readlink(filename, path, PATH_MAX); 46 if (count >= PATH_MAX) 47 return -1; 48 49 /* For device does not have a driver */ 50 if (count < 0) 51 return 1; 52 53 path[count] = '\0'; 54 55 name = strrchr(path, '/'); 56 if (name) { 57 strlcpy(dri_name, name + 1, len); 58 return 0; 59 } 60 61 return -1; 62 } 63 64 /* Map pci device */ 65 int 66 rte_pci_map_device(struct rte_pci_device *dev) 67 { 68 int ret = -1; 69 70 /* try mapping the NIC resources using VFIO if it exists */ 71 switch (dev->kdrv) { 72 case RTE_KDRV_VFIO: 73 #ifdef VFIO_PRESENT 74 if (pci_vfio_is_enabled()) 75 ret = pci_vfio_map_resource(dev); 76 #endif 77 break; 78 case RTE_KDRV_IGB_UIO: 79 case RTE_KDRV_UIO_GENERIC: 80 if (rte_eal_using_phys_addrs()) { 81 /* map resources for devices that use uio */ 82 ret = pci_uio_map_resource(dev); 83 } 84 break; 85 default: 86 RTE_LOG(DEBUG, EAL, 87 " Not managed by a supported kernel driver, skipped\n"); 88 ret = 1; 89 break; 90 } 91 92 return ret; 93 } 94 95 /* Unmap pci device */ 96 void 97 rte_pci_unmap_device(struct rte_pci_device *dev) 98 { 99 /* try unmapping the NIC resources using VFIO if it exists */ 100 switch (dev->kdrv) { 101 case RTE_KDRV_VFIO: 102 #ifdef VFIO_PRESENT 103 if (pci_vfio_is_enabled()) 104 pci_vfio_unmap_resource(dev); 105 #endif 106 break; 107 case RTE_KDRV_IGB_UIO: 108 case RTE_KDRV_UIO_GENERIC: 109 /* unmap resources for devices that use uio */ 110 pci_uio_unmap_resource(dev); 111 break; 112 default: 113 RTE_LOG(DEBUG, EAL, 114 " Not managed by a supported kernel driver, skipped\n"); 115 break; 116 } 117 } 118 119 static int 120 find_max_end_va(const struct rte_memseg_list *msl, void *arg) 121 { 122 size_t sz = msl->len; 123 void *end_va = RTE_PTR_ADD(msl->base_va, sz); 124 void **max_va = arg; 125 126 if (*max_va < end_va) 127 *max_va = end_va; 128 return 0; 129 } 130 131 void * 132 pci_find_max_end_va(void) 133 { 134 void *va = NULL; 135 136 rte_memseg_list_walk(find_max_end_va, &va); 137 return va; 138 } 139 140 141 /* parse one line of the "resource" sysfs file (note that the 'line' 142 * string is modified) 143 */ 144 int 145 pci_parse_one_sysfs_resource(char *line, size_t len, uint64_t *phys_addr, 146 uint64_t *end_addr, uint64_t *flags) 147 { 148 union pci_resource_info { 149 struct { 150 char *phys_addr; 151 char *end_addr; 152 char *flags; 153 }; 154 char *ptrs[PCI_RESOURCE_FMT_NVAL]; 155 } res_info; 156 157 if (rte_strsplit(line, len, res_info.ptrs, 3, ' ') != 3) { 158 RTE_LOG(ERR, EAL, 159 "%s(): bad resource format\n", __func__); 160 return -1; 161 } 162 errno = 0; 163 *phys_addr = strtoull(res_info.phys_addr, NULL, 16); 164 *end_addr = strtoull(res_info.end_addr, NULL, 16); 165 *flags = strtoull(res_info.flags, NULL, 16); 166 if (errno != 0) { 167 RTE_LOG(ERR, EAL, 168 "%s(): bad resource format\n", __func__); 169 return -1; 170 } 171 172 return 0; 173 } 174 175 /* parse the "resource" sysfs file */ 176 static int 177 pci_parse_sysfs_resource(const char *filename, struct rte_pci_device *dev) 178 { 179 FILE *f; 180 char buf[BUFSIZ]; 181 int i; 182 uint64_t phys_addr, end_addr, flags; 183 184 f = fopen(filename, "r"); 185 if (f == NULL) { 186 RTE_LOG(ERR, EAL, "Cannot open sysfs resource\n"); 187 return -1; 188 } 189 190 for (i = 0; i<PCI_MAX_RESOURCE; i++) { 191 192 if (fgets(buf, sizeof(buf), f) == NULL) { 193 RTE_LOG(ERR, EAL, 194 "%s(): cannot read resource\n", __func__); 195 goto error; 196 } 197 if (pci_parse_one_sysfs_resource(buf, sizeof(buf), &phys_addr, 198 &end_addr, &flags) < 0) 199 goto error; 200 201 if (flags & IORESOURCE_MEM) { 202 dev->mem_resource[i].phys_addr = phys_addr; 203 dev->mem_resource[i].len = end_addr - phys_addr + 1; 204 /* not mapped for now */ 205 dev->mem_resource[i].addr = NULL; 206 } 207 } 208 fclose(f); 209 return 0; 210 211 error: 212 fclose(f); 213 return -1; 214 } 215 216 /* Scan one pci sysfs entry, and fill the devices list from it. */ 217 static int 218 pci_scan_one(const char *dirname, const struct rte_pci_addr *addr) 219 { 220 char filename[PATH_MAX]; 221 unsigned long tmp; 222 struct rte_pci_device *dev; 223 char driver[PATH_MAX]; 224 int ret; 225 226 dev = malloc(sizeof(*dev)); 227 if (dev == NULL) 228 return -1; 229 230 memset(dev, 0, sizeof(*dev)); 231 dev->device.bus = &rte_pci_bus.bus; 232 dev->addr = *addr; 233 234 /* get vendor id */ 235 snprintf(filename, sizeof(filename), "%s/vendor", dirname); 236 if (eal_parse_sysfs_value(filename, &tmp) < 0) { 237 free(dev); 238 return -1; 239 } 240 dev->id.vendor_id = (uint16_t)tmp; 241 242 /* get device id */ 243 snprintf(filename, sizeof(filename), "%s/device", dirname); 244 if (eal_parse_sysfs_value(filename, &tmp) < 0) { 245 free(dev); 246 return -1; 247 } 248 dev->id.device_id = (uint16_t)tmp; 249 250 /* get subsystem_vendor id */ 251 snprintf(filename, sizeof(filename), "%s/subsystem_vendor", 252 dirname); 253 if (eal_parse_sysfs_value(filename, &tmp) < 0) { 254 free(dev); 255 return -1; 256 } 257 dev->id.subsystem_vendor_id = (uint16_t)tmp; 258 259 /* get subsystem_device id */ 260 snprintf(filename, sizeof(filename), "%s/subsystem_device", 261 dirname); 262 if (eal_parse_sysfs_value(filename, &tmp) < 0) { 263 free(dev); 264 return -1; 265 } 266 dev->id.subsystem_device_id = (uint16_t)tmp; 267 268 /* get class_id */ 269 snprintf(filename, sizeof(filename), "%s/class", 270 dirname); 271 if (eal_parse_sysfs_value(filename, &tmp) < 0) { 272 free(dev); 273 return -1; 274 } 275 /* the least 24 bits are valid: class, subclass, program interface */ 276 dev->id.class_id = (uint32_t)tmp & RTE_CLASS_ANY_ID; 277 278 /* get max_vfs */ 279 dev->max_vfs = 0; 280 snprintf(filename, sizeof(filename), "%s/max_vfs", dirname); 281 if (!access(filename, F_OK) && 282 eal_parse_sysfs_value(filename, &tmp) == 0) 283 dev->max_vfs = (uint16_t)tmp; 284 else { 285 /* for non igb_uio driver, need kernel version >= 3.8 */ 286 snprintf(filename, sizeof(filename), 287 "%s/sriov_numvfs", dirname); 288 if (!access(filename, F_OK) && 289 eal_parse_sysfs_value(filename, &tmp) == 0) 290 dev->max_vfs = (uint16_t)tmp; 291 } 292 293 /* get numa node, default to 0 if not present */ 294 snprintf(filename, sizeof(filename), "%s/numa_node", 295 dirname); 296 297 if (access(filename, F_OK) != -1) { 298 if (eal_parse_sysfs_value(filename, &tmp) == 0) 299 dev->device.numa_node = tmp; 300 else 301 dev->device.numa_node = -1; 302 } else { 303 dev->device.numa_node = 0; 304 } 305 306 pci_name_set(dev); 307 308 /* parse resources */ 309 snprintf(filename, sizeof(filename), "%s/resource", dirname); 310 if (pci_parse_sysfs_resource(filename, dev) < 0) { 311 RTE_LOG(ERR, EAL, "%s(): cannot parse resource\n", __func__); 312 free(dev); 313 return -1; 314 } 315 316 /* parse driver */ 317 snprintf(filename, sizeof(filename), "%s/driver", dirname); 318 ret = pci_get_kernel_driver_by_path(filename, driver, sizeof(driver)); 319 if (ret < 0) { 320 RTE_LOG(ERR, EAL, "Fail to get kernel driver\n"); 321 free(dev); 322 return -1; 323 } 324 325 if (!ret) { 326 if (!strcmp(driver, "vfio-pci")) 327 dev->kdrv = RTE_KDRV_VFIO; 328 else if (!strcmp(driver, "igb_uio")) 329 dev->kdrv = RTE_KDRV_IGB_UIO; 330 else if (!strcmp(driver, "uio_pci_generic")) 331 dev->kdrv = RTE_KDRV_UIO_GENERIC; 332 else if (!strcmp(driver, "mlx4_core") || 333 !strcmp(driver, "mlx5_core")) 334 dev->kdrv = RTE_KDRV_NIC_MLX; 335 else 336 dev->kdrv = RTE_KDRV_UNKNOWN; 337 } else 338 dev->kdrv = RTE_KDRV_NONE; 339 340 /* device is valid, add in list (sorted) */ 341 if (TAILQ_EMPTY(&rte_pci_bus.device_list)) { 342 rte_pci_add_device(dev); 343 } else { 344 struct rte_pci_device *dev2; 345 int ret; 346 347 TAILQ_FOREACH(dev2, &rte_pci_bus.device_list, next) { 348 ret = rte_pci_addr_cmp(&dev->addr, &dev2->addr); 349 if (ret > 0) 350 continue; 351 352 if (ret < 0) { 353 rte_pci_insert_device(dev2, dev); 354 } else { /* already registered */ 355 if (!rte_dev_is_probed(&dev2->device)) { 356 dev2->kdrv = dev->kdrv; 357 dev2->max_vfs = dev->max_vfs; 358 pci_name_set(dev2); 359 memmove(dev2->mem_resource, 360 dev->mem_resource, 361 sizeof(dev->mem_resource)); 362 } else { 363 /** 364 * If device is plugged and driver is 365 * probed already, (This happens when 366 * we call rte_dev_probe which will 367 * scan all device on the bus) we don't 368 * need to do anything here unless... 369 **/ 370 if (dev2->kdrv != dev->kdrv || 371 dev2->max_vfs != dev->max_vfs) 372 /* 373 * This should not happens. 374 * But it is still possible if 375 * we unbind a device from 376 * vfio or uio before hotplug 377 * remove and rebind it with 378 * a different configure. 379 * So we just print out the 380 * error as an alarm. 381 */ 382 RTE_LOG(ERR, EAL, "Unexpected device scan at %s!\n", 383 filename); 384 } 385 free(dev); 386 } 387 return 0; 388 } 389 390 rte_pci_add_device(dev); 391 } 392 393 return 0; 394 } 395 396 int 397 pci_update_device(const struct rte_pci_addr *addr) 398 { 399 char filename[PATH_MAX]; 400 401 snprintf(filename, sizeof(filename), "%s/" PCI_PRI_FMT, 402 rte_pci_get_sysfs_path(), addr->domain, addr->bus, addr->devid, 403 addr->function); 404 405 return pci_scan_one(filename, addr); 406 } 407 408 /* 409 * split up a pci address into its constituent parts. 410 */ 411 static int 412 parse_pci_addr_format(const char *buf, int bufsize, struct rte_pci_addr *addr) 413 { 414 /* first split on ':' */ 415 union splitaddr { 416 struct { 417 char *domain; 418 char *bus; 419 char *devid; 420 char *function; 421 }; 422 char *str[PCI_FMT_NVAL]; /* last element-separator is "." not ":" */ 423 } splitaddr; 424 425 char *buf_copy = strndup(buf, bufsize); 426 if (buf_copy == NULL) 427 return -1; 428 429 if (rte_strsplit(buf_copy, bufsize, splitaddr.str, PCI_FMT_NVAL, ':') 430 != PCI_FMT_NVAL - 1) 431 goto error; 432 /* final split is on '.' between devid and function */ 433 splitaddr.function = strchr(splitaddr.devid,'.'); 434 if (splitaddr.function == NULL) 435 goto error; 436 *splitaddr.function++ = '\0'; 437 438 /* now convert to int values */ 439 errno = 0; 440 addr->domain = strtoul(splitaddr.domain, NULL, 16); 441 addr->bus = strtoul(splitaddr.bus, NULL, 16); 442 addr->devid = strtoul(splitaddr.devid, NULL, 16); 443 addr->function = strtoul(splitaddr.function, NULL, 10); 444 if (errno != 0) 445 goto error; 446 447 free(buf_copy); /* free the copy made with strdup */ 448 return 0; 449 error: 450 free(buf_copy); 451 return -1; 452 } 453 454 /* 455 * Scan the content of the PCI bus, and the devices in the devices 456 * list 457 */ 458 int 459 rte_pci_scan(void) 460 { 461 struct dirent *e; 462 DIR *dir; 463 char dirname[PATH_MAX]; 464 struct rte_pci_addr addr; 465 466 /* for debug purposes, PCI can be disabled */ 467 if (!rte_eal_has_pci()) 468 return 0; 469 470 #ifdef VFIO_PRESENT 471 if (!pci_vfio_is_enabled()) 472 RTE_LOG(DEBUG, EAL, "VFIO PCI modules not loaded\n"); 473 #endif 474 475 dir = opendir(rte_pci_get_sysfs_path()); 476 if (dir == NULL) { 477 RTE_LOG(ERR, EAL, "%s(): opendir failed: %s\n", 478 __func__, strerror(errno)); 479 return -1; 480 } 481 482 while ((e = readdir(dir)) != NULL) { 483 if (e->d_name[0] == '.') 484 continue; 485 486 if (parse_pci_addr_format(e->d_name, sizeof(e->d_name), &addr) != 0) 487 continue; 488 489 snprintf(dirname, sizeof(dirname), "%s/%s", 490 rte_pci_get_sysfs_path(), e->d_name); 491 492 if (pci_scan_one(dirname, &addr) < 0) 493 goto error; 494 } 495 closedir(dir); 496 return 0; 497 498 error: 499 closedir(dir); 500 return -1; 501 } 502 503 /* 504 * Is pci device bound to any kdrv 505 */ 506 static inline int 507 pci_one_device_is_bound(void) 508 { 509 struct rte_pci_device *dev = NULL; 510 int ret = 0; 511 512 FOREACH_DEVICE_ON_PCIBUS(dev) { 513 if (dev->kdrv == RTE_KDRV_UNKNOWN || 514 dev->kdrv == RTE_KDRV_NONE) { 515 continue; 516 } else { 517 ret = 1; 518 break; 519 } 520 } 521 return ret; 522 } 523 524 /* 525 * Any one of the device bound to uio 526 */ 527 static inline int 528 pci_one_device_bound_uio(void) 529 { 530 struct rte_pci_device *dev = NULL; 531 struct rte_devargs *devargs; 532 int need_check; 533 534 FOREACH_DEVICE_ON_PCIBUS(dev) { 535 devargs = dev->device.devargs; 536 537 need_check = 0; 538 switch (rte_pci_bus.bus.conf.scan_mode) { 539 case RTE_BUS_SCAN_WHITELIST: 540 if (devargs && devargs->policy == RTE_DEV_WHITELISTED) 541 need_check = 1; 542 break; 543 case RTE_BUS_SCAN_UNDEFINED: 544 case RTE_BUS_SCAN_BLACKLIST: 545 if (devargs == NULL || 546 devargs->policy != RTE_DEV_BLACKLISTED) 547 need_check = 1; 548 break; 549 } 550 551 if (!need_check) 552 continue; 553 554 if (dev->kdrv == RTE_KDRV_IGB_UIO || 555 dev->kdrv == RTE_KDRV_UIO_GENERIC) { 556 return 1; 557 } 558 } 559 return 0; 560 } 561 562 /* 563 * Any one of the device has iova as va 564 */ 565 static inline int 566 pci_one_device_has_iova_va(void) 567 { 568 struct rte_pci_device *dev = NULL; 569 struct rte_pci_driver *drv = NULL; 570 571 FOREACH_DRIVER_ON_PCIBUS(drv) { 572 if (drv && drv->drv_flags & RTE_PCI_DRV_IOVA_AS_VA) { 573 FOREACH_DEVICE_ON_PCIBUS(dev) { 574 if ((dev->kdrv == RTE_KDRV_VFIO || 575 dev->kdrv == RTE_KDRV_NIC_MLX) && 576 rte_pci_match(drv, dev)) 577 return 1; 578 } 579 } 580 } 581 return 0; 582 } 583 584 #if defined(RTE_ARCH_X86) 585 static bool 586 pci_one_device_iommu_support_va(struct rte_pci_device *dev) 587 { 588 #define VTD_CAP_MGAW_SHIFT 16 589 #define VTD_CAP_MGAW_MASK (0x3fULL << VTD_CAP_MGAW_SHIFT) 590 #define X86_VA_WIDTH 47 /* From Documentation/x86/x86_64/mm.txt */ 591 struct rte_pci_addr *addr = &dev->addr; 592 char filename[PATH_MAX]; 593 FILE *fp; 594 uint64_t mgaw, vtd_cap_reg = 0; 595 596 snprintf(filename, sizeof(filename), 597 "%s/" PCI_PRI_FMT "/iommu/intel-iommu/cap", 598 rte_pci_get_sysfs_path(), addr->domain, addr->bus, addr->devid, 599 addr->function); 600 if (access(filename, F_OK) == -1) { 601 /* We don't have an Intel IOMMU, assume VA supported*/ 602 return true; 603 } 604 605 /* We have an intel IOMMU */ 606 fp = fopen(filename, "r"); 607 if (fp == NULL) { 608 RTE_LOG(ERR, EAL, "%s(): can't open %s\n", __func__, filename); 609 return false; 610 } 611 612 if (fscanf(fp, "%" PRIx64, &vtd_cap_reg) != 1) { 613 RTE_LOG(ERR, EAL, "%s(): can't read %s\n", __func__, filename); 614 fclose(fp); 615 return false; 616 } 617 618 fclose(fp); 619 620 mgaw = ((vtd_cap_reg & VTD_CAP_MGAW_MASK) >> VTD_CAP_MGAW_SHIFT) + 1; 621 622 /* 623 * Assuming there is no limitation by now. We can not know at this point 624 * because the memory has not been initialized yet. Setting the dma mask 625 * will force a check once memory initialization is done. We can not do 626 * a fallback to IOVA PA now, but if the dma check fails, the error 627 * message should advice for using '--iova-mode pa' if IOVA VA is the 628 * current mode. 629 */ 630 rte_mem_set_dma_mask(mgaw); 631 return true; 632 } 633 #elif defined(RTE_ARCH_PPC_64) 634 static bool 635 pci_one_device_iommu_support_va(__rte_unused struct rte_pci_device *dev) 636 { 637 return false; 638 } 639 #else 640 static bool 641 pci_one_device_iommu_support_va(__rte_unused struct rte_pci_device *dev) 642 { 643 return true; 644 } 645 #endif 646 647 /* 648 * All devices IOMMUs support VA as IOVA 649 */ 650 static bool 651 pci_devices_iommu_support_va(void) 652 { 653 struct rte_pci_device *dev = NULL; 654 struct rte_pci_driver *drv = NULL; 655 656 FOREACH_DRIVER_ON_PCIBUS(drv) { 657 FOREACH_DEVICE_ON_PCIBUS(dev) { 658 if (!rte_pci_match(drv, dev)) 659 continue; 660 /* 661 * just one PCI device needs to be checked out because 662 * the IOMMU hardware is the same for all of them. 663 */ 664 return pci_one_device_iommu_support_va(dev); 665 } 666 } 667 return true; 668 } 669 670 /* 671 * Get iommu class of PCI devices on the bus. 672 */ 673 enum rte_iova_mode 674 rte_pci_get_iommu_class(void) 675 { 676 bool is_bound; 677 bool is_vfio_noiommu_enabled = true; 678 bool has_iova_va; 679 bool is_bound_uio; 680 bool iommu_no_va; 681 682 is_bound = pci_one_device_is_bound(); 683 if (!is_bound) 684 return RTE_IOVA_DC; 685 686 has_iova_va = pci_one_device_has_iova_va(); 687 is_bound_uio = pci_one_device_bound_uio(); 688 iommu_no_va = !pci_devices_iommu_support_va(); 689 #ifdef VFIO_PRESENT 690 is_vfio_noiommu_enabled = rte_vfio_noiommu_is_enabled() == true ? 691 true : false; 692 #endif 693 694 if (has_iova_va && !is_bound_uio && !is_vfio_noiommu_enabled && 695 !iommu_no_va) 696 return RTE_IOVA_VA; 697 698 if (has_iova_va) { 699 RTE_LOG(WARNING, EAL, "Some devices want iova as va but pa will be used because.. "); 700 if (is_vfio_noiommu_enabled) 701 RTE_LOG(WARNING, EAL, "vfio-noiommu mode configured\n"); 702 if (is_bound_uio) 703 RTE_LOG(WARNING, EAL, "few device bound to UIO\n"); 704 if (iommu_no_va) 705 RTE_LOG(WARNING, EAL, "IOMMU does not support IOVA as VA\n"); 706 } 707 708 return RTE_IOVA_PA; 709 } 710 711 /* Read PCI config space. */ 712 int rte_pci_read_config(const struct rte_pci_device *device, 713 void *buf, size_t len, off_t offset) 714 { 715 char devname[RTE_DEV_NAME_MAX_LEN] = ""; 716 const struct rte_intr_handle *intr_handle = &device->intr_handle; 717 718 switch (device->kdrv) { 719 case RTE_KDRV_IGB_UIO: 720 case RTE_KDRV_UIO_GENERIC: 721 return pci_uio_read_config(intr_handle, buf, len, offset); 722 #ifdef VFIO_PRESENT 723 case RTE_KDRV_VFIO: 724 return pci_vfio_read_config(intr_handle, buf, len, offset); 725 #endif 726 default: 727 rte_pci_device_name(&device->addr, devname, 728 RTE_DEV_NAME_MAX_LEN); 729 RTE_LOG(ERR, EAL, 730 "Unknown driver type for %s\n", devname); 731 return -1; 732 } 733 } 734 735 /* Write PCI config space. */ 736 int rte_pci_write_config(const struct rte_pci_device *device, 737 const void *buf, size_t len, off_t offset) 738 { 739 char devname[RTE_DEV_NAME_MAX_LEN] = ""; 740 const struct rte_intr_handle *intr_handle = &device->intr_handle; 741 742 switch (device->kdrv) { 743 case RTE_KDRV_IGB_UIO: 744 case RTE_KDRV_UIO_GENERIC: 745 return pci_uio_write_config(intr_handle, buf, len, offset); 746 #ifdef VFIO_PRESENT 747 case RTE_KDRV_VFIO: 748 return pci_vfio_write_config(intr_handle, buf, len, offset); 749 #endif 750 default: 751 rte_pci_device_name(&device->addr, devname, 752 RTE_DEV_NAME_MAX_LEN); 753 RTE_LOG(ERR, EAL, 754 "Unknown driver type for %s\n", devname); 755 return -1; 756 } 757 } 758 759 #if defined(RTE_ARCH_X86) 760 static int 761 pci_ioport_map(struct rte_pci_device *dev, int bar __rte_unused, 762 struct rte_pci_ioport *p) 763 { 764 uint16_t start, end; 765 FILE *fp; 766 char *line = NULL; 767 char pci_id[16]; 768 int found = 0; 769 size_t linesz; 770 771 snprintf(pci_id, sizeof(pci_id), PCI_PRI_FMT, 772 dev->addr.domain, dev->addr.bus, 773 dev->addr.devid, dev->addr.function); 774 775 fp = fopen("/proc/ioports", "r"); 776 if (fp == NULL) { 777 RTE_LOG(ERR, EAL, "%s(): can't open ioports\n", __func__); 778 return -1; 779 } 780 781 while (getdelim(&line, &linesz, '\n', fp) > 0) { 782 char *ptr = line; 783 char *left; 784 int n; 785 786 n = strcspn(ptr, ":"); 787 ptr[n] = 0; 788 left = &ptr[n + 1]; 789 790 while (*left && isspace(*left)) 791 left++; 792 793 if (!strncmp(left, pci_id, strlen(pci_id))) { 794 found = 1; 795 796 while (*ptr && isspace(*ptr)) 797 ptr++; 798 799 sscanf(ptr, "%04hx-%04hx", &start, &end); 800 801 break; 802 } 803 } 804 805 free(line); 806 fclose(fp); 807 808 if (!found) 809 return -1; 810 811 p->base = start; 812 RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%x\n", start); 813 814 return 0; 815 } 816 #endif 817 818 int 819 rte_pci_ioport_map(struct rte_pci_device *dev, int bar, 820 struct rte_pci_ioport *p) 821 { 822 int ret = -1; 823 824 switch (dev->kdrv) { 825 #ifdef VFIO_PRESENT 826 case RTE_KDRV_VFIO: 827 if (pci_vfio_is_enabled()) 828 ret = pci_vfio_ioport_map(dev, bar, p); 829 break; 830 #endif 831 case RTE_KDRV_IGB_UIO: 832 ret = pci_uio_ioport_map(dev, bar, p); 833 break; 834 case RTE_KDRV_UIO_GENERIC: 835 #if defined(RTE_ARCH_X86) 836 ret = pci_ioport_map(dev, bar, p); 837 #else 838 ret = pci_uio_ioport_map(dev, bar, p); 839 #endif 840 break; 841 case RTE_KDRV_NONE: 842 #if defined(RTE_ARCH_X86) 843 ret = pci_ioport_map(dev, bar, p); 844 #endif 845 break; 846 default: 847 break; 848 } 849 850 if (!ret) 851 p->dev = dev; 852 853 return ret; 854 } 855 856 void 857 rte_pci_ioport_read(struct rte_pci_ioport *p, 858 void *data, size_t len, off_t offset) 859 { 860 switch (p->dev->kdrv) { 861 #ifdef VFIO_PRESENT 862 case RTE_KDRV_VFIO: 863 pci_vfio_ioport_read(p, data, len, offset); 864 break; 865 #endif 866 case RTE_KDRV_IGB_UIO: 867 pci_uio_ioport_read(p, data, len, offset); 868 break; 869 case RTE_KDRV_UIO_GENERIC: 870 pci_uio_ioport_read(p, data, len, offset); 871 break; 872 case RTE_KDRV_NONE: 873 #if defined(RTE_ARCH_X86) 874 pci_uio_ioport_read(p, data, len, offset); 875 #endif 876 break; 877 default: 878 break; 879 } 880 } 881 882 void 883 rte_pci_ioport_write(struct rte_pci_ioport *p, 884 const void *data, size_t len, off_t offset) 885 { 886 switch (p->dev->kdrv) { 887 #ifdef VFIO_PRESENT 888 case RTE_KDRV_VFIO: 889 pci_vfio_ioport_write(p, data, len, offset); 890 break; 891 #endif 892 case RTE_KDRV_IGB_UIO: 893 pci_uio_ioport_write(p, data, len, offset); 894 break; 895 case RTE_KDRV_UIO_GENERIC: 896 pci_uio_ioport_write(p, data, len, offset); 897 break; 898 case RTE_KDRV_NONE: 899 #if defined(RTE_ARCH_X86) 900 pci_uio_ioport_write(p, data, len, offset); 901 #endif 902 break; 903 default: 904 break; 905 } 906 } 907 908 int 909 rte_pci_ioport_unmap(struct rte_pci_ioport *p) 910 { 911 int ret = -1; 912 913 switch (p->dev->kdrv) { 914 #ifdef VFIO_PRESENT 915 case RTE_KDRV_VFIO: 916 if (pci_vfio_is_enabled()) 917 ret = pci_vfio_ioport_unmap(p); 918 break; 919 #endif 920 case RTE_KDRV_IGB_UIO: 921 ret = pci_uio_ioport_unmap(p); 922 break; 923 case RTE_KDRV_UIO_GENERIC: 924 #if defined(RTE_ARCH_X86) 925 ret = 0; 926 #else 927 ret = pci_uio_ioport_unmap(p); 928 #endif 929 break; 930 case RTE_KDRV_NONE: 931 #if defined(RTE_ARCH_X86) 932 ret = 0; 933 #endif 934 break; 935 default: 936 break; 937 } 938 939 return ret; 940 } 941