1 /****************************************************************************** 2 * 3 * Module Name: dswload - Dispatcher namespace load callbacks 4 * 5 *****************************************************************************/ 6 7 /****************************************************************************** 8 * 9 * 1. Copyright Notice 10 * 11 * Some or all of this work - Copyright (c) 1999 - 2020, Intel Corp. 12 * All rights reserved. 13 * 14 * 2. License 15 * 16 * 2.1. This is your license from Intel Corp. under its intellectual property 17 * rights. You may have additional license terms from the party that provided 18 * you this software, covering your right to use that party's intellectual 19 * property rights. 20 * 21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 22 * copy of the source code appearing in this file ("Covered Code") an 23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 24 * base code distributed originally by Intel ("Original Intel Code") to copy, 25 * make derivatives, distribute, use and display any portion of the Covered 26 * Code in any form, with the right to sublicense such rights; and 27 * 28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 29 * license (with the right to sublicense), under only those claims of Intel 30 * patents that are infringed by the Original Intel Code, to make, use, sell, 31 * offer to sell, and import the Covered Code and derivative works thereof 32 * solely to the minimum extent necessary to exercise the above copyright 33 * license, and in no event shall the patent license extend to any additions 34 * to or modifications of the Original Intel Code. No other license or right 35 * is granted directly or by implication, estoppel or otherwise; 36 * 37 * The above copyright and patent license is granted only if the following 38 * conditions are met: 39 * 40 * 3. Conditions 41 * 42 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43 * Redistribution of source code of any substantial portion of the Covered 44 * Code or modification with rights to further distribute source must include 45 * the above Copyright Notice, the above License, this list of Conditions, 46 * and the following Disclaimer and Export Compliance provision. In addition, 47 * Licensee must cause all Covered Code to which Licensee contributes to 48 * contain a file documenting the changes Licensee made to create that Covered 49 * Code and the date of any change. Licensee must include in that file the 50 * documentation of any changes made by any predecessor Licensee. Licensee 51 * must include a prominent statement that the modification is derived, 52 * directly or indirectly, from Original Intel Code. 53 * 54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 55 * Redistribution of source code of any substantial portion of the Covered 56 * Code or modification without rights to further distribute source must 57 * include the following Disclaimer and Export Compliance provision in the 58 * documentation and/or other materials provided with distribution. In 59 * addition, Licensee may not authorize further sublicense of source of any 60 * portion of the Covered Code, and must include terms to the effect that the 61 * license from Licensee to its licensee is limited to the intellectual 62 * property embodied in the software Licensee provides to its licensee, and 63 * not to intellectual property embodied in modifications its licensee may 64 * make. 65 * 66 * 3.3. Redistribution of Executable. Redistribution in executable form of any 67 * substantial portion of the Covered Code or modification must reproduce the 68 * above Copyright Notice, and the following Disclaimer and Export Compliance 69 * provision in the documentation and/or other materials provided with the 70 * distribution. 71 * 72 * 3.4. Intel retains all right, title, and interest in and to the Original 73 * Intel Code. 74 * 75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 76 * Intel shall be used in advertising or otherwise to promote the sale, use or 77 * other dealings in products derived from or relating to the Covered Code 78 * without prior written authorization from Intel. 79 * 80 * 4. Disclaimer and Export Compliance 81 * 82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 83 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 85 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 86 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 88 * PARTICULAR PURPOSE. 89 * 90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 97 * LIMITED REMEDY. 98 * 99 * 4.3. Licensee shall not export, either directly or indirectly, any of this 100 * software or system incorporating such software without first obtaining any 101 * required license or other approval from the U. S. Department of Commerce or 102 * any other agency or department of the United States Government. In the 103 * event Licensee exports any such software from the United States or 104 * re-exports any such software from a foreign destination, Licensee shall 105 * ensure that the distribution and export/re-export of the software is in 106 * compliance with all laws, regulations, orders, or other restrictions of the 107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 108 * any of its subsidiaries will export/re-export any technical data, process, 109 * software, or service, directly or indirectly, to any country for which the 110 * United States government or any agency thereof requires an export license, 111 * other governmental approval, or letter of assurance, without first obtaining 112 * such license, approval or letter. 113 * 114 ***************************************************************************** 115 * 116 * Alternatively, you may choose to be licensed under the terms of the 117 * following license: 118 * 119 * Redistribution and use in source and binary forms, with or without 120 * modification, are permitted provided that the following conditions 121 * are met: 122 * 1. Redistributions of source code must retain the above copyright 123 * notice, this list of conditions, and the following disclaimer, 124 * without modification. 125 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 126 * substantially similar to the "NO WARRANTY" disclaimer below 127 * ("Disclaimer") and any redistribution must be conditioned upon 128 * including a substantially similar Disclaimer requirement for further 129 * binary redistribution. 130 * 3. Neither the names of the above-listed copyright holders nor the names 131 * of any contributors may be used to endorse or promote products derived 132 * from this software without specific prior written permission. 133 * 134 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 135 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 136 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 137 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 138 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 139 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 140 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 141 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 142 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 143 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 144 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 145 * 146 * Alternatively, you may choose to be licensed under the terms of the 147 * GNU General Public License ("GPL") version 2 as published by the Free 148 * Software Foundation. 149 * 150 *****************************************************************************/ 151 152 #include <contrib/dev/acpica/compiler/aslcompiler.h> 153 #include <contrib/dev/acpica/include/amlcode.h> 154 #include <contrib/dev/acpica/include/acdispat.h> 155 #include <contrib/dev/acpica/include/acnamesp.h> 156 #include <contrib/dev/acpica/include/acparser.h> 157 #include "aslcompiler.y.h" 158 159 160 #define _COMPONENT ACPI_COMPILER 161 ACPI_MODULE_NAME ("aslload") 162 163 /* Local prototypes */ 164 165 static ACPI_STATUS 166 LdLoadFieldElements ( 167 UINT32 AmlType, 168 ACPI_PARSE_OBJECT *Op, 169 ACPI_WALK_STATE *WalkState); 170 171 static ACPI_STATUS 172 LdLoadResourceElements ( 173 ACPI_PARSE_OBJECT *Op, 174 ACPI_WALK_STATE *WalkState); 175 176 static ACPI_STATUS 177 LdNamespace1Begin ( 178 ACPI_PARSE_OBJECT *Op, 179 UINT32 Level, 180 void *Context); 181 182 static ACPI_STATUS 183 LdNamespace2Begin ( 184 ACPI_PARSE_OBJECT *Op, 185 UINT32 Level, 186 void *Context); 187 188 static ACPI_STATUS 189 LdCommonNamespaceEnd ( 190 ACPI_PARSE_OBJECT *Op, 191 UINT32 Level, 192 void *Context); 193 194 static void 195 LdCheckSpecialNames ( 196 ACPI_NAMESPACE_NODE *Node, 197 ACPI_PARSE_OBJECT *Op); 198 199 /******************************************************************************* 200 * 201 * FUNCTION: LdLoadNamespace 202 * 203 * PARAMETERS: RootOp - Root of the parse tree 204 * 205 * RETURN: Status 206 * 207 * DESCRIPTION: Perform a walk of the parse tree that in turn loads all of the 208 * named ASL/AML objects into the namespace. The namespace is 209 * constructed in order to resolve named references and references 210 * to named fields within resource templates/descriptors. 211 * 212 ******************************************************************************/ 213 214 ACPI_STATUS 215 LdLoadNamespace ( 216 ACPI_PARSE_OBJECT *RootOp) 217 { 218 ACPI_WALK_STATE *WalkState; 219 220 221 /* Create a new walk state */ 222 223 WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL); 224 if (!WalkState) 225 { 226 return (AE_NO_MEMORY); 227 } 228 229 /* Walk the entire parse tree, first pass */ 230 231 TrWalkParseTree (RootOp, ASL_WALK_VISIT_TWICE, LdNamespace1Begin, 232 LdCommonNamespaceEnd, WalkState); 233 234 /* Second pass to handle forward references */ 235 236 TrWalkParseTree (RootOp, ASL_WALK_VISIT_TWICE, LdNamespace2Begin, 237 LdCommonNamespaceEnd, WalkState); 238 239 /* Dump the namespace if debug is enabled */ 240 241 if (AcpiDbgLevel & ACPI_LV_TABLES) 242 { 243 AcpiNsDumpTables (ACPI_NS_ALL, ACPI_UINT32_MAX); 244 } 245 246 ACPI_FREE (WalkState); 247 return (AE_OK); 248 } 249 250 251 /******************************************************************************* 252 * 253 * FUNCTION: LdLoadFieldElements 254 * 255 * PARAMETERS: AmlType - Type to search 256 * Op - Parent node (Field) 257 * WalkState - Current walk state 258 * 259 * RETURN: Status 260 * 261 * DESCRIPTION: Enter the named elements of the field (children of the parent) 262 * into the namespace. 263 * 264 ******************************************************************************/ 265 266 static ACPI_STATUS 267 LdLoadFieldElements ( 268 UINT32 AmlType, 269 ACPI_PARSE_OBJECT *Op, 270 ACPI_WALK_STATE *WalkState) 271 { 272 ACPI_PARSE_OBJECT *Child = NULL; 273 ACPI_PARSE_OBJECT *SourceRegion; 274 ACPI_NAMESPACE_NODE *Node; 275 ACPI_STATUS Status; 276 char *ExternalPath; 277 278 279 SourceRegion = UtGetArg (Op, 0); 280 if (SourceRegion) 281 { 282 Status = AcpiNsLookup (WalkState->ScopeInfo, 283 SourceRegion->Asl.Value.String, AmlType, ACPI_IMODE_EXECUTE, 284 ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL, &Node); 285 if (Status == AE_NOT_FOUND) 286 { 287 /* 288 * If the named object is not found, it means that it is either a 289 * forward reference or the named object does not exist. 290 */ 291 SourceRegion->Asl.CompileFlags |= OP_NOT_FOUND_DURING_LOAD; 292 } 293 } 294 295 /* Get the first named field element */ 296 297 switch (Op->Asl.AmlOpcode) 298 { 299 case AML_BANK_FIELD_OP: 300 301 Child = UtGetArg (Op, 6); 302 break; 303 304 case AML_INDEX_FIELD_OP: 305 306 Child = UtGetArg (Op, 5); 307 break; 308 309 case AML_FIELD_OP: 310 311 Child = UtGetArg (Op, 4); 312 break; 313 314 default: 315 316 /* No other opcodes should arrive here */ 317 318 return (AE_BAD_PARAMETER); 319 } 320 321 /* Enter all elements into the namespace */ 322 323 while (Child) 324 { 325 switch (Child->Asl.AmlOpcode) 326 { 327 case AML_INT_RESERVEDFIELD_OP: 328 case AML_INT_ACCESSFIELD_OP: 329 case AML_INT_CONNECTION_OP: 330 break; 331 332 default: 333 334 Status = AcpiNsLookup (WalkState->ScopeInfo, 335 Child->Asl.Value.String, 336 ACPI_TYPE_LOCAL_REGION_FIELD, 337 ACPI_IMODE_LOAD_PASS1, 338 ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | 339 ACPI_NS_ERROR_IF_FOUND, NULL, &Node); 340 if (ACPI_FAILURE (Status)) 341 { 342 if (Status != AE_ALREADY_EXISTS) 343 { 344 AslError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION, Child, 345 Child->Asl.Value.String); 346 return (Status); 347 } 348 else if (Status == AE_ALREADY_EXISTS && 349 (Node->Flags & ANOBJ_IS_EXTERNAL)) 350 { 351 Node->Type = (UINT8) ACPI_TYPE_LOCAL_REGION_FIELD; 352 Node->Flags &= ~ANOBJ_IS_EXTERNAL; 353 } 354 else 355 { 356 /* 357 * The name already exists in this scope 358 * But continue processing the elements 359 */ 360 ExternalPath = AcpiNsGetNormalizedPathname (Node, TRUE); 361 362 AslDualParseOpError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Child, 363 ExternalPath, ASL_MSG_FOUND_HERE, Node->Op, 364 ExternalPath); 365 366 if (ExternalPath) 367 { 368 ACPI_FREE (ExternalPath); 369 } 370 } 371 } 372 else 373 { 374 Child->Asl.Node = Node; 375 Node->Op = Child; 376 } 377 break; 378 } 379 380 Child = Child->Asl.Next; 381 } 382 383 return (AE_OK); 384 } 385 386 387 /******************************************************************************* 388 * 389 * FUNCTION: LdLoadResourceElements 390 * 391 * PARAMETERS: Op - Parent node (Resource Descriptor) 392 * WalkState - Current walk state 393 * 394 * RETURN: Status 395 * 396 * DESCRIPTION: Enter the named elements of the resource descriptor (children 397 * of the parent) into the namespace. 398 * 399 * NOTE: In the real AML namespace, these named elements never exist. But 400 * we simply use the namespace here as a symbol table so we can look 401 * them up as they are referenced. 402 * 403 ******************************************************************************/ 404 405 static ACPI_STATUS 406 LdLoadResourceElements ( 407 ACPI_PARSE_OBJECT *Op, 408 ACPI_WALK_STATE *WalkState) 409 { 410 ACPI_PARSE_OBJECT *InitializerOp = NULL; 411 ACPI_NAMESPACE_NODE *Node; 412 ACPI_STATUS Status; 413 char *ExternalPath; 414 415 416 /* 417 * Enter the resource name into the namespace. Name must not already exist. 418 * This opens a scope, so later field names are guaranteed to be new/unique. 419 */ 420 Status = AcpiNsLookup (WalkState->ScopeInfo, Op->Asl.Namepath, 421 ACPI_TYPE_LOCAL_RESOURCE, ACPI_IMODE_LOAD_PASS1, 422 ACPI_NS_NO_UPSEARCH | ACPI_NS_ERROR_IF_FOUND, 423 WalkState, &Node); 424 if (ACPI_FAILURE (Status)) 425 { 426 if (Status == AE_ALREADY_EXISTS) 427 { 428 /* Actual node causing the error was saved in ParentMethod */ 429 430 ExternalPath = AcpiNsGetNormalizedPathname (Node, TRUE); 431 432 AslDualParseOpError (ASL_ERROR, ASL_MSG_NAME_EXISTS, 433 (ACPI_PARSE_OBJECT *) Op->Asl.ParentMethod, 434 ExternalPath, ASL_MSG_FOUND_HERE, Node->Op, 435 ExternalPath); 436 437 if (ExternalPath) 438 { 439 ACPI_FREE (ExternalPath); 440 } 441 return (AE_OK); 442 } 443 return (Status); 444 } 445 446 Node->Value = (UINT32) Op->Asl.Value.Integer; 447 Node->Op = Op; 448 Op->Asl.Node = Node; 449 450 /* 451 * Now enter the predefined fields, for easy lookup when referenced 452 * by the source ASL 453 */ 454 InitializerOp = ASL_GET_CHILD_NODE (Op); 455 while (InitializerOp) 456 { 457 if (InitializerOp->Asl.ExternalName) 458 { 459 Status = AcpiNsLookup (WalkState->ScopeInfo, 460 InitializerOp->Asl.ExternalName, 461 ACPI_TYPE_LOCAL_RESOURCE_FIELD, ACPI_IMODE_LOAD_PASS1, 462 ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE, NULL, &Node); 463 if (ACPI_FAILURE (Status)) 464 { 465 return (Status); 466 } 467 468 /* 469 * Store the field offset and length in the namespace node 470 * so it can be used when the field is referenced 471 */ 472 Node->Value = InitializerOp->Asl.Value.Tag.BitOffset; 473 Node->Length = InitializerOp->Asl.Value.Tag.BitLength; 474 InitializerOp->Asl.Node = Node; 475 Node->Op = InitializerOp; 476 } 477 478 InitializerOp = ASL_GET_PEER_NODE (InitializerOp); 479 } 480 481 return (AE_OK); 482 } 483 484 485 /******************************************************************************* 486 * 487 * FUNCTION: LdNamespace1Begin 488 * 489 * PARAMETERS: ASL_WALK_CALLBACK 490 * 491 * RETURN: Status 492 * 493 * DESCRIPTION: Descending callback used during the parse tree walk. If this 494 * is a named AML opcode, enter into the namespace 495 * 496 ******************************************************************************/ 497 498 static ACPI_STATUS 499 LdNamespace1Begin ( 500 ACPI_PARSE_OBJECT *Op, 501 UINT32 Level, 502 void *Context) 503 { 504 ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context; 505 ACPI_NAMESPACE_NODE *Node; 506 ACPI_PARSE_OBJECT *MethodOp; 507 ACPI_STATUS Status; 508 ACPI_OBJECT_TYPE ObjectType; 509 ACPI_OBJECT_TYPE ActualObjectType = ACPI_TYPE_ANY; 510 char *Path; 511 UINT32 Flags = ACPI_NS_NO_UPSEARCH; 512 ACPI_PARSE_OBJECT *Arg; 513 UINT32 i; 514 BOOLEAN ForceNewScope = FALSE; 515 const ACPI_OPCODE_INFO *OpInfo; 516 ACPI_PARSE_OBJECT *ParentOp; 517 char *ExternalPath; 518 519 520 ACPI_FUNCTION_NAME (LdNamespace1Begin); 521 522 523 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n", 524 Op, Op->Asl.ParseOpName)); 525 526 /* 527 * We are only interested in opcodes that have an associated name 528 * (or multiple names) 529 */ 530 switch (Op->Asl.AmlOpcode) 531 { 532 case AML_INDEX_FIELD_OP: 533 534 Status = LdLoadFieldElements (ACPI_TYPE_LOCAL_REGION_FIELD, Op, WalkState); 535 return (Status); 536 537 case AML_BANK_FIELD_OP: 538 case AML_FIELD_OP: 539 540 Status = LdLoadFieldElements (ACPI_TYPE_REGION, Op, WalkState); 541 return (Status); 542 543 case AML_INT_CONNECTION_OP: 544 545 if (Op->Asl.Child->Asl.AmlOpcode != AML_INT_NAMEPATH_OP) 546 { 547 break; 548 } 549 550 Arg = Op->Asl.Child; 551 Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Asl.ExternalName, 552 ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, 553 WalkState, &Node); 554 if (ACPI_FAILURE (Status)) 555 { 556 break; 557 } 558 559 break; 560 561 default: 562 563 /* All other opcodes go below */ 564 565 break; 566 } 567 568 /* Check if this object has already been installed in the namespace */ 569 570 if (Op->Asl.Node) 571 { 572 return (AE_OK); 573 } 574 575 /* Check for a possible illegal forward reference */ 576 577 if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG) || 578 (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING)) 579 { 580 /* 581 * Op->Asl.Namepath will be NULL for these opcodes. 582 * These opcodes are guaranteed to have a parent. 583 * Examine the parent opcode. 584 */ 585 ParentOp = Op->Asl.Parent; 586 OpInfo = AcpiPsGetOpcodeInfo (ParentOp->Asl.AmlOpcode); 587 588 /* 589 * Exclude all operators that actually declare a new name: 590 * Name (ABCD, 1) -> Ignore (AML_CLASS_NAMED_OBJECT) 591 * We only want references to named objects: 592 * Store (2, WXYZ) -> Attempt to resolve the name 593 */ 594 if (OpInfo->Class == AML_CLASS_NAMED_OBJECT) 595 { 596 return (AE_OK); 597 } 598 599 /* 600 * Check if the referenced object exists at this point during 601 * the load: 602 * 1) If it exists, then this cannot be a forward reference. 603 * 2) If it does not exist, it could be a forward reference or 604 * it truly does not exist (and no external declaration). 605 */ 606 Status = AcpiNsLookup (WalkState->ScopeInfo, 607 Op->Asl.Value.Name, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, 608 ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, 609 WalkState, &Node); 610 if (Status == AE_NOT_FOUND) 611 { 612 /* 613 * This is either a forward reference or the object truly 614 * does not exist. The two cases can only be differentiated 615 * during the cross-reference stage later. Mark the Op/Name 616 * as not-found for now to indicate the need for further 617 * processing. 618 * 619 * Special case: Allow forward references from elements of 620 * Package objects. This provides compatibility with other 621 * ACPI implementations. To correctly implement this, the 622 * ACPICA table load defers package resolution until the entire 623 * namespace has been loaded. 624 */ 625 if ((ParentOp->Asl.ParseOpcode != PARSEOP_PACKAGE) && 626 (ParentOp->Asl.ParseOpcode != PARSEOP_VAR_PACKAGE)) 627 { 628 Op->Asl.CompileFlags |= OP_NOT_FOUND_DURING_LOAD; 629 } 630 631 return (AE_OK); 632 } 633 634 return (Status); 635 } 636 637 Path = Op->Asl.Namepath; 638 if (!Path) 639 { 640 return (AE_OK); 641 } 642 643 /* Map the raw opcode into an internal object type */ 644 645 switch (Op->Asl.ParseOpcode) 646 { 647 case PARSEOP_NAME: 648 649 Arg = Op->Asl.Child; /* Get the NameSeg/NameString node */ 650 Arg = Arg->Asl.Next; /* First peer is the object to be associated with the name */ 651 652 /* 653 * If this name refers to a ResourceTemplate, we will need to open 654 * a new scope so that the resource subfield names can be entered into 655 * the namespace underneath this name 656 */ 657 if (Op->Asl.CompileFlags & OP_IS_RESOURCE_DESC) 658 { 659 ForceNewScope = TRUE; 660 } 661 662 /* Get the data type associated with the named object, not the name itself */ 663 664 /* Log2 loop to convert from Btype (binary) to Etype (encoded) */ 665 666 ObjectType = 1; 667 for (i = 1; i < Arg->Asl.AcpiBtype; i *= 2) 668 { 669 ObjectType++; 670 } 671 break; 672 673 case PARSEOP_EXTERNAL: 674 /* 675 * "External" simply enters a name and type into the namespace. 676 * We must be careful to not open a new scope, however, no matter 677 * what type the external name refers to (e.g., a method) 678 * 679 * first child is name, next child is ObjectType 680 */ 681 ActualObjectType = (UINT8) Op->Asl.Child->Asl.Next->Asl.Value.Integer; 682 ObjectType = ACPI_TYPE_ANY; 683 684 /* 685 * We will mark every new node along the path as "External". This 686 * allows some or all of the nodes to be created later in the ASL 687 * code. Handles cases like this: 688 * 689 * External (\_SB_.PCI0.ABCD, IntObj) 690 * Scope (_SB_) 691 * { 692 * Device (PCI0) 693 * { 694 * } 695 * } 696 * Method (X) 697 * { 698 * Store (\_SB_.PCI0.ABCD, Local0) 699 * } 700 */ 701 Flags |= ACPI_NS_EXTERNAL; 702 break; 703 704 case PARSEOP_DEFAULT_ARG: 705 706 if (Op->Asl.CompileFlags == OP_IS_RESOURCE_DESC) 707 { 708 Status = LdLoadResourceElements (Op, WalkState); 709 return_ACPI_STATUS (Status); 710 } 711 712 ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); 713 break; 714 715 case PARSEOP_SCOPE: 716 /* 717 * The name referenced by Scope(Name) must already exist at this point. 718 * In other words, forward references for Scope() are not supported. 719 * The only real reason for this is that the MS interpreter cannot 720 * handle this case. Perhaps someday this case can go away. 721 */ 722 Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY, 723 ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, WalkState, &Node); 724 if (ACPI_FAILURE (Status)) 725 { 726 if (Status == AE_NOT_FOUND) 727 { 728 /* The name was not found, go ahead and create it */ 729 730 Status = AcpiNsLookup (WalkState->ScopeInfo, Path, 731 ACPI_TYPE_LOCAL_SCOPE, ACPI_IMODE_LOAD_PASS1, 732 Flags, WalkState, &Node); 733 if (ACPI_FAILURE (Status)) 734 { 735 return_ACPI_STATUS (Status); 736 } 737 738 /* However, this is an error -- operand to Scope must exist */ 739 740 if (strlen (Op->Asl.ExternalName) == ACPI_NAMESEG_SIZE) 741 { 742 AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op, 743 Op->Asl.ExternalName); 744 } 745 else 746 { 747 AslError (ASL_ERROR, ASL_MSG_NAMEPATH_NOT_EXIST, Op, 748 Op->Asl.ExternalName); 749 } 750 751 goto FinishNode; 752 } 753 754 AslCoreSubsystemError (Op, Status, 755 "Failure from namespace lookup", FALSE); 756 757 return_ACPI_STATUS (Status); 758 } 759 else /* Status AE_OK */ 760 { 761 /* 762 * Do not allow references to external scopes from the DSDT. 763 * This is because the DSDT is always loaded first, and the 764 * external reference cannot be resolved -- causing a runtime 765 * error because Scope() must be resolved immediately. 766 * 10/2015. 767 */ 768 if ((Node->Flags & ANOBJ_IS_EXTERNAL) && 769 (ACPI_COMPARE_NAMESEG (AslGbl_TableSignature, "DSDT"))) 770 { 771 /* However, allowed if the reference is within a method */ 772 773 MethodOp = Op->Asl.Parent; 774 while (MethodOp && 775 (MethodOp->Asl.ParseOpcode != PARSEOP_METHOD)) 776 { 777 MethodOp = MethodOp->Asl.Parent; 778 } 779 780 if (!MethodOp) 781 { 782 /* Not in a control method, error */ 783 784 AslError (ASL_ERROR, ASL_MSG_CROSS_TABLE_SCOPE, Op, NULL); 785 } 786 } 787 } 788 789 /* We found a node with this name, now check the type */ 790 791 switch (Node->Type) 792 { 793 case ACPI_TYPE_LOCAL_SCOPE: 794 case ACPI_TYPE_DEVICE: 795 case ACPI_TYPE_POWER: 796 case ACPI_TYPE_PROCESSOR: 797 case ACPI_TYPE_THERMAL: 798 799 /* These are acceptable types - they all open a new scope */ 800 break; 801 802 case ACPI_TYPE_INTEGER: 803 case ACPI_TYPE_STRING: 804 case ACPI_TYPE_BUFFER: 805 /* 806 * These types we will allow, but we will change the type. 807 * This enables some existing code of the form: 808 * 809 * Name (DEB, 0) 810 * Scope (DEB) { ... } 811 * 812 * Which is used to workaround the fact that the MS interpreter 813 * does not allow Scope() forward references. 814 */ 815 sprintf (AslGbl_MsgBuffer, "%s [%s], changing type to [Scope]", 816 Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type)); 817 AslError (ASL_REMARK, ASL_MSG_SCOPE_TYPE, Op, AslGbl_MsgBuffer); 818 819 /* Switch the type to scope, open the new scope */ 820 821 Node->Type = ACPI_TYPE_LOCAL_SCOPE; 822 Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE, 823 WalkState); 824 if (ACPI_FAILURE (Status)) 825 { 826 return_ACPI_STATUS (Status); 827 } 828 break; 829 830 default: 831 832 /* All other types are an error */ 833 834 sprintf (AslGbl_MsgBuffer, "%s [%s]", Op->Asl.ExternalName, 835 AcpiUtGetTypeName (Node->Type)); 836 AslError (ASL_ERROR, ASL_MSG_SCOPE_TYPE, Op, AslGbl_MsgBuffer); 837 838 /* 839 * However, switch the type to be an actual scope so 840 * that compilation can continue without generating a whole 841 * cascade of additional errors. Open the new scope. 842 */ 843 Node->Type = ACPI_TYPE_LOCAL_SCOPE; 844 Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE, 845 WalkState); 846 if (ACPI_FAILURE (Status)) 847 { 848 return_ACPI_STATUS (Status); 849 } 850 break; 851 } 852 853 Status = AE_OK; 854 goto FinishNode; 855 856 default: 857 858 ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); 859 break; 860 } 861 862 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Loading name: %s, (%s)\n", 863 Op->Asl.ExternalName, AcpiUtGetTypeName (ObjectType))); 864 865 /* The name must not already exist */ 866 867 Flags |= ACPI_NS_ERROR_IF_FOUND; 868 869 /* 870 * For opcodes that enter new names into the namespace, 871 * all prefix NameSegs must exist. 872 */ 873 WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode); 874 if (((WalkState->OpInfo->Flags & AML_NAMED) || 875 (WalkState->OpInfo->Flags & AML_CREATE)) && 876 (Op->Asl.AmlOpcode != AML_EXTERNAL_OP)) 877 { 878 Flags |= ACPI_NS_PREFIX_MUST_EXIST; 879 } 880 881 /* 882 * Enter the named type into the internal namespace. We enter the name 883 * as we go downward in the parse tree. Any necessary subobjects that 884 * involve arguments to the opcode must be created as we go back up the 885 * parse tree later. 886 */ 887 Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType, 888 ACPI_IMODE_LOAD_PASS1, Flags, WalkState, &Node); 889 if (ACPI_FAILURE (Status)) 890 { 891 if (Status == AE_ALREADY_EXISTS) 892 { 893 /* The name already exists in this scope */ 894 895 if (Node->Type == ACPI_TYPE_LOCAL_SCOPE) 896 { 897 /* Allow multiple references to the same scope */ 898 899 Node->Type = (UINT8) ObjectType; 900 Status = AE_OK; 901 } 902 else if ((Node->Flags & ANOBJ_IS_EXTERNAL) && 903 (Op->Asl.ParseOpcode != PARSEOP_EXTERNAL)) 904 { 905 /* 906 * Allow one create on an object or segment that was 907 * previously declared External 908 */ 909 Node->Flags &= ~ANOBJ_IS_EXTERNAL; 910 Node->Type = (UINT8) ObjectType; 911 912 /* Just retyped a node, probably will need to open a scope */ 913 914 if (AcpiNsOpensScope (ObjectType)) 915 { 916 Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState); 917 if (ACPI_FAILURE (Status)) 918 { 919 return_ACPI_STATUS (Status); 920 } 921 } 922 923 Status = AE_OK; 924 } 925 else if (!(Node->Flags & ANOBJ_IS_EXTERNAL) && 926 (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL)) 927 { 928 /* 929 * Allow externals in same scope as the definition of the 930 * actual object. Similar to C. Allows multiple definition 931 * blocks that refer to each other in the same file. 932 */ 933 Status = AE_OK; 934 } 935 else if ((Node->Flags & ANOBJ_IS_EXTERNAL) && 936 (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL) && 937 (ObjectType == ACPI_TYPE_ANY)) 938 { 939 /* Allow update of externals of unknown type. */ 940 941 if (AcpiNsOpensScope (ActualObjectType)) 942 { 943 Node->Type = (UINT8) ActualObjectType; 944 Status = AE_OK; 945 } 946 else 947 { 948 sprintf (AslGbl_MsgBuffer, "%s [%s]", Op->Asl.ExternalName, 949 AcpiUtGetTypeName (Node->Type)); 950 AslError (ASL_ERROR, ASL_MSG_SCOPE_TYPE, Op, AslGbl_MsgBuffer); 951 return_ACPI_STATUS (AE_OK); 952 } 953 } 954 else 955 { 956 /* Valid error, object already exists */ 957 958 ExternalPath = AcpiNsGetNormalizedPathname (Node, TRUE); 959 960 AslDualParseOpError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Op, 961 ExternalPath, ASL_MSG_FOUND_HERE, Node->Op, 962 ExternalPath); 963 964 if (ExternalPath) 965 { 966 ACPI_FREE (ExternalPath); 967 } 968 return_ACPI_STATUS (AE_OK); 969 } 970 } 971 else if (AE_NOT_FOUND) 972 { 973 /* 974 * One or more prefix NameSegs of the NamePath do not exist 975 * (all of them must exist). Attempt to continue compilation 976 * by setting the current scope to the root. 977 */ 978 Node = AcpiGbl_RootNode; 979 Status = AE_OK; 980 } 981 else 982 { 983 /* Flag all other errors as coming from the ACPICA core */ 984 985 AslCoreSubsystemError (Op, Status, 986 "Failure from namespace lookup", FALSE); 987 return_ACPI_STATUS (Status); 988 } 989 } 990 991 /* Check special names like _WAK and _PTS */ 992 993 LdCheckSpecialNames (Node, Op); 994 995 if (ForceNewScope) 996 { 997 Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState); 998 if (ACPI_FAILURE (Status)) 999 { 1000 return_ACPI_STATUS (Status); 1001 } 1002 } 1003 1004 FinishNode: 1005 /* 1006 * Point the parse node to the new namespace node, and point 1007 * the Node back to the original Parse node 1008 */ 1009 Op->Asl.Node = Node; 1010 Node->Op = Op; 1011 1012 /* 1013 * Set the actual data type if appropriate (EXTERNAL term only) 1014 * As of 11/19/2019, ASL External() does not support parameter 1015 * counts. When an External method is loaded, the parameter count is 1016 * unknown setting Node->Value to ASL_EXTERNAL_METHOD_UNKNOWN_PARAMS 1017 * indicates that the parameter count for this method is unknown. 1018 * This information is used in ASL cross reference to help determine the 1019 * parameter count through method calls. 1020 */ 1021 if (ActualObjectType != ACPI_TYPE_ANY) 1022 { 1023 Node->Type = (UINT8) ActualObjectType; 1024 Node->Value = ASL_EXTERNAL_METHOD_UNKNOWN_PARAMS; 1025 } 1026 1027 if (Op->Asl.ParseOpcode == PARSEOP_METHOD) 1028 { 1029 /* 1030 * Get the method argument count from "Extra" and save 1031 * it in the namespace node 1032 */ 1033 Node->Value = (UINT32) Op->Asl.Extra; 1034 } 1035 1036 return_ACPI_STATUS (Status); 1037 } 1038 1039 1040 /******************************************************************************* 1041 * 1042 * FUNCTION: LdCheckSpecialNames 1043 * 1044 * PARAMETERS: Node - Node that represents the named object 1045 * Op - Named object declaring this named object 1046 * 1047 * RETURN: None 1048 * 1049 * DESCRIPTION: Check if certain named objects are declared in the incorrect 1050 * scope. Special named objects are listed in 1051 * AslGbl_SpecialNamedObjects and can only be declared at the root 1052 * scope. _UID inside of a processor declaration must not be a 1053 * string. 1054 * 1055 ******************************************************************************/ 1056 1057 static void 1058 LdCheckSpecialNames ( 1059 ACPI_NAMESPACE_NODE *Node, 1060 ACPI_PARSE_OBJECT *Op) 1061 { 1062 UINT32 i; 1063 1064 1065 for (i = 0; i < MAX_SPECIAL_NAMES; i++) 1066 { 1067 if (ACPI_COMPARE_NAMESEG(Node->Name.Ascii, AslGbl_SpecialNamedObjects[i]) && 1068 Node->Parent != AcpiGbl_RootNode) 1069 { 1070 AslError (ASL_ERROR, ASL_MSG_INVALID_SPECIAL_NAME, Op, Op->Asl.ExternalName); 1071 return; 1072 } 1073 } 1074 1075 if (ACPI_COMPARE_NAMESEG (Node->Name.Ascii, "_UID") && 1076 Node->Parent->Type == ACPI_TYPE_PROCESSOR && 1077 Node->Type == ACPI_TYPE_STRING) 1078 { 1079 AslError (ASL_ERROR, ASL_MSG_INVALID_PROCESSOR_UID , Op, "found a string"); 1080 } 1081 } 1082 1083 1084 /******************************************************************************* 1085 * 1086 * FUNCTION: LdNamespace2Begin 1087 * 1088 * PARAMETERS: ASL_WALK_CALLBACK 1089 * 1090 * RETURN: Status 1091 * 1092 * DESCRIPTION: Descending callback used during the pass 2 parse tree walk. 1093 * Second pass resolves some forward references. 1094 * 1095 * Notes: 1096 * Currently only needs to handle the Alias operator. 1097 * Could be used to allow forward references from the Scope() operator, but 1098 * the MS interpreter does not allow this, so this compiler does not either. 1099 * 1100 ******************************************************************************/ 1101 1102 static ACPI_STATUS 1103 LdNamespace2Begin ( 1104 ACPI_PARSE_OBJECT *Op, 1105 UINT32 Level, 1106 void *Context) 1107 { 1108 ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context; 1109 ACPI_STATUS Status; 1110 ACPI_NAMESPACE_NODE *Node; 1111 ACPI_OBJECT_TYPE ObjectType; 1112 BOOLEAN ForceNewScope = FALSE; 1113 ACPI_PARSE_OBJECT *Arg; 1114 char *Path; 1115 ACPI_NAMESPACE_NODE *TargetNode; 1116 1117 1118 ACPI_FUNCTION_NAME (LdNamespace2Begin); 1119 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n", 1120 Op, Op->Asl.ParseOpName)); 1121 1122 1123 /* Ignore Ops with no namespace node */ 1124 1125 Node = Op->Asl.Node; 1126 if (!Node) 1127 { 1128 return (AE_OK); 1129 } 1130 1131 /* Get the type to determine if we should push the scope */ 1132 1133 if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) && 1134 (Op->Asl.CompileFlags == OP_IS_RESOURCE_DESC)) 1135 { 1136 ObjectType = ACPI_TYPE_LOCAL_RESOURCE; 1137 } 1138 else 1139 { 1140 ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); 1141 } 1142 1143 /* Push scope for Resource Templates */ 1144 1145 if (Op->Asl.ParseOpcode == PARSEOP_NAME) 1146 { 1147 if (Op->Asl.CompileFlags & OP_IS_RESOURCE_DESC) 1148 { 1149 ForceNewScope = TRUE; 1150 } 1151 } 1152 1153 /* Push the scope stack */ 1154 1155 if (ForceNewScope || AcpiNsOpensScope (ObjectType)) 1156 { 1157 Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState); 1158 if (ACPI_FAILURE (Status)) 1159 { 1160 return_ACPI_STATUS (Status); 1161 } 1162 } 1163 1164 if (Op->Asl.ParseOpcode == PARSEOP_ALIAS) 1165 { 1166 /* 1167 * Complete the alias node by getting and saving the target node. 1168 * First child is the alias target 1169 */ 1170 Arg = Op->Asl.Child; 1171 1172 /* Get the target pathname */ 1173 1174 Path = Arg->Asl.Namepath; 1175 if (!Path) 1176 { 1177 Status = UtInternalizeName (Arg->Asl.ExternalName, &Path); 1178 if (ACPI_FAILURE (Status)) 1179 { 1180 return (Status); 1181 } 1182 } 1183 1184 /* Get the NS node associated with the target. It must exist. */ 1185 1186 Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY, 1187 ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, 1188 WalkState, &TargetNode); 1189 if (ACPI_FAILURE (Status)) 1190 { 1191 if (Status == AE_NOT_FOUND) 1192 { 1193 /* Standalone NameSeg vs. NamePath */ 1194 1195 if (strlen (Arg->Asl.ExternalName) == ACPI_NAMESEG_SIZE) 1196 { 1197 AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op, 1198 Arg->Asl.ExternalName); 1199 } 1200 else 1201 { 1202 AslError (ASL_ERROR, ASL_MSG_NAMEPATH_NOT_EXIST, Op, 1203 Arg->Asl.ExternalName); 1204 } 1205 1206 #if 0 1207 /* 1208 * NOTE: Removed 10/2018 to enhance compiler error reporting. No 1209 * regressions seen. 1210 */ 1211 /* 1212 * The name was not found, go ahead and create it. 1213 * This prevents more errors later. 1214 */ 1215 Status = AcpiNsLookup (WalkState->ScopeInfo, Path, 1216 ACPI_TYPE_ANY, ACPI_IMODE_LOAD_PASS1, 1217 ACPI_NS_NO_UPSEARCH, WalkState, &Node); 1218 #endif 1219 return (Status); 1220 /* Removed: return (AE_OK)*/ 1221 } 1222 1223 AslCoreSubsystemError (Op, Status, 1224 "Failure from namespace lookup", FALSE); 1225 return (AE_OK); 1226 } 1227 1228 /* Save the target node within the alias node */ 1229 1230 Node->Object = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, TargetNode); 1231 } 1232 1233 return (AE_OK); 1234 } 1235 1236 1237 /******************************************************************************* 1238 * 1239 * FUNCTION: LdCommonNamespaceEnd 1240 * 1241 * PARAMETERS: ASL_WALK_CALLBACK 1242 * 1243 * RETURN: Status 1244 * 1245 * DESCRIPTION: Ascending callback used during the loading of the namespace, 1246 * We only need to worry about managing the scope stack here. 1247 * 1248 ******************************************************************************/ 1249 1250 static ACPI_STATUS 1251 LdCommonNamespaceEnd ( 1252 ACPI_PARSE_OBJECT *Op, 1253 UINT32 Level, 1254 void *Context) 1255 { 1256 ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context; 1257 ACPI_OBJECT_TYPE ObjectType; 1258 BOOLEAN ForceNewScope = FALSE; 1259 1260 1261 ACPI_FUNCTION_NAME (LdCommonNamespaceEnd); 1262 1263 1264 /* We are only interested in opcodes that have an associated name */ 1265 1266 if (!Op->Asl.Namepath) 1267 { 1268 return (AE_OK); 1269 } 1270 1271 /* Get the type to determine if we should pop the scope */ 1272 1273 if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) && 1274 (Op->Asl.CompileFlags == OP_IS_RESOURCE_DESC)) 1275 { 1276 /* TBD: Merge into AcpiDsMapNamedOpcodeToDataType */ 1277 1278 ObjectType = ACPI_TYPE_LOCAL_RESOURCE; 1279 } 1280 else 1281 { 1282 ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); 1283 } 1284 1285 /* Pop scope that was pushed for Resource Templates */ 1286 1287 if (Op->Asl.ParseOpcode == PARSEOP_NAME) 1288 { 1289 if (Op->Asl.CompileFlags & OP_IS_RESOURCE_DESC) 1290 { 1291 ForceNewScope = TRUE; 1292 } 1293 } 1294 1295 /* Pop the scope stack */ 1296 1297 if (ForceNewScope || AcpiNsOpensScope (ObjectType)) 1298 { 1299 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 1300 "(%s): Popping scope for Op [%s] %p\n", 1301 AcpiUtGetTypeName (ObjectType), Op->Asl.ParseOpName, Op)); 1302 1303 (void) AcpiDsScopeStackPop (WalkState); 1304 } 1305 1306 return (AE_OK); 1307 } 1308