Hi,

most modern x86 hardware includes more than one PCI root segement.
E.g. a hardware that I have here has three PCI root segemnts with bus
numbers 0, 0x7f, 0x80 and 0xff respectively. (0x7f and 0xff host the
uncore devices of each processor).

These segments are already detected by APCI but this information is not
used when attaching PCI busses to the mainbus. Below is a patch that
should solve the PCI bus detection problem in a robust way.

There's a small problem though: Some of the secondary PCI segments
can show up as busses behind some kind of host bridge device dowstream
of pci bus 0, too. These PCI busses would be attached twice, now. Thus we
keep track of attached root segemnents in the ACPI code.

NOTE: Patch is currently i386 only but almost everything is MI.

    regards   Christian


Index: arch/i386/i386/mainbus.c
===================================================================
RCS file: /cvs/src/sys/arch/i386/i386/mainbus.c,v
retrieving revision 1.48
diff -u -r1.48 mainbus.c
--- arch/i386/i386/mainbus.c    3 Nov 2010 10:15:23 -0000       1.48
+++ arch/i386/i386/mainbus.c    6 Sep 2012 08:58:38 -0000
@@ -244,6 +244,9 @@
                mba.mba_pba.pba_domain = pci_ndomains++;
                mba.mba_pba.pba_bus = 0;
                config_found(self, &mba.mba_pba, mainbus_print);
+#if NACPI > 0
+               acpi_pciroots_attach(self, &mba.mba_pba, mainbus_print);
+#endif
        }
 #endif
 
Index: dev/acpi/acpi.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/acpi.c,v
retrieving revision 1.238
diff -u -r1.238 acpi.c
--- dev/acpi/acpi.c     13 Jul 2012 11:51:41 -0000      1.238
+++ dev/acpi/acpi.c     6 Sep 2012 08:58:39 -0000
@@ -392,6 +392,8 @@
 
 TAILQ_HEAD(, acpi_pci) acpi_pcidevs =
     TAILQ_HEAD_INITIALIZER(acpi_pcidevs);
+TAILQ_HEAD(, acpi_pci) acpi_pcirootdevs = 
+    TAILQ_HEAD_INITIALIZER(acpi_pcirootdevs);
 
 int acpi_getpci(struct aml_node *node, void *arg);
 int acpi_getminbus(union acpi_resource *crs, void *arg);
@@ -480,6 +482,7 @@
                        node->pci = pci;
                        dnprintf(10, "found PCI root: %s %d\n",
                            aml_nodename(node), pci->bus);
+                       TAILQ_INSERT_TAIL(&acpi_pcirootdevs, pci, next);
                }
                aml_freevalue(&res);
                return 0;
@@ -548,6 +551,31 @@
                            dev->dv_xname, aml_nodename(pdev->node));
                        pdev->device = dev;
                }
+       }
+}
+
+void
+acpi_pciroot_match(struct device *dev, int bus)
+{
+       struct acpi_pci *pdev;
+
+       TAILQ_FOREACH(pdev, &acpi_pcirootdevs, next) {
+               if (pdev->bus == bus)
+                       pdev->device = dev;
+       }
+}
+
+void
+acpi_pciroots_attach(struct device *dev, void *aux, cfprint_t pr)
+{
+       struct acpi_pci                 *pdev;
+       struct pcibus_attach_args       *pba = aux;
+
+       TAILQ_FOREACH(pdev, &acpi_pcirootdevs, next) {
+               if (pdev->device)       /* Already attached */
+                       continue;
+               pba->pba_bus = pdev->bus;
+               config_found(dev, pba, pr);
        }
 }
 
Index: dev/acpi/acpivar.h
===================================================================
RCS file: /cvs/src/sys/dev/acpi/acpivar.h,v
retrieving revision 1.71
diff -u -r1.71 acpivar.h
--- dev/acpi/acpivar.h  15 Apr 2011 17:34:51 -0000      1.71
+++ dev/acpi/acpivar.h  6 Sep 2012 08:58:39 -0000
@@ -322,6 +322,9 @@
 void   acpi_powerdown_task(void *, int);
 void   acpi_sleep_task(void *, int);
 
+void   acpi_pciroot_match(struct device *, int);
+void   acpi_pciroots_attach(struct device *, void *, cfprint_t);
+
 #endif
 
 #endif /* !_ACPI_WAKECODE */
Index: dev/pci/pci.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/pci.c,v
retrieving revision 1.94
diff -u -r1.94 pci.c
--- dev/pci/pci.c       10 Oct 2011 19:42:37 -0000      1.94
+++ dev/pci/pci.c       6 Sep 2012 08:58:39 -0000
@@ -46,6 +46,12 @@
 #include <dev/pci/pcidevs.h>
 #include <dev/pci/ppbreg.h>
 
+#include "acpi.h"
+
+#if NACPI > 0
+#include <dev/acpi/acpivar.h>
+#endif
+
 int pcimatch(struct device *, void *, void *);
 void pciattach(struct device *, struct device *, void *);
 int pcidetach(struct device *, int);
@@ -187,6 +193,9 @@
        if (pci_enumerate_bus(sc, pci_primary_vga, NULL))
                pci_vga_pci = sc;
        pci_enumerate_bus(sc, NULL, NULL);
+#if NACPI > 0
+       acpi_pciroot_match(self, pba->pba_bus);
+#endif
 }
 
 int

Reply via email to