1 /******************************************************************************* 2 * 3 * Module Name: nseval - Object evaluation, includes control method execution 4 * 5 ******************************************************************************/ 6 7 /****************************************************************************** 8 * 9 * 1. Copyright Notice 10 * 11 * Some or all of this work - Copyright (c) 1999 - 2016, Intel Corp. 12 * All rights reserved. 13 * 14 * 2. License 15 * 16 * 2.1. This is your license from Intel Corp. under its intellectual property 17 * rights. You may have additional license terms from the party that provided 18 * you this software, covering your right to use that party's intellectual 19 * property rights. 20 * 21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 22 * copy of the source code appearing in this file ("Covered Code") an 23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 24 * base code distributed originally by Intel ("Original Intel Code") to copy, 25 * make derivatives, distribute, use and display any portion of the Covered 26 * Code in any form, with the right to sublicense such rights; and 27 * 28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 29 * license (with the right to sublicense), under only those claims of Intel 30 * patents that are infringed by the Original Intel Code, to make, use, sell, 31 * offer to sell, and import the Covered Code and derivative works thereof 32 * solely to the minimum extent necessary to exercise the above copyright 33 * license, and in no event shall the patent license extend to any additions 34 * to or modifications of the Original Intel Code. No other license or right 35 * is granted directly or by implication, estoppel or otherwise; 36 * 37 * The above copyright and patent license is granted only if the following 38 * conditions are met: 39 * 40 * 3. Conditions 41 * 42 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43 * Redistribution of source code of any substantial portion of the Covered 44 * Code or modification with rights to further distribute source must include 45 * the above Copyright Notice, the above License, this list of Conditions, 46 * and the following Disclaimer and Export Compliance provision. In addition, 47 * Licensee must cause all Covered Code to which Licensee contributes to 48 * contain a file documenting the changes Licensee made to create that Covered 49 * Code and the date of any change. Licensee must include in that file the 50 * documentation of any changes made by any predecessor Licensee. Licensee 51 * must include a prominent statement that the modification is derived, 52 * directly or indirectly, from Original Intel Code. 53 * 54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 55 * Redistribution of source code of any substantial portion of the Covered 56 * Code or modification without rights to further distribute source must 57 * include the following Disclaimer and Export Compliance provision in the 58 * documentation and/or other materials provided with distribution. In 59 * addition, Licensee may not authorize further sublicense of source of any 60 * portion of the Covered Code, and must include terms to the effect that the 61 * license from Licensee to its licensee is limited to the intellectual 62 * property embodied in the software Licensee provides to its licensee, and 63 * not to intellectual property embodied in modifications its licensee may 64 * make. 65 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 #include "acpi.h" 118 #include "accommon.h" 119 #include "acparser.h" 120 #include "acinterp.h" 121 #include "acnamesp.h" 122 123 124 #define _COMPONENT ACPI_NAMESPACE 125 ACPI_MODULE_NAME ("nseval") 126 127 /* Local prototypes */ 128 129 static void 130 AcpiNsExecModuleCode ( 131 ACPI_OPERAND_OBJECT *MethodObj, 132 ACPI_EVALUATE_INFO *Info); 133 134 135 /******************************************************************************* 136 * 137 * FUNCTION: AcpiNsEvaluate 138 * 139 * PARAMETERS: Info - Evaluation info block, contains these fields 140 * and more: 141 * PrefixNode - Prefix or Method/Object Node to execute 142 * RelativePath - Name of method to execute, If NULL, the 143 * Node is the object to execute 144 * Parameters - List of parameters to pass to the method, 145 * terminated by NULL. Params itself may be 146 * NULL if no parameters are being passed. 147 * ParameterType - Type of Parameter list 148 * ReturnObject - Where to put method's return value (if 149 * any). If NULL, no value is returned. 150 * Flags - ACPI_IGNORE_RETURN_VALUE to delete return 151 * 152 * RETURN: Status 153 * 154 * DESCRIPTION: Execute a control method or return the current value of an 155 * ACPI namespace object. 156 * 157 * MUTEX: Locks interpreter 158 * 159 ******************************************************************************/ 160 161 ACPI_STATUS 162 AcpiNsEvaluate ( 163 ACPI_EVALUATE_INFO *Info) 164 { 165 ACPI_STATUS Status; 166 167 168 ACPI_FUNCTION_TRACE (NsEvaluate); 169 170 171 if (!Info) 172 { 173 return_ACPI_STATUS (AE_BAD_PARAMETER); 174 } 175 176 if (!Info->Node) 177 { 178 /* 179 * Get the actual namespace node for the target object if we 180 * need to. Handles these cases: 181 * 182 * 1) Null node, valid pathname from root (absolute path) 183 * 2) Node and valid pathname (path relative to Node) 184 * 3) Node, Null pathname 185 */ 186 Status = AcpiNsGetNode (Info->PrefixNode, Info->RelativePathname, 187 ACPI_NS_NO_UPSEARCH, &Info->Node); 188 if (ACPI_FAILURE (Status)) 189 { 190 return_ACPI_STATUS (Status); 191 } 192 } 193 194 /* 195 * For a method alias, we must grab the actual method node so that 196 * proper scoping context will be established before execution. 197 */ 198 if (AcpiNsGetType (Info->Node) == ACPI_TYPE_LOCAL_METHOD_ALIAS) 199 { 200 Info->Node = ACPI_CAST_PTR ( 201 ACPI_NAMESPACE_NODE, Info->Node->Object); 202 } 203 204 /* Complete the info block initialization */ 205 206 Info->ReturnObject = NULL; 207 Info->NodeFlags = Info->Node->Flags; 208 Info->ObjDesc = AcpiNsGetAttachedObject (Info->Node); 209 210 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%s [%p] Value %p\n", 211 Info->RelativePathname, Info->Node, 212 AcpiNsGetAttachedObject (Info->Node))); 213 214 /* Get info if we have a predefined name (_HID, etc.) */ 215 216 Info->Predefined = AcpiUtMatchPredefinedMethod (Info->Node->Name.Ascii); 217 218 /* Get the full pathname to the object, for use in warning messages */ 219 220 Info->FullPathname = AcpiNsGetNormalizedPathname (Info->Node, TRUE); 221 if (!Info->FullPathname) 222 { 223 return_ACPI_STATUS (AE_NO_MEMORY); 224 } 225 226 /* Count the number of arguments being passed in */ 227 228 Info->ParamCount = 0; 229 if (Info->Parameters) 230 { 231 while (Info->Parameters[Info->ParamCount]) 232 { 233 Info->ParamCount++; 234 } 235 236 /* Warn on impossible argument count */ 237 238 if (Info->ParamCount > ACPI_METHOD_NUM_ARGS) 239 { 240 ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, ACPI_WARN_ALWAYS, 241 "Excess arguments (%u) - using only %u", 242 Info->ParamCount, ACPI_METHOD_NUM_ARGS)); 243 244 Info->ParamCount = ACPI_METHOD_NUM_ARGS; 245 } 246 } 247 248 /* 249 * For predefined names: Check that the declared argument count 250 * matches the ACPI spec -- otherwise this is a BIOS error. 251 */ 252 AcpiNsCheckAcpiCompliance (Info->FullPathname, Info->Node, 253 Info->Predefined); 254 255 /* 256 * For all names: Check that the incoming argument count for 257 * this method/object matches the actual ASL/AML definition. 258 */ 259 AcpiNsCheckArgumentCount (Info->FullPathname, Info->Node, 260 Info->ParamCount, Info->Predefined); 261 262 /* For predefined names: Typecheck all incoming arguments */ 263 264 AcpiNsCheckArgumentTypes (Info); 265 266 /* 267 * Three major evaluation cases: 268 * 269 * 1) Object types that cannot be evaluated by definition 270 * 2) The object is a control method -- execute it 271 * 3) The object is not a method -- just return it's current value 272 */ 273 switch (AcpiNsGetType (Info->Node)) 274 { 275 case ACPI_TYPE_DEVICE: 276 case ACPI_TYPE_EVENT: 277 case ACPI_TYPE_MUTEX: 278 case ACPI_TYPE_REGION: 279 case ACPI_TYPE_THERMAL: 280 case ACPI_TYPE_LOCAL_SCOPE: 281 /* 282 * 1) Disallow evaluation of certain object types. For these, 283 * object evaluation is undefined and not supported. 284 */ 285 ACPI_ERROR ((AE_INFO, 286 "%s: Evaluation of object type [%s] is not supported", 287 Info->FullPathname, 288 AcpiUtGetTypeName (Info->Node->Type))); 289 290 Status = AE_TYPE; 291 goto Cleanup; 292 293 case ACPI_TYPE_METHOD: 294 /* 295 * 2) Object is a control method - execute it 296 */ 297 298 /* Verify that there is a method object associated with this node */ 299 300 if (!Info->ObjDesc) 301 { 302 ACPI_ERROR ((AE_INFO, "%s: Method has no attached sub-object", 303 Info->FullPathname)); 304 Status = AE_NULL_OBJECT; 305 goto Cleanup; 306 } 307 308 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 309 "**** Execute method [%s] at AML address %p length %X\n", 310 Info->FullPathname, 311 Info->ObjDesc->Method.AmlStart + 1, 312 Info->ObjDesc->Method.AmlLength - 1)); 313 314 /* 315 * Any namespace deletion must acquire both the namespace and 316 * interpreter locks to ensure that no thread is using the portion of 317 * the namespace that is being deleted. 318 * 319 * Execute the method via the interpreter. The interpreter is locked 320 * here before calling into the AML parser 321 */ 322 AcpiExEnterInterpreter (); 323 Status = AcpiPsExecuteMethod (Info); 324 AcpiExExitInterpreter (); 325 break; 326 327 default: 328 /* 329 * 3) All other non-method objects -- get the current object value 330 */ 331 332 /* 333 * Some objects require additional resolution steps (e.g., the Node 334 * may be a field that must be read, etc.) -- we can't just grab 335 * the object out of the node. 336 * 337 * Use ResolveNodeToValue() to get the associated value. 338 * 339 * NOTE: we can get away with passing in NULL for a walk state because 340 * the Node is guaranteed to not be a reference to either a method 341 * local or a method argument (because this interface is never called 342 * from a running method.) 343 * 344 * Even though we do not directly invoke the interpreter for object 345 * resolution, we must lock it because we could access an OpRegion. 346 * The OpRegion access code assumes that the interpreter is locked. 347 */ 348 AcpiExEnterInterpreter (); 349 350 /* TBD: ResolveNodeToValue has a strange interface, fix */ 351 352 Info->ReturnObject = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Info->Node); 353 354 Status = AcpiExResolveNodeToValue (ACPI_CAST_INDIRECT_PTR ( 355 ACPI_NAMESPACE_NODE, &Info->ReturnObject), NULL); 356 AcpiExExitInterpreter (); 357 358 if (ACPI_FAILURE (Status)) 359 { 360 Info->ReturnObject = NULL; 361 goto Cleanup; 362 } 363 364 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Returned object %p [%s]\n", 365 Info->ReturnObject, 366 AcpiUtGetObjectTypeName (Info->ReturnObject))); 367 368 Status = AE_CTRL_RETURN_VALUE; /* Always has a "return value" */ 369 break; 370 } 371 372 /* 373 * For predefined names, check the return value against the ACPI 374 * specification. Some incorrect return value types are repaired. 375 */ 376 (void) AcpiNsCheckReturnValue (Info->Node, Info, Info->ParamCount, 377 Status, &Info->ReturnObject); 378 379 /* Check if there is a return value that must be dealt with */ 380 381 if (Status == AE_CTRL_RETURN_VALUE) 382 { 383 /* If caller does not want the return value, delete it */ 384 385 if (Info->Flags & ACPI_IGNORE_RETURN_VALUE) 386 { 387 AcpiUtRemoveReference (Info->ReturnObject); 388 Info->ReturnObject = NULL; 389 } 390 391 /* Map AE_CTRL_RETURN_VALUE to AE_OK, we are done with it */ 392 393 Status = AE_OK; 394 } 395 396 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 397 "*** Completed evaluation of object %s ***\n", 398 Info->RelativePathname)); 399 400 Cleanup: 401 /* 402 * Namespace was unlocked by the handling AcpiNs* function, so we 403 * just free the pathname and return 404 */ 405 ACPI_FREE (Info->FullPathname); 406 Info->FullPathname = NULL; 407 return_ACPI_STATUS (Status); 408 } 409 410 411 /******************************************************************************* 412 * 413 * FUNCTION: AcpiNsExecModuleCodeList 414 * 415 * PARAMETERS: None 416 * 417 * RETURN: None. Exceptions during method execution are ignored, since 418 * we cannot abort a table load. 419 * 420 * DESCRIPTION: Execute all elements of the global module-level code list. 421 * Each element is executed as a single control method. 422 * 423 ******************************************************************************/ 424 425 void 426 AcpiNsExecModuleCodeList ( 427 void) 428 { 429 ACPI_OPERAND_OBJECT *Prev; 430 ACPI_OPERAND_OBJECT *Next; 431 ACPI_EVALUATE_INFO *Info; 432 UINT32 MethodCount = 0; 433 434 435 ACPI_FUNCTION_TRACE (NsExecModuleCodeList); 436 437 438 /* Exit now if the list is empty */ 439 440 Next = AcpiGbl_ModuleCodeList; 441 if (!Next) 442 { 443 return_VOID; 444 } 445 446 /* Allocate the evaluation information block */ 447 448 Info = ACPI_ALLOCATE (sizeof (ACPI_EVALUATE_INFO)); 449 if (!Info) 450 { 451 return_VOID; 452 } 453 454 /* Walk the list, executing each "method" */ 455 456 while (Next) 457 { 458 Prev = Next; 459 Next = Next->Method.Mutex; 460 461 /* Clear the link field and execute the method */ 462 463 Prev->Method.Mutex = NULL; 464 AcpiNsExecModuleCode (Prev, Info); 465 MethodCount++; 466 467 /* Delete the (temporary) method object */ 468 469 AcpiUtRemoveReference (Prev); 470 } 471 472 ACPI_INFO (( 473 "Executed %u blocks of module-level executable AML code", 474 MethodCount)); 475 476 ACPI_FREE (Info); 477 AcpiGbl_ModuleCodeList = NULL; 478 return_VOID; 479 } 480 481 482 /******************************************************************************* 483 * 484 * FUNCTION: AcpiNsExecModuleCode 485 * 486 * PARAMETERS: MethodObj - Object container for the module-level code 487 * Info - Info block for method evaluation 488 * 489 * RETURN: None. Exceptions during method execution are ignored, since 490 * we cannot abort a table load. 491 * 492 * DESCRIPTION: Execute a control method containing a block of module-level 493 * executable AML code. The control method is temporarily 494 * installed to the root node, then evaluated. 495 * 496 ******************************************************************************/ 497 498 static void 499 AcpiNsExecModuleCode ( 500 ACPI_OPERAND_OBJECT *MethodObj, 501 ACPI_EVALUATE_INFO *Info) 502 { 503 ACPI_OPERAND_OBJECT *ParentObj; 504 ACPI_NAMESPACE_NODE *ParentNode; 505 ACPI_OBJECT_TYPE Type; 506 ACPI_STATUS Status; 507 508 509 ACPI_FUNCTION_TRACE (NsExecModuleCode); 510 511 512 /* 513 * Get the parent node. We cheat by using the NextObject field 514 * of the method object descriptor. 515 */ 516 ParentNode = ACPI_CAST_PTR ( 517 ACPI_NAMESPACE_NODE, MethodObj->Method.NextObject); 518 Type = AcpiNsGetType (ParentNode); 519 520 /* 521 * Get the region handler and save it in the method object. We may need 522 * this if an operation region declaration causes a _REG method to be run. 523 * 524 * We can't do this in AcpiPsLinkModuleCode because 525 * AcpiGbl_RootNode->Object is NULL at PASS1. 526 */ 527 if ((Type == ACPI_TYPE_DEVICE) && ParentNode->Object) 528 { 529 MethodObj->Method.Dispatch.Handler = 530 ParentNode->Object->Device.Handler; 531 } 532 533 /* Must clear NextObject (AcpiNsAttachObject needs the field) */ 534 535 MethodObj->Method.NextObject = NULL; 536 537 /* Initialize the evaluation information block */ 538 539 memset (Info, 0, sizeof (ACPI_EVALUATE_INFO)); 540 Info->PrefixNode = ParentNode; 541 542 /* 543 * Get the currently attached parent object. Add a reference, 544 * because the ref count will be decreased when the method object 545 * is installed to the parent node. 546 */ 547 ParentObj = AcpiNsGetAttachedObject (ParentNode); 548 if (ParentObj) 549 { 550 AcpiUtAddReference (ParentObj); 551 } 552 553 /* Install the method (module-level code) in the parent node */ 554 555 Status = AcpiNsAttachObject (ParentNode, MethodObj, ACPI_TYPE_METHOD); 556 if (ACPI_FAILURE (Status)) 557 { 558 goto Exit; 559 } 560 561 /* Execute the parent node as a control method */ 562 563 Status = AcpiNsEvaluate (Info); 564 565 ACPI_DEBUG_PRINT ((ACPI_DB_INIT_NAMES, 566 "Executed module-level code at %p\n", 567 MethodObj->Method.AmlStart)); 568 569 /* Delete a possible implicit return value (in slack mode) */ 570 571 if (Info->ReturnObject) 572 { 573 AcpiUtRemoveReference (Info->ReturnObject); 574 } 575 576 /* Detach the temporary method object */ 577 578 AcpiNsDetachObject (ParentNode); 579 580 /* Restore the original parent object */ 581 582 if (ParentObj) 583 { 584 Status = AcpiNsAttachObject (ParentNode, ParentObj, Type); 585 } 586 else 587 { 588 ParentNode->Type = (UINT8) Type; 589 } 590 591 Exit: 592 if (ParentObj) 593 { 594 AcpiUtRemoveReference (ParentObj); 595 } 596 return_VOID; 597 } 598