Home | History | Annotate | Line # | Download | only in compiler
asloperands.c revision 1.1.1.8
      1 /******************************************************************************
      2  *
      3  * Module Name: asloperands - AML operand processing
      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 "amlcode.h"
     47 
     48 #define _COMPONENT          ACPI_COMPILER
     49         ACPI_MODULE_NAME    ("asloperands")
     50 
     51 /* Local prototypes */
     52 
     53 static void
     54 OpnDoField (
     55     ACPI_PARSE_OBJECT       *Op);
     56 
     57 static void
     58 OpnDoBankField (
     59     ACPI_PARSE_OBJECT       *Op);
     60 
     61 static void
     62 OpnDoBuffer (
     63     ACPI_PARSE_OBJECT       *Op);
     64 
     65 static void
     66 OpnDoDefinitionBlock (
     67     ACPI_PARSE_OBJECT       *Op);
     68 
     69 static void
     70 OpnDoFieldCommon (
     71     ACPI_PARSE_OBJECT       *FieldOp,
     72     ACPI_PARSE_OBJECT       *Op);
     73 
     74 static void
     75 OpnDoIndexField (
     76     ACPI_PARSE_OBJECT       *Op);
     77 
     78 static void
     79 OpnDoLoadTable (
     80     ACPI_PARSE_OBJECT       *Op);
     81 
     82 static void
     83 OpnDoMethod (
     84     ACPI_PARSE_OBJECT       *Op);
     85 
     86 static void
     87 OpnDoMutex (
     88     ACPI_PARSE_OBJECT       *Op);
     89 
     90 static void
     91 OpnDoRegion (
     92     ACPI_PARSE_OBJECT       *Op);
     93 
     94 static void
     95 OpnAttachNameToNode (
     96     ACPI_PARSE_OBJECT       *Op);
     97 
     98 
     99 /*******************************************************************************
    100  *
    101  * FUNCTION:    OpnDoMutex
    102  *
    103  * PARAMETERS:  Op        - The parent parse node
    104  *
    105  * RETURN:      None
    106  *
    107  * DESCRIPTION: Construct the operands for the MUTEX ASL keyword.
    108  *
    109  ******************************************************************************/
    110 
    111 static void
    112 OpnDoMutex (
    113     ACPI_PARSE_OBJECT       *Op)
    114 {
    115     ACPI_PARSE_OBJECT       *Next;
    116 
    117 
    118     Next = Op->Asl.Child;
    119     Next = Next->Asl.Next;
    120 
    121     if (Next->Asl.Value.Integer > 15)
    122     {
    123         AslError (ASL_ERROR, ASL_MSG_SYNC_LEVEL, Next, NULL);
    124     }
    125     return;
    126 }
    127 
    128 
    129 /*******************************************************************************
    130  *
    131  * FUNCTION:    OpnDoMethod
    132  *
    133  * PARAMETERS:  Op        - The parent parse node
    134  *
    135  * RETURN:      None
    136  *
    137  * DESCRIPTION: Construct the operands for the METHOD ASL keyword.
    138  *
    139  ******************************************************************************/
    140 
    141 static void
    142 OpnDoMethod (
    143     ACPI_PARSE_OBJECT       *Op)
    144 {
    145     ACPI_PARSE_OBJECT       *Next;
    146 
    147     /* Optional arguments for this opcode with defaults */
    148 
    149     UINT8                   NumArgs = 0;
    150     UINT8                   Serialized = 0;
    151     UINT8                   Concurrency = 0;
    152     UINT8                   MethodFlags;
    153 
    154 
    155     /* Opcode and package length first */
    156     /* Method name */
    157 
    158     Next = Op->Asl.Child;
    159 
    160     /* Num args */
    161 
    162     Next = Next->Asl.Next;
    163     if (Next->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
    164     {
    165         NumArgs = (UINT8) Next->Asl.Value.Integer;
    166         Next->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
    167     }
    168 
    169     /* Serialized Flag */
    170 
    171     Next = Next->Asl.Next;
    172     if (Next->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
    173     {
    174         Serialized = (UINT8) Next->Asl.Value.Integer;
    175         Next->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
    176     }
    177 
    178     /* Concurrency value (valid values are 0-15) */
    179 
    180     Next = Next->Asl.Next;
    181     if (Next->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
    182     {
    183         /* This is a ByteConstExpr, so eval the constant now */
    184 
    185         OpcAmlConstantWalk (Next, 0, NULL);
    186 
    187         if (Next->Asl.Value.Integer > 15)
    188         {
    189             AslError (ASL_ERROR, ASL_MSG_SYNC_LEVEL, Next, NULL);
    190         }
    191 
    192         Concurrency = (UINT8) Next->Asl.Value.Integer;
    193     }
    194 
    195     /* Put the bits in their proper places */
    196 
    197     MethodFlags = (UINT8)
    198         ((NumArgs & 0x7) |
    199         ((Serialized & 0x1) << 3) |
    200         ((Concurrency & 0xF) << 4));
    201 
    202     /* Use the last node for the combined flags byte */
    203 
    204     Next->Asl.Value.Integer = MethodFlags;
    205     Next->Asl.AmlOpcode = AML_RAW_DATA_BYTE;
    206     Next->Asl.AmlLength = 1;
    207     Next->Asl.ParseOpcode = PARSEOP_RAW_DATA;
    208 
    209     /* Save the arg count in the first node */
    210 
    211     Op->Asl.Extra = NumArgs;
    212 }
    213 
    214 
    215 /*******************************************************************************
    216  *
    217  * FUNCTION:    OpnDoFieldCommon
    218  *
    219  * PARAMETERS:  FieldOp       - Node for an ASL field
    220  *              Op            - The parent parse node
    221  *
    222  * RETURN:      None
    223  *
    224  * DESCRIPTION: Construct the AML operands for the various field keywords,
    225  *              FIELD, BANKFIELD, INDEXFIELD
    226  *
    227  ******************************************************************************/
    228 
    229 static void
    230 OpnDoFieldCommon (
    231     ACPI_PARSE_OBJECT       *FieldOp,
    232     ACPI_PARSE_OBJECT       *Op)
    233 {
    234     ACPI_PARSE_OBJECT       *Next;
    235     ACPI_PARSE_OBJECT       *PkgLengthNode;
    236     UINT32                  CurrentBitOffset;
    237     UINT32                  NewBitOffset;
    238     UINT8                   AccessType;
    239     UINT8                   LockRule;
    240     UINT8                   UpdateRule;
    241     UINT8                   FieldFlags;
    242     UINT32                  MinimumLength;
    243 
    244 
    245     /* AccessType -- not optional, so no need to check for DEFAULT_ARG */
    246 
    247     AccessType = (UINT8) Op->Asl.Value.Integer;
    248     Op->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
    249 
    250     /* Set the access type in the parent (field) node for use later */
    251 
    252     FieldOp->Asl.Value.Integer = AccessType;
    253 
    254     /* LockRule -- not optional, so no need to check for DEFAULT_ARG */
    255 
    256     Next = Op->Asl.Next;
    257     LockRule = (UINT8) Next->Asl.Value.Integer;
    258     Next->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
    259 
    260     /* UpdateRule -- not optional, so no need to check for DEFAULT_ARG */
    261 
    262     Next = Next->Asl.Next;
    263     UpdateRule = (UINT8) Next->Asl.Value.Integer;
    264 
    265     /*
    266      * Generate the flags byte. The various fields are already
    267      * in the right bit position via translation from the
    268      * keywords by the parser.
    269      */
    270     FieldFlags = (UINT8) (AccessType | LockRule | UpdateRule);
    271 
    272     /* Use the previous node to be the FieldFlags node */
    273 
    274     /* Set the node to RAW_DATA */
    275 
    276     Next->Asl.Value.Integer = FieldFlags;
    277     Next->Asl.AmlOpcode = AML_RAW_DATA_BYTE;
    278     Next->Asl.AmlLength = 1;
    279     Next->Asl.ParseOpcode = PARSEOP_RAW_DATA;
    280 
    281     /* Process the FieldUnitList */
    282 
    283     Next = Next->Asl.Next;
    284     CurrentBitOffset = 0;
    285 
    286     while (Next)
    287     {
    288         /* Save the offset of this field unit */
    289 
    290         Next->Asl.ExtraValue = CurrentBitOffset;
    291 
    292         switch (Next->Asl.ParseOpcode)
    293         {
    294         case PARSEOP_ACCESSAS:
    295 
    296             PkgLengthNode = Next->Asl.Child;
    297             AccessType = (UINT8) PkgLengthNode->Asl.Value.Integer;
    298 
    299             /* Nothing additional to do */
    300             break;
    301 
    302         case PARSEOP_OFFSET:
    303 
    304             /* New offset into the field */
    305 
    306             PkgLengthNode = Next->Asl.Child;
    307             NewBitOffset = ((UINT32) PkgLengthNode->Asl.Value.Integer) * 8;
    308 
    309             /*
    310              * Examine the specified offset in relation to the
    311              * current offset counter.
    312              */
    313             if (NewBitOffset < CurrentBitOffset)
    314             {
    315                 /*
    316                  * Not allowed to specify a backwards offset!
    317                  * Issue error and ignore this node.
    318                  */
    319                 AslError (ASL_ERROR, ASL_MSG_BACKWARDS_OFFSET, PkgLengthNode,
    320                     NULL);
    321                 Next->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
    322                 PkgLengthNode->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
    323             }
    324             else if (NewBitOffset == CurrentBitOffset)
    325             {
    326                 /*
    327                  * Offset is redundant; we don't need to output an
    328                  * offset opcode. Just set these nodes to default
    329                  */
    330                 Next->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
    331                 PkgLengthNode->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
    332             }
    333             else
    334             {
    335                 /*
    336                  * Valid new offset - set the value to be inserted into the AML
    337                  * and update the offset counter.
    338                  */
    339                 PkgLengthNode->Asl.Value.Integer =
    340                     NewBitOffset - CurrentBitOffset;
    341                 CurrentBitOffset = NewBitOffset;
    342             }
    343             break;
    344 
    345         case PARSEOP_NAMESEG:
    346         case PARSEOP_RESERVED_BYTES:
    347 
    348             /* Named or reserved field entry */
    349 
    350             PkgLengthNode = Next->Asl.Child;
    351             NewBitOffset = (UINT32) PkgLengthNode->Asl.Value.Integer;
    352             CurrentBitOffset += NewBitOffset;
    353 
    354             /* Save the current AccessAs value for error checking later */
    355 
    356             switch (AccessType)
    357             {
    358                 case AML_FIELD_ACCESS_ANY:
    359                 case AML_FIELD_ACCESS_BYTE:
    360                 case AML_FIELD_ACCESS_BUFFER:
    361                 default:
    362 
    363                     MinimumLength = 8;
    364                     break;
    365 
    366                 case AML_FIELD_ACCESS_WORD:
    367                     MinimumLength = 16;
    368                     break;
    369 
    370                 case AML_FIELD_ACCESS_DWORD:
    371                     MinimumLength = 32;
    372                     break;
    373 
    374                 case AML_FIELD_ACCESS_QWORD:
    375                     MinimumLength = 64;
    376                     break;
    377             }
    378 
    379             PkgLengthNode->Asl.ExtraValue = MinimumLength;
    380             break;
    381 
    382         default:
    383 
    384             /* All supported field opcodes must appear above */
    385 
    386             break;
    387         }
    388 
    389         /* Move on to next entry in the field list */
    390 
    391         Next = Next->Asl.Next;
    392     }
    393 }
    394 
    395 
    396 /*******************************************************************************
    397  *
    398  * FUNCTION:    OpnDoField
    399  *
    400  * PARAMETERS:  Op        - The parent parse node
    401  *
    402  * RETURN:      None
    403  *
    404  * DESCRIPTION: Construct the AML operands for the FIELD ASL keyword
    405  *
    406  ******************************************************************************/
    407 
    408 static void
    409 OpnDoField (
    410     ACPI_PARSE_OBJECT       *Op)
    411 {
    412     ACPI_PARSE_OBJECT       *Next;
    413 
    414 
    415     /* Opcode is parent node */
    416     /* First child is field name */
    417 
    418     Next = Op->Asl.Child;
    419 
    420     /* Second child is the AccessType */
    421 
    422     OpnDoFieldCommon (Op, Next->Asl.Next);
    423 }
    424 
    425 
    426 /*******************************************************************************
    427  *
    428  * FUNCTION:    OpnDoIndexField
    429  *
    430  * PARAMETERS:  Op        - The parent parse node
    431  *
    432  * RETURN:      None
    433  *
    434  * DESCRIPTION: Construct the AML operands for the INDEXFIELD ASL keyword
    435  *
    436  ******************************************************************************/
    437 
    438 static void
    439 OpnDoIndexField (
    440     ACPI_PARSE_OBJECT       *Op)
    441 {
    442     ACPI_PARSE_OBJECT       *Next;
    443 
    444 
    445     /* Opcode is parent node */
    446     /* First child is the index name */
    447 
    448     Next = Op->Asl.Child;
    449 
    450     /* Second child is the data name */
    451 
    452     Next = Next->Asl.Next;
    453 
    454     /* Third child is the AccessType */
    455 
    456     OpnDoFieldCommon (Op, Next->Asl.Next);
    457 }
    458 
    459 
    460 /*******************************************************************************
    461  *
    462  * FUNCTION:    OpnDoBankField
    463  *
    464  * PARAMETERS:  Op        - The parent parse node
    465  *
    466  * RETURN:      None
    467  *
    468  * DESCRIPTION: Construct the AML operands for the BANKFIELD ASL keyword
    469  *
    470  ******************************************************************************/
    471 
    472 static void
    473 OpnDoBankField (
    474     ACPI_PARSE_OBJECT       *Op)
    475 {
    476     ACPI_PARSE_OBJECT       *Next;
    477 
    478 
    479     /* Opcode is parent node */
    480     /* First child is the region name */
    481 
    482     Next = Op->Asl.Child;
    483 
    484     /* Second child is the bank name */
    485 
    486     Next = Next->Asl.Next;
    487 
    488     /* Third child is the bank value */
    489 
    490     Next = Next->Asl.Next;
    491 
    492     /* Fourth child is the AccessType */
    493 
    494     OpnDoFieldCommon (Op, Next->Asl.Next);
    495 }
    496 
    497 
    498 /*******************************************************************************
    499  *
    500  * FUNCTION:    OpnDoRegion
    501  *
    502  * PARAMETERS:  Op        - The parent parse node
    503  *
    504  * RETURN:      None
    505  *
    506  * DESCRIPTION: Tries to get the length of the region. Can only do this at
    507  *              compile time if the length is a constant.
    508  *
    509  ******************************************************************************/
    510 
    511 static void
    512 OpnDoRegion (
    513     ACPI_PARSE_OBJECT       *Op)
    514 {
    515     ACPI_PARSE_OBJECT       *Next;
    516 
    517 
    518     /* Opcode is parent node */
    519     /* First child is the region name */
    520 
    521     Next = Op->Asl.Child;
    522 
    523     /* Second child is the space ID*/
    524 
    525     Next = Next->Asl.Next;
    526 
    527     /* Third child is the region offset */
    528 
    529     Next = Next->Asl.Next;
    530 
    531     /* Fourth child is the region length */
    532 
    533     Next = Next->Asl.Next;
    534     if (Next->Asl.ParseOpcode == PARSEOP_INTEGER)
    535     {
    536         Op->Asl.Value.Integer = Next->Asl.Value.Integer;
    537     }
    538     else
    539     {
    540         Op->Asl.Value.Integer = ACPI_UINT64_MAX;
    541     }
    542 }
    543 
    544 
    545 /*******************************************************************************
    546  *
    547  * FUNCTION:    OpnDoBuffer
    548  *
    549  * PARAMETERS:  Op        - The parent parse node
    550  *
    551  * RETURN:      None
    552  *
    553  * DESCRIPTION: Construct the AML operands for the BUFFER ASL keyword. We
    554  *              build a single raw byte buffer from the initialization nodes,
    555  *              each parse node contains a buffer byte.
    556  *
    557  ******************************************************************************/
    558 
    559 static void
    560 OpnDoBuffer (
    561     ACPI_PARSE_OBJECT       *Op)
    562 {
    563     ACPI_PARSE_OBJECT       *InitializerOp;
    564     ACPI_PARSE_OBJECT       *BufferLengthOp;
    565 
    566     /* Optional arguments for this opcode with defaults */
    567 
    568     UINT32                  BufferLength = 0;
    569 
    570 
    571     /* Opcode and package length first */
    572     /* Buffer Length is next, followed by the initializer list */
    573 
    574     BufferLengthOp = Op->Asl.Child;
    575     InitializerOp = BufferLengthOp->Asl.Next;
    576 
    577     /*
    578      * If the BufferLength is not an INTEGER or was not specified in the ASL
    579      * (DEFAULT_ARG), it is a TermArg that is
    580      * evaluated at run-time, and we are therefore finished.
    581      */
    582     if ((BufferLengthOp->Asl.ParseOpcode != PARSEOP_INTEGER) &&
    583         (BufferLengthOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG))
    584     {
    585         return;
    586     }
    587 
    588     /*
    589      * We want to count the number of items in the initializer list, because if
    590      * it is larger than the buffer length, we will define the buffer size
    591      * to be the size of the initializer list (as per the ACPI Specification)
    592      */
    593     switch (InitializerOp->Asl.ParseOpcode)
    594     {
    595     case PARSEOP_INTEGER:
    596     case PARSEOP_BYTECONST:
    597     case PARSEOP_WORDCONST:
    598     case PARSEOP_DWORDCONST:
    599 
    600         /* The peer list contains the byte list (if any...) */
    601 
    602         while (InitializerOp)
    603         {
    604             /* For buffers, this is a list of raw bytes */
    605 
    606             InitializerOp->Asl.AmlOpcode = AML_RAW_DATA_BYTE;
    607             InitializerOp->Asl.AmlLength = 1;
    608             InitializerOp->Asl.ParseOpcode = PARSEOP_RAW_DATA;
    609 
    610             BufferLength++;
    611             InitializerOp = ASL_GET_PEER_NODE (InitializerOp);
    612         }
    613         break;
    614 
    615     case PARSEOP_STRING_LITERAL:
    616 
    617         /*
    618          * Only one initializer, the string. Buffer must be big enough to hold
    619          * the string plus the null termination byte
    620          */
    621         BufferLength = strlen (InitializerOp->Asl.Value.String) + 1;
    622 
    623         InitializerOp->Asl.AmlOpcode = AML_RAW_DATA_BUFFER;
    624         InitializerOp->Asl.AmlLength = BufferLength;
    625         InitializerOp->Asl.ParseOpcode = PARSEOP_RAW_DATA;
    626         break;
    627 
    628     case PARSEOP_RAW_DATA:
    629 
    630         /* Buffer nodes are already initialized (e.g. Unicode operator) */
    631         return;
    632 
    633     case PARSEOP_DEFAULT_ARG:
    634         break;
    635 
    636     default:
    637 
    638         AslError (ASL_ERROR, ASL_MSG_INVALID_OPERAND, InitializerOp,
    639             "Unknown buffer initializer opcode");
    640         printf ("Unknown buffer initializer opcode [%s]\n",
    641             UtGetOpName (InitializerOp->Asl.ParseOpcode));
    642         return;
    643     }
    644 
    645     /* Check if initializer list is longer than the buffer length */
    646 
    647     if (BufferLengthOp->Asl.Value.Integer > BufferLength)
    648     {
    649         BufferLength = (UINT32) BufferLengthOp->Asl.Value.Integer;
    650     }
    651 
    652     if (!BufferLength)
    653     {
    654         /* No length AND no items -- issue notice */
    655 
    656         AslError (ASL_REMARK, ASL_MSG_BUFFER_LENGTH, BufferLengthOp, NULL);
    657 
    658         /* But go ahead and put the buffer length of zero into the AML */
    659     }
    660 
    661     /*
    662      * Just set the buffer size node to be the buffer length, regardless
    663      * of whether it was previously an integer or a default_arg placeholder
    664      */
    665     BufferLengthOp->Asl.ParseOpcode = PARSEOP_INTEGER;
    666     BufferLengthOp->Asl.AmlOpcode = AML_DWORD_OP;
    667     BufferLengthOp->Asl.Value.Integer = BufferLength;
    668 
    669     (void) OpcSetOptimalIntegerSize (BufferLengthOp);
    670 
    671     /* Remaining nodes are handled via the tree walk */
    672 }
    673 
    674 
    675 /*******************************************************************************
    676  *
    677  * FUNCTION:    OpnDoPackage
    678  *
    679  * PARAMETERS:  Op        - The parent parse node
    680  *
    681  * RETURN:      None
    682  *
    683  * DESCRIPTION: Construct the AML operands for the PACKAGE ASL keyword. NOTE:
    684  *              can only be called after constants have been folded, to ensure
    685  *              that the PackageLength operand has been fully reduced.
    686  *
    687  ******************************************************************************/
    688 
    689 void
    690 OpnDoPackage (
    691     ACPI_PARSE_OBJECT       *Op)
    692 {
    693     ACPI_PARSE_OBJECT       *InitializerOp;
    694     ACPI_PARSE_OBJECT       *PackageLengthOp;
    695     UINT32                  PackageLength = 0;
    696 
    697 
    698     /* Opcode and package length first, followed by the initializer list */
    699 
    700     PackageLengthOp = Op->Asl.Child;
    701     InitializerOp = PackageLengthOp->Asl.Next;
    702 
    703     /* Count the number of items in the initializer list */
    704 
    705     if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
    706     {
    707         /* The peer list contains the byte list (if any...) */
    708 
    709         while (InitializerOp)
    710         {
    711             PackageLength++;
    712             InitializerOp = InitializerOp->Asl.Next;
    713         }
    714     }
    715 
    716     /* If package length is a constant, compare to the initializer list */
    717 
    718     if ((PackageLengthOp->Asl.ParseOpcode == PARSEOP_INTEGER)      ||
    719         (PackageLengthOp->Asl.ParseOpcode == PARSEOP_QWORDCONST))
    720     {
    721         if (PackageLengthOp->Asl.Value.Integer > PackageLength)
    722         {
    723             /*
    724              * Allow package length to be longer than the initializer
    725              * list -- but if the length of initializer list is nonzero,
    726              * issue a message since this is probably a coding error,
    727              * even though technically legal.
    728              */
    729             if (PackageLength > 0)
    730             {
    731                 AslError (ASL_REMARK, ASL_MSG_LIST_LENGTH_SHORT,
    732                     PackageLengthOp, NULL);
    733             }
    734 
    735             PackageLength = (UINT32) PackageLengthOp->Asl.Value.Integer;
    736         }
    737         else if (PackageLengthOp->Asl.Value.Integer < PackageLength)
    738         {
    739             /*
    740              * The package length is smaller than the length of the
    741              * initializer list. This is an error as per the ACPI spec.
    742              */
    743             AslError (ASL_ERROR, ASL_MSG_LIST_LENGTH_LONG,
    744                 PackageLengthOp, NULL);
    745         }
    746     }
    747 
    748     if (PackageLengthOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
    749     {
    750         /*
    751          * This is the case if the PackageLength was left empty - Package()
    752          * The package length becomes the length of the initializer list
    753          */
    754         Op->Asl.Child->Asl.ParseOpcode = PARSEOP_INTEGER;
    755         Op->Asl.Child->Asl.Value.Integer = PackageLength;
    756 
    757         /* Set the AML opcode */
    758 
    759         (void) OpcSetOptimalIntegerSize (Op->Asl.Child);
    760     }
    761 
    762     /* If not a variable-length package, check for a zero package length */
    763 
    764     if ((PackageLengthOp->Asl.ParseOpcode == PARSEOP_INTEGER)      ||
    765         (PackageLengthOp->Asl.ParseOpcode == PARSEOP_QWORDCONST)   ||
    766         (PackageLengthOp->Asl.ParseOpcode == PARSEOP_ZERO)         ||
    767         (PackageLengthOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG))
    768     {
    769         if (!PackageLength)
    770         {
    771             /* No length AND no initializer list -- issue a remark */
    772 
    773             AslError (ASL_REMARK, ASL_MSG_PACKAGE_LENGTH,
    774                 PackageLengthOp, NULL);
    775 
    776             /* But go ahead and put the buffer length of zero into the AML */
    777         }
    778     }
    779 
    780     /*
    781      * If the PackageLength is a constant <= 255, we can change the
    782      * AML opcode from VarPackage to a simple (ACPI 1.0) Package opcode.
    783      */
    784     if (((Op->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER) &&
    785             (Op->Asl.Child->Asl.Value.Integer <= 255))  ||
    786         (Op->Asl.Child->Asl.ParseOpcode == PARSEOP_ONE) ||
    787         (Op->Asl.Child->Asl.ParseOpcode == PARSEOP_ONES)||
    788         (Op->Asl.Child->Asl.ParseOpcode == PARSEOP_ZERO))
    789     {
    790         Op->Asl.AmlOpcode = AML_PACKAGE_OP;
    791         Op->Asl.ParseOpcode = PARSEOP_PACKAGE;
    792 
    793         /*
    794          * Just set the package size node to be the package length, regardless
    795          * of whether it was previously an integer or a default_arg placeholder
    796          */
    797         PackageLengthOp->Asl.AmlOpcode = AML_RAW_DATA_BYTE;
    798         PackageLengthOp->Asl.AmlLength = 1;
    799         PackageLengthOp->Asl.ParseOpcode = PARSEOP_RAW_DATA;
    800         PackageLengthOp->Asl.Value.Integer = PackageLength;
    801     }
    802 
    803     /* Remaining nodes are handled via the tree walk */
    804 }
    805 
    806 
    807 /*******************************************************************************
    808  *
    809  * FUNCTION:    OpnDoLoadTable
    810  *
    811  * PARAMETERS:  Op        - The parent parse node
    812  *
    813  * RETURN:      None
    814  *
    815  * DESCRIPTION: Construct the AML operands for the LOADTABLE ASL keyword.
    816  *
    817  ******************************************************************************/
    818 
    819 static void
    820 OpnDoLoadTable (
    821     ACPI_PARSE_OBJECT       *Op)
    822 {
    823     ACPI_PARSE_OBJECT       *Next;
    824 
    825 
    826     /* Opcode is parent node */
    827     /* First child is the table signature */
    828 
    829     Next = Op->Asl.Child;
    830 
    831     /* Second child is the OEM ID*/
    832 
    833     Next = Next->Asl.Next;
    834 
    835     /* Third child is the OEM table ID */
    836 
    837     Next = Next->Asl.Next;
    838 
    839     /* Fourth child is the RootPath string */
    840 
    841     Next = Next->Asl.Next;
    842     if (Next->Asl.ParseOpcode == PARSEOP_ZERO)
    843     {
    844         Next->Asl.ParseOpcode = PARSEOP_STRING_LITERAL;
    845         Next->Asl.Value.String = "\\";
    846         Next->Asl.AmlLength = 2;
    847         OpcGenerateAmlOpcode (Next);
    848     }
    849 
    850 #ifdef ASL_FUTURE_IMPLEMENTATION
    851 
    852     /* TBD: NOT IMPLEMENTED */
    853     /* Fifth child is the [optional] ParameterPathString */
    854     /* Sixth child is the [optional] ParameterData */
    855 
    856     Next = Next->Asl.Next;
    857     if (Next->Asl.ParseOpcode == DEFAULT_ARG)
    858     {
    859         Next->Asl.AmlLength = 1;
    860         Next->Asl.ParseOpcode = ZERO;
    861         OpcGenerateAmlOpcode (Next);
    862     }
    863 
    864 
    865     Next = Next->Asl.Next;
    866     if (Next->Asl.ParseOpcode == DEFAULT_ARG)
    867     {
    868         Next->Asl.AmlLength = 1;
    869         Next->Asl.ParseOpcode = ZERO;
    870         OpcGenerateAmlOpcode (Next);
    871     }
    872 #endif
    873 }
    874 
    875 
    876 /*******************************************************************************
    877  *
    878  * FUNCTION:    OpnDoDefinitionBlock
    879  *
    880  * PARAMETERS:  Op        - The parent parse node
    881  *
    882  * RETURN:      None
    883  *
    884  * DESCRIPTION: Construct the AML operands for the DEFINITIONBLOCK ASL keyword
    885  *
    886  ******************************************************************************/
    887 
    888 static void
    889 OpnDoDefinitionBlock (
    890     ACPI_PARSE_OBJECT       *Op)
    891 {
    892     ACPI_PARSE_OBJECT       *Child;
    893     ACPI_SIZE               Length;
    894     UINT32                  i;
    895     char                    *Filename;
    896 
    897 
    898     /*
    899      * These nodes get stuffed into the table header. They are special
    900      * cased when the table is written to the output file.
    901      *
    902      * Mark all of these nodes as non-usable so they won't get output
    903      * as AML opcodes!
    904      */
    905 
    906     /* Get AML filename. Use it if non-null */
    907 
    908     Child = Op->Asl.Child;
    909     if (Child->Asl.Value.Buffer  &&
    910         *Child->Asl.Value.Buffer &&
    911         (Gbl_UseDefaultAmlFilename))
    912     {
    913         /*
    914          * We will use the AML filename that is embedded in the source file
    915          * for the output filename.
    916          */
    917         Filename = UtStringCacheCalloc (strlen (Gbl_DirectoryPath) +
    918             strlen ((char *) Child->Asl.Value.Buffer) + 1);
    919 
    920         /* Prepend the current directory path */
    921 
    922         strcpy (Filename, Gbl_DirectoryPath);
    923         strcat (Filename, (char *) Child->Asl.Value.Buffer);
    924 
    925         Gbl_OutputFilenamePrefix = Filename;
    926         UtConvertBackslashes (Gbl_OutputFilenamePrefix);
    927     }
    928 
    929     Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
    930 
    931     /* Signature */
    932 
    933     Child = Child->Asl.Next;
    934     Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
    935     if (Child->Asl.Value.String)
    936     {
    937         Gbl_TableSignature = Child->Asl.Value.String;
    938         if (strlen (Gbl_TableSignature) != ACPI_NAME_SIZE)
    939         {
    940             AslError (ASL_ERROR, ASL_MSG_TABLE_SIGNATURE, Child,
    941                 "Length is not exactly 4");
    942         }
    943 
    944         for (i = 0; i < ACPI_NAME_SIZE; i++)
    945         {
    946             if (!isalnum ((int) Gbl_TableSignature[i]))
    947             {
    948                 AslError (ASL_ERROR, ASL_MSG_TABLE_SIGNATURE, Child,
    949                     "Contains non-alphanumeric characters");
    950             }
    951         }
    952     }
    953 
    954     /* Revision */
    955 
    956     Child = Child->Asl.Next;
    957     Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
    958     /*
    959      * We used the revision to set the integer width earlier
    960      */
    961 
    962     /* OEMID */
    963 
    964     Child = Child->Asl.Next;
    965     Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
    966 
    967     /* OEM TableID */
    968 
    969     Child = Child->Asl.Next;
    970     Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
    971     if (Child->Asl.Value.String)
    972     {
    973         Length = strlen (Child->Asl.Value.String);
    974         Gbl_TableId = UtStringCacheCalloc (Length + 1);
    975         strcpy (Gbl_TableId, Child->Asl.Value.String);
    976 
    977         /*
    978          * Convert anything non-alphanumeric to an underscore. This
    979          * allows us to use the TableID to generate unique C symbols.
    980          */
    981         for (i = 0; i < Length; i++)
    982         {
    983             if (!isalnum ((int) Gbl_TableId[i]))
    984             {
    985                 Gbl_TableId[i] = '_';
    986             }
    987         }
    988     }
    989 
    990     /* OEM Revision */
    991 
    992     Child = Child->Asl.Next;
    993     Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
    994 }
    995 
    996 
    997 /*******************************************************************************
    998  *
    999  * FUNCTION:    UtGetArg
   1000  *
   1001  * PARAMETERS:  Op              - Get an argument for this op
   1002  *              Argn            - Nth argument to get
   1003  *
   1004  * RETURN:      The argument (as an Op object). NULL if argument does not exist
   1005  *
   1006  * DESCRIPTION: Get the specified op's argument (peer)
   1007  *
   1008  ******************************************************************************/
   1009 
   1010 ACPI_PARSE_OBJECT *
   1011 UtGetArg (
   1012     ACPI_PARSE_OBJECT       *Op,
   1013     UINT32                  Argn)
   1014 {
   1015     ACPI_PARSE_OBJECT       *Arg = NULL;
   1016 
   1017 
   1018     /* Get the requested argument object */
   1019 
   1020     Arg = Op->Asl.Child;
   1021     while (Arg && Argn)
   1022     {
   1023         Argn--;
   1024         Arg = Arg->Asl.Next;
   1025     }
   1026 
   1027     return (Arg);
   1028 }
   1029 
   1030 
   1031 /*******************************************************************************
   1032  *
   1033  * FUNCTION:    OpnAttachNameToNode
   1034  *
   1035  * PARAMETERS:  Op        - The parent parse node
   1036  *
   1037  * RETURN:      None
   1038  *
   1039  * DESCRIPTION: For the named ASL/AML operators, get the actual name from the
   1040  *              argument list and attach it to the parent node so that we
   1041  *              can get to it quickly later.
   1042  *
   1043  ******************************************************************************/
   1044 
   1045 static void
   1046 OpnAttachNameToNode (
   1047     ACPI_PARSE_OBJECT       *Op)
   1048 {
   1049     ACPI_PARSE_OBJECT       *Child = NULL;
   1050 
   1051 
   1052     switch (Op->Asl.AmlOpcode)
   1053     {
   1054     case AML_DATA_REGION_OP:
   1055     case AML_DEVICE_OP:
   1056     case AML_EVENT_OP:
   1057     case AML_EXTERNAL_OP:
   1058     case AML_METHOD_OP:
   1059     case AML_MUTEX_OP:
   1060     case AML_REGION_OP:
   1061     case AML_POWER_RES_OP:
   1062     case AML_PROCESSOR_OP:
   1063     case AML_THERMAL_ZONE_OP:
   1064     case AML_NAME_OP:
   1065     case AML_SCOPE_OP:
   1066 
   1067         Child = UtGetArg (Op, 0);
   1068         break;
   1069 
   1070     case AML_ALIAS_OP:
   1071 
   1072         Child = UtGetArg (Op, 1);
   1073         break;
   1074 
   1075     case AML_CREATE_BIT_FIELD_OP:
   1076     case AML_CREATE_BYTE_FIELD_OP:
   1077     case AML_CREATE_WORD_FIELD_OP:
   1078     case AML_CREATE_DWORD_FIELD_OP:
   1079     case AML_CREATE_QWORD_FIELD_OP:
   1080 
   1081         Child = UtGetArg (Op, 2);
   1082         break;
   1083 
   1084     case AML_CREATE_FIELD_OP:
   1085 
   1086         Child = UtGetArg (Op, 3);
   1087         break;
   1088 
   1089     case AML_BANK_FIELD_OP:
   1090     case AML_INDEX_FIELD_OP:
   1091     case AML_FIELD_OP:
   1092 
   1093         return;
   1094 
   1095     default:
   1096 
   1097         return;
   1098     }
   1099 
   1100     if (Child)
   1101     {
   1102         UtAttachNamepathToOwner (Op, Child);
   1103     }
   1104 }
   1105 
   1106 
   1107 /*******************************************************************************
   1108  *
   1109  * FUNCTION:    OpnGenerateAmlOperands
   1110  *
   1111  * PARAMETERS:  Op        - The parent parse node
   1112  *
   1113  * RETURN:      None
   1114  *
   1115  * DESCRIPTION: Prepare nodes to be output as AML data and operands. The more
   1116  *              complex AML opcodes require processing of the child nodes
   1117  *              (arguments/operands).
   1118  *
   1119  ******************************************************************************/
   1120 
   1121 void
   1122 OpnGenerateAmlOperands (
   1123     ACPI_PARSE_OBJECT       *Op)
   1124 {
   1125 
   1126 
   1127     if (Op->Asl.AmlOpcode == AML_RAW_DATA_BYTE)
   1128     {
   1129         return;
   1130     }
   1131 
   1132     switch (Op->Asl.ParseOpcode)
   1133     {
   1134     case PARSEOP_DEFINITION_BLOCK:
   1135 
   1136         OpnDoDefinitionBlock (Op);
   1137         break;
   1138 
   1139     case PARSEOP_METHOD:
   1140 
   1141         OpnDoMethod (Op);
   1142         break;
   1143 
   1144     case PARSEOP_MUTEX:
   1145 
   1146         OpnDoMutex (Op);
   1147         break;
   1148 
   1149     case PARSEOP_FIELD:
   1150 
   1151         OpnDoField (Op);
   1152         break;
   1153 
   1154     case PARSEOP_INDEXFIELD:
   1155 
   1156         OpnDoIndexField (Op);
   1157         break;
   1158 
   1159     case PARSEOP_BANKFIELD:
   1160 
   1161         OpnDoBankField (Op);
   1162         break;
   1163 
   1164     case PARSEOP_BUFFER:
   1165 
   1166         OpnDoBuffer (Op);
   1167         break;
   1168 
   1169     case PARSEOP_LOADTABLE:
   1170 
   1171         OpnDoLoadTable (Op);
   1172         break;
   1173 
   1174     case PARSEOP_OPERATIONREGION:
   1175 
   1176         OpnDoRegion (Op);
   1177         break;
   1178 
   1179     case PARSEOP_RESOURCETEMPLATE:
   1180 
   1181         RsDoResourceTemplate (Op);
   1182         break;
   1183 
   1184     case PARSEOP_NAMESEG:
   1185     case PARSEOP_NAMESTRING:
   1186     case PARSEOP_METHODCALL:
   1187     case PARSEOP_STRING_LITERAL:
   1188     default:
   1189 
   1190         break;
   1191     }
   1192 
   1193     /* TBD: move */
   1194 
   1195     OpnAttachNameToNode (Op);
   1196 }
   1197