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