1 /******************************************************************************
2  *
3  * Module Name: aslopcode - AML opcode generation
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2014, Intel Corp.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions, and the following disclaimer,
16  *    without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  *    substantially similar to the "NO WARRANTY" disclaimer below
19  *    ("Disclaimer") and any redistribution must be conditioned upon
20  *    including a substantially similar Disclaimer requirement for further
21  *    binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  *    of any contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43 
44 #include "aslcompiler.h"
45 #include "aslcompiler.y.h"
46 #include "amlcode.h"
47 
48 #define _COMPONENT          ACPI_COMPILER
49         ACPI_MODULE_NAME    ("aslopcodes")
50 
51 
52 /* Local prototypes */
53 
54 static void
55 OpcDoAccessAs (
56     ACPI_PARSE_OBJECT       *Op);
57 
58 static void
59 OpcDoConnection (
60     ACPI_PARSE_OBJECT       *Op);
61 
62 static void
63 OpcDoUnicode (
64     ACPI_PARSE_OBJECT       *Op);
65 
66 static void
67 OpcDoEisaId (
68     ACPI_PARSE_OBJECT       *Op);
69 
70 static void
71 OpcDoUuId (
72     ACPI_PARSE_OBJECT       *Op);
73 
74 
75 /*******************************************************************************
76  *
77  * FUNCTION:    OpcAmlOpcodeUpdateWalk
78  *
79  * PARAMETERS:  ASL_WALK_CALLBACK
80  *
81  * RETURN:      Status
82  *
83  * DESCRIPTION: Opcode update walk, ascending callback
84  *
85  ******************************************************************************/
86 
87 ACPI_STATUS
88 OpcAmlOpcodeUpdateWalk (
89     ACPI_PARSE_OBJECT       *Op,
90     UINT32                  Level,
91     void                    *Context)
92 {
93 
94     /*
95      * Handle the Package() case where the actual opcode cannot be determined
96      * until the PackageLength operand has been folded and minimized.
97      * (PackageOp versus VarPackageOp)
98      *
99      * This is (as of ACPI 3.0) the only case where the AML opcode can change
100      * based upon the value of a parameter.
101      *
102      * The parser always inserts a VarPackage opcode, which can possibly be
103      * optimized to a Package opcode.
104      */
105     if (Op->Asl.ParseOpcode == PARSEOP_VAR_PACKAGE)
106     {
107         OpnDoPackage (Op);
108     }
109 
110     return (AE_OK);
111 }
112 
113 
114 /*******************************************************************************
115  *
116  * FUNCTION:    OpcAmlOpcodeWalk
117  *
118  * PARAMETERS:  ASL_WALK_CALLBACK
119  *
120  * RETURN:      Status
121  *
122  * DESCRIPTION: Parse tree walk to generate both the AML opcodes and the AML
123  *              operands.
124  *
125  ******************************************************************************/
126 
127 ACPI_STATUS
128 OpcAmlOpcodeWalk (
129     ACPI_PARSE_OBJECT       *Op,
130     UINT32                  Level,
131     void                    *Context)
132 {
133 
134     TotalParseNodes++;
135 
136     OpcGenerateAmlOpcode (Op);
137     OpnGenerateAmlOperands (Op);
138     return (AE_OK);
139 }
140 
141 
142 /*******************************************************************************
143  *
144  * FUNCTION:    OpcGetIntegerWidth
145  *
146  * PARAMETERS:  Op          - DEFINITION BLOCK op
147  *
148  * RETURN:      none
149  *
150  * DESCRIPTION: Extract integer width from the table revision
151  *
152  ******************************************************************************/
153 
154 void
155 OpcGetIntegerWidth (
156     ACPI_PARSE_OBJECT       *Op)
157 {
158     ACPI_PARSE_OBJECT       *Child;
159 
160 
161     if (!Op)
162     {
163         return;
164     }
165 
166     if (Gbl_RevisionOverride)
167     {
168         AcpiUtSetIntegerWidth (Gbl_RevisionOverride);
169     }
170     else
171     {
172         Child = Op->Asl.Child;
173         Child = Child->Asl.Next;
174         Child = Child->Asl.Next;
175 
176         /* Use the revision to set the integer width */
177 
178         AcpiUtSetIntegerWidth ((UINT8) Child->Asl.Value.Integer);
179     }
180 }
181 
182 
183 /*******************************************************************************
184  *
185  * FUNCTION:    OpcSetOptimalIntegerSize
186  *
187  * PARAMETERS:  Op        - A parse tree node
188  *
189  * RETURN:      Integer width, in bytes. Also sets the node AML opcode to the
190  *              optimal integer AML prefix opcode.
191  *
192  * DESCRIPTION: Determine the optimal AML encoding of an integer. All leading
193  *              zeros can be truncated to squeeze the integer into the
194  *              minimal number of AML bytes.
195  *
196  ******************************************************************************/
197 
198 UINT32
199 OpcSetOptimalIntegerSize (
200     ACPI_PARSE_OBJECT       *Op)
201 {
202 
203 #if 0
204     /*
205      * TBD: - we don't want to optimize integers in the block header, but the
206      * code below does not work correctly.
207      */
208     if (Op->Asl.Parent &&
209         Op->Asl.Parent->Asl.Parent &&
210        (Op->Asl.Parent->Asl.Parent->Asl.ParseOpcode == PARSEOP_DEFINITIONBLOCK))
211     {
212         return (0);
213     }
214 #endif
215 
216     /*
217      * Check for the special AML integers first - Zero, One, Ones.
218      * These are single-byte opcodes that are the smallest possible
219      * representation of an integer.
220      *
221      * This optimization is optional.
222      */
223     if (Gbl_IntegerOptimizationFlag)
224     {
225         switch (Op->Asl.Value.Integer)
226         {
227         case 0:
228 
229             Op->Asl.AmlOpcode = AML_ZERO_OP;
230             AslError (ASL_OPTIMIZATION, ASL_MSG_INTEGER_OPTIMIZATION,
231                 Op, "Zero");
232             return (1);
233 
234         case 1:
235 
236             Op->Asl.AmlOpcode = AML_ONE_OP;
237             AslError (ASL_OPTIMIZATION, ASL_MSG_INTEGER_OPTIMIZATION,
238                 Op, "One");
239             return (1);
240 
241         case ACPI_UINT32_MAX:
242 
243             /* Check for table integer width (32 or 64) */
244 
245             if (AcpiGbl_IntegerByteWidth == 4)
246             {
247                 Op->Asl.AmlOpcode = AML_ONES_OP;
248                 AslError (ASL_OPTIMIZATION, ASL_MSG_INTEGER_OPTIMIZATION,
249                     Op, "Ones");
250                 return (1);
251             }
252             break;
253 
254         case ACPI_UINT64_MAX:
255 
256             /* Check for table integer width (32 or 64) */
257 
258             if (AcpiGbl_IntegerByteWidth == 8)
259             {
260                 Op->Asl.AmlOpcode = AML_ONES_OP;
261                 AslError (ASL_OPTIMIZATION, ASL_MSG_INTEGER_OPTIMIZATION,
262                     Op, "Ones");
263                 return (1);
264             }
265             break;
266 
267         default:
268 
269             break;
270         }
271     }
272 
273     /* Find the best fit using the various AML integer prefixes */
274 
275     if (Op->Asl.Value.Integer <= ACPI_UINT8_MAX)
276     {
277         Op->Asl.AmlOpcode = AML_BYTE_OP;
278         return (1);
279     }
280     if (Op->Asl.Value.Integer <= ACPI_UINT16_MAX)
281     {
282         Op->Asl.AmlOpcode = AML_WORD_OP;
283         return (2);
284     }
285     if (Op->Asl.Value.Integer <= ACPI_UINT32_MAX)
286     {
287         Op->Asl.AmlOpcode = AML_DWORD_OP;
288         return (4);
289     }
290     else
291     {
292         if (AcpiGbl_IntegerByteWidth == 4)
293         {
294             AslError (ASL_WARNING, ASL_MSG_INTEGER_LENGTH,
295                 Op, NULL);
296 
297             if (!Gbl_IgnoreErrors)
298             {
299                 /* Truncate the integer to 32-bit */
300                 Op->Asl.AmlOpcode = AML_DWORD_OP;
301                 return (4);
302             }
303         }
304 
305         Op->Asl.AmlOpcode = AML_QWORD_OP;
306         return (8);
307     }
308 }
309 
310 
311 /*******************************************************************************
312  *
313  * FUNCTION:    OpcDoAccessAs
314  *
315  * PARAMETERS:  Op        - Parse node
316  *
317  * RETURN:      None
318  *
319  * DESCRIPTION: Implement the ACCESS_AS ASL keyword.
320  *
321  ******************************************************************************/
322 
323 static void
324 OpcDoAccessAs (
325     ACPI_PARSE_OBJECT       *Op)
326 {
327     ACPI_PARSE_OBJECT       *TypeOp;
328     ACPI_PARSE_OBJECT       *AttribOp;
329     ACPI_PARSE_OBJECT       *LengthOp;
330     UINT8                   Attribute;
331 
332 
333     Op->Asl.AmlOpcodeLength = 1;
334     TypeOp = Op->Asl.Child;
335 
336     /* First child is the access type */
337 
338     TypeOp->Asl.AmlOpcode = AML_RAW_DATA_BYTE;
339     TypeOp->Asl.ParseOpcode = PARSEOP_RAW_DATA;
340 
341     /* Second child is the optional access attribute */
342 
343     AttribOp = TypeOp->Asl.Next;
344     if (AttribOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
345     {
346         AttribOp->Asl.Value.Integer = 0;
347     }
348     AttribOp->Asl.AmlOpcode = AML_RAW_DATA_BYTE;
349     AttribOp->Asl.ParseOpcode = PARSEOP_RAW_DATA;
350 
351     /* Only a few AccessAttributes support AccessLength */
352 
353     Attribute = (UINT8) AttribOp->Asl.Value.Integer;
354     if ((Attribute != AML_FIELD_ATTRIB_MULTIBYTE) &&
355         (Attribute != AML_FIELD_ATTRIB_RAW_BYTES) &&
356         (Attribute != AML_FIELD_ATTRIB_RAW_PROCESS))
357     {
358         return;
359     }
360 
361     Op->Asl.AmlOpcode = AML_FIELD_EXT_ACCESS_OP;
362 
363     /*
364      * Child of Attributes is the AccessLength (required for Multibyte,
365      * RawBytes, RawProcess.)
366      */
367     LengthOp = AttribOp->Asl.Child;
368     if (!LengthOp)
369     {
370         return;
371     }
372 
373     /* TBD: probably can remove */
374 
375     if (LengthOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
376     {
377         LengthOp->Asl.Value.Integer = 16;
378     }
379 
380     LengthOp->Asl.AmlOpcode = AML_RAW_DATA_BYTE;
381     LengthOp->Asl.ParseOpcode = PARSEOP_RAW_DATA;
382 }
383 
384 
385 /*******************************************************************************
386  *
387  * FUNCTION:    OpcDoConnection
388  *
389  * PARAMETERS:  Op        - Parse node
390  *
391  * RETURN:      None
392  *
393  * DESCRIPTION: Implement the Connection ASL keyword.
394  *
395  ******************************************************************************/
396 
397 static void
398 OpcDoConnection (
399     ACPI_PARSE_OBJECT       *Op)
400 {
401     ASL_RESOURCE_NODE       *Rnode;
402     ACPI_PARSE_OBJECT       *BufferOp;
403     ACPI_PARSE_OBJECT       *BufferLengthOp;
404     ACPI_PARSE_OBJECT       *BufferDataOp;
405     UINT8                   State;
406 
407 
408     Op->Asl.AmlOpcodeLength = 1;
409 
410     if (Op->Asl.Child->Asl.AmlOpcode == AML_INT_NAMEPATH_OP)
411     {
412         return;
413     }
414 
415     BufferOp = Op->Asl.Child;
416     BufferLengthOp = BufferOp->Asl.Child;
417     BufferDataOp = BufferLengthOp->Asl.Next;
418 
419     State = ACPI_RSTATE_NORMAL;
420     Rnode = RsDoOneResourceDescriptor (BufferDataOp->Asl.Next, 0, &State);
421     if (!Rnode)
422     {
423         return; /* error */
424     }
425 
426     /*
427      * Transform the nodes into the following
428      *
429      * Op           -> AML_BUFFER_OP
430      * First Child  -> BufferLength
431      * Second Child -> Descriptor Buffer (raw byte data)
432      */
433     BufferOp->Asl.ParseOpcode         = PARSEOP_BUFFER;
434     BufferOp->Asl.AmlOpcode           = AML_BUFFER_OP;
435     BufferOp->Asl.CompileFlags        = NODE_AML_PACKAGE | NODE_IS_RESOURCE_DESC;
436     UtSetParseOpName (BufferOp);
437 
438     BufferLengthOp->Asl.ParseOpcode   = PARSEOP_INTEGER;
439     BufferLengthOp->Asl.Value.Integer = Rnode->BufferLength;
440     (void) OpcSetOptimalIntegerSize (BufferLengthOp);
441     UtSetParseOpName (BufferLengthOp);
442 
443     BufferDataOp->Asl.ParseOpcode         = PARSEOP_RAW_DATA;
444     BufferDataOp->Asl.AmlOpcode           = AML_RAW_DATA_CHAIN;
445     BufferDataOp->Asl.AmlOpcodeLength     = 0;
446     BufferDataOp->Asl.AmlLength           = Rnode->BufferLength;
447     BufferDataOp->Asl.Value.Buffer        = (UINT8 *) Rnode;
448     UtSetParseOpName (BufferDataOp);
449 }
450 
451 
452 /*******************************************************************************
453  *
454  * FUNCTION:    OpcDoUnicode
455  *
456  * PARAMETERS:  Op        - Parse node
457  *
458  * RETURN:      None
459  *
460  * DESCRIPTION: Implement the UNICODE ASL "macro".  Convert the input string
461  *              to a unicode buffer. There is no Unicode AML opcode.
462  *
463  * Note:  The Unicode string is 16 bits per character, no leading signature,
464  *        with a 16-bit terminating NULL.
465  *
466  ******************************************************************************/
467 
468 static void
469 OpcDoUnicode (
470     ACPI_PARSE_OBJECT       *Op)
471 {
472     ACPI_PARSE_OBJECT       *InitializerOp;
473     UINT32                  Length;
474     UINT32                  Count;
475     UINT32                  i;
476     UINT8                   *AsciiString;
477     UINT16                  *UnicodeString;
478     ACPI_PARSE_OBJECT       *BufferLengthOp;
479 
480 
481     /* Change op into a buffer object */
482 
483     Op->Asl.CompileFlags &= ~NODE_COMPILE_TIME_CONST;
484     Op->Asl.ParseOpcode = PARSEOP_BUFFER;
485     UtSetParseOpName (Op);
486 
487     /* Buffer Length is first, followed by the string */
488 
489     BufferLengthOp = Op->Asl.Child;
490     InitializerOp = BufferLengthOp->Asl.Next;
491 
492     AsciiString = (UINT8 *) InitializerOp->Asl.Value.String;
493 
494     /* Create a new buffer for the Unicode string */
495 
496     Count = strlen (InitializerOp->Asl.Value.String) + 1;
497     Length = Count * sizeof (UINT16);
498     UnicodeString = UtLocalCalloc (Length);
499 
500     /* Convert to Unicode string (including null terminator) */
501 
502     for (i = 0; i < Count; i++)
503     {
504         UnicodeString[i] = (UINT16) AsciiString[i];
505     }
506 
507     /*
508      * Just set the buffer size node to be the buffer length, regardless
509      * of whether it was previously an integer or a default_arg placeholder
510      */
511     BufferLengthOp->Asl.ParseOpcode   = PARSEOP_INTEGER;
512     BufferLengthOp->Asl.AmlOpcode     = AML_DWORD_OP;
513     BufferLengthOp->Asl.Value.Integer = Length;
514     UtSetParseOpName (BufferLengthOp);
515 
516     (void) OpcSetOptimalIntegerSize (BufferLengthOp);
517 
518     /* The Unicode string is a raw data buffer */
519 
520     InitializerOp->Asl.Value.Buffer   = (UINT8 *) UnicodeString;
521     InitializerOp->Asl.AmlOpcode      = AML_RAW_DATA_BUFFER;
522     InitializerOp->Asl.AmlLength      = Length;
523     InitializerOp->Asl.ParseOpcode    = PARSEOP_RAW_DATA;
524     InitializerOp->Asl.Child          = NULL;
525     UtSetParseOpName (InitializerOp);
526 }
527 
528 
529 /*******************************************************************************
530  *
531  * FUNCTION:    OpcDoEisaId
532  *
533  * PARAMETERS:  Op        - Parse node
534  *
535  * RETURN:      None
536  *
537  * DESCRIPTION: Convert a string EISA ID to numeric representation. See the
538  *              Pnp BIOS Specification for details. Here is an excerpt:
539  *
540  *              A seven character ASCII representation of the product
541  *              identifier compressed into a 32-bit identifier. The seven
542  *              character ID consists of a three character manufacturer code,
543  *              a three character hexadecimal product identifier, and a one
544  *              character hexadecimal revision number. The manufacturer code
545  *              is a 3 uppercase character code that is compressed into 3 5-bit
546  *              values as follows:
547  *                  1) Find hex ASCII value for each letter
548  *                  2) Subtract 40h from each ASCII value
549  *                  3) Retain 5 least significant bits for each letter by
550  *                     discarding upper 3 bits because they are always 0.
551  *                  4) Compressed code = concatenate 0 and the 3 5-bit values
552  *
553  *              The format of the compressed product identifier is as follows:
554  *              Byte 0: Bit 7       - Reserved (0)
555  *                      Bits 6-2:   - 1st character of compressed mfg code
556  *                      Bits 1-0    - Upper 2 bits of 2nd character of mfg code
557  *              Byte 1: Bits 7-5    - Lower 3 bits of 2nd character of mfg code
558  *                      Bits 4-0    - 3rd character of mfg code
559  *              Byte 2: Bits 7-4    - 1st hex digit of product number
560  *                      Bits 3-0    - 2nd hex digit of product number
561  *              Byte 3: Bits 7-4    - 3st hex digit of product number
562  *                      Bits 3-0    - Hex digit of the revision number
563  *
564  ******************************************************************************/
565 
566 static void
567 OpcDoEisaId (
568     ACPI_PARSE_OBJECT       *Op)
569 {
570     UINT32                  EisaId = 0;
571     UINT32                  BigEndianId;
572     char                    *InString;
573     ACPI_STATUS             Status = AE_OK;
574     UINT32                  i;
575 
576 
577     InString = (char *) Op->Asl.Value.String;
578 
579     /*
580      * The EISAID string must be exactly 7 characters and of the form
581      * "UUUXXXX" -- 3 uppercase letters and 4 hex digits (e.g., "PNP0001")
582      */
583     if (ACPI_STRLEN (InString) != 7)
584     {
585         Status = AE_BAD_PARAMETER;
586     }
587     else
588     {
589         /* Check all 7 characters for correct format */
590 
591         for (i = 0; i < 7; i++)
592         {
593             /* First 3 characters must be uppercase letters */
594 
595             if (i < 3)
596             {
597                 if (!isupper ((int) InString[i]))
598                 {
599                     Status = AE_BAD_PARAMETER;
600                 }
601             }
602 
603             /* Last 4 characters must be hex digits */
604 
605             else if (!isxdigit ((int) InString[i]))
606             {
607                 Status = AE_BAD_PARAMETER;
608             }
609         }
610     }
611 
612     if (ACPI_FAILURE (Status))
613     {
614         AslError (ASL_ERROR, ASL_MSG_INVALID_EISAID, Op, Op->Asl.Value.String);
615     }
616     else
617     {
618         /* Create ID big-endian first (bits are contiguous) */
619 
620         BigEndianId =
621             (UINT32) ((UINT8) (InString[0] - 0x40)) << 26 |
622             (UINT32) ((UINT8) (InString[1] - 0x40)) << 21 |
623             (UINT32) ((UINT8) (InString[2] - 0x40)) << 16 |
624 
625             (AcpiUtAsciiCharToHex (InString[3])) << 12 |
626             (AcpiUtAsciiCharToHex (InString[4])) << 8  |
627             (AcpiUtAsciiCharToHex (InString[5])) << 4  |
628              AcpiUtAsciiCharToHex (InString[6]);
629 
630         /* Swap to little-endian to get final ID (see function header) */
631 
632         EisaId = AcpiUtDwordByteSwap (BigEndianId);
633     }
634 
635     /*
636      * Morph the Op into an integer, regardless of whether there
637      * was an error in the EISAID string
638      */
639     Op->Asl.Value.Integer = EisaId;
640 
641     Op->Asl.CompileFlags &= ~NODE_COMPILE_TIME_CONST;
642     Op->Asl.ParseOpcode = PARSEOP_INTEGER;
643     (void) OpcSetOptimalIntegerSize (Op);
644 
645     /* Op is now an integer */
646 
647     UtSetParseOpName (Op);
648 }
649 
650 
651 /*******************************************************************************
652  *
653  * FUNCTION:    OpcDoUuId
654  *
655  * PARAMETERS:  Op        - Parse node
656  *
657  * RETURN:      None
658  *
659  * DESCRIPTION: Convert UUID string to 16-byte buffer
660  *
661  ******************************************************************************/
662 
663 static void
664 OpcDoUuId (
665     ACPI_PARSE_OBJECT       *Op)
666 {
667     char                    *InString;
668     UINT8                   *Buffer;
669     ACPI_STATUS             Status = AE_OK;
670     ACPI_PARSE_OBJECT       *NewOp;
671 
672 
673     InString = (char *) Op->Asl.Value.String;
674     Buffer = UtLocalCalloc (16);
675 
676     Status = AuValidateUuid (InString);
677     if (ACPI_FAILURE (Status))
678     {
679         AslError (ASL_ERROR, ASL_MSG_INVALID_UUID, Op, Op->Asl.Value.String);
680     }
681     else
682     {
683         AcpiUtConvertStringToUuid (InString, Buffer);
684     }
685 
686     /* Change Op to a Buffer */
687 
688     Op->Asl.ParseOpcode = PARSEOP_BUFFER;
689     Op->Common.AmlOpcode = AML_BUFFER_OP;
690 
691     /* Disable further optimization */
692 
693     Op->Asl.CompileFlags &= ~NODE_COMPILE_TIME_CONST;
694     UtSetParseOpName (Op);
695 
696     /* Child node is the buffer length */
697 
698     NewOp = TrAllocateNode (PARSEOP_INTEGER);
699 
700     NewOp->Asl.AmlOpcode     = AML_BYTE_OP;
701     NewOp->Asl.Value.Integer = 16;
702     NewOp->Asl.Parent        = Op;
703 
704     Op->Asl.Child = NewOp;
705     Op = NewOp;
706 
707     /* Peer to the child is the raw buffer data */
708 
709     NewOp = TrAllocateNode (PARSEOP_RAW_DATA);
710     NewOp->Asl.AmlOpcode     = AML_RAW_DATA_BUFFER;
711     NewOp->Asl.AmlLength     = 16;
712     NewOp->Asl.Value.String  = (char *) Buffer;
713     NewOp->Asl.Parent        = Op->Asl.Parent;
714 
715     Op->Asl.Next = NewOp;
716 }
717 
718 
719 /*******************************************************************************
720  *
721  * FUNCTION:    OpcGenerateAmlOpcode
722  *
723  * PARAMETERS:  Op        - Parse node
724  *
725  * RETURN:      None
726  *
727  * DESCRIPTION: Generate the AML opcode associated with the node and its
728  *              parse (lex/flex) keyword opcode. Essentially implements
729  *              a mapping between the parse opcodes and the actual AML opcodes.
730  *
731  ******************************************************************************/
732 
733 void
734 OpcGenerateAmlOpcode (
735     ACPI_PARSE_OBJECT       *Op)
736 {
737 
738     UINT16                  Index;
739 
740 
741     Index = (UINT16) (Op->Asl.ParseOpcode - ASL_PARSE_OPCODE_BASE);
742 
743     Op->Asl.AmlOpcode     = AslKeywordMapping[Index].AmlOpcode;
744     Op->Asl.AcpiBtype     = AslKeywordMapping[Index].AcpiBtype;
745     Op->Asl.CompileFlags |= AslKeywordMapping[Index].Flags;
746 
747     if (!Op->Asl.Value.Integer)
748     {
749         Op->Asl.Value.Integer = AslKeywordMapping[Index].Value;
750     }
751 
752     /* Special handling for some opcodes */
753 
754     switch (Op->Asl.ParseOpcode)
755     {
756     case PARSEOP_INTEGER:
757         /*
758          * Set the opcode based on the size of the integer
759          */
760         (void) OpcSetOptimalIntegerSize (Op);
761         break;
762 
763     case PARSEOP_OFFSET:
764 
765         Op->Asl.AmlOpcodeLength = 1;
766         break;
767 
768     case PARSEOP_ACCESSAS:
769 
770         OpcDoAccessAs (Op);
771         break;
772 
773     case PARSEOP_CONNECTION:
774 
775         OpcDoConnection (Op);
776         break;
777 
778     case PARSEOP_EISAID:
779 
780         OpcDoEisaId (Op);
781         break;
782 
783     case PARSEOP_TOUUID:
784 
785         OpcDoUuId (Op);
786         break;
787 
788     case PARSEOP_UNICODE:
789 
790         OpcDoUnicode (Op);
791         break;
792 
793     case PARSEOP_INCLUDE:
794 
795         Op->Asl.Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
796         Gbl_HasIncludeFiles = TRUE;
797         break;
798 
799     case PARSEOP_EXTERNAL:
800 
801         Op->Asl.Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
802         Op->Asl.Child->Asl.Next->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
803         break;
804 
805     case PARSEOP_TIMER:
806 
807         if (AcpiGbl_IntegerBitWidth == 32)
808         {
809             AslError (ASL_REMARK, ASL_MSG_TRUNCATION, Op, NULL);
810         }
811         break;
812 
813     default:
814 
815         /* Nothing to do for other opcodes */
816 
817         break;
818     }
819 
820     return;
821 }
822