]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/acpica/lib-acpi/src/acpica/compiler/asloperands.c
update
[l4.git] / l4 / pkg / acpica / lib-acpi / src / acpica / compiler / asloperands.c
1 /******************************************************************************
2  *
3  * Module Name: asloperands - AML operand processing
4  *
5  *****************************************************************************/
6
7 /******************************************************************************
8  *
9  * 1. Copyright Notice
10  *
11  * Some or all of this work - Copyright (c) 1999 - 2012, Intel Corp.
12  * All rights reserved.
13  *
14  * 2. License
15  *
16  * 2.1. This is your license from Intel Corp. under its intellectual property
17  * rights. You may have additional license terms from the party that provided
18  * you this software, covering your right to use that party's intellectual
19  * property rights.
20  *
21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22  * copy of the source code appearing in this file ("Covered Code") an
23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24  * base code distributed originally by Intel ("Original Intel Code") to copy,
25  * make derivatives, distribute, use and display any portion of the Covered
26  * Code in any form, with the right to sublicense such rights; and
27  *
28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29  * license (with the right to sublicense), under only those claims of Intel
30  * patents that are infringed by the Original Intel Code, to make, use, sell,
31  * offer to sell, and import the Covered Code and derivative works thereof
32  * solely to the minimum extent necessary to exercise the above copyright
33  * license, and in no event shall the patent license extend to any additions
34  * to or modifications of the Original Intel Code. No other license or right
35  * is granted directly or by implication, estoppel or otherwise;
36  *
37  * The above copyright and patent license is granted only if the following
38  * conditions are met:
39  *
40  * 3. Conditions
41  *
42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43  * Redistribution of source code of any substantial portion of the Covered
44  * Code or modification with rights to further distribute source must include
45  * the above Copyright Notice, the above License, this list of Conditions,
46  * and the following Disclaimer and Export Compliance provision. In addition,
47  * Licensee must cause all Covered Code to which Licensee contributes to
48  * contain a file documenting the changes Licensee made to create that Covered
49  * Code and the date of any change. Licensee must include in that file the
50  * documentation of any changes made by any predecessor Licensee. Licensee
51  * must include a prominent statement that the modification is derived,
52  * directly or indirectly, from Original Intel Code.
53  *
54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55  * Redistribution of source code of any substantial portion of the Covered
56  * Code or modification without rights to further distribute source must
57  * include the following Disclaimer and Export Compliance provision in the
58  * documentation and/or other materials provided with distribution. In
59  * addition, Licensee may not authorize further sublicense of source of any
60  * portion of the Covered Code, and must include terms to the effect that the
61  * license from Licensee to its licensee is limited to the intellectual
62  * property embodied in the software Licensee provides to its licensee, and
63  * not to intellectual property embodied in modifications its licensee may
64  * make.
65  *
66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
67  * substantial portion of the Covered Code or modification must reproduce the
68  * above Copyright Notice, and the following Disclaimer and Export Compliance
69  * provision in the documentation and/or other materials provided with the
70  * distribution.
71  *
72  * 3.4. Intel retains all right, title, and interest in and to the Original
73  * Intel Code.
74  *
75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76  * Intel shall be used in advertising or otherwise to promote the sale, use or
77  * other dealings in products derived from or relating to the Covered Code
78  * without prior written authorization from Intel.
79  *
80  * 4. Disclaimer and Export Compliance
81  *
82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88  * PARTICULAR PURPOSE.
89  *
90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97  * LIMITED REMEDY.
98  *
99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
100  * software or system incorporating such software without first obtaining any
101  * required license or other approval from the U. S. Department of Commerce or
102  * any other agency or department of the United States Government. In the
103  * event Licensee exports any such software from the United States or
104  * re-exports any such software from a foreign destination, Licensee shall
105  * ensure that the distribution and export/re-export of the software is in
106  * compliance with all laws, regulations, orders, or other restrictions of the
107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108  * any of its subsidiaries will export/re-export any technical data, process,
109  * software, or service, directly or indirectly, to any country for which the
110  * United States government or any agency thereof requires an export license,
111  * other governmental approval, or letter of assurance, without first obtaining
112  * such license, approval or letter.
113  *
114  *****************************************************************************/
115
116
117 #include "aslcompiler.h"
118 #include "aslcompiler.y.h"
119 #include "amlcode.h"
120
121 #define _COMPONENT          ACPI_COMPILER
122         ACPI_MODULE_NAME    ("asloperands")
123
124 /* Local prototypes */
125
126 static void
127 OpnDoField (
128     ACPI_PARSE_OBJECT       *Op);
129
130 static void
131 OpnDoBankField (
132     ACPI_PARSE_OBJECT       *Op);
133
134 static void
135 OpnDoBuffer (
136     ACPI_PARSE_OBJECT       *Op);
137
138 static void
139 OpnDoDefinitionBlock (
140     ACPI_PARSE_OBJECT       *Op);
141
142 static void
143 OpnDoFieldCommon (
144     ACPI_PARSE_OBJECT       *FieldOp,
145     ACPI_PARSE_OBJECT       *Op);
146
147 static void
148 OpnDoIndexField (
149     ACPI_PARSE_OBJECT       *Op);
150
151 static void
152 OpnDoLoadTable (
153     ACPI_PARSE_OBJECT       *Op);
154
155 static void
156 OpnDoMethod (
157     ACPI_PARSE_OBJECT       *Op);
158
159 static void
160 OpnDoMutex (
161     ACPI_PARSE_OBJECT       *Op);
162
163 static void
164 OpnDoRegion (
165     ACPI_PARSE_OBJECT       *Op);
166
167 static void
168 OpnAttachNameToNode (
169     ACPI_PARSE_OBJECT       *Op);
170
171
172 /*******************************************************************************
173  *
174  * FUNCTION:    OpnDoMutex
175  *
176  * PARAMETERS:  Op        - The parent parse node
177  *
178  * RETURN:      None
179  *
180  * DESCRIPTION: Construct the operands for the MUTEX ASL keyword.
181  *
182  ******************************************************************************/
183
184 static void
185 OpnDoMutex (
186     ACPI_PARSE_OBJECT       *Op)
187 {
188     ACPI_PARSE_OBJECT       *Next;
189
190
191     Next = Op->Asl.Child;
192     Next = Next->Asl.Next;
193
194     if (Next->Asl.Value.Integer > 15)
195     {
196         AslError (ASL_ERROR, ASL_MSG_SYNC_LEVEL, Next, NULL);
197     }
198     return;
199 }
200
201
202 /*******************************************************************************
203  *
204  * FUNCTION:    OpnDoMethod
205  *
206  * PARAMETERS:  Op        - The parent parse node
207  *
208  * RETURN:      None
209  *
210  * DESCRIPTION: Construct the operands for the METHOD ASL keyword.
211  *
212  ******************************************************************************/
213
214 static void
215 OpnDoMethod (
216     ACPI_PARSE_OBJECT       *Op)
217 {
218     ACPI_PARSE_OBJECT       *Next;
219
220     /* Optional arguments for this opcode with defaults */
221
222     UINT8                   NumArgs = 0;
223     UINT8                   Serialized = 0;
224     UINT8                   Concurrency = 0;
225     UINT8                   MethodFlags;
226
227
228     /* Opcode and package length first */
229     /* Method name */
230
231     Next = Op->Asl.Child;
232
233     /* Num args */
234
235     Next = Next->Asl.Next;
236     if (Next->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
237     {
238         NumArgs = (UINT8) Next->Asl.Value.Integer;
239         Next->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
240     }
241
242     /* Serialized Flag */
243
244     Next = Next->Asl.Next;
245     if (Next->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
246     {
247         Serialized = (UINT8) Next->Asl.Value.Integer;
248         Next->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
249     }
250
251     /* Concurrency value (valid values are 0-15) */
252
253     Next = Next->Asl.Next;
254     if (Next->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
255     {
256         /* This is a ByteConstExpr, so eval the constant now */
257
258         OpcAmlConstantWalk (Next, 0, NULL);
259
260         if (Next->Asl.Value.Integer > 15)
261         {
262             AslError (ASL_ERROR, ASL_MSG_SYNC_LEVEL, Next, NULL);
263         }
264         Concurrency = (UINT8) Next->Asl.Value.Integer;
265     }
266
267     /* Put the bits in their proper places */
268
269     MethodFlags = (UINT8) ((NumArgs & 0x7) |
270                           ((Serialized & 0x1) << 3) |
271                           ((Concurrency & 0xF) << 4));
272
273     /* Use the last node for the combined flags byte */
274
275     Next->Asl.Value.Integer = MethodFlags;
276     Next->Asl.AmlOpcode = AML_RAW_DATA_BYTE;
277     Next->Asl.AmlLength = 1;
278     Next->Asl.ParseOpcode = PARSEOP_RAW_DATA;
279
280     /* Save the arg count in the first node */
281
282     Op->Asl.Extra = NumArgs;
283 }
284
285
286 /*******************************************************************************
287  *
288  * FUNCTION:    OpnDoFieldCommon
289  *
290  * PARAMETERS:  FieldOp       - Node for an ASL field
291  *              Op            - The parent parse node
292  *
293  * RETURN:      None
294  *
295  * DESCRIPTION: Construct the AML operands for the various field keywords,
296  *              FIELD, BANKFIELD, INDEXFIELD
297  *
298  ******************************************************************************/
299
300 static void
301 OpnDoFieldCommon (
302     ACPI_PARSE_OBJECT       *FieldOp,
303     ACPI_PARSE_OBJECT       *Op)
304 {
305     ACPI_PARSE_OBJECT       *Next;
306     ACPI_PARSE_OBJECT       *PkgLengthNode;
307     UINT32                  CurrentBitOffset;
308     UINT32                  NewBitOffset;
309     UINT8                   AccessType;
310     UINT8                   LockRule;
311     UINT8                   UpdateRule;
312     UINT8                   FieldFlags;
313     UINT32                  MinimumLength;
314
315
316     /* AccessType -- not optional, so no need to check for DEFAULT_ARG */
317
318     AccessType = (UINT8) Op->Asl.Value.Integer;
319     Op->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
320
321     /* Set the access type in the parent (field) node for use later */
322
323     FieldOp->Asl.Value.Integer = AccessType;
324
325     /* LockRule -- not optional, so no need to check for DEFAULT_ARG */
326
327     Next = Op->Asl.Next;
328     LockRule = (UINT8) Next->Asl.Value.Integer;
329     Next->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
330
331     /* UpdateRule -- not optional, so no need to check for DEFAULT_ARG */
332
333     Next = Next->Asl.Next;
334     UpdateRule = (UINT8) Next->Asl.Value.Integer;
335
336     /*
337      * Generate the flags byte. The various fields are already
338      * in the right bit position via translation from the
339      * keywords by the parser.
340      */
341     FieldFlags = (UINT8) (AccessType | LockRule | UpdateRule);
342
343     /* Use the previous node to be the FieldFlags node */
344
345     /* Set the node to RAW_DATA */
346
347     Next->Asl.Value.Integer = FieldFlags;
348     Next->Asl.AmlOpcode     = AML_RAW_DATA_BYTE;
349     Next->Asl.AmlLength     = 1;
350     Next->Asl.ParseOpcode   = PARSEOP_RAW_DATA;
351
352     /* Process the FieldUnitList */
353
354     Next = Next->Asl.Next;
355     CurrentBitOffset = 0;
356
357     while (Next)
358     {
359         /* Save the offset of this field unit */
360
361         Next->Asl.ExtraValue = CurrentBitOffset;
362
363         switch (Next->Asl.ParseOpcode)
364         {
365         case PARSEOP_ACCESSAS:
366
367             PkgLengthNode = Next->Asl.Child;
368             AccessType = (UINT8) PkgLengthNode->Asl.Value.Integer;
369
370             /* Nothing additional to do */
371             break;
372
373
374         case PARSEOP_OFFSET:
375
376             /* New offset into the field */
377
378             PkgLengthNode = Next->Asl.Child;
379             NewBitOffset = ((UINT32) PkgLengthNode->Asl.Value.Integer) * 8;
380
381             /*
382              * Examine the specified offset in relation to the
383              * current offset counter.
384              */
385             if (NewBitOffset < CurrentBitOffset)
386             {
387                 /*
388                  * Not allowed to specify a backwards offset!
389                  * Issue error and ignore this node.
390                  */
391                 AslError (ASL_ERROR, ASL_MSG_BACKWARDS_OFFSET, PkgLengthNode,
392                     NULL);
393                 Next->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
394                 PkgLengthNode->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
395             }
396             else if (NewBitOffset == CurrentBitOffset)
397             {
398                 /*
399                  * Offset is redundant; we don't need to output an
400                  * offset opcode. Just set these nodes to default
401                  */
402                 Next->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
403                 PkgLengthNode->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
404             }
405             else
406             {
407                 /*
408                  * Valid new offset - set the value to be inserted into the AML
409                  * and update the offset counter.
410                  */
411                 PkgLengthNode->Asl.Value.Integer =
412                     NewBitOffset - CurrentBitOffset;
413                 CurrentBitOffset = NewBitOffset;
414             }
415             break;
416
417
418         case PARSEOP_NAMESEG:
419         case PARSEOP_RESERVED_BYTES:
420
421             /* Named or reserved field entry */
422
423             PkgLengthNode     = Next->Asl.Child;
424             NewBitOffset      = (UINT32) PkgLengthNode->Asl.Value.Integer;
425             CurrentBitOffset += NewBitOffset;
426
427             /* Save the current AccessAs value for error checking later */
428
429             switch (AccessType)
430             {
431                 case AML_FIELD_ACCESS_ANY:
432                 case AML_FIELD_ACCESS_BYTE:
433                 case AML_FIELD_ACCESS_BUFFER:
434                 default:
435                     MinimumLength = 8;
436                     break;
437
438                 case AML_FIELD_ACCESS_WORD:
439                     MinimumLength = 16;
440                     break;
441
442                 case AML_FIELD_ACCESS_DWORD:
443                     MinimumLength = 32;
444                     break;
445
446                 case AML_FIELD_ACCESS_QWORD:
447                     MinimumLength = 64;
448                     break;
449             }
450
451             PkgLengthNode->Asl.ExtraValue = MinimumLength;
452             break;
453
454         default:
455             /* All supported field opcodes must appear above */
456             break;
457         }
458
459         /* Move on to next entry in the field list */
460
461         Next = Next->Asl.Next;
462     }
463 }
464
465
466 /*******************************************************************************
467  *
468  * FUNCTION:    OpnDoField
469  *
470  * PARAMETERS:  Op        - The parent parse node
471  *
472  * RETURN:      None
473  *
474  * DESCRIPTION: Construct the AML operands for the FIELD ASL keyword
475  *
476  ******************************************************************************/
477
478 static void
479 OpnDoField (
480     ACPI_PARSE_OBJECT       *Op)
481 {
482     ACPI_PARSE_OBJECT       *Next;
483
484
485     /* Opcode is parent node */
486     /* First child is field name */
487
488     Next = Op->Asl.Child;
489
490     /* Second child is the AccessType */
491
492     OpnDoFieldCommon (Op, Next->Asl.Next);
493 }
494
495
496 /*******************************************************************************
497  *
498  * FUNCTION:    OpnDoIndexField
499  *
500  * PARAMETERS:  Op        - The parent parse node
501  *
502  * RETURN:      None
503  *
504  * DESCRIPTION: Construct the AML operands for the INDEXFIELD ASL keyword
505  *
506  ******************************************************************************/
507
508 static void
509 OpnDoIndexField (
510     ACPI_PARSE_OBJECT       *Op)
511 {
512     ACPI_PARSE_OBJECT       *Next;
513
514
515     /* Opcode is parent node */
516     /* First child is the index name */
517
518     Next = Op->Asl.Child;
519
520     /* Second child is the data name */
521
522     Next = Next->Asl.Next;
523
524     /* Third child is the AccessType */
525
526     OpnDoFieldCommon (Op, Next->Asl.Next);
527 }
528
529
530 /*******************************************************************************
531  *
532  * FUNCTION:    OpnDoBankField
533  *
534  * PARAMETERS:  Op        - The parent parse node
535  *
536  * RETURN:      None
537  *
538  * DESCRIPTION: Construct the AML operands for the BANKFIELD ASL keyword
539  *
540  ******************************************************************************/
541
542 static void
543 OpnDoBankField (
544     ACPI_PARSE_OBJECT       *Op)
545 {
546     ACPI_PARSE_OBJECT       *Next;
547
548
549     /* Opcode is parent node */
550     /* First child is the region name */
551
552     Next = Op->Asl.Child;
553
554     /* Second child is the bank name */
555
556     Next = Next->Asl.Next;
557
558     /* Third child is the bank value */
559
560     Next = Next->Asl.Next;
561
562     /* Fourth child is the AccessType */
563
564     OpnDoFieldCommon (Op, Next->Asl.Next);
565 }
566
567
568 /*******************************************************************************
569  *
570  * FUNCTION:    OpnDoRegion
571  *
572  * PARAMETERS:  Op        - The parent parse node
573  *
574  * RETURN:      None
575  *
576  * DESCRIPTION: Tries to get the length of the region. Can only do this at
577  *              compile time if the length is a constant.
578  *
579  ******************************************************************************/
580
581 static void
582 OpnDoRegion (
583     ACPI_PARSE_OBJECT       *Op)
584 {
585     ACPI_PARSE_OBJECT       *Next;
586
587
588     /* Opcode is parent node */
589     /* First child is the region name */
590
591     Next = Op->Asl.Child;
592
593     /* Second child is the space ID*/
594
595     Next = Next->Asl.Next;
596
597     /* Third child is the region offset */
598
599     Next = Next->Asl.Next;
600
601     /* Fourth child is the region length */
602
603     Next = Next->Asl.Next;
604     if (Next->Asl.ParseOpcode == PARSEOP_INTEGER)
605     {
606         Op->Asl.Value.Integer = Next->Asl.Value.Integer;
607     }
608     else
609     {
610         Op->Asl.Value.Integer = ACPI_UINT64_MAX;
611     }
612 }
613
614
615 /*******************************************************************************
616  *
617  * FUNCTION:    OpnDoBuffer
618  *
619  * PARAMETERS:  Op        - The parent parse node
620  *
621  * RETURN:      None
622  *
623  * DESCRIPTION: Construct the AML operands for the BUFFER ASL keyword. We
624  *              build a single raw byte buffer from the initialization nodes,
625  *              each parse node contains a buffer byte.
626  *
627  ******************************************************************************/
628
629 static void
630 OpnDoBuffer (
631     ACPI_PARSE_OBJECT       *Op)
632 {
633     ACPI_PARSE_OBJECT       *InitializerOp;
634     ACPI_PARSE_OBJECT       *BufferLengthOp;
635
636     /* Optional arguments for this opcode with defaults */
637
638     UINT32                  BufferLength = 0;
639
640
641     /* Opcode and package length first */
642     /* Buffer Length is next, followed by the initializer list */
643
644     BufferLengthOp = Op->Asl.Child;
645     InitializerOp = BufferLengthOp->Asl.Next;
646
647     /*
648      * If the BufferLength is not an INTEGER or was not specified in the ASL
649      * (DEFAULT_ARG), it is a TermArg that is
650      * evaluated at run-time, and we are therefore finished.
651      */
652     if ((BufferLengthOp->Asl.ParseOpcode != PARSEOP_INTEGER) &&
653         (BufferLengthOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG))
654     {
655         return;
656     }
657
658     /*
659      * We want to count the number of items in the initializer list, because if
660      * it is larger than the buffer length, we will define the buffer size
661      * to be the size of the initializer list (as per the ACPI Specification)
662      */
663     switch (InitializerOp->Asl.ParseOpcode)
664     {
665     case PARSEOP_INTEGER:
666     case PARSEOP_BYTECONST:
667     case PARSEOP_WORDCONST:
668     case PARSEOP_DWORDCONST:
669
670         /* The peer list contains the byte list (if any...) */
671
672         while (InitializerOp)
673         {
674             /* For buffers, this is a list of raw bytes */
675
676             InitializerOp->Asl.AmlOpcode      = AML_RAW_DATA_BYTE;
677             InitializerOp->Asl.AmlLength      = 1;
678             InitializerOp->Asl.ParseOpcode    = PARSEOP_RAW_DATA;
679
680             BufferLength++;
681             InitializerOp = ASL_GET_PEER_NODE (InitializerOp);
682         }
683         break;
684
685
686     case PARSEOP_STRING_LITERAL:
687
688         /*
689          * Only one initializer, the string. Buffer must be big enough to hold
690          * the string plus the null termination byte
691          */
692         BufferLength = strlen (InitializerOp->Asl.Value.String) + 1;
693
694         InitializerOp->Asl.AmlOpcode      = AML_RAW_DATA_BUFFER;
695         InitializerOp->Asl.AmlLength      = BufferLength;
696         InitializerOp->Asl.ParseOpcode    = PARSEOP_RAW_DATA;
697         break;
698
699
700     case PARSEOP_RAW_DATA:
701
702         /* Buffer nodes are already initialized (e.g. Unicode operator) */
703         return;
704
705
706     case PARSEOP_DEFAULT_ARG:
707         break;
708
709
710     default:
711         AslError (ASL_ERROR, ASL_MSG_INVALID_OPERAND, InitializerOp,
712             "Unknown buffer initializer opcode");
713         printf ("Unknown buffer initializer opcode [%s]\n",
714                         UtGetOpName (InitializerOp->Asl.ParseOpcode));
715         return;
716     }
717
718     /* Check if initializer list is longer than the buffer length */
719
720     if (BufferLengthOp->Asl.Value.Integer > BufferLength)
721     {
722         BufferLength = (UINT32) BufferLengthOp->Asl.Value.Integer;
723     }
724
725     if (!BufferLength)
726     {
727         /* No length AND no items -- issue notice */
728
729         AslError (ASL_REMARK, ASL_MSG_BUFFER_LENGTH, BufferLengthOp, NULL);
730
731         /* But go ahead and put the buffer length of zero into the AML */
732     }
733
734     /*
735      * Just set the buffer size node to be the buffer length, regardless
736      * of whether it was previously an integer or a default_arg placeholder
737      */
738     BufferLengthOp->Asl.ParseOpcode   = PARSEOP_INTEGER;
739     BufferLengthOp->Asl.AmlOpcode     = AML_DWORD_OP;
740     BufferLengthOp->Asl.Value.Integer = BufferLength;
741
742     (void) OpcSetOptimalIntegerSize (BufferLengthOp);
743
744     /* Remaining nodes are handled via the tree walk */
745 }
746
747
748 /*******************************************************************************
749  *
750  * FUNCTION:    OpnDoPackage
751  *
752  * PARAMETERS:  Op        - The parent parse node
753  *
754  * RETURN:      None
755  *
756  * DESCRIPTION: Construct the AML operands for the PACKAGE ASL keyword. NOTE:
757  *              can only be called after constants have been folded, to ensure
758  *              that the PackageLength operand has been fully reduced.
759  *
760  ******************************************************************************/
761
762 void
763 OpnDoPackage (
764     ACPI_PARSE_OBJECT       *Op)
765 {
766     ACPI_PARSE_OBJECT       *InitializerOp;
767     ACPI_PARSE_OBJECT       *PackageLengthOp;
768     UINT32                  PackageLength = 0;
769
770
771     /* Opcode and package length first, followed by the initializer list */
772
773     PackageLengthOp = Op->Asl.Child;
774     InitializerOp = PackageLengthOp->Asl.Next;
775
776     /* Count the number of items in the initializer list */
777
778     if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
779     {
780         /* The peer list contains the byte list (if any...) */
781
782         while (InitializerOp)
783         {
784             PackageLength++;
785             InitializerOp = InitializerOp->Asl.Next;
786         }
787     }
788
789     /* If package length is a constant, compare to the initializer list */
790
791     if ((PackageLengthOp->Asl.ParseOpcode == PARSEOP_INTEGER)      ||
792         (PackageLengthOp->Asl.ParseOpcode == PARSEOP_QWORDCONST))
793     {
794         if (PackageLengthOp->Asl.Value.Integer > PackageLength)
795         {
796             /*
797              * Allow package length to be longer than the initializer
798              * list -- but if the length of initializer list is nonzero,
799              * issue a message since this is probably a coding error,
800              * even though technically legal.
801              */
802             if (PackageLength > 0)
803             {
804                 AslError (ASL_REMARK, ASL_MSG_LIST_LENGTH_SHORT,
805                     PackageLengthOp, NULL);
806             }
807
808             PackageLength = (UINT32) PackageLengthOp->Asl.Value.Integer;
809         }
810         else if (PackageLengthOp->Asl.Value.Integer < PackageLength)
811         {
812             /*
813              * The package length is smaller than the length of the
814              * initializer list. This is an error as per the ACPI spec.
815              */
816             AslError (ASL_ERROR, ASL_MSG_LIST_LENGTH_LONG,
817                 PackageLengthOp, NULL);
818         }
819     }
820
821     if (PackageLengthOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
822     {
823         /*
824          * This is the case if the PackageLength was left empty - Package()
825          * The package length becomes the length of the initializer list
826          */
827         Op->Asl.Child->Asl.ParseOpcode = PARSEOP_INTEGER;
828         Op->Asl.Child->Asl.Value.Integer = PackageLength;
829
830         /* Set the AML opcode */
831
832         (void) OpcSetOptimalIntegerSize (Op->Asl.Child);
833     }
834
835     /* If not a variable-length package, check for a zero package length */
836
837     if ((PackageLengthOp->Asl.ParseOpcode == PARSEOP_INTEGER)      ||
838         (PackageLengthOp->Asl.ParseOpcode == PARSEOP_QWORDCONST)   ||
839         (PackageLengthOp->Asl.ParseOpcode == PARSEOP_ZERO)         ||
840         (PackageLengthOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG))
841     {
842         if (!PackageLength)
843         {
844             /* No length AND no initializer list -- issue a remark */
845
846             AslError (ASL_REMARK, ASL_MSG_PACKAGE_LENGTH,
847                 PackageLengthOp, NULL);
848
849             /* But go ahead and put the buffer length of zero into the AML */
850         }
851     }
852
853     /*
854      * If the PackageLength is a constant <= 255, we can change the
855      * AML opcode from VarPackage to a simple (ACPI 1.0) Package opcode.
856      */
857     if (((Op->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER) &&
858             (Op->Asl.Child->Asl.Value.Integer <= 255))  ||
859         (Op->Asl.Child->Asl.ParseOpcode == PARSEOP_ONE) ||
860         (Op->Asl.Child->Asl.ParseOpcode == PARSEOP_ONES)||
861         (Op->Asl.Child->Asl.ParseOpcode == PARSEOP_ZERO))
862     {
863         Op->Asl.AmlOpcode = AML_PACKAGE_OP;
864         Op->Asl.ParseOpcode = PARSEOP_PACKAGE;
865
866         /*
867          * Just set the package size node to be the package length, regardless
868          * of whether it was previously an integer or a default_arg placeholder
869          */
870         PackageLengthOp->Asl.AmlOpcode = AML_RAW_DATA_BYTE;
871         PackageLengthOp->Asl.AmlLength = 1;
872         PackageLengthOp->Asl.ParseOpcode = PARSEOP_RAW_DATA;
873         PackageLengthOp->Asl.Value.Integer = PackageLength;
874     }
875
876     /* Remaining nodes are handled via the tree walk */
877 }
878
879
880 /*******************************************************************************
881  *
882  * FUNCTION:    OpnDoLoadTable
883  *
884  * PARAMETERS:  Op        - The parent parse node
885  *
886  * RETURN:      None
887  *
888  * DESCRIPTION: Construct the AML operands for the LOADTABLE ASL keyword.
889  *
890  ******************************************************************************/
891
892 static void
893 OpnDoLoadTable (
894     ACPI_PARSE_OBJECT       *Op)
895 {
896     ACPI_PARSE_OBJECT       *Next;
897
898
899     /* Opcode is parent node */
900     /* First child is the table signature */
901
902     Next = Op->Asl.Child;
903
904     /* Second child is the OEM ID*/
905
906     Next = Next->Asl.Next;
907
908     /* Third child is the OEM table ID */
909
910     Next = Next->Asl.Next;
911
912     /* Fourth child is the RootPath string */
913
914     Next = Next->Asl.Next;
915     if (Next->Asl.ParseOpcode == PARSEOP_ZERO)
916     {
917         Next->Asl.ParseOpcode    = PARSEOP_STRING_LITERAL;
918         Next->Asl.Value.String   = "\\";
919         Next->Asl.AmlLength      = 2;
920         OpcGenerateAmlOpcode (Next);
921     }
922
923 #ifdef ASL_FUTURE_IMPLEMENTATION
924
925     /* TBD: NOT IMPLEMENTED */
926     /* Fifth child is the [optional] ParameterPathString */
927     /* Sixth child is the [optional] ParameterData */
928
929     Next = Next->Asl.Next;
930     if (Next->Asl.ParseOpcode == DEFAULT_ARG)
931     {
932         Next->Asl.AmlLength = 1;
933         Next->Asl.ParseOpcode = ZERO;
934         OpcGenerateAmlOpcode (Next);
935     }
936
937
938     Next = Next->Asl.Next;
939     if (Next->Asl.ParseOpcode == DEFAULT_ARG)
940     {
941         Next->Asl.AmlLength = 1;
942         Next->Asl.ParseOpcode = ZERO;
943         OpcGenerateAmlOpcode (Next);
944     }
945 #endif
946 }
947
948
949 /*******************************************************************************
950  *
951  * FUNCTION:    OpnDoDefinitionBlock
952  *
953  * PARAMETERS:  Op        - The parent parse node
954  *
955  * RETURN:      None
956  *
957  * DESCRIPTION: Construct the AML operands for the DEFINITIONBLOCK ASL keyword
958  *
959  ******************************************************************************/
960
961 static void
962 OpnDoDefinitionBlock (
963     ACPI_PARSE_OBJECT       *Op)
964 {
965     ACPI_PARSE_OBJECT       *Child;
966     ACPI_SIZE               Length;
967     UINT32                  i;
968     char                    *Filename;
969
970
971     /*
972      * These nodes get stuffed into the table header. They are special
973      * cased when the table is written to the output file.
974      *
975      * Mark all of these nodes as non-usable so they won't get output
976      * as AML opcodes!
977      */
978
979     /* Get AML filename. Use it if non-null */
980
981     Child = Op->Asl.Child;
982     if (Child->Asl.Value.Buffer  &&
983         *Child->Asl.Value.Buffer &&
984         (Gbl_UseDefaultAmlFilename))
985     {
986         /*
987          * We will use the AML filename that is embedded in the source file
988          * for the output filename.
989          */
990         Filename = ACPI_ALLOCATE (strlen (Gbl_DirectoryPath) +
991                     strlen ((char *) Child->Asl.Value.Buffer) + 1);
992
993         /* Prepend the current directory path */
994
995         strcpy (Filename, Gbl_DirectoryPath);
996         strcat (Filename, (char *) Child->Asl.Value.Buffer);
997
998         Gbl_OutputFilenamePrefix = Filename;
999     }
1000     Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
1001
1002     /* Signature */
1003
1004     Child = Child->Asl.Next;
1005     Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
1006     if (Child->Asl.Value.String)
1007     {
1008         Gbl_TableSignature = Child->Asl.Value.String;
1009         if (ACPI_STRLEN (Gbl_TableSignature) != 4)
1010         {
1011             AslError (ASL_ERROR, ASL_MSG_TABLE_SIGNATURE, Child,
1012                 "Length not exactly 4");
1013         }
1014
1015         for (i = 0; i < 4; i++)
1016         {
1017             if (!isalnum ((int) Gbl_TableSignature[i]))
1018             {
1019                 AslError (ASL_ERROR, ASL_MSG_TABLE_SIGNATURE, Child,
1020                     "Contains non-alphanumeric characters");
1021             }
1022         }
1023     }
1024
1025     /* Revision */
1026
1027     Child = Child->Asl.Next;
1028     Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
1029     /*
1030      * We used the revision to set the integer width earlier
1031      */
1032
1033     /* OEMID */
1034
1035     Child = Child->Asl.Next;
1036     Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
1037
1038     /* OEM TableID */
1039
1040     Child = Child->Asl.Next;
1041     Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
1042     if (Child->Asl.Value.String)
1043     {
1044         Length = ACPI_STRLEN (Child->Asl.Value.String);
1045         Gbl_TableId = AcpiOsAllocate (Length + 1);
1046         ACPI_STRCPY (Gbl_TableId, Child->Asl.Value.String);
1047
1048         for (i = 0; i < Length; i++)
1049         {
1050             if (Gbl_TableId[i] == ' ')
1051             {
1052                 Gbl_TableId[i] = 0;
1053                 break;
1054             }
1055         }
1056     }
1057
1058     /* OEM Revision */
1059
1060     Child = Child->Asl.Next;
1061     Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
1062 }
1063
1064
1065 /*******************************************************************************
1066  *
1067  * FUNCTION:    UtGetArg
1068  *
1069  * PARAMETERS:  Op              - Get an argument for this op
1070  *              Argn            - Nth argument to get
1071  *
1072  * RETURN:      The argument (as an Op object). NULL if argument does not exist
1073  *
1074  * DESCRIPTION: Get the specified op's argument (peer)
1075  *
1076  ******************************************************************************/
1077
1078 ACPI_PARSE_OBJECT *
1079 UtGetArg (
1080     ACPI_PARSE_OBJECT       *Op,
1081     UINT32                  Argn)
1082 {
1083     ACPI_PARSE_OBJECT       *Arg = NULL;
1084
1085
1086     /* Get the requested argument object */
1087
1088     Arg = Op->Asl.Child;
1089     while (Arg && Argn)
1090     {
1091         Argn--;
1092         Arg = Arg->Asl.Next;
1093     }
1094
1095     return (Arg);
1096 }
1097
1098
1099 /*******************************************************************************
1100  *
1101  * FUNCTION:    OpnAttachNameToNode
1102  *
1103  * PARAMETERS:  Op        - The parent parse node
1104  *
1105  * RETURN:      None
1106  *
1107  * DESCRIPTION: For the named ASL/AML operators, get the actual name from the
1108  *              argument list and attach it to the parent node so that we
1109  *              can get to it quickly later.
1110  *
1111  ******************************************************************************/
1112
1113 static void
1114 OpnAttachNameToNode (
1115     ACPI_PARSE_OBJECT       *Op)
1116 {
1117     ACPI_PARSE_OBJECT       *Child = NULL;
1118
1119
1120     if (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL)
1121     {
1122         Child = UtGetArg (Op, 0);
1123     }
1124     else switch (Op->Asl.AmlOpcode)
1125     {
1126     case AML_DATA_REGION_OP:
1127     case AML_DEVICE_OP:
1128     case AML_EVENT_OP:
1129     case AML_METHOD_OP:
1130     case AML_MUTEX_OP:
1131     case AML_REGION_OP:
1132     case AML_POWER_RES_OP:
1133     case AML_PROCESSOR_OP:
1134     case AML_THERMAL_ZONE_OP:
1135     case AML_NAME_OP:
1136     case AML_SCOPE_OP:
1137
1138         Child = UtGetArg (Op, 0);
1139         break;
1140
1141     case AML_ALIAS_OP:
1142
1143         Child = UtGetArg (Op, 1);
1144         break;
1145
1146     case AML_CREATE_BIT_FIELD_OP:
1147     case AML_CREATE_BYTE_FIELD_OP:
1148     case AML_CREATE_WORD_FIELD_OP:
1149     case AML_CREATE_DWORD_FIELD_OP:
1150     case AML_CREATE_QWORD_FIELD_OP:
1151
1152         Child = UtGetArg (Op, 2);
1153         break;
1154
1155     case AML_CREATE_FIELD_OP:
1156
1157         Child = UtGetArg (Op, 3);
1158         break;
1159
1160     case AML_BANK_FIELD_OP:
1161     case AML_INDEX_FIELD_OP:
1162     case AML_FIELD_OP:
1163
1164         return;
1165
1166     default:
1167         return;
1168     }
1169
1170     if (Child)
1171     {
1172         UtAttachNamepathToOwner (Op, Child);
1173     }
1174 }
1175
1176
1177 /*******************************************************************************
1178  *
1179  * FUNCTION:    OpnGenerateAmlOperands
1180  *
1181  * PARAMETERS:  Op        - The parent parse node
1182  *
1183  * RETURN:      None
1184  *
1185  * DESCRIPTION: Prepare nodes to be output as AML data and operands. The more
1186  *              complex AML opcodes require processing of the child nodes
1187  *              (arguments/operands).
1188  *
1189  ******************************************************************************/
1190
1191 void
1192 OpnGenerateAmlOperands (
1193     ACPI_PARSE_OBJECT       *Op)
1194 {
1195
1196
1197     if (Op->Asl.AmlOpcode == AML_RAW_DATA_BYTE)
1198     {
1199         return;
1200     }
1201
1202     switch (Op->Asl.ParseOpcode)
1203     {
1204     case PARSEOP_DEFINITIONBLOCK:
1205         OpnDoDefinitionBlock (Op);
1206         break;
1207
1208     case PARSEOP_METHOD:
1209         OpnDoMethod (Op);
1210         break;
1211
1212     case PARSEOP_MUTEX:
1213         OpnDoMutex (Op);
1214         break;
1215
1216     case PARSEOP_FIELD:
1217         OpnDoField (Op);
1218         break;
1219
1220     case PARSEOP_INDEXFIELD:
1221         OpnDoIndexField (Op);
1222         break;
1223
1224     case PARSEOP_BANKFIELD:
1225         OpnDoBankField (Op);
1226         break;
1227
1228     case PARSEOP_BUFFER:
1229         OpnDoBuffer (Op);
1230         break;
1231
1232     case PARSEOP_LOADTABLE:
1233         OpnDoLoadTable (Op);
1234         break;
1235
1236     case PARSEOP_OPERATIONREGION:
1237         OpnDoRegion (Op);
1238         break;
1239
1240     case PARSEOP_RESOURCETEMPLATE:
1241         RsDoResourceTemplate (Op);
1242         break;
1243
1244     case PARSEOP_NAMESEG:
1245     case PARSEOP_NAMESTRING:
1246     case PARSEOP_METHODCALL:
1247     case PARSEOP_STRING_LITERAL:
1248         break;
1249
1250     default:
1251         break;
1252     }
1253
1254     /* TBD: move */
1255
1256     OpnAttachNameToNode (Op);
1257 }