1 /******************************************************************************
3 * Module Name: psloop - Main AML parse loop
5 *****************************************************************************/
7 /******************************************************************************
11 * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
12 * All rights reserved.
16 * 2.1. This is your license from Intel Corp. under its intellectual property
17 * rights. You may have additional license terms from the party that provided
18 * you this software, covering your right to use that party's intellectual
21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22 * copy of the source code appearing in this file ("Covered Code") an
23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24 * base code distributed originally by Intel ("Original Intel Code") to copy,
25 * make derivatives, distribute, use and display any portion of the Covered
26 * Code in any form, with the right to sublicense such rights; and
28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29 * license (with the right to sublicense), under only those claims of Intel
30 * patents that are infringed by the Original Intel Code, to make, use, sell,
31 * offer to sell, and import the Covered Code and derivative works thereof
32 * solely to the minimum extent necessary to exercise the above copyright
33 * license, and in no event shall the patent license extend to any additions
34 * to or modifications of the Original Intel Code. No other license or right
35 * is granted directly or by implication, estoppel or otherwise;
37 * The above copyright and patent license is granted only if the following
42 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43 * Redistribution of source code of any substantial portion of the Covered
44 * Code or modification with rights to further distribute source must include
45 * the above Copyright Notice, the above License, this list of Conditions,
46 * and the following Disclaimer and Export Compliance provision. In addition,
47 * Licensee must cause all Covered Code to which Licensee contributes to
48 * contain a file documenting the changes Licensee made to create that Covered
49 * Code and the date of any change. Licensee must include in that file the
50 * documentation of any changes made by any predecessor Licensee. Licensee
51 * must include a prominent statement that the modification is derived,
52 * directly or indirectly, from Original Intel Code.
54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55 * Redistribution of source code of any substantial portion of the Covered
56 * Code or modification without rights to further distribute source must
57 * include the following Disclaimer and Export Compliance provision in the
58 * documentation and/or other materials provided with distribution. In
59 * addition, Licensee may not authorize further sublicense of source of any
60 * portion of the Covered Code, and must include terms to the effect that the
61 * license from Licensee to its licensee is limited to the intellectual
62 * property embodied in the software Licensee provides to its licensee, and
63 * not to intellectual property embodied in modifications its licensee may
66 * 3.3. Redistribution of Executable. Redistribution in executable form of any
67 * substantial portion of the Covered Code or modification must reproduce the
68 * above Copyright Notice, and the following Disclaimer and Export Compliance
69 * provision in the documentation and/or other materials provided with the
72 * 3.4. Intel retains all right, title, and interest in and to the Original
75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76 * Intel shall be used in advertising or otherwise to promote the sale, use or
77 * other dealings in products derived from or relating to the Covered Code
78 * without prior written authorization from Intel.
80 * 4. Disclaimer and Export Compliance
82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
99 * 4.3. Licensee shall not export, either directly or indirectly, any of this
100 * software or system incorporating such software without first obtaining any
101 * required license or other approval from the U. S. Department of Commerce or
102 * any other agency or department of the United States Government. In the
103 * event Licensee exports any such software from the United States or
104 * re-exports any such software from a foreign destination, Licensee shall
105 * ensure that the distribution and export/re-export of the software is in
106 * compliance with all laws, regulations, orders, or other restrictions of the
107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108 * any of its subsidiaries will export/re-export any technical data, process,
109 * software, or service, directly or indirectly, to any country for which the
110 * United States government or any agency thereof requires an export license,
111 * other governmental approval, or letter of assurance, without first obtaining
112 * such license, approval or letter.
114 *****************************************************************************/
118 * Parse the AML and build an operation tree as most interpreters, (such as
119 * Perl) do. Parsing is done by hand rather than with a YACC generated parser
120 * to tightly constrain stack and dynamic memory usage. Parsing is kept
121 * flexible and the code fairly compact by parsing based on a list of AML
122 * opcode templates in AmlOpInfo[].
126 #include "accommon.h"
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 AcpiPsLinkModuleCode (
176 ACPI_PARSE_OBJECT
*ParentOp
,
179 ACPI_OWNER_ID OwnerId
);
182 /*******************************************************************************
184 * FUNCTION: AcpiPsGetAmlOpcode
186 * PARAMETERS: WalkState - Current state
190 * DESCRIPTION: Extract the next AML opcode from the input stream.
192 ******************************************************************************/
196 ACPI_WALK_STATE
*WalkState
)
199 ACPI_FUNCTION_TRACE_PTR (PsGetAmlOpcode
, WalkState
);
202 WalkState
->AmlOffset
= (UINT32
) ACPI_PTR_DIFF (WalkState
->ParserState
.Aml
,
203 WalkState
->ParserState
.AmlStart
);
204 WalkState
->Opcode
= AcpiPsPeekOpcode (&(WalkState
->ParserState
));
207 * First cut to determine what we have found:
208 * 1) A valid AML opcode
210 * 3) An unknown/invalid opcode
212 WalkState
->OpInfo
= AcpiPsGetOpcodeInfo (WalkState
->Opcode
);
214 switch (WalkState
->OpInfo
->Class
)
216 case AML_CLASS_ASCII
:
217 case AML_CLASS_PREFIX
:
219 * Starts with a valid prefix or ASCII char, this is a name
220 * string. Convert the bare name string to a namepath.
222 WalkState
->Opcode
= AML_INT_NAMEPATH_OP
;
223 WalkState
->ArgTypes
= ARGP_NAMESTRING
;
226 case AML_CLASS_UNKNOWN
:
228 /* The opcode is unrecognized. Just skip unknown opcodes */
230 ACPI_ERROR ((AE_INFO
,
231 "Found unknown opcode 0x%X at AML address %p offset 0x%X, ignoring",
232 WalkState
->Opcode
, WalkState
->ParserState
.Aml
, WalkState
->AmlOffset
));
234 ACPI_DUMP_BUFFER (WalkState
->ParserState
.Aml
, 128);
236 /* Assume one-byte bad opcode */
238 WalkState
->ParserState
.Aml
++;
239 return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE
);
243 /* Found opcode info, this is a normal opcode */
245 WalkState
->ParserState
.Aml
+= AcpiPsGetOpcodeSize (WalkState
->Opcode
);
246 WalkState
->ArgTypes
= WalkState
->OpInfo
->ParseArgs
;
250 return_ACPI_STATUS (AE_OK
);
254 /*******************************************************************************
256 * FUNCTION: AcpiPsBuildNamedOp
258 * PARAMETERS: WalkState - Current state
259 * AmlOpStart - Begin of named Op in AML
260 * UnnamedOp - Early Op (not a named Op)
265 * DESCRIPTION: Parse a named Op
267 ******************************************************************************/
271 ACPI_WALK_STATE
*WalkState
,
273 ACPI_PARSE_OBJECT
*UnnamedOp
,
274 ACPI_PARSE_OBJECT
**Op
)
276 ACPI_STATUS Status
= AE_OK
;
277 ACPI_PARSE_OBJECT
*Arg
= NULL
;
280 ACPI_FUNCTION_TRACE_PTR (PsBuildNamedOp
, WalkState
);
283 UnnamedOp
->Common
.Value
.Arg
= NULL
;
284 UnnamedOp
->Common
.ArgListLength
= 0;
285 UnnamedOp
->Common
.AmlOpcode
= WalkState
->Opcode
;
288 * Get and append arguments until we find the node that contains
289 * the name (the type ARGP_NAME).
291 while (GET_CURRENT_ARG_TYPE (WalkState
->ArgTypes
) &&
292 (GET_CURRENT_ARG_TYPE (WalkState
->ArgTypes
) != ARGP_NAME
))
294 Status
= AcpiPsGetNextArg (WalkState
, &(WalkState
->ParserState
),
295 GET_CURRENT_ARG_TYPE (WalkState
->ArgTypes
), &Arg
);
296 if (ACPI_FAILURE (Status
))
298 return_ACPI_STATUS (Status
);
301 AcpiPsAppendArg (UnnamedOp
, Arg
);
302 INCREMENT_ARG_LIST (WalkState
->ArgTypes
);
306 * Make sure that we found a NAME and didn't run out of arguments
308 if (!GET_CURRENT_ARG_TYPE (WalkState
->ArgTypes
))
310 return_ACPI_STATUS (AE_AML_NO_OPERAND
);
313 /* We know that this arg is a name, move to next arg */
315 INCREMENT_ARG_LIST (WalkState
->ArgTypes
);
318 * Find the object. This will either insert the object into
319 * the namespace or simply look it up
321 WalkState
->Op
= NULL
;
323 Status
= WalkState
->DescendingCallback (WalkState
, Op
);
324 if (ACPI_FAILURE (Status
))
326 ACPI_EXCEPTION ((AE_INFO
, Status
, "During name lookup/catalog"));
327 return_ACPI_STATUS (Status
);
332 return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE
);
335 Status
= AcpiPsNextParseState (WalkState
, *Op
, Status
);
336 if (ACPI_FAILURE (Status
))
338 if (Status
== AE_CTRL_PENDING
)
340 return_ACPI_STATUS (AE_CTRL_PARSE_PENDING
);
342 return_ACPI_STATUS (Status
);
345 AcpiPsAppendArg (*Op
, UnnamedOp
->Common
.Value
.Arg
);
348 if ((*Op
)->Common
.AmlOpcode
== AML_REGION_OP
||
349 (*Op
)->Common
.AmlOpcode
== AML_DATA_REGION_OP
)
352 * Defer final parsing of an OperationRegion body, because we don't
353 * have enough info in the first pass to parse it correctly (i.e.,
354 * there may be method calls within the TermArg elements of the body.)
356 * However, we must continue parsing because the opregion is not a
357 * standalone package -- we don't know where the end is at this point.
359 * (Length is unknown until parse of the body complete)
361 (*Op
)->Named
.Data
= AmlOpStart
;
362 (*Op
)->Named
.Length
= 0;
365 return_ACPI_STATUS (AE_OK
);
369 /*******************************************************************************
371 * FUNCTION: AcpiPsCreateOp
373 * PARAMETERS: WalkState - Current state
374 * AmlOpStart - Op start in AML
375 * NewOp - Returned Op
379 * DESCRIPTION: Get Op from AML
381 ******************************************************************************/
385 ACPI_WALK_STATE
*WalkState
,
387 ACPI_PARSE_OBJECT
**NewOp
)
389 ACPI_STATUS Status
= AE_OK
;
390 ACPI_PARSE_OBJECT
*Op
;
391 ACPI_PARSE_OBJECT
*NamedOp
= NULL
;
392 ACPI_PARSE_OBJECT
*ParentScope
;
394 const ACPI_OPCODE_INFO
*OpInfo
;
397 ACPI_FUNCTION_TRACE_PTR (PsCreateOp
, WalkState
);
400 Status
= AcpiPsGetAmlOpcode (WalkState
);
401 if (Status
== AE_CTRL_PARSE_CONTINUE
)
403 return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE
);
406 /* Create Op structure and append to parent's argument list */
408 WalkState
->OpInfo
= AcpiPsGetOpcodeInfo (WalkState
->Opcode
);
409 Op
= AcpiPsAllocOp (WalkState
->Opcode
);
412 return_ACPI_STATUS (AE_NO_MEMORY
);
415 if (WalkState
->OpInfo
->Flags
& AML_NAMED
)
417 Status
= AcpiPsBuildNamedOp (WalkState
, AmlOpStart
, Op
, &NamedOp
);
419 if (ACPI_FAILURE (Status
))
421 return_ACPI_STATUS (Status
);
425 return_ACPI_STATUS (AE_OK
);
428 /* Not a named opcode, just allocate Op and append to parent */
430 if (WalkState
->OpInfo
->Flags
& AML_CREATE
)
433 * Backup to beginning of CreateXXXfield declaration
434 * BodyLength is unknown until we parse the body
436 Op
->Named
.Data
= AmlOpStart
;
437 Op
->Named
.Length
= 0;
440 if (WalkState
->Opcode
== AML_BANK_FIELD_OP
)
443 * Backup to beginning of BankField declaration
444 * BodyLength is unknown until we parse the body
446 Op
->Named
.Data
= AmlOpStart
;
447 Op
->Named
.Length
= 0;
450 ParentScope
= AcpiPsGetParentScope (&(WalkState
->ParserState
));
451 AcpiPsAppendArg (ParentScope
, Op
);
455 OpInfo
= AcpiPsGetOpcodeInfo (ParentScope
->Common
.AmlOpcode
);
456 if (OpInfo
->Flags
& AML_HAS_TARGET
)
458 ArgumentCount
= AcpiPsGetArgumentCount (OpInfo
->Type
);
459 if (ParentScope
->Common
.ArgListLength
> ArgumentCount
)
461 Op
->Common
.Flags
|= ACPI_PARSEOP_TARGET
;
464 else if (ParentScope
->Common
.AmlOpcode
== AML_INCREMENT_OP
)
466 Op
->Common
.Flags
|= ACPI_PARSEOP_TARGET
;
470 if (WalkState
->DescendingCallback
!= NULL
)
473 * Find the object. This will either insert the object into
474 * the namespace or simply look it up
476 WalkState
->Op
= *NewOp
= Op
;
478 Status
= WalkState
->DescendingCallback (WalkState
, &Op
);
479 Status
= AcpiPsNextParseState (WalkState
, Op
, Status
);
480 if (Status
== AE_CTRL_PENDING
)
482 Status
= AE_CTRL_PARSE_PENDING
;
486 return_ACPI_STATUS (Status
);
490 /*******************************************************************************
492 * FUNCTION: AcpiPsGetArguments
494 * PARAMETERS: WalkState - Current state
495 * AmlOpStart - Op start in AML
500 * DESCRIPTION: Get arguments for passed Op.
502 ******************************************************************************/
506 ACPI_WALK_STATE
*WalkState
,
508 ACPI_PARSE_OBJECT
*Op
)
510 ACPI_STATUS Status
= AE_OK
;
511 ACPI_PARSE_OBJECT
*Arg
= NULL
;
512 const ACPI_OPCODE_INFO
*OpInfo
;
515 ACPI_FUNCTION_TRACE_PTR (PsGetArguments
, WalkState
);
518 switch (Op
->Common
.AmlOpcode
)
520 case AML_BYTE_OP
: /* AML_BYTEDATA_ARG */
521 case AML_WORD_OP
: /* AML_WORDDATA_ARG */
522 case AML_DWORD_OP
: /* AML_DWORDATA_ARG */
523 case AML_QWORD_OP
: /* AML_QWORDATA_ARG */
524 case AML_STRING_OP
: /* AML_ASCIICHARLIST_ARG */
526 /* Fill in constant or string argument directly */
528 AcpiPsGetNextSimpleArg (&(WalkState
->ParserState
),
529 GET_CURRENT_ARG_TYPE (WalkState
->ArgTypes
), Op
);
532 case AML_INT_NAMEPATH_OP
: /* AML_NAMESTRING_ARG */
534 Status
= AcpiPsGetNextNamepath (WalkState
, &(WalkState
->ParserState
), Op
, 1);
535 if (ACPI_FAILURE (Status
))
537 return_ACPI_STATUS (Status
);
540 WalkState
->ArgTypes
= 0;
545 * Op is not a constant or string, append each argument to the Op
547 while (GET_CURRENT_ARG_TYPE (WalkState
->ArgTypes
) && !WalkState
->ArgCount
)
549 WalkState
->AmlOffset
= (UINT32
) ACPI_PTR_DIFF (WalkState
->ParserState
.Aml
,
550 WalkState
->ParserState
.AmlStart
);
552 Status
= AcpiPsGetNextArg (WalkState
, &(WalkState
->ParserState
),
553 GET_CURRENT_ARG_TYPE (WalkState
->ArgTypes
), &Arg
);
554 if (ACPI_FAILURE (Status
))
556 return_ACPI_STATUS (Status
);
561 Arg
->Common
.AmlOffset
= WalkState
->AmlOffset
;
562 AcpiPsAppendArg (Op
, Arg
);
565 INCREMENT_ARG_LIST (WalkState
->ArgTypes
);
570 * Handle executable code at "module-level". This refers to
571 * executable opcodes that appear outside of any control method.
573 if ((WalkState
->PassNumber
<= ACPI_IMODE_LOAD_PASS2
) &&
574 ((WalkState
->ParseFlags
& ACPI_PARSE_DISASSEMBLE
) == 0))
577 * We want to skip If/Else/While constructs during Pass1 because we
578 * want to actually conditionally execute the code during Pass2.
580 * Except for disassembly, where we always want to walk the
581 * If/Else/While packages
583 switch (Op
->Common
.AmlOpcode
)
590 * Currently supported module-level opcodes are:
591 * IF/ELSE/WHILE. These appear to be the most common,
592 * and easiest to support since they open an AML
595 if (WalkState
->PassNumber
== ACPI_IMODE_LOAD_PASS1
)
597 AcpiPsLinkModuleCode (Op
->Common
.Parent
, AmlOpStart
,
598 (UINT32
) (WalkState
->ParserState
.PkgEnd
- AmlOpStart
),
602 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE
,
603 "Pass1: Skipping an If/Else/While body\n"));
605 /* Skip body of if/else/while in pass 1 */
607 WalkState
->ParserState
.Aml
= WalkState
->ParserState
.PkgEnd
;
608 WalkState
->ArgCount
= 0;
613 * Check for an unsupported executable opcode at module
614 * level. We must be in PASS1, the parent must be a SCOPE,
615 * The opcode class must be EXECUTE, and the opcode must
616 * not be an argument to another opcode.
618 if ((WalkState
->PassNumber
== ACPI_IMODE_LOAD_PASS1
) &&
619 (Op
->Common
.Parent
->Common
.AmlOpcode
== AML_SCOPE_OP
))
621 OpInfo
= AcpiPsGetOpcodeInfo (Op
->Common
.AmlOpcode
);
622 if ((OpInfo
->Class
== AML_CLASS_EXECUTE
) &&
625 ACPI_WARNING ((AE_INFO
,
626 "Detected an unsupported executable opcode "
627 "at module-level: [0x%.4X] at table offset 0x%.4X",
628 Op
->Common
.AmlOpcode
,
629 (UINT32
) (ACPI_PTR_DIFF (AmlOpStart
,
630 WalkState
->ParserState
.AmlStart
) +
631 sizeof (ACPI_TABLE_HEADER
))));
638 /* Special processing for certain opcodes */
640 switch (Op
->Common
.AmlOpcode
)
644 * Skip parsing of control method because we don't have enough
645 * info in the first pass to parse it correctly.
647 * Save the length and address of the body
649 Op
->Named
.Data
= WalkState
->ParserState
.Aml
;
650 Op
->Named
.Length
= (UINT32
)
651 (WalkState
->ParserState
.PkgEnd
- WalkState
->ParserState
.Aml
);
653 /* Skip body of method */
655 WalkState
->ParserState
.Aml
= WalkState
->ParserState
.PkgEnd
;
656 WalkState
->ArgCount
= 0;
661 case AML_VAR_PACKAGE_OP
:
663 if ((Op
->Common
.Parent
) &&
664 (Op
->Common
.Parent
->Common
.AmlOpcode
== AML_NAME_OP
) &&
665 (WalkState
->PassNumber
<= ACPI_IMODE_LOAD_PASS2
))
668 * Skip parsing of Buffers and Packages because we don't have
669 * enough info in the first pass to parse them correctly.
671 Op
->Named
.Data
= AmlOpStart
;
672 Op
->Named
.Length
= (UINT32
)
673 (WalkState
->ParserState
.PkgEnd
- AmlOpStart
);
677 WalkState
->ParserState
.Aml
= WalkState
->ParserState
.PkgEnd
;
678 WalkState
->ArgCount
= 0;
684 if (WalkState
->ControlState
)
686 WalkState
->ControlState
->Control
.PackageEnd
=
687 WalkState
->ParserState
.PkgEnd
;
693 /* No action for all other opcodes */
700 return_ACPI_STATUS (AE_OK
);
704 /*******************************************************************************
706 * FUNCTION: AcpiPsLinkModuleCode
708 * PARAMETERS: ParentOp - Parent parser op
709 * AmlStart - Pointer to the AML
710 * AmlLength - Length of executable AML
711 * OwnerId - OwnerId of module level code
715 * DESCRIPTION: Wrap the module-level code with a method object and link the
716 * object to the global list. Note, the mutex field of the method
717 * object is used to link multiple module-level code objects.
719 ******************************************************************************/
722 AcpiPsLinkModuleCode (
723 ACPI_PARSE_OBJECT
*ParentOp
,
726 ACPI_OWNER_ID OwnerId
)
728 ACPI_OPERAND_OBJECT
*Prev
;
729 ACPI_OPERAND_OBJECT
*Next
;
730 ACPI_OPERAND_OBJECT
*MethodObj
;
731 ACPI_NAMESPACE_NODE
*ParentNode
;
734 /* Get the tail of the list */
736 Prev
= Next
= AcpiGbl_ModuleCodeList
;
740 Next
= Next
->Method
.Mutex
;
744 * Insert the module level code into the list. Merge it if it is
745 * adjacent to the previous element.
748 ((Prev
->Method
.AmlStart
+ Prev
->Method
.AmlLength
) != AmlStart
))
750 /* Create, initialize, and link a new temporary method object */
752 MethodObj
= AcpiUtCreateInternalObject (ACPI_TYPE_METHOD
);
758 if (ParentOp
->Common
.Node
)
760 ParentNode
= ParentOp
->Common
.Node
;
764 ParentNode
= AcpiGbl_RootNode
;
767 MethodObj
->Method
.AmlStart
= AmlStart
;
768 MethodObj
->Method
.AmlLength
= AmlLength
;
769 MethodObj
->Method
.OwnerId
= OwnerId
;
770 MethodObj
->Method
.Flags
|= AOPOBJ_MODULE_LEVEL
;
773 * Save the parent node in NextObject. This is cheating, but we
774 * don't want to expand the method object.
776 MethodObj
->Method
.NextObject
=
777 ACPI_CAST_PTR (ACPI_OPERAND_OBJECT
, ParentNode
);
781 AcpiGbl_ModuleCodeList
= MethodObj
;
785 Prev
->Method
.Mutex
= MethodObj
;
790 Prev
->Method
.AmlLength
+= AmlLength
;
795 /*******************************************************************************
797 * FUNCTION: AcpiPsCompleteOp
799 * PARAMETERS: WalkState - Current state
801 * Status - Parse status before complete Op
805 * DESCRIPTION: Complete Op
807 ******************************************************************************/
811 ACPI_WALK_STATE
*WalkState
,
812 ACPI_PARSE_OBJECT
**Op
,
818 ACPI_FUNCTION_TRACE_PTR (PsCompleteOp
, WalkState
);
822 * Finished one argument of the containing scope
824 WalkState
->ParserState
.Scope
->ParseScope
.ArgCount
--;
826 /* Close this Op (will result in parse subtree deletion) */
828 Status2
= AcpiPsCompleteThisOp (WalkState
, *Op
);
829 if (ACPI_FAILURE (Status2
))
831 return_ACPI_STATUS (Status2
);
842 case AE_CTRL_TRANSFER
:
844 /* We are about to transfer to a called method */
846 WalkState
->PrevOp
= NULL
;
847 WalkState
->PrevArgTypes
= WalkState
->ArgTypes
;
848 return_ACPI_STATUS (Status
);
853 AcpiPsPopScope (&(WalkState
->ParserState
), Op
,
854 &WalkState
->ArgTypes
, &WalkState
->ArgCount
);
859 WalkState
->OpInfo
= AcpiPsGetOpcodeInfo ((*Op
)->Common
.AmlOpcode
);
860 WalkState
->Opcode
= (*Op
)->Common
.AmlOpcode
;
862 Status
= WalkState
->AscendingCallback (WalkState
);
863 Status
= AcpiPsNextParseState (WalkState
, *Op
, Status
);
865 Status2
= AcpiPsCompleteThisOp (WalkState
, *Op
);
866 if (ACPI_FAILURE (Status2
))
868 return_ACPI_STATUS (Status2
);
877 case AE_CTRL_CONTINUE
:
879 /* Pop off scopes until we find the While */
881 while (!(*Op
) || ((*Op
)->Common
.AmlOpcode
!= AML_WHILE_OP
))
883 AcpiPsPopScope (&(WalkState
->ParserState
), Op
,
884 &WalkState
->ArgTypes
, &WalkState
->ArgCount
);
887 /* Close this iteration of the While loop */
890 WalkState
->OpInfo
= AcpiPsGetOpcodeInfo ((*Op
)->Common
.AmlOpcode
);
891 WalkState
->Opcode
= (*Op
)->Common
.AmlOpcode
;
893 Status
= WalkState
->AscendingCallback (WalkState
);
894 Status
= AcpiPsNextParseState (WalkState
, *Op
, Status
);
896 Status2
= AcpiPsCompleteThisOp (WalkState
, *Op
);
897 if (ACPI_FAILURE (Status2
))
899 return_ACPI_STATUS (Status2
);
906 case AE_CTRL_TERMINATE
:
913 Status2
= AcpiPsCompleteThisOp (WalkState
, *Op
);
914 if (ACPI_FAILURE (Status2
))
916 return_ACPI_STATUS (Status2
);
919 AcpiUtDeleteGenericState (
920 AcpiUtPopGenericState (&WalkState
->ControlState
));
923 AcpiPsPopScope (&(WalkState
->ParserState
), Op
,
924 &WalkState
->ArgTypes
, &WalkState
->ArgCount
);
928 return_ACPI_STATUS (AE_OK
);
931 default: /* All other non-AE_OK status */
937 Status2
= AcpiPsCompleteThisOp (WalkState
, *Op
);
938 if (ACPI_FAILURE (Status2
))
940 return_ACPI_STATUS (Status2
);
944 AcpiPsPopScope (&(WalkState
->ParserState
), Op
,
945 &WalkState
->ArgTypes
, &WalkState
->ArgCount
);
952 * TBD: Cleanup parse ops on error
956 AcpiPsPopScope (ParserState
, Op
,
957 &WalkState
->ArgTypes
, &WalkState
->ArgCount
);
960 WalkState
->PrevOp
= NULL
;
961 WalkState
->PrevArgTypes
= WalkState
->ArgTypes
;
962 return_ACPI_STATUS (Status
);
965 /* This scope complete? */
967 if (AcpiPsHasCompletedScope (&(WalkState
->ParserState
)))
969 AcpiPsPopScope (&(WalkState
->ParserState
), Op
,
970 &WalkState
->ArgTypes
, &WalkState
->ArgCount
);
971 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE
, "Popped scope, Op=%p\n", *Op
));
978 return_ACPI_STATUS (AE_OK
);
982 /*******************************************************************************
984 * FUNCTION: AcpiPsCompleteFinalOp
986 * PARAMETERS: WalkState - Current state
988 * Status - Current parse status before complete last
993 * DESCRIPTION: Complete last Op.
995 ******************************************************************************/
998 AcpiPsCompleteFinalOp (
999 ACPI_WALK_STATE
*WalkState
,
1000 ACPI_PARSE_OBJECT
*Op
,
1003 ACPI_STATUS Status2
;
1006 ACPI_FUNCTION_TRACE_PTR (PsCompleteFinalOp
, WalkState
);
1010 * Complete the last Op (if not completed), and clear the scope stack.
1011 * It is easily possible to end an AML "package" with an unbounded number
1012 * of open scopes (such as when several ASL blocks are closed with
1013 * sequential closing braces). We want to terminate each one cleanly.
1015 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE
, "AML package complete at Op %p\n", Op
));
1020 if (WalkState
->AscendingCallback
!= NULL
)
1023 WalkState
->OpInfo
= AcpiPsGetOpcodeInfo (Op
->Common
.AmlOpcode
);
1024 WalkState
->Opcode
= Op
->Common
.AmlOpcode
;
1026 Status
= WalkState
->AscendingCallback (WalkState
);
1027 Status
= AcpiPsNextParseState (WalkState
, Op
, Status
);
1028 if (Status
== AE_CTRL_PENDING
)
1030 Status
= AcpiPsCompleteOp (WalkState
, &Op
, AE_OK
);
1031 if (ACPI_FAILURE (Status
))
1033 return_ACPI_STATUS (Status
);
1037 if (Status
== AE_CTRL_TERMINATE
)
1046 Status2
= AcpiPsCompleteThisOp (WalkState
, Op
);
1047 if (ACPI_FAILURE (Status2
))
1049 return_ACPI_STATUS (Status2
);
1053 AcpiPsPopScope (&(WalkState
->ParserState
), &Op
,
1054 &WalkState
->ArgTypes
, &WalkState
->ArgCount
);
1058 return_ACPI_STATUS (Status
);
1061 else if (ACPI_FAILURE (Status
))
1063 /* First error is most important */
1065 (void) AcpiPsCompleteThisOp (WalkState
, Op
);
1066 return_ACPI_STATUS (Status
);
1070 Status2
= AcpiPsCompleteThisOp (WalkState
, Op
);
1071 if (ACPI_FAILURE (Status2
))
1073 return_ACPI_STATUS (Status2
);
1077 AcpiPsPopScope (&(WalkState
->ParserState
), &Op
, &WalkState
->ArgTypes
,
1078 &WalkState
->ArgCount
);
1082 return_ACPI_STATUS (Status
);
1086 /*******************************************************************************
1088 * FUNCTION: AcpiPsParseLoop
1090 * PARAMETERS: WalkState - Current state
1094 * DESCRIPTION: Parse AML (pointed to by the current parser state) and return
1097 ******************************************************************************/
1101 ACPI_WALK_STATE
*WalkState
)
1103 ACPI_STATUS Status
= AE_OK
;
1104 ACPI_PARSE_OBJECT
*Op
= NULL
; /* current op */
1105 ACPI_PARSE_STATE
*ParserState
;
1106 UINT8
*AmlOpStart
= NULL
;
1109 ACPI_FUNCTION_TRACE_PTR (PsParseLoop
, WalkState
);
1112 if (WalkState
->DescendingCallback
== NULL
)
1114 return_ACPI_STATUS (AE_BAD_PARAMETER
);
1117 ParserState
= &WalkState
->ParserState
;
1118 WalkState
->ArgTypes
= 0;
1120 #if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY))
1122 if (WalkState
->WalkType
& ACPI_WALK_METHOD_RESTART
)
1124 /* We are restarting a preempted control method */
1126 if (AcpiPsHasCompletedScope (ParserState
))
1129 * We must check if a predicate to an IF or WHILE statement
1130 * was just completed
1132 if ((ParserState
->Scope
->ParseScope
.Op
) &&
1133 ((ParserState
->Scope
->ParseScope
.Op
->Common
.AmlOpcode
== AML_IF_OP
) ||
1134 (ParserState
->Scope
->ParseScope
.Op
->Common
.AmlOpcode
== AML_WHILE_OP
)) &&
1135 (WalkState
->ControlState
) &&
1136 (WalkState
->ControlState
->Common
.State
==
1137 ACPI_CONTROL_PREDICATE_EXECUTING
))
1140 * A predicate was just completed, get the value of the
1141 * predicate and branch based on that value
1143 WalkState
->Op
= NULL
;
1144 Status
= AcpiDsGetPredicateValue (WalkState
, ACPI_TO_POINTER (TRUE
));
1145 if (ACPI_FAILURE (Status
) &&
1146 ((Status
& AE_CODE_MASK
) != AE_CODE_CONTROL
))
1148 if (Status
== AE_AML_NO_RETURN_VALUE
)
1150 ACPI_EXCEPTION ((AE_INFO
, Status
,
1151 "Invoked method did not return a value"));
1154 ACPI_EXCEPTION ((AE_INFO
, Status
, "GetPredicate Failed"));
1155 return_ACPI_STATUS (Status
);
1158 Status
= AcpiPsNextParseState (WalkState
, Op
, Status
);
1161 AcpiPsPopScope (ParserState
, &Op
,
1162 &WalkState
->ArgTypes
, &WalkState
->ArgCount
);
1163 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE
, "Popped scope, Op=%p\n", Op
));
1165 else if (WalkState
->PrevOp
)
1167 /* We were in the middle of an op */
1169 Op
= WalkState
->PrevOp
;
1170 WalkState
->ArgTypes
= WalkState
->PrevArgTypes
;
1175 /* Iterative parsing loop, while there is more AML to process: */
1177 while ((ParserState
->Aml
< ParserState
->AmlEnd
) || (Op
))
1179 AmlOpStart
= ParserState
->Aml
;
1182 Status
= AcpiPsCreateOp (WalkState
, AmlOpStart
, &Op
);
1183 if (ACPI_FAILURE (Status
))
1185 if (Status
== AE_CTRL_PARSE_CONTINUE
)
1190 if (Status
== AE_CTRL_PARSE_PENDING
)
1195 Status
= AcpiPsCompleteOp (WalkState
, &Op
, Status
);
1196 if (ACPI_FAILURE (Status
))
1198 return_ACPI_STATUS (Status
);
1204 Op
->Common
.AmlOffset
= WalkState
->AmlOffset
;
1206 if (WalkState
->OpInfo
)
1208 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE
,
1209 "Opcode %4.4X [%s] Op %p Aml %p AmlOffset %5.5X\n",
1210 (UINT32
) Op
->Common
.AmlOpcode
, WalkState
->OpInfo
->Name
,
1211 Op
, ParserState
->Aml
, Op
->Common
.AmlOffset
));
1217 * Start ArgCount at zero because we don't know if there are
1220 WalkState
->ArgCount
= 0;
1222 /* Are there any arguments that must be processed? */
1224 if (WalkState
->ArgTypes
)
1228 Status
= AcpiPsGetArguments (WalkState
, AmlOpStart
, Op
);
1229 if (ACPI_FAILURE (Status
))
1231 Status
= AcpiPsCompleteOp (WalkState
, &Op
, Status
);
1232 if (ACPI_FAILURE (Status
))
1234 return_ACPI_STATUS (Status
);
1241 /* Check for arguments that need to be processed */
1243 if (WalkState
->ArgCount
)
1246 * There are arguments (complex ones), push Op and
1247 * prepare for argument
1249 Status
= AcpiPsPushScope (ParserState
, Op
,
1250 WalkState
->ArgTypes
, WalkState
->ArgCount
);
1251 if (ACPI_FAILURE (Status
))
1253 Status
= AcpiPsCompleteOp (WalkState
, &Op
, Status
);
1254 if (ACPI_FAILURE (Status
))
1256 return_ACPI_STATUS (Status
);
1267 * All arguments have been processed -- Op is complete,
1270 WalkState
->OpInfo
= AcpiPsGetOpcodeInfo (Op
->Common
.AmlOpcode
);
1271 if (WalkState
->OpInfo
->Flags
& AML_NAMED
)
1278 if (Op
->Common
.AmlOpcode
== AML_REGION_OP
||
1279 Op
->Common
.AmlOpcode
== AML_DATA_REGION_OP
)
1282 * Skip parsing of control method or opregion body,
1283 * because we don't have enough info in the first pass
1284 * to parse them correctly.
1286 * Completed parsing an OpRegion declaration, we now
1289 Op
->Named
.Length
= (UINT32
) (ParserState
->Aml
- Op
->Named
.Data
);
1293 if (WalkState
->OpInfo
->Flags
& AML_CREATE
)
1296 * Backup to beginning of CreateXXXfield declaration (1 for
1299 * BodyLength is unknown until we parse the body
1301 Op
->Named
.Length
= (UINT32
) (ParserState
->Aml
- Op
->Named
.Data
);
1304 if (Op
->Common
.AmlOpcode
== AML_BANK_FIELD_OP
)
1307 * Backup to beginning of BankField declaration
1309 * BodyLength is unknown until we parse the body
1311 Op
->Named
.Length
= (UINT32
) (ParserState
->Aml
- Op
->Named
.Data
);
1314 /* This op complete, notify the dispatcher */
1316 if (WalkState
->AscendingCallback
!= NULL
)
1319 WalkState
->Opcode
= Op
->Common
.AmlOpcode
;
1321 Status
= WalkState
->AscendingCallback (WalkState
);
1322 Status
= AcpiPsNextParseState (WalkState
, Op
, Status
);
1323 if (Status
== AE_CTRL_PENDING
)
1329 Status
= AcpiPsCompleteOp (WalkState
, &Op
, Status
);
1330 if (ACPI_FAILURE (Status
))
1332 return_ACPI_STATUS (Status
);
1335 } /* while ParserState->Aml */
1337 Status
= AcpiPsCompleteFinalOp (WalkState
, Op
, Status
);
1338 return_ACPI_STATUS (Status
);