1 /******************************************************************************
   2  *
   3  * Module Name: dswload - Dispatcher namespace load callbacks
   4  *
   5  *****************************************************************************/
   6 
   7 /*
   8  * Copyright (C) 2000 - 2013, Intel Corp.
   9  * All rights reserved.
  10  *
  11  * Redistribution and use in source and binary forms, with or without
  12  * modification, are permitted provided that the following conditions
  13  * are met:
  14  * 1. Redistributions of source code must retain the above copyright
  15  *    notice, this list of conditions, and the following disclaimer,
  16  *    without modification.
  17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  18  *    substantially similar to the "NO WARRANTY" disclaimer below
  19  *    ("Disclaimer") and any redistribution must be conditioned upon
  20  *    including a substantially similar Disclaimer requirement for further
  21  *    binary redistribution.
  22  * 3. Neither the names of the above-listed copyright holders nor the names
  23  *    of any contributors may be used to endorse or promote products derived
  24  *    from this software without specific prior written permission.
  25  *
  26  * Alternatively, this software may be distributed under the terms of the
  27  * GNU General Public License ("GPL") version 2 as published by the Free
  28  * Software Foundation.
  29  *
  30  * NO WARRANTY
  31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
  34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  41  * POSSIBILITY OF SUCH DAMAGES.
  42  */
  43 
  44 #define __ASLLOAD_C__
  45 
  46 #include "aslcompiler.h"
  47 #include "amlcode.h"
  48 #include "acdispat.h"
  49 #include "acnamesp.h"
  50 
  51 #include "aslcompiler.y.h"
  52 
  53 #define _COMPONENT          ACPI_COMPILER
  54         ACPI_MODULE_NAME    ("aslload")
  55 
  56 /* Local prototypes */
  57 
  58 static ACPI_STATUS
  59 LdLoadFieldElements (
  60     ACPI_PARSE_OBJECT       *Op,
  61     ACPI_WALK_STATE         *WalkState);
  62 
  63 static ACPI_STATUS
  64 LdLoadResourceElements (
  65     ACPI_PARSE_OBJECT       *Op,
  66     ACPI_WALK_STATE         *WalkState);
  67 
  68 static ACPI_STATUS
  69 LdNamespace1Begin (
  70     ACPI_PARSE_OBJECT       *Op,
  71     UINT32                  Level,
  72     void                    *Context);
  73 
  74 static ACPI_STATUS
  75 LdNamespace2Begin (
  76     ACPI_PARSE_OBJECT       *Op,
  77     UINT32                  Level,
  78     void                    *Context);
  79 
  80 static ACPI_STATUS
  81 LdCommonNamespaceEnd (
  82     ACPI_PARSE_OBJECT       *Op,
  83     UINT32                  Level,
  84     void                    *Context);
  85 
  86 
  87 /*******************************************************************************
  88  *
  89  * FUNCTION:    LdLoadNamespace
  90  *
  91  * PARAMETERS:  RootOp      - Root of the parse tree
  92  *
  93  * RETURN:      Status
  94  *
  95  * DESCRIPTION: Perform a walk of the parse tree that in turn loads all of the
  96  *              named ASL/AML objects into the namespace. The namespace is
  97  *              constructed in order to resolve named references and references
  98  *              to named fields within resource templates/descriptors.
  99  *
 100  ******************************************************************************/
 101 
 102 ACPI_STATUS
 103 LdLoadNamespace (
 104     ACPI_PARSE_OBJECT       *RootOp)
 105 {
 106     ACPI_WALK_STATE         *WalkState;
 107 
 108 
 109     DbgPrint (ASL_DEBUG_OUTPUT, "\nCreating namespace\n\n");
 110 
 111     /* Create a new walk state */
 112 
 113     WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
 114     if (!WalkState)
 115     {
 116         return (AE_NO_MEMORY);
 117     }
 118 
 119     /* Walk the entire parse tree, first pass */
 120 
 121     TrWalkParseTree (RootOp, ASL_WALK_VISIT_TWICE, LdNamespace1Begin,
 122         LdCommonNamespaceEnd, WalkState);
 123 
 124     /* Second pass to handle forward references */
 125 
 126     TrWalkParseTree (RootOp, ASL_WALK_VISIT_TWICE, LdNamespace2Begin,
 127         LdCommonNamespaceEnd, WalkState);
 128 
 129     /* Dump the namespace if debug is enabled */
 130 
 131     AcpiNsDumpTables (ACPI_NS_ALL, ACPI_UINT32_MAX);
 132     return (AE_OK);
 133 }
 134 
 135 
 136 /*******************************************************************************
 137  *
 138  * FUNCTION:    LdLoadFieldElements
 139  *
 140  * PARAMETERS:  Op              - Parent node (Field)
 141  *              WalkState       - Current walk state
 142  *
 143  * RETURN:      Status
 144  *
 145  * DESCRIPTION: Enter the named elements of the field (children of the parent)
 146  *              into the namespace.
 147  *
 148  ******************************************************************************/
 149 
 150 static ACPI_STATUS
 151 LdLoadFieldElements (
 152     ACPI_PARSE_OBJECT       *Op,
 153     ACPI_WALK_STATE         *WalkState)
 154 {
 155     ACPI_PARSE_OBJECT       *Child = NULL;
 156     ACPI_NAMESPACE_NODE     *Node;
 157     ACPI_STATUS             Status;
 158 
 159 
 160     /* Get the first named field element */
 161 
 162     switch (Op->Asl.AmlOpcode)
 163     {
 164     case AML_BANK_FIELD_OP:
 165 
 166         Child = UtGetArg (Op, 6);
 167         break;
 168 
 169     case AML_INDEX_FIELD_OP:
 170 
 171         Child = UtGetArg (Op, 5);
 172         break;
 173 
 174     case AML_FIELD_OP:
 175 
 176         Child = UtGetArg (Op, 4);
 177         break;
 178 
 179     default:
 180 
 181         /* No other opcodes should arrive here */
 182 
 183         return (AE_BAD_PARAMETER);
 184     }
 185 
 186     /* Enter all elements into the namespace */
 187 
 188     while (Child)
 189     {
 190         switch (Child->Asl.AmlOpcode)
 191         {
 192         case AML_INT_RESERVEDFIELD_OP:
 193         case AML_INT_ACCESSFIELD_OP:
 194         case AML_INT_CONNECTION_OP:
 195             break;
 196 
 197         default:
 198 
 199             Status = AcpiNsLookup (WalkState->ScopeInfo,
 200                         Child->Asl.Value.String,
 201                         ACPI_TYPE_LOCAL_REGION_FIELD,
 202                         ACPI_IMODE_LOAD_PASS1,
 203                         ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
 204                             ACPI_NS_ERROR_IF_FOUND,
 205                         NULL, &Node);
 206             if (ACPI_FAILURE (Status))
 207             {
 208                 if (Status != AE_ALREADY_EXISTS)
 209                 {
 210                     AslError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION, Child,
 211                         Child->Asl.Value.String);
 212                     return (Status);
 213                 }
 214 
 215                 /*
 216                  * The name already exists in this scope
 217                  * But continue processing the elements
 218                  */
 219                 AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Child,
 220                     Child->Asl.Value.String);
 221             }
 222             else
 223             {
 224                 Child->Asl.Node = Node;
 225                 Node->Op = Child;
 226             }
 227             break;
 228         }
 229 
 230         Child = Child->Asl.Next;
 231     }
 232 
 233     return (AE_OK);
 234 }
 235 
 236 
 237 /*******************************************************************************
 238  *
 239  * FUNCTION:    LdLoadResourceElements
 240  *
 241  * PARAMETERS:  Op              - Parent node (Resource Descriptor)
 242  *              WalkState       - Current walk state
 243  *
 244  * RETURN:      Status
 245  *
 246  * DESCRIPTION: Enter the named elements of the resource descriptor (children
 247  *              of the parent) into the namespace.
 248  *
 249  * NOTE: In the real AML namespace, these named elements never exist. But
 250  *       we simply use the namespace here as a symbol table so we can look
 251  *       them up as they are referenced.
 252  *
 253  ******************************************************************************/
 254 
 255 static ACPI_STATUS
 256 LdLoadResourceElements (
 257     ACPI_PARSE_OBJECT       *Op,
 258     ACPI_WALK_STATE         *WalkState)
 259 {
 260     ACPI_PARSE_OBJECT       *InitializerOp = NULL;
 261     ACPI_NAMESPACE_NODE     *Node;
 262     ACPI_STATUS             Status;
 263 
 264 
 265     /*
 266      * Enter the resource name into the namespace. Name must not already exist.
 267      * This opens a scope, so later field names are guaranteed to be new/unique.
 268      */
 269     Status = AcpiNsLookup (WalkState->ScopeInfo, Op->Asl.Namepath,
 270                 ACPI_TYPE_LOCAL_RESOURCE, ACPI_IMODE_LOAD_PASS1,
 271                 ACPI_NS_NO_UPSEARCH | ACPI_NS_ERROR_IF_FOUND,
 272                 WalkState, &Node);
 273     if (ACPI_FAILURE (Status))
 274     {
 275         if (Status == AE_ALREADY_EXISTS)
 276         {
 277             /* Actual node causing the error was saved in ParentMethod */
 278 
 279             AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS,
 280                 (ACPI_PARSE_OBJECT *) Op->Asl.ParentMethod, Op->Asl.Namepath);
 281             return (AE_OK);
 282         }
 283         return (Status);
 284     }
 285 
 286     Node->Value = (UINT32) Op->Asl.Value.Integer;
 287     Node->Op = Op;
 288     Op->Asl.Node = Node;
 289 
 290     /*
 291      * Now enter the predefined fields, for easy lookup when referenced
 292      * by the source ASL
 293      */
 294     InitializerOp = ASL_GET_CHILD_NODE (Op);
 295     while (InitializerOp)
 296     {
 297         if (InitializerOp->Asl.ExternalName)
 298         {
 299             Status = AcpiNsLookup (WalkState->ScopeInfo,
 300                         InitializerOp->Asl.ExternalName,
 301                         ACPI_TYPE_LOCAL_RESOURCE_FIELD,
 302                         ACPI_IMODE_LOAD_PASS1,
 303                         ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE,
 304                         NULL, &Node);
 305             if (ACPI_FAILURE (Status))
 306             {
 307                 return (Status);
 308             }
 309 
 310             /*
 311              * Store the field offset and length in the namespace node
 312              * so it can be used when the field is referenced
 313              */
 314             Node->Value = InitializerOp->Asl.Value.Tag.BitOffset;
 315             Node->Length = InitializerOp->Asl.Value.Tag.BitLength;
 316             InitializerOp->Asl.Node = Node;
 317             Node->Op = InitializerOp;
 318         }
 319 
 320         InitializerOp = ASL_GET_PEER_NODE (InitializerOp);
 321     }
 322 
 323     return (AE_OK);
 324 }
 325 
 326 
 327 /*******************************************************************************
 328  *
 329  * FUNCTION:    LdNamespace1Begin
 330  *
 331  * PARAMETERS:  ASL_WALK_CALLBACK
 332  *
 333  * RETURN:      Status
 334  *
 335  * DESCRIPTION: Descending callback used during the parse tree walk. If this
 336  *              is a named AML opcode, enter into the namespace
 337  *
 338  ******************************************************************************/
 339 
 340 static ACPI_STATUS
 341 LdNamespace1Begin (
 342     ACPI_PARSE_OBJECT       *Op,
 343     UINT32                  Level,
 344     void                    *Context)
 345 {
 346     ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
 347     ACPI_NAMESPACE_NODE     *Node;
 348     ACPI_STATUS             Status;
 349     ACPI_OBJECT_TYPE        ObjectType;
 350     ACPI_OBJECT_TYPE        ActualObjectType = ACPI_TYPE_ANY;
 351     char                    *Path;
 352     UINT32                  Flags = ACPI_NS_NO_UPSEARCH;
 353     ACPI_PARSE_OBJECT       *Arg;
 354     UINT32                  i;
 355     BOOLEAN                 ForceNewScope = FALSE;
 356 
 357 
 358     ACPI_FUNCTION_NAME (LdNamespace1Begin);
 359     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n",
 360         Op, Op->Asl.ParseOpName));
 361 
 362 
 363     /*
 364      * We are only interested in opcodes that have an associated name
 365      * (or multiple names)
 366      */
 367     switch (Op->Asl.AmlOpcode)
 368     {
 369     case AML_BANK_FIELD_OP:
 370     case AML_INDEX_FIELD_OP:
 371     case AML_FIELD_OP:
 372 
 373         Status = LdLoadFieldElements (Op, WalkState);
 374         return (Status);
 375 
 376     default:
 377 
 378         /* All other opcodes go below */
 379 
 380         break;
 381     }
 382 
 383     /* Check if this object has already been installed in the namespace */
 384 
 385     if (Op->Asl.Node)
 386     {
 387         return (AE_OK);
 388     }
 389 
 390     Path = Op->Asl.Namepath;
 391     if (!Path)
 392     {
 393         return (AE_OK);
 394     }
 395 
 396     /* Map the raw opcode into an internal object type */
 397 
 398     switch (Op->Asl.ParseOpcode)
 399     {
 400     case PARSEOP_NAME:
 401 
 402         Arg = Op->Asl.Child;  /* Get the NameSeg/NameString node */
 403         Arg = Arg->Asl.Next;  /* First peer is the object to be associated with the name */
 404 
 405         /*
 406          * If this name refers to a ResourceTemplate, we will need to open
 407          * a new scope so that the resource subfield names can be entered into
 408          * the namespace underneath this name
 409          */
 410         if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC)
 411         {
 412             ForceNewScope = TRUE;
 413         }
 414 
 415         /* Get the data type associated with the named object, not the name itself */
 416 
 417         /* Log2 loop to convert from Btype (binary) to Etype (encoded) */
 418 
 419         ObjectType = 1;
 420         for (i = 1; i < Arg->Asl.AcpiBtype; i *= 2)
 421         {
 422             ObjectType++;
 423         }
 424         break;
 425 
 426 
 427     case PARSEOP_EXTERNAL:
 428         /*
 429          * "External" simply enters a name and type into the namespace.
 430          * We must be careful to not open a new scope, however, no matter
 431          * what type the external name refers to (e.g., a method)
 432          *
 433          * first child is name, next child is ObjectType
 434          */
 435         ActualObjectType = (UINT8) Op->Asl.Child->Asl.Next->Asl.Value.Integer;
 436         ObjectType = ACPI_TYPE_ANY;
 437 
 438         /*
 439          * We will mark every new node along the path as "External". This
 440          * allows some or all of the nodes to be created later in the ASL
 441          * code. Handles cases like this:
 442          *
 443          *   External (\_SB_.PCI0.ABCD, IntObj)
 444          *   Scope (_SB_)
 445          *   {
 446          *       Device (PCI0)
 447          *       {
 448          *       }
 449          *   }
 450          *   Method (X)
 451          *   {
 452          *       Store (\_SB_.PCI0.ABCD, Local0)
 453          *   }
 454          */
 455         Flags |= ACPI_NS_EXTERNAL;
 456         break;
 457 
 458     case PARSEOP_DEFAULT_ARG:
 459 
 460         if (Op->Asl.CompileFlags == NODE_IS_RESOURCE_DESC)
 461         {
 462             Status = LdLoadResourceElements (Op, WalkState);
 463             return_ACPI_STATUS (Status);
 464         }
 465 
 466         ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
 467         break;
 468 
 469 
 470     case PARSEOP_SCOPE:
 471         /*
 472          * The name referenced by Scope(Name) must already exist at this point.
 473          * In other words, forward references for Scope() are not supported.
 474          * The only real reason for this is that the MS interpreter cannot
 475          * handle this case. Perhaps someday this case can go away.
 476          */
 477         Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY,
 478                     ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
 479                     WalkState, &(Node));
 480         if (ACPI_FAILURE (Status))
 481         {
 482             if (Status == AE_NOT_FOUND)
 483             {
 484                 /* The name was not found, go ahead and create it */
 485 
 486                 Status = AcpiNsLookup (WalkState->ScopeInfo, Path,
 487                             ACPI_TYPE_LOCAL_SCOPE,
 488                             ACPI_IMODE_LOAD_PASS1, Flags,
 489                             WalkState, &(Node));
 490                 if (ACPI_FAILURE (Status))
 491                 {
 492                     return_ACPI_STATUS (Status);
 493                 }
 494 
 495                 /*
 496                  * However, this is an error -- primarily because the MS
 497                  * interpreter can't handle a forward reference from the
 498                  * Scope() operator.
 499                  */
 500                 AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op,
 501                     Op->Asl.ExternalName);
 502                 AslError (ASL_ERROR, ASL_MSG_SCOPE_FWD_REF, Op,
 503                     Op->Asl.ExternalName);
 504                 goto FinishNode;
 505             }
 506 
 507             AslCoreSubsystemError (Op, Status,
 508                 "Failure from namespace lookup", FALSE);
 509 
 510             return_ACPI_STATUS (Status);
 511         }
 512 
 513         /* We found a node with this name, now check the type */
 514 
 515         switch (Node->Type)
 516         {
 517         case ACPI_TYPE_LOCAL_SCOPE:
 518         case ACPI_TYPE_DEVICE:
 519         case ACPI_TYPE_POWER:
 520         case ACPI_TYPE_PROCESSOR:
 521         case ACPI_TYPE_THERMAL:
 522 
 523             /* These are acceptable types - they all open a new scope */
 524             break;
 525 
 526         case ACPI_TYPE_INTEGER:
 527         case ACPI_TYPE_STRING:
 528         case ACPI_TYPE_BUFFER:
 529             /*
 530              * These types we will allow, but we will change the type.
 531              * This enables some existing code of the form:
 532              *
 533              *  Name (DEB, 0)
 534              *  Scope (DEB) { ... }
 535              *
 536              * Which is used to workaround the fact that the MS interpreter
 537              * does not allow Scope() forward references.
 538              */
 539             sprintf (MsgBuffer, "%s [%s], changing type to [Scope]",
 540                 Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type));
 541             AslError (ASL_REMARK, ASL_MSG_SCOPE_TYPE, Op, MsgBuffer);
 542 
 543             /* Switch the type to scope, open the new scope */
 544 
 545             Node->Type = ACPI_TYPE_LOCAL_SCOPE;
 546             Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE,
 547                         WalkState);
 548             if (ACPI_FAILURE (Status))
 549             {
 550                 return_ACPI_STATUS (Status);
 551             }
 552             break;
 553 
 554         default:
 555 
 556             /* All other types are an error */
 557 
 558             sprintf (MsgBuffer, "%s [%s]", Op->Asl.ExternalName,
 559                 AcpiUtGetTypeName (Node->Type));
 560             AslError (ASL_ERROR, ASL_MSG_SCOPE_TYPE, Op, MsgBuffer);
 561 
 562             /*
 563              * However, switch the type to be an actual scope so
 564              * that compilation can continue without generating a whole
 565              * cascade of additional errors. Open the new scope.
 566              */
 567             Node->Type = ACPI_TYPE_LOCAL_SCOPE;
 568             Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE,
 569                         WalkState);
 570             if (ACPI_FAILURE (Status))
 571             {
 572                 return_ACPI_STATUS (Status);
 573             }
 574             break;
 575         }
 576 
 577         Status = AE_OK;
 578         goto FinishNode;
 579 
 580 
 581     default:
 582 
 583         ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
 584         break;
 585     }
 586 
 587 
 588     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Loading name: %s, (%s)\n",
 589             Op->Asl.ExternalName, AcpiUtGetTypeName (ObjectType)));
 590 
 591     /* The name must not already exist */
 592 
 593     Flags |= ACPI_NS_ERROR_IF_FOUND;
 594 
 595     /*
 596      * Enter the named type into the internal namespace. We enter the name
 597      * as we go downward in the parse tree. Any necessary subobjects that
 598      * involve arguments to the opcode must be created as we go back up the
 599      * parse tree later.
 600      */
 601     Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
 602                     ACPI_IMODE_LOAD_PASS1, Flags, WalkState, &Node);
 603     if (ACPI_FAILURE (Status))
 604     {
 605         if (Status == AE_ALREADY_EXISTS)
 606         {
 607             /* The name already exists in this scope */
 608 
 609             if (Node->Type == ACPI_TYPE_LOCAL_SCOPE)
 610             {
 611                 /* Allow multiple references to the same scope */
 612 
 613                 Node->Type = (UINT8) ObjectType;
 614                 Status = AE_OK;
 615             }
 616             else if ((Node->Flags & ANOBJ_IS_EXTERNAL) &&
 617                      (Op->Asl.ParseOpcode != PARSEOP_EXTERNAL))
 618             {
 619                 /*
 620                  * Allow one create on an object or segment that was
 621                  * previously declared External
 622                  */
 623                 Node->Flags &= ~ANOBJ_IS_EXTERNAL;
 624                 Node->Type = (UINT8) ObjectType;
 625 
 626                 /* Just retyped a node, probably will need to open a scope */
 627 
 628                 if (AcpiNsOpensScope (ObjectType))
 629                 {
 630                     Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);
 631                     if (ACPI_FAILURE (Status))
 632                     {
 633                         return_ACPI_STATUS (Status);
 634                     }
 635                 }
 636                 Status = AE_OK;
 637             }
 638             else
 639             {
 640                 /* Valid error, object already exists */
 641 
 642                 AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Op,
 643                     Op->Asl.ExternalName);
 644                 return_ACPI_STATUS (AE_OK);
 645             }
 646         }
 647         else
 648         {
 649             AslCoreSubsystemError (Op, Status,
 650                 "Failure from namespace lookup", FALSE);
 651             return_ACPI_STATUS (Status);
 652         }
 653     }
 654 
 655     if (ForceNewScope)
 656     {
 657         Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);
 658         if (ACPI_FAILURE (Status))
 659         {
 660             return_ACPI_STATUS (Status);
 661         }
 662     }
 663 
 664 FinishNode:
 665     /*
 666      * Point the parse node to the new namespace node, and point
 667      * the Node back to the original Parse node
 668      */
 669     Op->Asl.Node = Node;
 670     Node->Op = Op;
 671 
 672     /* Set the actual data type if appropriate (EXTERNAL term only) */
 673 
 674     if (ActualObjectType != ACPI_TYPE_ANY)
 675     {
 676         Node->Type = (UINT8) ActualObjectType;
 677         Node->Value = ASL_EXTERNAL_METHOD;
 678     }
 679 
 680     if (Op->Asl.ParseOpcode == PARSEOP_METHOD)
 681     {
 682         /*
 683          * Get the method argument count from "Extra" and save
 684          * it in the namespace node
 685          */
 686         Node->Value = (UINT32) Op->Asl.Extra;
 687     }
 688 
 689     return_ACPI_STATUS (Status);
 690 }
 691 
 692 
 693 /*******************************************************************************
 694  *
 695  * FUNCTION:    LdNamespace2Begin
 696  *
 697  * PARAMETERS:  ASL_WALK_CALLBACK
 698  *
 699  * RETURN:      Status
 700  *
 701  * DESCRIPTION: Descending callback used during the pass 2 parse tree walk.
 702  *              Second pass resolves some forward references.
 703  *
 704  * Notes:
 705  * Currently only needs to handle the Alias operator.
 706  * Could be used to allow forward references from the Scope() operator, but
 707  * the MS interpreter does not allow this, so this compiler does not either.
 708  *
 709  ******************************************************************************/
 710 
 711 static ACPI_STATUS
 712 LdNamespace2Begin (
 713     ACPI_PARSE_OBJECT       *Op,
 714     UINT32                  Level,
 715     void                    *Context)
 716 {
 717     ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
 718     ACPI_STATUS             Status;
 719     ACPI_NAMESPACE_NODE     *Node;
 720     ACPI_OBJECT_TYPE        ObjectType;
 721     BOOLEAN                 ForceNewScope = FALSE;
 722     ACPI_PARSE_OBJECT       *Arg;
 723     char                    *Path;
 724     ACPI_NAMESPACE_NODE     *TargetNode;
 725 
 726 
 727     ACPI_FUNCTION_NAME (LdNamespace2Begin);
 728     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n",
 729         Op, Op->Asl.ParseOpName));
 730 
 731 
 732     /* Ignore Ops with no namespace node */
 733 
 734     Node = Op->Asl.Node;
 735     if (!Node)
 736     {
 737         return (AE_OK);
 738     }
 739 
 740     /* Get the type to determine if we should push the scope */
 741 
 742     if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) &&
 743         (Op->Asl.CompileFlags == NODE_IS_RESOURCE_DESC))
 744     {
 745         ObjectType = ACPI_TYPE_LOCAL_RESOURCE;
 746     }
 747     else
 748     {
 749         ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
 750     }
 751 
 752     /* Push scope for Resource Templates */
 753 
 754     if (Op->Asl.ParseOpcode == PARSEOP_NAME)
 755     {
 756         if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC)
 757         {
 758             ForceNewScope = TRUE;
 759         }
 760     }
 761 
 762     /* Push the scope stack */
 763 
 764     if (ForceNewScope || AcpiNsOpensScope (ObjectType))
 765     {
 766         Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);
 767         if (ACPI_FAILURE (Status))
 768         {
 769             return_ACPI_STATUS (Status);
 770         }
 771     }
 772 
 773     if (Op->Asl.ParseOpcode == PARSEOP_ALIAS)
 774     {
 775         /* Complete the alias node by getting and saving the target node */
 776 
 777         /* First child is the alias target */
 778 
 779         Arg = Op->Asl.Child;
 780 
 781         /* Get the target pathname */
 782 
 783         Path = Arg->Asl.Namepath;
 784         if (!Path)
 785         {
 786             Status = UtInternalizeName (Arg->Asl.ExternalName, &Path);
 787             if (ACPI_FAILURE (Status))
 788             {
 789                 return (Status);
 790             }
 791         }
 792 
 793         /* Get the NS node associated with the target. It must exist. */
 794 
 795         Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY,
 796                     ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
 797                     WalkState, &TargetNode);
 798         if (ACPI_FAILURE (Status))
 799         {
 800             if (Status == AE_NOT_FOUND)
 801             {
 802                 AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op,
 803                     Op->Asl.ExternalName);
 804 
 805                 /*
 806                  * The name was not found, go ahead and create it.
 807                  * This prevents more errors later.
 808                  */
 809                 Status = AcpiNsLookup (WalkState->ScopeInfo, Path,
 810                             ACPI_TYPE_ANY,
 811                             ACPI_IMODE_LOAD_PASS1, ACPI_NS_NO_UPSEARCH,
 812                             WalkState, &(Node));
 813                 return (AE_OK);
 814             }
 815 
 816             AslCoreSubsystemError (Op, Status,
 817                 "Failure from namespace lookup", FALSE);
 818             return (AE_OK);
 819         }
 820 
 821         /* Save the target node within the alias node */
 822 
 823         Node->Object = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, TargetNode);
 824     }
 825 
 826     return (AE_OK);
 827 }
 828 
 829 
 830 /*******************************************************************************
 831  *
 832  * FUNCTION:    LdCommonNamespaceEnd
 833  *
 834  * PARAMETERS:  ASL_WALK_CALLBACK
 835  *
 836  * RETURN:      Status
 837  *
 838  * DESCRIPTION: Ascending callback used during the loading of the namespace,
 839  *              We only need to worry about managing the scope stack here.
 840  *
 841  ******************************************************************************/
 842 
 843 static ACPI_STATUS
 844 LdCommonNamespaceEnd (
 845     ACPI_PARSE_OBJECT       *Op,
 846     UINT32                  Level,
 847     void                    *Context)
 848 {
 849     ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
 850     ACPI_OBJECT_TYPE        ObjectType;
 851     BOOLEAN                 ForceNewScope = FALSE;
 852 
 853 
 854     ACPI_FUNCTION_NAME (LdCommonNamespaceEnd);
 855 
 856 
 857     /* We are only interested in opcodes that have an associated name */
 858 
 859     if (!Op->Asl.Namepath)
 860     {
 861         return (AE_OK);
 862     }
 863 
 864     /* Get the type to determine if we should pop the scope */
 865 
 866     if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) &&
 867         (Op->Asl.CompileFlags == NODE_IS_RESOURCE_DESC))
 868     {
 869         /* TBD: Merge into AcpiDsMapNamedOpcodeToDataType */
 870 
 871         ObjectType = ACPI_TYPE_LOCAL_RESOURCE;
 872     }
 873     else
 874     {
 875         ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
 876     }
 877 
 878     /* Pop scope that was pushed for Resource Templates */
 879 
 880     if (Op->Asl.ParseOpcode == PARSEOP_NAME)
 881     {
 882         if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC)
 883         {
 884             ForceNewScope = TRUE;
 885         }
 886     }
 887 
 888     /* Pop the scope stack */
 889 
 890     if (ForceNewScope || AcpiNsOpensScope (ObjectType))
 891     {
 892         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
 893             "(%s): Popping scope for Op [%s] %p\n",
 894             AcpiUtGetTypeName (ObjectType), Op->Asl.ParseOpName, Op));
 895 
 896         (void) AcpiDsScopeStackPop (WalkState);
 897     }
 898 
 899     return (AE_OK);
 900 }