x86_pci.c revision dc7d6647
1/* 2 * Copyright (c) 2018 Damien Zammit 3 * Copyright (c) 2017 Joan Lledó 4 * Copyright (c) 2009, 2012 Samuel Thibault 5 * Heavily inspired from the freebsd, netbsd, and openbsd backends 6 * (C) Copyright Eric Anholt 2006 7 * (C) Copyright IBM Corporation 2006 8 * Copyright (c) 2008 Juan Romero Pardines 9 * Copyright (c) 2008 Mark Kettenis 10 * 11 * Permission to use, copy, modify, and distribute this software for any 12 * purpose with or without fee is hereby granted, provided that the above 13 * copyright notice and this permission notice appear in all copies. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 16 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 17 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 18 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 19 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 20 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 21 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 22 */ 23#ifdef HAVE_CONFIG_H 24#include "config.h" 25#endif 26 27#include "x86_pci.h" 28 29#include <unistd.h> 30#include <stdio.h> 31#include <stdlib.h> 32#include <errno.h> 33#include <fcntl.h> 34#include <sys/mman.h> 35#include <string.h> 36#include <strings.h> 37 38#include "pciaccess.h" 39#include "pciaccess_private.h" 40 41#if defined(__GNU__) 42 43#include <sys/io.h> 44 45int 46x86_enable_io(void) 47{ 48 if (!ioperm(0, 0xffff, 1)) 49 return 0; 50 return errno; 51} 52 53int 54x86_disable_io(void) 55{ 56 if (!ioperm(0, 0xffff, 0)) 57 return 0; 58 return errno; 59} 60 61#elif defined(__GLIBC__) 62 63#include <sys/io.h> 64 65static int 66x86_enable_io(void) 67{ 68 if (!iopl(3)) 69 return 0; 70 return errno; 71} 72 73static int 74x86_disable_io(void) 75{ 76 if (!iopl(0)) 77 return 0; 78 return errno; 79} 80 81#elif defined(__CYGWIN__) 82 83#include <windows.h> 84 85/* WinIo declarations */ 86typedef BYTE bool; 87typedef struct tagPhysStruct { 88 DWORD64 dwPhysMemSizeInBytes; 89 DWORD64 pvPhysAddress; 90 DWORD64 PhysicalMemoryHandle; 91 DWORD64 pvPhysMemLin; 92 DWORD64 pvPhysSection; 93} tagPhysStruct; 94 95typedef bool (_stdcall* INITIALIZEWINIO)(void); 96typedef void (_stdcall* SHUTDOWNWINIO)(void); 97typedef bool (_stdcall* GETPORTVAL)(WORD,PDWORD,BYTE); 98typedef bool (_stdcall* SETPORTVAL)(WORD,DWORD,BYTE); 99typedef PBYTE (_stdcall* MAPPHYSTOLIN)(tagPhysStruct*); 100typedef bool (_stdcall* UNMAPPHYSMEM)(tagPhysStruct*); 101 102SHUTDOWNWINIO ShutdownWinIo; 103GETPORTVAL GetPortVal; 104SETPORTVAL SetPortVal; 105INITIALIZEWINIO InitializeWinIo; 106MAPPHYSTOLIN MapPhysToLin; 107UNMAPPHYSMEM UnmapPhysicalMemory; 108 109static int 110x86_enable_io(void) 111{ 112 HMODULE lib = NULL; 113 114 if ((GetVersion() & 0x80000000) == 0) { 115 /* running on NT, try WinIo version 3 (32 or 64 bits) */ 116#ifdef WIN64 117 lib = LoadLibrary("WinIo64.dll"); 118#else 119 lib = LoadLibrary("WinIo32.dll"); 120#endif 121 } 122 123 if (!lib) { 124 fprintf(stderr, "Failed to load WinIo library.\n"); 125 return 1; 126 } 127 128#define GETPROC(n, d) \ 129 n = (d) GetProcAddress(lib, #n); \ 130 if (!n) { \ 131 fprintf(stderr, "Failed to load " #n " function.\n"); \ 132 return 1; \ 133 } 134 135 GETPROC(InitializeWinIo, INITIALIZEWINIO); 136 GETPROC(ShutdownWinIo, SHUTDOWNWINIO); 137 GETPROC(GetPortVal, GETPORTVAL); 138 GETPROC(SetPortVal, SETPORTVAL); 139 GETPROC(MapPhysToLin, MAPPHYSTOLIN); 140 GETPROC(UnmapPhysicalMemory, UNMAPPHYSMEM); 141 142#undef GETPROC 143 144 if (!InitializeWinIo()) { 145 fprintf(stderr, "Failed to initialize WinIo.\n" 146 "NOTE: WinIo.dll and WinIo.sys must be in the same directory as the executable!\n"); 147 return 0; 148 } 149 150 return 0; 151} 152 153static int 154x86_disable_io(void) 155{ 156 ShutdownWinIo(); 157 return 1; 158} 159 160static inline uint8_t 161inb(uint16_t port) 162{ 163 DWORD pv; 164 165 if (GetPortVal(port, &pv, 1)) 166 return (uint8_t)pv; 167 return 0; 168} 169 170static inline uint16_t 171inw(uint16_t port) 172{ 173 DWORD pv; 174 175 if (GetPortVal(port, &pv, 2)) 176 return (uint16_t)pv; 177 return 0; 178} 179 180static inline uint32_t 181inl(uint16_t port) 182{ 183 DWORD pv; 184 185 if (GetPortVal(port, &pv, 4)) 186 return (uint32_t)pv; 187 return 0; 188} 189 190static inline void 191outb(uint8_t value, uint16_t port) 192{ 193 SetPortVal(port, value, 1); 194} 195 196static inline void 197outw(uint16_t value, uint16_t port) 198{ 199 SetPortVal(port, value, 2); 200} 201 202static inline void 203outl(uint32_t value, uint16_t port) 204{ 205 SetPortVal(port, value, 4); 206} 207 208#else 209 210#error How to enable IO ports on this system? 211 212#endif 213 214static int 215pci_system_x86_conf1_probe(void) 216{ 217 unsigned long sav; 218 int res = ENODEV; 219 220 outb(0x01, 0xCFB); 221 sav = inl(0xCF8); 222 outl(0x80000000, 0xCF8); 223 if (inl(0xCF8) == 0x80000000) 224 res = 0; 225 outl(sav, 0xCF8); 226 227 return res; 228} 229 230static int 231pci_system_x86_conf1_read(unsigned bus, unsigned dev, unsigned func, pciaddr_t reg, void *data, unsigned size) 232{ 233 unsigned addr = 0xCFC + (reg & 3); 234 unsigned long sav; 235 int ret = 0; 236 237 if (bus >= 0x100 || dev >= 32 || func >= 8 || reg >= 0x100 || size > 4 || size == 3) 238 return EIO; 239 240 sav = inl(0xCF8); 241 outl(0x80000000 | (bus << 16) | (dev << 11) | (func << 8) | (reg & ~3), 0xCF8); 242 /* NOTE: x86 is already LE */ 243 switch (size) { 244 case 1: { 245 uint8_t *val = data; 246 *val = inb(addr); 247 break; 248 } 249 case 2: { 250 uint16_t *val = data; 251 *val = inw(addr); 252 break; 253 } 254 case 4: { 255 uint32_t *val = data; 256 *val = inl(addr); 257 break; 258 } 259 } 260 outl(sav, 0xCF8); 261 262 return ret; 263} 264 265static int 266pci_system_x86_conf1_write(unsigned bus, unsigned dev, unsigned func, pciaddr_t reg, const void *data, unsigned size) 267{ 268 unsigned addr = 0xCFC + (reg & 3); 269 unsigned long sav; 270 int ret = 0; 271 272 if (bus >= 0x100 || dev >= 32 || func >= 8 || reg >= 0x100 || size > 4 || size == 3) 273 return EIO; 274 275 sav = inl(0xCF8); 276 outl(0x80000000 | (bus << 16) | (dev << 11) | (func << 8) | (reg & ~3), 0xCF8); 277 /* NOTE: x86 is already LE */ 278 switch (size) { 279 case 1: { 280 const uint8_t *val = data; 281 outb(*val, addr); 282 break; 283 } 284 case 2: { 285 const uint16_t *val = data; 286 outw(*val, addr); 287 break; 288 } 289 case 4: { 290 const uint32_t *val = data; 291 outl(*val, addr); 292 break; 293 } 294 } 295 outl(sav, 0xCF8); 296 297 return ret; 298} 299 300static int 301pci_system_x86_conf2_probe(void) 302{ 303 outb(0, 0xCFB); 304 outb(0, 0xCF8); 305 outb(0, 0xCFA); 306 if (inb(0xCF8) == 0 && inb(0xCFA) == 0) 307 return 0; 308 309 return ENODEV; 310} 311 312static int 313pci_system_x86_conf2_read(unsigned bus, unsigned dev, unsigned func, pciaddr_t reg, void *data, unsigned size) 314{ 315 unsigned addr = 0xC000 | dev << 8 | reg; 316 int ret = 0; 317 318 if (bus >= 0x100 || dev >= 16 || func >= 8 || reg >= 0x100) 319 return EIO; 320 321 outb((func << 1) | 0xF0, 0xCF8); 322 outb(bus, 0xCFA); 323 /* NOTE: x86 is already LE */ 324 switch (size) { 325 case 1: { 326 uint8_t *val = data; 327 *val = inb(addr); 328 break; 329 } 330 case 2: { 331 uint16_t *val = data; 332 *val = inw(addr); 333 break; 334 } 335 case 4: { 336 uint32_t *val = data; 337 *val = inl(addr); 338 break; 339 } 340 default: 341 ret = EIO; 342 break; 343 } 344 outb(0, 0xCF8); 345 346 return ret; 347} 348 349static int 350pci_system_x86_conf2_write(unsigned bus, unsigned dev, unsigned func, pciaddr_t reg, const void *data, unsigned size) 351{ 352 unsigned addr = 0xC000 | dev << 8 | reg; 353 int ret = 0; 354 355 if (bus >= 0x100 || dev >= 16 || func >= 8 || reg >= 0x100) 356 return EIO; 357 358 outb((func << 1) | 0xF0, 0xCF8); 359 outb(bus, 0xCFA); 360 /* NOTE: x86 is already LE */ 361 switch (size) { 362 case 1: { 363 const uint8_t *val = data; 364 outb(*val, addr); 365 break; 366 } 367 case 2: { 368 const uint16_t *val = data; 369 outw(*val, addr); 370 break; 371 } 372 case 4: { 373 const uint32_t *val = data; 374 outl(*val, addr); 375 break; 376 } 377 default: 378 ret = EIO; 379 break; 380 } 381 outb(0, 0xCF8); 382 383 return ret; 384} 385 386/* Check that this really looks like a PCI configuration. */ 387static error_t 388pci_system_x86_check (void) 389{ 390 int dev; 391 uint16_t class, vendor; 392 struct pci_device tmpdev = { 0 }; 393 394 /* Look on bus 0 for a device that is a host bridge, a VGA card, 395 * or an intel or compaq device. */ 396 tmpdev.bus = 0; 397 tmpdev.func = 0; 398 class = 0; 399 vendor = 0; 400 401 for (dev = 0; dev < 32; dev++) { 402 tmpdev.dev = dev; 403 if (pci_device_cfg_read_u16 (&tmpdev, &class, PCI_CLASS_DEVICE)) 404 continue; 405 if (class == PCI_CLASS_BRIDGE_HOST || class == PCI_CLASS_DISPLAY_VGA) 406 return 0; 407 if (pci_device_cfg_read_u16 (&tmpdev, &vendor, PCI_VENDOR_ID)) 408 continue; 409 if (vendor == PCI_VENDOR_ID_INTEL || class == PCI_VENDOR_ID_COMPAQ) 410 return 0; 411 } 412 413 return ENODEV; 414} 415 416static int 417pci_nfuncs(struct pci_device *dev, uint8_t *nfuncs) 418{ 419 uint8_t hdr; 420 int err; 421 struct pci_device tmpdev = *dev; 422 423 tmpdev.func = 0; 424 425 err = pci_device_cfg_read_u8 (&tmpdev, &hdr, PCI_HDRTYPE); 426 427 if (err) 428 return err; 429 430 *nfuncs = hdr & 0x80 ? 8 : 1; 431 return err; 432} 433 434/** 435 * Read a PCI rom. 436 */ 437static error_t 438pci_device_x86_read_rom(struct pci_device *dev, void *buffer) 439{ 440 void *bios; 441 int memfd; 442 struct pci_device_private *d = (struct pci_device_private *)dev; 443 444 memfd = open("/dev/mem", O_RDONLY | O_CLOEXEC); 445 if (memfd == -1) 446 return errno; 447 448 bios = mmap(NULL, dev->rom_size, PROT_READ, MAP_SHARED, memfd, d->rom_base); 449 if (bios == MAP_FAILED) { 450 close(memfd); 451 return errno; 452 } 453 454 memcpy(buffer, bios, dev->rom_size); 455 456 munmap(bios, dev->rom_size); 457 close(memfd); 458 459 return 0; 460} 461 462/** Returns the number of regions (base address registers) the device has */ 463static int 464pci_device_x86_get_num_regions(uint8_t header_type) 465{ 466 switch (header_type & 0x7f) { 467 case 0: 468 return 6; 469 case 1: 470 return 2; 471 case 2: 472 return 1; 473 default: 474 fprintf(stderr,"unknown header type %02x\n", header_type); 475 return 0; 476 } 477} 478 479/** Masks out the flag bigs of the base address register value */ 480static uint32_t 481get_map_base( uint32_t val ) 482{ 483 if (val & 0x01) 484 return val & ~0x03; 485 else 486 return val & ~0x0f; 487} 488 489/** Returns the size of a region based on the all-ones test value */ 490static unsigned 491get_test_val_size( uint32_t testval ) 492{ 493 unsigned size = 1; 494 495 if (testval == 0) 496 return 0; 497 498 /* Mask out the flag bits */ 499 testval = get_map_base( testval ); 500 if (!testval) 501 return 0; 502 503 while ((testval & 1) == 0) { 504 size <<= 1; 505 testval >>= 1; 506 } 507 508 return size; 509} 510 511/* Read BAR `reg_num' in `dev' and map the data if any */ 512static error_t 513pci_device_x86_region_probe (struct pci_device *dev, int reg_num) 514{ 515 error_t err; 516 uint8_t offset; 517 uint32_t reg, addr, testval; 518 int memfd; 519 520 offset = PCI_BAR_ADDR_0 + 0x4 * reg_num; 521 522 /* Get the base address */ 523 err = pci_device_cfg_read_u32 (dev, &addr, offset); 524 if (err) 525 return err; 526 527 /* Test write all ones to the register, then restore it. */ 528 reg = 0xffffffff; 529 err = pci_device_cfg_write_u32 (dev, reg, offset); 530 if (err) 531 return err; 532 err = pci_device_cfg_read_u32 (dev, &testval, offset); 533 if (err) 534 return err; 535 err = pci_device_cfg_write_u32 (dev, addr, offset); 536 if (err) 537 return err; 538 539 if (addr & 0x01) 540 dev->regions[reg_num].is_IO = 1; 541 if (addr & 0x04) 542 dev->regions[reg_num].is_64 = 1; 543 if (addr & 0x08) 544 dev->regions[reg_num].is_prefetchable = 1; 545 546 /* Set the size */ 547 dev->regions[reg_num].size = get_test_val_size (testval); 548 549 /* Set the base address value */ 550 dev->regions[reg_num].base_addr = get_map_base (addr); 551 552 if (dev->regions[reg_num].is_64) 553 { 554 err = pci_device_cfg_read_u32 (dev, &addr, offset + 4); 555 if (err) 556 return err; 557 558 dev->regions[reg_num].base_addr |= ((uint64_t) addr << 32); 559 } 560 561 if (dev->regions[reg_num].is_IO) 562 { 563 /* Enable the I/O Space bit */ 564 err = pci_device_cfg_read_u32 (dev, ®, PCI_COMMAND); 565 if (err) 566 return err; 567 568 if (!(reg & 0x1)) 569 { 570 reg |= 0x1; 571 572 err = pci_device_cfg_write_u32 (dev, reg, PCI_COMMAND); 573 if (err) 574 return err; 575 } 576 577 /* Clear the map pointer */ 578 dev->regions[reg_num].memory = 0; 579 } 580 else if (dev->regions[reg_num].size > 0) 581 { 582 /* Enable the Memory Space bit */ 583 err = pci_device_cfg_read_u32 (dev, ®, PCI_COMMAND); 584 if (err) 585 return err; 586 587 if (!(reg & 0x2)) 588 { 589 reg |= 0x2; 590 591 err = pci_device_cfg_write_u32 (dev, reg, PCI_COMMAND); 592 if (err) 593 return err; 594 } 595 596 /* Map the region in our space */ 597 memfd = open ("/dev/mem", O_RDWR | O_CLOEXEC); 598 if (memfd == -1) 599 return errno; 600 601 dev->regions[reg_num].memory = 602 mmap (NULL, dev->regions[reg_num].size, PROT_READ | PROT_WRITE, MAP_SHARED, 603 memfd, dev->regions[reg_num].base_addr); 604 if (dev->regions[reg_num].memory == MAP_FAILED) 605 { 606 dev->regions[reg_num].memory = 0; 607 close (memfd); 608 return errno; 609 } 610 } 611 612 return 0; 613} 614 615/* Read the XROMBAR in `dev' and save the rom size and rom base */ 616static error_t 617pci_device_x86_probe_rom (struct pci_device *dev) 618{ 619 error_t err; 620 uint8_t reg_8, xrombar_addr; 621 uint32_t reg, reg_back; 622 pciaddr_t rom_size; 623 pciaddr_t rom_base; 624 struct pci_device_private *d = (struct pci_device_private *)dev; 625 626 /* First we need to know which type of header is this */ 627 err = pci_device_cfg_read_u8 (dev, ®_8, PCI_HDRTYPE); 628 if (err) 629 return err; 630 631 /* Get the XROMBAR register address */ 632 switch (reg_8 & 0x3) 633 { 634 case PCI_HDRTYPE_DEVICE: 635 xrombar_addr = PCI_XROMBAR_ADDR_00; 636 break; 637 case PCI_HDRTYPE_BRIDGE: 638 xrombar_addr = PCI_XROMBAR_ADDR_01; 639 break; 640 default: 641 return -1; 642 } 643 644 /* Get size and physical address */ 645 err = pci_device_cfg_read_u32 (dev, ®, xrombar_addr); 646 if (err) 647 return err; 648 649 reg_back = reg; 650 reg = 0xFFFFF800; /* Base address: first 21 bytes */ 651 err = pci_device_cfg_write_u32 (dev, reg, xrombar_addr); 652 if (err) 653 return err; 654 err = pci_device_cfg_read_u32 (dev, ®, xrombar_addr); 655 if (err) 656 return err; 657 658 rom_size = (~reg + 1); 659 rom_base = reg_back & reg; 660 661 if (rom_size == 0) 662 return 0; 663 664 /* Enable the address decoder and write the physical address back */ 665 reg_back |= 0x1; 666 err = pci_device_cfg_write_u32 (dev, reg_back, xrombar_addr); 667 if (err) 668 return err; 669 670 /* Enable the Memory Space bit */ 671 err = pci_device_cfg_read_u32 (dev, ®, PCI_COMMAND); 672 if (err) 673 return err; 674 675 if (!(reg & 0x2)) 676 { 677 reg |= 0x2; 678 679 err = pci_device_cfg_write_u32 (dev, reg, PCI_COMMAND); 680 if (err) 681 return err; 682 } 683 684 dev->rom_size = rom_size; 685 d->rom_base = rom_base; 686 687 return 0; 688} 689 690/* Configure BARs and ROM */ 691static error_t 692pci_device_x86_probe (struct pci_device *dev) 693{ 694 error_t err; 695 uint8_t hdrtype; 696 int i; 697 698 /* Probe BARs */ 699 err = pci_device_cfg_read_u8 (dev, &hdrtype, PCI_HDRTYPE); 700 if (err) 701 return err; 702 703 for (i = 0; i < pci_device_x86_get_num_regions (hdrtype); i++) 704 { 705 err = pci_device_x86_region_probe (dev, i); 706 if (err) 707 return err; 708 709 if (dev->regions[i].is_64) 710 /* Move the pointer one BAR ahead */ 711 i++; 712 } 713 714 /* Probe ROM */ 715 pci_device_x86_probe_rom(dev); 716 717 return 0; 718} 719 720/* Recursively scan bus number `bus' */ 721static error_t 722pci_system_x86_scan_bus (uint8_t bus) 723{ 724 error_t err; 725 uint8_t dev, func, nfuncs, hdrtype, secbus; 726 uint32_t reg; 727 struct pci_device_private *d, *devices; 728 struct pci_device scratchdev; 729 730 scratchdev.bus = bus; 731 732 for (dev = 0; dev < 32; dev++) 733 { 734 scratchdev.dev = dev; 735 scratchdev.func = 0; 736 err = pci_nfuncs (&scratchdev, &nfuncs); 737 if (err) 738 return err; 739 740 for (func = 0; func < nfuncs; func++) 741 { 742 scratchdev.func = func; 743 err = pci_device_cfg_read_u32 (&scratchdev, ®, PCI_VENDOR_ID); 744 if (err) 745 return err; 746 747 if (PCI_VENDOR (reg) == PCI_VENDOR_INVALID || PCI_VENDOR (reg) == 0) 748 continue; 749 750 err = pci_device_cfg_read_u32 (&scratchdev, ®, PCI_CLASS); 751 if (err) 752 return err; 753 754 err = pci_device_cfg_read_u8 (&scratchdev, &hdrtype, PCI_HDRTYPE); 755 if (err) 756 return err; 757 758 devices = 759 realloc (pci_sys->devices, 760 (pci_sys->num_devices + 1) * sizeof (struct pci_device_private)); 761 if (!devices) 762 return ENOMEM; 763 764 d = devices + pci_sys->num_devices; 765 memset (d, 0, sizeof (struct pci_device_private)); 766 767 /* Fixed values as PCI express is still not supported */ 768 d->base.domain = 0; 769 d->base.bus = bus; 770 d->base.dev = dev; 771 d->base.func = func; 772 773 d->base.device_class = reg >> 8; 774 775 err = pci_device_x86_probe (&d->base); 776 if (err) 777 return err; 778 779 pci_sys->devices = devices; 780 pci_sys->num_devices++; 781 782 switch (hdrtype & 0x3) 783 { 784 case PCI_HDRTYPE_DEVICE: 785 break; 786 case PCI_HDRTYPE_BRIDGE: 787 case PCI_HDRTYPE_CARDBUS: 788 { 789 err = pci_device_cfg_read_u8 (&scratchdev, &secbus, PCI_SECONDARY_BUS); 790 if (err) 791 return err; 792 793 err = pci_system_x86_scan_bus (secbus); 794 if (err) 795 return err; 796 797 break; 798 } 799 default: 800 /* Unknown header, do nothing */ 801 break; 802 } 803 } 804 } 805 806 return 0; 807} 808 809#if defined(__CYGWIN__) 810 811static int 812pci_device_x86_map_range(struct pci_device *dev, 813 struct pci_device_mapping *map) 814{ 815 tagPhysStruct phys; 816 817 phys.pvPhysAddress = (DWORD64)(DWORD32)map->base; 818 phys.dwPhysMemSizeInBytes = map->size; 819 820 map->memory = (PDWORD)MapPhysToLin(&phys); 821 if (map->memory == NULL) 822 return EFAULT; 823 824 return 0; 825} 826 827static int 828pci_device_x86_unmap_range(struct pci_device *dev, 829 struct pci_device_mapping *map) 830{ 831 tagPhysStruct phys; 832 833 phys.pvPhysAddress = (DWORD64)(DWORD32)map->base; 834 phys.dwPhysMemSizeInBytes = map->size; 835 836 if (!UnmapPhysicalMemory(&phys)) 837 return EFAULT; 838 839 return 0; 840} 841 842#else 843 844int 845pci_device_x86_map_range(struct pci_device *dev, 846 struct pci_device_mapping *map) 847{ 848 int memfd = open("/dev/mem", O_RDWR | O_CLOEXEC); 849 int prot = PROT_READ; 850 851 if (memfd == -1) 852 return errno; 853 854 if (map->flags & PCI_DEV_MAP_FLAG_WRITABLE) 855 prot |= PROT_WRITE; 856 857 map->memory = mmap(NULL, map->size, prot, MAP_SHARED, memfd, map->base); 858 if (map->memory == MAP_FAILED) { 859 close(memfd); 860 return errno; 861 } 862 return 0; 863} 864 865int 866pci_device_x86_unmap_range(struct pci_device *dev, 867 struct pci_device_mapping *map) 868{ 869 return pci_device_generic_unmap_range(dev, map); 870} 871 872#endif 873 874static int 875pci_device_x86_read_conf1(struct pci_device *dev, void *data, 876 pciaddr_t offset, pciaddr_t size, pciaddr_t *bytes_read) 877{ 878 int err; 879 880 *bytes_read = 0; 881 while (size > 0) { 882 int toread = 1 << (ffs(0x4 + (offset & 0x03)) - 1); 883 if (toread > size) 884 toread = size; 885 886 err = pci_system_x86_conf1_read(dev->bus, dev->dev, dev->func, offset, data, toread); 887 if (err) 888 return err; 889 890 offset += toread; 891 data = (char*)data + toread; 892 size -= toread; 893 *bytes_read += toread; 894 } 895 return 0; 896} 897 898static int 899pci_device_x86_read_conf2(struct pci_device *dev, void *data, 900 pciaddr_t offset, pciaddr_t size, pciaddr_t *bytes_read) 901{ 902 int err; 903 904 *bytes_read = 0; 905 while (size > 0) { 906 int toread = 1 << (ffs(0x4 + (offset & 0x03)) - 1); 907 if (toread > size) 908 toread = size; 909 910 err = pci_system_x86_conf2_read(dev->bus, dev->dev, dev->func, offset, data, toread); 911 if (err) 912 return err; 913 914 offset += toread; 915 data = (char*)data + toread; 916 size -= toread; 917 *bytes_read += toread; 918 } 919 return 0; 920} 921 922static int 923pci_device_x86_write_conf1(struct pci_device *dev, const void *data, 924 pciaddr_t offset, pciaddr_t size, pciaddr_t *bytes_written) 925{ 926 int err; 927 928 *bytes_written = 0; 929 while (size > 0) { 930 int towrite = 4; 931 if (towrite > size) 932 towrite = size; 933 if (towrite > 4 - (offset & 0x3)) 934 towrite = 4 - (offset & 0x3); 935 936 err = pci_system_x86_conf1_write(dev->bus, dev->dev, dev->func, offset, data, towrite); 937 if (err) 938 return err; 939 940 offset += towrite; 941 data = (const char*)data + towrite; 942 size -= towrite; 943 *bytes_written += towrite; 944 } 945 return 0; 946} 947 948static int 949pci_device_x86_write_conf2(struct pci_device *dev, const void *data, 950 pciaddr_t offset, pciaddr_t size, pciaddr_t *bytes_written) 951{ 952 int err; 953 954 *bytes_written = 0; 955 while (size > 0) { 956 int towrite = 4; 957 if (towrite > size) 958 towrite = size; 959 if (towrite > 4 - (offset & 0x3)) 960 towrite = 4 - (offset & 0x3); 961 962 err = pci_system_x86_conf2_write(dev->bus, dev->dev, dev->func, offset, data, towrite); 963 if (err) 964 return err; 965 966 offset += towrite; 967 data = (const char*)data + towrite; 968 size -= towrite; 969 *bytes_written += towrite; 970 } 971 return 0; 972} 973 974void 975pci_system_x86_destroy(void) 976{ 977 x86_disable_io(); 978} 979 980struct pci_io_handle * 981pci_device_x86_open_legacy_io(struct pci_io_handle *ret, 982 struct pci_device *dev, pciaddr_t base, pciaddr_t size) 983{ 984 x86_enable_io(); 985 986 ret->base = base; 987 ret->size = size; 988 ret->is_legacy = 1; 989 990 return ret; 991} 992 993void 994pci_device_x86_close_io(struct pci_device *dev, struct pci_io_handle *handle) 995{ 996 /* Like in the Linux case, do not disable I/O, as it may be opened several 997 * times, and closed fewer times. */ 998 /* x86_disable_io(); */ 999} 1000 1001uint32_t 1002pci_device_x86_read32(struct pci_io_handle *handle, uint32_t reg) 1003{ 1004 return inl(reg + handle->base); 1005} 1006 1007uint16_t 1008pci_device_x86_read16(struct pci_io_handle *handle, uint32_t reg) 1009{ 1010 return inw(reg + handle->base); 1011} 1012 1013uint8_t 1014pci_device_x86_read8(struct pci_io_handle *handle, uint32_t reg) 1015{ 1016 return inb(reg + handle->base); 1017} 1018 1019void 1020pci_device_x86_write32(struct pci_io_handle *handle, uint32_t reg, 1021 uint32_t data) 1022{ 1023 outl(data, reg + handle->base); 1024} 1025 1026void 1027pci_device_x86_write16(struct pci_io_handle *handle, uint32_t reg, 1028 uint16_t data) 1029{ 1030 outw(data, reg + handle->base); 1031} 1032 1033void 1034pci_device_x86_write8(struct pci_io_handle *handle, uint32_t reg, 1035 uint8_t data) 1036{ 1037 outb(data, reg + handle->base); 1038} 1039 1040int 1041pci_device_x86_map_legacy(struct pci_device *dev, pciaddr_t base, 1042 pciaddr_t size, unsigned map_flags, void **addr) 1043{ 1044 struct pci_device_mapping map; 1045 int err; 1046 1047 map.base = base; 1048 map.size = size; 1049 map.flags = map_flags; 1050 err = pci_device_x86_map_range(dev, &map); 1051 *addr = map.memory; 1052 1053 return err; 1054} 1055 1056int 1057pci_device_x86_unmap_legacy(struct pci_device *dev, void *addr, 1058 pciaddr_t size) 1059{ 1060 struct pci_device_mapping map; 1061 1062 map.size = size; 1063 map.flags = 0; 1064 map.memory = addr; 1065 1066 return pci_device_x86_unmap_range(dev, &map); 1067} 1068 1069static const struct pci_system_methods x86_pci_method_conf1 = { 1070 .destroy = pci_system_x86_destroy, 1071 .read_rom = pci_device_x86_read_rom, 1072 .probe = pci_device_x86_probe, 1073 .map_range = pci_device_x86_map_range, 1074 .unmap_range = pci_device_x86_unmap_range, 1075 .read = pci_device_x86_read_conf1, 1076 .write = pci_device_x86_write_conf1, 1077 .fill_capabilities = pci_fill_capabilities_generic, 1078 .open_legacy_io = pci_device_x86_open_legacy_io, 1079 .close_io = pci_device_x86_close_io, 1080 .read32 = pci_device_x86_read32, 1081 .read16 = pci_device_x86_read16, 1082 .read8 = pci_device_x86_read8, 1083 .write32 = pci_device_x86_write32, 1084 .write16 = pci_device_x86_write16, 1085 .write8 = pci_device_x86_write8, 1086 .map_legacy = pci_device_x86_map_legacy, 1087 .unmap_legacy = pci_device_x86_unmap_legacy, 1088}; 1089 1090static const struct pci_system_methods x86_pci_method_conf2 = { 1091 .destroy = pci_system_x86_destroy, 1092 .read_rom = pci_device_x86_read_rom, 1093 .probe = pci_device_x86_probe, 1094 .map_range = pci_device_x86_map_range, 1095 .unmap_range = pci_device_x86_unmap_range, 1096 .read = pci_device_x86_read_conf2, 1097 .write = pci_device_x86_write_conf2, 1098 .fill_capabilities = pci_fill_capabilities_generic, 1099 .open_legacy_io = pci_device_x86_open_legacy_io, 1100 .close_io = pci_device_x86_close_io, 1101 .read32 = pci_device_x86_read32, 1102 .read16 = pci_device_x86_read16, 1103 .read8 = pci_device_x86_read8, 1104 .write32 = pci_device_x86_write32, 1105 .write16 = pci_device_x86_write16, 1106 .write8 = pci_device_x86_write8, 1107 .map_legacy = pci_device_x86_map_legacy, 1108 .unmap_legacy = pci_device_x86_unmap_legacy, 1109}; 1110 1111static int pci_probe(void) 1112{ 1113 pci_sys->methods = &x86_pci_method_conf1; 1114 if (pci_system_x86_conf1_probe() == 0) { 1115 if (pci_system_x86_check() == 0) 1116 return 1; 1117 } 1118 1119 pci_sys->methods = &x86_pci_method_conf2; 1120 if (pci_system_x86_conf2_probe() == 0) { 1121 if (pci_system_x86_check() == 0) 1122 return 2; 1123 } 1124 1125 pci_sys->methods = NULL; 1126 return 0; 1127} 1128 1129_pci_hidden int 1130pci_system_x86_create(void) 1131{ 1132 error_t err; 1133 int confx; 1134 1135 err = x86_enable_io (); 1136 if (err) 1137 return err; 1138 1139 pci_sys = calloc (1, sizeof (struct pci_system)); 1140 if (pci_sys == NULL) 1141 { 1142 x86_disable_io (); 1143 return ENOMEM; 1144 } 1145 1146 confx = pci_probe (); 1147 if (!confx) 1148 { 1149 x86_disable_io (); 1150 free (pci_sys); 1151 pci_sys = NULL; 1152 return ENODEV; 1153 } 1154 else if (confx == 1) 1155 pci_sys->methods = &x86_pci_method_conf1; 1156 else 1157 pci_sys->methods = &x86_pci_method_conf2; 1158 1159 /* Recursive scan */ 1160 pci_sys->num_devices = 0; 1161 err = pci_system_x86_scan_bus (0); 1162 if (err) 1163 { 1164 x86_disable_io (); 1165 free (pci_sys); 1166 pci_sys = NULL; 1167 return err; 1168 } 1169 1170 return 0; 1171} 1172