Home | History | Annotate | Line # | Download | only in compiler
aslwalks.c revision 1.1.1.6
      1 /******************************************************************************
      2  *
      3  * Module Name: aslwalks.c - Miscellaneous analytical parse tree walks
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2016, 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 #include "aslcompiler.h"
     45 #include "aslcompiler.y.h"
     46 #include "acparser.h"
     47 #include "amlcode.h"
     48 
     49 
     50 #define _COMPONENT          ACPI_COMPILER
     51         ACPI_MODULE_NAME    ("aslwalks")
     52 
     53 
     54 /* Local prototypes */
     55 
     56 static void
     57 AnAnalyzeStoreOperator (
     58     ACPI_PARSE_OBJECT       *Op);
     59 
     60 
     61 /*******************************************************************************
     62  *
     63  * FUNCTION:    AnMethodTypingWalkEnd
     64  *
     65  * PARAMETERS:  ASL_WALK_CALLBACK
     66  *
     67  * RETURN:      Status
     68  *
     69  * DESCRIPTION: Ascending callback for typing walk. Complete the method
     70  *              return analysis. Check methods for:
     71  *              1) Initialized local variables
     72  *              2) Valid arguments
     73  *              3) Return types
     74  *
     75  ******************************************************************************/
     76 
     77 ACPI_STATUS
     78 AnMethodTypingWalkEnd (
     79     ACPI_PARSE_OBJECT       *Op,
     80     UINT32                  Level,
     81     void                    *Context)
     82 {
     83     UINT32                  ThisOpBtype;
     84 
     85 
     86     switch (Op->Asl.ParseOpcode)
     87     {
     88     case PARSEOP_METHOD:
     89 
     90         Op->Asl.CompileFlags |= NODE_METHOD_TYPED;
     91         break;
     92 
     93     case PARSEOP_RETURN:
     94 
     95         if ((Op->Asl.Child) &&
     96             (Op->Asl.Child->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG))
     97         {
     98             ThisOpBtype = AnGetBtype (Op->Asl.Child);
     99 
    100             if ((Op->Asl.Child->Asl.ParseOpcode == PARSEOP_METHODCALL) &&
    101                 (ThisOpBtype == (ACPI_UINT32_MAX -1)))
    102             {
    103                 /*
    104                  * The called method is untyped at this time (typically a
    105                  * forward reference).
    106                  *
    107                  * Check for a recursive method call first.
    108                  */
    109                 if (Op->Asl.ParentMethod != Op->Asl.Child->Asl.Node->Op)
    110                 {
    111                     /* We must type the method here */
    112 
    113                     TrWalkParseTree (Op->Asl.Child->Asl.Node->Op,
    114                         ASL_WALK_VISIT_UPWARD, NULL,
    115                         AnMethodTypingWalkEnd, NULL);
    116 
    117                     ThisOpBtype = AnGetBtype (Op->Asl.Child);
    118                 }
    119             }
    120 
    121             /* Returns a value, save the value type */
    122 
    123             if (Op->Asl.ParentMethod)
    124             {
    125                 Op->Asl.ParentMethod->Asl.AcpiBtype |= ThisOpBtype;
    126             }
    127         }
    128         break;
    129 
    130     default:
    131 
    132         break;
    133     }
    134 
    135     return (AE_OK);
    136 }
    137 
    138 
    139 /*******************************************************************************
    140  *
    141  * FUNCTION:    AnOperandTypecheckWalkEnd
    142  *
    143  * PARAMETERS:  ASL_WALK_CALLBACK
    144  *
    145  * RETURN:      Status
    146  *
    147  * DESCRIPTION: Ascending callback for analysis walk. Complete method
    148  *              return analysis.
    149  *
    150  ******************************************************************************/
    151 
    152 ACPI_STATUS
    153 AnOperandTypecheckWalkEnd (
    154     ACPI_PARSE_OBJECT       *Op,
    155     UINT32                  Level,
    156     void                    *Context)
    157 {
    158     const ACPI_OPCODE_INFO  *OpInfo;
    159     UINT32                  RuntimeArgTypes;
    160     UINT32                  RuntimeArgTypes2;
    161     UINT32                  RequiredBtypes;
    162     UINT32                  ThisNodeBtype;
    163     UINT32                  CommonBtypes;
    164     UINT32                  OpcodeClass;
    165     ACPI_PARSE_OBJECT       *ArgOp;
    166     UINT32                  ArgType;
    167 
    168 
    169     switch (Op->Asl.AmlOpcode)
    170     {
    171     case AML_RAW_DATA_BYTE:
    172     case AML_RAW_DATA_WORD:
    173     case AML_RAW_DATA_DWORD:
    174     case AML_RAW_DATA_QWORD:
    175     case AML_RAW_DATA_BUFFER:
    176     case AML_RAW_DATA_CHAIN:
    177     case AML_PACKAGE_LENGTH:
    178     case AML_UNASSIGNED_OPCODE:
    179     case AML_DEFAULT_ARG_OP:
    180 
    181         /* Ignore the internal (compiler-only) AML opcodes */
    182 
    183         return (AE_OK);
    184 
    185     default:
    186 
    187         break;
    188     }
    189 
    190     OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
    191     if (!OpInfo)
    192     {
    193         return (AE_OK);
    194     }
    195 
    196     ArgOp = Op->Asl.Child;
    197     OpcodeClass = OpInfo->Class;
    198     RuntimeArgTypes = OpInfo->RuntimeArgs;
    199 
    200 #ifdef ASL_ERROR_NAMED_OBJECT_IN_WHILE
    201     /*
    202      * Update 11/2008: In practice, we can't perform this check. A simple
    203      * analysis is not sufficient. Also, it can cause errors when compiling
    204      * disassembled code because of the way Switch operators are implemented
    205      * (a While(One) loop with a named temp variable created within.)
    206      */
    207 
    208     /*
    209      * If we are creating a named object, check if we are within a while loop
    210      * by checking if the parent is a WHILE op. This is a simple analysis, but
    211      * probably sufficient for many cases.
    212      *
    213      * Allow Scope(), Buffer(), and Package().
    214      */
    215     if (((OpcodeClass == AML_CLASS_NAMED_OBJECT) && (Op->Asl.AmlOpcode != AML_SCOPE_OP)) ||
    216         ((OpcodeClass == AML_CLASS_CREATE) && (OpInfo->Flags & AML_NSNODE)))
    217     {
    218         if (Op->Asl.Parent->Asl.AmlOpcode == AML_WHILE_OP)
    219         {
    220             AslError (ASL_ERROR, ASL_MSG_NAMED_OBJECT_IN_WHILE, Op, NULL);
    221         }
    222     }
    223 #endif
    224 
    225     /*
    226      * Special case for control opcodes IF/RETURN/WHILE since they
    227      * have no runtime arg list (at this time)
    228      */
    229     switch (Op->Asl.AmlOpcode)
    230     {
    231     case AML_IF_OP:
    232     case AML_WHILE_OP:
    233     case AML_RETURN_OP:
    234 
    235         if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL)
    236         {
    237             /* Check for an internal method */
    238 
    239             if (AnIsInternalMethod (ArgOp))
    240             {
    241                 return (AE_OK);
    242             }
    243 
    244             /* The lone arg is a method call, check it */
    245 
    246             RequiredBtypes = AnMapArgTypeToBtype (ARGI_INTEGER);
    247             if (Op->Asl.AmlOpcode == AML_RETURN_OP)
    248             {
    249                 RequiredBtypes = 0xFFFFFFFF;
    250             }
    251 
    252             ThisNodeBtype = AnGetBtype (ArgOp);
    253             if (ThisNodeBtype == ACPI_UINT32_MAX)
    254             {
    255                 return (AE_OK);
    256             }
    257 
    258             AnCheckMethodReturnValue (Op, OpInfo, ArgOp,
    259                 RequiredBtypes, ThisNodeBtype);
    260         }
    261         return (AE_OK);
    262 
    263     case AML_EXTERNAL_OP:
    264         /*
    265          * Not really a "runtime" opcode since it used by disassembler only.
    266          * The parser will find any issues with the operands.
    267          */
    268         return (AE_OK);
    269 
    270     default:
    271 
    272         break;
    273     }
    274 
    275     /* Ignore the non-executable opcodes */
    276 
    277     if (RuntimeArgTypes == ARGI_INVALID_OPCODE)
    278     {
    279         return (AE_OK);
    280     }
    281 
    282     /*
    283      * Special handling for certain opcodes.
    284      */
    285     switch (Op->Asl.AmlOpcode)
    286     {
    287         /* BankField has one TermArg */
    288 
    289     case AML_BANK_FIELD_OP:
    290 
    291         OpcodeClass = AML_CLASS_EXECUTE;
    292         ArgOp = ArgOp->Asl.Next;
    293         ArgOp = ArgOp->Asl.Next;
    294         break;
    295 
    296         /* Operation Region has 2 TermArgs */
    297 
    298     case AML_REGION_OP:
    299 
    300         OpcodeClass = AML_CLASS_EXECUTE;
    301         ArgOp = ArgOp->Asl.Next;
    302         ArgOp = ArgOp->Asl.Next;
    303         break;
    304 
    305         /* DataTableRegion has 3 TermArgs */
    306 
    307     case AML_DATA_REGION_OP:
    308 
    309         OpcodeClass = AML_CLASS_EXECUTE;
    310         ArgOp = ArgOp->Asl.Next;
    311         break;
    312 
    313         /* Buffers/Packages have a length that is a TermArg */
    314 
    315     case AML_BUFFER_OP:
    316     case AML_PACKAGE_OP:
    317     case AML_VAR_PACKAGE_OP:
    318 
    319             /* If length is a constant, we are done */
    320 
    321         if ((ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER) ||
    322             (ArgOp->Asl.ParseOpcode == PARSEOP_RAW_DATA))
    323         {
    324             return (AE_OK);
    325         }
    326         break;
    327 
    328         /* Store can write any object to the Debug object */
    329 
    330     case AML_STORE_OP:
    331         /*
    332          * If this is a Store() to the Debug object, we don't need
    333          * to perform any further validation -- because a Store of
    334          * any object to Debug is permitted and supported.
    335          */
    336         if (ArgOp->Asl.Next->Asl.AmlOpcode == AML_DEBUG_OP)
    337         {
    338             return (AE_OK);
    339         }
    340         break;
    341 
    342     default:
    343         break;
    344     }
    345 
    346     switch (OpcodeClass)
    347     {
    348     case AML_CLASS_EXECUTE:
    349     case AML_CLASS_CREATE:
    350     case AML_CLASS_CONTROL:
    351     case AML_CLASS_RETURN_VALUE:
    352 
    353         /* Reverse the runtime argument list */
    354 
    355         RuntimeArgTypes2 = 0;
    356         while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes)))
    357         {
    358             RuntimeArgTypes2 <<= ARG_TYPE_WIDTH;
    359             RuntimeArgTypes2 |= ArgType;
    360             INCREMENT_ARG_LIST (RuntimeArgTypes);
    361         }
    362 
    363         /* Typecheck each argument */
    364 
    365         while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes2)))
    366         {
    367             /* Get the required type(s) for the argument */
    368 
    369             RequiredBtypes = AnMapArgTypeToBtype (ArgType);
    370 
    371             if (!ArgOp)
    372             {
    373                 AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op,
    374                     "Null ArgOp in argument loop");
    375                 AslAbort ();
    376             }
    377 
    378             /* Get the actual type of the argument */
    379 
    380             ThisNodeBtype = AnGetBtype (ArgOp);
    381             if (ThisNodeBtype == ACPI_UINT32_MAX)
    382             {
    383                 goto NextArgument;
    384             }
    385 
    386             /* Examine the arg based on the required type of the arg */
    387 
    388             switch (ArgType)
    389             {
    390             case ARGI_TARGETREF:
    391 
    392                 if (ArgOp->Asl.ParseOpcode == PARSEOP_ZERO)
    393                 {
    394                     /* ZERO is the placeholder for "don't store result" */
    395 
    396                     ThisNodeBtype = RequiredBtypes;
    397                     break;
    398                 }
    399 
    400             /* Fallthrough */
    401 
    402             case ARGI_STORE_TARGET:
    403 
    404                 if (ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER)
    405                 {
    406                     /*
    407                      * This is the case where an original reference to a resource
    408                      * descriptor field has been replaced by an (Integer) offset.
    409                      * These named fields are supported at compile-time only;
    410                      * the names are not passed to the interpreter (via the AML).
    411                      */
    412                     if ((ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE_FIELD) ||
    413                         (ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE))
    414                     {
    415                         AslError (ASL_ERROR, ASL_MSG_RESOURCE_FIELD,
    416                             ArgOp, NULL);
    417                     }
    418                     else
    419                     {
    420                         AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE,
    421                             ArgOp, NULL);
    422                     }
    423                 }
    424                 break;
    425 
    426 
    427 #ifdef __FUTURE_IMPLEMENTATION
    428 /*
    429  * Possible future typechecking support
    430  */
    431             case ARGI_REFERENCE:            /* References */
    432             case ARGI_INTEGER_REF:
    433             case ARGI_OBJECT_REF:
    434             case ARGI_DEVICE_REF:
    435 
    436                 switch (ArgOp->Asl.ParseOpcode)
    437                 {
    438                 case PARSEOP_LOCAL0:
    439                 case PARSEOP_LOCAL1:
    440                 case PARSEOP_LOCAL2:
    441                 case PARSEOP_LOCAL3:
    442                 case PARSEOP_LOCAL4:
    443                 case PARSEOP_LOCAL5:
    444                 case PARSEOP_LOCAL6:
    445                 case PARSEOP_LOCAL7:
    446 
    447                     /* TBD: implement analysis of current value (type) of the local */
    448                     /* For now, just treat any local as a typematch */
    449 
    450                     /*ThisNodeBtype = RequiredBtypes;*/
    451                     break;
    452 
    453                 case PARSEOP_ARG0:
    454                 case PARSEOP_ARG1:
    455                 case PARSEOP_ARG2:
    456                 case PARSEOP_ARG3:
    457                 case PARSEOP_ARG4:
    458                 case PARSEOP_ARG5:
    459                 case PARSEOP_ARG6:
    460 
    461                     /* Hard to analyze argument types, so we won't */
    462                     /* for now. Just treat any arg as a typematch */
    463 
    464                     /* ThisNodeBtype = RequiredBtypes; */
    465                     break;
    466 
    467                 case PARSEOP_DEBUG:
    468                 case PARSEOP_REFOF:
    469                 case PARSEOP_INDEX:
    470                 default:
    471 
    472                     break;
    473                 }
    474                 break;
    475 #endif
    476             case ARGI_INTEGER:
    477             default:
    478 
    479                 break;
    480             }
    481 
    482 
    483             /* Check for a type mismatch (required versus actual) */
    484 
    485             CommonBtypes = ThisNodeBtype & RequiredBtypes;
    486 
    487             if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL)
    488             {
    489                 if (AnIsInternalMethod (ArgOp))
    490                 {
    491                     return (AE_OK);
    492                 }
    493 
    494                 /* Check a method call for a valid return value */
    495 
    496                 AnCheckMethodReturnValue (Op, OpInfo, ArgOp,
    497                     RequiredBtypes, ThisNodeBtype);
    498             }
    499 
    500             /*
    501              * Now check if the actual type(s) match at least one
    502              * bit to the required type
    503              */
    504             else if (!CommonBtypes)
    505             {
    506                 /* No match -- this is a type mismatch error */
    507 
    508                 AnFormatBtype (StringBuffer, ThisNodeBtype);
    509                 AnFormatBtype (StringBuffer2, RequiredBtypes);
    510 
    511                 sprintf (MsgBuffer, "[%s] found, %s operator requires [%s]",
    512                     StringBuffer, OpInfo->Name, StringBuffer2);
    513 
    514                 AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE,
    515                     ArgOp, MsgBuffer);
    516             }
    517 
    518         NextArgument:
    519             ArgOp = ArgOp->Asl.Next;
    520             INCREMENT_ARG_LIST (RuntimeArgTypes2);
    521         }
    522         break;
    523 
    524     default:
    525 
    526         break;
    527     }
    528 
    529     return (AE_OK);
    530 }
    531 
    532 
    533 /*******************************************************************************
    534  *
    535  * FUNCTION:    AnOtherSemanticAnalysisWalkBegin
    536  *
    537  * PARAMETERS:  ASL_WALK_CALLBACK
    538  *
    539  * RETURN:      Status
    540  *
    541  * DESCRIPTION: Descending callback for the analysis walk. Checks for
    542  *              miscellaneous issues in the code.
    543  *
    544  ******************************************************************************/
    545 
    546 ACPI_STATUS
    547 AnOtherSemanticAnalysisWalkBegin (
    548     ACPI_PARSE_OBJECT       *Op,
    549     UINT32                  Level,
    550     void                    *Context)
    551 {
    552     ACPI_PARSE_OBJECT       *ArgOp;
    553     ACPI_PARSE_OBJECT       *PrevArgOp = NULL;
    554     const ACPI_OPCODE_INFO  *OpInfo;
    555     ACPI_NAMESPACE_NODE     *Node;
    556 
    557 
    558     OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
    559 
    560 
    561     /*
    562      * Determine if an execution class operator actually does something by
    563      * checking if it has a target and/or the function return value is used.
    564      * (Target is optional, so a standalone statement can actually do nothing.)
    565      */
    566     if ((OpInfo->Class == AML_CLASS_EXECUTE) &&
    567         (OpInfo->Flags & AML_HAS_RETVAL) &&
    568         (!AnIsResultUsed (Op)))
    569     {
    570         if (OpInfo->Flags & AML_HAS_TARGET)
    571         {
    572             /*
    573              * Find the target node, it is always the last child. If the target
    574              * is not specified in the ASL, a default node of type Zero was
    575              * created by the parser.
    576              */
    577             ArgOp = Op->Asl.Child;
    578             while (ArgOp->Asl.Next)
    579             {
    580                 PrevArgOp = ArgOp;
    581                 ArgOp = ArgOp->Asl.Next;
    582             }
    583 
    584             /* Divide() is the only weird case, it has two targets */
    585 
    586             if (Op->Asl.AmlOpcode == AML_DIVIDE_OP)
    587             {
    588                 if ((ArgOp->Asl.ParseOpcode == PARSEOP_ZERO) &&
    589                     (PrevArgOp) &&
    590                     (PrevArgOp->Asl.ParseOpcode == PARSEOP_ZERO))
    591                 {
    592                     AslError (ASL_ERROR, ASL_MSG_RESULT_NOT_USED,
    593                         Op, Op->Asl.ExternalName);
    594                 }
    595             }
    596 
    597             else if (ArgOp->Asl.ParseOpcode == PARSEOP_ZERO)
    598             {
    599                 AslError (ASL_ERROR, ASL_MSG_RESULT_NOT_USED,
    600                     Op, Op->Asl.ExternalName);
    601             }
    602         }
    603         else
    604         {
    605             /*
    606              * Has no target and the result is not used. Only a couple opcodes
    607              * can have this combination.
    608              */
    609             switch (Op->Asl.ParseOpcode)
    610             {
    611             case PARSEOP_ACQUIRE:
    612             case PARSEOP_WAIT:
    613             case PARSEOP_LOADTABLE:
    614 
    615                 break;
    616 
    617             default:
    618 
    619                 AslError (ASL_ERROR, ASL_MSG_RESULT_NOT_USED,
    620                     Op, Op->Asl.ExternalName);
    621                 break;
    622             }
    623         }
    624     }
    625 
    626 
    627     /*
    628      * Semantic checks for individual ASL operators
    629      */
    630     switch (Op->Asl.ParseOpcode)
    631     {
    632     case PARSEOP_STORE:
    633 
    634         if (Gbl_DoTypechecking)
    635         {
    636             AnAnalyzeStoreOperator (Op);
    637         }
    638         break;
    639 
    640 
    641     case PARSEOP_ACQUIRE:
    642     case PARSEOP_WAIT:
    643         /*
    644          * Emit a warning if the timeout parameter for these operators is not
    645          * ACPI_WAIT_FOREVER, and the result value from the operator is not
    646          * checked, meaning that a timeout could happen, but the code
    647          * would not know about it.
    648          */
    649 
    650         /* First child is the namepath, 2nd child is timeout */
    651 
    652         ArgOp = Op->Asl.Child;
    653         ArgOp = ArgOp->Asl.Next;
    654 
    655         /*
    656          * Check for the WAIT_FOREVER case - defined by the ACPI spec to be
    657          * 0xFFFF or greater
    658          */
    659         if (((ArgOp->Asl.ParseOpcode == PARSEOP_WORDCONST) ||
    660              (ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER))  &&
    661              (ArgOp->Asl.Value.Integer >= (UINT64) ACPI_WAIT_FOREVER))
    662         {
    663             break;
    664         }
    665 
    666         /*
    667          * The operation could timeout. If the return value is not used
    668          * (indicates timeout occurred), issue a warning
    669          */
    670         if (!AnIsResultUsed (Op))
    671         {
    672             AslError (ASL_WARNING, ASL_MSG_TIMEOUT, ArgOp,
    673                 Op->Asl.ExternalName);
    674         }
    675         break;
    676 
    677     case PARSEOP_CREATEFIELD:
    678         /*
    679          * Check for a zero Length (NumBits) operand. NumBits is the 3rd operand
    680          */
    681         ArgOp = Op->Asl.Child;
    682         ArgOp = ArgOp->Asl.Next;
    683         ArgOp = ArgOp->Asl.Next;
    684 
    685         if ((ArgOp->Asl.ParseOpcode == PARSEOP_ZERO) ||
    686            ((ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER) &&
    687             (ArgOp->Asl.Value.Integer == 0)))
    688         {
    689             AslError (ASL_ERROR, ASL_MSG_NON_ZERO, ArgOp, NULL);
    690         }
    691         break;
    692 
    693     case PARSEOP_CONNECTION:
    694         /*
    695          * Ensure that the referenced operation region has the correct SPACE_ID.
    696          * From the grammar/parser, we know the parent is a FIELD definition.
    697          */
    698         ArgOp = Op->Asl.Parent;     /* Field definition */
    699         ArgOp = ArgOp->Asl.Child;   /* First child is the OpRegion Name */
    700         Node = ArgOp->Asl.Node;     /* OpRegion namespace node */
    701         if (!Node)
    702         {
    703             break;
    704         }
    705 
    706         ArgOp = Node->Op;           /* OpRegion definition */
    707         ArgOp = ArgOp->Asl.Child;   /* First child is the OpRegion Name */
    708         ArgOp = ArgOp->Asl.Next;    /* Next peer is the SPACE_ID (what we want) */
    709 
    710         /*
    711          * The Connection() operator is only valid for the following operation
    712          * region SpaceIds: GeneralPurposeIo and GenericSerialBus.
    713          */
    714         if ((ArgOp->Asl.Value.Integer != ACPI_ADR_SPACE_GPIO) &&
    715             (ArgOp->Asl.Value.Integer != ACPI_ADR_SPACE_GSBUS))
    716         {
    717             AslError (ASL_ERROR, ASL_MSG_CONNECTION_INVALID, Op, NULL);
    718         }
    719         break;
    720 
    721     case PARSEOP_FIELD:
    722         /*
    723          * Ensure that fields for GeneralPurposeIo and GenericSerialBus
    724          * contain at least one Connection() operator
    725          */
    726         ArgOp = Op->Asl.Child;      /* 1st child is the OpRegion Name */
    727         Node = ArgOp->Asl.Node;     /* OpRegion namespace node */
    728         if (!Node)
    729         {
    730             break;
    731         }
    732 
    733         ArgOp = Node->Op;           /* OpRegion definition */
    734         ArgOp = ArgOp->Asl.Child;   /* First child is the OpRegion Name */
    735         ArgOp = ArgOp->Asl.Next;    /* Next peer is the SPACE_ID (what we want) */
    736 
    737         /* We are only interested in GeneralPurposeIo and GenericSerialBus */
    738 
    739         if ((ArgOp->Asl.Value.Integer != ACPI_ADR_SPACE_GPIO) &&
    740             (ArgOp->Asl.Value.Integer != ACPI_ADR_SPACE_GSBUS))
    741         {
    742             break;
    743         }
    744 
    745         ArgOp = Op->Asl.Child;      /* 1st child is the OpRegion Name */
    746         ArgOp = ArgOp->Asl.Next;    /* AccessType */
    747         ArgOp = ArgOp->Asl.Next;    /* LockRule */
    748         ArgOp = ArgOp->Asl.Next;    /* UpdateRule */
    749         ArgOp = ArgOp->Asl.Next;    /* Start of FieldUnitList */
    750 
    751         /* Walk the FieldUnitList */
    752 
    753         while (ArgOp)
    754         {
    755             if (ArgOp->Asl.ParseOpcode == PARSEOP_CONNECTION)
    756             {
    757                 break;
    758             }
    759             else if (ArgOp->Asl.ParseOpcode == PARSEOP_NAMESEG)
    760             {
    761                 AslError (ASL_ERROR, ASL_MSG_CONNECTION_MISSING, ArgOp, NULL);
    762                 break;
    763             }
    764 
    765             ArgOp = ArgOp->Asl.Next;
    766         }
    767         break;
    768 
    769     default:
    770 
    771         break;
    772     }
    773 
    774     return (AE_OK);
    775 }
    776 
    777 
    778 /*******************************************************************************
    779  *
    780  * FUNCTION:    AnAnalyzeStoreOperator
    781  *
    782  * PARAMETERS:  Op                  - Store() operator
    783  *
    784  * RETURN:      None
    785  *
    786  * DESCRIPTION: Analyze a store operator. Mostly for stores to/from package
    787  *              objects where there are more restrictions than other data
    788  *              types.
    789  *
    790  ******************************************************************************/
    791 
    792 static void
    793 AnAnalyzeStoreOperator (
    794     ACPI_PARSE_OBJECT       *Op)
    795 {
    796     ACPI_NAMESPACE_NODE     *SourceNode;
    797     ACPI_NAMESPACE_NODE     *TargetNode;
    798     ACPI_PARSE_OBJECT       *SourceOperandOp;
    799     ACPI_PARSE_OBJECT       *TargetOperandOp;
    800     UINT32                  SourceOperandBtype;
    801     UINT32                  TargetOperandBtype;
    802 
    803 
    804     /* Extract the two operands for STORE */
    805 
    806     SourceOperandOp = Op->Asl.Child;
    807     TargetOperandOp = SourceOperandOp->Asl.Next;
    808 
    809     /*
    810      * Ignore these Source operand opcodes, they cannot be typechecked,
    811      * the actual result is unknown here.
    812      */
    813     switch (SourceOperandOp->Asl.ParseOpcode)
    814     {
    815     /* For these, type of the returned value is unknown at compile time */
    816 
    817     case PARSEOP_DEREFOF:
    818     case PARSEOP_METHODCALL:
    819     case PARSEOP_STORE:
    820     case PARSEOP_COPYOBJECT:
    821 
    822         return;
    823 
    824     case PARSEOP_INDEX:
    825     case PARSEOP_REFOF:
    826 
    827         if (!Gbl_EnableReferenceTypechecking)
    828         {
    829             return;
    830         }
    831 
    832         /*
    833          * These opcodes always return an object reference, and thus
    834          * the result can only be stored to a Local, Arg, or Debug.
    835          */
    836         if (TargetOperandOp->Asl.AmlOpcode == AML_DEBUG_OP)
    837         {
    838             return;
    839         }
    840 
    841         if ((TargetOperandOp->Asl.AmlOpcode < AML_LOCAL0) ||
    842             (TargetOperandOp->Asl.AmlOpcode > AML_ARG6))
    843         {
    844             AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, TargetOperandOp,
    845                 "Source [Reference], Target must be [Local/Arg/Debug]");
    846         }
    847         return;
    848 
    849     default:
    850         break;
    851     }
    852 
    853     /*
    854      * Ignore these Target operand opcodes, they cannot be typechecked
    855      */
    856     switch (TargetOperandOp->Asl.ParseOpcode)
    857     {
    858     case PARSEOP_DEBUG:
    859     case PARSEOP_DEREFOF:
    860     case PARSEOP_REFOF:
    861     case PARSEOP_INDEX:
    862     case PARSEOP_METHODCALL:
    863 
    864         return;
    865 
    866     default:
    867         break;
    868     }
    869 
    870     /*
    871      * Ignore typecheck for External() operands of type "UnknownObj",
    872      * we don't know the actual type (source or target).
    873      */
    874     SourceNode = SourceOperandOp->Asl.Node;
    875     if (SourceNode &&
    876         (SourceNode->Flags & ANOBJ_IS_EXTERNAL) &&
    877         (SourceNode->Type == ACPI_TYPE_ANY))
    878     {
    879         return;
    880     }
    881 
    882     TargetNode = TargetOperandOp->Asl.Node;
    883     if (TargetNode &&
    884         (TargetNode->Flags & ANOBJ_IS_EXTERNAL) &&
    885         (TargetNode->Type == ACPI_TYPE_ANY))
    886     {
    887         return;
    888     }
    889 
    890     /*
    891      * A NULL node with a namepath AML opcode indicates non-existent
    892      * name. Just return, the error message is generated elsewhere.
    893      */
    894     if ((!SourceNode && (SourceOperandOp->Asl.AmlOpcode == AML_INT_NAMEPATH_OP)) ||
    895         (!TargetNode && (TargetOperandOp->Asl.AmlOpcode == AML_INT_NAMEPATH_OP)))
    896     {
    897         return;
    898     }
    899 
    900     /*
    901      * Simple check for source same as target via NS node.
    902      * -- Could be expanded to locals and args.
    903      */
    904     if (SourceNode && TargetNode)
    905     {
    906         if (SourceNode == TargetNode)
    907         {
    908             AslError (ASL_WARNING, ASL_MSG_DUPLICATE_ITEM,
    909                 TargetOperandOp, "Source is the same as Target");
    910             return;
    911         }
    912     }
    913 
    914     /* Ignore typecheck if either source or target is a local or arg */
    915 
    916     if ((SourceOperandOp->Asl.AmlOpcode >= AML_LOCAL0) &&
    917         (SourceOperandOp->Asl.AmlOpcode <= AML_ARG6))
    918     {
    919         return; /* Cannot type a local/arg at compile time */
    920     }
    921 
    922     if ((TargetOperandOp->Asl.AmlOpcode >= AML_LOCAL0) &&
    923         (TargetOperandOp->Asl.AmlOpcode <= AML_ARG6))
    924     {
    925         return; /* Cannot type a local/arg at compile time */
    926     }
    927 
    928     /*
    929      * Package objects are a special case because they cannot by implicitly
    930      * converted to/from anything. Check for these two illegal cases:
    931      *
    932      *      Store (non-package, package)
    933      *      Store (package, non-package)
    934      */
    935     SourceOperandBtype = AnGetBtype (SourceOperandOp);
    936     TargetOperandBtype = AnGetBtype (TargetOperandOp);
    937 
    938     /* Check source first for (package, non-package) case */
    939 
    940     if (SourceOperandBtype & ACPI_BTYPE_PACKAGE)
    941     {
    942         /* If Source is PACKAGE-->Target must be PACKAGE */
    943 
    944         if (!(TargetOperandBtype & ACPI_BTYPE_PACKAGE))
    945         {
    946             AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, TargetOperandOp,
    947                 "Source is [Package], Target must be a package also");
    948         }
    949     }
    950 
    951     /* Else check target for (non-package, package) case */
    952 
    953     else if (TargetOperandBtype & ACPI_BTYPE_PACKAGE)
    954     {
    955         /* If Target is PACKAGE, Source must be PACKAGE */
    956 
    957         if (!(SourceOperandBtype & ACPI_BTYPE_PACKAGE))
    958         {
    959             AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, SourceOperandOp,
    960                 "Target is [Package], Source must be a package also");
    961         }
    962     }
    963 }
    964