e704444cf6ee9205bd0cf8bbdf1aa92493c5897c
[seabios.git] / src / pci.c
1 // PCI config space access functions.
2 //
3 // Copyright (C) 2008  Kevin O'Connor <kevin@koconnor.net>
4 // Copyright (C) 2002  MandrakeSoft S.A.
5 //
6 // This file may be distributed under the terms of the GNU GPLv3 license.
7
8 #include "pci.h" // PCIDevice
9 #include "ioport.h" // outl
10 #include "util.h" // dprintf
11
12 #define MAX_BUS 1
13
14 void pci_config_writel(PCIDevice d, u32 addr, u32 val)
15 {
16     outl(0x80000000 | (d.bus << 16) | (d.devfn << 8) | (addr & 0xfc)
17          , PORT_PCI_CMD);
18     outl(val, PORT_PCI_DATA);
19 }
20
21 void pci_config_writew(PCIDevice d, u32 addr, u16 val)
22 {
23     outl(0x80000000 | (d.bus << 16) | (d.devfn << 8) | (addr & 0xfc)
24          , PORT_PCI_CMD);
25     outw(val, PORT_PCI_DATA + (addr & 2));
26 }
27
28 void pci_config_writeb(PCIDevice d, u32 addr, u8 val)
29 {
30     outl(0x80000000 | (d.bus << 16) | (d.devfn << 8) | (addr & 0xfc)
31          , PORT_PCI_CMD);
32     outb(val, PORT_PCI_DATA + (addr & 3));
33 }
34
35 u32 pci_config_readl(PCIDevice d, u32 addr)
36 {
37     outl(0x80000000 | (d.bus << 16) | (d.devfn << 8) | (addr & 0xfc)
38          , PORT_PCI_CMD);
39     return inl(PORT_PCI_DATA);
40 }
41
42 u16 pci_config_readw(PCIDevice d, u32 addr)
43 {
44     outl(0x80000000 | (d.bus << 16) | (d.devfn << 8) | (addr & 0xfc)
45          , PORT_PCI_CMD);
46     return inw(PORT_PCI_DATA + (addr & 2));
47 }
48
49 u8 pci_config_readb(PCIDevice d, u32 addr)
50 {
51     outl(0x80000000 | (d.bus << 16) | (d.devfn << 8) | (addr & 0xfc)
52          , PORT_PCI_CMD);
53     return inb(PORT_PCI_DATA + (addr & 3));
54 }
55
56 int
57 pci_find_device(u16 vendid, u16 devid, int index, PCIDevice *dev)
58 {
59     int devfn, bus;
60     u32 id = (devid << 16) | vendid;
61     for (bus=0; bus < MAX_BUS; bus++) {
62         for (devfn=0; devfn<0x100; devfn++) {
63             PCIDevice d = pci_bd(bus, devfn);
64             u32 v = pci_config_readl(d, 0x00);
65             if (v != id)
66                 continue;
67             if (index) {
68                 index--;
69                 continue;
70             }
71             // Found it.
72             *dev = d;
73             return 0;
74         }
75     }
76     return -1;
77 }
78
79 int
80 pci_find_class(u32 classid, int index, PCIDevice *dev)
81 {
82     int devfn, bus;
83     u32 id = classid << 8;
84     for (bus=0; bus < MAX_BUS; bus++) {
85         for (devfn=0; devfn<0x100; devfn++) {
86             PCIDevice d = pci_bd(bus, devfn);
87             u32 v = pci_config_readl(d, 0x08);
88             if (v != id)
89                 continue;
90             if (index) {
91                 index--;
92                 continue;
93             }
94             // Found it.
95             *dev = d;
96             return 0;
97         }
98     }
99     return -1;
100 }