1*7851SDana.Myers@Sun.COM /****************************************************************************** 2*7851SDana.Myers@Sun.COM * 3*7851SDana.Myers@Sun.COM * Module Name: psloop - Main AML parse loop 4*7851SDana.Myers@Sun.COM * $Revision: 1.19 $ 5*7851SDana.Myers@Sun.COM * 6*7851SDana.Myers@Sun.COM *****************************************************************************/ 7*7851SDana.Myers@Sun.COM 8*7851SDana.Myers@Sun.COM /****************************************************************************** 9*7851SDana.Myers@Sun.COM * 10*7851SDana.Myers@Sun.COM * 1. Copyright Notice 11*7851SDana.Myers@Sun.COM * 12*7851SDana.Myers@Sun.COM * Some or all of this work - Copyright (c) 1999 - 2008, Intel Corp. 13*7851SDana.Myers@Sun.COM * All rights reserved. 14*7851SDana.Myers@Sun.COM * 15*7851SDana.Myers@Sun.COM * 2. License 16*7851SDana.Myers@Sun.COM * 17*7851SDana.Myers@Sun.COM * 2.1. This is your license from Intel Corp. under its intellectual property 18*7851SDana.Myers@Sun.COM * rights. You may have additional license terms from the party that provided 19*7851SDana.Myers@Sun.COM * you this software, covering your right to use that party's intellectual 20*7851SDana.Myers@Sun.COM * property rights. 21*7851SDana.Myers@Sun.COM * 22*7851SDana.Myers@Sun.COM * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 23*7851SDana.Myers@Sun.COM * copy of the source code appearing in this file ("Covered Code") an 24*7851SDana.Myers@Sun.COM * irrevocable, perpetual, worldwide license under Intel's copyrights in the 25*7851SDana.Myers@Sun.COM * base code distributed originally by Intel ("Original Intel Code") to copy, 26*7851SDana.Myers@Sun.COM * make derivatives, distribute, use and display any portion of the Covered 27*7851SDana.Myers@Sun.COM * Code in any form, with the right to sublicense such rights; and 28*7851SDana.Myers@Sun.COM * 29*7851SDana.Myers@Sun.COM * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 30*7851SDana.Myers@Sun.COM * license (with the right to sublicense), under only those claims of Intel 31*7851SDana.Myers@Sun.COM * patents that are infringed by the Original Intel Code, to make, use, sell, 32*7851SDana.Myers@Sun.COM * offer to sell, and import the Covered Code and derivative works thereof 33*7851SDana.Myers@Sun.COM * solely to the minimum extent necessary to exercise the above copyright 34*7851SDana.Myers@Sun.COM * license, and in no event shall the patent license extend to any additions 35*7851SDana.Myers@Sun.COM * to or modifications of the Original Intel Code. No other license or right 36*7851SDana.Myers@Sun.COM * is granted directly or by implication, estoppel or otherwise; 37*7851SDana.Myers@Sun.COM * 38*7851SDana.Myers@Sun.COM * The above copyright and patent license is granted only if the following 39*7851SDana.Myers@Sun.COM * conditions are met: 40*7851SDana.Myers@Sun.COM * 41*7851SDana.Myers@Sun.COM * 3. Conditions 42*7851SDana.Myers@Sun.COM * 43*7851SDana.Myers@Sun.COM * 3.1. Redistribution of Source with Rights to Further Distribute Source. 44*7851SDana.Myers@Sun.COM * Redistribution of source code of any substantial portion of the Covered 45*7851SDana.Myers@Sun.COM * Code or modification with rights to further distribute source must include 46*7851SDana.Myers@Sun.COM * the above Copyright Notice, the above License, this list of Conditions, 47*7851SDana.Myers@Sun.COM * and the following Disclaimer and Export Compliance provision. In addition, 48*7851SDana.Myers@Sun.COM * Licensee must cause all Covered Code to which Licensee contributes to 49*7851SDana.Myers@Sun.COM * contain a file documenting the changes Licensee made to create that Covered 50*7851SDana.Myers@Sun.COM * Code and the date of any change. Licensee must include in that file the 51*7851SDana.Myers@Sun.COM * documentation of any changes made by any predecessor Licensee. Licensee 52*7851SDana.Myers@Sun.COM * must include a prominent statement that the modification is derived, 53*7851SDana.Myers@Sun.COM * directly or indirectly, from Original Intel Code. 54*7851SDana.Myers@Sun.COM * 55*7851SDana.Myers@Sun.COM * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 56*7851SDana.Myers@Sun.COM * Redistribution of source code of any substantial portion of the Covered 57*7851SDana.Myers@Sun.COM * Code or modification without rights to further distribute source must 58*7851SDana.Myers@Sun.COM * include the following Disclaimer and Export Compliance provision in the 59*7851SDana.Myers@Sun.COM * documentation and/or other materials provided with distribution. In 60*7851SDana.Myers@Sun.COM * addition, Licensee may not authorize further sublicense of source of any 61*7851SDana.Myers@Sun.COM * portion of the Covered Code, and must include terms to the effect that the 62*7851SDana.Myers@Sun.COM * license from Licensee to its licensee is limited to the intellectual 63*7851SDana.Myers@Sun.COM * property embodied in the software Licensee provides to its licensee, and 64*7851SDana.Myers@Sun.COM * not to intellectual property embodied in modifications its licensee may 65*7851SDana.Myers@Sun.COM * make. 66*7851SDana.Myers@Sun.COM * 67*7851SDana.Myers@Sun.COM * 3.3. Redistribution of Executable. Redistribution in executable form of any 68*7851SDana.Myers@Sun.COM * substantial portion of the Covered Code or modification must reproduce the 69*7851SDana.Myers@Sun.COM * above Copyright Notice, and the following Disclaimer and Export Compliance 70*7851SDana.Myers@Sun.COM * provision in the documentation and/or other materials provided with the 71*7851SDana.Myers@Sun.COM * distribution. 72*7851SDana.Myers@Sun.COM * 73*7851SDana.Myers@Sun.COM * 3.4. Intel retains all right, title, and interest in and to the Original 74*7851SDana.Myers@Sun.COM * Intel Code. 75*7851SDana.Myers@Sun.COM * 76*7851SDana.Myers@Sun.COM * 3.5. Neither the name Intel nor any other trademark owned or controlled by 77*7851SDana.Myers@Sun.COM * Intel shall be used in advertising or otherwise to promote the sale, use or 78*7851SDana.Myers@Sun.COM * other dealings in products derived from or relating to the Covered Code 79*7851SDana.Myers@Sun.COM * without prior written authorization from Intel. 80*7851SDana.Myers@Sun.COM * 81*7851SDana.Myers@Sun.COM * 4. Disclaimer and Export Compliance 82*7851SDana.Myers@Sun.COM * 83*7851SDana.Myers@Sun.COM * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 84*7851SDana.Myers@Sun.COM * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 85*7851SDana.Myers@Sun.COM * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 86*7851SDana.Myers@Sun.COM * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 87*7851SDana.Myers@Sun.COM * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 88*7851SDana.Myers@Sun.COM * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 89*7851SDana.Myers@Sun.COM * PARTICULAR PURPOSE. 90*7851SDana.Myers@Sun.COM * 91*7851SDana.Myers@Sun.COM * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 92*7851SDana.Myers@Sun.COM * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 93*7851SDana.Myers@Sun.COM * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 94*7851SDana.Myers@Sun.COM * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 95*7851SDana.Myers@Sun.COM * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 96*7851SDana.Myers@Sun.COM * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 97*7851SDana.Myers@Sun.COM * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 98*7851SDana.Myers@Sun.COM * LIMITED REMEDY. 99*7851SDana.Myers@Sun.COM * 100*7851SDana.Myers@Sun.COM * 4.3. Licensee shall not export, either directly or indirectly, any of this 101*7851SDana.Myers@Sun.COM * software or system incorporating such software without first obtaining any 102*7851SDana.Myers@Sun.COM * required license or other approval from the U. S. Department of Commerce or 103*7851SDana.Myers@Sun.COM * any other agency or department of the United States Government. In the 104*7851SDana.Myers@Sun.COM * event Licensee exports any such software from the United States or 105*7851SDana.Myers@Sun.COM * re-exports any such software from a foreign destination, Licensee shall 106*7851SDana.Myers@Sun.COM * ensure that the distribution and export/re-export of the software is in 107*7851SDana.Myers@Sun.COM * compliance with all laws, regulations, orders, or other restrictions of the 108*7851SDana.Myers@Sun.COM * U.S. Export Administration Regulations. Licensee agrees that neither it nor 109*7851SDana.Myers@Sun.COM * any of its subsidiaries will export/re-export any technical data, process, 110*7851SDana.Myers@Sun.COM * software, or service, directly or indirectly, to any country for which the 111*7851SDana.Myers@Sun.COM * United States government or any agency thereof requires an export license, 112*7851SDana.Myers@Sun.COM * other governmental approval, or letter of assurance, without first obtaining 113*7851SDana.Myers@Sun.COM * such license, approval or letter. 114*7851SDana.Myers@Sun.COM * 115*7851SDana.Myers@Sun.COM *****************************************************************************/ 116*7851SDana.Myers@Sun.COM 117*7851SDana.Myers@Sun.COM 118*7851SDana.Myers@Sun.COM /* 119*7851SDana.Myers@Sun.COM * Parse the AML and build an operation tree as most interpreters, (such as 120*7851SDana.Myers@Sun.COM * Perl) do. Parsing is done by hand rather than with a YACC generated parser 121*7851SDana.Myers@Sun.COM * to tightly constrain stack and dynamic memory usage. Parsing is kept 122*7851SDana.Myers@Sun.COM * flexible and the code fairly compact by parsing based on a list of AML 123*7851SDana.Myers@Sun.COM * opcode templates in AmlOpInfo[]. 124*7851SDana.Myers@Sun.COM */ 125*7851SDana.Myers@Sun.COM 126*7851SDana.Myers@Sun.COM #include "acpi.h" 127*7851SDana.Myers@Sun.COM #include "acparser.h" 128*7851SDana.Myers@Sun.COM #include "acdispat.h" 129*7851SDana.Myers@Sun.COM #include "amlcode.h" 130*7851SDana.Myers@Sun.COM 131*7851SDana.Myers@Sun.COM #define _COMPONENT ACPI_PARSER 132*7851SDana.Myers@Sun.COM ACPI_MODULE_NAME ("psloop") 133*7851SDana.Myers@Sun.COM 134*7851SDana.Myers@Sun.COM static UINT32 AcpiGbl_Depth = 0; 135*7851SDana.Myers@Sun.COM 136*7851SDana.Myers@Sun.COM 137*7851SDana.Myers@Sun.COM /* Local prototypes */ 138*7851SDana.Myers@Sun.COM 139*7851SDana.Myers@Sun.COM static ACPI_STATUS 140*7851SDana.Myers@Sun.COM AcpiPsGetAmlOpcode ( 141*7851SDana.Myers@Sun.COM ACPI_WALK_STATE *WalkState); 142*7851SDana.Myers@Sun.COM 143*7851SDana.Myers@Sun.COM static ACPI_STATUS 144*7851SDana.Myers@Sun.COM AcpiPsBuildNamedOp ( 145*7851SDana.Myers@Sun.COM ACPI_WALK_STATE *WalkState, 146*7851SDana.Myers@Sun.COM UINT8 *AmlOpStart, 147*7851SDana.Myers@Sun.COM ACPI_PARSE_OBJECT *UnnamedOp, 148*7851SDana.Myers@Sun.COM ACPI_PARSE_OBJECT **Op); 149*7851SDana.Myers@Sun.COM 150*7851SDana.Myers@Sun.COM static ACPI_STATUS 151*7851SDana.Myers@Sun.COM AcpiPsCreateOp ( 152*7851SDana.Myers@Sun.COM ACPI_WALK_STATE *WalkState, 153*7851SDana.Myers@Sun.COM UINT8 *AmlOpStart, 154*7851SDana.Myers@Sun.COM ACPI_PARSE_OBJECT **NewOp); 155*7851SDana.Myers@Sun.COM 156*7851SDana.Myers@Sun.COM static ACPI_STATUS 157*7851SDana.Myers@Sun.COM AcpiPsGetArguments ( 158*7851SDana.Myers@Sun.COM ACPI_WALK_STATE *WalkState, 159*7851SDana.Myers@Sun.COM UINT8 *AmlOpStart, 160*7851SDana.Myers@Sun.COM ACPI_PARSE_OBJECT *Op); 161*7851SDana.Myers@Sun.COM 162*7851SDana.Myers@Sun.COM static ACPI_STATUS 163*7851SDana.Myers@Sun.COM AcpiPsCompleteOp ( 164*7851SDana.Myers@Sun.COM ACPI_WALK_STATE *WalkState, 165*7851SDana.Myers@Sun.COM ACPI_PARSE_OBJECT **Op, 166*7851SDana.Myers@Sun.COM ACPI_STATUS Status); 167*7851SDana.Myers@Sun.COM 168*7851SDana.Myers@Sun.COM static ACPI_STATUS 169*7851SDana.Myers@Sun.COM AcpiPsCompleteFinalOp ( 170*7851SDana.Myers@Sun.COM ACPI_WALK_STATE *WalkState, 171*7851SDana.Myers@Sun.COM ACPI_PARSE_OBJECT *Op, 172*7851SDana.Myers@Sun.COM ACPI_STATUS Status); 173*7851SDana.Myers@Sun.COM 174*7851SDana.Myers@Sun.COM 175*7851SDana.Myers@Sun.COM /******************************************************************************* 176*7851SDana.Myers@Sun.COM * 177*7851SDana.Myers@Sun.COM * FUNCTION: AcpiPsGetAmlOpcode 178*7851SDana.Myers@Sun.COM * 179*7851SDana.Myers@Sun.COM * PARAMETERS: WalkState - Current state 180*7851SDana.Myers@Sun.COM * 181*7851SDana.Myers@Sun.COM * RETURN: Status 182*7851SDana.Myers@Sun.COM * 183*7851SDana.Myers@Sun.COM * DESCRIPTION: Extract the next AML opcode from the input stream. 184*7851SDana.Myers@Sun.COM * 185*7851SDana.Myers@Sun.COM ******************************************************************************/ 186*7851SDana.Myers@Sun.COM 187*7851SDana.Myers@Sun.COM static ACPI_STATUS 188*7851SDana.Myers@Sun.COM AcpiPsGetAmlOpcode ( 189*7851SDana.Myers@Sun.COM ACPI_WALK_STATE *WalkState) 190*7851SDana.Myers@Sun.COM { 191*7851SDana.Myers@Sun.COM 192*7851SDana.Myers@Sun.COM ACPI_FUNCTION_TRACE_PTR (PsGetAmlOpcode, WalkState); 193*7851SDana.Myers@Sun.COM 194*7851SDana.Myers@Sun.COM 195*7851SDana.Myers@Sun.COM WalkState->AmlOffset = (UINT32) ACPI_PTR_DIFF (WalkState->ParserState.Aml, 196*7851SDana.Myers@Sun.COM WalkState->ParserState.AmlStart); 197*7851SDana.Myers@Sun.COM WalkState->Opcode = AcpiPsPeekOpcode (&(WalkState->ParserState)); 198*7851SDana.Myers@Sun.COM 199*7851SDana.Myers@Sun.COM /* 200*7851SDana.Myers@Sun.COM * First cut to determine what we have found: 201*7851SDana.Myers@Sun.COM * 1) A valid AML opcode 202*7851SDana.Myers@Sun.COM * 2) A name string 203*7851SDana.Myers@Sun.COM * 3) An unknown/invalid opcode 204*7851SDana.Myers@Sun.COM */ 205*7851SDana.Myers@Sun.COM WalkState->OpInfo = AcpiPsGetOpcodeInfo (WalkState->Opcode); 206*7851SDana.Myers@Sun.COM 207*7851SDana.Myers@Sun.COM switch (WalkState->OpInfo->Class) 208*7851SDana.Myers@Sun.COM { 209*7851SDana.Myers@Sun.COM case AML_CLASS_ASCII: 210*7851SDana.Myers@Sun.COM case AML_CLASS_PREFIX: 211*7851SDana.Myers@Sun.COM /* 212*7851SDana.Myers@Sun.COM * Starts with a valid prefix or ASCII char, this is a name 213*7851SDana.Myers@Sun.COM * string. Convert the bare name string to a namepath. 214*7851SDana.Myers@Sun.COM */ 215*7851SDana.Myers@Sun.COM WalkState->Opcode = AML_INT_NAMEPATH_OP; 216*7851SDana.Myers@Sun.COM WalkState->ArgTypes = ARGP_NAMESTRING; 217*7851SDana.Myers@Sun.COM break; 218*7851SDana.Myers@Sun.COM 219*7851SDana.Myers@Sun.COM case AML_CLASS_UNKNOWN: 220*7851SDana.Myers@Sun.COM 221*7851SDana.Myers@Sun.COM /* The opcode is unrecognized. Just skip unknown opcodes */ 222*7851SDana.Myers@Sun.COM 223*7851SDana.Myers@Sun.COM ACPI_ERROR ((AE_INFO, 224*7851SDana.Myers@Sun.COM "Found unknown opcode %X at AML address %p offset %X, ignoring", 225*7851SDana.Myers@Sun.COM WalkState->Opcode, WalkState->ParserState.Aml, WalkState->AmlOffset)); 226*7851SDana.Myers@Sun.COM 227*7851SDana.Myers@Sun.COM ACPI_DUMP_BUFFER (WalkState->ParserState.Aml, 128); 228*7851SDana.Myers@Sun.COM 229*7851SDana.Myers@Sun.COM /* Assume one-byte bad opcode */ 230*7851SDana.Myers@Sun.COM 231*7851SDana.Myers@Sun.COM WalkState->ParserState.Aml++; 232*7851SDana.Myers@Sun.COM return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE); 233*7851SDana.Myers@Sun.COM 234*7851SDana.Myers@Sun.COM default: 235*7851SDana.Myers@Sun.COM 236*7851SDana.Myers@Sun.COM /* Found opcode info, this is a normal opcode */ 237*7851SDana.Myers@Sun.COM 238*7851SDana.Myers@Sun.COM WalkState->ParserState.Aml += AcpiPsGetOpcodeSize (WalkState->Opcode); 239*7851SDana.Myers@Sun.COM WalkState->ArgTypes = WalkState->OpInfo->ParseArgs; 240*7851SDana.Myers@Sun.COM break; 241*7851SDana.Myers@Sun.COM } 242*7851SDana.Myers@Sun.COM 243*7851SDana.Myers@Sun.COM return_ACPI_STATUS (AE_OK); 244*7851SDana.Myers@Sun.COM } 245*7851SDana.Myers@Sun.COM 246*7851SDana.Myers@Sun.COM 247*7851SDana.Myers@Sun.COM /******************************************************************************* 248*7851SDana.Myers@Sun.COM * 249*7851SDana.Myers@Sun.COM * FUNCTION: AcpiPsBuildNamedOp 250*7851SDana.Myers@Sun.COM * 251*7851SDana.Myers@Sun.COM * PARAMETERS: WalkState - Current state 252*7851SDana.Myers@Sun.COM * AmlOpStart - Begin of named Op in AML 253*7851SDana.Myers@Sun.COM * UnnamedOp - Early Op (not a named Op) 254*7851SDana.Myers@Sun.COM * Op - Returned Op 255*7851SDana.Myers@Sun.COM * 256*7851SDana.Myers@Sun.COM * RETURN: Status 257*7851SDana.Myers@Sun.COM * 258*7851SDana.Myers@Sun.COM * DESCRIPTION: Parse a named Op 259*7851SDana.Myers@Sun.COM * 260*7851SDana.Myers@Sun.COM ******************************************************************************/ 261*7851SDana.Myers@Sun.COM 262*7851SDana.Myers@Sun.COM static ACPI_STATUS 263*7851SDana.Myers@Sun.COM AcpiPsBuildNamedOp ( 264*7851SDana.Myers@Sun.COM ACPI_WALK_STATE *WalkState, 265*7851SDana.Myers@Sun.COM UINT8 *AmlOpStart, 266*7851SDana.Myers@Sun.COM ACPI_PARSE_OBJECT *UnnamedOp, 267*7851SDana.Myers@Sun.COM ACPI_PARSE_OBJECT **Op) 268*7851SDana.Myers@Sun.COM { 269*7851SDana.Myers@Sun.COM ACPI_STATUS Status = AE_OK; 270*7851SDana.Myers@Sun.COM ACPI_PARSE_OBJECT *Arg = NULL; 271*7851SDana.Myers@Sun.COM 272*7851SDana.Myers@Sun.COM 273*7851SDana.Myers@Sun.COM ACPI_FUNCTION_TRACE_PTR (PsBuildNamedOp, WalkState); 274*7851SDana.Myers@Sun.COM 275*7851SDana.Myers@Sun.COM 276*7851SDana.Myers@Sun.COM UnnamedOp->Common.Value.Arg = NULL; 277*7851SDana.Myers@Sun.COM UnnamedOp->Common.ArgListLength = 0; 278*7851SDana.Myers@Sun.COM UnnamedOp->Common.AmlOpcode = WalkState->Opcode; 279*7851SDana.Myers@Sun.COM 280*7851SDana.Myers@Sun.COM /* 281*7851SDana.Myers@Sun.COM * Get and append arguments until we find the node that contains 282*7851SDana.Myers@Sun.COM * the name (the type ARGP_NAME). 283*7851SDana.Myers@Sun.COM */ 284*7851SDana.Myers@Sun.COM while (GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) && 285*7851SDana.Myers@Sun.COM (GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) != ARGP_NAME)) 286*7851SDana.Myers@Sun.COM { 287*7851SDana.Myers@Sun.COM Status = AcpiPsGetNextArg (WalkState, &(WalkState->ParserState), 288*7851SDana.Myers@Sun.COM GET_CURRENT_ARG_TYPE (WalkState->ArgTypes), &Arg); 289*7851SDana.Myers@Sun.COM if (ACPI_FAILURE (Status)) 290*7851SDana.Myers@Sun.COM { 291*7851SDana.Myers@Sun.COM return_ACPI_STATUS (Status); 292*7851SDana.Myers@Sun.COM } 293*7851SDana.Myers@Sun.COM 294*7851SDana.Myers@Sun.COM AcpiPsAppendArg (UnnamedOp, Arg); 295*7851SDana.Myers@Sun.COM INCREMENT_ARG_LIST (WalkState->ArgTypes); 296*7851SDana.Myers@Sun.COM } 297*7851SDana.Myers@Sun.COM 298*7851SDana.Myers@Sun.COM /* 299*7851SDana.Myers@Sun.COM * Make sure that we found a NAME and didn't run out of arguments 300*7851SDana.Myers@Sun.COM */ 301*7851SDana.Myers@Sun.COM if (!GET_CURRENT_ARG_TYPE (WalkState->ArgTypes)) 302*7851SDana.Myers@Sun.COM { 303*7851SDana.Myers@Sun.COM return_ACPI_STATUS (AE_AML_NO_OPERAND); 304*7851SDana.Myers@Sun.COM } 305*7851SDana.Myers@Sun.COM 306*7851SDana.Myers@Sun.COM /* We know that this arg is a name, move to next arg */ 307*7851SDana.Myers@Sun.COM 308*7851SDana.Myers@Sun.COM INCREMENT_ARG_LIST (WalkState->ArgTypes); 309*7851SDana.Myers@Sun.COM 310*7851SDana.Myers@Sun.COM /* 311*7851SDana.Myers@Sun.COM * Find the object. This will either insert the object into 312*7851SDana.Myers@Sun.COM * the namespace or simply look it up 313*7851SDana.Myers@Sun.COM */ 314*7851SDana.Myers@Sun.COM WalkState->Op = NULL; 315*7851SDana.Myers@Sun.COM 316*7851SDana.Myers@Sun.COM Status = WalkState->DescendingCallback (WalkState, Op); 317*7851SDana.Myers@Sun.COM if (ACPI_FAILURE (Status)) 318*7851SDana.Myers@Sun.COM { 319*7851SDana.Myers@Sun.COM ACPI_EXCEPTION ((AE_INFO, Status, "During name lookup/catalog")); 320*7851SDana.Myers@Sun.COM return_ACPI_STATUS (Status); 321*7851SDana.Myers@Sun.COM } 322*7851SDana.Myers@Sun.COM 323*7851SDana.Myers@Sun.COM if (!*Op) 324*7851SDana.Myers@Sun.COM { 325*7851SDana.Myers@Sun.COM return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE); 326*7851SDana.Myers@Sun.COM } 327*7851SDana.Myers@Sun.COM 328*7851SDana.Myers@Sun.COM Status = AcpiPsNextParseState (WalkState, *Op, Status); 329*7851SDana.Myers@Sun.COM if (ACPI_FAILURE (Status)) 330*7851SDana.Myers@Sun.COM { 331*7851SDana.Myers@Sun.COM if (Status == AE_CTRL_PENDING) 332*7851SDana.Myers@Sun.COM { 333*7851SDana.Myers@Sun.COM return_ACPI_STATUS (AE_CTRL_PARSE_PENDING); 334*7851SDana.Myers@Sun.COM } 335*7851SDana.Myers@Sun.COM return_ACPI_STATUS (Status); 336*7851SDana.Myers@Sun.COM } 337*7851SDana.Myers@Sun.COM 338*7851SDana.Myers@Sun.COM AcpiPsAppendArg (*Op, UnnamedOp->Common.Value.Arg); 339*7851SDana.Myers@Sun.COM AcpiGbl_Depth++; 340*7851SDana.Myers@Sun.COM 341*7851SDana.Myers@Sun.COM if ((*Op)->Common.AmlOpcode == AML_REGION_OP || 342*7851SDana.Myers@Sun.COM (*Op)->Common.AmlOpcode == AML_DATA_REGION_OP) 343*7851SDana.Myers@Sun.COM { 344*7851SDana.Myers@Sun.COM /* 345*7851SDana.Myers@Sun.COM * Defer final parsing of an OperationRegion body, because we don't 346*7851SDana.Myers@Sun.COM * have enough info in the first pass to parse it correctly (i.e., 347*7851SDana.Myers@Sun.COM * there may be method calls within the TermArg elements of the body.) 348*7851SDana.Myers@Sun.COM * 349*7851SDana.Myers@Sun.COM * However, we must continue parsing because the opregion is not a 350*7851SDana.Myers@Sun.COM * standalone package -- we don't know where the end is at this point. 351*7851SDana.Myers@Sun.COM * 352*7851SDana.Myers@Sun.COM * (Length is unknown until parse of the body complete) 353*7851SDana.Myers@Sun.COM */ 354*7851SDana.Myers@Sun.COM (*Op)->Named.Data = AmlOpStart; 355*7851SDana.Myers@Sun.COM (*Op)->Named.Length = 0; 356*7851SDana.Myers@Sun.COM } 357*7851SDana.Myers@Sun.COM 358*7851SDana.Myers@Sun.COM return_ACPI_STATUS (AE_OK); 359*7851SDana.Myers@Sun.COM } 360*7851SDana.Myers@Sun.COM 361*7851SDana.Myers@Sun.COM 362*7851SDana.Myers@Sun.COM /******************************************************************************* 363*7851SDana.Myers@Sun.COM * 364*7851SDana.Myers@Sun.COM * FUNCTION: AcpiPsCreateOp 365*7851SDana.Myers@Sun.COM * 366*7851SDana.Myers@Sun.COM * PARAMETERS: WalkState - Current state 367*7851SDana.Myers@Sun.COM * AmlOpStart - Op start in AML 368*7851SDana.Myers@Sun.COM * NewOp - Returned Op 369*7851SDana.Myers@Sun.COM * 370*7851SDana.Myers@Sun.COM * RETURN: Status 371*7851SDana.Myers@Sun.COM * 372*7851SDana.Myers@Sun.COM * DESCRIPTION: Get Op from AML 373*7851SDana.Myers@Sun.COM * 374*7851SDana.Myers@Sun.COM ******************************************************************************/ 375*7851SDana.Myers@Sun.COM 376*7851SDana.Myers@Sun.COM static ACPI_STATUS 377*7851SDana.Myers@Sun.COM AcpiPsCreateOp ( 378*7851SDana.Myers@Sun.COM ACPI_WALK_STATE *WalkState, 379*7851SDana.Myers@Sun.COM UINT8 *AmlOpStart, 380*7851SDana.Myers@Sun.COM ACPI_PARSE_OBJECT **NewOp) 381*7851SDana.Myers@Sun.COM { 382*7851SDana.Myers@Sun.COM ACPI_STATUS Status = AE_OK; 383*7851SDana.Myers@Sun.COM ACPI_PARSE_OBJECT *Op; 384*7851SDana.Myers@Sun.COM ACPI_PARSE_OBJECT *NamedOp = NULL; 385*7851SDana.Myers@Sun.COM ACPI_PARSE_OBJECT *ParentScope; 386*7851SDana.Myers@Sun.COM UINT8 ArgumentCount; 387*7851SDana.Myers@Sun.COM const ACPI_OPCODE_INFO *OpInfo; 388*7851SDana.Myers@Sun.COM 389*7851SDana.Myers@Sun.COM 390*7851SDana.Myers@Sun.COM ACPI_FUNCTION_TRACE_PTR (PsCreateOp, WalkState); 391*7851SDana.Myers@Sun.COM 392*7851SDana.Myers@Sun.COM 393*7851SDana.Myers@Sun.COM Status = AcpiPsGetAmlOpcode (WalkState); 394*7851SDana.Myers@Sun.COM if (Status == AE_CTRL_PARSE_CONTINUE) 395*7851SDana.Myers@Sun.COM { 396*7851SDana.Myers@Sun.COM return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE); 397*7851SDana.Myers@Sun.COM } 398*7851SDana.Myers@Sun.COM 399*7851SDana.Myers@Sun.COM /* Create Op structure and append to parent's argument list */ 400*7851SDana.Myers@Sun.COM 401*7851SDana.Myers@Sun.COM WalkState->OpInfo = AcpiPsGetOpcodeInfo (WalkState->Opcode); 402*7851SDana.Myers@Sun.COM Op = AcpiPsAllocOp (WalkState->Opcode); 403*7851SDana.Myers@Sun.COM if (!Op) 404*7851SDana.Myers@Sun.COM { 405*7851SDana.Myers@Sun.COM return_ACPI_STATUS (AE_NO_MEMORY); 406*7851SDana.Myers@Sun.COM } 407*7851SDana.Myers@Sun.COM 408*7851SDana.Myers@Sun.COM if (WalkState->OpInfo->Flags & AML_NAMED) 409*7851SDana.Myers@Sun.COM { 410*7851SDana.Myers@Sun.COM Status = AcpiPsBuildNamedOp (WalkState, AmlOpStart, Op, &NamedOp); 411*7851SDana.Myers@Sun.COM AcpiPsFreeOp (Op); 412*7851SDana.Myers@Sun.COM if (ACPI_FAILURE (Status)) 413*7851SDana.Myers@Sun.COM { 414*7851SDana.Myers@Sun.COM return_ACPI_STATUS (Status); 415*7851SDana.Myers@Sun.COM } 416*7851SDana.Myers@Sun.COM 417*7851SDana.Myers@Sun.COM *NewOp = NamedOp; 418*7851SDana.Myers@Sun.COM return_ACPI_STATUS (AE_OK); 419*7851SDana.Myers@Sun.COM } 420*7851SDana.Myers@Sun.COM 421*7851SDana.Myers@Sun.COM /* Not a named opcode, just allocate Op and append to parent */ 422*7851SDana.Myers@Sun.COM 423*7851SDana.Myers@Sun.COM if (WalkState->OpInfo->Flags & AML_CREATE) 424*7851SDana.Myers@Sun.COM { 425*7851SDana.Myers@Sun.COM /* 426*7851SDana.Myers@Sun.COM * Backup to beginning of CreateXXXfield declaration 427*7851SDana.Myers@Sun.COM * BodyLength is unknown until we parse the body 428*7851SDana.Myers@Sun.COM */ 429*7851SDana.Myers@Sun.COM Op->Named.Data = AmlOpStart; 430*7851SDana.Myers@Sun.COM Op->Named.Length = 0; 431*7851SDana.Myers@Sun.COM } 432*7851SDana.Myers@Sun.COM 433*7851SDana.Myers@Sun.COM if (WalkState->Opcode == AML_BANK_FIELD_OP) 434*7851SDana.Myers@Sun.COM { 435*7851SDana.Myers@Sun.COM /* 436*7851SDana.Myers@Sun.COM * Backup to beginning of BankField declaration 437*7851SDana.Myers@Sun.COM * BodyLength is unknown until we parse the body 438*7851SDana.Myers@Sun.COM */ 439*7851SDana.Myers@Sun.COM Op->Named.Data = AmlOpStart; 440*7851SDana.Myers@Sun.COM Op->Named.Length = 0; 441*7851SDana.Myers@Sun.COM } 442*7851SDana.Myers@Sun.COM 443*7851SDana.Myers@Sun.COM ParentScope = AcpiPsGetParentScope (&(WalkState->ParserState)); 444*7851SDana.Myers@Sun.COM AcpiPsAppendArg (ParentScope, Op); 445*7851SDana.Myers@Sun.COM 446*7851SDana.Myers@Sun.COM if (ParentScope) 447*7851SDana.Myers@Sun.COM { 448*7851SDana.Myers@Sun.COM OpInfo = AcpiPsGetOpcodeInfo (ParentScope->Common.AmlOpcode); 449*7851SDana.Myers@Sun.COM if (OpInfo->Flags & AML_HAS_TARGET) 450*7851SDana.Myers@Sun.COM { 451*7851SDana.Myers@Sun.COM ArgumentCount = AcpiPsGetArgumentCount (OpInfo->Type); 452*7851SDana.Myers@Sun.COM if (ParentScope->Common.ArgListLength > ArgumentCount) 453*7851SDana.Myers@Sun.COM { 454*7851SDana.Myers@Sun.COM Op->Common.Flags |= ACPI_PARSEOP_TARGET; 455*7851SDana.Myers@Sun.COM } 456*7851SDana.Myers@Sun.COM } 457*7851SDana.Myers@Sun.COM else if (ParentScope->Common.AmlOpcode == AML_INCREMENT_OP) 458*7851SDana.Myers@Sun.COM { 459*7851SDana.Myers@Sun.COM Op->Common.Flags |= ACPI_PARSEOP_TARGET; 460*7851SDana.Myers@Sun.COM } 461*7851SDana.Myers@Sun.COM } 462*7851SDana.Myers@Sun.COM 463*7851SDana.Myers@Sun.COM if (WalkState->DescendingCallback != NULL) 464*7851SDana.Myers@Sun.COM { 465*7851SDana.Myers@Sun.COM /* 466*7851SDana.Myers@Sun.COM * Find the object. This will either insert the object into 467*7851SDana.Myers@Sun.COM * the namespace or simply look it up 468*7851SDana.Myers@Sun.COM */ 469*7851SDana.Myers@Sun.COM WalkState->Op = *NewOp = Op; 470*7851SDana.Myers@Sun.COM 471*7851SDana.Myers@Sun.COM Status = WalkState->DescendingCallback (WalkState, &Op); 472*7851SDana.Myers@Sun.COM Status = AcpiPsNextParseState (WalkState, Op, Status); 473*7851SDana.Myers@Sun.COM if (Status == AE_CTRL_PENDING) 474*7851SDana.Myers@Sun.COM { 475*7851SDana.Myers@Sun.COM Status = AE_CTRL_PARSE_PENDING; 476*7851SDana.Myers@Sun.COM } 477*7851SDana.Myers@Sun.COM } 478*7851SDana.Myers@Sun.COM 479*7851SDana.Myers@Sun.COM return_ACPI_STATUS (Status); 480*7851SDana.Myers@Sun.COM } 481*7851SDana.Myers@Sun.COM 482*7851SDana.Myers@Sun.COM 483*7851SDana.Myers@Sun.COM /******************************************************************************* 484*7851SDana.Myers@Sun.COM * 485*7851SDana.Myers@Sun.COM * FUNCTION: AcpiPsGetArguments 486*7851SDana.Myers@Sun.COM * 487*7851SDana.Myers@Sun.COM * PARAMETERS: WalkState - Current state 488*7851SDana.Myers@Sun.COM * AmlOpStart - Op start in AML 489*7851SDana.Myers@Sun.COM * Op - Current Op 490*7851SDana.Myers@Sun.COM * 491*7851SDana.Myers@Sun.COM * RETURN: Status 492*7851SDana.Myers@Sun.COM * 493*7851SDana.Myers@Sun.COM * DESCRIPTION: Get arguments for passed Op. 494*7851SDana.Myers@Sun.COM * 495*7851SDana.Myers@Sun.COM ******************************************************************************/ 496*7851SDana.Myers@Sun.COM 497*7851SDana.Myers@Sun.COM static ACPI_STATUS 498*7851SDana.Myers@Sun.COM AcpiPsGetArguments ( 499*7851SDana.Myers@Sun.COM ACPI_WALK_STATE *WalkState, 500*7851SDana.Myers@Sun.COM UINT8 *AmlOpStart, 501*7851SDana.Myers@Sun.COM ACPI_PARSE_OBJECT *Op) 502*7851SDana.Myers@Sun.COM { 503*7851SDana.Myers@Sun.COM ACPI_STATUS Status = AE_OK; 504*7851SDana.Myers@Sun.COM ACPI_PARSE_OBJECT *Arg = NULL; 505*7851SDana.Myers@Sun.COM 506*7851SDana.Myers@Sun.COM 507*7851SDana.Myers@Sun.COM ACPI_FUNCTION_TRACE_PTR (PsGetArguments, WalkState); 508*7851SDana.Myers@Sun.COM 509*7851SDana.Myers@Sun.COM 510*7851SDana.Myers@Sun.COM switch (Op->Common.AmlOpcode) 511*7851SDana.Myers@Sun.COM { 512*7851SDana.Myers@Sun.COM case AML_BYTE_OP: /* AML_BYTEDATA_ARG */ 513*7851SDana.Myers@Sun.COM case AML_WORD_OP: /* AML_WORDDATA_ARG */ 514*7851SDana.Myers@Sun.COM case AML_DWORD_OP: /* AML_DWORDATA_ARG */ 515*7851SDana.Myers@Sun.COM case AML_QWORD_OP: /* AML_QWORDATA_ARG */ 516*7851SDana.Myers@Sun.COM case AML_STRING_OP: /* AML_ASCIICHARLIST_ARG */ 517*7851SDana.Myers@Sun.COM 518*7851SDana.Myers@Sun.COM /* Fill in constant or string argument directly */ 519*7851SDana.Myers@Sun.COM 520*7851SDana.Myers@Sun.COM AcpiPsGetNextSimpleArg (&(WalkState->ParserState), 521*7851SDana.Myers@Sun.COM GET_CURRENT_ARG_TYPE (WalkState->ArgTypes), Op); 522*7851SDana.Myers@Sun.COM break; 523*7851SDana.Myers@Sun.COM 524*7851SDana.Myers@Sun.COM case AML_INT_NAMEPATH_OP: /* AML_NAMESTRING_ARG */ 525*7851SDana.Myers@Sun.COM 526*7851SDana.Myers@Sun.COM Status = AcpiPsGetNextNamepath (WalkState, &(WalkState->ParserState), Op, 1); 527*7851SDana.Myers@Sun.COM if (ACPI_FAILURE (Status)) 528*7851SDana.Myers@Sun.COM { 529*7851SDana.Myers@Sun.COM return_ACPI_STATUS (Status); 530*7851SDana.Myers@Sun.COM } 531*7851SDana.Myers@Sun.COM 532*7851SDana.Myers@Sun.COM WalkState->ArgTypes = 0; 533*7851SDana.Myers@Sun.COM break; 534*7851SDana.Myers@Sun.COM 535*7851SDana.Myers@Sun.COM default: 536*7851SDana.Myers@Sun.COM /* 537*7851SDana.Myers@Sun.COM * Op is not a constant or string, append each argument to the Op 538*7851SDana.Myers@Sun.COM */ 539*7851SDana.Myers@Sun.COM while (GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) && !WalkState->ArgCount) 540*7851SDana.Myers@Sun.COM { 541*7851SDana.Myers@Sun.COM WalkState->AmlOffset = (UINT32) ACPI_PTR_DIFF (WalkState->ParserState.Aml, 542*7851SDana.Myers@Sun.COM WalkState->ParserState.AmlStart); 543*7851SDana.Myers@Sun.COM 544*7851SDana.Myers@Sun.COM Status = AcpiPsGetNextArg (WalkState, &(WalkState->ParserState), 545*7851SDana.Myers@Sun.COM GET_CURRENT_ARG_TYPE (WalkState->ArgTypes), &Arg); 546*7851SDana.Myers@Sun.COM if (ACPI_FAILURE (Status)) 547*7851SDana.Myers@Sun.COM { 548*7851SDana.Myers@Sun.COM return_ACPI_STATUS (Status); 549*7851SDana.Myers@Sun.COM } 550*7851SDana.Myers@Sun.COM 551*7851SDana.Myers@Sun.COM if (Arg) 552*7851SDana.Myers@Sun.COM { 553*7851SDana.Myers@Sun.COM Arg->Common.AmlOffset = WalkState->AmlOffset; 554*7851SDana.Myers@Sun.COM AcpiPsAppendArg (Op, Arg); 555*7851SDana.Myers@Sun.COM } 556*7851SDana.Myers@Sun.COM 557*7851SDana.Myers@Sun.COM INCREMENT_ARG_LIST (WalkState->ArgTypes); 558*7851SDana.Myers@Sun.COM } 559*7851SDana.Myers@Sun.COM 560*7851SDana.Myers@Sun.COM 561*7851SDana.Myers@Sun.COM /* Special processing for certain opcodes */ 562*7851SDana.Myers@Sun.COM 563*7851SDana.Myers@Sun.COM /* TBD (remove): Temporary mechanism to disable this code if needed */ 564*7851SDana.Myers@Sun.COM 565*7851SDana.Myers@Sun.COM #ifdef ACPI_ENABLE_MODULE_LEVEL_CODE 566*7851SDana.Myers@Sun.COM 567*7851SDana.Myers@Sun.COM if ((WalkState->PassNumber <= ACPI_IMODE_LOAD_PASS1) && 568*7851SDana.Myers@Sun.COM ((WalkState->ParseFlags & ACPI_PARSE_DISASSEMBLE) == 0)) 569*7851SDana.Myers@Sun.COM { 570*7851SDana.Myers@Sun.COM /* 571*7851SDana.Myers@Sun.COM * We want to skip If/Else/While constructs during Pass1 because we 572*7851SDana.Myers@Sun.COM * want to actually conditionally execute the code during Pass2. 573*7851SDana.Myers@Sun.COM * 574*7851SDana.Myers@Sun.COM * Except for disassembly, where we always want to walk the 575*7851SDana.Myers@Sun.COM * If/Else/While packages 576*7851SDana.Myers@Sun.COM */ 577*7851SDana.Myers@Sun.COM switch (Op->Common.AmlOpcode) 578*7851SDana.Myers@Sun.COM { 579*7851SDana.Myers@Sun.COM case AML_IF_OP: 580*7851SDana.Myers@Sun.COM case AML_ELSE_OP: 581*7851SDana.Myers@Sun.COM case AML_WHILE_OP: 582*7851SDana.Myers@Sun.COM 583*7851SDana.Myers@Sun.COM ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, 584*7851SDana.Myers@Sun.COM "Pass1: Skipping an If/Else/While body\n")); 585*7851SDana.Myers@Sun.COM 586*7851SDana.Myers@Sun.COM /* Skip body of if/else/while in pass 1 */ 587*7851SDana.Myers@Sun.COM 588*7851SDana.Myers@Sun.COM WalkState->ParserState.Aml = WalkState->ParserState.PkgEnd; 589*7851SDana.Myers@Sun.COM WalkState->ArgCount = 0; 590*7851SDana.Myers@Sun.COM break; 591*7851SDana.Myers@Sun.COM 592*7851SDana.Myers@Sun.COM default: 593*7851SDana.Myers@Sun.COM break; 594*7851SDana.Myers@Sun.COM } 595*7851SDana.Myers@Sun.COM } 596*7851SDana.Myers@Sun.COM #endif 597*7851SDana.Myers@Sun.COM 598*7851SDana.Myers@Sun.COM switch (Op->Common.AmlOpcode) 599*7851SDana.Myers@Sun.COM { 600*7851SDana.Myers@Sun.COM case AML_METHOD_OP: 601*7851SDana.Myers@Sun.COM /* 602*7851SDana.Myers@Sun.COM * Skip parsing of control method because we don't have enough 603*7851SDana.Myers@Sun.COM * info in the first pass to parse it correctly. 604*7851SDana.Myers@Sun.COM * 605*7851SDana.Myers@Sun.COM * Save the length and address of the body 606*7851SDana.Myers@Sun.COM */ 607*7851SDana.Myers@Sun.COM Op->Named.Data = WalkState->ParserState.Aml; 608*7851SDana.Myers@Sun.COM Op->Named.Length = (UINT32) 609*7851SDana.Myers@Sun.COM (WalkState->ParserState.PkgEnd - WalkState->ParserState.Aml); 610*7851SDana.Myers@Sun.COM 611*7851SDana.Myers@Sun.COM /* Skip body of method */ 612*7851SDana.Myers@Sun.COM 613*7851SDana.Myers@Sun.COM WalkState->ParserState.Aml = WalkState->ParserState.PkgEnd; 614*7851SDana.Myers@Sun.COM WalkState->ArgCount = 0; 615*7851SDana.Myers@Sun.COM break; 616*7851SDana.Myers@Sun.COM 617*7851SDana.Myers@Sun.COM case AML_BUFFER_OP: 618*7851SDana.Myers@Sun.COM case AML_PACKAGE_OP: 619*7851SDana.Myers@Sun.COM case AML_VAR_PACKAGE_OP: 620*7851SDana.Myers@Sun.COM 621*7851SDana.Myers@Sun.COM if ((Op->Common.Parent) && 622*7851SDana.Myers@Sun.COM (Op->Common.Parent->Common.AmlOpcode == AML_NAME_OP) && 623*7851SDana.Myers@Sun.COM (WalkState->PassNumber <= ACPI_IMODE_LOAD_PASS2)) 624*7851SDana.Myers@Sun.COM { 625*7851SDana.Myers@Sun.COM /* 626*7851SDana.Myers@Sun.COM * Skip parsing of Buffers and Packages because we don't have 627*7851SDana.Myers@Sun.COM * enough info in the first pass to parse them correctly. 628*7851SDana.Myers@Sun.COM */ 629*7851SDana.Myers@Sun.COM Op->Named.Data = AmlOpStart; 630*7851SDana.Myers@Sun.COM Op->Named.Length = (UINT32) 631*7851SDana.Myers@Sun.COM (WalkState->ParserState.PkgEnd - AmlOpStart); 632*7851SDana.Myers@Sun.COM 633*7851SDana.Myers@Sun.COM /* Skip body */ 634*7851SDana.Myers@Sun.COM 635*7851SDana.Myers@Sun.COM WalkState->ParserState.Aml = WalkState->ParserState.PkgEnd; 636*7851SDana.Myers@Sun.COM WalkState->ArgCount = 0; 637*7851SDana.Myers@Sun.COM } 638*7851SDana.Myers@Sun.COM break; 639*7851SDana.Myers@Sun.COM 640*7851SDana.Myers@Sun.COM case AML_WHILE_OP: 641*7851SDana.Myers@Sun.COM 642*7851SDana.Myers@Sun.COM if (WalkState->ControlState) 643*7851SDana.Myers@Sun.COM { 644*7851SDana.Myers@Sun.COM WalkState->ControlState->Control.PackageEnd = 645*7851SDana.Myers@Sun.COM WalkState->ParserState.PkgEnd; 646*7851SDana.Myers@Sun.COM } 647*7851SDana.Myers@Sun.COM break; 648*7851SDana.Myers@Sun.COM 649*7851SDana.Myers@Sun.COM default: 650*7851SDana.Myers@Sun.COM 651*7851SDana.Myers@Sun.COM /* No action for all other opcodes */ 652*7851SDana.Myers@Sun.COM break; 653*7851SDana.Myers@Sun.COM } 654*7851SDana.Myers@Sun.COM 655*7851SDana.Myers@Sun.COM break; 656*7851SDana.Myers@Sun.COM } 657*7851SDana.Myers@Sun.COM 658*7851SDana.Myers@Sun.COM return_ACPI_STATUS (AE_OK); 659*7851SDana.Myers@Sun.COM } 660*7851SDana.Myers@Sun.COM 661*7851SDana.Myers@Sun.COM 662*7851SDana.Myers@Sun.COM /******************************************************************************* 663*7851SDana.Myers@Sun.COM * 664*7851SDana.Myers@Sun.COM * FUNCTION: AcpiPsCompleteOp 665*7851SDana.Myers@Sun.COM * 666*7851SDana.Myers@Sun.COM * PARAMETERS: WalkState - Current state 667*7851SDana.Myers@Sun.COM * Op - Returned Op 668*7851SDana.Myers@Sun.COM * Status - Parse status before complete Op 669*7851SDana.Myers@Sun.COM * 670*7851SDana.Myers@Sun.COM * RETURN: Status 671*7851SDana.Myers@Sun.COM * 672*7851SDana.Myers@Sun.COM * DESCRIPTION: Complete Op 673*7851SDana.Myers@Sun.COM * 674*7851SDana.Myers@Sun.COM ******************************************************************************/ 675*7851SDana.Myers@Sun.COM 676*7851SDana.Myers@Sun.COM static ACPI_STATUS 677*7851SDana.Myers@Sun.COM AcpiPsCompleteOp ( 678*7851SDana.Myers@Sun.COM ACPI_WALK_STATE *WalkState, 679*7851SDana.Myers@Sun.COM ACPI_PARSE_OBJECT **Op, 680*7851SDana.Myers@Sun.COM ACPI_STATUS Status) 681*7851SDana.Myers@Sun.COM { 682*7851SDana.Myers@Sun.COM ACPI_STATUS Status2; 683*7851SDana.Myers@Sun.COM 684*7851SDana.Myers@Sun.COM 685*7851SDana.Myers@Sun.COM ACPI_FUNCTION_TRACE_PTR (PsCompleteOp, WalkState); 686*7851SDana.Myers@Sun.COM 687*7851SDana.Myers@Sun.COM 688*7851SDana.Myers@Sun.COM /* 689*7851SDana.Myers@Sun.COM * Finished one argument of the containing scope 690*7851SDana.Myers@Sun.COM */ 691*7851SDana.Myers@Sun.COM WalkState->ParserState.Scope->ParseScope.ArgCount--; 692*7851SDana.Myers@Sun.COM 693*7851SDana.Myers@Sun.COM /* Close this Op (will result in parse subtree deletion) */ 694*7851SDana.Myers@Sun.COM 695*7851SDana.Myers@Sun.COM Status2 = AcpiPsCompleteThisOp (WalkState, *Op); 696*7851SDana.Myers@Sun.COM if (ACPI_FAILURE (Status2)) 697*7851SDana.Myers@Sun.COM { 698*7851SDana.Myers@Sun.COM return_ACPI_STATUS (Status2); 699*7851SDana.Myers@Sun.COM } 700*7851SDana.Myers@Sun.COM 701*7851SDana.Myers@Sun.COM *Op = NULL; 702*7851SDana.Myers@Sun.COM 703*7851SDana.Myers@Sun.COM switch (Status) 704*7851SDana.Myers@Sun.COM { 705*7851SDana.Myers@Sun.COM case AE_OK: 706*7851SDana.Myers@Sun.COM break; 707*7851SDana.Myers@Sun.COM 708*7851SDana.Myers@Sun.COM 709*7851SDana.Myers@Sun.COM case AE_CTRL_TRANSFER: 710*7851SDana.Myers@Sun.COM 711*7851SDana.Myers@Sun.COM /* We are about to transfer to a called method */ 712*7851SDana.Myers@Sun.COM 713*7851SDana.Myers@Sun.COM WalkState->PrevOp = NULL; 714*7851SDana.Myers@Sun.COM WalkState->PrevArgTypes = WalkState->ArgTypes; 715*7851SDana.Myers@Sun.COM return_ACPI_STATUS (Status); 716*7851SDana.Myers@Sun.COM 717*7851SDana.Myers@Sun.COM 718*7851SDana.Myers@Sun.COM case AE_CTRL_END: 719*7851SDana.Myers@Sun.COM 720*7851SDana.Myers@Sun.COM AcpiPsPopScope (&(WalkState->ParserState), Op, 721*7851SDana.Myers@Sun.COM &WalkState->ArgTypes, &WalkState->ArgCount); 722*7851SDana.Myers@Sun.COM 723*7851SDana.Myers@Sun.COM if (*Op) 724*7851SDana.Myers@Sun.COM { 725*7851SDana.Myers@Sun.COM WalkState->Op = *Op; 726*7851SDana.Myers@Sun.COM WalkState->OpInfo = AcpiPsGetOpcodeInfo ((*Op)->Common.AmlOpcode); 727*7851SDana.Myers@Sun.COM WalkState->Opcode = (*Op)->Common.AmlOpcode; 728*7851SDana.Myers@Sun.COM 729*7851SDana.Myers@Sun.COM Status = WalkState->AscendingCallback (WalkState); 730*7851SDana.Myers@Sun.COM Status = AcpiPsNextParseState (WalkState, *Op, Status); 731*7851SDana.Myers@Sun.COM 732*7851SDana.Myers@Sun.COM Status2 = AcpiPsCompleteThisOp (WalkState, *Op); 733*7851SDana.Myers@Sun.COM if (ACPI_FAILURE (Status2)) 734*7851SDana.Myers@Sun.COM { 735*7851SDana.Myers@Sun.COM return_ACPI_STATUS (Status2); 736*7851SDana.Myers@Sun.COM } 737*7851SDana.Myers@Sun.COM } 738*7851SDana.Myers@Sun.COM 739*7851SDana.Myers@Sun.COM Status = AE_OK; 740*7851SDana.Myers@Sun.COM break; 741*7851SDana.Myers@Sun.COM 742*7851SDana.Myers@Sun.COM 743*7851SDana.Myers@Sun.COM case AE_CTRL_BREAK: 744*7851SDana.Myers@Sun.COM case AE_CTRL_CONTINUE: 745*7851SDana.Myers@Sun.COM 746*7851SDana.Myers@Sun.COM /* Pop off scopes until we find the While */ 747*7851SDana.Myers@Sun.COM 748*7851SDana.Myers@Sun.COM while (!(*Op) || ((*Op)->Common.AmlOpcode != AML_WHILE_OP)) 749*7851SDana.Myers@Sun.COM { 750*7851SDana.Myers@Sun.COM AcpiPsPopScope (&(WalkState->ParserState), Op, 751*7851SDana.Myers@Sun.COM &WalkState->ArgTypes, &WalkState->ArgCount); 752*7851SDana.Myers@Sun.COM } 753*7851SDana.Myers@Sun.COM 754*7851SDana.Myers@Sun.COM /* Close this iteration of the While loop */ 755*7851SDana.Myers@Sun.COM 756*7851SDana.Myers@Sun.COM WalkState->Op = *Op; 757*7851SDana.Myers@Sun.COM WalkState->OpInfo = AcpiPsGetOpcodeInfo ((*Op)->Common.AmlOpcode); 758*7851SDana.Myers@Sun.COM WalkState->Opcode = (*Op)->Common.AmlOpcode; 759*7851SDana.Myers@Sun.COM 760*7851SDana.Myers@Sun.COM Status = WalkState->AscendingCallback (WalkState); 761*7851SDana.Myers@Sun.COM Status = AcpiPsNextParseState (WalkState, *Op, Status); 762*7851SDana.Myers@Sun.COM 763*7851SDana.Myers@Sun.COM Status2 = AcpiPsCompleteThisOp (WalkState, *Op); 764*7851SDana.Myers@Sun.COM if (ACPI_FAILURE (Status2)) 765*7851SDana.Myers@Sun.COM { 766*7851SDana.Myers@Sun.COM return_ACPI_STATUS (Status2); 767*7851SDana.Myers@Sun.COM } 768*7851SDana.Myers@Sun.COM 769*7851SDana.Myers@Sun.COM Status = AE_OK; 770*7851SDana.Myers@Sun.COM break; 771*7851SDana.Myers@Sun.COM 772*7851SDana.Myers@Sun.COM 773*7851SDana.Myers@Sun.COM case AE_CTRL_TERMINATE: 774*7851SDana.Myers@Sun.COM 775*7851SDana.Myers@Sun.COM /* Clean up */ 776*7851SDana.Myers@Sun.COM do 777*7851SDana.Myers@Sun.COM { 778*7851SDana.Myers@Sun.COM if (*Op) 779*7851SDana.Myers@Sun.COM { 780*7851SDana.Myers@Sun.COM Status2 = AcpiPsCompleteThisOp (WalkState, *Op); 781*7851SDana.Myers@Sun.COM if (ACPI_FAILURE (Status2)) 782*7851SDana.Myers@Sun.COM { 783*7851SDana.Myers@Sun.COM return_ACPI_STATUS (Status2); 784*7851SDana.Myers@Sun.COM } 785*7851SDana.Myers@Sun.COM 786*7851SDana.Myers@Sun.COM AcpiUtDeleteGenericState ( 787*7851SDana.Myers@Sun.COM AcpiUtPopGenericState (&WalkState->ControlState)); 788*7851SDana.Myers@Sun.COM } 789*7851SDana.Myers@Sun.COM 790*7851SDana.Myers@Sun.COM AcpiPsPopScope (&(WalkState->ParserState), Op, 791*7851SDana.Myers@Sun.COM &WalkState->ArgTypes, &WalkState->ArgCount); 792*7851SDana.Myers@Sun.COM 793*7851SDana.Myers@Sun.COM } while (*Op); 794*7851SDana.Myers@Sun.COM 795*7851SDana.Myers@Sun.COM return_ACPI_STATUS (AE_OK); 796*7851SDana.Myers@Sun.COM 797*7851SDana.Myers@Sun.COM 798*7851SDana.Myers@Sun.COM default: /* All other non-AE_OK status */ 799*7851SDana.Myers@Sun.COM 800*7851SDana.Myers@Sun.COM do 801*7851SDana.Myers@Sun.COM { 802*7851SDana.Myers@Sun.COM if (*Op) 803*7851SDana.Myers@Sun.COM { 804*7851SDana.Myers@Sun.COM Status2 = AcpiPsCompleteThisOp (WalkState, *Op); 805*7851SDana.Myers@Sun.COM if (ACPI_FAILURE (Status2)) 806*7851SDana.Myers@Sun.COM { 807*7851SDana.Myers@Sun.COM return_ACPI_STATUS (Status2); 808*7851SDana.Myers@Sun.COM } 809*7851SDana.Myers@Sun.COM } 810*7851SDana.Myers@Sun.COM 811*7851SDana.Myers@Sun.COM AcpiPsPopScope (&(WalkState->ParserState), Op, 812*7851SDana.Myers@Sun.COM &WalkState->ArgTypes, &WalkState->ArgCount); 813*7851SDana.Myers@Sun.COM 814*7851SDana.Myers@Sun.COM } while (*Op); 815*7851SDana.Myers@Sun.COM 816*7851SDana.Myers@Sun.COM 817*7851SDana.Myers@Sun.COM #if 0 818*7851SDana.Myers@Sun.COM /* 819*7851SDana.Myers@Sun.COM * TBD: Cleanup parse ops on error 820*7851SDana.Myers@Sun.COM */ 821*7851SDana.Myers@Sun.COM if (*Op == NULL) 822*7851SDana.Myers@Sun.COM { 823*7851SDana.Myers@Sun.COM AcpiPsPopScope (ParserState, Op, 824*7851SDana.Myers@Sun.COM &WalkState->ArgTypes, &WalkState->ArgCount); 825*7851SDana.Myers@Sun.COM } 826*7851SDana.Myers@Sun.COM #endif 827*7851SDana.Myers@Sun.COM WalkState->PrevOp = NULL; 828*7851SDana.Myers@Sun.COM WalkState->PrevArgTypes = WalkState->ArgTypes; 829*7851SDana.Myers@Sun.COM return_ACPI_STATUS (Status); 830*7851SDana.Myers@Sun.COM } 831*7851SDana.Myers@Sun.COM 832*7851SDana.Myers@Sun.COM /* This scope complete? */ 833*7851SDana.Myers@Sun.COM 834*7851SDana.Myers@Sun.COM if (AcpiPsHasCompletedScope (&(WalkState->ParserState))) 835*7851SDana.Myers@Sun.COM { 836*7851SDana.Myers@Sun.COM AcpiPsPopScope (&(WalkState->ParserState), Op, 837*7851SDana.Myers@Sun.COM &WalkState->ArgTypes, &WalkState->ArgCount); 838*7851SDana.Myers@Sun.COM ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", *Op)); 839*7851SDana.Myers@Sun.COM } 840*7851SDana.Myers@Sun.COM else 841*7851SDana.Myers@Sun.COM { 842*7851SDana.Myers@Sun.COM *Op = NULL; 843*7851SDana.Myers@Sun.COM } 844*7851SDana.Myers@Sun.COM 845*7851SDana.Myers@Sun.COM return_ACPI_STATUS (AE_OK); 846*7851SDana.Myers@Sun.COM } 847*7851SDana.Myers@Sun.COM 848*7851SDana.Myers@Sun.COM 849*7851SDana.Myers@Sun.COM /******************************************************************************* 850*7851SDana.Myers@Sun.COM * 851*7851SDana.Myers@Sun.COM * FUNCTION: AcpiPsCompleteFinalOp 852*7851SDana.Myers@Sun.COM * 853*7851SDana.Myers@Sun.COM * PARAMETERS: WalkState - Current state 854*7851SDana.Myers@Sun.COM * Op - Current Op 855*7851SDana.Myers@Sun.COM * Status - Current parse status before complete last 856*7851SDana.Myers@Sun.COM * Op 857*7851SDana.Myers@Sun.COM * 858*7851SDana.Myers@Sun.COM * RETURN: Status 859*7851SDana.Myers@Sun.COM * 860*7851SDana.Myers@Sun.COM * DESCRIPTION: Complete last Op. 861*7851SDana.Myers@Sun.COM * 862*7851SDana.Myers@Sun.COM ******************************************************************************/ 863*7851SDana.Myers@Sun.COM 864*7851SDana.Myers@Sun.COM static ACPI_STATUS 865*7851SDana.Myers@Sun.COM AcpiPsCompleteFinalOp ( 866*7851SDana.Myers@Sun.COM ACPI_WALK_STATE *WalkState, 867*7851SDana.Myers@Sun.COM ACPI_PARSE_OBJECT *Op, 868*7851SDana.Myers@Sun.COM ACPI_STATUS Status) 869*7851SDana.Myers@Sun.COM { 870*7851SDana.Myers@Sun.COM ACPI_STATUS Status2; 871*7851SDana.Myers@Sun.COM 872*7851SDana.Myers@Sun.COM 873*7851SDana.Myers@Sun.COM ACPI_FUNCTION_TRACE_PTR (PsCompleteFinalOp, WalkState); 874*7851SDana.Myers@Sun.COM 875*7851SDana.Myers@Sun.COM 876*7851SDana.Myers@Sun.COM /* 877*7851SDana.Myers@Sun.COM * Complete the last Op (if not completed), and clear the scope stack. 878*7851SDana.Myers@Sun.COM * It is easily possible to end an AML "package" with an unbounded number 879*7851SDana.Myers@Sun.COM * of open scopes (such as when several ASL blocks are closed with 880*7851SDana.Myers@Sun.COM * sequential closing braces). We want to terminate each one cleanly. 881*7851SDana.Myers@Sun.COM */ 882*7851SDana.Myers@Sun.COM ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "AML package complete at Op %p\n", Op)); 883*7851SDana.Myers@Sun.COM do 884*7851SDana.Myers@Sun.COM { 885*7851SDana.Myers@Sun.COM if (Op) 886*7851SDana.Myers@Sun.COM { 887*7851SDana.Myers@Sun.COM if (WalkState->AscendingCallback != NULL) 888*7851SDana.Myers@Sun.COM { 889*7851SDana.Myers@Sun.COM WalkState->Op = Op; 890*7851SDana.Myers@Sun.COM WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 891*7851SDana.Myers@Sun.COM WalkState->Opcode = Op->Common.AmlOpcode; 892*7851SDana.Myers@Sun.COM 893*7851SDana.Myers@Sun.COM Status = WalkState->AscendingCallback (WalkState); 894*7851SDana.Myers@Sun.COM Status = AcpiPsNextParseState (WalkState, Op, Status); 895*7851SDana.Myers@Sun.COM if (Status == AE_CTRL_PENDING) 896*7851SDana.Myers@Sun.COM { 897*7851SDana.Myers@Sun.COM Status = AcpiPsCompleteOp (WalkState, &Op, AE_OK); 898*7851SDana.Myers@Sun.COM if (ACPI_FAILURE (Status)) 899*7851SDana.Myers@Sun.COM { 900*7851SDana.Myers@Sun.COM return_ACPI_STATUS (Status); 901*7851SDana.Myers@Sun.COM } 902*7851SDana.Myers@Sun.COM } 903*7851SDana.Myers@Sun.COM 904*7851SDana.Myers@Sun.COM if (Status == AE_CTRL_TERMINATE) 905*7851SDana.Myers@Sun.COM { 906*7851SDana.Myers@Sun.COM Status = AE_OK; 907*7851SDana.Myers@Sun.COM 908*7851SDana.Myers@Sun.COM /* Clean up */ 909*7851SDana.Myers@Sun.COM do 910*7851SDana.Myers@Sun.COM { 911*7851SDana.Myers@Sun.COM if (Op) 912*7851SDana.Myers@Sun.COM { 913*7851SDana.Myers@Sun.COM Status2 = AcpiPsCompleteThisOp (WalkState, Op); 914*7851SDana.Myers@Sun.COM if (ACPI_FAILURE (Status2)) 915*7851SDana.Myers@Sun.COM { 916*7851SDana.Myers@Sun.COM return_ACPI_STATUS (Status2); 917*7851SDana.Myers@Sun.COM } 918*7851SDana.Myers@Sun.COM } 919*7851SDana.Myers@Sun.COM 920*7851SDana.Myers@Sun.COM AcpiPsPopScope (&(WalkState->ParserState), &Op, 921*7851SDana.Myers@Sun.COM &WalkState->ArgTypes, &WalkState->ArgCount); 922*7851SDana.Myers@Sun.COM 923*7851SDana.Myers@Sun.COM } while (Op); 924*7851SDana.Myers@Sun.COM 925*7851SDana.Myers@Sun.COM return_ACPI_STATUS (Status); 926*7851SDana.Myers@Sun.COM } 927*7851SDana.Myers@Sun.COM 928*7851SDana.Myers@Sun.COM else if (ACPI_FAILURE (Status)) 929*7851SDana.Myers@Sun.COM { 930*7851SDana.Myers@Sun.COM /* First error is most important */ 931*7851SDana.Myers@Sun.COM 932*7851SDana.Myers@Sun.COM (void) AcpiPsCompleteThisOp (WalkState, Op); 933*7851SDana.Myers@Sun.COM return_ACPI_STATUS (Status); 934*7851SDana.Myers@Sun.COM } 935*7851SDana.Myers@Sun.COM } 936*7851SDana.Myers@Sun.COM 937*7851SDana.Myers@Sun.COM Status2 = AcpiPsCompleteThisOp (WalkState, Op); 938*7851SDana.Myers@Sun.COM if (ACPI_FAILURE (Status2)) 939*7851SDana.Myers@Sun.COM { 940*7851SDana.Myers@Sun.COM return_ACPI_STATUS (Status2); 941*7851SDana.Myers@Sun.COM } 942*7851SDana.Myers@Sun.COM } 943*7851SDana.Myers@Sun.COM 944*7851SDana.Myers@Sun.COM AcpiPsPopScope (&(WalkState->ParserState), &Op, &WalkState->ArgTypes, 945*7851SDana.Myers@Sun.COM &WalkState->ArgCount); 946*7851SDana.Myers@Sun.COM 947*7851SDana.Myers@Sun.COM } while (Op); 948*7851SDana.Myers@Sun.COM 949*7851SDana.Myers@Sun.COM return_ACPI_STATUS (Status); 950*7851SDana.Myers@Sun.COM } 951*7851SDana.Myers@Sun.COM 952*7851SDana.Myers@Sun.COM 953*7851SDana.Myers@Sun.COM /******************************************************************************* 954*7851SDana.Myers@Sun.COM * 955*7851SDana.Myers@Sun.COM * FUNCTION: AcpiPsParseLoop 956*7851SDana.Myers@Sun.COM * 957*7851SDana.Myers@Sun.COM * PARAMETERS: WalkState - Current state 958*7851SDana.Myers@Sun.COM * 959*7851SDana.Myers@Sun.COM * RETURN: Status 960*7851SDana.Myers@Sun.COM * 961*7851SDana.Myers@Sun.COM * DESCRIPTION: Parse AML (pointed to by the current parser state) and return 962*7851SDana.Myers@Sun.COM * a tree of ops. 963*7851SDana.Myers@Sun.COM * 964*7851SDana.Myers@Sun.COM ******************************************************************************/ 965*7851SDana.Myers@Sun.COM 966*7851SDana.Myers@Sun.COM ACPI_STATUS 967*7851SDana.Myers@Sun.COM AcpiPsParseLoop ( 968*7851SDana.Myers@Sun.COM ACPI_WALK_STATE *WalkState) 969*7851SDana.Myers@Sun.COM { 970*7851SDana.Myers@Sun.COM ACPI_STATUS Status = AE_OK; 971*7851SDana.Myers@Sun.COM ACPI_PARSE_OBJECT *Op = NULL; /* current op */ 972*7851SDana.Myers@Sun.COM ACPI_PARSE_STATE *ParserState; 973*7851SDana.Myers@Sun.COM UINT8 *AmlOpStart = NULL; 974*7851SDana.Myers@Sun.COM 975*7851SDana.Myers@Sun.COM 976*7851SDana.Myers@Sun.COM ACPI_FUNCTION_TRACE_PTR (PsParseLoop, WalkState); 977*7851SDana.Myers@Sun.COM 978*7851SDana.Myers@Sun.COM 979*7851SDana.Myers@Sun.COM if (WalkState->DescendingCallback == NULL) 980*7851SDana.Myers@Sun.COM { 981*7851SDana.Myers@Sun.COM return_ACPI_STATUS (AE_BAD_PARAMETER); 982*7851SDana.Myers@Sun.COM } 983*7851SDana.Myers@Sun.COM 984*7851SDana.Myers@Sun.COM ParserState = &WalkState->ParserState; 985*7851SDana.Myers@Sun.COM WalkState->ArgTypes = 0; 986*7851SDana.Myers@Sun.COM 987*7851SDana.Myers@Sun.COM #if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY)) 988*7851SDana.Myers@Sun.COM 989*7851SDana.Myers@Sun.COM if (WalkState->WalkType & ACPI_WALK_METHOD_RESTART) 990*7851SDana.Myers@Sun.COM { 991*7851SDana.Myers@Sun.COM /* We are restarting a preempted control method */ 992*7851SDana.Myers@Sun.COM 993*7851SDana.Myers@Sun.COM if (AcpiPsHasCompletedScope (ParserState)) 994*7851SDana.Myers@Sun.COM { 995*7851SDana.Myers@Sun.COM /* 996*7851SDana.Myers@Sun.COM * We must check if a predicate to an IF or WHILE statement 997*7851SDana.Myers@Sun.COM * was just completed 998*7851SDana.Myers@Sun.COM */ 999*7851SDana.Myers@Sun.COM if ((ParserState->Scope->ParseScope.Op) && 1000*7851SDana.Myers@Sun.COM ((ParserState->Scope->ParseScope.Op->Common.AmlOpcode == AML_IF_OP) || 1001*7851SDana.Myers@Sun.COM (ParserState->Scope->ParseScope.Op->Common.AmlOpcode == AML_WHILE_OP)) && 1002*7851SDana.Myers@Sun.COM (WalkState->ControlState) && 1003*7851SDana.Myers@Sun.COM (WalkState->ControlState->Common.State == 1004*7851SDana.Myers@Sun.COM ACPI_CONTROL_PREDICATE_EXECUTING)) 1005*7851SDana.Myers@Sun.COM { 1006*7851SDana.Myers@Sun.COM /* 1007*7851SDana.Myers@Sun.COM * A predicate was just completed, get the value of the 1008*7851SDana.Myers@Sun.COM * predicate and branch based on that value 1009*7851SDana.Myers@Sun.COM */ 1010*7851SDana.Myers@Sun.COM WalkState->Op = NULL; 1011*7851SDana.Myers@Sun.COM Status = AcpiDsGetPredicateValue (WalkState, ACPI_TO_POINTER (TRUE)); 1012*7851SDana.Myers@Sun.COM if (ACPI_FAILURE (Status) && 1013*7851SDana.Myers@Sun.COM ((Status & AE_CODE_MASK) != AE_CODE_CONTROL)) 1014*7851SDana.Myers@Sun.COM { 1015*7851SDana.Myers@Sun.COM if (Status == AE_AML_NO_RETURN_VALUE) 1016*7851SDana.Myers@Sun.COM { 1017*7851SDana.Myers@Sun.COM ACPI_EXCEPTION ((AE_INFO, Status, 1018*7851SDana.Myers@Sun.COM "Invoked method did not return a value")); 1019*7851SDana.Myers@Sun.COM 1020*7851SDana.Myers@Sun.COM } 1021*7851SDana.Myers@Sun.COM 1022*7851SDana.Myers@Sun.COM ACPI_EXCEPTION ((AE_INFO, Status, "GetPredicate Failed")); 1023*7851SDana.Myers@Sun.COM return_ACPI_STATUS (Status); 1024*7851SDana.Myers@Sun.COM } 1025*7851SDana.Myers@Sun.COM 1026*7851SDana.Myers@Sun.COM Status = AcpiPsNextParseState (WalkState, Op, Status); 1027*7851SDana.Myers@Sun.COM } 1028*7851SDana.Myers@Sun.COM 1029*7851SDana.Myers@Sun.COM AcpiPsPopScope (ParserState, &Op, 1030*7851SDana.Myers@Sun.COM &WalkState->ArgTypes, &WalkState->ArgCount); 1031*7851SDana.Myers@Sun.COM ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", Op)); 1032*7851SDana.Myers@Sun.COM } 1033*7851SDana.Myers@Sun.COM else if (WalkState->PrevOp) 1034*7851SDana.Myers@Sun.COM { 1035*7851SDana.Myers@Sun.COM /* We were in the middle of an op */ 1036*7851SDana.Myers@Sun.COM 1037*7851SDana.Myers@Sun.COM Op = WalkState->PrevOp; 1038*7851SDana.Myers@Sun.COM WalkState->ArgTypes = WalkState->PrevArgTypes; 1039*7851SDana.Myers@Sun.COM } 1040*7851SDana.Myers@Sun.COM } 1041*7851SDana.Myers@Sun.COM #endif 1042*7851SDana.Myers@Sun.COM 1043*7851SDana.Myers@Sun.COM /* Iterative parsing loop, while there is more AML to process: */ 1044*7851SDana.Myers@Sun.COM 1045*7851SDana.Myers@Sun.COM while ((ParserState->Aml < ParserState->AmlEnd) || (Op)) 1046*7851SDana.Myers@Sun.COM { 1047*7851SDana.Myers@Sun.COM AmlOpStart = ParserState->Aml; 1048*7851SDana.Myers@Sun.COM if (!Op) 1049*7851SDana.Myers@Sun.COM { 1050*7851SDana.Myers@Sun.COM Status = AcpiPsCreateOp (WalkState, AmlOpStart, &Op); 1051*7851SDana.Myers@Sun.COM if (ACPI_FAILURE (Status)) 1052*7851SDana.Myers@Sun.COM { 1053*7851SDana.Myers@Sun.COM if (Status == AE_CTRL_PARSE_CONTINUE) 1054*7851SDana.Myers@Sun.COM { 1055*7851SDana.Myers@Sun.COM continue; 1056*7851SDana.Myers@Sun.COM } 1057*7851SDana.Myers@Sun.COM 1058*7851SDana.Myers@Sun.COM if (Status == AE_CTRL_PARSE_PENDING) 1059*7851SDana.Myers@Sun.COM { 1060*7851SDana.Myers@Sun.COM Status = AE_OK; 1061*7851SDana.Myers@Sun.COM } 1062*7851SDana.Myers@Sun.COM 1063*7851SDana.Myers@Sun.COM Status = AcpiPsCompleteOp (WalkState, &Op, Status); 1064*7851SDana.Myers@Sun.COM if (ACPI_FAILURE (Status)) 1065*7851SDana.Myers@Sun.COM { 1066*7851SDana.Myers@Sun.COM return_ACPI_STATUS (Status); 1067*7851SDana.Myers@Sun.COM } 1068*7851SDana.Myers@Sun.COM 1069*7851SDana.Myers@Sun.COM continue; 1070*7851SDana.Myers@Sun.COM } 1071*7851SDana.Myers@Sun.COM 1072*7851SDana.Myers@Sun.COM Op->Common.AmlOffset = WalkState->AmlOffset; 1073*7851SDana.Myers@Sun.COM 1074*7851SDana.Myers@Sun.COM if (WalkState->OpInfo) 1075*7851SDana.Myers@Sun.COM { 1076*7851SDana.Myers@Sun.COM ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, 1077*7851SDana.Myers@Sun.COM "Opcode %4.4X [%s] Op %p Aml %p AmlOffset %5.5X\n", 1078*7851SDana.Myers@Sun.COM (UINT32) Op->Common.AmlOpcode, WalkState->OpInfo->Name, 1079*7851SDana.Myers@Sun.COM Op, ParserState->Aml, Op->Common.AmlOffset)); 1080*7851SDana.Myers@Sun.COM } 1081*7851SDana.Myers@Sun.COM } 1082*7851SDana.Myers@Sun.COM 1083*7851SDana.Myers@Sun.COM 1084*7851SDana.Myers@Sun.COM /* 1085*7851SDana.Myers@Sun.COM * Start ArgCount at zero because we don't know if there are 1086*7851SDana.Myers@Sun.COM * any args yet 1087*7851SDana.Myers@Sun.COM */ 1088*7851SDana.Myers@Sun.COM WalkState->ArgCount = 0; 1089*7851SDana.Myers@Sun.COM 1090*7851SDana.Myers@Sun.COM /* Are there any arguments that must be processed? */ 1091*7851SDana.Myers@Sun.COM 1092*7851SDana.Myers@Sun.COM if (WalkState->ArgTypes) 1093*7851SDana.Myers@Sun.COM { 1094*7851SDana.Myers@Sun.COM /* Get arguments */ 1095*7851SDana.Myers@Sun.COM 1096*7851SDana.Myers@Sun.COM Status = AcpiPsGetArguments (WalkState, AmlOpStart, Op); 1097*7851SDana.Myers@Sun.COM if (ACPI_FAILURE (Status)) 1098*7851SDana.Myers@Sun.COM { 1099*7851SDana.Myers@Sun.COM Status = AcpiPsCompleteOp (WalkState, &Op, Status); 1100*7851SDana.Myers@Sun.COM if (ACPI_FAILURE (Status)) 1101*7851SDana.Myers@Sun.COM { 1102*7851SDana.Myers@Sun.COM return_ACPI_STATUS (Status); 1103*7851SDana.Myers@Sun.COM } 1104*7851SDana.Myers@Sun.COM 1105*7851SDana.Myers@Sun.COM continue; 1106*7851SDana.Myers@Sun.COM } 1107*7851SDana.Myers@Sun.COM } 1108*7851SDana.Myers@Sun.COM 1109*7851SDana.Myers@Sun.COM /* Check for arguments that need to be processed */ 1110*7851SDana.Myers@Sun.COM 1111*7851SDana.Myers@Sun.COM if (WalkState->ArgCount) 1112*7851SDana.Myers@Sun.COM { 1113*7851SDana.Myers@Sun.COM /* 1114*7851SDana.Myers@Sun.COM * There are arguments (complex ones), push Op and 1115*7851SDana.Myers@Sun.COM * prepare for argument 1116*7851SDana.Myers@Sun.COM */ 1117*7851SDana.Myers@Sun.COM Status = AcpiPsPushScope (ParserState, Op, 1118*7851SDana.Myers@Sun.COM WalkState->ArgTypes, WalkState->ArgCount); 1119*7851SDana.Myers@Sun.COM if (ACPI_FAILURE (Status)) 1120*7851SDana.Myers@Sun.COM { 1121*7851SDana.Myers@Sun.COM Status = AcpiPsCompleteOp (WalkState, &Op, Status); 1122*7851SDana.Myers@Sun.COM if (ACPI_FAILURE (Status)) 1123*7851SDana.Myers@Sun.COM { 1124*7851SDana.Myers@Sun.COM return_ACPI_STATUS (Status); 1125*7851SDana.Myers@Sun.COM } 1126*7851SDana.Myers@Sun.COM 1127*7851SDana.Myers@Sun.COM continue; 1128*7851SDana.Myers@Sun.COM } 1129*7851SDana.Myers@Sun.COM 1130*7851SDana.Myers@Sun.COM Op = NULL; 1131*7851SDana.Myers@Sun.COM continue; 1132*7851SDana.Myers@Sun.COM } 1133*7851SDana.Myers@Sun.COM 1134*7851SDana.Myers@Sun.COM /* 1135*7851SDana.Myers@Sun.COM * All arguments have been processed -- Op is complete, 1136*7851SDana.Myers@Sun.COM * prepare for next 1137*7851SDana.Myers@Sun.COM */ 1138*7851SDana.Myers@Sun.COM WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 1139*7851SDana.Myers@Sun.COM if (WalkState->OpInfo->Flags & AML_NAMED) 1140*7851SDana.Myers@Sun.COM { 1141*7851SDana.Myers@Sun.COM if (AcpiGbl_Depth) 1142*7851SDana.Myers@Sun.COM { 1143*7851SDana.Myers@Sun.COM AcpiGbl_Depth--; 1144*7851SDana.Myers@Sun.COM } 1145*7851SDana.Myers@Sun.COM 1146*7851SDana.Myers@Sun.COM if (Op->Common.AmlOpcode == AML_REGION_OP || 1147*7851SDana.Myers@Sun.COM Op->Common.AmlOpcode == AML_DATA_REGION_OP) 1148*7851SDana.Myers@Sun.COM { 1149*7851SDana.Myers@Sun.COM /* 1150*7851SDana.Myers@Sun.COM * Skip parsing of control method or opregion body, 1151*7851SDana.Myers@Sun.COM * because we don't have enough info in the first pass 1152*7851SDana.Myers@Sun.COM * to parse them correctly. 1153*7851SDana.Myers@Sun.COM * 1154*7851SDana.Myers@Sun.COM * Completed parsing an OpRegion declaration, we now 1155*7851SDana.Myers@Sun.COM * know the length. 1156*7851SDana.Myers@Sun.COM */ 1157*7851SDana.Myers@Sun.COM Op->Named.Length = (UINT32) (ParserState->Aml - Op->Named.Data); 1158*7851SDana.Myers@Sun.COM } 1159*7851SDana.Myers@Sun.COM } 1160*7851SDana.Myers@Sun.COM 1161*7851SDana.Myers@Sun.COM if (WalkState->OpInfo->Flags & AML_CREATE) 1162*7851SDana.Myers@Sun.COM { 1163*7851SDana.Myers@Sun.COM /* 1164*7851SDana.Myers@Sun.COM * Backup to beginning of CreateXXXfield declaration (1 for 1165*7851SDana.Myers@Sun.COM * Opcode) 1166*7851SDana.Myers@Sun.COM * 1167*7851SDana.Myers@Sun.COM * BodyLength is unknown until we parse the body 1168*7851SDana.Myers@Sun.COM */ 1169*7851SDana.Myers@Sun.COM Op->Named.Length = (UINT32) (ParserState->Aml - Op->Named.Data); 1170*7851SDana.Myers@Sun.COM } 1171*7851SDana.Myers@Sun.COM 1172*7851SDana.Myers@Sun.COM if (Op->Common.AmlOpcode == AML_BANK_FIELD_OP) 1173*7851SDana.Myers@Sun.COM { 1174*7851SDana.Myers@Sun.COM /* 1175*7851SDana.Myers@Sun.COM * Backup to beginning of BankField declaration 1176*7851SDana.Myers@Sun.COM * 1177*7851SDana.Myers@Sun.COM * BodyLength is unknown until we parse the body 1178*7851SDana.Myers@Sun.COM */ 1179*7851SDana.Myers@Sun.COM Op->Named.Length = (UINT32) (ParserState->Aml - Op->Named.Data); 1180*7851SDana.Myers@Sun.COM } 1181*7851SDana.Myers@Sun.COM 1182*7851SDana.Myers@Sun.COM /* This op complete, notify the dispatcher */ 1183*7851SDana.Myers@Sun.COM 1184*7851SDana.Myers@Sun.COM if (WalkState->AscendingCallback != NULL) 1185*7851SDana.Myers@Sun.COM { 1186*7851SDana.Myers@Sun.COM WalkState->Op = Op; 1187*7851SDana.Myers@Sun.COM WalkState->Opcode = Op->Common.AmlOpcode; 1188*7851SDana.Myers@Sun.COM 1189*7851SDana.Myers@Sun.COM Status = WalkState->AscendingCallback (WalkState); 1190*7851SDana.Myers@Sun.COM Status = AcpiPsNextParseState (WalkState, Op, Status); 1191*7851SDana.Myers@Sun.COM if (Status == AE_CTRL_PENDING) 1192*7851SDana.Myers@Sun.COM { 1193*7851SDana.Myers@Sun.COM Status = AE_OK; 1194*7851SDana.Myers@Sun.COM } 1195*7851SDana.Myers@Sun.COM } 1196*7851SDana.Myers@Sun.COM 1197*7851SDana.Myers@Sun.COM Status = AcpiPsCompleteOp (WalkState, &Op, Status); 1198*7851SDana.Myers@Sun.COM if (ACPI_FAILURE (Status)) 1199*7851SDana.Myers@Sun.COM { 1200*7851SDana.Myers@Sun.COM return_ACPI_STATUS (Status); 1201*7851SDana.Myers@Sun.COM } 1202*7851SDana.Myers@Sun.COM 1203*7851SDana.Myers@Sun.COM } /* while ParserState->Aml */ 1204*7851SDana.Myers@Sun.COM 1205*7851SDana.Myers@Sun.COM Status = AcpiPsCompleteFinalOp (WalkState, Op, Status); 1206*7851SDana.Myers@Sun.COM return_ACPI_STATUS (Status); 1207*7851SDana.Myers@Sun.COM } 1208*7851SDana.Myers@Sun.COM 1209