1 /****************************************************************************** 2 * 3 * Module Name: dsobject - Dispatcher object management routines 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2015, 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 (WalkState, Op, Op->Common.AmlOpcode, 232 &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 = ACPI_ALLOCATE_ZEROED ( 340 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 (WalkState, Arg, 472 &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 (WalkState, Arg, 485 &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 ((AE_INFO, 542 "Actual Package length (%u) is larger than NumElements field (%u), truncated", 543 i, ElementCount)); 544 } 545 else if (i < ElementCount) 546 { 547 /* 548 * Arg list (elements) was exhausted, but we did not reach NumElements count. 549 * Note: this is not an error, the package is padded out with NULLs. 550 */ 551 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 552 "Package List length (%u) smaller than NumElements count (%u), padded with null elements\n", 553 i, ElementCount)); 554 } 555 556 ObjDesc->Package.Flags |= AOPOBJ_DATA_VALID; 557 Op->Common.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjDesc); 558 return_ACPI_STATUS (Status); 559 } 560 561 562 /******************************************************************************* 563 * 564 * FUNCTION: AcpiDsCreateNode 565 * 566 * PARAMETERS: WalkState - Current walk state 567 * Node - NS Node to be initialized 568 * Op - Parser object to be translated 569 * 570 * RETURN: Status 571 * 572 * DESCRIPTION: Create the object to be associated with a namespace node 573 * 574 ******************************************************************************/ 575 576 ACPI_STATUS 577 AcpiDsCreateNode ( 578 ACPI_WALK_STATE *WalkState, 579 ACPI_NAMESPACE_NODE *Node, 580 ACPI_PARSE_OBJECT *Op) 581 { 582 ACPI_STATUS Status; 583 ACPI_OPERAND_OBJECT *ObjDesc; 584 585 586 ACPI_FUNCTION_TRACE_PTR (DsCreateNode, Op); 587 588 589 /* 590 * Because of the execution pass through the non-control-method 591 * parts of the table, we can arrive here twice. Only init 592 * the named object node the first time through 593 */ 594 if (AcpiNsGetAttachedObject (Node)) 595 { 596 return_ACPI_STATUS (AE_OK); 597 } 598 599 if (!Op->Common.Value.Arg) 600 { 601 /* No arguments, there is nothing to do */ 602 603 return_ACPI_STATUS (AE_OK); 604 } 605 606 /* Build an internal object for the argument(s) */ 607 608 Status = AcpiDsBuildInternalObject (WalkState, Op->Common.Value.Arg, 609 &ObjDesc); 610 if (ACPI_FAILURE (Status)) 611 { 612 return_ACPI_STATUS (Status); 613 } 614 615 /* Re-type the object according to its argument */ 616 617 Node->Type = ObjDesc->Common.Type; 618 619 /* Attach obj to node */ 620 621 Status = AcpiNsAttachObject (Node, ObjDesc, Node->Type); 622 623 /* Remove local reference to the object */ 624 625 AcpiUtRemoveReference (ObjDesc); 626 return_ACPI_STATUS (Status); 627 } 628 629 #endif /* ACPI_NO_METHOD_EXECUTION */ 630 631 632 /******************************************************************************* 633 * 634 * FUNCTION: AcpiDsInitObjectFromOp 635 * 636 * PARAMETERS: WalkState - Current walk state 637 * Op - Parser op used to init the internal object 638 * Opcode - AML opcode associated with the object 639 * RetObjDesc - Namespace object to be initialized 640 * 641 * RETURN: Status 642 * 643 * DESCRIPTION: Initialize a namespace object from a parser Op and its 644 * associated arguments. The namespace object is a more compact 645 * representation of the Op and its arguments. 646 * 647 ******************************************************************************/ 648 649 ACPI_STATUS 650 AcpiDsInitObjectFromOp ( 651 ACPI_WALK_STATE *WalkState, 652 ACPI_PARSE_OBJECT *Op, 653 UINT16 Opcode, 654 ACPI_OPERAND_OBJECT **RetObjDesc) 655 { 656 const ACPI_OPCODE_INFO *OpInfo; 657 ACPI_OPERAND_OBJECT *ObjDesc; 658 ACPI_STATUS Status = AE_OK; 659 660 661 ACPI_FUNCTION_TRACE (DsInitObjectFromOp); 662 663 664 ObjDesc = *RetObjDesc; 665 OpInfo = AcpiPsGetOpcodeInfo (Opcode); 666 if (OpInfo->Class == AML_CLASS_UNKNOWN) 667 { 668 /* Unknown opcode */ 669 670 return_ACPI_STATUS (AE_TYPE); 671 } 672 673 /* Perform per-object initialization */ 674 675 switch (ObjDesc->Common.Type) 676 { 677 case ACPI_TYPE_BUFFER: 678 /* 679 * Defer evaluation of Buffer TermArg operand 680 */ 681 ObjDesc->Buffer.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, 682 WalkState->Operands[0]); 683 ObjDesc->Buffer.AmlStart = Op->Named.Data; 684 ObjDesc->Buffer.AmlLength = Op->Named.Length; 685 break; 686 687 case ACPI_TYPE_PACKAGE: 688 /* 689 * Defer evaluation of Package TermArg operand 690 */ 691 ObjDesc->Package.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, 692 WalkState->Operands[0]); 693 ObjDesc->Package.AmlStart = Op->Named.Data; 694 ObjDesc->Package.AmlLength = Op->Named.Length; 695 break; 696 697 case ACPI_TYPE_INTEGER: 698 699 switch (OpInfo->Type) 700 { 701 case AML_TYPE_CONSTANT: 702 /* 703 * Resolve AML Constants here - AND ONLY HERE! 704 * All constants are integers. 705 * We mark the integer with a flag that indicates that it started 706 * life as a constant -- so that stores to constants will perform 707 * as expected (noop). ZeroOp is used as a placeholder for optional 708 * target operands. 709 */ 710 ObjDesc->Common.Flags = AOPOBJ_AML_CONSTANT; 711 712 switch (Opcode) 713 { 714 case AML_ZERO_OP: 715 716 ObjDesc->Integer.Value = 0; 717 break; 718 719 case AML_ONE_OP: 720 721 ObjDesc->Integer.Value = 1; 722 break; 723 724 case AML_ONES_OP: 725 726 ObjDesc->Integer.Value = ACPI_UINT64_MAX; 727 728 /* Truncate value if we are executing from a 32-bit ACPI table */ 729 730 #ifndef ACPI_NO_METHOD_EXECUTION 731 (void) AcpiExTruncateFor32bitTable (ObjDesc); 732 #endif 733 break; 734 735 case AML_REVISION_OP: 736 737 ObjDesc->Integer.Value = ACPI_CA_VERSION; 738 break; 739 740 default: 741 742 ACPI_ERROR ((AE_INFO, 743 "Unknown constant opcode 0x%X", Opcode)); 744 Status = AE_AML_OPERAND_TYPE; 745 break; 746 } 747 break; 748 749 case AML_TYPE_LITERAL: 750 751 ObjDesc->Integer.Value = Op->Common.Value.Integer; 752 753 #ifndef ACPI_NO_METHOD_EXECUTION 754 if (AcpiExTruncateFor32bitTable (ObjDesc)) 755 { 756 /* Warn if we found a 64-bit constant in a 32-bit table */ 757 758 ACPI_WARNING ((AE_INFO, 759 "Truncated 64-bit constant found in 32-bit table: %8.8X%8.8X => %8.8X", 760 ACPI_FORMAT_UINT64 (Op->Common.Value.Integer), 761 (UINT32) ObjDesc->Integer.Value)); 762 } 763 #endif 764 break; 765 766 default: 767 768 ACPI_ERROR ((AE_INFO, "Unknown Integer type 0x%X", 769 OpInfo->Type)); 770 Status = AE_AML_OPERAND_TYPE; 771 break; 772 } 773 break; 774 775 case ACPI_TYPE_STRING: 776 777 ObjDesc->String.Pointer = Op->Common.Value.String; 778 ObjDesc->String.Length = (UINT32) strlen (Op->Common.Value.String); 779 780 /* 781 * The string is contained in the ACPI table, don't ever try 782 * to delete it 783 */ 784 ObjDesc->Common.Flags |= AOPOBJ_STATIC_POINTER; 785 break; 786 787 case ACPI_TYPE_METHOD: 788 break; 789 790 case ACPI_TYPE_LOCAL_REFERENCE: 791 792 switch (OpInfo->Type) 793 { 794 case AML_TYPE_LOCAL_VARIABLE: 795 796 /* Local ID (0-7) is (AML opcode - base AML_LOCAL_OP) */ 797 798 ObjDesc->Reference.Value = ((UINT32) Opcode) - AML_LOCAL_OP; 799 ObjDesc->Reference.Class = ACPI_REFCLASS_LOCAL; 800 801 #ifndef ACPI_NO_METHOD_EXECUTION 802 Status = AcpiDsMethodDataGetNode (ACPI_REFCLASS_LOCAL, 803 ObjDesc->Reference.Value, WalkState, 804 ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, 805 &ObjDesc->Reference.Object)); 806 #endif 807 break; 808 809 case AML_TYPE_METHOD_ARGUMENT: 810 811 /* Arg ID (0-6) is (AML opcode - base AML_ARG_OP) */ 812 813 ObjDesc->Reference.Value = ((UINT32) Opcode) - AML_ARG_OP; 814 ObjDesc->Reference.Class = ACPI_REFCLASS_ARG; 815 816 #ifndef ACPI_NO_METHOD_EXECUTION 817 Status = AcpiDsMethodDataGetNode (ACPI_REFCLASS_ARG, 818 ObjDesc->Reference.Value, WalkState, 819 ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, 820 &ObjDesc->Reference.Object)); 821 #endif 822 break; 823 824 default: /* Object name or Debug object */ 825 826 switch (Op->Common.AmlOpcode) 827 { 828 case AML_INT_NAMEPATH_OP: 829 830 /* Node was saved in Op */ 831 832 ObjDesc->Reference.Node = Op->Common.Node; 833 ObjDesc->Reference.Object = Op->Common.Node->Object; 834 ObjDesc->Reference.Class = ACPI_REFCLASS_NAME; 835 break; 836 837 case AML_DEBUG_OP: 838 839 ObjDesc->Reference.Class = ACPI_REFCLASS_DEBUG; 840 break; 841 842 default: 843 844 ACPI_ERROR ((AE_INFO, 845 "Unimplemented reference type for AML opcode: 0x%4.4X", Opcode)); 846 return_ACPI_STATUS (AE_AML_OPERAND_TYPE); 847 } 848 break; 849 } 850 break; 851 852 default: 853 854 ACPI_ERROR ((AE_INFO, "Unimplemented data type: 0x%X", 855 ObjDesc->Common.Type)); 856 857 Status = AE_AML_OPERAND_TYPE; 858 break; 859 } 860 861 return_ACPI_STATUS (Status); 862 } 863