Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygendsutils.c
Go to the documentation of this file.
00001 /******************************************************************************* 00002 * 00003 * Module Name: dsutils - Dispatcher utilities 00004 * 00005 ******************************************************************************/ 00006 00007 /****************************************************************************** 00008 * 00009 * 1. Copyright Notice 00010 * 00011 * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp. 00012 * All rights reserved. 00013 * 00014 * 2. License 00015 * 00016 * 2.1. This is your license from Intel Corp. under its intellectual property 00017 * rights. You may have additional license terms from the party that provided 00018 * you this software, covering your right to use that party's intellectual 00019 * property rights. 00020 * 00021 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 00022 * copy of the source code appearing in this file ("Covered Code") an 00023 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 00024 * base code distributed originally by Intel ("Original Intel Code") to copy, 00025 * make derivatives, distribute, use and display any portion of the Covered 00026 * Code in any form, with the right to sublicense such rights; and 00027 * 00028 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 00029 * license (with the right to sublicense), under only those claims of Intel 00030 * patents that are infringed by the Original Intel Code, to make, use, sell, 00031 * offer to sell, and import the Covered Code and derivative works thereof 00032 * solely to the minimum extent necessary to exercise the above copyright 00033 * license, and in no event shall the patent license extend to any additions 00034 * to or modifications of the Original Intel Code. No other license or right 00035 * is granted directly or by implication, estoppel or otherwise; 00036 * 00037 * The above copyright and patent license is granted only if the following 00038 * conditions are met: 00039 * 00040 * 3. Conditions 00041 * 00042 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 00043 * Redistribution of source code of any substantial portion of the Covered 00044 * Code or modification with rights to further distribute source must include 00045 * the above Copyright Notice, the above License, this list of Conditions, 00046 * and the following Disclaimer and Export Compliance provision. In addition, 00047 * Licensee must cause all Covered Code to which Licensee contributes to 00048 * contain a file documenting the changes Licensee made to create that Covered 00049 * Code and the date of any change. Licensee must include in that file the 00050 * documentation of any changes made by any predecessor Licensee. Licensee 00051 * must include a prominent statement that the modification is derived, 00052 * directly or indirectly, from Original Intel Code. 00053 * 00054 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 00055 * Redistribution of source code of any substantial portion of the Covered 00056 * Code or modification without rights to further distribute source must 00057 * include the following Disclaimer and Export Compliance provision in the 00058 * documentation and/or other materials provided with distribution. In 00059 * addition, Licensee may not authorize further sublicense of source of any 00060 * portion of the Covered Code, and must include terms to the effect that the 00061 * license from Licensee to its licensee is limited to the intellectual 00062 * property embodied in the software Licensee provides to its licensee, and 00063 * not to intellectual property embodied in modifications its licensee may 00064 * make. 00065 * 00066 * 3.3. Redistribution of Executable. Redistribution in executable form of any 00067 * substantial portion of the Covered Code or modification must reproduce the 00068 * above Copyright Notice, and the following Disclaimer and Export Compliance 00069 * provision in the documentation and/or other materials provided with the 00070 * distribution. 00071 * 00072 * 3.4. Intel retains all right, title, and interest in and to the Original 00073 * Intel Code. 00074 * 00075 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 00076 * Intel shall be used in advertising or otherwise to promote the sale, use or 00077 * other dealings in products derived from or relating to the Covered Code 00078 * without prior written authorization from Intel. 00079 * 00080 * 4. Disclaimer and Export Compliance 00081 * 00082 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 00083 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 00084 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 00085 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 00086 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 00087 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 00088 * PARTICULAR PURPOSE. 00089 * 00090 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 00091 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 00092 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 00093 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 00094 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 00095 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 00096 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 00097 * LIMITED REMEDY. 00098 * 00099 * 4.3. Licensee shall not export, either directly or indirectly, any of this 00100 * software or system incorporating such software without first obtaining any 00101 * required license or other approval from the U. S. Department of Commerce or 00102 * any other agency or department of the United States Government. In the 00103 * event Licensee exports any such software from the United States or 00104 * re-exports any such software from a foreign destination, Licensee shall 00105 * ensure that the distribution and export/re-export of the software is in 00106 * compliance with all laws, regulations, orders, or other restrictions of the 00107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 00108 * any of its subsidiaries will export/re-export any technical data, process, 00109 * software, or service, directly or indirectly, to any country for which the 00110 * United States government or any agency thereof requires an export license, 00111 * other governmental approval, or letter of assurance, without first obtaining 00112 * such license, approval or letter. 00113 * 00114 *****************************************************************************/ 00115 00116 #define __DSUTILS_C__ 00117 00118 #include "acpi.h" 00119 #include "accommon.h" 00120 #include "acparser.h" 00121 #include "amlcode.h" 00122 #include "acdispat.h" 00123 #include "acinterp.h" 00124 #include "acnamesp.h" 00125 #include "acdebug.h" 00126 00127 #define _COMPONENT ACPI_DISPATCHER 00128 ACPI_MODULE_NAME ("dsutils") 00129 00130 00131 /******************************************************************************* 00132 * 00133 * FUNCTION: AcpiDsClearImplicitReturn 00134 * 00135 * PARAMETERS: WalkState - Current State 00136 * 00137 * RETURN: None. 00138 * 00139 * DESCRIPTION: Clear and remove a reference on an implicit return value. Used 00140 * to delete "stale" return values (if enabled, the return value 00141 * from every operator is saved at least momentarily, in case the 00142 * parent method exits.) 00143 * 00144 ******************************************************************************/ 00145 00146 void 00147 AcpiDsClearImplicitReturn ( 00148 ACPI_WALK_STATE *WalkState) 00149 { 00150 ACPI_FUNCTION_NAME (DsClearImplicitReturn); 00151 00152 00153 /* 00154 * Slack must be enabled for this feature 00155 */ 00156 if (!AcpiGbl_EnableInterpreterSlack) 00157 { 00158 return; 00159 } 00160 00161 if (WalkState->ImplicitReturnObj) 00162 { 00163 /* 00164 * Delete any "stale" implicit return. However, in 00165 * complex statements, the implicit return value can be 00166 * bubbled up several levels. 00167 */ 00168 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 00169 "Removing reference on stale implicit return obj %p\n", 00170 WalkState->ImplicitReturnObj)); 00171 00172 AcpiUtRemoveReference (WalkState->ImplicitReturnObj); 00173 WalkState->ImplicitReturnObj = NULL; 00174 } 00175 } 00176 00177 00178 #ifndef ACPI_NO_METHOD_EXECUTION 00179 /******************************************************************************* 00180 * 00181 * FUNCTION: AcpiDsDoImplicitReturn 00182 * 00183 * PARAMETERS: ReturnDesc - The return value 00184 * WalkState - Current State 00185 * AddReference - True if a reference should be added to the 00186 * return object 00187 * 00188 * RETURN: TRUE if implicit return enabled, FALSE otherwise 00189 * 00190 * DESCRIPTION: Implements the optional "implicit return". We save the result 00191 * of every ASL operator and control method invocation in case the 00192 * parent method exit. Before storing a new return value, we 00193 * delete the previous return value. 00194 * 00195 ******************************************************************************/ 00196 00197 BOOLEAN 00198 AcpiDsDoImplicitReturn ( 00199 ACPI_OPERAND_OBJECT *ReturnDesc, 00200 ACPI_WALK_STATE *WalkState, 00201 BOOLEAN AddReference) 00202 { 00203 ACPI_FUNCTION_NAME (DsDoImplicitReturn); 00204 00205 00206 /* 00207 * Slack must be enabled for this feature, and we must 00208 * have a valid return object 00209 */ 00210 if ((!AcpiGbl_EnableInterpreterSlack) || 00211 (!ReturnDesc)) 00212 { 00213 return (FALSE); 00214 } 00215 00216 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 00217 "Result %p will be implicitly returned; Prev=%p\n", 00218 ReturnDesc, 00219 WalkState->ImplicitReturnObj)); 00220 00221 /* 00222 * Delete any "stale" implicit return value first. However, in 00223 * complex statements, the implicit return value can be 00224 * bubbled up several levels, so we don't clear the value if it 00225 * is the same as the ReturnDesc. 00226 */ 00227 if (WalkState->ImplicitReturnObj) 00228 { 00229 if (WalkState->ImplicitReturnObj == ReturnDesc) 00230 { 00231 return (TRUE); 00232 } 00233 AcpiDsClearImplicitReturn (WalkState); 00234 } 00235 00236 /* Save the implicit return value, add a reference if requested */ 00237 00238 WalkState->ImplicitReturnObj = ReturnDesc; 00239 if (AddReference) 00240 { 00241 AcpiUtAddReference (ReturnDesc); 00242 } 00243 00244 return (TRUE); 00245 } 00246 00247 00248 /******************************************************************************* 00249 * 00250 * FUNCTION: AcpiDsIsResultUsed 00251 * 00252 * PARAMETERS: Op - Current Op 00253 * WalkState - Current State 00254 * 00255 * RETURN: TRUE if result is used, FALSE otherwise 00256 * 00257 * DESCRIPTION: Check if a result object will be used by the parent 00258 * 00259 ******************************************************************************/ 00260 00261 BOOLEAN 00262 AcpiDsIsResultUsed ( 00263 ACPI_PARSE_OBJECT *Op, 00264 ACPI_WALK_STATE *WalkState) 00265 { 00266 const ACPI_OPCODE_INFO *ParentInfo; 00267 00268 ACPI_FUNCTION_TRACE_PTR (DsIsResultUsed, Op); 00269 00270 00271 /* Must have both an Op and a Result Object */ 00272 00273 if (!Op) 00274 { 00275 ACPI_ERROR ((AE_INFO, "Null Op")); 00276 return_UINT8 (TRUE); 00277 } 00278 00279 /* 00280 * We know that this operator is not a 00281 * Return() operator (would not come here.) The following code is the 00282 * optional support for a so-called "implicit return". Some AML code 00283 * assumes that the last value of the method is "implicitly" returned 00284 * to the caller. Just save the last result as the return value. 00285 * NOTE: this is optional because the ASL language does not actually 00286 * support this behavior. 00287 */ 00288 (void) AcpiDsDoImplicitReturn (WalkState->ResultObj, WalkState, TRUE); 00289 00290 /* 00291 * Now determine if the parent will use the result 00292 * 00293 * If there is no parent, or the parent is a ScopeOp, we are executing 00294 * at the method level. An executing method typically has no parent, 00295 * since each method is parsed separately. A method invoked externally 00296 * via ExecuteControlMethod has a ScopeOp as the parent. 00297 */ 00298 if ((!Op->Common.Parent) || 00299 (Op->Common.Parent->Common.AmlOpcode == AML_SCOPE_OP)) 00300 { 00301 /* No parent, the return value cannot possibly be used */ 00302 00303 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 00304 "At Method level, result of [%s] not used\n", 00305 AcpiPsGetOpcodeName (Op->Common.AmlOpcode))); 00306 return_UINT8 (FALSE); 00307 } 00308 00309 /* Get info on the parent. The RootOp is AML_SCOPE */ 00310 00311 ParentInfo = AcpiPsGetOpcodeInfo (Op->Common.Parent->Common.AmlOpcode); 00312 if (ParentInfo->Class == AML_CLASS_UNKNOWN) 00313 { 00314 ACPI_ERROR ((AE_INFO, 00315 "Unknown parent opcode Op=%p", Op)); 00316 return_UINT8 (FALSE); 00317 } 00318 00319 /* 00320 * Decide what to do with the result based on the parent. If 00321 * the parent opcode will not use the result, delete the object. 00322 * Otherwise leave it as is, it will be deleted when it is used 00323 * as an operand later. 00324 */ 00325 switch (ParentInfo->Class) 00326 { 00327 case AML_CLASS_CONTROL: 00328 00329 switch (Op->Common.Parent->Common.AmlOpcode) 00330 { 00331 case AML_RETURN_OP: 00332 00333 /* Never delete the return value associated with a return opcode */ 00334 00335 goto ResultUsed; 00336 00337 case AML_IF_OP: 00338 case AML_WHILE_OP: 00339 00340 /* 00341 * If we are executing the predicate AND this is the predicate op, 00342 * we will use the return value 00343 */ 00344 if ((WalkState->ControlState->Common.State == ACPI_CONTROL_PREDICATE_EXECUTING) && 00345 (WalkState->ControlState->Control.PredicateOp == Op)) 00346 { 00347 goto ResultUsed; 00348 } 00349 break; 00350 00351 default: 00352 /* Ignore other control opcodes */ 00353 break; 00354 } 00355 00356 /* The general control opcode returns no result */ 00357 00358 goto ResultNotUsed; 00359 00360 00361 case AML_CLASS_CREATE: 00362 00363 /* 00364 * These opcodes allow TermArg(s) as operands and therefore 00365 * the operands can be method calls. The result is used. 00366 */ 00367 goto ResultUsed; 00368 00369 00370 case AML_CLASS_NAMED_OBJECT: 00371 00372 if ((Op->Common.Parent->Common.AmlOpcode == AML_REGION_OP) || 00373 (Op->Common.Parent->Common.AmlOpcode == AML_DATA_REGION_OP) || 00374 (Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) || 00375 (Op->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP) || 00376 (Op->Common.Parent->Common.AmlOpcode == AML_BUFFER_OP) || 00377 (Op->Common.Parent->Common.AmlOpcode == AML_INT_EVAL_SUBTREE_OP) || 00378 (Op->Common.Parent->Common.AmlOpcode == AML_BANK_FIELD_OP)) 00379 { 00380 /* 00381 * These opcodes allow TermArg(s) as operands and therefore 00382 * the operands can be method calls. The result is used. 00383 */ 00384 goto ResultUsed; 00385 } 00386 00387 goto ResultNotUsed; 00388 00389 00390 default: 00391 00392 /* 00393 * In all other cases. the parent will actually use the return 00394 * object, so keep it. 00395 */ 00396 goto ResultUsed; 00397 } 00398 00399 00400 ResultUsed: 00401 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 00402 "Result of [%s] used by Parent [%s] Op=%p\n", 00403 AcpiPsGetOpcodeName (Op->Common.AmlOpcode), 00404 AcpiPsGetOpcodeName (Op->Common.Parent->Common.AmlOpcode), Op)); 00405 00406 return_UINT8 (TRUE); 00407 00408 00409 ResultNotUsed: 00410 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 00411 "Result of [%s] not used by Parent [%s] Op=%p\n", 00412 AcpiPsGetOpcodeName (Op->Common.AmlOpcode), 00413 AcpiPsGetOpcodeName (Op->Common.Parent->Common.AmlOpcode), Op)); 00414 00415 return_UINT8 (FALSE); 00416 } 00417 00418 00419 /******************************************************************************* 00420 * 00421 * FUNCTION: AcpiDsDeleteResultIfNotUsed 00422 * 00423 * PARAMETERS: Op - Current parse Op 00424 * ResultObj - Result of the operation 00425 * WalkState - Current state 00426 * 00427 * RETURN: Status 00428 * 00429 * DESCRIPTION: Used after interpretation of an opcode. If there is an internal 00430 * result descriptor, check if the parent opcode will actually use 00431 * this result. If not, delete the result now so that it will 00432 * not become orphaned. 00433 * 00434 ******************************************************************************/ 00435 00436 void 00437 AcpiDsDeleteResultIfNotUsed ( 00438 ACPI_PARSE_OBJECT *Op, 00439 ACPI_OPERAND_OBJECT *ResultObj, 00440 ACPI_WALK_STATE *WalkState) 00441 { 00442 ACPI_OPERAND_OBJECT *ObjDesc; 00443 ACPI_STATUS Status; 00444 00445 00446 ACPI_FUNCTION_TRACE_PTR (DsDeleteResultIfNotUsed, ResultObj); 00447 00448 00449 if (!Op) 00450 { 00451 ACPI_ERROR ((AE_INFO, "Null Op")); 00452 return_VOID; 00453 } 00454 00455 if (!ResultObj) 00456 { 00457 return_VOID; 00458 } 00459 00460 if (!AcpiDsIsResultUsed (Op, WalkState)) 00461 { 00462 /* Must pop the result stack (ObjDesc should be equal to ResultObj) */ 00463 00464 Status = AcpiDsResultPop (&ObjDesc, WalkState); 00465 if (ACPI_SUCCESS (Status)) 00466 { 00467 AcpiUtRemoveReference (ResultObj); 00468 } 00469 } 00470 00471 return_VOID; 00472 } 00473 00474 00475 /******************************************************************************* 00476 * 00477 * FUNCTION: AcpiDsResolveOperands 00478 * 00479 * PARAMETERS: WalkState - Current walk state with operands on stack 00480 * 00481 * RETURN: Status 00482 * 00483 * DESCRIPTION: Resolve all operands to their values. Used to prepare 00484 * arguments to a control method invocation (a call from one 00485 * method to another.) 00486 * 00487 ******************************************************************************/ 00488 00489 ACPI_STATUS 00490 AcpiDsResolveOperands ( 00491 ACPI_WALK_STATE *WalkState) 00492 { 00493 UINT32 i; 00494 ACPI_STATUS Status = AE_OK; 00495 00496 00497 ACPI_FUNCTION_TRACE_PTR (DsResolveOperands, WalkState); 00498 00499 00500 /* 00501 * Attempt to resolve each of the valid operands 00502 * Method arguments are passed by reference, not by value. This means 00503 * that the actual objects are passed, not copies of the objects. 00504 */ 00505 for (i = 0; i < WalkState->NumOperands; i++) 00506 { 00507 Status = AcpiExResolveToValue (&WalkState->Operands[i], WalkState); 00508 if (ACPI_FAILURE (Status)) 00509 { 00510 break; 00511 } 00512 } 00513 00514 return_ACPI_STATUS (Status); 00515 } 00516 00517 00518 /******************************************************************************* 00519 * 00520 * FUNCTION: AcpiDsClearOperands 00521 * 00522 * PARAMETERS: WalkState - Current walk state with operands on stack 00523 * 00524 * RETURN: None 00525 * 00526 * DESCRIPTION: Clear all operands on the current walk state operand stack. 00527 * 00528 ******************************************************************************/ 00529 00530 void 00531 AcpiDsClearOperands ( 00532 ACPI_WALK_STATE *WalkState) 00533 { 00534 UINT32 i; 00535 00536 00537 ACPI_FUNCTION_TRACE_PTR (DsClearOperands, WalkState); 00538 00539 00540 /* Remove a reference on each operand on the stack */ 00541 00542 for (i = 0; i < WalkState->NumOperands; i++) 00543 { 00544 /* 00545 * Remove a reference to all operands, including both 00546 * "Arguments" and "Targets". 00547 */ 00548 AcpiUtRemoveReference (WalkState->Operands[i]); 00549 WalkState->Operands[i] = NULL; 00550 } 00551 00552 WalkState->NumOperands = 0; 00553 return_VOID; 00554 } 00555 #endif 00556 00557 00558 /******************************************************************************* 00559 * 00560 * FUNCTION: AcpiDsCreateOperand 00561 * 00562 * PARAMETERS: WalkState - Current walk state 00563 * Arg - Parse object for the argument 00564 * ArgIndex - Which argument (zero based) 00565 * 00566 * RETURN: Status 00567 * 00568 * DESCRIPTION: Translate a parse tree object that is an argument to an AML 00569 * opcode to the equivalent interpreter object. This may include 00570 * looking up a name or entering a new name into the internal 00571 * namespace. 00572 * 00573 ******************************************************************************/ 00574 00575 ACPI_STATUS 00576 AcpiDsCreateOperand ( 00577 ACPI_WALK_STATE *WalkState, 00578 ACPI_PARSE_OBJECT *Arg, 00579 UINT32 ArgIndex) 00580 { 00581 ACPI_STATUS Status = AE_OK; 00582 char *NameString; 00583 UINT32 NameLength; 00584 ACPI_OPERAND_OBJECT *ObjDesc; 00585 ACPI_PARSE_OBJECT *ParentOp; 00586 UINT16 Opcode; 00587 ACPI_INTERPRETER_MODE InterpreterMode; 00588 const ACPI_OPCODE_INFO *OpInfo; 00589 00590 00591 ACPI_FUNCTION_TRACE_PTR (DsCreateOperand, Arg); 00592 00593 00594 /* A valid name must be looked up in the namespace */ 00595 00596 if ((Arg->Common.AmlOpcode == AML_INT_NAMEPATH_OP) && 00597 (Arg->Common.Value.String) && 00598 !(Arg->Common.Flags & ACPI_PARSEOP_IN_STACK)) 00599 { 00600 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Getting a name: Arg=%p\n", Arg)); 00601 00602 /* Get the entire name string from the AML stream */ 00603 00604 Status = AcpiExGetNameString (ACPI_TYPE_ANY, Arg->Common.Value.Buffer, 00605 &NameString, &NameLength); 00606 00607 if (ACPI_FAILURE (Status)) 00608 { 00609 return_ACPI_STATUS (Status); 00610 } 00611 00612 /* All prefixes have been handled, and the name is in NameString */ 00613 00614 /* 00615 * Special handling for BufferField declarations. This is a deferred 00616 * opcode that unfortunately defines the field name as the last 00617 * parameter instead of the first. We get here when we are performing 00618 * the deferred execution, so the actual name of the field is already 00619 * in the namespace. We don't want to attempt to look it up again 00620 * because we may be executing in a different scope than where the 00621 * actual opcode exists. 00622 */ 00623 if ((WalkState->DeferredNode) && 00624 (WalkState->DeferredNode->Type == ACPI_TYPE_BUFFER_FIELD) && 00625 (ArgIndex == (UINT32) ((WalkState->Opcode == AML_CREATE_FIELD_OP) ? 3 : 2))) 00626 { 00627 ObjDesc = ACPI_CAST_PTR ( 00628 ACPI_OPERAND_OBJECT, WalkState->DeferredNode); 00629 Status = AE_OK; 00630 } 00631 else /* All other opcodes */ 00632 { 00633 /* 00634 * Differentiate between a namespace "create" operation 00635 * versus a "lookup" operation (IMODE_LOAD_PASS2 vs. 00636 * IMODE_EXECUTE) in order to support the creation of 00637 * namespace objects during the execution of control methods. 00638 */ 00639 ParentOp = Arg->Common.Parent; 00640 OpInfo = AcpiPsGetOpcodeInfo (ParentOp->Common.AmlOpcode); 00641 if ((OpInfo->Flags & AML_NSNODE) && 00642 (ParentOp->Common.AmlOpcode != AML_INT_METHODCALL_OP) && 00643 (ParentOp->Common.AmlOpcode != AML_REGION_OP) && 00644 (ParentOp->Common.AmlOpcode != AML_INT_NAMEPATH_OP)) 00645 { 00646 /* Enter name into namespace if not found */ 00647 00648 InterpreterMode = ACPI_IMODE_LOAD_PASS2; 00649 } 00650 else 00651 { 00652 /* Return a failure if name not found */ 00653 00654 InterpreterMode = ACPI_IMODE_EXECUTE; 00655 } 00656 00657 Status = AcpiNsLookup (WalkState->ScopeInfo, NameString, 00658 ACPI_TYPE_ANY, InterpreterMode, 00659 ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, 00660 WalkState, 00661 ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, &ObjDesc)); 00662 /* 00663 * The only case where we pass through (ignore) a NOT_FOUND 00664 * error is for the CondRefOf opcode. 00665 */ 00666 if (Status == AE_NOT_FOUND) 00667 { 00668 if (ParentOp->Common.AmlOpcode == AML_COND_REF_OF_OP) 00669 { 00670 /* 00671 * For the Conditional Reference op, it's OK if 00672 * the name is not found; We just need a way to 00673 * indicate this to the interpreter, set the 00674 * object to the root 00675 */ 00676 ObjDesc = ACPI_CAST_PTR ( 00677 ACPI_OPERAND_OBJECT, AcpiGbl_RootNode); 00678 Status = AE_OK; 00679 } 00680 else 00681 { 00682 /* 00683 * We just plain didn't find it -- which is a 00684 * very serious error at this point 00685 */ 00686 Status = AE_AML_NAME_NOT_FOUND; 00687 } 00688 } 00689 00690 if (ACPI_FAILURE (Status)) 00691 { 00692 ACPI_ERROR_NAMESPACE (NameString, Status); 00693 } 00694 } 00695 00696 /* Free the namestring created above */ 00697 00698 ACPI_FREE (NameString); 00699 00700 /* Check status from the lookup */ 00701 00702 if (ACPI_FAILURE (Status)) 00703 { 00704 return_ACPI_STATUS (Status); 00705 } 00706 00707 /* Put the resulting object onto the current object stack */ 00708 00709 Status = AcpiDsObjStackPush (ObjDesc, WalkState); 00710 if (ACPI_FAILURE (Status)) 00711 { 00712 return_ACPI_STATUS (Status); 00713 } 00714 ACPI_DEBUGGER_EXEC (AcpiDbDisplayArgumentObject (ObjDesc, WalkState)); 00715 } 00716 else 00717 { 00718 /* Check for null name case */ 00719 00720 if ((Arg->Common.AmlOpcode == AML_INT_NAMEPATH_OP) && 00721 !(Arg->Common.Flags & ACPI_PARSEOP_IN_STACK)) 00722 { 00723 /* 00724 * If the name is null, this means that this is an 00725 * optional result parameter that was not specified 00726 * in the original ASL. Create a Zero Constant for a 00727 * placeholder. (Store to a constant is a Noop.) 00728 */ 00729 Opcode = AML_ZERO_OP; /* Has no arguments! */ 00730 00731 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 00732 "Null namepath: Arg=%p\n", Arg)); 00733 } 00734 else 00735 { 00736 Opcode = Arg->Common.AmlOpcode; 00737 } 00738 00739 /* Get the object type of the argument */ 00740 00741 OpInfo = AcpiPsGetOpcodeInfo (Opcode); 00742 if (OpInfo->ObjectType == ACPI_TYPE_INVALID) 00743 { 00744 return_ACPI_STATUS (AE_NOT_IMPLEMENTED); 00745 } 00746 00747 if ((OpInfo->Flags & AML_HAS_RETVAL) || (Arg->Common.Flags & ACPI_PARSEOP_IN_STACK)) 00748 { 00749 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 00750 "Argument previously created, already stacked\n")); 00751 00752 ACPI_DEBUGGER_EXEC (AcpiDbDisplayArgumentObject ( 00753 WalkState->Operands [WalkState->NumOperands - 1], WalkState)); 00754 00755 /* 00756 * Use value that was already previously returned 00757 * by the evaluation of this argument 00758 */ 00759 Status = AcpiDsResultPop (&ObjDesc, WalkState); 00760 if (ACPI_FAILURE (Status)) 00761 { 00762 /* 00763 * Only error is underflow, and this indicates 00764 * a missing or null operand! 00765 */ 00766 ACPI_EXCEPTION ((AE_INFO, Status, 00767 "Missing or null operand")); 00768 return_ACPI_STATUS (Status); 00769 } 00770 } 00771 else 00772 { 00773 /* Create an ACPI_INTERNAL_OBJECT for the argument */ 00774 00775 ObjDesc = AcpiUtCreateInternalObject (OpInfo->ObjectType); 00776 if (!ObjDesc) 00777 { 00778 return_ACPI_STATUS (AE_NO_MEMORY); 00779 } 00780 00781 /* Initialize the new object */ 00782 00783 Status = AcpiDsInitObjectFromOp ( 00784 WalkState, Arg, Opcode, &ObjDesc); 00785 if (ACPI_FAILURE (Status)) 00786 { 00787 AcpiUtDeleteObjectDesc (ObjDesc); 00788 return_ACPI_STATUS (Status); 00789 } 00790 } 00791 00792 /* Put the operand object on the object stack */ 00793 00794 Status = AcpiDsObjStackPush (ObjDesc, WalkState); 00795 if (ACPI_FAILURE (Status)) 00796 { 00797 return_ACPI_STATUS (Status); 00798 } 00799 00800 ACPI_DEBUGGER_EXEC (AcpiDbDisplayArgumentObject (ObjDesc, WalkState)); 00801 } 00802 00803 return_ACPI_STATUS (AE_OK); 00804 } 00805 00806 00807 /******************************************************************************* 00808 * 00809 * FUNCTION: AcpiDsCreateOperands 00810 * 00811 * PARAMETERS: WalkState - Current state 00812 * FirstArg - First argument of a parser argument tree 00813 * 00814 * RETURN: Status 00815 * 00816 * DESCRIPTION: Convert an operator's arguments from a parse tree format to 00817 * namespace objects and place those argument object on the object 00818 * stack in preparation for evaluation by the interpreter. 00819 * 00820 ******************************************************************************/ 00821 00822 ACPI_STATUS 00823 AcpiDsCreateOperands ( 00824 ACPI_WALK_STATE *WalkState, 00825 ACPI_PARSE_OBJECT *FirstArg) 00826 { 00827 ACPI_STATUS Status = AE_OK; 00828 ACPI_PARSE_OBJECT *Arg; 00829 ACPI_PARSE_OBJECT *Arguments[ACPI_OBJ_NUM_OPERANDS]; 00830 UINT32 ArgCount = 0; 00831 UINT32 Index = WalkState->NumOperands; 00832 UINT32 i; 00833 00834 00835 ACPI_FUNCTION_TRACE_PTR (DsCreateOperands, FirstArg); 00836 00837 00838 /* Get all arguments in the list */ 00839 00840 Arg = FirstArg; 00841 while (Arg) 00842 { 00843 if (Index >= ACPI_OBJ_NUM_OPERANDS) 00844 { 00845 return_ACPI_STATUS (AE_BAD_DATA); 00846 } 00847 00848 Arguments[Index] = Arg; 00849 WalkState->Operands [Index] = NULL; 00850 00851 /* Move on to next argument, if any */ 00852 00853 Arg = Arg->Common.Next; 00854 ArgCount++; 00855 Index++; 00856 } 00857 00858 Index--; 00859 00860 /* It is the appropriate order to get objects from the Result stack */ 00861 00862 for (i = 0; i < ArgCount; i++) 00863 { 00864 Arg = Arguments[Index]; 00865 00866 /* Force the filling of the operand stack in inverse order */ 00867 00868 WalkState->OperandIndex = (UINT8) Index; 00869 00870 Status = AcpiDsCreateOperand (WalkState, Arg, Index); 00871 if (ACPI_FAILURE (Status)) 00872 { 00873 goto Cleanup; 00874 } 00875 00876 Index--; 00877 00878 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Arg #%u (%p) done, Arg1=%p\n", 00879 Index, Arg, FirstArg)); 00880 } 00881 00882 return_ACPI_STATUS (Status); 00883 00884 00885 Cleanup: 00886 /* 00887 * We must undo everything done above; meaning that we must 00888 * pop everything off of the operand stack and delete those 00889 * objects 00890 */ 00891 AcpiDsObjStackPopAndDelete (ArgCount, WalkState); 00892 00893 ACPI_EXCEPTION ((AE_INFO, Status, "While creating Arg %u", Index)); 00894 return_ACPI_STATUS (Status); 00895 } 00896 00897 00898 /***************************************************************************** 00899 * 00900 * FUNCTION: AcpiDsEvaluateNamePath 00901 * 00902 * PARAMETERS: WalkState - Current state of the parse tree walk, 00903 * the opcode of current operation should be 00904 * AML_INT_NAMEPATH_OP 00905 * 00906 * RETURN: Status 00907 * 00908 * DESCRIPTION: Translate the -NamePath- parse tree object to the equivalent 00909 * interpreter object, convert it to value, if needed, duplicate 00910 * it, if needed, and push it onto the current result stack. 00911 * 00912 ****************************************************************************/ 00913 00914 ACPI_STATUS 00915 AcpiDsEvaluateNamePath ( 00916 ACPI_WALK_STATE *WalkState) 00917 { 00918 ACPI_STATUS Status = AE_OK; 00919 ACPI_PARSE_OBJECT *Op = WalkState->Op; 00920 ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0]; 00921 ACPI_OPERAND_OBJECT *NewObjDesc; 00922 UINT8 Type; 00923 00924 00925 ACPI_FUNCTION_TRACE_PTR (DsEvaluateNamePath, WalkState); 00926 00927 00928 if (!Op->Common.Parent) 00929 { 00930 /* This happens after certain exception processing */ 00931 00932 goto Exit; 00933 } 00934 00935 if ((Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) || 00936 (Op->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP) || 00937 (Op->Common.Parent->Common.AmlOpcode == AML_REF_OF_OP)) 00938 { 00939 /* TBD: Should we specify this feature as a bit of OpInfo->Flags of these opcodes? */ 00940 00941 goto Exit; 00942 } 00943 00944 Status = AcpiDsCreateOperand (WalkState, Op, 0); 00945 if (ACPI_FAILURE (Status)) 00946 { 00947 goto Exit; 00948 } 00949 00950 if (Op->Common.Flags & ACPI_PARSEOP_TARGET) 00951 { 00952 NewObjDesc = *Operand; 00953 goto PushResult; 00954 } 00955 00956 Type = (*Operand)->Common.Type; 00957 00958 Status = AcpiExResolveToValue (Operand, WalkState); 00959 if (ACPI_FAILURE (Status)) 00960 { 00961 goto Exit; 00962 } 00963 00964 if (Type == ACPI_TYPE_INTEGER) 00965 { 00966 /* It was incremented by AcpiExResolveToValue */ 00967 00968 AcpiUtRemoveReference (*Operand); 00969 00970 Status = AcpiUtCopyIobjectToIobject (*Operand, &NewObjDesc, WalkState); 00971 if (ACPI_FAILURE (Status)) 00972 { 00973 goto Exit; 00974 } 00975 } 00976 else 00977 { 00978 /* 00979 * The object either was anew created or is 00980 * a Namespace node - don't decrement it. 00981 */ 00982 NewObjDesc = *Operand; 00983 } 00984 00985 /* Cleanup for name-path operand */ 00986 00987 Status = AcpiDsObjStackPop (1, WalkState); 00988 if (ACPI_FAILURE (Status)) 00989 { 00990 WalkState->ResultObj = NewObjDesc; 00991 goto Exit; 00992 } 00993 00994 PushResult: 00995 00996 WalkState->ResultObj = NewObjDesc; 00997 00998 Status = AcpiDsResultPush (WalkState->ResultObj, WalkState); 00999 if (ACPI_SUCCESS (Status)) 01000 { 01001 /* Force to take it from stack */ 01002 01003 Op->Common.Flags |= ACPI_PARSEOP_IN_STACK; 01004 } 01005 01006 Exit: 01007 01008 return_ACPI_STATUS (Status); 01009 } Generated on Mon May 28 2012 04:26:55 for ReactOS by
1.7.6.1
|