|
||||
Warning, cross-references for /kernel/drivers/acpica/dsutils.c need to be fixed.
0001 /******************************************************************************* 0002 * 0003 * Module Name: dsutils - Dispatcher utilities 0004 * 0005 ******************************************************************************/ 0006 0007 /****************************************************************************** 0008 * 0009 * 1. Copyright Notice 0010 * 0011 * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. 0012 * All rights reserved. 0013 * 0014 * 2. License 0015 * 0016 * 2.1. This is your license from Intel Corp. under its intellectual property 0017 * rights. You may have additional license terms from the party that provided 0018 * you this software, covering your right to use that party's intellectual 0019 * property rights. 0020 * 0021 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 0022 * copy of the source code appearing in this file ("Covered Code") an 0023 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 0024 * base code distributed originally by Intel ("Original Intel Code") to copy, 0025 * make derivatives, distribute, use and display any portion of the Covered 0026 * Code in any form, with the right to sublicense such rights; and 0027 * 0028 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 0029 * license (with the right to sublicense), under only those claims of Intel 0030 * patents that are infringed by the Original Intel Code, to make, use, sell, 0031 * offer to sell, and import the Covered Code and derivative works thereof 0032 * solely to the minimum extent necessary to exercise the above copyright 0033 * license, and in no event shall the patent license extend to any additions 0034 * to or modifications of the Original Intel Code. No other license or right 0035 * is granted directly or by implication, estoppel or otherwise; 0036 * 0037 * The above copyright and patent license is granted only if the following 0038 * conditions are met: 0039 * 0040 * 3. Conditions 0041 * 0042 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 0043 * Redistribution of source code of any substantial portion of the Covered 0044 * Code or modification with rights to further distribute source must include 0045 * the above Copyright Notice, the above License, this list of Conditions, 0046 * and the following Disclaimer and Export Compliance provision. In addition, 0047 * Licensee must cause all Covered Code to which Licensee contributes to 0048 * contain a file documenting the changes Licensee made to create that Covered 0049 * Code and the date of any change. Licensee must include in that file the 0050 * documentation of any changes made by any predecessor Licensee. Licensee 0051 * must include a prominent statement that the modification is derived, 0052 * directly or indirectly, from Original Intel Code. 0053 * 0054 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 0055 * Redistribution of source code of any substantial portion of the Covered 0056 * Code or modification without rights to further distribute source must 0057 * include the following Disclaimer and Export Compliance provision in the 0058 * documentation and/or other materials provided with distribution. In 0059 * addition, Licensee may not authorize further sublicense of source of any 0060 * portion of the Covered Code, and must include terms to the effect that the 0061 * license from Licensee to its licensee is limited to the intellectual 0062 * property embodied in the software Licensee provides to its licensee, and 0063 * not to intellectual property embodied in modifications its licensee may 0064 * make. 0065 * 0066 * 3.3. Redistribution of Executable. Redistribution in executable form of any 0067 * substantial portion of the Covered Code or modification must reproduce the 0068 * above Copyright Notice, and the following Disclaimer and Export Compliance 0069 * provision in the documentation and/or other materials provided with the 0070 * distribution. 0071 * 0072 * 3.4. Intel retains all right, title, and interest in and to the Original 0073 * Intel Code. 0074 * 0075 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 0076 * Intel shall be used in advertising or otherwise to promote the sale, use or 0077 * other dealings in products derived from or relating to the Covered Code 0078 * without prior written authorization from Intel. 0079 * 0080 * 4. Disclaimer and Export Compliance 0081 * 0082 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 0083 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 0084 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 0085 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 0086 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 0087 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 0088 * PARTICULAR PURPOSE. 0089 * 0090 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 0091 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 0092 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 0093 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 0094 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 0095 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 0096 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 0097 * LIMITED REMEDY. 0098 * 0099 * 4.3. Licensee shall not export, either directly or indirectly, any of this 0100 * software or system incorporating such software without first obtaining any 0101 * required license or other approval from the U. S. Department of Commerce or 0102 * any other agency or department of the United States Government. In the 0103 * event Licensee exports any such software from the United States or 0104 * re-exports any such software from a foreign destination, Licensee shall 0105 * ensure that the distribution and export/re-export of the software is in 0106 * compliance with all laws, regulations, orders, or other restrictions of the 0107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 0108 * any of its subsidiaries will export/re-export any technical data, process, 0109 * software, or service, directly or indirectly, to any country for which the 0110 * United States government or any agency thereof requires an export license, 0111 * other governmental approval, or letter of assurance, without first obtaining 0112 * such license, approval or letter. 0113 * 0114 *****************************************************************************/ 0115 0116 #define __DSUTILS_C__ 0117 0118 #include "acpi.h" 0119 #include "accommon.h" 0120 #include "acparser.h" 0121 #include "amlcode.h" 0122 #include "acdispat.h" 0123 #include "acinterp.h" 0124 #include "acnamesp.h" 0125 #include "acdebug.h" 0126 0127 #define _COMPONENT ACPI_DISPATCHER 0128 ACPI_MODULE_NAME ("dsutils") 0129 0130 0131 /******************************************************************************* 0132 * 0133 * FUNCTION: AcpiDsClearImplicitReturn 0134 * 0135 * PARAMETERS: WalkState - Current State 0136 * 0137 * RETURN: None. 0138 * 0139 * DESCRIPTION: Clear and remove a reference on an implicit return value. Used 0140 * to delete "stale" return values (if enabled, the return value 0141 * from every operator is saved at least momentarily, in case the 0142 * parent method exits.) 0143 * 0144 ******************************************************************************/ 0145 0146 void 0147 AcpiDsClearImplicitReturn ( 0148 ACPI_WALK_STATE *WalkState) 0149 { 0150 ACPI_FUNCTION_NAME (DsClearImplicitReturn); 0151 0152 0153 /* 0154 * Slack must be enabled for this feature 0155 */ 0156 if (!AcpiGbl_EnableInterpreterSlack) 0157 { 0158 return; 0159 } 0160 0161 if (WalkState->ImplicitReturnObj) 0162 { 0163 /* 0164 * Delete any "stale" implicit return. However, in 0165 * complex statements, the implicit return value can be 0166 * bubbled up several levels. 0167 */ 0168 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 0169 "Removing reference on stale implicit return obj %p\n", 0170 WalkState->ImplicitReturnObj)); 0171 0172 AcpiUtRemoveReference (WalkState->ImplicitReturnObj); 0173 WalkState->ImplicitReturnObj = NULL; 0174 } 0175 } 0176 0177 0178 #ifndef ACPI_NO_METHOD_EXECUTION 0179 /******************************************************************************* 0180 * 0181 * FUNCTION: AcpiDsDoImplicitReturn 0182 * 0183 * PARAMETERS: ReturnDesc - The return value 0184 * WalkState - Current State 0185 * AddReference - True if a reference should be added to the 0186 * return object 0187 * 0188 * RETURN: TRUE if implicit return enabled, FALSE otherwise 0189 * 0190 * DESCRIPTION: Implements the optional "implicit return". We save the result 0191 * of every ASL operator and control method invocation in case the 0192 * parent method exit. Before storing a new return value, we 0193 * delete the previous return value. 0194 * 0195 ******************************************************************************/ 0196 0197 BOOLEAN 0198 AcpiDsDoImplicitReturn ( 0199 ACPI_OPERAND_OBJECT *ReturnDesc, 0200 ACPI_WALK_STATE *WalkState, 0201 BOOLEAN AddReference) 0202 { 0203 ACPI_FUNCTION_NAME (DsDoImplicitReturn); 0204 0205 0206 /* 0207 * Slack must be enabled for this feature, and we must 0208 * have a valid return object 0209 */ 0210 if ((!AcpiGbl_EnableInterpreterSlack) || 0211 (!ReturnDesc)) 0212 { 0213 return (FALSE); 0214 } 0215 0216 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 0217 "Result %p will be implicitly returned; Prev=%p\n", 0218 ReturnDesc, 0219 WalkState->ImplicitReturnObj)); 0220 0221 /* 0222 * Delete any "stale" implicit return value first. However, in 0223 * complex statements, the implicit return value can be 0224 * bubbled up several levels, so we don't clear the value if it 0225 * is the same as the ReturnDesc. 0226 */ 0227 if (WalkState->ImplicitReturnObj) 0228 { 0229 if (WalkState->ImplicitReturnObj == ReturnDesc) 0230 { 0231 return (TRUE); 0232 } 0233 AcpiDsClearImplicitReturn (WalkState); 0234 } 0235 0236 /* Save the implicit return value, add a reference if requested */ 0237 0238 WalkState->ImplicitReturnObj = ReturnDesc; 0239 if (AddReference) 0240 { 0241 AcpiUtAddReference (ReturnDesc); 0242 } 0243 0244 return (TRUE); 0245 } 0246 0247 0248 /******************************************************************************* 0249 * 0250 * FUNCTION: AcpiDsIsResultUsed 0251 * 0252 * PARAMETERS: Op - Current Op 0253 * WalkState - Current State 0254 * 0255 * RETURN: TRUE if result is used, FALSE otherwise 0256 * 0257 * DESCRIPTION: Check if a result object will be used by the parent 0258 * 0259 ******************************************************************************/ 0260 0261 BOOLEAN 0262 AcpiDsIsResultUsed ( 0263 ACPI_PARSE_OBJECT *Op, 0264 ACPI_WALK_STATE *WalkState) 0265 { 0266 const ACPI_OPCODE_INFO *ParentInfo; 0267 0268 ACPI_FUNCTION_TRACE_PTR (DsIsResultUsed, Op); 0269 0270 0271 /* Must have both an Op and a Result Object */ 0272 0273 if (!Op) 0274 { 0275 ACPI_ERROR ((AE_INFO, "Null Op")); 0276 return_UINT8 (TRUE); 0277 } 0278 0279 /* 0280 * We know that this operator is not a 0281 * Return() operator (would not come here.) The following code is the 0282 * optional support for a so-called "implicit return". Some AML code 0283 * assumes that the last value of the method is "implicitly" returned 0284 * to the caller. Just save the last result as the return value. 0285 * NOTE: this is optional because the ASL language does not actually 0286 * support this behavior. 0287 */ 0288 (void) AcpiDsDoImplicitReturn (WalkState->ResultObj, WalkState, TRUE); 0289 0290 /* 0291 * Now determine if the parent will use the result 0292 * 0293 * If there is no parent, or the parent is a ScopeOp, we are executing 0294 * at the method level. An executing method typically has no parent, 0295 * since each method is parsed separately. A method invoked externally 0296 * via ExecuteControlMethod has a ScopeOp as the parent. 0297 */ 0298 if ((!Op->Common.Parent) || 0299 (Op->Common.Parent->Common.AmlOpcode == AML_SCOPE_OP)) 0300 { 0301 /* No parent, the return value cannot possibly be used */ 0302 0303 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 0304 "At Method level, result of [%s] not used\n", 0305 AcpiPsGetOpcodeName (Op->Common.AmlOpcode))); 0306 return_UINT8 (FALSE); 0307 } 0308 0309 /* Get info on the parent. The RootOp is AML_SCOPE */ 0310 0311 ParentInfo = AcpiPsGetOpcodeInfo (Op->Common.Parent->Common.AmlOpcode); 0312 if (ParentInfo->Class == AML_CLASS_UNKNOWN) 0313 { 0314 ACPI_ERROR ((AE_INFO, 0315 "Unknown parent opcode Op=%p", Op)); 0316 return_UINT8 (FALSE); 0317 } 0318 0319 /* 0320 * Decide what to do with the result based on the parent. If 0321 * the parent opcode will not use the result, delete the object. 0322 * Otherwise leave it as is, it will be deleted when it is used 0323 * as an operand later. 0324 */ 0325 switch (ParentInfo->Class) 0326 { 0327 case AML_CLASS_CONTROL: 0328 0329 switch (Op->Common.Parent->Common.AmlOpcode) 0330 { 0331 case AML_RETURN_OP: 0332 0333 /* Never delete the return value associated with a return opcode */ 0334 0335 goto ResultUsed; 0336 0337 case AML_IF_OP: 0338 case AML_WHILE_OP: 0339 0340 /* 0341 * If we are executing the predicate AND this is the predicate op, 0342 * we will use the return value 0343 */ 0344 if ((WalkState->ControlState->Common.State == ACPI_CONTROL_PREDICATE_EXECUTING) && 0345 (WalkState->ControlState->Control.PredicateOp == Op)) 0346 { 0347 goto ResultUsed; 0348 } 0349 break; 0350 0351 default: 0352 /* Ignore other control opcodes */ 0353 break; 0354 } 0355 0356 /* The general control opcode returns no result */ 0357 0358 goto ResultNotUsed; 0359 0360 0361 case AML_CLASS_CREATE: 0362 0363 /* 0364 * These opcodes allow TermArg(s) as operands and therefore 0365 * the operands can be method calls. The result is used. 0366 */ 0367 goto ResultUsed; 0368 0369 0370 case AML_CLASS_NAMED_OBJECT: 0371 0372 if ((Op->Common.Parent->Common.AmlOpcode == AML_REGION_OP) || 0373 (Op->Common.Parent->Common.AmlOpcode == AML_DATA_REGION_OP) || 0374 (Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) || 0375 (Op->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP) || 0376 (Op->Common.Parent->Common.AmlOpcode == AML_BUFFER_OP) || 0377 (Op->Common.Parent->Common.AmlOpcode == AML_INT_EVAL_SUBTREE_OP) || 0378 (Op->Common.Parent->Common.AmlOpcode == AML_BANK_FIELD_OP)) 0379 { 0380 /* 0381 * These opcodes allow TermArg(s) as operands and therefore 0382 * the operands can be method calls. The result is used. 0383 */ 0384 goto ResultUsed; 0385 } 0386 0387 goto ResultNotUsed; 0388 0389 0390 default: 0391 0392 /* 0393 * In all other cases. the parent will actually use the return 0394 * object, so keep it. 0395 */ 0396 goto ResultUsed; 0397 } 0398 0399 0400 ResultUsed: 0401 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 0402 "Result of [%s] used by Parent [%s] Op=%p\n", 0403 AcpiPsGetOpcodeName (Op->Common.AmlOpcode), 0404 AcpiPsGetOpcodeName (Op->Common.Parent->Common.AmlOpcode), Op)); 0405 0406 return_UINT8 (TRUE); 0407 0408 0409 ResultNotUsed: 0410 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 0411 "Result of [%s] not used by Parent [%s] Op=%p\n", 0412 AcpiPsGetOpcodeName (Op->Common.AmlOpcode), 0413 AcpiPsGetOpcodeName (Op->Common.Parent->Common.AmlOpcode), Op)); 0414 0415 return_UINT8 (FALSE); 0416 } 0417 0418 0419 /******************************************************************************* 0420 * 0421 * FUNCTION: AcpiDsDeleteResultIfNotUsed 0422 * 0423 * PARAMETERS: Op - Current parse Op 0424 * ResultObj - Result of the operation 0425 * WalkState - Current state 0426 * 0427 * RETURN: Status 0428 * 0429 * DESCRIPTION: Used after interpretation of an opcode. If there is an internal 0430 * result descriptor, check if the parent opcode will actually use 0431 * this result. If not, delete the result now so that it will 0432 * not become orphaned. 0433 * 0434 ******************************************************************************/ 0435 0436 void 0437 AcpiDsDeleteResultIfNotUsed ( 0438 ACPI_PARSE_OBJECT *Op, 0439 ACPI_OPERAND_OBJECT *ResultObj, 0440 ACPI_WALK_STATE *WalkState) 0441 { 0442 ACPI_OPERAND_OBJECT *ObjDesc; 0443 ACPI_STATUS Status; 0444 0445 0446 ACPI_FUNCTION_TRACE_PTR (DsDeleteResultIfNotUsed, ResultObj); 0447 0448 0449 if (!Op) 0450 { 0451 ACPI_ERROR ((AE_INFO, "Null Op")); 0452 return_VOID; 0453 } 0454 0455 if (!ResultObj) 0456 { 0457 return_VOID; 0458 } 0459 0460 if (!AcpiDsIsResultUsed (Op, WalkState)) 0461 { 0462 /* Must pop the result stack (ObjDesc should be equal to ResultObj) */ 0463 0464 Status = AcpiDsResultPop (&ObjDesc, WalkState); 0465 if (ACPI_SUCCESS (Status)) 0466 { 0467 AcpiUtRemoveReference (ResultObj); 0468 } 0469 } 0470 0471 return_VOID; 0472 } 0473 0474 0475 /******************************************************************************* 0476 * 0477 * FUNCTION: AcpiDsResolveOperands 0478 * 0479 * PARAMETERS: WalkState - Current walk state with operands on stack 0480 * 0481 * RETURN: Status 0482 * 0483 * DESCRIPTION: Resolve all operands to their values. Used to prepare 0484 * arguments to a control method invocation (a call from one 0485 * method to another.) 0486 * 0487 ******************************************************************************/ 0488 0489 ACPI_STATUS 0490 AcpiDsResolveOperands ( 0491 ACPI_WALK_STATE *WalkState) 0492 { 0493 UINT32 i; 0494 ACPI_STATUS Status = AE_OK; 0495 0496 0497 ACPI_FUNCTION_TRACE_PTR (DsResolveOperands, WalkState); 0498 0499 0500 /* 0501 * Attempt to resolve each of the valid operands 0502 * Method arguments are passed by reference, not by value. This means 0503 * that the actual objects are passed, not copies of the objects. 0504 */ 0505 for (i = 0; i < WalkState->NumOperands; i++) 0506 { 0507 Status = AcpiExResolveToValue (&WalkState->Operands[i], WalkState); 0508 if (ACPI_FAILURE (Status)) 0509 { 0510 break; 0511 } 0512 } 0513 0514 return_ACPI_STATUS (Status); 0515 } 0516 0517 0518 /******************************************************************************* 0519 * 0520 * FUNCTION: AcpiDsClearOperands 0521 * 0522 * PARAMETERS: WalkState - Current walk state with operands on stack 0523 * 0524 * RETURN: None 0525 * 0526 * DESCRIPTION: Clear all operands on the current walk state operand stack. 0527 * 0528 ******************************************************************************/ 0529 0530 void 0531 AcpiDsClearOperands ( 0532 ACPI_WALK_STATE *WalkState) 0533 { 0534 UINT32 i; 0535 0536 0537 ACPI_FUNCTION_TRACE_PTR (DsClearOperands, WalkState); 0538 0539 0540 /* Remove a reference on each operand on the stack */ 0541 0542 for (i = 0; i < WalkState->NumOperands; i++) 0543 { 0544 /* 0545 * Remove a reference to all operands, including both 0546 * "Arguments" and "Targets". 0547 */ 0548 AcpiUtRemoveReference (WalkState->Operands[i]); 0549 WalkState->Operands[i] = NULL; 0550 } 0551 0552 WalkState->NumOperands = 0; 0553 return_VOID; 0554 } 0555 #endif 0556 0557 0558 /******************************************************************************* 0559 * 0560 * FUNCTION: AcpiDsCreateOperand 0561 * 0562 * PARAMETERS: WalkState - Current walk state 0563 * Arg - Parse object for the argument 0564 * ArgIndex - Which argument (zero based) 0565 * 0566 * RETURN: Status 0567 * 0568 * DESCRIPTION: Translate a parse tree object that is an argument to an AML 0569 * opcode to the equivalent interpreter object. This may include 0570 * looking up a name or entering a new name into the internal 0571 * namespace. 0572 * 0573 ******************************************************************************/ 0574 0575 ACPI_STATUS 0576 AcpiDsCreateOperand ( 0577 ACPI_WALK_STATE *WalkState, 0578 ACPI_PARSE_OBJECT *Arg, 0579 UINT32 ArgIndex) 0580 { 0581 ACPI_STATUS Status = AE_OK; 0582 char *NameString; 0583 UINT32 NameLength; 0584 ACPI_OPERAND_OBJECT *ObjDesc; 0585 ACPI_PARSE_OBJECT *ParentOp; 0586 UINT16 Opcode; 0587 ACPI_INTERPRETER_MODE InterpreterMode; 0588 const ACPI_OPCODE_INFO *OpInfo; 0589 0590 0591 ACPI_FUNCTION_TRACE_PTR (DsCreateOperand, Arg); 0592 0593 0594 /* A valid name must be looked up in the namespace */ 0595 0596 if ((Arg->Common.AmlOpcode == AML_INT_NAMEPATH_OP) && 0597 (Arg->Common.Value.String) && 0598 !(Arg->Common.Flags & ACPI_PARSEOP_IN_STACK)) 0599 { 0600 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Getting a name: Arg=%p\n", Arg)); 0601 0602 /* Get the entire name string from the AML stream */ 0603 0604 Status = AcpiExGetNameString (ACPI_TYPE_ANY, Arg->Common.Value.Buffer, 0605 &NameString, &NameLength); 0606 0607 if (ACPI_FAILURE (Status)) 0608 { 0609 return_ACPI_STATUS (Status); 0610 } 0611 0612 /* All prefixes have been handled, and the name is in NameString */ 0613 0614 /* 0615 * Special handling for BufferField declarations. This is a deferred 0616 * opcode that unfortunately defines the field name as the last 0617 * parameter instead of the first. We get here when we are performing 0618 * the deferred execution, so the actual name of the field is already 0619 * in the namespace. We don't want to attempt to look it up again 0620 * because we may be executing in a different scope than where the 0621 * actual opcode exists. 0622 */ 0623 if ((WalkState->DeferredNode) && 0624 (WalkState->DeferredNode->Type == ACPI_TYPE_BUFFER_FIELD) && 0625 (ArgIndex == (UINT32) ((WalkState->Opcode == AML_CREATE_FIELD_OP) ? 3 : 2))) 0626 { 0627 ObjDesc = ACPI_CAST_PTR ( 0628 ACPI_OPERAND_OBJECT, WalkState->DeferredNode); 0629 Status = AE_OK; 0630 } 0631 else /* All other opcodes */ 0632 { 0633 /* 0634 * Differentiate between a namespace "create" operation 0635 * versus a "lookup" operation (IMODE_LOAD_PASS2 vs. 0636 * IMODE_EXECUTE) in order to support the creation of 0637 * namespace objects during the execution of control methods. 0638 */ 0639 ParentOp = Arg->Common.Parent; 0640 OpInfo = AcpiPsGetOpcodeInfo (ParentOp->Common.AmlOpcode); 0641 if ((OpInfo->Flags & AML_NSNODE) && 0642 (ParentOp->Common.AmlOpcode != AML_INT_METHODCALL_OP) && 0643 (ParentOp->Common.AmlOpcode != AML_REGION_OP) && 0644 (ParentOp->Common.AmlOpcode != AML_INT_NAMEPATH_OP)) 0645 { 0646 /* Enter name into namespace if not found */ 0647 0648 InterpreterMode = ACPI_IMODE_LOAD_PASS2; 0649 } 0650 else 0651 { 0652 /* Return a failure if name not found */ 0653 0654 InterpreterMode = ACPI_IMODE_EXECUTE; 0655 } 0656 0657 Status = AcpiNsLookup (WalkState->ScopeInfo, NameString, 0658 ACPI_TYPE_ANY, InterpreterMode, 0659 ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, 0660 WalkState, 0661 ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, &ObjDesc)); 0662 /* 0663 * The only case where we pass through (ignore) a NOT_FOUND 0664 * error is for the CondRefOf opcode. 0665 */ 0666 if (Status == AE_NOT_FOUND) 0667 { 0668 if (ParentOp->Common.AmlOpcode == AML_COND_REF_OF_OP) 0669 { 0670 /* 0671 * For the Conditional Reference op, it's OK if 0672 * the name is not found; We just need a way to 0673 * indicate this to the interpreter, set the 0674 * object to the root 0675 */ 0676 ObjDesc = ACPI_CAST_PTR ( 0677 ACPI_OPERAND_OBJECT, AcpiGbl_RootNode); 0678 Status = AE_OK; 0679 } 0680 else 0681 { 0682 /* 0683 * We just plain didn't find it -- which is a 0684 * very serious error at this point 0685 */ 0686 Status = AE_AML_NAME_NOT_FOUND; 0687 } 0688 } 0689 0690 if (ACPI_FAILURE (Status)) 0691 { 0692 ACPI_ERROR_NAMESPACE (NameString, Status); 0693 } 0694 } 0695 0696 /* Free the namestring created above */ 0697 0698 ACPI_FREE (NameString); 0699 0700 /* Check status from the lookup */ 0701 0702 if (ACPI_FAILURE (Status)) 0703 { 0704 return_ACPI_STATUS (Status); 0705 } 0706 0707 /* Put the resulting object onto the current object stack */ 0708 0709 Status = AcpiDsObjStackPush (ObjDesc, WalkState); 0710 if (ACPI_FAILURE (Status)) 0711 { 0712 return_ACPI_STATUS (Status); 0713 } 0714 ACPI_DEBUGGER_EXEC (AcpiDbDisplayArgumentObject (ObjDesc, WalkState)); 0715 } 0716 else 0717 { 0718 /* Check for null name case */ 0719 0720 if ((Arg->Common.AmlOpcode == AML_INT_NAMEPATH_OP) && 0721 !(Arg->Common.Flags & ACPI_PARSEOP_IN_STACK)) 0722 { 0723 /* 0724 * If the name is null, this means that this is an 0725 * optional result parameter that was not specified 0726 * in the original ASL. Create a Zero Constant for a 0727 * placeholder. (Store to a constant is a Noop.) 0728 */ 0729 Opcode = AML_ZERO_OP; /* Has no arguments! */ 0730 0731 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 0732 "Null namepath: Arg=%p\n", Arg)); 0733 } 0734 else 0735 { 0736 Opcode = Arg->Common.AmlOpcode; 0737 } 0738 0739 /* Get the object type of the argument */ 0740 0741 OpInfo = AcpiPsGetOpcodeInfo (Opcode); 0742 if (OpInfo->ObjectType == ACPI_TYPE_INVALID) 0743 { 0744 return_ACPI_STATUS (AE_NOT_IMPLEMENTED); 0745 } 0746 0747 if ((OpInfo->Flags & AML_HAS_RETVAL) || (Arg->Common.Flags & ACPI_PARSEOP_IN_STACK)) 0748 { 0749 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 0750 "Argument previously created, already stacked\n")); 0751 0752 ACPI_DEBUGGER_EXEC (AcpiDbDisplayArgumentObject ( 0753 WalkState->Operands [WalkState->NumOperands - 1], WalkState)); 0754 0755 /* 0756 * Use value that was already previously returned 0757 * by the evaluation of this argument 0758 */ 0759 Status = AcpiDsResultPop (&ObjDesc, WalkState); 0760 if (ACPI_FAILURE (Status)) 0761 { 0762 /* 0763 * Only error is underflow, and this indicates 0764 * a missing or null operand! 0765 */ 0766 ACPI_EXCEPTION ((AE_INFO, Status, 0767 "Missing or null operand")); 0768 return_ACPI_STATUS (Status); 0769 } 0770 } 0771 else 0772 { 0773 /* Create an ACPI_INTERNAL_OBJECT for the argument */ 0774 0775 ObjDesc = AcpiUtCreateInternalObject (OpInfo->ObjectType); 0776 if (!ObjDesc) 0777 { 0778 return_ACPI_STATUS (AE_NO_MEMORY); 0779 } 0780 0781 /* Initialize the new object */ 0782 0783 Status = AcpiDsInitObjectFromOp ( 0784 WalkState, Arg, Opcode, &ObjDesc); 0785 if (ACPI_FAILURE (Status)) 0786 { 0787 AcpiUtDeleteObjectDesc (ObjDesc); 0788 return_ACPI_STATUS (Status); 0789 } 0790 } 0791 0792 /* Put the operand object on the object stack */ 0793 0794 Status = AcpiDsObjStackPush (ObjDesc, WalkState); 0795 if (ACPI_FAILURE (Status)) 0796 { 0797 return_ACPI_STATUS (Status); 0798 } 0799 0800 ACPI_DEBUGGER_EXEC (AcpiDbDisplayArgumentObject (ObjDesc, WalkState)); 0801 } 0802 0803 return_ACPI_STATUS (AE_OK); 0804 } 0805 0806 0807 /******************************************************************************* 0808 * 0809 * FUNCTION: AcpiDsCreateOperands 0810 * 0811 * PARAMETERS: WalkState - Current state 0812 * FirstArg - First argument of a parser argument tree 0813 * 0814 * RETURN: Status 0815 * 0816 * DESCRIPTION: Convert an operator's arguments from a parse tree format to 0817 * namespace objects and place those argument object on the object 0818 * stack in preparation for evaluation by the interpreter. 0819 * 0820 ******************************************************************************/ 0821 0822 ACPI_STATUS 0823 AcpiDsCreateOperands ( 0824 ACPI_WALK_STATE *WalkState, 0825 ACPI_PARSE_OBJECT *FirstArg) 0826 { 0827 ACPI_STATUS Status = AE_OK; 0828 ACPI_PARSE_OBJECT *Arg; 0829 ACPI_PARSE_OBJECT *Arguments[ACPI_OBJ_NUM_OPERANDS]; 0830 UINT32 ArgCount = 0; 0831 UINT32 Index = WalkState->NumOperands; 0832 UINT32 i; 0833 0834 0835 ACPI_FUNCTION_TRACE_PTR (DsCreateOperands, FirstArg); 0836 0837 0838 /* Get all arguments in the list */ 0839 0840 Arg = FirstArg; 0841 while (Arg) 0842 { 0843 if (Index >= ACPI_OBJ_NUM_OPERANDS) 0844 { 0845 return_ACPI_STATUS (AE_BAD_DATA); 0846 } 0847 0848 Arguments[Index] = Arg; 0849 WalkState->Operands [Index] = NULL; 0850 0851 /* Move on to next argument, if any */ 0852 0853 Arg = Arg->Common.Next; 0854 ArgCount++; 0855 Index++; 0856 } 0857 0858 Index--; 0859 0860 /* It is the appropriate order to get objects from the Result stack */ 0861 0862 for (i = 0; i < ArgCount; i++) 0863 { 0864 Arg = Arguments[Index]; 0865 0866 /* Force the filling of the operand stack in inverse order */ 0867 0868 WalkState->OperandIndex = (UINT8) Index; 0869 0870 Status = AcpiDsCreateOperand (WalkState, Arg, Index); 0871 if (ACPI_FAILURE (Status)) 0872 { 0873 goto Cleanup; 0874 } 0875 0876 Index--; 0877 0878 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Arg #%d (%p) done, Arg1=%p\n", 0879 Index, Arg, FirstArg)); 0880 } 0881 0882 return_ACPI_STATUS (Status); 0883 0884 0885 Cleanup: 0886 /* 0887 * We must undo everything done above; meaning that we must 0888 * pop everything off of the operand stack and delete those 0889 * objects 0890 */ 0891 AcpiDsObjStackPopAndDelete (ArgCount, WalkState); 0892 0893 ACPI_EXCEPTION ((AE_INFO, Status, "While creating Arg %d", Index)); 0894 return_ACPI_STATUS (Status); 0895 } 0896 0897 0898 /***************************************************************************** 0899 * 0900 * FUNCTION: AcpiDsEvaluateNamePath 0901 * 0902 * PARAMETERS: WalkState - Current state of the parse tree walk, 0903 * the opcode of current operation should be 0904 * AML_INT_NAMEPATH_OP 0905 * 0906 * RETURN: Status 0907 * 0908 * DESCRIPTION: Translate the -NamePath- parse tree object to the equivalent 0909 * interpreter object, convert it to value, if needed, duplicate 0910 * it, if needed, and push it onto the current result stack. 0911 * 0912 ****************************************************************************/ 0913 0914 ACPI_STATUS 0915 AcpiDsEvaluateNamePath ( 0916 ACPI_WALK_STATE *WalkState) 0917 { 0918 ACPI_STATUS Status = AE_OK; 0919 ACPI_PARSE_OBJECT *Op = WalkState->Op; 0920 ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0]; 0921 ACPI_OPERAND_OBJECT *NewObjDesc; 0922 UINT8 Type; 0923 0924 0925 ACPI_FUNCTION_TRACE_PTR (DsEvaluateNamePath, WalkState); 0926 0927 0928 if (!Op->Common.Parent) 0929 { 0930 /* This happens after certain exception processing */ 0931 0932 goto Exit; 0933 } 0934 0935 if ((Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) || 0936 (Op->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP) || 0937 (Op->Common.Parent->Common.AmlOpcode == AML_REF_OF_OP)) 0938 { 0939 /* TBD: Should we specify this feature as a bit of OpInfo->Flags of these opcodes? */ 0940 0941 goto Exit; 0942 } 0943 0944 Status = AcpiDsCreateOperand (WalkState, Op, 0); 0945 if (ACPI_FAILURE (Status)) 0946 { 0947 goto Exit; 0948 } 0949 0950 if (Op->Common.Flags & ACPI_PARSEOP_TARGET) 0951 { 0952 NewObjDesc = *Operand; 0953 goto PushResult; 0954 } 0955 0956 Type = (*Operand)->Common.Type; 0957 0958 Status = AcpiExResolveToValue (Operand, WalkState); 0959 if (ACPI_FAILURE (Status)) 0960 { 0961 goto Exit; 0962 } 0963 0964 if (Type == ACPI_TYPE_INTEGER) 0965 { 0966 /* It was incremented by AcpiExResolveToValue */ 0967 0968 AcpiUtRemoveReference (*Operand); 0969 0970 Status = AcpiUtCopyIobjectToIobject (*Operand, &NewObjDesc, WalkState); 0971 if (ACPI_FAILURE (Status)) 0972 { 0973 goto Exit; 0974 } 0975 } 0976 else 0977 { 0978 /* 0979 * The object either was anew created or is 0980 * a Namespace node - don't decrement it. 0981 */ 0982 NewObjDesc = *Operand; 0983 } 0984 0985 /* Cleanup for name-path operand */ 0986 0987 Status = AcpiDsObjStackPop (1, WalkState); 0988 if (ACPI_FAILURE (Status)) 0989 { 0990 WalkState->ResultObj = NewObjDesc; 0991 goto Exit; 0992 } 0993 0994 PushResult: 0995 0996 WalkState->ResultObj = NewObjDesc; 0997 0998 Status = AcpiDsResultPush (WalkState->ResultObj, WalkState); 0999 if (ACPI_SUCCESS (Status)) 1000 { 1001 /* Force to take it from stack */ 1002 1003 Op->Common.Flags |= ACPI_PARSEOP_IN_STACK; 1004 } 1005 1006 Exit: 1007 1008 return_ACPI_STATUS (Status); 1009 }
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 1.2.0 LXR engine. |