exresolv.c revision 70243
1 2/****************************************************************************** 3 * 4 * Module Name: amresolv - AML Interpreter object resolution 5 * $Revision: 79 $ 6 * 7 *****************************************************************************/ 8 9/****************************************************************************** 10 * 11 * 1. Copyright Notice 12 * 13 * Some or all of this work - Copyright (c) 1999, 2000, 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 __AMRESOLV_C__ 119 120#include "acpi.h" 121#include "amlcode.h" 122#include "acparser.h" 123#include "acdispat.h" 124#include "acinterp.h" 125#include "acnamesp.h" 126#include "actables.h" 127#include "acevents.h" 128 129 130#define _COMPONENT INTERPRETER 131 MODULE_NAME ("amresolv") 132 133 134/******************************************************************************* 135 * 136 * FUNCTION: AcpiAmlGetFieldUnitValue 137 * 138 * PARAMETERS: *FieldDesc - Pointer to a FieldUnit 139 * *ResultDesc - Pointer to an empty descriptor 140 * which will become a Number 141 * containing the field's value. 142 * 143 * RETURN: Status 144 * 145 * DESCRIPTION: Retrieve the value from a FieldUnit 146 * 147 ******************************************************************************/ 148 149ACPI_STATUS 150AcpiAmlGetFieldUnitValue ( 151 ACPI_OPERAND_OBJECT *FieldDesc, 152 ACPI_OPERAND_OBJECT *ResultDesc) 153{ 154 ACPI_STATUS Status = AE_OK; 155 UINT32 Mask; 156 UINT8 *Location = NULL; 157 BOOLEAN Locked = FALSE; 158 159 160 FUNCTION_TRACE ("AmlGetFieldUnitValue"); 161 162 163 if (!FieldDesc) 164 { 165 DEBUG_PRINT (ACPI_ERROR, 166 ("AmlGetFieldUnitValue: Internal error - null field pointer\n")); 167 Status = AE_AML_NO_OPERAND; 168 } 169 170 if (!(FieldDesc->Common.Flags & AOPOBJ_DATA_VALID)) 171 { 172 Status = AcpiDsGetFieldUnitArguments (FieldDesc); 173 if (ACPI_FAILURE (Status)) 174 { 175 return_ACPI_STATUS (Status); 176 } 177 } 178 179 if (!FieldDesc->FieldUnit.Container) 180 { 181 DEBUG_PRINT (ACPI_ERROR, 182 ("AmlGetFieldUnitValue: Internal error - null container pointer\n")); 183 Status = AE_AML_INTERNAL; 184 } 185 186 else if (ACPI_TYPE_BUFFER != FieldDesc->FieldUnit.Container->Common.Type) 187 { 188 DEBUG_PRINT (ACPI_ERROR, 189 ("AmlGetFieldUnitValue: Internal error - container is not a Buffer\n")); 190 Status = AE_AML_OPERAND_TYPE; 191 } 192 193 else if (!ResultDesc) 194 { 195 DEBUG_PRINT (ACPI_ERROR, 196 ("AmlGetFieldUnitValue: Internal error - null result pointer\n")); 197 Status = AE_AML_INTERNAL; 198 } 199 200 if (ACPI_FAILURE (Status)) 201 { 202 return_ACPI_STATUS (Status); 203 } 204 205 206 /* Get the global lock if needed */ 207 208 Locked = AcpiAmlAcquireGlobalLock (FieldDesc->FieldUnit.LockRule); 209 210 /* Field location is (base of buffer) + (byte offset) */ 211 212 Location = FieldDesc->FieldUnit.Container->Buffer.Pointer 213 + FieldDesc->FieldUnit.Offset; 214 215 /* 216 * Construct Mask with as many 1 bits as the field width 217 * 218 * NOTE: Only the bottom 5 bits are valid for a shift operation, so 219 * special care must be taken for any shift greater than 31 bits. 220 * 221 * TBD: [Unhandled] Fields greater than 32-bits will not work. 222 */ 223 224 if (FieldDesc->FieldUnit.Length < 32) 225 { 226 Mask = ((UINT32) 1 << FieldDesc->FieldUnit.Length) - (UINT32) 1; 227 } 228 else 229 { 230 Mask = ACPI_UINT32_MAX; 231 } 232 233 ResultDesc->Number.Type = (UINT8) ACPI_TYPE_NUMBER; 234 235 /* Get the 32 bit value at the location */ 236 237 MOVE_UNALIGNED32_TO_32 (&ResultDesc->Number.Value, Location); 238 239 /* 240 * Shift the 32-bit word containing the field, and mask off the 241 * resulting value 242 */ 243 244 ResultDesc->Number.Value = 245 (ResultDesc->Number.Value >> FieldDesc->FieldUnit.BitOffset) & Mask; 246 247 DEBUG_PRINT (ACPI_INFO, 248 ("** Read from buffer %p byte %ld bit %d width %d addr %p mask %08lx val %08lx\n", 249 FieldDesc->FieldUnit.Container->Buffer.Pointer, 250 FieldDesc->FieldUnit.Offset, 251 FieldDesc->FieldUnit.BitOffset, 252 FieldDesc->FieldUnit.Length, 253 Location, Mask, ResultDesc->Number.Value)); 254 255 /* Release global lock if we acquired it earlier */ 256 257 AcpiAmlReleaseGlobalLock (Locked); 258 259 return_ACPI_STATUS (Status); 260} 261 262 263/******************************************************************************* 264 * 265 * FUNCTION: AcpiAmlResolveToValue 266 * 267 * PARAMETERS: **StackPtr - Points to entry on ObjStack, which can 268 * be either an (ACPI_OPERAND_OBJECT *) 269 * or an ACPI_HANDLE. 270 * 271 * RETURN: Status 272 * 273 * DESCRIPTION: Convert Reference entries on ObjStack to Rvalues 274 * 275 ******************************************************************************/ 276 277ACPI_STATUS 278AcpiAmlResolveToValue ( 279 ACPI_OPERAND_OBJECT **StackPtr, 280 ACPI_WALK_STATE *WalkState) 281{ 282 ACPI_STATUS Status = AE_OK; 283 284 285 FUNCTION_TRACE_PTR ("AmlResolveToValue", StackPtr); 286 287 288 if (!StackPtr || !*StackPtr) 289 { 290 DEBUG_PRINT (ACPI_ERROR, 291 ("AmlResolveToValue: Internal error - null pointer\n")); 292 return_ACPI_STATUS (AE_AML_NO_OPERAND); 293 } 294 295 296 /* 297 * The entity pointed to by the StackPtr can be either 298 * 1) A valid ACPI_OPERAND_OBJECT, or 299 * 2) A ACPI_NAMESPACE_NODE (NamedObj) 300 */ 301 302 if (VALID_DESCRIPTOR_TYPE (*StackPtr, ACPI_DESC_TYPE_INTERNAL)) 303 { 304 305 Status = AcpiAmlResolveObjectToValue (StackPtr, WalkState); 306 if (ACPI_FAILURE (Status)) 307 { 308 return_ACPI_STATUS (Status); 309 } 310 } 311 312 /* 313 * Object on the stack may have changed if AcpiAmlResolveObjectToValue() 314 * was called (i.e., we can't use an _else_ here.) 315 */ 316 317 if (VALID_DESCRIPTOR_TYPE (*StackPtr, ACPI_DESC_TYPE_NAMED)) 318 { 319 Status = AcpiAmlResolveNodeToValue ((ACPI_NAMESPACE_NODE **) StackPtr, WalkState); 320 } 321 322 323 DEBUG_PRINT (ACPI_INFO, 324 ("AmlResolveToValue: Returning resolved object %p\n", *StackPtr)); 325 326 return_ACPI_STATUS (Status); 327} 328 329 330/******************************************************************************* 331 * 332 * FUNCTION: AcpiAmlResolveObjectToValue 333 * 334 * PARAMETERS: StackPtr - Pointer to a stack location that contains a 335 * ptr to an internal object. 336 * 337 * RETURN: Status 338 * 339 * DESCRIPTION: Retrieve the value from an internal object. The Reference type 340 * uses the associated AML opcode to determine the value. 341 * 342 ******************************************************************************/ 343 344ACPI_STATUS 345AcpiAmlResolveObjectToValue ( 346 ACPI_OPERAND_OBJECT **StackPtr, 347 ACPI_WALK_STATE *WalkState) 348{ 349 ACPI_OPERAND_OBJECT *StackDesc; 350 ACPI_STATUS Status = AE_OK; 351 ACPI_HANDLE TempHandle = NULL; 352 ACPI_OPERAND_OBJECT *ObjDesc = NULL; 353 UINT32 Index = 0; 354 UINT16 Opcode; 355 356 357 FUNCTION_TRACE ("AmlResolveObjectToValue"); 358 359 360 StackDesc = *StackPtr; 361 362 /* This is an ACPI_OPERAND_OBJECT */ 363 364 switch (StackDesc->Common.Type) 365 { 366 367 case INTERNAL_TYPE_REFERENCE: 368 369 Opcode = StackDesc->Reference.OpCode; 370 371 switch (Opcode) 372 { 373 374 case AML_NAME_OP: 375 376 /* 377 * Convert indirect name ptr to a direct name ptr. 378 * Then, AcpiAmlResolveNodeToValue can be used to get the value 379 */ 380 381 TempHandle = StackDesc->Reference.Object; 382 383 /* Delete the Reference Object */ 384 385 AcpiCmRemoveReference (StackDesc); 386 387 /* Put direct name pointer onto stack and exit */ 388 389 (*StackPtr) = TempHandle; 390 Status = AE_OK; 391 break; 392 393 394 case AML_LOCAL_OP: 395 396 Index = StackDesc->Reference.Offset; 397 398 /* 399 * Get the local from the method's state info 400 * Note: this increments the local's object reference count 401 */ 402 403 Status = AcpiDsMethodDataGetValue (MTH_TYPE_LOCAL, Index, 404 WalkState, &ObjDesc); 405 if (ACPI_FAILURE (Status)) 406 { 407 return_ACPI_STATUS (Status); 408 } 409 410 /* 411 * Now we can delete the original Reference Object and 412 * replace it with the resolve value 413 */ 414 415 AcpiCmRemoveReference (StackDesc); 416 *StackPtr = ObjDesc; 417 418 DEBUG_PRINT (ACPI_INFO, 419 ("AmlResolveObjectToValue: [Local%d] ValueObj is %p\n", 420 Index, ObjDesc)); 421 422 if (ACPI_TYPE_NUMBER == ObjDesc->Common.Type) 423 { 424 /* Value is a Number */ 425 426 DEBUG_PRINT (ACPI_INFO, 427 ("AmlResolveObjectToValue: [Local%d] value=%X \n", 428 Index, ObjDesc->Number.Value)); 429 } 430 431 break; 432 433 434 case AML_ARG_OP: 435 436 Index = StackDesc->Reference.Offset; 437 438 439 /* 440 * Get the argument from the method's state info 441 * Note: this increments the object reference count 442 */ 443 444 Status = AcpiDsMethodDataGetValue (MTH_TYPE_ARG, Index, 445 WalkState, &ObjDesc); 446 if (ACPI_FAILURE (Status)) 447 { 448 return_ACPI_STATUS (Status); 449 } 450 451 /* 452 * Now we can delete the original Reference Object and 453 * replace it with the resolve value 454 */ 455 456 AcpiCmRemoveReference (StackDesc); 457 *StackPtr = ObjDesc; 458 459 DEBUG_PRINT (TRACE_EXEC, 460 ("AmlResolveObjectToValue: [Arg%d] ValueObj is %p\n", 461 Index, ObjDesc)); 462 463 if (ACPI_TYPE_NUMBER == ObjDesc->Common.Type) 464 { 465 /* Value is a Number */ 466 467 DEBUG_PRINT (ACPI_INFO, 468 ("AmlResolveObjectToValue: [Arg%d] value=%X\n", 469 Index, ObjDesc->Number.Value)); 470 } 471 472 break; 473 474 475 /* 476 * TBD: [Restructure] These next three opcodes change the type of 477 * the object, which is actually a no-no. 478 */ 479 480 case AML_ZERO_OP: 481 482 StackDesc->Common.Type = (UINT8) ACPI_TYPE_NUMBER; 483 StackDesc->Number.Value = 0; 484 break; 485 486 487 case AML_ONE_OP: 488 489 StackDesc->Common.Type = (UINT8) ACPI_TYPE_NUMBER; 490 StackDesc->Number.Value = 1; 491 break; 492 493 494 case AML_ONES_OP: 495 496 StackDesc->Common.Type = (UINT8) ACPI_TYPE_NUMBER; 497 StackDesc->Number.Value = ACPI_INTEGER_MAX; 498 499 /* Truncate value if we are executing from a 32-bit ACPI table */ 500 501 AcpiAmlTruncateFor32bitTable (StackDesc, WalkState); 502 break; 503 504 505 case AML_INDEX_OP: 506 507 switch (StackDesc->Reference.TargetType) 508 { 509 case ACPI_TYPE_BUFFER_FIELD: 510 511 /* Just return - leave the Reference on the stack */ 512 break; 513 514 515 case ACPI_TYPE_PACKAGE: 516 ObjDesc = *StackDesc->Reference.Where; 517 if (ObjDesc) 518 { 519 /* 520 * Valid obj descriptor, copy pointer to return value 521 * (i.e., dereference the package index) 522 * Delete the ref object, increment the returned object 523 */ 524 AcpiCmRemoveReference (StackDesc); 525 AcpiCmAddReference (ObjDesc); 526 *StackPtr = ObjDesc; 527 } 528 529 else 530 { 531 /* 532 * A NULL object descriptor means an unitialized element of 533 * the package, can't deref it 534 */ 535 536 DEBUG_PRINT (ACPI_ERROR, 537 ("AmlResolveObjectToValue: Attempt to deref an Index to NULL pkg element Idx=%p\n", StackDesc)); 538 Status = AE_AML_UNINITIALIZED_ELEMENT; 539 } 540 break; 541 542 default: 543 /* Invalid reference OBJ*/ 544 545 DEBUG_PRINT (ACPI_ERROR, 546 ("AmlResolveObjectToValue: Unknown TargetType %X in Index/Reference obj %p\n", 547 StackDesc->Reference.TargetType, StackDesc)); 548 Status = AE_AML_INTERNAL; 549 break; 550 } 551 552 break; 553 554 555 case AML_DEBUG_OP: 556 557 /* Just leave the object as-is */ 558 break; 559 560 561 default: 562 563 DEBUG_PRINT (ACPI_ERROR, 564 ("AmlResolveObjectToValue: Unknown Reference object subtype %02X in %p\n", 565 Opcode, StackDesc)); 566 Status = AE_AML_INTERNAL; 567 568 } /* switch (Opcode) */ 569 570 571 if (ACPI_FAILURE (Status)) 572 { 573 return_ACPI_STATUS (Status); 574 } 575 576 break; /* case INTERNAL_TYPE_REFERENCE */ 577 578 579 case ACPI_TYPE_FIELD_UNIT: 580 581 ObjDesc = AcpiCmCreateInternalObject (ACPI_TYPE_ANY); 582 if (!ObjDesc) 583 { 584 /* Descriptor allocation failure */ 585 586 return_ACPI_STATUS (AE_NO_MEMORY); 587 } 588 589 Status = AcpiAmlGetFieldUnitValue (StackDesc, ObjDesc); 590 if (ACPI_FAILURE (Status)) 591 { 592 AcpiCmRemoveReference (ObjDesc); 593 ObjDesc = NULL; 594 } 595 596 *StackPtr = (void *) ObjDesc; 597 break; 598 599 600 case INTERNAL_TYPE_BANK_FIELD: 601 602 ObjDesc = AcpiCmCreateInternalObject (ACPI_TYPE_ANY); 603 if (!ObjDesc) 604 { 605 /* Descriptor allocation failure */ 606 607 return_ACPI_STATUS (AE_NO_MEMORY); 608 } 609 610 Status = AcpiAmlGetFieldUnitValue (StackDesc, ObjDesc); 611 if (ACPI_FAILURE (Status)) 612 { 613 AcpiCmRemoveReference (ObjDesc); 614 ObjDesc = NULL; 615 } 616 617 *StackPtr = (void *) ObjDesc; 618 break; 619 620 621 /* TBD: [Future] - may need to handle IndexField, and DefField someday */ 622 623 default: 624 625 break; 626 627 } /* switch (StackDesc->Common.Type) */ 628 629 630 return_ACPI_STATUS (Status); 631} 632 633 634