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