![]() |
|
|||
File indexing completed on 2025-05-11 08:24:02
0001 /****************************************************************************** 0002 * 0003 * Module Name: dscontrol - Support for execution control opcodes - 0004 * if/else/while/return 0005 * 0006 *****************************************************************************/ 0007 0008 /****************************************************************************** 0009 * 0010 * 1. Copyright Notice 0011 * 0012 * Some or all of this work - Copyright (c) 1999 - 2024, Intel Corp. 0013 * All rights reserved. 0014 * 0015 * 2. License 0016 * 0017 * 2.1. This is your license from Intel Corp. under its intellectual property 0018 * rights. You may have additional license terms from the party that provided 0019 * you this software, covering your right to use that party's intellectual 0020 * property rights. 0021 * 0022 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 0023 * copy of the source code appearing in this file ("Covered Code") an 0024 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 0025 * base code distributed originally by Intel ("Original Intel Code") to copy, 0026 * make derivatives, distribute, use and display any portion of the Covered 0027 * Code in any form, with the right to sublicense such rights; and 0028 * 0029 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 0030 * license (with the right to sublicense), under only those claims of Intel 0031 * patents that are infringed by the Original Intel Code, to make, use, sell, 0032 * offer to sell, and import the Covered Code and derivative works thereof 0033 * solely to the minimum extent necessary to exercise the above copyright 0034 * license, and in no event shall the patent license extend to any additions 0035 * to or modifications of the Original Intel Code. No other license or right 0036 * is granted directly or by implication, estoppel or otherwise; 0037 * 0038 * The above copyright and patent license is granted only if the following 0039 * conditions are met: 0040 * 0041 * 3. Conditions 0042 * 0043 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 0044 * Redistribution of source code of any substantial portion of the Covered 0045 * Code or modification with rights to further distribute source must include 0046 * the above Copyright Notice, the above License, this list of Conditions, 0047 * and the following Disclaimer and Export Compliance provision. In addition, 0048 * Licensee must cause all Covered Code to which Licensee contributes to 0049 * contain a file documenting the changes Licensee made to create that Covered 0050 * Code and the date of any change. Licensee must include in that file the 0051 * documentation of any changes made by any predecessor Licensee. Licensee 0052 * must include a prominent statement that the modification is derived, 0053 * directly or indirectly, from Original Intel Code. 0054 * 0055 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 0056 * Redistribution of source code of any substantial portion of the Covered 0057 * Code or modification without rights to further distribute source must 0058 * include the following Disclaimer and Export Compliance provision in the 0059 * documentation and/or other materials provided with distribution. In 0060 * addition, Licensee may not authorize further sublicense of source of any 0061 * portion of the Covered Code, and must include terms to the effect that the 0062 * license from Licensee to its licensee is limited to the intellectual 0063 * property embodied in the software Licensee provides to its licensee, and 0064 * not to intellectual property embodied in modifications its licensee may 0065 * make. 0066 * 0067 * 3.3. Redistribution of Executable. Redistribution in executable form of any 0068 * substantial portion of the Covered Code or modification must reproduce the 0069 * above Copyright Notice, and the following Disclaimer and Export Compliance 0070 * provision in the documentation and/or other materials provided with the 0071 * distribution. 0072 * 0073 * 3.4. Intel retains all right, title, and interest in and to the Original 0074 * Intel Code. 0075 * 0076 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 0077 * Intel shall be used in advertising or otherwise to promote the sale, use or 0078 * other dealings in products derived from or relating to the Covered Code 0079 * without prior written authorization from Intel. 0080 * 0081 * 4. Disclaimer and Export Compliance 0082 * 0083 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 0084 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 0085 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 0086 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 0087 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 0088 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 0089 * PARTICULAR PURPOSE. 0090 * 0091 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 0092 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 0093 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 0094 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 0095 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 0096 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 0097 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 0098 * LIMITED REMEDY. 0099 * 0100 * 4.3. Licensee shall not export, either directly or indirectly, any of this 0101 * software or system incorporating such software without first obtaining any 0102 * required license or other approval from the U. S. Department of Commerce or 0103 * any other agency or department of the United States Government. In the 0104 * event Licensee exports any such software from the United States or 0105 * re-exports any such software from a foreign destination, Licensee shall 0106 * ensure that the distribution and export/re-export of the software is in 0107 * compliance with all laws, regulations, orders, or other restrictions of the 0108 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 0109 * any of its subsidiaries will export/re-export any technical data, process, 0110 * software, or service, directly or indirectly, to any country for which the 0111 * United States government or any agency thereof requires an export license, 0112 * other governmental approval, or letter of assurance, without first obtaining 0113 * such license, approval or letter. 0114 * 0115 ***************************************************************************** 0116 * 0117 * Alternatively, you may choose to be licensed under the terms of the 0118 * following license: 0119 * 0120 * Redistribution and use in source and binary forms, with or without 0121 * modification, are permitted provided that the following conditions 0122 * are met: 0123 * 1. Redistributions of source code must retain the above copyright 0124 * notice, this list of conditions, and the following disclaimer, 0125 * without modification. 0126 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 0127 * substantially similar to the "NO WARRANTY" disclaimer below 0128 * ("Disclaimer") and any redistribution must be conditioned upon 0129 * including a substantially similar Disclaimer requirement for further 0130 * binary redistribution. 0131 * 3. Neither the names of the above-listed copyright holders nor the names 0132 * of any contributors may be used to endorse or promote products derived 0133 * from this software without specific prior written permission. 0134 * 0135 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 0136 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 0137 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 0138 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 0139 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 0140 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 0141 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 0142 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 0143 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 0144 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 0145 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 0146 * 0147 * Alternatively, you may choose to be licensed under the terms of the 0148 * GNU General Public License ("GPL") version 2 as published by the Free 0149 * Software Foundation. 0150 * 0151 *****************************************************************************/ 0152 0153 #include "acpi.h" 0154 #include "accommon.h" 0155 #include "amlcode.h" 0156 #include "acdispat.h" 0157 #include "acinterp.h" 0158 #include "acdebug.h" 0159 0160 #define _COMPONENT ACPI_DISPATCHER 0161 ACPI_MODULE_NAME ("dscontrol") 0162 0163 0164 /******************************************************************************* 0165 * 0166 * FUNCTION: AcpiDsExecBeginControlOp 0167 * 0168 * PARAMETERS: WalkList - The list that owns the walk stack 0169 * Op - The control Op 0170 * 0171 * RETURN: Status 0172 * 0173 * DESCRIPTION: Handles all control ops encountered during control method 0174 * execution. 0175 * 0176 ******************************************************************************/ 0177 0178 ACPI_STATUS 0179 AcpiDsExecBeginControlOp ( 0180 ACPI_WALK_STATE *WalkState, 0181 ACPI_PARSE_OBJECT *Op) 0182 { 0183 ACPI_STATUS Status = AE_OK; 0184 ACPI_GENERIC_STATE *ControlState; 0185 0186 0187 ACPI_FUNCTION_NAME (DsExecBeginControlOp); 0188 0189 0190 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p Opcode=%2.2X State=%p\n", 0191 Op, Op->Common.AmlOpcode, WalkState)); 0192 0193 switch (Op->Common.AmlOpcode) 0194 { 0195 case AML_WHILE_OP: 0196 /* 0197 * If this is an additional iteration of a while loop, continue. 0198 * There is no need to allocate a new control state. 0199 */ 0200 if (WalkState->ControlState) 0201 { 0202 if (WalkState->ControlState->Control.AmlPredicateStart == 0203 (WalkState->ParserState.Aml - 1)) 0204 { 0205 /* Reset the state to start-of-loop */ 0206 0207 WalkState->ControlState->Common.State = 0208 ACPI_CONTROL_CONDITIONAL_EXECUTING; 0209 break; 0210 } 0211 } 0212 0213 ACPI_FALLTHROUGH; 0214 0215 case AML_IF_OP: 0216 /* 0217 * IF/WHILE: Create a new control state to manage these 0218 * constructs. We need to manage these as a stack, in order 0219 * to handle nesting. 0220 */ 0221 ControlState = AcpiUtCreateControlState (); 0222 if (!ControlState) 0223 { 0224 Status = AE_NO_MEMORY; 0225 break; 0226 } 0227 /* 0228 * Save a pointer to the predicate for multiple executions 0229 * of a loop 0230 */ 0231 ControlState->Control.AmlPredicateStart = 0232 WalkState->ParserState.Aml - 1; 0233 ControlState->Control.PackageEnd = 0234 WalkState->ParserState.PkgEnd; 0235 ControlState->Control.Opcode = 0236 Op->Common.AmlOpcode; 0237 ControlState->Control.LoopTimeout = AcpiOsGetTimer () + 0238 ((UINT64) AcpiGbl_MaxLoopIterations * ACPI_100NSEC_PER_SEC); 0239 0240 /* Push the control state on this walk's control stack */ 0241 0242 AcpiUtPushGenericState (&WalkState->ControlState, ControlState); 0243 break; 0244 0245 case AML_ELSE_OP: 0246 0247 /* Predicate is in the state object */ 0248 /* If predicate is true, the IF was executed, ignore ELSE part */ 0249 0250 if (WalkState->LastPredicate) 0251 { 0252 Status = AE_CTRL_TRUE; 0253 } 0254 0255 break; 0256 0257 case AML_RETURN_OP: 0258 0259 break; 0260 0261 default: 0262 0263 break; 0264 } 0265 0266 return (Status); 0267 } 0268 0269 0270 /******************************************************************************* 0271 * 0272 * FUNCTION: AcpiDsExecEndControlOp 0273 * 0274 * PARAMETERS: WalkList - The list that owns the walk stack 0275 * Op - The control Op 0276 * 0277 * RETURN: Status 0278 * 0279 * DESCRIPTION: Handles all control ops encountered during control method 0280 * execution. 0281 * 0282 ******************************************************************************/ 0283 0284 ACPI_STATUS 0285 AcpiDsExecEndControlOp ( 0286 ACPI_WALK_STATE *WalkState, 0287 ACPI_PARSE_OBJECT *Op) 0288 { 0289 ACPI_STATUS Status = AE_OK; 0290 ACPI_GENERIC_STATE *ControlState; 0291 0292 0293 ACPI_FUNCTION_NAME (DsExecEndControlOp); 0294 0295 0296 switch (Op->Common.AmlOpcode) 0297 { 0298 case AML_IF_OP: 0299 0300 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[IF_OP] Op=%p\n", Op)); 0301 0302 /* 0303 * Save the result of the predicate in case there is an 0304 * ELSE to come 0305 */ 0306 WalkState->LastPredicate = 0307 (BOOLEAN) WalkState->ControlState->Common.Value; 0308 0309 /* 0310 * Pop the control state that was created at the start 0311 * of the IF and free it 0312 */ 0313 ControlState = AcpiUtPopGenericState (&WalkState->ControlState); 0314 AcpiUtDeleteGenericState (ControlState); 0315 break; 0316 0317 case AML_ELSE_OP: 0318 0319 break; 0320 0321 case AML_WHILE_OP: 0322 0323 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[WHILE_OP] Op=%p\n", Op)); 0324 0325 ControlState = WalkState->ControlState; 0326 if (ControlState->Common.Value) 0327 { 0328 /* Predicate was true, the body of the loop was just executed */ 0329 0330 /* 0331 * This infinite loop detection mechanism allows the interpreter 0332 * to escape possibly infinite loops. This can occur in poorly 0333 * written AML when the hardware does not respond within a while 0334 * loop and the loop does not implement a timeout. 0335 */ 0336 if (ACPI_TIME_AFTER (AcpiOsGetTimer (), 0337 ControlState->Control.LoopTimeout)) 0338 { 0339 Status = AE_AML_LOOP_TIMEOUT; 0340 break; 0341 } 0342 0343 /* 0344 * Go back and evaluate the predicate and maybe execute the loop 0345 * another time 0346 */ 0347 Status = AE_CTRL_PENDING; 0348 WalkState->AmlLastWhile = 0349 ControlState->Control.AmlPredicateStart; 0350 break; 0351 } 0352 0353 /* Predicate was false, terminate this while loop */ 0354 0355 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 0356 "[WHILE_OP] termination! Op=%p\n",Op)); 0357 0358 /* Pop this control state and free it */ 0359 0360 ControlState = AcpiUtPopGenericState (&WalkState->ControlState); 0361 AcpiUtDeleteGenericState (ControlState); 0362 break; 0363 0364 case AML_RETURN_OP: 0365 0366 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 0367 "[RETURN_OP] Op=%p Arg=%p\n",Op, Op->Common.Value.Arg)); 0368 0369 /* 0370 * One optional operand -- the return value 0371 * It can be either an immediate operand or a result that 0372 * has been bubbled up the tree 0373 */ 0374 if (Op->Common.Value.Arg) 0375 { 0376 /* Since we have a real Return(), delete any implicit return */ 0377 0378 AcpiDsClearImplicitReturn (WalkState); 0379 0380 /* Return statement has an immediate operand */ 0381 0382 Status = AcpiDsCreateOperands (WalkState, Op->Common.Value.Arg); 0383 if (ACPI_FAILURE (Status)) 0384 { 0385 return (Status); 0386 } 0387 0388 /* 0389 * If value being returned is a Reference (such as 0390 * an arg or local), resolve it now because it may 0391 * cease to exist at the end of the method. 0392 */ 0393 Status = AcpiExResolveToValue ( 0394 &WalkState->Operands [0], WalkState); 0395 if (ACPI_FAILURE (Status)) 0396 { 0397 return (Status); 0398 } 0399 0400 /* 0401 * Get the return value and save as the last result 0402 * value. This is the only place where WalkState->ReturnDesc 0403 * is set to anything other than zero! 0404 */ 0405 WalkState->ReturnDesc = WalkState->Operands[0]; 0406 } 0407 else if (WalkState->ResultCount) 0408 { 0409 /* Since we have a real Return(), delete any implicit return */ 0410 0411 AcpiDsClearImplicitReturn (WalkState); 0412 0413 /* 0414 * The return value has come from a previous calculation. 0415 * 0416 * If value being returned is a Reference (such as 0417 * an arg or local), resolve it now because it may 0418 * cease to exist at the end of the method. 0419 * 0420 * Allow references created by the Index operator to return 0421 * unchanged. 0422 */ 0423 if ((ACPI_GET_DESCRIPTOR_TYPE (WalkState->Results->Results.ObjDesc[0]) == 0424 ACPI_DESC_TYPE_OPERAND) && 0425 ((WalkState->Results->Results.ObjDesc [0])->Common.Type == 0426 ACPI_TYPE_LOCAL_REFERENCE) && 0427 ((WalkState->Results->Results.ObjDesc [0])->Reference.Class != 0428 ACPI_REFCLASS_INDEX)) 0429 { 0430 Status = AcpiExResolveToValue ( 0431 &WalkState->Results->Results.ObjDesc [0], WalkState); 0432 if (ACPI_FAILURE (Status)) 0433 { 0434 return (Status); 0435 } 0436 } 0437 0438 WalkState->ReturnDesc = WalkState->Results->Results.ObjDesc [0]; 0439 } 0440 else 0441 { 0442 /* No return operand */ 0443 0444 if (WalkState->NumOperands) 0445 { 0446 AcpiUtRemoveReference (WalkState->Operands [0]); 0447 } 0448 0449 WalkState->Operands[0] = NULL; 0450 WalkState->NumOperands = 0; 0451 WalkState->ReturnDesc = NULL; 0452 } 0453 0454 0455 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 0456 "Completed RETURN_OP State=%p, RetVal=%p\n", 0457 WalkState, WalkState->ReturnDesc)); 0458 0459 /* End the control method execution right now */ 0460 0461 Status = AE_CTRL_TERMINATE; 0462 break; 0463 0464 case AML_NOOP_OP: 0465 0466 /* Just do nothing! */ 0467 0468 break; 0469 0470 case AML_BREAKPOINT_OP: 0471 0472 AcpiDbSignalBreakPoint (WalkState); 0473 0474 /* Call to the OSL in case OS wants a piece of the action */ 0475 0476 Status = AcpiOsSignal (ACPI_SIGNAL_BREAKPOINT, 0477 "Executed AML Breakpoint opcode"); 0478 break; 0479 0480 case AML_BREAK_OP: 0481 case AML_CONTINUE_OP: /* ACPI 2.0 */ 0482 0483 /* Pop and delete control states until we find a while */ 0484 0485 while (WalkState->ControlState && 0486 (WalkState->ControlState->Control.Opcode != AML_WHILE_OP)) 0487 { 0488 ControlState = AcpiUtPopGenericState (&WalkState->ControlState); 0489 AcpiUtDeleteGenericState (ControlState); 0490 } 0491 0492 /* No while found? */ 0493 0494 if (!WalkState->ControlState) 0495 { 0496 return (AE_AML_NO_WHILE); 0497 } 0498 0499 /* Was: WalkState->AmlLastWhile = WalkState->ControlState->Control.AmlPredicateStart; */ 0500 0501 WalkState->AmlLastWhile = 0502 WalkState->ControlState->Control.PackageEnd; 0503 0504 /* Return status depending on opcode */ 0505 0506 if (Op->Common.AmlOpcode == AML_BREAK_OP) 0507 { 0508 Status = AE_CTRL_BREAK; 0509 } 0510 else 0511 { 0512 Status = AE_CTRL_CONTINUE; 0513 } 0514 break; 0515 0516 default: 0517 0518 ACPI_ERROR ((AE_INFO, "Unknown control opcode=0x%X Op=%p", 0519 Op->Common.AmlOpcode, Op)); 0520 0521 Status = AE_AML_BAD_OPCODE; 0522 break; 0523 } 0524 0525 return (Status); 0526 }
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |