--- /dev/null	jeu. déc. 26 13:48:28 2013
+++ new/usr/src/common/acpica/compiler/asllength.c	jeu. déc. 26 13:48:28 2013
@@ -0,0 +1,457 @@
+/******************************************************************************
+ *
+ * Module Name: asllength - Tree walk to determine package and opcode lengths
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2013, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include "aslcompiler.h"
+#include "aslcompiler.y.h"
+#include "amlcode.h"
+
+
+#define _COMPONENT          ACPI_COMPILER
+        ACPI_MODULE_NAME    ("asllength")
+
+/* Local prototypes */
+
+static UINT8
+CgGetPackageLenByteCount (
+    ACPI_PARSE_OBJECT       *Op,
+    UINT32                  PackageLength);
+
+static void
+CgGenerateAmlOpcodeLength (
+    ACPI_PARSE_OBJECT       *Op);
+
+
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+void
+LnAdjustLengthToRoot (
+    ACPI_PARSE_OBJECT       *Op,
+    UINT32                  LengthDelta);
+#endif
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    LnInitLengthsWalk
+ *
+ * PARAMETERS:  ASL_WALK_CALLBACK
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Walk callback to initialize (and re-initialize) the node
+ *              subtree length(s) to zero. The Subtree lengths are bubbled
+ *              up to the root node in order to get a total AML length.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+LnInitLengthsWalk (
+    ACPI_PARSE_OBJECT       *Op,
+    UINT32                  Level,
+    void                    *Context)
+{
+
+    Op->Asl.AmlSubtreeLength = 0;
+    return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    LnPackageLengthWalk
+ *
+ * PARAMETERS:  ASL_WALK_CALLBACK
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Walk callback to calculate the total AML length.
+ *              1) Calculate the AML lengths (opcode, package length, etc.) for
+ *                 THIS node.
+ *              2) Bubbble up all of these lengths to the parent node by summing
+ *                 them all into the parent subtree length.
+ *
+ * Note:  The SubtreeLength represents the total AML length of all child nodes
+ *        in all subtrees under a given node. Therefore, once this walk is
+ *        complete, the Root Node subtree length is the AML length of the entire
+ *        tree (and thus, the entire ACPI table)
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+LnPackageLengthWalk (
+    ACPI_PARSE_OBJECT       *Op,
+    UINT32                  Level,
+    void                    *Context)
+{
+
+    /* Generate the AML lengths for this node */
+
+    CgGenerateAmlLengths (Op);
+
+    /* Bubble up all lengths (this node and all below it) to the parent */
+
+    if ((Op->Asl.Parent) &&
+        (Op->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG))
+    {
+        Op->Asl.Parent->Asl.AmlSubtreeLength += (Op->Asl.AmlLength +
+                                           Op->Asl.AmlOpcodeLength +
+                                           Op->Asl.AmlPkgLenBytes +
+                                           Op->Asl.AmlSubtreeLength);
+    }
+    return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    CgGetPackageLenByteCount
+ *
+ * PARAMETERS:  Op              - Parse node
+ *              PackageLength   - Length to be encoded
+ *
+ * RETURN:      Required length of the package length encoding
+ *
+ * DESCRIPTION: Calculate the number of bytes required to encode the given
+ *              package length.
+ *
+ ******************************************************************************/
+
+static UINT8
+CgGetPackageLenByteCount (
+    ACPI_PARSE_OBJECT       *Op,
+    UINT32                  PackageLength)
+{
+
+    /*
+     * Determine the number of bytes required to encode the package length
+     * Note: the package length includes the number of bytes used to encode
+     * the package length, so we must account for this also.
+     */
+    if (PackageLength <= (0x0000003F - 1))
+    {
+        return (1);
+    }
+    else if (PackageLength <= (0x00000FFF - 2))
+    {
+        return (2);
+    }
+    else if (PackageLength <= (0x000FFFFF - 3))
+    {
+        return (3);
+    }
+    else if (PackageLength <= (0x0FFFFFFF - 4))
+    {
+        return (4);
+    }
+    else
+    {
+        /* Fatal error - the package length is too large to encode */
+
+        AslError (ASL_ERROR, ASL_MSG_ENCODING_LENGTH, Op, NULL);
+    }
+
+    return (0);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    CgGenerateAmlOpcodeLength
+ *
+ * PARAMETERS:  Op          - Parse node whose AML opcode lengths will be
+ *                            calculated
+ *
+ * RETURN:      None.
+ *
+ * DESCRIPTION: Calculate the AmlOpcodeLength, AmlPkgLenBytes, and AmlLength
+ *              fields for this node.
+ *
+ ******************************************************************************/
+
+static void
+CgGenerateAmlOpcodeLength (
+    ACPI_PARSE_OBJECT       *Op)
+{
+
+    /* Check for two-byte opcode */
+
+    if (Op->Asl.AmlOpcode > 0x00FF)
+    {
+        Op->Asl.AmlOpcodeLength = 2;
+    }
+    else
+    {
+        Op->Asl.AmlOpcodeLength = 1;
+    }
+
+    /* Does this opcode have an associated "PackageLength" field? */
+
+    Op->Asl.AmlPkgLenBytes = 0;
+    if (Op->Asl.CompileFlags & NODE_AML_PACKAGE)
+    {
+        Op->Asl.AmlPkgLenBytes = CgGetPackageLenByteCount (
+                                    Op, Op->Asl.AmlSubtreeLength);
+    }
+
+    /* Data opcode lengths are easy */
+
+    switch (Op->Asl.AmlOpcode)
+    {
+    case AML_BYTE_OP:
+
+        Op->Asl.AmlLength = 1;
+        break;
+
+    case AML_WORD_OP:
+
+        Op->Asl.AmlLength = 2;
+        break;
+
+    case AML_DWORD_OP:
+
+        Op->Asl.AmlLength = 4;
+        break;
+
+    case AML_QWORD_OP:
+
+        Op->Asl.AmlLength = 8;
+        break;
+
+    default:
+
+        /* All data opcodes must be above */
+        break;
+    }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    CgGenerateAmlLengths
+ *
+ * PARAMETERS:  Op        - Parse node
+ *
+ * RETURN:      None.
+ *
+ * DESCRIPTION: Generate internal length fields based on the AML opcode or
+ *              parse opcode.
+ *
+ ******************************************************************************/
+
+void
+CgGenerateAmlLengths (
+    ACPI_PARSE_OBJECT       *Op)
+{
+    char                    *Buffer;
+    ACPI_STATUS             Status;
+
+
+    switch (Op->Asl.AmlOpcode)
+    {
+    case AML_RAW_DATA_BYTE:
+
+        Op->Asl.AmlOpcodeLength = 0;
+        Op->Asl.AmlLength = 1;
+        return;
+
+    case AML_RAW_DATA_WORD:
+
+        Op->Asl.AmlOpcodeLength = 0;
+        Op->Asl.AmlLength = 2;
+        return;
+
+    case AML_RAW_DATA_DWORD:
+
+        Op->Asl.AmlOpcodeLength = 0;
+        Op->Asl.AmlLength = 4;
+        return;
+
+    case AML_RAW_DATA_QWORD:
+
+        Op->Asl.AmlOpcodeLength = 0;
+        Op->Asl.AmlLength = 8;
+        return;
+
+    case AML_RAW_DATA_BUFFER:
+
+        /* Aml length is/was set by creator */
+
+        Op->Asl.AmlOpcodeLength = 0;
+        return;
+
+    case AML_RAW_DATA_CHAIN:
+
+        /* Aml length is/was set by creator */
+
+        Op->Asl.AmlOpcodeLength = 0;
+        return;
+
+    default:
+
+        break;
+    }
+
+    switch (Op->Asl.ParseOpcode)
+    {
+    case PARSEOP_DEFINITIONBLOCK:
+
+        Gbl_TableLength = sizeof (ACPI_TABLE_HEADER) +
+                            Op->Asl.AmlSubtreeLength;
+        break;
+
+    case PARSEOP_NAMESEG:
+
+        Op->Asl.AmlOpcodeLength = 0;
+        Op->Asl.AmlLength = 4;
+        Op->Asl.ExternalName = Op->Asl.Value.String;
+        break;
+
+    case PARSEOP_NAMESTRING:
+    case PARSEOP_METHODCALL:
+
+        if (Op->Asl.CompileFlags & NODE_NAME_INTERNALIZED)
+        {
+            break;
+        }
+
+        Op->Asl.AmlOpcodeLength = 0;
+        Status = UtInternalizeName (Op->Asl.Value.String, &Buffer);
+        if (ACPI_FAILURE (Status))
+        {
+            DbgPrint (ASL_DEBUG_OUTPUT,
+                "Failure from internalize name %X\n", Status);
+            break;
+        }
+
+        Op->Asl.ExternalName = Op->Asl.Value.String;
+        Op->Asl.Value.String = Buffer;
+        Op->Asl.CompileFlags |= NODE_NAME_INTERNALIZED;
+
+        Op->Asl.AmlLength = strlen (Buffer);
+
+        /*
+         * Check for single backslash reference to root,
+         * make it a null terminated string in the AML
+         */
+        if (Op->Asl.AmlLength == 1)
+        {
+            Op->Asl.AmlLength = 2;
+        }
+        break;
+
+    case PARSEOP_STRING_LITERAL:
+
+        Op->Asl.AmlOpcodeLength = 1;
+
+        /* Get null terminator */
+
+        Op->Asl.AmlLength = strlen (Op->Asl.Value.String) + 1;
+        break;
+
+    case PARSEOP_PACKAGE_LENGTH:
+
+        Op->Asl.AmlOpcodeLength = 0;
+        Op->Asl.AmlPkgLenBytes = CgGetPackageLenByteCount (Op,
+                                    (UINT32) Op->Asl.Value.Integer);
+        break;
+
+    case PARSEOP_RAW_DATA:
+
+        Op->Asl.AmlOpcodeLength = 0;
+        break;
+
+    case PARSEOP_DEFAULT_ARG:
+    case PARSEOP_EXTERNAL:
+    case PARSEOP_INCLUDE:
+    case PARSEOP_INCLUDE_END:
+
+        /* Ignore the "default arg" nodes, they are extraneous at this point */
+
+        break;
+
+    default:
+
+        CgGenerateAmlOpcodeLength (Op);
+        break;
+    }
+}
+
+
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+/*******************************************************************************
+ *
+ * FUNCTION:    LnAdjustLengthToRoot
+ *
+ * PARAMETERS:  Op      - Node whose Length was changed
+ *
+ * RETURN:      None.
+ *
+ * DESCRIPTION: Change the Subtree length of the given node, and bubble the
+ *              change all the way up to the root node. This allows for
+ *              last second changes to a package length (for example, if the
+ *              package length encoding gets shorter or longer.)
+ *
+ ******************************************************************************/
+
+void
+LnAdjustLengthToRoot (
+    ACPI_PARSE_OBJECT       *SubtreeOp,
+    UINT32                  LengthDelta)
+{
+    ACPI_PARSE_OBJECT       *Op;
+
+
+    /* Adjust all subtree lengths up to the root */
+
+    Op = SubtreeOp->Asl.Parent;
+    while (Op)
+    {
+        Op->Asl.AmlSubtreeLength -= LengthDelta;
+        Op = Op->Asl.Parent;
+    }
+
+    /* Adjust the global table length */
+
+    Gbl_TableLength -= LengthDelta;
+}
+#endif
