aslresource.c revision 298714
1118611Snjl/******************************************************************************
2118611Snjl *
3207344Sjkim * Module Name: aslresource - Resource template/descriptor utilities
4118611Snjl *
5118611Snjl *****************************************************************************/
6118611Snjl
7217365Sjkim/*
8298714Sjkim * Copyright (C) 2000 - 2016, Intel Corp.
9118611Snjl * All rights reserved.
10118611Snjl *
11217365Sjkim * Redistribution and use in source and binary forms, with or without
12217365Sjkim * modification, are permitted provided that the following conditions
13217365Sjkim * are met:
14217365Sjkim * 1. Redistributions of source code must retain the above copyright
15217365Sjkim *    notice, this list of conditions, and the following disclaimer,
16217365Sjkim *    without modification.
17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18217365Sjkim *    substantially similar to the "NO WARRANTY" disclaimer below
19217365Sjkim *    ("Disclaimer") and any redistribution must be conditioned upon
20217365Sjkim *    including a substantially similar Disclaimer requirement for further
21217365Sjkim *    binary redistribution.
22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names
23217365Sjkim *    of any contributors may be used to endorse or promote products derived
24217365Sjkim *    from this software without specific prior written permission.
25118611Snjl *
26217365Sjkim * Alternatively, this software may be distributed under the terms of the
27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free
28217365Sjkim * Software Foundation.
29118611Snjl *
30217365Sjkim * NO WARRANTY
31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41217365Sjkim * POSSIBILITY OF SUCH DAMAGES.
42217365Sjkim */
43118611Snjl
44151937Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h>
45118611Snjl#include "aslcompiler.y.h"
46193529Sjkim#include <contrib/dev/acpica/include/amlcode.h>
47118611Snjl
48118611Snjl
49118611Snjl#define _COMPONENT          ACPI_COMPILER
50118611Snjl        ACPI_MODULE_NAME    ("aslresource")
51118611Snjl
52118611Snjl
53118611Snjl/*******************************************************************************
54118611Snjl *
55207344Sjkim * FUNCTION:    RsSmallAddressCheck
56207344Sjkim *
57207344Sjkim * PARAMETERS:  Minimum             - Address Min value
58207344Sjkim *              Maximum             - Address Max value
59207344Sjkim *              Length              - Address range value
60207344Sjkim *              Alignment           - Address alignment value
61207344Sjkim *              MinOp               - Original Op for Address Min
62207344Sjkim *              MaxOp               - Original Op for Address Max
63207344Sjkim *              LengthOp            - Original Op for address range
64207344Sjkim *              AlignOp             - Original Op for address alignment. If
65207344Sjkim *                                    NULL, means "zero value for alignment is
66207344Sjkim *                                    OK, and means 64K alignment" (for
67207344Sjkim *                                    Memory24 descriptor)
68213806Sjkim *              Op                  - Parent Op for entire construct
69207344Sjkim *
70207344Sjkim * RETURN:      None. Adds error messages to error log if necessary
71207344Sjkim *
72207344Sjkim * DESCRIPTION: Perform common value checks for "small" address descriptors.
73207344Sjkim *              Currently:
74207344Sjkim *                  Io, Memory24, Memory32
75207344Sjkim *
76207344Sjkim ******************************************************************************/
77207344Sjkim
78207344Sjkimvoid
79207344SjkimRsSmallAddressCheck (
80207344Sjkim    UINT8                   Type,
81207344Sjkim    UINT32                  Minimum,
82207344Sjkim    UINT32                  Maximum,
83207344Sjkim    UINT32                  Length,
84207344Sjkim    UINT32                  Alignment,
85207344Sjkim    ACPI_PARSE_OBJECT       *MinOp,
86207344Sjkim    ACPI_PARSE_OBJECT       *MaxOp,
87207344Sjkim    ACPI_PARSE_OBJECT       *LengthOp,
88213806Sjkim    ACPI_PARSE_OBJECT       *AlignOp,
89213806Sjkim    ACPI_PARSE_OBJECT       *Op)
90207344Sjkim{
91207344Sjkim
92207344Sjkim    if (Gbl_NoResourceChecking)
93207344Sjkim    {
94207344Sjkim        return;
95207344Sjkim    }
96207344Sjkim
97213806Sjkim    /*
98213806Sjkim     * Check for a so-called "null descriptor". These are descriptors that are
99213806Sjkim     * created with most fields set to zero. The intent is that the descriptor
100213806Sjkim     * will be updated/completed at runtime via a BufferField.
101213806Sjkim     *
102213806Sjkim     * If the descriptor does NOT have a resource tag, it cannot be referenced
103213806Sjkim     * by a BufferField and we will flag this as an error. Conversely, if
104213806Sjkim     * the descriptor has a resource tag, we will assume that a BufferField
105213806Sjkim     * will be used to dynamically update it, so no error.
106213806Sjkim     *
107213806Sjkim     * A possible enhancement to this check would be to verify that in fact
108213806Sjkim     * a BufferField is created using the resource tag, and perhaps even
109213806Sjkim     * verify that a Store is performed to the BufferField.
110213806Sjkim     *
111213806Sjkim     * Note: for these descriptors, Alignment is allowed to be zero
112213806Sjkim     */
113213806Sjkim    if (!Minimum && !Maximum && !Length)
114213806Sjkim    {
115213806Sjkim        if (!Op->Asl.ExternalName)
116213806Sjkim        {
117213806Sjkim            /* No resource tag. Descriptor is fixed and is also illegal */
118213806Sjkim
119213806Sjkim            AslError (ASL_ERROR, ASL_MSG_NULL_DESCRIPTOR, Op, NULL);
120213806Sjkim        }
121213806Sjkim
122213806Sjkim        return;
123213806Sjkim    }
124213806Sjkim
125272444Sjkim    /*
126272444Sjkim     * Range checks for Memory24 and Memory32.
127272444Sjkim     * IO descriptor has different definition of min/max, don't check.
128272444Sjkim     */
129207344Sjkim    if (Type != ACPI_RESOURCE_NAME_IO)
130207344Sjkim    {
131207344Sjkim        /* Basic checks on Min/Max/Length */
132207344Sjkim
133207344Sjkim        if (Minimum > Maximum)
134207344Sjkim        {
135207344Sjkim            AslError (ASL_ERROR, ASL_MSG_INVALID_MIN_MAX, MinOp, NULL);
136207344Sjkim        }
137207344Sjkim        else if (Length > (Maximum - Minimum + 1))
138207344Sjkim        {
139207344Sjkim            AslError (ASL_ERROR, ASL_MSG_INVALID_LENGTH, LengthOp, NULL);
140207344Sjkim        }
141272444Sjkim
142272444Sjkim        /* Special case for Memory24, min/max values are compressed */
143272444Sjkim
144272444Sjkim        if (Type == ACPI_RESOURCE_NAME_MEMORY24)
145272444Sjkim        {
146272444Sjkim            if (!Alignment) /* Alignment==0 means 64K alignment */
147272444Sjkim            {
148272444Sjkim                Alignment = ACPI_UINT16_MAX + 1;
149272444Sjkim            }
150272444Sjkim
151272444Sjkim            Minimum <<= 8;
152272444Sjkim            Maximum <<= 8;
153272444Sjkim        }
154207344Sjkim    }
155207344Sjkim
156207344Sjkim    /* Alignment of zero is not in ACPI spec, but is used to mean byte acc */
157207344Sjkim
158207344Sjkim    if (!Alignment)
159207344Sjkim    {
160207344Sjkim        Alignment = 1;
161207344Sjkim    }
162207344Sjkim
163207344Sjkim    /* Addresses must be an exact multiple of the alignment value */
164207344Sjkim
165207344Sjkim    if (Minimum % Alignment)
166207344Sjkim    {
167207344Sjkim        AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MinOp, NULL);
168207344Sjkim    }
169207344Sjkim    if (Maximum % Alignment)
170207344Sjkim    {
171207344Sjkim        AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MaxOp, NULL);
172207344Sjkim    }
173207344Sjkim}
174207344Sjkim
175207344Sjkim
176207344Sjkim/*******************************************************************************
177207344Sjkim *
178207344Sjkim * FUNCTION:    RsLargeAddressCheck
179207344Sjkim *
180207344Sjkim * PARAMETERS:  Minimum             - Address Min value
181207344Sjkim *              Maximum             - Address Max value
182207344Sjkim *              Length              - Address range value
183207344Sjkim *              Granularity         - Address granularity value
184207344Sjkim *              Flags               - General flags for address descriptors:
185207344Sjkim *                                    _MIF, _MAF, _DEC
186207344Sjkim *              MinOp               - Original Op for Address Min
187207344Sjkim *              MaxOp               - Original Op for Address Max
188207344Sjkim *              LengthOp            - Original Op for address range
189207344Sjkim *              GranOp              - Original Op for address granularity
190213806Sjkim *              Op                  - Parent Op for entire construct
191207344Sjkim *
192207344Sjkim * RETURN:      None. Adds error messages to error log if necessary
193207344Sjkim *
194207344Sjkim * DESCRIPTION: Perform common value checks for "large" address descriptors.
195207344Sjkim *              Currently:
196207344Sjkim *                  WordIo,     WordBusNumber,  WordSpace
197207344Sjkim *                  DWordIo,    DWordMemory,    DWordSpace
198207344Sjkim *                  QWordIo,    QWordMemory,    QWordSpace
199207344Sjkim *                  ExtendedIo, ExtendedMemory, ExtendedSpace
200207344Sjkim *
201207344Sjkim * _MIF flag set means that the minimum address is fixed and is not relocatable
202207344Sjkim * _MAF flag set means that the maximum address is fixed and is not relocatable
203207344Sjkim * Length of zero means that the record size is variable
204207344Sjkim *
205207344Sjkim * This function implements the LEN/MIF/MAF/MIN/MAX/GRA rules within Table 6-40
206207344Sjkim * of the ACPI 4.0a specification. Added 04/2010.
207207344Sjkim *
208207344Sjkim ******************************************************************************/
209207344Sjkim
210207344Sjkimvoid
211207344SjkimRsLargeAddressCheck (
212207344Sjkim    UINT64                  Minimum,
213207344Sjkim    UINT64                  Maximum,
214207344Sjkim    UINT64                  Length,
215207344Sjkim    UINT64                  Granularity,
216207344Sjkim    UINT8                   Flags,
217207344Sjkim    ACPI_PARSE_OBJECT       *MinOp,
218207344Sjkim    ACPI_PARSE_OBJECT       *MaxOp,
219207344Sjkim    ACPI_PARSE_OBJECT       *LengthOp,
220213806Sjkim    ACPI_PARSE_OBJECT       *GranOp,
221213806Sjkim    ACPI_PARSE_OBJECT       *Op)
222207344Sjkim{
223207344Sjkim
224207344Sjkim    if (Gbl_NoResourceChecking)
225207344Sjkim    {
226207344Sjkim        return;
227207344Sjkim    }
228207344Sjkim
229213806Sjkim    /*
230213806Sjkim     * Check for a so-called "null descriptor". These are descriptors that are
231213806Sjkim     * created with most fields set to zero. The intent is that the descriptor
232213806Sjkim     * will be updated/completed at runtime via a BufferField.
233213806Sjkim     *
234213806Sjkim     * If the descriptor does NOT have a resource tag, it cannot be referenced
235213806Sjkim     * by a BufferField and we will flag this as an error. Conversely, if
236213806Sjkim     * the descriptor has a resource tag, we will assume that a BufferField
237213806Sjkim     * will be used to dynamically update it, so no error.
238213806Sjkim     *
239213806Sjkim     * A possible enhancement to this check would be to verify that in fact
240213806Sjkim     * a BufferField is created using the resource tag, and perhaps even
241213806Sjkim     * verify that a Store is performed to the BufferField.
242213806Sjkim     */
243213806Sjkim    if (!Minimum && !Maximum && !Length && !Granularity)
244213806Sjkim    {
245213806Sjkim        if (!Op->Asl.ExternalName)
246213806Sjkim        {
247213806Sjkim            /* No resource tag. Descriptor is fixed and is also illegal */
248213806Sjkim
249213806Sjkim            AslError (ASL_ERROR, ASL_MSG_NULL_DESCRIPTOR, Op, NULL);
250213806Sjkim        }
251213806Sjkim
252213806Sjkim        return;
253213806Sjkim    }
254213806Sjkim
255207344Sjkim    /* Basic checks on Min/Max/Length */
256207344Sjkim
257207344Sjkim    if (Minimum > Maximum)
258207344Sjkim    {
259207344Sjkim        AslError (ASL_ERROR, ASL_MSG_INVALID_MIN_MAX, MinOp, NULL);
260207344Sjkim        return;
261207344Sjkim    }
262207344Sjkim    else if (Length > (Maximum - Minimum + 1))
263207344Sjkim    {
264207344Sjkim        AslError (ASL_ERROR, ASL_MSG_INVALID_LENGTH, LengthOp, NULL);
265207344Sjkim        return;
266207344Sjkim    }
267207344Sjkim
268207344Sjkim    /* If specified (non-zero), ensure granularity is a power-of-two minus one */
269207344Sjkim
270207344Sjkim    if (Granularity)
271207344Sjkim    {
272207344Sjkim        if ((Granularity + 1) &
273207344Sjkim             Granularity)
274207344Sjkim        {
275207344Sjkim            AslError (ASL_ERROR, ASL_MSG_INVALID_GRANULARITY, GranOp, NULL);
276207344Sjkim            return;
277207344Sjkim        }
278207344Sjkim    }
279207344Sjkim
280207344Sjkim    /*
281207344Sjkim     * Check the various combinations of Length, MinFixed, and MaxFixed
282207344Sjkim     */
283207344Sjkim    if (Length)
284207344Sjkim    {
285207344Sjkim        /* Fixed non-zero length */
286207344Sjkim
287207344Sjkim        switch (Flags & (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF))
288207344Sjkim        {
289207344Sjkim        case 0:
290207344Sjkim            /*
291207344Sjkim             * Fixed length, variable locations (both _MIN and _MAX).
292207344Sjkim             * Length must be a multiple of granularity
293207344Sjkim             */
294207344Sjkim            if (Granularity & Length)
295207344Sjkim            {
296207344Sjkim                AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, LengthOp, NULL);
297207344Sjkim            }
298207344Sjkim            break;
299207344Sjkim
300207344Sjkim        case (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF):
301207344Sjkim
302207344Sjkim            /* Fixed length, fixed location. Granularity must be zero */
303207344Sjkim
304207344Sjkim            if (Granularity != 0)
305207344Sjkim            {
306207344Sjkim                AslError (ASL_ERROR, ASL_MSG_INVALID_GRAN_FIXED, GranOp, NULL);
307207344Sjkim            }
308207344Sjkim
309207344Sjkim            /* Length must be exactly the size of the min/max window */
310207344Sjkim
311207344Sjkim            if (Length != (Maximum - Minimum + 1))
312207344Sjkim            {
313207344Sjkim                AslError (ASL_ERROR, ASL_MSG_INVALID_LENGTH_FIXED, LengthOp, NULL);
314207344Sjkim            }
315207344Sjkim            break;
316207344Sjkim
317207344Sjkim        /* All other combinations are invalid */
318207344Sjkim
319207344Sjkim        case ACPI_RESOURCE_FLAG_MIF:
320207344Sjkim        case ACPI_RESOURCE_FLAG_MAF:
321207344Sjkim        default:
322250838Sjkim
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:
368250838Sjkim
369207344Sjkim            AslError (ASL_ERROR, ASL_MSG_INVALID_ADDR_FLAGS, LengthOp, NULL);
370207344Sjkim        }
371207344Sjkim    }
372207344Sjkim}
373207344Sjkim
374207344Sjkim
375207344Sjkim/*******************************************************************************
376207344Sjkim *
377207344Sjkim * FUNCTION:    RsGetStringDataLength
378207344Sjkim *
379207344Sjkim * PARAMETERS:  InitializerOp     - Start of a subtree of init nodes
380207344Sjkim *
381207344Sjkim * RETURN:      Valid string length if a string node is found (otherwise 0)
382207344Sjkim *
383207344Sjkim * DESCRIPTION: In a list of peer nodes, find the first one that contains a
384207344Sjkim *              string and return the length of the string.
385207344Sjkim *
386207344Sjkim ******************************************************************************/
387207344Sjkim
388207344SjkimUINT16
389207344SjkimRsGetStringDataLength (
390207344Sjkim    ACPI_PARSE_OBJECT       *InitializerOp)
391207344Sjkim{
392207344Sjkim
393207344Sjkim    while (InitializerOp)
394207344Sjkim    {
395207344Sjkim        if (InitializerOp->Asl.ParseOpcode == PARSEOP_STRING_LITERAL)
396207344Sjkim        {
397207344Sjkim            return ((UINT16) (strlen (InitializerOp->Asl.Value.String) + 1));
398207344Sjkim        }
399298714Sjkim
400207344Sjkim        InitializerOp = ASL_GET_PEER_NODE (InitializerOp);
401207344Sjkim    }
402207344Sjkim
403241973Sjkim    return (0);
404207344Sjkim}
405207344Sjkim
406207344Sjkim
407207344Sjkim/*******************************************************************************
408207344Sjkim *
409118611Snjl * FUNCTION:    RsAllocateResourceNode
410118611Snjl *
411118611Snjl * PARAMETERS:  Size        - Size of node in bytes
412118611Snjl *
413118611Snjl * RETURN:      The allocated node - aborts on allocation failure
414118611Snjl *
415118611Snjl * DESCRIPTION: Allocate a resource description node and the resource
416118611Snjl *              descriptor itself (the nodes are used to link descriptors).
417118611Snjl *
418118611Snjl ******************************************************************************/
419118611Snjl
420118611SnjlASL_RESOURCE_NODE *
421118611SnjlRsAllocateResourceNode (
422118611Snjl    UINT32                  Size)
423118611Snjl{
424118611Snjl    ASL_RESOURCE_NODE       *Rnode;
425118611Snjl
426118611Snjl
427118611Snjl    /* Allocate the node */
428118611Snjl
429118611Snjl    Rnode = UtLocalCalloc (sizeof (ASL_RESOURCE_NODE));
430118611Snjl
431118611Snjl    /* Allocate the resource descriptor itself */
432118611Snjl
433118611Snjl    Rnode->Buffer = UtLocalCalloc (Size);
434118611Snjl    Rnode->BufferLength = Size;
435118611Snjl    return (Rnode);
436118611Snjl}
437118611Snjl
438118611Snjl
439118611Snjl/*******************************************************************************
440118611Snjl *
441228110Sjkim * FUNCTION:    RsCreateResourceField
442118611Snjl *
443151937Sjkim * PARAMETERS:  Op              - Resource field node
444118611Snjl *              Name            - Name of the field (Used only to reference
445118611Snjl *                                the field in the ASL, not in the AML)
446118611Snjl *              ByteOffset      - Offset from the field start
447118611Snjl *              BitOffset       - Additional bit offset
448228110Sjkim *              BitLength       - Number of bits in the field
449118611Snjl *
450118611Snjl * RETURN:      None, sets fields within the input node
451118611Snjl *
452118611Snjl * DESCRIPTION: Utility function to generate a named bit field within a
453241973Sjkim *              resource descriptor. Mark a node as 1) a field in a resource
454118611Snjl *              descriptor, and 2) set the value to be a BIT offset
455118611Snjl *
456118611Snjl ******************************************************************************/
457118611Snjl
458118611Snjlvoid
459228110SjkimRsCreateResourceField (
460118611Snjl    ACPI_PARSE_OBJECT       *Op,
461118611Snjl    char                    *Name,
462118611Snjl    UINT32                  ByteOffset,
463228110Sjkim    UINT32                  BitOffset,
464228110Sjkim    UINT32                  BitLength)
465118611Snjl{
466118611Snjl
467228110Sjkim    Op->Asl.ExternalName = Name;
468228110Sjkim    Op->Asl.CompileFlags |= NODE_IS_RESOURCE_FIELD;
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
487241973Sjkim *              node. Will use a default value if the node is DEFAULT, meaning
488241973Sjkim *              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 (
647272444Sjkim    ASL_RESOURCE_INFO       *Info,
648118611Snjl    UINT8                   *State)
649118611Snjl{
650118611Snjl    ASL_RESOURCE_NODE       *Rnode = NULL;
651118611Snjl
652118611Snjl
653167802Sjkim    /* Construct the resource */
654118611Snjl
655272444Sjkim    switch (Info->DescriptorTypeOp->Asl.ParseOpcode)
656118611Snjl    {
657118611Snjl    case PARSEOP_DMA:
658250838Sjkim
659272444Sjkim        Rnode = RsDoDmaDescriptor (Info);
660118611Snjl        break;
661118611Snjl
662228110Sjkim    case PARSEOP_FIXEDDMA:
663250838Sjkim
664272444Sjkim        Rnode = RsDoFixedDmaDescriptor (Info);
665228110Sjkim        break;
666228110Sjkim
667118611Snjl    case PARSEOP_DWORDIO:
668250838Sjkim
669272444Sjkim        Rnode = RsDoDwordIoDescriptor (Info);
670118611Snjl        break;
671118611Snjl
672118611Snjl    case PARSEOP_DWORDMEMORY:
673250838Sjkim
674272444Sjkim        Rnode = RsDoDwordMemoryDescriptor (Info);
675118611Snjl        break;
676118611Snjl
677151937Sjkim    case PARSEOP_DWORDSPACE:
678250838Sjkim
679272444Sjkim        Rnode = RsDoDwordSpaceDescriptor (Info);
680151937Sjkim        break;
681151937Sjkim
682118611Snjl    case PARSEOP_ENDDEPENDENTFN:
683250838Sjkim
684118611Snjl        switch (*State)
685118611Snjl        {
686118611Snjl        case ACPI_RSTATE_NORMAL:
687250838Sjkim
688151937Sjkim            AslError (ASL_ERROR, ASL_MSG_MISSING_STARTDEPENDENT,
689272444Sjkim                Info->DescriptorTypeOp, NULL);
690118611Snjl            break;
691118611Snjl
692118611Snjl        case ACPI_RSTATE_START_DEPENDENT:
693250838Sjkim
694151937Sjkim            AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING,
695272444Sjkim                Info->DescriptorTypeOp, NULL);
696118611Snjl            break;
697118611Snjl
698118611Snjl        case ACPI_RSTATE_DEPENDENT_LIST:
699118611Snjl        default:
700250838Sjkim
701118611Snjl            break;
702118611Snjl        }
703118611Snjl
704118611Snjl        *State = ACPI_RSTATE_NORMAL;
705272444Sjkim        Rnode = RsDoEndDependentDescriptor (Info);
706118611Snjl        break;
707118611Snjl
708167802Sjkim    case PARSEOP_ENDTAG:
709250838Sjkim
710272444Sjkim        Rnode = RsDoEndTagDescriptor (Info);
711167802Sjkim        break;
712167802Sjkim
713151937Sjkim    case PARSEOP_EXTENDEDIO:
714250838Sjkim
715272444Sjkim        Rnode = RsDoExtendedIoDescriptor (Info);
716151937Sjkim        break;
717151937Sjkim
718151937Sjkim    case PARSEOP_EXTENDEDMEMORY:
719250838Sjkim
720272444Sjkim        Rnode = RsDoExtendedMemoryDescriptor (Info);
721151937Sjkim        break;
722151937Sjkim
723151937Sjkim    case PARSEOP_EXTENDEDSPACE:
724250838Sjkim
725272444Sjkim        Rnode = RsDoExtendedSpaceDescriptor (Info);
726151937Sjkim        break;
727151937Sjkim
728118611Snjl    case PARSEOP_FIXEDIO:
729250838Sjkim
730272444Sjkim        Rnode = RsDoFixedIoDescriptor (Info);
731118611Snjl        break;
732118611Snjl
733118611Snjl    case PARSEOP_INTERRUPT:
734250838Sjkim
735272444Sjkim        Rnode = RsDoInterruptDescriptor (Info);
736118611Snjl        break;
737118611Snjl
738118611Snjl    case PARSEOP_IO:
739250838Sjkim
740272444Sjkim        Rnode = RsDoIoDescriptor (Info);
741118611Snjl        break;
742118611Snjl
743118611Snjl    case PARSEOP_IRQ:
744250838Sjkim
745272444Sjkim        Rnode = RsDoIrqDescriptor (Info);
746118611Snjl        break;
747118611Snjl
748118611Snjl    case PARSEOP_IRQNOFLAGS:
749250838Sjkim
750272444Sjkim        Rnode = RsDoIrqNoFlagsDescriptor (Info);
751118611Snjl        break;
752118611Snjl
753118611Snjl    case PARSEOP_MEMORY24:
754250838Sjkim
755272444Sjkim        Rnode = RsDoMemory24Descriptor (Info);
756118611Snjl        break;
757118611Snjl
758118611Snjl    case PARSEOP_MEMORY32:
759250838Sjkim
760272444Sjkim        Rnode = RsDoMemory32Descriptor (Info);
761118611Snjl        break;
762118611Snjl
763118611Snjl    case PARSEOP_MEMORY32FIXED:
764250838Sjkim
765272444Sjkim        Rnode = RsDoMemory32FixedDescriptor (Info);
766118611Snjl        break;
767118611Snjl
768118611Snjl    case PARSEOP_QWORDIO:
769250838Sjkim
770272444Sjkim        Rnode = RsDoQwordIoDescriptor (Info);
771118611Snjl        break;
772118611Snjl
773118611Snjl    case PARSEOP_QWORDMEMORY:
774250838Sjkim
775272444Sjkim        Rnode = RsDoQwordMemoryDescriptor (Info);
776118611Snjl        break;
777118611Snjl
778151937Sjkim    case PARSEOP_QWORDSPACE:
779250838Sjkim
780272444Sjkim        Rnode = RsDoQwordSpaceDescriptor (Info);
781151937Sjkim        break;
782151937Sjkim
783118611Snjl    case PARSEOP_REGISTER:
784250838Sjkim
785272444Sjkim        Rnode = RsDoGeneralRegisterDescriptor (Info);
786118611Snjl        break;
787118611Snjl
788118611Snjl    case PARSEOP_STARTDEPENDENTFN:
789250838Sjkim
790118611Snjl        switch (*State)
791118611Snjl        {
792118611Snjl        case ACPI_RSTATE_START_DEPENDENT:
793250838Sjkim
794151937Sjkim            AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING,
795272444Sjkim                Info->DescriptorTypeOp, NULL);
796118611Snjl            break;
797118611Snjl
798118611Snjl        case ACPI_RSTATE_NORMAL:
799118611Snjl        case ACPI_RSTATE_DEPENDENT_LIST:
800118611Snjl        default:
801250838Sjkim
802118611Snjl            break;
803118611Snjl        }
804118611Snjl
805118611Snjl        *State = ACPI_RSTATE_START_DEPENDENT;
806272444Sjkim        Rnode = RsDoStartDependentDescriptor (Info);
807118611Snjl        *State = ACPI_RSTATE_DEPENDENT_LIST;
808118611Snjl        break;
809118611Snjl
810118611Snjl    case PARSEOP_STARTDEPENDENTFN_NOPRI:
811250838Sjkim
812118611Snjl        switch (*State)
813118611Snjl        {
814118611Snjl        case ACPI_RSTATE_START_DEPENDENT:
815250838Sjkim
816151937Sjkim            AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING,
817272444Sjkim                Info->DescriptorTypeOp, NULL);
818118611Snjl            break;
819118611Snjl
820118611Snjl        case ACPI_RSTATE_NORMAL:
821118611Snjl        case ACPI_RSTATE_DEPENDENT_LIST:
822118611Snjl        default:
823250838Sjkim
824118611Snjl            break;
825118611Snjl        }
826118611Snjl
827118611Snjl        *State = ACPI_RSTATE_START_DEPENDENT;
828272444Sjkim        Rnode = RsDoStartDependentNoPriDescriptor (Info);
829118611Snjl        *State = ACPI_RSTATE_DEPENDENT_LIST;
830118611Snjl        break;
831118611Snjl
832118611Snjl    case PARSEOP_VENDORLONG:
833250838Sjkim
834272444Sjkim        Rnode = RsDoVendorLargeDescriptor (Info);
835118611Snjl        break;
836118611Snjl
837118611Snjl    case PARSEOP_VENDORSHORT:
838250838Sjkim
839272444Sjkim        Rnode = RsDoVendorSmallDescriptor (Info);
840118611Snjl        break;
841118611Snjl
842118611Snjl    case PARSEOP_WORDBUSNUMBER:
843250838Sjkim
844272444Sjkim        Rnode = RsDoWordBusNumberDescriptor (Info);
845118611Snjl        break;
846118611Snjl
847118611Snjl    case PARSEOP_WORDIO:
848250838Sjkim
849272444Sjkim        Rnode = RsDoWordIoDescriptor (Info);
850118611Snjl        break;
851118611Snjl
852151937Sjkim    case PARSEOP_WORDSPACE:
853250838Sjkim
854272444Sjkim        Rnode = RsDoWordSpaceDescriptor (Info);
855151937Sjkim        break;
856151937Sjkim
857228110Sjkim    case PARSEOP_GPIO_INT:
858250838Sjkim
859272444Sjkim        Rnode = RsDoGpioIntDescriptor (Info);
860228110Sjkim        break;
861228110Sjkim
862228110Sjkim    case PARSEOP_GPIO_IO:
863250838Sjkim
864272444Sjkim        Rnode = RsDoGpioIoDescriptor (Info);
865228110Sjkim        break;
866228110Sjkim
867228110Sjkim    case PARSEOP_I2C_SERIALBUS:
868298714Sjkim    case PARSEOP_I2C_SERIALBUS_V2:
869250838Sjkim
870272444Sjkim        Rnode = RsDoI2cSerialBusDescriptor (Info);
871228110Sjkim        break;
872228110Sjkim
873228110Sjkim    case PARSEOP_SPI_SERIALBUS:
874298714Sjkim    case PARSEOP_SPI_SERIALBUS_V2:
875250838Sjkim
876272444Sjkim        Rnode = RsDoSpiSerialBusDescriptor (Info);
877228110Sjkim        break;
878228110Sjkim
879228110Sjkim    case PARSEOP_UART_SERIALBUS:
880298714Sjkim    case PARSEOP_UART_SERIALBUS_V2:
881250838Sjkim
882272444Sjkim        Rnode = RsDoUartSerialBusDescriptor (Info);
883228110Sjkim        break;
884228110Sjkim
885118611Snjl    case PARSEOP_DEFAULT_ARG:
886250838Sjkim
887118611Snjl        /* Just ignore any of these, they are used as fillers/placeholders */
888118611Snjl        break;
889118611Snjl
890118611Snjl    default:
891250838Sjkim
892118611Snjl        printf ("Unknown resource descriptor type [%s]\n",
893298714Sjkim            Info->DescriptorTypeOp->Asl.ParseOpName);
894118611Snjl        break;
895118611Snjl    }
896118611Snjl
897118611Snjl    /*
898118611Snjl     * Mark original node as unused, but head of a resource descriptor.
899118611Snjl     * This allows the resource to be installed in the namespace so that
900118611Snjl     * references to the descriptor can be resolved.
901118611Snjl     */
902272444Sjkim    Info->DescriptorTypeOp->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
903272444Sjkim    Info->DescriptorTypeOp->Asl.CompileFlags = NODE_IS_RESOURCE_DESC;
904272444Sjkim    Info->DescriptorTypeOp->Asl.Value.Integer = Info->CurrentByteOffset;
905118611Snjl
906167802Sjkim    if (Rnode)
907167802Sjkim    {
908272444Sjkim        Info->DescriptorTypeOp->Asl.FinalAmlLength = Rnode->BufferLength;
909298714Sjkim        Info->DescriptorTypeOp->Asl.Extra =
910298714Sjkim            ((AML_RESOURCE *) Rnode->Buffer)->DescriptorType;
911167802Sjkim    }
912167802Sjkim
913118611Snjl    return (Rnode);
914118611Snjl}
915118611Snjl
916118611Snjl
917118611Snjl/*******************************************************************************
918118611Snjl *
919118611Snjl * FUNCTION:    RsLinkDescriptorChain
920118611Snjl *
921118611Snjl * PARAMETERS:  PreviousRnode       - Pointer to the node that will be previous
922118611Snjl *                                    to the linked node,  At exit, set to the
923118611Snjl *                                    last node in the new chain.
924118611Snjl *              Rnode               - Resource node to link into the list
925118611Snjl *
926118611Snjl * RETURN:      Cumulative buffer byte offset of the new segment of chain
927118611Snjl *
928118611Snjl * DESCRIPTION: Link a descriptor chain at the end of an existing chain.
929118611Snjl *
930118611Snjl ******************************************************************************/
931118611Snjl
932118611SnjlUINT32
933118611SnjlRsLinkDescriptorChain (
934118611Snjl    ASL_RESOURCE_NODE       **PreviousRnode,
935118611Snjl    ASL_RESOURCE_NODE       *Rnode)
936118611Snjl{
937118611Snjl    ASL_RESOURCE_NODE       *LastRnode;
938118611Snjl    UINT32                  CurrentByteOffset;
939118611Snjl
940118611Snjl
941118611Snjl    /* Anything to do? */
942118611Snjl
943118611Snjl    if (!Rnode)
944118611Snjl    {
945241973Sjkim        return (0);
946118611Snjl    }
947118611Snjl
948118611Snjl    /* Point the previous node to the new node */
949118611Snjl
950118611Snjl    (*PreviousRnode)->Next = Rnode;
951118611Snjl    CurrentByteOffset = Rnode->BufferLength;
952118611Snjl
953118611Snjl    /* Walk to the end of the chain headed by Rnode */
954118611Snjl
955118611Snjl    LastRnode = Rnode;
956118611Snjl    while (LastRnode->Next)
957118611Snjl    {
958118611Snjl        LastRnode = LastRnode->Next;
959118611Snjl        CurrentByteOffset += LastRnode->BufferLength;
960118611Snjl    }
961118611Snjl
962118611Snjl    /* Previous node becomes the last node in the chain */
963118611Snjl
964118611Snjl    *PreviousRnode = LastRnode;
965241973Sjkim    return (CurrentByteOffset);
966118611Snjl}
967118611Snjl
968118611Snjl
969118611Snjl/*******************************************************************************
970118611Snjl *
971118611Snjl * FUNCTION:    RsDoResourceTemplate
972118611Snjl *
973118611Snjl * PARAMETERS:  Op        - Parent of a resource template list
974118611Snjl *
975241973Sjkim * RETURN:      None. Sets input node to point to a list of AML code
976118611Snjl *
977118611Snjl * DESCRIPTION: Merge a list of resource descriptors into a single AML buffer,
978118611Snjl *              in preparation for output to the AML output file.
979118611Snjl *
980118611Snjl ******************************************************************************/
981118611Snjl
982118611Snjlvoid
983118611SnjlRsDoResourceTemplate (
984118611Snjl    ACPI_PARSE_OBJECT       *Op)
985118611Snjl{
986118611Snjl    ACPI_PARSE_OBJECT       *BufferLengthOp;
987118611Snjl    ACPI_PARSE_OBJECT       *BufferOp;
988118611Snjl    ACPI_PARSE_OBJECT       *DescriptorTypeOp;
989118611Snjl    ACPI_PARSE_OBJECT       *LastOp = NULL;
990118611Snjl    UINT32                  CurrentByteOffset = 0;
991118611Snjl    ASL_RESOURCE_NODE       HeadRnode;
992118611Snjl    ASL_RESOURCE_NODE       *PreviousRnode;
993118611Snjl    ASL_RESOURCE_NODE       *Rnode;
994272444Sjkim    ASL_RESOURCE_INFO       Info;
995118611Snjl    UINT8                   State;
996118611Snjl
997118611Snjl
998167802Sjkim    /* Mark parent as containing a resource template */
999167802Sjkim
1000167802Sjkim    if (Op->Asl.Parent)
1001167802Sjkim    {
1002167802Sjkim        Op->Asl.Parent->Asl.CompileFlags |= NODE_IS_RESOURCE_DESC;
1003167802Sjkim    }
1004167802Sjkim
1005118611Snjl    /* ResourceTemplate Opcode is first (Op) */
1006118611Snjl    /* Buffer Length node is first child */
1007118611Snjl
1008118611Snjl    BufferLengthOp = ASL_GET_CHILD_NODE (Op);
1009118611Snjl
1010118611Snjl    /* Buffer Op is first peer */
1011118611Snjl
1012118611Snjl    BufferOp = ASL_GET_PEER_NODE (BufferLengthOp);
1013118611Snjl
1014118611Snjl    /* First Descriptor type is next */
1015118611Snjl
1016118611Snjl    DescriptorTypeOp = ASL_GET_PEER_NODE (BufferOp);
1017118611Snjl
1018167802Sjkim    /*
1019167802Sjkim     * Process all resource descriptors in the list
1020167802Sjkim     * Note: It is assumed that the EndTag node has been automatically
1021167802Sjkim     * inserted at the end of the template by the parser.
1022167802Sjkim     */
1023118611Snjl    State = ACPI_RSTATE_NORMAL;
1024118611Snjl    PreviousRnode = &HeadRnode;
1025118611Snjl    while (DescriptorTypeOp)
1026118611Snjl    {
1027272444Sjkim        /* Save information for optional mapfile */
1028272444Sjkim
1029272444Sjkim        if (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONNECTION)
1030272444Sjkim        {
1031272444Sjkim            Info.MappingOp = Op->Asl.Parent;
1032272444Sjkim        }
1033272444Sjkim        else
1034272444Sjkim        {
1035272444Sjkim            Info.MappingOp = DescriptorTypeOp;
1036272444Sjkim        }
1037272444Sjkim
1038272444Sjkim        Info.DescriptorTypeOp = DescriptorTypeOp;
1039272444Sjkim        Info.CurrentByteOffset = CurrentByteOffset;
1040272444Sjkim
1041167802Sjkim        DescriptorTypeOp->Asl.CompileFlags |= NODE_IS_RESOURCE_DESC;
1042272444Sjkim        Rnode = RsDoOneResourceDescriptor (&Info, &State);
1043118611Snjl
1044118611Snjl        /*
1045118611Snjl         * Update current byte offset to indicate the number of bytes from the
1046241973Sjkim         * start of the buffer. Buffer can include multiple descriptors, we
1047118611Snjl         * must keep track of the offset of not only each descriptor, but each
1048118611Snjl         * element (field) within each descriptor as well.
1049118611Snjl         */
1050118611Snjl        CurrentByteOffset += RsLinkDescriptorChain (&PreviousRnode, Rnode);
1051118611Snjl
1052118611Snjl        /* Get the next descriptor in the list */
1053118611Snjl
1054118611Snjl        LastOp = DescriptorTypeOp;
1055118611Snjl        DescriptorTypeOp = ASL_GET_PEER_NODE (DescriptorTypeOp);
1056118611Snjl    }
1057118611Snjl
1058118611Snjl    if (State == ACPI_RSTATE_DEPENDENT_LIST)
1059118611Snjl    {
1060118611Snjl        if (LastOp)
1061118611Snjl        {
1062118611Snjl            LastOp = LastOp->Asl.Parent;
1063118611Snjl        }
1064118611Snjl        AslError (ASL_ERROR, ASL_MSG_MISSING_ENDDEPENDENT, LastOp, NULL);
1065118611Snjl    }
1066118611Snjl
1067118611Snjl    /*
1068118611Snjl     * Transform the nodes into the following
1069118611Snjl     *
1070118611Snjl     * Op           -> AML_BUFFER_OP
1071118611Snjl     * First Child  -> BufferLength
1072118611Snjl     * Second Child -> Descriptor Buffer (raw byte data)
1073118611Snjl     */
1074118611Snjl    Op->Asl.ParseOpcode               = PARSEOP_BUFFER;
1075118611Snjl    Op->Asl.AmlOpcode                 = AML_BUFFER_OP;
1076167802Sjkim    Op->Asl.CompileFlags              = NODE_AML_PACKAGE | NODE_IS_RESOURCE_DESC;
1077228110Sjkim    UtSetParseOpName (Op);
1078118611Snjl
1079118611Snjl    BufferLengthOp->Asl.ParseOpcode   = PARSEOP_INTEGER;
1080118611Snjl    BufferLengthOp->Asl.Value.Integer = CurrentByteOffset;
1081118611Snjl    (void) OpcSetOptimalIntegerSize (BufferLengthOp);
1082228110Sjkim    UtSetParseOpName (BufferLengthOp);
1083118611Snjl
1084118611Snjl    BufferOp->Asl.ParseOpcode         = PARSEOP_RAW_DATA;
1085118611Snjl    BufferOp->Asl.AmlOpcode           = AML_RAW_DATA_CHAIN;
1086118611Snjl    BufferOp->Asl.AmlOpcodeLength     = 0;
1087118611Snjl    BufferOp->Asl.AmlLength           = CurrentByteOffset;
1088118611Snjl    BufferOp->Asl.Value.Buffer        = (UINT8 *) HeadRnode.Next;
1089167802Sjkim    BufferOp->Asl.CompileFlags       |= NODE_IS_RESOURCE_DATA;
1090228110Sjkim    UtSetParseOpName (BufferOp);
1091118611Snjl
1092118611Snjl    return;
1093118611Snjl}
1094