1 /****************************************************************************** 2 * 3 * Module Name: dswload - Dispatcher namespace load callbacks 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2012, 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 /* No other opcodes should arrive here */ 181 return (AE_BAD_PARAMETER); 182 } 183 184 /* Enter all elements into the namespace */ 185 186 while (Child) 187 { 188 switch (Child->Asl.AmlOpcode) 189 { 190 case AML_INT_RESERVEDFIELD_OP: 191 case AML_INT_ACCESSFIELD_OP: 192 case AML_INT_CONNECTION_OP: 193 break; 194 195 default: 196 197 Status = AcpiNsLookup (WalkState->ScopeInfo, 198 Child->Asl.Value.String, 199 ACPI_TYPE_LOCAL_REGION_FIELD, 200 ACPI_IMODE_LOAD_PASS1, 201 ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | 202 ACPI_NS_ERROR_IF_FOUND, 203 NULL, &Node); 204 if (ACPI_FAILURE (Status)) 205 { 206 if (Status != AE_ALREADY_EXISTS) 207 { 208 AslError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION, Child, 209 Child->Asl.Value.String); 210 return (Status); 211 } 212 213 /* 214 * The name already exists in this scope 215 * But continue processing the elements 216 */ 217 AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Child, 218 Child->Asl.Value.String); 219 } 220 else 221 { 222 Child->Asl.Node = Node; 223 Node->Op = Child; 224 } 225 break; 226 } 227 228 Child = Child->Asl.Next; 229 } 230 231 return (AE_OK); 232 } 233 234 235 /******************************************************************************* 236 * 237 * FUNCTION: LdLoadResourceElements 238 * 239 * PARAMETERS: Op - Parent node (Resource Descriptor) 240 * WalkState - Current walk state 241 * 242 * RETURN: Status 243 * 244 * DESCRIPTION: Enter the named elements of the resource descriptor (children 245 * of the parent) into the namespace. 246 * 247 * NOTE: In the real AML namespace, these named elements never exist. But 248 * we simply use the namespace here as a symbol table so we can look 249 * them up as they are referenced. 250 * 251 ******************************************************************************/ 252 253 static ACPI_STATUS 254 LdLoadResourceElements ( 255 ACPI_PARSE_OBJECT *Op, 256 ACPI_WALK_STATE *WalkState) 257 { 258 ACPI_PARSE_OBJECT *InitializerOp = NULL; 259 ACPI_NAMESPACE_NODE *Node; 260 ACPI_STATUS Status; 261 262 263 /* 264 * Enter the resource name into the namespace. Name must not already exist. 265 * This opens a scope, so later field names are guaranteed to be new/unique. 266 */ 267 Status = AcpiNsLookup (WalkState->ScopeInfo, Op->Asl.Namepath, 268 ACPI_TYPE_LOCAL_RESOURCE, ACPI_IMODE_LOAD_PASS1, 269 ACPI_NS_NO_UPSEARCH | ACPI_NS_ERROR_IF_FOUND, 270 WalkState, &Node); 271 if (ACPI_FAILURE (Status)) 272 { 273 if (Status == AE_ALREADY_EXISTS) 274 { 275 /* Actual node causing the error was saved in ParentMethod */ 276 277 AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS, 278 (ACPI_PARSE_OBJECT *) Op->Asl.ParentMethod, Op->Asl.Namepath); 279 return (AE_OK); 280 } 281 return (Status); 282 } 283 284 Node->Value = (UINT32) Op->Asl.Value.Integer; 285 Node->Op = Op; 286 Op->Asl.Node = Node; 287 288 /* 289 * Now enter the predefined fields, for easy lookup when referenced 290 * by the source ASL 291 */ 292 InitializerOp = ASL_GET_CHILD_NODE (Op); 293 while (InitializerOp) 294 { 295 if (InitializerOp->Asl.ExternalName) 296 { 297 Status = AcpiNsLookup (WalkState->ScopeInfo, 298 InitializerOp->Asl.ExternalName, 299 ACPI_TYPE_LOCAL_RESOURCE_FIELD, 300 ACPI_IMODE_LOAD_PASS1, 301 ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE, 302 NULL, &Node); 303 if (ACPI_FAILURE (Status)) 304 { 305 return (Status); 306 } 307 308 /* 309 * Store the field offset and length in the namespace node 310 * so it can be used when the field is referenced 311 */ 312 Node->Value = InitializerOp->Asl.Value.Tag.BitOffset; 313 Node->Length = InitializerOp->Asl.Value.Tag.BitLength; 314 InitializerOp->Asl.Node = Node; 315 Node->Op = InitializerOp; 316 } 317 318 InitializerOp = ASL_GET_PEER_NODE (InitializerOp); 319 } 320 321 return (AE_OK); 322 } 323 324 325 /******************************************************************************* 326 * 327 * FUNCTION: LdNamespace1Begin 328 * 329 * PARAMETERS: ASL_WALK_CALLBACK 330 * 331 * RETURN: Status 332 * 333 * DESCRIPTION: Descending callback used during the parse tree walk. If this 334 * is a named AML opcode, enter into the namespace 335 * 336 ******************************************************************************/ 337 338 static ACPI_STATUS 339 LdNamespace1Begin ( 340 ACPI_PARSE_OBJECT *Op, 341 UINT32 Level, 342 void *Context) 343 { 344 ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context; 345 ACPI_NAMESPACE_NODE *Node; 346 ACPI_STATUS Status; 347 ACPI_OBJECT_TYPE ObjectType; 348 ACPI_OBJECT_TYPE ActualObjectType = ACPI_TYPE_ANY; 349 char *Path; 350 UINT32 Flags = ACPI_NS_NO_UPSEARCH; 351 ACPI_PARSE_OBJECT *Arg; 352 UINT32 i; 353 BOOLEAN ForceNewScope = FALSE; 354 355 356 ACPI_FUNCTION_NAME (LdNamespace1Begin); 357 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n", 358 Op, Op->Asl.ParseOpName)); 359 360 361 /* 362 * We are only interested in opcodes that have an associated name 363 * (or multiple names) 364 */ 365 switch (Op->Asl.AmlOpcode) 366 { 367 case AML_BANK_FIELD_OP: 368 case AML_INDEX_FIELD_OP: 369 case AML_FIELD_OP: 370 371 Status = LdLoadFieldElements (Op, WalkState); 372 return (Status); 373 374 default: 375 376 /* All other opcodes go below */ 377 break; 378 } 379 380 /* Check if this object has already been installed in the namespace */ 381 382 if (Op->Asl.Node) 383 { 384 return (AE_OK); 385 } 386 387 Path = Op->Asl.Namepath; 388 if (!Path) 389 { 390 return (AE_OK); 391 } 392 393 /* Map the raw opcode into an internal object type */ 394 395 switch (Op->Asl.ParseOpcode) 396 { 397 case PARSEOP_NAME: 398 399 Arg = Op->Asl.Child; /* Get the NameSeg/NameString node */ 400 Arg = Arg->Asl.Next; /* First peer is the object to be associated with the name */ 401 402 /* 403 * If this name refers to a ResourceTemplate, we will need to open 404 * a new scope so that the resource subfield names can be entered into 405 * the namespace underneath this name 406 */ 407 if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC) 408 { 409 ForceNewScope = TRUE; 410 } 411 412 /* Get the data type associated with the named object, not the name itself */ 413 414 /* Log2 loop to convert from Btype (binary) to Etype (encoded) */ 415 416 ObjectType = 1; 417 for (i = 1; i < Arg->Asl.AcpiBtype; i *= 2) 418 { 419 ObjectType++; 420 } 421 break; 422 423 424 case PARSEOP_EXTERNAL: 425 426 /* 427 * "External" simply enters a name and type into the namespace. 428 * We must be careful to not open a new scope, however, no matter 429 * what type the external name refers to (e.g., a method) 430 * 431 * first child is name, next child is ObjectType 432 */ 433 ActualObjectType = (UINT8) Op->Asl.Child->Asl.Next->Asl.Value.Integer; 434 ObjectType = ACPI_TYPE_ANY; 435 436 /* 437 * We will mark every new node along the path as "External". This 438 * allows some or all of the nodes to be created later in the ASL 439 * code. Handles cases like this: 440 * 441 * External (\_SB_.PCI0.ABCD, IntObj) 442 * Scope (_SB_) 443 * { 444 * Device (PCI0) 445 * { 446 * } 447 * } 448 * Method (X) 449 * { 450 * Store (\_SB_.PCI0.ABCD, Local0) 451 * } 452 */ 453 Flags |= ACPI_NS_EXTERNAL; 454 break; 455 456 case PARSEOP_DEFAULT_ARG: 457 458 if (Op->Asl.CompileFlags == NODE_IS_RESOURCE_DESC) 459 { 460 Status = LdLoadResourceElements (Op, WalkState); 461 return_ACPI_STATUS (Status); 462 } 463 464 ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); 465 break; 466 467 468 case PARSEOP_SCOPE: 469 470 /* 471 * The name referenced by Scope(Name) must already exist at this point. 472 * In other words, forward references for Scope() are not supported. 473 * The only real reason for this is that the MS interpreter cannot 474 * handle this case. Perhaps someday this case can go away. 475 */ 476 Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY, 477 ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, 478 WalkState, &(Node)); 479 if (ACPI_FAILURE (Status)) 480 { 481 if (Status == AE_NOT_FOUND) 482 { 483 /* The name was not found, go ahead and create it */ 484 485 Status = AcpiNsLookup (WalkState->ScopeInfo, Path, 486 ACPI_TYPE_LOCAL_SCOPE, 487 ACPI_IMODE_LOAD_PASS1, Flags, 488 WalkState, &(Node)); 489 490 /* 491 * However, this is an error -- primarily because the MS 492 * interpreter can't handle a forward reference from the 493 * Scope() operator. 494 */ 495 AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op, 496 Op->Asl.ExternalName); 497 AslError (ASL_ERROR, ASL_MSG_SCOPE_FWD_REF, Op, 498 Op->Asl.ExternalName); 499 goto FinishNode; 500 } 501 502 AslCoreSubsystemError (Op, Status, 503 "Failure from namespace lookup", FALSE); 504 505 return_ACPI_STATUS (Status); 506 } 507 508 /* We found a node with this name, now check the type */ 509 510 switch (Node->Type) 511 { 512 case ACPI_TYPE_LOCAL_SCOPE: 513 case ACPI_TYPE_DEVICE: 514 case ACPI_TYPE_POWER: 515 case ACPI_TYPE_PROCESSOR: 516 case ACPI_TYPE_THERMAL: 517 518 /* These are acceptable types - they all open a new scope */ 519 break; 520 521 case ACPI_TYPE_INTEGER: 522 case ACPI_TYPE_STRING: 523 case ACPI_TYPE_BUFFER: 524 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