psobject.c revision 250838
1244971Sjkim/****************************************************************************** 2244971Sjkim * 3244971Sjkim * Module Name: psobject - Support for parse objects 4244971Sjkim * 5244971Sjkim *****************************************************************************/ 6244971Sjkim 7244971Sjkim/* 8245582Sjkim * Copyright (C) 2000 - 2013, Intel Corp. 9244971Sjkim * All rights reserved. 10244971Sjkim * 11244971Sjkim * Redistribution and use in source and binary forms, with or without 12244971Sjkim * modification, are permitted provided that the following conditions 13244971Sjkim * are met: 14244971Sjkim * 1. Redistributions of source code must retain the above copyright 15244971Sjkim * notice, this list of conditions, and the following disclaimer, 16244971Sjkim * without modification. 17244971Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18244971Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 19244971Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 20244971Sjkim * including a substantially similar Disclaimer requirement for further 21244971Sjkim * binary redistribution. 22244971Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 23244971Sjkim * of any contributors may be used to endorse or promote products derived 24244971Sjkim * from this software without specific prior written permission. 25244971Sjkim * 26244971Sjkim * Alternatively, this software may be distributed under the terms of the 27244971Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 28244971Sjkim * Software Foundation. 29244971Sjkim * 30244971Sjkim * NO WARRANTY 31244971Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32244971Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33244971Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34244971Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35244971Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36244971Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37244971Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38244971Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39244971Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40244971Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41244971Sjkim * POSSIBILITY OF SUCH DAMAGES. 42244971Sjkim */ 43244971Sjkim 44244971Sjkim 45245582Sjkim#include <contrib/dev/acpica/include/acpi.h> 46245582Sjkim#include <contrib/dev/acpica/include/accommon.h> 47245582Sjkim#include <contrib/dev/acpica/include/acparser.h> 48245582Sjkim#include <contrib/dev/acpica/include/amlcode.h> 49244971Sjkim 50244971Sjkim#define _COMPONENT ACPI_PARSER 51244971Sjkim ACPI_MODULE_NAME ("psobject") 52244971Sjkim 53244971Sjkim 54244971Sjkim/* Local prototypes */ 55244971Sjkim 56244971Sjkimstatic ACPI_STATUS 57244971SjkimAcpiPsGetAmlOpcode ( 58244971Sjkim ACPI_WALK_STATE *WalkState); 59244971Sjkim 60244971Sjkim 61244971Sjkim/******************************************************************************* 62244971Sjkim * 63244971Sjkim * FUNCTION: AcpiPsGetAmlOpcode 64244971Sjkim * 65244971Sjkim * PARAMETERS: WalkState - Current state 66244971Sjkim * 67244971Sjkim * RETURN: Status 68244971Sjkim * 69244971Sjkim * DESCRIPTION: Extract the next AML opcode from the input stream. 70244971Sjkim * 71244971Sjkim ******************************************************************************/ 72244971Sjkim 73244971Sjkimstatic ACPI_STATUS 74244971SjkimAcpiPsGetAmlOpcode ( 75244971Sjkim ACPI_WALK_STATE *WalkState) 76244971Sjkim{ 77244971Sjkim 78244971Sjkim ACPI_FUNCTION_TRACE_PTR (PsGetAmlOpcode, WalkState); 79244971Sjkim 80244971Sjkim 81244971Sjkim WalkState->AmlOffset = (UINT32) ACPI_PTR_DIFF (WalkState->ParserState.Aml, 82244971Sjkim WalkState->ParserState.AmlStart); 83244971Sjkim WalkState->Opcode = AcpiPsPeekOpcode (&(WalkState->ParserState)); 84244971Sjkim 85244971Sjkim /* 86244971Sjkim * First cut to determine what we have found: 87244971Sjkim * 1) A valid AML opcode 88244971Sjkim * 2) A name string 89244971Sjkim * 3) An unknown/invalid opcode 90244971Sjkim */ 91244971Sjkim WalkState->OpInfo = AcpiPsGetOpcodeInfo (WalkState->Opcode); 92244971Sjkim 93244971Sjkim switch (WalkState->OpInfo->Class) 94244971Sjkim { 95244971Sjkim case AML_CLASS_ASCII: 96244971Sjkim case AML_CLASS_PREFIX: 97244971Sjkim /* 98244971Sjkim * Starts with a valid prefix or ASCII char, this is a name 99244971Sjkim * string. Convert the bare name string to a namepath. 100244971Sjkim */ 101244971Sjkim WalkState->Opcode = AML_INT_NAMEPATH_OP; 102244971Sjkim WalkState->ArgTypes = ARGP_NAMESTRING; 103244971Sjkim break; 104244971Sjkim 105244971Sjkim case AML_CLASS_UNKNOWN: 106244971Sjkim 107244971Sjkim /* The opcode is unrecognized. Complain and skip unknown opcodes */ 108244971Sjkim 109244971Sjkim if (WalkState->PassNumber == 2) 110244971Sjkim { 111244971Sjkim ACPI_ERROR ((AE_INFO, 112244971Sjkim "Unknown opcode 0x%.2X at table offset 0x%.4X, ignoring", 113244971Sjkim WalkState->Opcode, 114244971Sjkim (UINT32) (WalkState->AmlOffset + sizeof (ACPI_TABLE_HEADER)))); 115244971Sjkim 116244971Sjkim ACPI_DUMP_BUFFER ((WalkState->ParserState.Aml - 16), 48); 117244971Sjkim 118244971Sjkim#ifdef ACPI_ASL_COMPILER 119244971Sjkim /* 120244971Sjkim * This is executed for the disassembler only. Output goes 121244971Sjkim * to the disassembled ASL output file. 122244971Sjkim */ 123244971Sjkim AcpiOsPrintf ( 124244971Sjkim "/*\nError: Unknown opcode 0x%.2X at table offset 0x%.4X, context:\n", 125244971Sjkim WalkState->Opcode, 126244971Sjkim (UINT32) (WalkState->AmlOffset + sizeof (ACPI_TABLE_HEADER))); 127244971Sjkim 128244971Sjkim /* Dump the context surrounding the invalid opcode */ 129244971Sjkim 130244971Sjkim AcpiUtDumpBuffer (((UINT8 *) WalkState->ParserState.Aml - 16), 131244971Sjkim 48, DB_BYTE_DISPLAY, 132244971Sjkim (WalkState->AmlOffset + sizeof (ACPI_TABLE_HEADER) - 16)); 133244971Sjkim AcpiOsPrintf (" */\n"); 134244971Sjkim#endif 135244971Sjkim } 136244971Sjkim 137244971Sjkim /* Increment past one-byte or two-byte opcode */ 138244971Sjkim 139244971Sjkim WalkState->ParserState.Aml++; 140244971Sjkim if (WalkState->Opcode > 0xFF) /* Can only happen if first byte is 0x5B */ 141244971Sjkim { 142244971Sjkim WalkState->ParserState.Aml++; 143244971Sjkim } 144244971Sjkim 145244971Sjkim return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE); 146244971Sjkim 147244971Sjkim default: 148244971Sjkim 149244971Sjkim /* Found opcode info, this is a normal opcode */ 150244971Sjkim 151244971Sjkim WalkState->ParserState.Aml += AcpiPsGetOpcodeSize (WalkState->Opcode); 152244971Sjkim WalkState->ArgTypes = WalkState->OpInfo->ParseArgs; 153244971Sjkim break; 154244971Sjkim } 155244971Sjkim 156244971Sjkim return_ACPI_STATUS (AE_OK); 157244971Sjkim} 158244971Sjkim 159244971Sjkim 160244971Sjkim/******************************************************************************* 161244971Sjkim * 162244971Sjkim * FUNCTION: AcpiPsBuildNamedOp 163244971Sjkim * 164244971Sjkim * PARAMETERS: WalkState - Current state 165244971Sjkim * AmlOpStart - Begin of named Op in AML 166244971Sjkim * UnnamedOp - Early Op (not a named Op) 167244971Sjkim * Op - Returned Op 168244971Sjkim * 169244971Sjkim * RETURN: Status 170244971Sjkim * 171244971Sjkim * DESCRIPTION: Parse a named Op 172244971Sjkim * 173244971Sjkim ******************************************************************************/ 174244971Sjkim 175244971SjkimACPI_STATUS 176244971SjkimAcpiPsBuildNamedOp ( 177244971Sjkim ACPI_WALK_STATE *WalkState, 178244971Sjkim UINT8 *AmlOpStart, 179244971Sjkim ACPI_PARSE_OBJECT *UnnamedOp, 180244971Sjkim ACPI_PARSE_OBJECT **Op) 181244971Sjkim{ 182244971Sjkim ACPI_STATUS Status = AE_OK; 183244971Sjkim ACPI_PARSE_OBJECT *Arg = NULL; 184244971Sjkim 185244971Sjkim 186244971Sjkim ACPI_FUNCTION_TRACE_PTR (PsBuildNamedOp, WalkState); 187244971Sjkim 188244971Sjkim 189244971Sjkim UnnamedOp->Common.Value.Arg = NULL; 190244971Sjkim UnnamedOp->Common.ArgListLength = 0; 191244971Sjkim UnnamedOp->Common.AmlOpcode = WalkState->Opcode; 192244971Sjkim 193244971Sjkim /* 194244971Sjkim * Get and append arguments until we find the node that contains 195244971Sjkim * the name (the type ARGP_NAME). 196244971Sjkim */ 197244971Sjkim while (GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) && 198244971Sjkim (GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) != ARGP_NAME)) 199244971Sjkim { 200244971Sjkim Status = AcpiPsGetNextArg (WalkState, &(WalkState->ParserState), 201244971Sjkim GET_CURRENT_ARG_TYPE (WalkState->ArgTypes), &Arg); 202244971Sjkim if (ACPI_FAILURE (Status)) 203244971Sjkim { 204244971Sjkim return_ACPI_STATUS (Status); 205244971Sjkim } 206244971Sjkim 207244971Sjkim AcpiPsAppendArg (UnnamedOp, Arg); 208244971Sjkim INCREMENT_ARG_LIST (WalkState->ArgTypes); 209244971Sjkim } 210244971Sjkim 211244971Sjkim /* 212244971Sjkim * Make sure that we found a NAME and didn't run out of arguments 213244971Sjkim */ 214244971Sjkim if (!GET_CURRENT_ARG_TYPE (WalkState->ArgTypes)) 215244971Sjkim { 216244971Sjkim return_ACPI_STATUS (AE_AML_NO_OPERAND); 217244971Sjkim } 218244971Sjkim 219244971Sjkim /* We know that this arg is a name, move to next arg */ 220244971Sjkim 221244971Sjkim INCREMENT_ARG_LIST (WalkState->ArgTypes); 222244971Sjkim 223244971Sjkim /* 224244971Sjkim * Find the object. This will either insert the object into 225244971Sjkim * the namespace or simply look it up 226244971Sjkim */ 227244971Sjkim WalkState->Op = NULL; 228244971Sjkim 229244971Sjkim Status = WalkState->DescendingCallback (WalkState, Op); 230244971Sjkim if (ACPI_FAILURE (Status)) 231244971Sjkim { 232244971Sjkim ACPI_EXCEPTION ((AE_INFO, Status, "During name lookup/catalog")); 233244971Sjkim return_ACPI_STATUS (Status); 234244971Sjkim } 235244971Sjkim 236244971Sjkim if (!*Op) 237244971Sjkim { 238244971Sjkim return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE); 239244971Sjkim } 240244971Sjkim 241244971Sjkim Status = AcpiPsNextParseState (WalkState, *Op, Status); 242244971Sjkim if (ACPI_FAILURE (Status)) 243244971Sjkim { 244244971Sjkim if (Status == AE_CTRL_PENDING) 245244971Sjkim { 246244971Sjkim return_ACPI_STATUS (AE_CTRL_PARSE_PENDING); 247244971Sjkim } 248244971Sjkim return_ACPI_STATUS (Status); 249244971Sjkim } 250244971Sjkim 251244971Sjkim AcpiPsAppendArg (*Op, UnnamedOp->Common.Value.Arg); 252244971Sjkim 253244971Sjkim if ((*Op)->Common.AmlOpcode == AML_REGION_OP || 254244971Sjkim (*Op)->Common.AmlOpcode == AML_DATA_REGION_OP) 255244971Sjkim { 256244971Sjkim /* 257244971Sjkim * Defer final parsing of an OperationRegion body, because we don't 258244971Sjkim * have enough info in the first pass to parse it correctly (i.e., 259244971Sjkim * there may be method calls within the TermArg elements of the body.) 260244971Sjkim * 261244971Sjkim * However, we must continue parsing because the opregion is not a 262244971Sjkim * standalone package -- we don't know where the end is at this point. 263244971Sjkim * 264244971Sjkim * (Length is unknown until parse of the body complete) 265244971Sjkim */ 266244971Sjkim (*Op)->Named.Data = AmlOpStart; 267244971Sjkim (*Op)->Named.Length = 0; 268244971Sjkim } 269244971Sjkim 270244971Sjkim return_ACPI_STATUS (AE_OK); 271244971Sjkim} 272244971Sjkim 273244971Sjkim 274244971Sjkim/******************************************************************************* 275244971Sjkim * 276244971Sjkim * FUNCTION: AcpiPsCreateOp 277244971Sjkim * 278244971Sjkim * PARAMETERS: WalkState - Current state 279244971Sjkim * AmlOpStart - Op start in AML 280244971Sjkim * NewOp - Returned Op 281244971Sjkim * 282244971Sjkim * RETURN: Status 283244971Sjkim * 284244971Sjkim * DESCRIPTION: Get Op from AML 285244971Sjkim * 286244971Sjkim ******************************************************************************/ 287244971Sjkim 288244971SjkimACPI_STATUS 289244971SjkimAcpiPsCreateOp ( 290244971Sjkim ACPI_WALK_STATE *WalkState, 291244971Sjkim UINT8 *AmlOpStart, 292244971Sjkim ACPI_PARSE_OBJECT **NewOp) 293244971Sjkim{ 294244971Sjkim ACPI_STATUS Status = AE_OK; 295244971Sjkim ACPI_PARSE_OBJECT *Op; 296244971Sjkim ACPI_PARSE_OBJECT *NamedOp = NULL; 297244971Sjkim ACPI_PARSE_OBJECT *ParentScope; 298244971Sjkim UINT8 ArgumentCount; 299244971Sjkim const ACPI_OPCODE_INFO *OpInfo; 300244971Sjkim 301244971Sjkim 302244971Sjkim ACPI_FUNCTION_TRACE_PTR (PsCreateOp, WalkState); 303244971Sjkim 304244971Sjkim 305244971Sjkim Status = AcpiPsGetAmlOpcode (WalkState); 306244971Sjkim if (Status == AE_CTRL_PARSE_CONTINUE) 307244971Sjkim { 308244971Sjkim return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE); 309244971Sjkim } 310244971Sjkim 311244971Sjkim /* Create Op structure and append to parent's argument list */ 312244971Sjkim 313244971Sjkim WalkState->OpInfo = AcpiPsGetOpcodeInfo (WalkState->Opcode); 314244971Sjkim Op = AcpiPsAllocOp (WalkState->Opcode); 315244971Sjkim if (!Op) 316244971Sjkim { 317244971Sjkim return_ACPI_STATUS (AE_NO_MEMORY); 318244971Sjkim } 319244971Sjkim 320244971Sjkim if (WalkState->OpInfo->Flags & AML_NAMED) 321244971Sjkim { 322244971Sjkim Status = AcpiPsBuildNamedOp (WalkState, AmlOpStart, Op, &NamedOp); 323244971Sjkim AcpiPsFreeOp (Op); 324244971Sjkim if (ACPI_FAILURE (Status)) 325244971Sjkim { 326244971Sjkim return_ACPI_STATUS (Status); 327244971Sjkim } 328244971Sjkim 329244971Sjkim *NewOp = NamedOp; 330244971Sjkim return_ACPI_STATUS (AE_OK); 331244971Sjkim } 332244971Sjkim 333244971Sjkim /* Not a named opcode, just allocate Op and append to parent */ 334244971Sjkim 335244971Sjkim if (WalkState->OpInfo->Flags & AML_CREATE) 336244971Sjkim { 337244971Sjkim /* 338244971Sjkim * Backup to beginning of CreateXXXfield declaration 339244971Sjkim * BodyLength is unknown until we parse the body 340244971Sjkim */ 341244971Sjkim Op->Named.Data = AmlOpStart; 342244971Sjkim Op->Named.Length = 0; 343244971Sjkim } 344244971Sjkim 345244971Sjkim if (WalkState->Opcode == AML_BANK_FIELD_OP) 346244971Sjkim { 347244971Sjkim /* 348244971Sjkim * Backup to beginning of BankField declaration 349244971Sjkim * BodyLength is unknown until we parse the body 350244971Sjkim */ 351244971Sjkim Op->Named.Data = AmlOpStart; 352244971Sjkim Op->Named.Length = 0; 353244971Sjkim } 354244971Sjkim 355244971Sjkim ParentScope = AcpiPsGetParentScope (&(WalkState->ParserState)); 356244971Sjkim AcpiPsAppendArg (ParentScope, Op); 357244971Sjkim 358244971Sjkim if (ParentScope) 359244971Sjkim { 360244971Sjkim OpInfo = AcpiPsGetOpcodeInfo (ParentScope->Common.AmlOpcode); 361244971Sjkim if (OpInfo->Flags & AML_HAS_TARGET) 362244971Sjkim { 363244971Sjkim ArgumentCount = AcpiPsGetArgumentCount (OpInfo->Type); 364244971Sjkim if (ParentScope->Common.ArgListLength > ArgumentCount) 365244971Sjkim { 366244971Sjkim Op->Common.Flags |= ACPI_PARSEOP_TARGET; 367244971Sjkim } 368244971Sjkim } 369244971Sjkim else if (ParentScope->Common.AmlOpcode == AML_INCREMENT_OP) 370244971Sjkim { 371244971Sjkim Op->Common.Flags |= ACPI_PARSEOP_TARGET; 372244971Sjkim } 373244971Sjkim } 374244971Sjkim 375244971Sjkim if (WalkState->DescendingCallback != NULL) 376244971Sjkim { 377244971Sjkim /* 378244971Sjkim * Find the object. This will either insert the object into 379244971Sjkim * the namespace or simply look it up 380244971Sjkim */ 381244971Sjkim WalkState->Op = *NewOp = Op; 382244971Sjkim 383244971Sjkim Status = WalkState->DescendingCallback (WalkState, &Op); 384244971Sjkim Status = AcpiPsNextParseState (WalkState, Op, Status); 385244971Sjkim if (Status == AE_CTRL_PENDING) 386244971Sjkim { 387244971Sjkim Status = AE_CTRL_PARSE_PENDING; 388244971Sjkim } 389244971Sjkim } 390244971Sjkim 391244971Sjkim return_ACPI_STATUS (Status); 392244971Sjkim} 393244971Sjkim 394244971Sjkim 395244971Sjkim/******************************************************************************* 396244971Sjkim * 397244971Sjkim * FUNCTION: AcpiPsCompleteOp 398244971Sjkim * 399244971Sjkim * PARAMETERS: WalkState - Current state 400244971Sjkim * Op - Returned Op 401244971Sjkim * Status - Parse status before complete Op 402244971Sjkim * 403244971Sjkim * RETURN: Status 404244971Sjkim * 405244971Sjkim * DESCRIPTION: Complete Op 406244971Sjkim * 407244971Sjkim ******************************************************************************/ 408244971Sjkim 409244971SjkimACPI_STATUS 410244971SjkimAcpiPsCompleteOp ( 411244971Sjkim ACPI_WALK_STATE *WalkState, 412244971Sjkim ACPI_PARSE_OBJECT **Op, 413244971Sjkim ACPI_STATUS Status) 414244971Sjkim{ 415244971Sjkim ACPI_STATUS Status2; 416244971Sjkim 417244971Sjkim 418244971Sjkim ACPI_FUNCTION_TRACE_PTR (PsCompleteOp, WalkState); 419244971Sjkim 420244971Sjkim 421244971Sjkim /* 422244971Sjkim * Finished one argument of the containing scope 423244971Sjkim */ 424244971Sjkim WalkState->ParserState.Scope->ParseScope.ArgCount--; 425244971Sjkim 426244971Sjkim /* Close this Op (will result in parse subtree deletion) */ 427244971Sjkim 428244971Sjkim Status2 = AcpiPsCompleteThisOp (WalkState, *Op); 429244971Sjkim if (ACPI_FAILURE (Status2)) 430244971Sjkim { 431244971Sjkim return_ACPI_STATUS (Status2); 432244971Sjkim } 433244971Sjkim 434244971Sjkim *Op = NULL; 435244971Sjkim 436244971Sjkim switch (Status) 437244971Sjkim { 438244971Sjkim case AE_OK: 439250838Sjkim 440244971Sjkim break; 441244971Sjkim 442244971Sjkim case AE_CTRL_TRANSFER: 443244971Sjkim 444244971Sjkim /* We are about to transfer to a called method */ 445244971Sjkim 446244971Sjkim WalkState->PrevOp = NULL; 447244971Sjkim WalkState->PrevArgTypes = WalkState->ArgTypes; 448244971Sjkim return_ACPI_STATUS (Status); 449244971Sjkim 450244971Sjkim case AE_CTRL_END: 451244971Sjkim 452244971Sjkim AcpiPsPopScope (&(WalkState->ParserState), Op, 453244971Sjkim &WalkState->ArgTypes, &WalkState->ArgCount); 454244971Sjkim 455244971Sjkim if (*Op) 456244971Sjkim { 457244971Sjkim WalkState->Op = *Op; 458244971Sjkim WalkState->OpInfo = AcpiPsGetOpcodeInfo ((*Op)->Common.AmlOpcode); 459244971Sjkim WalkState->Opcode = (*Op)->Common.AmlOpcode; 460244971Sjkim 461244971Sjkim Status = WalkState->AscendingCallback (WalkState); 462244971Sjkim Status = AcpiPsNextParseState (WalkState, *Op, Status); 463244971Sjkim 464244971Sjkim Status2 = AcpiPsCompleteThisOp (WalkState, *Op); 465244971Sjkim if (ACPI_FAILURE (Status2)) 466244971Sjkim { 467244971Sjkim return_ACPI_STATUS (Status2); 468244971Sjkim } 469244971Sjkim } 470244971Sjkim 471244971Sjkim Status = AE_OK; 472244971Sjkim break; 473244971Sjkim 474244971Sjkim case AE_CTRL_BREAK: 475244971Sjkim case AE_CTRL_CONTINUE: 476244971Sjkim 477244971Sjkim /* Pop off scopes until we find the While */ 478244971Sjkim 479244971Sjkim while (!(*Op) || ((*Op)->Common.AmlOpcode != AML_WHILE_OP)) 480244971Sjkim { 481244971Sjkim AcpiPsPopScope (&(WalkState->ParserState), Op, 482244971Sjkim &WalkState->ArgTypes, &WalkState->ArgCount); 483244971Sjkim } 484244971Sjkim 485244971Sjkim /* Close this iteration of the While loop */ 486244971Sjkim 487244971Sjkim WalkState->Op = *Op; 488244971Sjkim WalkState->OpInfo = AcpiPsGetOpcodeInfo ((*Op)->Common.AmlOpcode); 489244971Sjkim WalkState->Opcode = (*Op)->Common.AmlOpcode; 490244971Sjkim 491244971Sjkim Status = WalkState->AscendingCallback (WalkState); 492244971Sjkim Status = AcpiPsNextParseState (WalkState, *Op, Status); 493244971Sjkim 494244971Sjkim Status2 = AcpiPsCompleteThisOp (WalkState, *Op); 495244971Sjkim if (ACPI_FAILURE (Status2)) 496244971Sjkim { 497244971Sjkim return_ACPI_STATUS (Status2); 498244971Sjkim } 499244971Sjkim 500244971Sjkim Status = AE_OK; 501244971Sjkim break; 502244971Sjkim 503244971Sjkim case AE_CTRL_TERMINATE: 504244971Sjkim 505244971Sjkim /* Clean up */ 506244971Sjkim do 507244971Sjkim { 508244971Sjkim if (*Op) 509244971Sjkim { 510244971Sjkim Status2 = AcpiPsCompleteThisOp (WalkState, *Op); 511244971Sjkim if (ACPI_FAILURE (Status2)) 512244971Sjkim { 513244971Sjkim return_ACPI_STATUS (Status2); 514244971Sjkim } 515244971Sjkim 516244971Sjkim AcpiUtDeleteGenericState ( 517244971Sjkim AcpiUtPopGenericState (&WalkState->ControlState)); 518244971Sjkim } 519244971Sjkim 520244971Sjkim AcpiPsPopScope (&(WalkState->ParserState), Op, 521244971Sjkim &WalkState->ArgTypes, &WalkState->ArgCount); 522244971Sjkim 523244971Sjkim } while (*Op); 524244971Sjkim 525244971Sjkim return_ACPI_STATUS (AE_OK); 526244971Sjkim 527244971Sjkim default: /* All other non-AE_OK status */ 528244971Sjkim 529244971Sjkim do 530244971Sjkim { 531244971Sjkim if (*Op) 532244971Sjkim { 533244971Sjkim Status2 = AcpiPsCompleteThisOp (WalkState, *Op); 534244971Sjkim if (ACPI_FAILURE (Status2)) 535244971Sjkim { 536244971Sjkim return_ACPI_STATUS (Status2); 537244971Sjkim } 538244971Sjkim } 539244971Sjkim 540244971Sjkim AcpiPsPopScope (&(WalkState->ParserState), Op, 541244971Sjkim &WalkState->ArgTypes, &WalkState->ArgCount); 542244971Sjkim 543244971Sjkim } while (*Op); 544244971Sjkim 545244971Sjkim 546244971Sjkim#if 0 547244971Sjkim /* 548244971Sjkim * TBD: Cleanup parse ops on error 549244971Sjkim */ 550244971Sjkim if (*Op == NULL) 551244971Sjkim { 552244971Sjkim AcpiPsPopScope (ParserState, Op, 553244971Sjkim &WalkState->ArgTypes, &WalkState->ArgCount); 554244971Sjkim } 555244971Sjkim#endif 556244971Sjkim WalkState->PrevOp = NULL; 557244971Sjkim WalkState->PrevArgTypes = WalkState->ArgTypes; 558244971Sjkim return_ACPI_STATUS (Status); 559244971Sjkim } 560244971Sjkim 561244971Sjkim /* This scope complete? */ 562244971Sjkim 563244971Sjkim if (AcpiPsHasCompletedScope (&(WalkState->ParserState))) 564244971Sjkim { 565244971Sjkim AcpiPsPopScope (&(WalkState->ParserState), Op, 566244971Sjkim &WalkState->ArgTypes, &WalkState->ArgCount); 567244971Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", *Op)); 568244971Sjkim } 569244971Sjkim else 570244971Sjkim { 571244971Sjkim *Op = NULL; 572244971Sjkim } 573244971Sjkim 574244971Sjkim return_ACPI_STATUS (AE_OK); 575244971Sjkim} 576244971Sjkim 577244971Sjkim 578244971Sjkim/******************************************************************************* 579244971Sjkim * 580244971Sjkim * FUNCTION: AcpiPsCompleteFinalOp 581244971Sjkim * 582244971Sjkim * PARAMETERS: WalkState - Current state 583244971Sjkim * Op - Current Op 584244971Sjkim * Status - Current parse status before complete last 585244971Sjkim * Op 586244971Sjkim * 587244971Sjkim * RETURN: Status 588244971Sjkim * 589244971Sjkim * DESCRIPTION: Complete last Op. 590244971Sjkim * 591244971Sjkim ******************************************************************************/ 592244971Sjkim 593244971SjkimACPI_STATUS 594244971SjkimAcpiPsCompleteFinalOp ( 595244971Sjkim ACPI_WALK_STATE *WalkState, 596244971Sjkim ACPI_PARSE_OBJECT *Op, 597244971Sjkim ACPI_STATUS Status) 598244971Sjkim{ 599244971Sjkim ACPI_STATUS Status2; 600244971Sjkim 601244971Sjkim 602244971Sjkim ACPI_FUNCTION_TRACE_PTR (PsCompleteFinalOp, WalkState); 603244971Sjkim 604244971Sjkim 605244971Sjkim /* 606244971Sjkim * Complete the last Op (if not completed), and clear the scope stack. 607244971Sjkim * It is easily possible to end an AML "package" with an unbounded number 608244971Sjkim * of open scopes (such as when several ASL blocks are closed with 609244971Sjkim * sequential closing braces). We want to terminate each one cleanly. 610244971Sjkim */ 611244971Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "AML package complete at Op %p\n", Op)); 612244971Sjkim do 613244971Sjkim { 614244971Sjkim if (Op) 615244971Sjkim { 616244971Sjkim if (WalkState->AscendingCallback != NULL) 617244971Sjkim { 618244971Sjkim WalkState->Op = Op; 619244971Sjkim WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 620244971Sjkim WalkState->Opcode = Op->Common.AmlOpcode; 621244971Sjkim 622244971Sjkim Status = WalkState->AscendingCallback (WalkState); 623244971Sjkim Status = AcpiPsNextParseState (WalkState, Op, Status); 624244971Sjkim if (Status == AE_CTRL_PENDING) 625244971Sjkim { 626244971Sjkim Status = AcpiPsCompleteOp (WalkState, &Op, AE_OK); 627244971Sjkim if (ACPI_FAILURE (Status)) 628244971Sjkim { 629244971Sjkim return_ACPI_STATUS (Status); 630244971Sjkim } 631244971Sjkim } 632244971Sjkim 633244971Sjkim if (Status == AE_CTRL_TERMINATE) 634244971Sjkim { 635244971Sjkim Status = AE_OK; 636244971Sjkim 637244971Sjkim /* Clean up */ 638244971Sjkim do 639244971Sjkim { 640244971Sjkim if (Op) 641244971Sjkim { 642244971Sjkim Status2 = AcpiPsCompleteThisOp (WalkState, Op); 643244971Sjkim if (ACPI_FAILURE (Status2)) 644244971Sjkim { 645244971Sjkim return_ACPI_STATUS (Status2); 646244971Sjkim } 647244971Sjkim } 648244971Sjkim 649244971Sjkim AcpiPsPopScope (&(WalkState->ParserState), &Op, 650244971Sjkim &WalkState->ArgTypes, &WalkState->ArgCount); 651244971Sjkim 652244971Sjkim } while (Op); 653244971Sjkim 654244971Sjkim return_ACPI_STATUS (Status); 655244971Sjkim } 656244971Sjkim 657244971Sjkim else if (ACPI_FAILURE (Status)) 658244971Sjkim { 659244971Sjkim /* First error is most important */ 660244971Sjkim 661244971Sjkim (void) AcpiPsCompleteThisOp (WalkState, Op); 662244971Sjkim return_ACPI_STATUS (Status); 663244971Sjkim } 664244971Sjkim } 665244971Sjkim 666244971Sjkim Status2 = AcpiPsCompleteThisOp (WalkState, Op); 667244971Sjkim if (ACPI_FAILURE (Status2)) 668244971Sjkim { 669244971Sjkim return_ACPI_STATUS (Status2); 670244971Sjkim } 671244971Sjkim } 672244971Sjkim 673244971Sjkim AcpiPsPopScope (&(WalkState->ParserState), &Op, &WalkState->ArgTypes, 674244971Sjkim &WalkState->ArgCount); 675244971Sjkim 676244971Sjkim } while (Op); 677244971Sjkim 678244971Sjkim return_ACPI_STATUS (Status); 679244971Sjkim} 680