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