OSDN Git Service

b938068471b6ac102248615a7c91a3cf98ce4c9d
[android-x86/external-libpciaccess.git] / src / x86_pci.c
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
39 static int
40 x86_enable_io(void)
41 {
42     if (!ioperm(0, 0xffff, 1))
43         return 0;
44     return errno;
45 }
46
47 static int
48 x86_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
59 static int
60 x86_enable_io(void)
61 {
62     if (!iopl(3))
63         return 0;
64     return errno;
65 }
66
67 static int
68 x86_disable_io(void)
69 {
70     if (!iopl(0))
71         return 0;
72     return errno;
73 }
74
75 #elif defined(__CYGWIN__)
76
77 #include <windows.h>
78
79 /* WinIo declarations */
80 typedef BYTE bool;
81 typedef struct tagPhysStruct {
82     DWORD64 dwPhysMemSizeInBytes;
83     DWORD64 pvPhysAddress;
84     DWORD64 PhysicalMemoryHandle;
85     DWORD64 pvPhysMemLin;
86     DWORD64 pvPhysSection;
87 } tagPhysStruct;
88
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*);
95
96 SHUTDOWNWINIO ShutdownWinIo;
97 GETPORTVAL GetPortVal;
98 SETPORTVAL SetPortVal;
99 INITIALIZEWINIO InitializeWinIo;
100 MAPPHYSTOLIN MapPhysToLin;
101 UNMAPPHYSMEM UnmapPhysicalMemory;
102
103 static int
104 x86_enable_io(void)
105 {
106     HMODULE lib = NULL;
107
108     if ((GetVersion() & 0x80000000) == 0) {
109       /* running on NT, try WinIo version 3 (32 or 64 bits) */
110 #ifdef WIN64
111       lib = LoadLibrary("WinIo64.dll");
112 #else
113       lib = LoadLibrary("WinIo32.dll");
114 #endif
115     }
116
117     if (!lib) {
118       fprintf(stderr, "Failed to load WinIo library.\n");
119       return 1;
120     }
121
122 #define GETPROC(n, d)                                           \
123     n = (d) GetProcAddress(lib, #n);                            \
124     if (!n) {                                                   \
125       fprintf(stderr, "Failed to load " #n " function.\n");     \
126       return 1;                                                 \
127     }
128
129     GETPROC(InitializeWinIo, INITIALIZEWINIO);
130     GETPROC(ShutdownWinIo, SHUTDOWNWINIO);
131     GETPROC(GetPortVal, GETPORTVAL);
132     GETPROC(SetPortVal, SETPORTVAL);
133     GETPROC(MapPhysToLin, MAPPHYSTOLIN);
134     GETPROC(UnmapPhysicalMemory, UNMAPPHYSMEM);
135
136 #undef GETPROC
137
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");
141       return 0;
142     }
143
144     return 0;
145 }
146
147 static int
148 x86_disable_io(void)
149 {
150     ShutdownWinIo();
151     return 1;
152 }
153
154 static inline uint8_t
155 inb(uint16_t port)
156 {
157     DWORD pv;
158
159     if (GetPortVal(port, &pv, 1))
160       return (uint8_t)pv;
161     return 0;
162 }
163
164 static inline uint16_t
165 inw(uint16_t port)
166 {
167     DWORD pv;
168
169     if (GetPortVal(port, &pv, 2))
170       return (uint16_t)pv;
171     return 0;
172 }
173
174 static inline uint32_t
175 inl(uint16_t port)
176 {
177     DWORD pv;
178
179     if (GetPortVal(port, &pv, 4))
180         return (uint32_t)pv;
181     return 0;
182 }
183
184 static inline void
185 outb(uint8_t value, uint16_t port)
186 {
187     SetPortVal(port, value, 1);
188 }
189
190 static inline void
191 outw(uint16_t value, uint16_t port)
192 {
193     SetPortVal(port, value, 2);
194 }
195
196 static inline void
197 outl(uint32_t value, uint16_t port)
198 {
199     SetPortVal(port, value, 4);
200 }
201
202 #else
203
204 #error How to enable IO ports on this system?
205
206 #endif
207
208 #define PCI_VENDOR(reg)         ((reg) & 0xFFFF)
209 #define PCI_VENDOR_INVALID      0xFFFF
210
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
215
216 #define PCI_DEVICE(reg)         (((reg) >> 16) & 0xFFFF)
217 #define PCI_DEVICE_INVALID      0xFFFF
218
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
223
224 #define PCIC_DISPLAY    0x03
225 #define PCIS_DISPLAY_VGA        0x00
226
227 #define PCI_HDRTYPE     0x0E
228 #define PCI_IRQ         0x3C
229
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);
234 };
235
236 static int
237 pci_system_x86_conf1_probe(void)
238 {
239     unsigned long sav;
240     int res = ENODEV;
241
242     outb(0x01, 0xCFB);
243     sav = inl(0xCF8);
244     outl(0x80000000, 0xCF8);
245     if (inl(0xCF8) == 0x80000000)
246         res = 0;
247     outl(sav, 0xCF8);
248
249     return res;
250 }
251
252 static int
253 pci_system_x86_conf1_read(unsigned bus, unsigned dev, unsigned func, pciaddr_t reg, void *data, unsigned size)
254 {
255     unsigned addr = 0xCFC + (reg & 3);
256     unsigned long sav;
257     int ret = 0;
258
259     if (bus >= 0x100 || dev >= 32 || func >= 8 || reg >= 0x100 || size > 4 || size == 3)
260         return EIO;
261
262     sav = inl(0xCF8);
263     outl(0x80000000 | (bus << 16) | (dev << 11) | (func << 8) | (reg & ~3), 0xCF8);
264     /* NOTE: x86 is already LE */
265     switch (size) {
266         case 1: {
267             uint8_t *val = data;
268             *val = inb(addr);
269             break;
270         }
271         case 2: {
272             uint16_t *val = data;
273             *val = inw(addr);
274             break;
275         }
276         case 4: {
277             uint32_t *val = data;
278             *val = inl(addr);
279             break;
280         }
281     }
282     outl(sav, 0xCF8);
283
284     return ret;
285 }
286
287 static int
288 pci_system_x86_conf1_write(unsigned bus, unsigned dev, unsigned func, pciaddr_t reg, const void *data, unsigned size)
289 {
290     unsigned addr = 0xCFC + (reg & 3);
291     unsigned long sav;
292     int ret = 0;
293
294     if (bus >= 0x100 || dev >= 32 || func >= 8 || reg >= 0x100 || size > 4 || size == 3)
295         return EIO;
296
297     sav = inl(0xCF8);
298     outl(0x80000000 | (bus << 16) | (dev << 11) | (func << 8) | (reg & ~3), 0xCF8);
299     /* NOTE: x86 is already LE */
300     switch (size) {
301         case 1: {
302             const uint8_t *val = data;
303             outb(*val, addr);
304             break;
305         }
306         case 2: {
307             const uint16_t *val = data;
308             outw(*val, addr);
309             break;
310         }
311         case 4: {
312             const uint32_t *val = data;
313             outl(*val, addr);
314             break;
315         }
316     }
317     outl(sav, 0xCF8);
318
319     return ret;
320 }
321
322 static int
323 pci_system_x86_conf2_probe(void)
324 {
325     outb(0, 0xCFB);
326     outb(0, 0xCF8);
327     outb(0, 0xCFA);
328     if (inb(0xCF8) == 0 && inb(0xCFA) == 0)
329         return 0;
330
331     return ENODEV;
332 }
333
334 static int
335 pci_system_x86_conf2_read(unsigned bus, unsigned dev, unsigned func, pciaddr_t reg, void *data, unsigned size)
336 {
337     unsigned addr = 0xC000 | dev << 8 | reg;
338     int ret = 0;
339
340     if (bus >= 0x100 || dev >= 16 || func >= 8 || reg >= 0x100)
341         return EIO;
342
343     outb((func << 1) | 0xF0, 0xCF8);
344     outb(bus, 0xCFA);
345     /* NOTE: x86 is already LE */
346     switch (size) {
347         case 1: {
348             uint8_t *val = data;
349             *val = inb(addr);
350             break;
351         }
352         case 2: {
353             uint16_t *val = data;
354             *val = inw(addr);
355             break;
356         }
357         case 4: {
358             uint32_t *val = data;
359             *val = inl(addr);
360             break;
361         }
362         default:
363             ret = EIO;
364             break;
365     }
366     outb(0, 0xCF8);
367
368     return ret;
369 }
370
371 static int
372 pci_system_x86_conf2_write(unsigned bus, unsigned dev, unsigned func, pciaddr_t reg, const void *data, unsigned size)
373 {
374     unsigned addr = 0xC000 | dev << 8 | reg;
375     int ret = 0;
376
377     if (bus >= 0x100 || dev >= 16 || func >= 8 || reg >= 0x100)
378         return EIO;
379
380     outb((func << 1) | 0xF0, 0xCF8);
381     outb(bus, 0xCFA);
382     /* NOTE: x86 is already LE */
383     switch (size) {
384         case 1: {
385             const uint8_t *val = data;
386             outb(*val, addr);
387             break;
388         }
389         case 2: {
390             const uint16_t *val = data;
391             outw(*val, addr);
392             break;
393         }
394         case 4: {
395             const uint32_t *val = data;
396             outl(*val, addr);
397             break;
398         }
399         default:
400             ret = EIO;
401             break;
402     }
403     outb(0, 0xCF8);
404
405     return ret;
406 }
407
408 /* Check that this really looks like a PCI configuration. */
409 static int
410 pci_system_x86_check(struct pci_system_x86 *pci_sys_x86)
411 {
412     int dev;
413     uint16_t class, vendor;
414
415     /* Look on bus 0 for a device that is a host bridge, a VGA card,
416      * or an intel or compaq device.  */
417
418     for (dev = 0; dev < 32; dev++) {
419         if (pci_sys_x86->read(0, dev, 0, PCI_CLASS_DEVICE, &class, sizeof(class)))
420             continue;
421         if (class == PCI_CLASS_BRIDGE_HOST || class == PCI_CLASS_DISPLAY_VGA)
422             return 0;
423         if (pci_sys_x86->read(0, dev, 0, PCI_VENDOR_ID, &vendor, sizeof(vendor)))
424             continue;
425         if (vendor == PCI_VENDOR_ID_INTEL || class == PCI_VENDOR_ID_COMPAQ)
426             return 0;
427     }
428
429     return ENODEV;
430 }
431
432 static int
433 pci_nfuncs(struct pci_system_x86 *pci_sys_x86, int bus, int dev)
434 {
435     uint8_t hdr;
436     int err;
437
438     err = pci_sys_x86->read(bus, dev, 0, PCI_HDRTYPE, &hdr, sizeof(hdr));
439
440     if (err)
441         return err;
442
443     return hdr & 0x80 ? 8 : 1;
444 }
445
446 /**
447  * Read a VGA rom using the 0xc0000 mapping.
448  */
449 static int
450 pci_device_x86_read_rom(struct pci_device *dev, void *buffer)
451 {
452     void *bios;
453     int memfd;
454
455     if ((dev->device_class & 0x00ffff00) !=
456          ((PCIC_DISPLAY << 16) | ( PCIS_DISPLAY_VGA << 8))) {
457         return ENOSYS;
458     }
459
460     memfd = open("/dev/mem", O_RDONLY | O_CLOEXEC);
461     if (memfd == -1)
462         return errno;
463
464     bios = mmap(NULL, dev->rom_size, PROT_READ, 0, memfd, 0xc0000);
465     if (bios == MAP_FAILED) {
466         close(memfd);
467         return errno;
468     }
469
470     memcpy(buffer, bios, dev->rom_size);
471
472     munmap(bios, dev->rom_size);
473     close(memfd);
474
475     return 0;
476 }
477
478 /** Returns the number of regions (base address registers) the device has */
479 static int
480 pci_device_x86_get_num_regions(uint8_t header_type)
481 {
482     switch (header_type & 0x7f) {
483         case 0:
484             return 6;
485         case 1:
486             return 2;
487         case 2:
488             return 1;
489         default:
490             fprintf(stderr,"unknown header type %02x\n", header_type);
491             return 0;
492     }
493 }
494
495 /** Masks out the flag bigs of the base address register value */
496 static uint32_t
497 get_map_base( uint32_t val )
498 {
499     if (val & 0x01)
500         return val & ~0x03;
501     else
502         return val & ~0x0f;
503 }
504
505 /** Returns the size of a region based on the all-ones test value */
506 static unsigned
507 get_test_val_size( uint32_t testval )
508 {
509     unsigned size = 1;
510
511     if (testval == 0)
512         return 0;
513
514     /* Mask out the flag bits */
515     testval = get_map_base( testval );
516     if (!testval)
517         return 0;
518
519     while ((testval & 1) == 0) {
520         size <<= 1;
521         testval >>= 1;
522     }
523
524     return size;
525 }
526
527 static int
528 pci_device_x86_probe(struct pci_device *dev)
529 {
530     uint8_t irq, hdrtype;
531     int err, i, bar;
532
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.
535      */
536
537     err = pci_device_cfg_read_u8(dev, &irq, PCI_IRQ);
538     if (err)
539         return err;
540     dev->irq = irq;
541
542     err = pci_device_cfg_read_u8(dev, &hdrtype, PCI_HDRTYPE);
543     if (err)
544         return err;
545
546     bar = 0x10;
547     for (i = 0; i < pci_device_x86_get_num_regions(hdrtype); i++, bar += 4) {
548         uint32_t addr, testval;
549
550         /* Get the base address */
551         err = pci_device_cfg_read_u32(dev, &addr, bar);
552         if (err != 0)
553             continue;
554
555         /* Test write all ones to the register, then restore it. */
556         err = pci_device_cfg_write_u32(dev, 0xffffffff, bar);
557         if (err != 0)
558             continue;
559         pci_device_cfg_read_u32(dev, &testval, bar);
560         err = pci_device_cfg_write_u32(dev, addr, bar);
561
562         if (addr & 0x01)
563             dev->regions[i].is_IO = 1;
564         if (addr & 0x04)
565             dev->regions[i].is_64 = 1;
566         if (addr & 0x08)
567             dev->regions[i].is_prefetchable = 1;
568
569         /* Set the size */
570         dev->regions[i].size = get_test_val_size(testval);
571
572         /* Set the base address value */
573         if (dev->regions[i].is_64) {
574             uint32_t top;
575
576             err = pci_device_cfg_read_u32(dev, &top, bar + 4);
577             if (err != 0)
578                 continue;
579
580             dev->regions[i].base_addr = ((uint64_t)top << 32) |
581                                         get_map_base(addr);
582             bar += 4;
583             i++;
584         } else {
585             dev->regions[i].base_addr = get_map_base(addr);
586         }
587     }
588
589     /* If it's a VGA device, set up the rom size for read_rom using the
590      * 0xc0000 mapping.
591      */
592     if ((dev->device_class & 0x00ffff00) ==
593         ((PCIC_DISPLAY << 16) | (PCIS_DISPLAY_VGA << 8)))
594     {
595         dev->rom_size = 64 * 1024;
596     }
597
598     return 0;
599 }
600
601 #if defined(__CYGWIN__)
602
603 static int
604 pci_device_x86_map_range(struct pci_device *dev,
605     struct pci_device_mapping *map)
606 {
607     tagPhysStruct phys;
608
609     phys.pvPhysAddress        = (DWORD64)(DWORD32)map->base;
610     phys.dwPhysMemSizeInBytes = map->size;
611
612     map->memory = (PDWORD)MapPhysToLin(&phys);
613     if (map->memory == NULL)
614         return EFAULT;
615
616     return 0;
617 }
618
619 static int
620 pci_device_x86_unmap_range(struct pci_device *dev,
621     struct pci_device_mapping *map)
622 {
623     tagPhysStruct phys;
624
625     phys.pvPhysAddress        = (DWORD64)(DWORD32)map->base;
626     phys.dwPhysMemSizeInBytes = map->size;
627
628     if (!UnmapPhysicalMemory(&phys))
629         return EFAULT;
630
631     return 0;
632 }
633
634 #else
635
636 static int
637 pci_device_x86_map_range(struct pci_device *dev,
638     struct pci_device_mapping *map)
639 {
640     int memfd = open("/dev/mem", O_RDWR | O_CLOEXEC);
641     int prot = PROT_READ;
642
643     if (memfd == -1)
644         return errno;
645
646     if (map->flags & PCI_DEV_MAP_FLAG_WRITABLE)
647         prot |= PROT_WRITE;
648
649     map->memory = mmap(NULL, map->size, prot, MAP_SHARED, memfd, map->base);
650     close(memfd);
651     if (map->memory == MAP_FAILED)
652         return errno;
653
654     return 0;
655 }
656
657 static int
658 pci_device_x86_unmap_range(struct pci_device *dev,
659     struct pci_device_mapping *map)
660 {
661     return pci_device_generic_unamp_range(dev, map);
662 }
663
664 #endif
665
666 static int
667 pci_device_x86_read(struct pci_device *dev, void *data,
668     pciaddr_t offset, pciaddr_t size, pciaddr_t *bytes_read)
669 {
670     struct pci_system_x86 *pci_sys_x86 = (struct pci_system_x86 *) pci_sys;
671     int err;
672
673     *bytes_read = 0;
674     while (size > 0) {
675         int toread = 1 << (ffs(0x4 + (offset & 0x03)) - 1);
676         if (toread > size)
677             toread = size;
678
679         err = pci_sys_x86->read(dev->bus, dev->dev, dev->func, offset, data, toread);
680         if (err)
681             return err;
682
683         offset += toread;
684         data = (char*)data + toread;
685         size -= toread;
686         *bytes_read += toread;
687     }
688     return 0;
689 }
690
691 static int
692 pci_device_x86_write(struct pci_device *dev, const void *data,
693     pciaddr_t offset, pciaddr_t size, pciaddr_t *bytes_written)
694 {
695     struct pci_system_x86 *pci_sys_x86 = (struct pci_system_x86 *) pci_sys;
696     int err;
697
698     *bytes_written = 0;
699     while (size > 0) {
700         int towrite = 4;
701         if (towrite > size)
702             towrite = size;
703         if (towrite > 4 - (offset & 0x3))
704             towrite = 4 - (offset & 0x3);
705
706         err = pci_sys_x86->write(dev->bus, dev->dev, dev->func, offset, data, towrite);
707         if (err)
708             return err;
709
710         offset += towrite;
711         data = (const char*)data + towrite;
712         size -= towrite;
713         *bytes_written += towrite;
714     }
715     return 0;
716 }
717
718 static void
719 pci_system_x86_destroy(void)
720 {
721     x86_disable_io();
722 }
723
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)
727 {
728     x86_enable_io();
729
730     ret->base = base;
731     ret->size = size;
732
733     return ret;
734 }
735
736 static void
737 pci_device_x86_close_io(struct pci_device *dev, struct pci_io_handle *handle)
738 {
739     /* Like in the Linux case, do not disable I/O, as it may be opened several
740      * times, and closed fewer times. */
741     /* x86_disable_io(); */
742 }
743
744 static uint32_t
745 pci_device_x86_read32(struct pci_io_handle *handle, uint32_t reg)
746 {
747     return inl(reg + handle->base);
748 }
749
750 static uint16_t
751 pci_device_x86_read16(struct pci_io_handle *handle, uint32_t reg)
752 {
753     return inw(reg + handle->base);
754 }
755
756 static uint8_t
757 pci_device_x86_read8(struct pci_io_handle *handle, uint32_t reg)
758 {
759     return inb(reg + handle->base);
760 }
761
762 static void
763 pci_device_x86_write32(struct pci_io_handle *handle, uint32_t reg,
764                        uint32_t data)
765 {
766     outl(data, reg + handle->base);
767 }
768
769 static void
770 pci_device_x86_write16(struct pci_io_handle *handle, uint32_t reg,
771                        uint16_t data)
772 {
773     outw(data, reg + handle->base);
774 }
775
776 static void
777 pci_device_x86_write8(struct pci_io_handle *handle, uint32_t reg,
778                       uint8_t data)
779 {
780     outb(data, reg + handle->base);
781 }
782
783 static int
784 pci_device_x86_map_legacy(struct pci_device *dev, pciaddr_t base,
785     pciaddr_t size, unsigned map_flags, void **addr)
786 {
787     struct pci_device_mapping map;
788     int err;
789
790     map.base = base;
791     map.size = size;
792     map.flags = map_flags;
793     err = pci_device_x86_map_range(dev, &map);
794     *addr = map.memory;
795
796     return err;
797 }
798
799 static int
800 pci_device_x86_unmap_legacy(struct pci_device *dev, void *addr,
801     pciaddr_t size)
802 {
803     struct pci_device_mapping map;
804
805     map.size = size;
806     map.flags = 0;
807     map.memory = addr;
808
809     return pci_device_x86_unmap_range(dev, &map);
810 }
811
812 static const struct pci_system_methods x86_pci_methods = {
813     .destroy = pci_system_x86_destroy,
814     .read_rom = pci_device_x86_read_rom,
815     .probe = pci_device_x86_probe,
816     .map_range = pci_device_x86_map_range,
817     .unmap_range = pci_device_x86_unmap_range,
818     .read = pci_device_x86_read,
819     .write = pci_device_x86_write,
820     .fill_capabilities = pci_fill_capabilities_generic,
821     .open_legacy_io = pci_device_x86_open_legacy_io,
822     .close_io = pci_device_x86_close_io,
823     .read32 = pci_device_x86_read32,
824     .read16 = pci_device_x86_read16,
825     .read8 = pci_device_x86_read8,
826     .write32 = pci_device_x86_write32,
827     .write16 = pci_device_x86_write16,
828     .write8 = pci_device_x86_write8,
829     .map_legacy = pci_device_x86_map_legacy,
830     .unmap_legacy = pci_device_x86_unmap_legacy,
831 };
832
833 static int pci_probe(struct pci_system_x86 *pci_sys_x86)
834 {
835     if (pci_system_x86_conf1_probe() == 0) {
836         pci_sys_x86->read = pci_system_x86_conf1_read;
837         pci_sys_x86->write = pci_system_x86_conf1_write;
838         if (pci_system_x86_check(pci_sys_x86) == 0)
839             return 0;
840     }
841
842     if (pci_system_x86_conf2_probe() == 0) {
843         pci_sys_x86->read = pci_system_x86_conf2_read;
844         pci_sys_x86->write = pci_system_x86_conf2_write;
845         if (pci_system_x86_check(pci_sys_x86) == 0)
846             return 0;
847     }
848
849     return ENODEV;
850 }
851
852 _pci_hidden int
853 pci_system_x86_create(void)
854 {
855     struct pci_device_private *device;
856     int ret, bus, dev, ndevs, func, nfuncs;
857     struct pci_system_x86 *pci_sys_x86;
858     uint32_t reg;
859
860     ret = x86_enable_io();
861     if (ret)
862         return ret;
863
864     pci_sys_x86 = calloc(1, sizeof(struct pci_system_x86));
865     if (pci_sys_x86 == NULL) {
866         x86_disable_io();
867         return ENOMEM;
868     }
869     pci_sys = &pci_sys_x86->system;
870
871     ret = pci_probe(pci_sys_x86);
872     if (ret) {
873         x86_disable_io();
874         free(pci_sys_x86);
875         pci_sys = NULL;
876         return ret;
877     }
878
879     pci_sys->methods = &x86_pci_methods;
880
881     ndevs = 0;
882     for (bus = 0; bus < 256; bus++) {
883         for (dev = 0; dev < 32; dev++) {
884             nfuncs = pci_nfuncs(pci_sys_x86, bus, dev);
885             for (func = 0; func < nfuncs; func++) {
886                 if (pci_sys_x86->read(bus, dev, func, PCI_VENDOR_ID, &reg, sizeof(reg)) != 0)
887                     continue;
888                 if (PCI_VENDOR(reg) == PCI_VENDOR_INVALID ||
889                     PCI_VENDOR(reg) == 0)
890                     continue;
891                 ndevs++;
892             }
893         }
894     }
895
896     pci_sys->num_devices = ndevs;
897     pci_sys->devices = calloc(ndevs, sizeof(struct pci_device_private));
898     if (pci_sys->devices == NULL) {
899         x86_disable_io();
900         free(pci_sys_x86);
901         pci_sys = NULL;
902         return ENOMEM;
903     }
904
905     device = pci_sys->devices;
906     for (bus = 0; bus < 256; bus++) {
907         for (dev = 0; dev < 32; dev++) {
908             nfuncs = pci_nfuncs(pci_sys_x86, bus, dev);
909             for (func = 0; func < nfuncs; func++) {
910                 if (pci_sys_x86->read(bus, dev, func, PCI_VENDOR_ID, &reg, sizeof(reg)) != 0)
911                     continue;
912                 if (PCI_VENDOR(reg) == PCI_VENDOR_INVALID ||
913                     PCI_VENDOR(reg) == 0)
914                     continue;
915                 device->base.domain = 0;
916                 device->base.bus = bus;
917                 device->base.dev = dev;
918                 device->base.func = func;
919                 device->base.vendor_id = PCI_VENDOR(reg);
920                 device->base.device_id = PCI_DEVICE(reg);
921
922                 if (pci_sys_x86->read(bus, dev, func, PCI_CLASS, &reg, sizeof(reg)) != 0)
923                     continue;
924                 device->base.device_class = reg >> 8;
925                 device->base.revision = reg & 0xFF;
926
927                 if (pci_sys_x86->read(bus, dev, func, PCI_SUB_VENDOR_ID, &reg, sizeof(reg)) != 0)
928                     continue;
929                 device->base.subvendor_id = PCI_VENDOR(reg);
930                 device->base.subdevice_id = PCI_DEVICE(reg);
931
932                 device++;
933             }
934         }
935     }
936
937     return 0;
938 }