2 * General-purpose PCI probe routines
3 * NetWatch system management mode administration console
5 * Copyright (c) 2008 Jacob Potter and Joshua Wise. All rights reserved.
6 * This program is free software; you can redistribute and/or modify it under
7 * the terms found in the file LICENSE in the root of this source tree.
14 int pci_probe(pci_probe_fn_t probe, void *data)
22 for (bus = 0; bus < 0x100; bus++)
23 for (dev = 0; dev < 0x20; dev++)
25 if (pci_read32(bus, dev, 0, 0) == 0xFFFFFFFF)
27 for (fn = 0; fn < 8; fn++)
31 if (pci_read32(bus, dev, fn, 0) == 0xFFFFFFFF)
34 if ((fn != 0) && !(pci_read8(bus, dev, 0, 0x0E) & 0x80))
40 pdev.vid = pci_read16(bus, dev, fn, 0);
41 pdev.did = pci_read16(bus, dev, fn, 2);
43 for (bar = 0; bar < 6; bar++)
45 unsigned long bardat = pci_read32(bus, dev, fn, 0x10 + bar*4);
48 pdev.bars[bar].type = PCI_BAR_NONE;
53 pdev.bars[bar].type = PCI_BAR_IO;
54 pdev.bars[bar].addr = bardat & ~0x3;
56 pdev.bars[bar].prefetchable = (bardat >> 3) & 1;
57 switch ((bardat >> 1) & 0x3)
60 pdev.bars[bar].type = PCI_BAR_MEMORY32;
61 pdev.bars[bar].addr = bardat & ~0xF;
64 pdev.bars[bar].type = PCI_BAR_MEMORY64;
66 pdev.bars[bar].type = PCI_BAR_NONE;
69 pdev.bars[bar].type = PCI_BAR_NONE;
75 devsfound += probe(&pdev, data);
82 static int _enumfn(pci_dev_t *pdev, void *data)
86 outputf("Found device: %02x:%02x.%1x: %04X:%04X",
87 pdev->bus, pdev->dev, pdev->fn,
88 pdev->vid, pdev->did);
89 for (bar = 0; bar < 6; bar++)
91 switch (pdev->bars[bar].type)
94 outputf(" BAR %d: I/O, Addr %04x", bar, pdev->bars[bar].addr);
96 case PCI_BAR_MEMORY32:
97 outputf(" BAR %d: Mem32, Addr %04x", bar, pdev->bars[bar].addr);
99 case PCI_BAR_MEMORY64:
100 outputf(" BAR %d: Mem64, Addr %04x", bar, pdev->bars[bar].addr);
111 pci_probe(_enumfn, 0x0);
114 static int _probefn(pci_dev_t *dev, void *d)
116 pci_driver_t *driver = d;
119 for (i = 0; i < driver->id_count; i++)
120 if ((dev->vid == driver->ids[i].vid) && (dev->did == driver->ids[i].did))
122 outputf("Probing PCI device: %s", driver->ids[i].name ? driver->ids[i].name : driver->name);
123 return driver->probe(dev, d);
128 int pci_probe_driver(pci_driver_t *driver)
130 return pci_probe(_probefn, driver);