Subversion Repositories Kolibri OS

Rev

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