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
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__)
75 #elif defined(__CYGWIN__)
79 /* WinIo declarations */
81 typedef struct tagPhysStruct {
82 DWORD64 dwPhysMemSizeInBytes;
83 DWORD64 pvPhysAddress;
84 DWORD64 PhysicalMemoryHandle;
86 DWORD64 pvPhysSection;
89 typedef bool (_stdcall* INITIALIZEWINIO)(void);
90 typedef void (_stdcall* SHUTDOWNWINIO)(void);
91 typedef bool (_stdcall* GETPORTVAL)(WORD,PDWORD,BYTE);
92 typedef bool (_stdcall* SETPORTVAL)(WORD,DWORD,BYTE);
93 typedef PBYTE (_stdcall* MAPPHYSTOLIN)(tagPhysStruct*);
94 typedef bool (_stdcall* UNMAPPHYSMEM)(tagPhysStruct*);
96 SHUTDOWNWINIO ShutdownWinIo;
97 GETPORTVAL GetPortVal;
98 SETPORTVAL SetPortVal;
99 INITIALIZEWINIO InitializeWinIo;
100 MAPPHYSTOLIN MapPhysToLin;
101 UNMAPPHYSMEM UnmapPhysicalMemory;
108 if ((GetVersion() & 0x80000000) == 0) {
109 /* running on NT, try WinIo version 3 (32 or 64 bits) */
111 lib = LoadLibrary("WinIo64.dll");
113 lib = LoadLibrary("WinIo32.dll");
118 fprintf(stderr, "Failed to load WinIo library.\n");
122 #define GETPROC(n, d) \
123 n = (d) GetProcAddress(lib, #n); \
125 fprintf(stderr, "Failed to load " #n " function.\n"); \
129 GETPROC(InitializeWinIo, INITIALIZEWINIO);
130 GETPROC(ShutdownWinIo, SHUTDOWNWINIO);
131 GETPROC(GetPortVal, GETPORTVAL);
132 GETPROC(SetPortVal, SETPORTVAL);
133 GETPROC(MapPhysToLin, MAPPHYSTOLIN);
134 GETPROC(UnmapPhysicalMemory, UNMAPPHYSMEM);
138 if (!InitializeWinIo()) {
139 fprintf(stderr, "Failed to initialize WinIo.\n"
140 "NOTE: WinIo.dll and WinIo.sys must be in the same directory as the executable!\n");
154 static inline uint8_t
159 if (GetPortVal(port, &pv, 1))
164 static inline uint16_t
169 if (GetPortVal(port, &pv, 2))
174 static inline uint32_t
179 if (GetPortVal(port, &pv, 4))
185 outb(uint8_t value, uint16_t port)
187 SetPortVal(port, value, 1);
191 outw(uint16_t value, uint16_t port)
193 SetPortVal(port, value, 2);
197 outl(uint32_t value, uint16_t port)
199 SetPortVal(port, value, 4);
204 #error How to enable IO ports on this system?
208 #define PCI_VENDOR(reg) ((reg) & 0xFFFF)
209 #define PCI_VENDOR_INVALID 0xFFFF
211 #define PCI_VENDOR_ID 0x00
212 #define PCI_SUB_VENDOR_ID 0x2c
213 #define PCI_VENDOR_ID_COMPAQ 0x0e11
214 #define PCI_VENDOR_ID_INTEL 0x8086
216 #define PCI_DEVICE(reg) (((reg) >> 16) & 0xFFFF)
217 #define PCI_DEVICE_INVALID 0xFFFF
219 #define PCI_CLASS 0x08
220 #define PCI_CLASS_DEVICE 0x0a
221 #define PCI_CLASS_DISPLAY_VGA 0x0300
222 #define PCI_CLASS_BRIDGE_HOST 0x0600
224 #define PCIC_DISPLAY 0x03
225 #define PCIS_DISPLAY_VGA 0x00
227 #define PCI_HDRTYPE 0x0E
230 struct pci_system_x86 {
231 struct pci_system system;
232 int (*read)(unsigned bus, unsigned dev, unsigned func, pciaddr_t reg, void *data, unsigned size);
233 int (*write)(unsigned bus, unsigned dev, unsigned func, pciaddr_t reg, const void *data, unsigned size);
237 pci_system_x86_conf1_probe(void)
244 outl(0x80000000, 0xCF8);
245 if (inl(0xCF8) == 0x80000000)
253 pci_system_x86_conf1_read(unsigned bus, unsigned dev, unsigned func, pciaddr_t reg, void *data, unsigned size)
255 unsigned addr = 0xCFC + (reg & 3);
259 if (bus >= 0x100 || dev >= 32 || func >= 8 || reg >= 0x100 || size > 4 || size == 3)
263 outl(0x80000000 | (bus << 16) | (dev << 11) | (func << 8) | (reg & ~3), 0xCF8);
264 /* NOTE: x86 is already LE */
272 uint16_t *val = data;
277 uint32_t *val = data;
288 pci_system_x86_conf1_write(unsigned bus, unsigned dev, unsigned func, pciaddr_t reg, const void *data, unsigned size)
290 unsigned addr = 0xCFC + (reg & 3);
294 if (bus >= 0x100 || dev >= 32 || func >= 8 || reg >= 0x100 || size > 4 || size == 3)
298 outl(0x80000000 | (bus << 16) | (dev << 11) | (func << 8) | (reg & ~3), 0xCF8);
299 /* NOTE: x86 is already LE */
302 const uint8_t *val = data;
307 const uint16_t *val = data;
312 const uint32_t *val = data;
323 pci_system_x86_conf2_probe(void)
328 if (inb(0xCF8) == 0 && inb(0xCFA) == 0)
335 pci_system_x86_conf2_read(unsigned bus, unsigned dev, unsigned func, pciaddr_t reg, void *data, unsigned size)
337 unsigned addr = 0xC000 | dev << 8 | reg;
340 if (bus >= 0x100 || dev >= 16 || func >= 8 || reg >= 0x100)
343 outb((func << 1) | 0xF0, 0xCF8);
345 /* NOTE: x86 is already LE */
353 uint16_t *val = data;
358 uint32_t *val = data;
372 pci_system_x86_conf2_write(unsigned bus, unsigned dev, unsigned func, pciaddr_t reg, const void *data, unsigned size)
374 unsigned addr = 0xC000 | dev << 8 | reg;
377 if (bus >= 0x100 || dev >= 16 || func >= 8 || reg >= 0x100)
380 outb((func << 1) | 0xF0, 0xCF8);
382 /* NOTE: x86 is already LE */
385 const uint8_t *val = data;
390 const uint16_t *val = data;
395 const uint32_t *val = data;
408 /* Check that this really looks like a PCI configuration. */
410 pci_system_x86_check(struct pci_system_x86 *pci_sys_x86)
413 uint16_t class, vendor;
415 /* Look on bus 0 for a device that is a host bridge, a VGA card,
416 * or an intel or compaq device. */
418 for (dev = 0; dev < 32; dev++) {
419 if (pci_sys_x86->read(0, dev, 0, PCI_CLASS_DEVICE, &class, sizeof(class)))
421 if (class == PCI_CLASS_BRIDGE_HOST || class == PCI_CLASS_DISPLAY_VGA)
423 if (pci_sys_x86->read(0, dev, 0, PCI_VENDOR_ID, &vendor, sizeof(vendor)))
425 if (vendor == PCI_VENDOR_ID_INTEL || class == PCI_VENDOR_ID_COMPAQ)
433 pci_nfuncs(struct pci_system_x86 *pci_sys_x86, int bus, int dev)
438 err = pci_sys_x86->read(bus, dev, 0, PCI_HDRTYPE, &hdr, sizeof(hdr));
443 return hdr & 0x80 ? 8 : 1;
447 * Read a VGA rom using the 0xc0000 mapping.
450 pci_device_x86_read_rom(struct pci_device *dev, void *buffer)
455 if ((dev->device_class & 0x00ffff00) !=
456 ((PCIC_DISPLAY << 16) | ( PCIS_DISPLAY_VGA << 8))) {
460 memfd = open("/dev/mem", O_RDONLY | O_CLOEXEC);
464 bios = mmap(NULL, dev->rom_size, PROT_READ, 0, memfd, 0xc0000);
465 if (bios == MAP_FAILED) {
470 memcpy(buffer, bios, dev->rom_size);
472 munmap(bios, dev->rom_size);
478 /** Returns the number of regions (base address registers) the device has */
480 pci_device_x86_get_num_regions(uint8_t header_type)
482 switch (header_type & 0x7f) {
490 fprintf(stderr,"unknown header type %02x\n", header_type);
495 /** Masks out the flag bigs of the base address register value */
497 get_map_base( uint32_t val )
505 /** Returns the size of a region based on the all-ones test value */
507 get_test_val_size( uint32_t testval )
514 /* Mask out the flag bits */
515 testval = get_map_base( testval );
519 while ((testval & 1) == 0) {
528 pci_device_x86_probe(struct pci_device *dev)
530 uint8_t irq, hdrtype;
533 /* Many of the fields were filled in during initial device enumeration.
534 * At this point, we need to fill in regions, rom_size, and irq.
537 err = pci_device_cfg_read_u8(dev, &irq, PCI_IRQ);
542 err = pci_device_cfg_read_u8(dev, &hdrtype, PCI_HDRTYPE);
547 for (i = 0; i < pci_device_x86_get_num_regions(hdrtype); i++, bar += 4) {
548 uint32_t addr, testval;
550 /* Get the base address */
551 err = pci_device_cfg_read_u32(dev, &addr, bar);
555 /* Test write all ones to the register, then restore it. */
556 err = pci_device_cfg_write_u32(dev, 0xffffffff, bar);
559 pci_device_cfg_read_u32(dev, &testval, bar);
560 err = pci_device_cfg_write_u32(dev, addr, bar);
563 dev->regions[i].is_IO = 1;
565 dev->regions[i].is_64 = 1;
567 dev->regions[i].is_prefetchable = 1;
570 dev->regions[i].size = get_test_val_size(testval);
572 /* Set the base address value */
573 if (dev->regions[i].is_64) {
576 err = pci_device_cfg_read_u32(dev, &top, bar + 4);
580 dev->regions[i].base_addr = ((uint64_t)top << 32) |
585 dev->regions[i].base_addr = get_map_base(addr);
589 /* If it's a VGA device, set up the rom size for read_rom using the
592 if ((dev->device_class & 0x00ffff00) ==
593 ((PCIC_DISPLAY << 16) | (PCIS_DISPLAY_VGA << 8)))
595 dev->rom_size = 64 * 1024;
601 #if defined(__CYGWIN__)
604 pci_device_x86_map_range(struct pci_device *dev,
605 struct pci_device_mapping *map)
609 phys.pvPhysAddress = (DWORD64)(DWORD32)map->base;
610 phys.dwPhysMemSizeInBytes = map->size;
612 map->memory = (PDWORD)MapPhysToLin(&phys);
613 if (map->memory == NULL)
620 pci_device_x86_unmap_range(struct pci_device *dev,
621 struct pci_device_mapping *map)
625 phys.pvPhysAddress = (DWORD64)(DWORD32)map->base;
626 phys.dwPhysMemSizeInBytes = map->size;
628 if (!UnmapPhysicalMemory(&phys))
637 pci_device_x86_map_range(struct pci_device *dev,
638 struct pci_device_mapping *map)
640 int memfd = open("/dev/mem", O_RDWR | O_CLOEXEC);
641 int prot = PROT_READ;
646 if (map->flags & PCI_DEV_MAP_FLAG_WRITABLE)
649 map->memory = mmap(NULL, map->size, prot, MAP_SHARED, memfd, map->base);
651 if (map->memory == MAP_FAILED)
658 pci_device_x86_unmap_range(struct pci_device *dev,
659 struct pci_device_mapping *map)
661 return pci_device_generic_unmap_range(dev, map);
667 pci_device_x86_read(struct pci_device *dev, void *data,
668 pciaddr_t offset, pciaddr_t size, pciaddr_t *bytes_read)
670 struct pci_system_x86 *pci_sys_x86 = (struct pci_system_x86 *) pci_sys;
675 int toread = 1 << (ffs(0x4 + (offset & 0x03)) - 1);
679 err = pci_sys_x86->read(dev->bus, dev->dev, dev->func, offset, data, toread);
684 data = (char*)data + toread;
686 *bytes_read += toread;
692 pci_device_x86_write(struct pci_device *dev, const void *data,
693 pciaddr_t offset, pciaddr_t size, pciaddr_t *bytes_written)
695 struct pci_system_x86 *pci_sys_x86 = (struct pci_system_x86 *) pci_sys;
703 if (towrite > 4 - (offset & 0x3))
704 towrite = 4 - (offset & 0x3);
706 err = pci_sys_x86->write(dev->bus, dev->dev, dev->func, offset, data, towrite);
711 data = (const char*)data + towrite;
713 *bytes_written += towrite;
719 pci_system_x86_destroy(void)
724 static struct pci_io_handle *
725 pci_device_x86_open_legacy_io(struct pci_io_handle *ret,
726 struct pci_device *dev, pciaddr_t base, pciaddr_t size)
738 pci_device_x86_close_io(struct pci_device *dev, struct pci_io_handle *handle)
740 /* Like in the Linux case, do not disable I/O, as it may be opened several
741 * times, and closed fewer times. */
742 /* x86_disable_io(); */
746 pci_device_x86_read32(struct pci_io_handle *handle, uint32_t reg)
748 return inl(reg + handle->base);
752 pci_device_x86_read16(struct pci_io_handle *handle, uint32_t reg)
754 return inw(reg + handle->base);
758 pci_device_x86_read8(struct pci_io_handle *handle, uint32_t reg)
760 return inb(reg + handle->base);
764 pci_device_x86_write32(struct pci_io_handle *handle, uint32_t reg,
767 outl(data, reg + handle->base);
771 pci_device_x86_write16(struct pci_io_handle *handle, uint32_t reg,
774 outw(data, reg + handle->base);
778 pci_device_x86_write8(struct pci_io_handle *handle, uint32_t reg,
781 outb(data, reg + handle->base);
785 pci_device_x86_map_legacy(struct pci_device *dev, pciaddr_t base,
786 pciaddr_t size, unsigned map_flags, void **addr)
788 struct pci_device_mapping map;
793 map.flags = map_flags;
794 err = pci_device_x86_map_range(dev, &map);
801 pci_device_x86_unmap_legacy(struct pci_device *dev, void *addr,
804 struct pci_device_mapping map;
810 return pci_device_x86_unmap_range(dev, &map);
813 static const struct pci_system_methods x86_pci_methods = {
814 .destroy = pci_system_x86_destroy,
815 .read_rom = pci_device_x86_read_rom,
816 .probe = pci_device_x86_probe,
817 .map_range = pci_device_x86_map_range,
818 .unmap_range = pci_device_x86_unmap_range,
819 .read = pci_device_x86_read,
820 .write = pci_device_x86_write,
821 .fill_capabilities = pci_fill_capabilities_generic,
822 .open_legacy_io = pci_device_x86_open_legacy_io,
823 .close_io = pci_device_x86_close_io,
824 .read32 = pci_device_x86_read32,
825 .read16 = pci_device_x86_read16,
826 .read8 = pci_device_x86_read8,
827 .write32 = pci_device_x86_write32,
828 .write16 = pci_device_x86_write16,
829 .write8 = pci_device_x86_write8,
830 .map_legacy = pci_device_x86_map_legacy,
831 .unmap_legacy = pci_device_x86_unmap_legacy,
834 static int pci_probe(struct pci_system_x86 *pci_sys_x86)
836 if (pci_system_x86_conf1_probe() == 0) {
837 pci_sys_x86->read = pci_system_x86_conf1_read;
838 pci_sys_x86->write = pci_system_x86_conf1_write;
839 if (pci_system_x86_check(pci_sys_x86) == 0)
843 if (pci_system_x86_conf2_probe() == 0) {
844 pci_sys_x86->read = pci_system_x86_conf2_read;
845 pci_sys_x86->write = pci_system_x86_conf2_write;
846 if (pci_system_x86_check(pci_sys_x86) == 0)
854 pci_system_x86_create(void)
856 struct pci_device_private *device;
857 int ret, bus, dev, ndevs, func, nfuncs;
858 struct pci_system_x86 *pci_sys_x86;
861 ret = x86_enable_io();
865 pci_sys_x86 = calloc(1, sizeof(struct pci_system_x86));
866 if (pci_sys_x86 == NULL) {
870 pci_sys = &pci_sys_x86->system;
872 ret = pci_probe(pci_sys_x86);
880 pci_sys->methods = &x86_pci_methods;
883 for (bus = 0; bus < 256; bus++) {
884 for (dev = 0; dev < 32; dev++) {
885 nfuncs = pci_nfuncs(pci_sys_x86, bus, dev);
886 for (func = 0; func < nfuncs; func++) {
887 if (pci_sys_x86->read(bus, dev, func, PCI_VENDOR_ID, ®, sizeof(reg)) != 0)
889 if (PCI_VENDOR(reg) == PCI_VENDOR_INVALID ||
890 PCI_VENDOR(reg) == 0)
897 pci_sys->num_devices = ndevs;
898 pci_sys->devices = calloc(ndevs, sizeof(struct pci_device_private));
899 if (pci_sys->devices == NULL) {
906 device = pci_sys->devices;
907 for (bus = 0; bus < 256; bus++) {
908 for (dev = 0; dev < 32; dev++) {
909 nfuncs = pci_nfuncs(pci_sys_x86, bus, dev);
910 for (func = 0; func < nfuncs; func++) {
911 if (pci_sys_x86->read(bus, dev, func, PCI_VENDOR_ID, ®, sizeof(reg)) != 0)
913 if (PCI_VENDOR(reg) == PCI_VENDOR_INVALID ||
914 PCI_VENDOR(reg) == 0)
916 device->base.domain = 0;
917 device->base.bus = bus;
918 device->base.dev = dev;
919 device->base.func = func;
920 device->base.vendor_id = PCI_VENDOR(reg);
921 device->base.device_id = PCI_DEVICE(reg);
923 if (pci_sys_x86->read(bus, dev, func, PCI_CLASS, ®, sizeof(reg)) != 0)
925 device->base.device_class = reg >> 8;
926 device->base.revision = reg & 0xFF;
928 if (pci_sys_x86->read(bus, dev, func, PCI_SUB_VENDOR_ID, ®, sizeof(reg)) != 0)
930 device->base.subvendor_id = PCI_VENDOR(reg);
931 device->base.subdevice_id = PCI_DEVICE(reg);