1 /******************************************************************************
   2  *
   3  * Module Name: dswload - Dispatcher first pass namespace load callbacks
   4  *
   5  *****************************************************************************/
   6 
   7 /*
   8  * Copyright (C) 2000 - 2011, 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 __DSWLOAD_C__
  45 
  46 #include "acpi.h"
  47 #include "accommon.h"
  48 #include "acparser.h"
  49 #include "amlcode.h"
  50 #include "acdispat.h"
  51 #include "acinterp.h"
  52 #include "acnamesp.h"
  53 
  54 #ifdef ACPI_ASL_COMPILER
  55 #include "acdisasm.h"
  56 #endif
  57 
  58 #define _COMPONENT          ACPI_DISPATCHER
  59         ACPI_MODULE_NAME    ("dswload")
  60 
  61 
  62 /*******************************************************************************
  63  *
  64  * FUNCTION:    AcpiDsInitCallbacks
  65  *
  66  * PARAMETERS:  WalkState       - Current state of the parse tree walk
  67  *              PassNumber      - 1, 2, or 3
  68  *
  69  * RETURN:      Status
  70  *
  71  * DESCRIPTION: Init walk state callbacks
  72  *
  73  ******************************************************************************/
  74 
  75 ACPI_STATUS
  76 AcpiDsInitCallbacks (
  77     ACPI_WALK_STATE         *WalkState,
  78     UINT32                  PassNumber)
  79 {
  80 
  81     switch (PassNumber)
  82     {
  83     case 1:
  84         WalkState->ParseFlags         = ACPI_PARSE_LOAD_PASS1 |
  85                                         ACPI_PARSE_DELETE_TREE;
  86         WalkState->DescendingCallback = AcpiDsLoad1BeginOp;
  87         WalkState->AscendingCallback  = AcpiDsLoad1EndOp;
  88         break;
  89 
  90     case 2:
  91         WalkState->ParseFlags         = ACPI_PARSE_LOAD_PASS1 |
  92                                         ACPI_PARSE_DELETE_TREE;
  93         WalkState->DescendingCallback = AcpiDsLoad2BeginOp;
  94         WalkState->AscendingCallback  = AcpiDsLoad2EndOp;
  95         break;
  96 
  97     case 3:
  98 #ifndef ACPI_NO_METHOD_EXECUTION
  99         WalkState->ParseFlags        |= ACPI_PARSE_EXECUTE  |
 100                                         ACPI_PARSE_DELETE_TREE;
 101         WalkState->DescendingCallback = AcpiDsExecBeginOp;
 102         WalkState->AscendingCallback  = AcpiDsExecEndOp;
 103 #endif
 104         break;
 105 
 106     default:
 107         return (AE_BAD_PARAMETER);
 108     }
 109 
 110     return (AE_OK);
 111 }
 112 
 113 
 114 /*******************************************************************************
 115  *
 116  * FUNCTION:    AcpiDsLoad1BeginOp
 117  *
 118  * PARAMETERS:  WalkState       - Current state of the parse tree walk
 119  *              OutOp           - Where to return op if a new one is created
 120  *
 121  * RETURN:      Status
 122  *
 123  * DESCRIPTION: Descending callback used during the loading of ACPI tables.
 124  *
 125  ******************************************************************************/
 126 
 127 ACPI_STATUS
 128 AcpiDsLoad1BeginOp (
 129     ACPI_WALK_STATE         *WalkState,
 130     ACPI_PARSE_OBJECT       **OutOp)
 131 {
 132     ACPI_PARSE_OBJECT       *Op;
 133     ACPI_NAMESPACE_NODE     *Node;
 134     ACPI_STATUS             Status;
 135     ACPI_OBJECT_TYPE        ObjectType;
 136     char                    *Path;
 137     UINT32                  Flags;
 138 
 139 
 140     ACPI_FUNCTION_TRACE (DsLoad1BeginOp);
 141 
 142 
 143     Op = WalkState->Op;
 144     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p State=%p\n", Op, WalkState));
 145 
 146     /* We are only interested in opcodes that have an associated name */
 147 
 148     if (Op)
 149     {
 150         if (!(WalkState->OpInfo->Flags & AML_NAMED))
 151         {
 152             *OutOp = Op;
 153             return_ACPI_STATUS (AE_OK);
 154         }
 155 
 156         /* Check if this object has already been installed in the namespace */
 157 
 158         if (Op->Common.Node)
 159         {
 160             *OutOp = Op;
 161             return_ACPI_STATUS (AE_OK);
 162         }
 163     }
 164 
 165     Path = AcpiPsGetNextNamestring (&WalkState->ParserState);
 166 
 167     /* Map the raw opcode into an internal object type */
 168 
 169     ObjectType = WalkState->OpInfo->ObjectType;
 170 
 171     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
 172         "State=%p Op=%p [%s]\n", WalkState, Op, AcpiUtGetTypeName (ObjectType)));
 173 
 174     switch (WalkState->Opcode)
 175     {
 176     case AML_SCOPE_OP:
 177 
 178         /*
 179          * The target name of the Scope() operator must exist at this point so
 180          * that we can actually open the scope to enter new names underneath it.
 181          * Allow search-to-root for single namesegs.
 182          */
 183         Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
 184                         ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, WalkState, &(Node));
 185 #ifdef ACPI_ASL_COMPILER
 186         if (Status == AE_NOT_FOUND)
 187         {
 188             /*
 189              * Table disassembly:
 190              * Target of Scope() not found. Generate an External for it, and
 191              * insert the name into the namespace.
 192              */
 193             AcpiDmAddToExternalList (Op, Path, ACPI_TYPE_DEVICE, 0);
 194             Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
 195                        ACPI_IMODE_LOAD_PASS1, ACPI_NS_SEARCH_PARENT,
 196                        WalkState, &Node);
 197         }
 198 #endif
 199         if (ACPI_FAILURE (Status))
 200         {
 201             ACPI_ERROR_NAMESPACE (Path, Status);
 202             return_ACPI_STATUS (Status);
 203         }
 204 
 205         /*
 206          * Check to make sure that the target is
 207          * one of the opcodes that actually opens a scope
 208          */
 209         switch (Node->Type)
 210         {
 211         case ACPI_TYPE_ANY:
 212         case ACPI_TYPE_LOCAL_SCOPE:         /* Scope  */
 213         case ACPI_TYPE_DEVICE:
 214         case ACPI_TYPE_POWER:
 215         case ACPI_TYPE_PROCESSOR:
 216         case ACPI_TYPE_THERMAL:
 217 
 218             /* These are acceptable types */
 219             break;
 220 
 221         case ACPI_TYPE_INTEGER:
 222         case ACPI_TYPE_STRING:
 223         case ACPI_TYPE_BUFFER:
 224 
 225             /*
 226              * These types we will allow, but we will change the type.
 227              * This enables some existing code of the form:
 228              *
 229              *  Name (DEB, 0)
 230              *  Scope (DEB) { ... }
 231              *
 232              * Note: silently change the type here. On the second pass,
 233              * we will report a warning
 234              */
 235             ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
 236                 "Type override - [%4.4s] had invalid type (%s) "
 237                 "for Scope operator, changed to type ANY\n",
 238                 AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Node->Type)));
 239 
 240             Node->Type = ACPI_TYPE_ANY;
 241             WalkState->ScopeInfo->Common.Value = ACPI_TYPE_ANY;
 242             break;
 243 
 244         default:
 245 
 246             /* All other types are an error */
 247 
 248             ACPI_ERROR ((AE_INFO,
 249                 "Invalid type (%s) for target of "
 250                 "Scope operator [%4.4s] (Cannot override)",
 251                 AcpiUtGetTypeName (Node->Type), AcpiUtGetNodeName (Node)));
 252 
 253             return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
 254         }
 255         break;
 256 
 257 
 258     default:
 259         /*
 260          * For all other named opcodes, we will enter the name into
 261          * the namespace.
 262          *
 263          * Setup the search flags.
 264          * Since we are entering a name into the namespace, we do not want to
 265          * enable the search-to-root upsearch.
 266          *
 267          * There are only two conditions where it is acceptable that the name
 268          * already exists:
 269          *    1) the Scope() operator can reopen a scoping object that was
 270          *       previously defined (Scope, Method, Device, etc.)
 271          *    2) Whenever we are parsing a deferred opcode (OpRegion, Buffer,
 272          *       BufferField, or Package), the name of the object is already
 273          *       in the namespace.
 274          */
 275         if (WalkState->DeferredNode)
 276         {
 277             /* This name is already in the namespace, get the node */
 278 
 279             Node = WalkState->DeferredNode;
 280             Status = AE_OK;
 281             break;
 282         }
 283 
 284         /*
 285          * If we are executing a method, do not create any namespace objects
 286          * during the load phase, only during execution.
 287          */
 288         if (WalkState->MethodNode)
 289         {
 290             Node = NULL;
 291             Status = AE_OK;
 292             break;
 293         }
 294 
 295         Flags = ACPI_NS_NO_UPSEARCH;
 296         if ((WalkState->Opcode != AML_SCOPE_OP) &&
 297             (!(WalkState->ParseFlags & ACPI_PARSE_DEFERRED_OP)))
 298         {
 299             Flags |= ACPI_NS_ERROR_IF_FOUND;
 300             ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[%s] Cannot already exist\n",
 301                     AcpiUtGetTypeName (ObjectType)));
 302         }
 303         else
 304         {
 305             ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
 306                 "[%s] Both Find or Create allowed\n",
 307                     AcpiUtGetTypeName (ObjectType)));
 308         }
 309 
 310         /*
 311          * Enter the named type into the internal namespace. We enter the name
 312          * as we go downward in the parse tree. Any necessary subobjects that
 313          * involve arguments to the opcode must be created as we go back up the
 314          * parse tree later.
 315          */
 316         Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
 317                         ACPI_IMODE_LOAD_PASS1, Flags, WalkState, &Node);
 318         if (ACPI_FAILURE (Status))
 319         {
 320             if (Status == AE_ALREADY_EXISTS)
 321             {
 322                 /* The name already exists in this scope */
 323 
 324                 if (Node->Flags & ANOBJ_IS_EXTERNAL)
 325                 {
 326                     /*
 327                      * Allow one create on an object or segment that was
 328                      * previously declared External
 329                      */
 330                     Node->Flags &= ~ANOBJ_IS_EXTERNAL;
 331                     Node->Type = (UINT8) ObjectType;
 332 
 333                     /* Just retyped a node, probably will need to open a scope */
 334 
 335                     if (AcpiNsOpensScope (ObjectType))
 336                     {
 337                         Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);
 338                         if (ACPI_FAILURE (Status))
 339                         {
 340                             return_ACPI_STATUS (Status);
 341                         }
 342                     }
 343 
 344                     Status = AE_OK;
 345                 }
 346             }
 347 
 348             if (ACPI_FAILURE (Status))
 349             {
 350                 ACPI_ERROR_NAMESPACE (Path, Status);
 351                 return_ACPI_STATUS (Status);
 352             }
 353         }
 354         break;
 355     }
 356 
 357     /* Common exit */
 358 
 359     if (!Op)
 360     {
 361         /* Create a new op */
 362 
 363         Op = AcpiPsAllocOp (WalkState->Opcode);
 364         if (!Op)
 365         {
 366             return_ACPI_STATUS (AE_NO_MEMORY);
 367         }
 368     }
 369 
 370     /* Initialize the op */
 371 
 372 #if (defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY))
 373     Op->Named.Path = ACPI_CAST_PTR (UINT8, Path);
 374 #endif
 375 
 376     if (Node)
 377     {
 378         /*
 379          * Put the Node in the "op" object that the parser uses, so we
 380          * can get it again quickly when this scope is closed
 381          */
 382         Op->Common.Node = Node;
 383         Op->Named.Name = Node->Name.Integer;
 384     }
 385 
 386     AcpiPsAppendArg (AcpiPsGetParentScope (&WalkState->ParserState), Op);
 387     *OutOp = Op;
 388     return_ACPI_STATUS (Status);
 389 }
 390 
 391 
 392 /*******************************************************************************
 393  *
 394  * FUNCTION:    AcpiDsLoad1EndOp
 395  *
 396  * PARAMETERS:  WalkState       - Current state of the parse tree walk
 397  *
 398  * RETURN:      Status
 399  *
 400  * DESCRIPTION: Ascending callback used during the loading of the namespace,
 401  *              both control methods and everything else.
 402  *
 403  ******************************************************************************/
 404 
 405 ACPI_STATUS
 406 AcpiDsLoad1EndOp (
 407     ACPI_WALK_STATE         *WalkState)
 408 {
 409     ACPI_PARSE_OBJECT       *Op;
 410     ACPI_OBJECT_TYPE        ObjectType;
 411     ACPI_STATUS             Status = AE_OK;
 412 
 413 
 414     ACPI_FUNCTION_TRACE (DsLoad1EndOp);
 415 
 416 
 417     Op = WalkState->Op;
 418     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p State=%p\n", Op, WalkState));
 419 
 420     /* We are only interested in opcodes that have an associated name */
 421 
 422     if (!(WalkState->OpInfo->Flags & (AML_NAMED | AML_FIELD)))
 423     {
 424         return_ACPI_STATUS (AE_OK);
 425     }
 426 
 427     /* Get the object type to determine if we should pop the scope */
 428 
 429     ObjectType = WalkState->OpInfo->ObjectType;
 430 
 431 #ifndef ACPI_NO_METHOD_EXECUTION
 432     if (WalkState->OpInfo->Flags & AML_FIELD)
 433     {
 434         /*
 435          * If we are executing a method, do not create any namespace objects
 436          * during the load phase, only during execution.
 437          */
 438         if (!WalkState->MethodNode)
 439         {
 440             if (WalkState->Opcode == AML_FIELD_OP          ||
 441                 WalkState->Opcode == AML_BANK_FIELD_OP     ||
 442                 WalkState->Opcode == AML_INDEX_FIELD_OP)
 443             {
 444                 Status = AcpiDsInitFieldObjects (Op, WalkState);
 445             }
 446         }
 447         return_ACPI_STATUS (Status);
 448     }
 449 
 450     /*
 451      * If we are executing a method, do not create any namespace objects
 452      * during the load phase, only during execution.
 453      */
 454     if (!WalkState->MethodNode)
 455     {
 456         if (Op->Common.AmlOpcode == AML_REGION_OP)
 457         {
 458             Status = AcpiExCreateRegion (Op->Named.Data, Op->Named.Length,
 459                         (ACPI_ADR_SPACE_TYPE) ((Op->Common.Value.Arg)->Common.Value.Integer),
 460                         WalkState);
 461             if (ACPI_FAILURE (Status))
 462             {
 463                 return_ACPI_STATUS (Status);
 464             }
 465         }
 466         else if (Op->Common.AmlOpcode == AML_DATA_REGION_OP)
 467         {
 468             Status = AcpiExCreateRegion (Op->Named.Data, Op->Named.Length,
 469                         ACPI_ADR_SPACE_DATA_TABLE, WalkState);
 470             if (ACPI_FAILURE (Status))
 471             {
 472                 return_ACPI_STATUS (Status);
 473             }
 474         }
 475     }
 476 #endif
 477 
 478     if (Op->Common.AmlOpcode == AML_NAME_OP)
 479     {
 480         /* For Name opcode, get the object type from the argument */
 481 
 482         if (Op->Common.Value.Arg)
 483         {
 484             ObjectType = (AcpiPsGetOpcodeInfo (
 485                 (Op->Common.Value.Arg)->Common.AmlOpcode))->ObjectType;
 486 
 487             /* Set node type if we have a namespace node */
 488 
 489             if (Op->Common.Node)
 490             {
 491                 Op->Common.Node->Type = (UINT8) ObjectType;
 492             }
 493         }
 494     }
 495 
 496     /*
 497      * If we are executing a method, do not create any namespace objects
 498      * during the load phase, only during execution.
 499      */
 500     if (!WalkState->MethodNode)
 501     {
 502         if (Op->Common.AmlOpcode == AML_METHOD_OP)
 503         {
 504             /*
 505              * MethodOp PkgLength NameString MethodFlags TermList
 506              *
 507              * Note: We must create the method node/object pair as soon as we
 508              * see the method declaration. This allows later pass1 parsing
 509              * of invocations of the method (need to know the number of
 510              * arguments.)
 511              */
 512             ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
 513                 "LOADING-Method: State=%p Op=%p NamedObj=%p\n",
 514                 WalkState, Op, Op->Named.Node));
 515 
 516             if (!AcpiNsGetAttachedObject (Op->Named.Node))
 517             {
 518                 WalkState->Operands[0] = ACPI_CAST_PTR (void, Op->Named.Node);
 519                 WalkState->NumOperands = 1;
 520 
 521                 Status = AcpiDsCreateOperands (WalkState, Op->Common.Value.Arg);
 522                 if (ACPI_SUCCESS (Status))
 523                 {
 524                     Status = AcpiExCreateMethod (Op->Named.Data,
 525                                         Op->Named.Length, WalkState);
 526                 }
 527 
 528                 WalkState->Operands[0] = NULL;
 529                 WalkState->NumOperands = 0;
 530 
 531                 if (ACPI_FAILURE (Status))
 532                 {
 533                     return_ACPI_STATUS (Status);
 534                 }
 535             }
 536         }
 537     }
 538 
 539     /* Pop the scope stack (only if loading a table) */
 540 
 541     if (!WalkState->MethodNode &&
 542         AcpiNsOpensScope (ObjectType))
 543     {
 544         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "(%s): Popping scope for Op %p\n",
 545             AcpiUtGetTypeName (ObjectType), Op));
 546 
 547         Status = AcpiDsScopeStackPop (WalkState);
 548     }
 549 
 550     return_ACPI_STATUS (Status);
 551 }