1 /****************************************************************************** 2 * 3 * Module Name: dsobject - Dispatcher object management routines 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2013, 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 #define __DSOBJECT_C__ 45 46 #include <contrib/dev/acpica/include/acpi.h> 47 #include <contrib/dev/acpica/include/accommon.h> 48 #include <contrib/dev/acpica/include/acparser.h> 49 #include <contrib/dev/acpica/include/amlcode.h> 50 #include <contrib/dev/acpica/include/acdispat.h> 51 #include <contrib/dev/acpica/include/acnamesp.h> 52 #include <contrib/dev/acpica/include/acinterp.h> 53 54 #define _COMPONENT ACPI_DISPATCHER 55 ACPI_MODULE_NAME ("dsobject") 56 57 /* Local prototypes */ 58 59 static ACPI_STATUS 60 AcpiDsBuildInternalObject ( 61 ACPI_WALK_STATE *WalkState, 62 ACPI_PARSE_OBJECT *Op, 63 ACPI_OPERAND_OBJECT **ObjDescPtr); 64 65 66 #ifndef ACPI_NO_METHOD_EXECUTION 67 /******************************************************************************* 68 * 69 * FUNCTION: AcpiDsBuildInternalObject 70 * 71 * PARAMETERS: WalkState - Current walk state 72 * Op - Parser object to be translated 73 * ObjDescPtr - Where the ACPI internal object is returned 74 * 75 * RETURN: Status 76 * 77 * DESCRIPTION: Translate a parser Op object to the equivalent namespace object 78 * Simple objects are any objects other than a package object! 79 * 80 ******************************************************************************/ 81 82 static ACPI_STATUS 83 AcpiDsBuildInternalObject ( 84 ACPI_WALK_STATE *WalkState, 85 ACPI_PARSE_OBJECT *Op, 86 ACPI_OPERAND_OBJECT **ObjDescPtr) 87 { 88 ACPI_OPERAND_OBJECT *ObjDesc; 89 ACPI_STATUS Status; 90 ACPI_OBJECT_TYPE Type; 91 92 93 ACPI_FUNCTION_TRACE (DsBuildInternalObject); 94 95 96 *ObjDescPtr = NULL; 97 if (Op->Common.AmlOpcode == AML_INT_NAMEPATH_OP) 98 { 99 /* 100 * This is a named object reference. If this name was 101 * previously looked up in the namespace, it was stored in this op. 102 * Otherwise, go ahead and look it up now 103 */ 104 if (!Op->Common.Node) 105 { 106 Status = AcpiNsLookup (WalkState->ScopeInfo, 107 Op->Common.Value.String, 108 ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, 109 ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL, 110 ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, &(Op->Common.Node))); 111 if (ACPI_FAILURE (Status)) 112 { 113 /* Check if we are resolving a named reference within a package */ 114 115 if ((Status == AE_NOT_FOUND) && (AcpiGbl_EnableInterpreterSlack) && 116 117 ((Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) || 118 (Op->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP))) 119 { 120 /* 121 * We didn't find the target and we are populating elements 122 * of a package - ignore if slack enabled. Some ASL code 123 * contains dangling invalid references in packages and 124 * expects that no exception will be issued. Leave the 125 * element as a null element. It cannot be used, but it 126 * can be overwritten by subsequent ASL code - this is 127 * typically the case. 128 */ 129 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 130 "Ignoring unresolved reference in package [%4.4s]\n", 131 WalkState->ScopeInfo->Scope.Node->Name.Ascii)); 132 133 return_ACPI_STATUS (AE_OK); 134 } 135 else 136 { 137 ACPI_ERROR_NAMESPACE (Op->Common.Value.String, Status); 138 } 139 140 return_ACPI_STATUS (Status); 141 } 142 } 143 144 /* Special object resolution for elements of a package */ 145 146 if ((Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) || 147 (Op->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP)) 148 { 149 /* 150 * Attempt to resolve the node to a value before we insert it into 151 * the package. If this is a reference to a common data type, 152 * resolve it immediately. According to the ACPI spec, package 153 * elements can only be "data objects" or method references. 154 * Attempt to resolve to an Integer, Buffer, String or Package. 155 * If cannot, return the named reference (for things like Devices, 156 * Methods, etc.) Buffer Fields and Fields will resolve to simple 157 * objects (int/buf/str/pkg). 158 * 159 * NOTE: References to things like Devices, Methods, Mutexes, etc. 160 * will remain as named references. This behavior is not described 161 * in the ACPI spec, but it appears to be an oversight. 162 */ 163 ObjDesc = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Op->Common.Node); 164 165 Status = AcpiExResolveNodeToValue ( 166 ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, &ObjDesc), 167 WalkState); 168 if (ACPI_FAILURE (Status)) 169 { 170 return_ACPI_STATUS (Status); 171 } 172 173 /* 174 * Special handling for Alias objects. We need to setup the type 175 * and the Op->Common.Node to point to the Alias target. Note, 176 * Alias has at most one level of indirection internally. 177 */ 178 Type = Op->Common.Node->Type; 179 if (Type == ACPI_TYPE_LOCAL_ALIAS) 180 { 181 Type = ObjDesc->Common.Type; 182 Op->Common.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, 183 Op->Common.Node->Object); 184 } 185 186 switch (Type) 187 { 188 /* 189 * For these types, we need the actual node, not the subobject. 190 * However, the subobject did not get an extra reference count above. 191 * 192 * TBD: should ExResolveNodeToValue be changed to fix this? 193 */ 194 case ACPI_TYPE_DEVICE: 195 case ACPI_TYPE_THERMAL: 196 197 AcpiUtAddReference (Op->Common.Node->Object); 198 199 /*lint -fallthrough */ 200 /* 201 * For these types, we need the actual node, not the subobject. 202 * The subobject got an extra reference count in ExResolveNodeToValue. 203 */ 204 case ACPI_TYPE_MUTEX: 205 case ACPI_TYPE_METHOD: 206 case ACPI_TYPE_POWER: 207 case ACPI_TYPE_PROCESSOR: 208 case ACPI_TYPE_EVENT: 209 case ACPI_TYPE_REGION: 210 211 /* We will create a reference object for these types below */ 212 break; 213 214 default: 215 /* 216 * All other types - the node was resolved to an actual 217 * object, we are done. 218 */ 219 goto Exit; 220 } 221 } 222 } 223 224 /* Create and init a new internal ACPI object */ 225 226 ObjDesc = AcpiUtCreateInternalObject ( 227 (AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode))->ObjectType); 228 if (!ObjDesc) 229 { 230 return_ACPI_STATUS (AE_NO_MEMORY); 231 } 232 233 Status = AcpiDsInitObjectFromOp (WalkState, Op, Op->Common.AmlOpcode, 234 &ObjDesc); 235 if (ACPI_FAILURE (Status)) 236 { 237 AcpiUtRemoveReference (ObjDesc); 238 return_ACPI_STATUS (Status); 239 } 240 241 Exit: 242 *ObjDescPtr = ObjDesc; 243 return_ACPI_STATUS (Status); 244 } 245 246 247 /******************************************************************************* 248 * 249 * FUNCTION: AcpiDsBuildInternalBufferObj 250 * 251 * PARAMETERS: WalkState - Current walk state 252 * Op - Parser object to be translated 253 * BufferLength - Length of the buffer 254 * ObjDescPtr - Where the ACPI internal object is returned 255 * 256 * RETURN: Status 257 * 258 * DESCRIPTION: Translate a parser Op package object to the equivalent 259 * namespace object 260 * 261 ******************************************************************************/ 262 263 ACPI_STATUS 264 AcpiDsBuildInternalBufferObj ( 265 ACPI_WALK_STATE *WalkState, 266 ACPI_PARSE_OBJECT *Op, 267 UINT32 BufferLength, 268 ACPI_OPERAND_OBJECT **ObjDescPtr) 269 { 270 ACPI_PARSE_OBJECT *Arg; 271 ACPI_OPERAND_OBJECT *ObjDesc; 272 ACPI_PARSE_OBJECT *ByteList; 273 UINT32 ByteListLength = 0; 274 275 276 ACPI_FUNCTION_TRACE (DsBuildInternalBufferObj); 277 278 279 /* 280 * If we are evaluating a Named buffer object "Name (xxxx, Buffer)". 281 * The buffer object already exists (from the NS node), otherwise it must 282 * be created. 283 */ 284 ObjDesc = *ObjDescPtr; 285 if (!ObjDesc) 286 { 287 /* Create a new buffer object */ 288 289 ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_BUFFER); 290 *ObjDescPtr = ObjDesc; 291 if (!ObjDesc) 292 { 293 return_ACPI_STATUS (AE_NO_MEMORY); 294 } 295 } 296 297 /* 298 * Second arg is the buffer data (optional) ByteList can be either 299 * individual bytes or a string initializer. In either case, a 300 * ByteList appears in the AML. 301 */ 302 Arg = Op->Common.Value.Arg; /* skip first arg */ 303 304 ByteList = Arg->Named.Next; 305 if (ByteList) 306 { 307 if (ByteList->Common.AmlOpcode != AML_INT_BYTELIST_OP) 308 { 309 ACPI_ERROR ((AE_INFO, 310 "Expecting bytelist, found AML opcode 0x%X in op %p", 311 ByteList->Common.AmlOpcode, ByteList)); 312 313 AcpiUtRemoveReference (ObjDesc); 314 return (AE_TYPE); 315 } 316 317 ByteListLength = (UINT32) ByteList->Common.Value.Integer; 318 } 319 320 /* 321 * The buffer length (number of bytes) will be the larger of: 322 * 1) The specified buffer length and 323 * 2) The length of the initializer byte list 324 */ 325 ObjDesc->Buffer.Length = BufferLength; 326 if (ByteListLength > BufferLength) 327 { 328 ObjDesc->Buffer.Length = ByteListLength; 329 } 330 331 /* Allocate the buffer */ 332 333 if (ObjDesc->Buffer.Length == 0) 334 { 335 ObjDesc->Buffer.Pointer = NULL; 336 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 337 "Buffer defined with zero length in AML, creating\n")); 338 } 339 else 340 { 341 ObjDesc->Buffer.Pointer = ACPI_ALLOCATE_ZEROED ( 342 ObjDesc->Buffer.Length); 343 if (!ObjDesc->Buffer.Pointer) 344 { 345 AcpiUtDeleteObjectDesc (ObjDesc); 346 return_ACPI_STATUS (AE_NO_MEMORY); 347 } 348 349 /* Initialize buffer from the ByteList (if present) */ 350 351 if (ByteList) 352 { 353 ACPI_MEMCPY (ObjDesc->Buffer.Pointer, ByteList->Named.Data, 354 ByteListLength); 355 } 356 } 357 358 ObjDesc->Buffer.Flags |= AOPOBJ_DATA_VALID; 359 Op->Common.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjDesc); 360 return_ACPI_STATUS (AE_OK); 361 } 362 363 364 /******************************************************************************* 365 * 366 * FUNCTION: AcpiDsBuildInternalPackageObj 367 * 368 * PARAMETERS: WalkState - Current walk state 369 * Op - Parser object to be translated 370 * ElementCount - Number of elements in the package - this is 371 * the NumElements argument to Package() 372 * ObjDescPtr - Where the ACPI internal object is returned 373 * 374 * RETURN: Status 375 * 376 * DESCRIPTION: Translate a parser Op package object to the equivalent 377 * namespace object 378 * 379 * NOTE: The number of elements in the package will be always be the NumElements 380 * count, regardless of the number of elements in the package list. If 381 * NumElements is smaller, only that many package list elements are used. 382 * if NumElements is larger, the Package object is padded out with 383 * objects of type Uninitialized (as per ACPI spec.) 384 * 385 * Even though the ASL compilers do not allow NumElements to be smaller 386 * than the Package list length (for the fixed length package opcode), some 387 * BIOS code modifies the AML on the fly to adjust the NumElements, and 388 * this code compensates for that. This also provides compatibility with 389 * other AML interpreters. 390 * 391 ******************************************************************************/ 392 393 ACPI_STATUS 394 AcpiDsBuildInternalPackageObj ( 395 ACPI_WALK_STATE *WalkState, 396 ACPI_PARSE_OBJECT *Op, 397 UINT32 ElementCount, 398 ACPI_OPERAND_OBJECT **ObjDescPtr) 399 { 400 ACPI_PARSE_OBJECT *Arg; 401 ACPI_PARSE_OBJECT *Parent; 402 ACPI_OPERAND_OBJECT *ObjDesc = NULL; 403 ACPI_STATUS Status = AE_OK; 404 UINT32 i; 405 UINT16 Index; 406 UINT16 ReferenceCount; 407 408 409 ACPI_FUNCTION_TRACE (DsBuildInternalPackageObj); 410 411 412 /* Find the parent of a possibly nested package */ 413 414 Parent = Op->Common.Parent; 415 while ((Parent->Common.AmlOpcode == AML_PACKAGE_OP) || 416 (Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP)) 417 { 418 Parent = Parent->Common.Parent; 419 } 420 421 /* 422 * If we are evaluating a Named package object "Name (xxxx, Package)", 423 * the package object already exists, otherwise it must be created. 424 */ 425 ObjDesc = *ObjDescPtr; 426 if (!ObjDesc) 427 { 428 ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_PACKAGE); 429 *ObjDescPtr = ObjDesc; 430 if (!ObjDesc) 431 { 432 return_ACPI_STATUS (AE_NO_MEMORY); 433 } 434 435 ObjDesc->Package.Node = Parent->Common.Node; 436 } 437 438 /* 439 * Allocate the element array (array of pointers to the individual 440 * objects) based on the NumElements parameter. Add an extra pointer slot 441 * so that the list is always null terminated. 442 */ 443 ObjDesc->Package.Elements = ACPI_ALLOCATE_ZEROED ( 444 ((ACPI_SIZE) ElementCount + 1) * sizeof (void *)); 445 446 if (!ObjDesc->Package.Elements) 447 { 448 AcpiUtDeleteObjectDesc (ObjDesc); 449 return_ACPI_STATUS (AE_NO_MEMORY); 450 } 451 452 ObjDesc->Package.Count = ElementCount; 453 454 /* 455 * Initialize the elements of the package, up to the NumElements count. 456 * Package is automatically padded with uninitialized (NULL) elements 457 * if NumElements is greater than the package list length. Likewise, 458 * Package is truncated if NumElements is less than the list length. 459 */ 460 Arg = Op->Common.Value.Arg; 461 Arg = Arg->Common.Next; 462 for (i = 0; Arg && (i < ElementCount); i++) 463 { 464 if (Arg->Common.AmlOpcode == AML_INT_RETURN_VALUE_OP) 465 { 466 if (Arg->Common.Node->Type == ACPI_TYPE_METHOD) 467 { 468 /* 469 * A method reference "looks" to the parser to be a method 470 * invocation, so we special case it here 471 */ 472 Arg->Common.AmlOpcode = AML_INT_NAMEPATH_OP; 473 Status = AcpiDsBuildInternalObject (WalkState, Arg, 474 &ObjDesc->Package.Elements[i]); 475 } 476 else 477 { 478 /* This package element is already built, just get it */ 479 480 ObjDesc->Package.Elements[i] = 481 ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Arg->Common.Node); 482 } 483 } 484 else 485 { 486 Status = AcpiDsBuildInternalObject (WalkState, Arg, 487 &ObjDesc->Package.Elements[i]); 488 } 489 490 if (*ObjDescPtr) 491 { 492 /* Existing package, get existing reference count */ 493 494 ReferenceCount = (*ObjDescPtr)->Common.ReferenceCount; 495 if (ReferenceCount > 1) 496 { 497 /* Make new element ref count match original ref count */ 498 499 for (Index = 0; Index < (ReferenceCount - 1); Index++) 500 { 501 AcpiUtAddReference ((ObjDesc->Package.Elements[i])); 502 } 503 } 504 } 505 506 Arg = Arg->Common.Next; 507 } 508 509 /* Check for match between NumElements and actual length of PackageList */ 510 511 if (Arg) 512 { 513 /* 514 * NumElements was exhausted, but there are remaining elements in the 515 * PackageList. Truncate the package to NumElements. 516 * 517 * Note: technically, this is an error, from ACPI spec: "It is an error 518 * for NumElements to be less than the number of elements in the 519 * PackageList". However, we just print a message and 520 * no exception is returned. This provides Windows compatibility. Some 521 * BIOSs will alter the NumElements on the fly, creating this type 522 * of ill-formed package object. 523 */ 524 while (Arg) 525 { 526 /* 527 * We must delete any package elements that were created earlier 528 * and are not going to be used because of the package truncation. 529 */ 530 if (Arg->Common.Node) 531 { 532 AcpiUtRemoveReference ( 533 ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Arg->Common.Node)); 534 Arg->Common.Node = NULL; 535 } 536 537 /* Find out how many elements there really are */ 538 539 i++; 540 Arg = Arg->Common.Next; 541 } 542 543 ACPI_INFO ((AE_INFO, 544 "Actual Package length (%u) is larger than NumElements field (%u), truncated", 545 i, ElementCount)); 546 } 547 else if (i < ElementCount) 548 { 549 /* 550 * Arg list (elements) was exhausted, but we did not reach NumElements count. 551 * Note: this is not an error, the package is padded out with NULLs. 552 */ 553 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 554 "Package List length (%u) smaller than NumElements 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 (WalkState, Op->Common.Value.Arg, 611 &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 (ACPI_NAMESPACE_NODE, 684 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 (ACPI_NAMESPACE_NODE, 694 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) ACPI_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