]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - sys/contrib/dev/acpica/compiler/aslresource.c
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.git] / sys / contrib / dev / acpica / compiler / aslresource.c
1
2 /******************************************************************************
3  *
4  * Module Name: aslresource - Resource templates and descriptors
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:    RsAllocateResourceNode
130  *
131  * PARAMETERS:  Size        - Size of node in bytes
132  *
133  * RETURN:      The allocated node - aborts on allocation failure
134  *
135  * DESCRIPTION: Allocate a resource description node and the resource
136  *              descriptor itself (the nodes are used to link descriptors).
137  *
138  ******************************************************************************/
139
140 ASL_RESOURCE_NODE *
141 RsAllocateResourceNode (
142     UINT32                  Size)
143 {
144     ASL_RESOURCE_NODE       *Rnode;
145
146
147     /* Allocate the node */
148
149     Rnode = UtLocalCalloc (sizeof (ASL_RESOURCE_NODE));
150
151     /* Allocate the resource descriptor itself */
152
153     Rnode->Buffer = UtLocalCalloc (Size);
154     Rnode->BufferLength = Size;
155
156     return (Rnode);
157 }
158
159
160 /*******************************************************************************
161  *
162  * FUNCTION:    RsCreateBitField
163  *
164  * PARAMETERS:  Op              - Resource field node
165  *              Name            - Name of the field (Used only to reference
166  *                                the field in the ASL, not in the AML)
167  *              ByteOffset      - Offset from the field start
168  *              BitOffset       - Additional bit offset
169  *
170  * RETURN:      None, sets fields within the input node
171  *
172  * DESCRIPTION: Utility function to generate a named bit field within a
173  *              resource descriptor.  Mark a node as 1) a field in a resource
174  *              descriptor, and 2) set the value to be a BIT offset
175  *
176  ******************************************************************************/
177
178 void
179 RsCreateBitField (
180     ACPI_PARSE_OBJECT       *Op,
181     char                    *Name,
182     UINT32                  ByteOffset,
183     UINT32                  BitOffset)
184 {
185
186     Op->Asl.ExternalName      = Name;
187     Op->Asl.Value.Integer     = ((UINT64) ByteOffset * 8) + BitOffset;
188     Op->Asl.CompileFlags     |= (NODE_IS_RESOURCE_FIELD | NODE_IS_BIT_OFFSET);
189 }
190
191
192 /*******************************************************************************
193  *
194  * FUNCTION:    RsCreateByteField
195  *
196  * PARAMETERS:  Op              - Resource field node
197  *              Name            - Name of the field (Used only to reference
198  *                                the field in the ASL, not in the AML)
199  *              ByteOffset      - Offset from the field start
200  *
201  * RETURN:      None, sets fields within the input node
202  *
203  * DESCRIPTION: Utility function to generate a named byte field within a
204  *              resource descriptor.  Mark a node as 1) a field in a resource
205  *              descriptor, and 2) set the value to be a BYTE offset
206  *
207  ******************************************************************************/
208
209 void
210 RsCreateByteField (
211     ACPI_PARSE_OBJECT       *Op,
212     char                    *Name,
213     UINT32                  ByteOffset)
214 {
215
216     Op->Asl.ExternalName      = Name;
217     Op->Asl.Value.Integer     = ByteOffset;
218     Op->Asl.CompileFlags     |= NODE_IS_RESOURCE_FIELD;
219 }
220
221
222 /*******************************************************************************
223  *
224  * FUNCTION:    RsSetFlagBits
225  *
226  * PARAMETERS:  *Flags          - Pointer to the flag byte
227  *              Op              - Flag initialization node
228  *              Position        - Bit position within the flag byte
229  *              Default         - Used if the node is DEFAULT.
230  *
231  * RETURN:      Sets bits within the *Flags output byte.
232  *
233  * DESCRIPTION: Set a bit in a cumulative flags word from an initialization
234  *              node.  Will use a default value if the node is DEFAULT, meaning
235  *              that no value was specified in the ASL.  Used to merge multiple
236  *              keywords into a single flags byte.
237  *
238  ******************************************************************************/
239
240 void
241 RsSetFlagBits (
242     UINT8                   *Flags,
243     ACPI_PARSE_OBJECT       *Op,
244     UINT8                   Position,
245     UINT8                   DefaultBit)
246 {
247
248     if (Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
249     {
250         /* Use the default bit */
251
252         *Flags |= (DefaultBit << Position);
253     }
254     else
255     {
256         /* Use the bit specified in the initialization node */
257
258         *Flags |= (((UINT8) Op->Asl.Value.Integer) << Position);
259     }
260 }
261
262
263 /*******************************************************************************
264  *
265  * FUNCTION:    RsCompleteNodeAndGetNext
266  *
267  * PARAMETERS:  Op            - Resource node to be completed
268  *
269  * RETURN:      The next peer to the input node.
270  *
271  * DESCRIPTION: Mark the current node completed and return the next peer.
272  *              The node ParseOpcode is set to DEFAULT_ARG, meaning that
273  *              this node is to be ignored from now on.
274  *
275  ******************************************************************************/
276
277 ACPI_PARSE_OBJECT *
278 RsCompleteNodeAndGetNext (
279     ACPI_PARSE_OBJECT       *Op)
280 {
281
282     /* Mark this node unused */
283
284     Op->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
285
286     /* Move on to the next peer node in the initializer list */
287
288     return (ASL_GET_PEER_NODE (Op));
289 }
290
291
292 /*******************************************************************************
293  *
294  * FUNCTION:    RsCheckListForDuplicates
295  *
296  * PARAMETERS:  Op                  - First op in the initializer list
297  *
298  * RETURN:      None
299  *
300  * DESCRIPTION: Check an initializer list for duplicate values. Emits an error
301  *              if any duplicates are found.
302  *
303  ******************************************************************************/
304
305 void
306 RsCheckListForDuplicates (
307     ACPI_PARSE_OBJECT       *Op)
308 {
309     ACPI_PARSE_OBJECT       *NextValueOp = Op;
310     ACPI_PARSE_OBJECT       *NextOp;
311     UINT32                  Value;
312
313
314     if (!Op)
315     {
316         return;
317     }
318
319     /* Search list once for each value in the list */
320
321     while (NextValueOp)
322     {
323         Value = (UINT32) NextValueOp->Asl.Value.Integer;
324
325         /* Compare this value to all remaining values in the list */
326
327         NextOp = ASL_GET_PEER_NODE (NextValueOp);
328         while (NextOp)
329         {
330             if (NextOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
331             {
332                 /* Compare values */
333
334                 if (Value == (UINT32) NextOp->Asl.Value.Integer)
335                 {
336                     /* Emit error only once per duplicate node */
337
338                     if (!(NextOp->Asl.CompileFlags & NODE_IS_DUPLICATE))
339                     {
340                         NextOp->Asl.CompileFlags |= NODE_IS_DUPLICATE;
341                         AslError (ASL_ERROR, ASL_MSG_DUPLICATE_ITEM,
342                             NextOp, NULL);
343                     }
344                 }
345             }
346
347             NextOp = ASL_GET_PEER_NODE (NextOp);
348         }
349
350         NextValueOp = ASL_GET_PEER_NODE (NextValueOp);
351     }
352 }
353
354
355 /*******************************************************************************
356  *
357  * FUNCTION:    RsDoOneResourceDescriptor
358  *
359  * PARAMETERS:  DescriptorTypeOp    - Parent parse node of the descriptor
360  *              CurrentByteOffset   - Offset in the resource descriptor
361  *                                    buffer.
362  *
363  * RETURN:      A valid resource node for the descriptor
364  *
365  * DESCRIPTION: Dispatches the processing of one resource descriptor
366  *
367  ******************************************************************************/
368
369 ASL_RESOURCE_NODE *
370 RsDoOneResourceDescriptor (
371     ACPI_PARSE_OBJECT       *DescriptorTypeOp,
372     UINT32                  CurrentByteOffset,
373     UINT8                   *State)
374 {
375     ASL_RESOURCE_NODE       *Rnode = NULL;
376
377
378     /* Construct the resource */
379
380     switch (DescriptorTypeOp->Asl.ParseOpcode)
381     {
382     case PARSEOP_DMA:
383         Rnode = RsDoDmaDescriptor (DescriptorTypeOp,
384                     CurrentByteOffset);
385         break;
386
387     case PARSEOP_DWORDIO:
388         Rnode = RsDoDwordIoDescriptor (DescriptorTypeOp,
389                     CurrentByteOffset);
390         break;
391
392     case PARSEOP_DWORDMEMORY:
393         Rnode = RsDoDwordMemoryDescriptor (DescriptorTypeOp,
394                     CurrentByteOffset);
395         break;
396
397     case PARSEOP_DWORDSPACE:
398         Rnode = RsDoDwordSpaceDescriptor (DescriptorTypeOp,
399                     CurrentByteOffset);
400         break;
401
402     case PARSEOP_ENDDEPENDENTFN:
403         switch (*State)
404         {
405         case ACPI_RSTATE_NORMAL:
406             AslError (ASL_ERROR, ASL_MSG_MISSING_STARTDEPENDENT,
407                 DescriptorTypeOp, NULL);
408             break;
409
410         case ACPI_RSTATE_START_DEPENDENT:
411             AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING,
412                 DescriptorTypeOp, NULL);
413             break;
414
415         case ACPI_RSTATE_DEPENDENT_LIST:
416         default:
417             break;
418         }
419
420         *State = ACPI_RSTATE_NORMAL;
421         Rnode = RsDoEndDependentDescriptor (DescriptorTypeOp,
422                     CurrentByteOffset);
423         break;
424
425     case PARSEOP_ENDTAG:
426         Rnode = RsDoEndTagDescriptor (DescriptorTypeOp,
427                     CurrentByteOffset);
428         break;
429
430     case PARSEOP_EXTENDEDIO:
431         Rnode = RsDoExtendedIoDescriptor (DescriptorTypeOp,
432                     CurrentByteOffset);
433         break;
434
435     case PARSEOP_EXTENDEDMEMORY:
436         Rnode = RsDoExtendedMemoryDescriptor (DescriptorTypeOp,
437                     CurrentByteOffset);
438         break;
439
440     case PARSEOP_EXTENDEDSPACE:
441         Rnode = RsDoExtendedSpaceDescriptor (DescriptorTypeOp,
442                     CurrentByteOffset);
443         break;
444
445     case PARSEOP_FIXEDIO:
446         Rnode = RsDoFixedIoDescriptor (DescriptorTypeOp,
447                     CurrentByteOffset);
448         break;
449
450     case PARSEOP_INTERRUPT:
451         Rnode = RsDoInterruptDescriptor (DescriptorTypeOp,
452                     CurrentByteOffset);
453         break;
454
455     case PARSEOP_IO:
456         Rnode = RsDoIoDescriptor (DescriptorTypeOp,
457                     CurrentByteOffset);
458         break;
459
460     case PARSEOP_IRQ:
461         Rnode = RsDoIrqDescriptor (DescriptorTypeOp,
462                     CurrentByteOffset);
463         break;
464
465     case PARSEOP_IRQNOFLAGS:
466         Rnode = RsDoIrqNoFlagsDescriptor (DescriptorTypeOp,
467                     CurrentByteOffset);
468         break;
469
470     case PARSEOP_MEMORY24:
471         Rnode = RsDoMemory24Descriptor (DescriptorTypeOp,
472                     CurrentByteOffset);
473         break;
474
475     case PARSEOP_MEMORY32:
476         Rnode = RsDoMemory32Descriptor (DescriptorTypeOp,
477                     CurrentByteOffset);
478         break;
479
480     case PARSEOP_MEMORY32FIXED:
481         Rnode = RsDoMemory32FixedDescriptor (DescriptorTypeOp,
482                     CurrentByteOffset);
483         break;
484
485     case PARSEOP_QWORDIO:
486         Rnode = RsDoQwordIoDescriptor (DescriptorTypeOp,
487                     CurrentByteOffset);
488         break;
489
490     case PARSEOP_QWORDMEMORY:
491         Rnode = RsDoQwordMemoryDescriptor (DescriptorTypeOp,
492                     CurrentByteOffset);
493         break;
494
495     case PARSEOP_QWORDSPACE:
496         Rnode = RsDoQwordSpaceDescriptor (DescriptorTypeOp,
497                     CurrentByteOffset);
498         break;
499
500     case PARSEOP_REGISTER:
501         Rnode = RsDoGeneralRegisterDescriptor (DescriptorTypeOp,
502                     CurrentByteOffset);
503         break;
504
505     case PARSEOP_STARTDEPENDENTFN:
506         switch (*State)
507         {
508         case ACPI_RSTATE_START_DEPENDENT:
509             AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING,
510                 DescriptorTypeOp, NULL);
511             break;
512
513         case ACPI_RSTATE_NORMAL:
514         case ACPI_RSTATE_DEPENDENT_LIST:
515         default:
516             break;
517         }
518
519         *State = ACPI_RSTATE_START_DEPENDENT;
520         Rnode = RsDoStartDependentDescriptor (DescriptorTypeOp,
521                     CurrentByteOffset);
522         *State = ACPI_RSTATE_DEPENDENT_LIST;
523         break;
524
525     case PARSEOP_STARTDEPENDENTFN_NOPRI:
526         switch (*State)
527         {
528         case ACPI_RSTATE_START_DEPENDENT:
529             AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING,
530                 DescriptorTypeOp, NULL);
531             break;
532
533         case ACPI_RSTATE_NORMAL:
534         case ACPI_RSTATE_DEPENDENT_LIST:
535         default:
536             break;
537         }
538
539         *State = ACPI_RSTATE_START_DEPENDENT;
540         Rnode = RsDoStartDependentNoPriDescriptor (DescriptorTypeOp,
541                     CurrentByteOffset);
542         *State = ACPI_RSTATE_DEPENDENT_LIST;
543         break;
544
545     case PARSEOP_VENDORLONG:
546         Rnode = RsDoVendorLargeDescriptor (DescriptorTypeOp,
547                     CurrentByteOffset);
548         break;
549
550     case PARSEOP_VENDORSHORT:
551         Rnode = RsDoVendorSmallDescriptor (DescriptorTypeOp,
552                     CurrentByteOffset);
553         break;
554
555     case PARSEOP_WORDBUSNUMBER:
556         Rnode = RsDoWordBusNumberDescriptor (DescriptorTypeOp,
557                     CurrentByteOffset);
558         break;
559
560     case PARSEOP_WORDIO:
561         Rnode = RsDoWordIoDescriptor (DescriptorTypeOp,
562                     CurrentByteOffset);
563         break;
564
565     case PARSEOP_WORDSPACE:
566         Rnode = RsDoWordSpaceDescriptor (DescriptorTypeOp,
567                     CurrentByteOffset);
568         break;
569
570     case PARSEOP_DEFAULT_ARG:
571         /* Just ignore any of these, they are used as fillers/placeholders */
572         break;
573
574     default:
575         printf ("Unknown resource descriptor type [%s]\n",
576                     DescriptorTypeOp->Asl.ParseOpName);
577         break;
578     }
579
580     /*
581      * Mark original node as unused, but head of a resource descriptor.
582      * This allows the resource to be installed in the namespace so that
583      * references to the descriptor can be resolved.
584      */
585     DescriptorTypeOp->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
586     DescriptorTypeOp->Asl.CompileFlags = NODE_IS_RESOURCE_DESC;
587     DescriptorTypeOp->Asl.Value.Integer = CurrentByteOffset;
588
589     if (Rnode)
590     {
591         DescriptorTypeOp->Asl.FinalAmlLength = Rnode->BufferLength;
592     }
593
594     return (Rnode);
595 }
596
597
598 /*******************************************************************************
599  *
600  * FUNCTION:    RsLinkDescriptorChain
601  *
602  * PARAMETERS:  PreviousRnode       - Pointer to the node that will be previous
603  *                                    to the linked node,  At exit, set to the
604  *                                    last node in the new chain.
605  *              Rnode               - Resource node to link into the list
606  *
607  * RETURN:      Cumulative buffer byte offset of the new segment of chain
608  *
609  * DESCRIPTION: Link a descriptor chain at the end of an existing chain.
610  *
611  ******************************************************************************/
612
613 UINT32
614 RsLinkDescriptorChain (
615     ASL_RESOURCE_NODE       **PreviousRnode,
616     ASL_RESOURCE_NODE       *Rnode)
617 {
618     ASL_RESOURCE_NODE       *LastRnode;
619     UINT32                  CurrentByteOffset;
620
621
622     /* Anything to do? */
623
624     if (!Rnode)
625     {
626         return 0;
627     }
628
629     /* Point the previous node to the new node */
630
631     (*PreviousRnode)->Next = Rnode;
632     CurrentByteOffset = Rnode->BufferLength;
633
634     /* Walk to the end of the chain headed by Rnode */
635
636     LastRnode = Rnode;
637     while (LastRnode->Next)
638     {
639         LastRnode = LastRnode->Next;
640         CurrentByteOffset += LastRnode->BufferLength;
641     }
642
643     /* Previous node becomes the last node in the chain */
644
645     *PreviousRnode = LastRnode;
646     return CurrentByteOffset;
647 }
648
649
650 /*******************************************************************************
651  *
652  * FUNCTION:    RsDoResourceTemplate
653  *
654  * PARAMETERS:  Op        - Parent of a resource template list
655  *
656  * RETURN:      None.  Sets input node to point to a list of AML code
657  *
658  * DESCRIPTION: Merge a list of resource descriptors into a single AML buffer,
659  *              in preparation for output to the AML output file.
660  *
661  ******************************************************************************/
662
663 void
664 RsDoResourceTemplate (
665     ACPI_PARSE_OBJECT       *Op)
666 {
667     ACPI_PARSE_OBJECT       *BufferLengthOp;
668     ACPI_PARSE_OBJECT       *BufferOp;
669     ACPI_PARSE_OBJECT       *DescriptorTypeOp;
670     ACPI_PARSE_OBJECT       *LastOp = NULL;
671     UINT32                  CurrentByteOffset = 0;
672     ASL_RESOURCE_NODE       HeadRnode;
673     ASL_RESOURCE_NODE       *PreviousRnode;
674     ASL_RESOURCE_NODE       *Rnode;
675     UINT8                   State;
676
677
678     /* Mark parent as containing a resource template */
679
680     if (Op->Asl.Parent)
681     {
682         Op->Asl.Parent->Asl.CompileFlags |= NODE_IS_RESOURCE_DESC;
683     }
684
685     /* ResourceTemplate Opcode is first (Op) */
686     /* Buffer Length node is first child */
687
688     BufferLengthOp = ASL_GET_CHILD_NODE (Op);
689
690     /* Buffer Op is first peer */
691
692     BufferOp = ASL_GET_PEER_NODE (BufferLengthOp);
693
694     /* First Descriptor type is next */
695
696     DescriptorTypeOp = ASL_GET_PEER_NODE (BufferOp);
697
698     /*
699      * Process all resource descriptors in the list
700      * Note: It is assumed that the EndTag node has been automatically
701      * inserted at the end of the template by the parser.
702      */
703     State = ACPI_RSTATE_NORMAL;
704     PreviousRnode = &HeadRnode;
705     while (DescriptorTypeOp)
706     {
707         DescriptorTypeOp->Asl.CompileFlags |= NODE_IS_RESOURCE_DESC;
708         Rnode = RsDoOneResourceDescriptor (DescriptorTypeOp, CurrentByteOffset,
709                     &State);
710
711         /*
712          * Update current byte offset to indicate the number of bytes from the
713          * start of the buffer.  Buffer can include multiple descriptors, we
714          * must keep track of the offset of not only each descriptor, but each
715          * element (field) within each descriptor as well.
716          */
717         CurrentByteOffset += RsLinkDescriptorChain (&PreviousRnode, Rnode);
718
719         /* Get the next descriptor in the list */
720
721         LastOp = DescriptorTypeOp;
722         DescriptorTypeOp = ASL_GET_PEER_NODE (DescriptorTypeOp);
723     }
724
725     if (State == ACPI_RSTATE_DEPENDENT_LIST)
726     {
727         if (LastOp)
728         {
729             LastOp = LastOp->Asl.Parent;
730         }
731         AslError (ASL_ERROR, ASL_MSG_MISSING_ENDDEPENDENT, LastOp, NULL);
732     }
733
734     /*
735      * Transform the nodes into the following
736      *
737      * Op           -> AML_BUFFER_OP
738      * First Child  -> BufferLength
739      * Second Child -> Descriptor Buffer (raw byte data)
740      */
741     Op->Asl.ParseOpcode               = PARSEOP_BUFFER;
742     Op->Asl.AmlOpcode                 = AML_BUFFER_OP;
743     Op->Asl.CompileFlags              = NODE_AML_PACKAGE | NODE_IS_RESOURCE_DESC;
744
745     BufferLengthOp->Asl.ParseOpcode   = PARSEOP_INTEGER;
746     BufferLengthOp->Asl.Value.Integer = CurrentByteOffset;
747     (void) OpcSetOptimalIntegerSize (BufferLengthOp);
748
749     BufferOp->Asl.ParseOpcode         = PARSEOP_RAW_DATA;
750     BufferOp->Asl.AmlOpcode           = AML_RAW_DATA_CHAIN;
751     BufferOp->Asl.AmlOpcodeLength     = 0;
752     BufferOp->Asl.AmlLength           = CurrentByteOffset;
753     BufferOp->Asl.Value.Buffer        = (UINT8 *) HeadRnode.Next;
754     BufferOp->Asl.CompileFlags       |= NODE_IS_RESOURCE_DATA;
755
756     return;
757 }
758
759