]> Joshua Wise's Git repositories - netwatch.git/blob - pci/pci.c
Merge nyus.joshuawise.com:/storage/git/netwatch
[netwatch.git] / pci / pci.c
1 #include <pci.h>
2 #include <output.h>
3
4 int 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
72 static 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
99 void pci_bus_enum()
100 {
101         pci_probe(_enumfn, 0x0);
102 }
103
104 static 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
118 int pci_probe_driver(pci_driver_t driver)
119 {
120         return pci_probe(_probefn, &driver);
121 }
This page took 0.027128 seconds and 4 git commands to generate.