outputf("Current USB state is: %04x %04x", pci_read16(0, 31, 2, 0xC0), pci_read16(0, 31, 4, 0xC0));
outputf("Current SMI state is: %08x", inl(0x830));
-
smi_disable();
/* Try really hard to shut up USB_LEGKEY. */
pci_write16(0, 31, 2, 0xC0, 0);
pci_write16(0, 31, 4, 0xC0, pci_read16(0, 31, 4, 0xC0));
pci_write16(0, 31, 4, 0xC0, 0);
+
+ pci_bus_enum();
/* Open the SMRAM aperture and load our ELF. */
old_smramc = smram_save_state();
uint16_t pci_read16(int bus, int slot, int fn, int addr);
uint8_t pci_read8(int bus, int slot, int fn, int addr);
+/* Hardware-agnostic functions implemented by pci.c */
+typedef enum {
+ PCI_BAR_NONE = 0,
+ PCI_BAR_MEMORY32,
+ PCI_BAR_MEMORY64,
+ PCI_BAR_IO
+} pci_bar_type_t;
+
+typedef struct pci_bar {
+ pci_bar_type_t type;
+ unsigned char prefetchable;
+ unsigned long addr;
+} pci_bar_t;
+
+typedef struct pci_dev {
+ unsigned short vid, did;
+ int bus, dev, fn;
+ pci_bar_t bars[6];
+} pci_dev_t;
+
+typedef int (*pci_probe_fn_t)(pci_dev_t *);
+
+void pci_bus_enum();
+int pci_probe(pci_probe_fn_t probe);
+
#endif
--- /dev/null
+#include <pci.h>
+#include <output.h>
+
+int pci_probe(pci_probe_fn_t probe)
+{
+ int devsfound = 0;
+ pci_dev_t pdev;
+ unsigned int bus;
+ unsigned int dev;
+ unsigned int fn;
+
+ for (bus = 0; bus < 0x100; bus++)
+ for (dev = 0; dev < 0x20; dev++)
+ if (pci_read32(bus, dev, 0, 0) != 0xFFFFFFFF)
+ for (fn = 0; fn < 8; fn++)
+ {
+ int bar;
+
+ if (pci_read32(bus, dev, fn, 0) == 0xFFFFFFFF)
+ continue;
+
+ if ((fn != 0) && !(pci_read8(bus, dev, 0, 0x0E) & 0x80))
+ continue;
+
+ pdev.bus = bus;
+ pdev.dev = dev;
+ pdev.fn = fn;
+ pdev.vid = pci_read16(bus, dev, fn, 0);
+ pdev.did = pci_read16(bus, dev, fn, 2);
+
+ for (bar = 0; bar < 6; bar++)
+ {
+ unsigned long bardat = pci_read32(bus, dev, fn, 0x10 + bar*4);
+ if (bardat == 0)
+ {
+ pdev.bars[bar].type = PCI_BAR_NONE;
+ continue;
+ }
+ if (bardat & 1)
+ {
+ pdev.bars[bar].type = PCI_BAR_IO;
+ pdev.bars[bar].addr = bardat & ~0x3;
+ } else {
+ pdev.bars[bar].prefetchable = (bardat >> 3) & 1;
+ switch ((bardat >> 1) & 0x3)
+ {
+ case 0:
+ pdev.bars[bar].type = PCI_BAR_MEMORY32;
+ pdev.bars[bar].addr = bardat & ~0xF;
+ break;
+ case 2:
+ pdev.bars[bar].type = PCI_BAR_MEMORY64;
+ bar++;
+ pdev.bars[bar].type = PCI_BAR_NONE;
+ break;
+ default:
+ pdev.bars[bar].type = PCI_BAR_NONE;
+ continue;
+ }
+ }
+ }
+
+ devsfound += probe(&pdev);
+ }
+
+ return devsfound;
+}
+
+static int _enumfn(pci_dev_t *pdev)
+{
+ int bar;
+
+ outputf("Found device: %02x:%02x.%1x: %04X:%04X",
+ pdev->bus, pdev->dev, pdev->fn,
+ pdev->vid, pdev->did);
+ for (bar = 0; bar < 6; bar++)
+ {
+ switch (pdev->bars[bar].type)
+ {
+ case PCI_BAR_IO:
+ outputf(" BAR %d: I/O, Addr %04x", bar, pdev->bars[bar].addr);
+ break;
+ case PCI_BAR_MEMORY32:
+ outputf(" BAR %d: Mem32, Addr %04x", bar, pdev->bars[bar].addr);
+ break;
+ case PCI_BAR_MEMORY64:
+ outputf(" BAR %d: Mem64, Addr %04x", bar, pdev->bars[bar].addr);
+ break;
+ default:
+ break;
+ }
+ }
+ return 0;
+}
+
+void pci_bus_enum()
+{
+ pci_probe(_enumfn);
+}
+