RE: 4.7 regression - ACPICA: Hardware: Enhance acpi_hw_validate_register() with access_width/bit_offset awareness

Zheng, Lv
2016-06-23T00:33:41Z

Hi, Mike

> From: Mike Galbraith [mailto:umgwanakikbuti@gmail.com]
> Subject: 4.7 regression - ACPICA: Hardware: Enhance
> acpi_hw_validate_register() with access_width/bit_offset awareness
>
> In my aging (ok old) HP DL980 G7
[Lv Zheng]

Which may mean Windows Vista cannot run on this machine, and you need to use quirks to run recent Linux.
Could you try to boot it with one of the following parameters or both of the parameters:
acpi=rsdt
Or
acpi_force_32bit_fadt_addr

TBH, Windows preference of RSDT/XSDT and the preference of old 32-bit register/new GAS register descriptor are unknown to us.
But we prepared quirk for the users that my require an explicit preference to use the old platforms.

Please also send us the acpidump/dmidecode outputs for confirmation.

> ->access_width may be either 0 or
> max_bit_width, the later inspiring cpufreq to say go away. The below
> made box a happy camper again.
>
> ACPI Error: Unsupported register access width: 0x40 (20160422/hwregs-
> 165)
[Lv Zheng]
According to the ACPI specification.
The valid access size is:
Specifies access size.
0 Undefined (legacy reasons)
1 Byte access
2 Word access
3 Dword access
4 QWord access

0x40 is a too big number.
So you surely need a quirk because the value filled by the BIOS is not spec compliant.

Thanks and best regards
-Lv

>
> Dinged-up-by: my little hammer
> ---
> drivers/acpi/acpica/hwregs.c | 13 ++++++++++---
> 1 file changed, 10 insertions(+), 3 deletions(-)
>
> --- a/drivers/acpi/acpica/hwregs.c
> +++ b/drivers/acpi/acpica/hwregs.c
> @@ -83,7 +83,7 @@ acpi_hw_write_multiple(u32 value,
> static u8
> acpi_hw_get_access_bit_width(struct acpi_generic_address *reg, u8
> max_bit_width)
> {
> - if (!reg->access_width) {
> + if (!reg->access_width || reg->access_width == max_bit_width) {
> if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_IO) {
> max_bit_width = 32;
> }
> @@ -152,9 +152,16 @@ acpi_hw_validate_register(struct acpi_ge
> return (AE_SUPPORT);
> }
>
> - /* Validate the access_width */
> + /* Validate the access_width, or bit_width for old register
> descriptors */
>
> - if (reg->access_width > 4) {
> + if ((!reg->access_width || reg->access_width == max_bit_width)) {
> + if (reg->bit_width != 8 && reg->bit_width != 16 &&
> + reg->bit_width != 32 && reg->bit_width !=
> max_bit_width) {
> + ACPI_ERROR((AE_INFO, "Unsupported register bit
> width: 0x%X",
> + reg->bit_width));
> + return (AE_SUPPORT);
> + }
> + } else if (reg->access_width > 4) {
> ACPI_ERROR((AE_INFO,
> "Unsupported register access width: 0x%X",
> reg->access_width));