]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - source/compiler/aslopcodes.c
Import ACPICA 20140926.
[FreeBSD/FreeBSD.git] / source / compiler / aslopcodes.c
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     ASL_RESOURCE_INFO       Info;
406     UINT8                   State;
407
408
409     Op->Asl.AmlOpcodeLength = 1;
410
411     if (Op->Asl.Child->Asl.AmlOpcode == AML_INT_NAMEPATH_OP)
412     {
413         return;
414     }
415
416     BufferOp = Op->Asl.Child;
417     BufferLengthOp = BufferOp->Asl.Child;
418     BufferDataOp = BufferLengthOp->Asl.Next;
419
420     Info.DescriptorTypeOp = BufferDataOp->Asl.Next;
421     Info.CurrentByteOffset = 0;
422     State = ACPI_RSTATE_NORMAL;
423     Rnode = RsDoOneResourceDescriptor (&Info, &State);
424     if (!Rnode)
425     {
426         return; /* error */
427     }
428
429     /*
430      * Transform the nodes into the following
431      *
432      * Op           -> AML_BUFFER_OP
433      * First Child  -> BufferLength
434      * Second Child -> Descriptor Buffer (raw byte data)
435      */
436     BufferOp->Asl.ParseOpcode         = PARSEOP_BUFFER;
437     BufferOp->Asl.AmlOpcode           = AML_BUFFER_OP;
438     BufferOp->Asl.CompileFlags        = NODE_AML_PACKAGE | NODE_IS_RESOURCE_DESC;
439     UtSetParseOpName (BufferOp);
440
441     BufferLengthOp->Asl.ParseOpcode   = PARSEOP_INTEGER;
442     BufferLengthOp->Asl.Value.Integer = Rnode->BufferLength;
443     (void) OpcSetOptimalIntegerSize (BufferLengthOp);
444     UtSetParseOpName (BufferLengthOp);
445
446     BufferDataOp->Asl.ParseOpcode         = PARSEOP_RAW_DATA;
447     BufferDataOp->Asl.AmlOpcode           = AML_RAW_DATA_CHAIN;
448     BufferDataOp->Asl.AmlOpcodeLength     = 0;
449     BufferDataOp->Asl.AmlLength           = Rnode->BufferLength;
450     BufferDataOp->Asl.Value.Buffer        = (UINT8 *) Rnode;
451     UtSetParseOpName (BufferDataOp);
452 }
453
454
455 /*******************************************************************************
456  *
457  * FUNCTION:    OpcDoUnicode
458  *
459  * PARAMETERS:  Op        - Parse node
460  *
461  * RETURN:      None
462  *
463  * DESCRIPTION: Implement the UNICODE ASL "macro".  Convert the input string
464  *              to a unicode buffer. There is no Unicode AML opcode.
465  *
466  * Note:  The Unicode string is 16 bits per character, no leading signature,
467  *        with a 16-bit terminating NULL.
468  *
469  ******************************************************************************/
470
471 static void
472 OpcDoUnicode (
473     ACPI_PARSE_OBJECT       *Op)
474 {
475     ACPI_PARSE_OBJECT       *InitializerOp;
476     UINT32                  Length;
477     UINT32                  Count;
478     UINT32                  i;
479     UINT8                   *AsciiString;
480     UINT16                  *UnicodeString;
481     ACPI_PARSE_OBJECT       *BufferLengthOp;
482
483
484     /* Change op into a buffer object */
485
486     Op->Asl.CompileFlags &= ~NODE_COMPILE_TIME_CONST;
487     Op->Asl.ParseOpcode = PARSEOP_BUFFER;
488     UtSetParseOpName (Op);
489
490     /* Buffer Length is first, followed by the string */
491
492     BufferLengthOp = Op->Asl.Child;
493     InitializerOp = BufferLengthOp->Asl.Next;
494
495     AsciiString = (UINT8 *) InitializerOp->Asl.Value.String;
496
497     /* Create a new buffer for the Unicode string */
498
499     Count = strlen (InitializerOp->Asl.Value.String) + 1;
500     Length = Count * sizeof (UINT16);
501     UnicodeString = UtLocalCalloc (Length);
502
503     /* Convert to Unicode string (including null terminator) */
504
505     for (i = 0; i < Count; i++)
506     {
507         UnicodeString[i] = (UINT16) AsciiString[i];
508     }
509
510     /*
511      * Just set the buffer size node to be the buffer length, regardless
512      * of whether it was previously an integer or a default_arg placeholder
513      */
514     BufferLengthOp->Asl.ParseOpcode   = PARSEOP_INTEGER;
515     BufferLengthOp->Asl.AmlOpcode     = AML_DWORD_OP;
516     BufferLengthOp->Asl.Value.Integer = Length;
517     UtSetParseOpName (BufferLengthOp);
518
519     (void) OpcSetOptimalIntegerSize (BufferLengthOp);
520
521     /* The Unicode string is a raw data buffer */
522
523     InitializerOp->Asl.Value.Buffer   = (UINT8 *) UnicodeString;
524     InitializerOp->Asl.AmlOpcode      = AML_RAW_DATA_BUFFER;
525     InitializerOp->Asl.AmlLength      = Length;
526     InitializerOp->Asl.ParseOpcode    = PARSEOP_RAW_DATA;
527     InitializerOp->Asl.Child          = NULL;
528     UtSetParseOpName (InitializerOp);
529 }
530
531
532 /*******************************************************************************
533  *
534  * FUNCTION:    OpcDoEisaId
535  *
536  * PARAMETERS:  Op        - Parse node
537  *
538  * RETURN:      None
539  *
540  * DESCRIPTION: Convert a string EISA ID to numeric representation. See the
541  *              Pnp BIOS Specification for details. Here is an excerpt:
542  *
543  *              A seven character ASCII representation of the product
544  *              identifier compressed into a 32-bit identifier. The seven
545  *              character ID consists of a three character manufacturer code,
546  *              a three character hexadecimal product identifier, and a one
547  *              character hexadecimal revision number. The manufacturer code
548  *              is a 3 uppercase character code that is compressed into 3 5-bit
549  *              values as follows:
550  *                  1) Find hex ASCII value for each letter
551  *                  2) Subtract 40h from each ASCII value
552  *                  3) Retain 5 least significant bits for each letter by
553  *                     discarding upper 3 bits because they are always 0.
554  *                  4) Compressed code = concatenate 0 and the 3 5-bit values
555  *
556  *              The format of the compressed product identifier is as follows:
557  *              Byte 0: Bit 7       - Reserved (0)
558  *                      Bits 6-2:   - 1st character of compressed mfg code
559  *                      Bits 1-0    - Upper 2 bits of 2nd character of mfg code
560  *              Byte 1: Bits 7-5    - Lower 3 bits of 2nd character of mfg code
561  *                      Bits 4-0    - 3rd character of mfg code
562  *              Byte 2: Bits 7-4    - 1st hex digit of product number
563  *                      Bits 3-0    - 2nd hex digit of product number
564  *              Byte 3: Bits 7-4    - 3st hex digit of product number
565  *                      Bits 3-0    - Hex digit of the revision number
566  *
567  ******************************************************************************/
568
569 static void
570 OpcDoEisaId (
571     ACPI_PARSE_OBJECT       *Op)
572 {
573     UINT32                  EisaId = 0;
574     UINT32                  BigEndianId;
575     char                    *InString;
576     ACPI_STATUS             Status = AE_OK;
577     UINT32                  i;
578
579
580     InString = (char *) Op->Asl.Value.String;
581
582     /*
583      * The EISAID string must be exactly 7 characters and of the form
584      * "UUUXXXX" -- 3 uppercase letters and 4 hex digits (e.g., "PNP0001")
585      */
586     if (ACPI_STRLEN (InString) != 7)
587     {
588         Status = AE_BAD_PARAMETER;
589     }
590     else
591     {
592         /* Check all 7 characters for correct format */
593
594         for (i = 0; i < 7; i++)
595         {
596             /* First 3 characters must be uppercase letters */
597
598             if (i < 3)
599             {
600                 if (!isupper ((int) InString[i]))
601                 {
602                     Status = AE_BAD_PARAMETER;
603                 }
604             }
605
606             /* Last 4 characters must be hex digits */
607
608             else if (!isxdigit ((int) InString[i]))
609             {
610                 Status = AE_BAD_PARAMETER;
611             }
612         }
613     }
614
615     if (ACPI_FAILURE (Status))
616     {
617         AslError (ASL_ERROR, ASL_MSG_INVALID_EISAID, Op, Op->Asl.Value.String);
618     }
619     else
620     {
621         /* Create ID big-endian first (bits are contiguous) */
622
623         BigEndianId =
624             (UINT32) ((UINT8) (InString[0] - 0x40)) << 26 |
625             (UINT32) ((UINT8) (InString[1] - 0x40)) << 21 |
626             (UINT32) ((UINT8) (InString[2] - 0x40)) << 16 |
627
628             (AcpiUtAsciiCharToHex (InString[3])) << 12 |
629             (AcpiUtAsciiCharToHex (InString[4])) << 8  |
630             (AcpiUtAsciiCharToHex (InString[5])) << 4  |
631              AcpiUtAsciiCharToHex (InString[6]);
632
633         /* Swap to little-endian to get final ID (see function header) */
634
635         EisaId = AcpiUtDwordByteSwap (BigEndianId);
636     }
637
638     /*
639      * Morph the Op into an integer, regardless of whether there
640      * was an error in the EISAID string
641      */
642     Op->Asl.Value.Integer = EisaId;
643
644     Op->Asl.CompileFlags &= ~NODE_COMPILE_TIME_CONST;
645     Op->Asl.ParseOpcode = PARSEOP_INTEGER;
646     (void) OpcSetOptimalIntegerSize (Op);
647
648     /* Op is now an integer */
649
650     UtSetParseOpName (Op);
651 }
652
653
654 /*******************************************************************************
655  *
656  * FUNCTION:    OpcDoUuId
657  *
658  * PARAMETERS:  Op        - Parse node
659  *
660  * RETURN:      None
661  *
662  * DESCRIPTION: Convert UUID string to 16-byte buffer
663  *
664  ******************************************************************************/
665
666 static void
667 OpcDoUuId (
668     ACPI_PARSE_OBJECT       *Op)
669 {
670     char                    *InString;
671     UINT8                   *Buffer;
672     ACPI_STATUS             Status = AE_OK;
673     ACPI_PARSE_OBJECT       *NewOp;
674
675
676     InString = (char *) Op->Asl.Value.String;
677     Buffer = UtLocalCalloc (16);
678
679     Status = AuValidateUuid (InString);
680     if (ACPI_FAILURE (Status))
681     {
682         AslError (ASL_ERROR, ASL_MSG_INVALID_UUID, Op, Op->Asl.Value.String);
683     }
684     else
685     {
686         AcpiUtConvertStringToUuid (InString, Buffer);
687     }
688
689     /* Change Op to a Buffer */
690
691     Op->Asl.ParseOpcode = PARSEOP_BUFFER;
692     Op->Common.AmlOpcode = AML_BUFFER_OP;
693
694     /* Disable further optimization */
695
696     Op->Asl.CompileFlags &= ~NODE_COMPILE_TIME_CONST;
697     UtSetParseOpName (Op);
698
699     /* Child node is the buffer length */
700
701     NewOp = TrAllocateNode (PARSEOP_INTEGER);
702
703     NewOp->Asl.AmlOpcode     = AML_BYTE_OP;
704     NewOp->Asl.Value.Integer = 16;
705     NewOp->Asl.Parent        = Op;
706
707     Op->Asl.Child = NewOp;
708     Op = NewOp;
709
710     /* Peer to the child is the raw buffer data */
711
712     NewOp = TrAllocateNode (PARSEOP_RAW_DATA);
713     NewOp->Asl.AmlOpcode     = AML_RAW_DATA_BUFFER;
714     NewOp->Asl.AmlLength     = 16;
715     NewOp->Asl.Value.String  = (char *) Buffer;
716     NewOp->Asl.Parent        = Op->Asl.Parent;
717
718     Op->Asl.Next = NewOp;
719 }
720
721
722 /*******************************************************************************
723  *
724  * FUNCTION:    OpcGenerateAmlOpcode
725  *
726  * PARAMETERS:  Op        - Parse node
727  *
728  * RETURN:      None
729  *
730  * DESCRIPTION: Generate the AML opcode associated with the node and its
731  *              parse (lex/flex) keyword opcode. Essentially implements
732  *              a mapping between the parse opcodes and the actual AML opcodes.
733  *
734  ******************************************************************************/
735
736 void
737 OpcGenerateAmlOpcode (
738     ACPI_PARSE_OBJECT       *Op)
739 {
740
741     UINT16                  Index;
742
743
744     Index = (UINT16) (Op->Asl.ParseOpcode - ASL_PARSE_OPCODE_BASE);
745
746     Op->Asl.AmlOpcode     = AslKeywordMapping[Index].AmlOpcode;
747     Op->Asl.AcpiBtype     = AslKeywordMapping[Index].AcpiBtype;
748     Op->Asl.CompileFlags |= AslKeywordMapping[Index].Flags;
749
750     if (!Op->Asl.Value.Integer)
751     {
752         Op->Asl.Value.Integer = AslKeywordMapping[Index].Value;
753     }
754
755     /* Special handling for some opcodes */
756
757     switch (Op->Asl.ParseOpcode)
758     {
759     case PARSEOP_INTEGER:
760         /*
761          * Set the opcode based on the size of the integer
762          */
763         (void) OpcSetOptimalIntegerSize (Op);
764         break;
765
766     case PARSEOP_OFFSET:
767
768         Op->Asl.AmlOpcodeLength = 1;
769         break;
770
771     case PARSEOP_ACCESSAS:
772
773         OpcDoAccessAs (Op);
774         break;
775
776     case PARSEOP_CONNECTION:
777
778         OpcDoConnection (Op);
779         break;
780
781     case PARSEOP_EISAID:
782
783         OpcDoEisaId (Op);
784         break;
785
786     case PARSEOP_TOUUID:
787
788         OpcDoUuId (Op);
789         break;
790
791     case PARSEOP_UNICODE:
792
793         OpcDoUnicode (Op);
794         break;
795
796     case PARSEOP_INCLUDE:
797
798         Op->Asl.Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
799         Gbl_HasIncludeFiles = TRUE;
800         break;
801
802     case PARSEOP_EXTERNAL:
803
804         Op->Asl.Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
805         Op->Asl.Child->Asl.Next->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
806         break;
807
808     case PARSEOP_TIMER:
809
810         if (AcpiGbl_IntegerBitWidth == 32)
811         {
812             AslError (ASL_REMARK, ASL_MSG_TRUNCATION, Op, NULL);
813         }
814         break;
815
816     default:
817
818         /* Nothing to do for other opcodes */
819
820         break;
821     }
822
823     return;
824 }