Home | History | Annotate | Line # | Download | only in compiler
aslresource.c revision 1.1.1.2
      1 
      2 /******************************************************************************
      3  *
      4  * Module Name: aslresource - Resource template/descriptor utilities
      5  *
      6  *****************************************************************************/
      7 
      8 /*
      9  * Copyright (C) 2000 - 2011, Intel Corp.
     10  * All rights reserved.
     11  *
     12  * Redistribution and use in source and binary forms, with or without
     13  * modification, are permitted provided that the following conditions
     14  * are met:
     15  * 1. Redistributions of source code must retain the above copyright
     16  *    notice, this list of conditions, and the following disclaimer,
     17  *    without modification.
     18  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
     19  *    substantially similar to the "NO WARRANTY" disclaimer below
     20  *    ("Disclaimer") and any redistribution must be conditioned upon
     21  *    including a substantially similar Disclaimer requirement for further
     22  *    binary redistribution.
     23  * 3. Neither the names of the above-listed copyright holders nor the names
     24  *    of any contributors may be used to endorse or promote products derived
     25  *    from this software without specific prior written permission.
     26  *
     27  * Alternatively, this software may be distributed under the terms of the
     28  * GNU General Public License ("GPL") version 2 as published by the Free
     29  * Software Foundation.
     30  *
     31  * NO WARRANTY
     32  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     33  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     34  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
     35  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     36  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     37  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     38  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     39  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     40  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
     41  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     42  * POSSIBILITY OF SUCH DAMAGES.
     43  */
     44 
     45 
     46 #include "aslcompiler.h"
     47 #include "aslcompiler.y.h"
     48 #include "amlcode.h"
     49 
     50 
     51 #define _COMPONENT          ACPI_COMPILER
     52         ACPI_MODULE_NAME    ("aslresource")
     53 
     54 
     55 /*******************************************************************************
     56  *
     57  * FUNCTION:    RsSmallAddressCheck
     58  *
     59  * PARAMETERS:  Minimum             - Address Min value
     60  *              Maximum             - Address Max value
     61  *              Length              - Address range value
     62  *              Alignment           - Address alignment value
     63  *              MinOp               - Original Op for Address Min
     64  *              MaxOp               - Original Op for Address Max
     65  *              LengthOp            - Original Op for address range
     66  *              AlignOp             - Original Op for address alignment. If
     67  *                                    NULL, means "zero value for alignment is
     68  *                                    OK, and means 64K alignment" (for
     69  *                                    Memory24 descriptor)
     70  *              Op                  - Parent Op for entire construct
     71  *
     72  * RETURN:      None. Adds error messages to error log if necessary
     73  *
     74  * DESCRIPTION: Perform common value checks for "small" address descriptors.
     75  *              Currently:
     76  *                  Io, Memory24, Memory32
     77  *
     78  ******************************************************************************/
     79 
     80 void
     81 RsSmallAddressCheck (
     82     UINT8                   Type,
     83     UINT32                  Minimum,
     84     UINT32                  Maximum,
     85     UINT32                  Length,
     86     UINT32                  Alignment,
     87     ACPI_PARSE_OBJECT       *MinOp,
     88     ACPI_PARSE_OBJECT       *MaxOp,
     89     ACPI_PARSE_OBJECT       *LengthOp,
     90     ACPI_PARSE_OBJECT       *AlignOp,
     91     ACPI_PARSE_OBJECT       *Op)
     92 {
     93 
     94     if (Gbl_NoResourceChecking)
     95     {
     96         return;
     97     }
     98 
     99     /*
    100      * Check for a so-called "null descriptor". These are descriptors that are
    101      * created with most fields set to zero. The intent is that the descriptor
    102      * will be updated/completed at runtime via a BufferField.
    103      *
    104      * If the descriptor does NOT have a resource tag, it cannot be referenced
    105      * by a BufferField and we will flag this as an error. Conversely, if
    106      * the descriptor has a resource tag, we will assume that a BufferField
    107      * will be used to dynamically update it, so no error.
    108      *
    109      * A possible enhancement to this check would be to verify that in fact
    110      * a BufferField is created using the resource tag, and perhaps even
    111      * verify that a Store is performed to the BufferField.
    112      *
    113      * Note: for these descriptors, Alignment is allowed to be zero
    114      */
    115     if (!Minimum && !Maximum && !Length)
    116     {
    117         if (!Op->Asl.ExternalName)
    118         {
    119             /* No resource tag. Descriptor is fixed and is also illegal */
    120 
    121             AslError (ASL_ERROR, ASL_MSG_NULL_DESCRIPTOR, Op, NULL);
    122         }
    123 
    124         return;
    125     }
    126 
    127     /* Special case for Memory24, values are compressed */
    128 
    129     if (Type == ACPI_RESOURCE_NAME_MEMORY24)
    130     {
    131         if (!Alignment) /* Alignment==0 means 64K - no invalid alignment */
    132         {
    133             Alignment = ACPI_UINT16_MAX + 1;
    134         }
    135 
    136         Minimum <<= 8;
    137         Maximum <<= 8;
    138         Length *= 256;
    139     }
    140 
    141     /* IO descriptor has different definition of min/max, don't check */
    142 
    143     if (Type != ACPI_RESOURCE_NAME_IO)
    144     {
    145         /* Basic checks on Min/Max/Length */
    146 
    147         if (Minimum > Maximum)
    148         {
    149             AslError (ASL_ERROR, ASL_MSG_INVALID_MIN_MAX, MinOp, NULL);
    150         }
    151         else if (Length > (Maximum - Minimum + 1))
    152         {
    153             AslError (ASL_ERROR, ASL_MSG_INVALID_LENGTH, LengthOp, NULL);
    154         }
    155     }
    156 
    157     /* Alignment of zero is not in ACPI spec, but is used to mean byte acc */
    158 
    159     if (!Alignment)
    160     {
    161         Alignment = 1;
    162     }
    163 
    164     /* Addresses must be an exact multiple of the alignment value */
    165 
    166     if (Minimum % Alignment)
    167     {
    168         AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MinOp, NULL);
    169     }
    170     if (Maximum % Alignment)
    171     {
    172         AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MaxOp, NULL);
    173     }
    174 }
    175 
    176 
    177 /*******************************************************************************
    178  *
    179  * FUNCTION:    RsLargeAddressCheck
    180  *
    181  * PARAMETERS:  Minimum             - Address Min value
    182  *              Maximum             - Address Max value
    183  *              Length              - Address range value
    184  *              Granularity         - Address granularity value
    185  *              Flags               - General flags for address descriptors:
    186  *                                    _MIF, _MAF, _DEC
    187  *              MinOp               - Original Op for Address Min
    188  *              MaxOp               - Original Op for Address Max
    189  *              LengthOp            - Original Op for address range
    190  *              GranOp              - Original Op for address granularity
    191  *              Op                  - Parent Op for entire construct
    192  *
    193  * RETURN:      None. Adds error messages to error log if necessary
    194  *
    195  * DESCRIPTION: Perform common value checks for "large" address descriptors.
    196  *              Currently:
    197  *                  WordIo,     WordBusNumber,  WordSpace
    198  *                  DWordIo,    DWordMemory,    DWordSpace
    199  *                  QWordIo,    QWordMemory,    QWordSpace
    200  *                  ExtendedIo, ExtendedMemory, ExtendedSpace
    201  *
    202  * _MIF flag set means that the minimum address is fixed and is not relocatable
    203  * _MAF flag set means that the maximum address is fixed and is not relocatable
    204  * Length of zero means that the record size is variable
    205  *
    206  * This function implements the LEN/MIF/MAF/MIN/MAX/GRA rules within Table 6-40
    207  * of the ACPI 4.0a specification. Added 04/2010.
    208  *
    209  ******************************************************************************/
    210 
    211 void
    212 RsLargeAddressCheck (
    213     UINT64                  Minimum,
    214     UINT64                  Maximum,
    215     UINT64                  Length,
    216     UINT64                  Granularity,
    217     UINT8                   Flags,
    218     ACPI_PARSE_OBJECT       *MinOp,
    219     ACPI_PARSE_OBJECT       *MaxOp,
    220     ACPI_PARSE_OBJECT       *LengthOp,
    221     ACPI_PARSE_OBJECT       *GranOp,
    222     ACPI_PARSE_OBJECT       *Op)
    223 {
    224 
    225     if (Gbl_NoResourceChecking)
    226     {
    227         return;
    228     }
    229 
    230     /*
    231      * Check for a so-called "null descriptor". These are descriptors that are
    232      * created with most fields set to zero. The intent is that the descriptor
    233      * will be updated/completed at runtime via a BufferField.
    234      *
    235      * If the descriptor does NOT have a resource tag, it cannot be referenced
    236      * by a BufferField and we will flag this as an error. Conversely, if
    237      * the descriptor has a resource tag, we will assume that a BufferField
    238      * will be used to dynamically update it, so no error.
    239      *
    240      * A possible enhancement to this check would be to verify that in fact
    241      * a BufferField is created using the resource tag, and perhaps even
    242      * verify that a Store is performed to the BufferField.
    243      */
    244     if (!Minimum && !Maximum && !Length && !Granularity)
    245     {
    246         if (!Op->Asl.ExternalName)
    247         {
    248             /* No resource tag. Descriptor is fixed and is also illegal */
    249 
    250             AslError (ASL_ERROR, ASL_MSG_NULL_DESCRIPTOR, Op, NULL);
    251         }
    252 
    253         return;
    254     }
    255 
    256     /* Basic checks on Min/Max/Length */
    257 
    258     if (Minimum > Maximum)
    259     {
    260         AslError (ASL_ERROR, ASL_MSG_INVALID_MIN_MAX, MinOp, NULL);
    261         return;
    262     }
    263     else if (Length > (Maximum - Minimum + 1))
    264     {
    265         AslError (ASL_ERROR, ASL_MSG_INVALID_LENGTH, LengthOp, NULL);
    266         return;
    267     }
    268 
    269     /* If specified (non-zero), ensure granularity is a power-of-two minus one */
    270 
    271     if (Granularity)
    272     {
    273         if ((Granularity + 1) &
    274              Granularity)
    275         {
    276             AslError (ASL_ERROR, ASL_MSG_INVALID_GRANULARITY, GranOp, NULL);
    277             return;
    278         }
    279     }
    280 
    281     /*
    282      * Check the various combinations of Length, MinFixed, and MaxFixed
    283      */
    284     if (Length)
    285     {
    286         /* Fixed non-zero length */
    287 
    288         switch (Flags & (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF))
    289         {
    290         case 0:
    291             /*
    292              * Fixed length, variable locations (both _MIN and _MAX).
    293              * Length must be a multiple of granularity
    294              */
    295             if (Granularity & Length)
    296             {
    297                 AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, LengthOp, NULL);
    298             }
    299             break;
    300 
    301         case (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF):
    302 
    303             /* Fixed length, fixed location. Granularity must be zero */
    304 
    305             if (Granularity != 0)
    306             {
    307                 AslError (ASL_ERROR, ASL_MSG_INVALID_GRAN_FIXED, GranOp, NULL);
    308             }
    309 
    310             /* Length must be exactly the size of the min/max window */
    311 
    312             if (Length != (Maximum - Minimum + 1))
    313             {
    314                 AslError (ASL_ERROR, ASL_MSG_INVALID_LENGTH_FIXED, LengthOp, NULL);
    315             }
    316             break;
    317 
    318         /* All other combinations are invalid */
    319 
    320         case ACPI_RESOURCE_FLAG_MIF:
    321         case ACPI_RESOURCE_FLAG_MAF:
    322         default:
    323             AslError (ASL_ERROR, ASL_MSG_INVALID_ADDR_FLAGS, LengthOp, NULL);
    324         }
    325     }
    326     else
    327     {
    328         /* Variable length (length==0) */
    329 
    330         switch (Flags & (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF))
    331         {
    332         case 0:
    333             /*
    334              * Both _MIN and _MAX are variable.
    335              * No additional requirements, just exit
    336              */
    337             break;
    338 
    339         case ACPI_RESOURCE_FLAG_MIF:
    340 
    341             /* _MIN is fixed. _MIN must be multiple of _GRA */
    342 
    343             /*
    344              * The granularity is defined by the ACPI specification to be a
    345              * power-of-two minus one, therefore the granularity is a
    346              * bitmask which can be used to easily validate the addresses.
    347              */
    348             if (Granularity & Minimum)
    349             {
    350                 AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MinOp, NULL);
    351             }
    352             break;
    353 
    354         case ACPI_RESOURCE_FLAG_MAF:
    355 
    356             /* _MAX is fixed. (_MAX + 1) must be multiple of _GRA */
    357 
    358             if (Granularity & (Maximum + 1))
    359             {
    360                 AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MaxOp, "-1");
    361             }
    362             break;
    363 
    364         /* Both MIF/MAF set is invalid if length is zero */
    365 
    366         case (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF):
    367         default:
    368             AslError (ASL_ERROR, ASL_MSG_INVALID_ADDR_FLAGS, LengthOp, NULL);
    369         }
    370     }
    371 }
    372 
    373 
    374 /*******************************************************************************
    375  *
    376  * FUNCTION:    RsGetStringDataLength
    377  *
    378  * PARAMETERS:  InitializerOp     - Start of a subtree of init nodes
    379  *
    380  * RETURN:      Valid string length if a string node is found (otherwise 0)
    381  *
    382  * DESCRIPTION: In a list of peer nodes, find the first one that contains a
    383  *              string and return the length of the string.
    384  *
    385  ******************************************************************************/
    386 
    387 UINT16
    388 RsGetStringDataLength (
    389     ACPI_PARSE_OBJECT       *InitializerOp)
    390 {
    391 
    392     while (InitializerOp)
    393     {
    394         if (InitializerOp->Asl.ParseOpcode == PARSEOP_STRING_LITERAL)
    395         {
    396             return ((UINT16) (strlen (InitializerOp->Asl.Value.String) + 1));
    397         }
    398         InitializerOp = ASL_GET_PEER_NODE (InitializerOp);
    399     }
    400 
    401     return 0;
    402 }
    403 
    404 
    405 /*******************************************************************************
    406  *
    407  * FUNCTION:    RsAllocateResourceNode
    408  *
    409  * PARAMETERS:  Size        - Size of node in bytes
    410  *
    411  * RETURN:      The allocated node - aborts on allocation failure
    412  *
    413  * DESCRIPTION: Allocate a resource description node and the resource
    414  *              descriptor itself (the nodes are used to link descriptors).
    415  *
    416  ******************************************************************************/
    417 
    418 ASL_RESOURCE_NODE *
    419 RsAllocateResourceNode (
    420     UINT32                  Size)
    421 {
    422     ASL_RESOURCE_NODE       *Rnode;
    423 
    424 
    425     /* Allocate the node */
    426 
    427     Rnode = UtLocalCalloc (sizeof (ASL_RESOURCE_NODE));
    428 
    429     /* Allocate the resource descriptor itself */
    430 
    431     Rnode->Buffer = UtLocalCalloc (Size);
    432     Rnode->BufferLength = Size;
    433 
    434     return (Rnode);
    435 }
    436 
    437 
    438 /*******************************************************************************
    439  *
    440  * FUNCTION:    RsCreateBitField
    441  *
    442  * PARAMETERS:  Op              - Resource field node
    443  *              Name            - Name of the field (Used only to reference
    444  *                                the field in the ASL, not in the AML)
    445  *              ByteOffset      - Offset from the field start
    446  *              BitOffset       - Additional bit offset
    447  *
    448  * RETURN:      None, sets fields within the input node
    449  *
    450  * DESCRIPTION: Utility function to generate a named bit field within a
    451  *              resource descriptor.  Mark a node as 1) a field in a resource
    452  *              descriptor, and 2) set the value to be a BIT offset
    453  *
    454  ******************************************************************************/
    455 
    456 void
    457 RsCreateBitField (
    458     ACPI_PARSE_OBJECT       *Op,
    459     char                    *Name,
    460     UINT32                  ByteOffset,
    461     UINT32                  BitOffset)
    462 {
    463 
    464     Op->Asl.ExternalName      = Name;
    465     Op->Asl.Value.Integer     = ((UINT64) ByteOffset * 8) + BitOffset;
    466     Op->Asl.CompileFlags     |= (NODE_IS_RESOURCE_FIELD | NODE_IS_BIT_OFFSET);
    467 }
    468 
    469 
    470 /*******************************************************************************
    471  *
    472  * FUNCTION:    RsCreateByteField
    473  *
    474  * PARAMETERS:  Op              - Resource field node
    475  *              Name            - Name of the field (Used only to reference
    476  *                                the field in the ASL, not in the AML)
    477  *              ByteOffset      - Offset from the field start
    478  *
    479  * RETURN:      None, sets fields within the input node
    480  *
    481  * DESCRIPTION: Utility function to generate a named byte field within a
    482  *              resource descriptor.  Mark a node as 1) a field in a resource
    483  *              descriptor, and 2) set the value to be a BYTE offset
    484  *
    485  ******************************************************************************/
    486 
    487 void
    488 RsCreateByteField (
    489     ACPI_PARSE_OBJECT       *Op,
    490     char                    *Name,
    491     UINT32                  ByteOffset)
    492 {
    493 
    494     Op->Asl.ExternalName      = Name;
    495     Op->Asl.Value.Integer     = ByteOffset;
    496     Op->Asl.CompileFlags     |= NODE_IS_RESOURCE_FIELD;
    497 }
    498 
    499 
    500 /*******************************************************************************
    501  *
    502  * FUNCTION:    RsSetFlagBits
    503  *
    504  * PARAMETERS:  *Flags          - Pointer to the flag byte
    505  *              Op              - Flag initialization node
    506  *              Position        - Bit position within the flag byte
    507  *              Default         - Used if the node is DEFAULT.
    508  *
    509  * RETURN:      Sets bits within the *Flags output byte.
    510  *
    511  * DESCRIPTION: Set a bit in a cumulative flags word from an initialization
    512  *              node.  Will use a default value if the node is DEFAULT, meaning
    513  *              that no value was specified in the ASL.  Used to merge multiple
    514  *              keywords into a single flags byte.
    515  *
    516  ******************************************************************************/
    517 
    518 void
    519 RsSetFlagBits (
    520     UINT8                   *Flags,
    521     ACPI_PARSE_OBJECT       *Op,
    522     UINT8                   Position,
    523     UINT8                   DefaultBit)
    524 {
    525 
    526     if (Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
    527     {
    528         /* Use the default bit */
    529 
    530         *Flags |= (DefaultBit << Position);
    531     }
    532     else
    533     {
    534         /* Use the bit specified in the initialization node */
    535 
    536         *Flags |= (((UINT8) Op->Asl.Value.Integer) << Position);
    537     }
    538 }
    539 
    540 
    541 /*******************************************************************************
    542  *
    543  * FUNCTION:    RsCompleteNodeAndGetNext
    544  *
    545  * PARAMETERS:  Op            - Resource node to be completed
    546  *
    547  * RETURN:      The next peer to the input node.
    548  *
    549  * DESCRIPTION: Mark the current node completed and return the next peer.
    550  *              The node ParseOpcode is set to DEFAULT_ARG, meaning that
    551  *              this node is to be ignored from now on.
    552  *
    553  ******************************************************************************/
    554 
    555 ACPI_PARSE_OBJECT *
    556 RsCompleteNodeAndGetNext (
    557     ACPI_PARSE_OBJECT       *Op)
    558 {
    559 
    560     /* Mark this node unused */
    561 
    562     Op->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
    563 
    564     /* Move on to the next peer node in the initializer list */
    565 
    566     return (ASL_GET_PEER_NODE (Op));
    567 }
    568 
    569 
    570 /*******************************************************************************
    571  *
    572  * FUNCTION:    RsCheckListForDuplicates
    573  *
    574  * PARAMETERS:  Op                  - First op in the initializer list
    575  *
    576  * RETURN:      None
    577  *
    578  * DESCRIPTION: Check an initializer list for duplicate values. Emits an error
    579  *              if any duplicates are found.
    580  *
    581  ******************************************************************************/
    582 
    583 void
    584 RsCheckListForDuplicates (
    585     ACPI_PARSE_OBJECT       *Op)
    586 {
    587     ACPI_PARSE_OBJECT       *NextValueOp = Op;
    588     ACPI_PARSE_OBJECT       *NextOp;
    589     UINT32                  Value;
    590 
    591 
    592     if (!Op)
    593     {
    594         return;
    595     }
    596 
    597     /* Search list once for each value in the list */
    598 
    599     while (NextValueOp)
    600     {
    601         Value = (UINT32) NextValueOp->Asl.Value.Integer;
    602 
    603         /* Compare this value to all remaining values in the list */
    604 
    605         NextOp = ASL_GET_PEER_NODE (NextValueOp);
    606         while (NextOp)
    607         {
    608             if (NextOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
    609             {
    610                 /* Compare values */
    611 
    612                 if (Value == (UINT32) NextOp->Asl.Value.Integer)
    613                 {
    614                     /* Emit error only once per duplicate node */
    615 
    616                     if (!(NextOp->Asl.CompileFlags & NODE_IS_DUPLICATE))
    617                     {
    618                         NextOp->Asl.CompileFlags |= NODE_IS_DUPLICATE;
    619                         AslError (ASL_ERROR, ASL_MSG_DUPLICATE_ITEM,
    620                             NextOp, NULL);
    621                     }
    622                 }
    623             }
    624 
    625             NextOp = ASL_GET_PEER_NODE (NextOp);
    626         }
    627 
    628         NextValueOp = ASL_GET_PEER_NODE (NextValueOp);
    629     }
    630 }
    631 
    632 
    633 /*******************************************************************************
    634  *
    635  * FUNCTION:    RsDoOneResourceDescriptor
    636  *
    637  * PARAMETERS:  DescriptorTypeOp    - Parent parse node of the descriptor
    638  *              CurrentByteOffset   - Offset in the resource descriptor
    639  *                                    buffer.
    640  *
    641  * RETURN:      A valid resource node for the descriptor
    642  *
    643  * DESCRIPTION: Dispatches the processing of one resource descriptor
    644  *
    645  ******************************************************************************/
    646 
    647 ASL_RESOURCE_NODE *
    648 RsDoOneResourceDescriptor (
    649     ACPI_PARSE_OBJECT       *DescriptorTypeOp,
    650     UINT32                  CurrentByteOffset,
    651     UINT8                   *State)
    652 {
    653     ASL_RESOURCE_NODE       *Rnode = NULL;
    654 
    655 
    656     /* Construct the resource */
    657 
    658     switch (DescriptorTypeOp->Asl.ParseOpcode)
    659     {
    660     case PARSEOP_DMA:
    661         Rnode = RsDoDmaDescriptor (DescriptorTypeOp,
    662                     CurrentByteOffset);
    663         break;
    664 
    665     case PARSEOP_DWORDIO:
    666         Rnode = RsDoDwordIoDescriptor (DescriptorTypeOp,
    667                     CurrentByteOffset);
    668         break;
    669 
    670     case PARSEOP_DWORDMEMORY:
    671         Rnode = RsDoDwordMemoryDescriptor (DescriptorTypeOp,
    672                     CurrentByteOffset);
    673         break;
    674 
    675     case PARSEOP_DWORDSPACE:
    676         Rnode = RsDoDwordSpaceDescriptor (DescriptorTypeOp,
    677                     CurrentByteOffset);
    678         break;
    679 
    680     case PARSEOP_ENDDEPENDENTFN:
    681         switch (*State)
    682         {
    683         case ACPI_RSTATE_NORMAL:
    684             AslError (ASL_ERROR, ASL_MSG_MISSING_STARTDEPENDENT,
    685                 DescriptorTypeOp, NULL);
    686             break;
    687 
    688         case ACPI_RSTATE_START_DEPENDENT:
    689             AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING,
    690                 DescriptorTypeOp, NULL);
    691             break;
    692 
    693         case ACPI_RSTATE_DEPENDENT_LIST:
    694         default:
    695             break;
    696         }
    697 
    698         *State = ACPI_RSTATE_NORMAL;
    699         Rnode = RsDoEndDependentDescriptor (DescriptorTypeOp,
    700                     CurrentByteOffset);
    701         break;
    702 
    703     case PARSEOP_ENDTAG:
    704         Rnode = RsDoEndTagDescriptor (DescriptorTypeOp,
    705                     CurrentByteOffset);
    706         break;
    707 
    708     case PARSEOP_EXTENDEDIO:
    709         Rnode = RsDoExtendedIoDescriptor (DescriptorTypeOp,
    710                     CurrentByteOffset);
    711         break;
    712 
    713     case PARSEOP_EXTENDEDMEMORY:
    714         Rnode = RsDoExtendedMemoryDescriptor (DescriptorTypeOp,
    715                     CurrentByteOffset);
    716         break;
    717 
    718     case PARSEOP_EXTENDEDSPACE:
    719         Rnode = RsDoExtendedSpaceDescriptor (DescriptorTypeOp,
    720                     CurrentByteOffset);
    721         break;
    722 
    723     case PARSEOP_FIXEDIO:
    724         Rnode = RsDoFixedIoDescriptor (DescriptorTypeOp,
    725                     CurrentByteOffset);
    726         break;
    727 
    728     case PARSEOP_INTERRUPT:
    729         Rnode = RsDoInterruptDescriptor (DescriptorTypeOp,
    730                     CurrentByteOffset);
    731         break;
    732 
    733     case PARSEOP_IO:
    734         Rnode = RsDoIoDescriptor (DescriptorTypeOp,
    735                     CurrentByteOffset);
    736         break;
    737 
    738     case PARSEOP_IRQ:
    739         Rnode = RsDoIrqDescriptor (DescriptorTypeOp,
    740                     CurrentByteOffset);
    741         break;
    742 
    743     case PARSEOP_IRQNOFLAGS:
    744         Rnode = RsDoIrqNoFlagsDescriptor (DescriptorTypeOp,
    745                     CurrentByteOffset);
    746         break;
    747 
    748     case PARSEOP_MEMORY24:
    749         Rnode = RsDoMemory24Descriptor (DescriptorTypeOp,
    750                     CurrentByteOffset);
    751         break;
    752 
    753     case PARSEOP_MEMORY32:
    754         Rnode = RsDoMemory32Descriptor (DescriptorTypeOp,
    755                     CurrentByteOffset);
    756         break;
    757 
    758     case PARSEOP_MEMORY32FIXED:
    759         Rnode = RsDoMemory32FixedDescriptor (DescriptorTypeOp,
    760                     CurrentByteOffset);
    761         break;
    762 
    763     case PARSEOP_QWORDIO:
    764         Rnode = RsDoQwordIoDescriptor (DescriptorTypeOp,
    765                     CurrentByteOffset);
    766         break;
    767 
    768     case PARSEOP_QWORDMEMORY:
    769         Rnode = RsDoQwordMemoryDescriptor (DescriptorTypeOp,
    770                     CurrentByteOffset);
    771         break;
    772 
    773     case PARSEOP_QWORDSPACE:
    774         Rnode = RsDoQwordSpaceDescriptor (DescriptorTypeOp,
    775                     CurrentByteOffset);
    776         break;
    777 
    778     case PARSEOP_REGISTER:
    779         Rnode = RsDoGeneralRegisterDescriptor (DescriptorTypeOp,
    780                     CurrentByteOffset);
    781         break;
    782 
    783     case PARSEOP_STARTDEPENDENTFN:
    784         switch (*State)
    785         {
    786         case ACPI_RSTATE_START_DEPENDENT:
    787             AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING,
    788                 DescriptorTypeOp, NULL);
    789             break;
    790 
    791         case ACPI_RSTATE_NORMAL:
    792         case ACPI_RSTATE_DEPENDENT_LIST:
    793         default:
    794             break;
    795         }
    796 
    797         *State = ACPI_RSTATE_START_DEPENDENT;
    798         Rnode = RsDoStartDependentDescriptor (DescriptorTypeOp,
    799                     CurrentByteOffset);
    800         *State = ACPI_RSTATE_DEPENDENT_LIST;
    801         break;
    802 
    803     case PARSEOP_STARTDEPENDENTFN_NOPRI:
    804         switch (*State)
    805         {
    806         case ACPI_RSTATE_START_DEPENDENT:
    807             AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING,
    808                 DescriptorTypeOp, NULL);
    809             break;
    810 
    811         case ACPI_RSTATE_NORMAL:
    812         case ACPI_RSTATE_DEPENDENT_LIST:
    813         default:
    814             break;
    815         }
    816 
    817         *State = ACPI_RSTATE_START_DEPENDENT;
    818         Rnode = RsDoStartDependentNoPriDescriptor (DescriptorTypeOp,
    819                     CurrentByteOffset);
    820         *State = ACPI_RSTATE_DEPENDENT_LIST;
    821         break;
    822 
    823     case PARSEOP_VENDORLONG:
    824         Rnode = RsDoVendorLargeDescriptor (DescriptorTypeOp,
    825                     CurrentByteOffset);
    826         break;
    827 
    828     case PARSEOP_VENDORSHORT:
    829         Rnode = RsDoVendorSmallDescriptor (DescriptorTypeOp,
    830                     CurrentByteOffset);
    831         break;
    832 
    833     case PARSEOP_WORDBUSNUMBER:
    834         Rnode = RsDoWordBusNumberDescriptor (DescriptorTypeOp,
    835                     CurrentByteOffset);
    836         break;
    837 
    838     case PARSEOP_WORDIO:
    839         Rnode = RsDoWordIoDescriptor (DescriptorTypeOp,
    840                     CurrentByteOffset);
    841         break;
    842 
    843     case PARSEOP_WORDSPACE:
    844         Rnode = RsDoWordSpaceDescriptor (DescriptorTypeOp,
    845                     CurrentByteOffset);
    846         break;
    847 
    848     case PARSEOP_DEFAULT_ARG:
    849         /* Just ignore any of these, they are used as fillers/placeholders */
    850         break;
    851 
    852     default:
    853         printf ("Unknown resource descriptor type [%s]\n",
    854                     DescriptorTypeOp->Asl.ParseOpName);
    855         break;
    856     }
    857 
    858     /*
    859      * Mark original node as unused, but head of a resource descriptor.
    860      * This allows the resource to be installed in the namespace so that
    861      * references to the descriptor can be resolved.
    862      */
    863     DescriptorTypeOp->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
    864     DescriptorTypeOp->Asl.CompileFlags = NODE_IS_RESOURCE_DESC;
    865     DescriptorTypeOp->Asl.Value.Integer = CurrentByteOffset;
    866 
    867     if (Rnode)
    868     {
    869         DescriptorTypeOp->Asl.FinalAmlLength = Rnode->BufferLength;
    870     }
    871 
    872     return (Rnode);
    873 }
    874 
    875 
    876 /*******************************************************************************
    877  *
    878  * FUNCTION:    RsLinkDescriptorChain
    879  *
    880  * PARAMETERS:  PreviousRnode       - Pointer to the node that will be previous
    881  *                                    to the linked node,  At exit, set to the
    882  *                                    last node in the new chain.
    883  *              Rnode               - Resource node to link into the list
    884  *
    885  * RETURN:      Cumulative buffer byte offset of the new segment of chain
    886  *
    887  * DESCRIPTION: Link a descriptor chain at the end of an existing chain.
    888  *
    889  ******************************************************************************/
    890 
    891 UINT32
    892 RsLinkDescriptorChain (
    893     ASL_RESOURCE_NODE       **PreviousRnode,
    894     ASL_RESOURCE_NODE       *Rnode)
    895 {
    896     ASL_RESOURCE_NODE       *LastRnode;
    897     UINT32                  CurrentByteOffset;
    898 
    899 
    900     /* Anything to do? */
    901 
    902     if (!Rnode)
    903     {
    904         return 0;
    905     }
    906 
    907     /* Point the previous node to the new node */
    908 
    909     (*PreviousRnode)->Next = Rnode;
    910     CurrentByteOffset = Rnode->BufferLength;
    911 
    912     /* Walk to the end of the chain headed by Rnode */
    913 
    914     LastRnode = Rnode;
    915     while (LastRnode->Next)
    916     {
    917         LastRnode = LastRnode->Next;
    918         CurrentByteOffset += LastRnode->BufferLength;
    919     }
    920 
    921     /* Previous node becomes the last node in the chain */
    922 
    923     *PreviousRnode = LastRnode;
    924     return CurrentByteOffset;
    925 }
    926 
    927 
    928 /*******************************************************************************
    929  *
    930  * FUNCTION:    RsDoResourceTemplate
    931  *
    932  * PARAMETERS:  Op        - Parent of a resource template list
    933  *
    934  * RETURN:      None.  Sets input node to point to a list of AML code
    935  *
    936  * DESCRIPTION: Merge a list of resource descriptors into a single AML buffer,
    937  *              in preparation for output to the AML output file.
    938  *
    939  ******************************************************************************/
    940 
    941 void
    942 RsDoResourceTemplate (
    943     ACPI_PARSE_OBJECT       *Op)
    944 {
    945     ACPI_PARSE_OBJECT       *BufferLengthOp;
    946     ACPI_PARSE_OBJECT       *BufferOp;
    947     ACPI_PARSE_OBJECT       *DescriptorTypeOp;
    948     ACPI_PARSE_OBJECT       *LastOp = NULL;
    949     UINT32                  CurrentByteOffset = 0;
    950     ASL_RESOURCE_NODE       HeadRnode;
    951     ASL_RESOURCE_NODE       *PreviousRnode;
    952     ASL_RESOURCE_NODE       *Rnode;
    953     UINT8                   State;
    954 
    955 
    956     /* Mark parent as containing a resource template */
    957 
    958     if (Op->Asl.Parent)
    959     {
    960         Op->Asl.Parent->Asl.CompileFlags |= NODE_IS_RESOURCE_DESC;
    961     }
    962 
    963     /* ResourceTemplate Opcode is first (Op) */
    964     /* Buffer Length node is first child */
    965 
    966     BufferLengthOp = ASL_GET_CHILD_NODE (Op);
    967 
    968     /* Buffer Op is first peer */
    969 
    970     BufferOp = ASL_GET_PEER_NODE (BufferLengthOp);
    971 
    972     /* First Descriptor type is next */
    973 
    974     DescriptorTypeOp = ASL_GET_PEER_NODE (BufferOp);
    975 
    976     /*
    977      * Process all resource descriptors in the list
    978      * Note: It is assumed that the EndTag node has been automatically
    979      * inserted at the end of the template by the parser.
    980      */
    981     State = ACPI_RSTATE_NORMAL;
    982     PreviousRnode = &HeadRnode;
    983     while (DescriptorTypeOp)
    984     {
    985         DescriptorTypeOp->Asl.CompileFlags |= NODE_IS_RESOURCE_DESC;
    986         Rnode = RsDoOneResourceDescriptor (DescriptorTypeOp, CurrentByteOffset,
    987                     &State);
    988 
    989         /*
    990          * Update current byte offset to indicate the number of bytes from the
    991          * start of the buffer.  Buffer can include multiple descriptors, we
    992          * must keep track of the offset of not only each descriptor, but each
    993          * element (field) within each descriptor as well.
    994          */
    995         CurrentByteOffset += RsLinkDescriptorChain (&PreviousRnode, Rnode);
    996 
    997         /* Get the next descriptor in the list */
    998 
    999         LastOp = DescriptorTypeOp;
   1000         DescriptorTypeOp = ASL_GET_PEER_NODE (DescriptorTypeOp);
   1001     }
   1002 
   1003     if (State == ACPI_RSTATE_DEPENDENT_LIST)
   1004     {
   1005         if (LastOp)
   1006         {
   1007             LastOp = LastOp->Asl.Parent;
   1008         }
   1009         AslError (ASL_ERROR, ASL_MSG_MISSING_ENDDEPENDENT, LastOp, NULL);
   1010     }
   1011 
   1012     /*
   1013      * Transform the nodes into the following
   1014      *
   1015      * Op           -> AML_BUFFER_OP
   1016      * First Child  -> BufferLength
   1017      * Second Child -> Descriptor Buffer (raw byte data)
   1018      */
   1019     Op->Asl.ParseOpcode               = PARSEOP_BUFFER;
   1020     Op->Asl.AmlOpcode                 = AML_BUFFER_OP;
   1021     Op->Asl.CompileFlags              = NODE_AML_PACKAGE | NODE_IS_RESOURCE_DESC;
   1022 
   1023     BufferLengthOp->Asl.ParseOpcode   = PARSEOP_INTEGER;
   1024     BufferLengthOp->Asl.Value.Integer = CurrentByteOffset;
   1025     (void) OpcSetOptimalIntegerSize (BufferLengthOp);
   1026 
   1027     BufferOp->Asl.ParseOpcode         = PARSEOP_RAW_DATA;
   1028     BufferOp->Asl.AmlOpcode           = AML_RAW_DATA_CHAIN;
   1029     BufferOp->Asl.AmlOpcodeLength     = 0;
   1030     BufferOp->Asl.AmlLength           = CurrentByteOffset;
   1031     BufferOp->Asl.Value.Buffer        = (UINT8 *) HeadRnode.Next;
   1032     BufferOp->Asl.CompileFlags       |= NODE_IS_RESOURCE_DATA;
   1033 
   1034     return;
   1035 }
   1036 
   1037 
   1038