2 * Copyright (c) 2009 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
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.
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.
32 #include "pciaccess.h"
33 #include "pciaccess_private.h"
42 if (!ioperm(0, 0xffff, 1))
50 if (!ioperm(0, 0xffff, 0))
55 #elif defined(__GLIBC__)
77 #error How to enable IO ports on this system?
81 #define PCI_VENDOR(reg) ((reg) & 0xFFFF)
82 #define PCI_VENDOR_INVALID 0xFFFF
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
89 #define PCI_DEVICE(reg) (((reg) >> 16) & 0xFFFF)
90 #define PCI_DEVICE_INVALID 0xFFFF
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
97 #define PCIC_DISPLAY 0x03
98 #define PCIS_DISPLAY_VGA 0x00
100 #define PCI_HDRTYPE 0x0E
103 struct 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);
110 pci_system_x86_conf1_probe(void)
117 outl(0x80000000, 0xCF8);
118 if (inl(0xCF8) == 0x80000000)
126 pci_system_x86_conf1_read(unsigned bus, unsigned dev, unsigned func, pciaddr_t reg, void *data, unsigned size)
128 unsigned addr = 0xCFC + (reg & 3);
132 if (bus >= 0x100 || dev >= 32 || func >= 8 || reg >= 0x100 || size > 4 || size == 3)
136 outl(0x80000000 | (bus << 16) | (dev << 11) | (func << 8) | (reg & ~3), 0xCF8);
137 /* NOTE: x86 is already LE */
145 uint16_t *val = data;
150 uint32_t *val = data;
161 pci_system_x86_conf1_write(unsigned bus, unsigned dev, unsigned func, pciaddr_t reg, const void *data, unsigned size)
163 unsigned addr = 0xCFC + (reg & 3);
167 if (bus >= 0x100 || dev >= 32 || func >= 8 || reg >= 0x100 || size > 4 || size == 3)
171 outl(0x80000000 | (bus << 16) | (dev << 11) | (func << 8) | (reg & ~3), 0xCF8);
172 /* NOTE: x86 is already LE */
175 const uint8_t *val = data;
180 const uint16_t *val = data;
185 const uint32_t *val = data;
196 pci_system_x86_conf2_probe(void)
201 if (inb(0xCF8) == 0 && inb(0xCFA) == 0)
208 pci_system_x86_conf2_read(unsigned bus, unsigned dev, unsigned func, pciaddr_t reg, void *data, unsigned size)
210 unsigned addr = 0xC000 | dev << 8 | reg;
213 if (bus >= 0x100 || dev >= 16 || func >= 8 || reg >= 0x100)
216 outb((func << 1) | 0xF0, 0xCF8);
218 /* NOTE: x86 is already LE */
226 uint16_t *val = data;
231 uint32_t *val = data;
245 pci_system_x86_conf2_write(unsigned bus, unsigned dev, unsigned func, pciaddr_t reg, const void *data, unsigned size)
247 unsigned addr = 0xC000 | dev << 8 | reg;
250 if (bus >= 0x100 || dev >= 16 || func >= 8 || reg >= 0x100)
253 outb((func << 1) | 0xF0, 0xCF8);
255 /* NOTE: x86 is already LE */
258 const uint8_t *val = data;
263 const uint16_t *val = data;
268 const uint32_t *val = data;
281 /* Check that this really looks like a PCI configuration. */
283 pci_system_x86_check(struct pci_system_x86 *pci_sys_x86)
286 uint16_t class, vendor;
288 /* Look on bus 0 for a device that is a host bridge, a VGA card,
289 * or an intel or compaq device. */
291 for (dev = 0; dev < 32; dev++) {
292 if (pci_sys_x86->read(0, dev, 0, PCI_CLASS_DEVICE, &class, sizeof(class)))
294 if (class == PCI_CLASS_BRIDGE_HOST || class == PCI_CLASS_DISPLAY_VGA)
296 if (pci_sys_x86->read(0, dev, 0, PCI_VENDOR_ID, &vendor, sizeof(vendor)))
298 if (vendor == PCI_VENDOR_ID_INTEL || class == PCI_VENDOR_ID_COMPAQ)
306 pci_nfuncs(struct pci_system_x86 *pci_sys_x86, int bus, int dev)
311 err = pci_sys_x86->read(bus, dev, 0, PCI_HDRTYPE, &hdr, sizeof(hdr));
316 return hdr & 0x80 ? 8 : 1;
320 * Read a VGA rom using the 0xc0000 mapping.
323 pci_device_x86_read_rom(struct pci_device *dev, void *buffer)
328 if ((dev->device_class & 0x00ffff00) !=
329 ((PCIC_DISPLAY << 16) | ( PCIS_DISPLAY_VGA << 8))) {
333 memfd = open("/dev/mem", O_RDONLY | O_CLOEXEC);
337 bios = mmap(NULL, dev->rom_size, PROT_READ, 0, memfd, 0xc0000);
338 if (bios == MAP_FAILED) {
343 memcpy(buffer, bios, dev->rom_size);
345 munmap(bios, dev->rom_size);
351 /** Returns the number of regions (base address registers) the device has */
353 pci_device_x86_get_num_regions(uint8_t header_type)
355 switch (header_type & 0x7f) {
363 fprintf(stderr,"unknown header type %02x\n", header_type);
368 /** Masks out the flag bigs of the base address register value */
370 get_map_base( uint32_t val )
378 /** Returns the size of a region based on the all-ones test value */
380 get_test_val_size( uint32_t testval )
387 /* Mask out the flag bits */
388 testval = get_map_base( testval );
392 while ((testval & 1) == 0) {
401 pci_device_x86_probe(struct pci_device *dev)
403 uint8_t irq, hdrtype;
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.
410 err = pci_device_cfg_read_u8(dev, &irq, PCI_IRQ);
415 err = pci_device_cfg_read_u8(dev, &hdrtype, PCI_HDRTYPE);
420 for (i = 0; i < pci_device_x86_get_num_regions(hdrtype); i++, bar += 4) {
421 uint32_t addr, testval;
423 /* Get the base address */
424 err = pci_device_cfg_read_u32(dev, &addr, bar);
428 /* Test write all ones to the register, then restore it. */
429 err = pci_device_cfg_write_u32(dev, 0xffffffff, bar);
432 pci_device_cfg_read_u32(dev, &testval, bar);
433 err = pci_device_cfg_write_u32(dev, addr, bar);
436 dev->regions[i].is_IO = 1;
438 dev->regions[i].is_64 = 1;
440 dev->regions[i].is_prefetchable = 1;
443 dev->regions[i].size = get_test_val_size(testval);
445 /* Set the base address value */
446 if (dev->regions[i].is_64) {
449 err = pci_device_cfg_read_u32(dev, &top, bar + 4);
453 dev->regions[i].base_addr = ((uint64_t)top << 32) |
458 dev->regions[i].base_addr = get_map_base(addr);
462 /* If it's a VGA device, set up the rom size for read_rom using the
465 if ((dev->device_class & 0x00ffff00) ==
466 ((PCIC_DISPLAY << 16) | (PCIS_DISPLAY_VGA << 8)))
468 dev->rom_size = 64 * 1024;
475 pci_device_x86_map_range(struct pci_device *dev,
476 struct pci_device_mapping *map)
478 int memfd = open("/dev/mem", O_RDWR | O_CLOEXEC);
479 int prot = PROT_READ;
484 if (map->flags & PCI_DEV_MAP_FLAG_WRITABLE)
487 map->memory = mmap(NULL, map->size, prot, MAP_SHARED, memfd, map->base);
489 if (map->memory == MAP_FAILED)
496 pci_device_x86_read(struct pci_device *dev, void *data,
497 pciaddr_t offset, pciaddr_t size, pciaddr_t *bytes_read)
499 struct pci_system_x86 *pci_sys_x86 = (struct pci_system_x86 *) pci_sys;
504 int toread = 1 << (ffs(0x4 + (offset & 0x03)) - 1);
508 err = pci_sys_x86->read(dev->bus, dev->dev, dev->func, offset, data, toread);
513 data = (char*)data + toread;
515 *bytes_read += toread;
521 pci_device_x86_write(struct pci_device *dev, const void *data,
522 pciaddr_t offset, pciaddr_t size, pciaddr_t *bytes_written)
524 struct pci_system_x86 *pci_sys_x86 = (struct pci_system_x86 *) pci_sys;
532 if (towrite > 4 - (offset & 0x3))
533 towrite = 4 - (offset & 0x3);
535 err = pci_sys_x86->write(dev->bus, dev->dev, dev->func, offset, data, towrite);
540 data = (const char*)data + towrite;
542 *bytes_written += towrite;
548 pci_system_x86_destroy(void)
553 static const struct pci_system_methods x86_pci_methods = {
554 .destroy = pci_system_x86_destroy,
555 .read_rom = pci_device_x86_read_rom,
556 .probe = pci_device_x86_probe,
557 .map_range = pci_device_x86_map_range,
558 .unmap_range = pci_device_generic_unmap_range,
559 .read = pci_device_x86_read,
560 .write = pci_device_x86_write,
561 .fill_capabilities = pci_fill_capabilities_generic,
564 static int pci_probe(struct pci_system_x86 *pci_sys_x86)
566 if (pci_system_x86_conf1_probe() == 0) {
567 pci_sys_x86->read = pci_system_x86_conf1_read;
568 pci_sys_x86->write = pci_system_x86_conf1_write;
569 if (pci_system_x86_check(pci_sys_x86) == 0)
573 if (pci_system_x86_conf2_probe() == 0) {
574 pci_sys_x86->read = pci_system_x86_conf2_read;
575 pci_sys_x86->write = pci_system_x86_conf2_write;
576 if (pci_system_x86_check(pci_sys_x86) == 0)
584 pci_system_x86_create(void)
586 struct pci_device_private *device;
587 int ret, bus, dev, ndevs, func, nfuncs;
588 struct pci_system_x86 *pci_sys_x86;
591 ret = x86_enable_io();
595 pci_sys_x86 = calloc(1, sizeof(struct pci_system_x86));
596 if (pci_sys_x86 == NULL) {
600 pci_sys = &pci_sys_x86->system;
602 ret = pci_probe(pci_sys_x86);
610 pci_sys->methods = &x86_pci_methods;
613 for (bus = 0; bus < 256; bus++) {
614 for (dev = 0; dev < 32; dev++) {
615 nfuncs = pci_nfuncs(pci_sys_x86, bus, dev);
616 for (func = 0; func < nfuncs; func++) {
617 if (pci_sys_x86->read(bus, dev, func, PCI_VENDOR_ID, ®, sizeof(reg)) != 0)
619 if (PCI_VENDOR(reg) == PCI_VENDOR_INVALID ||
620 PCI_VENDOR(reg) == 0)
627 pci_sys->num_devices = ndevs;
628 pci_sys->devices = calloc(ndevs, sizeof(struct pci_device_private));
629 if (pci_sys->devices == NULL) {
636 device = pci_sys->devices;
637 for (bus = 0; bus < 256; bus++) {
638 for (dev = 0; dev < 32; dev++) {
639 nfuncs = pci_nfuncs(pci_sys_x86, bus, dev);
640 for (func = 0; func < nfuncs; func++) {
641 if (pci_sys_x86->read(bus, dev, func, PCI_VENDOR_ID, ®, sizeof(reg)) != 0)
643 if (PCI_VENDOR(reg) == PCI_VENDOR_INVALID ||
644 PCI_VENDOR(reg) == 0)
646 device->base.domain = 0;
647 device->base.bus = bus;
648 device->base.dev = dev;
649 device->base.func = func;
650 device->base.vendor_id = PCI_VENDOR(reg);
651 device->base.device_id = PCI_DEVICE(reg);
653 if (pci_sys_x86->read(bus, dev, func, PCI_CLASS, ®, sizeof(reg)) != 0)
655 device->base.device_class = reg >> 8;
656 device->base.revision = reg & 0xFF;
658 if (pci_sys_x86->read(bus, dev, func, PCI_SUB_VENDOR_ID, ®, sizeof(reg)) != 0)
660 device->base.subvendor_id = PCI_VENDOR(reg);
661 device->base.subdevice_id = PCI_DEVICE(reg);