aslresource.c revision 207344
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
151void
152RsSmallAddressCheck (
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
252void
253RsLargeAddressCheck (
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
401UINT16
402RsGetStringDataLength (
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
432ASL_RESOURCE_NODE *
433RsAllocateResourceNode (
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
470void
471RsCreateBitField (
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
501void
502RsCreateByteField (
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
532void
533RsSetFlagBits (
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
569ACPI_PARSE_OBJECT *
570RsCompleteNodeAndGetNext (
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
597void
598RsCheckListForDuplicates (
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
661ASL_RESOURCE_NODE *
662RsDoOneResourceDescriptor (
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
905UINT32
906RsLinkDescriptorChain (
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
955void
956RsDoResourceTemplate (
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