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 <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 /* 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 if ((Node->Flags & ANOBJ_IS_EXTERNAL) && 702 (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL) && 703 (ObjectType == ACPI_TYPE_ANY)) 704 { 705 /* Allow update of externals of unknown type. */ 706 707 if (AcpiNsOpensScope (ActualObjectType)) 708 { 709 Node->Type = (UINT8) ActualObjectType; 710 Status = AE_OK; 711 } 712 else 713 { 714 sprintf (MsgBuffer, "%s [%s]", Op->Asl.ExternalName, 715 AcpiUtGetTypeName (Node->Type)); 716 AslError (ASL_ERROR, ASL_MSG_SCOPE_TYPE, Op, MsgBuffer); 717 return_ACPI_STATUS (AE_OK); 718 } 719 } 720 else 721 { 722 /* Valid error, object already exists */ 723 724 AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Op, 725 Op->Asl.ExternalName); 726 return_ACPI_STATUS (AE_OK); 727 } 728 } 729 else 730 { 731 AslCoreSubsystemError (Op, Status, 732 "Failure from namespace lookup", FALSE); 733 return_ACPI_STATUS (Status); 734 } 735 } 736 737 if (ForceNewScope) 738 { 739 Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState); 740 if (ACPI_FAILURE (Status)) 741 { 742 return_ACPI_STATUS (Status); 743 } 744 } 745 746 FinishNode: 747 /* 748 * Point the parse node to the new namespace node, and point 749 * the Node back to the original Parse node 750 */ 751 Op->Asl.Node = Node; 752 Node->Op = Op; 753 754 /* Set the actual data type if appropriate (EXTERNAL term only) */ 755 756 if (ActualObjectType != ACPI_TYPE_ANY) 757 { 758 Node->Type = (UINT8) ActualObjectType; 759 Node->Value = ASL_EXTERNAL_METHOD; 760 } 761 762 if (Op->Asl.ParseOpcode == PARSEOP_METHOD) 763 { 764 /* 765 * Get the method argument count from "Extra" and save 766 * it in the namespace node 767 */ 768 Node->Value = (UINT32) Op->Asl.Extra; 769 } 770 771 return_ACPI_STATUS (Status); 772 } 773 774 775 /******************************************************************************* 776 * 777 * FUNCTION: LdNamespace2Begin 778 * 779 * PARAMETERS: ASL_WALK_CALLBACK 780 * 781 * RETURN: Status 782 * 783 * DESCRIPTION: Descending callback used during the pass 2 parse tree walk. 784 * Second pass resolves some forward references. 785 * 786 * Notes: 787 * Currently only needs to handle the Alias operator. 788 * Could be used to allow forward references from the Scope() operator, but 789 * the MS interpreter does not allow this, so this compiler does not either. 790 * 791 ******************************************************************************/ 792 793 static ACPI_STATUS 794 LdNamespace2Begin ( 795 ACPI_PARSE_OBJECT *Op, 796 UINT32 Level, 797 void *Context) 798 { 799 ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context; 800 ACPI_STATUS Status; 801 ACPI_NAMESPACE_NODE *Node; 802 ACPI_OBJECT_TYPE ObjectType; 803 BOOLEAN ForceNewScope = FALSE; 804 ACPI_PARSE_OBJECT *Arg; 805 char *Path; 806 ACPI_NAMESPACE_NODE *TargetNode; 807 808 809 ACPI_FUNCTION_NAME (LdNamespace2Begin); 810 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n", 811 Op, Op->Asl.ParseOpName)); 812 813 814 /* Ignore Ops with no namespace node */ 815 816 Node = Op->Asl.Node; 817 if (!Node) 818 { 819 return (AE_OK); 820 } 821 822 /* Get the type to determine if we should push the scope */ 823 824 if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) && 825 (Op->Asl.CompileFlags == NODE_IS_RESOURCE_DESC)) 826 { 827 ObjectType = ACPI_TYPE_LOCAL_RESOURCE; 828 } 829 else 830 { 831 ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); 832 } 833 834 /* Push scope for Resource Templates */ 835 836 if (Op->Asl.ParseOpcode == PARSEOP_NAME) 837 { 838 if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC) 839 { 840 ForceNewScope = TRUE; 841 } 842 } 843 844 /* Push the scope stack */ 845 846 if (ForceNewScope || AcpiNsOpensScope (ObjectType)) 847 { 848 Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState); 849 if (ACPI_FAILURE (Status)) 850 { 851 return_ACPI_STATUS (Status); 852 } 853 } 854 855 if (Op->Asl.ParseOpcode == PARSEOP_ALIAS) 856 { 857 /* Complete the alias node by getting and saving the target node */ 858 859 /* First child is the alias target */ 860 861 Arg = Op->Asl.Child; 862 863 /* Get the target pathname */ 864 865 Path = Arg->Asl.Namepath; 866 if (!Path) 867 { 868 Status = UtInternalizeName (Arg->Asl.ExternalName, &Path); 869 if (ACPI_FAILURE (Status)) 870 { 871 return (Status); 872 } 873 } 874 875 /* Get the NS node associated with the target. It must exist. */ 876 877 Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY, 878 ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, 879 WalkState, &TargetNode); 880 if (ACPI_FAILURE (Status)) 881 { 882 if (Status == AE_NOT_FOUND) 883 { 884 AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op, 885 Op->Asl.ExternalName); 886 887 /* 888 * The name was not found, go ahead and create it. 889 * This prevents more errors later. 890 */ 891 Status = AcpiNsLookup (WalkState->ScopeInfo, Path, 892 ACPI_TYPE_ANY, 893 ACPI_IMODE_LOAD_PASS1, ACPI_NS_NO_UPSEARCH, 894 WalkState, &(Node)); 895 return (AE_OK); 896 } 897 898 AslCoreSubsystemError (Op, Status, 899 "Failure from namespace lookup", FALSE); 900 return (AE_OK); 901 } 902 903 /* Save the target node within the alias node */ 904 905 Node->Object = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, TargetNode); 906 } 907 908 return (AE_OK); 909 } 910 911 912 /******************************************************************************* 913 * 914 * FUNCTION: LdCommonNamespaceEnd 915 * 916 * PARAMETERS: ASL_WALK_CALLBACK 917 * 918 * RETURN: Status 919 * 920 * DESCRIPTION: Ascending callback used during the loading of the namespace, 921 * We only need to worry about managing the scope stack here. 922 * 923 ******************************************************************************/ 924 925 static ACPI_STATUS 926 LdCommonNamespaceEnd ( 927 ACPI_PARSE_OBJECT *Op, 928 UINT32 Level, 929 void *Context) 930 { 931 ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context; 932 ACPI_OBJECT_TYPE ObjectType; 933 BOOLEAN ForceNewScope = FALSE; 934 935 936 ACPI_FUNCTION_NAME (LdCommonNamespaceEnd); 937 938 939 /* We are only interested in opcodes that have an associated name */ 940 941 if (!Op->Asl.Namepath) 942 { 943 return (AE_OK); 944 } 945 946 /* Get the type to determine if we should pop the scope */ 947 948 if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) && 949 (Op->Asl.CompileFlags == NODE_IS_RESOURCE_DESC)) 950 { 951 /* TBD: Merge into AcpiDsMapNamedOpcodeToDataType */ 952 953 ObjectType = ACPI_TYPE_LOCAL_RESOURCE; 954 } 955 else 956 { 957 ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); 958 } 959 960 /* Pop scope that was pushed for Resource Templates */ 961 962 if (Op->Asl.ParseOpcode == PARSEOP_NAME) 963 { 964 if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC) 965 { 966 ForceNewScope = TRUE; 967 } 968 } 969 970 /* Pop the scope stack */ 971 972 if (ForceNewScope || AcpiNsOpensScope (ObjectType)) 973 { 974 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 975 "(%s): Popping scope for Op [%s] %p\n", 976 AcpiUtGetTypeName (ObjectType), Op->Asl.ParseOpName, Op)); 977 978 (void) AcpiDsScopeStackPop (WalkState); 979 } 980 981 return (AE_OK); 982 } 983