nseval.c revision 128212
1/******************************************************************************* 2 * 3 * Module Name: nseval - Object evaluation interfaces -- includes control 4 * method lookup and execution. 5 * $Revision: 125 $ 6 * 7 ******************************************************************************/ 8 9/****************************************************************************** 10 * 11 * 1. Copyright Notice 12 * 13 * Some or all of this work - Copyright (c) 1999 - 2004, Intel Corp. 14 * All rights reserved. 15 * 16 * 2. License 17 * 18 * 2.1. This is your license from Intel Corp. under its intellectual property 19 * rights. You may have additional license terms from the party that provided 20 * you this software, covering your right to use that party's intellectual 21 * property rights. 22 * 23 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 24 * copy of the source code appearing in this file ("Covered Code") an 25 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 26 * base code distributed originally by Intel ("Original Intel Code") to copy, 27 * make derivatives, distribute, use and display any portion of the Covered 28 * Code in any form, with the right to sublicense such rights; and 29 * 30 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 31 * license (with the right to sublicense), under only those claims of Intel 32 * patents that are infringed by the Original Intel Code, to make, use, sell, 33 * offer to sell, and import the Covered Code and derivative works thereof 34 * solely to the minimum extent necessary to exercise the above copyright 35 * license, and in no event shall the patent license extend to any additions 36 * to or modifications of the Original Intel Code. No other license or right 37 * is granted directly or by implication, estoppel or otherwise; 38 * 39 * The above copyright and patent license is granted only if the following 40 * conditions are met: 41 * 42 * 3. Conditions 43 * 44 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 45 * Redistribution of source code of any substantial portion of the Covered 46 * Code or modification with rights to further distribute source must include 47 * the above Copyright Notice, the above License, this list of Conditions, 48 * and the following Disclaimer and Export Compliance provision. In addition, 49 * Licensee must cause all Covered Code to which Licensee contributes to 50 * contain a file documenting the changes Licensee made to create that Covered 51 * Code and the date of any change. Licensee must include in that file the 52 * documentation of any changes made by any predecessor Licensee. Licensee 53 * must include a prominent statement that the modification is derived, 54 * directly or indirectly, from Original Intel Code. 55 * 56 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 57 * Redistribution of source code of any substantial portion of the Covered 58 * Code or modification without rights to further distribute source must 59 * include the following Disclaimer and Export Compliance provision in the 60 * documentation and/or other materials provided with distribution. In 61 * addition, Licensee may not authorize further sublicense of source of any 62 * portion of the Covered Code, and must include terms to the effect that the 63 * license from Licensee to its licensee is limited to the intellectual 64 * property embodied in the software Licensee provides to its licensee, and 65 * not to intellectual property embodied in modifications its licensee may 66 * make. 67 68 * 69 * 3.3. Redistribution of Executable. Redistribution in executable form of any 70 * substantial portion of the Covered Code or modification must reproduce the 71 * above Copyright Notice, and the following Disclaimer and Export Compliance 72 * provision in the documentation and/or other materials provided with the 73 * distribution. 74 * 75 * 3.4. Intel retains all right, title, and interest in and to the Original 76 * Intel Code. 77 * 78 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 79 * Intel shall be used in advertising or otherwise to promote the sale, use or 80 * other dealings in products derived from or relating to the Covered Code 81 * without prior written authorization from Intel. 82 * 83 * 4. Disclaimer and Export Compliance 84 * 85 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 86 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 87 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 88 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 89 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 90 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 91 * PARTICULAR PURPOSE. 92 * 93 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 94 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 95 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 96 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 97 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 98 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 99 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 100 * LIMITED REMEDY. 101 * 102 * 4.3. Licensee shall not export, either directly or indirectly, any of this 103 * software or system incorporating such software without first obtaining any 104 * required license or other approval from the U. S. Department of Commerce or 105 * any other agency or department of the United States Government. In the 106 * event Licensee exports any such software from the United States or 107 * re-exports any such software from a foreign destination, Licensee shall 108 * ensure that the distribution and export/re-export of the software is in 109 * compliance with all laws, regulations, orders, or other restrictions of the 110 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 111 * any of its subsidiaries will export/re-export any technical data, process, 112 * software, or service, directly or indirectly, to any country for which the 113 * United States government or any agency thereof requires an export license, 114 * other governmental approval, or letter of assurance, without first obtaining 115 * such license, approval or letter. 116 * 117 *****************************************************************************/ 118 119#define __NSEVAL_C__ 120 121#include "acpi.h" 122#include "acparser.h" 123#include "acinterp.h" 124#include "acnamesp.h" 125 126 127#define _COMPONENT ACPI_NAMESPACE 128 ACPI_MODULE_NAME ("nseval") 129 130 131/******************************************************************************* 132 * 133 * FUNCTION: AcpiNsEvaluateRelative 134 * 135 * PARAMETERS: Handle - The relative containing object 136 * Pathname - Name of method to execute, If NULL, the 137 * handle is the object to execute 138 * Params - List of parameters to pass to the method, 139 * terminated by NULL. Params itself may be 140 * NULL if no parameters are being passed. 141 * ReturnObject - Where to put method's return value (if 142 * any). If NULL, no value is returned. 143 * 144 * RETURN: Status 145 * 146 * DESCRIPTION: Find and execute the requested method using the handle as a 147 * scope 148 * 149 * MUTEX: Locks Namespace 150 * 151 ******************************************************************************/ 152 153ACPI_STATUS 154AcpiNsEvaluateRelative ( 155 ACPI_NAMESPACE_NODE *Handle, 156 char *Pathname, 157 ACPI_OPERAND_OBJECT **Params, 158 ACPI_OPERAND_OBJECT **ReturnObject) 159{ 160 ACPI_STATUS Status; 161 ACPI_NAMESPACE_NODE *PrefixNode; 162 ACPI_NAMESPACE_NODE *Node = NULL; 163 ACPI_GENERIC_STATE *ScopeInfo; 164 char *InternalPath = NULL; 165 166 167 ACPI_FUNCTION_TRACE ("NsEvaluateRelative"); 168 169 170 /* 171 * Must have a valid object handle 172 */ 173 if (!Handle) 174 { 175 return_ACPI_STATUS (AE_BAD_PARAMETER); 176 } 177 178 /* Build an internal name string for the method */ 179 180 Status = AcpiNsInternalizeName (Pathname, &InternalPath); 181 if (ACPI_FAILURE (Status)) 182 { 183 return_ACPI_STATUS (Status); 184 } 185 186 ScopeInfo = AcpiUtCreateGenericState (); 187 if (!ScopeInfo) 188 { 189 goto Cleanup1; 190 } 191 192 /* Get the prefix handle and Node */ 193 194 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 195 if (ACPI_FAILURE (Status)) 196 { 197 goto Cleanup; 198 } 199 200 PrefixNode = AcpiNsMapHandleToNode (Handle); 201 if (!PrefixNode) 202 { 203 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 204 Status = AE_BAD_PARAMETER; 205 goto Cleanup; 206 } 207 208 /* Lookup the name in the namespace */ 209 210 ScopeInfo->Scope.Node = PrefixNode; 211 Status = AcpiNsLookup (ScopeInfo, InternalPath, ACPI_TYPE_ANY, 212 ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, NULL, 213 &Node); 214 215 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 216 217 if (ACPI_FAILURE (Status)) 218 { 219 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Object [%s] not found [%s]\n", 220 Pathname, AcpiFormatException (Status))); 221 goto Cleanup; 222 } 223 224 /* 225 * Now that we have a handle to the object, we can attempt 226 * to evaluate it. 227 */ 228 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%s [%p] Value %p\n", 229 Pathname, Node, AcpiNsGetAttachedObject (Node))); 230 231 Status = AcpiNsEvaluateByHandle (Node, Params, ReturnObject); 232 233 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "*** Completed eval of object %s ***\n", 234 Pathname)); 235 236Cleanup: 237 AcpiUtDeleteGenericState (ScopeInfo); 238 239Cleanup1: 240 ACPI_MEM_FREE (InternalPath); 241 return_ACPI_STATUS (Status); 242} 243 244 245/******************************************************************************* 246 * 247 * FUNCTION: AcpiNsEvaluateByName 248 * 249 * PARAMETERS: Pathname - Fully qualified pathname to the object 250 * ReturnObject - Where to put method's return value (if 251 * any). If NULL, no value is returned. 252 * Params - List of parameters to pass to the method, 253 * terminated by NULL. Params itself may be 254 * NULL if no parameters are being passed. 255 * 256 * RETURN: Status 257 * 258 * DESCRIPTION: Find and execute the requested method passing the given 259 * parameters 260 * 261 * MUTEX: Locks Namespace 262 * 263 ******************************************************************************/ 264 265ACPI_STATUS 266AcpiNsEvaluateByName ( 267 char *Pathname, 268 ACPI_OPERAND_OBJECT **Params, 269 ACPI_OPERAND_OBJECT **ReturnObject) 270{ 271 ACPI_STATUS Status; 272 ACPI_NAMESPACE_NODE *Node = NULL; 273 char *InternalPath = NULL; 274 275 276 ACPI_FUNCTION_TRACE ("NsEvaluateByName"); 277 278 279 /* Build an internal name string for the method */ 280 281 Status = AcpiNsInternalizeName (Pathname, &InternalPath); 282 if (ACPI_FAILURE (Status)) 283 { 284 return_ACPI_STATUS (Status); 285 } 286 287 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 288 if (ACPI_FAILURE (Status)) 289 { 290 goto Cleanup; 291 } 292 293 /* Lookup the name in the namespace */ 294 295 Status = AcpiNsLookup (NULL, InternalPath, ACPI_TYPE_ANY, 296 ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, NULL, 297 &Node); 298 299 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 300 301 if (ACPI_FAILURE (Status)) 302 { 303 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Object at [%s] was not found, status=%.4X\n", 304 Pathname, Status)); 305 goto Cleanup; 306 } 307 308 /* 309 * Now that we have a handle to the object, we can attempt 310 * to evaluate it. 311 */ 312 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%s [%p] Value %p\n", 313 Pathname, Node, AcpiNsGetAttachedObject (Node))); 314 315 Status = AcpiNsEvaluateByHandle (Node, Params, ReturnObject); 316 317 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "*** Completed eval of object %s ***\n", 318 Pathname)); 319 320 321Cleanup: 322 323 /* Cleanup */ 324 325 if (InternalPath) 326 { 327 ACPI_MEM_FREE (InternalPath); 328 } 329 330 return_ACPI_STATUS (Status); 331} 332 333 334/******************************************************************************* 335 * 336 * FUNCTION: AcpiNsEvaluateByHandle 337 * 338 * PARAMETERS: Handle - Method Node to execute 339 * Params - List of parameters to pass to the method, 340 * terminated by NULL. Params itself may be 341 * NULL if no parameters are being passed. 342 * ReturnObject - Where to put method's return value (if 343 * any). If NULL, no value is returned. 344 * 345 * RETURN: Status 346 * 347 * DESCRIPTION: Execute the requested method passing the given parameters 348 * 349 * MUTEX: Locks Namespace 350 * 351 ******************************************************************************/ 352 353ACPI_STATUS 354AcpiNsEvaluateByHandle ( 355 ACPI_NAMESPACE_NODE *Handle, 356 ACPI_OPERAND_OBJECT **Params, 357 ACPI_OPERAND_OBJECT **ReturnObject) 358{ 359 ACPI_NAMESPACE_NODE *Node; 360 ACPI_STATUS Status; 361 ACPI_OPERAND_OBJECT *LocalReturnObject; 362 363 364 ACPI_FUNCTION_TRACE ("NsEvaluateByHandle"); 365 366 367 /* Check if namespace has been initialized */ 368 369 if (!AcpiGbl_RootNode) 370 { 371 return_ACPI_STATUS (AE_NO_NAMESPACE); 372 } 373 374 /* Parameter Validation */ 375 376 if (!Handle) 377 { 378 return_ACPI_STATUS (AE_BAD_PARAMETER); 379 } 380 381 if (ReturnObject) 382 { 383 /* Initialize the return value to an invalid object */ 384 385 *ReturnObject = NULL; 386 } 387 388 /* Get the prefix handle and Node */ 389 390 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 391 if (ACPI_FAILURE (Status)) 392 { 393 return_ACPI_STATUS (Status); 394 } 395 396 Node = AcpiNsMapHandleToNode (Handle); 397 if (!Node) 398 { 399 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 400 return_ACPI_STATUS (AE_BAD_PARAMETER); 401 } 402 403 /* 404 * For a method alias, we must grab the actual method node 405 * so that proper scoping context will be established 406 * before execution. 407 */ 408 if (AcpiNsGetType (Node) == ACPI_TYPE_LOCAL_METHOD_ALIAS) 409 { 410 Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Node->Object); 411 } 412 413 /* 414 * Two major cases here: 415 * 1) The object is an actual control method -- execute it. 416 * 2) The object is not a method -- just return it's current 417 * value 418 * 419 * In both cases, the namespace is unlocked by the 420 * AcpiNs* procedure 421 */ 422 if (AcpiNsGetType (Node) == ACPI_TYPE_METHOD) 423 { 424 /* 425 * Case 1) We have an actual control method to execute 426 */ 427 Status = AcpiNsExecuteControlMethod (Node, Params, 428 &LocalReturnObject); 429 } 430 else 431 { 432 /* 433 * Case 2) Object is NOT a method, just return its 434 * current value 435 */ 436 Status = AcpiNsGetObjectValue (Node, &LocalReturnObject); 437 } 438 439 /* 440 * Check if there is a return value on the stack that must 441 * be dealt with 442 */ 443 if (Status == AE_CTRL_RETURN_VALUE) 444 { 445 /* 446 * If the Method returned a value and the caller 447 * provided a place to store a returned value, Copy 448 * the returned value to the object descriptor provided 449 * by the caller. 450 */ 451 if (ReturnObject) 452 { 453 /* 454 * Valid return object, copy the pointer to 455 * the returned object 456 */ 457 *ReturnObject = LocalReturnObject; 458 } 459 460 /* Map AE_CTRL_RETURN_VALUE to AE_OK, we are done with it */ 461 462 Status = AE_OK; 463 } 464 465 /* 466 * Namespace was unlocked by the handling AcpiNs* function, 467 * so we just return 468 */ 469 return_ACPI_STATUS (Status); 470} 471 472 473/******************************************************************************* 474 * 475 * FUNCTION: AcpiNsExecuteControlMethod 476 * 477 * PARAMETERS: MethodNode - The method to execute 478 * Params - List of parameters to pass to the method, 479 * terminated by NULL. Params itself may be 480 * NULL if no parameters are being passed. 481 * ReturnObjDesc - List of result objects to be returned 482 * from the method. 483 * 484 * RETURN: Status 485 * 486 * DESCRIPTION: Execute the requested method passing the given parameters 487 * 488 * MUTEX: Assumes namespace is locked 489 * 490 ******************************************************************************/ 491 492ACPI_STATUS 493AcpiNsExecuteControlMethod ( 494 ACPI_NAMESPACE_NODE *MethodNode, 495 ACPI_OPERAND_OBJECT **Params, 496 ACPI_OPERAND_OBJECT **ReturnObjDesc) 497{ 498 ACPI_STATUS Status; 499 ACPI_OPERAND_OBJECT *ObjDesc; 500 501 502 ACPI_FUNCTION_TRACE ("NsExecuteControlMethod"); 503 504 505 /* Verify that there is a method associated with this object */ 506 507 ObjDesc = AcpiNsGetAttachedObject (MethodNode); 508 if (!ObjDesc) 509 { 510 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No attached method object\n")); 511 512 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 513 return_ACPI_STATUS (AE_NULL_OBJECT); 514 } 515 516 ACPI_DUMP_PATHNAME (MethodNode, "Execute Method:", 517 ACPI_LV_INFO, _COMPONENT); 518 519 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Method at AML address %p Length %X\n", 520 ObjDesc->Method.AmlStart + 1, ObjDesc->Method.AmlLength - 1)); 521 522 /* 523 * Unlock the namespace before execution. This allows namespace access 524 * via the external Acpi* interfaces while a method is being executed. 525 * However, any namespace deletion must acquire both the namespace and 526 * interpreter locks to ensure that no thread is using the portion of the 527 * namespace that is being deleted. 528 */ 529 Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 530 if (ACPI_FAILURE (Status)) 531 { 532 return_ACPI_STATUS (Status); 533 } 534 535 /* 536 * Execute the method via the interpreter. The interpreter is locked 537 * here before calling into the AML parser 538 */ 539 Status = AcpiExEnterInterpreter (); 540 if (ACPI_FAILURE (Status)) 541 { 542 return_ACPI_STATUS (Status); 543 } 544 545 Status = AcpiPsxExecute (MethodNode, Params, ReturnObjDesc); 546 AcpiExExitInterpreter (); 547 548 return_ACPI_STATUS (Status); 549} 550 551 552/******************************************************************************* 553 * 554 * FUNCTION: AcpiNsGetObjectValue 555 * 556 * PARAMETERS: Node - The object 557 * ReturnObjDesc - Where the objects value is returned 558 * 559 * RETURN: Status 560 * 561 * DESCRIPTION: Return the current value of the object 562 * 563 * MUTEX: Assumes namespace is locked, leaves namespace unlocked 564 * 565 ******************************************************************************/ 566 567ACPI_STATUS 568AcpiNsGetObjectValue ( 569 ACPI_NAMESPACE_NODE *Node, 570 ACPI_OPERAND_OBJECT **ReturnObjDesc) 571{ 572 ACPI_STATUS Status = AE_OK; 573 ACPI_NAMESPACE_NODE *ResolvedNode = Node; 574 575 576 ACPI_FUNCTION_TRACE ("NsGetObjectValue"); 577 578 579 /* 580 * Objects require additional resolution steps (e.g., the 581 * Node may be a field that must be read, etc.) -- we can't just grab 582 * the object out of the node. 583 */ 584 585 /* 586 * Use ResolveNodeToValue() to get the associated value. This call 587 * always deletes ObjDesc (allocated above). 588 * 589 * NOTE: we can get away with passing in NULL for a walk state 590 * because ObjDesc is guaranteed to not be a reference to either 591 * a method local or a method argument (because this interface can only be 592 * called from the AcpiEvaluate external interface, never called from 593 * a running control method.) 594 * 595 * Even though we do not directly invoke the interpreter 596 * for this, we must enter it because we could access an opregion. 597 * The opregion access code assumes that the interpreter 598 * is locked. 599 * 600 * We must release the namespace lock before entering the 601 * intepreter. 602 */ 603 Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 604 if (ACPI_FAILURE (Status)) 605 { 606 return_ACPI_STATUS (Status); 607 } 608 609 Status = AcpiExEnterInterpreter (); 610 if (ACPI_SUCCESS (Status)) 611 { 612 Status = AcpiExResolveNodeToValue (&ResolvedNode, NULL); 613 /* 614 * If AcpiExResolveNodeToValue() succeeded, the return value was 615 * placed in ResolvedNode. 616 */ 617 AcpiExExitInterpreter (); 618 619 if (ACPI_SUCCESS (Status)) 620 { 621 Status = AE_CTRL_RETURN_VALUE; 622 *ReturnObjDesc = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, ResolvedNode); 623 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Returning object %p [%s]\n", 624 *ReturnObjDesc, AcpiUtGetObjectTypeName (*ReturnObjDesc))); 625 } 626 } 627 628 /* Namespace is unlocked */ 629 630 return_ACPI_STATUS (Status); 631} 632 633