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