]> Joshua Wise's Git repositories - netwatch.git/blame - pci/pci.c
Add PCI bus probe and enumeration routines.
[netwatch.git] / pci / pci.c
CommitLineData
83a02556
JW
1#include <pci.h>
2#include <output.h>
3
4int 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
69static 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
96void pci_bus_enum()
97{
98 pci_probe(_enumfn);
99}
100
This page took 0.031797 seconds and 4 git commands to generate.