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  *
143  * RETURN:      None. Adds error messages to error log if necessary
144  *
145  * DESCRIPTION: Perform common value checks for "small" address descriptors.
146  *              Currently:
147  *                  Io, Memory24, Memory32
148  *
149  ******************************************************************************/
150 
151 void
152 RsSmallAddressCheck (
153     UINT8                   Type,
154     UINT32                  Minimum,
155     UINT32                  Maximum,
156     UINT32                  Length,
157     UINT32                  Alignment,
158     ACPI_PARSE_OBJECT       *MinOp,
159     ACPI_PARSE_OBJECT       *MaxOp,
160     ACPI_PARSE_OBJECT       *LengthOp,
161     ACPI_PARSE_OBJECT       *AlignOp)
162 {
163 
164     if (Gbl_NoResourceChecking)
165     {
166         return;
167     }
168 
169     /* Special case for Memory24, values are compressed */
170 
171     if (Type == ACPI_RESOURCE_NAME_MEMORY24)
172     {
173         if (!Alignment) /* Alignment==0 means 64K - no invalid alignment */
174         {
175             Alignment = ACPI_UINT16_MAX + 1;
176         }
177 
178         Minimum <<= 8;
179         Maximum <<= 8;
180         Length *= 256;
181     }
182 
183     /* IO descriptor has different definition of min/max, don't check */
184 
185     if (Type != ACPI_RESOURCE_NAME_IO)
186     {
187         /* Basic checks on Min/Max/Length */
188 
189         if (Minimum > Maximum)
190         {
191             AslError (ASL_ERROR, ASL_MSG_INVALID_MIN_MAX, MinOp, NULL);
192         }
193         else if (Length > (Maximum - Minimum + 1))
194         {
195             AslError (ASL_ERROR, ASL_MSG_INVALID_LENGTH, LengthOp, NULL);
196         }
197     }
198 
199     /* Alignment of zero is not in ACPI spec, but is used to mean byte acc */
200 
201     if (!Alignment)
202     {
203         Alignment = 1;
204     }
205 
206     /* Addresses must be an exact multiple of the alignment value */
207 
208     if (Minimum % Alignment)
209     {
210         AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MinOp, NULL);
211     }
212     if (Maximum % Alignment)
213     {
214         AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MaxOp, NULL);
215     }
216 }
217 
218 
219 /*******************************************************************************
220  *
221  * FUNCTION:    RsLargeAddressCheck
222  *
223  * PARAMETERS:  Minimum             - Address Min value
224  *              Maximum             - Address Max value
225  *              Length              - Address range value
226  *              Granularity         - Address granularity value
227  *              Flags               - General flags for address descriptors:
228  *                                    _MIF, _MAF, _DEC
229  *              MinOp               - Original Op for Address Min
230  *              MaxOp               - Original Op for Address Max
231  *              LengthOp            - Original Op for address range
232  *              GranOp              - Original Op for address granularity
233  *
234  * RETURN:      None. Adds error messages to error log if necessary
235  *
236  * DESCRIPTION: Perform common value checks for "large" address descriptors.
237  *              Currently:
238  *                  WordIo,     WordBusNumber,  WordSpace
239  *                  DWordIo,    DWordMemory,    DWordSpace
240  *                  QWordIo,    QWordMemory,    QWordSpace
241  *                  ExtendedIo, ExtendedMemory, ExtendedSpace
242  *
243  * _MIF flag set means that the minimum address is fixed and is not relocatable
244  * _MAF flag set means that the maximum address is fixed and is not relocatable
245  * Length of zero means that the record size is variable
246  *
247  * This function implements the LEN/MIF/MAF/MIN/MAX/GRA rules within Table 6-40
248  * of the ACPI 4.0a specification. Added 04/2010.
249  *
250  ******************************************************************************/
251 
252 void
253 RsLargeAddressCheck (
254     UINT64                  Minimum,
255     UINT64                  Maximum,
256     UINT64                  Length,
257     UINT64                  Granularity,
258     UINT8                   Flags,
259     ACPI_PARSE_OBJECT       *MinOp,
260     ACPI_PARSE_OBJECT       *MaxOp,
261     ACPI_PARSE_OBJECT       *LengthOp,
262     ACPI_PARSE_OBJECT       *GranOp)
263 {
264 
265     if (Gbl_NoResourceChecking)
266     {
267         return;
268     }
269 
270     /* Basic checks on Min/Max/Length */
271 
272     if (Minimum > Maximum)
273     {
274         AslError (ASL_ERROR, ASL_MSG_INVALID_MIN_MAX, MinOp, NULL);
275         return;
276     }
277     else if (Length > (Maximum - Minimum + 1))
278     {
279         AslError (ASL_ERROR, ASL_MSG_INVALID_LENGTH, LengthOp, NULL);
280         return;
281     }
282 
283     /* If specified (non-zero), ensure granularity is a power-of-two minus one */
284 
285     if (Granularity)
286     {
287         if ((Granularity + 1) &
288              Granularity)
289         {
290             AslError (ASL_ERROR, ASL_MSG_INVALID_GRANULARITY, GranOp, NULL);
291             return;
292         }
293     }
294 
295     /*
296      * Check the various combinations of Length, MinFixed, and MaxFixed
297      */
298     if (Length)
299     {
300         /* Fixed non-zero length */
301 
302         switch (Flags & (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF))
303         {
304         case 0:
305             /*
306              * Fixed length, variable locations (both _MIN and _MAX).
307              * Length must be a multiple of granularity
308              */
309             if (Granularity & Length)
310             {
311                 AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, LengthOp, NULL);
312             }
313             break;
314 
315         case (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF):
316 
317             /* Fixed length, fixed location. Granularity must be zero */
318 
319             if (Granularity != 0)
320             {
321                 AslError (ASL_ERROR, ASL_MSG_INVALID_GRAN_FIXED, GranOp, NULL);
322             }
323 
324             /* Length must be exactly the size of the min/max window */
325 
326             if (Length != (Maximum - Minimum + 1))
327             {
328                 AslError (ASL_ERROR, ASL_MSG_INVALID_LENGTH_FIXED, LengthOp, NULL);
329             }
330             break;
331 
332         /* All other combinations are invalid */
333 
334         case ACPI_RESOURCE_FLAG_MIF:
335         case ACPI_RESOURCE_FLAG_MAF:
336         default:
337             AslError (ASL_ERROR, ASL_MSG_INVALID_ADDR_FLAGS, LengthOp, NULL);
338         }
339     }
340     else
341     {
342         /* Variable length (length==0) */
343 
344         switch (Flags & (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF))
345         {
346         case 0:
347             /*
348              * Both _MIN and _MAX are variable.
349              * No additional requirements, just exit
350              */
351             break;
352 
353         case ACPI_RESOURCE_FLAG_MIF:
354 
355             /* _MIN is fixed. _MIN must be multiple of _GRA */
356 
357             /*
358              * The granularity is defined by the ACPI specification to be a
359              * power-of-two minus one, therefore the granularity is a
360              * bitmask which can be used to easily validate the addresses.
361              */
362             if (Granularity & Minimum)
363             {
364                 AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MinOp, NULL);
365             }
366             break;
367 
368         case ACPI_RESOURCE_FLAG_MAF:
369 
370             /* _MAX is fixed. (_MAX + 1) must be multiple of _GRA */
371 
372             if (Granularity & (Maximum + 1))
373             {
374                 AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MaxOp, "-1");
375             }
376             break;
377 
378         /* Both MIF/MAF set is invalid if length is zero */
379 
380         case (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF):
381         default:
382             AslError (ASL_ERROR, ASL_MSG_INVALID_ADDR_FLAGS, LengthOp, NULL);
383         }
384     }
385 }
386 
387 
388 /*******************************************************************************
389  *
390  * FUNCTION:    RsGetStringDataLength
391  *
392  * PARAMETERS:  InitializerOp     - Start of a subtree of init nodes
393  *
394  * RETURN:      Valid string length if a string node is found (otherwise 0)
395  *
396  * DESCRIPTION: In a list of peer nodes, find the first one that contains a
397  *              string and return the length of the string.
398  *
399  ******************************************************************************/
400 
401 UINT16
402 RsGetStringDataLength (
403     ACPI_PARSE_OBJECT       *InitializerOp)
404 {
405 
406     while (InitializerOp)
407     {
408         if (InitializerOp->Asl.ParseOpcode == PARSEOP_STRING_LITERAL)
409         {
410             return ((UINT16) (strlen (InitializerOp->Asl.Value.String) + 1));
411         }
412         InitializerOp = ASL_GET_PEER_NODE (InitializerOp);
413     }
414 
415     return 0;
416 }
417 
418 
419 /*******************************************************************************
420  *
421  * FUNCTION:    RsAllocateResourceNode
422  *
423  * PARAMETERS:  Size        - Size of node in bytes
424  *
425  * RETURN:      The allocated node - aborts on allocation failure
426  *
427  * DESCRIPTION: Allocate a resource description node and the resource
428  *              descriptor itself (the nodes are used to link descriptors).
429  *
430  ******************************************************************************/
431 
432 ASL_RESOURCE_NODE *
433 RsAllocateResourceNode (
434     UINT32                  Size)
435 {
436     ASL_RESOURCE_NODE       *Rnode;
437 
438 
439     /* Allocate the node */
440 
441     Rnode = UtLocalCalloc (sizeof (ASL_RESOURCE_NODE));
442 
443     /* Allocate the resource descriptor itself */
444 
445     Rnode->Buffer = UtLocalCalloc (Size);
446     Rnode->BufferLength = Size;
447 
448     return (Rnode);
449 }
450 
451 
452 /*******************************************************************************
453  *
454  * FUNCTION:    RsCreateBitField
455  *
456  * PARAMETERS:  Op              - Resource field node
457  *              Name            - Name of the field (Used only to reference
458  *                                the field in the ASL, not in the AML)
459  *              ByteOffset      - Offset from the field start
460  *              BitOffset       - Additional bit offset
461  *
462  * RETURN:      None, sets fields within the input node
463  *
464  * DESCRIPTION: Utility function to generate a named bit field within a
465  *              resource descriptor.  Mark a node as 1) a field in a resource
466  *              descriptor, and 2) set the value to be a BIT offset
467  *
468  ******************************************************************************/
469 
470 void
471 RsCreateBitField (
472     ACPI_PARSE_OBJECT       *Op,
473     char                    *Name,
474     UINT32                  ByteOffset,
475     UINT32                  BitOffset)
476 {
477 
478     Op->Asl.ExternalName      = Name;
479     Op->Asl.Value.Integer     = ((UINT64) ByteOffset * 8) + BitOffset;
480     Op->Asl.CompileFlags     |= (NODE_IS_RESOURCE_FIELD | NODE_IS_BIT_OFFSET);
481 }
482 
483 
484 /*******************************************************************************
485  *
486  * FUNCTION:    RsCreateByteField
487  *
488  * PARAMETERS:  Op              - Resource field node
489  *              Name            - Name of the field (Used only to reference
490  *                                the field in the ASL, not in the AML)
491  *              ByteOffset      - Offset from the field start
492  *
493  * RETURN:      None, sets fields within the input node
494  *
495  * DESCRIPTION: Utility function to generate a named byte field within a
496  *              resource descriptor.  Mark a node as 1) a field in a resource
497  *              descriptor, and 2) set the value to be a BYTE offset
498  *
499  ******************************************************************************/
500 
501 void
502 RsCreateByteField (
503     ACPI_PARSE_OBJECT       *Op,
504     char                    *Name,
505     UINT32                  ByteOffset)
506 {
507 
508     Op->Asl.ExternalName      = Name;
509     Op->Asl.Value.Integer     = ByteOffset;
510     Op->Asl.CompileFlags     |= NODE_IS_RESOURCE_FIELD;
511 }
512 
513 
514 /*******************************************************************************
515  *
516  * FUNCTION:    RsSetFlagBits
517  *
518  * PARAMETERS:  *Flags          - Pointer to the flag byte
519  *              Op              - Flag initialization node
520  *              Position        - Bit position within the flag byte
521  *              Default         - Used if the node is DEFAULT.
522  *
523  * RETURN:      Sets bits within the *Flags output byte.
524  *
525  * DESCRIPTION: Set a bit in a cumulative flags word from an initialization
526  *              node.  Will use a default value if the node is DEFAULT, meaning
527  *              that no value was specified in the ASL.  Used to merge multiple
528  *              keywords into a single flags byte.
529  *
530  ******************************************************************************/
531 
532 void
533 RsSetFlagBits (
534     UINT8                   *Flags,
535     ACPI_PARSE_OBJECT       *Op,
536     UINT8                   Position,
537     UINT8                   DefaultBit)
538 {
539 
540     if (Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
541     {
542         /* Use the default bit */
543 
544         *Flags |= (DefaultBit << Position);
545     }
546     else
547     {
548         /* Use the bit specified in the initialization node */
549 
550         *Flags |= (((UINT8) Op->Asl.Value.Integer) << Position);
551     }
552 }
553 
554 
555 /*******************************************************************************
556  *
557  * FUNCTION:    RsCompleteNodeAndGetNext
558  *
559  * PARAMETERS:  Op            - Resource node to be completed
560  *
561  * RETURN:      The next peer to the input node.
562  *
563  * DESCRIPTION: Mark the current node completed and return the next peer.
564  *              The node ParseOpcode is set to DEFAULT_ARG, meaning that
565  *              this node is to be ignored from now on.
566  *
567  ******************************************************************************/
568 
569 ACPI_PARSE_OBJECT *
570 RsCompleteNodeAndGetNext (
571     ACPI_PARSE_OBJECT       *Op)
572 {
573 
574     /* Mark this node unused */
575 
576     Op->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
577 
578     /* Move on to the next peer node in the initializer list */
579 
580     return (ASL_GET_PEER_NODE (Op));
581 }
582 
583 
584 /*******************************************************************************
585  *
586  * FUNCTION:    RsCheckListForDuplicates
587  *
588  * PARAMETERS:  Op                  - First op in the initializer list
589  *
590  * RETURN:      None
591  *
592  * DESCRIPTION: Check an initializer list for duplicate values. Emits an error
593  *              if any duplicates are found.
594  *
595  ******************************************************************************/
596 
597 void
598 RsCheckListForDuplicates (
599     ACPI_PARSE_OBJECT       *Op)
600 {
601     ACPI_PARSE_OBJECT       *NextValueOp = Op;
602     ACPI_PARSE_OBJECT       *NextOp;
603     UINT32                  Value;
604 
605 
606     if (!Op)
607     {
608         return;
609     }
610 
611     /* Search list once for each value in the list */
612 
613     while (NextValueOp)
614     {
615         Value = (UINT32) NextValueOp->Asl.Value.Integer;
616 
617         /* Compare this value to all remaining values in the list */
618 
619         NextOp = ASL_GET_PEER_NODE (NextValueOp);
620         while (NextOp)
621         {
622             if (NextOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
623             {
624                 /* Compare values */
625 
626                 if (Value == (UINT32) NextOp->Asl.Value.Integer)
627                 {
628                     /* Emit error only once per duplicate node */
629 
630                     if (!(NextOp->Asl.CompileFlags & NODE_IS_DUPLICATE))
631                     {
632                         NextOp->Asl.CompileFlags |= NODE_IS_DUPLICATE;
633                         AslError (ASL_ERROR, ASL_MSG_DUPLICATE_ITEM,
634                             NextOp, NULL);
635                     }
636                 }
637             }
638 
639             NextOp = ASL_GET_PEER_NODE (NextOp);
640         }
641 
642         NextValueOp = ASL_GET_PEER_NODE (NextValueOp);
643     }
644 }
645 
646 
647 /*******************************************************************************
648  *
649  * FUNCTION:    RsDoOneResourceDescriptor
650  *
651  * PARAMETERS:  DescriptorTypeOp    - Parent parse node of the descriptor
652  *              CurrentByteOffset   - Offset in the resource descriptor
653  *                                    buffer.
654  *
655  * RETURN:      A valid resource node for the descriptor
656  *
657  * DESCRIPTION: Dispatches the processing of one resource descriptor
658  *
659  ******************************************************************************/
660 
661 ASL_RESOURCE_NODE *
662 RsDoOneResourceDescriptor (
663     ACPI_PARSE_OBJECT       *DescriptorTypeOp,
664     UINT32                  CurrentByteOffset,
665     UINT8                   *State)
666 {
667     ASL_RESOURCE_NODE       *Rnode = NULL;
668 
669 
670     /* Construct the resource */
671 
672     switch (DescriptorTypeOp->Asl.ParseOpcode)
673     {
674     case PARSEOP_DMA:
675         Rnode = RsDoDmaDescriptor (DescriptorTypeOp,
676                     CurrentByteOffset);
677         break;
678 
679     case PARSEOP_DWORDIO:
680         Rnode = RsDoDwordIoDescriptor (DescriptorTypeOp,
681                     CurrentByteOffset);
682         break;
683 
684     case PARSEOP_DWORDMEMORY:
685         Rnode = RsDoDwordMemoryDescriptor (DescriptorTypeOp,
686                     CurrentByteOffset);
687         break;
688 
689     case PARSEOP_DWORDSPACE:
690         Rnode = RsDoDwordSpaceDescriptor (DescriptorTypeOp,
691                     CurrentByteOffset);
692         break;
693 
694     case PARSEOP_ENDDEPENDENTFN:
695         switch (*State)
696         {
697         case ACPI_RSTATE_NORMAL:
698             AslError (ASL_ERROR, ASL_MSG_MISSING_STARTDEPENDENT,
699                 DescriptorTypeOp, NULL);
700             break;
701 
702         case ACPI_RSTATE_START_DEPENDENT:
703             AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING,
704                 DescriptorTypeOp, NULL);
705             break;
706 
707         case ACPI_RSTATE_DEPENDENT_LIST:
708         default:
709             break;
710         }
711 
712         *State = ACPI_RSTATE_NORMAL;
713         Rnode = RsDoEndDependentDescriptor (DescriptorTypeOp,
714                     CurrentByteOffset);
715         break;
716 
717     case PARSEOP_ENDTAG:
718         Rnode = RsDoEndTagDescriptor (DescriptorTypeOp,
719                     CurrentByteOffset);
720         break;
721 
722     case PARSEOP_EXTENDEDIO:
723         Rnode = RsDoExtendedIoDescriptor (DescriptorTypeOp,
724                     CurrentByteOffset);
725         break;
726 
727     case PARSEOP_EXTENDEDMEMORY:
728         Rnode = RsDoExtendedMemoryDescriptor (DescriptorTypeOp,
729                     CurrentByteOffset);
730         break;
731 
732     case PARSEOP_EXTENDEDSPACE:
733         Rnode = RsDoExtendedSpaceDescriptor (DescriptorTypeOp,
734                     CurrentByteOffset);
735         break;
736 
737     case PARSEOP_FIXEDIO:
738         Rnode = RsDoFixedIoDescriptor (DescriptorTypeOp,
739                     CurrentByteOffset);
740         break;
741 
742     case PARSEOP_INTERRUPT:
743         Rnode = RsDoInterruptDescriptor (DescriptorTypeOp,
744                     CurrentByteOffset);
745         break;
746 
747     case PARSEOP_IO:
748         Rnode = RsDoIoDescriptor (DescriptorTypeOp,
749                     CurrentByteOffset);
750         break;
751 
752     case PARSEOP_IRQ:
753         Rnode = RsDoIrqDescriptor (DescriptorTypeOp,
754                     CurrentByteOffset);
755         break;
756 
757     case PARSEOP_IRQNOFLAGS:
758         Rnode = RsDoIrqNoFlagsDescriptor (DescriptorTypeOp,
759                     CurrentByteOffset);
760         break;
761 
762     case PARSEOP_MEMORY24:
763         Rnode = RsDoMemory24Descriptor (DescriptorTypeOp,
764                     CurrentByteOffset);
765         break;
766 
767     case PARSEOP_MEMORY32:
768         Rnode = RsDoMemory32Descriptor (DescriptorTypeOp,
769                     CurrentByteOffset);
770         break;
771 
772     case PARSEOP_MEMORY32FIXED:
773         Rnode = RsDoMemory32FixedDescriptor (DescriptorTypeOp,
774                     CurrentByteOffset);
775         break;
776 
777     case PARSEOP_QWORDIO:
778         Rnode = RsDoQwordIoDescriptor (DescriptorTypeOp,
779                     CurrentByteOffset);
780         break;
781 
782     case PARSEOP_QWORDMEMORY:
783         Rnode = RsDoQwordMemoryDescriptor (DescriptorTypeOp,
784                     CurrentByteOffset);
785         break;
786 
787     case PARSEOP_QWORDSPACE:
788         Rnode = RsDoQwordSpaceDescriptor (DescriptorTypeOp,
789                     CurrentByteOffset);
790         break;
791 
792     case PARSEOP_REGISTER:
793         Rnode = RsDoGeneralRegisterDescriptor (DescriptorTypeOp,
794                     CurrentByteOffset);
795         break;
796 
797     case PARSEOP_STARTDEPENDENTFN:
798         switch (*State)
799         {
800         case ACPI_RSTATE_START_DEPENDENT:
801             AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING,
802                 DescriptorTypeOp, NULL);
803             break;
804 
805         case ACPI_RSTATE_NORMAL:
806         case ACPI_RSTATE_DEPENDENT_LIST:
807         default:
808             break;
809         }
810 
811         *State = ACPI_RSTATE_START_DEPENDENT;
812         Rnode = RsDoStartDependentDescriptor (DescriptorTypeOp,
813                     CurrentByteOffset);
814         *State = ACPI_RSTATE_DEPENDENT_LIST;
815         break;
816 
817     case PARSEOP_STARTDEPENDENTFN_NOPRI:
818         switch (*State)
819         {
820         case ACPI_RSTATE_START_DEPENDENT:
821             AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING,
822                 DescriptorTypeOp, NULL);
823             break;
824 
825         case ACPI_RSTATE_NORMAL:
826         case ACPI_RSTATE_DEPENDENT_LIST:
827         default:
828             break;
829         }
830 
831         *State = ACPI_RSTATE_START_DEPENDENT;
832         Rnode = RsDoStartDependentNoPriDescriptor (DescriptorTypeOp,
833                     CurrentByteOffset);
834         *State = ACPI_RSTATE_DEPENDENT_LIST;
835         break;
836 
837     case PARSEOP_VENDORLONG:
838         Rnode = RsDoVendorLargeDescriptor (DescriptorTypeOp,
839                     CurrentByteOffset);
840         break;
841 
842     case PARSEOP_VENDORSHORT:
843         Rnode = RsDoVendorSmallDescriptor (DescriptorTypeOp,
844                     CurrentByteOffset);
845         break;
846 
847     case PARSEOP_WORDBUSNUMBER:
848         Rnode = RsDoWordBusNumberDescriptor (DescriptorTypeOp,
849                     CurrentByteOffset);
850         break;
851 
852     case PARSEOP_WORDIO:
853         Rnode = RsDoWordIoDescriptor (DescriptorTypeOp,
854                     CurrentByteOffset);
855         break;
856 
857     case PARSEOP_WORDSPACE:
858         Rnode = RsDoWordSpaceDescriptor (DescriptorTypeOp,
859                     CurrentByteOffset);
860         break;
861 
862     case PARSEOP_DEFAULT_ARG:
863         /* Just ignore any of these, they are used as fillers/placeholders */
864         break;
865 
866     default:
867         printf ("Unknown resource descriptor type [%s]\n",
868                     DescriptorTypeOp->Asl.ParseOpName);
869         break;
870     }
871 
872     /*
873      * Mark original node as unused, but head of a resource descriptor.
874      * This allows the resource to be installed in the namespace so that
875      * references to the descriptor can be resolved.
876      */
877     DescriptorTypeOp->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
878     DescriptorTypeOp->Asl.CompileFlags = NODE_IS_RESOURCE_DESC;
879     DescriptorTypeOp->Asl.Value.Integer = CurrentByteOffset;
880 
881     if (Rnode)
882     {
883         DescriptorTypeOp->Asl.FinalAmlLength = Rnode->BufferLength;
884     }
885 
886     return (Rnode);
887 }
888 
889 
890 /*******************************************************************************
891  *
892  * FUNCTION:    RsLinkDescriptorChain
893  *
894  * PARAMETERS:  PreviousRnode       - Pointer to the node that will be previous
895  *                                    to the linked node,  At exit, set to the
896  *                                    last node in the new chain.
897  *              Rnode               - Resource node to link into the list
898  *
899  * RETURN:      Cumulative buffer byte offset of the new segment of chain
900  *
901  * DESCRIPTION: Link a descriptor chain at the end of an existing chain.
902  *
903  ******************************************************************************/
904 
905 UINT32
906 RsLinkDescriptorChain (
907     ASL_RESOURCE_NODE       **PreviousRnode,
908     ASL_RESOURCE_NODE       *Rnode)
909 {
910     ASL_RESOURCE_NODE       *LastRnode;
911     UINT32                  CurrentByteOffset;
912 
913 
914     /* Anything to do? */
915 
916     if (!Rnode)
917     {
918         return 0;
919     }
920 
921     /* Point the previous node to the new node */
922 
923     (*PreviousRnode)->Next = Rnode;
924     CurrentByteOffset = Rnode->BufferLength;
925 
926     /* Walk to the end of the chain headed by Rnode */
927 
928     LastRnode = Rnode;
929     while (LastRnode->Next)
930     {
931         LastRnode = LastRnode->Next;
932         CurrentByteOffset += LastRnode->BufferLength;
933     }
934 
935     /* Previous node becomes the last node in the chain */
936 
937     *PreviousRnode = LastRnode;
938     return CurrentByteOffset;
939 }
940 
941 
942 /*******************************************************************************
943  *
944  * FUNCTION:    RsDoResourceTemplate
945  *
946  * PARAMETERS:  Op        - Parent of a resource template list
947  *
948  * RETURN:      None.  Sets input node to point to a list of AML code
949  *
950  * DESCRIPTION: Merge a list of resource descriptors into a single AML buffer,
951  *              in preparation for output to the AML output file.
952  *
953  ******************************************************************************/
954 
955 void
956 RsDoResourceTemplate (
957     ACPI_PARSE_OBJECT       *Op)
958 {
959     ACPI_PARSE_OBJECT       *BufferLengthOp;
960     ACPI_PARSE_OBJECT       *BufferOp;
961     ACPI_PARSE_OBJECT       *DescriptorTypeOp;
962     ACPI_PARSE_OBJECT       *LastOp = NULL;
963     UINT32                  CurrentByteOffset = 0;
964     ASL_RESOURCE_NODE       HeadRnode;
965     ASL_RESOURCE_NODE       *PreviousRnode;
966     ASL_RESOURCE_NODE       *Rnode;
967     UINT8                   State;
968 
969 
970     /* Mark parent as containing a resource template */
971 
972     if (Op->Asl.Parent)
973     {
974         Op->Asl.Parent->Asl.CompileFlags |= NODE_IS_RESOURCE_DESC;
975     }
976 
977     /* ResourceTemplate Opcode is first (Op) */
978     /* Buffer Length node is first child */
979 
980     BufferLengthOp = ASL_GET_CHILD_NODE (Op);
981 
982     /* Buffer Op is first peer */
983 
984     BufferOp = ASL_GET_PEER_NODE (BufferLengthOp);
985 
986     /* First Descriptor type is next */
987 
988     DescriptorTypeOp = ASL_GET_PEER_NODE (BufferOp);
989 
990     /*
991      * Process all resource descriptors in the list
992      * Note: It is assumed that the EndTag node has been automatically
993      * inserted at the end of the template by the parser.
994      */
995     State = ACPI_RSTATE_NORMAL;
996     PreviousRnode = &HeadRnode;
997     while (DescriptorTypeOp)
998     {
999         DescriptorTypeOp->Asl.CompileFlags |= NODE_IS_RESOURCE_DESC;
1000         Rnode = RsDoOneResourceDescriptor (DescriptorTypeOp, CurrentByteOffset,
1001                     &State);
1002 
1003         /*
1004          * Update current byte offset to indicate the number of bytes from the
1005          * start of the buffer.  Buffer can include multiple descriptors, we
1006          * must keep track of the offset of not only each descriptor, but each
1007          * element (field) within each descriptor as well.
1008          */
1009         CurrentByteOffset += RsLinkDescriptorChain (&PreviousRnode, Rnode);
1010 
1011         /* Get the next descriptor in the list */
1012 
1013         LastOp = DescriptorTypeOp;
1014         DescriptorTypeOp = ASL_GET_PEER_NODE (DescriptorTypeOp);
1015     }
1016 
1017     if (State == ACPI_RSTATE_DEPENDENT_LIST)
1018     {
1019         if (LastOp)
1020         {
1021             LastOp = LastOp->Asl.Parent;
1022         }
1023         AslError (ASL_ERROR, ASL_MSG_MISSING_ENDDEPENDENT, LastOp, NULL);
1024     }
1025 
1026     /*
1027      * Transform the nodes into the following
1028      *
1029      * Op           -> AML_BUFFER_OP
1030      * First Child  -> BufferLength
1031      * Second Child -> Descriptor Buffer (raw byte data)
1032      */
1033     Op->Asl.ParseOpcode               = PARSEOP_BUFFER;
1034     Op->Asl.AmlOpcode                 = AML_BUFFER_OP;
1035     Op->Asl.CompileFlags              = NODE_AML_PACKAGE | NODE_IS_RESOURCE_DESC;
1036 
1037     BufferLengthOp->Asl.ParseOpcode   = PARSEOP_INTEGER;
1038     BufferLengthOp->Asl.Value.Integer = CurrentByteOffset;
1039     (void) OpcSetOptimalIntegerSize (BufferLengthOp);
1040 
1041     BufferOp->Asl.ParseOpcode         = PARSEOP_RAW_DATA;
1042     BufferOp->Asl.AmlOpcode           = AML_RAW_DATA_CHAIN;
1043     BufferOp->Asl.AmlOpcodeLength     = 0;
1044     BufferOp->Asl.AmlLength           = CurrentByteOffset;
1045     BufferOp->Asl.Value.Buffer        = (UINT8 *) HeadRnode.Next;
1046     BufferOp->Asl.CompileFlags       |= NODE_IS_RESOURCE_DATA;
1047 
1048     return;
1049 }
1050 
1051 
1052