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