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>