+
+ for (bar = 0; bar < PCI_NUM_BARS; bar++)
+ {
+ if (dev->resources[bar].start != 0 ||
+ dev->resources[bar].end != 0)
+ {
+ printf ("PCI: %s ",
+ dev->resources[bar].type == PCI_BAR_TYPE_MEM
+ ? "Memory" : "IO");
+ printf ("range %d: %08x-%08x\n",
+ bar, dev->resources[bar].start, dev->resources[bar].end);
+ }
+ }
+}
+
+static void
+pci_setup_bases (struct pci_dev *dev)
+{
+ int bar;
+ unsigned bar_reg;
+ uint32_t base, size;
+ struct resource *res;
+
+ for (bar = 0; bar < PCI_NUM_BARS; bar++)
+ {
+ bar_reg = PCI_REGNUM_BASE_ADDRESS + bar;
+
+ res = &dev->resources[bar];
+ res->start = 0;
+ res->end = 0;
+
+ /* Get the base address out of the BAR */
+ base = pci_read_config(dev->bus_id,
+ dev->devfn >> 4,
+ dev->devfn & 0xf,
+ bar_reg);
+
+ /* Write 1's and get the size from the BAR */
+ pci_write_config(dev->bus_id,
+ dev->devfn >> 4,
+ dev->devfn & 0xf,
+ bar_reg,
+ ~0);
+ size = pci_read_config(dev->bus_id,
+ dev->devfn >> 4,
+ dev->devfn & 0xf,
+ bar_reg);
+
+ /* Put the base address back in the BAR */
+ pci_write_config(dev->bus_id,
+ dev->devfn >> 4,
+ dev->devfn & 0xf,
+ bar_reg,
+ base);
+
+ /* If the size is unreasonable, skip this BAR.
+ Is this redundant for Pintos? */
+ if (!size || size == 0xffffffff) {
+ continue;
+ }
+
+ /* Broken hardware that requests a base at the end?
+ Maybe redundant for Pintos? */
+ if (base == 0xffffffff) {
+ base = 0;
+ }
+
+ /* Make a new resource, tag it for I/O vs. memory */
+ res->type = base & PCI_BAR_TYPE_MASK;
+ if (res->type == PCI_BAR_TYPE_MEM)
+ {
+ res->start = base & PCI_BAR_MASK_MEM;
+ size = size & PCI_BAR_MASK_MEM;
+ }
+ else
+ {
+ res->start = base & PCI_BAR_MASK_IO;
+ size = size & PCI_BAR_MASK_IO;
+ }
+ res->end = res->start + size;
+ }