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