Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/external/bsd/acpica/dist Apply patch https://github.com/...



details:   https://anonhg.NetBSD.org/src/rev/8c6dbf26fd7f
branches:  trunk
changeset: 345414:8c6dbf26fd7f
user:      christos <christos%NetBSD.org@localhost>
date:      Wed May 25 18:35:13 2016 +0000

description:
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@localhost>, Fixed by Lv Zheng <lv.zheng%intel.com@localhost>,
Tested by Jung-uk Kim <jkim%freebsd.org@localhost>.

diffstat:

 sys/external/bsd/acpica/dist/hardware/hwregs.c  |  74 ++++++++++++++++++++----
 sys/external/bsd/acpica/dist/include/acmacros.h |   3 +-
 2 files changed, 64 insertions(+), 13 deletions(-)

diffs (177 lines):

diff -r 1196ae67a8fc -r 8c6dbf26fd7f sys/external/bsd/acpica/dist/hardware/hwregs.c
--- a/sys/external/bsd/acpica/dist/hardware/hwregs.c    Wed May 25 17:43:58 2016 +0000
+++ b/sys/external/bsd/acpica/dist/hardware/hwregs.c    Wed May 25 18:35:13 2016 +0000
@@ -92,16 +92,34 @@
     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 @@
     Index = 0;
     while (BitWidth)
     {
-        if (BitOffset > AccessWidth)
+        if (BitOffset >= AccessWidth)
         {
             Value32 = 0;
             BitOffset -= AccessWidth;
@@ -271,6 +289,12 @@
                     &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 @@
             }
         }
 
+        /*
+         * 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 @@
     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 @@
                         &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 @@
                         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 @@
             }
         }
 
+        /*
+         * Index * AccessWidth is ensured to be less than 32-bits by
+         * AcpiHwValidateRegister().
+         */
         BitWidth -= BitWidth > AccessWidth ? AccessWidth : BitWidth;
         Index++;
     }
diff -r 1196ae67a8fc -r 8c6dbf26fd7f sys/external/bsd/acpica/dist/include/acmacros.h
--- a/sys/external/bsd/acpica/dist/include/acmacros.h   Wed May 25 17:43:58 2016 +0000
+++ b/sys/external/bsd/acpica/dist/include/acmacros.h   Wed May 25 18:35:13 2016 +0000
@@ -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



Home | Main Index | Thread Index | Old Index