1a9643ea8Slogwang /******************************************************************************
2a9643ea8Slogwang  *
3a9643ea8Slogwang  * Module Name: psloop - Main AML parse loop
4a9643ea8Slogwang  *
5a9643ea8Slogwang  *****************************************************************************/
6a9643ea8Slogwang 
7*22ce4affSfengbojiang /******************************************************************************
8*22ce4affSfengbojiang  *
9*22ce4affSfengbojiang  * 1. Copyright Notice
10*22ce4affSfengbojiang  *
11*22ce4affSfengbojiang  * Some or all of this work - Copyright (c) 1999 - 2020, Intel Corp.
12a9643ea8Slogwang  * All rights reserved.
13a9643ea8Slogwang  *
14*22ce4affSfengbojiang  * 2. License
15*22ce4affSfengbojiang  *
16*22ce4affSfengbojiang  * 2.1. This is your license from Intel Corp. under its intellectual property
17*22ce4affSfengbojiang  * rights. You may have additional license terms from the party that provided
18*22ce4affSfengbojiang  * you this software, covering your right to use that party's intellectual
19*22ce4affSfengbojiang  * property rights.
20*22ce4affSfengbojiang  *
21*22ce4affSfengbojiang  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22*22ce4affSfengbojiang  * copy of the source code appearing in this file ("Covered Code") an
23*22ce4affSfengbojiang  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24*22ce4affSfengbojiang  * base code distributed originally by Intel ("Original Intel Code") to copy,
25*22ce4affSfengbojiang  * make derivatives, distribute, use and display any portion of the Covered
26*22ce4affSfengbojiang  * Code in any form, with the right to sublicense such rights; and
27*22ce4affSfengbojiang  *
28*22ce4affSfengbojiang  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29*22ce4affSfengbojiang  * license (with the right to sublicense), under only those claims of Intel
30*22ce4affSfengbojiang  * patents that are infringed by the Original Intel Code, to make, use, sell,
31*22ce4affSfengbojiang  * offer to sell, and import the Covered Code and derivative works thereof
32*22ce4affSfengbojiang  * solely to the minimum extent necessary to exercise the above copyright
33*22ce4affSfengbojiang  * license, and in no event shall the patent license extend to any additions
34*22ce4affSfengbojiang  * to or modifications of the Original Intel Code. No other license or right
35*22ce4affSfengbojiang  * is granted directly or by implication, estoppel or otherwise;
36*22ce4affSfengbojiang  *
37*22ce4affSfengbojiang  * The above copyright and patent license is granted only if the following
38*22ce4affSfengbojiang  * conditions are met:
39*22ce4affSfengbojiang  *
40*22ce4affSfengbojiang  * 3. Conditions
41*22ce4affSfengbojiang  *
42*22ce4affSfengbojiang  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43*22ce4affSfengbojiang  * Redistribution of source code of any substantial portion of the Covered
44*22ce4affSfengbojiang  * Code or modification with rights to further distribute source must include
45*22ce4affSfengbojiang  * the above Copyright Notice, the above License, this list of Conditions,
46*22ce4affSfengbojiang  * and the following Disclaimer and Export Compliance provision. In addition,
47*22ce4affSfengbojiang  * Licensee must cause all Covered Code to which Licensee contributes to
48*22ce4affSfengbojiang  * contain a file documenting the changes Licensee made to create that Covered
49*22ce4affSfengbojiang  * Code and the date of any change. Licensee must include in that file the
50*22ce4affSfengbojiang  * documentation of any changes made by any predecessor Licensee. Licensee
51*22ce4affSfengbojiang  * must include a prominent statement that the modification is derived,
52*22ce4affSfengbojiang  * directly or indirectly, from Original Intel Code.
53*22ce4affSfengbojiang  *
54*22ce4affSfengbojiang  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55*22ce4affSfengbojiang  * Redistribution of source code of any substantial portion of the Covered
56*22ce4affSfengbojiang  * Code or modification without rights to further distribute source must
57*22ce4affSfengbojiang  * include the following Disclaimer and Export Compliance provision in the
58*22ce4affSfengbojiang  * documentation and/or other materials provided with distribution. In
59*22ce4affSfengbojiang  * addition, Licensee may not authorize further sublicense of source of any
60*22ce4affSfengbojiang  * portion of the Covered Code, and must include terms to the effect that the
61*22ce4affSfengbojiang  * license from Licensee to its licensee is limited to the intellectual
62*22ce4affSfengbojiang  * property embodied in the software Licensee provides to its licensee, and
63*22ce4affSfengbojiang  * not to intellectual property embodied in modifications its licensee may
64*22ce4affSfengbojiang  * make.
65*22ce4affSfengbojiang  *
66*22ce4affSfengbojiang  * 3.3. Redistribution of Executable. Redistribution in executable form of any
67*22ce4affSfengbojiang  * substantial portion of the Covered Code or modification must reproduce the
68*22ce4affSfengbojiang  * above Copyright Notice, and the following Disclaimer and Export Compliance
69*22ce4affSfengbojiang  * provision in the documentation and/or other materials provided with the
70*22ce4affSfengbojiang  * distribution.
71*22ce4affSfengbojiang  *
72*22ce4affSfengbojiang  * 3.4. Intel retains all right, title, and interest in and to the Original
73*22ce4affSfengbojiang  * Intel Code.
74*22ce4affSfengbojiang  *
75*22ce4affSfengbojiang  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76*22ce4affSfengbojiang  * Intel shall be used in advertising or otherwise to promote the sale, use or
77*22ce4affSfengbojiang  * other dealings in products derived from or relating to the Covered Code
78*22ce4affSfengbojiang  * without prior written authorization from Intel.
79*22ce4affSfengbojiang  *
80*22ce4affSfengbojiang  * 4. Disclaimer and Export Compliance
81*22ce4affSfengbojiang  *
82*22ce4affSfengbojiang  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83*22ce4affSfengbojiang  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84*22ce4affSfengbojiang  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85*22ce4affSfengbojiang  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86*22ce4affSfengbojiang  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87*22ce4affSfengbojiang  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88*22ce4affSfengbojiang  * PARTICULAR PURPOSE.
89*22ce4affSfengbojiang  *
90*22ce4affSfengbojiang  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91*22ce4affSfengbojiang  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92*22ce4affSfengbojiang  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93*22ce4affSfengbojiang  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94*22ce4affSfengbojiang  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95*22ce4affSfengbojiang  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96*22ce4affSfengbojiang  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97*22ce4affSfengbojiang  * LIMITED REMEDY.
98*22ce4affSfengbojiang  *
99*22ce4affSfengbojiang  * 4.3. Licensee shall not export, either directly or indirectly, any of this
100*22ce4affSfengbojiang  * software or system incorporating such software without first obtaining any
101*22ce4affSfengbojiang  * required license or other approval from the U. S. Department of Commerce or
102*22ce4affSfengbojiang  * any other agency or department of the United States Government. In the
103*22ce4affSfengbojiang  * event Licensee exports any such software from the United States or
104*22ce4affSfengbojiang  * re-exports any such software from a foreign destination, Licensee shall
105*22ce4affSfengbojiang  * ensure that the distribution and export/re-export of the software is in
106*22ce4affSfengbojiang  * compliance with all laws, regulations, orders, or other restrictions of the
107*22ce4affSfengbojiang  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108*22ce4affSfengbojiang  * any of its subsidiaries will export/re-export any technical data, process,
109*22ce4affSfengbojiang  * software, or service, directly or indirectly, to any country for which the
110*22ce4affSfengbojiang  * United States government or any agency thereof requires an export license,
111*22ce4affSfengbojiang  * other governmental approval, or letter of assurance, without first obtaining
112*22ce4affSfengbojiang  * such license, approval or letter.
113*22ce4affSfengbojiang  *
114*22ce4affSfengbojiang  *****************************************************************************
115*22ce4affSfengbojiang  *
116*22ce4affSfengbojiang  * Alternatively, you may choose to be licensed under the terms of the
117*22ce4affSfengbojiang  * following license:
118*22ce4affSfengbojiang  *
119a9643ea8Slogwang  * Redistribution and use in source and binary forms, with or without
120a9643ea8Slogwang  * modification, are permitted provided that the following conditions
121a9643ea8Slogwang  * are met:
122a9643ea8Slogwang  * 1. Redistributions of source code must retain the above copyright
123a9643ea8Slogwang  *    notice, this list of conditions, and the following disclaimer,
124a9643ea8Slogwang  *    without modification.
125a9643ea8Slogwang  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126a9643ea8Slogwang  *    substantially similar to the "NO WARRANTY" disclaimer below
127a9643ea8Slogwang  *    ("Disclaimer") and any redistribution must be conditioned upon
128a9643ea8Slogwang  *    including a substantially similar Disclaimer requirement for further
129a9643ea8Slogwang  *    binary redistribution.
130a9643ea8Slogwang  * 3. Neither the names of the above-listed copyright holders nor the names
131a9643ea8Slogwang  *    of any contributors may be used to endorse or promote products derived
132a9643ea8Slogwang  *    from this software without specific prior written permission.
133a9643ea8Slogwang  *
134*22ce4affSfengbojiang  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135*22ce4affSfengbojiang  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136*22ce4affSfengbojiang  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137*22ce4affSfengbojiang  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138*22ce4affSfengbojiang  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139*22ce4affSfengbojiang  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140*22ce4affSfengbojiang  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141*22ce4affSfengbojiang  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142*22ce4affSfengbojiang  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143*22ce4affSfengbojiang  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144*22ce4affSfengbojiang  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145*22ce4affSfengbojiang  *
146*22ce4affSfengbojiang  * Alternatively, you may choose to be licensed under the terms of the
147a9643ea8Slogwang  * GNU General Public License ("GPL") version 2 as published by the Free
148a9643ea8Slogwang  * Software Foundation.
149a9643ea8Slogwang  *
150*22ce4affSfengbojiang  *****************************************************************************/
151a9643ea8Slogwang 
152a9643ea8Slogwang /*
153a9643ea8Slogwang  * Parse the AML and build an operation tree as most interpreters, (such as
154a9643ea8Slogwang  * Perl) do. Parsing is done by hand rather than with a YACC generated parser
155a9643ea8Slogwang  * to tightly constrain stack and dynamic memory usage. Parsing is kept
156a9643ea8Slogwang  * flexible and the code fairly compact by parsing based on a list of AML
157a9643ea8Slogwang  * opcode templates in AmlOpInfo[].
158a9643ea8Slogwang  */
159a9643ea8Slogwang 
160a9643ea8Slogwang #include <contrib/dev/acpica/include/acpi.h>
161a9643ea8Slogwang #include <contrib/dev/acpica/include/accommon.h>
162a9643ea8Slogwang #include <contrib/dev/acpica/include/acinterp.h>
163a9643ea8Slogwang #include <contrib/dev/acpica/include/acparser.h>
164a9643ea8Slogwang #include <contrib/dev/acpica/include/acdispat.h>
165a9643ea8Slogwang #include <contrib/dev/acpica/include/amlcode.h>
166*22ce4affSfengbojiang #include <contrib/dev/acpica/include/acconvert.h>
167*22ce4affSfengbojiang #include <contrib/dev/acpica/include/acnamesp.h>
168a9643ea8Slogwang 
169a9643ea8Slogwang #define _COMPONENT          ACPI_PARSER
170a9643ea8Slogwang         ACPI_MODULE_NAME    ("psloop")
171a9643ea8Slogwang 
172a9643ea8Slogwang 
173a9643ea8Slogwang /* Local prototypes */
174a9643ea8Slogwang 
175a9643ea8Slogwang static ACPI_STATUS
176a9643ea8Slogwang AcpiPsGetArguments (
177a9643ea8Slogwang     ACPI_WALK_STATE         *WalkState,
178a9643ea8Slogwang     UINT8                   *AmlOpStart,
179a9643ea8Slogwang     ACPI_PARSE_OBJECT       *Op);
180a9643ea8Slogwang 
181a9643ea8Slogwang 
182a9643ea8Slogwang /*******************************************************************************
183a9643ea8Slogwang  *
184a9643ea8Slogwang  * FUNCTION:    AcpiPsGetArguments
185a9643ea8Slogwang  *
186a9643ea8Slogwang  * PARAMETERS:  WalkState           - Current state
187a9643ea8Slogwang  *              AmlOpStart          - Op start in AML
188a9643ea8Slogwang  *              Op                  - Current Op
189a9643ea8Slogwang  *
190a9643ea8Slogwang  * RETURN:      Status
191a9643ea8Slogwang  *
192a9643ea8Slogwang  * DESCRIPTION: Get arguments for passed Op.
193a9643ea8Slogwang  *
194a9643ea8Slogwang  ******************************************************************************/
195a9643ea8Slogwang 
196a9643ea8Slogwang static ACPI_STATUS
AcpiPsGetArguments(ACPI_WALK_STATE * WalkState,UINT8 * AmlOpStart,ACPI_PARSE_OBJECT * Op)197a9643ea8Slogwang AcpiPsGetArguments (
198a9643ea8Slogwang     ACPI_WALK_STATE         *WalkState,
199a9643ea8Slogwang     UINT8                   *AmlOpStart,
200a9643ea8Slogwang     ACPI_PARSE_OBJECT       *Op)
201a9643ea8Slogwang {
202a9643ea8Slogwang     ACPI_STATUS             Status = AE_OK;
203a9643ea8Slogwang     ACPI_PARSE_OBJECT       *Arg = NULL;
204a9643ea8Slogwang 
205a9643ea8Slogwang 
206a9643ea8Slogwang     ACPI_FUNCTION_TRACE_PTR (PsGetArguments, WalkState);
207a9643ea8Slogwang 
208a9643ea8Slogwang 
209*22ce4affSfengbojiang     ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
210*22ce4affSfengbojiang         "Get arguments for opcode [%s]\n", Op->Common.AmlOpName));
211*22ce4affSfengbojiang 
212a9643ea8Slogwang     switch (Op->Common.AmlOpcode)
213a9643ea8Slogwang     {
214a9643ea8Slogwang     case AML_BYTE_OP:       /* AML_BYTEDATA_ARG */
215a9643ea8Slogwang     case AML_WORD_OP:       /* AML_WORDDATA_ARG */
216a9643ea8Slogwang     case AML_DWORD_OP:      /* AML_DWORDATA_ARG */
217a9643ea8Slogwang     case AML_QWORD_OP:      /* AML_QWORDATA_ARG */
218a9643ea8Slogwang     case AML_STRING_OP:     /* AML_ASCIICHARLIST_ARG */
219a9643ea8Slogwang 
220a9643ea8Slogwang         /* Fill in constant or string argument directly */
221a9643ea8Slogwang 
222a9643ea8Slogwang         AcpiPsGetNextSimpleArg (&(WalkState->ParserState),
223a9643ea8Slogwang             GET_CURRENT_ARG_TYPE (WalkState->ArgTypes), Op);
224a9643ea8Slogwang         break;
225a9643ea8Slogwang 
226a9643ea8Slogwang     case AML_INT_NAMEPATH_OP:   /* AML_NAMESTRING_ARG */
227a9643ea8Slogwang 
228a9643ea8Slogwang         Status = AcpiPsGetNextNamepath (WalkState,
229a9643ea8Slogwang             &(WalkState->ParserState), Op, ACPI_POSSIBLE_METHOD_CALL);
230a9643ea8Slogwang         if (ACPI_FAILURE (Status))
231a9643ea8Slogwang         {
232a9643ea8Slogwang             return_ACPI_STATUS (Status);
233a9643ea8Slogwang         }
234a9643ea8Slogwang 
235a9643ea8Slogwang         WalkState->ArgTypes = 0;
236a9643ea8Slogwang         break;
237a9643ea8Slogwang 
238a9643ea8Slogwang     default:
239a9643ea8Slogwang         /*
240a9643ea8Slogwang          * Op is not a constant or string, append each argument to the Op
241a9643ea8Slogwang          */
242a9643ea8Slogwang         while (GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) &&
243a9643ea8Slogwang             !WalkState->ArgCount)
244a9643ea8Slogwang         {
245a9643ea8Slogwang             WalkState->Aml = WalkState->ParserState.Aml;
246a9643ea8Slogwang 
247*22ce4affSfengbojiang             switch (Op->Common.AmlOpcode)
248*22ce4affSfengbojiang             {
249*22ce4affSfengbojiang             case AML_METHOD_OP:
250*22ce4affSfengbojiang             case AML_BUFFER_OP:
251*22ce4affSfengbojiang             case AML_PACKAGE_OP:
252*22ce4affSfengbojiang             case AML_VARIABLE_PACKAGE_OP:
253*22ce4affSfengbojiang             case AML_WHILE_OP:
254*22ce4affSfengbojiang 
255*22ce4affSfengbojiang                 break;
256*22ce4affSfengbojiang 
257*22ce4affSfengbojiang             default:
258*22ce4affSfengbojiang 
259*22ce4affSfengbojiang                 ASL_CV_CAPTURE_COMMENTS (WalkState);
260*22ce4affSfengbojiang                 break;
261*22ce4affSfengbojiang             }
262*22ce4affSfengbojiang 
263a9643ea8Slogwang             Status = AcpiPsGetNextArg (WalkState, &(WalkState->ParserState),
264a9643ea8Slogwang                 GET_CURRENT_ARG_TYPE (WalkState->ArgTypes), &Arg);
265a9643ea8Slogwang             if (ACPI_FAILURE (Status))
266a9643ea8Slogwang             {
267a9643ea8Slogwang                 return_ACPI_STATUS (Status);
268a9643ea8Slogwang             }
269a9643ea8Slogwang 
270a9643ea8Slogwang             if (Arg)
271a9643ea8Slogwang             {
272a9643ea8Slogwang                 AcpiPsAppendArg (Op, Arg);
273a9643ea8Slogwang             }
274a9643ea8Slogwang 
275a9643ea8Slogwang             INCREMENT_ARG_LIST (WalkState->ArgTypes);
276a9643ea8Slogwang         }
277a9643ea8Slogwang 
278a9643ea8Slogwang         ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
279*22ce4affSfengbojiang             "Final argument count: %8.8X pass %u\n",
280*22ce4affSfengbojiang             WalkState->ArgCount, WalkState->PassNumber));
281a9643ea8Slogwang 
282a9643ea8Slogwang         /* Special processing for certain opcodes */
283a9643ea8Slogwang 
284a9643ea8Slogwang         switch (Op->Common.AmlOpcode)
285a9643ea8Slogwang         {
286a9643ea8Slogwang         case AML_METHOD_OP:
287a9643ea8Slogwang             /*
288a9643ea8Slogwang              * Skip parsing of control method because we don't have enough
289a9643ea8Slogwang              * info in the first pass to parse it correctly.
290a9643ea8Slogwang              *
291a9643ea8Slogwang              * Save the length and address of the body
292a9643ea8Slogwang              */
293a9643ea8Slogwang             Op->Named.Data = WalkState->ParserState.Aml;
294a9643ea8Slogwang             Op->Named.Length = (UINT32)
295a9643ea8Slogwang                 (WalkState->ParserState.PkgEnd - WalkState->ParserState.Aml);
296a9643ea8Slogwang 
297a9643ea8Slogwang             /* Skip body of method */
298a9643ea8Slogwang 
299a9643ea8Slogwang             WalkState->ParserState.Aml = WalkState->ParserState.PkgEnd;
300a9643ea8Slogwang             WalkState->ArgCount = 0;
301a9643ea8Slogwang             break;
302a9643ea8Slogwang 
303a9643ea8Slogwang         case AML_BUFFER_OP:
304a9643ea8Slogwang         case AML_PACKAGE_OP:
305*22ce4affSfengbojiang         case AML_VARIABLE_PACKAGE_OP:
306a9643ea8Slogwang 
307a9643ea8Slogwang             if ((Op->Common.Parent) &&
308a9643ea8Slogwang                 (Op->Common.Parent->Common.AmlOpcode == AML_NAME_OP) &&
309a9643ea8Slogwang                 (WalkState->PassNumber <= ACPI_IMODE_LOAD_PASS2))
310a9643ea8Slogwang             {
311*22ce4affSfengbojiang                 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
312*22ce4affSfengbojiang                     "Setup Package/Buffer: Pass %u, AML Ptr: %p\n",
313*22ce4affSfengbojiang                     WalkState->PassNumber, AmlOpStart));
314*22ce4affSfengbojiang 
315a9643ea8Slogwang                 /*
316a9643ea8Slogwang                  * Skip parsing of Buffers and Packages because we don't have
317a9643ea8Slogwang                  * enough info in the first pass to parse them correctly.
318a9643ea8Slogwang                  */
319a9643ea8Slogwang                 Op->Named.Data = AmlOpStart;
320a9643ea8Slogwang                 Op->Named.Length = (UINT32)
321a9643ea8Slogwang                     (WalkState->ParserState.PkgEnd - AmlOpStart);
322a9643ea8Slogwang 
323a9643ea8Slogwang                 /* Skip body */
324a9643ea8Slogwang 
325a9643ea8Slogwang                 WalkState->ParserState.Aml = WalkState->ParserState.PkgEnd;
326a9643ea8Slogwang                 WalkState->ArgCount = 0;
327a9643ea8Slogwang             }
328a9643ea8Slogwang             break;
329a9643ea8Slogwang 
330a9643ea8Slogwang         case AML_WHILE_OP:
331a9643ea8Slogwang 
332a9643ea8Slogwang             if (WalkState->ControlState)
333a9643ea8Slogwang             {
334a9643ea8Slogwang                 WalkState->ControlState->Control.PackageEnd =
335a9643ea8Slogwang                     WalkState->ParserState.PkgEnd;
336a9643ea8Slogwang             }
337a9643ea8Slogwang             break;
338a9643ea8Slogwang 
339a9643ea8Slogwang         default:
340a9643ea8Slogwang 
341a9643ea8Slogwang             /* No action for all other opcodes */
342a9643ea8Slogwang 
343a9643ea8Slogwang             break;
344a9643ea8Slogwang         }
345a9643ea8Slogwang 
346a9643ea8Slogwang         break;
347a9643ea8Slogwang     }
348a9643ea8Slogwang 
349a9643ea8Slogwang     return_ACPI_STATUS (AE_OK);
350a9643ea8Slogwang }
351a9643ea8Slogwang 
352a9643ea8Slogwang 
353a9643ea8Slogwang /*******************************************************************************
354a9643ea8Slogwang  *
355a9643ea8Slogwang  * FUNCTION:    AcpiPsParseLoop
356a9643ea8Slogwang  *
357a9643ea8Slogwang  * PARAMETERS:  WalkState           - Current state
358a9643ea8Slogwang  *
359a9643ea8Slogwang  * RETURN:      Status
360a9643ea8Slogwang  *
361a9643ea8Slogwang  * DESCRIPTION: Parse AML (pointed to by the current parser state) and return
362a9643ea8Slogwang  *              a tree of ops.
363a9643ea8Slogwang  *
364a9643ea8Slogwang  ******************************************************************************/
365a9643ea8Slogwang 
366a9643ea8Slogwang ACPI_STATUS
AcpiPsParseLoop(ACPI_WALK_STATE * WalkState)367a9643ea8Slogwang AcpiPsParseLoop (
368a9643ea8Slogwang     ACPI_WALK_STATE         *WalkState)
369a9643ea8Slogwang {
370a9643ea8Slogwang     ACPI_STATUS             Status = AE_OK;
371a9643ea8Slogwang     ACPI_PARSE_OBJECT       *Op = NULL;     /* current op */
372a9643ea8Slogwang     ACPI_PARSE_STATE        *ParserState;
373a9643ea8Slogwang     UINT8                   *AmlOpStart = NULL;
374*22ce4affSfengbojiang     UINT8                   OpcodeLength;
375a9643ea8Slogwang 
376a9643ea8Slogwang 
377a9643ea8Slogwang     ACPI_FUNCTION_TRACE_PTR (PsParseLoop, WalkState);
378a9643ea8Slogwang 
379a9643ea8Slogwang 
380a9643ea8Slogwang     if (WalkState->DescendingCallback == NULL)
381a9643ea8Slogwang     {
382a9643ea8Slogwang         return_ACPI_STATUS (AE_BAD_PARAMETER);
383a9643ea8Slogwang     }
384a9643ea8Slogwang 
385a9643ea8Slogwang     ParserState = &WalkState->ParserState;
386a9643ea8Slogwang     WalkState->ArgTypes = 0;
387a9643ea8Slogwang 
388*22ce4affSfengbojiang #ifndef ACPI_CONSTANT_EVAL_ONLY
389a9643ea8Slogwang 
390a9643ea8Slogwang     if (WalkState->WalkType & ACPI_WALK_METHOD_RESTART)
391a9643ea8Slogwang     {
392a9643ea8Slogwang         /* We are restarting a preempted control method */
393a9643ea8Slogwang 
394a9643ea8Slogwang         if (AcpiPsHasCompletedScope (ParserState))
395a9643ea8Slogwang         {
396a9643ea8Slogwang             /*
397a9643ea8Slogwang              * We must check if a predicate to an IF or WHILE statement
398a9643ea8Slogwang              * was just completed
399a9643ea8Slogwang              */
400a9643ea8Slogwang             if ((ParserState->Scope->ParseScope.Op) &&
401a9643ea8Slogwang                ((ParserState->Scope->ParseScope.Op->Common.AmlOpcode == AML_IF_OP) ||
402a9643ea8Slogwang                 (ParserState->Scope->ParseScope.Op->Common.AmlOpcode == AML_WHILE_OP)) &&
403a9643ea8Slogwang                 (WalkState->ControlState) &&
404a9643ea8Slogwang                 (WalkState->ControlState->Common.State ==
405a9643ea8Slogwang                     ACPI_CONTROL_PREDICATE_EXECUTING))
406a9643ea8Slogwang             {
407a9643ea8Slogwang                 /*
408a9643ea8Slogwang                  * A predicate was just completed, get the value of the
409a9643ea8Slogwang                  * predicate and branch based on that value
410a9643ea8Slogwang                  */
411a9643ea8Slogwang                 WalkState->Op = NULL;
412a9643ea8Slogwang                 Status = AcpiDsGetPredicateValue (WalkState, ACPI_TO_POINTER (TRUE));
413a9643ea8Slogwang                 if (ACPI_FAILURE (Status) &&
414a9643ea8Slogwang                     ((Status & AE_CODE_MASK) != AE_CODE_CONTROL))
415a9643ea8Slogwang                 {
416a9643ea8Slogwang                     if (Status == AE_AML_NO_RETURN_VALUE)
417a9643ea8Slogwang                     {
418a9643ea8Slogwang                         ACPI_EXCEPTION ((AE_INFO, Status,
419a9643ea8Slogwang                             "Invoked method did not return a value"));
420a9643ea8Slogwang                     }
421a9643ea8Slogwang 
422a9643ea8Slogwang                     ACPI_EXCEPTION ((AE_INFO, Status, "GetPredicate Failed"));
423a9643ea8Slogwang                     return_ACPI_STATUS (Status);
424a9643ea8Slogwang                 }
425a9643ea8Slogwang 
426a9643ea8Slogwang                 Status = AcpiPsNextParseState (WalkState, Op, Status);
427a9643ea8Slogwang             }
428a9643ea8Slogwang 
429a9643ea8Slogwang             AcpiPsPopScope (ParserState, &Op,
430a9643ea8Slogwang                 &WalkState->ArgTypes, &WalkState->ArgCount);
431a9643ea8Slogwang             ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", Op));
432a9643ea8Slogwang         }
433a9643ea8Slogwang         else if (WalkState->PrevOp)
434a9643ea8Slogwang         {
435a9643ea8Slogwang             /* We were in the middle of an op */
436a9643ea8Slogwang 
437a9643ea8Slogwang             Op = WalkState->PrevOp;
438a9643ea8Slogwang             WalkState->ArgTypes = WalkState->PrevArgTypes;
439a9643ea8Slogwang         }
440a9643ea8Slogwang     }
441a9643ea8Slogwang #endif
442a9643ea8Slogwang 
443a9643ea8Slogwang     /* Iterative parsing loop, while there is more AML to process: */
444a9643ea8Slogwang 
445a9643ea8Slogwang     while ((ParserState->Aml < ParserState->AmlEnd) || (Op))
446a9643ea8Slogwang     {
447*22ce4affSfengbojiang         ASL_CV_CAPTURE_COMMENTS (WalkState);
448*22ce4affSfengbojiang 
449a9643ea8Slogwang         AmlOpStart = ParserState->Aml;
450a9643ea8Slogwang         if (!Op)
451a9643ea8Slogwang         {
452a9643ea8Slogwang             Status = AcpiPsCreateOp (WalkState, AmlOpStart, &Op);
453a9643ea8Slogwang             if (ACPI_FAILURE (Status))
454a9643ea8Slogwang             {
455*22ce4affSfengbojiang                 /*
456*22ce4affSfengbojiang                  * ACPI_PARSE_MODULE_LEVEL means that we are loading a table by
457*22ce4affSfengbojiang                  * executing it as a control method. However, if we encounter
458*22ce4affSfengbojiang                  * an error while loading the table, we need to keep trying to
459*22ce4affSfengbojiang                  * load the table rather than aborting the table load. Set the
460*22ce4affSfengbojiang                  * status to AE_OK to proceed with the table load.
461*22ce4affSfengbojiang                  */
462*22ce4affSfengbojiang                 if ((WalkState->ParseFlags & ACPI_PARSE_MODULE_LEVEL) &&
463*22ce4affSfengbojiang                     ((Status == AE_ALREADY_EXISTS) || (Status == AE_NOT_FOUND)))
464*22ce4affSfengbojiang                 {
465*22ce4affSfengbojiang                     Status = AE_OK;
466*22ce4affSfengbojiang                 }
467a9643ea8Slogwang                 if (Status == AE_CTRL_PARSE_CONTINUE)
468a9643ea8Slogwang                 {
469a9643ea8Slogwang                     continue;
470a9643ea8Slogwang                 }
471a9643ea8Slogwang 
472a9643ea8Slogwang                 if (Status == AE_CTRL_PARSE_PENDING)
473a9643ea8Slogwang                 {
474a9643ea8Slogwang                     Status = AE_OK;
475a9643ea8Slogwang                 }
476a9643ea8Slogwang 
477a9643ea8Slogwang                 if (Status == AE_CTRL_TERMINATE)
478a9643ea8Slogwang                 {
479a9643ea8Slogwang                     return_ACPI_STATUS (Status);
480a9643ea8Slogwang                 }
481a9643ea8Slogwang 
482a9643ea8Slogwang                 Status = AcpiPsCompleteOp (WalkState, &Op, Status);
483a9643ea8Slogwang                 if (ACPI_FAILURE (Status))
484a9643ea8Slogwang                 {
485a9643ea8Slogwang                     return_ACPI_STATUS (Status);
486a9643ea8Slogwang                 }
487*22ce4affSfengbojiang                 if (AcpiNsOpensScope (
488*22ce4affSfengbojiang                     AcpiPsGetOpcodeInfo (WalkState->Opcode)->ObjectType))
489*22ce4affSfengbojiang                 {
490*22ce4affSfengbojiang                     /*
491*22ce4affSfengbojiang                      * If the scope/device op fails to parse, skip the body of
492*22ce4affSfengbojiang                      * the scope op because the parse failure indicates that
493*22ce4affSfengbojiang                      * the device may not exist.
494*22ce4affSfengbojiang                      */
495*22ce4affSfengbojiang                     ACPI_INFO (("Skipping parse of AML opcode: %s (0x%4.4X)",
496*22ce4affSfengbojiang                         AcpiPsGetOpcodeName (WalkState->Opcode), WalkState->Opcode));
497*22ce4affSfengbojiang 
498*22ce4affSfengbojiang                     /*
499*22ce4affSfengbojiang                      * Determine the opcode length before skipping the opcode.
500*22ce4affSfengbojiang                      * An opcode can be 1 byte or 2 bytes in length.
501*22ce4affSfengbojiang                      */
502*22ce4affSfengbojiang                     OpcodeLength = 1;
503*22ce4affSfengbojiang                     if ((WalkState->Opcode & 0xFF00) == AML_EXTENDED_OPCODE)
504*22ce4affSfengbojiang                     {
505*22ce4affSfengbojiang                         OpcodeLength = 2;
506*22ce4affSfengbojiang                     }
507*22ce4affSfengbojiang                     WalkState->ParserState.Aml = WalkState->Aml + OpcodeLength;
508*22ce4affSfengbojiang 
509*22ce4affSfengbojiang                     WalkState->ParserState.Aml =
510*22ce4affSfengbojiang                         AcpiPsGetNextPackageEnd(&WalkState->ParserState);
511*22ce4affSfengbojiang                     WalkState->Aml = WalkState->ParserState.Aml;
512*22ce4affSfengbojiang                 }
513a9643ea8Slogwang 
514a9643ea8Slogwang                 continue;
515a9643ea8Slogwang             }
516a9643ea8Slogwang 
517a9643ea8Slogwang             AcpiExStartTraceOpcode (Op, WalkState);
518a9643ea8Slogwang         }
519a9643ea8Slogwang 
520a9643ea8Slogwang         /*
521a9643ea8Slogwang          * Start ArgCount at zero because we don't know if there are
522a9643ea8Slogwang          * any args yet
523a9643ea8Slogwang          */
524a9643ea8Slogwang         WalkState->ArgCount = 0;
525a9643ea8Slogwang 
526*22ce4affSfengbojiang         switch (Op->Common.AmlOpcode)
527*22ce4affSfengbojiang         {
528*22ce4affSfengbojiang         case AML_BYTE_OP:
529*22ce4affSfengbojiang         case AML_WORD_OP:
530*22ce4affSfengbojiang         case AML_DWORD_OP:
531*22ce4affSfengbojiang         case AML_QWORD_OP:
532*22ce4affSfengbojiang 
533*22ce4affSfengbojiang             break;
534*22ce4affSfengbojiang 
535*22ce4affSfengbojiang         default:
536*22ce4affSfengbojiang 
537*22ce4affSfengbojiang             ASL_CV_CAPTURE_COMMENTS (WalkState);
538*22ce4affSfengbojiang             break;
539*22ce4affSfengbojiang         }
540*22ce4affSfengbojiang 
541a9643ea8Slogwang         /* Are there any arguments that must be processed? */
542a9643ea8Slogwang 
543a9643ea8Slogwang         if (WalkState->ArgTypes)
544a9643ea8Slogwang         {
545a9643ea8Slogwang             /* Get arguments */
546a9643ea8Slogwang 
547a9643ea8Slogwang             Status = AcpiPsGetArguments (WalkState, AmlOpStart, Op);
548a9643ea8Slogwang             if (ACPI_FAILURE (Status))
549a9643ea8Slogwang             {
550a9643ea8Slogwang                 Status = AcpiPsCompleteOp (WalkState, &Op, Status);
551a9643ea8Slogwang                 if (ACPI_FAILURE (Status))
552a9643ea8Slogwang                 {
553a9643ea8Slogwang                     return_ACPI_STATUS (Status);
554a9643ea8Slogwang                 }
555*22ce4affSfengbojiang                 if ((WalkState->ControlState) &&
556*22ce4affSfengbojiang                     ((WalkState->ControlState->Control.Opcode == AML_IF_OP) ||
557*22ce4affSfengbojiang                     (WalkState->ControlState->Control.Opcode == AML_WHILE_OP)))
558*22ce4affSfengbojiang                 {
559*22ce4affSfengbojiang                     /*
560*22ce4affSfengbojiang                      * If the if/while op fails to parse, we will skip parsing
561*22ce4affSfengbojiang                      * the body of the op.
562*22ce4affSfengbojiang                      */
563*22ce4affSfengbojiang                     ParserState->Aml =
564*22ce4affSfengbojiang                         WalkState->ControlState->Control.AmlPredicateStart + 1;
565*22ce4affSfengbojiang                     ParserState->Aml =
566*22ce4affSfengbojiang                         AcpiPsGetNextPackageEnd (ParserState);
567*22ce4affSfengbojiang                     WalkState->Aml = ParserState->Aml;
568a9643ea8Slogwang 
569*22ce4affSfengbojiang                     ACPI_ERROR ((AE_INFO, "Skipping While/If block"));
570*22ce4affSfengbojiang                     if (*WalkState->Aml == AML_ELSE_OP)
571*22ce4affSfengbojiang                     {
572*22ce4affSfengbojiang                         ACPI_ERROR ((AE_INFO, "Skipping Else block"));
573*22ce4affSfengbojiang                         WalkState->ParserState.Aml = WalkState->Aml + 1;
574*22ce4affSfengbojiang                         WalkState->ParserState.Aml =
575*22ce4affSfengbojiang                             AcpiPsGetNextPackageEnd (ParserState);
576*22ce4affSfengbojiang                         WalkState->Aml = ParserState->Aml;
577*22ce4affSfengbojiang                     }
578*22ce4affSfengbojiang                     ACPI_FREE(AcpiUtPopGenericState (&WalkState->ControlState));
579*22ce4affSfengbojiang                 }
580*22ce4affSfengbojiang                 Op = NULL;
581a9643ea8Slogwang                 continue;
582a9643ea8Slogwang             }
583a9643ea8Slogwang         }
584a9643ea8Slogwang 
585a9643ea8Slogwang         /* Check for arguments that need to be processed */
586a9643ea8Slogwang 
587*22ce4affSfengbojiang         ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
588*22ce4affSfengbojiang             "Parseloop: argument count: %8.8X\n", WalkState->ArgCount));
589*22ce4affSfengbojiang 
590a9643ea8Slogwang         if (WalkState->ArgCount)
591a9643ea8Slogwang         {
592a9643ea8Slogwang             /*
593a9643ea8Slogwang              * There are arguments (complex ones), push Op and
594a9643ea8Slogwang              * prepare for argument
595a9643ea8Slogwang              */
596a9643ea8Slogwang             Status = AcpiPsPushScope (ParserState, Op,
597a9643ea8Slogwang                 WalkState->ArgTypes, WalkState->ArgCount);
598a9643ea8Slogwang             if (ACPI_FAILURE (Status))
599a9643ea8Slogwang             {
600a9643ea8Slogwang                 Status = AcpiPsCompleteOp (WalkState, &Op, Status);
601a9643ea8Slogwang                 if (ACPI_FAILURE (Status))
602a9643ea8Slogwang                 {
603a9643ea8Slogwang                     return_ACPI_STATUS (Status);
604a9643ea8Slogwang                 }
605a9643ea8Slogwang 
606a9643ea8Slogwang                 continue;
607a9643ea8Slogwang             }
608a9643ea8Slogwang 
609a9643ea8Slogwang             Op = NULL;
610a9643ea8Slogwang             continue;
611a9643ea8Slogwang         }
612a9643ea8Slogwang 
613a9643ea8Slogwang         /*
614a9643ea8Slogwang          * All arguments have been processed -- Op is complete,
615a9643ea8Slogwang          * prepare for next
616a9643ea8Slogwang          */
617a9643ea8Slogwang         WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
618a9643ea8Slogwang         if (WalkState->OpInfo->Flags & AML_NAMED)
619a9643ea8Slogwang         {
620a9643ea8Slogwang             if (Op->Common.AmlOpcode == AML_REGION_OP ||
621a9643ea8Slogwang                 Op->Common.AmlOpcode == AML_DATA_REGION_OP)
622a9643ea8Slogwang             {
623a9643ea8Slogwang                 /*
624a9643ea8Slogwang                  * Skip parsing of control method or opregion body,
625a9643ea8Slogwang                  * because we don't have enough info in the first pass
626a9643ea8Slogwang                  * to parse them correctly.
627a9643ea8Slogwang                  *
628a9643ea8Slogwang                  * Completed parsing an OpRegion declaration, we now
629a9643ea8Slogwang                  * know the length.
630a9643ea8Slogwang                  */
631a9643ea8Slogwang                 Op->Named.Length = (UINT32) (ParserState->Aml - Op->Named.Data);
632a9643ea8Slogwang             }
633a9643ea8Slogwang         }
634a9643ea8Slogwang 
635a9643ea8Slogwang         if (WalkState->OpInfo->Flags & AML_CREATE)
636a9643ea8Slogwang         {
637a9643ea8Slogwang             /*
638a9643ea8Slogwang              * Backup to beginning of CreateXXXfield declaration (1 for
639a9643ea8Slogwang              * Opcode)
640a9643ea8Slogwang              *
641a9643ea8Slogwang              * BodyLength is unknown until we parse the body
642a9643ea8Slogwang              */
643a9643ea8Slogwang             Op->Named.Length = (UINT32) (ParserState->Aml - Op->Named.Data);
644a9643ea8Slogwang         }
645a9643ea8Slogwang 
646a9643ea8Slogwang         if (Op->Common.AmlOpcode == AML_BANK_FIELD_OP)
647a9643ea8Slogwang         {
648a9643ea8Slogwang             /*
649a9643ea8Slogwang              * Backup to beginning of BankField declaration
650a9643ea8Slogwang              *
651a9643ea8Slogwang              * BodyLength is unknown until we parse the body
652a9643ea8Slogwang              */
653a9643ea8Slogwang             Op->Named.Length = (UINT32) (ParserState->Aml - Op->Named.Data);
654a9643ea8Slogwang         }
655a9643ea8Slogwang 
656a9643ea8Slogwang         /* This op complete, notify the dispatcher */
657a9643ea8Slogwang 
658a9643ea8Slogwang         if (WalkState->AscendingCallback != NULL)
659a9643ea8Slogwang         {
660a9643ea8Slogwang             WalkState->Op = Op;
661a9643ea8Slogwang             WalkState->Opcode = Op->Common.AmlOpcode;
662a9643ea8Slogwang 
663a9643ea8Slogwang             Status = WalkState->AscendingCallback (WalkState);
664a9643ea8Slogwang             Status = AcpiPsNextParseState (WalkState, Op, Status);
665a9643ea8Slogwang             if (Status == AE_CTRL_PENDING)
666a9643ea8Slogwang             {
667a9643ea8Slogwang                 Status = AE_OK;
668a9643ea8Slogwang             }
669*22ce4affSfengbojiang             else if ((WalkState->ParseFlags & ACPI_PARSE_MODULE_LEVEL) &&
670*22ce4affSfengbojiang                 (ACPI_AML_EXCEPTION(Status) || Status == AE_ALREADY_EXISTS ||
671*22ce4affSfengbojiang                 Status == AE_NOT_FOUND))
672*22ce4affSfengbojiang             {
673*22ce4affSfengbojiang                 /*
674*22ce4affSfengbojiang                  * ACPI_PARSE_MODULE_LEVEL flag means that we are currently
675*22ce4affSfengbojiang                  * loading a table by executing it as a control method.
676*22ce4affSfengbojiang                  * However, if we encounter an error while loading the table,
677*22ce4affSfengbojiang                  * we need to keep trying to load the table rather than
678*22ce4affSfengbojiang                  * aborting the table load (setting the status to AE_OK
679*22ce4affSfengbojiang                  * continues the table load). If we get a failure at this
680*22ce4affSfengbojiang                  * point, it means that the dispatcher got an error while
681*22ce4affSfengbojiang                  * trying to execute the Op.
682*22ce4affSfengbojiang                  */
683*22ce4affSfengbojiang                 Status = AE_OK;
684*22ce4affSfengbojiang             }
685a9643ea8Slogwang         }
686a9643ea8Slogwang 
687a9643ea8Slogwang         Status = AcpiPsCompleteOp (WalkState, &Op, Status);
688a9643ea8Slogwang         if (ACPI_FAILURE (Status))
689a9643ea8Slogwang         {
690a9643ea8Slogwang             return_ACPI_STATUS (Status);
691a9643ea8Slogwang         }
692a9643ea8Slogwang 
693a9643ea8Slogwang     } /* while ParserState->Aml */
694a9643ea8Slogwang 
695a9643ea8Slogwang     Status = AcpiPsCompleteFinalOp (WalkState, Op, Status);
696a9643ea8Slogwang     return_ACPI_STATUS (Status);
697a9643ea8Slogwang }
698