dsobject.c revision 104470
1/****************************************************************************** 2 * 3 * Module Name: dsobject - Dispatcher object management routines 4 * $Revision: 108 $ 5 * 6 *****************************************************************************/ 7 8/****************************************************************************** 9 * 10 * 1. Copyright Notice 11 * 12 * Some or all of this work - Copyright (c) 1999 - 2002, Intel Corp. 13 * All rights reserved. 14 * 15 * 2. License 16 * 17 * 2.1. This is your license from Intel Corp. under its intellectual property 18 * rights. You may have additional license terms from the party that provided 19 * you this software, covering your right to use that party's intellectual 20 * property rights. 21 * 22 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 23 * copy of the source code appearing in this file ("Covered Code") an 24 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 25 * base code distributed originally by Intel ("Original Intel Code") to copy, 26 * make derivatives, distribute, use and display any portion of the Covered 27 * Code in any form, with the right to sublicense such rights; and 28 * 29 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 30 * license (with the right to sublicense), under only those claims of Intel 31 * patents that are infringed by the Original Intel Code, to make, use, sell, 32 * offer to sell, and import the Covered Code and derivative works thereof 33 * solely to the minimum extent necessary to exercise the above copyright 34 * license, and in no event shall the patent license extend to any additions 35 * to or modifications of the Original Intel Code. No other license or right 36 * is granted directly or by implication, estoppel or otherwise; 37 * 38 * The above copyright and patent license is granted only if the following 39 * conditions are met: 40 * 41 * 3. Conditions 42 * 43 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 44 * Redistribution of source code of any substantial portion of the Covered 45 * Code or modification with rights to further distribute source must include 46 * the above Copyright Notice, the above License, this list of Conditions, 47 * and the following Disclaimer and Export Compliance provision. In addition, 48 * Licensee must cause all Covered Code to which Licensee contributes to 49 * contain a file documenting the changes Licensee made to create that Covered 50 * Code and the date of any change. Licensee must include in that file the 51 * documentation of any changes made by any predecessor Licensee. Licensee 52 * must include a prominent statement that the modification is derived, 53 * directly or indirectly, from Original Intel Code. 54 * 55 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 56 * Redistribution of source code of any substantial portion of the Covered 57 * Code or modification without rights to further distribute source must 58 * include the following Disclaimer and Export Compliance provision in the 59 * documentation and/or other materials provided with distribution. In 60 * addition, Licensee may not authorize further sublicense of source of any 61 * portion of the Covered Code, and must include terms to the effect that the 62 * license from Licensee to its licensee is limited to the intellectual 63 * property embodied in the software Licensee provides to its licensee, and 64 * not to intellectual property embodied in modifications its licensee may 65 * make. 66 * 67 * 3.3. Redistribution of Executable. Redistribution in executable form of any 68 * substantial portion of the Covered Code or modification must reproduce the 69 * above Copyright Notice, and the following Disclaimer and Export Compliance 70 * provision in the documentation and/or other materials provided with the 71 * distribution. 72 * 73 * 3.4. Intel retains all right, title, and interest in and to the Original 74 * Intel Code. 75 * 76 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 77 * Intel shall be used in advertising or otherwise to promote the sale, use or 78 * other dealings in products derived from or relating to the Covered Code 79 * without prior written authorization from Intel. 80 * 81 * 4. Disclaimer and Export Compliance 82 * 83 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 84 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 85 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 86 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 87 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 88 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 89 * PARTICULAR PURPOSE. 90 * 91 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 92 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 93 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 94 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 95 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 96 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 97 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 98 * LIMITED REMEDY. 99 * 100 * 4.3. Licensee shall not export, either directly or indirectly, any of this 101 * software or system incorporating such software without first obtaining any 102 * required license or other approval from the U. S. Department of Commerce or 103 * any other agency or department of the United States Government. In the 104 * event Licensee exports any such software from the United States or 105 * re-exports any such software from a foreign destination, Licensee shall 106 * ensure that the distribution and export/re-export of the software is in 107 * compliance with all laws, regulations, orders, or other restrictions of the 108 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 109 * any of its subsidiaries will export/re-export any technical data, process, 110 * software, or service, directly or indirectly, to any country for which the 111 * United States government or any agency thereof requires an export license, 112 * other governmental approval, or letter of assurance, without first obtaining 113 * such license, approval or letter. 114 * 115 *****************************************************************************/ 116 117#define __DSOBJECT_C__ 118 119#include "acpi.h" 120#include "acparser.h" 121#include "amlcode.h" 122#include "acdispat.h" 123#include "acnamesp.h" 124#include "acinterp.h" 125 126#define _COMPONENT ACPI_DISPATCHER 127 ACPI_MODULE_NAME ("dsobject") 128 129 130#ifndef ACPI_NO_METHOD_EXECUTION 131/******************************************************************************* 132 * 133 * FUNCTION: AcpiDsInitOneObject 134 * 135 * PARAMETERS: ObjHandle - Node 136 * Level - Current nesting level 137 * Context - Points to a init info struct 138 * ReturnValue - Not used 139 * 140 * RETURN: Status 141 * 142 * DESCRIPTION: Callback from AcpiWalkNamespace. Invoked for every object 143 * within the namespace. 144 * 145 * Currently, the only objects that require initialization are: 146 * 1) Methods 147 * 2) Operation Regions 148 * 149 ******************************************************************************/ 150 151ACPI_STATUS 152AcpiDsInitOneObject ( 153 ACPI_HANDLE ObjHandle, 154 UINT32 Level, 155 void *Context, 156 void **ReturnValue) 157{ 158 ACPI_OBJECT_TYPE Type; 159 ACPI_STATUS Status; 160 ACPI_INIT_WALK_INFO *Info = (ACPI_INIT_WALK_INFO *) Context; 161 162 163 ACPI_FUNCTION_NAME ("DsInitOneObject"); 164 165 166 /* 167 * We are only interested in objects owned by the table that 168 * was just loaded 169 */ 170 if (((ACPI_NAMESPACE_NODE *) ObjHandle)->OwnerId != 171 Info->TableDesc->TableId) 172 { 173 return (AE_OK); 174 } 175 176 Info->ObjectCount++; 177 178 /* And even then, we are only interested in a few object types */ 179 180 Type = AcpiNsGetType (ObjHandle); 181 182 switch (Type) 183 { 184 case ACPI_TYPE_REGION: 185 186 Status = AcpiDsInitializeRegion (ObjHandle); 187 if (ACPI_FAILURE (Status)) 188 { 189 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Region %p [%4.4s] - Init failure, %s\n", 190 ObjHandle, ((ACPI_NAMESPACE_NODE *) ObjHandle)->Name.Ascii, 191 AcpiFormatException (Status))); 192 } 193 194 Info->OpRegionCount++; 195 break; 196 197 198 case ACPI_TYPE_METHOD: 199 200 Info->MethodCount++; 201 202 if (!(AcpiDbgLevel & ACPI_LV_INIT)) 203 { 204 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, ".")); 205 } 206 207 /* 208 * Set the execution data width (32 or 64) based upon the 209 * revision number of the parent ACPI table. 210 * TBD: This is really for possible future support of integer width 211 * on a per-table basis. Currently, we just use a global for the width. 212 */ 213 if (Info->TableDesc->Pointer->Revision == 1) 214 { 215 ((ACPI_NAMESPACE_NODE *) ObjHandle)->Flags |= ANOBJ_DATA_WIDTH_32; 216 } 217 218 /* 219 * Always parse methods to detect errors, we may delete 220 * the parse tree below 221 */ 222 Status = AcpiDsParseMethod (ObjHandle); 223 if (ACPI_FAILURE (Status)) 224 { 225 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Method %p [%4.4s] - parse failure, %s\n", 226 ObjHandle, ((ACPI_NAMESPACE_NODE *) ObjHandle)->Name.Ascii, 227 AcpiFormatException (Status))); 228 229 /* This parse failed, but we will continue parsing more methods */ 230 231 break; 232 } 233 234 /* 235 * Delete the parse tree. We simple re-parse the method 236 * for every execution since there isn't much overhead 237 */ 238 AcpiNsDeleteNamespaceSubtree (ObjHandle); 239 AcpiNsDeleteNamespaceByOwner (((ACPI_NAMESPACE_NODE *) ObjHandle)->Object->Method.OwningId); 240 break; 241 242 243 case ACPI_TYPE_DEVICE: 244 245 Info->DeviceCount++; 246 break; 247 248 249 default: 250 break; 251 } 252 253 /* 254 * We ignore errors from above, and always return OK, since 255 * we don't want to abort the walk on a single error. 256 */ 257 return (AE_OK); 258} 259 260 261/******************************************************************************* 262 * 263 * FUNCTION: AcpiDsInitializeObjects 264 * 265 * PARAMETERS: TableDesc - Descriptor for parent ACPI table 266 * StartNode - Root of subtree to be initialized. 267 * 268 * RETURN: Status 269 * 270 * DESCRIPTION: Walk the namespace starting at "StartNode" and perform any 271 * necessary initialization on the objects found therein 272 * 273 ******************************************************************************/ 274 275ACPI_STATUS 276AcpiDsInitializeObjects ( 277 ACPI_TABLE_DESC *TableDesc, 278 ACPI_NAMESPACE_NODE *StartNode) 279{ 280 ACPI_STATUS Status; 281 ACPI_INIT_WALK_INFO Info; 282 283 284 ACPI_FUNCTION_TRACE ("DsInitializeObjects"); 285 286 287 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 288 "**** Starting initialization of namespace objects ****\n")); 289 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, "Parsing Methods:")); 290 291 Info.MethodCount = 0; 292 Info.OpRegionCount = 0; 293 Info.ObjectCount = 0; 294 Info.DeviceCount = 0; 295 Info.TableDesc = TableDesc; 296 297 /* Walk entire namespace from the supplied root */ 298 299 Status = AcpiWalkNamespace (ACPI_TYPE_ANY, StartNode, ACPI_UINT32_MAX, 300 AcpiDsInitOneObject, &Info, NULL); 301 if (ACPI_FAILURE (Status)) 302 { 303 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "WalkNamespace failed, %s\n", 304 AcpiFormatException (Status))); 305 } 306 307 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, 308 "\nTable [%4.4s] - %hd Objects with %hd Devices %hd Methods %hd Regions\n", 309 TableDesc->Pointer->Signature, Info.ObjectCount, 310 Info.DeviceCount, Info.MethodCount, Info.OpRegionCount)); 311 312 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 313 "%hd Methods, %hd Regions\n", Info.MethodCount, Info.OpRegionCount)); 314 315 return_ACPI_STATUS (AE_OK); 316} 317 318 319/***************************************************************************** 320 * 321 * FUNCTION: AcpiDsBuildInternalObject 322 * 323 * PARAMETERS: WalkState - Current walk state 324 * Op - Parser object to be translated 325 * ObjDescPtr - Where the ACPI internal object is returned 326 * 327 * RETURN: Status 328 * 329 * DESCRIPTION: Translate a parser Op object to the equivalent namespace object 330 * Simple objects are any objects other than a package object! 331 * 332 ****************************************************************************/ 333 334ACPI_STATUS 335AcpiDsBuildInternalObject ( 336 ACPI_WALK_STATE *WalkState, 337 ACPI_PARSE_OBJECT *Op, 338 ACPI_OPERAND_OBJECT **ObjDescPtr) 339{ 340 ACPI_OPERAND_OBJECT *ObjDesc; 341 ACPI_STATUS Status; 342 343 344 ACPI_FUNCTION_TRACE ("DsBuildInternalObject"); 345 346 347 *ObjDescPtr = NULL; 348 if (Op->Common.AmlOpcode == AML_INT_NAMEPATH_OP) 349 { 350 /* 351 * This is an named object reference. If this name was 352 * previously looked up in the namespace, it was stored in this op. 353 * Otherwise, go ahead and look it up now 354 */ 355 if (!Op->Common.Node) 356 { 357 Status = AcpiNsLookup (WalkState->ScopeInfo, Op->Common.Value.String, 358 ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, 359 ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL, 360 (ACPI_NAMESPACE_NODE **) &(Op->Common.Node)); 361 362 if (ACPI_FAILURE (Status)) 363 { 364 ACPI_REPORT_NSERROR (Op->Common.Value.String, Status); 365 return_ACPI_STATUS (Status); 366 } 367 } 368 } 369 370 /* Create and init the internal ACPI object */ 371 372 ObjDesc = AcpiUtCreateInternalObject ((AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode))->ObjectType); 373 if (!ObjDesc) 374 { 375 return_ACPI_STATUS (AE_NO_MEMORY); 376 } 377 378 Status = AcpiDsInitObjectFromOp (WalkState, Op, Op->Common.AmlOpcode, &ObjDesc); 379 if (ACPI_FAILURE (Status)) 380 { 381 AcpiUtRemoveReference (ObjDesc); 382 return_ACPI_STATUS (Status); 383 } 384 385 *ObjDescPtr = ObjDesc; 386 return_ACPI_STATUS (AE_OK); 387} 388 389 390/***************************************************************************** 391 * 392 * FUNCTION: AcpiDsBuildInternalBufferObj 393 * 394 * PARAMETERS: WalkState - Current walk state 395 * Op - Parser object to be translated 396 * BufferLength - Length of the buffer 397 * ObjDescPtr - Where the ACPI internal object is returned 398 * 399 * RETURN: Status 400 * 401 * DESCRIPTION: Translate a parser Op package object to the equivalent 402 * namespace object 403 * 404 ****************************************************************************/ 405 406ACPI_STATUS 407AcpiDsBuildInternalBufferObj ( 408 ACPI_WALK_STATE *WalkState, 409 ACPI_PARSE_OBJECT *Op, 410 UINT32 BufferLength, 411 ACPI_OPERAND_OBJECT **ObjDescPtr) 412{ 413 ACPI_PARSE_OBJECT *Arg; 414 ACPI_OPERAND_OBJECT *ObjDesc; 415 ACPI_PARSE_OBJECT *ByteList; 416 UINT32 ByteListLength = 0; 417 418 419 ACPI_FUNCTION_TRACE ("DsBuildInternalBufferObj"); 420 421 422 ObjDesc = *ObjDescPtr; 423 if (ObjDesc) 424 { 425 /* 426 * We are evaluating a Named buffer object "Name (xxxx, Buffer)". 427 * The buffer object already exists (from the NS node) 428 */ 429 } 430 else 431 { 432 /* Create a new buffer object */ 433 434 ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_BUFFER); 435 *ObjDescPtr = ObjDesc; 436 if (!ObjDesc) 437 { 438 return_ACPI_STATUS (AE_NO_MEMORY); 439 } 440 } 441 442 /* 443 * Second arg is the buffer data (optional) ByteList can be either 444 * individual bytes or a string initializer. In either case, a 445 * ByteList appears in the AML. 446 */ 447 Arg = Op->Common.Value.Arg; /* skip first arg */ 448 449 ByteList = Arg->Named.Next; 450 if (ByteList) 451 { 452 if (ByteList->Common.AmlOpcode != AML_INT_BYTELIST_OP) 453 { 454 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 455 "Expecting bytelist, got AML opcode %X in op %p\n", 456 ByteList->Common.AmlOpcode, ByteList)); 457 458 AcpiUtRemoveReference (ObjDesc); 459 return (AE_TYPE); 460 } 461 462 ByteListLength = ByteList->Common.Value.Integer32; 463 } 464 465 /* 466 * The buffer length (number of bytes) will be the larger of: 467 * 1) The specified buffer length and 468 * 2) The length of the initializer byte list 469 */ 470 ObjDesc->Buffer.Length = BufferLength; 471 if (ByteListLength > BufferLength) 472 { 473 ObjDesc->Buffer.Length = ByteListLength; 474 } 475 476 /* Allocate the buffer */ 477 478 if (ObjDesc->Buffer.Length == 0) 479 { 480 ObjDesc->Buffer.Pointer = NULL; 481 ACPI_REPORT_WARNING (("Buffer created with zero length in AML\n")); 482 return_ACPI_STATUS (AE_OK); 483 } 484 485 ObjDesc->Buffer.Pointer = ACPI_MEM_CALLOCATE ( 486 ObjDesc->Buffer.Length); 487 if (!ObjDesc->Buffer.Pointer) 488 { 489 AcpiUtDeleteObjectDesc (ObjDesc); 490 return_ACPI_STATUS (AE_NO_MEMORY); 491 } 492 493 /* Initialize buffer from the ByteList (if present) */ 494 495 if (ByteList) 496 { 497 ACPI_MEMCPY (ObjDesc->Buffer.Pointer, ByteList->Named.Data, 498 ByteListLength); 499 } 500 501 ObjDesc->Buffer.Flags |= AOPOBJ_DATA_VALID; 502 Op->Common.Node = (ACPI_NAMESPACE_NODE *) ObjDesc; 503 return_ACPI_STATUS (AE_OK); 504} 505 506 507/***************************************************************************** 508 * 509 * FUNCTION: AcpiDsBuildInternalPackageObj 510 * 511 * PARAMETERS: WalkState - Current walk state 512 * Op - Parser object to be translated 513 * PackageLength - Number of elements in the package 514 * ObjDescPtr - Where the ACPI internal object is returned 515 * 516 * RETURN: Status 517 * 518 * DESCRIPTION: Translate a parser Op package object to the equivalent 519 * namespace object 520 * 521 ****************************************************************************/ 522 523ACPI_STATUS 524AcpiDsBuildInternalPackageObj ( 525 ACPI_WALK_STATE *WalkState, 526 ACPI_PARSE_OBJECT *Op, 527 UINT32 PackageLength, 528 ACPI_OPERAND_OBJECT **ObjDescPtr) 529{ 530 ACPI_PARSE_OBJECT *Arg; 531 ACPI_PARSE_OBJECT *Parent; 532 ACPI_OPERAND_OBJECT *ObjDesc = NULL; 533 UINT32 PackageListLength; 534 ACPI_STATUS Status = AE_OK; 535 UINT32 i; 536 537 538 ACPI_FUNCTION_TRACE ("DsBuildInternalPackageObj"); 539 540 541 /* Find the parent of a possibly nested package */ 542 543 Parent = Op->Common.Parent; 544 while ((Parent->Common.AmlOpcode == AML_PACKAGE_OP) || 545 (Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP)) 546 { 547 Parent = Parent->Common.Parent; 548 } 549 550 ObjDesc = *ObjDescPtr; 551 if (ObjDesc) 552 { 553 /* 554 * We are evaluating a Named package object "Name (xxxx, Package)". 555 * Get the existing package object from the NS node 556 */ 557 } 558 else 559 { 560 ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_PACKAGE); 561 *ObjDescPtr = ObjDesc; 562 if (!ObjDesc) 563 { 564 return_ACPI_STATUS (AE_NO_MEMORY); 565 } 566 567 ObjDesc->Package.Node = Parent->Common.Node; 568 } 569 570 ObjDesc->Package.Count = PackageLength; 571 572 /* Count the number of items in the package list */ 573 574 PackageListLength = 0; 575 Arg = Op->Common.Value.Arg; 576 Arg = Arg->Common.Next; 577 while (Arg) 578 { 579 PackageListLength++; 580 Arg = Arg->Common.Next; 581 } 582 583 /* 584 * The package length (number of elements) will be the greater 585 * of the specified length and the length of the initializer list 586 */ 587 if (PackageListLength > PackageLength) 588 { 589 ObjDesc->Package.Count = PackageListLength; 590 } 591 592 /* 593 * Allocate the pointer array (array of pointers to the 594 * individual objects). Add an extra pointer slot so 595 * that the list is always null terminated. 596 */ 597 ObjDesc->Package.Elements = ACPI_MEM_CALLOCATE ( 598 ((ACPI_SIZE) ObjDesc->Package.Count + 1) * sizeof (void *)); 599 600 if (!ObjDesc->Package.Elements) 601 { 602 AcpiUtDeleteObjectDesc (ObjDesc); 603 return_ACPI_STATUS (AE_NO_MEMORY); 604 } 605 606 /* 607 * Now init the elements of the package 608 */ 609 i = 0; 610 Arg = Op->Common.Value.Arg; 611 Arg = Arg->Common.Next; 612 while (Arg) 613 { 614 if (Arg->Common.AmlOpcode == AML_INT_RETURN_VALUE_OP) 615 { 616 /* Object (package or buffer) is already built */ 617 618 ObjDesc->Package.Elements[i] = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Arg->Common.Node); 619 } 620 else 621 { 622 Status = AcpiDsBuildInternalObject (WalkState, Arg, 623 &ObjDesc->Package.Elements[i]); 624 } 625 626 i++; 627 Arg = Arg->Common.Next; 628 } 629 630 ObjDesc->Package.Flags |= AOPOBJ_DATA_VALID; 631 Op->Common.Node = (ACPI_NAMESPACE_NODE *) ObjDesc; 632 return_ACPI_STATUS (Status); 633} 634 635 636/***************************************************************************** 637 * 638 * FUNCTION: AcpiDsCreateNode 639 * 640 * PARAMETERS: WalkState - Current walk state 641 * Node - NS Node to be initialized 642 * Op - Parser object to be translated 643 * 644 * RETURN: Status 645 * 646 * DESCRIPTION: Create the object to be associated with a namespace node 647 * 648 ****************************************************************************/ 649 650ACPI_STATUS 651AcpiDsCreateNode ( 652 ACPI_WALK_STATE *WalkState, 653 ACPI_NAMESPACE_NODE *Node, 654 ACPI_PARSE_OBJECT *Op) 655{ 656 ACPI_STATUS Status; 657 ACPI_OPERAND_OBJECT *ObjDesc; 658 659 660 ACPI_FUNCTION_TRACE_PTR ("DsCreateNode", Op); 661 662 663 /* 664 * Because of the execution pass through the non-control-method 665 * parts of the table, we can arrive here twice. Only init 666 * the named object node the first time through 667 */ 668 if (AcpiNsGetAttachedObject (Node)) 669 { 670 return_ACPI_STATUS (AE_OK); 671 } 672 673 if (!Op->Common.Value.Arg) 674 { 675 /* No arguments, there is nothing to do */ 676 677 return_ACPI_STATUS (AE_OK); 678 } 679 680 /* Build an internal object for the argument(s) */ 681 682 Status = AcpiDsBuildInternalObject (WalkState, Op->Common.Value.Arg, &ObjDesc); 683 if (ACPI_FAILURE (Status)) 684 { 685 return_ACPI_STATUS (Status); 686 } 687 688 /* Re-type the object according to it's argument */ 689 690 Node->Type = ACPI_GET_OBJECT_TYPE (ObjDesc); 691 692 /* Attach obj to node */ 693 694 Status = AcpiNsAttachObject (Node, ObjDesc, Node->Type); 695 696 /* Remove local reference to the object */ 697 698 AcpiUtRemoveReference (ObjDesc); 699 return_ACPI_STATUS (Status); 700} 701 702#endif /* ACPI_NO_METHOD_EXECUTION */ 703 704 705/***************************************************************************** 706 * 707 * FUNCTION: AcpiDsInitObjectFromOp 708 * 709 * PARAMETERS: WalkState - Current walk state 710 * Op - Parser op used to init the internal object 711 * Opcode - AML opcode associated with the object 712 * RetObjDesc - Namespace object to be initialized 713 * 714 * RETURN: Status 715 * 716 * DESCRIPTION: Initialize a namespace object from a parser Op and its 717 * associated arguments. The namespace object is a more compact 718 * representation of the Op and its arguments. 719 * 720 ****************************************************************************/ 721 722ACPI_STATUS 723AcpiDsInitObjectFromOp ( 724 ACPI_WALK_STATE *WalkState, 725 ACPI_PARSE_OBJECT *Op, 726 UINT16 Opcode, 727 ACPI_OPERAND_OBJECT **RetObjDesc) 728{ 729 const ACPI_OPCODE_INFO *OpInfo; 730 ACPI_OPERAND_OBJECT *ObjDesc; 731 ACPI_STATUS Status = AE_OK; 732 733 734 ACPI_FUNCTION_TRACE ("DsInitObjectFromOp"); 735 736 737 ObjDesc = *RetObjDesc; 738 OpInfo = AcpiPsGetOpcodeInfo (Opcode); 739 if (OpInfo->Class == AML_CLASS_UNKNOWN) 740 { 741 /* Unknown opcode */ 742 743 return_ACPI_STATUS (AE_TYPE); 744 } 745 746 /* Perform per-object initialization */ 747 748 switch (ACPI_GET_OBJECT_TYPE (ObjDesc)) 749 { 750 case ACPI_TYPE_BUFFER: 751 752 /* 753 * Defer evaluation of Buffer TermArg operand 754 */ 755 ObjDesc->Buffer.Node = (ACPI_NAMESPACE_NODE *) WalkState->Operands[0]; 756 ObjDesc->Buffer.AmlStart = Op->Named.Data; 757 ObjDesc->Buffer.AmlLength = Op->Named.Length; 758 break; 759 760 761 case ACPI_TYPE_PACKAGE: 762 763 /* 764 * Defer evaluation of Package TermArg operand 765 */ 766 ObjDesc->Package.Node = (ACPI_NAMESPACE_NODE *) WalkState->Operands[0]; 767 ObjDesc->Package.AmlStart = Op->Named.Data; 768 ObjDesc->Package.AmlLength = Op->Named.Length; 769 break; 770 771 772 case ACPI_TYPE_INTEGER: 773 774 switch (OpInfo->Type) 775 { 776 case AML_TYPE_CONSTANT: 777 /* 778 * Resolve AML Constants here - AND ONLY HERE! 779 * All constants are integers. 780 * We mark the integer with a flag that indicates that it started life 781 * as a constant -- so that stores to constants will perform as expected (noop). 782 * (ZeroOp is used as a placeholder for optional target operands.) 783 */ 784 ObjDesc->Common.Flags = AOPOBJ_AML_CONSTANT; 785 786 switch (Opcode) 787 { 788 case AML_ZERO_OP: 789 790 ObjDesc->Integer.Value = 0; 791 break; 792 793 case AML_ONE_OP: 794 795 ObjDesc->Integer.Value = 1; 796 break; 797 798 case AML_ONES_OP: 799 800 ObjDesc->Integer.Value = ACPI_INTEGER_MAX; 801 802 /* Truncate value if we are executing from a 32-bit ACPI table */ 803 804#ifndef ACPI_NO_METHOD_EXECUTION 805 AcpiExTruncateFor32bitTable (ObjDesc); 806#endif 807 break; 808 809 case AML_REVISION_OP: 810 811 ObjDesc->Integer.Value = ACPI_CA_SUPPORT_LEVEL; 812 break; 813 814 default: 815 816 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown constant opcode %X\n", Opcode)); 817 Status = AE_AML_OPERAND_TYPE; 818 break; 819 } 820 break; 821 822 823 case AML_TYPE_LITERAL: 824 825 ObjDesc->Integer.Value = Op->Common.Value.Integer; 826 break; 827 828 829 default: 830 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Integer type %X\n", OpInfo->Type)); 831 Status = AE_AML_OPERAND_TYPE; 832 break; 833 } 834 break; 835 836 837 case ACPI_TYPE_STRING: 838 839 ObjDesc->String.Pointer = Op->Common.Value.String; 840 ObjDesc->String.Length = ACPI_STRLEN (Op->Common.Value.String); 841 842 /* 843 * The string is contained in the ACPI table, don't ever try 844 * to delete it 845 */ 846 ObjDesc->Common.Flags |= AOPOBJ_STATIC_POINTER; 847 break; 848 849 850 case ACPI_TYPE_METHOD: 851 break; 852 853 854 case INTERNAL_TYPE_REFERENCE: 855 856 switch (OpInfo->Type) 857 { 858 case AML_TYPE_LOCAL_VARIABLE: 859 860 /* Split the opcode into a base opcode + offset */ 861 862 ObjDesc->Reference.Opcode = AML_LOCAL_OP; 863 ObjDesc->Reference.Offset = Opcode - AML_LOCAL_OP; 864 865#ifndef ACPI_NO_METHOD_EXECUTION 866 Status = AcpiDsMethodDataGetNode (AML_LOCAL_OP, ObjDesc->Reference.Offset, 867 WalkState, (ACPI_NAMESPACE_NODE **) &ObjDesc->Reference.Object); 868#endif 869 break; 870 871 872 case AML_TYPE_METHOD_ARGUMENT: 873 874 /* Split the opcode into a base opcode + offset */ 875 876 ObjDesc->Reference.Opcode = AML_ARG_OP; 877 ObjDesc->Reference.Offset = Opcode - AML_ARG_OP; 878 break; 879 880 default: /* Other literals, etc.. */ 881 882 if (Op->Common.AmlOpcode == AML_INT_NAMEPATH_OP) 883 { 884 /* Node was saved in Op */ 885 886 ObjDesc->Reference.Node = Op->Common.Node; 887 } 888 889 ObjDesc->Reference.Opcode = Opcode; 890 break; 891 } 892 break; 893 894 895 default: 896 897 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unimplemented data type: %X\n", 898 ACPI_GET_OBJECT_TYPE (ObjDesc))); 899 900 Status = AE_AML_OPERAND_TYPE; 901 break; 902 } 903 904 return_ACPI_STATUS (Status); 905} 906 907 908