Hi,
I tried to run fiasco and L4Linux on an SMP machine that features two idenpendent PCI root bridges. Currently, the io process fails to scan the bus connected to the second bridge.
It properly detects that two PCI root bridges are present and creates two seperate Pci_port_root_bridge objects. However, it fails to initialize the Pci_bridge::num field properly. As a result, the io process scans the first bus twice. This causes major havoc as PCI devices on the second bus don't show up in L4Linux at all and devices on the first bus are detected twice.
According to http://www.acpi.info/acpi_faq.htm the ACPI structures should contain a _BBN method to detect the bus number of both root busses. The following patch uses this method to detect and set the Pci_bridge::num field properly.
A patch to fix this is provided below. With this patch NICs on both PCI busses are detected and work properly on the hardware in question.
As always comments are appreciated.
regards Christian
The contributions made by this patch are licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php).
diff --git a/src/l4/pkg/io/server/src/acpi.cc b/src/l4/pkg/io/server/src/acpi.cc index f76c768..4179c4e 100644 --- a/src/l4/pkg/io/server/src/acpi.cc +++ b/src/l4/pkg/io/server/src/acpi.cc @@ -572,9 +572,25 @@ discover_pre_cb(ACPI_HANDLE obj, UINT32 nl, void *ctxt, void **) //AcpiUtReleaseMutex(ACPI_MTX_NAMESPACE);
// hm, this seems very specific for PCI + /* + * Systems with multiple PCI root bridges must provide the PCI bus + * number of each bus via the _BBN method. + */ if (pci_rb) { - d_printf(DBG_DEBUG, "Found PCI root bridge...\n"); + ACPI_INTEGER pci_int; + bool have_bbn = false; + + if (ACPI_SUCCESS(AcpiUtEvaluateNumericObject((char*)METHOD_NAME__BBN, + node, &pci_int))) + { + d_printf(DBG_DEBUG, "PCI root bridge with BBN=%llx...\n", pci_int); + have_bbn = true; + } + else + { + d_printf(DBG_DEBUG, "Found PCI root bridge without BBN...\n"); + } if (Pci_root_bridge *rb = pci_root_bridge(0)) { if (rb->host()) @@ -582,9 +598,13 @@ discover_pre_cb(ACPI_HANDLE obj, UINT32 nl, void *ctxt, void **) // we found a second root bridge // create a new root pridge instance rb = new Pci_port_root_bridge(nd); + if (!have_bbn) + d_printf(DBG_ERR, "ERROR: Multiple root bridges without BBN\n"); } else rb->set_host(nd); + if (have_bbn) + rb->num = pci_int;
nd->set_discover_bus_if(rb); }