aslresource.c revision 228110
1118611Snjl
2118611Snjl/******************************************************************************
3118611Snjl *
4207344Sjkim * Module Name: aslresource - Resource template/descriptor utilities
5118611Snjl *
6118611Snjl *****************************************************************************/
7118611Snjl
8217365Sjkim/*
9217365Sjkim * Copyright (C) 2000 - 2011, Intel Corp.
10118611Snjl * All rights reserved.
11118611Snjl *
12217365Sjkim * Redistribution and use in source and binary forms, with or without
13217365Sjkim * modification, are permitted provided that the following conditions
14217365Sjkim * are met:
15217365Sjkim * 1. Redistributions of source code must retain the above copyright
16217365Sjkim *    notice, this list of conditions, and the following disclaimer,
17217365Sjkim *    without modification.
18217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19217365Sjkim *    substantially similar to the "NO WARRANTY" disclaimer below
20217365Sjkim *    ("Disclaimer") and any redistribution must be conditioned upon
21217365Sjkim *    including a substantially similar Disclaimer requirement for further
22217365Sjkim *    binary redistribution.
23217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names
24217365Sjkim *    of any contributors may be used to endorse or promote products derived
25217365Sjkim *    from this software without specific prior written permission.
26118611Snjl *
27217365Sjkim * Alternatively, this software may be distributed under the terms of the
28217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free
29217365Sjkim * Software Foundation.
30118611Snjl *
31217365Sjkim * NO WARRANTY
32217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42217365Sjkim * POSSIBILITY OF SUCH DAMAGES.
43217365Sjkim */
44118611Snjl
45118611Snjl
46151937Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h>
47118611Snjl#include "aslcompiler.y.h"
48193529Sjkim#include <contrib/dev/acpica/include/amlcode.h>
49118611Snjl
50118611Snjl
51118611Snjl#define _COMPONENT          ACPI_COMPILER
52118611Snjl        ACPI_MODULE_NAME    ("aslresource")
53118611Snjl
54118611Snjl
55118611Snjl/*******************************************************************************
56118611Snjl *
57207344Sjkim * FUNCTION:    RsSmallAddressCheck
58207344Sjkim *
59207344Sjkim * PARAMETERS:  Minimum             - Address Min value
60207344Sjkim *              Maximum             - Address Max value
61207344Sjkim *              Length              - Address range value
62207344Sjkim *              Alignment           - Address alignment value
63207344Sjkim *              MinOp               - Original Op for Address Min
64207344Sjkim *              MaxOp               - Original Op for Address Max
65207344Sjkim *              LengthOp            - Original Op for address range
66207344Sjkim *              AlignOp             - Original Op for address alignment. If
67207344Sjkim *                                    NULL, means "zero value for alignment is
68207344Sjkim *                                    OK, and means 64K alignment" (for
69207344Sjkim *                                    Memory24 descriptor)
70213806Sjkim *              Op                  - Parent Op for entire construct
71207344Sjkim *
72207344Sjkim * RETURN:      None. Adds error messages to error log if necessary
73207344Sjkim *
74207344Sjkim * DESCRIPTION: Perform common value checks for "small" address descriptors.
75207344Sjkim *              Currently:
76207344Sjkim *                  Io, Memory24, Memory32
77207344Sjkim *
78207344Sjkim ******************************************************************************/
79207344Sjkim
80207344Sjkimvoid
81207344SjkimRsSmallAddressCheck (
82207344Sjkim    UINT8                   Type,
83207344Sjkim    UINT32                  Minimum,
84207344Sjkim    UINT32                  Maximum,
85207344Sjkim    UINT32                  Length,
86207344Sjkim    UINT32                  Alignment,
87207344Sjkim    ACPI_PARSE_OBJECT       *MinOp,
88207344Sjkim    ACPI_PARSE_OBJECT       *MaxOp,
89207344Sjkim    ACPI_PARSE_OBJECT       *LengthOp,
90213806Sjkim    ACPI_PARSE_OBJECT       *AlignOp,
91213806Sjkim    ACPI_PARSE_OBJECT       *Op)
92207344Sjkim{
93207344Sjkim
94207344Sjkim    if (Gbl_NoResourceChecking)
95207344Sjkim    {
96207344Sjkim        return;
97207344Sjkim    }
98207344Sjkim
99213806Sjkim    /*
100213806Sjkim     * Check for a so-called "null descriptor". These are descriptors that are
101213806Sjkim     * created with most fields set to zero. The intent is that the descriptor
102213806Sjkim     * will be updated/completed at runtime via a BufferField.
103213806Sjkim     *
104213806Sjkim     * If the descriptor does NOT have a resource tag, it cannot be referenced
105213806Sjkim     * by a BufferField and we will flag this as an error. Conversely, if
106213806Sjkim     * the descriptor has a resource tag, we will assume that a BufferField
107213806Sjkim     * will be used to dynamically update it, so no error.
108213806Sjkim     *
109213806Sjkim     * A possible enhancement to this check would be to verify that in fact
110213806Sjkim     * a BufferField is created using the resource tag, and perhaps even
111213806Sjkim     * verify that a Store is performed to the BufferField.
112213806Sjkim     *
113213806Sjkim     * Note: for these descriptors, Alignment is allowed to be zero
114213806Sjkim     */
115213806Sjkim    if (!Minimum && !Maximum && !Length)
116213806Sjkim    {
117213806Sjkim        if (!Op->Asl.ExternalName)
118213806Sjkim        {
119213806Sjkim            /* No resource tag. Descriptor is fixed and is also illegal */
120213806Sjkim
121213806Sjkim            AslError (ASL_ERROR, ASL_MSG_NULL_DESCRIPTOR, Op, NULL);
122213806Sjkim        }
123213806Sjkim
124213806Sjkim        return;
125213806Sjkim    }
126213806Sjkim
127207344Sjkim    /* Special case for Memory24, values are compressed */
128207344Sjkim
129207344Sjkim    if (Type == ACPI_RESOURCE_NAME_MEMORY24)
130207344Sjkim    {
131207344Sjkim        if (!Alignment) /* Alignment==0 means 64K - no invalid alignment */
132207344Sjkim        {
133207344Sjkim            Alignment = ACPI_UINT16_MAX + 1;
134207344Sjkim        }
135207344Sjkim
136207344Sjkim        Minimum <<= 8;
137207344Sjkim        Maximum <<= 8;
138207344Sjkim        Length *= 256;
139207344Sjkim    }
140207344Sjkim
141207344Sjkim    /* IO descriptor has different definition of min/max, don't check */
142207344Sjkim
143207344Sjkim    if (Type != ACPI_RESOURCE_NAME_IO)
144207344Sjkim    {
145207344Sjkim        /* Basic checks on Min/Max/Length */
146207344Sjkim
147207344Sjkim        if (Minimum > Maximum)
148207344Sjkim        {
149207344Sjkim            AslError (ASL_ERROR, ASL_MSG_INVALID_MIN_MAX, MinOp, NULL);
150207344Sjkim        }
151207344Sjkim        else if (Length > (Maximum - Minimum + 1))
152207344Sjkim        {
153207344Sjkim            AslError (ASL_ERROR, ASL_MSG_INVALID_LENGTH, LengthOp, NULL);
154207344Sjkim        }
155207344Sjkim    }
156207344Sjkim
157207344Sjkim    /* Alignment of zero is not in ACPI spec, but is used to mean byte acc */
158207344Sjkim
159207344Sjkim    if (!Alignment)
160207344Sjkim    {
161207344Sjkim        Alignment = 1;
162207344Sjkim    }
163207344Sjkim
164207344Sjkim    /* Addresses must be an exact multiple of the alignment value */
165207344Sjkim
166207344Sjkim    if (Minimum % Alignment)
167207344Sjkim    {
168207344Sjkim        AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MinOp, NULL);
169207344Sjkim    }
170207344Sjkim    if (Maximum % Alignment)
171207344Sjkim    {
172207344Sjkim        AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MaxOp, NULL);
173207344Sjkim    }
174207344Sjkim}
175207344Sjkim
176207344Sjkim
177207344Sjkim/*******************************************************************************
178207344Sjkim *
179207344Sjkim * FUNCTION:    RsLargeAddressCheck
180207344Sjkim *
181207344Sjkim * PARAMETERS:  Minimum             - Address Min value
182207344Sjkim *              Maximum             - Address Max value
183207344Sjkim *              Length              - Address range value
184207344Sjkim *              Granularity         - Address granularity value
185207344Sjkim *              Flags               - General flags for address descriptors:
186207344Sjkim *                                    _MIF, _MAF, _DEC
187207344Sjkim *              MinOp               - Original Op for Address Min
188207344Sjkim *              MaxOp               - Original Op for Address Max
189207344Sjkim *              LengthOp            - Original Op for address range
190207344Sjkim *              GranOp              - Original Op for address granularity
191213806Sjkim *              Op                  - Parent Op for entire construct
192207344Sjkim *
193207344Sjkim * RETURN:      None. Adds error messages to error log if necessary
194207344Sjkim *
195207344Sjkim * DESCRIPTION: Perform common value checks for "large" address descriptors.
196207344Sjkim *              Currently:
197207344Sjkim *                  WordIo,     WordBusNumber,  WordSpace
198207344Sjkim *                  DWordIo,    DWordMemory,    DWordSpace
199207344Sjkim *                  QWordIo,    QWordMemory,    QWordSpace
200207344Sjkim *                  ExtendedIo, ExtendedMemory, ExtendedSpace
201207344Sjkim *
202207344Sjkim * _MIF flag set means that the minimum address is fixed and is not relocatable
203207344Sjkim * _MAF flag set means that the maximum address is fixed and is not relocatable
204207344Sjkim * Length of zero means that the record size is variable
205207344Sjkim *
206207344Sjkim * This function implements the LEN/MIF/MAF/MIN/MAX/GRA rules within Table 6-40
207207344Sjkim * of the ACPI 4.0a specification. Added 04/2010.
208207344Sjkim *
209207344Sjkim ******************************************************************************/
210207344Sjkim
211207344Sjkimvoid
212207344SjkimRsLargeAddressCheck (
213207344Sjkim    UINT64                  Minimum,
214207344Sjkim    UINT64                  Maximum,
215207344Sjkim    UINT64                  Length,
216207344Sjkim    UINT64                  Granularity,
217207344Sjkim    UINT8                   Flags,
218207344Sjkim    ACPI_PARSE_OBJECT       *MinOp,
219207344Sjkim    ACPI_PARSE_OBJECT       *MaxOp,
220207344Sjkim    ACPI_PARSE_OBJECT       *LengthOp,
221213806Sjkim    ACPI_PARSE_OBJECT       *GranOp,
222213806Sjkim    ACPI_PARSE_OBJECT       *Op)
223207344Sjkim{
224207344Sjkim
225207344Sjkim    if (Gbl_NoResourceChecking)
226207344Sjkim    {
227207344Sjkim        return;
228207344Sjkim    }
229207344Sjkim
230213806Sjkim    /*
231213806Sjkim     * Check for a so-called "null descriptor". These are descriptors that are
232213806Sjkim     * created with most fields set to zero. The intent is that the descriptor
233213806Sjkim     * will be updated/completed at runtime via a BufferField.
234213806Sjkim     *
235213806Sjkim     * If the descriptor does NOT have a resource tag, it cannot be referenced
236213806Sjkim     * by a BufferField and we will flag this as an error. Conversely, if
237213806Sjkim     * the descriptor has a resource tag, we will assume that a BufferField
238213806Sjkim     * will be used to dynamically update it, so no error.
239213806Sjkim     *
240213806Sjkim     * A possible enhancement to this check would be to verify that in fact
241213806Sjkim     * a BufferField is created using the resource tag, and perhaps even
242213806Sjkim     * verify that a Store is performed to the BufferField.
243213806Sjkim     */
244213806Sjkim    if (!Minimum && !Maximum && !Length && !Granularity)
245213806Sjkim    {
246213806Sjkim        if (!Op->Asl.ExternalName)
247213806Sjkim        {
248213806Sjkim            /* No resource tag. Descriptor is fixed and is also illegal */
249213806Sjkim
250213806Sjkim            AslError (ASL_ERROR, ASL_MSG_NULL_DESCRIPTOR, Op, NULL);
251213806Sjkim        }
252213806Sjkim
253213806Sjkim        return;
254213806Sjkim    }
255213806Sjkim
256207344Sjkim    /* Basic checks on Min/Max/Length */
257207344Sjkim
258207344Sjkim    if (Minimum > Maximum)
259207344Sjkim    {
260207344Sjkim        AslError (ASL_ERROR, ASL_MSG_INVALID_MIN_MAX, MinOp, NULL);
261207344Sjkim        return;
262207344Sjkim    }
263207344Sjkim    else if (Length > (Maximum - Minimum + 1))
264207344Sjkim    {
265207344Sjkim        AslError (ASL_ERROR, ASL_MSG_INVALID_LENGTH, LengthOp, NULL);
266207344Sjkim        return;
267207344Sjkim    }
268207344Sjkim
269207344Sjkim    /* If specified (non-zero), ensure granularity is a power-of-two minus one */
270207344Sjkim
271207344Sjkim    if (Granularity)
272207344Sjkim    {
273207344Sjkim        if ((Granularity + 1) &
274207344Sjkim             Granularity)
275207344Sjkim        {
276207344Sjkim            AslError (ASL_ERROR, ASL_MSG_INVALID_GRANULARITY, GranOp, NULL);
277207344Sjkim            return;
278207344Sjkim        }
279207344Sjkim    }
280207344Sjkim
281207344Sjkim    /*
282207344Sjkim     * Check the various combinations of Length, MinFixed, and MaxFixed
283207344Sjkim     */
284207344Sjkim    if (Length)
285207344Sjkim    {
286207344Sjkim        /* Fixed non-zero length */
287207344Sjkim
288207344Sjkim        switch (Flags & (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF))
289207344Sjkim        {
290207344Sjkim        case 0:
291207344Sjkim            /*
292207344Sjkim             * Fixed length, variable locations (both _MIN and _MAX).
293207344Sjkim             * Length must be a multiple of granularity
294207344Sjkim             */
295207344Sjkim            if (Granularity & Length)
296207344Sjkim            {
297207344Sjkim                AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, LengthOp, NULL);
298207344Sjkim            }
299207344Sjkim            break;
300207344Sjkim
301207344Sjkim        case (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF):
302207344Sjkim
303207344Sjkim            /* Fixed length, fixed location. Granularity must be zero */
304207344Sjkim
305207344Sjkim            if (Granularity != 0)
306207344Sjkim            {
307207344Sjkim                AslError (ASL_ERROR, ASL_MSG_INVALID_GRAN_FIXED, GranOp, NULL);
308207344Sjkim            }
309207344Sjkim
310207344Sjkim            /* Length must be exactly the size of the min/max window */
311207344Sjkim
312207344Sjkim            if (Length != (Maximum - Minimum + 1))
313207344Sjkim            {
314207344Sjkim                AslError (ASL_ERROR, ASL_MSG_INVALID_LENGTH_FIXED, LengthOp, NULL);
315207344Sjkim            }
316207344Sjkim            break;
317207344Sjkim
318207344Sjkim        /* All other combinations are invalid */
319207344Sjkim
320207344Sjkim        case ACPI_RESOURCE_FLAG_MIF:
321207344Sjkim        case ACPI_RESOURCE_FLAG_MAF:
322207344Sjkim        default:
323207344Sjkim            AslError (ASL_ERROR, ASL_MSG_INVALID_ADDR_FLAGS, LengthOp, NULL);
324207344Sjkim        }
325207344Sjkim    }
326207344Sjkim    else
327207344Sjkim    {
328207344Sjkim        /* Variable length (length==0) */
329207344Sjkim
330207344Sjkim        switch (Flags & (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF))
331207344Sjkim        {
332207344Sjkim        case 0:
333207344Sjkim            /*
334207344Sjkim             * Both _MIN and _MAX are variable.
335207344Sjkim             * No additional requirements, just exit
336207344Sjkim             */
337207344Sjkim            break;
338207344Sjkim
339207344Sjkim        case ACPI_RESOURCE_FLAG_MIF:
340207344Sjkim
341207344Sjkim            /* _MIN is fixed. _MIN must be multiple of _GRA */
342207344Sjkim
343207344Sjkim            /*
344207344Sjkim             * The granularity is defined by the ACPI specification to be a
345207344Sjkim             * power-of-two minus one, therefore the granularity is a
346207344Sjkim             * bitmask which can be used to easily validate the addresses.
347207344Sjkim             */
348207344Sjkim            if (Granularity & Minimum)
349207344Sjkim            {
350207344Sjkim                AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MinOp, NULL);
351207344Sjkim            }
352207344Sjkim            break;
353207344Sjkim
354207344Sjkim        case ACPI_RESOURCE_FLAG_MAF:
355207344Sjkim
356207344Sjkim            /* _MAX is fixed. (_MAX + 1) must be multiple of _GRA */
357207344Sjkim
358207344Sjkim            if (Granularity & (Maximum + 1))
359207344Sjkim            {
360207344Sjkim                AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MaxOp, "-1");
361207344Sjkim            }
362207344Sjkim            break;
363207344Sjkim
364207344Sjkim        /* Both MIF/MAF set is invalid if length is zero */
365207344Sjkim
366207344Sjkim        case (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF):
367207344Sjkim        default:
368207344Sjkim            AslError (ASL_ERROR, ASL_MSG_INVALID_ADDR_FLAGS, LengthOp, NULL);
369207344Sjkim        }
370207344Sjkim    }
371207344Sjkim}
372207344Sjkim
373207344Sjkim
374207344Sjkim/*******************************************************************************
375207344Sjkim *
376207344Sjkim * FUNCTION:    RsGetStringDataLength
377207344Sjkim *
378207344Sjkim * PARAMETERS:  InitializerOp     - Start of a subtree of init nodes
379207344Sjkim *
380207344Sjkim * RETURN:      Valid string length if a string node is found (otherwise 0)
381207344Sjkim *
382207344Sjkim * DESCRIPTION: In a list of peer nodes, find the first one that contains a
383207344Sjkim *              string and return the length of the string.
384207344Sjkim *
385207344Sjkim ******************************************************************************/
386207344Sjkim
387207344SjkimUINT16
388207344SjkimRsGetStringDataLength (
389207344Sjkim    ACPI_PARSE_OBJECT       *InitializerOp)
390207344Sjkim{
391207344Sjkim
392207344Sjkim    while (InitializerOp)
393207344Sjkim    {
394207344Sjkim        if (InitializerOp->Asl.ParseOpcode == PARSEOP_STRING_LITERAL)
395207344Sjkim        {
396207344Sjkim            return ((UINT16) (strlen (InitializerOp->Asl.Value.String) + 1));
397207344Sjkim        }
398207344Sjkim        InitializerOp = ASL_GET_PEER_NODE (InitializerOp);
399207344Sjkim    }
400207344Sjkim
401207344Sjkim    return 0;
402207344Sjkim}
403207344Sjkim
404207344Sjkim
405207344Sjkim/*******************************************************************************
406207344Sjkim *
407118611Snjl * FUNCTION:    RsAllocateResourceNode
408118611Snjl *
409118611Snjl * PARAMETERS:  Size        - Size of node in bytes
410118611Snjl *
411118611Snjl * RETURN:      The allocated node - aborts on allocation failure
412118611Snjl *
413118611Snjl * DESCRIPTION: Allocate a resource description node and the resource
414118611Snjl *              descriptor itself (the nodes are used to link descriptors).
415118611Snjl *
416118611Snjl ******************************************************************************/
417118611Snjl
418118611SnjlASL_RESOURCE_NODE *
419118611SnjlRsAllocateResourceNode (
420118611Snjl    UINT32                  Size)
421118611Snjl{
422118611Snjl    ASL_RESOURCE_NODE       *Rnode;
423118611Snjl
424118611Snjl
425118611Snjl    /* Allocate the node */
426118611Snjl
427118611Snjl    Rnode = UtLocalCalloc (sizeof (ASL_RESOURCE_NODE));
428118611Snjl
429118611Snjl    /* Allocate the resource descriptor itself */
430118611Snjl
431118611Snjl    Rnode->Buffer = UtLocalCalloc (Size);
432118611Snjl    Rnode->BufferLength = Size;
433118611Snjl
434118611Snjl    return (Rnode);
435118611Snjl}
436118611Snjl
437118611Snjl
438118611Snjl/*******************************************************************************
439118611Snjl *
440228110Sjkim * FUNCTION:    RsCreateResourceField
441118611Snjl *
442151937Sjkim * PARAMETERS:  Op              - Resource field node
443118611Snjl *              Name            - Name of the field (Used only to reference
444118611Snjl *                                the field in the ASL, not in the AML)
445118611Snjl *              ByteOffset      - Offset from the field start
446118611Snjl *              BitOffset       - Additional bit offset
447228110Sjkim *              BitLength       - Number of bits in the field
448118611Snjl *
449118611Snjl * RETURN:      None, sets fields within the input node
450118611Snjl *
451118611Snjl * DESCRIPTION: Utility function to generate a named bit field within a
452118611Snjl *              resource descriptor.  Mark a node as 1) a field in a resource
453118611Snjl *              descriptor, and 2) set the value to be a BIT offset
454118611Snjl *
455118611Snjl ******************************************************************************/
456118611Snjl
457118611Snjlvoid
458228110SjkimRsCreateResourceField (
459118611Snjl    ACPI_PARSE_OBJECT       *Op,
460118611Snjl    char                    *Name,
461118611Snjl    UINT32                  ByteOffset,
462228110Sjkim    UINT32                  BitOffset,
463228110Sjkim    UINT32                  BitLength)
464118611Snjl{
465118611Snjl
466228110Sjkim    Op->Asl.ExternalName = Name;
467228110Sjkim    Op->Asl.CompileFlags |= NODE_IS_RESOURCE_FIELD;
468118611Snjl
469118611Snjl
470228110Sjkim    Op->Asl.Value.Tag.BitOffset = (ByteOffset * 8) + BitOffset;
471228110Sjkim    Op->Asl.Value.Tag.BitLength = BitLength;
472118611Snjl}
473118611Snjl
474118611Snjl
475118611Snjl/*******************************************************************************
476118611Snjl *
477118611Snjl * FUNCTION:    RsSetFlagBits
478118611Snjl *
479118611Snjl * PARAMETERS:  *Flags          - Pointer to the flag byte
480151937Sjkim *              Op              - Flag initialization node
481118611Snjl *              Position        - Bit position within the flag byte
482118611Snjl *              Default         - Used if the node is DEFAULT.
483118611Snjl *
484118611Snjl * RETURN:      Sets bits within the *Flags output byte.
485118611Snjl *
486118611Snjl * DESCRIPTION: Set a bit in a cumulative flags word from an initialization
487118611Snjl *              node.  Will use a default value if the node is DEFAULT, meaning
488118611Snjl *              that no value was specified in the ASL.  Used to merge multiple
489118611Snjl *              keywords into a single flags byte.
490118611Snjl *
491118611Snjl ******************************************************************************/
492118611Snjl
493118611Snjlvoid
494118611SnjlRsSetFlagBits (
495118611Snjl    UINT8                   *Flags,
496118611Snjl    ACPI_PARSE_OBJECT       *Op,
497118611Snjl    UINT8                   Position,
498118611Snjl    UINT8                   DefaultBit)
499118611Snjl{
500118611Snjl
501118611Snjl    if (Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
502118611Snjl    {
503118611Snjl        /* Use the default bit */
504118611Snjl
505118611Snjl        *Flags |= (DefaultBit << Position);
506118611Snjl    }
507118611Snjl    else
508118611Snjl    {
509118611Snjl        /* Use the bit specified in the initialization node */
510118611Snjl
511118611Snjl        *Flags |= (((UINT8) Op->Asl.Value.Integer) << Position);
512118611Snjl    }
513118611Snjl}
514118611Snjl
515118611Snjl
516228110Sjkimvoid
517228110SjkimRsSetFlagBits16 (
518228110Sjkim    UINT16                  *Flags,
519228110Sjkim    ACPI_PARSE_OBJECT       *Op,
520228110Sjkim    UINT8                   Position,
521228110Sjkim    UINT8                   DefaultBit)
522228110Sjkim{
523228110Sjkim
524228110Sjkim    if (Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
525228110Sjkim    {
526228110Sjkim        /* Use the default bit */
527228110Sjkim
528228110Sjkim        *Flags |= (DefaultBit << Position);
529228110Sjkim    }
530228110Sjkim    else
531228110Sjkim    {
532228110Sjkim        /* Use the bit specified in the initialization node */
533228110Sjkim
534228110Sjkim        *Flags |= (((UINT16) Op->Asl.Value.Integer) << Position);
535228110Sjkim    }
536228110Sjkim}
537228110Sjkim
538228110Sjkim
539118611Snjl/*******************************************************************************
540118611Snjl *
541118611Snjl * FUNCTION:    RsCompleteNodeAndGetNext
542118611Snjl *
543118611Snjl * PARAMETERS:  Op            - Resource node to be completed
544118611Snjl *
545118611Snjl * RETURN:      The next peer to the input node.
546118611Snjl *
547118611Snjl * DESCRIPTION: Mark the current node completed and return the next peer.
548118611Snjl *              The node ParseOpcode is set to DEFAULT_ARG, meaning that
549118611Snjl *              this node is to be ignored from now on.
550118611Snjl *
551118611Snjl ******************************************************************************/
552118611Snjl
553118611SnjlACPI_PARSE_OBJECT *
554118611SnjlRsCompleteNodeAndGetNext (
555118611Snjl    ACPI_PARSE_OBJECT       *Op)
556118611Snjl{
557118611Snjl
558118611Snjl    /* Mark this node unused */
559118611Snjl
560118611Snjl    Op->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
561118611Snjl
562118611Snjl    /* Move on to the next peer node in the initializer list */
563118611Snjl
564118611Snjl    return (ASL_GET_PEER_NODE (Op));
565118611Snjl}
566118611Snjl
567118611Snjl
568118611Snjl/*******************************************************************************
569118611Snjl *
570151937Sjkim * FUNCTION:    RsCheckListForDuplicates
571151937Sjkim *
572151937Sjkim * PARAMETERS:  Op                  - First op in the initializer list
573151937Sjkim *
574151937Sjkim * RETURN:      None
575151937Sjkim *
576151937Sjkim * DESCRIPTION: Check an initializer list for duplicate values. Emits an error
577151937Sjkim *              if any duplicates are found.
578151937Sjkim *
579151937Sjkim ******************************************************************************/
580151937Sjkim
581151937Sjkimvoid
582151937SjkimRsCheckListForDuplicates (
583151937Sjkim    ACPI_PARSE_OBJECT       *Op)
584151937Sjkim{
585151937Sjkim    ACPI_PARSE_OBJECT       *NextValueOp = Op;
586151937Sjkim    ACPI_PARSE_OBJECT       *NextOp;
587151937Sjkim    UINT32                  Value;
588151937Sjkim
589151937Sjkim
590151937Sjkim    if (!Op)
591151937Sjkim    {
592151937Sjkim        return;
593151937Sjkim    }
594151937Sjkim
595151937Sjkim    /* Search list once for each value in the list */
596151937Sjkim
597151937Sjkim    while (NextValueOp)
598151937Sjkim    {
599151937Sjkim        Value = (UINT32) NextValueOp->Asl.Value.Integer;
600151937Sjkim
601151937Sjkim        /* Compare this value to all remaining values in the list */
602151937Sjkim
603151937Sjkim        NextOp = ASL_GET_PEER_NODE (NextValueOp);
604151937Sjkim        while (NextOp)
605151937Sjkim        {
606151937Sjkim            if (NextOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
607151937Sjkim            {
608151937Sjkim                /* Compare values */
609151937Sjkim
610151937Sjkim                if (Value == (UINT32) NextOp->Asl.Value.Integer)
611151937Sjkim                {
612151937Sjkim                    /* Emit error only once per duplicate node */
613151937Sjkim
614151937Sjkim                    if (!(NextOp->Asl.CompileFlags & NODE_IS_DUPLICATE))
615151937Sjkim                    {
616151937Sjkim                        NextOp->Asl.CompileFlags |= NODE_IS_DUPLICATE;
617151937Sjkim                        AslError (ASL_ERROR, ASL_MSG_DUPLICATE_ITEM,
618151937Sjkim                            NextOp, NULL);
619151937Sjkim                    }
620151937Sjkim                }
621151937Sjkim            }
622151937Sjkim
623151937Sjkim            NextOp = ASL_GET_PEER_NODE (NextOp);
624151937Sjkim        }
625151937Sjkim
626151937Sjkim        NextValueOp = ASL_GET_PEER_NODE (NextValueOp);
627151937Sjkim    }
628151937Sjkim}
629151937Sjkim
630151937Sjkim
631151937Sjkim/*******************************************************************************
632151937Sjkim *
633118611Snjl * FUNCTION:    RsDoOneResourceDescriptor
634118611Snjl *
635118611Snjl * PARAMETERS:  DescriptorTypeOp    - Parent parse node of the descriptor
636118611Snjl *              CurrentByteOffset   - Offset in the resource descriptor
637118611Snjl *                                    buffer.
638118611Snjl *
639118611Snjl * RETURN:      A valid resource node for the descriptor
640118611Snjl *
641118611Snjl * DESCRIPTION: Dispatches the processing of one resource descriptor
642118611Snjl *
643118611Snjl ******************************************************************************/
644118611Snjl
645118611SnjlASL_RESOURCE_NODE *
646118611SnjlRsDoOneResourceDescriptor (
647118611Snjl    ACPI_PARSE_OBJECT       *DescriptorTypeOp,
648118611Snjl    UINT32                  CurrentByteOffset,
649118611Snjl    UINT8                   *State)
650118611Snjl{
651118611Snjl    ASL_RESOURCE_NODE       *Rnode = NULL;
652118611Snjl
653118611Snjl
654167802Sjkim    /* Construct the resource */
655118611Snjl
656118611Snjl    switch (DescriptorTypeOp->Asl.ParseOpcode)
657118611Snjl    {
658118611Snjl    case PARSEOP_DMA:
659151937Sjkim        Rnode = RsDoDmaDescriptor (DescriptorTypeOp,
660151937Sjkim                    CurrentByteOffset);
661118611Snjl        break;
662118611Snjl
663228110Sjkim    case PARSEOP_FIXEDDMA:
664228110Sjkim        Rnode = RsDoFixedDmaDescriptor (DescriptorTypeOp,
665228110Sjkim                    CurrentByteOffset);
666228110Sjkim        break;
667228110Sjkim
668118611Snjl    case PARSEOP_DWORDIO:
669151937Sjkim        Rnode = RsDoDwordIoDescriptor (DescriptorTypeOp,
670151937Sjkim                    CurrentByteOffset);
671118611Snjl        break;
672118611Snjl
673118611Snjl    case PARSEOP_DWORDMEMORY:
674151937Sjkim        Rnode = RsDoDwordMemoryDescriptor (DescriptorTypeOp,
675151937Sjkim                    CurrentByteOffset);
676118611Snjl        break;
677118611Snjl
678151937Sjkim    case PARSEOP_DWORDSPACE:
679151937Sjkim        Rnode = RsDoDwordSpaceDescriptor (DescriptorTypeOp,
680151937Sjkim                    CurrentByteOffset);
681151937Sjkim        break;
682151937Sjkim
683118611Snjl    case PARSEOP_ENDDEPENDENTFN:
684118611Snjl        switch (*State)
685118611Snjl        {
686118611Snjl        case ACPI_RSTATE_NORMAL:
687151937Sjkim            AslError (ASL_ERROR, ASL_MSG_MISSING_STARTDEPENDENT,
688151937Sjkim                DescriptorTypeOp, NULL);
689118611Snjl            break;
690118611Snjl
691118611Snjl        case ACPI_RSTATE_START_DEPENDENT:
692151937Sjkim            AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING,
693151937Sjkim                DescriptorTypeOp, NULL);
694118611Snjl            break;
695118611Snjl
696118611Snjl        case ACPI_RSTATE_DEPENDENT_LIST:
697118611Snjl        default:
698118611Snjl            break;
699118611Snjl        }
700118611Snjl
701118611Snjl        *State = ACPI_RSTATE_NORMAL;
702151937Sjkim        Rnode = RsDoEndDependentDescriptor (DescriptorTypeOp,
703151937Sjkim                    CurrentByteOffset);
704118611Snjl        break;
705118611Snjl
706167802Sjkim    case PARSEOP_ENDTAG:
707167802Sjkim        Rnode = RsDoEndTagDescriptor (DescriptorTypeOp,
708167802Sjkim                    CurrentByteOffset);
709167802Sjkim        break;
710167802Sjkim
711151937Sjkim    case PARSEOP_EXTENDEDIO:
712151937Sjkim        Rnode = RsDoExtendedIoDescriptor (DescriptorTypeOp,
713151937Sjkim                    CurrentByteOffset);
714151937Sjkim        break;
715151937Sjkim
716151937Sjkim    case PARSEOP_EXTENDEDMEMORY:
717151937Sjkim        Rnode = RsDoExtendedMemoryDescriptor (DescriptorTypeOp,
718151937Sjkim                    CurrentByteOffset);
719151937Sjkim        break;
720151937Sjkim
721151937Sjkim    case PARSEOP_EXTENDEDSPACE:
722151937Sjkim        Rnode = RsDoExtendedSpaceDescriptor (DescriptorTypeOp,
723151937Sjkim                    CurrentByteOffset);
724151937Sjkim        break;
725151937Sjkim
726118611Snjl    case PARSEOP_FIXEDIO:
727151937Sjkim        Rnode = RsDoFixedIoDescriptor (DescriptorTypeOp,
728151937Sjkim                    CurrentByteOffset);
729118611Snjl        break;
730118611Snjl
731118611Snjl    case PARSEOP_INTERRUPT:
732151937Sjkim        Rnode = RsDoInterruptDescriptor (DescriptorTypeOp,
733151937Sjkim                    CurrentByteOffset);
734118611Snjl        break;
735118611Snjl
736118611Snjl    case PARSEOP_IO:
737151937Sjkim        Rnode = RsDoIoDescriptor (DescriptorTypeOp,
738151937Sjkim                    CurrentByteOffset);
739118611Snjl        break;
740118611Snjl
741118611Snjl    case PARSEOP_IRQ:
742151937Sjkim        Rnode = RsDoIrqDescriptor (DescriptorTypeOp,
743151937Sjkim                    CurrentByteOffset);
744118611Snjl        break;
745118611Snjl
746118611Snjl    case PARSEOP_IRQNOFLAGS:
747151937Sjkim        Rnode = RsDoIrqNoFlagsDescriptor (DescriptorTypeOp,
748151937Sjkim                    CurrentByteOffset);
749118611Snjl        break;
750118611Snjl
751118611Snjl    case PARSEOP_MEMORY24:
752151937Sjkim        Rnode = RsDoMemory24Descriptor (DescriptorTypeOp,
753151937Sjkim                    CurrentByteOffset);
754118611Snjl        break;
755118611Snjl
756118611Snjl    case PARSEOP_MEMORY32:
757151937Sjkim        Rnode = RsDoMemory32Descriptor (DescriptorTypeOp,
758151937Sjkim                    CurrentByteOffset);
759118611Snjl        break;
760118611Snjl
761118611Snjl    case PARSEOP_MEMORY32FIXED:
762151937Sjkim        Rnode = RsDoMemory32FixedDescriptor (DescriptorTypeOp,
763151937Sjkim                    CurrentByteOffset);
764118611Snjl        break;
765118611Snjl
766118611Snjl    case PARSEOP_QWORDIO:
767151937Sjkim        Rnode = RsDoQwordIoDescriptor (DescriptorTypeOp,
768151937Sjkim                    CurrentByteOffset);
769118611Snjl        break;
770118611Snjl
771118611Snjl    case PARSEOP_QWORDMEMORY:
772151937Sjkim        Rnode = RsDoQwordMemoryDescriptor (DescriptorTypeOp,
773151937Sjkim                    CurrentByteOffset);
774118611Snjl        break;
775118611Snjl
776151937Sjkim    case PARSEOP_QWORDSPACE:
777151937Sjkim        Rnode = RsDoQwordSpaceDescriptor (DescriptorTypeOp,
778151937Sjkim                    CurrentByteOffset);
779151937Sjkim        break;
780151937Sjkim
781118611Snjl    case PARSEOP_REGISTER:
782151937Sjkim        Rnode = RsDoGeneralRegisterDescriptor (DescriptorTypeOp,
783151937Sjkim                    CurrentByteOffset);
784118611Snjl        break;
785118611Snjl
786118611Snjl    case PARSEOP_STARTDEPENDENTFN:
787118611Snjl        switch (*State)
788118611Snjl        {
789118611Snjl        case ACPI_RSTATE_START_DEPENDENT:
790151937Sjkim            AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING,
791151937Sjkim                DescriptorTypeOp, NULL);
792118611Snjl            break;
793118611Snjl
794118611Snjl        case ACPI_RSTATE_NORMAL:
795118611Snjl        case ACPI_RSTATE_DEPENDENT_LIST:
796118611Snjl        default:
797118611Snjl            break;
798118611Snjl        }
799118611Snjl
800118611Snjl        *State = ACPI_RSTATE_START_DEPENDENT;
801151937Sjkim        Rnode = RsDoStartDependentDescriptor (DescriptorTypeOp,
802151937Sjkim                    CurrentByteOffset);
803118611Snjl        *State = ACPI_RSTATE_DEPENDENT_LIST;
804118611Snjl        break;
805118611Snjl
806118611Snjl    case PARSEOP_STARTDEPENDENTFN_NOPRI:
807118611Snjl        switch (*State)
808118611Snjl        {
809118611Snjl        case ACPI_RSTATE_START_DEPENDENT:
810151937Sjkim            AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING,
811151937Sjkim                DescriptorTypeOp, NULL);
812118611Snjl            break;
813118611Snjl
814118611Snjl        case ACPI_RSTATE_NORMAL:
815118611Snjl        case ACPI_RSTATE_DEPENDENT_LIST:
816118611Snjl        default:
817118611Snjl            break;
818118611Snjl        }
819118611Snjl
820118611Snjl        *State = ACPI_RSTATE_START_DEPENDENT;
821151937Sjkim        Rnode = RsDoStartDependentNoPriDescriptor (DescriptorTypeOp,
822151937Sjkim                    CurrentByteOffset);
823118611Snjl        *State = ACPI_RSTATE_DEPENDENT_LIST;
824118611Snjl        break;
825118611Snjl
826118611Snjl    case PARSEOP_VENDORLONG:
827151937Sjkim        Rnode = RsDoVendorLargeDescriptor (DescriptorTypeOp,
828151937Sjkim                    CurrentByteOffset);
829118611Snjl        break;
830118611Snjl
831118611Snjl    case PARSEOP_VENDORSHORT:
832151937Sjkim        Rnode = RsDoVendorSmallDescriptor (DescriptorTypeOp,
833151937Sjkim                    CurrentByteOffset);
834118611Snjl        break;
835118611Snjl
836118611Snjl    case PARSEOP_WORDBUSNUMBER:
837151937Sjkim        Rnode = RsDoWordBusNumberDescriptor (DescriptorTypeOp,
838151937Sjkim                    CurrentByteOffset);
839118611Snjl        break;
840118611Snjl
841118611Snjl    case PARSEOP_WORDIO:
842151937Sjkim        Rnode = RsDoWordIoDescriptor (DescriptorTypeOp,
843151937Sjkim                    CurrentByteOffset);
844118611Snjl        break;
845118611Snjl
846151937Sjkim    case PARSEOP_WORDSPACE:
847151937Sjkim        Rnode = RsDoWordSpaceDescriptor (DescriptorTypeOp,
848151937Sjkim                    CurrentByteOffset);
849151937Sjkim        break;
850151937Sjkim
851228110Sjkim    case PARSEOP_GPIO_INT:
852228110Sjkim        Rnode = RsDoGpioIntDescriptor (DescriptorTypeOp,
853228110Sjkim                    CurrentByteOffset);
854228110Sjkim        break;
855228110Sjkim
856228110Sjkim    case PARSEOP_GPIO_IO:
857228110Sjkim        Rnode = RsDoGpioIoDescriptor (DescriptorTypeOp,
858228110Sjkim                    CurrentByteOffset);
859228110Sjkim        break;
860228110Sjkim
861228110Sjkim    case PARSEOP_I2C_SERIALBUS:
862228110Sjkim        Rnode = RsDoI2cSerialBusDescriptor (DescriptorTypeOp,
863228110Sjkim                    CurrentByteOffset);
864228110Sjkim        break;
865228110Sjkim
866228110Sjkim    case PARSEOP_SPI_SERIALBUS:
867228110Sjkim        Rnode = RsDoSpiSerialBusDescriptor (DescriptorTypeOp,
868228110Sjkim                    CurrentByteOffset);
869228110Sjkim        break;
870228110Sjkim
871228110Sjkim    case PARSEOP_UART_SERIALBUS:
872228110Sjkim        Rnode = RsDoUartSerialBusDescriptor (DescriptorTypeOp,
873228110Sjkim                    CurrentByteOffset);
874228110Sjkim        break;
875228110Sjkim
876118611Snjl    case PARSEOP_DEFAULT_ARG:
877118611Snjl        /* Just ignore any of these, they are used as fillers/placeholders */
878118611Snjl        break;
879118611Snjl
880118611Snjl    default:
881118611Snjl        printf ("Unknown resource descriptor type [%s]\n",
882118611Snjl                    DescriptorTypeOp->Asl.ParseOpName);
883118611Snjl        break;
884118611Snjl    }
885118611Snjl
886118611Snjl    /*
887118611Snjl     * Mark original node as unused, but head of a resource descriptor.
888118611Snjl     * This allows the resource to be installed in the namespace so that
889118611Snjl     * references to the descriptor can be resolved.
890118611Snjl     */
891118611Snjl    DescriptorTypeOp->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
892118611Snjl    DescriptorTypeOp->Asl.CompileFlags = NODE_IS_RESOURCE_DESC;
893167802Sjkim    DescriptorTypeOp->Asl.Value.Integer = CurrentByteOffset;
894118611Snjl
895167802Sjkim    if (Rnode)
896167802Sjkim    {
897167802Sjkim        DescriptorTypeOp->Asl.FinalAmlLength = Rnode->BufferLength;
898167802Sjkim    }
899167802Sjkim
900118611Snjl    return (Rnode);
901118611Snjl}
902118611Snjl
903118611Snjl
904118611Snjl/*******************************************************************************
905118611Snjl *
906118611Snjl * FUNCTION:    RsLinkDescriptorChain
907118611Snjl *
908118611Snjl * PARAMETERS:  PreviousRnode       - Pointer to the node that will be previous
909118611Snjl *                                    to the linked node,  At exit, set to the
910118611Snjl *                                    last node in the new chain.
911118611Snjl *              Rnode               - Resource node to link into the list
912118611Snjl *
913118611Snjl * RETURN:      Cumulative buffer byte offset of the new segment of chain
914118611Snjl *
915118611Snjl * DESCRIPTION: Link a descriptor chain at the end of an existing chain.
916118611Snjl *
917118611Snjl ******************************************************************************/
918118611Snjl
919118611SnjlUINT32
920118611SnjlRsLinkDescriptorChain (
921118611Snjl    ASL_RESOURCE_NODE       **PreviousRnode,
922118611Snjl    ASL_RESOURCE_NODE       *Rnode)
923118611Snjl{
924118611Snjl    ASL_RESOURCE_NODE       *LastRnode;
925118611Snjl    UINT32                  CurrentByteOffset;
926118611Snjl
927118611Snjl
928118611Snjl    /* Anything to do? */
929118611Snjl
930118611Snjl    if (!Rnode)
931118611Snjl    {
932118611Snjl        return 0;
933118611Snjl    }
934118611Snjl
935118611Snjl    /* Point the previous node to the new node */
936118611Snjl
937118611Snjl    (*PreviousRnode)->Next = Rnode;
938118611Snjl    CurrentByteOffset = Rnode->BufferLength;
939118611Snjl
940118611Snjl    /* Walk to the end of the chain headed by Rnode */
941118611Snjl
942118611Snjl    LastRnode = Rnode;
943118611Snjl    while (LastRnode->Next)
944118611Snjl    {
945118611Snjl        LastRnode = LastRnode->Next;
946118611Snjl        CurrentByteOffset += LastRnode->BufferLength;
947118611Snjl    }
948118611Snjl
949118611Snjl    /* Previous node becomes the last node in the chain */
950118611Snjl
951118611Snjl    *PreviousRnode = LastRnode;
952118611Snjl    return CurrentByteOffset;
953118611Snjl}
954118611Snjl
955118611Snjl
956118611Snjl/*******************************************************************************
957118611Snjl *
958118611Snjl * FUNCTION:    RsDoResourceTemplate
959118611Snjl *
960118611Snjl * PARAMETERS:  Op        - Parent of a resource template list
961118611Snjl *
962118611Snjl * RETURN:      None.  Sets input node to point to a list of AML code
963118611Snjl *
964118611Snjl * DESCRIPTION: Merge a list of resource descriptors into a single AML buffer,
965118611Snjl *              in preparation for output to the AML output file.
966118611Snjl *
967118611Snjl ******************************************************************************/
968118611Snjl
969118611Snjlvoid
970118611SnjlRsDoResourceTemplate (
971118611Snjl    ACPI_PARSE_OBJECT       *Op)
972118611Snjl{
973118611Snjl    ACPI_PARSE_OBJECT       *BufferLengthOp;
974118611Snjl    ACPI_PARSE_OBJECT       *BufferOp;
975118611Snjl    ACPI_PARSE_OBJECT       *DescriptorTypeOp;
976118611Snjl    ACPI_PARSE_OBJECT       *LastOp = NULL;
977118611Snjl    UINT32                  CurrentByteOffset = 0;
978118611Snjl    ASL_RESOURCE_NODE       HeadRnode;
979118611Snjl    ASL_RESOURCE_NODE       *PreviousRnode;
980118611Snjl    ASL_RESOURCE_NODE       *Rnode;
981118611Snjl    UINT8                   State;
982118611Snjl
983118611Snjl
984167802Sjkim    /* Mark parent as containing a resource template */
985167802Sjkim
986167802Sjkim    if (Op->Asl.Parent)
987167802Sjkim    {
988167802Sjkim        Op->Asl.Parent->Asl.CompileFlags |= NODE_IS_RESOURCE_DESC;
989167802Sjkim    }
990167802Sjkim
991118611Snjl    /* ResourceTemplate Opcode is first (Op) */
992118611Snjl    /* Buffer Length node is first child */
993118611Snjl
994118611Snjl    BufferLengthOp = ASL_GET_CHILD_NODE (Op);
995118611Snjl
996118611Snjl    /* Buffer Op is first peer */
997118611Snjl
998118611Snjl    BufferOp = ASL_GET_PEER_NODE (BufferLengthOp);
999118611Snjl
1000118611Snjl    /* First Descriptor type is next */
1001118611Snjl
1002118611Snjl    DescriptorTypeOp = ASL_GET_PEER_NODE (BufferOp);
1003118611Snjl
1004167802Sjkim    /*
1005167802Sjkim     * Process all resource descriptors in the list
1006167802Sjkim     * Note: It is assumed that the EndTag node has been automatically
1007167802Sjkim     * inserted at the end of the template by the parser.
1008167802Sjkim     */
1009118611Snjl    State = ACPI_RSTATE_NORMAL;
1010118611Snjl    PreviousRnode = &HeadRnode;
1011118611Snjl    while (DescriptorTypeOp)
1012118611Snjl    {
1013167802Sjkim        DescriptorTypeOp->Asl.CompileFlags |= NODE_IS_RESOURCE_DESC;
1014151937Sjkim        Rnode = RsDoOneResourceDescriptor (DescriptorTypeOp, CurrentByteOffset,
1015151937Sjkim                    &State);
1016118611Snjl
1017118611Snjl        /*
1018118611Snjl         * Update current byte offset to indicate the number of bytes from the
1019118611Snjl         * start of the buffer.  Buffer can include multiple descriptors, we
1020118611Snjl         * must keep track of the offset of not only each descriptor, but each
1021118611Snjl         * element (field) within each descriptor as well.
1022118611Snjl         */
1023118611Snjl        CurrentByteOffset += RsLinkDescriptorChain (&PreviousRnode, Rnode);
1024118611Snjl
1025118611Snjl        /* Get the next descriptor in the list */
1026118611Snjl
1027118611Snjl        LastOp = DescriptorTypeOp;
1028118611Snjl        DescriptorTypeOp = ASL_GET_PEER_NODE (DescriptorTypeOp);
1029118611Snjl    }
1030118611Snjl
1031118611Snjl    if (State == ACPI_RSTATE_DEPENDENT_LIST)
1032118611Snjl    {
1033118611Snjl        if (LastOp)
1034118611Snjl        {
1035118611Snjl            LastOp = LastOp->Asl.Parent;
1036118611Snjl        }
1037118611Snjl        AslError (ASL_ERROR, ASL_MSG_MISSING_ENDDEPENDENT, LastOp, NULL);
1038118611Snjl    }
1039118611Snjl
1040118611Snjl    /*
1041118611Snjl     * Transform the nodes into the following
1042118611Snjl     *
1043118611Snjl     * Op           -> AML_BUFFER_OP
1044118611Snjl     * First Child  -> BufferLength
1045118611Snjl     * Second Child -> Descriptor Buffer (raw byte data)
1046118611Snjl     */
1047118611Snjl    Op->Asl.ParseOpcode               = PARSEOP_BUFFER;
1048118611Snjl    Op->Asl.AmlOpcode                 = AML_BUFFER_OP;
1049167802Sjkim    Op->Asl.CompileFlags              = NODE_AML_PACKAGE | NODE_IS_RESOURCE_DESC;
1050228110Sjkim    UtSetParseOpName (Op);
1051118611Snjl
1052118611Snjl    BufferLengthOp->Asl.ParseOpcode   = PARSEOP_INTEGER;
1053118611Snjl    BufferLengthOp->Asl.Value.Integer = CurrentByteOffset;
1054118611Snjl    (void) OpcSetOptimalIntegerSize (BufferLengthOp);
1055228110Sjkim    UtSetParseOpName (BufferLengthOp);
1056118611Snjl
1057118611Snjl    BufferOp->Asl.ParseOpcode         = PARSEOP_RAW_DATA;
1058118611Snjl    BufferOp->Asl.AmlOpcode           = AML_RAW_DATA_CHAIN;
1059118611Snjl    BufferOp->Asl.AmlOpcodeLength     = 0;
1060118611Snjl    BufferOp->Asl.AmlLength           = CurrentByteOffset;
1061118611Snjl    BufferOp->Asl.Value.Buffer        = (UINT8 *) HeadRnode.Next;
1062167802Sjkim    BufferOp->Asl.CompileFlags       |= NODE_IS_RESOURCE_DATA;
1063228110Sjkim    UtSetParseOpName (BufferOp);
1064118611Snjl
1065118611Snjl    return;
1066118611Snjl}
1067