1*a159c266SJung-uk Kim /****************************************************************************** 2*a159c266SJung-uk Kim * 3*a159c266SJung-uk Kim * Module Name: dscontrol - Support for execution control opcodes - 4*a159c266SJung-uk Kim * if/else/while/return 5*a159c266SJung-uk Kim * 6*a159c266SJung-uk Kim *****************************************************************************/ 7*a159c266SJung-uk Kim 8*a159c266SJung-uk Kim /* 9*a159c266SJung-uk Kim * Copyright (C) 2000 - 2012, Intel Corp. 10*a159c266SJung-uk Kim * All rights reserved. 11*a159c266SJung-uk Kim * 12*a159c266SJung-uk Kim * Redistribution and use in source and binary forms, with or without 13*a159c266SJung-uk Kim * modification, are permitted provided that the following conditions 14*a159c266SJung-uk Kim * are met: 15*a159c266SJung-uk Kim * 1. Redistributions of source code must retain the above copyright 16*a159c266SJung-uk Kim * notice, this list of conditions, and the following disclaimer, 17*a159c266SJung-uk Kim * without modification. 18*a159c266SJung-uk Kim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 19*a159c266SJung-uk Kim * substantially similar to the "NO WARRANTY" disclaimer below 20*a159c266SJung-uk Kim * ("Disclaimer") and any redistribution must be conditioned upon 21*a159c266SJung-uk Kim * including a substantially similar Disclaimer requirement for further 22*a159c266SJung-uk Kim * binary redistribution. 23*a159c266SJung-uk Kim * 3. Neither the names of the above-listed copyright holders nor the names 24*a159c266SJung-uk Kim * of any contributors may be used to endorse or promote products derived 25*a159c266SJung-uk Kim * from this software without specific prior written permission. 26*a159c266SJung-uk Kim * 27*a159c266SJung-uk Kim * Alternatively, this software may be distributed under the terms of the 28*a159c266SJung-uk Kim * GNU General Public License ("GPL") version 2 as published by the Free 29*a159c266SJung-uk Kim * Software Foundation. 30*a159c266SJung-uk Kim * 31*a159c266SJung-uk Kim * NO WARRANTY 32*a159c266SJung-uk Kim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 33*a159c266SJung-uk Kim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 34*a159c266SJung-uk Kim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 35*a159c266SJung-uk Kim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 36*a159c266SJung-uk Kim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 37*a159c266SJung-uk Kim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 38*a159c266SJung-uk Kim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 39*a159c266SJung-uk Kim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 40*a159c266SJung-uk Kim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 41*a159c266SJung-uk Kim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 42*a159c266SJung-uk Kim * POSSIBILITY OF SUCH DAMAGES. 43*a159c266SJung-uk Kim */ 44*a159c266SJung-uk Kim 45*a159c266SJung-uk Kim #define __DSCONTROL_C__ 46*a159c266SJung-uk Kim 47*a159c266SJung-uk Kim #include <contrib/dev/acpica/include/acpi.h> 48*a159c266SJung-uk Kim #include <contrib/dev/acpica/include/accommon.h> 49*a159c266SJung-uk Kim #include <contrib/dev/acpica/include/amlcode.h> 50*a159c266SJung-uk Kim #include <contrib/dev/acpica/include/acdispat.h> 51*a159c266SJung-uk Kim #include <contrib/dev/acpica/include/acinterp.h> 52*a159c266SJung-uk Kim 53*a159c266SJung-uk Kim #define _COMPONENT ACPI_DISPATCHER 54*a159c266SJung-uk Kim ACPI_MODULE_NAME ("dscontrol") 55*a159c266SJung-uk Kim 56*a159c266SJung-uk Kim 57*a159c266SJung-uk Kim /******************************************************************************* 58*a159c266SJung-uk Kim * 59*a159c266SJung-uk Kim * FUNCTION: AcpiDsExecBeginControlOp 60*a159c266SJung-uk Kim * 61*a159c266SJung-uk Kim * PARAMETERS: WalkList - The list that owns the walk stack 62*a159c266SJung-uk Kim * Op - The control Op 63*a159c266SJung-uk Kim * 64*a159c266SJung-uk Kim * RETURN: Status 65*a159c266SJung-uk Kim * 66*a159c266SJung-uk Kim * DESCRIPTION: Handles all control ops encountered during control method 67*a159c266SJung-uk Kim * execution. 68*a159c266SJung-uk Kim * 69*a159c266SJung-uk Kim ******************************************************************************/ 70*a159c266SJung-uk Kim 71*a159c266SJung-uk Kim ACPI_STATUS 72*a159c266SJung-uk Kim AcpiDsExecBeginControlOp ( 73*a159c266SJung-uk Kim ACPI_WALK_STATE *WalkState, 74*a159c266SJung-uk Kim ACPI_PARSE_OBJECT *Op) 75*a159c266SJung-uk Kim { 76*a159c266SJung-uk Kim ACPI_STATUS Status = AE_OK; 77*a159c266SJung-uk Kim ACPI_GENERIC_STATE *ControlState; 78*a159c266SJung-uk Kim 79*a159c266SJung-uk Kim 80*a159c266SJung-uk Kim ACPI_FUNCTION_NAME (DsExecBeginControlOp); 81*a159c266SJung-uk Kim 82*a159c266SJung-uk Kim 83*a159c266SJung-uk Kim ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p Opcode=%2.2X State=%p\n", 84*a159c266SJung-uk Kim Op, Op->Common.AmlOpcode, WalkState)); 85*a159c266SJung-uk Kim 86*a159c266SJung-uk Kim switch (Op->Common.AmlOpcode) 87*a159c266SJung-uk Kim { 88*a159c266SJung-uk Kim case AML_WHILE_OP: 89*a159c266SJung-uk Kim 90*a159c266SJung-uk Kim /* 91*a159c266SJung-uk Kim * If this is an additional iteration of a while loop, continue. 92*a159c266SJung-uk Kim * There is no need to allocate a new control state. 93*a159c266SJung-uk Kim */ 94*a159c266SJung-uk Kim if (WalkState->ControlState) 95*a159c266SJung-uk Kim { 96*a159c266SJung-uk Kim if (WalkState->ControlState->Control.AmlPredicateStart == 97*a159c266SJung-uk Kim (WalkState->ParserState.Aml - 1)) 98*a159c266SJung-uk Kim { 99*a159c266SJung-uk Kim /* Reset the state to start-of-loop */ 100*a159c266SJung-uk Kim 101*a159c266SJung-uk Kim WalkState->ControlState->Common.State = 102*a159c266SJung-uk Kim ACPI_CONTROL_CONDITIONAL_EXECUTING; 103*a159c266SJung-uk Kim break; 104*a159c266SJung-uk Kim } 105*a159c266SJung-uk Kim } 106*a159c266SJung-uk Kim 107*a159c266SJung-uk Kim /*lint -fallthrough */ 108*a159c266SJung-uk Kim 109*a159c266SJung-uk Kim case AML_IF_OP: 110*a159c266SJung-uk Kim 111*a159c266SJung-uk Kim /* 112*a159c266SJung-uk Kim * IF/WHILE: Create a new control state to manage these 113*a159c266SJung-uk Kim * constructs. We need to manage these as a stack, in order 114*a159c266SJung-uk Kim * to handle nesting. 115*a159c266SJung-uk Kim */ 116*a159c266SJung-uk Kim ControlState = AcpiUtCreateControlState (); 117*a159c266SJung-uk Kim if (!ControlState) 118*a159c266SJung-uk Kim { 119*a159c266SJung-uk Kim Status = AE_NO_MEMORY; 120*a159c266SJung-uk Kim break; 121*a159c266SJung-uk Kim } 122*a159c266SJung-uk Kim /* 123*a159c266SJung-uk Kim * Save a pointer to the predicate for multiple executions 124*a159c266SJung-uk Kim * of a loop 125*a159c266SJung-uk Kim */ 126*a159c266SJung-uk Kim ControlState->Control.AmlPredicateStart = WalkState->ParserState.Aml - 1; 127*a159c266SJung-uk Kim ControlState->Control.PackageEnd = WalkState->ParserState.PkgEnd; 128*a159c266SJung-uk Kim ControlState->Control.Opcode = Op->Common.AmlOpcode; 129*a159c266SJung-uk Kim 130*a159c266SJung-uk Kim 131*a159c266SJung-uk Kim /* Push the control state on this walk's control stack */ 132*a159c266SJung-uk Kim 133*a159c266SJung-uk Kim AcpiUtPushGenericState (&WalkState->ControlState, ControlState); 134*a159c266SJung-uk Kim break; 135*a159c266SJung-uk Kim 136*a159c266SJung-uk Kim case AML_ELSE_OP: 137*a159c266SJung-uk Kim 138*a159c266SJung-uk Kim /* Predicate is in the state object */ 139*a159c266SJung-uk Kim /* If predicate is true, the IF was executed, ignore ELSE part */ 140*a159c266SJung-uk Kim 141*a159c266SJung-uk Kim if (WalkState->LastPredicate) 142*a159c266SJung-uk Kim { 143*a159c266SJung-uk Kim Status = AE_CTRL_TRUE; 144*a159c266SJung-uk Kim } 145*a159c266SJung-uk Kim 146*a159c266SJung-uk Kim break; 147*a159c266SJung-uk Kim 148*a159c266SJung-uk Kim case AML_RETURN_OP: 149*a159c266SJung-uk Kim 150*a159c266SJung-uk Kim break; 151*a159c266SJung-uk Kim 152*a159c266SJung-uk Kim default: 153*a159c266SJung-uk Kim break; 154*a159c266SJung-uk Kim } 155*a159c266SJung-uk Kim 156*a159c266SJung-uk Kim return (Status); 157*a159c266SJung-uk Kim } 158*a159c266SJung-uk Kim 159*a159c266SJung-uk Kim 160*a159c266SJung-uk Kim /******************************************************************************* 161*a159c266SJung-uk Kim * 162*a159c266SJung-uk Kim * FUNCTION: AcpiDsExecEndControlOp 163*a159c266SJung-uk Kim * 164*a159c266SJung-uk Kim * PARAMETERS: WalkList - The list that owns the walk stack 165*a159c266SJung-uk Kim * Op - The control Op 166*a159c266SJung-uk Kim * 167*a159c266SJung-uk Kim * RETURN: Status 168*a159c266SJung-uk Kim * 169*a159c266SJung-uk Kim * DESCRIPTION: Handles all control ops encountered during control method 170*a159c266SJung-uk Kim * execution. 171*a159c266SJung-uk Kim * 172*a159c266SJung-uk Kim ******************************************************************************/ 173*a159c266SJung-uk Kim 174*a159c266SJung-uk Kim ACPI_STATUS 175*a159c266SJung-uk Kim AcpiDsExecEndControlOp ( 176*a159c266SJung-uk Kim ACPI_WALK_STATE *WalkState, 177*a159c266SJung-uk Kim ACPI_PARSE_OBJECT *Op) 178*a159c266SJung-uk Kim { 179*a159c266SJung-uk Kim ACPI_STATUS Status = AE_OK; 180*a159c266SJung-uk Kim ACPI_GENERIC_STATE *ControlState; 181*a159c266SJung-uk Kim 182*a159c266SJung-uk Kim 183*a159c266SJung-uk Kim ACPI_FUNCTION_NAME (DsExecEndControlOp); 184*a159c266SJung-uk Kim 185*a159c266SJung-uk Kim 186*a159c266SJung-uk Kim switch (Op->Common.AmlOpcode) 187*a159c266SJung-uk Kim { 188*a159c266SJung-uk Kim case AML_IF_OP: 189*a159c266SJung-uk Kim 190*a159c266SJung-uk Kim ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[IF_OP] Op=%p\n", Op)); 191*a159c266SJung-uk Kim 192*a159c266SJung-uk Kim /* 193*a159c266SJung-uk Kim * Save the result of the predicate in case there is an 194*a159c266SJung-uk Kim * ELSE to come 195*a159c266SJung-uk Kim */ 196*a159c266SJung-uk Kim WalkState->LastPredicate = 197*a159c266SJung-uk Kim (BOOLEAN) WalkState->ControlState->Common.Value; 198*a159c266SJung-uk Kim 199*a159c266SJung-uk Kim /* 200*a159c266SJung-uk Kim * Pop the control state that was created at the start 201*a159c266SJung-uk Kim * of the IF and free it 202*a159c266SJung-uk Kim */ 203*a159c266SJung-uk Kim ControlState = AcpiUtPopGenericState (&WalkState->ControlState); 204*a159c266SJung-uk Kim AcpiUtDeleteGenericState (ControlState); 205*a159c266SJung-uk Kim break; 206*a159c266SJung-uk Kim 207*a159c266SJung-uk Kim 208*a159c266SJung-uk Kim case AML_ELSE_OP: 209*a159c266SJung-uk Kim 210*a159c266SJung-uk Kim break; 211*a159c266SJung-uk Kim 212*a159c266SJung-uk Kim 213*a159c266SJung-uk Kim case AML_WHILE_OP: 214*a159c266SJung-uk Kim 215*a159c266SJung-uk Kim ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[WHILE_OP] Op=%p\n", Op)); 216*a159c266SJung-uk Kim 217*a159c266SJung-uk Kim ControlState = WalkState->ControlState; 218*a159c266SJung-uk Kim if (ControlState->Common.Value) 219*a159c266SJung-uk Kim { 220*a159c266SJung-uk Kim /* Predicate was true, the body of the loop was just executed */ 221*a159c266SJung-uk Kim 222*a159c266SJung-uk Kim /* 223*a159c266SJung-uk Kim * This loop counter mechanism allows the interpreter to escape 224*a159c266SJung-uk Kim * possibly infinite loops. This can occur in poorly written AML 225*a159c266SJung-uk Kim * when the hardware does not respond within a while loop and the 226*a159c266SJung-uk Kim * loop does not implement a timeout. 227*a159c266SJung-uk Kim */ 228*a159c266SJung-uk Kim ControlState->Control.LoopCount++; 229*a159c266SJung-uk Kim if (ControlState->Control.LoopCount > ACPI_MAX_LOOP_ITERATIONS) 230*a159c266SJung-uk Kim { 231*a159c266SJung-uk Kim Status = AE_AML_INFINITE_LOOP; 232*a159c266SJung-uk Kim break; 233*a159c266SJung-uk Kim } 234*a159c266SJung-uk Kim 235*a159c266SJung-uk Kim /* 236*a159c266SJung-uk Kim * Go back and evaluate the predicate and maybe execute the loop 237*a159c266SJung-uk Kim * another time 238*a159c266SJung-uk Kim */ 239*a159c266SJung-uk Kim Status = AE_CTRL_PENDING; 240*a159c266SJung-uk Kim WalkState->AmlLastWhile = ControlState->Control.AmlPredicateStart; 241*a159c266SJung-uk Kim break; 242*a159c266SJung-uk Kim } 243*a159c266SJung-uk Kim 244*a159c266SJung-uk Kim /* Predicate was false, terminate this while loop */ 245*a159c266SJung-uk Kim 246*a159c266SJung-uk Kim ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 247*a159c266SJung-uk Kim "[WHILE_OP] termination! Op=%p\n",Op)); 248*a159c266SJung-uk Kim 249*a159c266SJung-uk Kim /* Pop this control state and free it */ 250*a159c266SJung-uk Kim 251*a159c266SJung-uk Kim ControlState = AcpiUtPopGenericState (&WalkState->ControlState); 252*a159c266SJung-uk Kim AcpiUtDeleteGenericState (ControlState); 253*a159c266SJung-uk Kim break; 254*a159c266SJung-uk Kim 255*a159c266SJung-uk Kim 256*a159c266SJung-uk Kim case AML_RETURN_OP: 257*a159c266SJung-uk Kim 258*a159c266SJung-uk Kim ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 259*a159c266SJung-uk Kim "[RETURN_OP] Op=%p Arg=%p\n",Op, Op->Common.Value.Arg)); 260*a159c266SJung-uk Kim 261*a159c266SJung-uk Kim /* 262*a159c266SJung-uk Kim * One optional operand -- the return value 263*a159c266SJung-uk Kim * It can be either an immediate operand or a result that 264*a159c266SJung-uk Kim * has been bubbled up the tree 265*a159c266SJung-uk Kim */ 266*a159c266SJung-uk Kim if (Op->Common.Value.Arg) 267*a159c266SJung-uk Kim { 268*a159c266SJung-uk Kim /* Since we have a real Return(), delete any implicit return */ 269*a159c266SJung-uk Kim 270*a159c266SJung-uk Kim AcpiDsClearImplicitReturn (WalkState); 271*a159c266SJung-uk Kim 272*a159c266SJung-uk Kim /* Return statement has an immediate operand */ 273*a159c266SJung-uk Kim 274*a159c266SJung-uk Kim Status = AcpiDsCreateOperands (WalkState, Op->Common.Value.Arg); 275*a159c266SJung-uk Kim if (ACPI_FAILURE (Status)) 276*a159c266SJung-uk Kim { 277*a159c266SJung-uk Kim return (Status); 278*a159c266SJung-uk Kim } 279*a159c266SJung-uk Kim 280*a159c266SJung-uk Kim /* 281*a159c266SJung-uk Kim * If value being returned is a Reference (such as 282*a159c266SJung-uk Kim * an arg or local), resolve it now because it may 283*a159c266SJung-uk Kim * cease to exist at the end of the method. 284*a159c266SJung-uk Kim */ 285*a159c266SJung-uk Kim Status = AcpiExResolveToValue (&WalkState->Operands [0], WalkState); 286*a159c266SJung-uk Kim if (ACPI_FAILURE (Status)) 287*a159c266SJung-uk Kim { 288*a159c266SJung-uk Kim return (Status); 289*a159c266SJung-uk Kim } 290*a159c266SJung-uk Kim 291*a159c266SJung-uk Kim /* 292*a159c266SJung-uk Kim * Get the return value and save as the last result 293*a159c266SJung-uk Kim * value. This is the only place where WalkState->ReturnDesc 294*a159c266SJung-uk Kim * is set to anything other than zero! 295*a159c266SJung-uk Kim */ 296*a159c266SJung-uk Kim WalkState->ReturnDesc = WalkState->Operands[0]; 297*a159c266SJung-uk Kim } 298*a159c266SJung-uk Kim else if (WalkState->ResultCount) 299*a159c266SJung-uk Kim { 300*a159c266SJung-uk Kim /* Since we have a real Return(), delete any implicit return */ 301*a159c266SJung-uk Kim 302*a159c266SJung-uk Kim AcpiDsClearImplicitReturn (WalkState); 303*a159c266SJung-uk Kim 304*a159c266SJung-uk Kim /* 305*a159c266SJung-uk Kim * The return value has come from a previous calculation. 306*a159c266SJung-uk Kim * 307*a159c266SJung-uk Kim * If value being returned is a Reference (such as 308*a159c266SJung-uk Kim * an arg or local), resolve it now because it may 309*a159c266SJung-uk Kim * cease to exist at the end of the method. 310*a159c266SJung-uk Kim * 311*a159c266SJung-uk Kim * Allow references created by the Index operator to return 312*a159c266SJung-uk Kim * unchanged. 313*a159c266SJung-uk Kim */ 314*a159c266SJung-uk Kim if ((ACPI_GET_DESCRIPTOR_TYPE (WalkState->Results->Results.ObjDesc[0]) == ACPI_DESC_TYPE_OPERAND) && 315*a159c266SJung-uk Kim ((WalkState->Results->Results.ObjDesc [0])->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) && 316*a159c266SJung-uk Kim ((WalkState->Results->Results.ObjDesc [0])->Reference.Class != ACPI_REFCLASS_INDEX)) 317*a159c266SJung-uk Kim { 318*a159c266SJung-uk Kim Status = AcpiExResolveToValue (&WalkState->Results->Results.ObjDesc [0], WalkState); 319*a159c266SJung-uk Kim if (ACPI_FAILURE (Status)) 320*a159c266SJung-uk Kim { 321*a159c266SJung-uk Kim return (Status); 322*a159c266SJung-uk Kim } 323*a159c266SJung-uk Kim } 324*a159c266SJung-uk Kim 325*a159c266SJung-uk Kim WalkState->ReturnDesc = WalkState->Results->Results.ObjDesc [0]; 326*a159c266SJung-uk Kim } 327*a159c266SJung-uk Kim else 328*a159c266SJung-uk Kim { 329*a159c266SJung-uk Kim /* No return operand */ 330*a159c266SJung-uk Kim 331*a159c266SJung-uk Kim if (WalkState->NumOperands) 332*a159c266SJung-uk Kim { 333*a159c266SJung-uk Kim AcpiUtRemoveReference (WalkState->Operands [0]); 334*a159c266SJung-uk Kim } 335*a159c266SJung-uk Kim 336*a159c266SJung-uk Kim WalkState->Operands [0] = NULL; 337*a159c266SJung-uk Kim WalkState->NumOperands = 0; 338*a159c266SJung-uk Kim WalkState->ReturnDesc = NULL; 339*a159c266SJung-uk Kim } 340*a159c266SJung-uk Kim 341*a159c266SJung-uk Kim 342*a159c266SJung-uk Kim ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 343*a159c266SJung-uk Kim "Completed RETURN_OP State=%p, RetVal=%p\n", 344*a159c266SJung-uk Kim WalkState, WalkState->ReturnDesc)); 345*a159c266SJung-uk Kim 346*a159c266SJung-uk Kim /* End the control method execution right now */ 347*a159c266SJung-uk Kim 348*a159c266SJung-uk Kim Status = AE_CTRL_TERMINATE; 349*a159c266SJung-uk Kim break; 350*a159c266SJung-uk Kim 351*a159c266SJung-uk Kim 352*a159c266SJung-uk Kim case AML_NOOP_OP: 353*a159c266SJung-uk Kim 354*a159c266SJung-uk Kim /* Just do nothing! */ 355*a159c266SJung-uk Kim break; 356*a159c266SJung-uk Kim 357*a159c266SJung-uk Kim 358*a159c266SJung-uk Kim case AML_BREAK_POINT_OP: 359*a159c266SJung-uk Kim 360*a159c266SJung-uk Kim /* 361*a159c266SJung-uk Kim * Set the single-step flag. This will cause the debugger (if present) 362*a159c266SJung-uk Kim * to break to the console within the AML debugger at the start of the 363*a159c266SJung-uk Kim * next AML instruction. 364*a159c266SJung-uk Kim */ 365*a159c266SJung-uk Kim ACPI_DEBUGGER_EXEC ( 366*a159c266SJung-uk Kim AcpiGbl_CmSingleStep = TRUE); 367*a159c266SJung-uk Kim ACPI_DEBUGGER_EXEC ( 368*a159c266SJung-uk Kim AcpiOsPrintf ("**break** Executed AML BreakPoint opcode\n")); 369*a159c266SJung-uk Kim 370*a159c266SJung-uk Kim /* Call to the OSL in case OS wants a piece of the action */ 371*a159c266SJung-uk Kim 372*a159c266SJung-uk Kim Status = AcpiOsSignal (ACPI_SIGNAL_BREAKPOINT, 373*a159c266SJung-uk Kim "Executed AML Breakpoint opcode"); 374*a159c266SJung-uk Kim break; 375*a159c266SJung-uk Kim 376*a159c266SJung-uk Kim 377*a159c266SJung-uk Kim case AML_BREAK_OP: 378*a159c266SJung-uk Kim case AML_CONTINUE_OP: /* ACPI 2.0 */ 379*a159c266SJung-uk Kim 380*a159c266SJung-uk Kim 381*a159c266SJung-uk Kim /* Pop and delete control states until we find a while */ 382*a159c266SJung-uk Kim 383*a159c266SJung-uk Kim while (WalkState->ControlState && 384*a159c266SJung-uk Kim (WalkState->ControlState->Control.Opcode != AML_WHILE_OP)) 385*a159c266SJung-uk Kim { 386*a159c266SJung-uk Kim ControlState = AcpiUtPopGenericState (&WalkState->ControlState); 387*a159c266SJung-uk Kim AcpiUtDeleteGenericState (ControlState); 388*a159c266SJung-uk Kim } 389*a159c266SJung-uk Kim 390*a159c266SJung-uk Kim /* No while found? */ 391*a159c266SJung-uk Kim 392*a159c266SJung-uk Kim if (!WalkState->ControlState) 393*a159c266SJung-uk Kim { 394*a159c266SJung-uk Kim return (AE_AML_NO_WHILE); 395*a159c266SJung-uk Kim } 396*a159c266SJung-uk Kim 397*a159c266SJung-uk Kim /* Was: WalkState->AmlLastWhile = WalkState->ControlState->Control.AmlPredicateStart; */ 398*a159c266SJung-uk Kim 399*a159c266SJung-uk Kim WalkState->AmlLastWhile = WalkState->ControlState->Control.PackageEnd; 400*a159c266SJung-uk Kim 401*a159c266SJung-uk Kim /* Return status depending on opcode */ 402*a159c266SJung-uk Kim 403*a159c266SJung-uk Kim if (Op->Common.AmlOpcode == AML_BREAK_OP) 404*a159c266SJung-uk Kim { 405*a159c266SJung-uk Kim Status = AE_CTRL_BREAK; 406*a159c266SJung-uk Kim } 407*a159c266SJung-uk Kim else 408*a159c266SJung-uk Kim { 409*a159c266SJung-uk Kim Status = AE_CTRL_CONTINUE; 410*a159c266SJung-uk Kim } 411*a159c266SJung-uk Kim break; 412*a159c266SJung-uk Kim 413*a159c266SJung-uk Kim 414*a159c266SJung-uk Kim default: 415*a159c266SJung-uk Kim 416*a159c266SJung-uk Kim ACPI_ERROR ((AE_INFO, "Unknown control opcode=0x%X Op=%p", 417*a159c266SJung-uk Kim Op->Common.AmlOpcode, Op)); 418*a159c266SJung-uk Kim 419*a159c266SJung-uk Kim Status = AE_AML_BAD_OPCODE; 420*a159c266SJung-uk Kim break; 421*a159c266SJung-uk Kim } 422*a159c266SJung-uk Kim 423*a159c266SJung-uk Kim return (Status); 424*a159c266SJung-uk Kim } 425