No empty .Rs/.Re
[netbsd-mini2440.git] / sys / external / intel-public / acpica / dist / parser / psloop.c
blob65b5b4fce0b9e9424a8d429b5c4f07beccdfe4e9
1 /******************************************************************************
3 * Module Name: psloop - Main AML parse loop
5 *****************************************************************************/
7 /******************************************************************************
9 * 1. Copyright Notice
11 * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp.
12 * All rights reserved.
14 * 2. License
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
19 * property rights.
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
38 * conditions are met:
40 * 3. Conditions
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
64 * make.
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
70 * distribution.
72 * 3.4. Intel retains all right, title, and interest in and to the Original
73 * Intel Code.
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
88 * PARTICULAR PURPOSE.
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
97 * LIMITED REMEDY.
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[].
125 #include "acpi.h"
126 #include "accommon.h"
127 #include "acparser.h"
128 #include "acdispat.h"
129 #include "amlcode.h"
131 #define _COMPONENT ACPI_PARSER
132 ACPI_MODULE_NAME ("psloop")
134 static UINT32 AcpiGbl_Depth = 0;
137 /* Local prototypes */
139 static ACPI_STATUS
140 AcpiPsGetAmlOpcode (
141 ACPI_WALK_STATE *WalkState);
143 static ACPI_STATUS
144 AcpiPsBuildNamedOp (
145 ACPI_WALK_STATE *WalkState,
146 UINT8 *AmlOpStart,
147 ACPI_PARSE_OBJECT *UnnamedOp,
148 ACPI_PARSE_OBJECT **Op);
150 static ACPI_STATUS
151 AcpiPsCreateOp (
152 ACPI_WALK_STATE *WalkState,
153 UINT8 *AmlOpStart,
154 ACPI_PARSE_OBJECT **NewOp);
156 static ACPI_STATUS
157 AcpiPsGetArguments (
158 ACPI_WALK_STATE *WalkState,
159 UINT8 *AmlOpStart,
160 ACPI_PARSE_OBJECT *Op);
162 static ACPI_STATUS
163 AcpiPsCompleteOp (
164 ACPI_WALK_STATE *WalkState,
165 ACPI_PARSE_OBJECT **Op,
166 ACPI_STATUS Status);
168 static ACPI_STATUS
169 AcpiPsCompleteFinalOp (
170 ACPI_WALK_STATE *WalkState,
171 ACPI_PARSE_OBJECT *Op,
172 ACPI_STATUS Status);
174 static void
175 AcpiPsLinkModuleCode (
176 UINT8 *AmlStart,
177 UINT32 AmlLength,
178 ACPI_OWNER_ID OwnerId);
181 /*******************************************************************************
183 * FUNCTION: AcpiPsGetAmlOpcode
185 * PARAMETERS: WalkState - Current state
187 * RETURN: Status
189 * DESCRIPTION: Extract the next AML opcode from the input stream.
191 ******************************************************************************/
193 static ACPI_STATUS
194 AcpiPsGetAmlOpcode (
195 ACPI_WALK_STATE *WalkState)
198 ACPI_FUNCTION_TRACE_PTR (PsGetAmlOpcode, WalkState);
201 WalkState->AmlOffset = (UINT32) ACPI_PTR_DIFF (WalkState->ParserState.Aml,
202 WalkState->ParserState.AmlStart);
203 WalkState->Opcode = AcpiPsPeekOpcode (&(WalkState->ParserState));
206 * First cut to determine what we have found:
207 * 1) A valid AML opcode
208 * 2) A name string
209 * 3) An unknown/invalid opcode
211 WalkState->OpInfo = AcpiPsGetOpcodeInfo (WalkState->Opcode);
213 switch (WalkState->OpInfo->Class)
215 case AML_CLASS_ASCII:
216 case AML_CLASS_PREFIX:
218 * Starts with a valid prefix or ASCII char, this is a name
219 * string. Convert the bare name string to a namepath.
221 WalkState->Opcode = AML_INT_NAMEPATH_OP;
222 WalkState->ArgTypes = ARGP_NAMESTRING;
223 break;
225 case AML_CLASS_UNKNOWN:
227 /* The opcode is unrecognized. Just skip unknown opcodes */
229 ACPI_ERROR ((AE_INFO,
230 "Found unknown opcode %X at AML address %p offset %X, ignoring",
231 WalkState->Opcode, WalkState->ParserState.Aml, WalkState->AmlOffset));
233 ACPI_DUMP_BUFFER (WalkState->ParserState.Aml, 128);
235 /* Assume one-byte bad opcode */
237 WalkState->ParserState.Aml++;
238 return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE);
240 default:
242 /* Found opcode info, this is a normal opcode */
244 WalkState->ParserState.Aml += AcpiPsGetOpcodeSize (WalkState->Opcode);
245 WalkState->ArgTypes = WalkState->OpInfo->ParseArgs;
246 break;
249 return_ACPI_STATUS (AE_OK);
253 /*******************************************************************************
255 * FUNCTION: AcpiPsBuildNamedOp
257 * PARAMETERS: WalkState - Current state
258 * AmlOpStart - Begin of named Op in AML
259 * UnnamedOp - Early Op (not a named Op)
260 * Op - Returned Op
262 * RETURN: Status
264 * DESCRIPTION: Parse a named Op
266 ******************************************************************************/
268 static ACPI_STATUS
269 AcpiPsBuildNamedOp (
270 ACPI_WALK_STATE *WalkState,
271 UINT8 *AmlOpStart,
272 ACPI_PARSE_OBJECT *UnnamedOp,
273 ACPI_PARSE_OBJECT **Op)
275 ACPI_STATUS Status = AE_OK;
276 ACPI_PARSE_OBJECT *Arg = NULL;
279 ACPI_FUNCTION_TRACE_PTR (PsBuildNamedOp, WalkState);
282 UnnamedOp->Common.Value.Arg = NULL;
283 UnnamedOp->Common.ArgListLength = 0;
284 UnnamedOp->Common.AmlOpcode = WalkState->Opcode;
287 * Get and append arguments until we find the node that contains
288 * the name (the type ARGP_NAME).
290 while (GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) &&
291 (GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) != ARGP_NAME))
293 Status = AcpiPsGetNextArg (WalkState, &(WalkState->ParserState),
294 GET_CURRENT_ARG_TYPE (WalkState->ArgTypes), &Arg);
295 if (ACPI_FAILURE (Status))
297 return_ACPI_STATUS (Status);
300 AcpiPsAppendArg (UnnamedOp, Arg);
301 INCREMENT_ARG_LIST (WalkState->ArgTypes);
305 * Make sure that we found a NAME and didn't run out of arguments
307 if (!GET_CURRENT_ARG_TYPE (WalkState->ArgTypes))
309 return_ACPI_STATUS (AE_AML_NO_OPERAND);
312 /* We know that this arg is a name, move to next arg */
314 INCREMENT_ARG_LIST (WalkState->ArgTypes);
317 * Find the object. This will either insert the object into
318 * the namespace or simply look it up
320 WalkState->Op = NULL;
322 Status = WalkState->DescendingCallback (WalkState, Op);
323 if (ACPI_FAILURE (Status))
325 ACPI_EXCEPTION ((AE_INFO, Status, "During name lookup/catalog"));
326 return_ACPI_STATUS (Status);
329 if (!*Op)
331 return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE);
334 Status = AcpiPsNextParseState (WalkState, *Op, Status);
335 if (ACPI_FAILURE (Status))
337 if (Status == AE_CTRL_PENDING)
339 return_ACPI_STATUS (AE_CTRL_PARSE_PENDING);
341 return_ACPI_STATUS (Status);
344 AcpiPsAppendArg (*Op, UnnamedOp->Common.Value.Arg);
345 AcpiGbl_Depth++;
347 if ((*Op)->Common.AmlOpcode == AML_REGION_OP ||
348 (*Op)->Common.AmlOpcode == AML_DATA_REGION_OP)
351 * Defer final parsing of an OperationRegion body, because we don't
352 * have enough info in the first pass to parse it correctly (i.e.,
353 * there may be method calls within the TermArg elements of the body.)
355 * However, we must continue parsing because the opregion is not a
356 * standalone package -- we don't know where the end is at this point.
358 * (Length is unknown until parse of the body complete)
360 (*Op)->Named.Data = AmlOpStart;
361 (*Op)->Named.Length = 0;
364 return_ACPI_STATUS (AE_OK);
368 /*******************************************************************************
370 * FUNCTION: AcpiPsCreateOp
372 * PARAMETERS: WalkState - Current state
373 * AmlOpStart - Op start in AML
374 * NewOp - Returned Op
376 * RETURN: Status
378 * DESCRIPTION: Get Op from AML
380 ******************************************************************************/
382 static ACPI_STATUS
383 AcpiPsCreateOp (
384 ACPI_WALK_STATE *WalkState,
385 UINT8 *AmlOpStart,
386 ACPI_PARSE_OBJECT **NewOp)
388 ACPI_STATUS Status = AE_OK;
389 ACPI_PARSE_OBJECT *Op;
390 ACPI_PARSE_OBJECT *NamedOp = NULL;
391 ACPI_PARSE_OBJECT *ParentScope;
392 UINT8 ArgumentCount;
393 const ACPI_OPCODE_INFO *OpInfo;
396 ACPI_FUNCTION_TRACE_PTR (PsCreateOp, WalkState);
399 Status = AcpiPsGetAmlOpcode (WalkState);
400 if (Status == AE_CTRL_PARSE_CONTINUE)
402 return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE);
405 /* Create Op structure and append to parent's argument list */
407 WalkState->OpInfo = AcpiPsGetOpcodeInfo (WalkState->Opcode);
408 Op = AcpiPsAllocOp (WalkState->Opcode);
409 if (!Op)
411 return_ACPI_STATUS (AE_NO_MEMORY);
414 if (WalkState->OpInfo->Flags & AML_NAMED)
416 Status = AcpiPsBuildNamedOp (WalkState, AmlOpStart, Op, &NamedOp);
417 AcpiPsFreeOp (Op);
418 if (ACPI_FAILURE (Status))
420 return_ACPI_STATUS (Status);
423 *NewOp = NamedOp;
424 return_ACPI_STATUS (AE_OK);
427 /* Not a named opcode, just allocate Op and append to parent */
429 if (WalkState->OpInfo->Flags & AML_CREATE)
432 * Backup to beginning of CreateXXXfield declaration
433 * BodyLength is unknown until we parse the body
435 Op->Named.Data = AmlOpStart;
436 Op->Named.Length = 0;
439 if (WalkState->Opcode == AML_BANK_FIELD_OP)
442 * Backup to beginning of BankField declaration
443 * BodyLength is unknown until we parse the body
445 Op->Named.Data = AmlOpStart;
446 Op->Named.Length = 0;
449 ParentScope = AcpiPsGetParentScope (&(WalkState->ParserState));
450 AcpiPsAppendArg (ParentScope, Op);
452 if (ParentScope)
454 OpInfo = AcpiPsGetOpcodeInfo (ParentScope->Common.AmlOpcode);
455 if (OpInfo->Flags & AML_HAS_TARGET)
457 ArgumentCount = AcpiPsGetArgumentCount (OpInfo->Type);
458 if (ParentScope->Common.ArgListLength > ArgumentCount)
460 Op->Common.Flags |= ACPI_PARSEOP_TARGET;
463 else if (ParentScope->Common.AmlOpcode == AML_INCREMENT_OP)
465 Op->Common.Flags |= ACPI_PARSEOP_TARGET;
469 if (WalkState->DescendingCallback != NULL)
472 * Find the object. This will either insert the object into
473 * the namespace or simply look it up
475 WalkState->Op = *NewOp = Op;
477 Status = WalkState->DescendingCallback (WalkState, &Op);
478 Status = AcpiPsNextParseState (WalkState, Op, Status);
479 if (Status == AE_CTRL_PENDING)
481 Status = AE_CTRL_PARSE_PENDING;
485 return_ACPI_STATUS (Status);
489 /*******************************************************************************
491 * FUNCTION: AcpiPsGetArguments
493 * PARAMETERS: WalkState - Current state
494 * AmlOpStart - Op start in AML
495 * Op - Current Op
497 * RETURN: Status
499 * DESCRIPTION: Get arguments for passed Op.
501 ******************************************************************************/
503 static ACPI_STATUS
504 AcpiPsGetArguments (
505 ACPI_WALK_STATE *WalkState,
506 UINT8 *AmlOpStart,
507 ACPI_PARSE_OBJECT *Op)
509 ACPI_STATUS Status = AE_OK;
510 ACPI_PARSE_OBJECT *Arg = NULL;
511 const ACPI_OPCODE_INFO *OpInfo;
514 ACPI_FUNCTION_TRACE_PTR (PsGetArguments, WalkState);
517 switch (Op->Common.AmlOpcode)
519 case AML_BYTE_OP: /* AML_BYTEDATA_ARG */
520 case AML_WORD_OP: /* AML_WORDDATA_ARG */
521 case AML_DWORD_OP: /* AML_DWORDATA_ARG */
522 case AML_QWORD_OP: /* AML_QWORDATA_ARG */
523 case AML_STRING_OP: /* AML_ASCIICHARLIST_ARG */
525 /* Fill in constant or string argument directly */
527 AcpiPsGetNextSimpleArg (&(WalkState->ParserState),
528 GET_CURRENT_ARG_TYPE (WalkState->ArgTypes), Op);
529 break;
531 case AML_INT_NAMEPATH_OP: /* AML_NAMESTRING_ARG */
533 Status = AcpiPsGetNextNamepath (WalkState, &(WalkState->ParserState), Op, 1);
534 if (ACPI_FAILURE (Status))
536 return_ACPI_STATUS (Status);
539 WalkState->ArgTypes = 0;
540 break;
542 default:
544 * Op is not a constant or string, append each argument to the Op
546 while (GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) && !WalkState->ArgCount)
548 WalkState->AmlOffset = (UINT32) ACPI_PTR_DIFF (WalkState->ParserState.Aml,
549 WalkState->ParserState.AmlStart);
551 Status = AcpiPsGetNextArg (WalkState, &(WalkState->ParserState),
552 GET_CURRENT_ARG_TYPE (WalkState->ArgTypes), &Arg);
553 if (ACPI_FAILURE (Status))
555 return_ACPI_STATUS (Status);
558 if (Arg)
560 Arg->Common.AmlOffset = WalkState->AmlOffset;
561 AcpiPsAppendArg (Op, Arg);
564 INCREMENT_ARG_LIST (WalkState->ArgTypes);
569 * Handle executable code at "module-level". This refers to
570 * executable opcodes that appear outside of any control method.
572 if ((WalkState->PassNumber <= ACPI_IMODE_LOAD_PASS2) &&
573 ((WalkState->ParseFlags & ACPI_PARSE_DISASSEMBLE) == 0))
576 * We want to skip If/Else/While constructs during Pass1 because we
577 * want to actually conditionally execute the code during Pass2.
579 * Except for disassembly, where we always want to walk the
580 * If/Else/While packages
582 switch (Op->Common.AmlOpcode)
584 case AML_IF_OP:
585 case AML_ELSE_OP:
586 case AML_WHILE_OP:
589 * Currently supported module-level opcodes are:
590 * IF/ELSE/WHILE. These appear to be the most common,
591 * and easiest to support since they open an AML
592 * package.
594 if (WalkState->PassNumber == ACPI_IMODE_LOAD_PASS1)
596 AcpiPsLinkModuleCode (AmlOpStart,
597 WalkState->ParserState.PkgEnd - AmlOpStart,
598 WalkState->OwnerId);
601 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
602 "Pass1: Skipping an If/Else/While body\n"));
604 /* Skip body of if/else/while in pass 1 */
606 WalkState->ParserState.Aml = WalkState->ParserState.PkgEnd;
607 WalkState->ArgCount = 0;
608 break;
610 default:
612 * Check for an unsupported executable opcode at module
613 * level. We must be in PASS1, the parent must be a SCOPE,
614 * The opcode class must be EXECUTE, and the opcode must
615 * not be an argument to another opcode.
617 if ((WalkState->PassNumber == ACPI_IMODE_LOAD_PASS1) &&
618 (Op->Common.Parent->Common.AmlOpcode == AML_SCOPE_OP))
620 OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
621 if ((OpInfo->Class == AML_CLASS_EXECUTE) &&
622 (!Arg))
624 ACPI_WARNING ((AE_INFO,
625 "Detected an unsupported executable opcode "
626 "at module-level: [0x%.4X] at table offset 0x%.4X",
627 Op->Common.AmlOpcode,
628 (UINT16)((AmlOpStart - WalkState->ParserState.AmlStart) +
629 sizeof (ACPI_TABLE_HEADER))));
632 break;
636 /* Special processing for certain opcodes */
638 switch (Op->Common.AmlOpcode)
640 case AML_METHOD_OP:
642 * Skip parsing of control method because we don't have enough
643 * info in the first pass to parse it correctly.
645 * Save the length and address of the body
647 Op->Named.Data = WalkState->ParserState.Aml;
648 Op->Named.Length = (UINT32)
649 (WalkState->ParserState.PkgEnd - WalkState->ParserState.Aml);
651 /* Skip body of method */
653 WalkState->ParserState.Aml = WalkState->ParserState.PkgEnd;
654 WalkState->ArgCount = 0;
655 break;
657 case AML_BUFFER_OP:
658 case AML_PACKAGE_OP:
659 case AML_VAR_PACKAGE_OP:
661 if ((Op->Common.Parent) &&
662 (Op->Common.Parent->Common.AmlOpcode == AML_NAME_OP) &&
663 (WalkState->PassNumber <= ACPI_IMODE_LOAD_PASS2))
666 * Skip parsing of Buffers and Packages because we don't have
667 * enough info in the first pass to parse them correctly.
669 Op->Named.Data = AmlOpStart;
670 Op->Named.Length = (UINT32)
671 (WalkState->ParserState.PkgEnd - AmlOpStart);
673 /* Skip body */
675 WalkState->ParserState.Aml = WalkState->ParserState.PkgEnd;
676 WalkState->ArgCount = 0;
678 break;
680 case AML_WHILE_OP:
682 if (WalkState->ControlState)
684 WalkState->ControlState->Control.PackageEnd =
685 WalkState->ParserState.PkgEnd;
687 break;
689 default:
691 /* No action for all other opcodes */
692 break;
695 break;
698 return_ACPI_STATUS (AE_OK);
702 /*******************************************************************************
704 * FUNCTION: AcpiPsLinkModuleCode
706 * PARAMETERS: AmlStart - Pointer to the AML
707 * AmlLength - Length of executable AML
708 * OwnerId - OwnerId of module level code
710 * RETURN: None.
712 * DESCRIPTION: Wrap the module-level code with a method object and link the
713 * object to the global list. Note, the mutex field of the method
714 * object is used to link multiple module-level code objects.
716 ******************************************************************************/
718 static void
719 AcpiPsLinkModuleCode (
720 UINT8 *AmlStart,
721 UINT32 AmlLength,
722 ACPI_OWNER_ID OwnerId)
724 ACPI_OPERAND_OBJECT *Prev;
725 ACPI_OPERAND_OBJECT *Next;
726 ACPI_OPERAND_OBJECT *MethodObj;
729 /* Get the tail of the list */
731 Prev = Next = AcpiGbl_ModuleCodeList;
732 while (Next)
734 Prev = Next;
735 Next = Next->Method.Mutex;
739 * Insert the module level code into the list. Merge it if it is
740 * adjacent to the previous element.
742 if (!Prev ||
743 ((Prev->Method.AmlStart + Prev->Method.AmlLength) != AmlStart))
745 /* Create, initialize, and link a new temporary method object */
747 MethodObj = AcpiUtCreateInternalObject (ACPI_TYPE_METHOD);
748 if (!MethodObj)
750 return;
753 MethodObj->Method.AmlStart = AmlStart;
754 MethodObj->Method.AmlLength = AmlLength;
755 MethodObj->Method.OwnerId = OwnerId;
756 MethodObj->Method.Flags |= AOPOBJ_MODULE_LEVEL;
758 if (!Prev)
760 AcpiGbl_ModuleCodeList = MethodObj;
762 else
764 Prev->Method.Mutex = MethodObj;
767 else
769 Prev->Method.AmlLength += AmlLength;
774 /*******************************************************************************
776 * FUNCTION: AcpiPsCompleteOp
778 * PARAMETERS: WalkState - Current state
779 * Op - Returned Op
780 * Status - Parse status before complete Op
782 * RETURN: Status
784 * DESCRIPTION: Complete Op
786 ******************************************************************************/
788 static ACPI_STATUS
789 AcpiPsCompleteOp (
790 ACPI_WALK_STATE *WalkState,
791 ACPI_PARSE_OBJECT **Op,
792 ACPI_STATUS Status)
794 ACPI_STATUS Status2;
797 ACPI_FUNCTION_TRACE_PTR (PsCompleteOp, WalkState);
801 * Finished one argument of the containing scope
803 WalkState->ParserState.Scope->ParseScope.ArgCount--;
805 /* Close this Op (will result in parse subtree deletion) */
807 Status2 = AcpiPsCompleteThisOp (WalkState, *Op);
808 if (ACPI_FAILURE (Status2))
810 return_ACPI_STATUS (Status2);
813 *Op = NULL;
815 switch (Status)
817 case AE_OK:
818 break;
821 case AE_CTRL_TRANSFER:
823 /* We are about to transfer to a called method */
825 WalkState->PrevOp = NULL;
826 WalkState->PrevArgTypes = WalkState->ArgTypes;
827 return_ACPI_STATUS (Status);
830 case AE_CTRL_END:
832 AcpiPsPopScope (&(WalkState->ParserState), Op,
833 &WalkState->ArgTypes, &WalkState->ArgCount);
835 if (*Op)
837 WalkState->Op = *Op;
838 WalkState->OpInfo = AcpiPsGetOpcodeInfo ((*Op)->Common.AmlOpcode);
839 WalkState->Opcode = (*Op)->Common.AmlOpcode;
841 Status = WalkState->AscendingCallback (WalkState);
842 Status = AcpiPsNextParseState (WalkState, *Op, Status);
844 Status2 = AcpiPsCompleteThisOp (WalkState, *Op);
845 if (ACPI_FAILURE (Status2))
847 return_ACPI_STATUS (Status2);
851 Status = AE_OK;
852 break;
855 case AE_CTRL_BREAK:
856 case AE_CTRL_CONTINUE:
858 /* Pop off scopes until we find the While */
860 while (!(*Op) || ((*Op)->Common.AmlOpcode != AML_WHILE_OP))
862 AcpiPsPopScope (&(WalkState->ParserState), Op,
863 &WalkState->ArgTypes, &WalkState->ArgCount);
866 /* Close this iteration of the While loop */
868 WalkState->Op = *Op;
869 WalkState->OpInfo = AcpiPsGetOpcodeInfo ((*Op)->Common.AmlOpcode);
870 WalkState->Opcode = (*Op)->Common.AmlOpcode;
872 Status = WalkState->AscendingCallback (WalkState);
873 Status = AcpiPsNextParseState (WalkState, *Op, Status);
875 Status2 = AcpiPsCompleteThisOp (WalkState, *Op);
876 if (ACPI_FAILURE (Status2))
878 return_ACPI_STATUS (Status2);
881 Status = AE_OK;
882 break;
885 case AE_CTRL_TERMINATE:
887 /* Clean up */
890 if (*Op)
892 Status2 = AcpiPsCompleteThisOp (WalkState, *Op);
893 if (ACPI_FAILURE (Status2))
895 return_ACPI_STATUS (Status2);
898 AcpiUtDeleteGenericState (
899 AcpiUtPopGenericState (&WalkState->ControlState));
902 AcpiPsPopScope (&(WalkState->ParserState), Op,
903 &WalkState->ArgTypes, &WalkState->ArgCount);
905 } while (*Op);
907 return_ACPI_STATUS (AE_OK);
910 default: /* All other non-AE_OK status */
914 if (*Op)
916 Status2 = AcpiPsCompleteThisOp (WalkState, *Op);
917 if (ACPI_FAILURE (Status2))
919 return_ACPI_STATUS (Status2);
923 AcpiPsPopScope (&(WalkState->ParserState), Op,
924 &WalkState->ArgTypes, &WalkState->ArgCount);
926 } while (*Op);
929 #if 0
931 * TBD: Cleanup parse ops on error
933 if (*Op == NULL)
935 AcpiPsPopScope (ParserState, Op,
936 &WalkState->ArgTypes, &WalkState->ArgCount);
938 #endif
939 WalkState->PrevOp = NULL;
940 WalkState->PrevArgTypes = WalkState->ArgTypes;
941 return_ACPI_STATUS (Status);
944 /* This scope complete? */
946 if (AcpiPsHasCompletedScope (&(WalkState->ParserState)))
948 AcpiPsPopScope (&(WalkState->ParserState), Op,
949 &WalkState->ArgTypes, &WalkState->ArgCount);
950 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", *Op));
952 else
954 *Op = NULL;
957 return_ACPI_STATUS (AE_OK);
961 /*******************************************************************************
963 * FUNCTION: AcpiPsCompleteFinalOp
965 * PARAMETERS: WalkState - Current state
966 * Op - Current Op
967 * Status - Current parse status before complete last
968 * Op
970 * RETURN: Status
972 * DESCRIPTION: Complete last Op.
974 ******************************************************************************/
976 static ACPI_STATUS
977 AcpiPsCompleteFinalOp (
978 ACPI_WALK_STATE *WalkState,
979 ACPI_PARSE_OBJECT *Op,
980 ACPI_STATUS Status)
982 ACPI_STATUS Status2;
985 ACPI_FUNCTION_TRACE_PTR (PsCompleteFinalOp, WalkState);
989 * Complete the last Op (if not completed), and clear the scope stack.
990 * It is easily possible to end an AML "package" with an unbounded number
991 * of open scopes (such as when several ASL blocks are closed with
992 * sequential closing braces). We want to terminate each one cleanly.
994 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "AML package complete at Op %p\n", Op));
997 if (Op)
999 if (WalkState->AscendingCallback != NULL)
1001 WalkState->Op = Op;
1002 WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
1003 WalkState->Opcode = Op->Common.AmlOpcode;
1005 Status = WalkState->AscendingCallback (WalkState);
1006 Status = AcpiPsNextParseState (WalkState, Op, Status);
1007 if (Status == AE_CTRL_PENDING)
1009 Status = AcpiPsCompleteOp (WalkState, &Op, AE_OK);
1010 if (ACPI_FAILURE (Status))
1012 return_ACPI_STATUS (Status);
1016 if (Status == AE_CTRL_TERMINATE)
1018 Status = AE_OK;
1020 /* Clean up */
1023 if (Op)
1025 Status2 = AcpiPsCompleteThisOp (WalkState, Op);
1026 if (ACPI_FAILURE (Status2))
1028 return_ACPI_STATUS (Status2);
1032 AcpiPsPopScope (&(WalkState->ParserState), &Op,
1033 &WalkState->ArgTypes, &WalkState->ArgCount);
1035 } while (Op);
1037 return_ACPI_STATUS (Status);
1040 else if (ACPI_FAILURE (Status))
1042 /* First error is most important */
1044 (void) AcpiPsCompleteThisOp (WalkState, Op);
1045 return_ACPI_STATUS (Status);
1049 Status2 = AcpiPsCompleteThisOp (WalkState, Op);
1050 if (ACPI_FAILURE (Status2))
1052 return_ACPI_STATUS (Status2);
1056 AcpiPsPopScope (&(WalkState->ParserState), &Op, &WalkState->ArgTypes,
1057 &WalkState->ArgCount);
1059 } while (Op);
1061 return_ACPI_STATUS (Status);
1065 /*******************************************************************************
1067 * FUNCTION: AcpiPsParseLoop
1069 * PARAMETERS: WalkState - Current state
1071 * RETURN: Status
1073 * DESCRIPTION: Parse AML (pointed to by the current parser state) and return
1074 * a tree of ops.
1076 ******************************************************************************/
1078 ACPI_STATUS
1079 AcpiPsParseLoop (
1080 ACPI_WALK_STATE *WalkState)
1082 ACPI_STATUS Status = AE_OK;
1083 ACPI_PARSE_OBJECT *Op = NULL; /* current op */
1084 ACPI_PARSE_STATE *ParserState;
1085 UINT8 *AmlOpStart = NULL;
1088 ACPI_FUNCTION_TRACE_PTR (PsParseLoop, WalkState);
1091 if (WalkState->DescendingCallback == NULL)
1093 return_ACPI_STATUS (AE_BAD_PARAMETER);
1096 ParserState = &WalkState->ParserState;
1097 WalkState->ArgTypes = 0;
1099 #if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY))
1101 if (WalkState->WalkType & ACPI_WALK_METHOD_RESTART)
1103 /* We are restarting a preempted control method */
1105 if (AcpiPsHasCompletedScope (ParserState))
1108 * We must check if a predicate to an IF or WHILE statement
1109 * was just completed
1111 if ((ParserState->Scope->ParseScope.Op) &&
1112 ((ParserState->Scope->ParseScope.Op->Common.AmlOpcode == AML_IF_OP) ||
1113 (ParserState->Scope->ParseScope.Op->Common.AmlOpcode == AML_WHILE_OP)) &&
1114 (WalkState->ControlState) &&
1115 (WalkState->ControlState->Common.State ==
1116 ACPI_CONTROL_PREDICATE_EXECUTING))
1119 * A predicate was just completed, get the value of the
1120 * predicate and branch based on that value
1122 WalkState->Op = NULL;
1123 Status = AcpiDsGetPredicateValue (WalkState, ACPI_TO_POINTER (TRUE));
1124 if (ACPI_FAILURE (Status) &&
1125 ((Status & AE_CODE_MASK) != AE_CODE_CONTROL))
1127 if (Status == AE_AML_NO_RETURN_VALUE)
1129 ACPI_EXCEPTION ((AE_INFO, Status,
1130 "Invoked method did not return a value"));
1134 ACPI_EXCEPTION ((AE_INFO, Status, "GetPredicate Failed"));
1135 return_ACPI_STATUS (Status);
1138 Status = AcpiPsNextParseState (WalkState, Op, Status);
1141 AcpiPsPopScope (ParserState, &Op,
1142 &WalkState->ArgTypes, &WalkState->ArgCount);
1143 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", Op));
1145 else if (WalkState->PrevOp)
1147 /* We were in the middle of an op */
1149 Op = WalkState->PrevOp;
1150 WalkState->ArgTypes = WalkState->PrevArgTypes;
1153 #endif
1155 /* Iterative parsing loop, while there is more AML to process: */
1157 while ((ParserState->Aml < ParserState->AmlEnd) || (Op))
1159 AmlOpStart = ParserState->Aml;
1160 if (!Op)
1162 Status = AcpiPsCreateOp (WalkState, AmlOpStart, &Op);
1163 if (ACPI_FAILURE (Status))
1165 if (Status == AE_CTRL_PARSE_CONTINUE)
1167 continue;
1170 if (Status == AE_CTRL_PARSE_PENDING)
1172 Status = AE_OK;
1175 Status = AcpiPsCompleteOp (WalkState, &Op, Status);
1176 if (ACPI_FAILURE (Status))
1178 return_ACPI_STATUS (Status);
1181 continue;
1184 Op->Common.AmlOffset = WalkState->AmlOffset;
1186 if (WalkState->OpInfo)
1188 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
1189 "Opcode %4.4X [%s] Op %p Aml %p AmlOffset %5.5X\n",
1190 (UINT32) Op->Common.AmlOpcode, WalkState->OpInfo->Name,
1191 Op, ParserState->Aml, Op->Common.AmlOffset));
1197 * Start ArgCount at zero because we don't know if there are
1198 * any args yet
1200 WalkState->ArgCount = 0;
1202 /* Are there any arguments that must be processed? */
1204 if (WalkState->ArgTypes)
1206 /* Get arguments */
1208 Status = AcpiPsGetArguments (WalkState, AmlOpStart, Op);
1209 if (ACPI_FAILURE (Status))
1211 Status = AcpiPsCompleteOp (WalkState, &Op, Status);
1212 if (ACPI_FAILURE (Status))
1214 return_ACPI_STATUS (Status);
1217 continue;
1221 /* Check for arguments that need to be processed */
1223 if (WalkState->ArgCount)
1226 * There are arguments (complex ones), push Op and
1227 * prepare for argument
1229 Status = AcpiPsPushScope (ParserState, Op,
1230 WalkState->ArgTypes, WalkState->ArgCount);
1231 if (ACPI_FAILURE (Status))
1233 Status = AcpiPsCompleteOp (WalkState, &Op, Status);
1234 if (ACPI_FAILURE (Status))
1236 return_ACPI_STATUS (Status);
1239 continue;
1242 Op = NULL;
1243 continue;
1247 * All arguments have been processed -- Op is complete,
1248 * prepare for next
1250 WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
1251 if (WalkState->OpInfo->Flags & AML_NAMED)
1253 if (AcpiGbl_Depth)
1255 AcpiGbl_Depth--;
1258 if (Op->Common.AmlOpcode == AML_REGION_OP ||
1259 Op->Common.AmlOpcode == AML_DATA_REGION_OP)
1262 * Skip parsing of control method or opregion body,
1263 * because we don't have enough info in the first pass
1264 * to parse them correctly.
1266 * Completed parsing an OpRegion declaration, we now
1267 * know the length.
1269 Op->Named.Length = (UINT32) (ParserState->Aml - Op->Named.Data);
1273 if (WalkState->OpInfo->Flags & AML_CREATE)
1276 * Backup to beginning of CreateXXXfield declaration (1 for
1277 * Opcode)
1279 * BodyLength is unknown until we parse the body
1281 Op->Named.Length = (UINT32) (ParserState->Aml - Op->Named.Data);
1284 if (Op->Common.AmlOpcode == AML_BANK_FIELD_OP)
1287 * Backup to beginning of BankField declaration
1289 * BodyLength is unknown until we parse the body
1291 Op->Named.Length = (UINT32) (ParserState->Aml - Op->Named.Data);
1294 /* This op complete, notify the dispatcher */
1296 if (WalkState->AscendingCallback != NULL)
1298 WalkState->Op = Op;
1299 WalkState->Opcode = Op->Common.AmlOpcode;
1301 Status = WalkState->AscendingCallback (WalkState);
1302 Status = AcpiPsNextParseState (WalkState, Op, Status);
1303 if (Status == AE_CTRL_PENDING)
1305 Status = AE_OK;
1309 Status = AcpiPsCompleteOp (WalkState, &Op, Status);
1310 if (ACPI_FAILURE (Status))
1312 return_ACPI_STATUS (Status);
1315 } /* while ParserState->Aml */
1317 Status = AcpiPsCompleteFinalOp (WalkState, Op, Status);
1318 return_ACPI_STATUS (Status);