Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 5 Jun 2009 10:30:29 -0400
From:      John Baldwin <jhb@freebsd.org>
To:        Josef Moellers <josef.moellers@ts.fujitsu.com>
Cc:        "freebsd-acpi@freebsd.org" <freebsd-acpi@freebsd.org>
Subject:   Re: Failure to get past a PCI bridge
Message-ID:  <200906051030.30236.jhb@freebsd.org>
In-Reply-To: <4A28E2A5.9030107@ts.fujitsu.com>
References:  <4A24D29A.5030604@ts.fujitsu.com> <200906041229.54888.jhb@freebsd.org> <4A28E2A5.9030107@ts.fujitsu.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Friday 05 June 2009 5:17:25 am Josef Moellers wrote:
> Difficult, since I can't boot properly.
> However, I have managed to get the dsdt using a SuSE Linux and have run 
> that through acpidump -d on a 7.2 running on a XEN virtual machine. 
> Here's the result.

Hmm, your BIOS is certainly hosed.  First, it does have separate processor
objects:

    Scope (\_PR)
    {
        Processor (PR00, 0x00, 0x00000000, 0x00) {}
        Processor (PR01, 0x08, 0x00000000, 0x00) {}
        Processor (PR02, 0x01, 0x00000000, 0x00) {}
        Processor (PR03, 0x09, 0x00000000, 0x00) {}
        Processor (PR04, 0x02, 0x00000000, 0x00) {}
        Processor (PR05, 0x0A, 0x00000000, 0x00) {}
        Processor (PR06, 0x03, 0x00000000, 0x00) {}
        Processor (PR07, 0x0B, 0x00000000, 0x00) {}
        Processor (PR10, 0x04, 0x00000000, 0x00) {}
        Processor (PR11, 0x0C, 0x00000000, 0x00) {}
        Processor (PR12, 0x05, 0x00000000, 0x00) {}
        Processor (PR13, 0x0D, 0x00000000, 0x00) {}
        Processor (PR14, 0x06, 0x00000000, 0x00) {}
        Processor (PR15, 0x0E, 0x00000000, 0x00) {}
        Processor (PR16, 0x07, 0x00000000, 0x00) {}
        Processor (PR17, 0x0F, 0x00000000, 0x00) {}
    }

However, \_SB_.CPU0 and \_SB_.CPU1 are listed as Host-PCI bridge devices, not
CPUs (CPUs are enumerated in ACPI as Processor() objects, not Device()'s, and
certainly not with the _HID == Host-PCI bridge):

        Device (CPU0)
        {
            Name (_HID, EisaId ("PNP0A03"))
            Name (_UID, 0x01)
	    Name (_BBN, 0xFF)

...

        Device (CPU1)
        {
            Name (_HID, EisaId ("PNP0A03"))
            Name (_UID, 0x02)
            Name (_BBN, 0xFE)

...

        Device (PCI0)
        {
            Name (_HID, EisaId ("PNP0A08"))
            Name (_CID, 0x030AD041)
            Name (_UID, 0x00)
            Name (_BBN, 0x00)
            Method (_INI, 0, NotSerialized)
            {
                \OSCK ()
            }

Hmm, it does have a valid _BBN value for your actual PCI bus.  Not sure why
it is using a bus number of 2.  Ahh, ok.  Hmm, so some machines with multipe
busses would set _BBN to 0 for all busses, so we don't trust a _BBN of 0 for
non-pcib0.  However, I think what we want to do is not trust a _BBN of 0 if
we already have a PCI bus 0 (in your case, pcib0 has PCI bus 255, pcib1 has
PCI bus 254, and pcib2 has PCI bus 0).  Try this:

--- //depot/vendor/freebsd/src/sys/dev/acpica/acpi_pcib_acpi.c	2009/02/05 18:45:20
+++ //depot/user/jhb/acpipci/dev/acpica/acpi_pcib_acpi.c	2009/06/05 14:28:27
@@ -146,6 +146,7 @@
 {
     struct acpi_hpcib_softc	*sc;
     ACPI_STATUS			status;
+    static int bus0_seen = 0;
     u_int addr, slot, func, busok;
     uint8_t busno;
 
@@ -156,6 +157,21 @@
     sc->ap_handle = acpi_get_handle(dev);
 
     /*
+     * Get our segment number by evaluating _SEG
+     * It's OK for this to not exist.
+     */
+    status = acpi_GetInteger(sc->ap_handle, "_SEG", &sc->ap_segment);
+    if (ACPI_FAILURE(status)) {
+	if (status != AE_NOT_FOUND) {
+	    device_printf(dev, "could not evaluate _SEG - %s\n",
+		AcpiFormatException(status));
+	    return_VALUE (ENXIO);
+	}
+	/* If it's not found, assume 0. */
+	sc->ap_segment = 0;
+    }
+
+    /*
      * Get our base bus number by evaluating _BBN.
      * If this doesn't work, we assume we're bus number 0.
      *
@@ -169,8 +185,10 @@
      * XXX invoke _REG on this for the PCI config space address space?
      * XXX It seems many BIOS's with multiple Host-PCI bridges do not set
      *     _BBN correctly.  They set _BBN to zero for all bridges.  Thus,
-     *     if _BBN is zero and pcib0 already exists, we try to read our
+     *     if _BBN is zero and PCI bus 0 already exists, we try to read our
      *     bus number from the configuration registers at address _ADR.
+     *     We only do this for domain/segment 0 in the hopes that this is
+     *     only needed for old single-domain machines.
      */
     status = acpi_GetInteger(sc->ap_handle, "_BBN", &sc->ap_bus);
     if (ACPI_FAILURE(status)) {
@@ -185,11 +203,11 @@
     }
 
     /*
-     * If the bus is zero and pcib0 already exists, read the bus number
-     * via PCI config space.
+     * If this is segment 0, the bus is zero, and PCI bus 0 already
+     * exists, read the bus number via PCI config space.
      */
     busok = 1;
-    if (sc->ap_bus == 0 && devclass_get_device(pcib_devclass, 0) != dev) {
+    if (sc->ap_segment == 0 && sc->ap_bus == 0 && bus0_seen) {
 	busok = 0;
 	status = acpi_GetInteger(sc->ap_handle, "_ADR", &addr);
 	if (ACPI_FAILURE(status)) {
@@ -226,20 +244,9 @@
 	device_printf(dev, "trying bus number %d\n", sc->ap_bus);
     }
 
-    /*
-     * Get our segment number by evaluating _SEG
-     * It's OK for this to not exist.
-     */
-    status = acpi_GetInteger(sc->ap_handle, "_SEG", &sc->ap_segment);
-    if (ACPI_FAILURE(status)) {
-	if (status != AE_NOT_FOUND) {
-	    device_printf(dev, "could not evaluate _SEG - %s\n",
-		AcpiFormatException(status));
-	    return_VALUE (ENXIO);
-	}
-	/* If it's not found, assume 0. */
-	sc->ap_segment = 0;
-    }
+    /* If this is bus 0 on segment 0, note that it has been seen already. */
+    if (sc->ap_segment == 0 && sc->ap_bus == 0)
+	    bus0_seen = 1;
 
     return (acpi_pcib_attach(dev, &sc->ap_prt, sc->ap_bus));
 }


-- 
John Baldwin



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200906051030.30236.jhb>