xref: /netbsd-src/sys/external/bsd/acpica/dist/compiler/aslresource.c (revision c7960b37466ae0fd417c32e6acbb4b956ac7a121)
128c506b8Sjruoho /******************************************************************************
228c506b8Sjruoho  *
328c506b8Sjruoho  * Module Name: aslresource - Resource template/descriptor utilities
428c506b8Sjruoho  *
528c506b8Sjruoho  *****************************************************************************/
628c506b8Sjruoho 
7124f4c82Sjruoho /*
8046a2985Schristos  * Copyright (C) 2000 - 2023, Intel Corp.
928c506b8Sjruoho  * All rights reserved.
1028c506b8Sjruoho  *
11124f4c82Sjruoho  * Redistribution and use in source and binary forms, with or without
12124f4c82Sjruoho  * modification, are permitted provided that the following conditions
13124f4c82Sjruoho  * are met:
14124f4c82Sjruoho  * 1. Redistributions of source code must retain the above copyright
15124f4c82Sjruoho  *    notice, this list of conditions, and the following disclaimer,
16124f4c82Sjruoho  *    without modification.
17124f4c82Sjruoho  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18124f4c82Sjruoho  *    substantially similar to the "NO WARRANTY" disclaimer below
19124f4c82Sjruoho  *    ("Disclaimer") and any redistribution must be conditioned upon
20124f4c82Sjruoho  *    including a substantially similar Disclaimer requirement for further
21124f4c82Sjruoho  *    binary redistribution.
22124f4c82Sjruoho  * 3. Neither the names of the above-listed copyright holders nor the names
23124f4c82Sjruoho  *    of any contributors may be used to endorse or promote products derived
24124f4c82Sjruoho  *    from this software without specific prior written permission.
2528c506b8Sjruoho  *
26124f4c82Sjruoho  * Alternatively, this software may be distributed under the terms of the
27124f4c82Sjruoho  * GNU General Public License ("GPL") version 2 as published by the Free
28124f4c82Sjruoho  * Software Foundation.
2928c506b8Sjruoho  *
30124f4c82Sjruoho  * NO WARRANTY
31124f4c82Sjruoho  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32124f4c82Sjruoho  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3346a330b4Schristos  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34124f4c82Sjruoho  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35124f4c82Sjruoho  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36124f4c82Sjruoho  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37124f4c82Sjruoho  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38124f4c82Sjruoho  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39124f4c82Sjruoho  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40124f4c82Sjruoho  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41124f4c82Sjruoho  * POSSIBILITY OF SUCH DAMAGES.
42124f4c82Sjruoho  */
4328c506b8Sjruoho 
4428c506b8Sjruoho #include "aslcompiler.h"
4528c506b8Sjruoho #include "aslcompiler.y.h"
4628c506b8Sjruoho #include "amlcode.h"
4728c506b8Sjruoho 
4828c506b8Sjruoho 
4928c506b8Sjruoho #define _COMPONENT          ACPI_COMPILER
5028c506b8Sjruoho         ACPI_MODULE_NAME    ("aslresource")
5128c506b8Sjruoho 
5228c506b8Sjruoho 
5328c506b8Sjruoho /*******************************************************************************
5428c506b8Sjruoho  *
5528c506b8Sjruoho  * FUNCTION:    RsSmallAddressCheck
5628c506b8Sjruoho  *
5728c506b8Sjruoho  * PARAMETERS:  Minimum             - Address Min value
5828c506b8Sjruoho  *              Maximum             - Address Max value
5928c506b8Sjruoho  *              Length              - Address range value
6028c506b8Sjruoho  *              Alignment           - Address alignment value
6128c506b8Sjruoho  *              MinOp               - Original Op for Address Min
6228c506b8Sjruoho  *              MaxOp               - Original Op for Address Max
6328c506b8Sjruoho  *              LengthOp            - Original Op for address range
6428c506b8Sjruoho  *              AlignOp             - Original Op for address alignment. If
6528c506b8Sjruoho  *                                    NULL, means "zero value for alignment is
6628c506b8Sjruoho  *                                    OK, and means 64K alignment" (for
6728c506b8Sjruoho  *                                    Memory24 descriptor)
68124f4c82Sjruoho  *              Op                  - Parent Op for entire construct
6928c506b8Sjruoho  *
7028c506b8Sjruoho  * RETURN:      None. Adds error messages to error log if necessary
7128c506b8Sjruoho  *
7228c506b8Sjruoho  * DESCRIPTION: Perform common value checks for "small" address descriptors.
7328c506b8Sjruoho  *              Currently:
7428c506b8Sjruoho  *                  Io, Memory24, Memory32
7528c506b8Sjruoho  *
7628c506b8Sjruoho  ******************************************************************************/
7728c506b8Sjruoho 
7828c506b8Sjruoho void
7928c506b8Sjruoho RsSmallAddressCheck (
8028c506b8Sjruoho     UINT8                   Type,
8128c506b8Sjruoho     UINT32                  Minimum,
8228c506b8Sjruoho     UINT32                  Maximum,
8328c506b8Sjruoho     UINT32                  Length,
8428c506b8Sjruoho     UINT32                  Alignment,
8528c506b8Sjruoho     ACPI_PARSE_OBJECT       *MinOp,
8628c506b8Sjruoho     ACPI_PARSE_OBJECT       *MaxOp,
8728c506b8Sjruoho     ACPI_PARSE_OBJECT       *LengthOp,
88124f4c82Sjruoho     ACPI_PARSE_OBJECT       *AlignOp,
89124f4c82Sjruoho     ACPI_PARSE_OBJECT       *Op)
9028c506b8Sjruoho {
9128c506b8Sjruoho 
924c4e8184Schristos     if (AslGbl_NoResourceChecking)
9328c506b8Sjruoho     {
9428c506b8Sjruoho         return;
9528c506b8Sjruoho     }
9628c506b8Sjruoho 
97124f4c82Sjruoho     /*
98124f4c82Sjruoho      * Check for a so-called "null descriptor". These are descriptors that are
99124f4c82Sjruoho      * created with most fields set to zero. The intent is that the descriptor
100124f4c82Sjruoho      * will be updated/completed at runtime via a BufferField.
101124f4c82Sjruoho      *
102124f4c82Sjruoho      * If the descriptor does NOT have a resource tag, it cannot be referenced
103124f4c82Sjruoho      * by a BufferField and we will flag this as an error. Conversely, if
104124f4c82Sjruoho      * the descriptor has a resource tag, we will assume that a BufferField
105124f4c82Sjruoho      * will be used to dynamically update it, so no error.
106124f4c82Sjruoho      *
107124f4c82Sjruoho      * A possible enhancement to this check would be to verify that in fact
108124f4c82Sjruoho      * a BufferField is created using the resource tag, and perhaps even
109124f4c82Sjruoho      * verify that a Store is performed to the BufferField.
110124f4c82Sjruoho      *
111124f4c82Sjruoho      * Note: for these descriptors, Alignment is allowed to be zero
112124f4c82Sjruoho      */
113124f4c82Sjruoho     if (!Minimum && !Maximum && !Length)
114124f4c82Sjruoho     {
115124f4c82Sjruoho         if (!Op->Asl.ExternalName)
116124f4c82Sjruoho         {
117124f4c82Sjruoho             /* No resource tag. Descriptor is fixed and is also illegal */
118124f4c82Sjruoho 
119124f4c82Sjruoho             AslError (ASL_ERROR, ASL_MSG_NULL_DESCRIPTOR, Op, NULL);
120124f4c82Sjruoho         }
121124f4c82Sjruoho 
122124f4c82Sjruoho         return;
123124f4c82Sjruoho     }
124124f4c82Sjruoho 
125460301d4Schristos     /*
126460301d4Schristos      * Range checks for Memory24 and Memory32.
127460301d4Schristos      * IO descriptor has different definition of min/max, don't check.
128460301d4Schristos      */
12928c506b8Sjruoho     if (Type != ACPI_RESOURCE_NAME_IO)
13028c506b8Sjruoho     {
13128c506b8Sjruoho         /* Basic checks on Min/Max/Length */
13228c506b8Sjruoho 
13328c506b8Sjruoho         if (Minimum > Maximum)
13428c506b8Sjruoho         {
13528c506b8Sjruoho             AslError (ASL_ERROR, ASL_MSG_INVALID_MIN_MAX, MinOp, NULL);
13628c506b8Sjruoho         }
13728c506b8Sjruoho         else if (Length > (Maximum - Minimum + 1))
13828c506b8Sjruoho         {
13928c506b8Sjruoho             AslError (ASL_ERROR, ASL_MSG_INVALID_LENGTH, LengthOp, NULL);
14028c506b8Sjruoho         }
141460301d4Schristos 
142460301d4Schristos         /* Special case for Memory24, min/max values are compressed */
143460301d4Schristos 
144460301d4Schristos         if (Type == ACPI_RESOURCE_NAME_MEMORY24)
145460301d4Schristos         {
146460301d4Schristos             if (!Alignment) /* Alignment==0 means 64K alignment */
147460301d4Schristos             {
148460301d4Schristos                 Alignment = ACPI_UINT16_MAX + 1;
149460301d4Schristos             }
150460301d4Schristos 
151460301d4Schristos             Minimum <<= 8;
152460301d4Schristos             Maximum <<= 8;
153460301d4Schristos         }
15428c506b8Sjruoho     }
15528c506b8Sjruoho 
15628c506b8Sjruoho     /* Alignment of zero is not in ACPI spec, but is used to mean byte acc */
15728c506b8Sjruoho 
15828c506b8Sjruoho     if (!Alignment)
15928c506b8Sjruoho     {
16028c506b8Sjruoho         Alignment = 1;
16128c506b8Sjruoho     }
16228c506b8Sjruoho 
16328c506b8Sjruoho     /* Addresses must be an exact multiple of the alignment value */
16428c506b8Sjruoho 
16528c506b8Sjruoho     if (Minimum % Alignment)
16628c506b8Sjruoho     {
16728c506b8Sjruoho         AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MinOp, NULL);
16828c506b8Sjruoho     }
16928c506b8Sjruoho     if (Maximum % Alignment)
17028c506b8Sjruoho     {
17128c506b8Sjruoho         AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MaxOp, NULL);
17228c506b8Sjruoho     }
17328c506b8Sjruoho }
17428c506b8Sjruoho 
17528c506b8Sjruoho 
17628c506b8Sjruoho /*******************************************************************************
17728c506b8Sjruoho  *
17828c506b8Sjruoho  * FUNCTION:    RsLargeAddressCheck
17928c506b8Sjruoho  *
18028c506b8Sjruoho  * PARAMETERS:  Minimum             - Address Min value
18128c506b8Sjruoho  *              Maximum             - Address Max value
18228c506b8Sjruoho  *              Length              - Address range value
18328c506b8Sjruoho  *              Granularity         - Address granularity value
18428c506b8Sjruoho  *              Flags               - General flags for address descriptors:
18528c506b8Sjruoho  *                                    _MIF, _MAF, _DEC
18628c506b8Sjruoho  *              MinOp               - Original Op for Address Min
18728c506b8Sjruoho  *              MaxOp               - Original Op for Address Max
18828c506b8Sjruoho  *              LengthOp            - Original Op for address range
18928c506b8Sjruoho  *              GranOp              - Original Op for address granularity
190124f4c82Sjruoho  *              Op                  - Parent Op for entire construct
19128c506b8Sjruoho  *
19228c506b8Sjruoho  * RETURN:      None. Adds error messages to error log if necessary
19328c506b8Sjruoho  *
19428c506b8Sjruoho  * DESCRIPTION: Perform common value checks for "large" address descriptors.
19528c506b8Sjruoho  *              Currently:
19628c506b8Sjruoho  *                  WordIo,     WordBusNumber,  WordSpace
19728c506b8Sjruoho  *                  DWordIo,    DWordMemory,    DWordSpace
19828c506b8Sjruoho  *                  QWordIo,    QWordMemory,    QWordSpace
19928c506b8Sjruoho  *                  ExtendedIo, ExtendedMemory, ExtendedSpace
20028c506b8Sjruoho  *
20128c506b8Sjruoho  * _MIF flag set means that the minimum address is fixed and is not relocatable
20228c506b8Sjruoho  * _MAF flag set means that the maximum address is fixed and is not relocatable
20328c506b8Sjruoho  * Length of zero means that the record size is variable
20428c506b8Sjruoho  *
20528c506b8Sjruoho  * This function implements the LEN/MIF/MAF/MIN/MAX/GRA rules within Table 6-40
20628c506b8Sjruoho  * of the ACPI 4.0a specification. Added 04/2010.
20728c506b8Sjruoho  *
20828c506b8Sjruoho  ******************************************************************************/
20928c506b8Sjruoho 
21028c506b8Sjruoho void
21128c506b8Sjruoho RsLargeAddressCheck (
21228c506b8Sjruoho     UINT64                  Minimum,
21328c506b8Sjruoho     UINT64                  Maximum,
21428c506b8Sjruoho     UINT64                  Length,
21528c506b8Sjruoho     UINT64                  Granularity,
21628c506b8Sjruoho     UINT8                   Flags,
21728c506b8Sjruoho     ACPI_PARSE_OBJECT       *MinOp,
21828c506b8Sjruoho     ACPI_PARSE_OBJECT       *MaxOp,
21928c506b8Sjruoho     ACPI_PARSE_OBJECT       *LengthOp,
220124f4c82Sjruoho     ACPI_PARSE_OBJECT       *GranOp,
221124f4c82Sjruoho     ACPI_PARSE_OBJECT       *Op)
22228c506b8Sjruoho {
22328c506b8Sjruoho 
2244c4e8184Schristos     if (AslGbl_NoResourceChecking)
22528c506b8Sjruoho     {
22628c506b8Sjruoho         return;
22728c506b8Sjruoho     }
22828c506b8Sjruoho 
229124f4c82Sjruoho     /*
230124f4c82Sjruoho      * Check for a so-called "null descriptor". These are descriptors that are
231124f4c82Sjruoho      * created with most fields set to zero. The intent is that the descriptor
232124f4c82Sjruoho      * will be updated/completed at runtime via a BufferField.
233124f4c82Sjruoho      *
234124f4c82Sjruoho      * If the descriptor does NOT have a resource tag, it cannot be referenced
235124f4c82Sjruoho      * by a BufferField and we will flag this as an error. Conversely, if
236124f4c82Sjruoho      * the descriptor has a resource tag, we will assume that a BufferField
237124f4c82Sjruoho      * will be used to dynamically update it, so no error.
238124f4c82Sjruoho      *
239124f4c82Sjruoho      * A possible enhancement to this check would be to verify that in fact
240124f4c82Sjruoho      * a BufferField is created using the resource tag, and perhaps even
241124f4c82Sjruoho      * verify that a Store is performed to the BufferField.
242124f4c82Sjruoho      */
243124f4c82Sjruoho     if (!Minimum && !Maximum && !Length && !Granularity)
244124f4c82Sjruoho     {
245124f4c82Sjruoho         if (!Op->Asl.ExternalName)
246124f4c82Sjruoho         {
247124f4c82Sjruoho             /* No resource tag. Descriptor is fixed and is also illegal */
248124f4c82Sjruoho 
249124f4c82Sjruoho             AslError (ASL_ERROR, ASL_MSG_NULL_DESCRIPTOR, Op, NULL);
250124f4c82Sjruoho         }
251124f4c82Sjruoho 
252124f4c82Sjruoho         return;
253124f4c82Sjruoho     }
254124f4c82Sjruoho 
25528c506b8Sjruoho     /* Basic checks on Min/Max/Length */
25628c506b8Sjruoho 
25728c506b8Sjruoho     if (Minimum > Maximum)
25828c506b8Sjruoho     {
25928c506b8Sjruoho         AslError (ASL_ERROR, ASL_MSG_INVALID_MIN_MAX, MinOp, NULL);
26028c506b8Sjruoho         return;
26128c506b8Sjruoho     }
26228c506b8Sjruoho     else if (Length > (Maximum - Minimum + 1))
26328c506b8Sjruoho     {
26428c506b8Sjruoho         AslError (ASL_ERROR, ASL_MSG_INVALID_LENGTH, LengthOp, NULL);
26528c506b8Sjruoho         return;
26628c506b8Sjruoho     }
26728c506b8Sjruoho 
26828c506b8Sjruoho     /* If specified (non-zero), ensure granularity is a power-of-two minus one */
26928c506b8Sjruoho 
27028c506b8Sjruoho     if (Granularity)
27128c506b8Sjruoho     {
27228c506b8Sjruoho         if ((Granularity + 1) &
27328c506b8Sjruoho              Granularity)
27428c506b8Sjruoho         {
27528c506b8Sjruoho             AslError (ASL_ERROR, ASL_MSG_INVALID_GRANULARITY, GranOp, NULL);
27628c506b8Sjruoho             return;
27728c506b8Sjruoho         }
27828c506b8Sjruoho     }
27928c506b8Sjruoho 
28028c506b8Sjruoho     /*
28128c506b8Sjruoho      * Check the various combinations of Length, MinFixed, and MaxFixed
28228c506b8Sjruoho      */
28328c506b8Sjruoho     if (Length)
28428c506b8Sjruoho     {
28528c506b8Sjruoho         /* Fixed non-zero length */
28628c506b8Sjruoho 
28728c506b8Sjruoho         switch (Flags & (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF))
28828c506b8Sjruoho         {
28928c506b8Sjruoho         case 0:
29028c506b8Sjruoho             /*
29128c506b8Sjruoho              * Fixed length, variable locations (both _MIN and _MAX).
29228c506b8Sjruoho              * Length must be a multiple of granularity
29328c506b8Sjruoho              */
29428c506b8Sjruoho             if (Granularity & Length)
29528c506b8Sjruoho             {
29628c506b8Sjruoho                 AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, LengthOp, NULL);
29728c506b8Sjruoho             }
29828c506b8Sjruoho             break;
29928c506b8Sjruoho 
30028c506b8Sjruoho         case (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF):
30128c506b8Sjruoho 
30228c506b8Sjruoho             /* Fixed length, fixed location. Granularity must be zero */
30328c506b8Sjruoho 
30428c506b8Sjruoho             if (Granularity != 0)
30528c506b8Sjruoho             {
30628c506b8Sjruoho                 AslError (ASL_ERROR, ASL_MSG_INVALID_GRAN_FIXED, GranOp, NULL);
30728c506b8Sjruoho             }
30828c506b8Sjruoho 
30928c506b8Sjruoho             /* Length must be exactly the size of the min/max window */
31028c506b8Sjruoho 
31128c506b8Sjruoho             if (Length != (Maximum - Minimum + 1))
31228c506b8Sjruoho             {
31328c506b8Sjruoho                 AslError (ASL_ERROR, ASL_MSG_INVALID_LENGTH_FIXED, LengthOp, NULL);
31428c506b8Sjruoho             }
31528c506b8Sjruoho             break;
31628c506b8Sjruoho 
31728c506b8Sjruoho         /* All other combinations are invalid */
31828c506b8Sjruoho 
31928c506b8Sjruoho         case ACPI_RESOURCE_FLAG_MIF:
32028c506b8Sjruoho         case ACPI_RESOURCE_FLAG_MAF:
32128c506b8Sjruoho         default:
322ff4a156dSchristos 
32328c506b8Sjruoho             AslError (ASL_ERROR, ASL_MSG_INVALID_ADDR_FLAGS, LengthOp, NULL);
32428c506b8Sjruoho         }
32528c506b8Sjruoho     }
32628c506b8Sjruoho     else
32728c506b8Sjruoho     {
32828c506b8Sjruoho         /* Variable length (length==0) */
32928c506b8Sjruoho 
33028c506b8Sjruoho         switch (Flags & (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF))
33128c506b8Sjruoho         {
33228c506b8Sjruoho         case 0:
33328c506b8Sjruoho             /*
33428c506b8Sjruoho              * Both _MIN and _MAX are variable.
33528c506b8Sjruoho              * No additional requirements, just exit
33628c506b8Sjruoho              */
33728c506b8Sjruoho             break;
33828c506b8Sjruoho 
33928c506b8Sjruoho         case ACPI_RESOURCE_FLAG_MIF:
34028c506b8Sjruoho 
34128c506b8Sjruoho             /* _MIN is fixed. _MIN must be multiple of _GRA */
34228c506b8Sjruoho 
34328c506b8Sjruoho             /*
34428c506b8Sjruoho              * The granularity is defined by the ACPI specification to be a
34528c506b8Sjruoho              * power-of-two minus one, therefore the granularity is a
34628c506b8Sjruoho              * bitmask which can be used to easily validate the addresses.
34728c506b8Sjruoho              */
34828c506b8Sjruoho             if (Granularity & Minimum)
34928c506b8Sjruoho             {
35028c506b8Sjruoho                 AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MinOp, NULL);
35128c506b8Sjruoho             }
35228c506b8Sjruoho             break;
35328c506b8Sjruoho 
35428c506b8Sjruoho         case ACPI_RESOURCE_FLAG_MAF:
35528c506b8Sjruoho 
35628c506b8Sjruoho             /* _MAX is fixed. (_MAX + 1) must be multiple of _GRA */
35728c506b8Sjruoho 
35828c506b8Sjruoho             if (Granularity & (Maximum + 1))
35928c506b8Sjruoho             {
36028c506b8Sjruoho                 AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MaxOp, "-1");
36128c506b8Sjruoho             }
36228c506b8Sjruoho             break;
36328c506b8Sjruoho 
36428c506b8Sjruoho         /* Both MIF/MAF set is invalid if length is zero */
36528c506b8Sjruoho 
36628c506b8Sjruoho         case (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF):
36728c506b8Sjruoho         default:
368ff4a156dSchristos 
36928c506b8Sjruoho             AslError (ASL_ERROR, ASL_MSG_INVALID_ADDR_FLAGS, LengthOp, NULL);
37028c506b8Sjruoho         }
37128c506b8Sjruoho     }
37228c506b8Sjruoho }
37328c506b8Sjruoho 
37428c506b8Sjruoho 
37528c506b8Sjruoho /*******************************************************************************
37628c506b8Sjruoho  *
37728c506b8Sjruoho  * FUNCTION:    RsGetStringDataLength
37828c506b8Sjruoho  *
37928c506b8Sjruoho  * PARAMETERS:  InitializerOp     - Start of a subtree of init nodes
38028c506b8Sjruoho  *
38128c506b8Sjruoho  * RETURN:      Valid string length if a string node is found (otherwise 0)
38228c506b8Sjruoho  *
38328c506b8Sjruoho  * DESCRIPTION: In a list of peer nodes, find the first one that contains a
38428c506b8Sjruoho  *              string and return the length of the string.
38528c506b8Sjruoho  *
38628c506b8Sjruoho  ******************************************************************************/
38728c506b8Sjruoho 
38828c506b8Sjruoho UINT16
38928c506b8Sjruoho RsGetStringDataLength (
39028c506b8Sjruoho     ACPI_PARSE_OBJECT       *InitializerOp)
39128c506b8Sjruoho {
39228c506b8Sjruoho 
39328c506b8Sjruoho     while (InitializerOp)
39428c506b8Sjruoho     {
39528c506b8Sjruoho         if (InitializerOp->Asl.ParseOpcode == PARSEOP_STRING_LITERAL)
39628c506b8Sjruoho         {
39728c506b8Sjruoho             return ((UINT16) (strlen (InitializerOp->Asl.Value.String) + 1));
39828c506b8Sjruoho         }
39971e38f1dSchristos 
40028c506b8Sjruoho         InitializerOp = ASL_GET_PEER_NODE (InitializerOp);
40128c506b8Sjruoho     }
40228c506b8Sjruoho 
403ff4a156dSchristos     return (0);
40428c506b8Sjruoho }
40528c506b8Sjruoho 
40628c506b8Sjruoho 
40728c506b8Sjruoho /*******************************************************************************
40828c506b8Sjruoho  *
40928c506b8Sjruoho  * FUNCTION:    RsAllocateResourceNode
41028c506b8Sjruoho  *
41128c506b8Sjruoho  * PARAMETERS:  Size        - Size of node in bytes
41228c506b8Sjruoho  *
41328c506b8Sjruoho  * RETURN:      The allocated node - aborts on allocation failure
41428c506b8Sjruoho  *
41528c506b8Sjruoho  * DESCRIPTION: Allocate a resource description node and the resource
41628c506b8Sjruoho  *              descriptor itself (the nodes are used to link descriptors).
41728c506b8Sjruoho  *
41828c506b8Sjruoho  ******************************************************************************/
41928c506b8Sjruoho 
42028c506b8Sjruoho ASL_RESOURCE_NODE *
42128c506b8Sjruoho RsAllocateResourceNode (
42228c506b8Sjruoho     UINT32                  Size)
42328c506b8Sjruoho {
42428c506b8Sjruoho     ASL_RESOURCE_NODE       *Rnode;
42528c506b8Sjruoho 
42628c506b8Sjruoho 
42728c506b8Sjruoho     /* Allocate the node */
42828c506b8Sjruoho 
42928c506b8Sjruoho     Rnode = UtLocalCalloc (sizeof (ASL_RESOURCE_NODE));
43028c506b8Sjruoho 
43128c506b8Sjruoho     /* Allocate the resource descriptor itself */
43228c506b8Sjruoho 
43328c506b8Sjruoho     Rnode->Buffer = UtLocalCalloc (Size);
43428c506b8Sjruoho     Rnode->BufferLength = Size;
43528c506b8Sjruoho     return (Rnode);
43628c506b8Sjruoho }
43728c506b8Sjruoho 
43828c506b8Sjruoho 
43928c506b8Sjruoho /*******************************************************************************
44028c506b8Sjruoho  *
441ff4a156dSchristos  * FUNCTION:    RsCreateResourceField
44228c506b8Sjruoho  *
44328c506b8Sjruoho  * PARAMETERS:  Op              - Resource field node
44428c506b8Sjruoho  *              Name            - Name of the field (Used only to reference
44528c506b8Sjruoho  *                                the field in the ASL, not in the AML)
44628c506b8Sjruoho  *              ByteOffset      - Offset from the field start
44728c506b8Sjruoho  *              BitOffset       - Additional bit offset
448ff4a156dSchristos  *              BitLength       - Number of bits in the field
44928c506b8Sjruoho  *
45028c506b8Sjruoho  * RETURN:      None, sets fields within the input node
45128c506b8Sjruoho  *
45228c506b8Sjruoho  * DESCRIPTION: Utility function to generate a named bit field within a
45328c506b8Sjruoho  *              resource descriptor. Mark a node as 1) a field in a resource
45428c506b8Sjruoho  *              descriptor, and 2) set the value to be a BIT offset
45528c506b8Sjruoho  *
45628c506b8Sjruoho  ******************************************************************************/
45728c506b8Sjruoho 
45828c506b8Sjruoho void
459ff4a156dSchristos RsCreateResourceField (
46028c506b8Sjruoho     ACPI_PARSE_OBJECT       *Op,
46128c506b8Sjruoho     char                    *Name,
46228c506b8Sjruoho     UINT32                  ByteOffset,
463ff4a156dSchristos     UINT32                  BitOffset,
464ff4a156dSchristos     UINT32                  BitLength)
46528c506b8Sjruoho {
46628c506b8Sjruoho 
46728c506b8Sjruoho     Op->Asl.ExternalName = Name;
46889b8eb6cSchristos     Op->Asl.CompileFlags |= OP_IS_RESOURCE_FIELD;
469ff4a156dSchristos 
470ff4a156dSchristos     Op->Asl.Value.Tag.BitOffset = (ByteOffset * 8) + BitOffset;
471ff4a156dSchristos     Op->Asl.Value.Tag.BitLength = BitLength;
47228c506b8Sjruoho }
47328c506b8Sjruoho 
47428c506b8Sjruoho 
47528c506b8Sjruoho /*******************************************************************************
47628c506b8Sjruoho  *
47728c506b8Sjruoho  * FUNCTION:    RsSetFlagBits
47828c506b8Sjruoho  *
47928c506b8Sjruoho  * PARAMETERS:  *Flags          - Pointer to the flag byte
48028c506b8Sjruoho  *              Op              - Flag initialization node
48128c506b8Sjruoho  *              Position        - Bit position within the flag byte
48228c506b8Sjruoho  *              Default         - Used if the node is DEFAULT.
48328c506b8Sjruoho  *
48428c506b8Sjruoho  * RETURN:      Sets bits within the *Flags output byte.
48528c506b8Sjruoho  *
48628c506b8Sjruoho  * DESCRIPTION: Set a bit in a cumulative flags word from an initialization
48728c506b8Sjruoho  *              node. Will use a default value if the node is DEFAULT, meaning
48828c506b8Sjruoho  *              that no value was specified in the ASL. Used to merge multiple
48928c506b8Sjruoho  *              keywords into a single flags byte.
49028c506b8Sjruoho  *
49128c506b8Sjruoho  ******************************************************************************/
49228c506b8Sjruoho 
49328c506b8Sjruoho void
49428c506b8Sjruoho RsSetFlagBits (
49528c506b8Sjruoho     UINT8                   *Flags,
49628c506b8Sjruoho     ACPI_PARSE_OBJECT       *Op,
49728c506b8Sjruoho     UINT8                   Position,
49828c506b8Sjruoho     UINT8                   DefaultBit)
49928c506b8Sjruoho {
50028c506b8Sjruoho 
50128c506b8Sjruoho     if (Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
50228c506b8Sjruoho     {
50328c506b8Sjruoho         /* Use the default bit */
50428c506b8Sjruoho 
50528c506b8Sjruoho         *Flags |= (DefaultBit << Position);
50628c506b8Sjruoho     }
50728c506b8Sjruoho     else
50828c506b8Sjruoho     {
50928c506b8Sjruoho         /* Use the bit specified in the initialization node */
51028c506b8Sjruoho 
51128c506b8Sjruoho         *Flags |= (((UINT8) Op->Asl.Value.Integer) << Position);
51228c506b8Sjruoho     }
51328c506b8Sjruoho }
51428c506b8Sjruoho 
51528c506b8Sjruoho 
516ff4a156dSchristos void
517ff4a156dSchristos RsSetFlagBits16 (
518ff4a156dSchristos     UINT16                  *Flags,
519ff4a156dSchristos     ACPI_PARSE_OBJECT       *Op,
520ff4a156dSchristos     UINT8                   Position,
521ff4a156dSchristos     UINT8                   DefaultBit)
522ff4a156dSchristos {
523ff4a156dSchristos 
524ff4a156dSchristos     if (Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
525ff4a156dSchristos     {
526ff4a156dSchristos         /* Use the default bit */
527ff4a156dSchristos 
528ff4a156dSchristos         *Flags |= (DefaultBit << Position);
529ff4a156dSchristos     }
530ff4a156dSchristos     else
531ff4a156dSchristos     {
532ff4a156dSchristos         /* Use the bit specified in the initialization node */
533ff4a156dSchristos 
534ff4a156dSchristos         *Flags |= (((UINT16) Op->Asl.Value.Integer) << Position);
535ff4a156dSchristos     }
536ff4a156dSchristos }
537ff4a156dSchristos 
538ff4a156dSchristos 
53928c506b8Sjruoho /*******************************************************************************
54028c506b8Sjruoho  *
54128c506b8Sjruoho  * FUNCTION:    RsCompleteNodeAndGetNext
54228c506b8Sjruoho  *
54328c506b8Sjruoho  * PARAMETERS:  Op            - Resource node to be completed
54428c506b8Sjruoho  *
54528c506b8Sjruoho  * RETURN:      The next peer to the input node.
54628c506b8Sjruoho  *
54728c506b8Sjruoho  * DESCRIPTION: Mark the current node completed and return the next peer.
54828c506b8Sjruoho  *              The node ParseOpcode is set to DEFAULT_ARG, meaning that
54928c506b8Sjruoho  *              this node is to be ignored from now on.
55028c506b8Sjruoho  *
55128c506b8Sjruoho  ******************************************************************************/
55228c506b8Sjruoho 
55328c506b8Sjruoho ACPI_PARSE_OBJECT *
55428c506b8Sjruoho RsCompleteNodeAndGetNext (
55528c506b8Sjruoho     ACPI_PARSE_OBJECT       *Op)
55628c506b8Sjruoho {
55728c506b8Sjruoho 
55828c506b8Sjruoho     /* Mark this node unused */
55928c506b8Sjruoho 
56028c506b8Sjruoho     Op->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
56128c506b8Sjruoho 
56228c506b8Sjruoho     /* Move on to the next peer node in the initializer list */
56328c506b8Sjruoho 
56428c506b8Sjruoho     return (ASL_GET_PEER_NODE (Op));
56528c506b8Sjruoho }
56628c506b8Sjruoho 
56728c506b8Sjruoho 
56828c506b8Sjruoho /*******************************************************************************
56928c506b8Sjruoho  *
57028c506b8Sjruoho  * FUNCTION:    RsCheckListForDuplicates
57128c506b8Sjruoho  *
57228c506b8Sjruoho  * PARAMETERS:  Op                  - First op in the initializer list
57328c506b8Sjruoho  *
57428c506b8Sjruoho  * RETURN:      None
57528c506b8Sjruoho  *
57628c506b8Sjruoho  * DESCRIPTION: Check an initializer list for duplicate values. Emits an error
57728c506b8Sjruoho  *              if any duplicates are found.
57828c506b8Sjruoho  *
57928c506b8Sjruoho  ******************************************************************************/
58028c506b8Sjruoho 
58128c506b8Sjruoho void
58228c506b8Sjruoho RsCheckListForDuplicates (
58328c506b8Sjruoho     ACPI_PARSE_OBJECT       *Op)
58428c506b8Sjruoho {
58528c506b8Sjruoho     ACPI_PARSE_OBJECT       *NextValueOp = Op;
58628c506b8Sjruoho     ACPI_PARSE_OBJECT       *NextOp;
58728c506b8Sjruoho     UINT32                  Value;
58828c506b8Sjruoho 
58928c506b8Sjruoho 
59028c506b8Sjruoho     if (!Op)
59128c506b8Sjruoho     {
59228c506b8Sjruoho         return;
59328c506b8Sjruoho     }
59428c506b8Sjruoho 
59528c506b8Sjruoho     /* Search list once for each value in the list */
59628c506b8Sjruoho 
59728c506b8Sjruoho     while (NextValueOp)
59828c506b8Sjruoho     {
59928c506b8Sjruoho         Value = (UINT32) NextValueOp->Asl.Value.Integer;
60028c506b8Sjruoho 
60128c506b8Sjruoho         /* Compare this value to all remaining values in the list */
60228c506b8Sjruoho 
60328c506b8Sjruoho         NextOp = ASL_GET_PEER_NODE (NextValueOp);
60428c506b8Sjruoho         while (NextOp)
60528c506b8Sjruoho         {
60628c506b8Sjruoho             if (NextOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
60728c506b8Sjruoho             {
60828c506b8Sjruoho                 /* Compare values */
60928c506b8Sjruoho 
61028c506b8Sjruoho                 if (Value == (UINT32) NextOp->Asl.Value.Integer)
61128c506b8Sjruoho                 {
61228c506b8Sjruoho                     /* Emit error only once per duplicate node */
61328c506b8Sjruoho 
61489b8eb6cSchristos                     if (!(NextOp->Asl.CompileFlags & OP_IS_DUPLICATE))
61528c506b8Sjruoho                     {
61689b8eb6cSchristos                         NextOp->Asl.CompileFlags |= OP_IS_DUPLICATE;
61728c506b8Sjruoho                         AslError (ASL_ERROR, ASL_MSG_DUPLICATE_ITEM,
61828c506b8Sjruoho                             NextOp, NULL);
61928c506b8Sjruoho                     }
62028c506b8Sjruoho                 }
62128c506b8Sjruoho             }
62228c506b8Sjruoho 
62328c506b8Sjruoho             NextOp = ASL_GET_PEER_NODE (NextOp);
62428c506b8Sjruoho         }
62528c506b8Sjruoho 
62628c506b8Sjruoho         NextValueOp = ASL_GET_PEER_NODE (NextValueOp);
62728c506b8Sjruoho     }
62828c506b8Sjruoho }
62928c506b8Sjruoho 
63028c506b8Sjruoho 
63128c506b8Sjruoho /*******************************************************************************
63228c506b8Sjruoho  *
63328c506b8Sjruoho  * FUNCTION:    RsDoOneResourceDescriptor
63428c506b8Sjruoho  *
63528c506b8Sjruoho  * PARAMETERS:  DescriptorTypeOp    - Parent parse node of the descriptor
63628c506b8Sjruoho  *              CurrentByteOffset   - Offset in the resource descriptor
63728c506b8Sjruoho  *                                    buffer.
63828c506b8Sjruoho  *
63928c506b8Sjruoho  * RETURN:      A valid resource node for the descriptor
64028c506b8Sjruoho  *
64128c506b8Sjruoho  * DESCRIPTION: Dispatches the processing of one resource descriptor
64228c506b8Sjruoho  *
64328c506b8Sjruoho  ******************************************************************************/
64428c506b8Sjruoho 
64528c506b8Sjruoho ASL_RESOURCE_NODE *
64628c506b8Sjruoho RsDoOneResourceDescriptor (
647460301d4Schristos     ASL_RESOURCE_INFO       *Info,
64828c506b8Sjruoho     UINT8                   *State)
64928c506b8Sjruoho {
65028c506b8Sjruoho     ASL_RESOURCE_NODE       *Rnode = NULL;
65128c506b8Sjruoho 
65228c506b8Sjruoho 
65328c506b8Sjruoho     /* Construct the resource */
65428c506b8Sjruoho 
655460301d4Schristos     switch (Info->DescriptorTypeOp->Asl.ParseOpcode)
65628c506b8Sjruoho     {
657046a2985Schristos 
658046a2985Schristos     case PARSEOP_CLOCKINPUT:
659046a2985Schristos 
660046a2985Schristos         Rnode = RsDoClockInputDescriptor(Info);
661046a2985Schristos         break;
662046a2985Schristos 
66328c506b8Sjruoho     case PARSEOP_DMA:
664ff4a156dSchristos 
665460301d4Schristos         Rnode = RsDoDmaDescriptor (Info);
66628c506b8Sjruoho         break;
66728c506b8Sjruoho 
668ff4a156dSchristos     case PARSEOP_FIXEDDMA:
669ff4a156dSchristos 
670460301d4Schristos         Rnode = RsDoFixedDmaDescriptor (Info);
671ff4a156dSchristos         break;
672ff4a156dSchristos 
67328c506b8Sjruoho     case PARSEOP_DWORDIO:
674ff4a156dSchristos 
675460301d4Schristos         Rnode = RsDoDwordIoDescriptor (Info);
67628c506b8Sjruoho         break;
67728c506b8Sjruoho 
67828c506b8Sjruoho     case PARSEOP_DWORDMEMORY:
679ff4a156dSchristos 
680460301d4Schristos         Rnode = RsDoDwordMemoryDescriptor (Info);
68128c506b8Sjruoho         break;
68228c506b8Sjruoho 
683*c7960b37Schristos     case PARSEOP_DWORDPCC:
684*c7960b37Schristos 
685*c7960b37Schristos         Rnode = RsDoDwordPccDescriptor (Info);
686*c7960b37Schristos         break;
687*c7960b37Schristos 
68828c506b8Sjruoho     case PARSEOP_DWORDSPACE:
689ff4a156dSchristos 
690460301d4Schristos         Rnode = RsDoDwordSpaceDescriptor (Info);
69128c506b8Sjruoho         break;
69228c506b8Sjruoho 
69328c506b8Sjruoho     case PARSEOP_ENDDEPENDENTFN:
694ff4a156dSchristos 
69528c506b8Sjruoho         switch (*State)
69628c506b8Sjruoho         {
69728c506b8Sjruoho         case ACPI_RSTATE_NORMAL:
698ff4a156dSchristos 
69928c506b8Sjruoho             AslError (ASL_ERROR, ASL_MSG_MISSING_STARTDEPENDENT,
700460301d4Schristos                 Info->DescriptorTypeOp, NULL);
70128c506b8Sjruoho             break;
70228c506b8Sjruoho 
70328c506b8Sjruoho         case ACPI_RSTATE_START_DEPENDENT:
704ff4a156dSchristos 
70528c506b8Sjruoho             AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING,
706460301d4Schristos                 Info->DescriptorTypeOp, NULL);
70728c506b8Sjruoho             break;
70828c506b8Sjruoho 
70928c506b8Sjruoho         case ACPI_RSTATE_DEPENDENT_LIST:
71028c506b8Sjruoho         default:
711ff4a156dSchristos 
71228c506b8Sjruoho             break;
71328c506b8Sjruoho         }
71428c506b8Sjruoho 
71528c506b8Sjruoho         *State = ACPI_RSTATE_NORMAL;
716460301d4Schristos         Rnode = RsDoEndDependentDescriptor (Info);
71728c506b8Sjruoho         break;
71828c506b8Sjruoho 
71928c506b8Sjruoho     case PARSEOP_ENDTAG:
720ff4a156dSchristos 
721460301d4Schristos         Rnode = RsDoEndTagDescriptor (Info);
72228c506b8Sjruoho         break;
72328c506b8Sjruoho 
72428c506b8Sjruoho     case PARSEOP_EXTENDEDIO:
725ff4a156dSchristos 
726460301d4Schristos         Rnode = RsDoExtendedIoDescriptor (Info);
72728c506b8Sjruoho         break;
72828c506b8Sjruoho 
72928c506b8Sjruoho     case PARSEOP_EXTENDEDMEMORY:
730ff4a156dSchristos 
731460301d4Schristos         Rnode = RsDoExtendedMemoryDescriptor (Info);
73228c506b8Sjruoho         break;
73328c506b8Sjruoho 
73428c506b8Sjruoho     case PARSEOP_EXTENDEDSPACE:
735ff4a156dSchristos 
736460301d4Schristos         Rnode = RsDoExtendedSpaceDescriptor (Info);
73728c506b8Sjruoho         break;
73828c506b8Sjruoho 
73928c506b8Sjruoho     case PARSEOP_FIXEDIO:
740ff4a156dSchristos 
741460301d4Schristos         Rnode = RsDoFixedIoDescriptor (Info);
74228c506b8Sjruoho         break;
74328c506b8Sjruoho 
74428c506b8Sjruoho     case PARSEOP_INTERRUPT:
745ff4a156dSchristos 
746460301d4Schristos         Rnode = RsDoInterruptDescriptor (Info);
74728c506b8Sjruoho         break;
74828c506b8Sjruoho 
74928c506b8Sjruoho     case PARSEOP_IO:
750ff4a156dSchristos 
751460301d4Schristos         Rnode = RsDoIoDescriptor (Info);
75228c506b8Sjruoho         break;
75328c506b8Sjruoho 
75428c506b8Sjruoho     case PARSEOP_IRQ:
755ff4a156dSchristos 
756460301d4Schristos         Rnode = RsDoIrqDescriptor (Info);
75728c506b8Sjruoho         break;
75828c506b8Sjruoho 
75928c506b8Sjruoho     case PARSEOP_IRQNOFLAGS:
760ff4a156dSchristos 
761460301d4Schristos         Rnode = RsDoIrqNoFlagsDescriptor (Info);
76228c506b8Sjruoho         break;
76328c506b8Sjruoho 
76428c506b8Sjruoho     case PARSEOP_MEMORY24:
765ff4a156dSchristos 
766460301d4Schristos         Rnode = RsDoMemory24Descriptor (Info);
76728c506b8Sjruoho         break;
76828c506b8Sjruoho 
76928c506b8Sjruoho     case PARSEOP_MEMORY32:
770ff4a156dSchristos 
771460301d4Schristos         Rnode = RsDoMemory32Descriptor (Info);
77228c506b8Sjruoho         break;
77328c506b8Sjruoho 
77428c506b8Sjruoho     case PARSEOP_MEMORY32FIXED:
775ff4a156dSchristos 
776460301d4Schristos         Rnode = RsDoMemory32FixedDescriptor (Info);
77728c506b8Sjruoho         break;
77828c506b8Sjruoho 
77928c506b8Sjruoho     case PARSEOP_QWORDIO:
780ff4a156dSchristos 
781460301d4Schristos         Rnode = RsDoQwordIoDescriptor (Info);
78228c506b8Sjruoho         break;
78328c506b8Sjruoho 
78428c506b8Sjruoho     case PARSEOP_QWORDMEMORY:
785ff4a156dSchristos 
786460301d4Schristos         Rnode = RsDoQwordMemoryDescriptor (Info);
78728c506b8Sjruoho         break;
78828c506b8Sjruoho 
789*c7960b37Schristos     case PARSEOP_QWORDPCC:
790*c7960b37Schristos 
791*c7960b37Schristos         Rnode = RsDoQwordPccDescriptor (Info);
792*c7960b37Schristos         break;
793*c7960b37Schristos 
79428c506b8Sjruoho     case PARSEOP_QWORDSPACE:
795ff4a156dSchristos 
796460301d4Schristos         Rnode = RsDoQwordSpaceDescriptor (Info);
79728c506b8Sjruoho         break;
79828c506b8Sjruoho 
79928c506b8Sjruoho     case PARSEOP_REGISTER:
800ff4a156dSchristos 
801460301d4Schristos         Rnode = RsDoGeneralRegisterDescriptor (Info);
80228c506b8Sjruoho         break;
80328c506b8Sjruoho 
80428c506b8Sjruoho     case PARSEOP_STARTDEPENDENTFN:
805ff4a156dSchristos 
80628c506b8Sjruoho         switch (*State)
80728c506b8Sjruoho         {
80828c506b8Sjruoho         case ACPI_RSTATE_START_DEPENDENT:
809ff4a156dSchristos 
81028c506b8Sjruoho             AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING,
811460301d4Schristos                 Info->DescriptorTypeOp, NULL);
81228c506b8Sjruoho             break;
81328c506b8Sjruoho 
81428c506b8Sjruoho         case ACPI_RSTATE_NORMAL:
81528c506b8Sjruoho         case ACPI_RSTATE_DEPENDENT_LIST:
81628c506b8Sjruoho         default:
817ff4a156dSchristos 
81828c506b8Sjruoho             break;
81928c506b8Sjruoho         }
82028c506b8Sjruoho 
82128c506b8Sjruoho         *State = ACPI_RSTATE_START_DEPENDENT;
822460301d4Schristos         Rnode = RsDoStartDependentDescriptor (Info);
82328c506b8Sjruoho         *State = ACPI_RSTATE_DEPENDENT_LIST;
82428c506b8Sjruoho         break;
82528c506b8Sjruoho 
82628c506b8Sjruoho     case PARSEOP_STARTDEPENDENTFN_NOPRI:
827ff4a156dSchristos 
82828c506b8Sjruoho         switch (*State)
82928c506b8Sjruoho         {
83028c506b8Sjruoho         case ACPI_RSTATE_START_DEPENDENT:
831ff4a156dSchristos 
83228c506b8Sjruoho             AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING,
833460301d4Schristos                 Info->DescriptorTypeOp, NULL);
83428c506b8Sjruoho             break;
83528c506b8Sjruoho 
83628c506b8Sjruoho         case ACPI_RSTATE_NORMAL:
83728c506b8Sjruoho         case ACPI_RSTATE_DEPENDENT_LIST:
83828c506b8Sjruoho         default:
839ff4a156dSchristos 
84028c506b8Sjruoho             break;
84128c506b8Sjruoho         }
84228c506b8Sjruoho 
84328c506b8Sjruoho         *State = ACPI_RSTATE_START_DEPENDENT;
844460301d4Schristos         Rnode = RsDoStartDependentNoPriDescriptor (Info);
84528c506b8Sjruoho         *State = ACPI_RSTATE_DEPENDENT_LIST;
84628c506b8Sjruoho         break;
84728c506b8Sjruoho 
84828c506b8Sjruoho     case PARSEOP_VENDORLONG:
849ff4a156dSchristos 
850460301d4Schristos         Rnode = RsDoVendorLargeDescriptor (Info);
85128c506b8Sjruoho         break;
85228c506b8Sjruoho 
85328c506b8Sjruoho     case PARSEOP_VENDORSHORT:
854ff4a156dSchristos 
855460301d4Schristos         Rnode = RsDoVendorSmallDescriptor (Info);
85628c506b8Sjruoho         break;
85728c506b8Sjruoho 
85828c506b8Sjruoho     case PARSEOP_WORDBUSNUMBER:
859ff4a156dSchristos 
860460301d4Schristos         Rnode = RsDoWordBusNumberDescriptor (Info);
86128c506b8Sjruoho         break;
86228c506b8Sjruoho 
86328c506b8Sjruoho     case PARSEOP_WORDIO:
864ff4a156dSchristos 
865460301d4Schristos         Rnode = RsDoWordIoDescriptor (Info);
86628c506b8Sjruoho         break;
86728c506b8Sjruoho 
868*c7960b37Schristos     case PARSEOP_WORDPCC:
869*c7960b37Schristos 
870*c7960b37Schristos         Rnode = RsDoWordPccDescriptor (Info);
871*c7960b37Schristos         break;
872*c7960b37Schristos 
87328c506b8Sjruoho     case PARSEOP_WORDSPACE:
874ff4a156dSchristos 
875460301d4Schristos         Rnode = RsDoWordSpaceDescriptor (Info);
87628c506b8Sjruoho         break;
87728c506b8Sjruoho 
878ff4a156dSchristos     case PARSEOP_GPIO_INT:
879ff4a156dSchristos 
880460301d4Schristos         Rnode = RsDoGpioIntDescriptor (Info);
881ff4a156dSchristos         break;
882ff4a156dSchristos 
883ff4a156dSchristos     case PARSEOP_GPIO_IO:
884ff4a156dSchristos 
885460301d4Schristos         Rnode = RsDoGpioIoDescriptor (Info);
886ff4a156dSchristos         break;
887ff4a156dSchristos 
888ff4a156dSchristos     case PARSEOP_I2C_SERIALBUS:
889cfbb7280Schristos     case PARSEOP_I2C_SERIALBUS_V2:
890ff4a156dSchristos 
891460301d4Schristos         Rnode = RsDoI2cSerialBusDescriptor (Info);
892ff4a156dSchristos         break;
893ff4a156dSchristos 
894ff4a156dSchristos     case PARSEOP_SPI_SERIALBUS:
895cfbb7280Schristos     case PARSEOP_SPI_SERIALBUS_V2:
896ff4a156dSchristos 
897460301d4Schristos         Rnode = RsDoSpiSerialBusDescriptor (Info);
898ff4a156dSchristos         break;
899ff4a156dSchristos 
900ff4a156dSchristos     case PARSEOP_UART_SERIALBUS:
901cfbb7280Schristos     case PARSEOP_UART_SERIALBUS_V2:
902ff4a156dSchristos 
903460301d4Schristos         Rnode = RsDoUartSerialBusDescriptor (Info);
904ff4a156dSchristos         break;
905ff4a156dSchristos 
90646a330b4Schristos     case PARSEOP_CSI2_SERIALBUS:
90746a330b4Schristos 
90846a330b4Schristos         Rnode = RsDoCsi2SerialBusDescriptor (Info);
90946a330b4Schristos         break;
91046a330b4Schristos 
91189b8eb6cSchristos     case PARSEOP_PINCONFIG:
91289b8eb6cSchristos 
91389b8eb6cSchristos         Rnode = RsDoPinConfigDescriptor (Info);
91489b8eb6cSchristos         break;
91589b8eb6cSchristos 
91689b8eb6cSchristos     case PARSEOP_PINFUNCTION:
91789b8eb6cSchristos 
91889b8eb6cSchristos         Rnode = RsDoPinFunctionDescriptor (Info);
91989b8eb6cSchristos         break;
92089b8eb6cSchristos 
92189b8eb6cSchristos     case PARSEOP_PINGROUP:
92289b8eb6cSchristos 
92389b8eb6cSchristos         Rnode = RsDoPinGroupDescriptor (Info);
92489b8eb6cSchristos         break;
92589b8eb6cSchristos 
92689b8eb6cSchristos     case PARSEOP_PINGROUPFUNCTION:
92789b8eb6cSchristos 
92889b8eb6cSchristos         Rnode = RsDoPinGroupFunctionDescriptor (Info);
92989b8eb6cSchristos         break;
93089b8eb6cSchristos 
93189b8eb6cSchristos     case PARSEOP_PINGROUPCONFIG:
93289b8eb6cSchristos 
93389b8eb6cSchristos         Rnode = RsDoPinGroupConfigDescriptor (Info);
93489b8eb6cSchristos         break;
93589b8eb6cSchristos 
93628c506b8Sjruoho     case PARSEOP_DEFAULT_ARG:
937ff4a156dSchristos 
93828c506b8Sjruoho         /* Just ignore any of these, they are used as fillers/placeholders */
93928c506b8Sjruoho         break;
94028c506b8Sjruoho 
94128c506b8Sjruoho     default:
942ff4a156dSchristos 
94328c506b8Sjruoho         printf ("Unknown resource descriptor type [%s]\n",
944460301d4Schristos             Info->DescriptorTypeOp->Asl.ParseOpName);
94528c506b8Sjruoho         break;
94628c506b8Sjruoho     }
94728c506b8Sjruoho 
94828c506b8Sjruoho     /*
94928c506b8Sjruoho      * Mark original node as unused, but head of a resource descriptor.
95028c506b8Sjruoho      * This allows the resource to be installed in the namespace so that
95128c506b8Sjruoho      * references to the descriptor can be resolved.
95228c506b8Sjruoho      */
953460301d4Schristos     Info->DescriptorTypeOp->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
95489b8eb6cSchristos     Info->DescriptorTypeOp->Asl.CompileFlags = OP_IS_RESOURCE_DESC;
955460301d4Schristos     Info->DescriptorTypeOp->Asl.Value.Integer = Info->CurrentByteOffset;
95628c506b8Sjruoho 
95728c506b8Sjruoho     if (Rnode)
95828c506b8Sjruoho     {
959460301d4Schristos         Info->DescriptorTypeOp->Asl.FinalAmlLength = Rnode->BufferLength;
96071e38f1dSchristos         Info->DescriptorTypeOp->Asl.Extra =
96171e38f1dSchristos             ((AML_RESOURCE *) Rnode->Buffer)->DescriptorType;
96228c506b8Sjruoho     }
96328c506b8Sjruoho 
96428c506b8Sjruoho     return (Rnode);
96528c506b8Sjruoho }
96628c506b8Sjruoho 
96728c506b8Sjruoho 
96828c506b8Sjruoho /*******************************************************************************
96928c506b8Sjruoho  *
97028c506b8Sjruoho  * FUNCTION:    RsLinkDescriptorChain
97128c506b8Sjruoho  *
97228c506b8Sjruoho  * PARAMETERS:  PreviousRnode       - Pointer to the node that will be previous
97328c506b8Sjruoho  *                                    to the linked node,  At exit, set to the
97428c506b8Sjruoho  *                                    last node in the new chain.
97528c506b8Sjruoho  *              Rnode               - Resource node to link into the list
97628c506b8Sjruoho  *
97728c506b8Sjruoho  * RETURN:      Cumulative buffer byte offset of the new segment of chain
97828c506b8Sjruoho  *
97928c506b8Sjruoho  * DESCRIPTION: Link a descriptor chain at the end of an existing chain.
98028c506b8Sjruoho  *
98128c506b8Sjruoho  ******************************************************************************/
98228c506b8Sjruoho 
98328c506b8Sjruoho UINT32
98428c506b8Sjruoho RsLinkDescriptorChain (
98528c506b8Sjruoho     ASL_RESOURCE_NODE       **PreviousRnode,
98628c506b8Sjruoho     ASL_RESOURCE_NODE       *Rnode)
98728c506b8Sjruoho {
98828c506b8Sjruoho     ASL_RESOURCE_NODE       *LastRnode;
98928c506b8Sjruoho     UINT32                  CurrentByteOffset;
99028c506b8Sjruoho 
99128c506b8Sjruoho 
99228c506b8Sjruoho     /* Anything to do? */
99328c506b8Sjruoho 
99428c506b8Sjruoho     if (!Rnode)
99528c506b8Sjruoho     {
996ff4a156dSchristos         return (0);
99728c506b8Sjruoho     }
99828c506b8Sjruoho 
99928c506b8Sjruoho     /* Point the previous node to the new node */
100028c506b8Sjruoho 
100128c506b8Sjruoho     (*PreviousRnode)->Next = Rnode;
100228c506b8Sjruoho     CurrentByteOffset = Rnode->BufferLength;
100328c506b8Sjruoho 
100428c506b8Sjruoho     /* Walk to the end of the chain headed by Rnode */
100528c506b8Sjruoho 
100628c506b8Sjruoho     LastRnode = Rnode;
100728c506b8Sjruoho     while (LastRnode->Next)
100828c506b8Sjruoho     {
100928c506b8Sjruoho         LastRnode = LastRnode->Next;
101028c506b8Sjruoho         CurrentByteOffset += LastRnode->BufferLength;
101128c506b8Sjruoho     }
101228c506b8Sjruoho 
101328c506b8Sjruoho     /* Previous node becomes the last node in the chain */
101428c506b8Sjruoho 
101528c506b8Sjruoho     *PreviousRnode = LastRnode;
1016ff4a156dSchristos     return (CurrentByteOffset);
101728c506b8Sjruoho }
101828c506b8Sjruoho 
101928c506b8Sjruoho 
102028c506b8Sjruoho /*******************************************************************************
102128c506b8Sjruoho  *
102228c506b8Sjruoho  * FUNCTION:    RsDoResourceTemplate
102328c506b8Sjruoho  *
102428c506b8Sjruoho  * PARAMETERS:  Op        - Parent of a resource template list
102528c506b8Sjruoho  *
102628c506b8Sjruoho  * RETURN:      None. Sets input node to point to a list of AML code
102728c506b8Sjruoho  *
102828c506b8Sjruoho  * DESCRIPTION: Merge a list of resource descriptors into a single AML buffer,
102928c506b8Sjruoho  *              in preparation for output to the AML output file.
103028c506b8Sjruoho  *
103128c506b8Sjruoho  ******************************************************************************/
103228c506b8Sjruoho 
103328c506b8Sjruoho void
103428c506b8Sjruoho RsDoResourceTemplate (
103528c506b8Sjruoho     ACPI_PARSE_OBJECT       *Op)
103628c506b8Sjruoho {
103728c506b8Sjruoho     ACPI_PARSE_OBJECT       *BufferLengthOp;
103828c506b8Sjruoho     ACPI_PARSE_OBJECT       *BufferOp;
103928c506b8Sjruoho     ACPI_PARSE_OBJECT       *DescriptorTypeOp;
104028c506b8Sjruoho     ACPI_PARSE_OBJECT       *LastOp = NULL;
104128c506b8Sjruoho     UINT32                  CurrentByteOffset = 0;
104228c506b8Sjruoho     ASL_RESOURCE_NODE       HeadRnode;
104328c506b8Sjruoho     ASL_RESOURCE_NODE       *PreviousRnode;
104428c506b8Sjruoho     ASL_RESOURCE_NODE       *Rnode;
1045460301d4Schristos     ASL_RESOURCE_INFO       Info;
104628c506b8Sjruoho     UINT8                   State;
104728c506b8Sjruoho 
104828c506b8Sjruoho 
104928c506b8Sjruoho     /* Mark parent as containing a resource template */
105028c506b8Sjruoho 
105128c506b8Sjruoho     if (Op->Asl.Parent)
105228c506b8Sjruoho     {
105389b8eb6cSchristos         Op->Asl.Parent->Asl.CompileFlags |= OP_IS_RESOURCE_DESC;
105428c506b8Sjruoho     }
105528c506b8Sjruoho 
105628c506b8Sjruoho     /* ResourceTemplate Opcode is first (Op) */
105728c506b8Sjruoho     /* Buffer Length node is first child */
105828c506b8Sjruoho 
105928c506b8Sjruoho     BufferLengthOp = ASL_GET_CHILD_NODE (Op);
106028c506b8Sjruoho 
106128c506b8Sjruoho     /* Buffer Op is first peer */
106228c506b8Sjruoho 
106328c506b8Sjruoho     BufferOp = ASL_GET_PEER_NODE (BufferLengthOp);
106428c506b8Sjruoho 
106528c506b8Sjruoho     /* First Descriptor type is next */
106628c506b8Sjruoho 
106728c506b8Sjruoho     DescriptorTypeOp = ASL_GET_PEER_NODE (BufferOp);
106828c506b8Sjruoho 
106989b8eb6cSchristos     /* DEFAULT_ARG indicates null template - ResourceTemplate(){} */
107089b8eb6cSchristos 
107189b8eb6cSchristos     if (DescriptorTypeOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
107289b8eb6cSchristos     {
107389b8eb6cSchristos         AslError (ASL_WARNING, ASL_MSG_NULL_RESOURCE_TEMPLATE,
107489b8eb6cSchristos             DescriptorTypeOp, DescriptorTypeOp->Asl.Value.String);
107589b8eb6cSchristos     }
107689b8eb6cSchristos 
107728c506b8Sjruoho     /*
107828c506b8Sjruoho      * Process all resource descriptors in the list
107928c506b8Sjruoho      * Note: It is assumed that the EndTag node has been automatically
108028c506b8Sjruoho      * inserted at the end of the template by the parser.
108128c506b8Sjruoho      */
108228c506b8Sjruoho     State = ACPI_RSTATE_NORMAL;
108328c506b8Sjruoho     PreviousRnode = &HeadRnode;
108428c506b8Sjruoho     while (DescriptorTypeOp)
108528c506b8Sjruoho     {
1086460301d4Schristos         /* Save information for optional mapfile */
1087460301d4Schristos 
1088460301d4Schristos         if (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONNECTION)
1089460301d4Schristos         {
1090460301d4Schristos             Info.MappingOp = Op->Asl.Parent;
1091460301d4Schristos         }
1092460301d4Schristos         else
1093460301d4Schristos         {
1094460301d4Schristos             Info.MappingOp = DescriptorTypeOp;
1095460301d4Schristos         }
1096460301d4Schristos 
1097460301d4Schristos         Info.DescriptorTypeOp = DescriptorTypeOp;
1098460301d4Schristos         Info.CurrentByteOffset = CurrentByteOffset;
1099460301d4Schristos 
110089b8eb6cSchristos         DescriptorTypeOp->Asl.CompileFlags |= OP_IS_RESOURCE_DESC;
1101460301d4Schristos         Rnode = RsDoOneResourceDescriptor (&Info, &State);
110228c506b8Sjruoho 
110328c506b8Sjruoho         /*
110428c506b8Sjruoho          * Update current byte offset to indicate the number of bytes from the
110528c506b8Sjruoho          * start of the buffer. Buffer can include multiple descriptors, we
110628c506b8Sjruoho          * must keep track of the offset of not only each descriptor, but each
110728c506b8Sjruoho          * element (field) within each descriptor as well.
110828c506b8Sjruoho          */
110928c506b8Sjruoho         CurrentByteOffset += RsLinkDescriptorChain (&PreviousRnode, Rnode);
111028c506b8Sjruoho 
111128c506b8Sjruoho         /* Get the next descriptor in the list */
111228c506b8Sjruoho 
111328c506b8Sjruoho         LastOp = DescriptorTypeOp;
111428c506b8Sjruoho         DescriptorTypeOp = ASL_GET_PEER_NODE (DescriptorTypeOp);
111528c506b8Sjruoho     }
111628c506b8Sjruoho 
111728c506b8Sjruoho     if (State == ACPI_RSTATE_DEPENDENT_LIST)
111828c506b8Sjruoho     {
111928c506b8Sjruoho         if (LastOp)
112028c506b8Sjruoho         {
112128c506b8Sjruoho             LastOp = LastOp->Asl.Parent;
112228c506b8Sjruoho         }
112328c506b8Sjruoho         AslError (ASL_ERROR, ASL_MSG_MISSING_ENDDEPENDENT, LastOp, NULL);
112428c506b8Sjruoho     }
112528c506b8Sjruoho 
112628c506b8Sjruoho     /*
112728c506b8Sjruoho      * Transform the nodes into the following
112828c506b8Sjruoho      *
112928c506b8Sjruoho      * Op           -> AML_BUFFER_OP
113028c506b8Sjruoho      * First Child  -> BufferLength
113128c506b8Sjruoho      * Second Child -> Descriptor Buffer (raw byte data)
113228c506b8Sjruoho      */
113328c506b8Sjruoho     Op->Asl.ParseOpcode               = PARSEOP_BUFFER;
113428c506b8Sjruoho     Op->Asl.AmlOpcode                 = AML_BUFFER_OP;
113589b8eb6cSchristos     Op->Asl.CompileFlags              = OP_AML_PACKAGE | OP_IS_RESOURCE_DESC;
1136ff4a156dSchristos     UtSetParseOpName (Op);
113728c506b8Sjruoho 
113828c506b8Sjruoho     BufferLengthOp->Asl.ParseOpcode   = PARSEOP_INTEGER;
113928c506b8Sjruoho     BufferLengthOp->Asl.Value.Integer = CurrentByteOffset;
114028c506b8Sjruoho     (void) OpcSetOptimalIntegerSize (BufferLengthOp);
1141ff4a156dSchristos     UtSetParseOpName (BufferLengthOp);
114228c506b8Sjruoho 
114328c506b8Sjruoho     BufferOp->Asl.ParseOpcode         = PARSEOP_RAW_DATA;
114428c506b8Sjruoho     BufferOp->Asl.AmlOpcode           = AML_RAW_DATA_CHAIN;
114528c506b8Sjruoho     BufferOp->Asl.AmlOpcodeLength     = 0;
114628c506b8Sjruoho     BufferOp->Asl.AmlLength           = CurrentByteOffset;
114732aedd46Schristos     BufferOp->Asl.Value.Buffer        = ACPI_CAST_PTR (UINT8,  HeadRnode.Next);
114889b8eb6cSchristos     BufferOp->Asl.CompileFlags       |= OP_IS_RESOURCE_DATA;
1149ff4a156dSchristos     UtSetParseOpName (BufferOp);
115028c506b8Sjruoho 
115128c506b8Sjruoho     return;
115228c506b8Sjruoho }
1153