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