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