• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2018 Damien Zammit
3  * Copyright (c) 2017 Joan Lledó
4  * Copyright (c) 2009, 2012, 2020 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 
45 int
x86_enable_io(void)46 x86_enable_io(void)
47 {
48     if (!ioperm(0, 0xffff, 1))
49         return 0;
50     return errno;
51 }
52 
53 int
x86_disable_io(void)54 x86_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 
65 static int
x86_enable_io(void)66 x86_enable_io(void)
67 {
68     if (!iopl(3))
69         return 0;
70     return errno;
71 }
72 
73 static int
x86_disable_io(void)74 x86_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 */
86 typedef BYTE bool;
87 typedef struct tagPhysStruct {
88     DWORD64 dwPhysMemSizeInBytes;
89     DWORD64 pvPhysAddress;
90     DWORD64 PhysicalMemoryHandle;
91     DWORD64 pvPhysMemLin;
92     DWORD64 pvPhysSection;
93 } tagPhysStruct;
94 
95 typedef bool  (_stdcall* INITIALIZEWINIO)(void);
96 typedef void  (_stdcall* SHUTDOWNWINIO)(void);
97 typedef bool  (_stdcall* GETPORTVAL)(WORD,PDWORD,BYTE);
98 typedef bool  (_stdcall* SETPORTVAL)(WORD,DWORD,BYTE);
99 typedef PBYTE (_stdcall* MAPPHYSTOLIN)(tagPhysStruct*);
100 typedef bool  (_stdcall* UNMAPPHYSMEM)(tagPhysStruct*);
101 
102 SHUTDOWNWINIO ShutdownWinIo;
103 GETPORTVAL GetPortVal;
104 SETPORTVAL SetPortVal;
105 INITIALIZEWINIO InitializeWinIo;
106 MAPPHYSTOLIN MapPhysToLin;
107 UNMAPPHYSMEM UnmapPhysicalMemory;
108 
109 static int
x86_enable_io(void)110 x86_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 
153 static int
x86_disable_io(void)154 x86_disable_io(void)
155 {
156     ShutdownWinIo();
157     return 1;
158 }
159 
160 static inline uint8_t
inb(uint16_t port)161 inb(uint16_t port)
162 {
163     DWORD pv;
164 
165     if (GetPortVal(port, &pv, 1))
166       return (uint8_t)pv;
167     return 0;
168 }
169 
170 static inline uint16_t
inw(uint16_t port)171 inw(uint16_t port)
172 {
173     DWORD pv;
174 
175     if (GetPortVal(port, &pv, 2))
176       return (uint16_t)pv;
177     return 0;
178 }
179 
180 static inline uint32_t
inl(uint16_t port)181 inl(uint16_t port)
182 {
183     DWORD pv;
184 
185     if (GetPortVal(port, &pv, 4))
186         return (uint32_t)pv;
187     return 0;
188 }
189 
190 static inline void
outb(uint8_t value,uint16_t port)191 outb(uint8_t value, uint16_t port)
192 {
193     SetPortVal(port, value, 1);
194 }
195 
196 static inline void
outw(uint16_t value,uint16_t port)197 outw(uint16_t value, uint16_t port)
198 {
199     SetPortVal(port, value, 2);
200 }
201 
202 static inline void
outl(uint32_t value,uint16_t port)203 outl(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 
cmp_devices(const void * dev1,const void * dev2)214 static int cmp_devices(const void *dev1, const void *dev2)
215 {
216     const struct pci_device *d1 = dev1;
217     const struct pci_device *d2 = dev2;
218 
219     if (d1->bus != d2->bus) {
220         return (d1->bus > d2->bus) ? 1 : -1;
221     }
222 
223     if (d1->dev != d2->dev) {
224         return (d1->dev > d2->dev) ? 1 : -1;
225     }
226 
227     return (d1->func > d2->func) ? 1 : -1;
228 }
229 
230 static void
sort_devices(void)231 sort_devices(void)
232 {
233     qsort(pci_sys->devices, pci_sys->num_devices,
234           sizeof (pci_sys->devices[0]), &cmp_devices);
235 }
236 
237 #if defined(__GNU__)
238 #include <mach.h>
239 #include <hurd.h>
240 #include <device/device.h>
241 #endif
242 
243 int
pci_system_x86_map_dev_mem(void ** dest,size_t mem_offset,size_t mem_size,int write)244 pci_system_x86_map_dev_mem(void **dest, size_t mem_offset, size_t mem_size, int write)
245 {
246 #if defined(__GNU__)
247     int err;
248     mach_port_t master_device;
249     mach_port_t devmem;
250     mach_port_t pager;
251     dev_mode_t mode = D_READ;
252     vm_prot_t prot = VM_PROT_READ;
253     int pagesize;
254 
255     if (get_privileged_ports (NULL, &master_device)) {
256         *dest = 0;
257         return EPERM;
258     }
259 
260     if (write) {
261         mode |= D_WRITE;
262         prot |= VM_PROT_WRITE;
263     }
264 
265     err = device_open (master_device, mode, "mem", &devmem);
266     mach_port_deallocate (mach_task_self (), master_device);
267     if (err)
268         return err;
269 
270     pagesize = getpagesize();
271     if (mem_size % pagesize)
272         mem_size += pagesize - (mem_size % pagesize);
273 
274     err = device_map (devmem, prot, mem_offset, mem_size, &pager, 0);
275     device_close (devmem);
276     mach_port_deallocate (mach_task_self (), devmem);
277     if (err)
278         return err;
279 
280     err = vm_map (mach_task_self (), (vm_address_t *)dest, mem_size,
281                   (vm_address_t) 0, /* mask */
282                   1, /* anywhere? */
283                   pager, 0,
284                   0, /* copy */
285                   prot, VM_PROT_ALL, VM_INHERIT_SHARE);
286     mach_port_deallocate (mach_task_self (), pager);
287     if (err)
288         return err;
289 
290     return err;
291 #else
292     int prot = PROT_READ;
293     int flags = O_RDONLY;
294     int memfd;
295 
296     if (write) {
297         prot |= PROT_WRITE;
298 	flags = O_RDWR;
299     }
300     memfd = open("/dev/mem", flags | O_CLOEXEC);
301     if (memfd == -1)
302 	return errno;
303 
304     *dest = mmap(NULL, mem_size, prot, MAP_SHARED, memfd, mem_offset);
305     if (*dest == MAP_FAILED) {
306 	close(memfd);
307 	*dest = NULL;
308 	return errno;
309     }
310 
311     close(memfd);
312     return 0;
313 #endif
314 }
315 
316 static int
pci_system_x86_conf1_probe(void)317 pci_system_x86_conf1_probe(void)
318 {
319     unsigned long sav;
320     int res = ENODEV;
321 
322     outb(0x01, 0xCFB);
323     sav = inl(0xCF8);
324     outl(0x80000000, 0xCF8);
325     if (inl(0xCF8) == 0x80000000)
326 	res = 0;
327     outl(sav, 0xCF8);
328 
329     return res;
330 }
331 
332 static int
pci_system_x86_conf1_read(unsigned bus,unsigned dev,unsigned func,pciaddr_t reg,void * data,unsigned size)333 pci_system_x86_conf1_read(unsigned bus, unsigned dev, unsigned func, pciaddr_t reg, void *data, unsigned size)
334 {
335     unsigned addr = 0xCFC + (reg & 3);
336     unsigned long sav;
337     int ret = 0;
338 
339     if (bus >= 0x100 || dev >= 32 || func >= 8 || reg >= 0x100 || size > 4 || size == 3)
340 	return EIO;
341 
342     sav = inl(0xCF8);
343     outl(0x80000000 | (bus << 16) | (dev << 11) | (func << 8) | (reg & ~3), 0xCF8);
344     /* NOTE: x86 is already LE */
345     switch (size) {
346 	case 1: {
347 	    uint8_t *val = data;
348 	    *val = inb(addr);
349 	    break;
350 	}
351 	case 2: {
352 	    uint16_t *val = data;
353 	    *val = inw(addr);
354 	    break;
355 	}
356 	case 4: {
357 	    uint32_t *val = data;
358 	    *val = inl(addr);
359 	    break;
360 	}
361     }
362     outl(sav, 0xCF8);
363 
364     return ret;
365 }
366 
367 static int
pci_system_x86_conf1_write(unsigned bus,unsigned dev,unsigned func,pciaddr_t reg,const void * data,unsigned size)368 pci_system_x86_conf1_write(unsigned bus, unsigned dev, unsigned func, pciaddr_t reg, const void *data, unsigned size)
369 {
370     unsigned addr = 0xCFC + (reg & 3);
371     unsigned long sav;
372     int ret = 0;
373 
374     if (bus >= 0x100 || dev >= 32 || func >= 8 || reg >= 0x100 || size > 4 || size == 3)
375 	return EIO;
376 
377     sav = inl(0xCF8);
378     outl(0x80000000 | (bus << 16) | (dev << 11) | (func << 8) | (reg & ~3), 0xCF8);
379     /* NOTE: x86 is already LE */
380     switch (size) {
381 	case 1: {
382 	    const uint8_t *val = data;
383 	    outb(*val, addr);
384 	    break;
385 	}
386 	case 2: {
387 	    const uint16_t *val = data;
388 	    outw(*val, addr);
389 	    break;
390 	}
391 	case 4: {
392 	    const uint32_t *val = data;
393 	    outl(*val, addr);
394 	    break;
395 	}
396     }
397     outl(sav, 0xCF8);
398 
399     return ret;
400 }
401 
402 static int
pci_system_x86_conf2_probe(void)403 pci_system_x86_conf2_probe(void)
404 {
405     outb(0, 0xCFB);
406     outb(0, 0xCF8);
407     outb(0, 0xCFA);
408     if (inb(0xCF8) == 0 && inb(0xCFA) == 0)
409 	return 0;
410 
411     return ENODEV;
412 }
413 
414 static int
pci_system_x86_conf2_read(unsigned bus,unsigned dev,unsigned func,pciaddr_t reg,void * data,unsigned size)415 pci_system_x86_conf2_read(unsigned bus, unsigned dev, unsigned func, pciaddr_t reg, void *data, unsigned size)
416 {
417     unsigned addr = 0xC000 | dev << 8 | reg;
418     int ret = 0;
419 
420     if (bus >= 0x100 || dev >= 16 || func >= 8 || reg >= 0x100)
421 	return EIO;
422 
423     outb((func << 1) | 0xF0, 0xCF8);
424     outb(bus, 0xCFA);
425     /* NOTE: x86 is already LE */
426     switch (size) {
427 	case 1: {
428 	    uint8_t *val = data;
429 	    *val = inb(addr);
430 	    break;
431 	}
432 	case 2: {
433 	    uint16_t *val = data;
434 	    *val = inw(addr);
435 	    break;
436 	}
437 	case 4: {
438 	    uint32_t *val = data;
439 	    *val = inl(addr);
440 	    break;
441 	}
442 	default:
443 	    ret = EIO;
444 	    break;
445     }
446     outb(0, 0xCF8);
447 
448     return ret;
449 }
450 
451 static int
pci_system_x86_conf2_write(unsigned bus,unsigned dev,unsigned func,pciaddr_t reg,const void * data,unsigned size)452 pci_system_x86_conf2_write(unsigned bus, unsigned dev, unsigned func, pciaddr_t reg, const void *data, unsigned size)
453 {
454     unsigned addr = 0xC000 | dev << 8 | reg;
455     int ret = 0;
456 
457     if (bus >= 0x100 || dev >= 16 || func >= 8 || reg >= 0x100)
458 	return EIO;
459 
460     outb((func << 1) | 0xF0, 0xCF8);
461     outb(bus, 0xCFA);
462     /* NOTE: x86 is already LE */
463     switch (size) {
464 	case 1: {
465 	    const uint8_t *val = data;
466 	    outb(*val, addr);
467 	    break;
468 	}
469 	case 2: {
470 	    const uint16_t *val = data;
471 	    outw(*val, addr);
472 	    break;
473 	}
474 	case 4: {
475 	    const uint32_t *val = data;
476 	    outl(*val, addr);
477 	    break;
478 	}
479 	default:
480 	    ret = EIO;
481 	    break;
482     }
483     outb(0, 0xCF8);
484 
485     return ret;
486 }
487 
488 /* Check that this really looks like a PCI configuration. */
489 static error_t
pci_system_x86_check(void)490 pci_system_x86_check (void)
491 {
492     int dev;
493     uint16_t class, vendor;
494     struct pci_device tmpdev = { 0 };
495 
496     /* Look on bus 0 for a device that is a host bridge, a VGA card,
497      * or an intel or compaq device.  */
498     tmpdev.bus = 0;
499     tmpdev.func = 0;
500     class = 0;
501     vendor = 0;
502 
503     for (dev = 0; dev < 32; dev++) {
504        tmpdev.dev = dev;
505        if (pci_device_cfg_read_u16 (&tmpdev, &class, PCI_CLASS_DEVICE))
506            continue;
507        if (class == PCI_CLASS_BRIDGE_HOST || class == PCI_CLASS_DISPLAY_VGA)
508            return 0;
509        if (pci_device_cfg_read_u16 (&tmpdev, &vendor, PCI_VENDOR_ID))
510            continue;
511        if (vendor == PCI_VENDOR_ID_INTEL || class == PCI_VENDOR_ID_COMPAQ)
512            return 0;
513     }
514 
515     return ENODEV;
516 }
517 
518 static int
pci_nfuncs(struct pci_device * dev,uint8_t * nfuncs)519 pci_nfuncs(struct pci_device *dev, uint8_t *nfuncs)
520 {
521     uint8_t hdr;
522     int err;
523     struct pci_device tmpdev = *dev;
524 
525     tmpdev.func = 0;
526 
527     err = pci_device_cfg_read_u8 (&tmpdev, &hdr, PCI_HDRTYPE);
528 
529     if (err)
530 	return err;
531 
532     *nfuncs = hdr & 0x80 ? 8 : 1;
533     return err;
534 }
535 
536 /**
537  * Read a PCI rom.
538  */
539 static error_t
pci_device_x86_read_rom(struct pci_device * dev,void * buffer)540 pci_device_x86_read_rom(struct pci_device *dev, void *buffer)
541 {
542     void *bios = NULL;
543     struct pci_device_private *d = (struct pci_device_private *)dev;
544 
545     int err;
546     if ( (err = pci_system_x86_map_dev_mem(&bios, d->rom_base, dev->rom_size, 0)) )
547         return err;
548 
549     memcpy(buffer, bios, dev->rom_size);
550     munmap(bios, dev->rom_size);
551     return 0;
552 }
553 
554 /** Returns the number of regions (base address registers) the device has */
555 static int
pci_device_x86_get_num_regions(uint8_t header_type)556 pci_device_x86_get_num_regions(uint8_t header_type)
557 {
558     switch (header_type & 0x7f) {
559 	case 0:
560 	    return 6;
561 	case 1:
562 	    return 2;
563 	case 2:
564 	    return 1;
565 	default:
566 	    fprintf(stderr,"unknown header type %02x\n", header_type);
567 	    return 0;
568     }
569 }
570 
571 /** Masks out the flag bigs of the base address register value */
572 static uint32_t
get_map_base(uint32_t val)573 get_map_base( uint32_t val )
574 {
575     if (val & 0x01)
576 	return val & ~0x03;
577     else
578 	return val & ~0x0f;
579 }
580 
581 /** Returns the size of a region based on the all-ones test value */
582 static unsigned
get_test_val_size(uint32_t testval)583 get_test_val_size( uint32_t testval )
584 {
585     unsigned size = 1;
586 
587     if (testval == 0)
588 	return 0;
589 
590     /* Mask out the flag bits */
591     testval = get_map_base( testval );
592     if (!testval)
593 	return 0;
594 
595     while ((testval & 1) == 0) {
596 	size <<= 1;
597 	testval >>= 1;
598     }
599 
600     return size;
601 }
602 
603 /* Read BAR `reg_num' in `dev' and map the data if any */
604 static error_t
pci_device_x86_region_probe(struct pci_device * dev,int reg_num)605 pci_device_x86_region_probe (struct pci_device *dev, int reg_num)
606 {
607     error_t err;
608     uint8_t offset;
609     uint32_t reg, addr, testval;
610 
611     offset = PCI_BAR_ADDR_0 + 0x4 * reg_num;
612 
613     /* Get the base address */
614     err = pci_device_cfg_read_u32 (dev, &addr, offset);
615     if (err)
616         return err;
617 
618     /* Test write all ones to the register, then restore it. */
619     reg = 0xffffffff;
620     err = pci_device_cfg_write_u32 (dev, reg, offset);
621     if (err)
622         return err;
623     err = pci_device_cfg_read_u32 (dev, &testval, offset);
624     if (err)
625         return err;
626     err = pci_device_cfg_write_u32 (dev, addr, offset);
627     if (err)
628         return err;
629 
630     if (addr & 0x01)
631         dev->regions[reg_num].is_IO = 1;
632     if (addr & 0x04)
633         dev->regions[reg_num].is_64 = 1;
634     if (addr & 0x08)
635         dev->regions[reg_num].is_prefetchable = 1;
636 
637     /* Set the size */
638     dev->regions[reg_num].size = get_test_val_size (testval);
639 
640     /* Set the base address value */
641     dev->regions[reg_num].base_addr = get_map_base (addr);
642 
643     if (dev->regions[reg_num].is_64)
644     {
645         err = pci_device_cfg_read_u32 (dev, &addr, offset + 4);
646         if (err)
647             return err;
648 
649         dev->regions[reg_num].base_addr |= ((uint64_t) addr << 32);
650     }
651 
652     if (dev->regions[reg_num].is_IO)
653     {
654         /* Enable the I/O Space bit */
655         err = pci_device_cfg_read_u32 (dev, &reg, PCI_COMMAND);
656         if (err)
657             return err;
658 
659         if (!(reg & 0x1))
660         {
661             reg |= 0x1;
662 
663             err = pci_device_cfg_write_u32 (dev, reg, PCI_COMMAND);
664             if (err)
665                 return err;
666         }
667     }
668     else if (dev->regions[reg_num].size > 0)
669     {
670         /* Enable the Memory Space bit */
671         err = pci_device_cfg_read_u32 (dev, &reg, 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 
685     /* Clear the map pointer */
686     dev->regions[reg_num].memory = 0;
687 
688     return 0;
689 }
690 
691 /* Read the XROMBAR in `dev' and save the rom size and rom base */
692 static error_t
pci_device_x86_probe_rom(struct pci_device * dev)693 pci_device_x86_probe_rom (struct pci_device *dev)
694 {
695     error_t err;
696     uint8_t reg_8, xrombar_addr;
697     uint32_t reg, reg_back;
698     pciaddr_t rom_size;
699     pciaddr_t rom_base;
700     struct pci_device_private *d = (struct pci_device_private *)dev;
701 
702     /* First we need to know which type of header is this */
703     err = pci_device_cfg_read_u8 (dev, &reg_8, PCI_HDRTYPE);
704     if (err)
705         return err;
706 
707     /* Get the XROMBAR register address */
708     switch (reg_8 & 0x3)
709     {
710     case PCI_HDRTYPE_DEVICE:
711         xrombar_addr = PCI_XROMBAR_ADDR_00;
712         break;
713     case PCI_HDRTYPE_BRIDGE:
714         xrombar_addr = PCI_XROMBAR_ADDR_01;
715         break;
716     default:
717         return -1;
718     }
719 
720     /* Get size and physical address */
721     err = pci_device_cfg_read_u32 (dev, &reg, xrombar_addr);
722     if (err)
723         return err;
724 
725     reg_back = reg;
726     reg = 0xFFFFF800;            /* Base address: first 21 bytes */
727     err = pci_device_cfg_write_u32 (dev, reg, xrombar_addr);
728     if (err)
729         return err;
730     err = pci_device_cfg_read_u32 (dev, &reg, xrombar_addr);
731     if (err)
732         return err;
733 
734     rom_size = (~reg + 1);
735     rom_base = reg_back & reg;
736 
737     if (rom_size == 0)
738         return 0;
739 
740     /* Enable the address decoder and write the physical address back */
741     reg_back |= 0x1;
742     err = pci_device_cfg_write_u32 (dev, reg_back, xrombar_addr);
743     if (err)
744         return err;
745 
746     /* Enable the Memory Space bit */
747     err = pci_device_cfg_read_u32 (dev, &reg, PCI_COMMAND);
748     if (err)
749         return err;
750 
751     if (!(reg & 0x2))
752     {
753         reg |= 0x2;
754 
755         err = pci_device_cfg_write_u32 (dev, reg, PCI_COMMAND);
756         if (err)
757             return err;
758     }
759 
760     dev->rom_size = rom_size;
761     d->rom_base = rom_base;
762 
763     return 0;
764 }
765 
766 /* Configure BARs and ROM */
767 static error_t
pci_device_x86_probe(struct pci_device * dev)768 pci_device_x86_probe (struct pci_device *dev)
769 {
770     error_t err;
771     uint8_t hdrtype;
772     int i;
773 
774     /* Probe BARs */
775     err = pci_device_cfg_read_u8 (dev, &hdrtype, PCI_HDRTYPE);
776     if (err)
777         return err;
778 
779     for (i = 0; i < pci_device_x86_get_num_regions (hdrtype); i++)
780     {
781         err = pci_device_x86_region_probe (dev, i);
782         if (err)
783             return err;
784 
785         if (dev->regions[i].is_64)
786             /* Move the pointer one BAR ahead */
787             i++;
788     }
789 
790     /* Probe ROM */
791     pci_device_x86_probe_rom(dev);
792 
793     return 0;
794 }
795 
796 /* Recursively scan bus number `bus' */
797 static error_t
pci_system_x86_scan_bus(uint8_t bus)798 pci_system_x86_scan_bus (uint8_t bus)
799 {
800     error_t err;
801     uint8_t dev, func, nfuncs, hdrtype, secbus;
802     uint32_t reg;
803     struct pci_device_private *d, *devices;
804     struct pci_device scratchdev;
805 
806     scratchdev.bus = bus;
807 
808     for (dev = 0; dev < 32; dev++)
809     {
810         scratchdev.dev = dev;
811         scratchdev.func = 0;
812         err = pci_nfuncs (&scratchdev, &nfuncs);
813         if (err)
814            return err;
815 
816         for (func = 0; func < nfuncs; func++)
817         {
818             scratchdev.func = func;
819             err = pci_device_cfg_read_u32 (&scratchdev, &reg, PCI_VENDOR_ID);
820             if (err)
821                 return err;
822 
823             if (PCI_VENDOR (reg) == PCI_VENDOR_INVALID || PCI_VENDOR (reg) == 0)
824                 continue;
825 
826             err = pci_device_cfg_read_u32 (&scratchdev, &reg, PCI_CLASS);
827             if (err)
828                 return err;
829 
830             err = pci_device_cfg_read_u8 (&scratchdev, &hdrtype, PCI_HDRTYPE);
831             if (err)
832                 return err;
833 
834             devices =
835               realloc (pci_sys->devices,
836                        (pci_sys->num_devices + 1) * sizeof (struct pci_device_private));
837             if (!devices)
838                 return ENOMEM;
839 
840             d = devices + pci_sys->num_devices;
841             memset (d, 0, sizeof (struct pci_device_private));
842 
843             /* Fixed values as PCI express is still not supported */
844             d->base.domain = 0;
845             d->base.bus = bus;
846             d->base.dev = dev;
847             d->base.func = func;
848 
849             d->base.device_class = reg >> 8;
850 
851             pci_sys->devices = devices;
852             pci_sys->num_devices++;
853 
854             switch (hdrtype & 0x3)
855             {
856             case PCI_HDRTYPE_DEVICE:
857                 break;
858             case PCI_HDRTYPE_BRIDGE:
859             case PCI_HDRTYPE_CARDBUS:
860                 {
861                     err = pci_device_cfg_read_u8 (&scratchdev, &secbus, PCI_SECONDARY_BUS);
862                     if (err)
863                         return err;
864 
865                     err = pci_system_x86_scan_bus (secbus);
866                     if (err)
867                         return err;
868 
869                     break;
870                 }
871             default:
872                 /* Unknown header, do nothing */
873                 break;
874             }
875         }
876     }
877 
878     return 0;
879 }
880 
881 #if defined(__CYGWIN__)
882 
883 static int
pci_device_x86_map_range(struct pci_device * dev,struct pci_device_mapping * map)884 pci_device_x86_map_range(struct pci_device *dev,
885     struct pci_device_mapping *map)
886 {
887     tagPhysStruct phys;
888 
889     phys.pvPhysAddress        = (DWORD64)(DWORD32)map->base;
890     phys.dwPhysMemSizeInBytes = map->size;
891 
892     map->memory = (PDWORD)MapPhysToLin(&phys);
893     if (map->memory == NULL)
894         return EFAULT;
895 
896     return 0;
897 }
898 
899 static int
pci_device_x86_unmap_range(struct pci_device * dev,struct pci_device_mapping * map)900 pci_device_x86_unmap_range(struct pci_device *dev,
901     struct pci_device_mapping *map)
902 {
903     tagPhysStruct phys;
904 
905     phys.pvPhysAddress        = (DWORD64)(DWORD32)map->base;
906     phys.dwPhysMemSizeInBytes = map->size;
907 
908     if (!UnmapPhysicalMemory(&phys))
909         return EFAULT;
910 
911     return 0;
912 }
913 
914 #else
915 
916 static int
pci_device_x86_map_range(struct pci_device * dev,struct pci_device_mapping * map)917 pci_device_x86_map_range(struct pci_device *dev,
918     struct pci_device_mapping *map)
919 {
920     int err;
921     if ( (err = pci_system_x86_map_dev_mem(&map->memory, map->base, map->size,
922                             map->flags & PCI_DEV_MAP_FLAG_WRITABLE)))
923         return err;
924 
925     return 0;
926 }
927 
928 static int
pci_device_x86_unmap_range(struct pci_device * dev,struct pci_device_mapping * map)929 pci_device_x86_unmap_range(struct pci_device *dev,
930     struct pci_device_mapping *map)
931 {
932     int err;
933     err = pci_device_generic_unmap_range(dev, map);
934     map->memory = NULL;
935 
936     return err;
937 }
938 
939 #endif
940 
941 static int
pci_device_x86_read_conf1(struct pci_device * dev,void * data,pciaddr_t offset,pciaddr_t size,pciaddr_t * bytes_read)942 pci_device_x86_read_conf1(struct pci_device *dev, void *data,
943     pciaddr_t offset, pciaddr_t size, pciaddr_t *bytes_read)
944 {
945     int err;
946 
947     *bytes_read = 0;
948     while (size > 0) {
949 	int toread = 1 << (ffs(0x4 + (offset & 0x03)) - 1);
950 	if (toread > size)
951 	    toread = size;
952 
953 	err = pci_system_x86_conf1_read(dev->bus, dev->dev, dev->func, offset, data, toread);
954 	if (err)
955 	    return err;
956 
957 	offset += toread;
958 	data = (char*)data + toread;
959 	size -= toread;
960 	*bytes_read += toread;
961     }
962     return 0;
963 }
964 
965 static int
pci_device_x86_read_conf2(struct pci_device * dev,void * data,pciaddr_t offset,pciaddr_t size,pciaddr_t * bytes_read)966 pci_device_x86_read_conf2(struct pci_device *dev, void *data,
967     pciaddr_t offset, pciaddr_t size, pciaddr_t *bytes_read)
968 {
969     int err;
970 
971     *bytes_read = 0;
972     while (size > 0) {
973 	int toread = 1 << (ffs(0x4 + (offset & 0x03)) - 1);
974 	if (toread > size)
975 	    toread = size;
976 
977 	err = pci_system_x86_conf2_read(dev->bus, dev->dev, dev->func, offset, data, toread);
978 	if (err)
979 	    return err;
980 
981 	offset += toread;
982 	data = (char*)data + toread;
983 	size -= toread;
984 	*bytes_read += toread;
985     }
986     return 0;
987 }
988 
989 static int
pci_device_x86_write_conf1(struct pci_device * dev,const void * data,pciaddr_t offset,pciaddr_t size,pciaddr_t * bytes_written)990 pci_device_x86_write_conf1(struct pci_device *dev, const void *data,
991     pciaddr_t offset, pciaddr_t size, pciaddr_t *bytes_written)
992 {
993     int err;
994 
995     *bytes_written = 0;
996     while (size > 0) {
997 	int towrite = 4;
998 	if (towrite > size)
999 	    towrite = size;
1000 	if (towrite > 4 - (offset & 0x3))
1001 	    towrite = 4 - (offset & 0x3);
1002 
1003 	err = pci_system_x86_conf1_write(dev->bus, dev->dev, dev->func, offset, data, towrite);
1004 	if (err)
1005 	    return err;
1006 
1007 	offset += towrite;
1008 	data = (const char*)data + towrite;
1009 	size -= towrite;
1010 	*bytes_written += towrite;
1011     }
1012     return 0;
1013 }
1014 
1015 static int
pci_device_x86_write_conf2(struct pci_device * dev,const void * data,pciaddr_t offset,pciaddr_t size,pciaddr_t * bytes_written)1016 pci_device_x86_write_conf2(struct pci_device *dev, const void *data,
1017     pciaddr_t offset, pciaddr_t size, pciaddr_t *bytes_written)
1018 {
1019     int err;
1020 
1021     *bytes_written = 0;
1022     while (size > 0) {
1023 	int towrite = 4;
1024 	if (towrite > size)
1025 	    towrite = size;
1026 	if (towrite > 4 - (offset & 0x3))
1027 	    towrite = 4 - (offset & 0x3);
1028 
1029 	err = pci_system_x86_conf2_write(dev->bus, dev->dev, dev->func, offset, data, towrite);
1030 	if (err)
1031 	    return err;
1032 
1033 	offset += towrite;
1034 	data = (const char*)data + towrite;
1035 	size -= towrite;
1036 	*bytes_written += towrite;
1037     }
1038     return 0;
1039 }
1040 
1041 void
pci_system_x86_destroy(void)1042 pci_system_x86_destroy(void)
1043 {
1044     x86_disable_io();
1045 }
1046 
1047 struct pci_io_handle *
pci_device_x86_open_legacy_io(struct pci_io_handle * ret,struct pci_device * dev,pciaddr_t base,pciaddr_t size)1048 pci_device_x86_open_legacy_io(struct pci_io_handle *ret,
1049     struct pci_device *dev, pciaddr_t base, pciaddr_t size)
1050 {
1051     x86_enable_io();
1052 
1053     ret->base = base;
1054     ret->size = size;
1055     ret->is_legacy = 1;
1056 
1057     return ret;
1058 }
1059 
1060 void
pci_device_x86_close_io(struct pci_device * dev,struct pci_io_handle * handle)1061 pci_device_x86_close_io(struct pci_device *dev, struct pci_io_handle *handle)
1062 {
1063     /* Like in the Linux case, do not disable I/O, as it may be opened several
1064      * times, and closed fewer times. */
1065     /* x86_disable_io(); */
1066 }
1067 
1068 uint32_t
pci_device_x86_read32(struct pci_io_handle * handle,uint32_t reg)1069 pci_device_x86_read32(struct pci_io_handle *handle, uint32_t reg)
1070 {
1071     return inl(reg + handle->base);
1072 }
1073 
1074 uint16_t
pci_device_x86_read16(struct pci_io_handle * handle,uint32_t reg)1075 pci_device_x86_read16(struct pci_io_handle *handle, uint32_t reg)
1076 {
1077     return inw(reg + handle->base);
1078 }
1079 
1080 uint8_t
pci_device_x86_read8(struct pci_io_handle * handle,uint32_t reg)1081 pci_device_x86_read8(struct pci_io_handle *handle, uint32_t reg)
1082 {
1083     return inb(reg + handle->base);
1084 }
1085 
1086 void
pci_device_x86_write32(struct pci_io_handle * handle,uint32_t reg,uint32_t data)1087 pci_device_x86_write32(struct pci_io_handle *handle, uint32_t reg,
1088 		       uint32_t data)
1089 {
1090     outl(data, reg + handle->base);
1091 }
1092 
1093 void
pci_device_x86_write16(struct pci_io_handle * handle,uint32_t reg,uint16_t data)1094 pci_device_x86_write16(struct pci_io_handle *handle, uint32_t reg,
1095 		       uint16_t data)
1096 {
1097     outw(data, reg + handle->base);
1098 }
1099 
1100 void
pci_device_x86_write8(struct pci_io_handle * handle,uint32_t reg,uint8_t data)1101 pci_device_x86_write8(struct pci_io_handle *handle, uint32_t reg,
1102 		      uint8_t data)
1103 {
1104     outb(data, reg + handle->base);
1105 }
1106 
1107 static int
pci_device_x86_map_legacy(struct pci_device * dev,pciaddr_t base,pciaddr_t size,unsigned map_flags,void ** addr)1108 pci_device_x86_map_legacy(struct pci_device *dev, pciaddr_t base,
1109     pciaddr_t size, unsigned map_flags, void **addr)
1110 {
1111     struct pci_device_mapping map;
1112     int err;
1113 
1114     map.base = base;
1115     map.size = size;
1116     map.flags = map_flags;
1117     err = pci_device_x86_map_range(dev, &map);
1118     *addr = map.memory;
1119 
1120     return err;
1121 }
1122 
1123 static int
pci_device_x86_unmap_legacy(struct pci_device * dev,void * addr,pciaddr_t size)1124 pci_device_x86_unmap_legacy(struct pci_device *dev, void *addr,
1125     pciaddr_t size)
1126 {
1127     struct pci_device_mapping map;
1128 
1129     map.size = size;
1130     map.flags = 0;
1131     map.memory = addr;
1132 
1133     return pci_device_x86_unmap_range(dev, &map);
1134 }
1135 
1136 static const struct pci_system_methods x86_pci_method_conf1 = {
1137     .destroy = pci_system_x86_destroy,
1138     .read_rom = pci_device_x86_read_rom,
1139     .probe = pci_device_x86_probe,
1140     .map_range = pci_device_x86_map_range,
1141     .unmap_range = pci_device_x86_unmap_range,
1142     .read = pci_device_x86_read_conf1,
1143     .write = pci_device_x86_write_conf1,
1144     .fill_capabilities = pci_fill_capabilities_generic,
1145     .open_legacy_io = pci_device_x86_open_legacy_io,
1146     .close_io = pci_device_x86_close_io,
1147     .read32 = pci_device_x86_read32,
1148     .read16 = pci_device_x86_read16,
1149     .read8 = pci_device_x86_read8,
1150     .write32 = pci_device_x86_write32,
1151     .write16 = pci_device_x86_write16,
1152     .write8 = pci_device_x86_write8,
1153     .map_legacy = pci_device_x86_map_legacy,
1154     .unmap_legacy = pci_device_x86_unmap_legacy,
1155 };
1156 
1157 static const struct pci_system_methods x86_pci_method_conf2 = {
1158     .destroy = pci_system_x86_destroy,
1159     .read_rom = pci_device_x86_read_rom,
1160     .probe = pci_device_x86_probe,
1161     .map_range = pci_device_x86_map_range,
1162     .unmap_range = pci_device_x86_unmap_range,
1163     .read = pci_device_x86_read_conf2,
1164     .write = pci_device_x86_write_conf2,
1165     .fill_capabilities = pci_fill_capabilities_generic,
1166     .open_legacy_io = pci_device_x86_open_legacy_io,
1167     .close_io = pci_device_x86_close_io,
1168     .read32 = pci_device_x86_read32,
1169     .read16 = pci_device_x86_read16,
1170     .read8 = pci_device_x86_read8,
1171     .write32 = pci_device_x86_write32,
1172     .write16 = pci_device_x86_write16,
1173     .write8 = pci_device_x86_write8,
1174     .map_legacy = pci_device_x86_map_legacy,
1175     .unmap_legacy = pci_device_x86_unmap_legacy,
1176 };
1177 
pci_probe(void)1178 static int pci_probe(void)
1179 {
1180     pci_sys->methods = &x86_pci_method_conf1;
1181     if (pci_system_x86_conf1_probe() == 0) {
1182 	if (pci_system_x86_check() == 0)
1183 	    return 1;
1184     }
1185 
1186     pci_sys->methods = &x86_pci_method_conf2;
1187     if (pci_system_x86_conf2_probe() == 0) {
1188 	if (pci_system_x86_check() == 0)
1189 	    return 2;
1190     }
1191 
1192     pci_sys->methods = NULL;
1193     return 0;
1194 }
1195 
1196 _pci_hidden int
pci_system_x86_create(void)1197 pci_system_x86_create(void)
1198 {
1199     error_t err;
1200     int confx;
1201 
1202     err = x86_enable_io ();
1203     if (err)
1204         return err;
1205 
1206     pci_sys = calloc (1, sizeof (struct pci_system));
1207     if (pci_sys == NULL)
1208     {
1209         x86_disable_io ();
1210         return ENOMEM;
1211     }
1212 
1213     confx = pci_probe ();
1214     if (!confx)
1215     {
1216         x86_disable_io ();
1217         free (pci_sys);
1218         pci_sys = NULL;
1219         return ENODEV;
1220     }
1221     else if (confx == 1)
1222         pci_sys->methods = &x86_pci_method_conf1;
1223     else
1224         pci_sys->methods = &x86_pci_method_conf2;
1225 
1226     /* Recursive scan */
1227     pci_sys->num_devices = 0;
1228     err = pci_system_x86_scan_bus (0);
1229     if (err)
1230     {
1231         x86_disable_io ();
1232         if (pci_sys->num_devices)
1233         {
1234             free (pci_sys->devices);
1235         }
1236         free (pci_sys);
1237         pci_sys = NULL;
1238         return err;
1239     }
1240 
1241     sort_devices ();
1242     return 0;
1243 }
1244