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 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, 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_PARSE_OBJECT *MethodOp; 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 else /* Status AE_OK */ 538 { 539 /* 540 * Do not allow references to external scopes from the DSDT. 541 * This is because the DSDT is always loaded first, and the 542 * external reference cannot be resolved -- causing a runtime 543 * error because Scope() must be resolved immediately. 544 * 10/2015. 545 */ 546 if ((Node->Flags & ANOBJ_IS_EXTERNAL) && 547 (ACPI_COMPARE_NAME (Gbl_TableSignature, "DSDT"))) 548 { 549 /* However, allowed if the reference is within a method */ 550 551 MethodOp = Op->Asl.Parent; 552 while (MethodOp && 553 (MethodOp->Asl.ParseOpcode != PARSEOP_METHOD)) 554 { 555 MethodOp = MethodOp->Asl.Parent; 556 } 557 558 if (!MethodOp) 559 { 560 /* Not in a control method, error */ 561 562 AslError (ASL_ERROR, ASL_MSG_CROSS_TABLE_SCOPE, Op, NULL); 563 } 564 } 565 } 566 567 /* We found a node with this name, now check the type */ 568 569 switch (Node->Type) 570 { 571 case ACPI_TYPE_LOCAL_SCOPE: 572 case ACPI_TYPE_DEVICE: 573 case ACPI_TYPE_POWER: 574 case ACPI_TYPE_PROCESSOR: 575 case ACPI_TYPE_THERMAL: 576 577 /* These are acceptable types - they all open a new scope */ 578 break; 579 580 case ACPI_TYPE_INTEGER: 581 case ACPI_TYPE_STRING: 582 case ACPI_TYPE_BUFFER: 583 /* 584 * These types we will allow, but we will change the type. 585 * This enables some existing code of the form: 586 * 587 * Name (DEB, 0) 588 * Scope (DEB) { ... } 589 * 590 * Which is used to workaround the fact that the MS interpreter 591 * does not allow Scope() forward references. 592 */ 593 sprintf (MsgBuffer, "%s [%s], changing type to [Scope]", 594 Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type)); 595 AslError (ASL_REMARK, ASL_MSG_SCOPE_TYPE, Op, MsgBuffer); 596 597 /* Switch the type to scope, open the new scope */ 598 599 Node->Type = ACPI_TYPE_LOCAL_SCOPE; 600 Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE, 601 WalkState); 602 if (ACPI_FAILURE (Status)) 603 { 604 return_ACPI_STATUS (Status); 605 } 606 break; 607 608 default: 609 610 /* All other types are an error */ 611 612 sprintf (MsgBuffer, "%s [%s]", Op->Asl.ExternalName, 613 AcpiUtGetTypeName (Node->Type)); 614 AslError (ASL_ERROR, ASL_MSG_SCOPE_TYPE, Op, MsgBuffer); 615 616 /* 617 * However, switch the type to be an actual scope so 618 * that compilation can continue without generating a whole 619 * cascade of additional errors. Open the new scope. 620 */ 621 Node->Type = ACPI_TYPE_LOCAL_SCOPE; 622 Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE, 623 WalkState); 624 if (ACPI_FAILURE (Status)) 625 { 626 return_ACPI_STATUS (Status); 627 } 628 break; 629 } 630 631 Status = AE_OK; 632 goto FinishNode; 633 634 635 default: 636 637 ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); 638 break; 639 } 640 641 642 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Loading name: %s, (%s)\n", 643 Op->Asl.ExternalName, AcpiUtGetTypeName (ObjectType))); 644 645 /* The name must not already exist */ 646 647 Flags |= ACPI_NS_ERROR_IF_FOUND; 648 649 /* 650 * Enter the named type into the internal namespace. We enter the name 651 * as we go downward in the parse tree. Any necessary subobjects that 652 * involve arguments to the opcode must be created as we go back up the 653 * parse tree later. 654 */ 655 Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType, 656 ACPI_IMODE_LOAD_PASS1, Flags, WalkState, &Node); 657 if (ACPI_FAILURE (Status)) 658 { 659 if (Status == AE_ALREADY_EXISTS) 660 { 661 /* The name already exists in this scope */ 662 663 if (Node->Type == ACPI_TYPE_LOCAL_SCOPE) 664 { 665 /* Allow multiple references to the same scope */ 666 667 Node->Type = (UINT8) ObjectType; 668 Status = AE_OK; 669 } 670 else if ((Node->Flags & ANOBJ_IS_EXTERNAL) && 671 (Op->Asl.ParseOpcode != PARSEOP_EXTERNAL)) 672 { 673 /* 674 * Allow one create on an object or segment that was 675 * previously declared External 676 */ 677 Node->Flags &= ~ANOBJ_IS_EXTERNAL; 678 Node->Type = (UINT8) ObjectType; 679 680 /* Just retyped a node, probably will need to open a scope */ 681 682 if (AcpiNsOpensScope (ObjectType)) 683 { 684 Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState); 685 if (ACPI_FAILURE (Status)) 686 { 687 return_ACPI_STATUS (Status); 688 } 689 } 690 691 Status = AE_OK; 692 } 693 else if (!(Node->Flags & ANOBJ_IS_EXTERNAL) && 694 (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL)) 695 { 696 /* 697 * Allow externals in same scope as the definition of the 698 * actual object. Similar to C. Allows multiple definition 699 * blocks that refer to each other in the same file. 700 */ 701 Status = AE_OK; 702 } 703 else 704 { 705 /* Valid error, object already exists */ 706 707 AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Op, 708 Op->Asl.ExternalName); 709 return_ACPI_STATUS (AE_OK); 710 } 711 } 712 else 713 { 714 AslCoreSubsystemError (Op, Status, 715 "Failure from namespace lookup", FALSE); 716 return_ACPI_STATUS (Status); 717 } 718 } 719 720 if (ForceNewScope) 721 { 722 Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState); 723 if (ACPI_FAILURE (Status)) 724 { 725 return_ACPI_STATUS (Status); 726 } 727 } 728 729 FinishNode: 730 /* 731 * Point the parse node to the new namespace node, and point 732 * the Node back to the original Parse node 733 */ 734 Op->Asl.Node = Node; 735 Node->Op = Op; 736 737 /* Set the actual data type if appropriate (EXTERNAL term only) */ 738 739 if (ActualObjectType != ACPI_TYPE_ANY) 740 { 741 Node->Type = (UINT8) ActualObjectType; 742 Node->Value = ASL_EXTERNAL_METHOD; 743 } 744 745 if (Op->Asl.ParseOpcode == PARSEOP_METHOD) 746 { 747 /* 748 * Get the method argument count from "Extra" and save 749 * it in the namespace node 750 */ 751 Node->Value = (UINT32) Op->Asl.Extra; 752 } 753 754 return_ACPI_STATUS (Status); 755 } 756 757 758 /******************************************************************************* 759 * 760 * FUNCTION: LdNamespace2Begin 761 * 762 * PARAMETERS: ASL_WALK_CALLBACK 763 * 764 * RETURN: Status 765 * 766 * DESCRIPTION: Descending callback used during the pass 2 parse tree walk. 767 * Second pass resolves some forward references. 768 * 769 * Notes: 770 * Currently only needs to handle the Alias operator. 771 * Could be used to allow forward references from the Scope() operator, but 772 * the MS interpreter does not allow this, so this compiler does not either. 773 * 774 ******************************************************************************/ 775 776 static ACPI_STATUS 777 LdNamespace2Begin ( 778 ACPI_PARSE_OBJECT *Op, 779 UINT32 Level, 780 void *Context) 781 { 782 ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context; 783 ACPI_STATUS Status; 784 ACPI_NAMESPACE_NODE *Node; 785 ACPI_OBJECT_TYPE ObjectType; 786 BOOLEAN ForceNewScope = FALSE; 787 ACPI_PARSE_OBJECT *Arg; 788 char *Path; 789 ACPI_NAMESPACE_NODE *TargetNode; 790 791 792 ACPI_FUNCTION_NAME (LdNamespace2Begin); 793 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n", 794 Op, Op->Asl.ParseOpName)); 795 796 797 /* Ignore Ops with no namespace node */ 798 799 Node = Op->Asl.Node; 800 if (!Node) 801 { 802 return (AE_OK); 803 } 804 805 /* Get the type to determine if we should push the scope */ 806 807 if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) && 808 (Op->Asl.CompileFlags == NODE_IS_RESOURCE_DESC)) 809 { 810 ObjectType = ACPI_TYPE_LOCAL_RESOURCE; 811 } 812 else 813 { 814 ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); 815 } 816 817 /* Push scope for Resource Templates */ 818 819 if (Op->Asl.ParseOpcode == PARSEOP_NAME) 820 { 821 if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC) 822 { 823 ForceNewScope = TRUE; 824 } 825 } 826 827 /* Push the scope stack */ 828 829 if (ForceNewScope || AcpiNsOpensScope (ObjectType)) 830 { 831 Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState); 832 if (ACPI_FAILURE (Status)) 833 { 834 return_ACPI_STATUS (Status); 835 } 836 } 837 838 if (Op->Asl.ParseOpcode == PARSEOP_ALIAS) 839 { 840 /* Complete the alias node by getting and saving the target node */ 841 842 /* First child is the alias target */ 843 844 Arg = Op->Asl.Child; 845 846 /* Get the target pathname */ 847 848 Path = Arg->Asl.Namepath; 849 if (!Path) 850 { 851 Status = UtInternalizeName (Arg->Asl.ExternalName, &Path); 852 if (ACPI_FAILURE (Status)) 853 { 854 return (Status); 855 } 856 } 857 858 /* Get the NS node associated with the target. It must exist. */ 859 860 Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY, 861 ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, 862 WalkState, &TargetNode); 863 if (ACPI_FAILURE (Status)) 864 { 865 if (Status == AE_NOT_FOUND) 866 { 867 AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op, 868 Op->Asl.ExternalName); 869 870 /* 871 * The name was not found, go ahead and create it. 872 * This prevents more errors later. 873 */ 874 Status = AcpiNsLookup (WalkState->ScopeInfo, Path, 875 ACPI_TYPE_ANY, 876 ACPI_IMODE_LOAD_PASS1, ACPI_NS_NO_UPSEARCH, 877 WalkState, &(Node)); 878 return (AE_OK); 879 } 880 881 AslCoreSubsystemError (Op, Status, 882 "Failure from namespace lookup", FALSE); 883 return (AE_OK); 884 } 885 886 /* Save the target node within the alias node */ 887 888 Node->Object = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, TargetNode); 889 } 890 891 return (AE_OK); 892 } 893 894 895 /******************************************************************************* 896 * 897 * FUNCTION: LdCommonNamespaceEnd 898 * 899 * PARAMETERS: ASL_WALK_CALLBACK 900 * 901 * RETURN: Status 902 * 903 * DESCRIPTION: Ascending callback used during the loading of the namespace, 904 * We only need to worry about managing the scope stack here. 905 * 906 ******************************************************************************/ 907 908 static ACPI_STATUS 909 LdCommonNamespaceEnd ( 910 ACPI_PARSE_OBJECT *Op, 911 UINT32 Level, 912 void *Context) 913 { 914 ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context; 915 ACPI_OBJECT_TYPE ObjectType; 916 BOOLEAN ForceNewScope = FALSE; 917 918 919 ACPI_FUNCTION_NAME (LdCommonNamespaceEnd); 920 921 922 /* We are only interested in opcodes that have an associated name */ 923 924 if (!Op->Asl.Namepath) 925 { 926 return (AE_OK); 927 } 928 929 /* Get the type to determine if we should pop the scope */ 930 931 if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) && 932 (Op->Asl.CompileFlags == NODE_IS_RESOURCE_DESC)) 933 { 934 /* TBD: Merge into AcpiDsMapNamedOpcodeToDataType */ 935 936 ObjectType = ACPI_TYPE_LOCAL_RESOURCE; 937 } 938 else 939 { 940 ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); 941 } 942 943 /* Pop scope that was pushed for Resource Templates */ 944 945 if (Op->Asl.ParseOpcode == PARSEOP_NAME) 946 { 947 if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC) 948 { 949 ForceNewScope = TRUE; 950 } 951 } 952 953 /* Pop the scope stack */ 954 955 if (ForceNewScope || AcpiNsOpensScope (ObjectType)) 956 { 957 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 958 "(%s): Popping scope for Op [%s] %p\n", 959 AcpiUtGetTypeName (ObjectType), Op->Asl.ParseOpName, Op)); 960 961 (void) AcpiDsScopeStackPop (WalkState); 962 } 963 964 return (AE_OK); 965 } 966