1 /******************************************************************************* 2 * 3 * Module Name: dsmthdat - control method arguments and local variables 4 * $Revision: 1.94 $ 5 * 6 ******************************************************************************/ 7 8 /****************************************************************************** 9 * 10 * 1. Copyright Notice 11 * 12 * Some or all of this work - Copyright (c) 1999 - 2008, Intel Corp. 13 * All rights reserved. 14 * 15 * 2. License 16 * 17 * 2.1. This is your license from Intel Corp. under its intellectual property 18 * rights. You may have additional license terms from the party that provided 19 * you this software, covering your right to use that party's intellectual 20 * property rights. 21 * 22 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 23 * copy of the source code appearing in this file ("Covered Code") an 24 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 25 * base code distributed originally by Intel ("Original Intel Code") to copy, 26 * make derivatives, distribute, use and display any portion of the Covered 27 * Code in any form, with the right to sublicense such rights; and 28 * 29 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 30 * license (with the right to sublicense), under only those claims of Intel 31 * patents that are infringed by the Original Intel Code, to make, use, sell, 32 * offer to sell, and import the Covered Code and derivative works thereof 33 * solely to the minimum extent necessary to exercise the above copyright 34 * license, and in no event shall the patent license extend to any additions 35 * to or modifications of the Original Intel Code. No other license or right 36 * is granted directly or by implication, estoppel or otherwise; 37 * 38 * The above copyright and patent license is granted only if the following 39 * conditions are met: 40 * 41 * 3. Conditions 42 * 43 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 44 * Redistribution of source code of any substantial portion of the Covered 45 * Code or modification with rights to further distribute source must include 46 * the above Copyright Notice, the above License, this list of Conditions, 47 * and the following Disclaimer and Export Compliance provision. In addition, 48 * Licensee must cause all Covered Code to which Licensee contributes to 49 * contain a file documenting the changes Licensee made to create that Covered 50 * Code and the date of any change. Licensee must include in that file the 51 * documentation of any changes made by any predecessor Licensee. Licensee 52 * must include a prominent statement that the modification is derived, 53 * directly or indirectly, from Original Intel Code. 54 * 55 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 56 * Redistribution of source code of any substantial portion of the Covered 57 * Code or modification without rights to further distribute source must 58 * include the following Disclaimer and Export Compliance provision in the 59 * documentation and/or other materials provided with distribution. In 60 * addition, Licensee may not authorize further sublicense of source of any 61 * portion of the Covered Code, and must include terms to the effect that the 62 * license from Licensee to its licensee is limited to the intellectual 63 * property embodied in the software Licensee provides to its licensee, and 64 * not to intellectual property embodied in modifications its licensee may 65 * make. 66 * 67 * 3.3. Redistribution of Executable. Redistribution in executable form of any 68 * substantial portion of the Covered Code or modification must reproduce the 69 * above Copyright Notice, and the following Disclaimer and Export Compliance 70 * provision in the documentation and/or other materials provided with the 71 * distribution. 72 * 73 * 3.4. Intel retains all right, title, and interest in and to the Original 74 * Intel Code. 75 * 76 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 77 * Intel shall be used in advertising or otherwise to promote the sale, use or 78 * other dealings in products derived from or relating to the Covered Code 79 * without prior written authorization from Intel. 80 * 81 * 4. Disclaimer and Export Compliance 82 * 83 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 84 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 85 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 86 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 87 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 88 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 89 * PARTICULAR PURPOSE. 90 * 91 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 92 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 93 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 94 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 95 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 96 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 97 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 98 * LIMITED REMEDY. 99 * 100 * 4.3. Licensee shall not export, either directly or indirectly, any of this 101 * software or system incorporating such software without first obtaining any 102 * required license or other approval from the U. S. Department of Commerce or 103 * any other agency or department of the United States Government. In the 104 * event Licensee exports any such software from the United States or 105 * re-exports any such software from a foreign destination, Licensee shall 106 * ensure that the distribution and export/re-export of the software is in 107 * compliance with all laws, regulations, orders, or other restrictions of the 108 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 109 * any of its subsidiaries will export/re-export any technical data, process, 110 * software, or service, directly or indirectly, to any country for which the 111 * United States government or any agency thereof requires an export license, 112 * other governmental approval, or letter of assurance, without first obtaining 113 * such license, approval or letter. 114 * 115 *****************************************************************************/ 116 117 #define __DSMTHDAT_C__ 118 119 #include "acpi.h" 120 #include "acdispat.h" 121 #include "acnamesp.h" 122 #include "acinterp.h" 123 124 125 #define _COMPONENT ACPI_DISPATCHER 126 ACPI_MODULE_NAME ("dsmthdat") 127 128 /* Local prototypes */ 129 130 static void 131 AcpiDsMethodDataDeleteValue ( 132 UINT8 Type, 133 UINT32 Index, 134 ACPI_WALK_STATE *WalkState); 135 136 static ACPI_STATUS 137 AcpiDsMethodDataSetValue ( 138 UINT8 Type, 139 UINT32 Index, 140 ACPI_OPERAND_OBJECT *Object, 141 ACPI_WALK_STATE *WalkState); 142 143 #ifdef ACPI_OBSOLETE_FUNCTIONS 144 ACPI_OBJECT_TYPE 145 AcpiDsMethodDataGetType ( 146 UINT16 Opcode, 147 UINT32 Index, 148 ACPI_WALK_STATE *WalkState); 149 #endif 150 151 152 /******************************************************************************* 153 * 154 * FUNCTION: AcpiDsMethodDataInit 155 * 156 * PARAMETERS: WalkState - Current walk state object 157 * 158 * RETURN: Status 159 * 160 * DESCRIPTION: Initialize the data structures that hold the method's arguments 161 * and locals. The data struct is an array of namespace nodes for 162 * each - this allows RefOf and DeRefOf to work properly for these 163 * special data types. 164 * 165 * NOTES: WalkState fields are initialized to zero by the 166 * ACPI_ALLOCATE_ZEROED(). 167 * 168 * A pseudo-Namespace Node is assigned to each argument and local 169 * so that RefOf() can return a pointer to the Node. 170 * 171 ******************************************************************************/ 172 173 void 174 AcpiDsMethodDataInit ( 175 ACPI_WALK_STATE *WalkState) 176 { 177 UINT32 i; 178 179 180 ACPI_FUNCTION_TRACE (DsMethodDataInit); 181 182 183 /* Init the method arguments */ 184 185 for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++) 186 { 187 ACPI_MOVE_32_TO_32 (&WalkState->Arguments[i].Name, NAMEOF_ARG_NTE); 188 WalkState->Arguments[i].Name.Integer |= (i << 24); 189 WalkState->Arguments[i].DescriptorType = ACPI_DESC_TYPE_NAMED; 190 WalkState->Arguments[i].Type = ACPI_TYPE_ANY; 191 WalkState->Arguments[i].Flags = 192 ANOBJ_END_OF_PEER_LIST | ANOBJ_METHOD_ARG; 193 } 194 195 /* Init the method locals */ 196 197 for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++) 198 { 199 ACPI_MOVE_32_TO_32 (&WalkState->LocalVariables[i].Name, NAMEOF_LOCAL_NTE); 200 201 WalkState->LocalVariables[i].Name.Integer |= (i << 24); 202 WalkState->LocalVariables[i].DescriptorType = ACPI_DESC_TYPE_NAMED; 203 WalkState->LocalVariables[i].Type = ACPI_TYPE_ANY; 204 WalkState->LocalVariables[i].Flags = 205 ANOBJ_END_OF_PEER_LIST | ANOBJ_METHOD_LOCAL; 206 } 207 208 return_VOID; 209 } 210 211 212 /******************************************************************************* 213 * 214 * FUNCTION: AcpiDsMethodDataDeleteAll 215 * 216 * PARAMETERS: WalkState - Current walk state object 217 * 218 * RETURN: None 219 * 220 * DESCRIPTION: Delete method locals and arguments. Arguments are only 221 * deleted if this method was called from another method. 222 * 223 ******************************************************************************/ 224 225 void 226 AcpiDsMethodDataDeleteAll ( 227 ACPI_WALK_STATE *WalkState) 228 { 229 UINT32 Index; 230 231 232 ACPI_FUNCTION_TRACE (DsMethodDataDeleteAll); 233 234 235 /* Detach the locals */ 236 237 for (Index = 0; Index < ACPI_METHOD_NUM_LOCALS; Index++) 238 { 239 if (WalkState->LocalVariables[Index].Object) 240 { 241 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Local%d=%p\n", 242 Index, WalkState->LocalVariables[Index].Object)); 243 244 /* Detach object (if present) and remove a reference */ 245 246 AcpiNsDetachObject (&WalkState->LocalVariables[Index]); 247 } 248 } 249 250 /* Detach the arguments */ 251 252 for (Index = 0; Index < ACPI_METHOD_NUM_ARGS; Index++) 253 { 254 if (WalkState->Arguments[Index].Object) 255 { 256 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Arg%d=%p\n", 257 Index, WalkState->Arguments[Index].Object)); 258 259 /* Detach object (if present) and remove a reference */ 260 261 AcpiNsDetachObject (&WalkState->Arguments[Index]); 262 } 263 } 264 265 AcpiDsClearImplicitReturn (WalkState); 266 267 return_VOID; 268 } 269 270 271 /******************************************************************************* 272 * 273 * FUNCTION: AcpiDsMethodDataInitArgs 274 * 275 * PARAMETERS: *Params - Pointer to a parameter list for the method 276 * MaxParamCount - The arg count for this method 277 * WalkState - Current walk state object 278 * 279 * RETURN: Status 280 * 281 * DESCRIPTION: Initialize arguments for a method. The parameter list is a list 282 * of ACPI operand objects, either null terminated or whose length 283 * is defined by MaxParamCount. 284 * 285 ******************************************************************************/ 286 287 ACPI_STATUS 288 AcpiDsMethodDataInitArgs ( 289 ACPI_OPERAND_OBJECT **Params, 290 UINT32 MaxParamCount, 291 ACPI_WALK_STATE *WalkState) 292 { 293 ACPI_STATUS Status; 294 UINT32 Index = 0; 295 296 297 ACPI_FUNCTION_TRACE_PTR (DsMethodDataInitArgs, Params); 298 299 300 if (!Params) 301 { 302 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "No param list passed to method\n")); 303 return_ACPI_STATUS (AE_OK); 304 } 305 306 /* Copy passed parameters into the new method stack frame */ 307 308 while ((Index < ACPI_METHOD_NUM_ARGS) && 309 (Index < MaxParamCount) && 310 Params[Index]) 311 { 312 /* 313 * A valid parameter. 314 * Store the argument in the method/walk descriptor. 315 * Do not copy the arg in order to implement call by reference 316 */ 317 Status = AcpiDsMethodDataSetValue (ACPI_REFCLASS_ARG, Index, 318 Params[Index], WalkState); 319 if (ACPI_FAILURE (Status)) 320 { 321 return_ACPI_STATUS (Status); 322 } 323 324 Index++; 325 } 326 327 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%d args passed to method\n", Index)); 328 return_ACPI_STATUS (AE_OK); 329 } 330 331 332 /******************************************************************************* 333 * 334 * FUNCTION: AcpiDsMethodDataGetNode 335 * 336 * PARAMETERS: Type - Either ACPI_REFCLASS_LOCAL or 337 * ACPI_REFCLASS_ARG 338 * Index - Which Local or Arg whose type to get 339 * WalkState - Current walk state object 340 * Node - Where the node is returned. 341 * 342 * RETURN: Status and node 343 * 344 * DESCRIPTION: Get the Node associated with a local or arg. 345 * 346 ******************************************************************************/ 347 348 ACPI_STATUS 349 AcpiDsMethodDataGetNode ( 350 UINT8 Type, 351 UINT32 Index, 352 ACPI_WALK_STATE *WalkState, 353 ACPI_NAMESPACE_NODE **Node) 354 { 355 ACPI_FUNCTION_TRACE (DsMethodDataGetNode); 356 357 358 /* 359 * Method Locals and Arguments are supported 360 */ 361 switch (Type) 362 { 363 case ACPI_REFCLASS_LOCAL: 364 365 if (Index > ACPI_METHOD_MAX_LOCAL) 366 { 367 ACPI_ERROR ((AE_INFO, 368 "Local index %d is invalid (max %d)", 369 Index, ACPI_METHOD_MAX_LOCAL)); 370 return_ACPI_STATUS (AE_AML_INVALID_INDEX); 371 } 372 373 /* Return a pointer to the pseudo-node */ 374 375 *Node = &WalkState->LocalVariables[Index]; 376 break; 377 378 case ACPI_REFCLASS_ARG: 379 380 if (Index > ACPI_METHOD_MAX_ARG) 381 { 382 ACPI_ERROR ((AE_INFO, 383 "Arg index %d is invalid (max %d)", 384 Index, ACPI_METHOD_MAX_ARG)); 385 return_ACPI_STATUS (AE_AML_INVALID_INDEX); 386 } 387 388 /* Return a pointer to the pseudo-node */ 389 390 *Node = &WalkState->Arguments[Index]; 391 break; 392 393 default: 394 ACPI_ERROR ((AE_INFO, "Type %d is invalid", Type)); 395 return_ACPI_STATUS (AE_TYPE); 396 } 397 398 return_ACPI_STATUS (AE_OK); 399 } 400 401 402 /******************************************************************************* 403 * 404 * FUNCTION: AcpiDsMethodDataSetValue 405 * 406 * PARAMETERS: Type - Either ACPI_REFCLASS_LOCAL or 407 * ACPI_REFCLASS_ARG 408 * Index - Which Local or Arg to get 409 * Object - Object to be inserted into the stack entry 410 * WalkState - Current walk state object 411 * 412 * RETURN: Status 413 * 414 * DESCRIPTION: Insert an object onto the method stack at entry Opcode:Index. 415 * Note: There is no "implicit conversion" for locals. 416 * 417 ******************************************************************************/ 418 419 static ACPI_STATUS 420 AcpiDsMethodDataSetValue ( 421 UINT8 Type, 422 UINT32 Index, 423 ACPI_OPERAND_OBJECT *Object, 424 ACPI_WALK_STATE *WalkState) 425 { 426 ACPI_STATUS Status; 427 ACPI_NAMESPACE_NODE *Node; 428 429 430 ACPI_FUNCTION_TRACE (DsMethodDataSetValue); 431 432 433 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 434 "NewObj %p Type %2.2X, Refs=%d [%s]\n", Object, 435 Type, Object->Common.ReferenceCount, 436 AcpiUtGetTypeName (Object->Common.Type))); 437 438 /* Get the namespace node for the arg/local */ 439 440 Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node); 441 if (ACPI_FAILURE (Status)) 442 { 443 return_ACPI_STATUS (Status); 444 } 445 446 /* 447 * Increment ref count so object can't be deleted while installed. 448 * NOTE: We do not copy the object in order to preserve the call by 449 * reference semantics of ACPI Control Method invocation. 450 * (See ACPI Specification 2.0C) 451 */ 452 AcpiUtAddReference (Object); 453 454 /* Install the object */ 455 456 Node->Object = Object; 457 return_ACPI_STATUS (Status); 458 } 459 460 461 /******************************************************************************* 462 * 463 * FUNCTION: AcpiDsMethodDataGetValue 464 * 465 * PARAMETERS: Type - Either ACPI_REFCLASS_LOCAL or 466 * ACPI_REFCLASS_ARG 467 * Index - Which localVar or argument to get 468 * WalkState - Current walk state object 469 * DestDesc - Where Arg or Local value is returned 470 * 471 * RETURN: Status 472 * 473 * DESCRIPTION: Retrieve value of selected Arg or Local for this method 474 * Used only in AcpiExResolveToValue(). 475 * 476 ******************************************************************************/ 477 478 ACPI_STATUS 479 AcpiDsMethodDataGetValue ( 480 UINT8 Type, 481 UINT32 Index, 482 ACPI_WALK_STATE *WalkState, 483 ACPI_OPERAND_OBJECT **DestDesc) 484 { 485 ACPI_STATUS Status; 486 ACPI_NAMESPACE_NODE *Node; 487 ACPI_OPERAND_OBJECT *Object; 488 489 490 ACPI_FUNCTION_TRACE (DsMethodDataGetValue); 491 492 493 /* Validate the object descriptor */ 494 495 if (!DestDesc) 496 { 497 ACPI_ERROR ((AE_INFO, "Null object descriptor pointer")); 498 return_ACPI_STATUS (AE_BAD_PARAMETER); 499 } 500 501 /* Get the namespace node for the arg/local */ 502 503 Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node); 504 if (ACPI_FAILURE (Status)) 505 { 506 return_ACPI_STATUS (Status); 507 } 508 509 /* Get the object from the node */ 510 511 Object = Node->Object; 512 513 /* Examine the returned object, it must be valid. */ 514 515 if (!Object) 516 { 517 /* 518 * Index points to uninitialized object. 519 * This means that either 1) The expected argument was 520 * not passed to the method, or 2) A local variable 521 * was referenced by the method (via the ASL) 522 * before it was initialized. Either case is an error. 523 */ 524 525 /* If slack enabled, init the LocalX/ArgX to an Integer of value zero */ 526 527 if (AcpiGbl_EnableInterpreterSlack) 528 { 529 Object = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); 530 if (!Object) 531 { 532 return_ACPI_STATUS (AE_NO_MEMORY); 533 } 534 535 Object->Integer.Value = 0; 536 Node->Object = Object; 537 } 538 539 /* Otherwise, return the error */ 540 541 else switch (Type) 542 { 543 case ACPI_REFCLASS_ARG: 544 545 ACPI_ERROR ((AE_INFO, 546 "Uninitialized Arg[%d] at node %p", 547 Index, Node)); 548 549 return_ACPI_STATUS (AE_AML_UNINITIALIZED_ARG); 550 551 case ACPI_REFCLASS_LOCAL: 552 553 ACPI_ERROR ((AE_INFO, 554 "Uninitialized Local[%d] at node %p", Index, Node)); 555 556 return_ACPI_STATUS (AE_AML_UNINITIALIZED_LOCAL); 557 558 default: 559 560 ACPI_ERROR ((AE_INFO, "Not a Arg/Local opcode: %X", Type)); 561 return_ACPI_STATUS (AE_AML_INTERNAL); 562 } 563 } 564 565 /* 566 * The Index points to an initialized and valid object. 567 * Return an additional reference to the object 568 */ 569 *DestDesc = Object; 570 AcpiUtAddReference (Object); 571 572 return_ACPI_STATUS (AE_OK); 573 } 574 575 576 /******************************************************************************* 577 * 578 * FUNCTION: AcpiDsMethodDataDeleteValue 579 * 580 * PARAMETERS: Type - Either ACPI_REFCLASS_LOCAL or 581 * ACPI_REFCLASS_ARG 582 * Index - Which localVar or argument to delete 583 * WalkState - Current walk state object 584 * 585 * RETURN: None 586 * 587 * DESCRIPTION: Delete the entry at Opcode:Index. Inserts 588 * a null into the stack slot after the object is deleted. 589 * 590 ******************************************************************************/ 591 592 static void 593 AcpiDsMethodDataDeleteValue ( 594 UINT8 Type, 595 UINT32 Index, 596 ACPI_WALK_STATE *WalkState) 597 { 598 ACPI_STATUS Status; 599 ACPI_NAMESPACE_NODE *Node; 600 ACPI_OPERAND_OBJECT *Object; 601 602 603 ACPI_FUNCTION_TRACE (DsMethodDataDeleteValue); 604 605 606 /* Get the namespace node for the arg/local */ 607 608 Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node); 609 if (ACPI_FAILURE (Status)) 610 { 611 return_VOID; 612 } 613 614 /* Get the associated object */ 615 616 Object = AcpiNsGetAttachedObject (Node); 617 618 /* 619 * Undefine the Arg or Local by setting its descriptor 620 * pointer to NULL. Locals/Args can contain both 621 * ACPI_OPERAND_OBJECTS and ACPI_NAMESPACE_NODEs 622 */ 623 Node->Object = NULL; 624 625 if ((Object) && 626 (ACPI_GET_DESCRIPTOR_TYPE (Object) == ACPI_DESC_TYPE_OPERAND)) 627 { 628 /* 629 * There is a valid object. 630 * Decrement the reference count by one to balance the 631 * increment when the object was stored. 632 */ 633 AcpiUtRemoveReference (Object); 634 } 635 636 return_VOID; 637 } 638 639 640 /******************************************************************************* 641 * 642 * FUNCTION: AcpiDsStoreObjectToLocal 643 * 644 * PARAMETERS: Type - Either ACPI_REFCLASS_LOCAL or 645 * ACPI_REFCLASS_ARG 646 * Index - Which Local or Arg to set 647 * ObjDesc - Value to be stored 648 * WalkState - Current walk state 649 * 650 * RETURN: Status 651 * 652 * DESCRIPTION: Store a value in an Arg or Local. The ObjDesc is installed 653 * as the new value for the Arg or Local and the reference count 654 * for ObjDesc is incremented. 655 * 656 ******************************************************************************/ 657 658 ACPI_STATUS 659 AcpiDsStoreObjectToLocal ( 660 UINT8 Type, 661 UINT32 Index, 662 ACPI_OPERAND_OBJECT *ObjDesc, 663 ACPI_WALK_STATE *WalkState) 664 { 665 ACPI_STATUS Status; 666 ACPI_NAMESPACE_NODE *Node; 667 ACPI_OPERAND_OBJECT *CurrentObjDesc; 668 ACPI_OPERAND_OBJECT *NewObjDesc; 669 670 671 ACPI_FUNCTION_TRACE (DsStoreObjectToLocal); 672 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Type=%2.2X Index=%d Obj=%p\n", 673 Type, Index, ObjDesc)); 674 675 /* Parameter validation */ 676 677 if (!ObjDesc) 678 { 679 return_ACPI_STATUS (AE_BAD_PARAMETER); 680 } 681 682 /* Get the namespace node for the arg/local */ 683 684 Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node); 685 if (ACPI_FAILURE (Status)) 686 { 687 return_ACPI_STATUS (Status); 688 } 689 690 CurrentObjDesc = AcpiNsGetAttachedObject (Node); 691 if (CurrentObjDesc == ObjDesc) 692 { 693 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p already installed!\n", 694 ObjDesc)); 695 return_ACPI_STATUS (Status); 696 } 697 698 /* 699 * If the reference count on the object is more than one, we must 700 * take a copy of the object before we store. A reference count 701 * of exactly 1 means that the object was just created during the 702 * evaluation of an expression, and we can safely use it since it 703 * is not used anywhere else. 704 */ 705 NewObjDesc = ObjDesc; 706 if (ObjDesc->Common.ReferenceCount > 1) 707 { 708 Status = AcpiUtCopyIobjectToIobject (ObjDesc, &NewObjDesc, WalkState); 709 if (ACPI_FAILURE (Status)) 710 { 711 return_ACPI_STATUS (Status); 712 } 713 } 714 715 /* 716 * If there is an object already in this slot, we either 717 * have to delete it, or if this is an argument and there 718 * is an object reference stored there, we have to do 719 * an indirect store! 720 */ 721 if (CurrentObjDesc) 722 { 723 /* 724 * Check for an indirect store if an argument 725 * contains an object reference (stored as an Node). 726 * We don't allow this automatic dereferencing for 727 * locals, since a store to a local should overwrite 728 * anything there, including an object reference. 729 * 730 * If both Arg0 and Local0 contain RefOf (Local4): 731 * 732 * Store (1, Arg0) - Causes indirect store to local4 733 * Store (1, Local0) - Stores 1 in local0, overwriting 734 * the reference to local4 735 * Store (1, DeRefof (Local0)) - Causes indirect store to local4 736 * 737 * Weird, but true. 738 */ 739 if (Type == ACPI_REFCLASS_ARG) 740 { 741 /* 742 * If we have a valid reference object that came from RefOf(), 743 * do the indirect store 744 */ 745 if ((ACPI_GET_DESCRIPTOR_TYPE (CurrentObjDesc) == ACPI_DESC_TYPE_OPERAND) && 746 (CurrentObjDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) && 747 (CurrentObjDesc->Reference.Class == ACPI_REFCLASS_REFOF)) 748 { 749 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 750 "Arg (%p) is an ObjRef(Node), storing in node %p\n", 751 NewObjDesc, CurrentObjDesc)); 752 753 /* 754 * Store this object to the Node (perform the indirect store) 755 * NOTE: No implicit conversion is performed, as per the ACPI 756 * specification rules on storing to Locals/Args. 757 */ 758 Status = AcpiExStoreObjectToNode (NewObjDesc, 759 CurrentObjDesc->Reference.Object, WalkState, 760 ACPI_NO_IMPLICIT_CONVERSION); 761 762 /* Remove local reference if we copied the object above */ 763 764 if (NewObjDesc != ObjDesc) 765 { 766 AcpiUtRemoveReference (NewObjDesc); 767 } 768 return_ACPI_STATUS (Status); 769 } 770 } 771 772 /* Delete the existing object before storing the new one */ 773 774 AcpiDsMethodDataDeleteValue (Type, Index, WalkState); 775 } 776 777 /* 778 * Install the Obj descriptor (*NewObjDesc) into 779 * the descriptor for the Arg or Local. 780 * (increments the object reference count by one) 781 */ 782 Status = AcpiDsMethodDataSetValue (Type, Index, NewObjDesc, WalkState); 783 784 /* Remove local reference if we copied the object above */ 785 786 if (NewObjDesc != ObjDesc) 787 { 788 AcpiUtRemoveReference (NewObjDesc); 789 } 790 791 return_ACPI_STATUS (Status); 792 } 793 794 795 #ifdef ACPI_OBSOLETE_FUNCTIONS 796 /******************************************************************************* 797 * 798 * FUNCTION: AcpiDsMethodDataGetType 799 * 800 * PARAMETERS: Opcode - Either AML_LOCAL_OP or AML_ARG_OP 801 * Index - Which Local or Arg whose type to get 802 * WalkState - Current walk state object 803 * 804 * RETURN: Data type of current value of the selected Arg or Local 805 * 806 * DESCRIPTION: Get the type of the object stored in the Local or Arg 807 * 808 ******************************************************************************/ 809 810 ACPI_OBJECT_TYPE 811 AcpiDsMethodDataGetType ( 812 UINT16 Opcode, 813 UINT32 Index, 814 ACPI_WALK_STATE *WalkState) 815 { 816 ACPI_STATUS Status; 817 ACPI_NAMESPACE_NODE *Node; 818 ACPI_OPERAND_OBJECT *Object; 819 820 821 ACPI_FUNCTION_TRACE (DsMethodDataGetType); 822 823 824 /* Get the namespace node for the arg/local */ 825 826 Status = AcpiDsMethodDataGetNode (Opcode, Index, WalkState, &Node); 827 if (ACPI_FAILURE (Status)) 828 { 829 return_VALUE ((ACPI_TYPE_NOT_FOUND)); 830 } 831 832 /* Get the object */ 833 834 Object = AcpiNsGetAttachedObject (Node); 835 if (!Object) 836 { 837 /* Uninitialized local/arg, return TYPE_ANY */ 838 839 return_VALUE (ACPI_TYPE_ANY); 840 } 841 842 /* Get the object type */ 843 844 return_VALUE (ACPI_GET_OBJECT_TYPE (Object)); 845 } 846 #endif 847 848 849