1 /****************************************************************************** 2 * 3 * Module Name: dswload - Dispatcher namespace load callbacks 4 * 5 *****************************************************************************/ 6 7 /****************************************************************************** 8 * 9 * 1. Copyright Notice 10 * 11 * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. 12 * All rights reserved. 13 * 14 * 2. License 15 * 16 * 2.1. This is your license from Intel Corp. under its intellectual property 17 * rights. You may have additional license terms from the party that provided 18 * you this software, covering your right to use that party's intellectual 19 * property rights. 20 * 21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 22 * copy of the source code appearing in this file ("Covered Code") an 23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 24 * base code distributed originally by Intel ("Original Intel Code") to copy, 25 * make derivatives, distribute, use and display any portion of the Covered 26 * Code in any form, with the right to sublicense such rights; and 27 * 28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 29 * license (with the right to sublicense), under only those claims of Intel 30 * patents that are infringed by the Original Intel Code, to make, use, sell, 31 * offer to sell, and import the Covered Code and derivative works thereof 32 * solely to the minimum extent necessary to exercise the above copyright 33 * license, and in no event shall the patent license extend to any additions 34 * to or modifications of the Original Intel Code. No other license or right 35 * is granted directly or by implication, estoppel or otherwise; 36 * 37 * The above copyright and patent license is granted only if the following 38 * conditions are met: 39 * 40 * 3. Conditions 41 * 42 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43 * Redistribution of source code of any substantial portion of the Covered 44 * Code or modification with rights to further distribute source must include 45 * the above Copyright Notice, the above License, this list of Conditions, 46 * and the following Disclaimer and Export Compliance provision. In addition, 47 * Licensee must cause all Covered Code to which Licensee contributes to 48 * contain a file documenting the changes Licensee made to create that Covered 49 * Code and the date of any change. Licensee must include in that file the 50 * documentation of any changes made by any predecessor Licensee. Licensee 51 * must include a prominent statement that the modification is derived, 52 * directly or indirectly, from Original Intel Code. 53 * 54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 55 * Redistribution of source code of any substantial portion of the Covered 56 * Code or modification without rights to further distribute source must 57 * include the following Disclaimer and Export Compliance provision in the 58 * documentation and/or other materials provided with distribution. In 59 * addition, Licensee may not authorize further sublicense of source of any 60 * portion of the Covered Code, and must include terms to the effect that the 61 * license from Licensee to its licensee is limited to the intellectual 62 * property embodied in the software Licensee provides to its licensee, and 63 * not to intellectual property embodied in modifications its licensee may 64 * make. 65 * 66 * 3.3. Redistribution of Executable. Redistribution in executable form of any 67 * substantial portion of the Covered Code or modification must reproduce the 68 * above Copyright Notice, and the following Disclaimer and Export Compliance 69 * provision in the documentation and/or other materials provided with the 70 * distribution. 71 * 72 * 3.4. Intel retains all right, title, and interest in and to the Original 73 * Intel Code. 74 * 75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 76 * Intel shall be used in advertising or otherwise to promote the sale, use or 77 * other dealings in products derived from or relating to the Covered Code 78 * without prior written authorization from Intel. 79 * 80 * 4. Disclaimer and Export Compliance 81 * 82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 83 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 85 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 86 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 88 * PARTICULAR PURPOSE. 89 * 90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 97 * LIMITED REMEDY. 98 * 99 * 4.3. Licensee shall not export, either directly or indirectly, any of this 100 * software or system incorporating such software without first obtaining any 101 * required license or other approval from the U. S. Department of Commerce or 102 * any other agency or department of the United States Government. In the 103 * event Licensee exports any such software from the United States or 104 * re-exports any such software from a foreign destination, Licensee shall 105 * ensure that the distribution and export/re-export of the software is in 106 * compliance with all laws, regulations, orders, or other restrictions of the 107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 108 * any of its subsidiaries will export/re-export any technical data, process, 109 * software, or service, directly or indirectly, to any country for which the 110 * United States government or any agency thereof requires an export license, 111 * other governmental approval, or letter of assurance, without first obtaining 112 * such license, approval or letter. 113 * 114 *****************************************************************************/ 115 116 #define __ASLLOAD_C__ 117 118 #include <contrib/dev/acpica/compiler/aslcompiler.h> 119 #include <contrib/dev/acpica/include/amlcode.h> 120 #include <contrib/dev/acpica/include/acdispat.h> 121 #include <contrib/dev/acpica/include/acnamesp.h> 122 123 #include "aslcompiler.y.h" 124 125 #define _COMPONENT ACPI_COMPILER 126 ACPI_MODULE_NAME ("aslload") 127 128 /* Local prototypes */ 129 130 static ACPI_STATUS 131 LdLoadFieldElements ( 132 ACPI_PARSE_OBJECT *Op, 133 ACPI_WALK_STATE *WalkState); 134 135 static ACPI_STATUS 136 LdLoadResourceElements ( 137 ACPI_PARSE_OBJECT *Op, 138 ACPI_WALK_STATE *WalkState); 139 140 static ACPI_STATUS 141 LdNamespace1Begin ( 142 ACPI_PARSE_OBJECT *Op, 143 UINT32 Level, 144 void *Context); 145 146 static ACPI_STATUS 147 LdNamespace2Begin ( 148 ACPI_PARSE_OBJECT *Op, 149 UINT32 Level, 150 void *Context); 151 152 static ACPI_STATUS 153 LdCommonNamespaceEnd ( 154 ACPI_PARSE_OBJECT *Op, 155 UINT32 Level, 156 void *Context); 157 158 159 /******************************************************************************* 160 * 161 * FUNCTION: LdLoadNamespace 162 * 163 * PARAMETERS: RootOp - Root of the parse tree 164 * 165 * RETURN: Status 166 * 167 * DESCRIPTION: Perform a walk of the parse tree that in turn loads all of the 168 * named ASL/AML objects into the namespace. The namespace is 169 * constructed in order to resolve named references and references 170 * to named fields within resource templates/descriptors. 171 * 172 ******************************************************************************/ 173 174 ACPI_STATUS 175 LdLoadNamespace ( 176 ACPI_PARSE_OBJECT *RootOp) 177 { 178 ACPI_WALK_STATE *WalkState; 179 180 181 DbgPrint (ASL_DEBUG_OUTPUT, "\nCreating namespace\n\n"); 182 183 /* Create a new walk state */ 184 185 WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL); 186 if (!WalkState) 187 { 188 return AE_NO_MEMORY; 189 } 190 191 /* Walk the entire parse tree, first pass */ 192 193 TrWalkParseTree (RootOp, ASL_WALK_VISIT_TWICE, LdNamespace1Begin, 194 LdCommonNamespaceEnd, WalkState); 195 196 /* Second pass to handle forward references */ 197 198 TrWalkParseTree (RootOp, ASL_WALK_VISIT_TWICE, LdNamespace2Begin, 199 LdCommonNamespaceEnd, WalkState); 200 201 /* Dump the namespace if debug is enabled */ 202 203 AcpiNsDumpTables (ACPI_NS_ALL, ACPI_UINT32_MAX); 204 return AE_OK; 205 } 206 207 208 /******************************************************************************* 209 * 210 * FUNCTION: LdLoadFieldElements 211 * 212 * PARAMETERS: Op - Parent node (Field) 213 * WalkState - Current walk state 214 * 215 * RETURN: Status 216 * 217 * DESCRIPTION: Enter the named elements of the field (children of the parent) 218 * into the namespace. 219 * 220 ******************************************************************************/ 221 222 static ACPI_STATUS 223 LdLoadFieldElements ( 224 ACPI_PARSE_OBJECT *Op, 225 ACPI_WALK_STATE *WalkState) 226 { 227 ACPI_PARSE_OBJECT *Child = NULL; 228 ACPI_NAMESPACE_NODE *Node; 229 ACPI_STATUS Status; 230 231 232 /* Get the first named field element */ 233 234 switch (Op->Asl.AmlOpcode) 235 { 236 case AML_BANK_FIELD_OP: 237 238 Child = UtGetArg (Op, 6); 239 break; 240 241 case AML_INDEX_FIELD_OP: 242 243 Child = UtGetArg (Op, 5); 244 break; 245 246 case AML_FIELD_OP: 247 248 Child = UtGetArg (Op, 4); 249 break; 250 251 default: 252 /* No other opcodes should arrive here */ 253 return (AE_BAD_PARAMETER); 254 } 255 256 /* Enter all elements into the namespace */ 257 258 while (Child) 259 { 260 switch (Child->Asl.AmlOpcode) 261 { 262 case AML_INT_RESERVEDFIELD_OP: 263 case AML_INT_ACCESSFIELD_OP: 264 265 break; 266 267 default: 268 269 Status = AcpiNsLookup (WalkState->ScopeInfo, 270 Child->Asl.Value.String, 271 ACPI_TYPE_LOCAL_REGION_FIELD, 272 ACPI_IMODE_LOAD_PASS1, 273 ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | 274 ACPI_NS_ERROR_IF_FOUND, 275 NULL, &Node); 276 if (ACPI_FAILURE (Status)) 277 { 278 if (Status != AE_ALREADY_EXISTS) 279 { 280 AslError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION, Child, 281 Child->Asl.Value.String); 282 return (Status); 283 } 284 285 /* 286 * The name already exists in this scope 287 * But continue processing the elements 288 */ 289 AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Child, 290 Child->Asl.Value.String); 291 } 292 else 293 { 294 Child->Asl.Node = Node; 295 Node->Op = Child; 296 } 297 break; 298 } 299 Child = Child->Asl.Next; 300 } 301 return (AE_OK); 302 } 303 304 305 /******************************************************************************* 306 * 307 * FUNCTION: LdLoadResourceElements 308 * 309 * PARAMETERS: Op - Parent node (Resource Descriptor) 310 * WalkState - Current walk state 311 * 312 * RETURN: Status 313 * 314 * DESCRIPTION: Enter the named elements of the resource descriptor (children 315 * of the parent) into the namespace. 316 * 317 * NOTE: In the real AML namespace, these named elements never exist. But 318 * we simply use the namespace here as a symbol table so we can look 319 * them up as they are referenced. 320 * 321 ******************************************************************************/ 322 323 static ACPI_STATUS 324 LdLoadResourceElements ( 325 ACPI_PARSE_OBJECT *Op, 326 ACPI_WALK_STATE *WalkState) 327 { 328 ACPI_PARSE_OBJECT *InitializerOp = NULL; 329 ACPI_NAMESPACE_NODE *Node; 330 ACPI_STATUS Status; 331 332 333 /* 334 * Enter the resource name into the namespace. Name must not already exist. 335 * This opens a scope, so later field names are guaranteed to be new/unique. 336 */ 337 Status = AcpiNsLookup (WalkState->ScopeInfo, Op->Asl.Namepath, 338 ACPI_TYPE_LOCAL_RESOURCE, ACPI_IMODE_LOAD_PASS1, 339 ACPI_NS_NO_UPSEARCH | ACPI_NS_ERROR_IF_FOUND, 340 WalkState, &Node); 341 if (ACPI_FAILURE (Status)) 342 { 343 if (Status == AE_ALREADY_EXISTS) 344 { 345 /* Actual node causing the error was saved in ParentMethod */ 346 347 AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS, 348 (ACPI_PARSE_OBJECT *) Op->Asl.ParentMethod, Op->Asl.Namepath); 349 return (AE_OK); 350 } 351 return (Status); 352 } 353 354 Node->Value = (UINT32) Op->Asl.Value.Integer; 355 Node->Op = Op; 356 357 /* 358 * Now enter the predefined fields, for easy lookup when referenced 359 * by the source ASL 360 */ 361 InitializerOp = ASL_GET_CHILD_NODE (Op); 362 while (InitializerOp) 363 { 364 365 if (InitializerOp->Asl.ExternalName) 366 { 367 Status = AcpiNsLookup (WalkState->ScopeInfo, 368 InitializerOp->Asl.ExternalName, 369 ACPI_TYPE_LOCAL_RESOURCE_FIELD, 370 ACPI_IMODE_LOAD_PASS1, 371 ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE, 372 NULL, &Node); 373 if (ACPI_FAILURE (Status)) 374 { 375 return (Status); 376 } 377 378 /* 379 * Store the field offset in the namespace node so it 380 * can be used when the field is referenced 381 */ 382 Node->Value = (UINT32) InitializerOp->Asl.Value.Integer; 383 InitializerOp->Asl.Node = Node; 384 Node->Op = InitializerOp; 385 386 /* Pass thru the field type (Bitfield or Bytefield) */ 387 388 if (InitializerOp->Asl.CompileFlags & NODE_IS_BIT_OFFSET) 389 { 390 Node->Flags |= ANOBJ_IS_BIT_OFFSET; 391 } 392 } 393 InitializerOp = ASL_GET_PEER_NODE (InitializerOp); 394 } 395 396 return (AE_OK); 397 } 398 399 400 /******************************************************************************* 401 * 402 * FUNCTION: LdNamespace1Begin 403 * 404 * PARAMETERS: ASL_WALK_CALLBACK 405 * 406 * RETURN: Status 407 * 408 * DESCRIPTION: Descending callback used during the parse tree walk. If this 409 * is a named AML opcode, enter into the namespace 410 * 411 ******************************************************************************/ 412 413 static ACPI_STATUS 414 LdNamespace1Begin ( 415 ACPI_PARSE_OBJECT *Op, 416 UINT32 Level, 417 void *Context) 418 { 419 ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context; 420 ACPI_NAMESPACE_NODE *Node; 421 ACPI_STATUS Status; 422 ACPI_OBJECT_TYPE ObjectType; 423 ACPI_OBJECT_TYPE ActualObjectType = ACPI_TYPE_ANY; 424 char *Path; 425 UINT32 Flags = ACPI_NS_NO_UPSEARCH; 426 ACPI_PARSE_OBJECT *Arg; 427 UINT32 i; 428 BOOLEAN ForceNewScope = FALSE; 429 430 431 ACPI_FUNCTION_NAME (LdNamespace1Begin); 432 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n", 433 Op, Op->Asl.ParseOpName)); 434 435 436 /* 437 * We are only interested in opcodes that have an associated name 438 * (or multiple names) 439 */ 440 switch (Op->Asl.AmlOpcode) 441 { 442 case AML_BANK_FIELD_OP: 443 case AML_INDEX_FIELD_OP: 444 case AML_FIELD_OP: 445 446 Status = LdLoadFieldElements (Op, WalkState); 447 return (Status); 448 449 default: 450 451 /* All other opcodes go below */ 452 break; 453 } 454 455 /* Check if this object has already been installed in the namespace */ 456 457 if (Op->Asl.Node) 458 { 459 return (AE_OK); 460 } 461 462 Path = Op->Asl.Namepath; 463 if (!Path) 464 { 465 return (AE_OK); 466 } 467 468 /* Map the raw opcode into an internal object type */ 469 470 switch (Op->Asl.ParseOpcode) 471 { 472 case PARSEOP_NAME: 473 474 Arg = Op->Asl.Child; /* Get the NameSeg/NameString node */ 475 Arg = Arg->Asl.Next; /* First peer is the object to be associated with the name */ 476 477 /* 478 * If this name refers to a ResourceTemplate, we will need to open 479 * a new scope so that the resource subfield names can be entered into 480 * the namespace underneath this name 481 */ 482 if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC) 483 { 484 ForceNewScope = TRUE; 485 } 486 487 /* Get the data type associated with the named object, not the name itself */ 488 489 /* Log2 loop to convert from Btype (binary) to Etype (encoded) */ 490 491 ObjectType = 1; 492 for (i = 1; i < Arg->Asl.AcpiBtype; i *= 2) 493 { 494 ObjectType++; 495 } 496 break; 497 498 499 case PARSEOP_EXTERNAL: 500 501 /* 502 * "External" simply enters a name and type into the namespace. 503 * We must be careful to not open a new scope, however, no matter 504 * what type the external name refers to (e.g., a method) 505 * 506 * first child is name, next child is ObjectType 507 */ 508 ActualObjectType = (UINT8) Op->Asl.Child->Asl.Next->Asl.Value.Integer; 509 ObjectType = ACPI_TYPE_ANY; 510 511 /* 512 * We will mark every new node along the path as "External". This 513 * allows some or all of the nodes to be created later in the ASL 514 * code. Handles cases like this: 515 * 516 * External (\_SB_.PCI0.ABCD, IntObj) 517 * Scope (_SB_) 518 * { 519 * Device (PCI0) 520 * { 521 * } 522 * } 523 * Method (X) 524 * { 525 * Store (\_SB_.PCI0.ABCD, Local0) 526 * } 527 */ 528 Flags |= ACPI_NS_EXTERNAL; 529 break; 530 531 case PARSEOP_DEFAULT_ARG: 532 533 if (Op->Asl.CompileFlags == NODE_IS_RESOURCE_DESC) 534 { 535 Status = LdLoadResourceElements (Op, WalkState); 536 goto Exit; 537 } 538 539 ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); 540 break; 541 542 543 case PARSEOP_SCOPE: 544 545 /* 546 * The name referenced by Scope(Name) must already exist at this point. 547 * In other words, forward references for Scope() are not supported. 548 * The only real reason for this is that the MS interpreter cannot 549 * handle this case. Perhaps someday this case can go away. 550 */ 551 Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY, 552 ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, 553 WalkState, &(Node)); 554 if (ACPI_FAILURE (Status)) 555 { 556 if (Status == AE_NOT_FOUND) 557 { 558 /* The name was not found, go ahead and create it */ 559 560 Status = AcpiNsLookup (WalkState->ScopeInfo, Path, 561 ACPI_TYPE_LOCAL_SCOPE, 562 ACPI_IMODE_LOAD_PASS1, Flags, 563 WalkState, &(Node)); 564 565 /* 566 * However, this is an error -- primarily because the MS 567 * interpreter can't handle a forward reference from the 568 * Scope() operator. 569 */ 570 AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op, 571 Op->Asl.ExternalName); 572 AslError (ASL_ERROR, ASL_MSG_SCOPE_FWD_REF, Op, 573 Op->Asl.ExternalName); 574 goto FinishNode; 575 } 576 577 AslCoreSubsystemError (Op, Status, "Failure from lookup\n", FALSE); 578 goto Exit; 579 } 580 581 /* We found a node with this name, now check the type */ 582 583 switch (Node->Type) 584 { 585 case ACPI_TYPE_LOCAL_SCOPE: 586 case ACPI_TYPE_DEVICE: 587 case ACPI_TYPE_POWER: 588 case ACPI_TYPE_PROCESSOR: 589 case ACPI_TYPE_THERMAL: 590 591 /* These are acceptable types - they all open a new scope */ 592 break; 593 594 case ACPI_TYPE_INTEGER: 595 case ACPI_TYPE_STRING: 596 case ACPI_TYPE_BUFFER: 597 598 /* 599 * These types we will allow, but we will change the type. 600 * This enables some existing code of the form: 601 * 602 * Name (DEB, 0) 603 * Scope (DEB) { ... } 604 * 605 * Which is used to workaround the fact that the MS interpreter 606 * does not allow Scope() forward references. 607 */ 608 sprintf (MsgBuffer, "%s [%s], changing type to [Scope]", 609 Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type)); 610 AslError (ASL_REMARK, ASL_MSG_SCOPE_TYPE, Op, MsgBuffer); 611 612 /* Switch the type to scope, open the new scope */ 613 614 Node->Type = ACPI_TYPE_LOCAL_SCOPE; 615 Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE, 616 WalkState); 617 if (ACPI_FAILURE (Status)) 618 { 619 return_ACPI_STATUS (Status); 620 } 621 break; 622 623 default: 624 625 /* All other types are an error */ 626 627 sprintf (MsgBuffer, "%s [%s]", Op->Asl.ExternalName, 628 AcpiUtGetTypeName (Node->Type)); 629 AslError (ASL_ERROR, ASL_MSG_SCOPE_TYPE, Op, MsgBuffer); 630 631 /* 632 * However, switch the type to be an actual scope so 633 * that compilation can continue without generating a whole 634 * cascade of additional errors. Open the new scope. 635 */ 636 Node->Type = ACPI_TYPE_LOCAL_SCOPE; 637 Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE, 638 WalkState); 639 if (ACPI_FAILURE (Status)) 640 { 641 return_ACPI_STATUS (Status); 642 } 643 break; 644 } 645 646 Status = AE_OK; 647 goto FinishNode; 648 649 650 default: 651 652 ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); 653 break; 654 } 655 656 657 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Loading name: %s, (%s)\n", 658 Op->Asl.ExternalName, AcpiUtGetTypeName (ObjectType))); 659 660 /* The name must not already exist */ 661 662 Flags |= ACPI_NS_ERROR_IF_FOUND; 663 664 /* 665 * Enter the named type into the internal namespace. We enter the name 666 * as we go downward in the parse tree. Any necessary subobjects that 667 * involve arguments to the opcode must be created as we go back up the 668 * parse tree later. 669 */ 670 Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType, 671 ACPI_IMODE_LOAD_PASS1, Flags, WalkState, &Node); 672 if (ACPI_FAILURE (Status)) 673 { 674 if (Status == AE_ALREADY_EXISTS) 675 { 676 /* The name already exists in this scope */ 677 678 if (Node->Type == ACPI_TYPE_LOCAL_SCOPE) 679 { 680 /* Allow multiple references to the same scope */ 681 682 Node->Type = (UINT8) ObjectType; 683 Status = AE_OK; 684 } 685 else if ((Node->Flags & ANOBJ_IS_EXTERNAL) && 686 (Op->Asl.ParseOpcode != PARSEOP_EXTERNAL)) 687 { 688 /* 689 * Allow one create on an object or segment that was 690 * previously declared External 691 */ 692 Node->Flags &= ~ANOBJ_IS_EXTERNAL; 693 Node->Type = (UINT8) ObjectType; 694 695 /* Just retyped a node, probably will need to open a scope */ 696 697 if (AcpiNsOpensScope (ObjectType)) 698 { 699 Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState); 700 if (ACPI_FAILURE (Status)) 701 { 702 return_ACPI_STATUS (Status); 703 } 704 } 705 Status = AE_OK; 706 } 707 else 708 { 709 /* Valid error, object already exists */ 710 711 AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Op, 712 Op->Asl.ExternalName); 713 Status = AE_OK; 714 goto Exit; 715 } 716 } 717 else 718 { 719 AslCoreSubsystemError (Op, Status, 720 "Failure from lookup %s\n", FALSE); 721 goto Exit; 722 } 723 } 724 725 if (ForceNewScope) 726 { 727 Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState); 728 if (ACPI_FAILURE (Status)) 729 { 730 return_ACPI_STATUS (Status); 731 } 732 } 733 734 FinishNode: 735 /* 736 * Point the parse node to the new namespace node, and point 737 * the Node back to the original Parse node 738 */ 739 Op->Asl.Node = Node; 740 Node->Op = Op; 741 742 /* Set the actual data type if appropriate (EXTERNAL term only) */ 743 744 if (ActualObjectType != ACPI_TYPE_ANY) 745 { 746 Node->Type = (UINT8) ActualObjectType; 747 Node->Value = ASL_EXTERNAL_METHOD; 748 } 749 750 if (Op->Asl.ParseOpcode == PARSEOP_METHOD) 751 { 752 /* 753 * Get the method argument count from "Extra" and save 754 * it in the namespace node 755 */ 756 Node->Value = (UINT32) Op->Asl.Extra; 757 } 758 759 Exit: 760 return (Status); 761 } 762 763 764 /******************************************************************************* 765 * 766 * FUNCTION: LdNamespace2Begin 767 * 768 * PARAMETERS: ASL_WALK_CALLBACK 769 * 770 * RETURN: Status 771 * 772 * DESCRIPTION: Descending callback used during the pass 2 parse tree walk. 773 * Second pass resolves some forward references. 774 * 775 * Notes: 776 * Currently only needs to handle the Alias operator. 777 * Could be used to allow forward references from the Scope() operator, but 778 * the MS interpreter does not allow this, so this compiler does not either. 779 * 780 ******************************************************************************/ 781 782 static ACPI_STATUS 783 LdNamespace2Begin ( 784 ACPI_PARSE_OBJECT *Op, 785 UINT32 Level, 786 void *Context) 787 { 788 ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context; 789 ACPI_STATUS Status; 790 ACPI_NAMESPACE_NODE *Node; 791 ACPI_OBJECT_TYPE ObjectType; 792 BOOLEAN ForceNewScope = FALSE; 793 ACPI_PARSE_OBJECT *Arg; 794 char *Path; 795 ACPI_NAMESPACE_NODE *TargetNode; 796 797 798 ACPI_FUNCTION_NAME (LdNamespace2Begin); 799 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n", 800 Op, Op->Asl.ParseOpName)); 801 802 803 /* Ignore Ops with no namespace node */ 804 805 Node = Op->Asl.Node; 806 if (!Node) 807 { 808 return (AE_OK); 809 } 810 811 /* Get the type to determine if we should push the scope */ 812 813 if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) && 814 (Op->Asl.CompileFlags == NODE_IS_RESOURCE_DESC)) 815 { 816 ObjectType = ACPI_TYPE_LOCAL_RESOURCE; 817 } 818 else 819 { 820 ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); 821 } 822 823 /* Push scope for Resource Templates */ 824 825 if (Op->Asl.ParseOpcode == PARSEOP_NAME) 826 { 827 if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC) 828 { 829 ForceNewScope = TRUE; 830 } 831 } 832 833 /* Push the scope stack */ 834 835 if (ForceNewScope || AcpiNsOpensScope (ObjectType)) 836 { 837 Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState); 838 if (ACPI_FAILURE (Status)) 839 { 840 return_ACPI_STATUS (Status); 841 } 842 } 843 844 if (Op->Asl.ParseOpcode == PARSEOP_ALIAS) 845 { 846 /* Complete the alias node by getting and saving the target node */ 847 848 /* First child is the alias target */ 849 850 Arg = Op->Asl.Child; 851 852 /* Get the target pathname */ 853 854 Path = Arg->Asl.Namepath; 855 if (!Path) 856 { 857 Status = UtInternalizeName (Arg->Asl.ExternalName, &Path); 858 if (ACPI_FAILURE (Status)) 859 { 860 return (Status); 861 } 862 } 863 864 /* Get the NS node associated with the target. It must exist. */ 865 866 Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY, 867 ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, 868 WalkState, &TargetNode); 869 if (ACPI_FAILURE (Status)) 870 { 871 if (Status == AE_NOT_FOUND) 872 { 873 AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op, 874 Op->Asl.ExternalName); 875 876 /* 877 * The name was not found, go ahead and create it. 878 * This prevents more errors later. 879 */ 880 Status = AcpiNsLookup (WalkState->ScopeInfo, Path, 881 ACPI_TYPE_ANY, 882 ACPI_IMODE_LOAD_PASS1, ACPI_NS_NO_UPSEARCH, 883 WalkState, &(Node)); 884 return (AE_OK); 885 } 886 887 AslCoreSubsystemError (Op, Status, "Failure from lookup\n", FALSE); 888 return (AE_OK); 889 } 890 891 /* Save the target node within the alias node */ 892 893 Node->Object = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, TargetNode); 894 } 895 896 return (AE_OK); 897 } 898 899 900 /******************************************************************************* 901 * 902 * FUNCTION: LdCommonNamespaceEnd 903 * 904 * PARAMETERS: ASL_WALK_CALLBACK 905 * 906 * RETURN: Status 907 * 908 * DESCRIPTION: Ascending callback used during the loading of the namespace, 909 * We only need to worry about managing the scope stack here. 910 * 911 ******************************************************************************/ 912 913 static ACPI_STATUS 914 LdCommonNamespaceEnd ( 915 ACPI_PARSE_OBJECT *Op, 916 UINT32 Level, 917 void *Context) 918 { 919 ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context; 920 ACPI_OBJECT_TYPE ObjectType; 921 BOOLEAN ForceNewScope = FALSE; 922 923 924 ACPI_FUNCTION_NAME (LdCommonNamespaceEnd); 925 926 927 /* We are only interested in opcodes that have an associated name */ 928 929 if (!Op->Asl.Namepath) 930 { 931 return (AE_OK); 932 } 933 934 /* Get the type to determine if we should pop the scope */ 935 936 if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) && 937 (Op->Asl.CompileFlags == NODE_IS_RESOURCE_DESC)) 938 { 939 /* TBD: Merge into AcpiDsMapNamedOpcodeToDataType */ 940 941 ObjectType = ACPI_TYPE_LOCAL_RESOURCE; 942 } 943 else 944 { 945 ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); 946 } 947 948 /* Pop scope that was pushed for Resource Templates */ 949 950 if (Op->Asl.ParseOpcode == PARSEOP_NAME) 951 { 952 if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC) 953 { 954 ForceNewScope = TRUE; 955 } 956 } 957 958 /* Pop the scope stack */ 959 960 if (ForceNewScope || AcpiNsOpensScope (ObjectType)) 961 { 962 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 963 "(%s): Popping scope for Op [%s] %p\n", 964 AcpiUtGetTypeName (ObjectType), Op->Asl.ParseOpName, Op)); 965 966 (void) AcpiDsScopeStackPop (WalkState); 967 } 968 969 return (AE_OK); 970 } 971 972 973