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