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