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