exresolv.c revision 167802
1 2/****************************************************************************** 3 * 4 * Module Name: exresolv - AML Interpreter object resolution 5 * $Revision: 1.142 $ 6 * 7 *****************************************************************************/ 8 9/****************************************************************************** 10 * 11 * 1. Copyright Notice 12 * 13 * Some or all of this work - Copyright (c) 1999 - 2007, 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 * 3.3. Redistribution of Executable. Redistribution in executable form of any 69 * substantial portion of the Covered Code or modification must reproduce the 70 * above Copyright Notice, and the following Disclaimer and Export Compliance 71 * provision in the documentation and/or other materials provided with the 72 * distribution. 73 * 74 * 3.4. Intel retains all right, title, and interest in and to the Original 75 * Intel Code. 76 * 77 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 78 * Intel shall be used in advertising or otherwise to promote the sale, use or 79 * other dealings in products derived from or relating to the Covered Code 80 * without prior written authorization from Intel. 81 * 82 * 4. Disclaimer and Export Compliance 83 * 84 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 85 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 86 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 87 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 88 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 89 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 90 * PARTICULAR PURPOSE. 91 * 92 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 93 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 94 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 95 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 96 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 97 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 98 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 99 * LIMITED REMEDY. 100 * 101 * 4.3. Licensee shall not export, either directly or indirectly, any of this 102 * software or system incorporating such software without first obtaining any 103 * required license or other approval from the U. S. Department of Commerce or 104 * any other agency or department of the United States Government. In the 105 * event Licensee exports any such software from the United States or 106 * re-exports any such software from a foreign destination, Licensee shall 107 * ensure that the distribution and export/re-export of the software is in 108 * compliance with all laws, regulations, orders, or other restrictions of the 109 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 110 * any of its subsidiaries will export/re-export any technical data, process, 111 * software, or service, directly or indirectly, to any country for which the 112 * United States government or any agency thereof requires an export license, 113 * other governmental approval, or letter of assurance, without first obtaining 114 * such license, approval or letter. 115 * 116 *****************************************************************************/ 117 118#define __EXRESOLV_C__ 119 120#include <contrib/dev/acpica/acpi.h> 121#include <contrib/dev/acpica/amlcode.h> 122#include <contrib/dev/acpica/acdispat.h> 123#include <contrib/dev/acpica/acinterp.h> 124#include <contrib/dev/acpica/acnamesp.h> 125#include <contrib/dev/acpica/acparser.h> 126 127 128#define _COMPONENT ACPI_EXECUTER 129 ACPI_MODULE_NAME ("exresolv") 130 131/* Local prototypes */ 132 133static ACPI_STATUS 134AcpiExResolveObjectToValue ( 135 ACPI_OPERAND_OBJECT **StackPtr, 136 ACPI_WALK_STATE *WalkState); 137 138 139/******************************************************************************* 140 * 141 * FUNCTION: AcpiExResolveToValue 142 * 143 * PARAMETERS: **StackPtr - Points to entry on ObjStack, which can 144 * be either an (ACPI_OPERAND_OBJECT *) 145 * or an ACPI_HANDLE. 146 * WalkState - Current method state 147 * 148 * RETURN: Status 149 * 150 * DESCRIPTION: Convert Reference objects to values 151 * 152 ******************************************************************************/ 153 154ACPI_STATUS 155AcpiExResolveToValue ( 156 ACPI_OPERAND_OBJECT **StackPtr, 157 ACPI_WALK_STATE *WalkState) 158{ 159 ACPI_STATUS Status; 160 161 162 ACPI_FUNCTION_TRACE_PTR (ExResolveToValue, StackPtr); 163 164 165 if (!StackPtr || !*StackPtr) 166 { 167 ACPI_ERROR ((AE_INFO, "Internal - null pointer")); 168 return_ACPI_STATUS (AE_AML_NO_OPERAND); 169 } 170 171 /* 172 * The entity pointed to by the StackPtr can be either 173 * 1) A valid ACPI_OPERAND_OBJECT, or 174 * 2) A ACPI_NAMESPACE_NODE (NamedObj) 175 */ 176 if (ACPI_GET_DESCRIPTOR_TYPE (*StackPtr) == ACPI_DESC_TYPE_OPERAND) 177 { 178 Status = AcpiExResolveObjectToValue (StackPtr, WalkState); 179 if (ACPI_FAILURE (Status)) 180 { 181 return_ACPI_STATUS (Status); 182 } 183 184 if (!*StackPtr) 185 { 186 ACPI_ERROR ((AE_INFO, "Internal - null pointer")); 187 return_ACPI_STATUS (AE_AML_NO_OPERAND); 188 } 189 } 190 191 /* 192 * Object on the stack may have changed if AcpiExResolveObjectToValue() 193 * was called (i.e., we can't use an _else_ here.) 194 */ 195 if (ACPI_GET_DESCRIPTOR_TYPE (*StackPtr) == ACPI_DESC_TYPE_NAMED) 196 { 197 Status = AcpiExResolveNodeToValue ( 198 ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, StackPtr), 199 WalkState); 200 if (ACPI_FAILURE (Status)) 201 { 202 return_ACPI_STATUS (Status); 203 } 204 } 205 206 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Resolved object %p\n", *StackPtr)); 207 return_ACPI_STATUS (AE_OK); 208} 209 210 211/******************************************************************************* 212 * 213 * FUNCTION: AcpiExResolveObjectToValue 214 * 215 * PARAMETERS: StackPtr - Pointer to an internal object 216 * WalkState - Current method state 217 * 218 * RETURN: Status 219 * 220 * DESCRIPTION: Retrieve the value from an internal object. The Reference type 221 * uses the associated AML opcode to determine the value. 222 * 223 ******************************************************************************/ 224 225static ACPI_STATUS 226AcpiExResolveObjectToValue ( 227 ACPI_OPERAND_OBJECT **StackPtr, 228 ACPI_WALK_STATE *WalkState) 229{ 230 ACPI_STATUS Status = AE_OK; 231 ACPI_OPERAND_OBJECT *StackDesc; 232 ACPI_OPERAND_OBJECT *ObjDesc = NULL; 233 UINT16 Opcode; 234 235 236 ACPI_FUNCTION_TRACE (ExResolveObjectToValue); 237 238 239 StackDesc = *StackPtr; 240 241 /* This is an ACPI_OPERAND_OBJECT */ 242 243 switch (ACPI_GET_OBJECT_TYPE (StackDesc)) 244 { 245 case ACPI_TYPE_LOCAL_REFERENCE: 246 247 Opcode = StackDesc->Reference.Opcode; 248 249 switch (Opcode) 250 { 251 case AML_LOCAL_OP: 252 case AML_ARG_OP: 253 254 /* 255 * Get the local from the method's state info 256 * Note: this increments the local's object reference count 257 */ 258 Status = AcpiDsMethodDataGetValue (Opcode, 259 StackDesc->Reference.Offset, WalkState, &ObjDesc); 260 if (ACPI_FAILURE (Status)) 261 { 262 return_ACPI_STATUS (Status); 263 } 264 265 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Arg/Local %X] ValueObj is %p\n", 266 StackDesc->Reference.Offset, ObjDesc)); 267 268 /* 269 * Now we can delete the original Reference Object and 270 * replace it with the resolved value 271 */ 272 AcpiUtRemoveReference (StackDesc); 273 *StackPtr = ObjDesc; 274 break; 275 276 277 case AML_INDEX_OP: 278 279 switch (StackDesc->Reference.TargetType) 280 { 281 case ACPI_TYPE_BUFFER_FIELD: 282 283 /* Just return - leave the Reference on the stack */ 284 break; 285 286 287 case ACPI_TYPE_PACKAGE: 288 289 ObjDesc = *StackDesc->Reference.Where; 290 if (ObjDesc) 291 { 292 /* 293 * Valid obj descriptor, copy pointer to return value 294 * (i.e., dereference the package index) 295 * Delete the ref object, increment the returned object 296 */ 297 AcpiUtRemoveReference (StackDesc); 298 AcpiUtAddReference (ObjDesc); 299 *StackPtr = ObjDesc; 300 } 301 else 302 { 303 /* 304 * A NULL object descriptor means an unitialized element of 305 * the package, can't dereference it 306 */ 307 ACPI_ERROR ((AE_INFO, 308 "Attempt to deref an Index to NULL pkg element Idx=%p", 309 StackDesc)); 310 Status = AE_AML_UNINITIALIZED_ELEMENT; 311 } 312 break; 313 314 315 default: 316 317 /* Invalid reference object */ 318 319 ACPI_ERROR ((AE_INFO, 320 "Unknown TargetType %X in Index/Reference obj %p", 321 StackDesc->Reference.TargetType, StackDesc)); 322 Status = AE_AML_INTERNAL; 323 break; 324 } 325 break; 326 327 328 case AML_REF_OF_OP: 329 case AML_DEBUG_OP: 330 case AML_LOAD_OP: 331 332 /* Just leave the object as-is */ 333 334 break; 335 336 case AML_INT_NAMEPATH_OP: /* Reference to a named object */ 337 338 /* Dereference the name */ 339 340 if ((StackDesc->Reference.Node->Type == ACPI_TYPE_DEVICE) || 341 (StackDesc->Reference.Node->Type == ACPI_TYPE_THERMAL)) 342 { 343 /* These node types do not have 'real' subobjects */ 344 345 *StackPtr = (void *) StackDesc->Reference.Node; 346 } 347 else 348 { 349 /* Get the object pointed to by the namespace node */ 350 351 *StackPtr = (StackDesc->Reference.Node)->Object; 352 AcpiUtAddReference (*StackPtr); 353 } 354 355 AcpiUtRemoveReference (StackDesc); 356 break; 357 358 default: 359 360 ACPI_ERROR ((AE_INFO, 361 "Unknown Reference opcode %X (%s) in %p", 362 Opcode, AcpiPsGetOpcodeName (Opcode), StackDesc)); 363 Status = AE_AML_INTERNAL; 364 break; 365 } 366 break; 367 368 369 case ACPI_TYPE_BUFFER: 370 371 Status = AcpiDsGetBufferArguments (StackDesc); 372 break; 373 374 375 case ACPI_TYPE_PACKAGE: 376 377 Status = AcpiDsGetPackageArguments (StackDesc); 378 break; 379 380 381 case ACPI_TYPE_BUFFER_FIELD: 382 case ACPI_TYPE_LOCAL_REGION_FIELD: 383 case ACPI_TYPE_LOCAL_BANK_FIELD: 384 case ACPI_TYPE_LOCAL_INDEX_FIELD: 385 386 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "FieldRead SourceDesc=%p Type=%X\n", 387 StackDesc, ACPI_GET_OBJECT_TYPE (StackDesc))); 388 389 Status = AcpiExReadDataFromField (WalkState, StackDesc, &ObjDesc); 390 391 /* Remove a reference to the original operand, then override */ 392 393 AcpiUtRemoveReference (*StackPtr); 394 *StackPtr = (void *) ObjDesc; 395 break; 396 397 default: 398 break; 399 } 400 401 return_ACPI_STATUS (Status); 402} 403 404 405/******************************************************************************* 406 * 407 * FUNCTION: AcpiExResolveMultiple 408 * 409 * PARAMETERS: WalkState - Current state (contains AML opcode) 410 * Operand - Starting point for resolution 411 * ReturnType - Where the object type is returned 412 * ReturnDesc - Where the resolved object is returned 413 * 414 * RETURN: Status 415 * 416 * DESCRIPTION: Return the base object and type. Traverse a reference list if 417 * necessary to get to the base object. 418 * 419 ******************************************************************************/ 420 421ACPI_STATUS 422AcpiExResolveMultiple ( 423 ACPI_WALK_STATE *WalkState, 424 ACPI_OPERAND_OBJECT *Operand, 425 ACPI_OBJECT_TYPE *ReturnType, 426 ACPI_OPERAND_OBJECT **ReturnDesc) 427{ 428 ACPI_OPERAND_OBJECT *ObjDesc = (void *) Operand; 429 ACPI_NAMESPACE_NODE *Node; 430 ACPI_OBJECT_TYPE Type; 431 ACPI_STATUS Status; 432 433 434 ACPI_FUNCTION_TRACE (AcpiExResolveMultiple); 435 436 437 /* Operand can be either a namespace node or an operand descriptor */ 438 439 switch (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc)) 440 { 441 case ACPI_DESC_TYPE_OPERAND: 442 Type = ObjDesc->Common.Type; 443 break; 444 445 case ACPI_DESC_TYPE_NAMED: 446 Type = ((ACPI_NAMESPACE_NODE *) ObjDesc)->Type; 447 ObjDesc = AcpiNsGetAttachedObject ((ACPI_NAMESPACE_NODE *) ObjDesc); 448 449 /* If we had an Alias node, use the attached object for type info */ 450 451 if (Type == ACPI_TYPE_LOCAL_ALIAS) 452 { 453 Type = ((ACPI_NAMESPACE_NODE *) ObjDesc)->Type; 454 ObjDesc = AcpiNsGetAttachedObject ((ACPI_NAMESPACE_NODE *) ObjDesc); 455 } 456 break; 457 458 default: 459 return_ACPI_STATUS (AE_AML_OPERAND_TYPE); 460 } 461 462 /* If type is anything other than a reference, we are done */ 463 464 if (Type != ACPI_TYPE_LOCAL_REFERENCE) 465 { 466 goto Exit; 467 } 468 469 /* 470 * For reference objects created via the RefOf or Index operators, 471 * we need to get to the base object (as per the ACPI specification 472 * of the ObjectType and SizeOf operators). This means traversing 473 * the list of possibly many nested references. 474 */ 475 while (ACPI_GET_OBJECT_TYPE (ObjDesc) == ACPI_TYPE_LOCAL_REFERENCE) 476 { 477 switch (ObjDesc->Reference.Opcode) 478 { 479 case AML_REF_OF_OP: 480 case AML_INT_NAMEPATH_OP: 481 482 /* Dereference the reference pointer */ 483 484 if (ObjDesc->Reference.Opcode == AML_REF_OF_OP) 485 { 486 Node = ObjDesc->Reference.Object; 487 } 488 else /* AML_INT_NAMEPATH_OP */ 489 { 490 Node = ObjDesc->Reference.Node; 491 } 492 493 /* All "References" point to a NS node */ 494 495 if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED) 496 { 497 ACPI_ERROR ((AE_INFO, 498 "Not a NS node %p [%s]", 499 Node, AcpiUtGetDescriptorName (Node))); 500 return_ACPI_STATUS (AE_AML_INTERNAL); 501 } 502 503 /* Get the attached object */ 504 505 ObjDesc = AcpiNsGetAttachedObject (Node); 506 if (!ObjDesc) 507 { 508 /* No object, use the NS node type */ 509 510 Type = AcpiNsGetType (Node); 511 goto Exit; 512 } 513 514 /* Check for circular references */ 515 516 if (ObjDesc == Operand) 517 { 518 return_ACPI_STATUS (AE_AML_CIRCULAR_REFERENCE); 519 } 520 break; 521 522 523 case AML_INDEX_OP: 524 525 /* Get the type of this reference (index into another object) */ 526 527 Type = ObjDesc->Reference.TargetType; 528 if (Type != ACPI_TYPE_PACKAGE) 529 { 530 goto Exit; 531 } 532 533 /* 534 * The main object is a package, we want to get the type 535 * of the individual package element that is referenced by 536 * the index. 537 * 538 * This could of course in turn be another reference object. 539 */ 540 ObjDesc = *(ObjDesc->Reference.Where); 541 if (!ObjDesc) 542 { 543 /* NULL package elements are allowed */ 544 545 Type = 0; /* Uninitialized */ 546 goto Exit; 547 } 548 break; 549 550 551 case AML_LOCAL_OP: 552 case AML_ARG_OP: 553 554 if (ReturnDesc) 555 { 556 Status = AcpiDsMethodDataGetValue (ObjDesc->Reference.Opcode, 557 ObjDesc->Reference.Offset, WalkState, &ObjDesc); 558 if (ACPI_FAILURE (Status)) 559 { 560 return_ACPI_STATUS (Status); 561 } 562 AcpiUtRemoveReference (ObjDesc); 563 } 564 else 565 { 566 Status = AcpiDsMethodDataGetNode (ObjDesc->Reference.Opcode, 567 ObjDesc->Reference.Offset, WalkState, &Node); 568 if (ACPI_FAILURE (Status)) 569 { 570 return_ACPI_STATUS (Status); 571 } 572 573 ObjDesc = AcpiNsGetAttachedObject (Node); 574 if (!ObjDesc) 575 { 576 Type = ACPI_TYPE_ANY; 577 goto Exit; 578 } 579 } 580 break; 581 582 583 case AML_DEBUG_OP: 584 585 /* The Debug Object is of type "DebugObject" */ 586 587 Type = ACPI_TYPE_DEBUG_OBJECT; 588 goto Exit; 589 590 591 default: 592 593 ACPI_ERROR ((AE_INFO, 594 "Unknown Reference subtype %X", 595 ObjDesc->Reference.Opcode)); 596 return_ACPI_STATUS (AE_AML_INTERNAL); 597 } 598 } 599 600 /* 601 * Now we are guaranteed to have an object that has not been created 602 * via the RefOf or Index operators. 603 */ 604 Type = ACPI_GET_OBJECT_TYPE (ObjDesc); 605 606 607Exit: 608 /* Convert internal types to external types */ 609 610 switch (Type) 611 { 612 case ACPI_TYPE_LOCAL_REGION_FIELD: 613 case ACPI_TYPE_LOCAL_BANK_FIELD: 614 case ACPI_TYPE_LOCAL_INDEX_FIELD: 615 616 Type = ACPI_TYPE_FIELD_UNIT; 617 break; 618 619 case ACPI_TYPE_LOCAL_SCOPE: 620 621 /* Per ACPI Specification, Scope is untyped */ 622 623 Type = ACPI_TYPE_ANY; 624 break; 625 626 default: 627 /* No change to Type required */ 628 break; 629 } 630 631 *ReturnType = Type; 632 if (ReturnDesc) 633 { 634 *ReturnDesc = ObjDesc; 635 } 636 return_ACPI_STATUS (AE_OK); 637} 638 639 640