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