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