]> Joshua Wise's Git repositories - netwatch.git/blame_incremental - pci/pci.c
Avoid suffering from wrong CS_SEGSEL syndrome.
[netwatch.git] / pci / pci.c
... / ...
CommitLineData
1#include <pci.h>
2#include <output.h>
3
4int pci_probe(pci_probe_fn_t probe, void *data)
5{
6 int devsfound = 0;
7 pci_dev_t pdev;
8 unsigned int bus;
9 unsigned int dev;
10 unsigned int fn;
11
12 for (bus = 0; bus < 0x100; bus++)
13 for (dev = 0; dev < 0x20; dev++)
14 {
15 if (pci_read32(bus, dev, 0, 0) == 0xFFFFFFFF)
16 continue;
17 for (fn = 0; fn < 8; fn++)
18 {
19 int bar;
20
21 if (pci_read32(bus, dev, fn, 0) == 0xFFFFFFFF)
22 continue;
23
24 if ((fn != 0) && !(pci_read8(bus, dev, 0, 0x0E) & 0x80))
25 continue;
26
27 pdev.bus = bus;
28 pdev.dev = dev;
29 pdev.fn = fn;
30 pdev.vid = pci_read16(bus, dev, fn, 0);
31 pdev.did = pci_read16(bus, dev, fn, 2);
32
33 for (bar = 0; bar < 6; bar++)
34 {
35 unsigned long bardat = pci_read32(bus, dev, fn, 0x10 + bar*4);
36 if (bardat == 0)
37 {
38 pdev.bars[bar].type = PCI_BAR_NONE;
39 continue;
40 }
41 if (bardat & 1)
42 {
43 pdev.bars[bar].type = PCI_BAR_IO;
44 pdev.bars[bar].addr = bardat & ~0x3;
45 } else {
46 pdev.bars[bar].prefetchable = (bardat >> 3) & 1;
47 switch ((bardat >> 1) & 0x3)
48 {
49 case 0:
50 pdev.bars[bar].type = PCI_BAR_MEMORY32;
51 pdev.bars[bar].addr = bardat & ~0xF;
52 break;
53 case 2:
54 pdev.bars[bar].type = PCI_BAR_MEMORY64;
55 bar++;
56 pdev.bars[bar].type = PCI_BAR_NONE;
57 break;
58 default:
59 pdev.bars[bar].type = PCI_BAR_NONE;
60 continue;
61 }
62 }
63 }
64
65 devsfound += probe(&pdev, data);
66 }
67 }
68
69 return devsfound;
70}
71
72static int _enumfn(pci_dev_t *pdev, void *data)
73{
74 int bar;
75
76 outputf("Found device: %02x:%02x.%1x: %04X:%04X",
77 pdev->bus, pdev->dev, pdev->fn,
78 pdev->vid, pdev->did);
79 for (bar = 0; bar < 6; bar++)
80 {
81 switch (pdev->bars[bar].type)
82 {
83 case PCI_BAR_IO:
84 outputf(" BAR %d: I/O, Addr %04x", bar, pdev->bars[bar].addr);
85 break;
86 case PCI_BAR_MEMORY32:
87 outputf(" BAR %d: Mem32, Addr %04x", bar, pdev->bars[bar].addr);
88 break;
89 case PCI_BAR_MEMORY64:
90 outputf(" BAR %d: Mem64, Addr %04x", bar, pdev->bars[bar].addr);
91 break;
92 default:
93 break;
94 }
95 }
96 return 0;
97}
98
99void pci_bus_enum()
100{
101 pci_probe(_enumfn, 0x0);
102}
103
104static int _probefn(pci_dev_t *dev, void *d)
105{
106 pci_driver_t *driver = d;
107 int i;
108
109 for (i = 0; i < driver->id_count; i++)
110 if ((dev->vid == driver->ids[i].vid) && (dev->did == driver->ids[i].did))
111 {
112 outputf("Probing PCI device: %s", driver->ids[i].name ? driver->ids[i].name : driver->name);
113 return driver->probe(dev, d);
114 }
115 return 0;
116}
117
118int pci_probe_driver(pci_driver_t *driver)
119{
120 return pci_probe(_probefn, driver);
121}
This page took 0.019364 seconds and 4 git commands to generate.