Skip site navigation (1)Skip section navigation (2)
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>