Subversion Repositories Kolibri OS

Rev

Rev 1498 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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