xref: /dflybsd-src/sys/contrib/dev/acpica/source/compiler/asltransform.c (revision 01d5d5df55caa9c47886aef5197b8c4301cc621b)
10d02842fSSascha Wildner /******************************************************************************
20d02842fSSascha Wildner  *
30d02842fSSascha Wildner  * Module Name: asltransform - Parse tree transforms
40d02842fSSascha Wildner  *
50d02842fSSascha Wildner  *****************************************************************************/
60d02842fSSascha Wildner 
7b4315fc7SSascha Wildner /******************************************************************************
8b4315fc7SSascha Wildner  *
9b4315fc7SSascha Wildner  * 1. Copyright Notice
10b4315fc7SSascha Wildner  *
11383048acSSascha Wildner  * Some or all of this work - Copyright (c) 1999 - 2021, Intel Corp.
120d02842fSSascha Wildner  * All rights reserved.
130d02842fSSascha Wildner  *
14b4315fc7SSascha Wildner  * 2. License
15b4315fc7SSascha Wildner  *
16b4315fc7SSascha Wildner  * 2.1. This is your license from Intel Corp. under its intellectual property
17b4315fc7SSascha Wildner  * rights. You may have additional license terms from the party that provided
18b4315fc7SSascha Wildner  * you this software, covering your right to use that party's intellectual
19b4315fc7SSascha Wildner  * property rights.
20b4315fc7SSascha Wildner  *
21b4315fc7SSascha Wildner  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22b4315fc7SSascha Wildner  * copy of the source code appearing in this file ("Covered Code") an
23b4315fc7SSascha Wildner  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24b4315fc7SSascha Wildner  * base code distributed originally by Intel ("Original Intel Code") to copy,
25b4315fc7SSascha Wildner  * make derivatives, distribute, use and display any portion of the Covered
26b4315fc7SSascha Wildner  * Code in any form, with the right to sublicense such rights; and
27b4315fc7SSascha Wildner  *
28b4315fc7SSascha Wildner  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29b4315fc7SSascha Wildner  * license (with the right to sublicense), under only those claims of Intel
30b4315fc7SSascha Wildner  * patents that are infringed by the Original Intel Code, to make, use, sell,
31b4315fc7SSascha Wildner  * offer to sell, and import the Covered Code and derivative works thereof
32b4315fc7SSascha Wildner  * solely to the minimum extent necessary to exercise the above copyright
33b4315fc7SSascha Wildner  * license, and in no event shall the patent license extend to any additions
34b4315fc7SSascha Wildner  * to or modifications of the Original Intel Code. No other license or right
35b4315fc7SSascha Wildner  * is granted directly or by implication, estoppel or otherwise;
36b4315fc7SSascha Wildner  *
37b4315fc7SSascha Wildner  * The above copyright and patent license is granted only if the following
38b4315fc7SSascha Wildner  * conditions are met:
39b4315fc7SSascha Wildner  *
40b4315fc7SSascha Wildner  * 3. Conditions
41b4315fc7SSascha Wildner  *
42b4315fc7SSascha Wildner  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43b4315fc7SSascha Wildner  * Redistribution of source code of any substantial portion of the Covered
44b4315fc7SSascha Wildner  * Code or modification with rights to further distribute source must include
45b4315fc7SSascha Wildner  * the above Copyright Notice, the above License, this list of Conditions,
46b4315fc7SSascha Wildner  * and the following Disclaimer and Export Compliance provision. In addition,
47b4315fc7SSascha Wildner  * Licensee must cause all Covered Code to which Licensee contributes to
48b4315fc7SSascha Wildner  * contain a file documenting the changes Licensee made to create that Covered
49b4315fc7SSascha Wildner  * Code and the date of any change. Licensee must include in that file the
50b4315fc7SSascha Wildner  * documentation of any changes made by any predecessor Licensee. Licensee
51b4315fc7SSascha Wildner  * must include a prominent statement that the modification is derived,
52b4315fc7SSascha Wildner  * directly or indirectly, from Original Intel Code.
53b4315fc7SSascha Wildner  *
54b4315fc7SSascha Wildner  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55b4315fc7SSascha Wildner  * Redistribution of source code of any substantial portion of the Covered
56b4315fc7SSascha Wildner  * Code or modification without rights to further distribute source must
57b4315fc7SSascha Wildner  * include the following Disclaimer and Export Compliance provision in the
58b4315fc7SSascha Wildner  * documentation and/or other materials provided with distribution. In
59b4315fc7SSascha Wildner  * addition, Licensee may not authorize further sublicense of source of any
60b4315fc7SSascha Wildner  * portion of the Covered Code, and must include terms to the effect that the
61b4315fc7SSascha Wildner  * license from Licensee to its licensee is limited to the intellectual
62b4315fc7SSascha Wildner  * property embodied in the software Licensee provides to its licensee, and
63b4315fc7SSascha Wildner  * not to intellectual property embodied in modifications its licensee may
64b4315fc7SSascha Wildner  * make.
65b4315fc7SSascha Wildner  *
66b4315fc7SSascha Wildner  * 3.3. Redistribution of Executable. Redistribution in executable form of any
67b4315fc7SSascha Wildner  * substantial portion of the Covered Code or modification must reproduce the
68b4315fc7SSascha Wildner  * above Copyright Notice, and the following Disclaimer and Export Compliance
69b4315fc7SSascha Wildner  * provision in the documentation and/or other materials provided with the
70b4315fc7SSascha Wildner  * distribution.
71b4315fc7SSascha Wildner  *
72b4315fc7SSascha Wildner  * 3.4. Intel retains all right, title, and interest in and to the Original
73b4315fc7SSascha Wildner  * Intel Code.
74b4315fc7SSascha Wildner  *
75b4315fc7SSascha Wildner  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76b4315fc7SSascha Wildner  * Intel shall be used in advertising or otherwise to promote the sale, use or
77b4315fc7SSascha Wildner  * other dealings in products derived from or relating to the Covered Code
78b4315fc7SSascha Wildner  * without prior written authorization from Intel.
79b4315fc7SSascha Wildner  *
80b4315fc7SSascha Wildner  * 4. Disclaimer and Export Compliance
81b4315fc7SSascha Wildner  *
82b4315fc7SSascha Wildner  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83b4315fc7SSascha Wildner  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84b4315fc7SSascha Wildner  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85b4315fc7SSascha Wildner  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86b4315fc7SSascha Wildner  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87b4315fc7SSascha Wildner  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88b4315fc7SSascha Wildner  * PARTICULAR PURPOSE.
89b4315fc7SSascha Wildner  *
90b4315fc7SSascha Wildner  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91b4315fc7SSascha Wildner  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92b4315fc7SSascha Wildner  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93b4315fc7SSascha Wildner  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94b4315fc7SSascha Wildner  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95b4315fc7SSascha Wildner  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96b4315fc7SSascha Wildner  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97b4315fc7SSascha Wildner  * LIMITED REMEDY.
98b4315fc7SSascha Wildner  *
99b4315fc7SSascha Wildner  * 4.3. Licensee shall not export, either directly or indirectly, any of this
100b4315fc7SSascha Wildner  * software or system incorporating such software without first obtaining any
101b4315fc7SSascha Wildner  * required license or other approval from the U. S. Department of Commerce or
102b4315fc7SSascha Wildner  * any other agency or department of the United States Government. In the
103b4315fc7SSascha Wildner  * event Licensee exports any such software from the United States or
104b4315fc7SSascha Wildner  * re-exports any such software from a foreign destination, Licensee shall
105b4315fc7SSascha Wildner  * ensure that the distribution and export/re-export of the software is in
106b4315fc7SSascha Wildner  * compliance with all laws, regulations, orders, or other restrictions of the
107b4315fc7SSascha Wildner  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108b4315fc7SSascha Wildner  * any of its subsidiaries will export/re-export any technical data, process,
109b4315fc7SSascha Wildner  * software, or service, directly or indirectly, to any country for which the
110b4315fc7SSascha Wildner  * United States government or any agency thereof requires an export license,
111b4315fc7SSascha Wildner  * other governmental approval, or letter of assurance, without first obtaining
112b4315fc7SSascha Wildner  * such license, approval or letter.
113b4315fc7SSascha Wildner  *
114b4315fc7SSascha Wildner  *****************************************************************************
115b4315fc7SSascha Wildner  *
116b4315fc7SSascha Wildner  * Alternatively, you may choose to be licensed under the terms of the
117b4315fc7SSascha Wildner  * following license:
118b4315fc7SSascha Wildner  *
1190d02842fSSascha Wildner  * Redistribution and use in source and binary forms, with or without
1200d02842fSSascha Wildner  * modification, are permitted provided that the following conditions
1210d02842fSSascha Wildner  * are met:
1220d02842fSSascha Wildner  * 1. Redistributions of source code must retain the above copyright
1230d02842fSSascha Wildner  *    notice, this list of conditions, and the following disclaimer,
1240d02842fSSascha Wildner  *    without modification.
1250d02842fSSascha Wildner  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
1260d02842fSSascha Wildner  *    substantially similar to the "NO WARRANTY" disclaimer below
1270d02842fSSascha Wildner  *    ("Disclaimer") and any redistribution must be conditioned upon
1280d02842fSSascha Wildner  *    including a substantially similar Disclaimer requirement for further
1290d02842fSSascha Wildner  *    binary redistribution.
1300d02842fSSascha Wildner  * 3. Neither the names of the above-listed copyright holders nor the names
1310d02842fSSascha Wildner  *    of any contributors may be used to endorse or promote products derived
1320d02842fSSascha Wildner  *    from this software without specific prior written permission.
1330d02842fSSascha Wildner  *
134b4315fc7SSascha Wildner  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135b4315fc7SSascha Wildner  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136b4315fc7SSascha Wildner  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137b4315fc7SSascha Wildner  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138b4315fc7SSascha Wildner  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139b4315fc7SSascha Wildner  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140b4315fc7SSascha Wildner  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141b4315fc7SSascha Wildner  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142b4315fc7SSascha Wildner  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143b4315fc7SSascha Wildner  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144b4315fc7SSascha Wildner  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145b4315fc7SSascha Wildner  *
146b4315fc7SSascha Wildner  * Alternatively, you may choose to be licensed under the terms of the
1470d02842fSSascha Wildner  * GNU General Public License ("GPL") version 2 as published by the Free
1480d02842fSSascha Wildner  * Software Foundation.
1490d02842fSSascha Wildner  *
150b4315fc7SSascha Wildner  *****************************************************************************/
1510d02842fSSascha Wildner 
1520d02842fSSascha Wildner #include "aslcompiler.h"
1530d02842fSSascha Wildner #include "aslcompiler.y.h"
154e5412f1eSSascha Wildner #include "acnamesp.h"
1550d02842fSSascha Wildner 
1560d02842fSSascha Wildner #define _COMPONENT          ACPI_COMPILER
1570d02842fSSascha Wildner         ACPI_MODULE_NAME    ("asltransform")
1580d02842fSSascha Wildner 
1590d02842fSSascha Wildner /* Local prototypes */
1600d02842fSSascha Wildner 
1610d02842fSSascha Wildner static void
1620d02842fSSascha Wildner TrTransformSubtree (
1630d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *Op);
1640d02842fSSascha Wildner 
1650d02842fSSascha Wildner static char *
1660d02842fSSascha Wildner TrAmlGetNextTempName (
1670d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *Op,
1680d02842fSSascha Wildner     UINT8                   *TempCount);
1690d02842fSSascha Wildner 
1700d02842fSSascha Wildner static void
1710d02842fSSascha Wildner TrAmlInitLineNumbers (
1720d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *Op,
1730d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *Neighbor);
1740d02842fSSascha Wildner 
1750d02842fSSascha Wildner static void
1760d02842fSSascha Wildner TrAmlInitNode (
1770d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *Op,
1780d02842fSSascha Wildner     UINT16                  ParseOpcode);
1790d02842fSSascha Wildner 
1800d02842fSSascha Wildner static void
1810d02842fSSascha Wildner TrAmlSetSubtreeParent (
1820d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *Op,
1830d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *Parent);
1840d02842fSSascha Wildner 
1850d02842fSSascha Wildner static void
1860d02842fSSascha Wildner TrAmlInsertPeer (
1870d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *Op,
1880d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *NewPeer);
1890d02842fSSascha Wildner 
1900d02842fSSascha Wildner static void
1910d02842fSSascha Wildner TrDoDefinitionBlock (
1920d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *Op);
1930d02842fSSascha Wildner 
1940d02842fSSascha Wildner static void
1950d02842fSSascha Wildner TrDoSwitch (
1960d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *StartNode);
1970d02842fSSascha Wildner 
198e5412f1eSSascha Wildner static void
199e5412f1eSSascha Wildner TrCheckForDuplicateCase (
200e5412f1eSSascha Wildner     ACPI_PARSE_OBJECT       *CaseOp,
201e5412f1eSSascha Wildner     ACPI_PARSE_OBJECT       *Predicate1);
202e5412f1eSSascha Wildner 
203e5412f1eSSascha Wildner static BOOLEAN
204e5412f1eSSascha Wildner TrCheckForBufferMatch (
205e5412f1eSSascha Wildner     ACPI_PARSE_OBJECT       *Next1,
206e5412f1eSSascha Wildner     ACPI_PARSE_OBJECT       *Next2);
207e5412f1eSSascha Wildner 
208ff3cb46dSSascha Wildner static void
209ff3cb46dSSascha Wildner TrDoMethod (
210ff3cb46dSSascha Wildner     ACPI_PARSE_OBJECT       *Op);
211ff3cb46dSSascha Wildner 
2120d02842fSSascha Wildner 
2130d02842fSSascha Wildner /*******************************************************************************
2140d02842fSSascha Wildner  *
2150d02842fSSascha Wildner  * FUNCTION:    TrAmlGetNextTempName
2160d02842fSSascha Wildner  *
2170d02842fSSascha Wildner  * PARAMETERS:  Op              - Current parse op
2180d02842fSSascha Wildner  *              TempCount       - Current temporary counter. Was originally
2190d02842fSSascha Wildner  *                                per-module; Currently per method, could be
2200d02842fSSascha Wildner  *                                expanded to per-scope.
2210d02842fSSascha Wildner  *
2220d02842fSSascha Wildner  * RETURN:      A pointer to name (allocated here).
2230d02842fSSascha Wildner  *
2240d02842fSSascha Wildner  * DESCRIPTION: Generate an ACPI name of the form _T_x. These names are
2250d02842fSSascha Wildner  *              reserved for use by the ASL compiler. (_T_0 through _T_Z)
2260d02842fSSascha Wildner  *
2270d02842fSSascha Wildner  ******************************************************************************/
2280d02842fSSascha Wildner 
2290d02842fSSascha Wildner static char *
TrAmlGetNextTempName(ACPI_PARSE_OBJECT * Op,UINT8 * TempCount)2300d02842fSSascha Wildner TrAmlGetNextTempName (
2310d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *Op,
2320d02842fSSascha Wildner     UINT8                   *TempCount)
2330d02842fSSascha Wildner {
2340d02842fSSascha Wildner     char                    *TempName;
2350d02842fSSascha Wildner 
2360d02842fSSascha Wildner 
2370d02842fSSascha Wildner     if (*TempCount >= (10 + 26))  /* 0-35 valid: 0-9 and A-Z for TempName[3] */
2380d02842fSSascha Wildner     {
2390d02842fSSascha Wildner         /* Too many temps */
2400d02842fSSascha Wildner 
2410d02842fSSascha Wildner         AslError (ASL_ERROR, ASL_MSG_TOO_MANY_TEMPS, Op, NULL);
2420d02842fSSascha Wildner         return (NULL);
2430d02842fSSascha Wildner     }
2440d02842fSSascha Wildner 
2450d02842fSSascha Wildner     TempName = UtLocalCalloc (5);
2460d02842fSSascha Wildner 
2470d02842fSSascha Wildner     if (*TempCount < 10)    /* 0-9 */
2480d02842fSSascha Wildner     {
2490d02842fSSascha Wildner         TempName[3] = (char) (*TempCount + '0');
2500d02842fSSascha Wildner     }
2510d02842fSSascha Wildner     else                    /* 10-35: A-Z */
2520d02842fSSascha Wildner     {
2530d02842fSSascha Wildner         TempName[3] = (char) (*TempCount + ('A' - 10));
2540d02842fSSascha Wildner     }
255820c5b08SSascha Wildner 
2560d02842fSSascha Wildner     (*TempCount)++;
2570d02842fSSascha Wildner 
2580d02842fSSascha Wildner     /* First three characters are always "_T_" */
2590d02842fSSascha Wildner 
2600d02842fSSascha Wildner     TempName[0] = '_';
2610d02842fSSascha Wildner     TempName[1] = 'T';
2620d02842fSSascha Wildner     TempName[2] = '_';
2630d02842fSSascha Wildner 
2640d02842fSSascha Wildner     return (TempName);
2650d02842fSSascha Wildner }
2660d02842fSSascha Wildner 
2670d02842fSSascha Wildner 
2680d02842fSSascha Wildner /*******************************************************************************
2690d02842fSSascha Wildner  *
2700d02842fSSascha Wildner  * FUNCTION:    TrAmlInitLineNumbers
2710d02842fSSascha Wildner  *
2720d02842fSSascha Wildner  * PARAMETERS:  Op              - Op to be initialized
2730d02842fSSascha Wildner  *              Neighbor        - Op used for initialization values
2740d02842fSSascha Wildner  *
2750d02842fSSascha Wildner  * RETURN:      None
2760d02842fSSascha Wildner  *
2770d02842fSSascha Wildner  * DESCRIPTION: Initialized the various line numbers for a parse node.
2780d02842fSSascha Wildner  *
2790d02842fSSascha Wildner  ******************************************************************************/
2800d02842fSSascha Wildner 
2810d02842fSSascha Wildner static void
TrAmlInitLineNumbers(ACPI_PARSE_OBJECT * Op,ACPI_PARSE_OBJECT * Neighbor)2820d02842fSSascha Wildner TrAmlInitLineNumbers (
2830d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *Op,
2840d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *Neighbor)
2850d02842fSSascha Wildner {
2860d02842fSSascha Wildner 
2870d02842fSSascha Wildner     Op->Asl.EndLine           = Neighbor->Asl.EndLine;
2880d02842fSSascha Wildner     Op->Asl.EndLogicalLine    = Neighbor->Asl.EndLogicalLine;
2890d02842fSSascha Wildner     Op->Asl.LineNumber        = Neighbor->Asl.LineNumber;
2900d02842fSSascha Wildner     Op->Asl.LogicalByteOffset = Neighbor->Asl.LogicalByteOffset;
2910d02842fSSascha Wildner     Op->Asl.LogicalLineNumber = Neighbor->Asl.LogicalLineNumber;
2920d02842fSSascha Wildner }
2930d02842fSSascha Wildner 
2940d02842fSSascha Wildner 
2950d02842fSSascha Wildner /*******************************************************************************
2960d02842fSSascha Wildner  *
2970d02842fSSascha Wildner  * FUNCTION:    TrAmlInitNode
2980d02842fSSascha Wildner  *
2990d02842fSSascha Wildner  * PARAMETERS:  Op              - Op to be initialized
3000d02842fSSascha Wildner  *              ParseOpcode     - Opcode for this node
3010d02842fSSascha Wildner  *
3020d02842fSSascha Wildner  * RETURN:      None
3030d02842fSSascha Wildner  *
3040d02842fSSascha Wildner  * DESCRIPTION: Initialize a node with the parse opcode and opcode name.
3050d02842fSSascha Wildner  *
3060d02842fSSascha Wildner  ******************************************************************************/
3070d02842fSSascha Wildner 
3080d02842fSSascha Wildner static void
TrAmlInitNode(ACPI_PARSE_OBJECT * Op,UINT16 ParseOpcode)3090d02842fSSascha Wildner TrAmlInitNode (
3100d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *Op,
3110d02842fSSascha Wildner     UINT16                  ParseOpcode)
3120d02842fSSascha Wildner {
3130d02842fSSascha Wildner 
3140d02842fSSascha Wildner     Op->Asl.ParseOpcode = ParseOpcode;
3150d02842fSSascha Wildner     UtSetParseOpName (Op);
3160d02842fSSascha Wildner }
3170d02842fSSascha Wildner 
3180d02842fSSascha Wildner 
3190d02842fSSascha Wildner /*******************************************************************************
3200d02842fSSascha Wildner  *
3210d02842fSSascha Wildner  * FUNCTION:    TrAmlSetSubtreeParent
3220d02842fSSascha Wildner  *
3230d02842fSSascha Wildner  * PARAMETERS:  Op              - First node in a list of peer nodes
3240d02842fSSascha Wildner  *              Parent          - Parent of the subtree
3250d02842fSSascha Wildner  *
3260d02842fSSascha Wildner  * RETURN:      None
3270d02842fSSascha Wildner  *
3280d02842fSSascha Wildner  * DESCRIPTION: Set the parent for all peer nodes in a subtree
3290d02842fSSascha Wildner  *
3300d02842fSSascha Wildner  ******************************************************************************/
3310d02842fSSascha Wildner 
3320d02842fSSascha Wildner static void
TrAmlSetSubtreeParent(ACPI_PARSE_OBJECT * Op,ACPI_PARSE_OBJECT * Parent)3330d02842fSSascha Wildner TrAmlSetSubtreeParent (
3340d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *Op,
3350d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *Parent)
3360d02842fSSascha Wildner {
3370d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *Next;
3380d02842fSSascha Wildner 
3390d02842fSSascha Wildner 
3400d02842fSSascha Wildner     Next = Op;
3410d02842fSSascha Wildner     while (Next)
3420d02842fSSascha Wildner     {
3430d02842fSSascha Wildner         Next->Asl.Parent = Parent;
3440d02842fSSascha Wildner         Next = Next->Asl.Next;
3450d02842fSSascha Wildner     }
3460d02842fSSascha Wildner }
3470d02842fSSascha Wildner 
3480d02842fSSascha Wildner 
3490d02842fSSascha Wildner /*******************************************************************************
3500d02842fSSascha Wildner  *
3510d02842fSSascha Wildner  * FUNCTION:    TrAmlInsertPeer
3520d02842fSSascha Wildner  *
3530d02842fSSascha Wildner  * PARAMETERS:  Op              - First node in a list of peer nodes
3540d02842fSSascha Wildner  *              NewPeer         - Peer node to insert
3550d02842fSSascha Wildner  *
3560d02842fSSascha Wildner  * RETURN:      None
3570d02842fSSascha Wildner  *
3580d02842fSSascha Wildner  * DESCRIPTION: Insert a new peer node into a list of peers.
3590d02842fSSascha Wildner  *
3600d02842fSSascha Wildner  ******************************************************************************/
3610d02842fSSascha Wildner 
3620d02842fSSascha Wildner static void
TrAmlInsertPeer(ACPI_PARSE_OBJECT * Op,ACPI_PARSE_OBJECT * NewPeer)3630d02842fSSascha Wildner TrAmlInsertPeer (
3640d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *Op,
3650d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *NewPeer)
3660d02842fSSascha Wildner {
3670d02842fSSascha Wildner 
3680d02842fSSascha Wildner     NewPeer->Asl.Next = Op->Asl.Next;
3690d02842fSSascha Wildner     Op->Asl.Next = NewPeer;
3700d02842fSSascha Wildner }
3710d02842fSSascha Wildner 
3720d02842fSSascha Wildner 
3730d02842fSSascha Wildner /*******************************************************************************
3740d02842fSSascha Wildner  *
3757c9678bcSSascha Wildner  * FUNCTION:    TrAmlTransformWalkBegin
3760d02842fSSascha Wildner  *
3770d02842fSSascha Wildner  * PARAMETERS:  ASL_WALK_CALLBACK
3780d02842fSSascha Wildner  *
3790d02842fSSascha Wildner  * RETURN:      None
3800d02842fSSascha Wildner  *
3810d02842fSSascha Wildner  * DESCRIPTION: Parse tree walk to generate both the AML opcodes and the AML
3820d02842fSSascha Wildner  *              operands.
3830d02842fSSascha Wildner  *
3840d02842fSSascha Wildner  ******************************************************************************/
3850d02842fSSascha Wildner 
3860d02842fSSascha Wildner ACPI_STATUS
TrAmlTransformWalkBegin(ACPI_PARSE_OBJECT * Op,UINT32 Level,void * Context)3877c9678bcSSascha Wildner TrAmlTransformWalkBegin (
3880d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *Op,
3890d02842fSSascha Wildner     UINT32                  Level,
3900d02842fSSascha Wildner     void                    *Context)
3910d02842fSSascha Wildner {
3920d02842fSSascha Wildner 
3930d02842fSSascha Wildner     TrTransformSubtree (Op);
3940d02842fSSascha Wildner     return (AE_OK);
3950d02842fSSascha Wildner }
3960d02842fSSascha Wildner 
3970d02842fSSascha Wildner 
3980d02842fSSascha Wildner /*******************************************************************************
3990d02842fSSascha Wildner  *
4007c9678bcSSascha Wildner  * FUNCTION:    TrAmlTransformWalkEnd
4017c9678bcSSascha Wildner  *
4027c9678bcSSascha Wildner  * PARAMETERS:  ASL_WALK_CALLBACK
4037c9678bcSSascha Wildner  *
4047c9678bcSSascha Wildner  * RETURN:      None
4057c9678bcSSascha Wildner  *
4067c9678bcSSascha Wildner  * DESCRIPTION: Parse tree walk to generate both the AML opcodes and the AML
4077c9678bcSSascha Wildner  *              operands.
4087c9678bcSSascha Wildner  *
4097c9678bcSSascha Wildner  ******************************************************************************/
4107c9678bcSSascha Wildner 
4117c9678bcSSascha Wildner ACPI_STATUS
TrAmlTransformWalkEnd(ACPI_PARSE_OBJECT * Op,UINT32 Level,void * Context)4127c9678bcSSascha Wildner TrAmlTransformWalkEnd (
4137c9678bcSSascha Wildner     ACPI_PARSE_OBJECT       *Op,
4147c9678bcSSascha Wildner     UINT32                  Level,
4157c9678bcSSascha Wildner     void                    *Context)
4167c9678bcSSascha Wildner {
4177c9678bcSSascha Wildner 
4187c9678bcSSascha Wildner     /* Save possible Externals list in the DefintionBlock Op */
4197c9678bcSSascha Wildner 
4207c9678bcSSascha Wildner     if (Op->Asl.ParseOpcode == PARSEOP_DEFINITION_BLOCK)
4217c9678bcSSascha Wildner     {
422806343b9SSascha Wildner         Op->Asl.Value.Arg = AslGbl_ExternalsListHead;
423806343b9SSascha Wildner         AslGbl_ExternalsListHead = NULL;
4247c9678bcSSascha Wildner     }
4257c9678bcSSascha Wildner 
4267c9678bcSSascha Wildner     return (AE_OK);
4277c9678bcSSascha Wildner }
4287c9678bcSSascha Wildner 
4297c9678bcSSascha Wildner 
4307c9678bcSSascha Wildner /*******************************************************************************
4317c9678bcSSascha Wildner  *
4320d02842fSSascha Wildner  * FUNCTION:    TrTransformSubtree
4330d02842fSSascha Wildner  *
4340d02842fSSascha Wildner  * PARAMETERS:  Op        - The parent parse node
4350d02842fSSascha Wildner  *
4360d02842fSSascha Wildner  * RETURN:      None
4370d02842fSSascha Wildner  *
4380d02842fSSascha Wildner  * DESCRIPTION: Prepare nodes to be output as AML data and operands. The more
4390d02842fSSascha Wildner  *              complex AML opcodes require processing of the child nodes
4400d02842fSSascha Wildner  *              (arguments/operands).
4410d02842fSSascha Wildner  *
4420d02842fSSascha Wildner  ******************************************************************************/
4430d02842fSSascha Wildner 
4440d02842fSSascha Wildner static void
TrTransformSubtree(ACPI_PARSE_OBJECT * Op)4450d02842fSSascha Wildner TrTransformSubtree (
4460d02842fSSascha Wildner     ACPI_PARSE_OBJECT           *Op)
4470d02842fSSascha Wildner {
4483c639e0cSSascha Wildner     ACPI_PARSE_OBJECT           *MethodOp;
449e5412f1eSSascha Wildner     ACPI_NAMESTRING_INFO        Info;
4503c639e0cSSascha Wildner 
4510d02842fSSascha Wildner 
4520d02842fSSascha Wildner     if (Op->Asl.AmlOpcode == AML_RAW_DATA_BYTE)
4530d02842fSSascha Wildner     {
4540d02842fSSascha Wildner         return;
4550d02842fSSascha Wildner     }
4560d02842fSSascha Wildner 
4570d02842fSSascha Wildner     switch (Op->Asl.ParseOpcode)
4580d02842fSSascha Wildner     {
459820c5b08SSascha Wildner     case PARSEOP_DEFINITION_BLOCK:
4600d02842fSSascha Wildner 
4610d02842fSSascha Wildner         TrDoDefinitionBlock (Op);
4620d02842fSSascha Wildner         break;
4630d02842fSSascha Wildner 
4640d02842fSSascha Wildner     case PARSEOP_SWITCH:
4650d02842fSSascha Wildner 
4660d02842fSSascha Wildner         TrDoSwitch (Op);
4670d02842fSSascha Wildner         break;
4680d02842fSSascha Wildner 
4690d02842fSSascha Wildner     case PARSEOP_METHOD:
470ff3cb46dSSascha Wildner 
471ff3cb46dSSascha Wildner         TrDoMethod (Op);
4720d02842fSSascha Wildner         break;
4730d02842fSSascha Wildner 
4747c9678bcSSascha Wildner     case PARSEOP_EXTERNAL:
4757c9678bcSSascha Wildner 
4767c9678bcSSascha Wildner         ExDoExternal (Op);
4777c9678bcSSascha Wildner         break;
4787c9678bcSSascha Wildner 
4793c639e0cSSascha Wildner     case PARSEOP___METHOD__:
4803c639e0cSSascha Wildner 
4813c639e0cSSascha Wildner         /* Transform to a string op containing the parent method name */
4823c639e0cSSascha Wildner 
4833c639e0cSSascha Wildner         Op->Asl.ParseOpcode = PARSEOP_STRING_LITERAL;
4843c639e0cSSascha Wildner         UtSetParseOpName (Op);
4853c639e0cSSascha Wildner 
4863c639e0cSSascha Wildner         /* Find the parent control method op */
4873c639e0cSSascha Wildner 
4883c639e0cSSascha Wildner         MethodOp = Op;
4893c639e0cSSascha Wildner         while (MethodOp)
4903c639e0cSSascha Wildner         {
4913c639e0cSSascha Wildner             if (MethodOp->Asl.ParseOpcode == PARSEOP_METHOD)
4923c639e0cSSascha Wildner             {
4933c639e0cSSascha Wildner                 /* First child contains the method name */
4943c639e0cSSascha Wildner 
4953c639e0cSSascha Wildner                 MethodOp = MethodOp->Asl.Child;
4963c639e0cSSascha Wildner                 Op->Asl.Value.String = MethodOp->Asl.Value.String;
4973c639e0cSSascha Wildner                 return;
4983c639e0cSSascha Wildner             }
4993c639e0cSSascha Wildner 
5003c639e0cSSascha Wildner             MethodOp = MethodOp->Asl.Parent;
5013c639e0cSSascha Wildner         }
5023c639e0cSSascha Wildner 
5033c639e0cSSascha Wildner         /* At the root, invocation not within a control method */
5043c639e0cSSascha Wildner 
5053c639e0cSSascha Wildner         Op->Asl.Value.String = "\\";
5063c639e0cSSascha Wildner         break;
5073c639e0cSSascha Wildner 
508e5412f1eSSascha Wildner     case PARSEOP_NAMESTRING:
509e5412f1eSSascha Wildner         /*
510e5412f1eSSascha Wildner          * A NameString can be up to 255 (0xFF) individual NameSegs maximum
511e5412f1eSSascha Wildner          * (with 254 dot separators) - as per the ACPI specification. Note:
512e5412f1eSSascha Wildner          * Cannot check for NumSegments == 0 because things like
513e5412f1eSSascha Wildner          * Scope(\) are legal and OK.
514e5412f1eSSascha Wildner          */
515e5412f1eSSascha Wildner         Info.ExternalName = Op->Asl.Value.String;
516e5412f1eSSascha Wildner         AcpiNsGetInternalNameLength (&Info);
517e5412f1eSSascha Wildner 
518e5412f1eSSascha Wildner         if (Info.NumSegments > 255)
519e5412f1eSSascha Wildner         {
520e5412f1eSSascha Wildner             AslError (ASL_ERROR, ASL_MSG_NAMESTRING_LENGTH, Op, NULL);
521e5412f1eSSascha Wildner         }
522e5412f1eSSascha Wildner         break;
523e5412f1eSSascha Wildner 
5246e376582SSascha Wildner     case PARSEOP_UNLOAD:
5256e376582SSascha Wildner 
5266e376582SSascha Wildner         AslError (ASL_WARNING, ASL_MSG_UNLOAD, Op, NULL);
5276e376582SSascha Wildner         break;
5286e376582SSascha Wildner 
52986615ef7SSascha Wildner     case PARSEOP_SLEEP:
53086615ef7SSascha Wildner 
53186615ef7SSascha Wildner         /* Remark for very long sleep values */
53286615ef7SSascha Wildner 
53386615ef7SSascha Wildner         if (Op->Asl.Child->Asl.Value.Integer > 1000)
53486615ef7SSascha Wildner         {
53586615ef7SSascha Wildner             AslError (ASL_REMARK, ASL_MSG_LONG_SLEEP, Op, NULL);
53686615ef7SSascha Wildner         }
53786615ef7SSascha Wildner         break;
53886615ef7SSascha Wildner 
539e5412f1eSSascha Wildner     case PARSEOP_PROCESSOR:
540e5412f1eSSascha Wildner 
541e5412f1eSSascha Wildner         AslError (ASL_WARNING, ASL_MSG_LEGACY_PROCESSOR_OP, Op, Op->Asl.ExternalName);
542e5412f1eSSascha Wildner         break;
543e5412f1eSSascha Wildner 
544*01d5d5dfSSascha Wildner     case PARSEOP_OBJECTTYPE_DDB:
545*01d5d5dfSSascha Wildner 
546*01d5d5dfSSascha Wildner         AslError (ASL_WARNING, ASL_MSG_LEGACY_DDB_TYPE, Op, Op->Asl.ExternalName);
547*01d5d5dfSSascha Wildner         break;
548*01d5d5dfSSascha Wildner 
5490d02842fSSascha Wildner     default:
5500d02842fSSascha Wildner 
5510d02842fSSascha Wildner         /* Nothing to do here for other opcodes */
5520d02842fSSascha Wildner 
5530d02842fSSascha Wildner         break;
5540d02842fSSascha Wildner     }
5550d02842fSSascha Wildner }
5560d02842fSSascha Wildner 
5570d02842fSSascha Wildner 
5580d02842fSSascha Wildner /*******************************************************************************
5590d02842fSSascha Wildner  *
5600d02842fSSascha Wildner  * FUNCTION:    TrDoDefinitionBlock
5610d02842fSSascha Wildner  *
5620d02842fSSascha Wildner  * PARAMETERS:  Op        - Parse node
5630d02842fSSascha Wildner  *
5640d02842fSSascha Wildner  * RETURN:      None
5650d02842fSSascha Wildner  *
5660d02842fSSascha Wildner  * DESCRIPTION: Find the end of the definition block and set a global to this
5670d02842fSSascha Wildner  *              node. It is used by the compiler to insert compiler-generated
5680d02842fSSascha Wildner  *              names at the root level of the namespace.
5690d02842fSSascha Wildner  *
5700d02842fSSascha Wildner  ******************************************************************************/
5710d02842fSSascha Wildner 
5720d02842fSSascha Wildner static void
TrDoDefinitionBlock(ACPI_PARSE_OBJECT * Op)5730d02842fSSascha Wildner TrDoDefinitionBlock (
5740d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *Op)
5750d02842fSSascha Wildner {
5760d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *Next;
5770d02842fSSascha Wildner     UINT32                  i;
5780d02842fSSascha Wildner 
5790d02842fSSascha Wildner 
5807c9678bcSSascha Wildner     /* Reset external list when starting a definition block */
5817c9678bcSSascha Wildner 
582806343b9SSascha Wildner     AslGbl_ExternalsListHead = NULL;
5837c9678bcSSascha Wildner 
5840d02842fSSascha Wildner     Next = Op->Asl.Child;
5850d02842fSSascha Wildner     for (i = 0; i < 5; i++)
5860d02842fSSascha Wildner     {
5870d02842fSSascha Wildner         Next = Next->Asl.Next;
5880d02842fSSascha Wildner         if (i == 0)
5890d02842fSSascha Wildner         {
5900d02842fSSascha Wildner             /*
5910d02842fSSascha Wildner              * This is the table signature. Only the DSDT can be assumed
5920d02842fSSascha Wildner              * to be at the root of the namespace;  Therefore, namepath
5930d02842fSSascha Wildner              * optimization can only be performed on the DSDT.
5940d02842fSSascha Wildner              */
595c1776041SSascha Wildner             if (!ACPI_COMPARE_NAMESEG (Next->Asl.Value.String, ACPI_SIG_DSDT))
5960d02842fSSascha Wildner             {
597806343b9SSascha Wildner                 AslGbl_ReferenceOptimizationFlag = FALSE;
5980d02842fSSascha Wildner             }
5990d02842fSSascha Wildner         }
6000d02842fSSascha Wildner     }
6010d02842fSSascha Wildner 
602806343b9SSascha Wildner     AslGbl_FirstLevelInsertionNode = Next;
6030d02842fSSascha Wildner }
6040d02842fSSascha Wildner 
6050d02842fSSascha Wildner 
6060d02842fSSascha Wildner /*******************************************************************************
6070d02842fSSascha Wildner  *
6080d02842fSSascha Wildner  * FUNCTION:    TrDoSwitch
6090d02842fSSascha Wildner  *
6100d02842fSSascha Wildner  * PARAMETERS:  StartNode        - Parse node for SWITCH
6110d02842fSSascha Wildner  *
6120d02842fSSascha Wildner  * RETURN:      None
6130d02842fSSascha Wildner  *
6140d02842fSSascha Wildner  * DESCRIPTION: Translate ASL SWITCH statement to if/else pairs. There is
6150d02842fSSascha Wildner  *              no actual AML opcode for SWITCH -- it must be simulated.
6160d02842fSSascha Wildner  *
6170d02842fSSascha Wildner  ******************************************************************************/
6180d02842fSSascha Wildner 
6190d02842fSSascha Wildner static void
TrDoSwitch(ACPI_PARSE_OBJECT * StartNode)6200d02842fSSascha Wildner TrDoSwitch (
6210d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *StartNode)
6220d02842fSSascha Wildner {
6230d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *Next;
6240d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *CaseOp = NULL;
6250d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *CaseBlock = NULL;
6260d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *DefaultOp = NULL;
6270d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *CurrentParentNode;
6280d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *Conditional = NULL;
6290d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *Predicate;
6300d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *Peer;
6310d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *NewOp;
6320d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *NewOp2;
6330d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *MethodOp;
6340d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *StoreOp;
6350d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *BreakOp;
6360d02842fSSascha Wildner     ACPI_PARSE_OBJECT       *BufferOp;
6370d02842fSSascha Wildner     char                    *PredicateValueName;
6380d02842fSSascha Wildner     UINT16                  Index;
6390d02842fSSascha Wildner     UINT32                  Btype;
6400d02842fSSascha Wildner 
6410d02842fSSascha Wildner 
6420d02842fSSascha Wildner     /* Start node is the Switch() node */
6430d02842fSSascha Wildner 
6440d02842fSSascha Wildner     CurrentParentNode  = StartNode;
6450d02842fSSascha Wildner 
6460d02842fSSascha Wildner     /* Create a new temp name of the form _T_x */
6470d02842fSSascha Wildner 
648806343b9SSascha Wildner     PredicateValueName = TrAmlGetNextTempName (StartNode, &AslGbl_TempCount);
6490d02842fSSascha Wildner     if (!PredicateValueName)
6500d02842fSSascha Wildner     {
6510d02842fSSascha Wildner         return;
6520d02842fSSascha Wildner     }
6530d02842fSSascha Wildner 
6540d02842fSSascha Wildner     /* First child is the Switch() predicate */
6550d02842fSSascha Wildner 
6560d02842fSSascha Wildner     Next = StartNode->Asl.Child;
6570d02842fSSascha Wildner 
6580d02842fSSascha Wildner     /*
6590d02842fSSascha Wildner      * Examine the return type of the Switch Value -
6600d02842fSSascha Wildner      * must be Integer/Buffer/String
6610d02842fSSascha Wildner      */
6620d02842fSSascha Wildner     Index = (UINT16) (Next->Asl.ParseOpcode - ASL_PARSE_OPCODE_BASE);
6630d02842fSSascha Wildner     Btype = AslKeywordMapping[Index].AcpiBtype;
6640d02842fSSascha Wildner     if ((Btype != ACPI_BTYPE_INTEGER) &&
6650d02842fSSascha Wildner         (Btype != ACPI_BTYPE_STRING)  &&
6660d02842fSSascha Wildner         (Btype != ACPI_BTYPE_BUFFER))
6670d02842fSSascha Wildner     {
6680d02842fSSascha Wildner         AslError (ASL_WARNING, ASL_MSG_SWITCH_TYPE, Next, NULL);
6690d02842fSSascha Wildner         Btype = ACPI_BTYPE_INTEGER;
6700d02842fSSascha Wildner     }
6710d02842fSSascha Wildner 
6720d02842fSSascha Wildner     /* CASE statements start at next child */
6730d02842fSSascha Wildner 
6740d02842fSSascha Wildner     Peer = Next->Asl.Next;
6750d02842fSSascha Wildner     while (Peer)
6760d02842fSSascha Wildner     {
6770d02842fSSascha Wildner         Next = Peer;
6780d02842fSSascha Wildner         Peer = Next->Asl.Next;
6790d02842fSSascha Wildner 
6800d02842fSSascha Wildner         if (Next->Asl.ParseOpcode == PARSEOP_CASE)
6810d02842fSSascha Wildner         {
682e5412f1eSSascha Wildner             TrCheckForDuplicateCase (Next, Next->Asl.Child);
683e5412f1eSSascha Wildner 
6840d02842fSSascha Wildner             if (CaseOp)
6850d02842fSSascha Wildner             {
6860d02842fSSascha Wildner                 /* Add an ELSE to complete the previous CASE */
6870d02842fSSascha Wildner 
6881093ca81SSascha Wildner                 NewOp = TrCreateLeafOp (PARSEOP_ELSE);
6890d02842fSSascha Wildner                 NewOp->Asl.Parent = Conditional->Asl.Parent;
6900d02842fSSascha Wildner                 TrAmlInitLineNumbers (NewOp, NewOp->Asl.Parent);
6910d02842fSSascha Wildner 
6920d02842fSSascha Wildner                 /* Link ELSE node as a peer to the previous IF */
6930d02842fSSascha Wildner 
6940d02842fSSascha Wildner                 TrAmlInsertPeer (Conditional, NewOp);
6950d02842fSSascha Wildner                 CurrentParentNode = NewOp;
6960d02842fSSascha Wildner             }
6970d02842fSSascha Wildner 
6980d02842fSSascha Wildner             CaseOp = Next;
6990d02842fSSascha Wildner             Conditional = CaseOp;
7000d02842fSSascha Wildner             CaseBlock = CaseOp->Asl.Child->Asl.Next;
7010d02842fSSascha Wildner             Conditional->Asl.Child->Asl.Next = NULL;
7020d02842fSSascha Wildner             Predicate = CaseOp->Asl.Child;
7030d02842fSSascha Wildner 
7040d02842fSSascha Wildner             if ((Predicate->Asl.ParseOpcode == PARSEOP_PACKAGE) ||
7050d02842fSSascha Wildner                 (Predicate->Asl.ParseOpcode == PARSEOP_VAR_PACKAGE))
7060d02842fSSascha Wildner             {
7070d02842fSSascha Wildner                 /*
7080d02842fSSascha Wildner                  * Convert the package declaration to this form:
7090d02842fSSascha Wildner                  *
7100d02842fSSascha Wildner                  * If (LNotEqual (Match (Package(<size>){<data>},
7110d02842fSSascha Wildner                  *                       MEQ, _T_x, MTR, Zero, Zero), Ones))
7120d02842fSSascha Wildner                  */
7131093ca81SSascha Wildner                 NewOp2              = TrCreateLeafOp (PARSEOP_MATCHTYPE_MEQ);
7140d02842fSSascha Wildner                 Predicate->Asl.Next = NewOp2;
7150d02842fSSascha Wildner                 TrAmlInitLineNumbers (NewOp2, Conditional);
7160d02842fSSascha Wildner 
7170d02842fSSascha Wildner                 NewOp               = NewOp2;
7181093ca81SSascha Wildner                 NewOp2              = TrCreateValuedLeafOp (PARSEOP_NAMESTRING,
7190d02842fSSascha Wildner                                         (UINT64) ACPI_TO_INTEGER (PredicateValueName));
7200d02842fSSascha Wildner                 NewOp->Asl.Next     = NewOp2;
7210d02842fSSascha Wildner                 TrAmlInitLineNumbers (NewOp2, Predicate);
7220d02842fSSascha Wildner 
7230d02842fSSascha Wildner                 NewOp               = NewOp2;
7241093ca81SSascha Wildner                 NewOp2              = TrCreateLeafOp (PARSEOP_MATCHTYPE_MTR);
7250d02842fSSascha Wildner                 NewOp->Asl.Next     = NewOp2;
7260d02842fSSascha Wildner                 TrAmlInitLineNumbers (NewOp2, Predicate);
7270d02842fSSascha Wildner 
7280d02842fSSascha Wildner                 NewOp               = NewOp2;
7291093ca81SSascha Wildner                 NewOp2              = TrCreateLeafOp (PARSEOP_ZERO);
7300d02842fSSascha Wildner                 NewOp->Asl.Next     = NewOp2;
7310d02842fSSascha Wildner                 TrAmlInitLineNumbers (NewOp2, Predicate);
7320d02842fSSascha Wildner 
7330d02842fSSascha Wildner                 NewOp               = NewOp2;
7341093ca81SSascha Wildner                 NewOp2              = TrCreateLeafOp (PARSEOP_ZERO);
7350d02842fSSascha Wildner                 NewOp->Asl.Next     = NewOp2;
7360d02842fSSascha Wildner                 TrAmlInitLineNumbers (NewOp2, Predicate);
7370d02842fSSascha Wildner 
7381093ca81SSascha Wildner                 NewOp2              = TrCreateLeafOp (PARSEOP_MATCH);
7390d02842fSSascha Wildner                 NewOp2->Asl.Child   = Predicate;  /* PARSEOP_PACKAGE */
7400d02842fSSascha Wildner                 TrAmlInitLineNumbers (NewOp2, Conditional);
7410d02842fSSascha Wildner                 TrAmlSetSubtreeParent (Predicate, NewOp2);
7420d02842fSSascha Wildner 
7430d02842fSSascha Wildner                 NewOp               = NewOp2;
7441093ca81SSascha Wildner                 NewOp2              = TrCreateLeafOp (PARSEOP_ONES);
7450d02842fSSascha Wildner                 NewOp->Asl.Next     = NewOp2;
7460d02842fSSascha Wildner                 TrAmlInitLineNumbers (NewOp2, Conditional);
7470d02842fSSascha Wildner 
7481093ca81SSascha Wildner                 NewOp2              = TrCreateLeafOp (PARSEOP_LEQUAL);
7490d02842fSSascha Wildner                 NewOp2->Asl.Child   = NewOp;
7500d02842fSSascha Wildner                 NewOp->Asl.Parent   = NewOp2;
7510d02842fSSascha Wildner                 TrAmlInitLineNumbers (NewOp2, Conditional);
7520d02842fSSascha Wildner                 TrAmlSetSubtreeParent (NewOp, NewOp2);
7530d02842fSSascha Wildner 
7540d02842fSSascha Wildner                 NewOp               = NewOp2;
7551093ca81SSascha Wildner                 NewOp2              = TrCreateLeafOp (PARSEOP_LNOT);
7560d02842fSSascha Wildner                 NewOp2->Asl.Child   = NewOp;
7570d02842fSSascha Wildner                 NewOp2->Asl.Parent  = Conditional;
7580d02842fSSascha Wildner                 NewOp->Asl.Parent   = NewOp2;
7590d02842fSSascha Wildner                 TrAmlInitLineNumbers (NewOp2, Conditional);
7600d02842fSSascha Wildner 
7610d02842fSSascha Wildner                 Conditional->Asl.Child = NewOp2;
7620d02842fSSascha Wildner                 NewOp2->Asl.Next = CaseBlock;
7630d02842fSSascha Wildner             }
7640d02842fSSascha Wildner             else
7650d02842fSSascha Wildner             {
7660d02842fSSascha Wildner                 /*
7670d02842fSSascha Wildner                  * Integer and Buffer case.
7680d02842fSSascha Wildner                  *
7690d02842fSSascha Wildner                  * Change CaseOp() to:  If (LEqual (SwitchValue, CaseValue)) {...}
7700d02842fSSascha Wildner                  * Note: SwitchValue is first to allow the CaseValue to be implicitly
7710d02842fSSascha Wildner                  * converted to the type of SwitchValue if necessary.
7720d02842fSSascha Wildner                  *
7730d02842fSSascha Wildner                  * CaseOp->Child is the case value
7740d02842fSSascha Wildner                  * CaseOp->Child->Peer is the beginning of the case block
7750d02842fSSascha Wildner                  */
7761093ca81SSascha Wildner                 NewOp = TrCreateValuedLeafOp (PARSEOP_NAMESTRING,
7770d02842fSSascha Wildner                     (UINT64) ACPI_TO_INTEGER (PredicateValueName));
7780d02842fSSascha Wildner                 NewOp->Asl.Next = Predicate;
7790d02842fSSascha Wildner                 TrAmlInitLineNumbers (NewOp, Predicate);
7800d02842fSSascha Wildner 
7811093ca81SSascha Wildner                 NewOp2              = TrCreateLeafOp (PARSEOP_LEQUAL);
7820d02842fSSascha Wildner                 NewOp2->Asl.Parent  = Conditional;
7830d02842fSSascha Wildner                 NewOp2->Asl.Child   = NewOp;
7840d02842fSSascha Wildner                 TrAmlInitLineNumbers (NewOp2, Conditional);
7850d02842fSSascha Wildner 
7860d02842fSSascha Wildner                 TrAmlSetSubtreeParent (NewOp, NewOp2);
7870d02842fSSascha Wildner 
7880d02842fSSascha Wildner                 Predicate           = NewOp2;
7890d02842fSSascha Wildner                 Predicate->Asl.Next = CaseBlock;
7900d02842fSSascha Wildner 
7910d02842fSSascha Wildner                 TrAmlSetSubtreeParent (Predicate, Conditional);
7920d02842fSSascha Wildner                 Conditional->Asl.Child = Predicate;
7930d02842fSSascha Wildner             }
7940d02842fSSascha Wildner 
7950d02842fSSascha Wildner             /* Reinitialize the CASE node to an IF node */
7960d02842fSSascha Wildner 
7970d02842fSSascha Wildner             TrAmlInitNode (Conditional, PARSEOP_IF);
7980d02842fSSascha Wildner 
7990d02842fSSascha Wildner             /*
8000d02842fSSascha Wildner              * The first CASE(IF) is not nested under an ELSE.
8010d02842fSSascha Wildner              * All other CASEs are children of a parent ELSE.
8020d02842fSSascha Wildner              */
8030d02842fSSascha Wildner             if (CurrentParentNode == StartNode)
8040d02842fSSascha Wildner             {
8050d02842fSSascha Wildner                 Conditional->Asl.Next = NULL;
8060d02842fSSascha Wildner             }
8070d02842fSSascha Wildner             else
8080d02842fSSascha Wildner             {
8090d02842fSSascha Wildner                 /*
8100d02842fSSascha Wildner                  * The IF is a child of previous IF/ELSE. It
8110d02842fSSascha Wildner                  * is therefore without peer.
8120d02842fSSascha Wildner                  */
8130d02842fSSascha Wildner                 CurrentParentNode->Asl.Child = Conditional;
8140d02842fSSascha Wildner                 Conditional->Asl.Parent      = CurrentParentNode;
8150d02842fSSascha Wildner                 Conditional->Asl.Next        = NULL;
8160d02842fSSascha Wildner             }
8170d02842fSSascha Wildner         }
8180d02842fSSascha Wildner         else if (Next->Asl.ParseOpcode == PARSEOP_DEFAULT)
8190d02842fSSascha Wildner         {
8200d02842fSSascha Wildner             if (DefaultOp)
8210d02842fSSascha Wildner             {
8220d02842fSSascha Wildner                 /*
8230d02842fSSascha Wildner                  * More than one Default
8240d02842fSSascha Wildner                  * (Parser does not catch this, must check here)
8250d02842fSSascha Wildner                  */
8260d02842fSSascha Wildner                 AslError (ASL_ERROR, ASL_MSG_MULTIPLE_DEFAULT, Next, NULL);
8270d02842fSSascha Wildner             }
8280d02842fSSascha Wildner             else
8290d02842fSSascha Wildner             {
8300d02842fSSascha Wildner                 /* Save the DEFAULT node for later, after CASEs */
8310d02842fSSascha Wildner 
8320d02842fSSascha Wildner                 DefaultOp = Next;
8330d02842fSSascha Wildner             }
8340d02842fSSascha Wildner         }
8350d02842fSSascha Wildner         else
8360d02842fSSascha Wildner         {
8370d02842fSSascha Wildner             /* Unknown peer opcode */
8380d02842fSSascha Wildner 
8390d02842fSSascha Wildner             AcpiOsPrintf ("Unknown parse opcode for switch statement: %s (%u)\n",
8400d02842fSSascha Wildner                 Next->Asl.ParseOpName, Next->Asl.ParseOpcode);
8410d02842fSSascha Wildner         }
8420d02842fSSascha Wildner     }
8430d02842fSSascha Wildner 
8440d02842fSSascha Wildner     /* Add the default case at the end of the if/else construct */
8450d02842fSSascha Wildner 
8460d02842fSSascha Wildner     if (DefaultOp)
8470d02842fSSascha Wildner     {
8480d02842fSSascha Wildner         /* If no CASE statements, this is an error - see below */
8490d02842fSSascha Wildner 
8500d02842fSSascha Wildner         if (CaseOp)
8510d02842fSSascha Wildner         {
8520d02842fSSascha Wildner             /* Convert the DEFAULT node to an ELSE */
8530d02842fSSascha Wildner 
8540d02842fSSascha Wildner             TrAmlInitNode (DefaultOp, PARSEOP_ELSE);
8550d02842fSSascha Wildner             DefaultOp->Asl.Parent = Conditional->Asl.Parent;
8560d02842fSSascha Wildner 
8570d02842fSSascha Wildner             /* Link ELSE node as a peer to the previous IF */
8580d02842fSSascha Wildner 
8590d02842fSSascha Wildner             TrAmlInsertPeer (Conditional, DefaultOp);
8600d02842fSSascha Wildner         }
8610d02842fSSascha Wildner     }
8620d02842fSSascha Wildner 
8630d02842fSSascha Wildner     if (!CaseOp)
8640d02842fSSascha Wildner     {
8650d02842fSSascha Wildner         AslError (ASL_ERROR, ASL_MSG_NO_CASES, StartNode, NULL);
8660d02842fSSascha Wildner     }
8670d02842fSSascha Wildner 
8680d02842fSSascha Wildner 
8690d02842fSSascha Wildner     /*
8700d02842fSSascha Wildner      * Create a Name(_T_x, ...) statement. This statement must appear at the
8710d02842fSSascha Wildner      * method level, in case a loop surrounds the switch statement and could
8720d02842fSSascha Wildner      * cause the name to be created twice (error).
8730d02842fSSascha Wildner      */
8740d02842fSSascha Wildner 
8750d02842fSSascha Wildner     /* Create the Name node */
8760d02842fSSascha Wildner 
8770d02842fSSascha Wildner     Predicate = StartNode->Asl.Child;
8781093ca81SSascha Wildner     NewOp = TrCreateLeafOp (PARSEOP_NAME);
8790d02842fSSascha Wildner     TrAmlInitLineNumbers (NewOp, StartNode);
8800d02842fSSascha Wildner 
8810d02842fSSascha Wildner     /* Find the parent method */
8820d02842fSSascha Wildner 
8830d02842fSSascha Wildner     Next = StartNode;
8840d02842fSSascha Wildner     while ((Next->Asl.ParseOpcode != PARSEOP_METHOD) &&
885820c5b08SSascha Wildner            (Next->Asl.ParseOpcode != PARSEOP_DEFINITION_BLOCK))
8860d02842fSSascha Wildner     {
8870d02842fSSascha Wildner         Next = Next->Asl.Parent;
8880d02842fSSascha Wildner     }
8890d02842fSSascha Wildner     MethodOp = Next;
8900d02842fSSascha Wildner 
8911093ca81SSascha Wildner     NewOp->Asl.CompileFlags |= OP_COMPILER_EMITTED;
8920d02842fSSascha Wildner     NewOp->Asl.Parent = Next;
8930d02842fSSascha Wildner 
8940d02842fSSascha Wildner     /* Insert name after the method name and arguments */
8950d02842fSSascha Wildner 
8960d02842fSSascha Wildner     Next = Next->Asl.Child; /* Name */
8970d02842fSSascha Wildner     Next = Next->Asl.Next;  /* NumArgs */
8980d02842fSSascha Wildner     Next = Next->Asl.Next;  /* SerializeRule */
8990d02842fSSascha Wildner 
9000d02842fSSascha Wildner     /*
9010d02842fSSascha Wildner      * If method is not Serialized, we must make is so, because of the way
9020d02842fSSascha Wildner      * that Switch() must be implemented -- we cannot allow multiple threads
9030d02842fSSascha Wildner      * to execute this method concurrently since we need to create local
9040d02842fSSascha Wildner      * temporary name(s).
9050d02842fSSascha Wildner      */
9060d02842fSSascha Wildner     if (Next->Asl.ParseOpcode != PARSEOP_SERIALIZERULE_SERIAL)
9070d02842fSSascha Wildner     {
908820c5b08SSascha Wildner         AslError (ASL_REMARK, ASL_MSG_SERIALIZED, MethodOp,
909820c5b08SSascha Wildner             "Due to use of Switch operator");
9100d02842fSSascha Wildner         Next->Asl.ParseOpcode = PARSEOP_SERIALIZERULE_SERIAL;
9110d02842fSSascha Wildner     }
9120d02842fSSascha Wildner 
9130d02842fSSascha Wildner     Next = Next->Asl.Next;  /* SyncLevel */
9140d02842fSSascha Wildner     Next = Next->Asl.Next;  /* ReturnType */
9150d02842fSSascha Wildner     Next = Next->Asl.Next;  /* ParameterTypes */
9160d02842fSSascha Wildner 
9170d02842fSSascha Wildner     TrAmlInsertPeer (Next, NewOp);
9180d02842fSSascha Wildner     TrAmlInitLineNumbers (NewOp, Next);
9190d02842fSSascha Wildner 
9200d02842fSSascha Wildner     /* Create the NameSeg child for the Name node */
9210d02842fSSascha Wildner 
9221093ca81SSascha Wildner     NewOp2 = TrCreateValuedLeafOp (PARSEOP_NAMESEG,
9230d02842fSSascha Wildner         (UINT64) ACPI_TO_INTEGER (PredicateValueName));
9240d02842fSSascha Wildner     TrAmlInitLineNumbers (NewOp2, NewOp);
9251093ca81SSascha Wildner     NewOp2->Asl.CompileFlags |= OP_IS_NAME_DECLARATION;
9260d02842fSSascha Wildner     NewOp->Asl.Child  = NewOp2;
9270d02842fSSascha Wildner 
9280d02842fSSascha Wildner     /* Create the initial value for the Name. Btype was already validated above */
9290d02842fSSascha Wildner 
9300d02842fSSascha Wildner     switch (Btype)
9310d02842fSSascha Wildner     {
9320d02842fSSascha Wildner     case ACPI_BTYPE_INTEGER:
9330d02842fSSascha Wildner 
9341093ca81SSascha Wildner         NewOp2->Asl.Next = TrCreateValuedLeafOp (PARSEOP_ZERO,
9350d02842fSSascha Wildner             (UINT64) 0);
9360d02842fSSascha Wildner         TrAmlInitLineNumbers (NewOp2->Asl.Next, NewOp);
9370d02842fSSascha Wildner         break;
9380d02842fSSascha Wildner 
9390d02842fSSascha Wildner     case ACPI_BTYPE_STRING:
9400d02842fSSascha Wildner 
9411093ca81SSascha Wildner         NewOp2->Asl.Next = TrCreateValuedLeafOp (PARSEOP_STRING_LITERAL,
9420d02842fSSascha Wildner             (UINT64) ACPI_TO_INTEGER (""));
9430d02842fSSascha Wildner         TrAmlInitLineNumbers (NewOp2->Asl.Next, NewOp);
9440d02842fSSascha Wildner         break;
9450d02842fSSascha Wildner 
9460d02842fSSascha Wildner     case ACPI_BTYPE_BUFFER:
9470d02842fSSascha Wildner 
9481093ca81SSascha Wildner         (void) TrLinkPeerOp (NewOp2, TrCreateValuedLeafOp (PARSEOP_BUFFER,
9490d02842fSSascha Wildner             (UINT64) 0));
9500d02842fSSascha Wildner         Next = NewOp2->Asl.Next;
9510d02842fSSascha Wildner         TrAmlInitLineNumbers (Next, NewOp2);
9521093ca81SSascha Wildner 
9531093ca81SSascha Wildner         (void) TrLinkOpChildren (Next, 1, TrCreateValuedLeafOp (PARSEOP_ZERO,
9540d02842fSSascha Wildner             (UINT64) 1));
9550d02842fSSascha Wildner         TrAmlInitLineNumbers (Next->Asl.Child, Next);
9560d02842fSSascha Wildner 
9571093ca81SSascha Wildner         BufferOp = TrCreateValuedLeafOp (PARSEOP_DEFAULT_ARG, (UINT64) 0);
9580d02842fSSascha Wildner         TrAmlInitLineNumbers (BufferOp, Next->Asl.Child);
9591093ca81SSascha Wildner         (void) TrLinkPeerOp (Next->Asl.Child, BufferOp);
9600d02842fSSascha Wildner 
9610d02842fSSascha Wildner         TrAmlSetSubtreeParent (Next->Asl.Child, Next);
9620d02842fSSascha Wildner         break;
9630d02842fSSascha Wildner 
9640d02842fSSascha Wildner     default:
9650d02842fSSascha Wildner 
9660d02842fSSascha Wildner         break;
9670d02842fSSascha Wildner     }
9680d02842fSSascha Wildner 
9690d02842fSSascha Wildner     TrAmlSetSubtreeParent (NewOp2, NewOp);
9700d02842fSSascha Wildner 
9710d02842fSSascha Wildner     /*
9720d02842fSSascha Wildner      * Transform the Switch() into a While(One)-Break node.
9730d02842fSSascha Wildner      * And create a Store() node which will be used to save the
9740d02842fSSascha Wildner      * Switch() value. The store is of the form: Store (Value, _T_x)
9750d02842fSSascha Wildner      * where _T_x is the temp variable.
9760d02842fSSascha Wildner      */
9770d02842fSSascha Wildner     TrAmlInitNode (StartNode, PARSEOP_WHILE);
9781093ca81SSascha Wildner     NewOp = TrCreateLeafOp (PARSEOP_ONE);
9790d02842fSSascha Wildner     TrAmlInitLineNumbers (NewOp, StartNode);
9800d02842fSSascha Wildner     NewOp->Asl.Next = Predicate->Asl.Next;
9810d02842fSSascha Wildner     NewOp->Asl.Parent = StartNode;
9820d02842fSSascha Wildner     StartNode->Asl.Child = NewOp;
9830d02842fSSascha Wildner 
9840d02842fSSascha Wildner     /* Create a Store() node */
9850d02842fSSascha Wildner 
9861093ca81SSascha Wildner     StoreOp = TrCreateLeafOp (PARSEOP_STORE);
9870d02842fSSascha Wildner     TrAmlInitLineNumbers (StoreOp, NewOp);
9880d02842fSSascha Wildner     StoreOp->Asl.Parent = StartNode;
9890d02842fSSascha Wildner     TrAmlInsertPeer (NewOp, StoreOp);
9900d02842fSSascha Wildner 
9910d02842fSSascha Wildner     /* Complete the Store subtree */
9920d02842fSSascha Wildner 
9930d02842fSSascha Wildner     StoreOp->Asl.Child = Predicate;
9940d02842fSSascha Wildner     Predicate->Asl.Parent = StoreOp;
9950d02842fSSascha Wildner 
9961093ca81SSascha Wildner     NewOp = TrCreateValuedLeafOp (PARSEOP_NAMESEG,
9970d02842fSSascha Wildner         (UINT64) ACPI_TO_INTEGER (PredicateValueName));
9980d02842fSSascha Wildner     TrAmlInitLineNumbers (NewOp, StoreOp);
9990d02842fSSascha Wildner     NewOp->Asl.Parent    = StoreOp;
10000d02842fSSascha Wildner     Predicate->Asl.Next  = NewOp;
10010d02842fSSascha Wildner 
10020d02842fSSascha Wildner     /* Create a Break() node and insert it into the end of While() */
10030d02842fSSascha Wildner 
10040d02842fSSascha Wildner     Conditional = StartNode->Asl.Child;
10050d02842fSSascha Wildner     while (Conditional->Asl.Next)
10060d02842fSSascha Wildner     {
10070d02842fSSascha Wildner         Conditional = Conditional->Asl.Next;
10080d02842fSSascha Wildner     }
10090d02842fSSascha Wildner 
10101093ca81SSascha Wildner     BreakOp = TrCreateLeafOp (PARSEOP_BREAK);
10110d02842fSSascha Wildner     TrAmlInitLineNumbers (BreakOp, NewOp);
10120d02842fSSascha Wildner     BreakOp->Asl.Parent = StartNode;
10130d02842fSSascha Wildner     TrAmlInsertPeer (Conditional, BreakOp);
10140d02842fSSascha Wildner }
1015e5412f1eSSascha Wildner 
1016e5412f1eSSascha Wildner 
1017e5412f1eSSascha Wildner /*******************************************************************************
1018e5412f1eSSascha Wildner  *
1019e5412f1eSSascha Wildner  * FUNCTION:    TrCheckForDuplicateCase
1020e5412f1eSSascha Wildner  *
1021e5412f1eSSascha Wildner  * PARAMETERS:  CaseOp          - Parse node for first Case statement in list
1022e5412f1eSSascha Wildner  *              Predicate1      - Case value for the input CaseOp
1023e5412f1eSSascha Wildner  *
1024e5412f1eSSascha Wildner  * RETURN:      None
1025e5412f1eSSascha Wildner  *
1026e5412f1eSSascha Wildner  * DESCRIPTION: Check for duplicate case values. Currently, only handles
1027e5412f1eSSascha Wildner  *              Integers, Strings and Buffers. No support for Package objects.
1028e5412f1eSSascha Wildner  *
1029e5412f1eSSascha Wildner  ******************************************************************************/
1030e5412f1eSSascha Wildner 
1031e5412f1eSSascha Wildner static void
TrCheckForDuplicateCase(ACPI_PARSE_OBJECT * CaseOp,ACPI_PARSE_OBJECT * Predicate1)1032e5412f1eSSascha Wildner TrCheckForDuplicateCase (
1033e5412f1eSSascha Wildner     ACPI_PARSE_OBJECT       *CaseOp,
1034e5412f1eSSascha Wildner     ACPI_PARSE_OBJECT       *Predicate1)
1035e5412f1eSSascha Wildner {
1036e5412f1eSSascha Wildner     ACPI_PARSE_OBJECT       *Next;
1037e5412f1eSSascha Wildner     ACPI_PARSE_OBJECT       *Predicate2;
1038e5412f1eSSascha Wildner 
1039e5412f1eSSascha Wildner 
1040e5412f1eSSascha Wildner     /* Walk the list of CASE opcodes */
1041e5412f1eSSascha Wildner 
1042e5412f1eSSascha Wildner     Next = CaseOp->Asl.Next;
1043e5412f1eSSascha Wildner     while (Next)
1044e5412f1eSSascha Wildner     {
1045e5412f1eSSascha Wildner         if (Next->Asl.ParseOpcode == PARSEOP_CASE)
1046e5412f1eSSascha Wildner         {
1047e5412f1eSSascha Wildner             /* Emit error only once */
1048e5412f1eSSascha Wildner 
1049e5412f1eSSascha Wildner             if (Next->Asl.CompileFlags & OP_IS_DUPLICATE)
1050e5412f1eSSascha Wildner             {
1051e5412f1eSSascha Wildner                 goto NextCase;
1052e5412f1eSSascha Wildner             }
1053e5412f1eSSascha Wildner 
1054e5412f1eSSascha Wildner             /* Check for a duplicate plain integer */
1055e5412f1eSSascha Wildner 
1056e5412f1eSSascha Wildner             Predicate2 = Next->Asl.Child;
1057e5412f1eSSascha Wildner             if ((Predicate1->Asl.ParseOpcode == PARSEOP_INTEGER) &&
1058e5412f1eSSascha Wildner                 (Predicate2->Asl.ParseOpcode == PARSEOP_INTEGER))
1059e5412f1eSSascha Wildner             {
1060e5412f1eSSascha Wildner                 if (Predicate1->Asl.Value.Integer == Predicate2->Asl.Value.Integer)
1061e5412f1eSSascha Wildner                 {
1062e5412f1eSSascha Wildner                     goto FoundDuplicate;
1063e5412f1eSSascha Wildner                 }
1064e5412f1eSSascha Wildner             }
1065e5412f1eSSascha Wildner 
1066e5412f1eSSascha Wildner             /* Check for pairs of the constants ZERO, ONE, ONES */
1067e5412f1eSSascha Wildner 
1068e5412f1eSSascha Wildner             else if (((Predicate1->Asl.ParseOpcode == PARSEOP_ZERO) &&
1069e5412f1eSSascha Wildner                 (Predicate2->Asl.ParseOpcode == PARSEOP_ZERO)) ||
1070e5412f1eSSascha Wildner                 ((Predicate1->Asl.ParseOpcode == PARSEOP_ONE) &&
1071e5412f1eSSascha Wildner                 (Predicate2->Asl.ParseOpcode == PARSEOP_ONE)) ||
1072e5412f1eSSascha Wildner                 ((Predicate1->Asl.ParseOpcode == PARSEOP_ONES) &&
1073e5412f1eSSascha Wildner                 (Predicate2->Asl.ParseOpcode == PARSEOP_ONES)))
1074e5412f1eSSascha Wildner             {
1075e5412f1eSSascha Wildner                 goto FoundDuplicate;
1076e5412f1eSSascha Wildner             }
1077e5412f1eSSascha Wildner 
1078e5412f1eSSascha Wildner             /* Check for a duplicate string constant (literal) */
1079e5412f1eSSascha Wildner 
1080e5412f1eSSascha Wildner             else if ((Predicate1->Asl.ParseOpcode == PARSEOP_STRING_LITERAL) &&
1081e5412f1eSSascha Wildner                 (Predicate2->Asl.ParseOpcode == PARSEOP_STRING_LITERAL))
1082e5412f1eSSascha Wildner             {
1083e5412f1eSSascha Wildner                 if (!strcmp (Predicate1->Asl.Value.String,
1084e5412f1eSSascha Wildner                         Predicate2->Asl.Value.String))
1085e5412f1eSSascha Wildner                 {
1086e5412f1eSSascha Wildner                     goto FoundDuplicate;
1087e5412f1eSSascha Wildner                 }
1088e5412f1eSSascha Wildner             }
1089e5412f1eSSascha Wildner 
1090e5412f1eSSascha Wildner             /* Check for a duplicate buffer constant */
1091e5412f1eSSascha Wildner 
1092e5412f1eSSascha Wildner             else if ((Predicate1->Asl.ParseOpcode == PARSEOP_BUFFER) &&
1093e5412f1eSSascha Wildner                 (Predicate2->Asl.ParseOpcode == PARSEOP_BUFFER))
1094e5412f1eSSascha Wildner             {
1095e5412f1eSSascha Wildner                 if (TrCheckForBufferMatch (Predicate1->Asl.Child,
1096e5412f1eSSascha Wildner                         Predicate2->Asl.Child))
1097e5412f1eSSascha Wildner                 {
1098e5412f1eSSascha Wildner                     goto FoundDuplicate;
1099e5412f1eSSascha Wildner                 }
1100e5412f1eSSascha Wildner             }
1101e5412f1eSSascha Wildner         }
1102e5412f1eSSascha Wildner         goto NextCase;
1103e5412f1eSSascha Wildner 
1104e5412f1eSSascha Wildner FoundDuplicate:
1105e5412f1eSSascha Wildner         /* Emit error message only once */
1106e5412f1eSSascha Wildner 
1107e5412f1eSSascha Wildner         Next->Asl.CompileFlags |= OP_IS_DUPLICATE;
1108e5412f1eSSascha Wildner 
1109e5412f1eSSascha Wildner         AslDualParseOpError (ASL_ERROR, ASL_MSG_DUPLICATE_CASE, Next,
1110e5412f1eSSascha Wildner             Next->Asl.Value.String, ASL_MSG_CASE_FOUND_HERE, CaseOp,
1111e5412f1eSSascha Wildner             CaseOp->Asl.ExternalName);
1112e5412f1eSSascha Wildner 
1113e5412f1eSSascha Wildner NextCase:
1114e5412f1eSSascha Wildner         Next = Next->Asl.Next;
1115e5412f1eSSascha Wildner     }
1116e5412f1eSSascha Wildner }
1117e5412f1eSSascha Wildner 
1118e5412f1eSSascha Wildner /*******************************************************************************
1119e5412f1eSSascha Wildner  *
1120e5412f1eSSascha Wildner  * FUNCTION:    TrBufferIsAllZero
1121e5412f1eSSascha Wildner  *
1122e5412f1eSSascha Wildner  * PARAMETERS:  Op          - Parse node for first opcode in buffer initializer
1123e5412f1eSSascha Wildner  *                            list
1124e5412f1eSSascha Wildner  *
1125e5412f1eSSascha Wildner  * RETURN:      TRUE if buffer contains all zeros or a DEFAULT_ARG
1126e5412f1eSSascha Wildner  *
1127e5412f1eSSascha Wildner  * DESCRIPTION: Check for duplicate Buffer case values.
1128e5412f1eSSascha Wildner  *
1129e5412f1eSSascha Wildner  ******************************************************************************/
1130e5412f1eSSascha Wildner 
1131e5412f1eSSascha Wildner static BOOLEAN
TrBufferIsAllZero(ACPI_PARSE_OBJECT * Op)1132e5412f1eSSascha Wildner TrBufferIsAllZero (
1133e5412f1eSSascha Wildner     ACPI_PARSE_OBJECT       *Op)
1134e5412f1eSSascha Wildner {
1135e5412f1eSSascha Wildner     while (Op)
1136e5412f1eSSascha Wildner     {
1137e5412f1eSSascha Wildner         if (Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
1138e5412f1eSSascha Wildner         {
1139e5412f1eSSascha Wildner             return (TRUE);
1140e5412f1eSSascha Wildner         }
1141e5412f1eSSascha Wildner         else if (Op->Asl.Value.Integer != 0)
1142e5412f1eSSascha Wildner         {
1143e5412f1eSSascha Wildner             return (FALSE);
1144e5412f1eSSascha Wildner         }
1145e5412f1eSSascha Wildner 
1146e5412f1eSSascha Wildner         Op = Op->Asl.Next;
1147e5412f1eSSascha Wildner     }
1148e5412f1eSSascha Wildner 
1149e5412f1eSSascha Wildner     return (TRUE);
1150e5412f1eSSascha Wildner }
1151e5412f1eSSascha Wildner 
1152e5412f1eSSascha Wildner 
1153e5412f1eSSascha Wildner /*******************************************************************************
1154e5412f1eSSascha Wildner  *
1155e5412f1eSSascha Wildner  * FUNCTION:    TrCheckForBufferMatch
1156e5412f1eSSascha Wildner  *
1157e5412f1eSSascha Wildner  * PARAMETERS:  Next1       - Parse node for first opcode in first buffer list
1158e5412f1eSSascha Wildner  *                              (The DEFAULT_ARG or INTEGER node)
1159e5412f1eSSascha Wildner  *              Next2       - Parse node for first opcode in second buffer list
1160e5412f1eSSascha Wildner  *                              (The DEFAULT_ARG or INTEGER node)
1161e5412f1eSSascha Wildner  *
1162e5412f1eSSascha Wildner  * RETURN:      TRUE if buffers match, FALSE otherwise
1163e5412f1eSSascha Wildner  *
1164e5412f1eSSascha Wildner  * DESCRIPTION: Check for duplicate Buffer case values.
1165e5412f1eSSascha Wildner  *
1166e5412f1eSSascha Wildner  ******************************************************************************/
1167e5412f1eSSascha Wildner 
1168e5412f1eSSascha Wildner static BOOLEAN
TrCheckForBufferMatch(ACPI_PARSE_OBJECT * NextOp1,ACPI_PARSE_OBJECT * NextOp2)1169e5412f1eSSascha Wildner TrCheckForBufferMatch (
1170e5412f1eSSascha Wildner     ACPI_PARSE_OBJECT       *NextOp1,
1171e5412f1eSSascha Wildner     ACPI_PARSE_OBJECT       *NextOp2)
1172e5412f1eSSascha Wildner {
1173e5412f1eSSascha Wildner     /*
1174e5412f1eSSascha Wildner      * The buffer length can be a DEFAULT_ARG or INTEGER. If any of the nodes
1175e5412f1eSSascha Wildner      * are DEFAULT_ARG, it means that the length has yet to be computed.
1176e5412f1eSSascha Wildner      * However, the initializer list can be compared to determine if these two
1177e5412f1eSSascha Wildner      * buffers match.
1178e5412f1eSSascha Wildner      */
1179e5412f1eSSascha Wildner     if ((NextOp1->Asl.ParseOpcode == PARSEOP_INTEGER &&
1180e5412f1eSSascha Wildner         NextOp2->Asl.ParseOpcode == PARSEOP_INTEGER) &&
1181e5412f1eSSascha Wildner         NextOp1->Asl.Value.Integer != NextOp2->Asl.Value.Integer)
1182e5412f1eSSascha Wildner     {
1183e5412f1eSSascha Wildner         return (FALSE);
1184e5412f1eSSascha Wildner     }
1185e5412f1eSSascha Wildner 
1186e5412f1eSSascha Wildner     /*
1187e5412f1eSSascha Wildner      * Buffers that have explicit lengths but no initializer lists are
1188e5412f1eSSascha Wildner      * filled with zeros at runtime. This is equivalent to buffers that have the
1189e5412f1eSSascha Wildner      * same length that are filled with zeros.
1190e5412f1eSSascha Wildner      *
1191e5412f1eSSascha Wildner      * In other words, the following buffers are equivalent:
1192e5412f1eSSascha Wildner      *
1193e5412f1eSSascha Wildner      * Buffer(0x4) {}
1194e5412f1eSSascha Wildner      * Buffer() {0x0, 0x0, 0x0, 0x0}
1195e5412f1eSSascha Wildner      *
1196e5412f1eSSascha Wildner      * This statement checks for matches where one buffer does not have an
1197e5412f1eSSascha Wildner      * initializer list and another buffer contains all zeros.
1198e5412f1eSSascha Wildner      */
1199e5412f1eSSascha Wildner     if (NextOp1->Asl.ParseOpcode != NextOp2->Asl.ParseOpcode &&
1200e5412f1eSSascha Wildner         TrBufferIsAllZero (NextOp1->Asl.Next) &&
1201e5412f1eSSascha Wildner         TrBufferIsAllZero (NextOp2->Asl.Next))
1202e5412f1eSSascha Wildner     {
1203e5412f1eSSascha Wildner         return (TRUE);
1204e5412f1eSSascha Wildner     }
1205e5412f1eSSascha Wildner 
1206e5412f1eSSascha Wildner     /* Start at the BYTECONST initializer node list */
1207e5412f1eSSascha Wildner 
1208e5412f1eSSascha Wildner     NextOp1 = NextOp1->Asl.Next;
1209e5412f1eSSascha Wildner     NextOp2 = NextOp2->Asl.Next;
1210e5412f1eSSascha Wildner 
1211e5412f1eSSascha Wildner     /*
1212e5412f1eSSascha Wildner      * Walk both lists until either a mismatch is found, or one or more
1213e5412f1eSSascha Wildner      * end-of-lists are found
1214e5412f1eSSascha Wildner      */
1215e5412f1eSSascha Wildner     while (NextOp1 && NextOp2)
1216e5412f1eSSascha Wildner     {
1217e5412f1eSSascha Wildner         if ((NextOp1->Asl.ParseOpcode == PARSEOP_STRING_LITERAL) &&
1218e5412f1eSSascha Wildner             (NextOp2->Asl.ParseOpcode == PARSEOP_STRING_LITERAL))
1219e5412f1eSSascha Wildner         {
1220e5412f1eSSascha Wildner             if (!strcmp (NextOp1->Asl.Value.String, NextOp2->Asl.Value.String))
1221e5412f1eSSascha Wildner             {
1222e5412f1eSSascha Wildner                 return (TRUE);
1223e5412f1eSSascha Wildner             }
1224e5412f1eSSascha Wildner             else
1225e5412f1eSSascha Wildner             {
1226e5412f1eSSascha Wildner                 return (FALSE);
1227e5412f1eSSascha Wildner             }
1228e5412f1eSSascha Wildner         }
1229e5412f1eSSascha Wildner         if ((UINT8) NextOp1->Asl.Value.Integer != (UINT8) NextOp2->Asl.Value.Integer)
1230e5412f1eSSascha Wildner         {
1231e5412f1eSSascha Wildner             return (FALSE);
1232e5412f1eSSascha Wildner         }
1233e5412f1eSSascha Wildner 
1234e5412f1eSSascha Wildner         NextOp1 = NextOp1->Asl.Next;
1235e5412f1eSSascha Wildner         NextOp2 = NextOp2->Asl.Next;
1236e5412f1eSSascha Wildner     }
1237e5412f1eSSascha Wildner 
1238e5412f1eSSascha Wildner     /* Not a match if one of the lists is not at end-of-list */
1239e5412f1eSSascha Wildner 
1240e5412f1eSSascha Wildner     if (NextOp1 || NextOp2)
1241e5412f1eSSascha Wildner     {
1242e5412f1eSSascha Wildner         return (FALSE);
1243e5412f1eSSascha Wildner     }
1244e5412f1eSSascha Wildner 
1245e5412f1eSSascha Wildner     /* Otherwise, the buffers match */
1246e5412f1eSSascha Wildner 
1247e5412f1eSSascha Wildner     return (TRUE);
1248e5412f1eSSascha Wildner }
1249ff3cb46dSSascha Wildner 
1250ff3cb46dSSascha Wildner 
1251ff3cb46dSSascha Wildner /*******************************************************************************
1252ff3cb46dSSascha Wildner  *
1253ff3cb46dSSascha Wildner  * FUNCTION:    TrDoMethod
1254ff3cb46dSSascha Wildner  *
1255ff3cb46dSSascha Wildner  * PARAMETERS:  Op               - Parse node for SWITCH
1256ff3cb46dSSascha Wildner  *
1257ff3cb46dSSascha Wildner  * RETURN:      None
1258ff3cb46dSSascha Wildner  *
1259ff3cb46dSSascha Wildner  * DESCRIPTION: Determine that parameter count of an ASL method node by
1260ff3cb46dSSascha Wildner  *              translating the parameter count parse node from
1261ff3cb46dSSascha Wildner  *              PARSEOP_DEFAULT_ARG to PARSEOP_BYTECONST.
1262ff3cb46dSSascha Wildner  *
1263ff3cb46dSSascha Wildner  ******************************************************************************/
1264ff3cb46dSSascha Wildner 
1265ff3cb46dSSascha Wildner static void
TrDoMethod(ACPI_PARSE_OBJECT * Op)1266ff3cb46dSSascha Wildner TrDoMethod (
1267ff3cb46dSSascha Wildner     ACPI_PARSE_OBJECT       *Op)
1268ff3cb46dSSascha Wildner {
1269ff3cb46dSSascha Wildner     ACPI_PARSE_OBJECT           *ArgCountOp;
1270ff3cb46dSSascha Wildner     UINT8                       ArgCount;
1271ff3cb46dSSascha Wildner     ACPI_PARSE_OBJECT           *ParameterOp;
1272ff3cb46dSSascha Wildner 
1273ff3cb46dSSascha Wildner 
1274ff3cb46dSSascha Wildner     /*
1275ff3cb46dSSascha Wildner      * TBD: Zero the tempname (_T_x) count. Probably shouldn't be a global,
1276ff3cb46dSSascha Wildner      * however
1277ff3cb46dSSascha Wildner      */
1278ff3cb46dSSascha Wildner     AslGbl_TempCount = 0;
1279ff3cb46dSSascha Wildner 
1280ff3cb46dSSascha Wildner     ArgCountOp = Op->Asl.Child->Asl.Next;
1281ff3cb46dSSascha Wildner     if (ArgCountOp->Asl.ParseOpcode == PARSEOP_BYTECONST)
1282ff3cb46dSSascha Wildner     {
1283ff3cb46dSSascha Wildner         /*
1284ff3cb46dSSascha Wildner          * Parameter count for this method has already been recorded in the
1285ff3cb46dSSascha Wildner          * method declaration.
1286ff3cb46dSSascha Wildner          */
1287ff3cb46dSSascha Wildner         return;
1288ff3cb46dSSascha Wildner     }
1289ff3cb46dSSascha Wildner 
1290ff3cb46dSSascha Wildner     /*
1291ff3cb46dSSascha Wildner      * Parameter count has been omitted in the method declaration.
1292ff3cb46dSSascha Wildner      * Count the amount of arguments here.
1293ff3cb46dSSascha Wildner      */
1294ff3cb46dSSascha Wildner     ParameterOp = ArgCountOp->Asl.Next->Asl.Next->Asl.Next->Asl.Next;
1295ff3cb46dSSascha Wildner     if (ParameterOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
1296ff3cb46dSSascha Wildner     {
1297ff3cb46dSSascha Wildner         ArgCount = 0;
1298ff3cb46dSSascha Wildner         ParameterOp = ParameterOp->Asl.Child;
1299ff3cb46dSSascha Wildner 
1300ff3cb46dSSascha Wildner         while (ParameterOp)
1301ff3cb46dSSascha Wildner         {
1302ff3cb46dSSascha Wildner             ParameterOp = ParameterOp->Asl.Next;
1303ff3cb46dSSascha Wildner             ArgCount++;
1304ff3cb46dSSascha Wildner         }
1305ff3cb46dSSascha Wildner 
1306ff3cb46dSSascha Wildner         ArgCountOp->Asl.Value.Integer = ArgCount;
1307ff3cb46dSSascha Wildner         ArgCountOp->Asl.ParseOpcode = PARSEOP_BYTECONST;
1308ff3cb46dSSascha Wildner     }
1309ff3cb46dSSascha Wildner     else
1310ff3cb46dSSascha Wildner     {
1311ff3cb46dSSascha Wildner         /*
1312ff3cb46dSSascha Wildner          * Method parameters can be counted by analyzing the Parameter type
1313ff3cb46dSSascha Wildner          * list. If the Parameter list contains more than 1 parameter, it
1314ff3cb46dSSascha Wildner          * is nested under PARSEOP_DEFAULT_ARG. When there is only 1
1315ff3cb46dSSascha Wildner          * parameter, the parse tree contains a single node representing
1316ff3cb46dSSascha Wildner          * that type.
1317ff3cb46dSSascha Wildner          */
1318ff3cb46dSSascha Wildner         ArgCountOp->Asl.Value.Integer = 1;
1319ff3cb46dSSascha Wildner         ArgCountOp->Asl.ParseOpcode = PARSEOP_BYTECONST;
1320ff3cb46dSSascha Wildner     }
1321ff3cb46dSSascha Wildner }
1322