Back to home page

Quest Cross Reference

 
 

    


Warning, cross-references for /kernel/drivers/acpica/psloop.c need to be fixed.

0001 /******************************************************************************
0002  *
0003  * Module Name: psloop - Main AML parse loop
0004  *
0005  *****************************************************************************/
0006 
0007 /******************************************************************************
0008  *
0009  * 1. Copyright Notice
0010  *
0011  * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp.
0012  * All rights reserved.
0013  *
0014  * 2. License
0015  *
0016  * 2.1. This is your license from Intel Corp. under its intellectual property
0017  * rights.  You may have additional license terms from the party that provided
0018  * you this software, covering your right to use that party's intellectual
0019  * property rights.
0020  *
0021  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
0022  * copy of the source code appearing in this file ("Covered Code") an
0023  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
0024  * base code distributed originally by Intel ("Original Intel Code") to copy,
0025  * make derivatives, distribute, use and display any portion of the Covered
0026  * Code in any form, with the right to sublicense such rights; and
0027  *
0028  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
0029  * license (with the right to sublicense), under only those claims of Intel
0030  * patents that are infringed by the Original Intel Code, to make, use, sell,
0031  * offer to sell, and import the Covered Code and derivative works thereof
0032  * solely to the minimum extent necessary to exercise the above copyright
0033  * license, and in no event shall the patent license extend to any additions
0034  * to or modifications of the Original Intel Code.  No other license or right
0035  * is granted directly or by implication, estoppel or otherwise;
0036  *
0037  * The above copyright and patent license is granted only if the following
0038  * conditions are met:
0039  *
0040  * 3. Conditions
0041  *
0042  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
0043  * Redistribution of source code of any substantial portion of the Covered
0044  * Code or modification with rights to further distribute source must include
0045  * the above Copyright Notice, the above License, this list of Conditions,
0046  * and the following Disclaimer and Export Compliance provision.  In addition,
0047  * Licensee must cause all Covered Code to which Licensee contributes to
0048  * contain a file documenting the changes Licensee made to create that Covered
0049  * Code and the date of any change.  Licensee must include in that file the
0050  * documentation of any changes made by any predecessor Licensee.  Licensee
0051  * must include a prominent statement that the modification is derived,
0052  * directly or indirectly, from Original Intel Code.
0053  *
0054  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
0055  * Redistribution of source code of any substantial portion of the Covered
0056  * Code or modification without rights to further distribute source must
0057  * include the following Disclaimer and Export Compliance provision in the
0058  * documentation and/or other materials provided with distribution.  In
0059  * addition, Licensee may not authorize further sublicense of source of any
0060  * portion of the Covered Code, and must include terms to the effect that the
0061  * license from Licensee to its licensee is limited to the intellectual
0062  * property embodied in the software Licensee provides to its licensee, and
0063  * not to intellectual property embodied in modifications its licensee may
0064  * make.
0065  *
0066  * 3.3. Redistribution of Executable. Redistribution in executable form of any
0067  * substantial portion of the Covered Code or modification must reproduce the
0068  * above Copyright Notice, and the following Disclaimer and Export Compliance
0069  * provision in the documentation and/or other materials provided with the
0070  * distribution.
0071  *
0072  * 3.4. Intel retains all right, title, and interest in and to the Original
0073  * Intel Code.
0074  *
0075  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
0076  * Intel shall be used in advertising or otherwise to promote the sale, use or
0077  * other dealings in products derived from or relating to the Covered Code
0078  * without prior written authorization from Intel.
0079  *
0080  * 4. Disclaimer and Export Compliance
0081  *
0082  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
0083  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
0084  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
0085  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
0086  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
0087  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
0088  * PARTICULAR PURPOSE.
0089  *
0090  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
0091  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
0092  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
0093  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
0094  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
0095  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
0096  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
0097  * LIMITED REMEDY.
0098  *
0099  * 4.3. Licensee shall not export, either directly or indirectly, any of this
0100  * software or system incorporating such software without first obtaining any
0101  * required license or other approval from the U. S. Department of Commerce or
0102  * any other agency or department of the United States Government.  In the
0103  * event Licensee exports any such software from the United States or
0104  * re-exports any such software from a foreign destination, Licensee shall
0105  * ensure that the distribution and export/re-export of the software is in
0106  * compliance with all laws, regulations, orders, or other restrictions of the
0107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
0108  * any of its subsidiaries will export/re-export any technical data, process,
0109  * software, or service, directly or indirectly, to any country for which the
0110  * United States government or any agency thereof requires an export license,
0111  * other governmental approval, or letter of assurance, without first obtaining
0112  * such license, approval or letter.
0113  *
0114  *****************************************************************************/
0115 
0116 
0117 /*
0118  * Parse the AML and build an operation tree as most interpreters, (such as
0119  * Perl) do. Parsing is done by hand rather than with a YACC generated parser
0120  * to tightly constrain stack and dynamic memory usage. Parsing is kept
0121  * flexible and the code fairly compact by parsing based on a list of AML
0122  * opcode templates in AmlOpInfo[].
0123  */
0124 
0125 #include "acpi.h"
0126 #include "accommon.h"
0127 #include "acparser.h"
0128 #include "acdispat.h"
0129 #include "amlcode.h"
0130 
0131 #define _COMPONENT          ACPI_PARSER
0132         ACPI_MODULE_NAME    ("psloop")
0133 
0134 static UINT32               AcpiGbl_Depth = 0;
0135 
0136 
0137 /* Local prototypes */
0138 
0139 static ACPI_STATUS
0140 AcpiPsGetAmlOpcode (
0141     ACPI_WALK_STATE         *WalkState);
0142 
0143 static ACPI_STATUS
0144 AcpiPsBuildNamedOp (
0145     ACPI_WALK_STATE         *WalkState,
0146     UINT8                   *AmlOpStart,
0147     ACPI_PARSE_OBJECT       *UnnamedOp,
0148     ACPI_PARSE_OBJECT       **Op);
0149 
0150 static ACPI_STATUS
0151 AcpiPsCreateOp (
0152     ACPI_WALK_STATE         *WalkState,
0153     UINT8                   *AmlOpStart,
0154     ACPI_PARSE_OBJECT       **NewOp);
0155 
0156 static ACPI_STATUS
0157 AcpiPsGetArguments (
0158     ACPI_WALK_STATE         *WalkState,
0159     UINT8                   *AmlOpStart,
0160     ACPI_PARSE_OBJECT       *Op);
0161 
0162 static ACPI_STATUS
0163 AcpiPsCompleteOp (
0164     ACPI_WALK_STATE         *WalkState,
0165     ACPI_PARSE_OBJECT       **Op,
0166     ACPI_STATUS             Status);
0167 
0168 static ACPI_STATUS
0169 AcpiPsCompleteFinalOp (
0170     ACPI_WALK_STATE         *WalkState,
0171     ACPI_PARSE_OBJECT       *Op,
0172     ACPI_STATUS             Status);
0173 
0174 
0175 /*******************************************************************************
0176  *
0177  * FUNCTION:    AcpiPsGetAmlOpcode
0178  *
0179  * PARAMETERS:  WalkState           - Current state
0180  *
0181  * RETURN:      Status
0182  *
0183  * DESCRIPTION: Extract the next AML opcode from the input stream.
0184  *
0185  ******************************************************************************/
0186 
0187 static ACPI_STATUS
0188 AcpiPsGetAmlOpcode (
0189     ACPI_WALK_STATE         *WalkState)
0190 {
0191 
0192     ACPI_FUNCTION_TRACE_PTR (PsGetAmlOpcode, WalkState);
0193 
0194 
0195     WalkState->AmlOffset = (UINT32) ACPI_PTR_DIFF (WalkState->ParserState.Aml,
0196                                 WalkState->ParserState.AmlStart);
0197     WalkState->Opcode = AcpiPsPeekOpcode (&(WalkState->ParserState));
0198 
0199     /*
0200      * First cut to determine what we have found:
0201      * 1) A valid AML opcode
0202      * 2) A name string
0203      * 3) An unknown/invalid opcode
0204      */
0205     WalkState->OpInfo = AcpiPsGetOpcodeInfo (WalkState->Opcode);
0206 
0207     switch (WalkState->OpInfo->Class)
0208     {
0209     case AML_CLASS_ASCII:
0210     case AML_CLASS_PREFIX:
0211         /*
0212          * Starts with a valid prefix or ASCII char, this is a name
0213          * string. Convert the bare name string to a namepath.
0214          */
0215         WalkState->Opcode = AML_INT_NAMEPATH_OP;
0216         WalkState->ArgTypes = ARGP_NAMESTRING;
0217         break;
0218 
0219     case AML_CLASS_UNKNOWN:
0220 
0221         /* The opcode is unrecognized. Just skip unknown opcodes */
0222 
0223         ACPI_ERROR ((AE_INFO,
0224              "Found unknown opcode %X at AML address %p offset %X, ignoring",
0225               WalkState->Opcode, WalkState->ParserState.Aml, WalkState->AmlOffset));
0226 
0227         ACPI_DUMP_BUFFER (WalkState->ParserState.Aml, 128);
0228 
0229         /* Assume one-byte bad opcode */
0230 
0231         WalkState->ParserState.Aml++;
0232         return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE);
0233 
0234     default:
0235 
0236         /* Found opcode info, this is a normal opcode */
0237 
0238         WalkState->ParserState.Aml += AcpiPsGetOpcodeSize (WalkState->Opcode);
0239         WalkState->ArgTypes = WalkState->OpInfo->ParseArgs;
0240         break;
0241     }
0242 
0243     return_ACPI_STATUS (AE_OK);
0244 }
0245 
0246 
0247 /*******************************************************************************
0248  *
0249  * FUNCTION:    AcpiPsBuildNamedOp
0250  *
0251  * PARAMETERS:  WalkState           - Current state
0252  *              AmlOpStart          - Begin of named Op in AML
0253  *              UnnamedOp           - Early Op (not a named Op)
0254  *              Op                  - Returned Op
0255  *
0256  * RETURN:      Status
0257  *
0258  * DESCRIPTION: Parse a named Op
0259  *
0260  ******************************************************************************/
0261 
0262 static ACPI_STATUS
0263 AcpiPsBuildNamedOp (
0264     ACPI_WALK_STATE         *WalkState,
0265     UINT8                   *AmlOpStart,
0266     ACPI_PARSE_OBJECT       *UnnamedOp,
0267     ACPI_PARSE_OBJECT       **Op)
0268 {
0269     ACPI_STATUS             Status = AE_OK;
0270     ACPI_PARSE_OBJECT       *Arg = NULL;
0271 
0272 
0273     ACPI_FUNCTION_TRACE_PTR (PsBuildNamedOp, WalkState);
0274 
0275 
0276     UnnamedOp->Common.Value.Arg = NULL;
0277     UnnamedOp->Common.ArgListLength = 0;
0278     UnnamedOp->Common.AmlOpcode = WalkState->Opcode;
0279 
0280     /*
0281      * Get and append arguments until we find the node that contains
0282      * the name (the type ARGP_NAME).
0283      */
0284     while (GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) &&
0285           (GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) != ARGP_NAME))
0286     {
0287         Status = AcpiPsGetNextArg (WalkState, &(WalkState->ParserState),
0288                     GET_CURRENT_ARG_TYPE (WalkState->ArgTypes), &Arg);
0289         if (ACPI_FAILURE (Status))
0290         {
0291             return_ACPI_STATUS (Status);
0292         }
0293 
0294         AcpiPsAppendArg (UnnamedOp, Arg);
0295         INCREMENT_ARG_LIST (WalkState->ArgTypes);
0296     }
0297 
0298     /*
0299      * Make sure that we found a NAME and didn't run out of arguments
0300      */
0301     if (!GET_CURRENT_ARG_TYPE (WalkState->ArgTypes))
0302     {
0303         return_ACPI_STATUS (AE_AML_NO_OPERAND);
0304     }
0305 
0306     /* We know that this arg is a name, move to next arg */
0307 
0308     INCREMENT_ARG_LIST (WalkState->ArgTypes);
0309 
0310     /*
0311      * Find the object. This will either insert the object into
0312      * the namespace or simply look it up
0313      */
0314     WalkState->Op = NULL;
0315 
0316     Status = WalkState->DescendingCallback (WalkState, Op);
0317     if (ACPI_FAILURE (Status))
0318     {
0319         ACPI_EXCEPTION ((AE_INFO, Status, "During name lookup/catalog"));
0320         return_ACPI_STATUS (Status);
0321     }
0322 
0323     if (!*Op)
0324     {
0325         return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE);
0326     }
0327 
0328     Status = AcpiPsNextParseState (WalkState, *Op, Status);
0329     if (ACPI_FAILURE (Status))
0330     {
0331         if (Status == AE_CTRL_PENDING)
0332         {
0333             return_ACPI_STATUS (AE_CTRL_PARSE_PENDING);
0334         }
0335         return_ACPI_STATUS (Status);
0336     }
0337 
0338     AcpiPsAppendArg (*Op, UnnamedOp->Common.Value.Arg);
0339     AcpiGbl_Depth++;
0340 
0341     if ((*Op)->Common.AmlOpcode == AML_REGION_OP ||
0342         (*Op)->Common.AmlOpcode == AML_DATA_REGION_OP)
0343     {
0344         /*
0345          * Defer final parsing of an OperationRegion body, because we don't
0346          * have enough info in the first pass to parse it correctly (i.e.,
0347          * there may be method calls within the TermArg elements of the body.)
0348          *
0349          * However, we must continue parsing because the opregion is not a
0350          * standalone package -- we don't know where the end is at this point.
0351          *
0352          * (Length is unknown until parse of the body complete)
0353          */
0354         (*Op)->Named.Data = AmlOpStart;
0355         (*Op)->Named.Length = 0;
0356     }
0357 
0358     return_ACPI_STATUS (AE_OK);
0359 }
0360 
0361 
0362 /*******************************************************************************
0363  *
0364  * FUNCTION:    AcpiPsCreateOp
0365  *
0366  * PARAMETERS:  WalkState           - Current state
0367  *              AmlOpStart          - Op start in AML
0368  *              NewOp               - Returned Op
0369  *
0370  * RETURN:      Status
0371  *
0372  * DESCRIPTION: Get Op from AML
0373  *
0374  ******************************************************************************/
0375 
0376 static ACPI_STATUS
0377 AcpiPsCreateOp (
0378     ACPI_WALK_STATE         *WalkState,
0379     UINT8                   *AmlOpStart,
0380     ACPI_PARSE_OBJECT       **NewOp)
0381 {
0382     ACPI_STATUS             Status = AE_OK;
0383     ACPI_PARSE_OBJECT       *Op;
0384     ACPI_PARSE_OBJECT       *NamedOp = NULL;
0385     ACPI_PARSE_OBJECT       *ParentScope;
0386     UINT8                   ArgumentCount;
0387     const ACPI_OPCODE_INFO  *OpInfo;
0388 
0389 
0390     ACPI_FUNCTION_TRACE_PTR (PsCreateOp, WalkState);
0391 
0392 
0393     Status = AcpiPsGetAmlOpcode (WalkState);
0394     if (Status == AE_CTRL_PARSE_CONTINUE)
0395     {
0396         return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE);
0397     }
0398 
0399     /* Create Op structure and append to parent's argument list */
0400 
0401     WalkState->OpInfo = AcpiPsGetOpcodeInfo (WalkState->Opcode);
0402     Op = AcpiPsAllocOp (WalkState->Opcode);
0403     if (!Op)
0404     {
0405         return_ACPI_STATUS (AE_NO_MEMORY);
0406     }
0407 
0408     if (WalkState->OpInfo->Flags & AML_NAMED)
0409     {
0410         Status = AcpiPsBuildNamedOp (WalkState, AmlOpStart, Op, &NamedOp);
0411         AcpiPsFreeOp (Op);
0412         if (ACPI_FAILURE (Status))
0413         {
0414             return_ACPI_STATUS (Status);
0415         }
0416 
0417         *NewOp = NamedOp;
0418         return_ACPI_STATUS (AE_OK);
0419     }
0420 
0421     /* Not a named opcode, just allocate Op and append to parent */
0422 
0423     if (WalkState->OpInfo->Flags & AML_CREATE)
0424     {
0425         /*
0426          * Backup to beginning of CreateXXXfield declaration
0427          * BodyLength is unknown until we parse the body
0428          */
0429         Op->Named.Data = AmlOpStart;
0430         Op->Named.Length = 0;
0431     }
0432 
0433     if (WalkState->Opcode == AML_BANK_FIELD_OP)
0434     {
0435         /*
0436          * Backup to beginning of BankField declaration
0437          * BodyLength is unknown until we parse the body
0438          */
0439         Op->Named.Data = AmlOpStart;
0440         Op->Named.Length = 0;
0441     }
0442 
0443     ParentScope = AcpiPsGetParentScope (&(WalkState->ParserState));
0444     AcpiPsAppendArg (ParentScope, Op);
0445 
0446     if (ParentScope)
0447     {
0448         OpInfo = AcpiPsGetOpcodeInfo (ParentScope->Common.AmlOpcode);
0449         if (OpInfo->Flags & AML_HAS_TARGET)
0450         {
0451             ArgumentCount = AcpiPsGetArgumentCount (OpInfo->Type);
0452             if (ParentScope->Common.ArgListLength > ArgumentCount)
0453             {
0454                 Op->Common.Flags |= ACPI_PARSEOP_TARGET;
0455             }
0456         }
0457         else if (ParentScope->Common.AmlOpcode == AML_INCREMENT_OP)
0458         {
0459             Op->Common.Flags |= ACPI_PARSEOP_TARGET;
0460         }
0461     }
0462 
0463     if (WalkState->DescendingCallback != NULL)
0464     {
0465         /*
0466          * Find the object. This will either insert the object into
0467          * the namespace or simply look it up
0468          */
0469         WalkState->Op = *NewOp = Op;
0470 
0471         Status = WalkState->DescendingCallback (WalkState, &Op);
0472         Status = AcpiPsNextParseState (WalkState, Op, Status);
0473         if (Status == AE_CTRL_PENDING)
0474         {
0475             Status = AE_CTRL_PARSE_PENDING;
0476         }
0477     }
0478 
0479     return_ACPI_STATUS (Status);
0480 }
0481 
0482 
0483 /*******************************************************************************
0484  *
0485  * FUNCTION:    AcpiPsGetArguments
0486  *
0487  * PARAMETERS:  WalkState           - Current state
0488  *              AmlOpStart          - Op start in AML
0489  *              Op                  - Current Op
0490  *
0491  * RETURN:      Status
0492  *
0493  * DESCRIPTION: Get arguments for passed Op.
0494  *
0495  ******************************************************************************/
0496 
0497 static ACPI_STATUS
0498 AcpiPsGetArguments (
0499     ACPI_WALK_STATE         *WalkState,
0500     UINT8                   *AmlOpStart,
0501     ACPI_PARSE_OBJECT       *Op)
0502 {
0503     ACPI_STATUS             Status = AE_OK;
0504     ACPI_PARSE_OBJECT       *Arg = NULL;
0505 
0506 
0507     ACPI_FUNCTION_TRACE_PTR (PsGetArguments, WalkState);
0508 
0509 
0510     switch (Op->Common.AmlOpcode)
0511     {
0512     case AML_BYTE_OP:       /* AML_BYTEDATA_ARG */
0513     case AML_WORD_OP:       /* AML_WORDDATA_ARG */
0514     case AML_DWORD_OP:      /* AML_DWORDATA_ARG */
0515     case AML_QWORD_OP:      /* AML_QWORDATA_ARG */
0516     case AML_STRING_OP:     /* AML_ASCIICHARLIST_ARG */
0517 
0518         /* Fill in constant or string argument directly */
0519 
0520         AcpiPsGetNextSimpleArg (&(WalkState->ParserState),
0521             GET_CURRENT_ARG_TYPE (WalkState->ArgTypes), Op);
0522         break;
0523 
0524     case AML_INT_NAMEPATH_OP:   /* AML_NAMESTRING_ARG */
0525 
0526         Status = AcpiPsGetNextNamepath (WalkState, &(WalkState->ParserState), Op, 1);
0527         if (ACPI_FAILURE (Status))
0528         {
0529             return_ACPI_STATUS (Status);
0530         }
0531 
0532         WalkState->ArgTypes = 0;
0533         break;
0534 
0535     default:
0536         /*
0537          * Op is not a constant or string, append each argument to the Op
0538          */
0539         while (GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) && !WalkState->ArgCount)
0540         {
0541             WalkState->AmlOffset = (UINT32) ACPI_PTR_DIFF (WalkState->ParserState.Aml,
0542                 WalkState->ParserState.AmlStart);
0543 
0544             Status = AcpiPsGetNextArg (WalkState, &(WalkState->ParserState),
0545                         GET_CURRENT_ARG_TYPE (WalkState->ArgTypes), &Arg);
0546             if (ACPI_FAILURE (Status))
0547             {
0548                 return_ACPI_STATUS (Status);
0549             }
0550 
0551             if (Arg)
0552             {
0553                 Arg->Common.AmlOffset = WalkState->AmlOffset;
0554                 AcpiPsAppendArg (Op, Arg);
0555             }
0556 
0557             INCREMENT_ARG_LIST (WalkState->ArgTypes);
0558         }
0559 
0560 
0561         /* Special processing for certain opcodes */
0562 
0563         /* TBD (remove): Temporary mechanism to disable this code if needed */
0564 
0565 #ifdef ACPI_ENABLE_MODULE_LEVEL_CODE
0566 
0567         if ((WalkState->PassNumber <= ACPI_IMODE_LOAD_PASS1) &&
0568             ((WalkState->ParseFlags & ACPI_PARSE_DISASSEMBLE) == 0))
0569         {
0570             /*
0571              * We want to skip If/Else/While constructs during Pass1 because we
0572              * want to actually conditionally execute the code during Pass2.
0573              *
0574              * Except for disassembly, where we always want to walk the
0575              * If/Else/While packages
0576              */
0577             switch (Op->Common.AmlOpcode)
0578             {
0579             case AML_IF_OP:
0580             case AML_ELSE_OP:
0581             case AML_WHILE_OP:
0582 
0583                 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
0584                     "Pass1: Skipping an If/Else/While body\n"));
0585 
0586                 /* Skip body of if/else/while in pass 1 */
0587 
0588                 WalkState->ParserState.Aml = WalkState->ParserState.PkgEnd;
0589                 WalkState->ArgCount = 0;
0590                 break;
0591 
0592             default:
0593                 break;
0594             }
0595         }
0596 #endif
0597 
0598         switch (Op->Common.AmlOpcode)
0599         {
0600         case AML_METHOD_OP:
0601             /*
0602              * Skip parsing of control method because we don't have enough
0603              * info in the first pass to parse it correctly.
0604              *
0605              * Save the length and address of the body
0606              */
0607             Op->Named.Data = WalkState->ParserState.Aml;
0608             Op->Named.Length = (UINT32)
0609                 (WalkState->ParserState.PkgEnd - WalkState->ParserState.Aml);
0610 
0611             /* Skip body of method */
0612 
0613             WalkState->ParserState.Aml = WalkState->ParserState.PkgEnd;
0614             WalkState->ArgCount = 0;
0615             break;
0616 
0617         case AML_BUFFER_OP:
0618         case AML_PACKAGE_OP:
0619         case AML_VAR_PACKAGE_OP:
0620 
0621             if ((Op->Common.Parent) &&
0622                 (Op->Common.Parent->Common.AmlOpcode == AML_NAME_OP) &&
0623                 (WalkState->PassNumber <= ACPI_IMODE_LOAD_PASS2))
0624             {
0625                 /*
0626                  * Skip parsing of Buffers and Packages because we don't have
0627                  * enough info in the first pass to parse them correctly.
0628                  */
0629                 Op->Named.Data = AmlOpStart;
0630                 Op->Named.Length = (UINT32)
0631                     (WalkState->ParserState.PkgEnd - AmlOpStart);
0632 
0633                 /* Skip body */
0634 
0635                 WalkState->ParserState.Aml = WalkState->ParserState.PkgEnd;
0636                 WalkState->ArgCount = 0;
0637             }
0638             break;
0639 
0640         case AML_WHILE_OP:
0641 
0642             if (WalkState->ControlState)
0643             {
0644                 WalkState->ControlState->Control.PackageEnd =
0645                     WalkState->ParserState.PkgEnd;
0646             }
0647             break;
0648 
0649         default:
0650 
0651             /* No action for all other opcodes */
0652             break;
0653         }
0654 
0655         break;
0656     }
0657 
0658     return_ACPI_STATUS (AE_OK);
0659 }
0660 
0661 
0662 /*******************************************************************************
0663  *
0664  * FUNCTION:    AcpiPsCompleteOp
0665  *
0666  * PARAMETERS:  WalkState           - Current state
0667  *              Op                  - Returned Op
0668  *              Status              - Parse status before complete Op
0669  *
0670  * RETURN:      Status
0671  *
0672  * DESCRIPTION: Complete Op
0673  *
0674  ******************************************************************************/
0675 
0676 static ACPI_STATUS
0677 AcpiPsCompleteOp (
0678     ACPI_WALK_STATE         *WalkState,
0679     ACPI_PARSE_OBJECT       **Op,
0680     ACPI_STATUS             Status)
0681 {
0682     ACPI_STATUS             Status2;
0683 
0684 
0685     ACPI_FUNCTION_TRACE_PTR (PsCompleteOp, WalkState);
0686 
0687 
0688     /*
0689      * Finished one argument of the containing scope
0690      */
0691     WalkState->ParserState.Scope->ParseScope.ArgCount--;
0692 
0693     /* Close this Op (will result in parse subtree deletion) */
0694 
0695     Status2 = AcpiPsCompleteThisOp (WalkState, *Op);
0696     if (ACPI_FAILURE (Status2))
0697     {
0698         return_ACPI_STATUS (Status2);
0699     }
0700 
0701     *Op = NULL;
0702 
0703     switch (Status)
0704     {
0705     case AE_OK:
0706         break;
0707 
0708 
0709     case AE_CTRL_TRANSFER:
0710 
0711         /* We are about to transfer to a called method */
0712 
0713         WalkState->PrevOp = NULL;
0714         WalkState->PrevArgTypes = WalkState->ArgTypes;
0715         return_ACPI_STATUS (Status);
0716 
0717 
0718     case AE_CTRL_END:
0719 
0720         AcpiPsPopScope (&(WalkState->ParserState), Op,
0721             &WalkState->ArgTypes, &WalkState->ArgCount);
0722 
0723         if (*Op)
0724         {
0725             WalkState->Op = *Op;
0726             WalkState->OpInfo = AcpiPsGetOpcodeInfo ((*Op)->Common.AmlOpcode);
0727             WalkState->Opcode = (*Op)->Common.AmlOpcode;
0728 
0729             Status = WalkState->AscendingCallback (WalkState);
0730             Status = AcpiPsNextParseState (WalkState, *Op, Status);
0731 
0732             Status2 = AcpiPsCompleteThisOp (WalkState, *Op);
0733             if (ACPI_FAILURE (Status2))
0734             {
0735                 return_ACPI_STATUS (Status2);
0736             }
0737         }
0738 
0739         Status = AE_OK;
0740         break;
0741 
0742 
0743     case AE_CTRL_BREAK:
0744     case AE_CTRL_CONTINUE:
0745 
0746         /* Pop off scopes until we find the While */
0747 
0748         while (!(*Op) || ((*Op)->Common.AmlOpcode != AML_WHILE_OP))
0749         {
0750             AcpiPsPopScope (&(WalkState->ParserState), Op,
0751                 &WalkState->ArgTypes, &WalkState->ArgCount);
0752         }
0753 
0754         /* Close this iteration of the While loop */
0755 
0756         WalkState->Op = *Op;
0757         WalkState->OpInfo = AcpiPsGetOpcodeInfo ((*Op)->Common.AmlOpcode);
0758         WalkState->Opcode = (*Op)->Common.AmlOpcode;
0759 
0760         Status = WalkState->AscendingCallback (WalkState);
0761         Status = AcpiPsNextParseState (WalkState, *Op, Status);
0762 
0763         Status2 = AcpiPsCompleteThisOp (WalkState, *Op);
0764         if (ACPI_FAILURE (Status2))
0765         {
0766             return_ACPI_STATUS (Status2);
0767         }
0768 
0769         Status = AE_OK;
0770         break;
0771 
0772 
0773     case AE_CTRL_TERMINATE:
0774 
0775         /* Clean up */
0776         do
0777         {
0778             if (*Op)
0779             {
0780                 Status2 = AcpiPsCompleteThisOp (WalkState, *Op);
0781                 if (ACPI_FAILURE (Status2))
0782                 {
0783                     return_ACPI_STATUS (Status2);
0784                 }
0785 
0786                 AcpiUtDeleteGenericState (
0787                     AcpiUtPopGenericState (&WalkState->ControlState));
0788             }
0789 
0790             AcpiPsPopScope (&(WalkState->ParserState), Op,
0791                 &WalkState->ArgTypes, &WalkState->ArgCount);
0792 
0793         } while (*Op);
0794 
0795         return_ACPI_STATUS (AE_OK);
0796 
0797 
0798     default:  /* All other non-AE_OK status */
0799 
0800         do
0801         {
0802             if (*Op)
0803             {
0804                 Status2 = AcpiPsCompleteThisOp (WalkState, *Op);
0805                 if (ACPI_FAILURE (Status2))
0806                 {
0807                     return_ACPI_STATUS (Status2);
0808                 }
0809             }
0810 
0811             AcpiPsPopScope (&(WalkState->ParserState), Op,
0812                 &WalkState->ArgTypes, &WalkState->ArgCount);
0813 
0814         } while (*Op);
0815 
0816 
0817 #if 0
0818         /*
0819          * TBD: Cleanup parse ops on error
0820          */
0821         if (*Op == NULL)
0822         {
0823             AcpiPsPopScope (ParserState, Op,
0824                 &WalkState->ArgTypes, &WalkState->ArgCount);
0825         }
0826 #endif
0827         WalkState->PrevOp = NULL;
0828         WalkState->PrevArgTypes = WalkState->ArgTypes;
0829         return_ACPI_STATUS (Status);
0830     }
0831 
0832     /* This scope complete? */
0833 
0834     if (AcpiPsHasCompletedScope (&(WalkState->ParserState)))
0835     {
0836         AcpiPsPopScope (&(WalkState->ParserState), Op,
0837             &WalkState->ArgTypes, &WalkState->ArgCount);
0838         ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", *Op));
0839     }
0840     else
0841     {
0842         *Op = NULL;
0843     }
0844 
0845     return_ACPI_STATUS (AE_OK);
0846 }
0847 
0848 
0849 /*******************************************************************************
0850  *
0851  * FUNCTION:    AcpiPsCompleteFinalOp
0852  *
0853  * PARAMETERS:  WalkState           - Current state
0854  *              Op                  - Current Op
0855  *              Status              - Current parse status before complete last
0856  *                                    Op
0857  *
0858  * RETURN:      Status
0859  *
0860  * DESCRIPTION: Complete last Op.
0861  *
0862  ******************************************************************************/
0863 
0864 static ACPI_STATUS
0865 AcpiPsCompleteFinalOp (
0866     ACPI_WALK_STATE         *WalkState,
0867     ACPI_PARSE_OBJECT       *Op,
0868     ACPI_STATUS             Status)
0869 {
0870     ACPI_STATUS             Status2;
0871 
0872 
0873     ACPI_FUNCTION_TRACE_PTR (PsCompleteFinalOp, WalkState);
0874 
0875 
0876     /*
0877      * Complete the last Op (if not completed), and clear the scope stack.
0878      * It is easily possible to end an AML "package" with an unbounded number
0879      * of open scopes (such as when several ASL blocks are closed with
0880      * sequential closing braces). We want to terminate each one cleanly.
0881      */
0882     ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "AML package complete at Op %p\n", Op));
0883     do
0884     {
0885         if (Op)
0886         {
0887             if (WalkState->AscendingCallback != NULL)
0888             {
0889                 WalkState->Op = Op;
0890                 WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
0891                 WalkState->Opcode = Op->Common.AmlOpcode;
0892 
0893                 Status = WalkState->AscendingCallback (WalkState);
0894                 Status = AcpiPsNextParseState (WalkState, Op, Status);
0895                 if (Status == AE_CTRL_PENDING)
0896                 {
0897                     Status = AcpiPsCompleteOp (WalkState, &Op, AE_OK);
0898                     if (ACPI_FAILURE (Status))
0899                     {
0900                         return_ACPI_STATUS (Status);
0901                     }
0902                 }
0903 
0904                 if (Status == AE_CTRL_TERMINATE)
0905                 {
0906                     Status = AE_OK;
0907 
0908                     /* Clean up */
0909                     do
0910                     {
0911                         if (Op)
0912                         {
0913                             Status2 = AcpiPsCompleteThisOp (WalkState, Op);
0914                             if (ACPI_FAILURE (Status2))
0915                             {
0916                                 return_ACPI_STATUS (Status2);
0917                             }
0918                         }
0919 
0920                         AcpiPsPopScope (&(WalkState->ParserState), &Op,
0921                             &WalkState->ArgTypes, &WalkState->ArgCount);
0922 
0923                     } while (Op);
0924 
0925                     return_ACPI_STATUS (Status);
0926                 }
0927 
0928                 else if (ACPI_FAILURE (Status))
0929                 {
0930                     /* First error is most important */
0931 
0932                     (void) AcpiPsCompleteThisOp (WalkState, Op);
0933                     return_ACPI_STATUS (Status);
0934                 }
0935             }
0936 
0937             Status2 = AcpiPsCompleteThisOp (WalkState, Op);
0938             if (ACPI_FAILURE (Status2))
0939             {
0940                 return_ACPI_STATUS (Status2);
0941             }
0942         }
0943 
0944         AcpiPsPopScope (&(WalkState->ParserState), &Op, &WalkState->ArgTypes,
0945             &WalkState->ArgCount);
0946 
0947     } while (Op);
0948 
0949     return_ACPI_STATUS (Status);
0950 }
0951 
0952 
0953 /*******************************************************************************
0954  *
0955  * FUNCTION:    AcpiPsParseLoop
0956  *
0957  * PARAMETERS:  WalkState           - Current state
0958  *
0959  * RETURN:      Status
0960  *
0961  * DESCRIPTION: Parse AML (pointed to by the current parser state) and return
0962  *              a tree of ops.
0963  *
0964  ******************************************************************************/
0965 
0966 ACPI_STATUS
0967 AcpiPsParseLoop (
0968     ACPI_WALK_STATE         *WalkState)
0969 {
0970     ACPI_STATUS             Status = AE_OK;
0971     ACPI_PARSE_OBJECT       *Op = NULL;     /* current op */
0972     ACPI_PARSE_STATE        *ParserState;
0973     UINT8                   *AmlOpStart = NULL;
0974 
0975 
0976     ACPI_FUNCTION_TRACE_PTR (PsParseLoop, WalkState);
0977 
0978 
0979     if (WalkState->DescendingCallback == NULL)
0980     {
0981         return_ACPI_STATUS (AE_BAD_PARAMETER);
0982     }
0983 
0984     ParserState = &WalkState->ParserState;
0985     WalkState->ArgTypes = 0;
0986 
0987 #if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY))
0988 
0989     if (WalkState->WalkType & ACPI_WALK_METHOD_RESTART)
0990     {
0991         /* We are restarting a preempted control method */
0992 
0993         if (AcpiPsHasCompletedScope (ParserState))
0994         {
0995             /*
0996              * We must check if a predicate to an IF or WHILE statement
0997              * was just completed
0998              */
0999             if ((ParserState->Scope->ParseScope.Op) &&
1000                ((ParserState->Scope->ParseScope.Op->Common.AmlOpcode == AML_IF_OP) ||
1001                 (ParserState->Scope->ParseScope.Op->Common.AmlOpcode == AML_WHILE_OP)) &&
1002                 (WalkState->ControlState) &&
1003                 (WalkState->ControlState->Common.State ==
1004                     ACPI_CONTROL_PREDICATE_EXECUTING))
1005             {
1006                 /*
1007                  * A predicate was just completed, get the value of the
1008                  * predicate and branch based on that value
1009                  */
1010                 WalkState->Op = NULL;
1011                 Status = AcpiDsGetPredicateValue (WalkState, ACPI_TO_POINTER (TRUE));
1012                 if (ACPI_FAILURE (Status) &&
1013                     ((Status & AE_CODE_MASK) != AE_CODE_CONTROL))
1014                 {
1015                     if (Status == AE_AML_NO_RETURN_VALUE)
1016                     {
1017                         ACPI_EXCEPTION ((AE_INFO, Status,
1018                             "Invoked method did not return a value"));
1019 
1020                     }
1021 
1022                     ACPI_EXCEPTION ((AE_INFO, Status, "GetPredicate Failed"));
1023                     return_ACPI_STATUS (Status);
1024                 }
1025 
1026                 Status = AcpiPsNextParseState (WalkState, Op, Status);
1027             }
1028 
1029             AcpiPsPopScope (ParserState, &Op,
1030                 &WalkState->ArgTypes, &WalkState->ArgCount);
1031             ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", Op));
1032         }
1033         else if (WalkState->PrevOp)
1034         {
1035             /* We were in the middle of an op */
1036 
1037             Op = WalkState->PrevOp;
1038             WalkState->ArgTypes = WalkState->PrevArgTypes;
1039         }
1040     }
1041 #endif
1042 
1043     /* Iterative parsing loop, while there is more AML to process: */
1044 
1045     while ((ParserState->Aml < ParserState->AmlEnd) || (Op))
1046     {
1047         AmlOpStart = ParserState->Aml;
1048         if (!Op)
1049         {
1050             Status = AcpiPsCreateOp (WalkState, AmlOpStart, &Op);
1051             if (ACPI_FAILURE (Status))
1052             {
1053                 if (Status == AE_CTRL_PARSE_CONTINUE)
1054                 {
1055                     continue;
1056                 }
1057 
1058                 if (Status == AE_CTRL_PARSE_PENDING)
1059                 {
1060                     Status = AE_OK;
1061                 }
1062 
1063                 Status = AcpiPsCompleteOp (WalkState, &Op, Status);
1064                 if (ACPI_FAILURE (Status))
1065                 {
1066                     return_ACPI_STATUS (Status);
1067                 }
1068 
1069                 continue;
1070             }
1071 
1072             Op->Common.AmlOffset = WalkState->AmlOffset;
1073 
1074             if (WalkState->OpInfo)
1075             {
1076                 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
1077                     "Opcode %4.4X [%s] Op %p Aml %p AmlOffset %5.5X\n",
1078                      (UINT32) Op->Common.AmlOpcode, WalkState->OpInfo->Name,
1079                      Op, ParserState->Aml, Op->Common.AmlOffset));
1080             }
1081         }
1082 
1083 
1084         /*
1085          * Start ArgCount at zero because we don't know if there are
1086          * any args yet
1087          */
1088         WalkState->ArgCount  = 0;
1089 
1090         /* Are there any arguments that must be processed? */
1091 
1092         if (WalkState->ArgTypes)
1093         {
1094             /* Get arguments */
1095 
1096             Status = AcpiPsGetArguments (WalkState, AmlOpStart, Op);
1097             if (ACPI_FAILURE (Status))
1098             {
1099                 Status = AcpiPsCompleteOp (WalkState, &Op, Status);
1100                 if (ACPI_FAILURE (Status))
1101                 {
1102                     return_ACPI_STATUS (Status);
1103                 }
1104 
1105                 continue;
1106             }
1107         }
1108 
1109         /* Check for arguments that need to be processed */
1110 
1111         if (WalkState->ArgCount)
1112         {
1113             /*
1114              * There are arguments (complex ones), push Op and
1115              * prepare for argument
1116              */
1117             Status = AcpiPsPushScope (ParserState, Op,
1118                         WalkState->ArgTypes, WalkState->ArgCount);
1119             if (ACPI_FAILURE (Status))
1120             {
1121                 Status = AcpiPsCompleteOp (WalkState, &Op, Status);
1122                 if (ACPI_FAILURE (Status))
1123                 {
1124                     return_ACPI_STATUS (Status);
1125                 }
1126 
1127                 continue;
1128             }
1129 
1130             Op = NULL;
1131             continue;
1132         }
1133 
1134         /*
1135          * All arguments have been processed -- Op is complete,
1136          * prepare for next
1137          */
1138         WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
1139         if (WalkState->OpInfo->Flags & AML_NAMED)
1140         {
1141             if (AcpiGbl_Depth)
1142             {
1143                 AcpiGbl_Depth--;
1144             }
1145 
1146             if (Op->Common.AmlOpcode == AML_REGION_OP ||
1147                 Op->Common.AmlOpcode == AML_DATA_REGION_OP)
1148             {
1149                 /*
1150                  * Skip parsing of control method or opregion body,
1151                  * because we don't have enough info in the first pass
1152                  * to parse them correctly.
1153                  *
1154                  * Completed parsing an OpRegion declaration, we now
1155                  * know the length.
1156                  */
1157                 Op->Named.Length = (UINT32) (ParserState->Aml - Op->Named.Data);
1158             }
1159         }
1160 
1161         if (WalkState->OpInfo->Flags & AML_CREATE)
1162         {
1163             /*
1164              * Backup to beginning of CreateXXXfield declaration (1 for
1165              * Opcode)
1166              *
1167              * BodyLength is unknown until we parse the body
1168              */
1169             Op->Named.Length = (UINT32) (ParserState->Aml - Op->Named.Data);
1170         }
1171 
1172         if (Op->Common.AmlOpcode == AML_BANK_FIELD_OP)
1173         {
1174             /*
1175              * Backup to beginning of BankField declaration
1176              *
1177              * BodyLength is unknown until we parse the body
1178              */
1179             Op->Named.Length = (UINT32) (ParserState->Aml - Op->Named.Data);
1180         }
1181 
1182         /* This op complete, notify the dispatcher */
1183 
1184         if (WalkState->AscendingCallback != NULL)
1185         {
1186             WalkState->Op = Op;
1187             WalkState->Opcode = Op->Common.AmlOpcode;
1188 
1189             Status = WalkState->AscendingCallback (WalkState);
1190             Status = AcpiPsNextParseState (WalkState, Op, Status);
1191             if (Status == AE_CTRL_PENDING)
1192             {
1193                 Status = AE_OK;
1194             }
1195         }
1196 
1197         Status = AcpiPsCompleteOp (WalkState, &Op, Status);
1198         if (ACPI_FAILURE (Status))
1199         {
1200             return_ACPI_STATUS (Status);
1201         }
1202 
1203     } /* while ParserState->Aml */
1204 
1205     Status = AcpiPsCompleteFinalOp (WalkState, Op, Status);
1206     return_ACPI_STATUS (Status);
1207 }
1208