c688dace313f12fb124f8b0c3b3e7e5cdc2328b9
[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
11 void pci_config_writel(PCIDevice d, u32 addr, u32 val)
12 {
13     outl(0x80000000 | (d.bus << 16) | (d.devfn << 8) | (addr & 0xfc)
14          , PORT_PCI_CMD);
15     outl(val, PORT_PCI_DATA);
16 }
17
18 void pci_config_writew(PCIDevice d, u32 addr, u16 val)
19 {
20     outl(0x80000000 | (d.bus << 16) | (d.devfn << 8) | (addr & 0xfc)
21          , PORT_PCI_CMD);
22     outw(val, PORT_PCI_DATA + (addr & 2));
23 }
24
25 void pci_config_writeb(PCIDevice d, u32 addr, u8 val)
26 {
27     outl(0x80000000 | (d.bus << 16) | (d.devfn << 8) | (addr & 0xfc)
28          , PORT_PCI_CMD);
29     outb(val, PORT_PCI_DATA + (addr & 3));
30 }
31
32 u32 pci_config_readl(PCIDevice d, u32 addr)
33 {
34     outl(0x80000000 | (d.bus << 16) | (d.devfn << 8) | (addr & 0xfc)
35          , PORT_PCI_CMD);
36     return inl(PORT_PCI_DATA);
37 }
38
39 u16 pci_config_readw(PCIDevice d, u32 addr)
40 {
41     outl(0x80000000 | (d.bus << 16) | (d.devfn << 8) | (addr & 0xfc)
42          , PORT_PCI_CMD);
43     return inw(PORT_PCI_DATA + (addr & 2));
44 }
45
46 u8 pci_config_readb(PCIDevice d, u32 addr)
47 {
48     outl(0x80000000 | (d.bus << 16) | (d.devfn << 8) | (addr & 0xfc)
49          , PORT_PCI_CMD);
50     return inb(PORT_PCI_DATA + (addr & 3));
51 }
52
53 int
54 pci_find_device(u16 vendid, u16 devid, int index, PCIDevice *dev)
55 {
56     int devfn;
57     u32 id = (devid << 16) | vendid;
58     for (devfn=0; devfn<0x100; devfn++) {
59         PCIDevice d = pci_bd(0, devfn);
60         u32 v = pci_config_readl(d, 0x00);
61         if (v != id)
62             continue;
63         if (index) {
64             index--;
65             continue;
66         }
67         // Found it.
68         *dev = d;
69         return 0;
70     }
71     return -1;
72 }
73
74 int
75 pci_find_class(u32 classid, int index, PCIDevice *dev)
76 {
77     int devfn;
78     u32 id = classid << 8;
79     for (devfn=0; devfn<0x100; devfn++) {
80         PCIDevice d = pci_bd(0, devfn);
81         u32 v = pci_config_readl(d, 0x08);
82         if (v != id)
83             continue;
84         if (index) {
85             index--;
86             continue;
87         }
88         // Found it.
89         *dev = d;
90         return 0;
91     }
92     return -1;
93 }