126f3cdf0SGordon Ross /****************************************************************************** 226f3cdf0SGordon Ross * 326f3cdf0SGordon Ross * Module Name: dscontrol - Support for execution control opcodes - 426f3cdf0SGordon Ross * if/else/while/return 526f3cdf0SGordon Ross * 626f3cdf0SGordon Ross *****************************************************************************/ 726f3cdf0SGordon Ross 826f3cdf0SGordon Ross /* 9*385cc6b4SJerry Jelinek * Copyright (C) 2000 - 2016, Intel Corp. 1026f3cdf0SGordon Ross * All rights reserved. 1126f3cdf0SGordon Ross * 1226f3cdf0SGordon Ross * Redistribution and use in source and binary forms, with or without 1326f3cdf0SGordon Ross * modification, are permitted provided that the following conditions 1426f3cdf0SGordon Ross * are met: 1526f3cdf0SGordon Ross * 1. Redistributions of source code must retain the above copyright 1626f3cdf0SGordon Ross * notice, this list of conditions, and the following disclaimer, 1726f3cdf0SGordon Ross * without modification. 1826f3cdf0SGordon Ross * 2. Redistributions in binary form must reproduce at minimum a disclaimer 1926f3cdf0SGordon Ross * substantially similar to the "NO WARRANTY" disclaimer below 2026f3cdf0SGordon Ross * ("Disclaimer") and any redistribution must be conditioned upon 2126f3cdf0SGordon Ross * including a substantially similar Disclaimer requirement for further 2226f3cdf0SGordon Ross * binary redistribution. 2326f3cdf0SGordon Ross * 3. Neither the names of the above-listed copyright holders nor the names 2426f3cdf0SGordon Ross * of any contributors may be used to endorse or promote products derived 2526f3cdf0SGordon Ross * from this software without specific prior written permission. 2626f3cdf0SGordon Ross * 2726f3cdf0SGordon Ross * Alternatively, this software may be distributed under the terms of the 2826f3cdf0SGordon Ross * GNU General Public License ("GPL") version 2 as published by the Free 2926f3cdf0SGordon Ross * Software Foundation. 3026f3cdf0SGordon Ross * 3126f3cdf0SGordon Ross * NO WARRANTY 3226f3cdf0SGordon Ross * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 3326f3cdf0SGordon Ross * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3426f3cdf0SGordon Ross * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 3526f3cdf0SGordon Ross * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3626f3cdf0SGordon Ross * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3726f3cdf0SGordon Ross * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3826f3cdf0SGordon Ross * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3926f3cdf0SGordon Ross * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 4026f3cdf0SGordon Ross * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 4126f3cdf0SGordon Ross * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 4226f3cdf0SGordon Ross * POSSIBILITY OF SUCH DAMAGES. 4326f3cdf0SGordon Ross */ 4426f3cdf0SGordon Ross 4526f3cdf0SGordon Ross #include "acpi.h" 4626f3cdf0SGordon Ross #include "accommon.h" 4726f3cdf0SGordon Ross #include "amlcode.h" 4826f3cdf0SGordon Ross #include "acdispat.h" 4926f3cdf0SGordon Ross #include "acinterp.h" 50*385cc6b4SJerry Jelinek #include "acdebug.h" 5126f3cdf0SGordon Ross 5226f3cdf0SGordon Ross #define _COMPONENT ACPI_DISPATCHER 5326f3cdf0SGordon Ross ACPI_MODULE_NAME ("dscontrol") 5426f3cdf0SGordon Ross 5526f3cdf0SGordon Ross 5626f3cdf0SGordon Ross /******************************************************************************* 5726f3cdf0SGordon Ross * 5826f3cdf0SGordon Ross * FUNCTION: AcpiDsExecBeginControlOp 5926f3cdf0SGordon Ross * 6026f3cdf0SGordon Ross * PARAMETERS: WalkList - The list that owns the walk stack 6126f3cdf0SGordon Ross * Op - The control Op 6226f3cdf0SGordon Ross * 6326f3cdf0SGordon Ross * RETURN: Status 6426f3cdf0SGordon Ross * 6526f3cdf0SGordon Ross * DESCRIPTION: Handles all control ops encountered during control method 6626f3cdf0SGordon Ross * execution. 6726f3cdf0SGordon Ross * 6826f3cdf0SGordon Ross ******************************************************************************/ 6926f3cdf0SGordon Ross 7026f3cdf0SGordon Ross ACPI_STATUS 7126f3cdf0SGordon Ross AcpiDsExecBeginControlOp ( 7226f3cdf0SGordon Ross ACPI_WALK_STATE *WalkState, 7326f3cdf0SGordon Ross ACPI_PARSE_OBJECT *Op) 7426f3cdf0SGordon Ross { 7526f3cdf0SGordon Ross ACPI_STATUS Status = AE_OK; 7626f3cdf0SGordon Ross ACPI_GENERIC_STATE *ControlState; 7726f3cdf0SGordon Ross 7826f3cdf0SGordon Ross 7926f3cdf0SGordon Ross ACPI_FUNCTION_NAME (DsExecBeginControlOp); 8026f3cdf0SGordon Ross 8126f3cdf0SGordon Ross 8226f3cdf0SGordon Ross ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p Opcode=%2.2X State=%p\n", 8326f3cdf0SGordon Ross Op, Op->Common.AmlOpcode, WalkState)); 8426f3cdf0SGordon Ross 8526f3cdf0SGordon Ross switch (Op->Common.AmlOpcode) 8626f3cdf0SGordon Ross { 8726f3cdf0SGordon Ross case AML_WHILE_OP: 8826f3cdf0SGordon Ross /* 8926f3cdf0SGordon Ross * If this is an additional iteration of a while loop, continue. 9026f3cdf0SGordon Ross * There is no need to allocate a new control state. 9126f3cdf0SGordon Ross */ 9226f3cdf0SGordon Ross if (WalkState->ControlState) 9326f3cdf0SGordon Ross { 9426f3cdf0SGordon Ross if (WalkState->ControlState->Control.AmlPredicateStart == 9526f3cdf0SGordon Ross (WalkState->ParserState.Aml - 1)) 9626f3cdf0SGordon Ross { 9726f3cdf0SGordon Ross /* Reset the state to start-of-loop */ 9826f3cdf0SGordon Ross 9926f3cdf0SGordon Ross WalkState->ControlState->Common.State = 10026f3cdf0SGordon Ross ACPI_CONTROL_CONDITIONAL_EXECUTING; 10126f3cdf0SGordon Ross break; 10226f3cdf0SGordon Ross } 10326f3cdf0SGordon Ross } 10426f3cdf0SGordon Ross 10526f3cdf0SGordon Ross /*lint -fallthrough */ 10626f3cdf0SGordon Ross 10726f3cdf0SGordon Ross case AML_IF_OP: 10826f3cdf0SGordon Ross /* 10926f3cdf0SGordon Ross * IF/WHILE: Create a new control state to manage these 11026f3cdf0SGordon Ross * constructs. We need to manage these as a stack, in order 11126f3cdf0SGordon Ross * to handle nesting. 11226f3cdf0SGordon Ross */ 11326f3cdf0SGordon Ross ControlState = AcpiUtCreateControlState (); 11426f3cdf0SGordon Ross if (!ControlState) 11526f3cdf0SGordon Ross { 11626f3cdf0SGordon Ross Status = AE_NO_MEMORY; 11726f3cdf0SGordon Ross break; 11826f3cdf0SGordon Ross } 11926f3cdf0SGordon Ross /* 12026f3cdf0SGordon Ross * Save a pointer to the predicate for multiple executions 12126f3cdf0SGordon Ross * of a loop 12226f3cdf0SGordon Ross */ 123*385cc6b4SJerry Jelinek ControlState->Control.AmlPredicateStart = 124*385cc6b4SJerry Jelinek WalkState->ParserState.Aml - 1; 125*385cc6b4SJerry Jelinek ControlState->Control.PackageEnd = 126*385cc6b4SJerry Jelinek WalkState->ParserState.PkgEnd; 127*385cc6b4SJerry Jelinek ControlState->Control.Opcode = 128*385cc6b4SJerry Jelinek Op->Common.AmlOpcode; 12926f3cdf0SGordon Ross 13026f3cdf0SGordon Ross 13126f3cdf0SGordon Ross /* Push the control state on this walk's control stack */ 13226f3cdf0SGordon Ross 13326f3cdf0SGordon Ross AcpiUtPushGenericState (&WalkState->ControlState, ControlState); 13426f3cdf0SGordon Ross break; 13526f3cdf0SGordon Ross 13626f3cdf0SGordon Ross case AML_ELSE_OP: 13726f3cdf0SGordon Ross 13826f3cdf0SGordon Ross /* Predicate is in the state object */ 13926f3cdf0SGordon Ross /* If predicate is true, the IF was executed, ignore ELSE part */ 14026f3cdf0SGordon Ross 14126f3cdf0SGordon Ross if (WalkState->LastPredicate) 14226f3cdf0SGordon Ross { 14326f3cdf0SGordon Ross Status = AE_CTRL_TRUE; 14426f3cdf0SGordon Ross } 14526f3cdf0SGordon Ross 14626f3cdf0SGordon Ross break; 14726f3cdf0SGordon Ross 14826f3cdf0SGordon Ross case AML_RETURN_OP: 14926f3cdf0SGordon Ross 15026f3cdf0SGordon Ross break; 15126f3cdf0SGordon Ross 15226f3cdf0SGordon Ross default: 153*385cc6b4SJerry Jelinek 15426f3cdf0SGordon Ross break; 15526f3cdf0SGordon Ross } 15626f3cdf0SGordon Ross 15726f3cdf0SGordon Ross return (Status); 15826f3cdf0SGordon Ross } 15926f3cdf0SGordon Ross 16026f3cdf0SGordon Ross 16126f3cdf0SGordon Ross /******************************************************************************* 16226f3cdf0SGordon Ross * 16326f3cdf0SGordon Ross * FUNCTION: AcpiDsExecEndControlOp 16426f3cdf0SGordon Ross * 16526f3cdf0SGordon Ross * PARAMETERS: WalkList - The list that owns the walk stack 16626f3cdf0SGordon Ross * Op - The control Op 16726f3cdf0SGordon Ross * 16826f3cdf0SGordon Ross * RETURN: Status 16926f3cdf0SGordon Ross * 17026f3cdf0SGordon Ross * DESCRIPTION: Handles all control ops encountered during control method 17126f3cdf0SGordon Ross * execution. 17226f3cdf0SGordon Ross * 17326f3cdf0SGordon Ross ******************************************************************************/ 17426f3cdf0SGordon Ross 17526f3cdf0SGordon Ross ACPI_STATUS 17626f3cdf0SGordon Ross AcpiDsExecEndControlOp ( 17726f3cdf0SGordon Ross ACPI_WALK_STATE *WalkState, 17826f3cdf0SGordon Ross ACPI_PARSE_OBJECT *Op) 17926f3cdf0SGordon Ross { 18026f3cdf0SGordon Ross ACPI_STATUS Status = AE_OK; 18126f3cdf0SGordon Ross ACPI_GENERIC_STATE *ControlState; 18226f3cdf0SGordon Ross 18326f3cdf0SGordon Ross 18426f3cdf0SGordon Ross ACPI_FUNCTION_NAME (DsExecEndControlOp); 18526f3cdf0SGordon Ross 18626f3cdf0SGordon Ross 18726f3cdf0SGordon Ross switch (Op->Common.AmlOpcode) 18826f3cdf0SGordon Ross { 18926f3cdf0SGordon Ross case AML_IF_OP: 19026f3cdf0SGordon Ross 19126f3cdf0SGordon Ross ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[IF_OP] Op=%p\n", Op)); 19226f3cdf0SGordon Ross 19326f3cdf0SGordon Ross /* 19426f3cdf0SGordon Ross * Save the result of the predicate in case there is an 19526f3cdf0SGordon Ross * ELSE to come 19626f3cdf0SGordon Ross */ 19726f3cdf0SGordon Ross WalkState->LastPredicate = 19826f3cdf0SGordon Ross (BOOLEAN) WalkState->ControlState->Common.Value; 19926f3cdf0SGordon Ross 20026f3cdf0SGordon Ross /* 20126f3cdf0SGordon Ross * Pop the control state that was created at the start 20226f3cdf0SGordon Ross * of the IF and free it 20326f3cdf0SGordon Ross */ 20426f3cdf0SGordon Ross ControlState = AcpiUtPopGenericState (&WalkState->ControlState); 20526f3cdf0SGordon Ross AcpiUtDeleteGenericState (ControlState); 20626f3cdf0SGordon Ross break; 20726f3cdf0SGordon Ross 20826f3cdf0SGordon Ross case AML_ELSE_OP: 20926f3cdf0SGordon Ross 21026f3cdf0SGordon Ross break; 21126f3cdf0SGordon Ross 21226f3cdf0SGordon Ross case AML_WHILE_OP: 21326f3cdf0SGordon Ross 21426f3cdf0SGordon Ross ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[WHILE_OP] Op=%p\n", Op)); 21526f3cdf0SGordon Ross 21626f3cdf0SGordon Ross ControlState = WalkState->ControlState; 21726f3cdf0SGordon Ross if (ControlState->Common.Value) 21826f3cdf0SGordon Ross { 21926f3cdf0SGordon Ross /* Predicate was true, the body of the loop was just executed */ 22026f3cdf0SGordon Ross 22126f3cdf0SGordon Ross /* 22226f3cdf0SGordon Ross * This loop counter mechanism allows the interpreter to escape 22326f3cdf0SGordon Ross * possibly infinite loops. This can occur in poorly written AML 22426f3cdf0SGordon Ross * when the hardware does not respond within a while loop and the 22526f3cdf0SGordon Ross * loop does not implement a timeout. 22626f3cdf0SGordon Ross */ 22726f3cdf0SGordon Ross ControlState->Control.LoopCount++; 228*385cc6b4SJerry Jelinek if (ControlState->Control.LoopCount > AcpiGbl_MaxLoopIterations) 22926f3cdf0SGordon Ross { 23026f3cdf0SGordon Ross Status = AE_AML_INFINITE_LOOP; 23126f3cdf0SGordon Ross break; 23226f3cdf0SGordon Ross } 23326f3cdf0SGordon Ross 23426f3cdf0SGordon Ross /* 23526f3cdf0SGordon Ross * Go back and evaluate the predicate and maybe execute the loop 23626f3cdf0SGordon Ross * another time 23726f3cdf0SGordon Ross */ 23826f3cdf0SGordon Ross Status = AE_CTRL_PENDING; 239*385cc6b4SJerry Jelinek WalkState->AmlLastWhile = 240*385cc6b4SJerry Jelinek ControlState->Control.AmlPredicateStart; 24126f3cdf0SGordon Ross break; 24226f3cdf0SGordon Ross } 24326f3cdf0SGordon Ross 24426f3cdf0SGordon Ross /* Predicate was false, terminate this while loop */ 24526f3cdf0SGordon Ross 24626f3cdf0SGordon Ross ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 24726f3cdf0SGordon Ross "[WHILE_OP] termination! Op=%p\n",Op)); 24826f3cdf0SGordon Ross 24926f3cdf0SGordon Ross /* Pop this control state and free it */ 25026f3cdf0SGordon Ross 25126f3cdf0SGordon Ross ControlState = AcpiUtPopGenericState (&WalkState->ControlState); 25226f3cdf0SGordon Ross AcpiUtDeleteGenericState (ControlState); 25326f3cdf0SGordon Ross break; 25426f3cdf0SGordon Ross 25526f3cdf0SGordon Ross case AML_RETURN_OP: 25626f3cdf0SGordon Ross 25726f3cdf0SGordon Ross ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 25826f3cdf0SGordon Ross "[RETURN_OP] Op=%p Arg=%p\n",Op, Op->Common.Value.Arg)); 25926f3cdf0SGordon Ross 26026f3cdf0SGordon Ross /* 26126f3cdf0SGordon Ross * One optional operand -- the return value 26226f3cdf0SGordon Ross * It can be either an immediate operand or a result that 26326f3cdf0SGordon Ross * has been bubbled up the tree 26426f3cdf0SGordon Ross */ 26526f3cdf0SGordon Ross if (Op->Common.Value.Arg) 26626f3cdf0SGordon Ross { 26726f3cdf0SGordon Ross /* Since we have a real Return(), delete any implicit return */ 26826f3cdf0SGordon Ross 26926f3cdf0SGordon Ross AcpiDsClearImplicitReturn (WalkState); 27026f3cdf0SGordon Ross 27126f3cdf0SGordon Ross /* Return statement has an immediate operand */ 27226f3cdf0SGordon Ross 27326f3cdf0SGordon Ross Status = AcpiDsCreateOperands (WalkState, Op->Common.Value.Arg); 27426f3cdf0SGordon Ross if (ACPI_FAILURE (Status)) 27526f3cdf0SGordon Ross { 27626f3cdf0SGordon Ross return (Status); 27726f3cdf0SGordon Ross } 27826f3cdf0SGordon Ross 27926f3cdf0SGordon Ross /* 28026f3cdf0SGordon Ross * If value being returned is a Reference (such as 28126f3cdf0SGordon Ross * an arg or local), resolve it now because it may 28226f3cdf0SGordon Ross * cease to exist at the end of the method. 28326f3cdf0SGordon Ross */ 284*385cc6b4SJerry Jelinek Status = AcpiExResolveToValue ( 285*385cc6b4SJerry Jelinek &WalkState->Operands [0], WalkState); 28626f3cdf0SGordon Ross if (ACPI_FAILURE (Status)) 28726f3cdf0SGordon Ross { 28826f3cdf0SGordon Ross return (Status); 28926f3cdf0SGordon Ross } 29026f3cdf0SGordon Ross 29126f3cdf0SGordon Ross /* 29226f3cdf0SGordon Ross * Get the return value and save as the last result 29326f3cdf0SGordon Ross * value. This is the only place where WalkState->ReturnDesc 29426f3cdf0SGordon Ross * is set to anything other than zero! 29526f3cdf0SGordon Ross */ 29626f3cdf0SGordon Ross WalkState->ReturnDesc = WalkState->Operands[0]; 29726f3cdf0SGordon Ross } 29826f3cdf0SGordon Ross else if (WalkState->ResultCount) 29926f3cdf0SGordon Ross { 30026f3cdf0SGordon Ross /* Since we have a real Return(), delete any implicit return */ 30126f3cdf0SGordon Ross 30226f3cdf0SGordon Ross AcpiDsClearImplicitReturn (WalkState); 30326f3cdf0SGordon Ross 30426f3cdf0SGordon Ross /* 30526f3cdf0SGordon Ross * The return value has come from a previous calculation. 30626f3cdf0SGordon Ross * 30726f3cdf0SGordon Ross * If value being returned is a Reference (such as 30826f3cdf0SGordon Ross * an arg or local), resolve it now because it may 30926f3cdf0SGordon Ross * cease to exist at the end of the method. 31026f3cdf0SGordon Ross * 31126f3cdf0SGordon Ross * Allow references created by the Index operator to return 31226f3cdf0SGordon Ross * unchanged. 31326f3cdf0SGordon Ross */ 314*385cc6b4SJerry Jelinek if ((ACPI_GET_DESCRIPTOR_TYPE (WalkState->Results->Results.ObjDesc[0]) == 315*385cc6b4SJerry Jelinek ACPI_DESC_TYPE_OPERAND) && 316*385cc6b4SJerry Jelinek ((WalkState->Results->Results.ObjDesc [0])->Common.Type == 317*385cc6b4SJerry Jelinek ACPI_TYPE_LOCAL_REFERENCE) && 318*385cc6b4SJerry Jelinek ((WalkState->Results->Results.ObjDesc [0])->Reference.Class != 319*385cc6b4SJerry Jelinek ACPI_REFCLASS_INDEX)) 32026f3cdf0SGordon Ross { 321*385cc6b4SJerry Jelinek Status = AcpiExResolveToValue ( 322*385cc6b4SJerry Jelinek &WalkState->Results->Results.ObjDesc [0], WalkState); 32326f3cdf0SGordon Ross if (ACPI_FAILURE (Status)) 32426f3cdf0SGordon Ross { 32526f3cdf0SGordon Ross return (Status); 32626f3cdf0SGordon Ross } 32726f3cdf0SGordon Ross } 32826f3cdf0SGordon Ross 32926f3cdf0SGordon Ross WalkState->ReturnDesc = WalkState->Results->Results.ObjDesc [0]; 33026f3cdf0SGordon Ross } 33126f3cdf0SGordon Ross else 33226f3cdf0SGordon Ross { 33326f3cdf0SGordon Ross /* No return operand */ 33426f3cdf0SGordon Ross 33526f3cdf0SGordon Ross if (WalkState->NumOperands) 33626f3cdf0SGordon Ross { 33726f3cdf0SGordon Ross AcpiUtRemoveReference (WalkState->Operands [0]); 33826f3cdf0SGordon Ross } 33926f3cdf0SGordon Ross 34026f3cdf0SGordon Ross WalkState->Operands[0] = NULL; 34126f3cdf0SGordon Ross WalkState->NumOperands = 0; 34226f3cdf0SGordon Ross WalkState->ReturnDesc = NULL; 34326f3cdf0SGordon Ross } 34426f3cdf0SGordon Ross 34526f3cdf0SGordon Ross 34626f3cdf0SGordon Ross ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 34726f3cdf0SGordon Ross "Completed RETURN_OP State=%p, RetVal=%p\n", 34826f3cdf0SGordon Ross WalkState, WalkState->ReturnDesc)); 34926f3cdf0SGordon Ross 35026f3cdf0SGordon Ross /* End the control method execution right now */ 35126f3cdf0SGordon Ross 35226f3cdf0SGordon Ross Status = AE_CTRL_TERMINATE; 35326f3cdf0SGordon Ross break; 35426f3cdf0SGordon Ross 35526f3cdf0SGordon Ross case AML_NOOP_OP: 35626f3cdf0SGordon Ross 35726f3cdf0SGordon Ross /* Just do nothing! */ 35826f3cdf0SGordon Ross 359*385cc6b4SJerry Jelinek break; 36026f3cdf0SGordon Ross 36126f3cdf0SGordon Ross case AML_BREAK_POINT_OP: 36226f3cdf0SGordon Ross 363*385cc6b4SJerry Jelinek #ifdef ACPI_DEBUGGER 364*385cc6b4SJerry Jelinek AcpiDbSignalBreakPoint (WalkState); 36526f3cdf0SGordon Ross 36626f3cdf0SGordon Ross /* Call to the OSL in case OS wants a piece of the action */ 36726f3cdf0SGordon Ross 36826f3cdf0SGordon Ross Status = AcpiOsSignal (ACPI_SIGNAL_BREAKPOINT, 36926f3cdf0SGordon Ross "Executed AML Breakpoint opcode"); 370*385cc6b4SJerry Jelinek #endif 37126f3cdf0SGordon Ross break; 37226f3cdf0SGordon Ross 37326f3cdf0SGordon Ross case AML_BREAK_OP: 37426f3cdf0SGordon Ross case AML_CONTINUE_OP: /* ACPI 2.0 */ 37526f3cdf0SGordon Ross 37626f3cdf0SGordon Ross /* Pop and delete control states until we find a while */ 37726f3cdf0SGordon Ross 37826f3cdf0SGordon Ross while (WalkState->ControlState && 37926f3cdf0SGordon Ross (WalkState->ControlState->Control.Opcode != AML_WHILE_OP)) 38026f3cdf0SGordon Ross { 38126f3cdf0SGordon Ross ControlState = AcpiUtPopGenericState (&WalkState->ControlState); 38226f3cdf0SGordon Ross AcpiUtDeleteGenericState (ControlState); 38326f3cdf0SGordon Ross } 38426f3cdf0SGordon Ross 38526f3cdf0SGordon Ross /* No while found? */ 38626f3cdf0SGordon Ross 38726f3cdf0SGordon Ross if (!WalkState->ControlState) 38826f3cdf0SGordon Ross { 38926f3cdf0SGordon Ross return (AE_AML_NO_WHILE); 39026f3cdf0SGordon Ross } 39126f3cdf0SGordon Ross 39226f3cdf0SGordon Ross /* Was: WalkState->AmlLastWhile = WalkState->ControlState->Control.AmlPredicateStart; */ 39326f3cdf0SGordon Ross 394*385cc6b4SJerry Jelinek WalkState->AmlLastWhile = 395*385cc6b4SJerry Jelinek WalkState->ControlState->Control.PackageEnd; 39626f3cdf0SGordon Ross 39726f3cdf0SGordon Ross /* Return status depending on opcode */ 39826f3cdf0SGordon Ross 39926f3cdf0SGordon Ross if (Op->Common.AmlOpcode == AML_BREAK_OP) 40026f3cdf0SGordon Ross { 40126f3cdf0SGordon Ross Status = AE_CTRL_BREAK; 40226f3cdf0SGordon Ross } 40326f3cdf0SGordon Ross else 40426f3cdf0SGordon Ross { 40526f3cdf0SGordon Ross Status = AE_CTRL_CONTINUE; 40626f3cdf0SGordon Ross } 40726f3cdf0SGordon Ross break; 40826f3cdf0SGordon Ross 40926f3cdf0SGordon Ross default: 41026f3cdf0SGordon Ross 41126f3cdf0SGordon Ross ACPI_ERROR ((AE_INFO, "Unknown control opcode=0x%X Op=%p", 41226f3cdf0SGordon Ross Op->Common.AmlOpcode, Op)); 41326f3cdf0SGordon Ross 41426f3cdf0SGordon Ross Status = AE_AML_BAD_OPCODE; 41526f3cdf0SGordon Ross break; 41626f3cdf0SGordon Ross } 41726f3cdf0SGordon Ross 41826f3cdf0SGordon Ross return (Status); 41926f3cdf0SGordon Ross } 420