Date: Mon, 16 Mar 2009 18:03:33 +0200 From: Andriy Gapon <avg@icyb.net.ua> To: freebsd-acpi@freebsd.org Subject: piix4: heuristic quirk for incorrect value of PM1a_CNT_BLK Message-ID: <49BE7855.40709@icyb.net.ua>
next in thread | raw e-mail | index | archive | help
I personally own two different systems (from different vendors) based on PIIX4E/440BX chipset. They both have incorrect value of PM1a_CNT_BLK and in both case it's 0x4040 instead 0x4004. I suspect that this was a common mistake that was made by a BIOS vendor and then propagated into a number of BIOSes for different motehrboard vendors. I've developed a local quirk/fix for this which works in heuristic way. It depends on the fact that PIIX4 and later ICH chipsets have the same layout for several ACPI-related registers in Power Management IO space. So it forces Pm1aControlBlock to pm_base + 4 if Pm1aEventBlock is at pm_base + 0 and PmTimerBlock is at pm_base + 8. But I am not sure if it won't break any non-Intel HW. So this patch is not likely to be ever committed to freebsd sources, but it might be useful for some people. This can help on the relevant systems that have problems with shutdown/reboot via ACPI. diff --git a/sys/dev/acpica/acpi_quirk.c b/sys/dev/acpica/acpi_quirk.c index b75a527..bb44088 100644 --- a/sys/dev/acpica/acpi_quirk.c +++ b/sys/dev/acpica/acpi_quirk.c @@ -140,6 +140,7 @@ acpi_table_quirks(int *quirks) const struct acpi_q_entry *entry; const struct acpi_q_rule *match; ACPI_TABLE_HEADER fadt, dsdt, xsdt, *hdr; + UINT32 pm_base; int done; /* First, allow the machdep system to set its idea of quirks. */ @@ -180,5 +181,21 @@ acpi_table_quirks(int *quirks) } } + /* Special check for incorrect PM1a_CNT_BLK address on PIIX4E systems, + * a mistake that was common for many BIOS vendors. + */ + pm_base = AcpiGbl_FADT.Pm1aControlBlock & 0xffffff00; + if ((AcpiGbl_FADT.PmTimerBlock & 0xffffff00) == pm_base + && (AcpiGbl_FADT.Pm1aEventBlock & 0xffffff00) == pm_base + && (AcpiGbl_FADT.PmTimerBlock & 0xff) == 0x08 + && (AcpiGbl_FADT.Pm1aEventBlock & 0xff) == 0x00 + && (AcpiGbl_FADT.Pm1aControlBlock & 0xff) != 0x04) + { + printf("detected a system that looks like PIIX4E with incorrect " + "PM1a_CNT_BLK address\n"); + printf("PM_BASE: %#x, PM1a_CNT_BLK: %#x => %#x\n", + pm_base, AcpiGbl_FADT.Pm1aControlBlock, pm_base | 0x04); + AcpiGbl_FADT.Pm1aControlBlock = pm_base | 0x04; + } return (0); } -- Andriy Gapon
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?49BE7855.40709>