1 /******************************************************************************
3 * Module Name: psloop - Main AML parse loop
6 *****************************************************************************/
8 /******************************************************************************
12 * Some or all of this work - Copyright (c) 1999 - 2006, Intel Corp.
13 * All rights reserved.
17 * 2.1. This is your license from Intel Corp. under its intellectual property
18 * rights. You may have additional license terms from the party that provided
19 * you this software, covering your right to use that party's intellectual
22 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
23 * copy of the source code appearing in this file ("Covered Code") an
24 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25 * base code distributed originally by Intel ("Original Intel Code") to copy,
26 * make derivatives, distribute, use and display any portion of the Covered
27 * Code in any form, with the right to sublicense such rights; and
29 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30 * license (with the right to sublicense), under only those claims of Intel
31 * patents that are infringed by the Original Intel Code, to make, use, sell,
32 * offer to sell, and import the Covered Code and derivative works thereof
33 * solely to the minimum extent necessary to exercise the above copyright
34 * license, and in no event shall the patent license extend to any additions
35 * to or modifications of the Original Intel Code. No other license or right
36 * is granted directly or by implication, estoppel or otherwise;
38 * The above copyright and patent license is granted only if the following
43 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44 * Redistribution of source code of any substantial portion of the Covered
45 * Code or modification with rights to further distribute source must include
46 * the above Copyright Notice, the above License, this list of Conditions,
47 * and the following Disclaimer and Export Compliance provision. In addition,
48 * Licensee must cause all Covered Code to which Licensee contributes to
49 * contain a file documenting the changes Licensee made to create that Covered
50 * Code and the date of any change. Licensee must include in that file the
51 * documentation of any changes made by any predecessor Licensee. Licensee
52 * must include a prominent statement that the modification is derived,
53 * directly or indirectly, from Original Intel Code.
55 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
56 * Redistribution of source code of any substantial portion of the Covered
57 * Code or modification without rights to further distribute source must
58 * include the following Disclaimer and Export Compliance provision in the
59 * documentation and/or other materials provided with distribution. In
60 * addition, Licensee may not authorize further sublicense of source of any
61 * portion of the Covered Code, and must include terms to the effect that the
62 * license from Licensee to its licensee is limited to the intellectual
63 * property embodied in the software Licensee provides to its licensee, and
64 * not to intellectual property embodied in modifications its licensee may
67 * 3.3. Redistribution of Executable. Redistribution in executable form of any
68 * substantial portion of the Covered Code or modification must reproduce the
69 * above Copyright Notice, and the following Disclaimer and Export Compliance
70 * provision in the documentation and/or other materials provided with the
73 * 3.4. Intel retains all right, title, and interest in and to the Original
76 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
77 * Intel shall be used in advertising or otherwise to promote the sale, use or
78 * other dealings in products derived from or relating to the Covered Code
79 * without prior written authorization from Intel.
81 * 4. Disclaimer and Export Compliance
83 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
84 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
85 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
86 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
87 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
88 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
91 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
93 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
95 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
96 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
97 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
100 * 4.3. Licensee shall not export, either directly or indirectly, any of this
101 * software or system incorporating such software without first obtaining any
102 * required license or other approval from the U. S. Department of Commerce or
103 * any other agency or department of the United States Government. In the
104 * event Licensee exports any such software from the United States or
105 * re-exports any such software from a foreign destination, Licensee shall
106 * ensure that the distribution and export/re-export of the software is in
107 * compliance with all laws, regulations, orders, or other restrictions of the
108 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
109 * any of its subsidiaries will export/re-export any technical data, process,
110 * software, or service, directly or indirectly, to any country for which the
111 * United States government or any agency thereof requires an export license,
112 * other governmental approval, or letter of assurance, without first obtaining
113 * such license, approval or letter.
115 *****************************************************************************/
119 * Parse the AML and build an operation tree as most interpreters, (such as
120 * Perl) do. Parsing is done by hand rather than with a YACC generated parser
121 * to tightly constrain stack and dynamic memory usage. Parsing is kept
122 * flexible and the code fairly compact by parsing based on a list of AML
123 * opcode templates in AmlOpInfo[].
127 #include "acparser.h"
128 #include "acdispat.h"
131 #define _COMPONENT ACPI_PARSER
132 ACPI_MODULE_NAME ("psloop")
134 static UINT32 AcpiGbl_Depth
= 0;
137 /* Local prototypes */
141 ACPI_WALK_STATE
*WalkState
);
145 ACPI_WALK_STATE
*WalkState
,
147 ACPI_PARSE_OBJECT
*UnnamedOp
,
148 ACPI_PARSE_OBJECT
**Op
);
152 ACPI_WALK_STATE
*WalkState
,
154 ACPI_PARSE_OBJECT
**NewOp
);
158 ACPI_WALK_STATE
*WalkState
,
160 ACPI_PARSE_OBJECT
*Op
);
164 ACPI_WALK_STATE
*WalkState
,
165 ACPI_PARSE_OBJECT
**Op
,
169 AcpiPsCompleteFinalOp (
170 ACPI_WALK_STATE
*WalkState
,
171 ACPI_PARSE_OBJECT
*Op
,
175 /*******************************************************************************
177 * FUNCTION: AcpiPsGetAmlOpcode
179 * PARAMETERS: WalkState - Current state
183 * DESCRIPTION: Extract the next AML opcode from the input stream.
185 ******************************************************************************/
189 ACPI_WALK_STATE
*WalkState
)
192 ACPI_FUNCTION_TRACE_PTR (PsGetAmlOpcode
, WalkState
);
195 WalkState
->AmlOffset
= (UINT32
) ACPI_PTR_DIFF (WalkState
->ParserState
.Aml
,
196 WalkState
->ParserState
.AmlStart
);
197 WalkState
->Opcode
= AcpiPsPeekOpcode (&(WalkState
->ParserState
));
200 * First cut to determine what we have found:
201 * 1) A valid AML opcode
203 * 3) An unknown/invalid opcode
205 WalkState
->OpInfo
= AcpiPsGetOpcodeInfo (WalkState
->Opcode
);
207 switch (WalkState
->OpInfo
->Class
)
209 case AML_CLASS_ASCII
:
210 case AML_CLASS_PREFIX
:
212 * Starts with a valid prefix or ASCII char, this is a name
213 * string. Convert the bare name string to a namepath.
215 WalkState
->Opcode
= AML_INT_NAMEPATH_OP
;
216 WalkState
->ArgTypes
= ARGP_NAMESTRING
;
219 case AML_CLASS_UNKNOWN
:
221 /* The opcode is unrecognized. Just skip unknown opcodes */
223 ACPI_ERROR ((AE_INFO
,
224 "Found unknown opcode %X at AML address %p offset %X, ignoring",
225 WalkState
->Opcode
, WalkState
->ParserState
.Aml
, WalkState
->AmlOffset
));
227 ACPI_DUMP_BUFFER (WalkState
->ParserState
.Aml
, 128);
229 /* Assume one-byte bad opcode */
231 WalkState
->ParserState
.Aml
++;
232 return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE
);
236 /* Found opcode info, this is a normal opcode */
238 WalkState
->ParserState
.Aml
+= AcpiPsGetOpcodeSize (WalkState
->Opcode
);
239 WalkState
->ArgTypes
= WalkState
->OpInfo
->ParseArgs
;
243 return_ACPI_STATUS (AE_OK
);
247 /*******************************************************************************
249 * FUNCTION: AcpiPsBuildNamedOp
251 * PARAMETERS: WalkState - Current state
252 * AmlOpStart - Begin of named Op in AML
253 * UnnamedOp - Early Op (not a named Op)
258 * DESCRIPTION: Parse a named Op
260 ******************************************************************************/
264 ACPI_WALK_STATE
*WalkState
,
266 ACPI_PARSE_OBJECT
*UnnamedOp
,
267 ACPI_PARSE_OBJECT
**Op
)
269 ACPI_STATUS Status
= AE_OK
;
270 ACPI_PARSE_OBJECT
*Arg
= NULL
;
273 ACPI_FUNCTION_TRACE_PTR (PsBuildNamedOp
, WalkState
);
276 UnnamedOp
->Common
.Value
.Arg
= NULL
;
277 UnnamedOp
->Common
.AmlOpcode
= WalkState
->Opcode
;
280 * Get and append arguments until we find the node that contains
281 * the name (the type ARGP_NAME).
283 while (GET_CURRENT_ARG_TYPE (WalkState
->ArgTypes
) &&
284 (GET_CURRENT_ARG_TYPE (WalkState
->ArgTypes
) != ARGP_NAME
))
286 Status
= AcpiPsGetNextArg (WalkState
, &(WalkState
->ParserState
),
287 GET_CURRENT_ARG_TYPE (WalkState
->ArgTypes
), &Arg
);
288 if (ACPI_FAILURE (Status
))
290 return_ACPI_STATUS (Status
);
293 AcpiPsAppendArg (UnnamedOp
, Arg
);
294 INCREMENT_ARG_LIST (WalkState
->ArgTypes
);
298 * Make sure that we found a NAME and didn't run out of arguments
300 if (!GET_CURRENT_ARG_TYPE (WalkState
->ArgTypes
))
302 return_ACPI_STATUS (AE_AML_NO_OPERAND
);
305 /* We know that this arg is a name, move to next arg */
307 INCREMENT_ARG_LIST (WalkState
->ArgTypes
);
310 * Find the object. This will either insert the object into
311 * the namespace or simply look it up
313 WalkState
->Op
= NULL
;
315 Status
= WalkState
->DescendingCallback (WalkState
, Op
);
316 if (ACPI_FAILURE (Status
))
318 ACPI_EXCEPTION ((AE_INFO
, Status
, "During name lookup/catalog"));
319 return_ACPI_STATUS (Status
);
324 return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE
);
327 Status
= AcpiPsNextParseState (WalkState
, *Op
, Status
);
328 if (ACPI_FAILURE (Status
))
330 if (Status
== AE_CTRL_PENDING
)
332 return_ACPI_STATUS (AE_CTRL_PARSE_PENDING
);
334 return_ACPI_STATUS (Status
);
337 AcpiPsAppendArg (*Op
, UnnamedOp
->Common
.Value
.Arg
);
340 if ((*Op
)->Common
.AmlOpcode
== AML_REGION_OP
)
343 * Defer final parsing of an OperationRegion body, because we don't
344 * have enough info in the first pass to parse it correctly (i.e.,
345 * there may be method calls within the TermArg elements of the body.)
347 * However, we must continue parsing because the opregion is not a
348 * standalone package -- we don't know where the end is at this point.
350 * (Length is unknown until parse of the body complete)
352 (*Op
)->Named
.Data
= AmlOpStart
;
353 (*Op
)->Named
.Length
= 0;
356 return_ACPI_STATUS (AE_OK
);
360 /*******************************************************************************
362 * FUNCTION: AcpiPsCreateOp
364 * PARAMETERS: WalkState - Current state
365 * AmlOpStart - Op start in AML
366 * NewOp - Returned Op
370 * DESCRIPTION: Get Op from AML
372 ******************************************************************************/
376 ACPI_WALK_STATE
*WalkState
,
378 ACPI_PARSE_OBJECT
**NewOp
)
380 ACPI_STATUS Status
= AE_OK
;
381 ACPI_PARSE_OBJECT
*Op
;
382 ACPI_PARSE_OBJECT
*NamedOp
= NULL
;
385 ACPI_FUNCTION_TRACE_PTR (PsCreateOp
, WalkState
);
388 Status
= AcpiPsGetAmlOpcode (WalkState
);
389 if (Status
== AE_CTRL_PARSE_CONTINUE
)
391 return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE
);
394 /* Create Op structure and append to parent's argument list */
396 WalkState
->OpInfo
= AcpiPsGetOpcodeInfo (WalkState
->Opcode
);
397 Op
= AcpiPsAllocOp (WalkState
->Opcode
);
400 return_ACPI_STATUS (AE_NO_MEMORY
);
403 if (WalkState
->OpInfo
->Flags
& AML_NAMED
)
405 Status
= AcpiPsBuildNamedOp (WalkState
, AmlOpStart
, Op
, &NamedOp
);
407 if (ACPI_FAILURE (Status
))
409 return_ACPI_STATUS (Status
);
413 return_ACPI_STATUS (AE_OK
);
416 /* Not a named opcode, just allocate Op and append to parent */
418 if (WalkState
->OpInfo
->Flags
& AML_CREATE
)
421 * Backup to beginning of CreateXXXfield declaration
422 * BodyLength is unknown until we parse the body
424 Op
->Named
.Data
= AmlOpStart
;
425 Op
->Named
.Length
= 0;
428 AcpiPsAppendArg (AcpiPsGetParentScope (&(WalkState
->ParserState
)), Op
);
430 if (WalkState
->DescendingCallback
!= NULL
)
433 * Find the object. This will either insert the object into
434 * the namespace or simply look it up
436 WalkState
->Op
= *NewOp
= Op
;
438 Status
= WalkState
->DescendingCallback (WalkState
, &Op
);
439 Status
= AcpiPsNextParseState (WalkState
, Op
, Status
);
440 if (Status
== AE_CTRL_PENDING
)
442 Status
= AE_CTRL_PARSE_PENDING
;
446 return_ACPI_STATUS (Status
);
450 /*******************************************************************************
452 * FUNCTION: AcpiPsGetArguments
454 * PARAMETERS: WalkState - Current state
455 * AmlOpStart - Op start in AML
460 * DESCRIPTION: Get arguments for passed Op.
462 ******************************************************************************/
466 ACPI_WALK_STATE
*WalkState
,
468 ACPI_PARSE_OBJECT
*Op
)
470 ACPI_STATUS Status
= AE_OK
;
471 ACPI_PARSE_OBJECT
*Arg
= NULL
;
474 ACPI_FUNCTION_TRACE_PTR (PsGetArguments
, WalkState
);
477 switch (Op
->Common
.AmlOpcode
)
479 case AML_BYTE_OP
: /* AML_BYTEDATA_ARG */
480 case AML_WORD_OP
: /* AML_WORDDATA_ARG */
481 case AML_DWORD_OP
: /* AML_DWORDATA_ARG */
482 case AML_QWORD_OP
: /* AML_QWORDATA_ARG */
483 case AML_STRING_OP
: /* AML_ASCIICHARLIST_ARG */
485 /* Fill in constant or string argument directly */
487 AcpiPsGetNextSimpleArg (&(WalkState
->ParserState
),
488 GET_CURRENT_ARG_TYPE (WalkState
->ArgTypes
), Op
);
491 case AML_INT_NAMEPATH_OP
: /* AML_NAMESTRING_ARG */
493 Status
= AcpiPsGetNextNamepath (WalkState
, &(WalkState
->ParserState
), Op
, 1);
494 if (ACPI_FAILURE (Status
))
496 return_ACPI_STATUS (Status
);
499 WalkState
->ArgTypes
= 0;
504 * Op is not a constant or string, append each argument to the Op
506 while (GET_CURRENT_ARG_TYPE (WalkState
->ArgTypes
) && !WalkState
->ArgCount
)
508 WalkState
->AmlOffset
= (UINT32
) ACPI_PTR_DIFF (WalkState
->ParserState
.Aml
,
509 WalkState
->ParserState
.AmlStart
);
511 Status
= AcpiPsGetNextArg (WalkState
, &(WalkState
->ParserState
),
512 GET_CURRENT_ARG_TYPE (WalkState
->ArgTypes
), &Arg
);
513 if (ACPI_FAILURE (Status
))
515 return_ACPI_STATUS (Status
);
520 Arg
->Common
.AmlOffset
= WalkState
->AmlOffset
;
521 AcpiPsAppendArg (Op
, Arg
);
524 INCREMENT_ARG_LIST (WalkState
->ArgTypes
);
528 /* Special processing for certain opcodes */
530 /* TBD (remove): Temporary mechanism to disable this code if needed */
532 #ifdef ACPI_ENABLE_MODULE_LEVEL_CODE
534 if ((WalkState
->PassNumber
<= ACPI_IMODE_LOAD_PASS1
) &&
535 ((WalkState
->ParseFlags
& ACPI_PARSE_DISASSEMBLE
) == 0))
538 * We want to skip If/Else/While constructs during Pass1 because we
539 * want to actually conditionally execute the code during Pass2.
541 * Except for disassembly, where we always want to walk the
542 * If/Else/While packages
544 switch (Op
->Common
.AmlOpcode
)
550 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE
,
551 "Pass1: Skipping an If/Else/While body\n"));
553 /* Skip body of if/else/while in pass 1 */
555 WalkState
->ParserState
.Aml
= WalkState
->ParserState
.PkgEnd
;
556 WalkState
->ArgCount
= 0;
565 switch (Op
->Common
.AmlOpcode
)
569 * Skip parsing of control method because we don't have enough
570 * info in the first pass to parse it correctly.
572 * Save the length and address of the body
574 Op
->Named
.Data
= WalkState
->ParserState
.Aml
;
575 Op
->Named
.Length
= (UINT32
)
576 (WalkState
->ParserState
.PkgEnd
- WalkState
->ParserState
.Aml
);
578 /* Skip body of method */
580 WalkState
->ParserState
.Aml
= WalkState
->ParserState
.PkgEnd
;
581 WalkState
->ArgCount
= 0;
586 case AML_VAR_PACKAGE_OP
:
588 if ((Op
->Common
.Parent
) &&
589 (Op
->Common
.Parent
->Common
.AmlOpcode
== AML_NAME_OP
) &&
590 (WalkState
->PassNumber
<= ACPI_IMODE_LOAD_PASS2
))
593 * Skip parsing of Buffers and Packages because we don't have
594 * enough info in the first pass to parse them correctly.
596 Op
->Named
.Data
= AmlOpStart
;
597 Op
->Named
.Length
= (UINT32
)
598 (WalkState
->ParserState
.PkgEnd
- AmlOpStart
);
602 WalkState
->ParserState
.Aml
= WalkState
->ParserState
.PkgEnd
;
603 WalkState
->ArgCount
= 0;
609 if (WalkState
->ControlState
)
611 WalkState
->ControlState
->Control
.PackageEnd
=
612 WalkState
->ParserState
.PkgEnd
;
618 /* No action for all other opcodes */
625 return_ACPI_STATUS (AE_OK
);
629 /*******************************************************************************
631 * FUNCTION: AcpiPsCompleteOp
633 * PARAMETERS: WalkState - Current state
635 * Status - Parse status before complete Op
639 * DESCRIPTION: Complete Op
641 ******************************************************************************/
645 ACPI_WALK_STATE
*WalkState
,
646 ACPI_PARSE_OBJECT
**Op
,
652 ACPI_FUNCTION_TRACE_PTR (PsCompleteOp
, WalkState
);
656 * Finished one argument of the containing scope
658 WalkState
->ParserState
.Scope
->ParseScope
.ArgCount
--;
660 /* Close this Op (will result in parse subtree deletion) */
662 Status2
= AcpiPsCompleteThisOp (WalkState
, *Op
);
663 if (ACPI_FAILURE (Status2
))
665 return_ACPI_STATUS (Status2
);
676 case AE_CTRL_TRANSFER
:
678 /* We are about to transfer to a called method */
680 WalkState
->PrevOp
= NULL
;
681 WalkState
->PrevArgTypes
= WalkState
->ArgTypes
;
682 return_ACPI_STATUS (Status
);
687 AcpiPsPopScope (&(WalkState
->ParserState
), Op
,
688 &WalkState
->ArgTypes
, &WalkState
->ArgCount
);
693 WalkState
->OpInfo
= AcpiPsGetOpcodeInfo ((*Op
)->Common
.AmlOpcode
);
694 WalkState
->Opcode
= (*Op
)->Common
.AmlOpcode
;
696 Status
= WalkState
->AscendingCallback (WalkState
);
697 Status
= AcpiPsNextParseState (WalkState
, *Op
, Status
);
699 Status2
= AcpiPsCompleteThisOp (WalkState
, *Op
);
700 if (ACPI_FAILURE (Status2
))
702 return_ACPI_STATUS (Status2
);
711 case AE_CTRL_CONTINUE
:
713 /* Pop off scopes until we find the While */
715 while (!(*Op
) || ((*Op
)->Common
.AmlOpcode
!= AML_WHILE_OP
))
717 AcpiPsPopScope (&(WalkState
->ParserState
), Op
,
718 &WalkState
->ArgTypes
, &WalkState
->ArgCount
);
720 if ((*Op
)->Common
.AmlOpcode
!= AML_WHILE_OP
)
722 Status2
= AcpiDsResultStackPop (WalkState
);
723 if (ACPI_FAILURE (Status2
))
725 return_ACPI_STATUS (Status2
);
730 /* Close this iteration of the While loop */
733 WalkState
->OpInfo
= AcpiPsGetOpcodeInfo ((*Op
)->Common
.AmlOpcode
);
734 WalkState
->Opcode
= (*Op
)->Common
.AmlOpcode
;
736 Status
= WalkState
->AscendingCallback (WalkState
);
737 Status
= AcpiPsNextParseState (WalkState
, *Op
, Status
);
739 Status2
= AcpiPsCompleteThisOp (WalkState
, *Op
);
740 if (ACPI_FAILURE (Status2
))
742 return_ACPI_STATUS (Status2
);
749 case AE_CTRL_TERMINATE
:
756 Status2
= AcpiPsCompleteThisOp (WalkState
, *Op
);
757 if (ACPI_FAILURE (Status2
))
759 return_ACPI_STATUS (Status2
);
761 Status2
= AcpiDsResultStackPop (WalkState
);
762 if (ACPI_FAILURE (Status2
))
764 return_ACPI_STATUS (Status2
);
767 AcpiUtDeleteGenericState (
768 AcpiUtPopGenericState (&WalkState
->ControlState
));
771 AcpiPsPopScope (&(WalkState
->ParserState
), Op
,
772 &WalkState
->ArgTypes
, &WalkState
->ArgCount
);
776 return_ACPI_STATUS (AE_OK
);
779 default: /* All other non-AE_OK status */
785 Status2
= AcpiPsCompleteThisOp (WalkState
, *Op
);
786 if (ACPI_FAILURE (Status2
))
788 return_ACPI_STATUS (Status2
);
792 AcpiPsPopScope (&(WalkState
->ParserState
), Op
,
793 &WalkState
->ArgTypes
, &WalkState
->ArgCount
);
800 * TBD: Cleanup parse ops on error
804 AcpiPsPopScope (ParserState
, Op
,
805 &WalkState
->ArgTypes
, &WalkState
->ArgCount
);
808 WalkState
->PrevOp
= NULL
;
809 WalkState
->PrevArgTypes
= WalkState
->ArgTypes
;
810 return_ACPI_STATUS (Status
);
813 /* This scope complete? */
815 if (AcpiPsHasCompletedScope (&(WalkState
->ParserState
)))
817 AcpiPsPopScope (&(WalkState
->ParserState
), Op
,
818 &WalkState
->ArgTypes
, &WalkState
->ArgCount
);
819 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE
, "Popped scope, Op=%p\n", *Op
));
826 return_ACPI_STATUS (AE_OK
);
830 /*******************************************************************************
832 * FUNCTION: AcpiPsCompleteFinalOp
834 * PARAMETERS: WalkState - Current state
836 * Status - Current parse status before complete last
841 * DESCRIPTION: Complete last Op.
843 ******************************************************************************/
846 AcpiPsCompleteFinalOp (
847 ACPI_WALK_STATE
*WalkState
,
848 ACPI_PARSE_OBJECT
*Op
,
854 ACPI_FUNCTION_TRACE_PTR (PsCompleteFinalOp
, WalkState
);
858 * Complete the last Op (if not completed), and clear the scope stack.
859 * It is easily possible to end an AML "package" with an unbounded number
860 * of open scopes (such as when several ASL blocks are closed with
861 * sequential closing braces). We want to terminate each one cleanly.
863 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE
, "AML package complete at Op %p\n", Op
));
868 if (WalkState
->AscendingCallback
!= NULL
)
871 WalkState
->OpInfo
= AcpiPsGetOpcodeInfo (Op
->Common
.AmlOpcode
);
872 WalkState
->Opcode
= Op
->Common
.AmlOpcode
;
874 Status
= WalkState
->AscendingCallback (WalkState
);
875 Status
= AcpiPsNextParseState (WalkState
, Op
, Status
);
876 if (Status
== AE_CTRL_PENDING
)
878 Status
= AcpiPsCompleteOp (WalkState
, &Op
, AE_OK
);
879 if (ACPI_FAILURE (Status
))
881 return_ACPI_STATUS (Status
);
885 if (Status
== AE_CTRL_TERMINATE
)
894 Status2
= AcpiPsCompleteThisOp (WalkState
, Op
);
895 if (ACPI_FAILURE (Status2
))
897 return_ACPI_STATUS (Status2
);
901 AcpiPsPopScope (&(WalkState
->ParserState
), &Op
,
902 &WalkState
->ArgTypes
, &WalkState
->ArgCount
);
906 return_ACPI_STATUS (Status
);
909 else if (ACPI_FAILURE (Status
))
911 /* First error is most important */
913 (void) AcpiPsCompleteThisOp (WalkState
, Op
);
914 return_ACPI_STATUS (Status
);
918 Status2
= AcpiPsCompleteThisOp (WalkState
, Op
);
919 if (ACPI_FAILURE (Status2
))
921 return_ACPI_STATUS (Status2
);
925 AcpiPsPopScope (&(WalkState
->ParserState
), &Op
, &WalkState
->ArgTypes
,
926 &WalkState
->ArgCount
);
930 return_ACPI_STATUS (Status
);
934 /*******************************************************************************
936 * FUNCTION: AcpiPsParseLoop
938 * PARAMETERS: WalkState - Current state
942 * DESCRIPTION: Parse AML (pointed to by the current parser state) and return
945 ******************************************************************************/
949 ACPI_WALK_STATE
*WalkState
)
951 ACPI_STATUS Status
= AE_OK
;
952 ACPI_PARSE_OBJECT
*Op
= NULL
; /* current op */
953 ACPI_PARSE_STATE
*ParserState
;
954 UINT8
*AmlOpStart
= NULL
;
957 ACPI_FUNCTION_TRACE_PTR (PsParseLoop
, WalkState
);
960 if (WalkState
->DescendingCallback
== NULL
)
962 return_ACPI_STATUS (AE_BAD_PARAMETER
);
965 ParserState
= &WalkState
->ParserState
;
966 WalkState
->ArgTypes
= 0;
968 #if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY))
970 if (WalkState
->WalkType
& ACPI_WALK_METHOD_RESTART
)
972 /* We are restarting a preempted control method */
974 if (AcpiPsHasCompletedScope (ParserState
))
977 * We must check if a predicate to an IF or WHILE statement
980 if ((ParserState
->Scope
->ParseScope
.Op
) &&
981 ((ParserState
->Scope
->ParseScope
.Op
->Common
.AmlOpcode
== AML_IF_OP
) ||
982 (ParserState
->Scope
->ParseScope
.Op
->Common
.AmlOpcode
== AML_WHILE_OP
)) &&
983 (WalkState
->ControlState
) &&
984 (WalkState
->ControlState
->Common
.State
==
985 ACPI_CONTROL_PREDICATE_EXECUTING
))
988 * A predicate was just completed, get the value of the
989 * predicate and branch based on that value
991 WalkState
->Op
= NULL
;
992 Status
= AcpiDsGetPredicateValue (WalkState
, ACPI_TO_POINTER (TRUE
));
993 if (ACPI_FAILURE (Status
) &&
994 ((Status
& AE_CODE_MASK
) != AE_CODE_CONTROL
))
996 if (Status
== AE_AML_NO_RETURN_VALUE
)
998 ACPI_EXCEPTION ((AE_INFO
, Status
,
999 "Invoked method did not return a value"));
1003 ACPI_EXCEPTION ((AE_INFO
, Status
, "GetPredicate Failed"));
1004 return_ACPI_STATUS (Status
);
1007 Status
= AcpiPsNextParseState (WalkState
, Op
, Status
);
1010 AcpiPsPopScope (ParserState
, &Op
,
1011 &WalkState
->ArgTypes
, &WalkState
->ArgCount
);
1012 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE
, "Popped scope, Op=%p\n", Op
));
1014 else if (WalkState
->PrevOp
)
1016 /* We were in the middle of an op */
1018 Op
= WalkState
->PrevOp
;
1019 WalkState
->ArgTypes
= WalkState
->PrevArgTypes
;
1024 /* Iterative parsing loop, while there is more AML to process: */
1026 while ((ParserState
->Aml
< ParserState
->AmlEnd
) || (Op
))
1028 AmlOpStart
= ParserState
->Aml
;
1031 Status
= AcpiPsCreateOp (WalkState
, AmlOpStart
, &Op
);
1032 if (ACPI_FAILURE (Status
))
1034 if (Status
== AE_CTRL_PARSE_CONTINUE
)
1039 if (Status
== AE_CTRL_PARSE_PENDING
)
1044 Status
= AcpiPsCompleteOp (WalkState
, &Op
, Status
);
1045 if (ACPI_FAILURE (Status
))
1047 return_ACPI_STATUS (Status
);
1053 Op
->Common
.AmlOffset
= WalkState
->AmlOffset
;
1055 if (WalkState
->OpInfo
)
1057 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE
,
1058 "Opcode %4.4X [%s] Op %p Aml %p AmlOffset %5.5X\n",
1059 (UINT32
) Op
->Common
.AmlOpcode
, WalkState
->OpInfo
->Name
,
1060 Op
, ParserState
->Aml
, Op
->Common
.AmlOffset
));
1066 * Start ArgCount at zero because we don't know if there are
1069 WalkState
->ArgCount
= 0;
1071 /* Are there any arguments that must be processed? */
1073 if (WalkState
->ArgTypes
)
1077 Status
= AcpiPsGetArguments (WalkState
, AmlOpStart
, Op
);
1078 if (ACPI_FAILURE (Status
))
1080 Status
= AcpiPsCompleteOp (WalkState
, &Op
, Status
);
1081 if (ACPI_FAILURE (Status
))
1083 return_ACPI_STATUS (Status
);
1090 /* Check for arguments that need to be processed */
1092 if (WalkState
->ArgCount
)
1095 * There are arguments (complex ones), push Op and
1096 * prepare for argument
1098 Status
= AcpiPsPushScope (ParserState
, Op
,
1099 WalkState
->ArgTypes
, WalkState
->ArgCount
);
1100 if (ACPI_FAILURE (Status
))
1102 Status
= AcpiPsCompleteOp (WalkState
, &Op
, Status
);
1103 if (ACPI_FAILURE (Status
))
1105 return_ACPI_STATUS (Status
);
1116 * All arguments have been processed -- Op is complete,
1119 WalkState
->OpInfo
= AcpiPsGetOpcodeInfo (Op
->Common
.AmlOpcode
);
1120 if (WalkState
->OpInfo
->Flags
& AML_NAMED
)
1127 if (Op
->Common
.AmlOpcode
== AML_REGION_OP
)
1130 * Skip parsing of control method or opregion body,
1131 * because we don't have enough info in the first pass
1132 * to parse them correctly.
1134 * Completed parsing an OpRegion declaration, we now
1137 Op
->Named
.Length
= (UINT32
) (ParserState
->Aml
- Op
->Named
.Data
);
1141 if (WalkState
->OpInfo
->Flags
& AML_CREATE
)
1144 * Backup to beginning of CreateXXXfield declaration (1 for
1147 * BodyLength is unknown until we parse the body
1149 Op
->Named
.Length
= (UINT32
) (ParserState
->Aml
- Op
->Named
.Data
);
1152 /* This op complete, notify the dispatcher */
1154 if (WalkState
->AscendingCallback
!= NULL
)
1157 WalkState
->Opcode
= Op
->Common
.AmlOpcode
;
1159 Status
= WalkState
->AscendingCallback (WalkState
);
1160 Status
= AcpiPsNextParseState (WalkState
, Op
, Status
);
1161 if (Status
== AE_CTRL_PENDING
)
1167 Status
= AcpiPsCompleteOp (WalkState
, &Op
, Status
);
1168 if (ACPI_FAILURE (Status
))
1170 return_ACPI_STATUS (Status
);
1173 } /* while ParserState->Aml */
1175 Status
= AcpiPsCompleteFinalOp (WalkState
, Op
, Status
);
1176 return_ACPI_STATUS (Status
);