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