aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2011-07-02 14:32:11 -0400
committerKevin O'Connor <kevin@koconnor.net>2011-07-02 23:37:39 -0400
commit0f654a976b9ec8d0346249f8aacc5fbd7d40e946 (patch)
tree6ff83c7bbb219d9ab0cfe3f126130c9baf690b8b
parent0cd700562357525c2975c5786d34afc237487b2d (diff)
downloadseabios-0f654a976b9ec8d0346249f8aacc5fbd7d40e946.tar.gz
Convert remaining callers of foreachbdf to foreachbdf_in_bus.
Convert the last few callers of foreachbdf to foreachbdf_in_bus. This is in preparation for simplification of foreachbdf_in_bus. Also add in addition debugging messages to pci_probe.
-rw-r--r--src/pci.c106
-rw-r--r--src/pcibios.c55
2 files changed, 89 insertions, 72 deletions
diff --git a/src/pci.c b/src/pci.c
index bbb58cf..ebc6f91 100644
--- a/src/pci.c
+++ b/src/pci.c
@@ -104,63 +104,77 @@ pci_next(int bdf, int *pmax)
}
struct pci_device *PCIDevices;
-int MaxPCIBus;
+int MaxPCIBus VAR16VISIBLE;
+// Find all PCI devices and populate PCIDevices linked list.
void
pci_probe(void)
{
- int rootbuses = 0;
+ dprintf(3, "PCI probe\n");
+ if (CONFIG_PCI_ROOT1 && CONFIG_PCI_ROOT1 > MaxPCIBus)
+ MaxPCIBus = CONFIG_PCI_ROOT1;
+ if (CONFIG_PCI_ROOT2 && CONFIG_PCI_ROOT2 > MaxPCIBus)
+ MaxPCIBus = CONFIG_PCI_ROOT2;
+
struct pci_device *busdevs[256];
memset(busdevs, 0, sizeof(busdevs));
-
struct pci_device **pprev = &PCIDevices;
- u8 lastbus = 0;
- int bdf, max;
- foreachbdf(bdf, max) {
- // Create new pci_device struct and add to list.
- struct pci_device *dev = malloc_tmp(sizeof(*dev));
- if (!dev) {
- warn_noalloc();
- return;
- }
- memset(dev, 0, sizeof(*dev));
- *pprev = dev;
- pprev = &dev->next;
+ int bus = -1, lastbus = 0, rootbuses = 0, count=0;
+ while (bus < MaxPCIBus) {
+ bus++;
+ int bdf, max;
+ foreachbdf_in_bus(bdf, max, bus) {
+ // Create new pci_device struct and add to list.
+ struct pci_device *dev = malloc_tmp(sizeof(*dev));
+ if (!dev) {
+ warn_noalloc();
+ return;
+ }
+ memset(dev, 0, sizeof(*dev));
+ *pprev = dev;
+ pprev = &dev->next;
+ count++;
- // Find parent device.
- u8 bus = pci_bdf_to_bus(bdf), rootbus;
- struct pci_device *parent = busdevs[bus];
- if (!parent) {
- if (bus != lastbus)
- rootbuses++;
- lastbus = bus;
- rootbus = rootbuses;
- } else {
- rootbus = parent->rootbus;
- }
- if (bus > MaxPCIBus)
- MaxPCIBus = bus;
+ // Find parent device.
+ int rootbus;
+ struct pci_device *parent = busdevs[bus];
+ if (!parent) {
+ if (bus != lastbus)
+ rootbuses++;
+ lastbus = bus;
+ rootbus = rootbuses;
+ } else {
+ rootbus = parent->rootbus;
+ }
- // Populate pci_device info.
- dev->bdf = bdf;
- dev->parent = parent;
- dev->rootbus = rootbus;
- u32 vendev = pci_config_readl(bdf, PCI_VENDOR_ID);
- dev->vendor = vendev & 0xffff;
- dev->device = vendev >> 16;
- u32 classrev = pci_config_readl(bdf, PCI_CLASS_REVISION);
- dev->class = classrev >> 16;
- dev->prog_if = classrev >> 8;
- dev->revision = classrev & 0xff;
- dev->header_type = pci_config_readb(bdf, PCI_HEADER_TYPE);
- u8 v = dev->header_type & 0x7f;
- if (v == PCI_HEADER_TYPE_BRIDGE || v == PCI_HEADER_TYPE_CARDBUS) {
- u8 secbus = pci_config_readb(bdf, PCI_SECONDARY_BUS);
- dev->secondary_bus = secbus;
- if (secbus > bus && !busdevs[secbus])
- busdevs[secbus] = dev;
+ // Populate pci_device info.
+ dev->bdf = bdf;
+ dev->parent = parent;
+ dev->rootbus = rootbus;
+ u32 vendev = pci_config_readl(bdf, PCI_VENDOR_ID);
+ dev->vendor = vendev & 0xffff;
+ dev->device = vendev >> 16;
+ u32 classrev = pci_config_readl(bdf, PCI_CLASS_REVISION);
+ dev->class = classrev >> 16;
+ dev->prog_if = classrev >> 8;
+ dev->revision = classrev & 0xff;
+ dev->header_type = pci_config_readb(bdf, PCI_HEADER_TYPE);
+ u8 v = dev->header_type & 0x7f;
+ if (v == PCI_HEADER_TYPE_BRIDGE || v == PCI_HEADER_TYPE_CARDBUS) {
+ u8 secbus = pci_config_readb(bdf, PCI_SECONDARY_BUS);
+ dev->secondary_bus = secbus;
+ if (secbus > bus && !busdevs[secbus])
+ busdevs[secbus] = dev;
+ if (secbus > MaxPCIBus)
+ MaxPCIBus = secbus;
+ }
+ dprintf(4, "PCI device %02x:%02x.%x (vd=%04x:%04x c=%04x)\n"
+ , pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf)
+ , pci_bdf_to_fn(bdf)
+ , dev->vendor, dev->device, dev->class);
}
}
+ dprintf(1, "Found %d PCI devices (max PCI bus is %02x)\n", count, MaxPCIBus);
}
// Search for a device with the specified vendor and device ids.
diff --git a/src/pcibios.c b/src/pcibios.c
index 4fdfd5e..ca91c15 100644
--- a/src/pcibios.c
+++ b/src/pcibios.c
@@ -25,14 +25,9 @@ extern void pcibios32_entry(void);
static void
handle_1ab101(struct bregs *regs)
{
- // Find max bus.
- int bdf, max;
- foreachbdf(bdf, max) {
- }
-
regs->al = 0x01; // Flags - "Config Mechanism #1" supported.
regs->bx = 0x0210; // PCI version 2.10
- regs->cl = pci_bdf_to_bus(max - 1);
+ regs->cl = GET_GLOBAL(MaxPCIBus);
regs->edx = 0x20494350; // "PCI "
regs->edi = (u32)pcibios32_entry + BUILD_BIOS_ADDR;
set_code_success(regs);
@@ -44,16 +39,20 @@ handle_1ab102(struct bregs *regs)
{
u32 id = (regs->cx << 16) | regs->dx;
int count = regs->si;
- int bdf, max;
- foreachbdf(bdf, max) {
- u32 v = pci_config_readl(bdf, PCI_VENDOR_ID);
- if (v != id)
- continue;
- if (count--)
- continue;
- regs->bx = bdf;
- set_code_success(regs);
- return;
+ int bus = -1;
+ while (bus < GET_GLOBAL(MaxPCIBus)) {
+ bus++;
+ int bdf, max;
+ foreachbdf_in_bus(bdf, max, bus) {
+ u32 v = pci_config_readl(bdf, PCI_VENDOR_ID);
+ if (v != id)
+ continue;
+ if (count--)
+ continue;
+ regs->bx = bdf;
+ set_code_success(regs);
+ return;
+ }
}
set_code_invalid(regs, RET_DEVICE_NOT_FOUND);
}
@@ -64,16 +63,20 @@ handle_1ab103(struct bregs *regs)
{
int count = regs->si;
u32 classprog = regs->ecx;
- int bdf, max;
- foreachbdf(bdf, max) {
- u32 v = pci_config_readl(bdf, PCI_CLASS_REVISION);
- if ((v>>8) != classprog)
- continue;
- if (count--)
- continue;
- regs->bx = bdf;
- set_code_success(regs);
- return;
+ int bus = -1;
+ while (bus < GET_GLOBAL(MaxPCIBus)) {
+ bus++;
+ int bdf, max;
+ foreachbdf_in_bus(bdf, max, bus) {
+ u32 v = pci_config_readl(bdf, PCI_CLASS_REVISION);
+ if ((v>>8) != classprog)
+ continue;
+ if (count--)
+ continue;
+ regs->bx = bdf;
+ set_code_success(regs);
+ return;
+ }
}
set_code_invalid(regs, RET_DEVICE_NOT_FOUND);
}