1118611Snjl/******************************************************************************
2118611Snjl *
3207344Sjkim * Module Name: aslresource - Resource template/descriptor utilities
4118611Snjl *
5118611Snjl *****************************************************************************/
6118611Snjl
7316303Sjkim/******************************************************************************
8316303Sjkim *
9316303Sjkim * 1. Copyright Notice
10316303Sjkim *
11316303Sjkim * Some or all of this work - Copyright (c) 1999 - 2017, Intel Corp.
12118611Snjl * All rights reserved.
13118611Snjl *
14316303Sjkim * 2. License
15316303Sjkim *
16316303Sjkim * 2.1. This is your license from Intel Corp. under its intellectual property
17316303Sjkim * rights. You may have additional license terms from the party that provided
18316303Sjkim * you this software, covering your right to use that party's intellectual
19316303Sjkim * property rights.
20316303Sjkim *
21316303Sjkim * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22316303Sjkim * copy of the source code appearing in this file ("Covered Code") an
23316303Sjkim * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24316303Sjkim * base code distributed originally by Intel ("Original Intel Code") to copy,
25316303Sjkim * make derivatives, distribute, use and display any portion of the Covered
26316303Sjkim * Code in any form, with the right to sublicense such rights; and
27316303Sjkim *
28316303Sjkim * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29316303Sjkim * license (with the right to sublicense), under only those claims of Intel
30316303Sjkim * patents that are infringed by the Original Intel Code, to make, use, sell,
31316303Sjkim * offer to sell, and import the Covered Code and derivative works thereof
32316303Sjkim * solely to the minimum extent necessary to exercise the above copyright
33316303Sjkim * license, and in no event shall the patent license extend to any additions
34316303Sjkim * to or modifications of the Original Intel Code. No other license or right
35316303Sjkim * is granted directly or by implication, estoppel or otherwise;
36316303Sjkim *
37316303Sjkim * The above copyright and patent license is granted only if the following
38316303Sjkim * conditions are met:
39316303Sjkim *
40316303Sjkim * 3. Conditions
41316303Sjkim *
42316303Sjkim * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43316303Sjkim * Redistribution of source code of any substantial portion of the Covered
44316303Sjkim * Code or modification with rights to further distribute source must include
45316303Sjkim * the above Copyright Notice, the above License, this list of Conditions,
46316303Sjkim * and the following Disclaimer and Export Compliance provision. In addition,
47316303Sjkim * Licensee must cause all Covered Code to which Licensee contributes to
48316303Sjkim * contain a file documenting the changes Licensee made to create that Covered
49316303Sjkim * Code and the date of any change. Licensee must include in that file the
50316303Sjkim * documentation of any changes made by any predecessor Licensee. Licensee
51316303Sjkim * must include a prominent statement that the modification is derived,
52316303Sjkim * directly or indirectly, from Original Intel Code.
53316303Sjkim *
54316303Sjkim * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55316303Sjkim * Redistribution of source code of any substantial portion of the Covered
56316303Sjkim * Code or modification without rights to further distribute source must
57316303Sjkim * include the following Disclaimer and Export Compliance provision in the
58316303Sjkim * documentation and/or other materials provided with distribution. In
59316303Sjkim * addition, Licensee may not authorize further sublicense of source of any
60316303Sjkim * portion of the Covered Code, and must include terms to the effect that the
61316303Sjkim * license from Licensee to its licensee is limited to the intellectual
62316303Sjkim * property embodied in the software Licensee provides to its licensee, and
63316303Sjkim * not to intellectual property embodied in modifications its licensee may
64316303Sjkim * make.
65316303Sjkim *
66316303Sjkim * 3.3. Redistribution of Executable. Redistribution in executable form of any
67316303Sjkim * substantial portion of the Covered Code or modification must reproduce the
68316303Sjkim * above Copyright Notice, and the following Disclaimer and Export Compliance
69316303Sjkim * provision in the documentation and/or other materials provided with the
70316303Sjkim * distribution.
71316303Sjkim *
72316303Sjkim * 3.4. Intel retains all right, title, and interest in and to the Original
73316303Sjkim * Intel Code.
74316303Sjkim *
75316303Sjkim * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76316303Sjkim * Intel shall be used in advertising or otherwise to promote the sale, use or
77316303Sjkim * other dealings in products derived from or relating to the Covered Code
78316303Sjkim * without prior written authorization from Intel.
79316303Sjkim *
80316303Sjkim * 4. Disclaimer and Export Compliance
81316303Sjkim *
82316303Sjkim * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83316303Sjkim * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84316303Sjkim * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85316303Sjkim * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86316303Sjkim * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87316303Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88316303Sjkim * PARTICULAR PURPOSE.
89316303Sjkim *
90316303Sjkim * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91316303Sjkim * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92316303Sjkim * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93316303Sjkim * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94316303Sjkim * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95316303Sjkim * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96316303Sjkim * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97316303Sjkim * LIMITED REMEDY.
98316303Sjkim *
99316303Sjkim * 4.3. Licensee shall not export, either directly or indirectly, any of this
100316303Sjkim * software or system incorporating such software without first obtaining any
101316303Sjkim * required license or other approval from the U. S. Department of Commerce or
102316303Sjkim * any other agency or department of the United States Government. In the
103316303Sjkim * event Licensee exports any such software from the United States or
104316303Sjkim * re-exports any such software from a foreign destination, Licensee shall
105316303Sjkim * ensure that the distribution and export/re-export of the software is in
106316303Sjkim * compliance with all laws, regulations, orders, or other restrictions of the
107316303Sjkim * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108316303Sjkim * any of its subsidiaries will export/re-export any technical data, process,
109316303Sjkim * software, or service, directly or indirectly, to any country for which the
110316303Sjkim * United States government or any agency thereof requires an export license,
111316303Sjkim * other governmental approval, or letter of assurance, without first obtaining
112316303Sjkim * such license, approval or letter.
113316303Sjkim *
114316303Sjkim *****************************************************************************
115316303Sjkim *
116316303Sjkim * Alternatively, you may choose to be licensed under the terms of the
117316303Sjkim * following license:
118316303Sjkim *
119217365Sjkim * Redistribution and use in source and binary forms, with or without
120217365Sjkim * modification, are permitted provided that the following conditions
121217365Sjkim * are met:
122217365Sjkim * 1. Redistributions of source code must retain the above copyright
123217365Sjkim *    notice, this list of conditions, and the following disclaimer,
124217365Sjkim *    without modification.
125217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126217365Sjkim *    substantially similar to the "NO WARRANTY" disclaimer below
127217365Sjkim *    ("Disclaimer") and any redistribution must be conditioned upon
128217365Sjkim *    including a substantially similar Disclaimer requirement for further
129217365Sjkim *    binary redistribution.
130217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names
131217365Sjkim *    of any contributors may be used to endorse or promote products derived
132217365Sjkim *    from this software without specific prior written permission.
133118611Snjl *
134316303Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135316303Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136316303Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137316303Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138316303Sjkim * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139316303Sjkim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140316303Sjkim * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141316303Sjkim * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142316303Sjkim * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143316303Sjkim * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144316303Sjkim * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145316303Sjkim *
146316303Sjkim * Alternatively, you may choose to be licensed under the terms of the
147217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free
148217365Sjkim * Software Foundation.
149118611Snjl *
150316303Sjkim *****************************************************************************/
151118611Snjl
152151937Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h>
153118611Snjl#include "aslcompiler.y.h"
154193529Sjkim#include <contrib/dev/acpica/include/amlcode.h>
155118611Snjl
156118611Snjl
157118611Snjl#define _COMPONENT          ACPI_COMPILER
158118611Snjl        ACPI_MODULE_NAME    ("aslresource")
159118611Snjl
160118611Snjl
161118611Snjl/*******************************************************************************
162118611Snjl *
163207344Sjkim * FUNCTION:    RsSmallAddressCheck
164207344Sjkim *
165207344Sjkim * PARAMETERS:  Minimum             - Address Min value
166207344Sjkim *              Maximum             - Address Max value
167207344Sjkim *              Length              - Address range value
168207344Sjkim *              Alignment           - Address alignment value
169207344Sjkim *              MinOp               - Original Op for Address Min
170207344Sjkim *              MaxOp               - Original Op for Address Max
171207344Sjkim *              LengthOp            - Original Op for address range
172207344Sjkim *              AlignOp             - Original Op for address alignment. If
173207344Sjkim *                                    NULL, means "zero value for alignment is
174207344Sjkim *                                    OK, and means 64K alignment" (for
175207344Sjkim *                                    Memory24 descriptor)
176213806Sjkim *              Op                  - Parent Op for entire construct
177207344Sjkim *
178207344Sjkim * RETURN:      None. Adds error messages to error log if necessary
179207344Sjkim *
180207344Sjkim * DESCRIPTION: Perform common value checks for "small" address descriptors.
181207344Sjkim *              Currently:
182207344Sjkim *                  Io, Memory24, Memory32
183207344Sjkim *
184207344Sjkim ******************************************************************************/
185207344Sjkim
186207344Sjkimvoid
187207344SjkimRsSmallAddressCheck (
188207344Sjkim    UINT8                   Type,
189207344Sjkim    UINT32                  Minimum,
190207344Sjkim    UINT32                  Maximum,
191207344Sjkim    UINT32                  Length,
192207344Sjkim    UINT32                  Alignment,
193207344Sjkim    ACPI_PARSE_OBJECT       *MinOp,
194207344Sjkim    ACPI_PARSE_OBJECT       *MaxOp,
195207344Sjkim    ACPI_PARSE_OBJECT       *LengthOp,
196213806Sjkim    ACPI_PARSE_OBJECT       *AlignOp,
197213806Sjkim    ACPI_PARSE_OBJECT       *Op)
198207344Sjkim{
199207344Sjkim
200207344Sjkim    if (Gbl_NoResourceChecking)
201207344Sjkim    {
202207344Sjkim        return;
203207344Sjkim    }
204207344Sjkim
205213806Sjkim    /*
206213806Sjkim     * Check for a so-called "null descriptor". These are descriptors that are
207213806Sjkim     * created with most fields set to zero. The intent is that the descriptor
208213806Sjkim     * will be updated/completed at runtime via a BufferField.
209213806Sjkim     *
210213806Sjkim     * If the descriptor does NOT have a resource tag, it cannot be referenced
211213806Sjkim     * by a BufferField and we will flag this as an error. Conversely, if
212213806Sjkim     * the descriptor has a resource tag, we will assume that a BufferField
213213806Sjkim     * will be used to dynamically update it, so no error.
214213806Sjkim     *
215213806Sjkim     * A possible enhancement to this check would be to verify that in fact
216213806Sjkim     * a BufferField is created using the resource tag, and perhaps even
217213806Sjkim     * verify that a Store is performed to the BufferField.
218213806Sjkim     *
219213806Sjkim     * Note: for these descriptors, Alignment is allowed to be zero
220213806Sjkim     */
221213806Sjkim    if (!Minimum && !Maximum && !Length)
222213806Sjkim    {
223213806Sjkim        if (!Op->Asl.ExternalName)
224213806Sjkim        {
225213806Sjkim            /* No resource tag. Descriptor is fixed and is also illegal */
226213806Sjkim
227213806Sjkim            AslError (ASL_ERROR, ASL_MSG_NULL_DESCRIPTOR, Op, NULL);
228213806Sjkim        }
229213806Sjkim
230213806Sjkim        return;
231213806Sjkim    }
232213806Sjkim
233272444Sjkim    /*
234272444Sjkim     * Range checks for Memory24 and Memory32.
235272444Sjkim     * IO descriptor has different definition of min/max, don't check.
236272444Sjkim     */
237207344Sjkim    if (Type != ACPI_RESOURCE_NAME_IO)
238207344Sjkim    {
239207344Sjkim        /* Basic checks on Min/Max/Length */
240207344Sjkim
241207344Sjkim        if (Minimum > Maximum)
242207344Sjkim        {
243207344Sjkim            AslError (ASL_ERROR, ASL_MSG_INVALID_MIN_MAX, MinOp, NULL);
244207344Sjkim        }
245207344Sjkim        else if (Length > (Maximum - Minimum + 1))
246207344Sjkim        {
247207344Sjkim            AslError (ASL_ERROR, ASL_MSG_INVALID_LENGTH, LengthOp, NULL);
248207344Sjkim        }
249272444Sjkim
250272444Sjkim        /* Special case for Memory24, min/max values are compressed */
251272444Sjkim
252272444Sjkim        if (Type == ACPI_RESOURCE_NAME_MEMORY24)
253272444Sjkim        {
254272444Sjkim            if (!Alignment) /* Alignment==0 means 64K alignment */
255272444Sjkim            {
256272444Sjkim                Alignment = ACPI_UINT16_MAX + 1;
257272444Sjkim            }
258272444Sjkim
259272444Sjkim            Minimum <<= 8;
260272444Sjkim            Maximum <<= 8;
261272444Sjkim        }
262207344Sjkim    }
263207344Sjkim
264207344Sjkim    /* Alignment of zero is not in ACPI spec, but is used to mean byte acc */
265207344Sjkim
266207344Sjkim    if (!Alignment)
267207344Sjkim    {
268207344Sjkim        Alignment = 1;
269207344Sjkim    }
270207344Sjkim
271207344Sjkim    /* Addresses must be an exact multiple of the alignment value */
272207344Sjkim
273207344Sjkim    if (Minimum % Alignment)
274207344Sjkim    {
275207344Sjkim        AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MinOp, NULL);
276207344Sjkim    }
277207344Sjkim    if (Maximum % Alignment)
278207344Sjkim    {
279207344Sjkim        AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MaxOp, NULL);
280207344Sjkim    }
281207344Sjkim}
282207344Sjkim
283207344Sjkim
284207344Sjkim/*******************************************************************************
285207344Sjkim *
286207344Sjkim * FUNCTION:    RsLargeAddressCheck
287207344Sjkim *
288207344Sjkim * PARAMETERS:  Minimum             - Address Min value
289207344Sjkim *              Maximum             - Address Max value
290207344Sjkim *              Length              - Address range value
291207344Sjkim *              Granularity         - Address granularity value
292207344Sjkim *              Flags               - General flags for address descriptors:
293207344Sjkim *                                    _MIF, _MAF, _DEC
294207344Sjkim *              MinOp               - Original Op for Address Min
295207344Sjkim *              MaxOp               - Original Op for Address Max
296207344Sjkim *              LengthOp            - Original Op for address range
297207344Sjkim *              GranOp              - Original Op for address granularity
298213806Sjkim *              Op                  - Parent Op for entire construct
299207344Sjkim *
300207344Sjkim * RETURN:      None. Adds error messages to error log if necessary
301207344Sjkim *
302207344Sjkim * DESCRIPTION: Perform common value checks for "large" address descriptors.
303207344Sjkim *              Currently:
304207344Sjkim *                  WordIo,     WordBusNumber,  WordSpace
305207344Sjkim *                  DWordIo,    DWordMemory,    DWordSpace
306207344Sjkim *                  QWordIo,    QWordMemory,    QWordSpace
307207344Sjkim *                  ExtendedIo, ExtendedMemory, ExtendedSpace
308207344Sjkim *
309207344Sjkim * _MIF flag set means that the minimum address is fixed and is not relocatable
310207344Sjkim * _MAF flag set means that the maximum address is fixed and is not relocatable
311207344Sjkim * Length of zero means that the record size is variable
312207344Sjkim *
313207344Sjkim * This function implements the LEN/MIF/MAF/MIN/MAX/GRA rules within Table 6-40
314207344Sjkim * of the ACPI 4.0a specification. Added 04/2010.
315207344Sjkim *
316207344Sjkim ******************************************************************************/
317207344Sjkim
318207344Sjkimvoid
319207344SjkimRsLargeAddressCheck (
320207344Sjkim    UINT64                  Minimum,
321207344Sjkim    UINT64                  Maximum,
322207344Sjkim    UINT64                  Length,
323207344Sjkim    UINT64                  Granularity,
324207344Sjkim    UINT8                   Flags,
325207344Sjkim    ACPI_PARSE_OBJECT       *MinOp,
326207344Sjkim    ACPI_PARSE_OBJECT       *MaxOp,
327207344Sjkim    ACPI_PARSE_OBJECT       *LengthOp,
328213806Sjkim    ACPI_PARSE_OBJECT       *GranOp,
329213806Sjkim    ACPI_PARSE_OBJECT       *Op)
330207344Sjkim{
331207344Sjkim
332207344Sjkim    if (Gbl_NoResourceChecking)
333207344Sjkim    {
334207344Sjkim        return;
335207344Sjkim    }
336207344Sjkim
337213806Sjkim    /*
338213806Sjkim     * Check for a so-called "null descriptor". These are descriptors that are
339213806Sjkim     * created with most fields set to zero. The intent is that the descriptor
340213806Sjkim     * will be updated/completed at runtime via a BufferField.
341213806Sjkim     *
342213806Sjkim     * If the descriptor does NOT have a resource tag, it cannot be referenced
343213806Sjkim     * by a BufferField and we will flag this as an error. Conversely, if
344213806Sjkim     * the descriptor has a resource tag, we will assume that a BufferField
345213806Sjkim     * will be used to dynamically update it, so no error.
346213806Sjkim     *
347213806Sjkim     * A possible enhancement to this check would be to verify that in fact
348213806Sjkim     * a BufferField is created using the resource tag, and perhaps even
349213806Sjkim     * verify that a Store is performed to the BufferField.
350213806Sjkim     */
351213806Sjkim    if (!Minimum && !Maximum && !Length && !Granularity)
352213806Sjkim    {
353213806Sjkim        if (!Op->Asl.ExternalName)
354213806Sjkim        {
355213806Sjkim            /* No resource tag. Descriptor is fixed and is also illegal */
356213806Sjkim
357213806Sjkim            AslError (ASL_ERROR, ASL_MSG_NULL_DESCRIPTOR, Op, NULL);
358213806Sjkim        }
359213806Sjkim
360213806Sjkim        return;
361213806Sjkim    }
362213806Sjkim
363207344Sjkim    /* Basic checks on Min/Max/Length */
364207344Sjkim
365207344Sjkim    if (Minimum > Maximum)
366207344Sjkim    {
367207344Sjkim        AslError (ASL_ERROR, ASL_MSG_INVALID_MIN_MAX, MinOp, NULL);
368207344Sjkim        return;
369207344Sjkim    }
370207344Sjkim    else if (Length > (Maximum - Minimum + 1))
371207344Sjkim    {
372207344Sjkim        AslError (ASL_ERROR, ASL_MSG_INVALID_LENGTH, LengthOp, NULL);
373207344Sjkim        return;
374207344Sjkim    }
375207344Sjkim
376207344Sjkim    /* If specified (non-zero), ensure granularity is a power-of-two minus one */
377207344Sjkim
378207344Sjkim    if (Granularity)
379207344Sjkim    {
380207344Sjkim        if ((Granularity + 1) &
381207344Sjkim             Granularity)
382207344Sjkim        {
383207344Sjkim            AslError (ASL_ERROR, ASL_MSG_INVALID_GRANULARITY, GranOp, NULL);
384207344Sjkim            return;
385207344Sjkim        }
386207344Sjkim    }
387207344Sjkim
388207344Sjkim    /*
389207344Sjkim     * Check the various combinations of Length, MinFixed, and MaxFixed
390207344Sjkim     */
391207344Sjkim    if (Length)
392207344Sjkim    {
393207344Sjkim        /* Fixed non-zero length */
394207344Sjkim
395207344Sjkim        switch (Flags & (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF))
396207344Sjkim        {
397207344Sjkim        case 0:
398207344Sjkim            /*
399207344Sjkim             * Fixed length, variable locations (both _MIN and _MAX).
400207344Sjkim             * Length must be a multiple of granularity
401207344Sjkim             */
402207344Sjkim            if (Granularity & Length)
403207344Sjkim            {
404207344Sjkim                AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, LengthOp, NULL);
405207344Sjkim            }
406207344Sjkim            break;
407207344Sjkim
408207344Sjkim        case (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF):
409207344Sjkim
410207344Sjkim            /* Fixed length, fixed location. Granularity must be zero */
411207344Sjkim
412207344Sjkim            if (Granularity != 0)
413207344Sjkim            {
414207344Sjkim                AslError (ASL_ERROR, ASL_MSG_INVALID_GRAN_FIXED, GranOp, NULL);
415207344Sjkim            }
416207344Sjkim
417207344Sjkim            /* Length must be exactly the size of the min/max window */
418207344Sjkim
419207344Sjkim            if (Length != (Maximum - Minimum + 1))
420207344Sjkim            {
421207344Sjkim                AslError (ASL_ERROR, ASL_MSG_INVALID_LENGTH_FIXED, LengthOp, NULL);
422207344Sjkim            }
423207344Sjkim            break;
424207344Sjkim
425207344Sjkim        /* All other combinations are invalid */
426207344Sjkim
427207344Sjkim        case ACPI_RESOURCE_FLAG_MIF:
428207344Sjkim        case ACPI_RESOURCE_FLAG_MAF:
429207344Sjkim        default:
430250838Sjkim
431207344Sjkim            AslError (ASL_ERROR, ASL_MSG_INVALID_ADDR_FLAGS, LengthOp, NULL);
432207344Sjkim        }
433207344Sjkim    }
434207344Sjkim    else
435207344Sjkim    {
436207344Sjkim        /* Variable length (length==0) */
437207344Sjkim
438207344Sjkim        switch (Flags & (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF))
439207344Sjkim        {
440207344Sjkim        case 0:
441207344Sjkim            /*
442207344Sjkim             * Both _MIN and _MAX are variable.
443207344Sjkim             * No additional requirements, just exit
444207344Sjkim             */
445207344Sjkim            break;
446207344Sjkim
447207344Sjkim        case ACPI_RESOURCE_FLAG_MIF:
448207344Sjkim
449207344Sjkim            /* _MIN is fixed. _MIN must be multiple of _GRA */
450207344Sjkim
451207344Sjkim            /*
452207344Sjkim             * The granularity is defined by the ACPI specification to be a
453207344Sjkim             * power-of-two minus one, therefore the granularity is a
454207344Sjkim             * bitmask which can be used to easily validate the addresses.
455207344Sjkim             */
456207344Sjkim            if (Granularity & Minimum)
457207344Sjkim            {
458207344Sjkim                AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MinOp, NULL);
459207344Sjkim            }
460207344Sjkim            break;
461207344Sjkim
462207344Sjkim        case ACPI_RESOURCE_FLAG_MAF:
463207344Sjkim
464207344Sjkim            /* _MAX is fixed. (_MAX + 1) must be multiple of _GRA */
465207344Sjkim
466207344Sjkim            if (Granularity & (Maximum + 1))
467207344Sjkim            {
468207344Sjkim                AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MaxOp, "-1");
469207344Sjkim            }
470207344Sjkim            break;
471207344Sjkim
472207344Sjkim        /* Both MIF/MAF set is invalid if length is zero */
473207344Sjkim
474207344Sjkim        case (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF):
475207344Sjkim        default:
476250838Sjkim
477207344Sjkim            AslError (ASL_ERROR, ASL_MSG_INVALID_ADDR_FLAGS, LengthOp, NULL);
478207344Sjkim        }
479207344Sjkim    }
480207344Sjkim}
481207344Sjkim
482207344Sjkim
483207344Sjkim/*******************************************************************************
484207344Sjkim *
485207344Sjkim * FUNCTION:    RsGetStringDataLength
486207344Sjkim *
487207344Sjkim * PARAMETERS:  InitializerOp     - Start of a subtree of init nodes
488207344Sjkim *
489207344Sjkim * RETURN:      Valid string length if a string node is found (otherwise 0)
490207344Sjkim *
491207344Sjkim * DESCRIPTION: In a list of peer nodes, find the first one that contains a
492207344Sjkim *              string and return the length of the string.
493207344Sjkim *
494207344Sjkim ******************************************************************************/
495207344Sjkim
496207344SjkimUINT16
497207344SjkimRsGetStringDataLength (
498207344Sjkim    ACPI_PARSE_OBJECT       *InitializerOp)
499207344Sjkim{
500207344Sjkim
501207344Sjkim    while (InitializerOp)
502207344Sjkim    {
503207344Sjkim        if (InitializerOp->Asl.ParseOpcode == PARSEOP_STRING_LITERAL)
504207344Sjkim        {
505207344Sjkim            return ((UINT16) (strlen (InitializerOp->Asl.Value.String) + 1));
506207344Sjkim        }
507298714Sjkim
508207344Sjkim        InitializerOp = ASL_GET_PEER_NODE (InitializerOp);
509207344Sjkim    }
510207344Sjkim
511241973Sjkim    return (0);
512207344Sjkim}
513207344Sjkim
514207344Sjkim
515207344Sjkim/*******************************************************************************
516207344Sjkim *
517118611Snjl * FUNCTION:    RsAllocateResourceNode
518118611Snjl *
519118611Snjl * PARAMETERS:  Size        - Size of node in bytes
520118611Snjl *
521118611Snjl * RETURN:      The allocated node - aborts on allocation failure
522118611Snjl *
523118611Snjl * DESCRIPTION: Allocate a resource description node and the resource
524118611Snjl *              descriptor itself (the nodes are used to link descriptors).
525118611Snjl *
526118611Snjl ******************************************************************************/
527118611Snjl
528118611SnjlASL_RESOURCE_NODE *
529118611SnjlRsAllocateResourceNode (
530118611Snjl    UINT32                  Size)
531118611Snjl{
532118611Snjl    ASL_RESOURCE_NODE       *Rnode;
533118611Snjl
534118611Snjl
535118611Snjl    /* Allocate the node */
536118611Snjl
537118611Snjl    Rnode = UtLocalCalloc (sizeof (ASL_RESOURCE_NODE));
538118611Snjl
539118611Snjl    /* Allocate the resource descriptor itself */
540118611Snjl
541118611Snjl    Rnode->Buffer = UtLocalCalloc (Size);
542118611Snjl    Rnode->BufferLength = Size;
543118611Snjl    return (Rnode);
544118611Snjl}
545118611Snjl
546118611Snjl
547118611Snjl/*******************************************************************************
548118611Snjl *
549228110Sjkim * FUNCTION:    RsCreateResourceField
550118611Snjl *
551151937Sjkim * PARAMETERS:  Op              - Resource field node
552118611Snjl *              Name            - Name of the field (Used only to reference
553118611Snjl *                                the field in the ASL, not in the AML)
554118611Snjl *              ByteOffset      - Offset from the field start
555118611Snjl *              BitOffset       - Additional bit offset
556228110Sjkim *              BitLength       - Number of bits in the field
557118611Snjl *
558118611Snjl * RETURN:      None, sets fields within the input node
559118611Snjl *
560118611Snjl * DESCRIPTION: Utility function to generate a named bit field within a
561241973Sjkim *              resource descriptor. Mark a node as 1) a field in a resource
562118611Snjl *              descriptor, and 2) set the value to be a BIT offset
563118611Snjl *
564118611Snjl ******************************************************************************/
565118611Snjl
566118611Snjlvoid
567228110SjkimRsCreateResourceField (
568118611Snjl    ACPI_PARSE_OBJECT       *Op,
569118611Snjl    char                    *Name,
570118611Snjl    UINT32                  ByteOffset,
571228110Sjkim    UINT32                  BitOffset,
572228110Sjkim    UINT32                  BitLength)
573118611Snjl{
574118611Snjl
575228110Sjkim    Op->Asl.ExternalName = Name;
576322877Sjkim    Op->Asl.CompileFlags |= OP_IS_RESOURCE_FIELD;
577118611Snjl
578228110Sjkim    Op->Asl.Value.Tag.BitOffset = (ByteOffset * 8) + BitOffset;
579228110Sjkim    Op->Asl.Value.Tag.BitLength = BitLength;
580118611Snjl}
581118611Snjl
582118611Snjl
583118611Snjl/*******************************************************************************
584118611Snjl *
585118611Snjl * FUNCTION:    RsSetFlagBits
586118611Snjl *
587118611Snjl * PARAMETERS:  *Flags          - Pointer to the flag byte
588151937Sjkim *              Op              - Flag initialization node
589118611Snjl *              Position        - Bit position within the flag byte
590118611Snjl *              Default         - Used if the node is DEFAULT.
591118611Snjl *
592118611Snjl * RETURN:      Sets bits within the *Flags output byte.
593118611Snjl *
594118611Snjl * DESCRIPTION: Set a bit in a cumulative flags word from an initialization
595241973Sjkim *              node. Will use a default value if the node is DEFAULT, meaning
596241973Sjkim *              that no value was specified in the ASL. Used to merge multiple
597118611Snjl *              keywords into a single flags byte.
598118611Snjl *
599118611Snjl ******************************************************************************/
600118611Snjl
601118611Snjlvoid
602118611SnjlRsSetFlagBits (
603118611Snjl    UINT8                   *Flags,
604118611Snjl    ACPI_PARSE_OBJECT       *Op,
605118611Snjl    UINT8                   Position,
606118611Snjl    UINT8                   DefaultBit)
607118611Snjl{
608118611Snjl
609118611Snjl    if (Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
610118611Snjl    {
611118611Snjl        /* Use the default bit */
612118611Snjl
613118611Snjl        *Flags |= (DefaultBit << Position);
614118611Snjl    }
615118611Snjl    else
616118611Snjl    {
617118611Snjl        /* Use the bit specified in the initialization node */
618118611Snjl
619118611Snjl        *Flags |= (((UINT8) Op->Asl.Value.Integer) << Position);
620118611Snjl    }
621118611Snjl}
622118611Snjl
623118611Snjl
624228110Sjkimvoid
625228110SjkimRsSetFlagBits16 (
626228110Sjkim    UINT16                  *Flags,
627228110Sjkim    ACPI_PARSE_OBJECT       *Op,
628228110Sjkim    UINT8                   Position,
629228110Sjkim    UINT8                   DefaultBit)
630228110Sjkim{
631228110Sjkim
632228110Sjkim    if (Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
633228110Sjkim    {
634228110Sjkim        /* Use the default bit */
635228110Sjkim
636228110Sjkim        *Flags |= (DefaultBit << Position);
637228110Sjkim    }
638228110Sjkim    else
639228110Sjkim    {
640228110Sjkim        /* Use the bit specified in the initialization node */
641228110Sjkim
642228110Sjkim        *Flags |= (((UINT16) Op->Asl.Value.Integer) << Position);
643228110Sjkim    }
644228110Sjkim}
645228110Sjkim
646228110Sjkim
647118611Snjl/*******************************************************************************
648118611Snjl *
649118611Snjl * FUNCTION:    RsCompleteNodeAndGetNext
650118611Snjl *
651118611Snjl * PARAMETERS:  Op            - Resource node to be completed
652118611Snjl *
653118611Snjl * RETURN:      The next peer to the input node.
654118611Snjl *
655118611Snjl * DESCRIPTION: Mark the current node completed and return the next peer.
656118611Snjl *              The node ParseOpcode is set to DEFAULT_ARG, meaning that
657118611Snjl *              this node is to be ignored from now on.
658118611Snjl *
659118611Snjl ******************************************************************************/
660118611Snjl
661118611SnjlACPI_PARSE_OBJECT *
662118611SnjlRsCompleteNodeAndGetNext (
663118611Snjl    ACPI_PARSE_OBJECT       *Op)
664118611Snjl{
665118611Snjl
666118611Snjl    /* Mark this node unused */
667118611Snjl
668118611Snjl    Op->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
669118611Snjl
670118611Snjl    /* Move on to the next peer node in the initializer list */
671118611Snjl
672118611Snjl    return (ASL_GET_PEER_NODE (Op));
673118611Snjl}
674118611Snjl
675118611Snjl
676118611Snjl/*******************************************************************************
677118611Snjl *
678151937Sjkim * FUNCTION:    RsCheckListForDuplicates
679151937Sjkim *
680151937Sjkim * PARAMETERS:  Op                  - First op in the initializer list
681151937Sjkim *
682151937Sjkim * RETURN:      None
683151937Sjkim *
684151937Sjkim * DESCRIPTION: Check an initializer list for duplicate values. Emits an error
685151937Sjkim *              if any duplicates are found.
686151937Sjkim *
687151937Sjkim ******************************************************************************/
688151937Sjkim
689151937Sjkimvoid
690151937SjkimRsCheckListForDuplicates (
691151937Sjkim    ACPI_PARSE_OBJECT       *Op)
692151937Sjkim{
693151937Sjkim    ACPI_PARSE_OBJECT       *NextValueOp = Op;
694151937Sjkim    ACPI_PARSE_OBJECT       *NextOp;
695151937Sjkim    UINT32                  Value;
696151937Sjkim
697151937Sjkim
698151937Sjkim    if (!Op)
699151937Sjkim    {
700151937Sjkim        return;
701151937Sjkim    }
702151937Sjkim
703151937Sjkim    /* Search list once for each value in the list */
704151937Sjkim
705151937Sjkim    while (NextValueOp)
706151937Sjkim    {
707151937Sjkim        Value = (UINT32) NextValueOp->Asl.Value.Integer;
708151937Sjkim
709151937Sjkim        /* Compare this value to all remaining values in the list */
710151937Sjkim
711151937Sjkim        NextOp = ASL_GET_PEER_NODE (NextValueOp);
712151937Sjkim        while (NextOp)
713151937Sjkim        {
714151937Sjkim            if (NextOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
715151937Sjkim            {
716151937Sjkim                /* Compare values */
717151937Sjkim
718151937Sjkim                if (Value == (UINT32) NextOp->Asl.Value.Integer)
719151937Sjkim                {
720151937Sjkim                    /* Emit error only once per duplicate node */
721151937Sjkim
722322877Sjkim                    if (!(NextOp->Asl.CompileFlags & OP_IS_DUPLICATE))
723151937Sjkim                    {
724322877Sjkim                        NextOp->Asl.CompileFlags |= OP_IS_DUPLICATE;
725151937Sjkim                        AslError (ASL_ERROR, ASL_MSG_DUPLICATE_ITEM,
726151937Sjkim                            NextOp, NULL);
727151937Sjkim                    }
728151937Sjkim                }
729151937Sjkim            }
730151937Sjkim
731151937Sjkim            NextOp = ASL_GET_PEER_NODE (NextOp);
732151937Sjkim        }
733151937Sjkim
734151937Sjkim        NextValueOp = ASL_GET_PEER_NODE (NextValueOp);
735151937Sjkim    }
736151937Sjkim}
737151937Sjkim
738151937Sjkim
739151937Sjkim/*******************************************************************************
740151937Sjkim *
741118611Snjl * FUNCTION:    RsDoOneResourceDescriptor
742118611Snjl *
743118611Snjl * PARAMETERS:  DescriptorTypeOp    - Parent parse node of the descriptor
744118611Snjl *              CurrentByteOffset   - Offset in the resource descriptor
745118611Snjl *                                    buffer.
746118611Snjl *
747118611Snjl * RETURN:      A valid resource node for the descriptor
748118611Snjl *
749118611Snjl * DESCRIPTION: Dispatches the processing of one resource descriptor
750118611Snjl *
751118611Snjl ******************************************************************************/
752118611Snjl
753118611SnjlASL_RESOURCE_NODE *
754118611SnjlRsDoOneResourceDescriptor (
755272444Sjkim    ASL_RESOURCE_INFO       *Info,
756118611Snjl    UINT8                   *State)
757118611Snjl{
758118611Snjl    ASL_RESOURCE_NODE       *Rnode = NULL;
759118611Snjl
760118611Snjl
761167802Sjkim    /* Construct the resource */
762118611Snjl
763272444Sjkim    switch (Info->DescriptorTypeOp->Asl.ParseOpcode)
764118611Snjl    {
765118611Snjl    case PARSEOP_DMA:
766250838Sjkim
767272444Sjkim        Rnode = RsDoDmaDescriptor (Info);
768118611Snjl        break;
769118611Snjl
770228110Sjkim    case PARSEOP_FIXEDDMA:
771250838Sjkim
772272444Sjkim        Rnode = RsDoFixedDmaDescriptor (Info);
773228110Sjkim        break;
774228110Sjkim
775118611Snjl    case PARSEOP_DWORDIO:
776250838Sjkim
777272444Sjkim        Rnode = RsDoDwordIoDescriptor (Info);
778118611Snjl        break;
779118611Snjl
780118611Snjl    case PARSEOP_DWORDMEMORY:
781250838Sjkim
782272444Sjkim        Rnode = RsDoDwordMemoryDescriptor (Info);
783118611Snjl        break;
784118611Snjl
785151937Sjkim    case PARSEOP_DWORDSPACE:
786250838Sjkim
787272444Sjkim        Rnode = RsDoDwordSpaceDescriptor (Info);
788151937Sjkim        break;
789151937Sjkim
790118611Snjl    case PARSEOP_ENDDEPENDENTFN:
791250838Sjkim
792118611Snjl        switch (*State)
793118611Snjl        {
794118611Snjl        case ACPI_RSTATE_NORMAL:
795250838Sjkim
796151937Sjkim            AslError (ASL_ERROR, ASL_MSG_MISSING_STARTDEPENDENT,
797272444Sjkim                Info->DescriptorTypeOp, NULL);
798118611Snjl            break;
799118611Snjl
800118611Snjl        case ACPI_RSTATE_START_DEPENDENT:
801250838Sjkim
802151937Sjkim            AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING,
803272444Sjkim                Info->DescriptorTypeOp, NULL);
804118611Snjl            break;
805118611Snjl
806118611Snjl        case ACPI_RSTATE_DEPENDENT_LIST:
807118611Snjl        default:
808250838Sjkim
809118611Snjl            break;
810118611Snjl        }
811118611Snjl
812118611Snjl        *State = ACPI_RSTATE_NORMAL;
813272444Sjkim        Rnode = RsDoEndDependentDescriptor (Info);
814118611Snjl        break;
815118611Snjl
816167802Sjkim    case PARSEOP_ENDTAG:
817250838Sjkim
818272444Sjkim        Rnode = RsDoEndTagDescriptor (Info);
819167802Sjkim        break;
820167802Sjkim
821151937Sjkim    case PARSEOP_EXTENDEDIO:
822250838Sjkim
823272444Sjkim        Rnode = RsDoExtendedIoDescriptor (Info);
824151937Sjkim        break;
825151937Sjkim
826151937Sjkim    case PARSEOP_EXTENDEDMEMORY:
827250838Sjkim
828272444Sjkim        Rnode = RsDoExtendedMemoryDescriptor (Info);
829151937Sjkim        break;
830151937Sjkim
831151937Sjkim    case PARSEOP_EXTENDEDSPACE:
832250838Sjkim
833272444Sjkim        Rnode = RsDoExtendedSpaceDescriptor (Info);
834151937Sjkim        break;
835151937Sjkim
836118611Snjl    case PARSEOP_FIXEDIO:
837250838Sjkim
838272444Sjkim        Rnode = RsDoFixedIoDescriptor (Info);
839118611Snjl        break;
840118611Snjl
841118611Snjl    case PARSEOP_INTERRUPT:
842250838Sjkim
843272444Sjkim        Rnode = RsDoInterruptDescriptor (Info);
844118611Snjl        break;
845118611Snjl
846118611Snjl    case PARSEOP_IO:
847250838Sjkim
848272444Sjkim        Rnode = RsDoIoDescriptor (Info);
849118611Snjl        break;
850118611Snjl
851118611Snjl    case PARSEOP_IRQ:
852250838Sjkim
853272444Sjkim        Rnode = RsDoIrqDescriptor (Info);
854118611Snjl        break;
855118611Snjl
856118611Snjl    case PARSEOP_IRQNOFLAGS:
857250838Sjkim
858272444Sjkim        Rnode = RsDoIrqNoFlagsDescriptor (Info);
859118611Snjl        break;
860118611Snjl
861118611Snjl    case PARSEOP_MEMORY24:
862250838Sjkim
863272444Sjkim        Rnode = RsDoMemory24Descriptor (Info);
864118611Snjl        break;
865118611Snjl
866118611Snjl    case PARSEOP_MEMORY32:
867250838Sjkim
868272444Sjkim        Rnode = RsDoMemory32Descriptor (Info);
869118611Snjl        break;
870118611Snjl
871118611Snjl    case PARSEOP_MEMORY32FIXED:
872250838Sjkim
873272444Sjkim        Rnode = RsDoMemory32FixedDescriptor (Info);
874118611Snjl        break;
875118611Snjl
876118611Snjl    case PARSEOP_QWORDIO:
877250838Sjkim
878272444Sjkim        Rnode = RsDoQwordIoDescriptor (Info);
879118611Snjl        break;
880118611Snjl
881118611Snjl    case PARSEOP_QWORDMEMORY:
882250838Sjkim
883272444Sjkim        Rnode = RsDoQwordMemoryDescriptor (Info);
884118611Snjl        break;
885118611Snjl
886151937Sjkim    case PARSEOP_QWORDSPACE:
887250838Sjkim
888272444Sjkim        Rnode = RsDoQwordSpaceDescriptor (Info);
889151937Sjkim        break;
890151937Sjkim
891118611Snjl    case PARSEOP_REGISTER:
892250838Sjkim
893272444Sjkim        Rnode = RsDoGeneralRegisterDescriptor (Info);
894118611Snjl        break;
895118611Snjl
896118611Snjl    case PARSEOP_STARTDEPENDENTFN:
897250838Sjkim
898118611Snjl        switch (*State)
899118611Snjl        {
900118611Snjl        case ACPI_RSTATE_START_DEPENDENT:
901250838Sjkim
902151937Sjkim            AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING,
903272444Sjkim                Info->DescriptorTypeOp, NULL);
904118611Snjl            break;
905118611Snjl
906118611Snjl        case ACPI_RSTATE_NORMAL:
907118611Snjl        case ACPI_RSTATE_DEPENDENT_LIST:
908118611Snjl        default:
909250838Sjkim
910118611Snjl            break;
911118611Snjl        }
912118611Snjl
913118611Snjl        *State = ACPI_RSTATE_START_DEPENDENT;
914272444Sjkim        Rnode = RsDoStartDependentDescriptor (Info);
915118611Snjl        *State = ACPI_RSTATE_DEPENDENT_LIST;
916118611Snjl        break;
917118611Snjl
918118611Snjl    case PARSEOP_STARTDEPENDENTFN_NOPRI:
919250838Sjkim
920118611Snjl        switch (*State)
921118611Snjl        {
922118611Snjl        case ACPI_RSTATE_START_DEPENDENT:
923250838Sjkim
924151937Sjkim            AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING,
925272444Sjkim                Info->DescriptorTypeOp, NULL);
926118611Snjl            break;
927118611Snjl
928118611Snjl        case ACPI_RSTATE_NORMAL:
929118611Snjl        case ACPI_RSTATE_DEPENDENT_LIST:
930118611Snjl        default:
931250838Sjkim
932118611Snjl            break;
933118611Snjl        }
934118611Snjl
935118611Snjl        *State = ACPI_RSTATE_START_DEPENDENT;
936272444Sjkim        Rnode = RsDoStartDependentNoPriDescriptor (Info);
937118611Snjl        *State = ACPI_RSTATE_DEPENDENT_LIST;
938118611Snjl        break;
939118611Snjl
940118611Snjl    case PARSEOP_VENDORLONG:
941250838Sjkim
942272444Sjkim        Rnode = RsDoVendorLargeDescriptor (Info);
943118611Snjl        break;
944118611Snjl
945118611Snjl    case PARSEOP_VENDORSHORT:
946250838Sjkim
947272444Sjkim        Rnode = RsDoVendorSmallDescriptor (Info);
948118611Snjl        break;
949118611Snjl
950118611Snjl    case PARSEOP_WORDBUSNUMBER:
951250838Sjkim
952272444Sjkim        Rnode = RsDoWordBusNumberDescriptor (Info);
953118611Snjl        break;
954118611Snjl
955118611Snjl    case PARSEOP_WORDIO:
956250838Sjkim
957272444Sjkim        Rnode = RsDoWordIoDescriptor (Info);
958118611Snjl        break;
959118611Snjl
960151937Sjkim    case PARSEOP_WORDSPACE:
961250838Sjkim
962272444Sjkim        Rnode = RsDoWordSpaceDescriptor (Info);
963151937Sjkim        break;
964151937Sjkim
965228110Sjkim    case PARSEOP_GPIO_INT:
966250838Sjkim
967272444Sjkim        Rnode = RsDoGpioIntDescriptor (Info);
968228110Sjkim        break;
969228110Sjkim
970228110Sjkim    case PARSEOP_GPIO_IO:
971250838Sjkim
972272444Sjkim        Rnode = RsDoGpioIoDescriptor (Info);
973228110Sjkim        break;
974228110Sjkim
975228110Sjkim    case PARSEOP_I2C_SERIALBUS:
976298714Sjkim    case PARSEOP_I2C_SERIALBUS_V2:
977250838Sjkim
978272444Sjkim        Rnode = RsDoI2cSerialBusDescriptor (Info);
979228110Sjkim        break;
980228110Sjkim
981228110Sjkim    case PARSEOP_SPI_SERIALBUS:
982298714Sjkim    case PARSEOP_SPI_SERIALBUS_V2:
983250838Sjkim
984272444Sjkim        Rnode = RsDoSpiSerialBusDescriptor (Info);
985228110Sjkim        break;
986228110Sjkim
987228110Sjkim    case PARSEOP_UART_SERIALBUS:
988298714Sjkim    case PARSEOP_UART_SERIALBUS_V2:
989250838Sjkim
990272444Sjkim        Rnode = RsDoUartSerialBusDescriptor (Info);
991228110Sjkim        break;
992228110Sjkim
993322877Sjkim    case PARSEOP_PINCONFIG:
994322877Sjkim
995322877Sjkim        Rnode = RsDoPinConfigDescriptor (Info);
996322877Sjkim        break;
997322877Sjkim
998322877Sjkim    case PARSEOP_PINFUNCTION:
999322877Sjkim
1000322877Sjkim        Rnode = RsDoPinFunctionDescriptor (Info);
1001322877Sjkim        break;
1002322877Sjkim
1003322877Sjkim    case PARSEOP_PINGROUP:
1004322877Sjkim
1005322877Sjkim        Rnode = RsDoPinGroupDescriptor (Info);
1006322877Sjkim        break;
1007322877Sjkim
1008322877Sjkim    case PARSEOP_PINGROUPFUNCTION:
1009322877Sjkim
1010322877Sjkim        Rnode = RsDoPinGroupFunctionDescriptor (Info);
1011322877Sjkim        break;
1012322877Sjkim
1013322877Sjkim    case PARSEOP_PINGROUPCONFIG:
1014322877Sjkim
1015322877Sjkim        Rnode = RsDoPinGroupConfigDescriptor (Info);
1016322877Sjkim        break;
1017322877Sjkim
1018118611Snjl    case PARSEOP_DEFAULT_ARG:
1019250838Sjkim
1020118611Snjl        /* Just ignore any of these, they are used as fillers/placeholders */
1021118611Snjl        break;
1022118611Snjl
1023118611Snjl    default:
1024250838Sjkim
1025118611Snjl        printf ("Unknown resource descriptor type [%s]\n",
1026298714Sjkim            Info->DescriptorTypeOp->Asl.ParseOpName);
1027118611Snjl        break;
1028118611Snjl    }
1029118611Snjl
1030118611Snjl    /*
1031118611Snjl     * Mark original node as unused, but head of a resource descriptor.
1032118611Snjl     * This allows the resource to be installed in the namespace so that
1033118611Snjl     * references to the descriptor can be resolved.
1034118611Snjl     */
1035272444Sjkim    Info->DescriptorTypeOp->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
1036322877Sjkim    Info->DescriptorTypeOp->Asl.CompileFlags = OP_IS_RESOURCE_DESC;
1037272444Sjkim    Info->DescriptorTypeOp->Asl.Value.Integer = Info->CurrentByteOffset;
1038118611Snjl
1039167802Sjkim    if (Rnode)
1040167802Sjkim    {
1041272444Sjkim        Info->DescriptorTypeOp->Asl.FinalAmlLength = Rnode->BufferLength;
1042298714Sjkim        Info->DescriptorTypeOp->Asl.Extra =
1043298714Sjkim            ((AML_RESOURCE *) Rnode->Buffer)->DescriptorType;
1044167802Sjkim    }
1045167802Sjkim
1046118611Snjl    return (Rnode);
1047118611Snjl}
1048118611Snjl
1049118611Snjl
1050118611Snjl/*******************************************************************************
1051118611Snjl *
1052118611Snjl * FUNCTION:    RsLinkDescriptorChain
1053118611Snjl *
1054118611Snjl * PARAMETERS:  PreviousRnode       - Pointer to the node that will be previous
1055118611Snjl *                                    to the linked node,  At exit, set to the
1056118611Snjl *                                    last node in the new chain.
1057118611Snjl *              Rnode               - Resource node to link into the list
1058118611Snjl *
1059118611Snjl * RETURN:      Cumulative buffer byte offset of the new segment of chain
1060118611Snjl *
1061118611Snjl * DESCRIPTION: Link a descriptor chain at the end of an existing chain.
1062118611Snjl *
1063118611Snjl ******************************************************************************/
1064118611Snjl
1065118611SnjlUINT32
1066118611SnjlRsLinkDescriptorChain (
1067118611Snjl    ASL_RESOURCE_NODE       **PreviousRnode,
1068118611Snjl    ASL_RESOURCE_NODE       *Rnode)
1069118611Snjl{
1070118611Snjl    ASL_RESOURCE_NODE       *LastRnode;
1071118611Snjl    UINT32                  CurrentByteOffset;
1072118611Snjl
1073118611Snjl
1074118611Snjl    /* Anything to do? */
1075118611Snjl
1076118611Snjl    if (!Rnode)
1077118611Snjl    {
1078241973Sjkim        return (0);
1079118611Snjl    }
1080118611Snjl
1081118611Snjl    /* Point the previous node to the new node */
1082118611Snjl
1083118611Snjl    (*PreviousRnode)->Next = Rnode;
1084118611Snjl    CurrentByteOffset = Rnode->BufferLength;
1085118611Snjl
1086118611Snjl    /* Walk to the end of the chain headed by Rnode */
1087118611Snjl
1088118611Snjl    LastRnode = Rnode;
1089118611Snjl    while (LastRnode->Next)
1090118611Snjl    {
1091118611Snjl        LastRnode = LastRnode->Next;
1092118611Snjl        CurrentByteOffset += LastRnode->BufferLength;
1093118611Snjl    }
1094118611Snjl
1095118611Snjl    /* Previous node becomes the last node in the chain */
1096118611Snjl
1097118611Snjl    *PreviousRnode = LastRnode;
1098241973Sjkim    return (CurrentByteOffset);
1099118611Snjl}
1100118611Snjl
1101118611Snjl
1102118611Snjl/*******************************************************************************
1103118611Snjl *
1104118611Snjl * FUNCTION:    RsDoResourceTemplate
1105118611Snjl *
1106118611Snjl * PARAMETERS:  Op        - Parent of a resource template list
1107118611Snjl *
1108241973Sjkim * RETURN:      None. Sets input node to point to a list of AML code
1109118611Snjl *
1110118611Snjl * DESCRIPTION: Merge a list of resource descriptors into a single AML buffer,
1111118611Snjl *              in preparation for output to the AML output file.
1112118611Snjl *
1113118611Snjl ******************************************************************************/
1114118611Snjl
1115118611Snjlvoid
1116118611SnjlRsDoResourceTemplate (
1117118611Snjl    ACPI_PARSE_OBJECT       *Op)
1118118611Snjl{
1119118611Snjl    ACPI_PARSE_OBJECT       *BufferLengthOp;
1120118611Snjl    ACPI_PARSE_OBJECT       *BufferOp;
1121118611Snjl    ACPI_PARSE_OBJECT       *DescriptorTypeOp;
1122118611Snjl    ACPI_PARSE_OBJECT       *LastOp = NULL;
1123118611Snjl    UINT32                  CurrentByteOffset = 0;
1124118611Snjl    ASL_RESOURCE_NODE       HeadRnode;
1125118611Snjl    ASL_RESOURCE_NODE       *PreviousRnode;
1126118611Snjl    ASL_RESOURCE_NODE       *Rnode;
1127272444Sjkim    ASL_RESOURCE_INFO       Info;
1128118611Snjl    UINT8                   State;
1129118611Snjl
1130118611Snjl
1131167802Sjkim    /* Mark parent as containing a resource template */
1132167802Sjkim
1133167802Sjkim    if (Op->Asl.Parent)
1134167802Sjkim    {
1135322877Sjkim        Op->Asl.Parent->Asl.CompileFlags |= OP_IS_RESOURCE_DESC;
1136167802Sjkim    }
1137167802Sjkim
1138118611Snjl    /* ResourceTemplate Opcode is first (Op) */
1139118611Snjl    /* Buffer Length node is first child */
1140118611Snjl
1141118611Snjl    BufferLengthOp = ASL_GET_CHILD_NODE (Op);
1142118611Snjl
1143118611Snjl    /* Buffer Op is first peer */
1144118611Snjl
1145118611Snjl    BufferOp = ASL_GET_PEER_NODE (BufferLengthOp);
1146118611Snjl
1147118611Snjl    /* First Descriptor type is next */
1148118611Snjl
1149118611Snjl    DescriptorTypeOp = ASL_GET_PEER_NODE (BufferOp);
1150118611Snjl
1151327557Sjkim    /* DEFAULT_ARG indicates null template - ResourceTemplate(){} */
1152327557Sjkim
1153327557Sjkim    if (DescriptorTypeOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
1154327557Sjkim    {
1155327557Sjkim        AslError (ASL_WARNING, ASL_MSG_NULL_RESOURCE_TEMPLATE,
1156327557Sjkim            DescriptorTypeOp, DescriptorTypeOp->Asl.Value.String);
1157327557Sjkim    }
1158327557Sjkim
1159167802Sjkim    /*
1160167802Sjkim     * Process all resource descriptors in the list
1161167802Sjkim     * Note: It is assumed that the EndTag node has been automatically
1162167802Sjkim     * inserted at the end of the template by the parser.
1163167802Sjkim     */
1164118611Snjl    State = ACPI_RSTATE_NORMAL;
1165118611Snjl    PreviousRnode = &HeadRnode;
1166118611Snjl    while (DescriptorTypeOp)
1167118611Snjl    {
1168272444Sjkim        /* Save information for optional mapfile */
1169272444Sjkim
1170272444Sjkim        if (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONNECTION)
1171272444Sjkim        {
1172272444Sjkim            Info.MappingOp = Op->Asl.Parent;
1173272444Sjkim        }
1174272444Sjkim        else
1175272444Sjkim        {
1176272444Sjkim            Info.MappingOp = DescriptorTypeOp;
1177272444Sjkim        }
1178272444Sjkim
1179272444Sjkim        Info.DescriptorTypeOp = DescriptorTypeOp;
1180272444Sjkim        Info.CurrentByteOffset = CurrentByteOffset;
1181272444Sjkim
1182322877Sjkim        DescriptorTypeOp->Asl.CompileFlags |= OP_IS_RESOURCE_DESC;
1183272444Sjkim        Rnode = RsDoOneResourceDescriptor (&Info, &State);
1184118611Snjl
1185118611Snjl        /*
1186118611Snjl         * Update current byte offset to indicate the number of bytes from the
1187241973Sjkim         * start of the buffer. Buffer can include multiple descriptors, we
1188118611Snjl         * must keep track of the offset of not only each descriptor, but each
1189118611Snjl         * element (field) within each descriptor as well.
1190118611Snjl         */
1191118611Snjl        CurrentByteOffset += RsLinkDescriptorChain (&PreviousRnode, Rnode);
1192118611Snjl
1193118611Snjl        /* Get the next descriptor in the list */
1194118611Snjl
1195118611Snjl        LastOp = DescriptorTypeOp;
1196118611Snjl        DescriptorTypeOp = ASL_GET_PEER_NODE (DescriptorTypeOp);
1197118611Snjl    }
1198118611Snjl
1199118611Snjl    if (State == ACPI_RSTATE_DEPENDENT_LIST)
1200118611Snjl    {
1201118611Snjl        if (LastOp)
1202118611Snjl        {
1203118611Snjl            LastOp = LastOp->Asl.Parent;
1204118611Snjl        }
1205118611Snjl        AslError (ASL_ERROR, ASL_MSG_MISSING_ENDDEPENDENT, LastOp, NULL);
1206118611Snjl    }
1207118611Snjl
1208118611Snjl    /*
1209118611Snjl     * Transform the nodes into the following
1210118611Snjl     *
1211118611Snjl     * Op           -> AML_BUFFER_OP
1212118611Snjl     * First Child  -> BufferLength
1213118611Snjl     * Second Child -> Descriptor Buffer (raw byte data)
1214118611Snjl     */
1215118611Snjl    Op->Asl.ParseOpcode               = PARSEOP_BUFFER;
1216118611Snjl    Op->Asl.AmlOpcode                 = AML_BUFFER_OP;
1217322877Sjkim    Op->Asl.CompileFlags              = OP_AML_PACKAGE | OP_IS_RESOURCE_DESC;
1218228110Sjkim    UtSetParseOpName (Op);
1219118611Snjl
1220118611Snjl    BufferLengthOp->Asl.ParseOpcode   = PARSEOP_INTEGER;
1221118611Snjl    BufferLengthOp->Asl.Value.Integer = CurrentByteOffset;
1222118611Snjl    (void) OpcSetOptimalIntegerSize (BufferLengthOp);
1223228110Sjkim    UtSetParseOpName (BufferLengthOp);
1224118611Snjl
1225118611Snjl    BufferOp->Asl.ParseOpcode         = PARSEOP_RAW_DATA;
1226118611Snjl    BufferOp->Asl.AmlOpcode           = AML_RAW_DATA_CHAIN;
1227118611Snjl    BufferOp->Asl.AmlOpcodeLength     = 0;
1228118611Snjl    BufferOp->Asl.AmlLength           = CurrentByteOffset;
1229118611Snjl    BufferOp->Asl.Value.Buffer        = (UINT8 *) HeadRnode.Next;
1230322877Sjkim    BufferOp->Asl.CompileFlags       |= OP_IS_RESOURCE_DATA;
1231228110Sjkim    UtSetParseOpName (BufferOp);
1232118611Snjl
1233118611Snjl    return;
1234118611Snjl}
1235