1*efcc2a30SJung-uk Kim /****************************************************************************** 2*efcc2a30SJung-uk Kim * 3*efcc2a30SJung-uk Kim * Module Name: psobject - Support for parse objects 4*efcc2a30SJung-uk Kim * 5*efcc2a30SJung-uk Kim *****************************************************************************/ 6*efcc2a30SJung-uk Kim 7*efcc2a30SJung-uk Kim /* 8*efcc2a30SJung-uk Kim * Copyright (C) 2000 - 2013, Intel Corp. 9*efcc2a30SJung-uk Kim * All rights reserved. 10*efcc2a30SJung-uk Kim * 11*efcc2a30SJung-uk Kim * Redistribution and use in source and binary forms, with or without 12*efcc2a30SJung-uk Kim * modification, are permitted provided that the following conditions 13*efcc2a30SJung-uk Kim * are met: 14*efcc2a30SJung-uk Kim * 1. Redistributions of source code must retain the above copyright 15*efcc2a30SJung-uk Kim * notice, this list of conditions, and the following disclaimer, 16*efcc2a30SJung-uk Kim * without modification. 17*efcc2a30SJung-uk Kim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18*efcc2a30SJung-uk Kim * substantially similar to the "NO WARRANTY" disclaimer below 19*efcc2a30SJung-uk Kim * ("Disclaimer") and any redistribution must be conditioned upon 20*efcc2a30SJung-uk Kim * including a substantially similar Disclaimer requirement for further 21*efcc2a30SJung-uk Kim * binary redistribution. 22*efcc2a30SJung-uk Kim * 3. Neither the names of the above-listed copyright holders nor the names 23*efcc2a30SJung-uk Kim * of any contributors may be used to endorse or promote products derived 24*efcc2a30SJung-uk Kim * from this software without specific prior written permission. 25*efcc2a30SJung-uk Kim * 26*efcc2a30SJung-uk Kim * Alternatively, this software may be distributed under the terms of the 27*efcc2a30SJung-uk Kim * GNU General Public License ("GPL") version 2 as published by the Free 28*efcc2a30SJung-uk Kim * Software Foundation. 29*efcc2a30SJung-uk Kim * 30*efcc2a30SJung-uk Kim * NO WARRANTY 31*efcc2a30SJung-uk Kim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32*efcc2a30SJung-uk Kim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33*efcc2a30SJung-uk Kim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34*efcc2a30SJung-uk Kim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35*efcc2a30SJung-uk Kim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36*efcc2a30SJung-uk Kim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37*efcc2a30SJung-uk Kim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38*efcc2a30SJung-uk Kim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39*efcc2a30SJung-uk Kim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40*efcc2a30SJung-uk Kim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41*efcc2a30SJung-uk Kim * POSSIBILITY OF SUCH DAMAGES. 42*efcc2a30SJung-uk Kim */ 43*efcc2a30SJung-uk Kim 44*efcc2a30SJung-uk Kim 45*efcc2a30SJung-uk Kim #include <contrib/dev/acpica/include/acpi.h> 46*efcc2a30SJung-uk Kim #include <contrib/dev/acpica/include/accommon.h> 47*efcc2a30SJung-uk Kim #include <contrib/dev/acpica/include/acparser.h> 48*efcc2a30SJung-uk Kim #include <contrib/dev/acpica/include/amlcode.h> 49*efcc2a30SJung-uk Kim 50*efcc2a30SJung-uk Kim #define _COMPONENT ACPI_PARSER 51*efcc2a30SJung-uk Kim ACPI_MODULE_NAME ("psobject") 52*efcc2a30SJung-uk Kim 53*efcc2a30SJung-uk Kim 54*efcc2a30SJung-uk Kim /* Local prototypes */ 55*efcc2a30SJung-uk Kim 56*efcc2a30SJung-uk Kim static ACPI_STATUS 57*efcc2a30SJung-uk Kim AcpiPsGetAmlOpcode ( 58*efcc2a30SJung-uk Kim ACPI_WALK_STATE *WalkState); 59*efcc2a30SJung-uk Kim 60*efcc2a30SJung-uk Kim 61*efcc2a30SJung-uk Kim /******************************************************************************* 62*efcc2a30SJung-uk Kim * 63*efcc2a30SJung-uk Kim * FUNCTION: AcpiPsGetAmlOpcode 64*efcc2a30SJung-uk Kim * 65*efcc2a30SJung-uk Kim * PARAMETERS: WalkState - Current state 66*efcc2a30SJung-uk Kim * 67*efcc2a30SJung-uk Kim * RETURN: Status 68*efcc2a30SJung-uk Kim * 69*efcc2a30SJung-uk Kim * DESCRIPTION: Extract the next AML opcode from the input stream. 70*efcc2a30SJung-uk Kim * 71*efcc2a30SJung-uk Kim ******************************************************************************/ 72*efcc2a30SJung-uk Kim 73*efcc2a30SJung-uk Kim static ACPI_STATUS 74*efcc2a30SJung-uk Kim AcpiPsGetAmlOpcode ( 75*efcc2a30SJung-uk Kim ACPI_WALK_STATE *WalkState) 76*efcc2a30SJung-uk Kim { 77*efcc2a30SJung-uk Kim 78*efcc2a30SJung-uk Kim ACPI_FUNCTION_TRACE_PTR (PsGetAmlOpcode, WalkState); 79*efcc2a30SJung-uk Kim 80*efcc2a30SJung-uk Kim 81*efcc2a30SJung-uk Kim WalkState->AmlOffset = (UINT32) ACPI_PTR_DIFF (WalkState->ParserState.Aml, 82*efcc2a30SJung-uk Kim WalkState->ParserState.AmlStart); 83*efcc2a30SJung-uk Kim WalkState->Opcode = AcpiPsPeekOpcode (&(WalkState->ParserState)); 84*efcc2a30SJung-uk Kim 85*efcc2a30SJung-uk Kim /* 86*efcc2a30SJung-uk Kim * First cut to determine what we have found: 87*efcc2a30SJung-uk Kim * 1) A valid AML opcode 88*efcc2a30SJung-uk Kim * 2) A name string 89*efcc2a30SJung-uk Kim * 3) An unknown/invalid opcode 90*efcc2a30SJung-uk Kim */ 91*efcc2a30SJung-uk Kim WalkState->OpInfo = AcpiPsGetOpcodeInfo (WalkState->Opcode); 92*efcc2a30SJung-uk Kim 93*efcc2a30SJung-uk Kim switch (WalkState->OpInfo->Class) 94*efcc2a30SJung-uk Kim { 95*efcc2a30SJung-uk Kim case AML_CLASS_ASCII: 96*efcc2a30SJung-uk Kim case AML_CLASS_PREFIX: 97*efcc2a30SJung-uk Kim /* 98*efcc2a30SJung-uk Kim * Starts with a valid prefix or ASCII char, this is a name 99*efcc2a30SJung-uk Kim * string. Convert the bare name string to a namepath. 100*efcc2a30SJung-uk Kim */ 101*efcc2a30SJung-uk Kim WalkState->Opcode = AML_INT_NAMEPATH_OP; 102*efcc2a30SJung-uk Kim WalkState->ArgTypes = ARGP_NAMESTRING; 103*efcc2a30SJung-uk Kim break; 104*efcc2a30SJung-uk Kim 105*efcc2a30SJung-uk Kim case AML_CLASS_UNKNOWN: 106*efcc2a30SJung-uk Kim 107*efcc2a30SJung-uk Kim /* The opcode is unrecognized. Complain and skip unknown opcodes */ 108*efcc2a30SJung-uk Kim 109*efcc2a30SJung-uk Kim if (WalkState->PassNumber == 2) 110*efcc2a30SJung-uk Kim { 111*efcc2a30SJung-uk Kim ACPI_ERROR ((AE_INFO, 112*efcc2a30SJung-uk Kim "Unknown opcode 0x%.2X at table offset 0x%.4X, ignoring", 113*efcc2a30SJung-uk Kim WalkState->Opcode, 114*efcc2a30SJung-uk Kim (UINT32) (WalkState->AmlOffset + sizeof (ACPI_TABLE_HEADER)))); 115*efcc2a30SJung-uk Kim 116*efcc2a30SJung-uk Kim ACPI_DUMP_BUFFER ((WalkState->ParserState.Aml - 16), 48); 117*efcc2a30SJung-uk Kim 118*efcc2a30SJung-uk Kim #ifdef ACPI_ASL_COMPILER 119*efcc2a30SJung-uk Kim /* 120*efcc2a30SJung-uk Kim * This is executed for the disassembler only. Output goes 121*efcc2a30SJung-uk Kim * to the disassembled ASL output file. 122*efcc2a30SJung-uk Kim */ 123*efcc2a30SJung-uk Kim AcpiOsPrintf ( 124*efcc2a30SJung-uk Kim "/*\nError: Unknown opcode 0x%.2X at table offset 0x%.4X, context:\n", 125*efcc2a30SJung-uk Kim WalkState->Opcode, 126*efcc2a30SJung-uk Kim (UINT32) (WalkState->AmlOffset + sizeof (ACPI_TABLE_HEADER))); 127*efcc2a30SJung-uk Kim 128*efcc2a30SJung-uk Kim /* Dump the context surrounding the invalid opcode */ 129*efcc2a30SJung-uk Kim 130*efcc2a30SJung-uk Kim AcpiUtDumpBuffer (((UINT8 *) WalkState->ParserState.Aml - 16), 131*efcc2a30SJung-uk Kim 48, DB_BYTE_DISPLAY, 132*efcc2a30SJung-uk Kim (WalkState->AmlOffset + sizeof (ACPI_TABLE_HEADER) - 16)); 133*efcc2a30SJung-uk Kim AcpiOsPrintf (" */\n"); 134*efcc2a30SJung-uk Kim #endif 135*efcc2a30SJung-uk Kim } 136*efcc2a30SJung-uk Kim 137*efcc2a30SJung-uk Kim /* Increment past one-byte or two-byte opcode */ 138*efcc2a30SJung-uk Kim 139*efcc2a30SJung-uk Kim WalkState->ParserState.Aml++; 140*efcc2a30SJung-uk Kim if (WalkState->Opcode > 0xFF) /* Can only happen if first byte is 0x5B */ 141*efcc2a30SJung-uk Kim { 142*efcc2a30SJung-uk Kim WalkState->ParserState.Aml++; 143*efcc2a30SJung-uk Kim } 144*efcc2a30SJung-uk Kim 145*efcc2a30SJung-uk Kim return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE); 146*efcc2a30SJung-uk Kim 147*efcc2a30SJung-uk Kim default: 148*efcc2a30SJung-uk Kim 149*efcc2a30SJung-uk Kim /* Found opcode info, this is a normal opcode */ 150*efcc2a30SJung-uk Kim 151*efcc2a30SJung-uk Kim WalkState->ParserState.Aml += AcpiPsGetOpcodeSize (WalkState->Opcode); 152*efcc2a30SJung-uk Kim WalkState->ArgTypes = WalkState->OpInfo->ParseArgs; 153*efcc2a30SJung-uk Kim break; 154*efcc2a30SJung-uk Kim } 155*efcc2a30SJung-uk Kim 156*efcc2a30SJung-uk Kim return_ACPI_STATUS (AE_OK); 157*efcc2a30SJung-uk Kim } 158*efcc2a30SJung-uk Kim 159*efcc2a30SJung-uk Kim 160*efcc2a30SJung-uk Kim /******************************************************************************* 161*efcc2a30SJung-uk Kim * 162*efcc2a30SJung-uk Kim * FUNCTION: AcpiPsBuildNamedOp 163*efcc2a30SJung-uk Kim * 164*efcc2a30SJung-uk Kim * PARAMETERS: WalkState - Current state 165*efcc2a30SJung-uk Kim * AmlOpStart - Begin of named Op in AML 166*efcc2a30SJung-uk Kim * UnnamedOp - Early Op (not a named Op) 167*efcc2a30SJung-uk Kim * Op - Returned Op 168*efcc2a30SJung-uk Kim * 169*efcc2a30SJung-uk Kim * RETURN: Status 170*efcc2a30SJung-uk Kim * 171*efcc2a30SJung-uk Kim * DESCRIPTION: Parse a named Op 172*efcc2a30SJung-uk Kim * 173*efcc2a30SJung-uk Kim ******************************************************************************/ 174*efcc2a30SJung-uk Kim 175*efcc2a30SJung-uk Kim ACPI_STATUS 176*efcc2a30SJung-uk Kim AcpiPsBuildNamedOp ( 177*efcc2a30SJung-uk Kim ACPI_WALK_STATE *WalkState, 178*efcc2a30SJung-uk Kim UINT8 *AmlOpStart, 179*efcc2a30SJung-uk Kim ACPI_PARSE_OBJECT *UnnamedOp, 180*efcc2a30SJung-uk Kim ACPI_PARSE_OBJECT **Op) 181*efcc2a30SJung-uk Kim { 182*efcc2a30SJung-uk Kim ACPI_STATUS Status = AE_OK; 183*efcc2a30SJung-uk Kim ACPI_PARSE_OBJECT *Arg = NULL; 184*efcc2a30SJung-uk Kim 185*efcc2a30SJung-uk Kim 186*efcc2a30SJung-uk Kim ACPI_FUNCTION_TRACE_PTR (PsBuildNamedOp, WalkState); 187*efcc2a30SJung-uk Kim 188*efcc2a30SJung-uk Kim 189*efcc2a30SJung-uk Kim UnnamedOp->Common.Value.Arg = NULL; 190*efcc2a30SJung-uk Kim UnnamedOp->Common.ArgListLength = 0; 191*efcc2a30SJung-uk Kim UnnamedOp->Common.AmlOpcode = WalkState->Opcode; 192*efcc2a30SJung-uk Kim 193*efcc2a30SJung-uk Kim /* 194*efcc2a30SJung-uk Kim * Get and append arguments until we find the node that contains 195*efcc2a30SJung-uk Kim * the name (the type ARGP_NAME). 196*efcc2a30SJung-uk Kim */ 197*efcc2a30SJung-uk Kim while (GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) && 198*efcc2a30SJung-uk Kim (GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) != ARGP_NAME)) 199*efcc2a30SJung-uk Kim { 200*efcc2a30SJung-uk Kim Status = AcpiPsGetNextArg (WalkState, &(WalkState->ParserState), 201*efcc2a30SJung-uk Kim GET_CURRENT_ARG_TYPE (WalkState->ArgTypes), &Arg); 202*efcc2a30SJung-uk Kim if (ACPI_FAILURE (Status)) 203*efcc2a30SJung-uk Kim { 204*efcc2a30SJung-uk Kim return_ACPI_STATUS (Status); 205*efcc2a30SJung-uk Kim } 206*efcc2a30SJung-uk Kim 207*efcc2a30SJung-uk Kim AcpiPsAppendArg (UnnamedOp, Arg); 208*efcc2a30SJung-uk Kim INCREMENT_ARG_LIST (WalkState->ArgTypes); 209*efcc2a30SJung-uk Kim } 210*efcc2a30SJung-uk Kim 211*efcc2a30SJung-uk Kim /* 212*efcc2a30SJung-uk Kim * Make sure that we found a NAME and didn't run out of arguments 213*efcc2a30SJung-uk Kim */ 214*efcc2a30SJung-uk Kim if (!GET_CURRENT_ARG_TYPE (WalkState->ArgTypes)) 215*efcc2a30SJung-uk Kim { 216*efcc2a30SJung-uk Kim return_ACPI_STATUS (AE_AML_NO_OPERAND); 217*efcc2a30SJung-uk Kim } 218*efcc2a30SJung-uk Kim 219*efcc2a30SJung-uk Kim /* We know that this arg is a name, move to next arg */ 220*efcc2a30SJung-uk Kim 221*efcc2a30SJung-uk Kim INCREMENT_ARG_LIST (WalkState->ArgTypes); 222*efcc2a30SJung-uk Kim 223*efcc2a30SJung-uk Kim /* 224*efcc2a30SJung-uk Kim * Find the object. This will either insert the object into 225*efcc2a30SJung-uk Kim * the namespace or simply look it up 226*efcc2a30SJung-uk Kim */ 227*efcc2a30SJung-uk Kim WalkState->Op = NULL; 228*efcc2a30SJung-uk Kim 229*efcc2a30SJung-uk Kim Status = WalkState->DescendingCallback (WalkState, Op); 230*efcc2a30SJung-uk Kim if (ACPI_FAILURE (Status)) 231*efcc2a30SJung-uk Kim { 232*efcc2a30SJung-uk Kim ACPI_EXCEPTION ((AE_INFO, Status, "During name lookup/catalog")); 233*efcc2a30SJung-uk Kim return_ACPI_STATUS (Status); 234*efcc2a30SJung-uk Kim } 235*efcc2a30SJung-uk Kim 236*efcc2a30SJung-uk Kim if (!*Op) 237*efcc2a30SJung-uk Kim { 238*efcc2a30SJung-uk Kim return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE); 239*efcc2a30SJung-uk Kim } 240*efcc2a30SJung-uk Kim 241*efcc2a30SJung-uk Kim Status = AcpiPsNextParseState (WalkState, *Op, Status); 242*efcc2a30SJung-uk Kim if (ACPI_FAILURE (Status)) 243*efcc2a30SJung-uk Kim { 244*efcc2a30SJung-uk Kim if (Status == AE_CTRL_PENDING) 245*efcc2a30SJung-uk Kim { 246*efcc2a30SJung-uk Kim return_ACPI_STATUS (AE_CTRL_PARSE_PENDING); 247*efcc2a30SJung-uk Kim } 248*efcc2a30SJung-uk Kim return_ACPI_STATUS (Status); 249*efcc2a30SJung-uk Kim } 250*efcc2a30SJung-uk Kim 251*efcc2a30SJung-uk Kim AcpiPsAppendArg (*Op, UnnamedOp->Common.Value.Arg); 252*efcc2a30SJung-uk Kim 253*efcc2a30SJung-uk Kim if ((*Op)->Common.AmlOpcode == AML_REGION_OP || 254*efcc2a30SJung-uk Kim (*Op)->Common.AmlOpcode == AML_DATA_REGION_OP) 255*efcc2a30SJung-uk Kim { 256*efcc2a30SJung-uk Kim /* 257*efcc2a30SJung-uk Kim * Defer final parsing of an OperationRegion body, because we don't 258*efcc2a30SJung-uk Kim * have enough info in the first pass to parse it correctly (i.e., 259*efcc2a30SJung-uk Kim * there may be method calls within the TermArg elements of the body.) 260*efcc2a30SJung-uk Kim * 261*efcc2a30SJung-uk Kim * However, we must continue parsing because the opregion is not a 262*efcc2a30SJung-uk Kim * standalone package -- we don't know where the end is at this point. 263*efcc2a30SJung-uk Kim * 264*efcc2a30SJung-uk Kim * (Length is unknown until parse of the body complete) 265*efcc2a30SJung-uk Kim */ 266*efcc2a30SJung-uk Kim (*Op)->Named.Data = AmlOpStart; 267*efcc2a30SJung-uk Kim (*Op)->Named.Length = 0; 268*efcc2a30SJung-uk Kim } 269*efcc2a30SJung-uk Kim 270*efcc2a30SJung-uk Kim return_ACPI_STATUS (AE_OK); 271*efcc2a30SJung-uk Kim } 272*efcc2a30SJung-uk Kim 273*efcc2a30SJung-uk Kim 274*efcc2a30SJung-uk Kim /******************************************************************************* 275*efcc2a30SJung-uk Kim * 276*efcc2a30SJung-uk Kim * FUNCTION: AcpiPsCreateOp 277*efcc2a30SJung-uk Kim * 278*efcc2a30SJung-uk Kim * PARAMETERS: WalkState - Current state 279*efcc2a30SJung-uk Kim * AmlOpStart - Op start in AML 280*efcc2a30SJung-uk Kim * NewOp - Returned Op 281*efcc2a30SJung-uk Kim * 282*efcc2a30SJung-uk Kim * RETURN: Status 283*efcc2a30SJung-uk Kim * 284*efcc2a30SJung-uk Kim * DESCRIPTION: Get Op from AML 285*efcc2a30SJung-uk Kim * 286*efcc2a30SJung-uk Kim ******************************************************************************/ 287*efcc2a30SJung-uk Kim 288*efcc2a30SJung-uk Kim ACPI_STATUS 289*efcc2a30SJung-uk Kim AcpiPsCreateOp ( 290*efcc2a30SJung-uk Kim ACPI_WALK_STATE *WalkState, 291*efcc2a30SJung-uk Kim UINT8 *AmlOpStart, 292*efcc2a30SJung-uk Kim ACPI_PARSE_OBJECT **NewOp) 293*efcc2a30SJung-uk Kim { 294*efcc2a30SJung-uk Kim ACPI_STATUS Status = AE_OK; 295*efcc2a30SJung-uk Kim ACPI_PARSE_OBJECT *Op; 296*efcc2a30SJung-uk Kim ACPI_PARSE_OBJECT *NamedOp = NULL; 297*efcc2a30SJung-uk Kim ACPI_PARSE_OBJECT *ParentScope; 298*efcc2a30SJung-uk Kim UINT8 ArgumentCount; 299*efcc2a30SJung-uk Kim const ACPI_OPCODE_INFO *OpInfo; 300*efcc2a30SJung-uk Kim 301*efcc2a30SJung-uk Kim 302*efcc2a30SJung-uk Kim ACPI_FUNCTION_TRACE_PTR (PsCreateOp, WalkState); 303*efcc2a30SJung-uk Kim 304*efcc2a30SJung-uk Kim 305*efcc2a30SJung-uk Kim Status = AcpiPsGetAmlOpcode (WalkState); 306*efcc2a30SJung-uk Kim if (Status == AE_CTRL_PARSE_CONTINUE) 307*efcc2a30SJung-uk Kim { 308*efcc2a30SJung-uk Kim return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE); 309*efcc2a30SJung-uk Kim } 310*efcc2a30SJung-uk Kim 311*efcc2a30SJung-uk Kim /* Create Op structure and append to parent's argument list */ 312*efcc2a30SJung-uk Kim 313*efcc2a30SJung-uk Kim WalkState->OpInfo = AcpiPsGetOpcodeInfo (WalkState->Opcode); 314*efcc2a30SJung-uk Kim Op = AcpiPsAllocOp (WalkState->Opcode); 315*efcc2a30SJung-uk Kim if (!Op) 316*efcc2a30SJung-uk Kim { 317*efcc2a30SJung-uk Kim return_ACPI_STATUS (AE_NO_MEMORY); 318*efcc2a30SJung-uk Kim } 319*efcc2a30SJung-uk Kim 320*efcc2a30SJung-uk Kim if (WalkState->OpInfo->Flags & AML_NAMED) 321*efcc2a30SJung-uk Kim { 322*efcc2a30SJung-uk Kim Status = AcpiPsBuildNamedOp (WalkState, AmlOpStart, Op, &NamedOp); 323*efcc2a30SJung-uk Kim AcpiPsFreeOp (Op); 324*efcc2a30SJung-uk Kim if (ACPI_FAILURE (Status)) 325*efcc2a30SJung-uk Kim { 326*efcc2a30SJung-uk Kim return_ACPI_STATUS (Status); 327*efcc2a30SJung-uk Kim } 328*efcc2a30SJung-uk Kim 329*efcc2a30SJung-uk Kim *NewOp = NamedOp; 330*efcc2a30SJung-uk Kim return_ACPI_STATUS (AE_OK); 331*efcc2a30SJung-uk Kim } 332*efcc2a30SJung-uk Kim 333*efcc2a30SJung-uk Kim /* Not a named opcode, just allocate Op and append to parent */ 334*efcc2a30SJung-uk Kim 335*efcc2a30SJung-uk Kim if (WalkState->OpInfo->Flags & AML_CREATE) 336*efcc2a30SJung-uk Kim { 337*efcc2a30SJung-uk Kim /* 338*efcc2a30SJung-uk Kim * Backup to beginning of CreateXXXfield declaration 339*efcc2a30SJung-uk Kim * BodyLength is unknown until we parse the body 340*efcc2a30SJung-uk Kim */ 341*efcc2a30SJung-uk Kim Op->Named.Data = AmlOpStart; 342*efcc2a30SJung-uk Kim Op->Named.Length = 0; 343*efcc2a30SJung-uk Kim } 344*efcc2a30SJung-uk Kim 345*efcc2a30SJung-uk Kim if (WalkState->Opcode == AML_BANK_FIELD_OP) 346*efcc2a30SJung-uk Kim { 347*efcc2a30SJung-uk Kim /* 348*efcc2a30SJung-uk Kim * Backup to beginning of BankField declaration 349*efcc2a30SJung-uk Kim * BodyLength is unknown until we parse the body 350*efcc2a30SJung-uk Kim */ 351*efcc2a30SJung-uk Kim Op->Named.Data = AmlOpStart; 352*efcc2a30SJung-uk Kim Op->Named.Length = 0; 353*efcc2a30SJung-uk Kim } 354*efcc2a30SJung-uk Kim 355*efcc2a30SJung-uk Kim ParentScope = AcpiPsGetParentScope (&(WalkState->ParserState)); 356*efcc2a30SJung-uk Kim AcpiPsAppendArg (ParentScope, Op); 357*efcc2a30SJung-uk Kim 358*efcc2a30SJung-uk Kim if (ParentScope) 359*efcc2a30SJung-uk Kim { 360*efcc2a30SJung-uk Kim OpInfo = AcpiPsGetOpcodeInfo (ParentScope->Common.AmlOpcode); 361*efcc2a30SJung-uk Kim if (OpInfo->Flags & AML_HAS_TARGET) 362*efcc2a30SJung-uk Kim { 363*efcc2a30SJung-uk Kim ArgumentCount = AcpiPsGetArgumentCount (OpInfo->Type); 364*efcc2a30SJung-uk Kim if (ParentScope->Common.ArgListLength > ArgumentCount) 365*efcc2a30SJung-uk Kim { 366*efcc2a30SJung-uk Kim Op->Common.Flags |= ACPI_PARSEOP_TARGET; 367*efcc2a30SJung-uk Kim } 368*efcc2a30SJung-uk Kim } 369*efcc2a30SJung-uk Kim else if (ParentScope->Common.AmlOpcode == AML_INCREMENT_OP) 370*efcc2a30SJung-uk Kim { 371*efcc2a30SJung-uk Kim Op->Common.Flags |= ACPI_PARSEOP_TARGET; 372*efcc2a30SJung-uk Kim } 373*efcc2a30SJung-uk Kim } 374*efcc2a30SJung-uk Kim 375*efcc2a30SJung-uk Kim if (WalkState->DescendingCallback != NULL) 376*efcc2a30SJung-uk Kim { 377*efcc2a30SJung-uk Kim /* 378*efcc2a30SJung-uk Kim * Find the object. This will either insert the object into 379*efcc2a30SJung-uk Kim * the namespace or simply look it up 380*efcc2a30SJung-uk Kim */ 381*efcc2a30SJung-uk Kim WalkState->Op = *NewOp = Op; 382*efcc2a30SJung-uk Kim 383*efcc2a30SJung-uk Kim Status = WalkState->DescendingCallback (WalkState, &Op); 384*efcc2a30SJung-uk Kim Status = AcpiPsNextParseState (WalkState, Op, Status); 385*efcc2a30SJung-uk Kim if (Status == AE_CTRL_PENDING) 386*efcc2a30SJung-uk Kim { 387*efcc2a30SJung-uk Kim Status = AE_CTRL_PARSE_PENDING; 388*efcc2a30SJung-uk Kim } 389*efcc2a30SJung-uk Kim } 390*efcc2a30SJung-uk Kim 391*efcc2a30SJung-uk Kim return_ACPI_STATUS (Status); 392*efcc2a30SJung-uk Kim } 393*efcc2a30SJung-uk Kim 394*efcc2a30SJung-uk Kim 395*efcc2a30SJung-uk Kim /******************************************************************************* 396*efcc2a30SJung-uk Kim * 397*efcc2a30SJung-uk Kim * FUNCTION: AcpiPsCompleteOp 398*efcc2a30SJung-uk Kim * 399*efcc2a30SJung-uk Kim * PARAMETERS: WalkState - Current state 400*efcc2a30SJung-uk Kim * Op - Returned Op 401*efcc2a30SJung-uk Kim * Status - Parse status before complete Op 402*efcc2a30SJung-uk Kim * 403*efcc2a30SJung-uk Kim * RETURN: Status 404*efcc2a30SJung-uk Kim * 405*efcc2a30SJung-uk Kim * DESCRIPTION: Complete Op 406*efcc2a30SJung-uk Kim * 407*efcc2a30SJung-uk Kim ******************************************************************************/ 408*efcc2a30SJung-uk Kim 409*efcc2a30SJung-uk Kim ACPI_STATUS 410*efcc2a30SJung-uk Kim AcpiPsCompleteOp ( 411*efcc2a30SJung-uk Kim ACPI_WALK_STATE *WalkState, 412*efcc2a30SJung-uk Kim ACPI_PARSE_OBJECT **Op, 413*efcc2a30SJung-uk Kim ACPI_STATUS Status) 414*efcc2a30SJung-uk Kim { 415*efcc2a30SJung-uk Kim ACPI_STATUS Status2; 416*efcc2a30SJung-uk Kim 417*efcc2a30SJung-uk Kim 418*efcc2a30SJung-uk Kim ACPI_FUNCTION_TRACE_PTR (PsCompleteOp, WalkState); 419*efcc2a30SJung-uk Kim 420*efcc2a30SJung-uk Kim 421*efcc2a30SJung-uk Kim /* 422*efcc2a30SJung-uk Kim * Finished one argument of the containing scope 423*efcc2a30SJung-uk Kim */ 424*efcc2a30SJung-uk Kim WalkState->ParserState.Scope->ParseScope.ArgCount--; 425*efcc2a30SJung-uk Kim 426*efcc2a30SJung-uk Kim /* Close this Op (will result in parse subtree deletion) */ 427*efcc2a30SJung-uk Kim 428*efcc2a30SJung-uk Kim Status2 = AcpiPsCompleteThisOp (WalkState, *Op); 429*efcc2a30SJung-uk Kim if (ACPI_FAILURE (Status2)) 430*efcc2a30SJung-uk Kim { 431*efcc2a30SJung-uk Kim return_ACPI_STATUS (Status2); 432*efcc2a30SJung-uk Kim } 433*efcc2a30SJung-uk Kim 434*efcc2a30SJung-uk Kim *Op = NULL; 435*efcc2a30SJung-uk Kim 436*efcc2a30SJung-uk Kim switch (Status) 437*efcc2a30SJung-uk Kim { 438*efcc2a30SJung-uk Kim case AE_OK: 439*efcc2a30SJung-uk Kim break; 440*efcc2a30SJung-uk Kim 441*efcc2a30SJung-uk Kim 442*efcc2a30SJung-uk Kim case AE_CTRL_TRANSFER: 443*efcc2a30SJung-uk Kim 444*efcc2a30SJung-uk Kim /* We are about to transfer to a called method */ 445*efcc2a30SJung-uk Kim 446*efcc2a30SJung-uk Kim WalkState->PrevOp = NULL; 447*efcc2a30SJung-uk Kim WalkState->PrevArgTypes = WalkState->ArgTypes; 448*efcc2a30SJung-uk Kim return_ACPI_STATUS (Status); 449*efcc2a30SJung-uk Kim 450*efcc2a30SJung-uk Kim 451*efcc2a30SJung-uk Kim case AE_CTRL_END: 452*efcc2a30SJung-uk Kim 453*efcc2a30SJung-uk Kim AcpiPsPopScope (&(WalkState->ParserState), Op, 454*efcc2a30SJung-uk Kim &WalkState->ArgTypes, &WalkState->ArgCount); 455*efcc2a30SJung-uk Kim 456*efcc2a30SJung-uk Kim if (*Op) 457*efcc2a30SJung-uk Kim { 458*efcc2a30SJung-uk Kim WalkState->Op = *Op; 459*efcc2a30SJung-uk Kim WalkState->OpInfo = AcpiPsGetOpcodeInfo ((*Op)->Common.AmlOpcode); 460*efcc2a30SJung-uk Kim WalkState->Opcode = (*Op)->Common.AmlOpcode; 461*efcc2a30SJung-uk Kim 462*efcc2a30SJung-uk Kim Status = WalkState->AscendingCallback (WalkState); 463*efcc2a30SJung-uk Kim Status = AcpiPsNextParseState (WalkState, *Op, Status); 464*efcc2a30SJung-uk Kim 465*efcc2a30SJung-uk Kim Status2 = AcpiPsCompleteThisOp (WalkState, *Op); 466*efcc2a30SJung-uk Kim if (ACPI_FAILURE (Status2)) 467*efcc2a30SJung-uk Kim { 468*efcc2a30SJung-uk Kim return_ACPI_STATUS (Status2); 469*efcc2a30SJung-uk Kim } 470*efcc2a30SJung-uk Kim } 471*efcc2a30SJung-uk Kim 472*efcc2a30SJung-uk Kim Status = AE_OK; 473*efcc2a30SJung-uk Kim break; 474*efcc2a30SJung-uk Kim 475*efcc2a30SJung-uk Kim 476*efcc2a30SJung-uk Kim case AE_CTRL_BREAK: 477*efcc2a30SJung-uk Kim case AE_CTRL_CONTINUE: 478*efcc2a30SJung-uk Kim 479*efcc2a30SJung-uk Kim /* Pop off scopes until we find the While */ 480*efcc2a30SJung-uk Kim 481*efcc2a30SJung-uk Kim while (!(*Op) || ((*Op)->Common.AmlOpcode != AML_WHILE_OP)) 482*efcc2a30SJung-uk Kim { 483*efcc2a30SJung-uk Kim AcpiPsPopScope (&(WalkState->ParserState), Op, 484*efcc2a30SJung-uk Kim &WalkState->ArgTypes, &WalkState->ArgCount); 485*efcc2a30SJung-uk Kim } 486*efcc2a30SJung-uk Kim 487*efcc2a30SJung-uk Kim /* Close this iteration of the While loop */ 488*efcc2a30SJung-uk Kim 489*efcc2a30SJung-uk Kim WalkState->Op = *Op; 490*efcc2a30SJung-uk Kim WalkState->OpInfo = AcpiPsGetOpcodeInfo ((*Op)->Common.AmlOpcode); 491*efcc2a30SJung-uk Kim WalkState->Opcode = (*Op)->Common.AmlOpcode; 492*efcc2a30SJung-uk Kim 493*efcc2a30SJung-uk Kim Status = WalkState->AscendingCallback (WalkState); 494*efcc2a30SJung-uk Kim Status = AcpiPsNextParseState (WalkState, *Op, Status); 495*efcc2a30SJung-uk Kim 496*efcc2a30SJung-uk Kim Status2 = AcpiPsCompleteThisOp (WalkState, *Op); 497*efcc2a30SJung-uk Kim if (ACPI_FAILURE (Status2)) 498*efcc2a30SJung-uk Kim { 499*efcc2a30SJung-uk Kim return_ACPI_STATUS (Status2); 500*efcc2a30SJung-uk Kim } 501*efcc2a30SJung-uk Kim 502*efcc2a30SJung-uk Kim Status = AE_OK; 503*efcc2a30SJung-uk Kim break; 504*efcc2a30SJung-uk Kim 505*efcc2a30SJung-uk Kim 506*efcc2a30SJung-uk Kim case AE_CTRL_TERMINATE: 507*efcc2a30SJung-uk Kim 508*efcc2a30SJung-uk Kim /* Clean up */ 509*efcc2a30SJung-uk Kim do 510*efcc2a30SJung-uk Kim { 511*efcc2a30SJung-uk Kim if (*Op) 512*efcc2a30SJung-uk Kim { 513*efcc2a30SJung-uk Kim Status2 = AcpiPsCompleteThisOp (WalkState, *Op); 514*efcc2a30SJung-uk Kim if (ACPI_FAILURE (Status2)) 515*efcc2a30SJung-uk Kim { 516*efcc2a30SJung-uk Kim return_ACPI_STATUS (Status2); 517*efcc2a30SJung-uk Kim } 518*efcc2a30SJung-uk Kim 519*efcc2a30SJung-uk Kim AcpiUtDeleteGenericState ( 520*efcc2a30SJung-uk Kim AcpiUtPopGenericState (&WalkState->ControlState)); 521*efcc2a30SJung-uk Kim } 522*efcc2a30SJung-uk Kim 523*efcc2a30SJung-uk Kim AcpiPsPopScope (&(WalkState->ParserState), Op, 524*efcc2a30SJung-uk Kim &WalkState->ArgTypes, &WalkState->ArgCount); 525*efcc2a30SJung-uk Kim 526*efcc2a30SJung-uk Kim } while (*Op); 527*efcc2a30SJung-uk Kim 528*efcc2a30SJung-uk Kim return_ACPI_STATUS (AE_OK); 529*efcc2a30SJung-uk Kim 530*efcc2a30SJung-uk Kim 531*efcc2a30SJung-uk Kim default: /* All other non-AE_OK status */ 532*efcc2a30SJung-uk Kim 533*efcc2a30SJung-uk Kim do 534*efcc2a30SJung-uk Kim { 535*efcc2a30SJung-uk Kim if (*Op) 536*efcc2a30SJung-uk Kim { 537*efcc2a30SJung-uk Kim Status2 = AcpiPsCompleteThisOp (WalkState, *Op); 538*efcc2a30SJung-uk Kim if (ACPI_FAILURE (Status2)) 539*efcc2a30SJung-uk Kim { 540*efcc2a30SJung-uk Kim return_ACPI_STATUS (Status2); 541*efcc2a30SJung-uk Kim } 542*efcc2a30SJung-uk Kim } 543*efcc2a30SJung-uk Kim 544*efcc2a30SJung-uk Kim AcpiPsPopScope (&(WalkState->ParserState), Op, 545*efcc2a30SJung-uk Kim &WalkState->ArgTypes, &WalkState->ArgCount); 546*efcc2a30SJung-uk Kim 547*efcc2a30SJung-uk Kim } while (*Op); 548*efcc2a30SJung-uk Kim 549*efcc2a30SJung-uk Kim 550*efcc2a30SJung-uk Kim #if 0 551*efcc2a30SJung-uk Kim /* 552*efcc2a30SJung-uk Kim * TBD: Cleanup parse ops on error 553*efcc2a30SJung-uk Kim */ 554*efcc2a30SJung-uk Kim if (*Op == NULL) 555*efcc2a30SJung-uk Kim { 556*efcc2a30SJung-uk Kim AcpiPsPopScope (ParserState, Op, 557*efcc2a30SJung-uk Kim &WalkState->ArgTypes, &WalkState->ArgCount); 558*efcc2a30SJung-uk Kim } 559*efcc2a30SJung-uk Kim #endif 560*efcc2a30SJung-uk Kim WalkState->PrevOp = NULL; 561*efcc2a30SJung-uk Kim WalkState->PrevArgTypes = WalkState->ArgTypes; 562*efcc2a30SJung-uk Kim return_ACPI_STATUS (Status); 563*efcc2a30SJung-uk Kim } 564*efcc2a30SJung-uk Kim 565*efcc2a30SJung-uk Kim /* This scope complete? */ 566*efcc2a30SJung-uk Kim 567*efcc2a30SJung-uk Kim if (AcpiPsHasCompletedScope (&(WalkState->ParserState))) 568*efcc2a30SJung-uk Kim { 569*efcc2a30SJung-uk Kim AcpiPsPopScope (&(WalkState->ParserState), Op, 570*efcc2a30SJung-uk Kim &WalkState->ArgTypes, &WalkState->ArgCount); 571*efcc2a30SJung-uk Kim ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", *Op)); 572*efcc2a30SJung-uk Kim } 573*efcc2a30SJung-uk Kim else 574*efcc2a30SJung-uk Kim { 575*efcc2a30SJung-uk Kim *Op = NULL; 576*efcc2a30SJung-uk Kim } 577*efcc2a30SJung-uk Kim 578*efcc2a30SJung-uk Kim return_ACPI_STATUS (AE_OK); 579*efcc2a30SJung-uk Kim } 580*efcc2a30SJung-uk Kim 581*efcc2a30SJung-uk Kim 582*efcc2a30SJung-uk Kim /******************************************************************************* 583*efcc2a30SJung-uk Kim * 584*efcc2a30SJung-uk Kim * FUNCTION: AcpiPsCompleteFinalOp 585*efcc2a30SJung-uk Kim * 586*efcc2a30SJung-uk Kim * PARAMETERS: WalkState - Current state 587*efcc2a30SJung-uk Kim * Op - Current Op 588*efcc2a30SJung-uk Kim * Status - Current parse status before complete last 589*efcc2a30SJung-uk Kim * Op 590*efcc2a30SJung-uk Kim * 591*efcc2a30SJung-uk Kim * RETURN: Status 592*efcc2a30SJung-uk Kim * 593*efcc2a30SJung-uk Kim * DESCRIPTION: Complete last Op. 594*efcc2a30SJung-uk Kim * 595*efcc2a30SJung-uk Kim ******************************************************************************/ 596*efcc2a30SJung-uk Kim 597*efcc2a30SJung-uk Kim ACPI_STATUS 598*efcc2a30SJung-uk Kim AcpiPsCompleteFinalOp ( 599*efcc2a30SJung-uk Kim ACPI_WALK_STATE *WalkState, 600*efcc2a30SJung-uk Kim ACPI_PARSE_OBJECT *Op, 601*efcc2a30SJung-uk Kim ACPI_STATUS Status) 602*efcc2a30SJung-uk Kim { 603*efcc2a30SJung-uk Kim ACPI_STATUS Status2; 604*efcc2a30SJung-uk Kim 605*efcc2a30SJung-uk Kim 606*efcc2a30SJung-uk Kim ACPI_FUNCTION_TRACE_PTR (PsCompleteFinalOp, WalkState); 607*efcc2a30SJung-uk Kim 608*efcc2a30SJung-uk Kim 609*efcc2a30SJung-uk Kim /* 610*efcc2a30SJung-uk Kim * Complete the last Op (if not completed), and clear the scope stack. 611*efcc2a30SJung-uk Kim * It is easily possible to end an AML "package" with an unbounded number 612*efcc2a30SJung-uk Kim * of open scopes (such as when several ASL blocks are closed with 613*efcc2a30SJung-uk Kim * sequential closing braces). We want to terminate each one cleanly. 614*efcc2a30SJung-uk Kim */ 615*efcc2a30SJung-uk Kim ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "AML package complete at Op %p\n", Op)); 616*efcc2a30SJung-uk Kim do 617*efcc2a30SJung-uk Kim { 618*efcc2a30SJung-uk Kim if (Op) 619*efcc2a30SJung-uk Kim { 620*efcc2a30SJung-uk Kim if (WalkState->AscendingCallback != NULL) 621*efcc2a30SJung-uk Kim { 622*efcc2a30SJung-uk Kim WalkState->Op = Op; 623*efcc2a30SJung-uk Kim WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 624*efcc2a30SJung-uk Kim WalkState->Opcode = Op->Common.AmlOpcode; 625*efcc2a30SJung-uk Kim 626*efcc2a30SJung-uk Kim Status = WalkState->AscendingCallback (WalkState); 627*efcc2a30SJung-uk Kim Status = AcpiPsNextParseState (WalkState, Op, Status); 628*efcc2a30SJung-uk Kim if (Status == AE_CTRL_PENDING) 629*efcc2a30SJung-uk Kim { 630*efcc2a30SJung-uk Kim Status = AcpiPsCompleteOp (WalkState, &Op, AE_OK); 631*efcc2a30SJung-uk Kim if (ACPI_FAILURE (Status)) 632*efcc2a30SJung-uk Kim { 633*efcc2a30SJung-uk Kim return_ACPI_STATUS (Status); 634*efcc2a30SJung-uk Kim } 635*efcc2a30SJung-uk Kim } 636*efcc2a30SJung-uk Kim 637*efcc2a30SJung-uk Kim if (Status == AE_CTRL_TERMINATE) 638*efcc2a30SJung-uk Kim { 639*efcc2a30SJung-uk Kim Status = AE_OK; 640*efcc2a30SJung-uk Kim 641*efcc2a30SJung-uk Kim /* Clean up */ 642*efcc2a30SJung-uk Kim do 643*efcc2a30SJung-uk Kim { 644*efcc2a30SJung-uk Kim if (Op) 645*efcc2a30SJung-uk Kim { 646*efcc2a30SJung-uk Kim Status2 = AcpiPsCompleteThisOp (WalkState, Op); 647*efcc2a30SJung-uk Kim if (ACPI_FAILURE (Status2)) 648*efcc2a30SJung-uk Kim { 649*efcc2a30SJung-uk Kim return_ACPI_STATUS (Status2); 650*efcc2a30SJung-uk Kim } 651*efcc2a30SJung-uk Kim } 652*efcc2a30SJung-uk Kim 653*efcc2a30SJung-uk Kim AcpiPsPopScope (&(WalkState->ParserState), &Op, 654*efcc2a30SJung-uk Kim &WalkState->ArgTypes, &WalkState->ArgCount); 655*efcc2a30SJung-uk Kim 656*efcc2a30SJung-uk Kim } while (Op); 657*efcc2a30SJung-uk Kim 658*efcc2a30SJung-uk Kim return_ACPI_STATUS (Status); 659*efcc2a30SJung-uk Kim } 660*efcc2a30SJung-uk Kim 661*efcc2a30SJung-uk Kim else if (ACPI_FAILURE (Status)) 662*efcc2a30SJung-uk Kim { 663*efcc2a30SJung-uk Kim /* First error is most important */ 664*efcc2a30SJung-uk Kim 665*efcc2a30SJung-uk Kim (void) AcpiPsCompleteThisOp (WalkState, Op); 666*efcc2a30SJung-uk Kim return_ACPI_STATUS (Status); 667*efcc2a30SJung-uk Kim } 668*efcc2a30SJung-uk Kim } 669*efcc2a30SJung-uk Kim 670*efcc2a30SJung-uk Kim Status2 = AcpiPsCompleteThisOp (WalkState, Op); 671*efcc2a30SJung-uk Kim if (ACPI_FAILURE (Status2)) 672*efcc2a30SJung-uk Kim { 673*efcc2a30SJung-uk Kim return_ACPI_STATUS (Status2); 674*efcc2a30SJung-uk Kim } 675*efcc2a30SJung-uk Kim } 676*efcc2a30SJung-uk Kim 677*efcc2a30SJung-uk Kim AcpiPsPopScope (&(WalkState->ParserState), &Op, &WalkState->ArgTypes, 678*efcc2a30SJung-uk Kim &WalkState->ArgCount); 679*efcc2a30SJung-uk Kim 680*efcc2a30SJung-uk Kim } while (Op); 681*efcc2a30SJung-uk Kim 682*efcc2a30SJung-uk Kim return_ACPI_STATUS (Status); 683*efcc2a30SJung-uk Kim } 684