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