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