Initial import of binutils 2.22 on the new vendor branch
[dragonfly.git] / sys / contrib / dev / acpica-unix / compiler / aslresource.c
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 - 2011, 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 "aslcompiler.h"
119 #include "aslcompiler.y.h"
120 #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
152 void
153 RsSmallAddressCheck (
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
283 void
284 RsLargeAddressCheck (
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
459 UINT16
460 RsGetStringDataLength (
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
490 ASL_RESOURCE_NODE *
491 RsAllocateResourceNode (
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
528 void
529 RsCreateBitField (
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
559 void
560 RsCreateByteField (
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
590 void
591 RsSetFlagBits (
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
627 ACPI_PARSE_OBJECT *
628 RsCompleteNodeAndGetNext (
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
655 void
656 RsCheckListForDuplicates (
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
719 ASL_RESOURCE_NODE *
720 RsDoOneResourceDescriptor (
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
963 UINT32
964 RsLinkDescriptorChain (
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
1013 void
1014 RsDoResourceTemplate (
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