X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fpci.c;h=49698ac58b8d0a7481007d9e42021d9c4336155b;hb=6f85049296d63d8e21946d0bb927047d66aaa16a;hp=ebc6f91b71c8f84ecb849dba34e99fa2123c1b6f;hpb=0f654a976b9ec8d0346249f8aacc5fbd7d40e946;p=seabios.git diff --git a/src/pci.c b/src/pci.c index ebc6f91..49698ac 100644 --- a/src/pci.c +++ b/src/pci.c @@ -8,8 +8,8 @@ #include "pci.h" // pci_config_writel #include "ioport.h" // outl #include "util.h" // dprintf -#include "config.h" // CONFIG_* -#include "farptr.h" // CONFIG_* +#include "paravirt.h" // romfile_loadint +#include "farptr.h" // MAKE_FLATPTR #include "pci_regs.h" // PCI_VENDOR_ID #include "pci_ids.h" // PCI_CLASS_DISPLAY_VGA @@ -59,48 +59,30 @@ pci_config_maskw(u16 bdf, u32 addr, u16 off, u16 on) // Helper function for foreachbdf() macro - return next device int -pci_next(int bdf, int *pmax) +pci_next(int bdf, int bus) { - if (pci_bdf_to_fn(bdf) == 1 - && (pci_config_readb(bdf-1, PCI_HEADER_TYPE) & 0x80) == 0) + if (pci_bdf_to_fn(bdf) == 0 + && (pci_config_readb(bdf, PCI_HEADER_TYPE) & 0x80) == 0) // Last found device wasn't a multi-function device - skip to // the next device. - bdf += 7; + bdf += 8; + else + bdf += 1; - int max = *pmax; for (;;) { - if (bdf >= max) { - if (CONFIG_PCI_ROOT1 && bdf <= (CONFIG_PCI_ROOT1 << 8)) - bdf = CONFIG_PCI_ROOT1 << 8; - else if (CONFIG_PCI_ROOT2 && bdf <= (CONFIG_PCI_ROOT2 << 8)) - bdf = CONFIG_PCI_ROOT2 << 8; - else - return -1; - *pmax = max = bdf + 0x0100; - } + if (pci_bdf_to_bus(bdf) != bus) + return -1; u16 v = pci_config_readw(bdf, PCI_VENDOR_ID); if (v != 0x0000 && v != 0xffff) // Device is present. - break; + return bdf; if (pci_bdf_to_fn(bdf) == 0) bdf += 8; else bdf += 1; } - - // Check if found device is a bridge. - u32 v = pci_config_readb(bdf, PCI_HEADER_TYPE); - v &= 0x7f; - if (v == PCI_HEADER_TYPE_BRIDGE || v == PCI_HEADER_TYPE_CARDBUS) { - v = pci_config_readl(bdf, PCI_PRIMARY_BUS); - int newmax = (v & 0xff00) + 0x0100; - if (newmax > max) - *pmax = newmax; - } - - return bdf; } struct pci_device *PCIDevices; @@ -111,19 +93,15 @@ void pci_probe(void) { 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; + int extraroots = romfile_loadint("etc/extra-pci-roots", 0); int bus = -1, lastbus = 0, rootbuses = 0, count=0; - while (bus < MaxPCIBus) { + while (bus < 0xff && (bus < MaxPCIBus || rootbuses < extraroots)) { bus++; - int bdf, max; - foreachbdf_in_bus(bdf, max, bus) { + int bdf; + foreachbdf(bdf, bus) { // Create new pci_device struct and add to list. struct pci_device *dev = malloc_tmp(sizeof(*dev)); if (!dev) { @@ -143,6 +121,8 @@ pci_probe(void) rootbuses++; lastbus = bus; rootbus = rootbuses; + if (bus > MaxPCIBus) + MaxPCIBus = bus; } else { rootbus = parent->rootbus; }