x86_pci.c revision 86ea1d58
1/* 2 * Copyright (c) 2009, 2012 Samuel Thibault 3 * Heavily inspired from the freebsd, netbsd, and openbsd backends 4 * (C) Copyright Eric Anholt 2006 5 * (C) Copyright IBM Corporation 2006 6 * Copyright (c) 2008 Juan Romero Pardines 7 * Copyright (c) 2008 Mark Kettenis 8 * 9 * Permission to use, copy, modify, and distribute this software for any 10 * purpose with or without fee is hereby granted, provided that the above 11 * copyright notice and this permission notice appear in all copies. 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 19 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 20 */ 21 22#define _GNU_SOURCE 23#include <unistd.h> 24#include <stdio.h> 25#include <stdlib.h> 26#include <errno.h> 27#include <fcntl.h> 28#include <sys/mman.h> 29#include <string.h> 30#include <strings.h> 31 32#include "pciaccess.h" 33#include "pciaccess_private.h" 34 35#if defined(__GNU__) 36 37#include <sys/io.h> 38 39static int 40x86_enable_io(void) 41{ 42 if (!ioperm(0, 0xffff, 1)) 43 return 0; 44 return errno; 45} 46 47static int 48x86_disable_io(void) 49{ 50 if (!ioperm(0, 0xffff, 0)) 51 return 0; 52 return errno; 53} 54 55#elif defined(__GLIBC__) 56 57#include <sys/io.h> 58 59static int 60x86_enable_io(void) 61{ 62 if (!iopl(3)) 63 return 0; 64 return errno; 65} 66 67static int 68x86_disable_io(void) 69{ 70 if (!iopl(0)) 71 return 0; 72 return errno; 73} 74 75#else 76 77#error How to enable IO ports on this system? 78 79#endif 80 81#define PCI_VENDOR(reg) ((reg) & 0xFFFF) 82#define PCI_VENDOR_INVALID 0xFFFF 83 84#define PCI_VENDOR_ID 0x00 85#define PCI_SUB_VENDOR_ID 0x2c 86#define PCI_VENDOR_ID_COMPAQ 0x0e11 87#define PCI_VENDOR_ID_INTEL 0x8086 88 89#define PCI_DEVICE(reg) (((reg) >> 16) & 0xFFFF) 90#define PCI_DEVICE_INVALID 0xFFFF 91 92#define PCI_CLASS 0x08 93#define PCI_CLASS_DEVICE 0x0a 94#define PCI_CLASS_DISPLAY_VGA 0x0300 95#define PCI_CLASS_BRIDGE_HOST 0x0600 96 97#define PCIC_DISPLAY 0x03 98#define PCIS_DISPLAY_VGA 0x00 99 100#define PCI_HDRTYPE 0x0E 101#define PCI_IRQ 0x3C 102 103struct pci_system_x86 { 104 struct pci_system system; 105 int (*read)(unsigned bus, unsigned dev, unsigned func, pciaddr_t reg, void *data, unsigned size); 106 int (*write)(unsigned bus, unsigned dev, unsigned func, pciaddr_t reg, const void *data, unsigned size); 107}; 108 109static int 110pci_system_x86_conf1_probe(void) 111{ 112 unsigned long sav; 113 int res = ENODEV; 114 115 outb(0x01, 0xCFB); 116 sav = inl(0xCF8); 117 outl(0x80000000, 0xCF8); 118 if (inl(0xCF8) == 0x80000000) 119 res = 0; 120 outl(sav, 0xCF8); 121 122 return res; 123} 124 125static int 126pci_system_x86_conf1_read(unsigned bus, unsigned dev, unsigned func, pciaddr_t reg, void *data, unsigned size) 127{ 128 unsigned addr = 0xCFC + (reg & 3); 129 unsigned long sav; 130 int ret = 0; 131 132 if (bus >= 0x100 || dev >= 32 || func >= 8 || reg >= 0x100 || size > 4 || size == 3) 133 return EIO; 134 135 sav = inl(0xCF8); 136 outl(0x80000000 | (bus << 16) | (dev << 11) | (func << 8) | (reg & ~3), 0xCF8); 137 /* NOTE: x86 is already LE */ 138 switch (size) { 139 case 1: { 140 uint8_t *val = data; 141 *val = inb(addr); 142 break; 143 } 144 case 2: { 145 uint16_t *val = data; 146 *val = inw(addr); 147 break; 148 } 149 case 4: { 150 uint32_t *val = data; 151 *val = inl(addr); 152 break; 153 } 154 } 155 outl(sav, 0xCF8); 156 157 return ret; 158} 159 160static int 161pci_system_x86_conf1_write(unsigned bus, unsigned dev, unsigned func, pciaddr_t reg, const void *data, unsigned size) 162{ 163 unsigned addr = 0xCFC + (reg & 3); 164 unsigned long sav; 165 int ret = 0; 166 167 if (bus >= 0x100 || dev >= 32 || func >= 8 || reg >= 0x100 || size > 4 || size == 3) 168 return EIO; 169 170 sav = inl(0xCF8); 171 outl(0x80000000 | (bus << 16) | (dev << 11) | (func << 8) | (reg & ~3), 0xCF8); 172 /* NOTE: x86 is already LE */ 173 switch (size) { 174 case 1: { 175 const uint8_t *val = data; 176 outb(*val, addr); 177 break; 178 } 179 case 2: { 180 const uint16_t *val = data; 181 outw(*val, addr); 182 break; 183 } 184 case 4: { 185 const uint32_t *val = data; 186 outl(*val, addr); 187 break; 188 } 189 } 190 outl(sav, 0xCF8); 191 192 return ret; 193} 194 195static int 196pci_system_x86_conf2_probe(void) 197{ 198 outb(0, 0xCFB); 199 outb(0, 0xCF8); 200 outb(0, 0xCFA); 201 if (inb(0xCF8) == 0 && inb(0xCFA) == 0) 202 return 0; 203 204 return ENODEV; 205} 206 207static int 208pci_system_x86_conf2_read(unsigned bus, unsigned dev, unsigned func, pciaddr_t reg, void *data, unsigned size) 209{ 210 unsigned addr = 0xC000 | dev << 8 | reg; 211 int ret = 0; 212 213 if (bus >= 0x100 || dev >= 16 || func >= 8 || reg >= 0x100) 214 return EIO; 215 216 outb((func << 1) | 0xF0, 0xCF8); 217 outb(bus, 0xCFA); 218 /* NOTE: x86 is already LE */ 219 switch (size) { 220 case 1: { 221 uint8_t *val = data; 222 *val = inb(addr); 223 break; 224 } 225 case 2: { 226 uint16_t *val = data; 227 *val = inw(addr); 228 break; 229 } 230 case 4: { 231 uint32_t *val = data; 232 *val = inl(addr); 233 break; 234 } 235 default: 236 ret = EIO; 237 break; 238 } 239 outb(0, 0xCF8); 240 241 return ret; 242} 243 244static int 245pci_system_x86_conf2_write(unsigned bus, unsigned dev, unsigned func, pciaddr_t reg, const void *data, unsigned size) 246{ 247 unsigned addr = 0xC000 | dev << 8 | reg; 248 int ret = 0; 249 250 if (bus >= 0x100 || dev >= 16 || func >= 8 || reg >= 0x100) 251 return EIO; 252 253 outb((func << 1) | 0xF0, 0xCF8); 254 outb(bus, 0xCFA); 255 /* NOTE: x86 is already LE */ 256 switch (size) { 257 case 1: { 258 const uint8_t *val = data; 259 outb(*val, addr); 260 break; 261 } 262 case 2: { 263 const uint16_t *val = data; 264 outw(*val, addr); 265 break; 266 } 267 case 4: { 268 const uint32_t *val = data; 269 outl(*val, addr); 270 break; 271 } 272 default: 273 ret = EIO; 274 break; 275 } 276 outb(0, 0xCF8); 277 278 return ret; 279} 280 281/* Check that this really looks like a PCI configuration. */ 282static int 283pci_system_x86_check(struct pci_system_x86 *pci_sys_x86) 284{ 285 int dev; 286 uint16_t class, vendor; 287 288 /* Look on bus 0 for a device that is a host bridge, a VGA card, 289 * or an intel or compaq device. */ 290 291 for (dev = 0; dev < 32; dev++) { 292 if (pci_sys_x86->read(0, dev, 0, PCI_CLASS_DEVICE, &class, sizeof(class))) 293 continue; 294 if (class == PCI_CLASS_BRIDGE_HOST || class == PCI_CLASS_DISPLAY_VGA) 295 return 0; 296 if (pci_sys_x86->read(0, dev, 0, PCI_VENDOR_ID, &vendor, sizeof(vendor))) 297 continue; 298 if (vendor == PCI_VENDOR_ID_INTEL || class == PCI_VENDOR_ID_COMPAQ) 299 return 0; 300 } 301 302 return ENODEV; 303} 304 305static int 306pci_nfuncs(struct pci_system_x86 *pci_sys_x86, int bus, int dev) 307{ 308 uint8_t hdr; 309 int err; 310 311 err = pci_sys_x86->read(bus, dev, 0, PCI_HDRTYPE, &hdr, sizeof(hdr)); 312 313 if (err) 314 return err; 315 316 return hdr & 0x80 ? 8 : 1; 317} 318 319/** 320 * Read a VGA rom using the 0xc0000 mapping. 321 */ 322static int 323pci_device_x86_read_rom(struct pci_device *dev, void *buffer) 324{ 325 void *bios; 326 int memfd; 327 328 if ((dev->device_class & 0x00ffff00) != 329 ((PCIC_DISPLAY << 16) | ( PCIS_DISPLAY_VGA << 8))) { 330 return ENOSYS; 331 } 332 333 memfd = open("/dev/mem", O_RDONLY | O_CLOEXEC); 334 if (memfd == -1) 335 return errno; 336 337 bios = mmap(NULL, dev->rom_size, PROT_READ, 0, memfd, 0xc0000); 338 if (bios == MAP_FAILED) { 339 close(memfd); 340 return errno; 341 } 342 343 memcpy(buffer, bios, dev->rom_size); 344 345 munmap(bios, dev->rom_size); 346 close(memfd); 347 348 return 0; 349} 350 351/** Returns the number of regions (base address registers) the device has */ 352static int 353pci_device_x86_get_num_regions(uint8_t header_type) 354{ 355 switch (header_type & 0x7f) { 356 case 0: 357 return 6; 358 case 1: 359 return 2; 360 case 2: 361 return 1; 362 default: 363 fprintf(stderr,"unknown header type %02x\n", header_type); 364 return 0; 365 } 366} 367 368/** Masks out the flag bigs of the base address register value */ 369static uint32_t 370get_map_base( uint32_t val ) 371{ 372 if (val & 0x01) 373 return val & ~0x03; 374 else 375 return val & ~0x0f; 376} 377 378/** Returns the size of a region based on the all-ones test value */ 379static unsigned 380get_test_val_size( uint32_t testval ) 381{ 382 unsigned size = 1; 383 384 if (testval == 0) 385 return 0; 386 387 /* Mask out the flag bits */ 388 testval = get_map_base( testval ); 389 if (!testval) 390 return 0; 391 392 while ((testval & 1) == 0) { 393 size <<= 1; 394 testval >>= 1; 395 } 396 397 return size; 398} 399 400static int 401pci_device_x86_probe(struct pci_device *dev) 402{ 403 uint8_t irq, hdrtype; 404 int err, i, bar; 405 406 /* Many of the fields were filled in during initial device enumeration. 407 * At this point, we need to fill in regions, rom_size, and irq. 408 */ 409 410 err = pci_device_cfg_read_u8(dev, &irq, PCI_IRQ); 411 if (err) 412 return err; 413 dev->irq = irq; 414 415 err = pci_device_cfg_read_u8(dev, &hdrtype, PCI_HDRTYPE); 416 if (err) 417 return err; 418 419 bar = 0x10; 420 for (i = 0; i < pci_device_x86_get_num_regions(hdrtype); i++, bar += 4) { 421 uint32_t addr, testval; 422 423 /* Get the base address */ 424 err = pci_device_cfg_read_u32(dev, &addr, bar); 425 if (err != 0) 426 continue; 427 428 /* Test write all ones to the register, then restore it. */ 429 err = pci_device_cfg_write_u32(dev, 0xffffffff, bar); 430 if (err != 0) 431 continue; 432 pci_device_cfg_read_u32(dev, &testval, bar); 433 err = pci_device_cfg_write_u32(dev, addr, bar); 434 435 if (addr & 0x01) 436 dev->regions[i].is_IO = 1; 437 if (addr & 0x04) 438 dev->regions[i].is_64 = 1; 439 if (addr & 0x08) 440 dev->regions[i].is_prefetchable = 1; 441 442 /* Set the size */ 443 dev->regions[i].size = get_test_val_size(testval); 444 445 /* Set the base address value */ 446 if (dev->regions[i].is_64) { 447 uint32_t top; 448 449 err = pci_device_cfg_read_u32(dev, &top, bar + 4); 450 if (err != 0) 451 continue; 452 453 dev->regions[i].base_addr = ((uint64_t)top << 32) | 454 get_map_base(addr); 455 bar += 4; 456 i++; 457 } else { 458 dev->regions[i].base_addr = get_map_base(addr); 459 } 460 } 461 462 /* If it's a VGA device, set up the rom size for read_rom using the 463 * 0xc0000 mapping. 464 */ 465 if ((dev->device_class & 0x00ffff00) == 466 ((PCIC_DISPLAY << 16) | (PCIS_DISPLAY_VGA << 8))) 467 { 468 dev->rom_size = 64 * 1024; 469 } 470 471 return 0; 472} 473 474static int 475pci_device_x86_map_range(struct pci_device *dev, 476 struct pci_device_mapping *map) 477{ 478 int memfd = open("/dev/mem", O_RDWR | O_CLOEXEC); 479 int prot = PROT_READ; 480 481 if (memfd == -1) 482 return errno; 483 484 if (map->flags & PCI_DEV_MAP_FLAG_WRITABLE) 485 prot |= PROT_WRITE; 486 487 map->memory = mmap(NULL, map->size, prot, MAP_SHARED, memfd, map->base); 488 close(memfd); 489 if (map->memory == MAP_FAILED) 490 return errno; 491 492 return 0; 493} 494 495static int 496pci_device_x86_read(struct pci_device *dev, void *data, 497 pciaddr_t offset, pciaddr_t size, pciaddr_t *bytes_read) 498{ 499 struct pci_system_x86 *pci_sys_x86 = (struct pci_system_x86 *) pci_sys; 500 int err; 501 502 *bytes_read = 0; 503 while (size > 0) { 504 int toread = 1 << (ffs(0x4 + (offset & 0x03)) - 1); 505 if (toread > size) 506 toread = size; 507 508 err = pci_sys_x86->read(dev->bus, dev->dev, dev->func, offset, data, toread); 509 if (err) 510 return err; 511 512 offset += toread; 513 data = (char*)data + toread; 514 size -= toread; 515 *bytes_read += toread; 516 } 517 return 0; 518} 519 520static int 521pci_device_x86_write(struct pci_device *dev, const void *data, 522 pciaddr_t offset, pciaddr_t size, pciaddr_t *bytes_written) 523{ 524 struct pci_system_x86 *pci_sys_x86 = (struct pci_system_x86 *) pci_sys; 525 int err; 526 527 *bytes_written = 0; 528 while (size > 0) { 529 int towrite = 4; 530 if (towrite > size) 531 towrite = size; 532 if (towrite > 4 - (offset & 0x3)) 533 towrite = 4 - (offset & 0x3); 534 535 err = pci_sys_x86->write(dev->bus, dev->dev, dev->func, offset, data, towrite); 536 if (err) 537 return err; 538 539 offset += towrite; 540 data = (const char*)data + towrite; 541 size -= towrite; 542 *bytes_written += towrite; 543 } 544 return 0; 545} 546 547static void 548pci_system_x86_destroy(void) 549{ 550 x86_disable_io(); 551} 552 553static struct pci_io_handle * 554pci_device_x86_open_legacy_io(struct pci_io_handle *ret, 555 struct pci_device *dev, pciaddr_t base, pciaddr_t size) 556{ 557 x86_enable_io(); 558 559 ret->base = base; 560 ret->size = size; 561 562 return ret; 563} 564 565static void 566pci_device_x86_close_io(struct pci_device *dev, struct pci_io_handle *handle) 567{ 568 /* Like in the Linux case, do not disable I/O, as it may be opened several 569 * times, and closed fewer times. */ 570 /* x86_disable_io(); */ 571} 572 573static uint32_t 574pci_device_x86_read32(struct pci_io_handle *handle, uint32_t reg) 575{ 576 return inl(reg + handle->base); 577} 578 579static uint16_t 580pci_device_x86_read16(struct pci_io_handle *handle, uint32_t reg) 581{ 582 return inw(reg + handle->base); 583} 584 585static uint8_t 586pci_device_x86_read8(struct pci_io_handle *handle, uint32_t reg) 587{ 588 return inb(reg + handle->base); 589} 590 591static void 592pci_device_x86_write32(struct pci_io_handle *handle, uint32_t reg, 593 uint32_t data) 594{ 595 outl(data, reg + handle->base); 596} 597 598static void 599pci_device_x86_write16(struct pci_io_handle *handle, uint32_t reg, 600 uint16_t data) 601{ 602 outw(data, reg + handle->base); 603} 604 605static void 606pci_device_x86_write8(struct pci_io_handle *handle, uint32_t reg, 607 uint8_t data) 608{ 609 outb(data, reg + handle->base); 610} 611 612static int 613pci_device_x86_map_legacy(struct pci_device *dev, pciaddr_t base, 614 pciaddr_t size, unsigned map_flags, void **addr) 615{ 616 struct pci_device_mapping map; 617 int err; 618 619 map.base = base; 620 map.size = size; 621 map.flags = map_flags; 622 err = pci_device_x86_map_range(dev, &map); 623 *addr = map.memory; 624 625 return err; 626} 627 628static int 629pci_device_x86_unmap_legacy(struct pci_device *dev, void *addr, 630 pciaddr_t size) 631{ 632 struct pci_device_mapping map; 633 634 map.size = size; 635 map.flags = 0; 636 map.memory = addr; 637 638 return pci_device_generic_unmap_range(dev, &map); 639} 640 641static const struct pci_system_methods x86_pci_methods = { 642 .destroy = pci_system_x86_destroy, 643 .read_rom = pci_device_x86_read_rom, 644 .probe = pci_device_x86_probe, 645 .map_range = pci_device_x86_map_range, 646 .unmap_range = pci_device_generic_unmap_range, 647 .read = pci_device_x86_read, 648 .write = pci_device_x86_write, 649 .fill_capabilities = pci_fill_capabilities_generic, 650 .open_legacy_io = pci_device_x86_open_legacy_io, 651 .close_io = pci_device_x86_close_io, 652 .read32 = pci_device_x86_read32, 653 .read16 = pci_device_x86_read16, 654 .read8 = pci_device_x86_read8, 655 .write32 = pci_device_x86_write32, 656 .write16 = pci_device_x86_write16, 657 .write8 = pci_device_x86_write8, 658 .map_legacy = pci_device_x86_map_legacy, 659 .unmap_legacy = pci_device_x86_unmap_legacy, 660}; 661 662static int pci_probe(struct pci_system_x86 *pci_sys_x86) 663{ 664 if (pci_system_x86_conf1_probe() == 0) { 665 pci_sys_x86->read = pci_system_x86_conf1_read; 666 pci_sys_x86->write = pci_system_x86_conf1_write; 667 if (pci_system_x86_check(pci_sys_x86) == 0) 668 return 0; 669 } 670 671 if (pci_system_x86_conf2_probe() == 0) { 672 pci_sys_x86->read = pci_system_x86_conf2_read; 673 pci_sys_x86->write = pci_system_x86_conf2_write; 674 if (pci_system_x86_check(pci_sys_x86) == 0) 675 return 0; 676 } 677 678 return ENODEV; 679} 680 681_pci_hidden int 682pci_system_x86_create(void) 683{ 684 struct pci_device_private *device; 685 int ret, bus, dev, ndevs, func, nfuncs; 686 struct pci_system_x86 *pci_sys_x86; 687 uint32_t reg; 688 689 ret = x86_enable_io(); 690 if (ret) 691 return ret; 692 693 pci_sys_x86 = calloc(1, sizeof(struct pci_system_x86)); 694 if (pci_sys_x86 == NULL) { 695 x86_disable_io(); 696 return ENOMEM; 697 } 698 pci_sys = &pci_sys_x86->system; 699 700 ret = pci_probe(pci_sys_x86); 701 if (ret) { 702 x86_disable_io(); 703 free(pci_sys_x86); 704 pci_sys = NULL; 705 return ret; 706 } 707 708 pci_sys->methods = &x86_pci_methods; 709 710 ndevs = 0; 711 for (bus = 0; bus < 256; bus++) { 712 for (dev = 0; dev < 32; dev++) { 713 nfuncs = pci_nfuncs(pci_sys_x86, bus, dev); 714 for (func = 0; func < nfuncs; func++) { 715 if (pci_sys_x86->read(bus, dev, func, PCI_VENDOR_ID, ®, sizeof(reg)) != 0) 716 continue; 717 if (PCI_VENDOR(reg) == PCI_VENDOR_INVALID || 718 PCI_VENDOR(reg) == 0) 719 continue; 720 ndevs++; 721 } 722 } 723 } 724 725 pci_sys->num_devices = ndevs; 726 pci_sys->devices = calloc(ndevs, sizeof(struct pci_device_private)); 727 if (pci_sys->devices == NULL) { 728 x86_disable_io(); 729 free(pci_sys_x86); 730 pci_sys = NULL; 731 return ENOMEM; 732 } 733 734 device = pci_sys->devices; 735 for (bus = 0; bus < 256; bus++) { 736 for (dev = 0; dev < 32; dev++) { 737 nfuncs = pci_nfuncs(pci_sys_x86, bus, dev); 738 for (func = 0; func < nfuncs; func++) { 739 if (pci_sys_x86->read(bus, dev, func, PCI_VENDOR_ID, ®, sizeof(reg)) != 0) 740 continue; 741 if (PCI_VENDOR(reg) == PCI_VENDOR_INVALID || 742 PCI_VENDOR(reg) == 0) 743 continue; 744 device->base.domain = 0; 745 device->base.bus = bus; 746 device->base.dev = dev; 747 device->base.func = func; 748 device->base.vendor_id = PCI_VENDOR(reg); 749 device->base.device_id = PCI_DEVICE(reg); 750 751 if (pci_sys_x86->read(bus, dev, func, PCI_CLASS, ®, sizeof(reg)) != 0) 752 continue; 753 device->base.device_class = reg >> 8; 754 device->base.revision = reg & 0xFF; 755 756 if (pci_sys_x86->read(bus, dev, func, PCI_SUB_VENDOR_ID, ®, sizeof(reg)) != 0) 757 continue; 758 device->base.subvendor_id = PCI_VENDOR(reg); 759 device->base.subdevice_id = PCI_DEVICE(reg); 760 761 device++; 762 } 763 } 764 } 765 766 return 0; 767} 768