1244971Sjkim/****************************************************************************** 2244971Sjkim * 3244971Sjkim * Module Name: psobject - Support for parse objects 4244971Sjkim * 5244971Sjkim *****************************************************************************/ 6244971Sjkim 7244971Sjkim/* 8306536Sjkim * Copyright (C) 2000 - 2016, 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 44245582Sjkim#include <contrib/dev/acpica/include/acpi.h> 45245582Sjkim#include <contrib/dev/acpica/include/accommon.h> 46245582Sjkim#include <contrib/dev/acpica/include/acparser.h> 47245582Sjkim#include <contrib/dev/acpica/include/amlcode.h> 48244971Sjkim 49244971Sjkim#define _COMPONENT ACPI_PARSER 50244971Sjkim ACPI_MODULE_NAME ("psobject") 51244971Sjkim 52244971Sjkim 53244971Sjkim/* Local prototypes */ 54244971Sjkim 55244971Sjkimstatic ACPI_STATUS 56244971SjkimAcpiPsGetAmlOpcode ( 57244971Sjkim ACPI_WALK_STATE *WalkState); 58244971Sjkim 59244971Sjkim 60244971Sjkim/******************************************************************************* 61244971Sjkim * 62244971Sjkim * FUNCTION: AcpiPsGetAmlOpcode 63244971Sjkim * 64244971Sjkim * PARAMETERS: WalkState - Current state 65244971Sjkim * 66244971Sjkim * RETURN: Status 67244971Sjkim * 68244971Sjkim * DESCRIPTION: Extract the next AML opcode from the input stream. 69244971Sjkim * 70244971Sjkim ******************************************************************************/ 71244971Sjkim 72244971Sjkimstatic ACPI_STATUS 73244971SjkimAcpiPsGetAmlOpcode ( 74244971Sjkim ACPI_WALK_STATE *WalkState) 75244971Sjkim{ 76306536Sjkim UINT32 AmlOffset; 77244971Sjkim 78306536Sjkim 79244971Sjkim ACPI_FUNCTION_TRACE_PTR (PsGetAmlOpcode, WalkState); 80244971Sjkim 81244971Sjkim 82306536Sjkim WalkState->Aml = WalkState->ParserState.Aml; 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 { 111306536Sjkim AmlOffset = (UINT32) ACPI_PTR_DIFF (WalkState->Aml, 112306536Sjkim WalkState->ParserState.AmlStart); 113306536Sjkim 114244971Sjkim ACPI_ERROR ((AE_INFO, 115244971Sjkim "Unknown opcode 0x%.2X at table offset 0x%.4X, ignoring", 116244971Sjkim WalkState->Opcode, 117306536Sjkim (UINT32) (AmlOffset + sizeof (ACPI_TABLE_HEADER)))); 118244971Sjkim 119244971Sjkim ACPI_DUMP_BUFFER ((WalkState->ParserState.Aml - 16), 48); 120244971Sjkim 121244971Sjkim#ifdef ACPI_ASL_COMPILER 122244971Sjkim /* 123244971Sjkim * This is executed for the disassembler only. Output goes 124244971Sjkim * to the disassembled ASL output file. 125244971Sjkim */ 126244971Sjkim AcpiOsPrintf ( 127244971Sjkim "/*\nError: Unknown opcode 0x%.2X at table offset 0x%.4X, context:\n", 128244971Sjkim WalkState->Opcode, 129306536Sjkim (UINT32) (AmlOffset + sizeof (ACPI_TABLE_HEADER))); 130244971Sjkim 131244971Sjkim /* Dump the context surrounding the invalid opcode */ 132244971Sjkim 133244971Sjkim AcpiUtDumpBuffer (((UINT8 *) WalkState->ParserState.Aml - 16), 134244971Sjkim 48, DB_BYTE_DISPLAY, 135306536Sjkim (AmlOffset + sizeof (ACPI_TABLE_HEADER) - 16)); 136244971Sjkim AcpiOsPrintf (" */\n"); 137244971Sjkim#endif 138244971Sjkim } 139244971Sjkim 140244971Sjkim /* Increment past one-byte or two-byte opcode */ 141244971Sjkim 142244971Sjkim WalkState->ParserState.Aml++; 143244971Sjkim if (WalkState->Opcode > 0xFF) /* Can only happen if first byte is 0x5B */ 144244971Sjkim { 145244971Sjkim WalkState->ParserState.Aml++; 146244971Sjkim } 147244971Sjkim 148244971Sjkim return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE); 149244971Sjkim 150244971Sjkim default: 151244971Sjkim 152244971Sjkim /* Found opcode info, this is a normal opcode */ 153244971Sjkim 154306536Sjkim WalkState->ParserState.Aml += 155306536Sjkim AcpiPsGetOpcodeSize (WalkState->Opcode); 156244971Sjkim WalkState->ArgTypes = WalkState->OpInfo->ParseArgs; 157244971Sjkim break; 158244971Sjkim } 159244971Sjkim 160244971Sjkim return_ACPI_STATUS (AE_OK); 161244971Sjkim} 162244971Sjkim 163244971Sjkim 164244971Sjkim/******************************************************************************* 165244971Sjkim * 166244971Sjkim * FUNCTION: AcpiPsBuildNamedOp 167244971Sjkim * 168244971Sjkim * PARAMETERS: WalkState - Current state 169244971Sjkim * AmlOpStart - Begin of named Op in AML 170244971Sjkim * UnnamedOp - Early Op (not a named Op) 171244971Sjkim * Op - Returned Op 172244971Sjkim * 173244971Sjkim * RETURN: Status 174244971Sjkim * 175244971Sjkim * DESCRIPTION: Parse a named Op 176244971Sjkim * 177244971Sjkim ******************************************************************************/ 178244971Sjkim 179244971SjkimACPI_STATUS 180244971SjkimAcpiPsBuildNamedOp ( 181244971Sjkim ACPI_WALK_STATE *WalkState, 182244971Sjkim UINT8 *AmlOpStart, 183244971Sjkim ACPI_PARSE_OBJECT *UnnamedOp, 184244971Sjkim ACPI_PARSE_OBJECT **Op) 185244971Sjkim{ 186244971Sjkim ACPI_STATUS Status = AE_OK; 187244971Sjkim ACPI_PARSE_OBJECT *Arg = NULL; 188244971Sjkim 189244971Sjkim 190244971Sjkim ACPI_FUNCTION_TRACE_PTR (PsBuildNamedOp, WalkState); 191244971Sjkim 192244971Sjkim 193244971Sjkim UnnamedOp->Common.Value.Arg = NULL; 194244971Sjkim UnnamedOp->Common.ArgListLength = 0; 195244971Sjkim UnnamedOp->Common.AmlOpcode = WalkState->Opcode; 196244971Sjkim 197244971Sjkim /* 198244971Sjkim * Get and append arguments until we find the node that contains 199244971Sjkim * the name (the type ARGP_NAME). 200244971Sjkim */ 201244971Sjkim while (GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) && 202244971Sjkim (GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) != ARGP_NAME)) 203244971Sjkim { 204244971Sjkim Status = AcpiPsGetNextArg (WalkState, &(WalkState->ParserState), 205306536Sjkim GET_CURRENT_ARG_TYPE (WalkState->ArgTypes), &Arg); 206244971Sjkim if (ACPI_FAILURE (Status)) 207244971Sjkim { 208244971Sjkim return_ACPI_STATUS (Status); 209244971Sjkim } 210244971Sjkim 211244971Sjkim AcpiPsAppendArg (UnnamedOp, Arg); 212244971Sjkim INCREMENT_ARG_LIST (WalkState->ArgTypes); 213244971Sjkim } 214244971Sjkim 215244971Sjkim /* 216244971Sjkim * Make sure that we found a NAME and didn't run out of arguments 217244971Sjkim */ 218244971Sjkim if (!GET_CURRENT_ARG_TYPE (WalkState->ArgTypes)) 219244971Sjkim { 220244971Sjkim return_ACPI_STATUS (AE_AML_NO_OPERAND); 221244971Sjkim } 222244971Sjkim 223244971Sjkim /* We know that this arg is a name, move to next arg */ 224244971Sjkim 225244971Sjkim INCREMENT_ARG_LIST (WalkState->ArgTypes); 226244971Sjkim 227244971Sjkim /* 228244971Sjkim * Find the object. This will either insert the object into 229244971Sjkim * the namespace or simply look it up 230244971Sjkim */ 231244971Sjkim WalkState->Op = NULL; 232244971Sjkim 233244971Sjkim Status = WalkState->DescendingCallback (WalkState, Op); 234244971Sjkim if (ACPI_FAILURE (Status)) 235244971Sjkim { 236281075Sdim if (Status != AE_CTRL_TERMINATE) 237281075Sdim { 238281075Sdim ACPI_EXCEPTION ((AE_INFO, Status, "During name lookup/catalog")); 239281075Sdim } 240244971Sjkim return_ACPI_STATUS (Status); 241244971Sjkim } 242244971Sjkim 243244971Sjkim if (!*Op) 244244971Sjkim { 245244971Sjkim return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE); 246244971Sjkim } 247244971Sjkim 248244971Sjkim Status = AcpiPsNextParseState (WalkState, *Op, Status); 249244971Sjkim if (ACPI_FAILURE (Status)) 250244971Sjkim { 251244971Sjkim if (Status == AE_CTRL_PENDING) 252244971Sjkim { 253281075Sdim Status = AE_CTRL_PARSE_PENDING; 254244971Sjkim } 255244971Sjkim return_ACPI_STATUS (Status); 256244971Sjkim } 257244971Sjkim 258244971Sjkim AcpiPsAppendArg (*Op, UnnamedOp->Common.Value.Arg); 259244971Sjkim 260244971Sjkim if ((*Op)->Common.AmlOpcode == AML_REGION_OP || 261244971Sjkim (*Op)->Common.AmlOpcode == AML_DATA_REGION_OP) 262244971Sjkim { 263244971Sjkim /* 264244971Sjkim * Defer final parsing of an OperationRegion body, because we don't 265244971Sjkim * have enough info in the first pass to parse it correctly (i.e., 266244971Sjkim * there may be method calls within the TermArg elements of the body.) 267244971Sjkim * 268244971Sjkim * However, we must continue parsing because the opregion is not a 269244971Sjkim * standalone package -- we don't know where the end is at this point. 270244971Sjkim * 271244971Sjkim * (Length is unknown until parse of the body complete) 272244971Sjkim */ 273244971Sjkim (*Op)->Named.Data = AmlOpStart; 274244971Sjkim (*Op)->Named.Length = 0; 275244971Sjkim } 276244971Sjkim 277244971Sjkim return_ACPI_STATUS (AE_OK); 278244971Sjkim} 279244971Sjkim 280244971Sjkim 281244971Sjkim/******************************************************************************* 282244971Sjkim * 283244971Sjkim * FUNCTION: AcpiPsCreateOp 284244971Sjkim * 285244971Sjkim * PARAMETERS: WalkState - Current state 286244971Sjkim * AmlOpStart - Op start in AML 287244971Sjkim * NewOp - Returned Op 288244971Sjkim * 289244971Sjkim * RETURN: Status 290244971Sjkim * 291244971Sjkim * DESCRIPTION: Get Op from AML 292244971Sjkim * 293244971Sjkim ******************************************************************************/ 294244971Sjkim 295244971SjkimACPI_STATUS 296244971SjkimAcpiPsCreateOp ( 297244971Sjkim ACPI_WALK_STATE *WalkState, 298244971Sjkim UINT8 *AmlOpStart, 299244971Sjkim ACPI_PARSE_OBJECT **NewOp) 300244971Sjkim{ 301244971Sjkim ACPI_STATUS Status = AE_OK; 302244971Sjkim ACPI_PARSE_OBJECT *Op; 303244971Sjkim ACPI_PARSE_OBJECT *NamedOp = NULL; 304244971Sjkim ACPI_PARSE_OBJECT *ParentScope; 305244971Sjkim UINT8 ArgumentCount; 306244971Sjkim const ACPI_OPCODE_INFO *OpInfo; 307244971Sjkim 308244971Sjkim 309244971Sjkim ACPI_FUNCTION_TRACE_PTR (PsCreateOp, WalkState); 310244971Sjkim 311244971Sjkim 312244971Sjkim Status = AcpiPsGetAmlOpcode (WalkState); 313244971Sjkim if (Status == AE_CTRL_PARSE_CONTINUE) 314244971Sjkim { 315244971Sjkim return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE); 316244971Sjkim } 317244971Sjkim 318244971Sjkim /* Create Op structure and append to parent's argument list */ 319244971Sjkim 320244971Sjkim WalkState->OpInfo = AcpiPsGetOpcodeInfo (WalkState->Opcode); 321306536Sjkim Op = AcpiPsAllocOp (WalkState->Opcode, AmlOpStart); 322244971Sjkim if (!Op) 323244971Sjkim { 324244971Sjkim return_ACPI_STATUS (AE_NO_MEMORY); 325244971Sjkim } 326244971Sjkim 327244971Sjkim if (WalkState->OpInfo->Flags & AML_NAMED) 328244971Sjkim { 329244971Sjkim Status = AcpiPsBuildNamedOp (WalkState, AmlOpStart, Op, &NamedOp); 330244971Sjkim AcpiPsFreeOp (Op); 331244971Sjkim if (ACPI_FAILURE (Status)) 332244971Sjkim { 333244971Sjkim return_ACPI_STATUS (Status); 334244971Sjkim } 335244971Sjkim 336244971Sjkim *NewOp = NamedOp; 337244971Sjkim return_ACPI_STATUS (AE_OK); 338244971Sjkim } 339244971Sjkim 340244971Sjkim /* Not a named opcode, just allocate Op and append to parent */ 341244971Sjkim 342244971Sjkim if (WalkState->OpInfo->Flags & AML_CREATE) 343244971Sjkim { 344244971Sjkim /* 345244971Sjkim * Backup to beginning of CreateXXXfield declaration 346244971Sjkim * BodyLength is unknown until we parse the body 347244971Sjkim */ 348244971Sjkim Op->Named.Data = AmlOpStart; 349244971Sjkim Op->Named.Length = 0; 350244971Sjkim } 351244971Sjkim 352244971Sjkim if (WalkState->Opcode == AML_BANK_FIELD_OP) 353244971Sjkim { 354244971Sjkim /* 355244971Sjkim * Backup to beginning of BankField declaration 356244971Sjkim * BodyLength is unknown until we parse the body 357244971Sjkim */ 358244971Sjkim Op->Named.Data = AmlOpStart; 359244971Sjkim Op->Named.Length = 0; 360244971Sjkim } 361244971Sjkim 362244971Sjkim ParentScope = AcpiPsGetParentScope (&(WalkState->ParserState)); 363244971Sjkim AcpiPsAppendArg (ParentScope, Op); 364244971Sjkim 365244971Sjkim if (ParentScope) 366244971Sjkim { 367244971Sjkim OpInfo = AcpiPsGetOpcodeInfo (ParentScope->Common.AmlOpcode); 368244971Sjkim if (OpInfo->Flags & AML_HAS_TARGET) 369244971Sjkim { 370244971Sjkim ArgumentCount = AcpiPsGetArgumentCount (OpInfo->Type); 371244971Sjkim if (ParentScope->Common.ArgListLength > ArgumentCount) 372244971Sjkim { 373244971Sjkim Op->Common.Flags |= ACPI_PARSEOP_TARGET; 374244971Sjkim } 375244971Sjkim } 376244971Sjkim else if (ParentScope->Common.AmlOpcode == AML_INCREMENT_OP) 377244971Sjkim { 378244971Sjkim Op->Common.Flags |= ACPI_PARSEOP_TARGET; 379244971Sjkim } 380244971Sjkim } 381244971Sjkim 382244971Sjkim if (WalkState->DescendingCallback != NULL) 383244971Sjkim { 384244971Sjkim /* 385244971Sjkim * Find the object. This will either insert the object into 386244971Sjkim * the namespace or simply look it up 387244971Sjkim */ 388244971Sjkim WalkState->Op = *NewOp = Op; 389244971Sjkim 390244971Sjkim Status = WalkState->DescendingCallback (WalkState, &Op); 391244971Sjkim Status = AcpiPsNextParseState (WalkState, Op, Status); 392244971Sjkim if (Status == AE_CTRL_PENDING) 393244971Sjkim { 394244971Sjkim Status = AE_CTRL_PARSE_PENDING; 395244971Sjkim } 396244971Sjkim } 397244971Sjkim 398244971Sjkim return_ACPI_STATUS (Status); 399244971Sjkim} 400244971Sjkim 401244971Sjkim 402244971Sjkim/******************************************************************************* 403244971Sjkim * 404244971Sjkim * FUNCTION: AcpiPsCompleteOp 405244971Sjkim * 406244971Sjkim * PARAMETERS: WalkState - Current state 407244971Sjkim * Op - Returned Op 408244971Sjkim * Status - Parse status before complete Op 409244971Sjkim * 410244971Sjkim * RETURN: Status 411244971Sjkim * 412244971Sjkim * DESCRIPTION: Complete Op 413244971Sjkim * 414244971Sjkim ******************************************************************************/ 415244971Sjkim 416244971SjkimACPI_STATUS 417244971SjkimAcpiPsCompleteOp ( 418244971Sjkim ACPI_WALK_STATE *WalkState, 419244971Sjkim ACPI_PARSE_OBJECT **Op, 420244971Sjkim ACPI_STATUS Status) 421244971Sjkim{ 422244971Sjkim ACPI_STATUS Status2; 423244971Sjkim 424244971Sjkim 425244971Sjkim ACPI_FUNCTION_TRACE_PTR (PsCompleteOp, WalkState); 426244971Sjkim 427244971Sjkim 428244971Sjkim /* 429244971Sjkim * Finished one argument of the containing scope 430244971Sjkim */ 431244971Sjkim WalkState->ParserState.Scope->ParseScope.ArgCount--; 432244971Sjkim 433244971Sjkim /* Close this Op (will result in parse subtree deletion) */ 434244971Sjkim 435244971Sjkim Status2 = AcpiPsCompleteThisOp (WalkState, *Op); 436244971Sjkim if (ACPI_FAILURE (Status2)) 437244971Sjkim { 438244971Sjkim return_ACPI_STATUS (Status2); 439244971Sjkim } 440244971Sjkim 441244971Sjkim *Op = NULL; 442244971Sjkim 443244971Sjkim switch (Status) 444244971Sjkim { 445244971Sjkim case AE_OK: 446250838Sjkim 447244971Sjkim break; 448244971Sjkim 449244971Sjkim case AE_CTRL_TRANSFER: 450244971Sjkim 451244971Sjkim /* We are about to transfer to a called method */ 452244971Sjkim 453244971Sjkim WalkState->PrevOp = NULL; 454244971Sjkim WalkState->PrevArgTypes = WalkState->ArgTypes; 455244971Sjkim return_ACPI_STATUS (Status); 456244971Sjkim 457244971Sjkim case AE_CTRL_END: 458244971Sjkim 459244971Sjkim AcpiPsPopScope (&(WalkState->ParserState), Op, 460244971Sjkim &WalkState->ArgTypes, &WalkState->ArgCount); 461244971Sjkim 462244971Sjkim if (*Op) 463244971Sjkim { 464244971Sjkim WalkState->Op = *Op; 465244971Sjkim WalkState->OpInfo = AcpiPsGetOpcodeInfo ((*Op)->Common.AmlOpcode); 466244971Sjkim WalkState->Opcode = (*Op)->Common.AmlOpcode; 467244971Sjkim 468244971Sjkim Status = WalkState->AscendingCallback (WalkState); 469244971Sjkim Status = AcpiPsNextParseState (WalkState, *Op, Status); 470244971Sjkim 471244971Sjkim Status2 = AcpiPsCompleteThisOp (WalkState, *Op); 472244971Sjkim if (ACPI_FAILURE (Status2)) 473244971Sjkim { 474244971Sjkim return_ACPI_STATUS (Status2); 475244971Sjkim } 476244971Sjkim } 477244971Sjkim 478244971Sjkim Status = AE_OK; 479244971Sjkim break; 480244971Sjkim 481244971Sjkim case AE_CTRL_BREAK: 482244971Sjkim case AE_CTRL_CONTINUE: 483244971Sjkim 484244971Sjkim /* Pop off scopes until we find the While */ 485244971Sjkim 486244971Sjkim while (!(*Op) || ((*Op)->Common.AmlOpcode != AML_WHILE_OP)) 487244971Sjkim { 488244971Sjkim AcpiPsPopScope (&(WalkState->ParserState), Op, 489244971Sjkim &WalkState->ArgTypes, &WalkState->ArgCount); 490244971Sjkim } 491244971Sjkim 492244971Sjkim /* Close this iteration of the While loop */ 493244971Sjkim 494244971Sjkim WalkState->Op = *Op; 495244971Sjkim WalkState->OpInfo = AcpiPsGetOpcodeInfo ((*Op)->Common.AmlOpcode); 496244971Sjkim WalkState->Opcode = (*Op)->Common.AmlOpcode; 497244971Sjkim 498244971Sjkim Status = WalkState->AscendingCallback (WalkState); 499244971Sjkim Status = AcpiPsNextParseState (WalkState, *Op, Status); 500244971Sjkim 501244971Sjkim Status2 = AcpiPsCompleteThisOp (WalkState, *Op); 502244971Sjkim if (ACPI_FAILURE (Status2)) 503244971Sjkim { 504244971Sjkim return_ACPI_STATUS (Status2); 505244971Sjkim } 506244971Sjkim 507244971Sjkim Status = AE_OK; 508244971Sjkim break; 509244971Sjkim 510244971Sjkim case AE_CTRL_TERMINATE: 511244971Sjkim 512244971Sjkim /* Clean up */ 513244971Sjkim do 514244971Sjkim { 515244971Sjkim if (*Op) 516244971Sjkim { 517244971Sjkim Status2 = AcpiPsCompleteThisOp (WalkState, *Op); 518244971Sjkim if (ACPI_FAILURE (Status2)) 519244971Sjkim { 520244971Sjkim return_ACPI_STATUS (Status2); 521244971Sjkim } 522244971Sjkim 523244971Sjkim AcpiUtDeleteGenericState ( 524244971Sjkim AcpiUtPopGenericState (&WalkState->ControlState)); 525244971Sjkim } 526244971Sjkim 527244971Sjkim AcpiPsPopScope (&(WalkState->ParserState), Op, 528244971Sjkim &WalkState->ArgTypes, &WalkState->ArgCount); 529244971Sjkim 530244971Sjkim } while (*Op); 531244971Sjkim 532244971Sjkim return_ACPI_STATUS (AE_OK); 533244971Sjkim 534244971Sjkim default: /* All other non-AE_OK status */ 535244971Sjkim 536244971Sjkim do 537244971Sjkim { 538244971Sjkim if (*Op) 539244971Sjkim { 540244971Sjkim Status2 = AcpiPsCompleteThisOp (WalkState, *Op); 541244971Sjkim if (ACPI_FAILURE (Status2)) 542244971Sjkim { 543244971Sjkim return_ACPI_STATUS (Status2); 544244971Sjkim } 545244971Sjkim } 546244971Sjkim 547244971Sjkim AcpiPsPopScope (&(WalkState->ParserState), Op, 548244971Sjkim &WalkState->ArgTypes, &WalkState->ArgCount); 549244971Sjkim 550244971Sjkim } while (*Op); 551244971Sjkim 552244971Sjkim 553244971Sjkim#if 0 554244971Sjkim /* 555244971Sjkim * TBD: Cleanup parse ops on error 556244971Sjkim */ 557244971Sjkim if (*Op == NULL) 558244971Sjkim { 559244971Sjkim AcpiPsPopScope (ParserState, Op, 560244971Sjkim &WalkState->ArgTypes, &WalkState->ArgCount); 561244971Sjkim } 562244971Sjkim#endif 563244971Sjkim WalkState->PrevOp = NULL; 564244971Sjkim WalkState->PrevArgTypes = WalkState->ArgTypes; 565244971Sjkim return_ACPI_STATUS (Status); 566244971Sjkim } 567244971Sjkim 568244971Sjkim /* This scope complete? */ 569244971Sjkim 570244971Sjkim if (AcpiPsHasCompletedScope (&(WalkState->ParserState))) 571244971Sjkim { 572244971Sjkim AcpiPsPopScope (&(WalkState->ParserState), Op, 573244971Sjkim &WalkState->ArgTypes, &WalkState->ArgCount); 574244971Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", *Op)); 575244971Sjkim } 576244971Sjkim else 577244971Sjkim { 578244971Sjkim *Op = NULL; 579244971Sjkim } 580244971Sjkim 581244971Sjkim return_ACPI_STATUS (AE_OK); 582244971Sjkim} 583244971Sjkim 584244971Sjkim 585244971Sjkim/******************************************************************************* 586244971Sjkim * 587244971Sjkim * FUNCTION: AcpiPsCompleteFinalOp 588244971Sjkim * 589244971Sjkim * PARAMETERS: WalkState - Current state 590244971Sjkim * Op - Current Op 591244971Sjkim * Status - Current parse status before complete last 592244971Sjkim * Op 593244971Sjkim * 594244971Sjkim * RETURN: Status 595244971Sjkim * 596244971Sjkim * DESCRIPTION: Complete last Op. 597244971Sjkim * 598244971Sjkim ******************************************************************************/ 599244971Sjkim 600244971SjkimACPI_STATUS 601244971SjkimAcpiPsCompleteFinalOp ( 602244971Sjkim ACPI_WALK_STATE *WalkState, 603244971Sjkim ACPI_PARSE_OBJECT *Op, 604244971Sjkim ACPI_STATUS Status) 605244971Sjkim{ 606244971Sjkim ACPI_STATUS Status2; 607244971Sjkim 608244971Sjkim 609244971Sjkim ACPI_FUNCTION_TRACE_PTR (PsCompleteFinalOp, WalkState); 610244971Sjkim 611244971Sjkim 612244971Sjkim /* 613244971Sjkim * Complete the last Op (if not completed), and clear the scope stack. 614244971Sjkim * It is easily possible to end an AML "package" with an unbounded number 615244971Sjkim * of open scopes (such as when several ASL blocks are closed with 616244971Sjkim * sequential closing braces). We want to terminate each one cleanly. 617244971Sjkim */ 618244971Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "AML package complete at Op %p\n", Op)); 619244971Sjkim do 620244971Sjkim { 621244971Sjkim if (Op) 622244971Sjkim { 623244971Sjkim if (WalkState->AscendingCallback != NULL) 624244971Sjkim { 625244971Sjkim WalkState->Op = Op; 626244971Sjkim WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 627244971Sjkim WalkState->Opcode = Op->Common.AmlOpcode; 628244971Sjkim 629244971Sjkim Status = WalkState->AscendingCallback (WalkState); 630244971Sjkim Status = AcpiPsNextParseState (WalkState, Op, Status); 631244971Sjkim if (Status == AE_CTRL_PENDING) 632244971Sjkim { 633244971Sjkim Status = AcpiPsCompleteOp (WalkState, &Op, AE_OK); 634244971Sjkim if (ACPI_FAILURE (Status)) 635244971Sjkim { 636244971Sjkim return_ACPI_STATUS (Status); 637244971Sjkim } 638244971Sjkim } 639244971Sjkim 640244971Sjkim if (Status == AE_CTRL_TERMINATE) 641244971Sjkim { 642244971Sjkim Status = AE_OK; 643244971Sjkim 644244971Sjkim /* Clean up */ 645244971Sjkim do 646244971Sjkim { 647244971Sjkim if (Op) 648244971Sjkim { 649244971Sjkim Status2 = AcpiPsCompleteThisOp (WalkState, Op); 650244971Sjkim if (ACPI_FAILURE (Status2)) 651244971Sjkim { 652244971Sjkim return_ACPI_STATUS (Status2); 653244971Sjkim } 654244971Sjkim } 655244971Sjkim 656244971Sjkim AcpiPsPopScope (&(WalkState->ParserState), &Op, 657244971Sjkim &WalkState->ArgTypes, &WalkState->ArgCount); 658244971Sjkim 659244971Sjkim } while (Op); 660244971Sjkim 661244971Sjkim return_ACPI_STATUS (Status); 662244971Sjkim } 663244971Sjkim 664244971Sjkim else if (ACPI_FAILURE (Status)) 665244971Sjkim { 666244971Sjkim /* First error is most important */ 667244971Sjkim 668244971Sjkim (void) AcpiPsCompleteThisOp (WalkState, Op); 669244971Sjkim return_ACPI_STATUS (Status); 670244971Sjkim } 671244971Sjkim } 672244971Sjkim 673244971Sjkim Status2 = AcpiPsCompleteThisOp (WalkState, Op); 674244971Sjkim if (ACPI_FAILURE (Status2)) 675244971Sjkim { 676244971Sjkim return_ACPI_STATUS (Status2); 677244971Sjkim } 678244971Sjkim } 679244971Sjkim 680244971Sjkim AcpiPsPopScope (&(WalkState->ParserState), &Op, &WalkState->ArgTypes, 681244971Sjkim &WalkState->ArgCount); 682244971Sjkim 683244971Sjkim } while (Op); 684244971Sjkim 685244971Sjkim return_ACPI_STATUS (Status); 686244971Sjkim} 687