Properly detect muliple PCI root brings in L4Re's io process
Christian_Ehrhardt at genua.de
Wed Jun 1 17:20:32 CEST 2011
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
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.
The contributions made by this patch are licensed under the MIT license
diff --git a/src/l4/pkg/io/server/src/acpi.cc b/src/l4/pkg/io/server/src/acpi.cc
index f76c768..4179c4e 100644
@@ -572,9 +572,25 @@ discover_pre_cb(ACPI_HANDLE obj, UINT32 nl, void *ctxt, void **)
// 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.
- 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;
+ d_printf(DBG_DEBUG, "Found PCI root bridge without BBN...\n");
if (Pci_root_bridge *rb = pci_root_bridge(0))
@@ -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");
+ if (have_bbn)
+ rb->num = pci_int;
More information about the l4-hackers