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
45int
46x86_enable_io(void)
47{
48    if (!ioperm(0, 0xffff, 1))
49        return 0;
50    return errno;
51}
52
53int
54x86_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
65static int
66x86_enable_io(void)
67{
68    if (!iopl(3))
69        return 0;
70    return errno;
71}
72
73static int
74x86_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 */
86typedef BYTE bool;
87typedef struct tagPhysStruct {
88    DWORD64 dwPhysMemSizeInBytes;
89    DWORD64 pvPhysAddress;
90    DWORD64 PhysicalMemoryHandle;
91    DWORD64 pvPhysMemLin;
92    DWORD64 pvPhysSection;
93} tagPhysStruct;
94
95typedef bool  (_stdcall* INITIALIZEWINIO)(void);
96typedef void  (_stdcall* SHUTDOWNWINIO)(void);
97typedef bool  (_stdcall* GETPORTVAL)(WORD,PDWORD,BYTE);
98typedef bool  (_stdcall* SETPORTVAL)(WORD,DWORD,BYTE);
99typedef PBYTE (_stdcall* MAPPHYSTOLIN)(tagPhysStruct*);
100typedef bool  (_stdcall* UNMAPPHYSMEM)(tagPhysStruct*);
101
102SHUTDOWNWINIO ShutdownWinIo;
103GETPORTVAL GetPortVal;
104SETPORTVAL SetPortVal;
105INITIALIZEWINIO InitializeWinIo;
106MAPPHYSTOLIN MapPhysToLin;
107UNMAPPHYSMEM UnmapPhysicalMemory;
108
109static int
110x86_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
153static int
154x86_disable_io(void)
155{
156    ShutdownWinIo();
157    return 1;
158}
159
160static inline uint8_t
161inb(uint16_t port)
162{
163    DWORD pv;
164
165    if (GetPortVal(port, &pv, 1))
166      return (uint8_t)pv;
167    return 0;
168}
169
170static inline uint16_t
171inw(uint16_t port)
172{
173    DWORD pv;
174
175    if (GetPortVal(port, &pv, 2))
176      return (uint16_t)pv;
177    return 0;
178}
179
180static inline uint32_t
181inl(uint16_t port)
182{
183    DWORD pv;
184
185    if (GetPortVal(port, &pv, 4))
186        return (uint32_t)pv;
187    return 0;
188}
189
190static inline void
191outb(uint8_t value, uint16_t port)
192{
193    SetPortVal(port, value, 1);
194}
195
196static inline void
197outw(uint16_t value, uint16_t port)
198{
199    SetPortVal(port, value, 2);
200}
201
202static inline void
203outl(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
214static 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
230static void
231sort_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
243int
244pci_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
316static int
317pci_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
332static int
333pci_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
367static int
368pci_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
402static int
403pci_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
414static int
415pci_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
451static int
452pci_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. */
489static error_t
490pci_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
518static int
519pci_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 */
539static error_t
540pci_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 */
555static int
556pci_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 */
572static uint32_t
573get_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 */
582static unsigned
583get_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 */
604static error_t
605pci_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 */
692static error_t
693pci_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 */
767static error_t
768pci_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' */
797static error_t
798pci_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
883static int
884pci_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
899static int
900pci_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
916static int
917pci_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
928static int
929pci_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
941static int
942pci_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
965static int
966pci_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
989static int
990pci_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
1015static int
1016pci_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
1041void
1042pci_system_x86_destroy(void)
1043{
1044    x86_disable_io();
1045}
1046
1047struct pci_io_handle *
1048pci_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
1060void
1061pci_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
1068uint32_t
1069pci_device_x86_read32(struct pci_io_handle *handle, uint32_t reg)
1070{
1071    return inl(reg + handle->base);
1072}
1073
1074uint16_t
1075pci_device_x86_read16(struct pci_io_handle *handle, uint32_t reg)
1076{
1077    return inw(reg + handle->base);
1078}
1079
1080uint8_t
1081pci_device_x86_read8(struct pci_io_handle *handle, uint32_t reg)
1082{
1083    return inb(reg + handle->base);
1084}
1085
1086void
1087pci_device_x86_write32(struct pci_io_handle *handle, uint32_t reg,
1088		       uint32_t data)
1089{
1090    outl(data, reg + handle->base);
1091}
1092
1093void
1094pci_device_x86_write16(struct pci_io_handle *handle, uint32_t reg,
1095		       uint16_t data)
1096{
1097    outw(data, reg + handle->base);
1098}
1099
1100void
1101pci_device_x86_write8(struct pci_io_handle *handle, uint32_t reg,
1102		      uint8_t data)
1103{
1104    outb(data, reg + handle->base);
1105}
1106
1107static int
1108pci_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
1123static int
1124pci_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
1136static 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
1157static 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
1178static 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
1197pci_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