]> Joshua Wise's Git repositories - netwatch.git/blob - pci/pci.c
e5ab8169dd8231423d1f47ce85eb08b957fbe079
[netwatch.git] / pci / pci.c
1 #include <pci.h>
2 #include <output.h>
3
4 int pci_probe(pci_probe_fn_t probe)
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                         if (pci_read32(bus, dev, 0, 0) != 0xFFFFFFFF)
15                                 for (fn = 0; fn < 8; fn++)
16                                 {
17                                         int bar;
18                                         
19                                         if (pci_read32(bus, dev, fn, 0) == 0xFFFFFFFF)
20                                                 continue;
21                                         
22                                         if ((fn != 0) && !(pci_read8(bus, dev, 0, 0x0E) & 0x80))
23                                                 continue;
24                                         
25                                         pdev.bus = bus;
26                                         pdev.dev = dev;
27                                         pdev.fn = fn;
28                                         pdev.vid = pci_read16(bus, dev, fn, 0);
29                                         pdev.did = pci_read16(bus, dev, fn, 2);
30                                         
31                                         for (bar = 0; bar < 6; bar++)
32                                         {
33                                                 unsigned long bardat = pci_read32(bus, dev, fn, 0x10 + bar*4);
34                                                 if (bardat == 0)
35                                                 {
36                                                         pdev.bars[bar].type = PCI_BAR_NONE;
37                                                         continue;
38                                                 }
39                                                 if (bardat & 1)
40                                                 {
41                                                         pdev.bars[bar].type = PCI_BAR_IO;
42                                                         pdev.bars[bar].addr = bardat & ~0x3;
43                                                 } else {
44                                                         pdev.bars[bar].prefetchable = (bardat >> 3) & 1;
45                                                         switch ((bardat >> 1) & 0x3)
46                                                         {
47                                                         case 0:
48                                                                 pdev.bars[bar].type = PCI_BAR_MEMORY32;
49                                                                 pdev.bars[bar].addr = bardat & ~0xF;
50                                                                 break;
51                                                         case 2:
52                                                                 pdev.bars[bar].type = PCI_BAR_MEMORY64;
53                                                                 bar++;
54                                                                 pdev.bars[bar].type = PCI_BAR_NONE;
55                                                                 break;
56                                                         default:
57                                                                 pdev.bars[bar].type = PCI_BAR_NONE;
58                                                                 continue;
59                                                         }
60                                                 }
61                                         }
62                                         
63                                         devsfound += probe(&pdev);
64                                 }
65         
66         return devsfound;
67 }
68
69 static int _enumfn(pci_dev_t *pdev)
70 {
71         int bar;
72         
73         outputf("Found device: %02x:%02x.%1x: %04X:%04X",
74                 pdev->bus, pdev->dev, pdev->fn,
75                 pdev->vid, pdev->did);
76         for (bar = 0; bar < 6; bar++)
77         {
78                 switch (pdev->bars[bar].type)
79                 {
80                 case PCI_BAR_IO:
81                         outputf("  BAR %d: I/O, Addr %04x", bar, pdev->bars[bar].addr);
82                         break;
83                 case PCI_BAR_MEMORY32:
84                         outputf("  BAR %d: Mem32, Addr %04x", bar, pdev->bars[bar].addr);
85                         break;
86                 case PCI_BAR_MEMORY64:
87                         outputf("  BAR %d: Mem64, Addr %04x", bar, pdev->bars[bar].addr);
88                         break;
89                 default:
90                         break;
91                 }
92         }
93         return 0;
94 }
95
96 void pci_bus_enum()
97 {
98         pci_probe(_enumfn);
99 }
100
This page took 0.020644 seconds and 2 git commands to generate.