Apply patch https://github.com/acpica/acpica/commit/\
c450c13615f7af0673230041da4216b3de5bc4d3.patch This patch fixes 2 issues in AccessWidth/BitOffset support and adds comments to justify the BitOffset/BitWidth style macro usages. Lv Zheng. This patch introduces ACPI_IS_ALIGNED() macro. Lv Zheng. The old register descriptors are translated in AcpiTbInitGenericAddress() with AccessWidth being filled with 0. This breaks code in AcpiHwGetAccessBitWidth() when the registers are 16-bit IO ports and their BitWidth fields are filled with 16. The rapid fix is meant to make code written for AcpiHwGetAccessBitWidth() regression safer before the issue is correctly fixed from AcpiTbInitGenericAddress(). Reported by John Baldwin <jhb@freebsd.org>, Fixed by Lv Zheng <lv.zheng@intel.com>, Tested by Jung-uk Kim <jkim@freebsd.org>.
This commit is contained in:
parent
19ea743456
commit
1c46e02997
74
sys/external/bsd/acpica/dist/hardware/hwregs.c
vendored
74
sys/external/bsd/acpica/dist/hardware/hwregs.c
vendored
@ -92,16 +92,34 @@ AcpiHwGetAccessBitWidth (
|
||||
ACPI_GENERIC_ADDRESS *Reg,
|
||||
UINT8 MaxBitWidth)
|
||||
{
|
||||
UINT64 Address;
|
||||
|
||||
|
||||
if (!Reg->AccessWidth)
|
||||
{
|
||||
if (Reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_IO)
|
||||
/*
|
||||
* Detect old register descriptors where only the BitWidth field
|
||||
* makes senses. The target address is copied to handle possible
|
||||
* alignment issues.
|
||||
*/
|
||||
ACPI_MOVE_64_TO_64 (&Address, &Reg->Address);
|
||||
if (!Reg->BitOffset && Reg->BitWidth &&
|
||||
ACPI_IS_POWER_OF_TWO (Reg->BitWidth) &&
|
||||
ACPI_IS_ALIGNED (Reg->BitWidth, 8) &&
|
||||
ACPI_IS_ALIGNED (Address, Reg->BitWidth))
|
||||
{
|
||||
return (32);
|
||||
return (Reg->BitWidth);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (MaxBitWidth);
|
||||
if (Reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_IO)
|
||||
{
|
||||
return (32);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (MaxBitWidth);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -250,7 +268,7 @@ AcpiHwRead (
|
||||
Index = 0;
|
||||
while (BitWidth)
|
||||
{
|
||||
if (BitOffset > AccessWidth)
|
||||
if (BitOffset >= AccessWidth)
|
||||
{
|
||||
Value32 = 0;
|
||||
BitOffset -= AccessWidth;
|
||||
@ -271,6 +289,12 @@ AcpiHwRead (
|
||||
&Value32, AccessWidth);
|
||||
}
|
||||
|
||||
/*
|
||||
* Use offset style bit masks because:
|
||||
* BitOffset < AccessWidth/BitWidth < AccessWidth, and
|
||||
* AccessWidth is ensured to be less than 32-bits by
|
||||
* AcpiHwValidateRegister().
|
||||
*/
|
||||
if (BitOffset)
|
||||
{
|
||||
Value32 &= ACPI_MASK_BITS_BELOW (BitOffset);
|
||||
@ -282,6 +306,10 @@ AcpiHwRead (
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Use offset style bit writes because "Index * AccessWidth" is
|
||||
* ensured to be less than 32-bits by AcpiHwValidateRegister().
|
||||
*/
|
||||
ACPI_SET_BITS (Value, Index * AccessWidth,
|
||||
ACPI_MASK_BITS_ABOVE_32 (AccessWidth), Value32);
|
||||
|
||||
@ -352,20 +380,28 @@ AcpiHwWrite (
|
||||
Index = 0;
|
||||
while (BitWidth)
|
||||
{
|
||||
/*
|
||||
* Use offset style bit reads because "Index * AccessWidth" is
|
||||
* ensured to be less than 32-bits by AcpiHwValidateRegister().
|
||||
*/
|
||||
NewValue32 = ACPI_GET_BITS (&Value, Index * AccessWidth,
|
||||
ACPI_MASK_BITS_ABOVE_32 (AccessWidth));
|
||||
|
||||
if (BitOffset > AccessWidth)
|
||||
if (BitOffset >= AccessWidth)
|
||||
{
|
||||
BitOffset -= AccessWidth;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Use offset style bit masks because AccessWidth is ensured
|
||||
* to be less than 32-bits by AcpiHwValidateRegister() and
|
||||
* BitOffset/BitWidth is less than AccessWidth here.
|
||||
*/
|
||||
if (BitOffset)
|
||||
{
|
||||
NewValue32 &= ACPI_MASK_BITS_BELOW (BitOffset);
|
||||
}
|
||||
|
||||
if (BitWidth < AccessWidth)
|
||||
{
|
||||
NewValue32 &= ACPI_MASK_BITS_ABOVE (BitWidth);
|
||||
@ -384,15 +420,20 @@ AcpiHwWrite (
|
||||
&Value64, AccessWidth);
|
||||
OldValue32 = (UINT32) Value64;
|
||||
|
||||
/*
|
||||
* Use offset style bit masks because AccessWidth is
|
||||
* ensured to be less than 32-bits by
|
||||
* AcpiHwValidateRegister() and BitOffset/BitWidth is
|
||||
* less than AccessWidth here.
|
||||
*/
|
||||
if (BitOffset)
|
||||
{
|
||||
OldValue32 &= ACPI_MASK_BITS_ABOVE (BitOffset + 1);
|
||||
OldValue32 &= ACPI_MASK_BITS_ABOVE (BitOffset);
|
||||
BitOffset = 0;
|
||||
}
|
||||
|
||||
if (BitWidth < AccessWidth)
|
||||
{
|
||||
OldValue32 &= ACPI_MASK_BITS_BELOW (BitWidth - 1);
|
||||
OldValue32 &= ACPI_MASK_BITS_BELOW (BitWidth);
|
||||
}
|
||||
|
||||
NewValue32 |= OldValue32;
|
||||
@ -415,15 +456,20 @@ AcpiHwWrite (
|
||||
Address + Index * ACPI_DIV_8 (AccessWidth),
|
||||
&OldValue32, AccessWidth);
|
||||
|
||||
/*
|
||||
* Use offset style bit masks because AccessWidth is
|
||||
* ensured to be less than 32-bits by
|
||||
* AcpiHwValidateRegister() and BitOffset/BitWidth is
|
||||
* less than AccessWidth here.
|
||||
*/
|
||||
if (BitOffset)
|
||||
{
|
||||
OldValue32 &= ACPI_MASK_BITS_ABOVE (BitOffset + 1);
|
||||
OldValue32 &= ACPI_MASK_BITS_ABOVE (BitOffset);
|
||||
BitOffset = 0;
|
||||
}
|
||||
|
||||
if (BitWidth < AccessWidth)
|
||||
{
|
||||
OldValue32 &= ACPI_MASK_BITS_BELOW (BitWidth - 1);
|
||||
OldValue32 &= ACPI_MASK_BITS_BELOW (BitWidth);
|
||||
}
|
||||
|
||||
NewValue32 |= OldValue32;
|
||||
@ -435,6 +481,10 @@ AcpiHwWrite (
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Index * AccessWidth is ensured to be less than 32-bits by
|
||||
* AcpiHwValidateRegister().
|
||||
*/
|
||||
BitWidth -= BitWidth > AccessWidth ? AccessWidth : BitWidth;
|
||||
Index++;
|
||||
}
|
||||
|
@ -266,7 +266,8 @@
|
||||
|
||||
/* Generic (power-of-two) rounding */
|
||||
|
||||
#define ACPI_IS_POWER_OF_TWO(a) (((a) & ((a) - 1)) == 0)
|
||||
#define ACPI_IS_ALIGNED(a, s) (((a) & ((s) - 1)) == 0)
|
||||
#define ACPI_IS_POWER_OF_TWO(a) ACPI_IS_ALIGNED(a, a)
|
||||
|
||||
/*
|
||||
* Bitmask creation
|
||||
|
Loading…
Reference in New Issue
Block a user