1 /****************************************************************************** 2 * 3 * Module Name: dswload - Dispatcher namespace load callbacks 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2014, 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 __ASLLOAD_C__ 45 46 #include "aslcompiler.h" 47 #include "amlcode.h" 48 #include "acdispat.h" 49 #include "acnamesp.h" 50 51 #include "aslcompiler.y.h" 52 53 #define _COMPONENT ACPI_COMPILER 54 ACPI_MODULE_NAME ("aslload") 55 56 /* Local prototypes */ 57 58 static ACPI_STATUS 59 LdLoadFieldElements ( 60 ACPI_PARSE_OBJECT *Op, 61 ACPI_WALK_STATE *WalkState); 62 63 static ACPI_STATUS 64 LdLoadResourceElements ( 65 ACPI_PARSE_OBJECT *Op, 66 ACPI_WALK_STATE *WalkState); 67 68 static ACPI_STATUS 69 LdNamespace1Begin ( 70 ACPI_PARSE_OBJECT *Op, 71 UINT32 Level, 72 void *Context); 73 74 static ACPI_STATUS 75 LdNamespace2Begin ( 76 ACPI_PARSE_OBJECT *Op, 77 UINT32 Level, 78 void *Context); 79 80 static ACPI_STATUS 81 LdCommonNamespaceEnd ( 82 ACPI_PARSE_OBJECT *Op, 83 UINT32 Level, 84 void *Context); 85 86 87 /******************************************************************************* 88 * 89 * FUNCTION: LdLoadNamespace 90 * 91 * PARAMETERS: RootOp - Root of the parse tree 92 * 93 * RETURN: Status 94 * 95 * DESCRIPTION: Perform a walk of the parse tree that in turn loads all of the 96 * named ASL/AML objects into the namespace. The namespace is 97 * constructed in order to resolve named references and references 98 * to named fields within resource templates/descriptors. 99 * 100 ******************************************************************************/ 101 102 ACPI_STATUS 103 LdLoadNamespace ( 104 ACPI_PARSE_OBJECT *RootOp) 105 { 106 ACPI_WALK_STATE *WalkState; 107 108 109 DbgPrint (ASL_DEBUG_OUTPUT, "\nCreating namespace\n\n"); 110 111 /* Create a new walk state */ 112 113 WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL); 114 if (!WalkState) 115 { 116 return (AE_NO_MEMORY); 117 } 118 119 /* Walk the entire parse tree, first pass */ 120 121 TrWalkParseTree (RootOp, ASL_WALK_VISIT_TWICE, LdNamespace1Begin, 122 LdCommonNamespaceEnd, WalkState); 123 124 /* Second pass to handle forward references */ 125 126 TrWalkParseTree (RootOp, ASL_WALK_VISIT_TWICE, LdNamespace2Begin, 127 LdCommonNamespaceEnd, WalkState); 128 129 /* Dump the namespace if debug is enabled */ 130 131 AcpiNsDumpTables (ACPI_NS_ALL, ACPI_UINT32_MAX); 132 ACPI_FREE (WalkState); 133 return (AE_OK); 134 } 135 136 137 /******************************************************************************* 138 * 139 * FUNCTION: LdLoadFieldElements 140 * 141 * PARAMETERS: Op - Parent node (Field) 142 * WalkState - Current walk state 143 * 144 * RETURN: Status 145 * 146 * DESCRIPTION: Enter the named elements of the field (children of the parent) 147 * into the namespace. 148 * 149 ******************************************************************************/ 150 151 static ACPI_STATUS 152 LdLoadFieldElements ( 153 ACPI_PARSE_OBJECT *Op, 154 ACPI_WALK_STATE *WalkState) 155 { 156 ACPI_PARSE_OBJECT *Child = NULL; 157 ACPI_NAMESPACE_NODE *Node; 158 ACPI_STATUS Status; 159 160 161 /* Get the first named field element */ 162 163 switch (Op->Asl.AmlOpcode) 164 { 165 case AML_BANK_FIELD_OP: 166 167 Child = UtGetArg (Op, 6); 168 break; 169 170 case AML_INDEX_FIELD_OP: 171 172 Child = UtGetArg (Op, 5); 173 break; 174 175 case AML_FIELD_OP: 176 177 Child = UtGetArg (Op, 4); 178 break; 179 180 default: 181 182 /* No other opcodes should arrive here */ 183 184 return (AE_BAD_PARAMETER); 185 } 186 187 /* Enter all elements into the namespace */ 188 189 while (Child) 190 { 191 switch (Child->Asl.AmlOpcode) 192 { 193 case AML_INT_RESERVEDFIELD_OP: 194 case AML_INT_ACCESSFIELD_OP: 195 case AML_INT_CONNECTION_OP: 196 break; 197 198 default: 199 200 Status = AcpiNsLookup (WalkState->ScopeInfo, 201 Child->Asl.Value.String, 202 ACPI_TYPE_LOCAL_REGION_FIELD, 203 ACPI_IMODE_LOAD_PASS1, 204 ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | 205 ACPI_NS_ERROR_IF_FOUND, 206 NULL, &Node); 207 if (ACPI_FAILURE (Status)) 208 { 209 if (Status != AE_ALREADY_EXISTS) 210 { 211 AslError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION, Child, 212 Child->Asl.Value.String); 213 return (Status); 214 } 215 216 /* 217 * The name already exists in this scope 218 * But continue processing the elements 219 */ 220 AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Child, 221 Child->Asl.Value.String); 222 } 223 else 224 { 225 Child->Asl.Node = Node; 226 Node->Op = Child; 227 } 228 break; 229 } 230 231 Child = Child->Asl.Next; 232 } 233 234 return (AE_OK); 235 } 236 237 238 /******************************************************************************* 239 * 240 * FUNCTION: LdLoadResourceElements 241 * 242 * PARAMETERS: Op - Parent node (Resource Descriptor) 243 * WalkState - Current walk state 244 * 245 * RETURN: Status 246 * 247 * DESCRIPTION: Enter the named elements of the resource descriptor (children 248 * of the parent) into the namespace. 249 * 250 * NOTE: In the real AML namespace, these named elements never exist. But 251 * we simply use the namespace here as a symbol table so we can look 252 * them up as they are referenced. 253 * 254 ******************************************************************************/ 255 256 static ACPI_STATUS 257 LdLoadResourceElements ( 258 ACPI_PARSE_OBJECT *Op, 259 ACPI_WALK_STATE *WalkState) 260 { 261 ACPI_PARSE_OBJECT *InitializerOp = NULL; 262 ACPI_NAMESPACE_NODE *Node; 263 ACPI_STATUS Status; 264 265 266 /* 267 * Enter the resource name into the namespace. Name must not already exist. 268 * This opens a scope, so later field names are guaranteed to be new/unique. 269 */ 270 Status = AcpiNsLookup (WalkState->ScopeInfo, Op->Asl.Namepath, 271 ACPI_TYPE_LOCAL_RESOURCE, ACPI_IMODE_LOAD_PASS1, 272 ACPI_NS_NO_UPSEARCH | ACPI_NS_ERROR_IF_FOUND, 273 WalkState, &Node); 274 if (ACPI_FAILURE (Status)) 275 { 276 if (Status == AE_ALREADY_EXISTS) 277 { 278 /* Actual node causing the error was saved in ParentMethod */ 279 280 AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS, 281 (ACPI_PARSE_OBJECT *) Op->Asl.ParentMethod, Op->Asl.Namepath); 282 return (AE_OK); 283 } 284 return (Status); 285 } 286 287 Node->Value = (UINT32) Op->Asl.Value.Integer; 288 Node->Op = Op; 289 Op->Asl.Node = Node; 290 291 /* 292 * Now enter the predefined fields, for easy lookup when referenced 293 * by the source ASL 294 */ 295 InitializerOp = ASL_GET_CHILD_NODE (Op); 296 while (InitializerOp) 297 { 298 if (InitializerOp->Asl.ExternalName) 299 { 300 Status = AcpiNsLookup (WalkState->ScopeInfo, 301 InitializerOp->Asl.ExternalName, 302 ACPI_TYPE_LOCAL_RESOURCE_FIELD, 303 ACPI_IMODE_LOAD_PASS1, 304 ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE, 305 NULL, &Node); 306 if (ACPI_FAILURE (Status)) 307 { 308 return (Status); 309 } 310 311 /* 312 * Store the field offset and length in the namespace node 313 * so it can be used when the field is referenced 314 */ 315 Node->Value = InitializerOp->Asl.Value.Tag.BitOffset; 316 Node->Length = InitializerOp->Asl.Value.Tag.BitLength; 317 InitializerOp->Asl.Node = Node; 318 Node->Op = InitializerOp; 319 } 320 321 InitializerOp = ASL_GET_PEER_NODE (InitializerOp); 322 } 323 324 return (AE_OK); 325 } 326 327 328 /******************************************************************************* 329 * 330 * FUNCTION: LdNamespace1Begin 331 * 332 * PARAMETERS: ASL_WALK_CALLBACK 333 * 334 * RETURN: Status 335 * 336 * DESCRIPTION: Descending callback used during the parse tree walk. If this 337 * is a named AML opcode, enter into the namespace 338 * 339 ******************************************************************************/ 340 341 static ACPI_STATUS 342 LdNamespace1Begin ( 343 ACPI_PARSE_OBJECT *Op, 344 UINT32 Level, 345 void *Context) 346 { 347 ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context; 348 ACPI_NAMESPACE_NODE *Node; 349 ACPI_STATUS Status; 350 ACPI_OBJECT_TYPE ObjectType; 351 ACPI_OBJECT_TYPE ActualObjectType = ACPI_TYPE_ANY; 352 char *Path; 353 UINT32 Flags = ACPI_NS_NO_UPSEARCH; 354 ACPI_PARSE_OBJECT *Arg; 355 UINT32 i; 356 BOOLEAN ForceNewScope = FALSE; 357 358 359 ACPI_FUNCTION_NAME (LdNamespace1Begin); 360 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n", 361 Op, Op->Asl.ParseOpName)); 362 363 364 /* 365 * We are only interested in opcodes that have an associated name 366 * (or multiple names) 367 */ 368 switch (Op->Asl.AmlOpcode) 369 { 370 case AML_BANK_FIELD_OP: 371 case AML_INDEX_FIELD_OP: 372 case AML_FIELD_OP: 373 374 Status = LdLoadFieldElements (Op, WalkState); 375 return (Status); 376 377 default: 378 379 /* All other opcodes go below */ 380 381 break; 382 } 383 384 /* Check if this object has already been installed in the namespace */ 385 386 if (Op->Asl.Node) 387 { 388 return (AE_OK); 389 } 390 391 Path = Op->Asl.Namepath; 392 if (!Path) 393 { 394 return (AE_OK); 395 } 396 397 /* Map the raw opcode into an internal object type */ 398 399 switch (Op->Asl.ParseOpcode) 400 { 401 case PARSEOP_NAME: 402 403 Arg = Op->Asl.Child; /* Get the NameSeg/NameString node */ 404 Arg = Arg->Asl.Next; /* First peer is the object to be associated with the name */ 405 406 /* 407 * If this name refers to a ResourceTemplate, we will need to open 408 * a new scope so that the resource subfield names can be entered into 409 * the namespace underneath this name 410 */ 411 if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC) 412 { 413 ForceNewScope = TRUE; 414 } 415 416 /* Get the data type associated with the named object, not the name itself */ 417 418 /* Log2 loop to convert from Btype (binary) to Etype (encoded) */ 419 420 ObjectType = 1; 421 for (i = 1; i < Arg->Asl.AcpiBtype; i *= 2) 422 { 423 ObjectType++; 424 } 425 break; 426 427 428 case PARSEOP_EXTERNAL: 429 /* 430 * "External" simply enters a name and type into the namespace. 431 * We must be careful to not open a new scope, however, no matter 432 * what type the external name refers to (e.g., a method) 433 * 434 * first child is name, next child is ObjectType 435 */ 436 ActualObjectType = (UINT8) Op->Asl.Child->Asl.Next->Asl.Value.Integer; 437 ObjectType = ACPI_TYPE_ANY; 438 439 /* 440 * We will mark every new node along the path as "External". This 441 * allows some or all of the nodes to be created later in the ASL 442 * code. Handles cases like this: 443 * 444 * External (\_SB_.PCI0.ABCD, IntObj) 445 * Scope (_SB_) 446 * { 447 * Device (PCI0) 448 * { 449 * } 450 * } 451 * Method (X) 452 * { 453 * Store (\_SB_.PCI0.ABCD, Local0) 454 * } 455 */ 456 Flags |= ACPI_NS_EXTERNAL; 457 break; 458 459 case PARSEOP_DEFAULT_ARG: 460 461 if (Op->Asl.CompileFlags == NODE_IS_RESOURCE_DESC) 462 { 463 Status = LdLoadResourceElements (Op, WalkState); 464 return_ACPI_STATUS (Status); 465 } 466 467 ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); 468 break; 469 470 471 case PARSEOP_SCOPE: 472 /* 473 * The name referenced by Scope(Name) must already exist at this point. 474 * In other words, forward references for Scope() are not supported. 475 * The only real reason for this is that the MS interpreter cannot 476 * handle this case. Perhaps someday this case can go away. 477 */ 478 Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY, 479 ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, 480 WalkState, &(Node)); 481 if (ACPI_FAILURE (Status)) 482 { 483 if (Status == AE_NOT_FOUND) 484 { 485 /* The name was not found, go ahead and create it */ 486 487 Status = AcpiNsLookup (WalkState->ScopeInfo, Path, 488 ACPI_TYPE_LOCAL_SCOPE, 489 ACPI_IMODE_LOAD_PASS1, Flags, 490 WalkState, &(Node)); 491 if (ACPI_FAILURE (Status)) 492 { 493 return_ACPI_STATUS (Status); 494 } 495 496 /* 497 * However, this is an error -- primarily because the MS 498 * interpreter can't handle a forward reference from the 499 * Scope() operator. 500 */ 501 AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op, 502 Op->Asl.ExternalName); 503 AslError (ASL_ERROR, ASL_MSG_SCOPE_FWD_REF, Op, 504 Op->Asl.ExternalName); 505 goto FinishNode; 506 } 507 508 AslCoreSubsystemError (Op, Status, 509 "Failure from namespace lookup", FALSE); 510 511 return_ACPI_STATUS (Status); 512 } 513 514 /* We found a node with this name, now check the type */ 515 516 switch (Node->Type) 517 { 518 case ACPI_TYPE_LOCAL_SCOPE: 519 case ACPI_TYPE_DEVICE: 520 case ACPI_TYPE_POWER: 521 case ACPI_TYPE_PROCESSOR: 522 case ACPI_TYPE_THERMAL: 523 524 /* These are acceptable types - they all open a new scope */ 525 break; 526 527 case ACPI_TYPE_INTEGER: 528 case ACPI_TYPE_STRING: 529 case ACPI_TYPE_BUFFER: 530 /* 531 * These types we will allow, but we will change the type. 532 * This enables some existing code of the form: 533 * 534 * Name (DEB, 0) 535 * Scope (DEB) { ... } 536 * 537 * Which is used to workaround the fact that the MS interpreter 538 * does not allow Scope() forward references. 539 */ 540 sprintf (MsgBuffer, "%s [%s], changing type to [Scope]", 541 Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type)); 542 AslError (ASL_REMARK, ASL_MSG_SCOPE_TYPE, Op, MsgBuffer); 543 544 /* Switch the type to scope, open the new scope */ 545 546 Node->Type = ACPI_TYPE_LOCAL_SCOPE; 547 Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE, 548 WalkState); 549 if (ACPI_FAILURE (Status)) 550 { 551 return_ACPI_STATUS (Status); 552 } 553 break; 554 555 default: 556 557 /* All other types are an error */ 558 559 sprintf (MsgBuffer, "%s [%s]", Op->Asl.ExternalName, 560 AcpiUtGetTypeName (Node->Type)); 561 AslError (ASL_ERROR, ASL_MSG_SCOPE_TYPE, Op, MsgBuffer); 562 563 /* 564 * However, switch the type to be an actual scope so 565 * that compilation can continue without generating a whole 566 * cascade of additional errors. Open the new scope. 567 */ 568 Node->Type = ACPI_TYPE_LOCAL_SCOPE; 569 Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE, 570 WalkState); 571 if (ACPI_FAILURE (Status)) 572 { 573 return_ACPI_STATUS (Status); 574 } 575 break; 576 } 577 578 Status = AE_OK; 579 goto FinishNode; 580 581 582 default: 583 584 ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); 585 break; 586 } 587 588 589 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Loading name: %s, (%s)\n", 590 Op->Asl.ExternalName, AcpiUtGetTypeName (ObjectType))); 591 592 /* The name must not already exist */ 593 594 Flags |= ACPI_NS_ERROR_IF_FOUND; 595 596 /* 597 * Enter the named type into the internal namespace. We enter the name 598 * as we go downward in the parse tree. Any necessary subobjects that 599 * involve arguments to the opcode must be created as we go back up the 600 * parse tree later. 601 */ 602 Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType, 603 ACPI_IMODE_LOAD_PASS1, Flags, WalkState, &Node); 604 if (ACPI_FAILURE (Status)) 605 { 606 if (Status == AE_ALREADY_EXISTS) 607 { 608 /* The name already exists in this scope */ 609 610 if (Node->Type == ACPI_TYPE_LOCAL_SCOPE) 611 { 612 /* Allow multiple references to the same scope */ 613 614 Node->Type = (UINT8) ObjectType; 615 Status = AE_OK; 616 } 617 else if ((Node->Flags & ANOBJ_IS_EXTERNAL) && 618 (Op->Asl.ParseOpcode != PARSEOP_EXTERNAL)) 619 { 620 /* 621 * Allow one create on an object or segment that was 622 * previously declared External 623 */ 624 Node->Flags &= ~ANOBJ_IS_EXTERNAL; 625 Node->Type = (UINT8) ObjectType; 626 627 /* Just retyped a node, probably will need to open a scope */ 628 629 if (AcpiNsOpensScope (ObjectType)) 630 { 631 Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState); 632 if (ACPI_FAILURE (Status)) 633 { 634 return_ACPI_STATUS (Status); 635 } 636 } 637 Status = AE_OK; 638 } 639 else 640 { 641 /* Valid error, object already exists */ 642 643 AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Op, 644 Op->Asl.ExternalName); 645 return_ACPI_STATUS (AE_OK); 646 } 647 } 648 else 649 { 650 AslCoreSubsystemError (Op, Status, 651 "Failure from namespace lookup", FALSE); 652 return_ACPI_STATUS (Status); 653 } 654 } 655 656 if (ForceNewScope) 657 { 658 Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState); 659 if (ACPI_FAILURE (Status)) 660 { 661 return_ACPI_STATUS (Status); 662 } 663 } 664 665 FinishNode: 666 /* 667 * Point the parse node to the new namespace node, and point 668 * the Node back to the original Parse node 669 */ 670 Op->Asl.Node = Node; 671 Node->Op = Op; 672 673 /* Set the actual data type if appropriate (EXTERNAL term only) */ 674 675 if (ActualObjectType != ACPI_TYPE_ANY) 676 { 677 Node->Type = (UINT8) ActualObjectType; 678 Node->Value = ASL_EXTERNAL_METHOD; 679 } 680 681 if (Op->Asl.ParseOpcode == PARSEOP_METHOD) 682 { 683 /* 684 * Get the method argument count from "Extra" and save 685 * it in the namespace node 686 */ 687 Node->Value = (UINT32) Op->Asl.Extra; 688 } 689 690 return_ACPI_STATUS (Status); 691 } 692 693 694 /******************************************************************************* 695 * 696 * FUNCTION: LdNamespace2Begin 697 * 698 * PARAMETERS: ASL_WALK_CALLBACK 699 * 700 * RETURN: Status 701 * 702 * DESCRIPTION: Descending callback used during the pass 2 parse tree walk. 703 * Second pass resolves some forward references. 704 * 705 * Notes: 706 * Currently only needs to handle the Alias operator. 707 * Could be used to allow forward references from the Scope() operator, but 708 * the MS interpreter does not allow this, so this compiler does not either. 709 * 710 ******************************************************************************/ 711 712 static ACPI_STATUS 713 LdNamespace2Begin ( 714 ACPI_PARSE_OBJECT *Op, 715 UINT32 Level, 716 void *Context) 717 { 718 ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context; 719 ACPI_STATUS Status; 720 ACPI_NAMESPACE_NODE *Node; 721 ACPI_OBJECT_TYPE ObjectType; 722 BOOLEAN ForceNewScope = FALSE; 723 ACPI_PARSE_OBJECT *Arg; 724 char *Path; 725 ACPI_NAMESPACE_NODE *TargetNode; 726 727 728 ACPI_FUNCTION_NAME (LdNamespace2Begin); 729 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n", 730 Op, Op->Asl.ParseOpName)); 731 732 733 /* Ignore Ops with no namespace node */ 734 735 Node = Op->Asl.Node; 736 if (!Node) 737 { 738 return (AE_OK); 739 } 740 741 /* Get the type to determine if we should push the scope */ 742 743 if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) && 744 (Op->Asl.CompileFlags == NODE_IS_RESOURCE_DESC)) 745 { 746 ObjectType = ACPI_TYPE_LOCAL_RESOURCE; 747 } 748 else 749 { 750 ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); 751 } 752 753 /* Push scope for Resource Templates */ 754 755 if (Op->Asl.ParseOpcode == PARSEOP_NAME) 756 { 757 if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC) 758 { 759 ForceNewScope = TRUE; 760 } 761 } 762 763 /* Push the scope stack */ 764 765 if (ForceNewScope || AcpiNsOpensScope (ObjectType)) 766 { 767 Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState); 768 if (ACPI_FAILURE (Status)) 769 { 770 return_ACPI_STATUS (Status); 771 } 772 } 773 774 if (Op->Asl.ParseOpcode == PARSEOP_ALIAS) 775 { 776 /* Complete the alias node by getting and saving the target node */ 777 778 /* First child is the alias target */ 779 780 Arg = Op->Asl.Child; 781 782 /* Get the target pathname */ 783 784 Path = Arg->Asl.Namepath; 785 if (!Path) 786 { 787 Status = UtInternalizeName (Arg->Asl.ExternalName, &Path); 788 if (ACPI_FAILURE (Status)) 789 { 790 return (Status); 791 } 792 } 793 794 /* Get the NS node associated with the target. It must exist. */ 795 796 Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY, 797 ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, 798 WalkState, &TargetNode); 799 if (ACPI_FAILURE (Status)) 800 { 801 if (Status == AE_NOT_FOUND) 802 { 803 AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op, 804 Op->Asl.ExternalName); 805 806 /* 807 * The name was not found, go ahead and create it. 808 * This prevents more errors later. 809 */ 810 Status = AcpiNsLookup (WalkState->ScopeInfo, Path, 811 ACPI_TYPE_ANY, 812 ACPI_IMODE_LOAD_PASS1, ACPI_NS_NO_UPSEARCH, 813 WalkState, &(Node)); 814 return (AE_OK); 815 } 816 817 AslCoreSubsystemError (Op, Status, 818 "Failure from namespace lookup", FALSE); 819 return (AE_OK); 820 } 821 822 /* Save the target node within the alias node */ 823 824 Node->Object = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, TargetNode); 825 } 826 827 return (AE_OK); 828 } 829 830 831 /******************************************************************************* 832 * 833 * FUNCTION: LdCommonNamespaceEnd 834 * 835 * PARAMETERS: ASL_WALK_CALLBACK 836 * 837 * RETURN: Status 838 * 839 * DESCRIPTION: Ascending callback used during the loading of the namespace, 840 * We only need to worry about managing the scope stack here. 841 * 842 ******************************************************************************/ 843 844 static ACPI_STATUS 845 LdCommonNamespaceEnd ( 846 ACPI_PARSE_OBJECT *Op, 847 UINT32 Level, 848 void *Context) 849 { 850 ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context; 851 ACPI_OBJECT_TYPE ObjectType; 852 BOOLEAN ForceNewScope = FALSE; 853 854 855 ACPI_FUNCTION_NAME (LdCommonNamespaceEnd); 856 857 858 /* We are only interested in opcodes that have an associated name */ 859 860 if (!Op->Asl.Namepath) 861 { 862 return (AE_OK); 863 } 864 865 /* Get the type to determine if we should pop the scope */ 866 867 if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) && 868 (Op->Asl.CompileFlags == NODE_IS_RESOURCE_DESC)) 869 { 870 /* TBD: Merge into AcpiDsMapNamedOpcodeToDataType */ 871 872 ObjectType = ACPI_TYPE_LOCAL_RESOURCE; 873 } 874 else 875 { 876 ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); 877 } 878 879 /* Pop scope that was pushed for Resource Templates */ 880 881 if (Op->Asl.ParseOpcode == PARSEOP_NAME) 882 { 883 if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC) 884 { 885 ForceNewScope = TRUE; 886 } 887 } 888 889 /* Pop the scope stack */ 890 891 if (ForceNewScope || AcpiNsOpensScope (ObjectType)) 892 { 893 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 894 "(%s): Popping scope for Op [%s] %p\n", 895 AcpiUtGetTypeName (ObjectType), Op->Asl.ParseOpName, Op)); 896 897 (void) AcpiDsScopeStackPop (WalkState); 898 } 899 900 return (AE_OK); 901 } 902