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