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