1 /****************************************************************************** 2 * 3 * Module Name: dsobject - Dispatcher object management routines 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2016, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 #include <contrib/dev/acpica/include/acpi.h> 45 #include <contrib/dev/acpica/include/accommon.h> 46 #include <contrib/dev/acpica/include/acparser.h> 47 #include <contrib/dev/acpica/include/amlcode.h> 48 #include <contrib/dev/acpica/include/acdispat.h> 49 #include <contrib/dev/acpica/include/acnamesp.h> 50 #include <contrib/dev/acpica/include/acinterp.h> 51 52 #define _COMPONENT ACPI_DISPATCHER 53 ACPI_MODULE_NAME ("dsobject") 54 55 /* Local prototypes */ 56 57 static ACPI_STATUS 58 AcpiDsBuildInternalObject ( 59 ACPI_WALK_STATE *WalkState, 60 ACPI_PARSE_OBJECT *Op, 61 ACPI_OPERAND_OBJECT **ObjDescPtr); 62 63 64 #ifndef ACPI_NO_METHOD_EXECUTION 65 /******************************************************************************* 66 * 67 * FUNCTION: AcpiDsBuildInternalObject 68 * 69 * PARAMETERS: WalkState - Current walk state 70 * Op - Parser object to be translated 71 * ObjDescPtr - Where the ACPI internal object is returned 72 * 73 * RETURN: Status 74 * 75 * DESCRIPTION: Translate a parser Op object to the equivalent namespace object 76 * Simple objects are any objects other than a package object! 77 * 78 ******************************************************************************/ 79 80 static ACPI_STATUS 81 AcpiDsBuildInternalObject ( 82 ACPI_WALK_STATE *WalkState, 83 ACPI_PARSE_OBJECT *Op, 84 ACPI_OPERAND_OBJECT **ObjDescPtr) 85 { 86 ACPI_OPERAND_OBJECT *ObjDesc; 87 ACPI_STATUS Status; 88 ACPI_OBJECT_TYPE Type; 89 90 91 ACPI_FUNCTION_TRACE (DsBuildInternalObject); 92 93 94 *ObjDescPtr = NULL; 95 if (Op->Common.AmlOpcode == AML_INT_NAMEPATH_OP) 96 { 97 /* 98 * This is a named object reference. If this name was 99 * previously looked up in the namespace, it was stored in this op. 100 * Otherwise, go ahead and look it up now 101 */ 102 if (!Op->Common.Node) 103 { 104 Status = AcpiNsLookup (WalkState->ScopeInfo, 105 Op->Common.Value.String, 106 ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, 107 ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL, 108 ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, &(Op->Common.Node))); 109 if (ACPI_FAILURE (Status)) 110 { 111 /* Check if we are resolving a named reference within a package */ 112 113 if ((Status == AE_NOT_FOUND) && (AcpiGbl_EnableInterpreterSlack) && 114 115 ((Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) || 116 (Op->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP))) 117 { 118 /* 119 * We didn't find the target and we are populating elements 120 * of a package - ignore if slack enabled. Some ASL code 121 * contains dangling invalid references in packages and 122 * expects that no exception will be issued. Leave the 123 * element as a null element. It cannot be used, but it 124 * can be overwritten by subsequent ASL code - this is 125 * typically the case. 126 */ 127 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 128 "Ignoring unresolved reference in package [%4.4s]\n", 129 WalkState->ScopeInfo->Scope.Node->Name.Ascii)); 130 131 return_ACPI_STATUS (AE_OK); 132 } 133 else 134 { 135 ACPI_ERROR_NAMESPACE (Op->Common.Value.String, Status); 136 } 137 138 return_ACPI_STATUS (Status); 139 } 140 } 141 142 /* Special object resolution for elements of a package */ 143 144 if ((Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) || 145 (Op->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP)) 146 { 147 /* 148 * Attempt to resolve the node to a value before we insert it into 149 * the package. If this is a reference to a common data type, 150 * resolve it immediately. According to the ACPI spec, package 151 * elements can only be "data objects" or method references. 152 * Attempt to resolve to an Integer, Buffer, String or Package. 153 * If cannot, return the named reference (for things like Devices, 154 * Methods, etc.) Buffer Fields and Fields will resolve to simple 155 * objects (int/buf/str/pkg). 156 * 157 * NOTE: References to things like Devices, Methods, Mutexes, etc. 158 * will remain as named references. This behavior is not described 159 * in the ACPI spec, but it appears to be an oversight. 160 */ 161 ObjDesc = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Op->Common.Node); 162 163 Status = AcpiExResolveNodeToValue ( 164 ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, &ObjDesc), 165 WalkState); 166 if (ACPI_FAILURE (Status)) 167 { 168 return_ACPI_STATUS (Status); 169 } 170 171 /* 172 * Special handling for Alias objects. We need to setup the type 173 * and the Op->Common.Node to point to the Alias target. Note, 174 * Alias has at most one level of indirection internally. 175 */ 176 Type = Op->Common.Node->Type; 177 if (Type == ACPI_TYPE_LOCAL_ALIAS) 178 { 179 Type = ObjDesc->Common.Type; 180 Op->Common.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, 181 Op->Common.Node->Object); 182 } 183 184 switch (Type) 185 { 186 /* 187 * For these types, we need the actual node, not the subobject. 188 * However, the subobject did not get an extra reference count above. 189 * 190 * TBD: should ExResolveNodeToValue be changed to fix this? 191 */ 192 case ACPI_TYPE_DEVICE: 193 case ACPI_TYPE_THERMAL: 194 195 AcpiUtAddReference (Op->Common.Node->Object); 196 197 /*lint -fallthrough */ 198 /* 199 * For these types, we need the actual node, not the subobject. 200 * The subobject got an extra reference count in ExResolveNodeToValue. 201 */ 202 case ACPI_TYPE_MUTEX: 203 case ACPI_TYPE_METHOD: 204 case ACPI_TYPE_POWER: 205 case ACPI_TYPE_PROCESSOR: 206 case ACPI_TYPE_EVENT: 207 case ACPI_TYPE_REGION: 208 209 /* We will create a reference object for these types below */ 210 break; 211 212 default: 213 /* 214 * All other types - the node was resolved to an actual 215 * object, we are done. 216 */ 217 goto Exit; 218 } 219 } 220 } 221 222 /* Create and init a new internal ACPI object */ 223 224 ObjDesc = AcpiUtCreateInternalObject ( 225 (AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode))->ObjectType); 226 if (!ObjDesc) 227 { 228 return_ACPI_STATUS (AE_NO_MEMORY); 229 } 230 231 Status = AcpiDsInitObjectFromOp ( 232 WalkState, Op, Op->Common.AmlOpcode, &ObjDesc); 233 if (ACPI_FAILURE (Status)) 234 { 235 AcpiUtRemoveReference (ObjDesc); 236 return_ACPI_STATUS (Status); 237 } 238 239 Exit: 240 *ObjDescPtr = ObjDesc; 241 return_ACPI_STATUS (Status); 242 } 243 244 245 /******************************************************************************* 246 * 247 * FUNCTION: AcpiDsBuildInternalBufferObj 248 * 249 * PARAMETERS: WalkState - Current walk state 250 * Op - Parser object to be translated 251 * BufferLength - Length of the buffer 252 * ObjDescPtr - Where the ACPI internal object is returned 253 * 254 * RETURN: Status 255 * 256 * DESCRIPTION: Translate a parser Op package object to the equivalent 257 * namespace object 258 * 259 ******************************************************************************/ 260 261 ACPI_STATUS 262 AcpiDsBuildInternalBufferObj ( 263 ACPI_WALK_STATE *WalkState, 264 ACPI_PARSE_OBJECT *Op, 265 UINT32 BufferLength, 266 ACPI_OPERAND_OBJECT **ObjDescPtr) 267 { 268 ACPI_PARSE_OBJECT *Arg; 269 ACPI_OPERAND_OBJECT *ObjDesc; 270 ACPI_PARSE_OBJECT *ByteList; 271 UINT32 ByteListLength = 0; 272 273 274 ACPI_FUNCTION_TRACE (DsBuildInternalBufferObj); 275 276 277 /* 278 * If we are evaluating a Named buffer object "Name (xxxx, Buffer)". 279 * The buffer object already exists (from the NS node), otherwise it must 280 * be created. 281 */ 282 ObjDesc = *ObjDescPtr; 283 if (!ObjDesc) 284 { 285 /* Create a new buffer object */ 286 287 ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_BUFFER); 288 *ObjDescPtr = ObjDesc; 289 if (!ObjDesc) 290 { 291 return_ACPI_STATUS (AE_NO_MEMORY); 292 } 293 } 294 295 /* 296 * Second arg is the buffer data (optional) ByteList can be either 297 * individual bytes or a string initializer. In either case, a 298 * ByteList appears in the AML. 299 */ 300 Arg = Op->Common.Value.Arg; /* skip first arg */ 301 302 ByteList = Arg->Named.Next; 303 if (ByteList) 304 { 305 if (ByteList->Common.AmlOpcode != AML_INT_BYTELIST_OP) 306 { 307 ACPI_ERROR ((AE_INFO, 308 "Expecting bytelist, found AML opcode 0x%X in op %p", 309 ByteList->Common.AmlOpcode, ByteList)); 310 311 AcpiUtRemoveReference (ObjDesc); 312 return (AE_TYPE); 313 } 314 315 ByteListLength = (UINT32) ByteList->Common.Value.Integer; 316 } 317 318 /* 319 * The buffer length (number of bytes) will be the larger of: 320 * 1) The specified buffer length and 321 * 2) The length of the initializer byte list 322 */ 323 ObjDesc->Buffer.Length = BufferLength; 324 if (ByteListLength > BufferLength) 325 { 326 ObjDesc->Buffer.Length = ByteListLength; 327 } 328 329 /* Allocate the buffer */ 330 331 if (ObjDesc->Buffer.Length == 0) 332 { 333 ObjDesc->Buffer.Pointer = NULL; 334 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 335 "Buffer defined with zero length in AML, creating\n")); 336 } 337 else 338 { 339 ObjDesc->Buffer.Pointer = 340 ACPI_ALLOCATE_ZEROED (ObjDesc->Buffer.Length); 341 if (!ObjDesc->Buffer.Pointer) 342 { 343 AcpiUtDeleteObjectDesc (ObjDesc); 344 return_ACPI_STATUS (AE_NO_MEMORY); 345 } 346 347 /* Initialize buffer from the ByteList (if present) */ 348 349 if (ByteList) 350 { 351 memcpy (ObjDesc->Buffer.Pointer, ByteList->Named.Data, 352 ByteListLength); 353 } 354 } 355 356 ObjDesc->Buffer.Flags |= AOPOBJ_DATA_VALID; 357 Op->Common.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjDesc); 358 return_ACPI_STATUS (AE_OK); 359 } 360 361 362 /******************************************************************************* 363 * 364 * FUNCTION: AcpiDsBuildInternalPackageObj 365 * 366 * PARAMETERS: WalkState - Current walk state 367 * Op - Parser object to be translated 368 * ElementCount - Number of elements in the package - this is 369 * the NumElements argument to Package() 370 * ObjDescPtr - Where the ACPI internal object is returned 371 * 372 * RETURN: Status 373 * 374 * DESCRIPTION: Translate a parser Op package object to the equivalent 375 * namespace object 376 * 377 * NOTE: The number of elements in the package will be always be the NumElements 378 * count, regardless of the number of elements in the package list. If 379 * NumElements is smaller, only that many package list elements are used. 380 * if NumElements is larger, the Package object is padded out with 381 * objects of type Uninitialized (as per ACPI spec.) 382 * 383 * Even though the ASL compilers do not allow NumElements to be smaller 384 * than the Package list length (for the fixed length package opcode), some 385 * BIOS code modifies the AML on the fly to adjust the NumElements, and 386 * this code compensates for that. This also provides compatibility with 387 * other AML interpreters. 388 * 389 ******************************************************************************/ 390 391 ACPI_STATUS 392 AcpiDsBuildInternalPackageObj ( 393 ACPI_WALK_STATE *WalkState, 394 ACPI_PARSE_OBJECT *Op, 395 UINT32 ElementCount, 396 ACPI_OPERAND_OBJECT **ObjDescPtr) 397 { 398 ACPI_PARSE_OBJECT *Arg; 399 ACPI_PARSE_OBJECT *Parent; 400 ACPI_OPERAND_OBJECT *ObjDesc = NULL; 401 ACPI_STATUS Status = AE_OK; 402 UINT32 i; 403 UINT16 Index; 404 UINT16 ReferenceCount; 405 406 407 ACPI_FUNCTION_TRACE (DsBuildInternalPackageObj); 408 409 410 /* Find the parent of a possibly nested package */ 411 412 Parent = Op->Common.Parent; 413 while ((Parent->Common.AmlOpcode == AML_PACKAGE_OP) || 414 (Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP)) 415 { 416 Parent = Parent->Common.Parent; 417 } 418 419 /* 420 * If we are evaluating a Named package object "Name (xxxx, Package)", 421 * the package object already exists, otherwise it must be created. 422 */ 423 ObjDesc = *ObjDescPtr; 424 if (!ObjDesc) 425 { 426 ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_PACKAGE); 427 *ObjDescPtr = ObjDesc; 428 if (!ObjDesc) 429 { 430 return_ACPI_STATUS (AE_NO_MEMORY); 431 } 432 433 ObjDesc->Package.Node = Parent->Common.Node; 434 } 435 436 /* 437 * Allocate the element array (array of pointers to the individual 438 * objects) based on the NumElements parameter. Add an extra pointer slot 439 * so that the list is always null terminated. 440 */ 441 ObjDesc->Package.Elements = ACPI_ALLOCATE_ZEROED ( 442 ((ACPI_SIZE) ElementCount + 1) * sizeof (void *)); 443 444 if (!ObjDesc->Package.Elements) 445 { 446 AcpiUtDeleteObjectDesc (ObjDesc); 447 return_ACPI_STATUS (AE_NO_MEMORY); 448 } 449 450 ObjDesc->Package.Count = ElementCount; 451 452 /* 453 * Initialize the elements of the package, up to the NumElements count. 454 * Package is automatically padded with uninitialized (NULL) elements 455 * if NumElements is greater than the package list length. Likewise, 456 * Package is truncated if NumElements is less than the list length. 457 */ 458 Arg = Op->Common.Value.Arg; 459 Arg = Arg->Common.Next; 460 for (i = 0; Arg && (i < ElementCount); i++) 461 { 462 if (Arg->Common.AmlOpcode == AML_INT_RETURN_VALUE_OP) 463 { 464 if (Arg->Common.Node->Type == ACPI_TYPE_METHOD) 465 { 466 /* 467 * A method reference "looks" to the parser to be a method 468 * invocation, so we special case it here 469 */ 470 Arg->Common.AmlOpcode = AML_INT_NAMEPATH_OP; 471 Status = AcpiDsBuildInternalObject ( 472 WalkState, Arg, &ObjDesc->Package.Elements[i]); 473 } 474 else 475 { 476 /* This package element is already built, just get it */ 477 478 ObjDesc->Package.Elements[i] = 479 ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Arg->Common.Node); 480 } 481 } 482 else 483 { 484 Status = AcpiDsBuildInternalObject ( 485 WalkState, Arg, &ObjDesc->Package.Elements[i]); 486 } 487 488 if (*ObjDescPtr) 489 { 490 /* Existing package, get existing reference count */ 491 492 ReferenceCount = (*ObjDescPtr)->Common.ReferenceCount; 493 if (ReferenceCount > 1) 494 { 495 /* Make new element ref count match original ref count */ 496 497 for (Index = 0; Index < (ReferenceCount - 1); Index++) 498 { 499 AcpiUtAddReference ((ObjDesc->Package.Elements[i])); 500 } 501 } 502 } 503 504 Arg = Arg->Common.Next; 505 } 506 507 /* Check for match between NumElements and actual length of PackageList */ 508 509 if (Arg) 510 { 511 /* 512 * NumElements was exhausted, but there are remaining elements in the 513 * PackageList. Truncate the package to NumElements. 514 * 515 * Note: technically, this is an error, from ACPI spec: "It is an error 516 * for NumElements to be less than the number of elements in the 517 * PackageList". However, we just print a message and 518 * no exception is returned. This provides Windows compatibility. Some 519 * BIOSs will alter the NumElements on the fly, creating this type 520 * of ill-formed package object. 521 */ 522 while (Arg) 523 { 524 /* 525 * We must delete any package elements that were created earlier 526 * and are not going to be used because of the package truncation. 527 */ 528 if (Arg->Common.Node) 529 { 530 AcpiUtRemoveReference ( 531 ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Arg->Common.Node)); 532 Arg->Common.Node = NULL; 533 } 534 535 /* Find out how many elements there really are */ 536 537 i++; 538 Arg = Arg->Common.Next; 539 } 540 541 ACPI_INFO (( 542 "Actual Package length (%u) is larger than " 543 "NumElements field (%u), truncated", 544 i, ElementCount)); 545 } 546 else if (i < ElementCount) 547 { 548 /* 549 * Arg list (elements) was exhausted, but we did not reach NumElements count. 550 * Note: this is not an error, the package is padded out with NULLs. 551 */ 552 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 553 "Package List length (%u) smaller than NumElements " 554 "count (%u), padded with null elements\n", 555 i, ElementCount)); 556 } 557 558 ObjDesc->Package.Flags |= AOPOBJ_DATA_VALID; 559 Op->Common.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjDesc); 560 return_ACPI_STATUS (Status); 561 } 562 563 564 /******************************************************************************* 565 * 566 * FUNCTION: AcpiDsCreateNode 567 * 568 * PARAMETERS: WalkState - Current walk state 569 * Node - NS Node to be initialized 570 * Op - Parser object to be translated 571 * 572 * RETURN: Status 573 * 574 * DESCRIPTION: Create the object to be associated with a namespace node 575 * 576 ******************************************************************************/ 577 578 ACPI_STATUS 579 AcpiDsCreateNode ( 580 ACPI_WALK_STATE *WalkState, 581 ACPI_NAMESPACE_NODE *Node, 582 ACPI_PARSE_OBJECT *Op) 583 { 584 ACPI_STATUS Status; 585 ACPI_OPERAND_OBJECT *ObjDesc; 586 587 588 ACPI_FUNCTION_TRACE_PTR (DsCreateNode, Op); 589 590 591 /* 592 * Because of the execution pass through the non-control-method 593 * parts of the table, we can arrive here twice. Only init 594 * the named object node the first time through 595 */ 596 if (AcpiNsGetAttachedObject (Node)) 597 { 598 return_ACPI_STATUS (AE_OK); 599 } 600 601 if (!Op->Common.Value.Arg) 602 { 603 /* No arguments, there is nothing to do */ 604 605 return_ACPI_STATUS (AE_OK); 606 } 607 608 /* Build an internal object for the argument(s) */ 609 610 Status = AcpiDsBuildInternalObject ( 611 WalkState, Op->Common.Value.Arg, &ObjDesc); 612 if (ACPI_FAILURE (Status)) 613 { 614 return_ACPI_STATUS (Status); 615 } 616 617 /* Re-type the object according to its argument */ 618 619 Node->Type = ObjDesc->Common.Type; 620 621 /* Attach obj to node */ 622 623 Status = AcpiNsAttachObject (Node, ObjDesc, Node->Type); 624 625 /* Remove local reference to the object */ 626 627 AcpiUtRemoveReference (ObjDesc); 628 return_ACPI_STATUS (Status); 629 } 630 631 #endif /* ACPI_NO_METHOD_EXECUTION */ 632 633 634 /******************************************************************************* 635 * 636 * FUNCTION: AcpiDsInitObjectFromOp 637 * 638 * PARAMETERS: WalkState - Current walk state 639 * Op - Parser op used to init the internal object 640 * Opcode - AML opcode associated with the object 641 * RetObjDesc - Namespace object to be initialized 642 * 643 * RETURN: Status 644 * 645 * DESCRIPTION: Initialize a namespace object from a parser Op and its 646 * associated arguments. The namespace object is a more compact 647 * representation of the Op and its arguments. 648 * 649 ******************************************************************************/ 650 651 ACPI_STATUS 652 AcpiDsInitObjectFromOp ( 653 ACPI_WALK_STATE *WalkState, 654 ACPI_PARSE_OBJECT *Op, 655 UINT16 Opcode, 656 ACPI_OPERAND_OBJECT **RetObjDesc) 657 { 658 const ACPI_OPCODE_INFO *OpInfo; 659 ACPI_OPERAND_OBJECT *ObjDesc; 660 ACPI_STATUS Status = AE_OK; 661 662 663 ACPI_FUNCTION_TRACE (DsInitObjectFromOp); 664 665 666 ObjDesc = *RetObjDesc; 667 OpInfo = AcpiPsGetOpcodeInfo (Opcode); 668 if (OpInfo->Class == AML_CLASS_UNKNOWN) 669 { 670 /* Unknown opcode */ 671 672 return_ACPI_STATUS (AE_TYPE); 673 } 674 675 /* Perform per-object initialization */ 676 677 switch (ObjDesc->Common.Type) 678 { 679 case ACPI_TYPE_BUFFER: 680 /* 681 * Defer evaluation of Buffer TermArg operand 682 */ 683 ObjDesc->Buffer.Node = ACPI_CAST_PTR ( 684 ACPI_NAMESPACE_NODE, WalkState->Operands[0]); 685 ObjDesc->Buffer.AmlStart = Op->Named.Data; 686 ObjDesc->Buffer.AmlLength = Op->Named.Length; 687 break; 688 689 case ACPI_TYPE_PACKAGE: 690 /* 691 * Defer evaluation of Package TermArg operand 692 */ 693 ObjDesc->Package.Node = ACPI_CAST_PTR ( 694 ACPI_NAMESPACE_NODE, WalkState->Operands[0]); 695 ObjDesc->Package.AmlStart = Op->Named.Data; 696 ObjDesc->Package.AmlLength = Op->Named.Length; 697 break; 698 699 case ACPI_TYPE_INTEGER: 700 701 switch (OpInfo->Type) 702 { 703 case AML_TYPE_CONSTANT: 704 /* 705 * Resolve AML Constants here - AND ONLY HERE! 706 * All constants are integers. 707 * We mark the integer with a flag that indicates that it started 708 * life as a constant -- so that stores to constants will perform 709 * as expected (noop). ZeroOp is used as a placeholder for optional 710 * target operands. 711 */ 712 ObjDesc->Common.Flags = AOPOBJ_AML_CONSTANT; 713 714 switch (Opcode) 715 { 716 case AML_ZERO_OP: 717 718 ObjDesc->Integer.Value = 0; 719 break; 720 721 case AML_ONE_OP: 722 723 ObjDesc->Integer.Value = 1; 724 break; 725 726 case AML_ONES_OP: 727 728 ObjDesc->Integer.Value = ACPI_UINT64_MAX; 729 730 /* Truncate value if we are executing from a 32-bit ACPI table */ 731 732 #ifndef ACPI_NO_METHOD_EXECUTION 733 (void) AcpiExTruncateFor32bitTable (ObjDesc); 734 #endif 735 break; 736 737 case AML_REVISION_OP: 738 739 ObjDesc->Integer.Value = ACPI_CA_VERSION; 740 break; 741 742 default: 743 744 ACPI_ERROR ((AE_INFO, 745 "Unknown constant opcode 0x%X", Opcode)); 746 Status = AE_AML_OPERAND_TYPE; 747 break; 748 } 749 break; 750 751 case AML_TYPE_LITERAL: 752 753 ObjDesc->Integer.Value = Op->Common.Value.Integer; 754 755 #ifndef ACPI_NO_METHOD_EXECUTION 756 if (AcpiExTruncateFor32bitTable (ObjDesc)) 757 { 758 /* Warn if we found a 64-bit constant in a 32-bit table */ 759 760 ACPI_WARNING ((AE_INFO, 761 "Truncated 64-bit constant found in 32-bit table: %8.8X%8.8X => %8.8X", 762 ACPI_FORMAT_UINT64 (Op->Common.Value.Integer), 763 (UINT32) ObjDesc->Integer.Value)); 764 } 765 #endif 766 break; 767 768 default: 769 770 ACPI_ERROR ((AE_INFO, "Unknown Integer type 0x%X", 771 OpInfo->Type)); 772 Status = AE_AML_OPERAND_TYPE; 773 break; 774 } 775 break; 776 777 case ACPI_TYPE_STRING: 778 779 ObjDesc->String.Pointer = Op->Common.Value.String; 780 ObjDesc->String.Length = (UINT32) strlen (Op->Common.Value.String); 781 782 /* 783 * The string is contained in the ACPI table, don't ever try 784 * to delete it 785 */ 786 ObjDesc->Common.Flags |= AOPOBJ_STATIC_POINTER; 787 break; 788 789 case ACPI_TYPE_METHOD: 790 break; 791 792 case ACPI_TYPE_LOCAL_REFERENCE: 793 794 switch (OpInfo->Type) 795 { 796 case AML_TYPE_LOCAL_VARIABLE: 797 798 /* Local ID (0-7) is (AML opcode - base AML_LOCAL_OP) */ 799 800 ObjDesc->Reference.Value = ((UINT32) Opcode) - AML_LOCAL_OP; 801 ObjDesc->Reference.Class = ACPI_REFCLASS_LOCAL; 802 803 #ifndef ACPI_NO_METHOD_EXECUTION 804 Status = AcpiDsMethodDataGetNode (ACPI_REFCLASS_LOCAL, 805 ObjDesc->Reference.Value, WalkState, 806 ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, 807 &ObjDesc->Reference.Object)); 808 #endif 809 break; 810 811 case AML_TYPE_METHOD_ARGUMENT: 812 813 /* Arg ID (0-6) is (AML opcode - base AML_ARG_OP) */ 814 815 ObjDesc->Reference.Value = ((UINT32) Opcode) - AML_ARG_OP; 816 ObjDesc->Reference.Class = ACPI_REFCLASS_ARG; 817 818 #ifndef ACPI_NO_METHOD_EXECUTION 819 Status = AcpiDsMethodDataGetNode (ACPI_REFCLASS_ARG, 820 ObjDesc->Reference.Value, WalkState, 821 ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, 822 &ObjDesc->Reference.Object)); 823 #endif 824 break; 825 826 default: /* Object name or Debug object */ 827 828 switch (Op->Common.AmlOpcode) 829 { 830 case AML_INT_NAMEPATH_OP: 831 832 /* Node was saved in Op */ 833 834 ObjDesc->Reference.Node = Op->Common.Node; 835 ObjDesc->Reference.Object = Op->Common.Node->Object; 836 ObjDesc->Reference.Class = ACPI_REFCLASS_NAME; 837 break; 838 839 case AML_DEBUG_OP: 840 841 ObjDesc->Reference.Class = ACPI_REFCLASS_DEBUG; 842 break; 843 844 default: 845 846 ACPI_ERROR ((AE_INFO, 847 "Unimplemented reference type for AML opcode: 0x%4.4X", Opcode)); 848 return_ACPI_STATUS (AE_AML_OPERAND_TYPE); 849 } 850 break; 851 } 852 break; 853 854 default: 855 856 ACPI_ERROR ((AE_INFO, "Unimplemented data type: 0x%X", 857 ObjDesc->Common.Type)); 858 859 Status = AE_AML_OPERAND_TYPE; 860 break; 861 } 862 863 return_ACPI_STATUS (Status); 864 } 865