Sync ACPICA with Intel's version 20150717.
[dragonfly.git] / sys / contrib / dev / acpica / source / compiler / aslopcodes.c
1 /******************************************************************************
2  *
3  * Module Name: aslopcode - AML opcode generation
4  *
5  *****************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2015, 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 OpcDoPld (
72     ACPI_PARSE_OBJECT       *Op);
73
74 static void
75 OpcDoUuId (
76     ACPI_PARSE_OBJECT       *Op);
77
78 static UINT8 *
79 OpcEncodePldBuffer (
80     ACPI_PLD_INFO           *PldInfo);
81
82
83 /* ToPld strings */
84
85 static char *AslPldPanelList[] =
86 {
87     "TOP",
88     "BOTTOM",
89     "LEFT",
90     "RIGHT",
91     "FRONT",
92     "BACK",
93     "UNKNOWN",
94     NULL
95 };
96
97 static char *AslPldVerticalPositionList[] =
98 {
99     "UPPER",
100     "CENTER",
101     "LOWER",
102     NULL
103 };
104
105 static char *AslPldHorizontalPositionList[] =
106 {
107     "LEFT",
108     "CENTER",
109     "RIGHT",
110     NULL
111 };
112
113 static char *AslPldShapeList[] =
114 {
115     "ROUND",
116     "OVAL",
117     "SQUARE",
118     "VERTICALRECTANGLE",
119     "HORIZONTALRECTANGLE",
120     "VERTICALTRAPEZOID",
121     "HORIZONTALTRAPEZOID",
122     "UNKNOWN",
123     "CHAMFERED",
124     NULL
125 };
126
127
128 /*******************************************************************************
129  *
130  * FUNCTION:    OpcAmlOpcodeUpdateWalk
131  *
132  * PARAMETERS:  ASL_WALK_CALLBACK
133  *
134  * RETURN:      Status
135  *
136  * DESCRIPTION: Opcode update walk, ascending callback
137  *
138  ******************************************************************************/
139
140 ACPI_STATUS
141 OpcAmlOpcodeUpdateWalk (
142     ACPI_PARSE_OBJECT       *Op,
143     UINT32                  Level,
144     void                    *Context)
145 {
146
147     /*
148      * Handle the Package() case where the actual opcode cannot be determined
149      * until the PackageLength operand has been folded and minimized.
150      * (PackageOp versus VarPackageOp)
151      *
152      * This is (as of ACPI 3.0) the only case where the AML opcode can change
153      * based upon the value of a parameter.
154      *
155      * The parser always inserts a VarPackage opcode, which can possibly be
156      * optimized to a Package opcode.
157      */
158     if (Op->Asl.ParseOpcode == PARSEOP_VAR_PACKAGE)
159     {
160         OpnDoPackage (Op);
161     }
162
163     return (AE_OK);
164 }
165
166
167 /*******************************************************************************
168  *
169  * FUNCTION:    OpcAmlOpcodeWalk
170  *
171  * PARAMETERS:  ASL_WALK_CALLBACK
172  *
173  * RETURN:      Status
174  *
175  * DESCRIPTION: Parse tree walk to generate both the AML opcodes and the AML
176  *              operands.
177  *
178  ******************************************************************************/
179
180 ACPI_STATUS
181 OpcAmlOpcodeWalk (
182     ACPI_PARSE_OBJECT       *Op,
183     UINT32                  Level,
184     void                    *Context)
185 {
186
187     TotalParseNodes++;
188
189     OpcGenerateAmlOpcode (Op);
190     OpnGenerateAmlOperands (Op);
191     return (AE_OK);
192 }
193
194
195 /*******************************************************************************
196  *
197  * FUNCTION:    OpcGetIntegerWidth
198  *
199  * PARAMETERS:  Op          - DEFINITION BLOCK op
200  *
201  * RETURN:      none
202  *
203  * DESCRIPTION: Extract integer width from the table revision
204  *
205  ******************************************************************************/
206
207 void
208 OpcGetIntegerWidth (
209     ACPI_PARSE_OBJECT       *Op)
210 {
211     ACPI_PARSE_OBJECT       *Child;
212
213
214     if (!Op)
215     {
216         return;
217     }
218
219     if (Gbl_RevisionOverride)
220     {
221         AcpiUtSetIntegerWidth (Gbl_RevisionOverride);
222     }
223     else
224     {
225         Child = Op->Asl.Child;
226         Child = Child->Asl.Next;
227         Child = Child->Asl.Next;
228
229         /* Use the revision to set the integer width */
230
231         AcpiUtSetIntegerWidth ((UINT8) Child->Asl.Value.Integer);
232     }
233 }
234
235
236 /*******************************************************************************
237  *
238  * FUNCTION:    OpcSetOptimalIntegerSize
239  *
240  * PARAMETERS:  Op        - A parse tree node
241  *
242  * RETURN:      Integer width, in bytes. Also sets the node AML opcode to the
243  *              optimal integer AML prefix opcode.
244  *
245  * DESCRIPTION: Determine the optimal AML encoding of an integer. All leading
246  *              zeros can be truncated to squeeze the integer into the
247  *              minimal number of AML bytes.
248  *
249  ******************************************************************************/
250
251 UINT32
252 OpcSetOptimalIntegerSize (
253     ACPI_PARSE_OBJECT       *Op)
254 {
255
256 #if 0
257     /*
258      * TBD: - we don't want to optimize integers in the block header, but the
259      * code below does not work correctly.
260      */
261     if (Op->Asl.Parent &&
262         Op->Asl.Parent->Asl.Parent &&
263        (Op->Asl.Parent->Asl.Parent->Asl.ParseOpcode == PARSEOP_DEFINITIONBLOCK))
264     {
265         return (0);
266     }
267 #endif
268
269     /*
270      * Check for the special AML integers first - Zero, One, Ones.
271      * These are single-byte opcodes that are the smallest possible
272      * representation of an integer.
273      *
274      * This optimization is optional.
275      */
276     if (Gbl_IntegerOptimizationFlag)
277     {
278         switch (Op->Asl.Value.Integer)
279         {
280         case 0:
281
282             Op->Asl.AmlOpcode = AML_ZERO_OP;
283             AslError (ASL_OPTIMIZATION, ASL_MSG_INTEGER_OPTIMIZATION,
284                 Op, "Zero");
285             return (1);
286
287         case 1:
288
289             Op->Asl.AmlOpcode = AML_ONE_OP;
290             AslError (ASL_OPTIMIZATION, ASL_MSG_INTEGER_OPTIMIZATION,
291                 Op, "One");
292             return (1);
293
294         case ACPI_UINT32_MAX:
295
296             /* Check for table integer width (32 or 64) */
297
298             if (AcpiGbl_IntegerByteWidth == 4)
299             {
300                 Op->Asl.AmlOpcode = AML_ONES_OP;
301                 AslError (ASL_OPTIMIZATION, ASL_MSG_INTEGER_OPTIMIZATION,
302                     Op, "Ones");
303                 return (1);
304             }
305             break;
306
307         case ACPI_UINT64_MAX:
308
309             /* Check for table integer width (32 or 64) */
310
311             if (AcpiGbl_IntegerByteWidth == 8)
312             {
313                 Op->Asl.AmlOpcode = AML_ONES_OP;
314                 AslError (ASL_OPTIMIZATION, ASL_MSG_INTEGER_OPTIMIZATION,
315                     Op, "Ones");
316                 return (1);
317             }
318             break;
319
320         default:
321
322             break;
323         }
324     }
325
326     /* Find the best fit using the various AML integer prefixes */
327
328     if (Op->Asl.Value.Integer <= ACPI_UINT8_MAX)
329     {
330         Op->Asl.AmlOpcode = AML_BYTE_OP;
331         return (1);
332     }
333     if (Op->Asl.Value.Integer <= ACPI_UINT16_MAX)
334     {
335         Op->Asl.AmlOpcode = AML_WORD_OP;
336         return (2);
337     }
338     if (Op->Asl.Value.Integer <= ACPI_UINT32_MAX)
339     {
340         Op->Asl.AmlOpcode = AML_DWORD_OP;
341         return (4);
342     }
343     else
344     {
345         if (AcpiGbl_IntegerByteWidth == 4)
346         {
347             AslError (ASL_WARNING, ASL_MSG_INTEGER_LENGTH,
348                 Op, NULL);
349
350             if (!Gbl_IgnoreErrors)
351             {
352                 /* Truncate the integer to 32-bit */
353                 Op->Asl.AmlOpcode = AML_DWORD_OP;
354                 return (4);
355             }
356         }
357
358         Op->Asl.AmlOpcode = AML_QWORD_OP;
359         return (8);
360     }
361 }
362
363
364 /*******************************************************************************
365  *
366  * FUNCTION:    OpcDoAccessAs
367  *
368  * PARAMETERS:  Op        - Parse node
369  *
370  * RETURN:      None
371  *
372  * DESCRIPTION: Implement the ACCESS_AS ASL keyword.
373  *
374  ******************************************************************************/
375
376 static void
377 OpcDoAccessAs (
378     ACPI_PARSE_OBJECT       *Op)
379 {
380     ACPI_PARSE_OBJECT       *TypeOp;
381     ACPI_PARSE_OBJECT       *AttribOp;
382     ACPI_PARSE_OBJECT       *LengthOp;
383     UINT8                   Attribute;
384
385
386     Op->Asl.AmlOpcodeLength = 1;
387     TypeOp = Op->Asl.Child;
388
389     /* First child is the access type */
390
391     TypeOp->Asl.AmlOpcode = AML_RAW_DATA_BYTE;
392     TypeOp->Asl.ParseOpcode = PARSEOP_RAW_DATA;
393
394     /* Second child is the optional access attribute */
395
396     AttribOp = TypeOp->Asl.Next;
397     if (AttribOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
398     {
399         AttribOp->Asl.Value.Integer = 0;
400     }
401     AttribOp->Asl.AmlOpcode = AML_RAW_DATA_BYTE;
402     AttribOp->Asl.ParseOpcode = PARSEOP_RAW_DATA;
403
404     /* Only a few AccessAttributes support AccessLength */
405
406     Attribute = (UINT8) AttribOp->Asl.Value.Integer;
407     if ((Attribute != AML_FIELD_ATTRIB_MULTIBYTE) &&
408         (Attribute != AML_FIELD_ATTRIB_RAW_BYTES) &&
409         (Attribute != AML_FIELD_ATTRIB_RAW_PROCESS))
410     {
411         return;
412     }
413
414     Op->Asl.AmlOpcode = AML_FIELD_EXT_ACCESS_OP;
415
416     /*
417      * Child of Attributes is the AccessLength (required for Multibyte,
418      * RawBytes, RawProcess.)
419      */
420     LengthOp = AttribOp->Asl.Child;
421     if (!LengthOp)
422     {
423         return;
424     }
425
426     /* TBD: probably can remove */
427
428     if (LengthOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
429     {
430         LengthOp->Asl.Value.Integer = 16;
431     }
432
433     LengthOp->Asl.AmlOpcode = AML_RAW_DATA_BYTE;
434     LengthOp->Asl.ParseOpcode = PARSEOP_RAW_DATA;
435 }
436
437
438 /*******************************************************************************
439  *
440  * FUNCTION:    OpcDoConnection
441  *
442  * PARAMETERS:  Op        - Parse node
443  *
444  * RETURN:      None
445  *
446  * DESCRIPTION: Implement the Connection ASL keyword.
447  *
448  ******************************************************************************/
449
450 static void
451 OpcDoConnection (
452     ACPI_PARSE_OBJECT       *Op)
453 {
454     ASL_RESOURCE_NODE       *Rnode;
455     ACPI_PARSE_OBJECT       *BufferOp;
456     ACPI_PARSE_OBJECT       *BufferLengthOp;
457     ACPI_PARSE_OBJECT       *BufferDataOp;
458     ASL_RESOURCE_INFO       Info;
459     UINT8                   State;
460
461
462     Op->Asl.AmlOpcodeLength = 1;
463
464     if (Op->Asl.Child->Asl.AmlOpcode == AML_INT_NAMEPATH_OP)
465     {
466         return;
467     }
468
469     BufferOp = Op->Asl.Child;
470     BufferLengthOp = BufferOp->Asl.Child;
471     BufferDataOp = BufferLengthOp->Asl.Next;
472
473     Info.DescriptorTypeOp = BufferDataOp->Asl.Next;
474     Info.CurrentByteOffset = 0;
475     State = ACPI_RSTATE_NORMAL;
476     Rnode = RsDoOneResourceDescriptor (&Info, &State);
477     if (!Rnode)
478     {
479         return; /* error */
480     }
481
482     /*
483      * Transform the nodes into the following
484      *
485      * Op           -> AML_BUFFER_OP
486      * First Child  -> BufferLength
487      * Second Child -> Descriptor Buffer (raw byte data)
488      */
489     BufferOp->Asl.ParseOpcode         = PARSEOP_BUFFER;
490     BufferOp->Asl.AmlOpcode           = AML_BUFFER_OP;
491     BufferOp->Asl.CompileFlags        = NODE_AML_PACKAGE | NODE_IS_RESOURCE_DESC;
492     UtSetParseOpName (BufferOp);
493
494     BufferLengthOp->Asl.ParseOpcode   = PARSEOP_INTEGER;
495     BufferLengthOp->Asl.Value.Integer = Rnode->BufferLength;
496     (void) OpcSetOptimalIntegerSize (BufferLengthOp);
497     UtSetParseOpName (BufferLengthOp);
498
499     BufferDataOp->Asl.ParseOpcode         = PARSEOP_RAW_DATA;
500     BufferDataOp->Asl.AmlOpcode           = AML_RAW_DATA_CHAIN;
501     BufferDataOp->Asl.AmlOpcodeLength     = 0;
502     BufferDataOp->Asl.AmlLength           = Rnode->BufferLength;
503     BufferDataOp->Asl.Value.Buffer        = (UINT8 *) Rnode;
504     UtSetParseOpName (BufferDataOp);
505 }
506
507
508 /*******************************************************************************
509  *
510  * FUNCTION:    OpcDoUnicode
511  *
512  * PARAMETERS:  Op        - Parse node
513  *
514  * RETURN:      None
515  *
516  * DESCRIPTION: Implement the UNICODE ASL "macro".  Convert the input string
517  *              to a unicode buffer. There is no Unicode AML opcode.
518  *
519  * Note:  The Unicode string is 16 bits per character, no leading signature,
520  *        with a 16-bit terminating NULL.
521  *
522  ******************************************************************************/
523
524 static void
525 OpcDoUnicode (
526     ACPI_PARSE_OBJECT       *Op)
527 {
528     ACPI_PARSE_OBJECT       *InitializerOp;
529     UINT32                  Length;
530     UINT32                  Count;
531     UINT32                  i;
532     UINT8                   *AsciiString;
533     UINT16                  *UnicodeString;
534     ACPI_PARSE_OBJECT       *BufferLengthOp;
535
536
537     /* Change op into a buffer object */
538
539     Op->Asl.CompileFlags &= ~NODE_COMPILE_TIME_CONST;
540     Op->Asl.ParseOpcode = PARSEOP_BUFFER;
541     UtSetParseOpName (Op);
542
543     /* Buffer Length is first, followed by the string */
544
545     BufferLengthOp = Op->Asl.Child;
546     InitializerOp = BufferLengthOp->Asl.Next;
547
548     AsciiString = (UINT8 *) InitializerOp->Asl.Value.String;
549
550     /* Create a new buffer for the Unicode string */
551
552     Count = strlen (InitializerOp->Asl.Value.String) + 1;
553     Length = Count * sizeof (UINT16);
554     UnicodeString = UtLocalCalloc (Length);
555
556     /* Convert to Unicode string (including null terminator) */
557
558     for (i = 0; i < Count; i++)
559     {
560         UnicodeString[i] = (UINT16) AsciiString[i];
561     }
562
563     /*
564      * Just set the buffer size node to be the buffer length, regardless
565      * of whether it was previously an integer or a default_arg placeholder
566      */
567     BufferLengthOp->Asl.ParseOpcode   = PARSEOP_INTEGER;
568     BufferLengthOp->Asl.AmlOpcode     = AML_DWORD_OP;
569     BufferLengthOp->Asl.Value.Integer = Length;
570     UtSetParseOpName (BufferLengthOp);
571
572     (void) OpcSetOptimalIntegerSize (BufferLengthOp);
573
574     /* The Unicode string is a raw data buffer */
575
576     InitializerOp->Asl.Value.Buffer   = (UINT8 *) UnicodeString;
577     InitializerOp->Asl.AmlOpcode      = AML_RAW_DATA_BUFFER;
578     InitializerOp->Asl.AmlLength      = Length;
579     InitializerOp->Asl.ParseOpcode    = PARSEOP_RAW_DATA;
580     InitializerOp->Asl.Child          = NULL;
581     UtSetParseOpName (InitializerOp);
582 }
583
584
585 /*******************************************************************************
586  *
587  * FUNCTION:    OpcDoEisaId
588  *
589  * PARAMETERS:  Op        - Parse node
590  *
591  * RETURN:      None
592  *
593  * DESCRIPTION: Convert a string EISA ID to numeric representation. See the
594  *              Pnp BIOS Specification for details. Here is an excerpt:
595  *
596  *              A seven character ASCII representation of the product
597  *              identifier compressed into a 32-bit identifier. The seven
598  *              character ID consists of a three character manufacturer code,
599  *              a three character hexadecimal product identifier, and a one
600  *              character hexadecimal revision number. The manufacturer code
601  *              is a 3 uppercase character code that is compressed into 3 5-bit
602  *              values as follows:
603  *                  1) Find hex ASCII value for each letter
604  *                  2) Subtract 40h from each ASCII value
605  *                  3) Retain 5 least significant bits for each letter by
606  *                     discarding upper 3 bits because they are always 0.
607  *                  4) Compressed code = concatenate 0 and the 3 5-bit values
608  *
609  *              The format of the compressed product identifier is as follows:
610  *              Byte 0: Bit 7       - Reserved (0)
611  *                      Bits 6-2:   - 1st character of compressed mfg code
612  *                      Bits 1-0    - Upper 2 bits of 2nd character of mfg code
613  *              Byte 1: Bits 7-5    - Lower 3 bits of 2nd character of mfg code
614  *                      Bits 4-0    - 3rd character of mfg code
615  *              Byte 2: Bits 7-4    - 1st hex digit of product number
616  *                      Bits 3-0    - 2nd hex digit of product number
617  *              Byte 3: Bits 7-4    - 3st hex digit of product number
618  *                      Bits 3-0    - Hex digit of the revision number
619  *
620  ******************************************************************************/
621
622 static void
623 OpcDoEisaId (
624     ACPI_PARSE_OBJECT       *Op)
625 {
626     UINT32                  EisaId = 0;
627     UINT32                  BigEndianId;
628     char                    *InString;
629     ACPI_STATUS             Status = AE_OK;
630     UINT32                  i;
631
632
633     InString = (char *) Op->Asl.Value.String;
634
635     /*
636      * The EISAID string must be exactly 7 characters and of the form
637      * "UUUXXXX" -- 3 uppercase letters and 4 hex digits (e.g., "PNP0001")
638      */
639     if (strlen (InString) != 7)
640     {
641         Status = AE_BAD_PARAMETER;
642     }
643     else
644     {
645         /* Check all 7 characters for correct format */
646
647         for (i = 0; i < 7; i++)
648         {
649             /* First 3 characters must be uppercase letters */
650
651             if (i < 3)
652             {
653                 if (!isupper ((int) InString[i]))
654                 {
655                     Status = AE_BAD_PARAMETER;
656                 }
657             }
658
659             /* Last 4 characters must be hex digits */
660
661             else if (!isxdigit ((int) InString[i]))
662             {
663                 Status = AE_BAD_PARAMETER;
664             }
665         }
666     }
667
668     if (ACPI_FAILURE (Status))
669     {
670         AslError (ASL_ERROR, ASL_MSG_INVALID_EISAID, Op, Op->Asl.Value.String);
671     }
672     else
673     {
674         /* Create ID big-endian first (bits are contiguous) */
675
676         BigEndianId =
677             (UINT32) ((UINT8) (InString[0] - 0x40)) << 26 |
678             (UINT32) ((UINT8) (InString[1] - 0x40)) << 21 |
679             (UINT32) ((UINT8) (InString[2] - 0x40)) << 16 |
680
681             (AcpiUtAsciiCharToHex (InString[3])) << 12 |
682             (AcpiUtAsciiCharToHex (InString[4])) << 8  |
683             (AcpiUtAsciiCharToHex (InString[5])) << 4  |
684              AcpiUtAsciiCharToHex (InString[6]);
685
686         /* Swap to little-endian to get final ID (see function header) */
687
688         EisaId = AcpiUtDwordByteSwap (BigEndianId);
689     }
690
691     /*
692      * Morph the Op into an integer, regardless of whether there
693      * was an error in the EISAID string
694      */
695     Op->Asl.Value.Integer = EisaId;
696
697     Op->Asl.CompileFlags &= ~NODE_COMPILE_TIME_CONST;
698     Op->Asl.ParseOpcode = PARSEOP_INTEGER;
699     (void) OpcSetOptimalIntegerSize (Op);
700
701     /* Op is now an integer */
702
703     UtSetParseOpName (Op);
704 }
705
706
707 /*******************************************************************************
708  *
709  * FUNCTION:    OpcEncodePldBuffer
710  *
711  * PARAMETERS:  PldInfo             - _PLD buffer struct (Using local struct)
712  *
713  * RETURN:      Encode _PLD buffer suitable for return value from _PLD
714  *
715  * DESCRIPTION: Bit-packs a _PLD buffer struct.
716  *
717  ******************************************************************************/
718
719 static UINT8 *
720 OpcEncodePldBuffer (
721     ACPI_PLD_INFO           *PldInfo)
722 {
723     UINT32                  *Buffer;
724     UINT32                  Dword;
725
726
727     Buffer = ACPI_ALLOCATE_ZEROED (ACPI_PLD_BUFFER_SIZE);
728     if (!Buffer)
729     {
730         return (NULL);
731     }
732
733     /* First 32 bits */
734
735     Dword = 0;
736     ACPI_PLD_SET_REVISION       (&Dword, PldInfo->Revision);
737     ACPI_PLD_SET_IGNORE_COLOR   (&Dword, PldInfo->IgnoreColor);
738     ACPI_PLD_SET_RED            (&Dword, PldInfo->Red);
739     ACPI_PLD_SET_GREEN          (&Dword, PldInfo->Green);
740     ACPI_PLD_SET_BLUE           (&Dword, PldInfo->Blue);
741     ACPI_MOVE_32_TO_32          (&Buffer[0], &Dword);
742
743     /* Second 32 bits */
744
745     Dword = 0;
746     ACPI_PLD_SET_WIDTH          (&Dword, PldInfo->Width);
747     ACPI_PLD_SET_HEIGHT         (&Dword, PldInfo->Height);
748     ACPI_MOVE_32_TO_32          (&Buffer[1], &Dword);
749
750     /* Third 32 bits */
751
752     Dword = 0;
753     ACPI_PLD_SET_USER_VISIBLE   (&Dword, PldInfo->UserVisible);
754     ACPI_PLD_SET_DOCK           (&Dword, PldInfo->Dock);
755     ACPI_PLD_SET_LID            (&Dword, PldInfo->Lid);
756     ACPI_PLD_SET_PANEL          (&Dword, PldInfo->Panel);
757     ACPI_PLD_SET_VERTICAL       (&Dword, PldInfo->VerticalPosition);
758     ACPI_PLD_SET_HORIZONTAL     (&Dword, PldInfo->HorizontalPosition);
759     ACPI_PLD_SET_SHAPE          (&Dword, PldInfo->Shape);
760     ACPI_PLD_SET_ORIENTATION    (&Dword, PldInfo->GroupOrientation);
761     ACPI_PLD_SET_TOKEN          (&Dword, PldInfo->GroupToken);
762     ACPI_PLD_SET_POSITION       (&Dword, PldInfo->GroupPosition);
763     ACPI_PLD_SET_BAY            (&Dword, PldInfo->Bay);
764     ACPI_MOVE_32_TO_32          (&Buffer[2], &Dword);
765
766     /* Fourth 32 bits */
767
768     Dword = 0;
769     ACPI_PLD_SET_EJECTABLE      (&Dword, PldInfo->Ejectable);
770     ACPI_PLD_SET_OSPM_EJECT     (&Dword, PldInfo->OspmEjectRequired);
771     ACPI_PLD_SET_CABINET        (&Dword, PldInfo->CabinetNumber);
772     ACPI_PLD_SET_CARD_CAGE      (&Dword, PldInfo->CardCageNumber);
773     ACPI_PLD_SET_REFERENCE      (&Dword, PldInfo->Reference);
774     ACPI_PLD_SET_ROTATION       (&Dword, PldInfo->Rotation);
775     ACPI_PLD_SET_ORDER          (&Dword, PldInfo->Order);
776     ACPI_MOVE_32_TO_32          (&Buffer[3], &Dword);
777
778     if (PldInfo->Revision >= 2)
779     {
780         /* Fifth 32 bits */
781
782         Dword = 0;
783         ACPI_PLD_SET_VERT_OFFSET    (&Dword, PldInfo->VerticalOffset);
784         ACPI_PLD_SET_HORIZ_OFFSET   (&Dword, PldInfo->HorizontalOffset);
785         ACPI_MOVE_32_TO_32          (&Buffer[4], &Dword);
786     }
787
788     return (ACPI_CAST_PTR (UINT8, Buffer));
789 }
790
791
792 /*******************************************************************************
793  *
794  * FUNCTION:    OpcFindName
795  *
796  * PARAMETERS:  List                - Array of char strings to be searched
797  *              Name                - Char string to string for
798  *              Index               - Index value to set if found
799  *
800  * RETURN:      TRUE if any names matched, FALSE otherwise
801  *
802  * DESCRIPTION: Match PLD name to value in lookup table. Sets Value to
803  *              equivalent parameter value.
804  *
805  ******************************************************************************/
806
807 static BOOLEAN
808 OpcFindName (
809     char                    **List,
810     char                    *Name,
811     UINT64                  *Index)
812 {
813     char                     *Str;
814     UINT32                   i;
815
816
817     AcpiUtStrupr (Name);
818
819     for (i = 0, Str = List[0]; Str; i++, Str = List[i])
820     {
821         if (!(strncmp (Str, Name, strlen (Name))))
822         {
823             *Index = i;
824             return (TRUE);
825         }
826     }
827
828     return (FALSE);
829 }
830
831
832 /*******************************************************************************
833  *
834  * FUNCTION:    OpcDoPld
835  *
836  * PARAMETERS:  Op                  - Parse node
837  *
838  * RETURN:      None
839  *
840  * DESCRIPTION: Convert ToPLD macro to 20-byte buffer
841  *
842  ******************************************************************************/
843
844 static void
845 OpcDoPld (
846     ACPI_PARSE_OBJECT       *Op)
847 {
848     UINT8                   *Buffer;
849     ACPI_PARSE_OBJECT       *Node;
850     ACPI_PLD_INFO           PldInfo;
851     ACPI_PARSE_OBJECT       *NewOp;
852
853
854     if (!Op)
855     {
856         AslError(ASL_ERROR, ASL_MSG_NOT_EXIST, Op, NULL);
857         return;
858     }
859
860     if (Op->Asl.ParseOpcode != PARSEOP_TOPLD)
861     {
862         AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Op, NULL);
863         return;
864     }
865
866     memset (&PldInfo, 0, sizeof (ACPI_PLD_INFO));
867
868     Node = Op->Asl.Child;
869     while (Node)
870     {
871         switch (Node->Asl.ParseOpcode)
872         {
873         case PARSEOP_PLD_REVISION:
874
875             if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
876             {
877                 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
878                 break;
879             }
880
881             if (Node->Asl.Child->Asl.Value.Integer > 127)
882             {
883                 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
884                 break;
885             }
886
887             PldInfo.Revision = (UINT8) Node->Asl.Child->Asl.Value.Integer;
888             break;
889
890         case PARSEOP_PLD_IGNORECOLOR:
891
892             if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
893             {
894                 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
895                 break;
896             }
897
898             if (Node->Asl.Child->Asl.Value.Integer > 1)
899             {
900                 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
901                 break;
902             }
903
904             PldInfo.IgnoreColor = (UINT8) Node->Asl.Child->Asl.Value.Integer;
905             break;
906
907         case PARSEOP_PLD_RED:
908         case PARSEOP_PLD_GREEN:
909         case PARSEOP_PLD_BLUE:
910
911             if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
912             {
913                 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
914                 break;
915             }
916
917             if (Node->Asl.Child->Asl.Value.Integer > 255)
918             {
919                 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
920                 break;
921             }
922
923             if (Node->Asl.ParseOpcode == PARSEOP_PLD_RED)
924             {
925                 PldInfo.Red = (UINT8) Node->Asl.Child->Asl.Value.Integer;
926             }
927             else if (Node->Asl.ParseOpcode == PARSEOP_PLD_GREEN)
928             {
929                 PldInfo.Green = (UINT8) Node->Asl.Child->Asl.Value.Integer;
930             }
931             else /* PARSEOP_PLD_BLUE */
932             {
933                 PldInfo.Blue = (UINT8) Node->Asl.Child->Asl.Value.Integer;
934             }
935             break;
936
937         case PARSEOP_PLD_WIDTH:
938         case PARSEOP_PLD_HEIGHT:
939
940             if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
941             {
942                 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
943                 break;
944             }
945
946             if (Node->Asl.Child->Asl.Value.Integer > 65535)
947             {
948                 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
949                 break;
950             }
951
952             if (Node->Asl.ParseOpcode == PARSEOP_PLD_WIDTH)
953             {
954                 PldInfo.Width = (UINT16) Node->Asl.Child->Asl.Value.Integer;
955             }
956             else /* PARSEOP_PLD_HEIGHT */
957             {
958                 PldInfo.Height = (UINT16) Node->Asl.Child->Asl.Value.Integer;
959             }
960
961             break;
962
963         case PARSEOP_PLD_USERVISIBLE:
964         case PARSEOP_PLD_DOCK:
965         case PARSEOP_PLD_LID:
966
967             if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
968             {
969                 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
970                 break;
971             }
972
973             if (Node->Asl.Child->Asl.Value.Integer > 1)
974             {
975                 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
976                 break;
977             }
978
979             if (Node->Asl.ParseOpcode == PARSEOP_PLD_USERVISIBLE)
980             {
981                 PldInfo.UserVisible = (UINT8) Node->Asl.Child->Asl.Value.Integer;
982             }
983             else if (Node->Asl.ParseOpcode == PARSEOP_PLD_DOCK)
984             {
985                 PldInfo.Dock = (UINT8) Node->Asl.Child->Asl.Value.Integer;
986             }
987             else
988             {
989                 PldInfo.Lid = (UINT8) Node->Asl.Child->Asl.Value.Integer;
990             }
991
992             break;
993
994         case PARSEOP_PLD_PANEL:
995
996             if (Node->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER)
997             {
998                 if (Node->Asl.Child->Asl.Value.Integer > 6)
999                 {
1000                     AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
1001                     break;
1002                 }
1003             }
1004             else /* PARSEOP_STRING */
1005             {
1006                 if (!OpcFindName(AslPldPanelList,
1007                     Node->Asl.Child->Asl.Value.String,
1008                     &Node->Asl.Child->Asl.Value.Integer))
1009                 {
1010                     AslError(ASL_ERROR, ASL_MSG_INVALID_OPERAND, Node, NULL);
1011                     break;
1012                 }
1013             }
1014
1015             PldInfo.Panel = (UINT8) Node->Asl.Child->Asl.Value.Integer;
1016             break;
1017
1018         case PARSEOP_PLD_VERTICALPOSITION:
1019
1020             if (Node->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER)
1021             {
1022                 if (Node->Asl.Child->Asl.Value.Integer > 2)
1023                 {
1024                     AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
1025                     break;
1026                 }
1027             }
1028             else /* PARSEOP_STRING */
1029             {
1030                 if (!OpcFindName(AslPldVerticalPositionList,
1031                     Node->Asl.Child->Asl.Value.String,
1032                     &Node->Asl.Child->Asl.Value.Integer))
1033                 {
1034                     AslError(ASL_ERROR, ASL_MSG_INVALID_OPERAND, Node, NULL);
1035                     break;
1036                 }
1037             }
1038
1039             PldInfo.VerticalPosition = (UINT8) Node->Asl.Child->Asl.Value.Integer;
1040             break;
1041
1042         case PARSEOP_PLD_HORIZONTALPOSITION:
1043
1044             if (Node->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER)
1045             {
1046                 if (Node->Asl.Child->Asl.Value.Integer > 2)
1047                 {
1048                     AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
1049                     break;
1050                 }
1051             }
1052             else /* PARSEOP_STRING */
1053             {
1054                 if (!OpcFindName(AslPldHorizontalPositionList,
1055                     Node->Asl.Child->Asl.Value.String,
1056                     &Node->Asl.Child->Asl.Value.Integer))
1057                 {
1058                     AslError(ASL_ERROR, ASL_MSG_INVALID_OPERAND, Node, NULL);
1059                     break;
1060                 }
1061             }
1062
1063             PldInfo.HorizontalPosition = (UINT8) Node->Asl.Child->Asl.Value.Integer;
1064             break;
1065
1066         case PARSEOP_PLD_SHAPE:
1067
1068             if (Node->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER)
1069             {
1070                 if (Node->Asl.Child->Asl.Value.Integer > 8)
1071                 {
1072                     AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
1073                     break;
1074                 }
1075             }
1076             else /* PARSEOP_STRING */
1077             {
1078                 if (!OpcFindName(AslPldShapeList,
1079                     Node->Asl.Child->Asl.Value.String,
1080                     &Node->Asl.Child->Asl.Value.Integer))
1081                 {
1082                     AslError(ASL_ERROR, ASL_MSG_INVALID_OPERAND, Node, NULL);
1083                     break;
1084                 }
1085             }
1086
1087             PldInfo.Shape = (UINT8) Node->Asl.Child->Asl.Value.Integer;
1088             break;
1089
1090         case PARSEOP_PLD_GROUPORIENTATION:
1091
1092             if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
1093             {
1094                 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
1095                 break;
1096             }
1097
1098             if (Node->Asl.Child->Asl.Value.Integer > 1)
1099             {
1100                 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
1101                 break;
1102             }
1103
1104             PldInfo.GroupOrientation = (UINT8) Node->Asl.Child->Asl.Value.Integer;
1105             break;
1106
1107         case PARSEOP_PLD_GROUPTOKEN:
1108         case PARSEOP_PLD_GROUPPOSITION:
1109
1110             if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
1111             {
1112                 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
1113                 break;
1114             }
1115
1116             if (Node->Asl.Child->Asl.Value.Integer > 255)
1117             {
1118                 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
1119                 break;
1120             }
1121
1122
1123             if (Node->Asl.ParseOpcode == PARSEOP_PLD_GROUPTOKEN)
1124             {
1125                 PldInfo.GroupToken = (UINT8) Node->Asl.Child->Asl.Value.Integer;
1126             }
1127             else /* PARSEOP_PLD_GROUPPOSITION */
1128             {
1129                 PldInfo.GroupPosition = (UINT8) Node->Asl.Child->Asl.Value.Integer;
1130             }
1131
1132             break;
1133
1134         case PARSEOP_PLD_BAY:
1135         case PARSEOP_PLD_EJECTABLE:
1136         case PARSEOP_PLD_EJECTREQUIRED:
1137
1138             if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
1139             {
1140                 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
1141                 break;
1142             }
1143
1144             if (Node->Asl.Child->Asl.Value.Integer > 1)
1145             {
1146                 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
1147                 break;
1148             }
1149
1150             if (Node->Asl.ParseOpcode == PARSEOP_PLD_BAY)
1151             {
1152                 PldInfo.Bay = (UINT8) Node->Asl.Child->Asl.Value.Integer;
1153             }
1154             else if (Node->Asl.ParseOpcode == PARSEOP_PLD_EJECTABLE)
1155             {
1156                 PldInfo.Ejectable = (UINT8) Node->Asl.Child->Asl.Value.Integer;
1157             }
1158             else /* PARSEOP_PLD_EJECTREQUIRED */
1159             {
1160                 PldInfo.OspmEjectRequired = (UINT8) Node->Asl.Child->Asl.Value.Integer;
1161             }
1162
1163             break;
1164
1165         case PARSEOP_PLD_CABINETNUMBER:
1166         case PARSEOP_PLD_CARDCAGENUMBER:
1167
1168             if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
1169             {
1170                 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
1171                 break;
1172             }
1173
1174             if (Node->Asl.Child->Asl.Value.Integer > 255)
1175             {
1176                 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
1177                 break;
1178             }
1179
1180             if (Node->Asl.ParseOpcode == PARSEOP_PLD_CABINETNUMBER)
1181             {
1182                 PldInfo.CabinetNumber = (UINT8) Node->Asl.Child->Asl.Value.Integer;
1183             }
1184             else /* PARSEOP_PLD_CARDCAGENUMBER */
1185             {
1186                 PldInfo.CardCageNumber = (UINT8) Node->Asl.Child->Asl.Value.Integer;
1187             }
1188
1189             break;
1190
1191         case PARSEOP_PLD_REFERENCE:
1192
1193             if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
1194             {
1195                 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
1196                 break;
1197             }
1198
1199             if (Node->Asl.Child->Asl.Value.Integer > 1)
1200             {
1201                 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
1202                 break;
1203             }
1204
1205             PldInfo.Reference = (UINT8) Node->Asl.Child->Asl.Value.Integer;
1206             break;
1207
1208         case PARSEOP_PLD_ROTATION:
1209
1210             if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
1211             {
1212                 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
1213                 break;
1214             }
1215
1216             if (Node->Asl.Child->Asl.Value.Integer > 7)
1217             {
1218                 switch (Node->Asl.Child->Asl.Value.Integer)
1219                 {
1220                 case 45:
1221
1222                     Node->Asl.Child->Asl.Value.Integer = 1;
1223                     break;
1224
1225                 case 90:
1226
1227                     Node->Asl.Child->Asl.Value.Integer = 2;
1228                     break;
1229
1230                 case 135:
1231
1232                     Node->Asl.Child->Asl.Value.Integer = 3;
1233                     break;
1234
1235                 case 180:
1236
1237                     Node->Asl.Child->Asl.Value.Integer = 4;
1238                     break;
1239
1240                 case 225:
1241
1242                     Node->Asl.Child->Asl.Value.Integer = 5;
1243                     break;
1244
1245                 case 270:
1246
1247                     Node->Asl.Child->Asl.Value.Integer = 6;
1248                     break;
1249
1250                 case 315:
1251
1252                     Node->Asl.Child->Asl.Value.Integer = 7;
1253                     break;
1254
1255                 default:
1256
1257                     AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
1258                     break;
1259                 }
1260             }
1261
1262             PldInfo.Rotation = (UINT8) Node->Asl.Child->Asl.Value.Integer;
1263             break;
1264
1265         case PARSEOP_PLD_ORDER:
1266
1267             if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
1268             {
1269                 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
1270                 break;
1271             }
1272
1273             if (Node->Asl.Child->Asl.Value.Integer > 31)
1274             {
1275                 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
1276                 break;
1277             }
1278
1279             PldInfo.Order = (UINT8) Node->Asl.Child->Asl.Value.Integer;
1280             break;
1281
1282         case PARSEOP_PLD_VERTICALOFFSET:
1283         case PARSEOP_PLD_HORIZONTALOFFSET:
1284
1285             if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
1286             {
1287                 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
1288                 break;
1289             }
1290
1291             if (Node->Asl.Child->Asl.Value.Integer > 65535)
1292             {
1293                 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
1294                 break;
1295             }
1296
1297             if (Node->Asl.ParseOpcode == PARSEOP_PLD_VERTICALOFFSET)
1298             {
1299                 PldInfo.VerticalOffset = (UINT16) Node->Asl.Child->Asl.Value.Integer;
1300             }
1301             else /* PARSEOP_PLD_HORIZONTALOFFSET */
1302             {
1303                 PldInfo.HorizontalOffset = (UINT16) Node->Asl.Child->Asl.Value.Integer;
1304             }
1305
1306             break;
1307
1308         default:
1309
1310             AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
1311             break;
1312         }
1313
1314         Node = Node->Asl.Next;
1315     }
1316
1317     Buffer = OpcEncodePldBuffer(&PldInfo);
1318
1319     /* Change Op to a Buffer */
1320
1321     Op->Asl.ParseOpcode = PARSEOP_BUFFER;
1322     Op->Common.AmlOpcode = AML_BUFFER_OP;
1323
1324     /* Disable further optimization */
1325
1326     Op->Asl.CompileFlags &= ~NODE_COMPILE_TIME_CONST;
1327     UtSetParseOpName (Op);
1328
1329     /* Child node is the buffer length */
1330
1331     NewOp = TrAllocateNode (PARSEOP_INTEGER);
1332
1333     NewOp->Asl.AmlOpcode     = AML_BYTE_OP;
1334     NewOp->Asl.Value.Integer = 20;
1335     NewOp->Asl.Parent        = Op;
1336
1337     Op->Asl.Child = NewOp;
1338     Op = NewOp;
1339
1340     /* Peer to the child is the raw buffer data */
1341
1342     NewOp = TrAllocateNode (PARSEOP_RAW_DATA);
1343     NewOp->Asl.AmlOpcode     = AML_RAW_DATA_BUFFER;
1344     NewOp->Asl.AmlLength     = 20;
1345     NewOp->Asl.Value.String  = ACPI_CAST_PTR (char, Buffer);
1346     NewOp->Asl.Parent        = Op->Asl.Parent;
1347
1348     Op->Asl.Next = NewOp;
1349 }
1350
1351
1352 /*******************************************************************************
1353  *
1354  * FUNCTION:    OpcDoUuId
1355  *
1356  * PARAMETERS:  Op                  - Parse node
1357  *
1358  * RETURN:      None
1359  *
1360  * DESCRIPTION: Convert UUID string to 16-byte buffer
1361  *
1362  ******************************************************************************/
1363
1364 static void
1365 OpcDoUuId (
1366     ACPI_PARSE_OBJECT       *Op)
1367 {
1368     char                    *InString;
1369     UINT8                   *Buffer;
1370     ACPI_STATUS             Status = AE_OK;
1371     ACPI_PARSE_OBJECT       *NewOp;
1372
1373
1374     InString = ACPI_CAST_PTR (char, Op->Asl.Value.String);
1375     Buffer = UtLocalCalloc (16);
1376
1377     Status = AuValidateUuid (InString);
1378     if (ACPI_FAILURE (Status))
1379     {
1380         AslError (ASL_ERROR, ASL_MSG_INVALID_UUID, Op, Op->Asl.Value.String);
1381     }
1382     else
1383     {
1384         AcpiUtConvertStringToUuid (InString, Buffer);
1385     }
1386
1387     /* Change Op to a Buffer */
1388
1389     Op->Asl.ParseOpcode = PARSEOP_BUFFER;
1390     Op->Common.AmlOpcode = AML_BUFFER_OP;
1391
1392     /* Disable further optimization */
1393
1394     Op->Asl.CompileFlags &= ~NODE_COMPILE_TIME_CONST;
1395     UtSetParseOpName (Op);
1396
1397     /* Child node is the buffer length */
1398
1399     NewOp = TrAllocateNode (PARSEOP_INTEGER);
1400
1401     NewOp->Asl.AmlOpcode     = AML_BYTE_OP;
1402     NewOp->Asl.Value.Integer = 16;
1403     NewOp->Asl.Parent        = Op;
1404
1405     Op->Asl.Child = NewOp;
1406     Op = NewOp;
1407
1408     /* Peer to the child is the raw buffer data */
1409
1410     NewOp = TrAllocateNode (PARSEOP_RAW_DATA);
1411     NewOp->Asl.AmlOpcode     = AML_RAW_DATA_BUFFER;
1412     NewOp->Asl.AmlLength     = 16;
1413     NewOp->Asl.Value.String  = ACPI_CAST_PTR (char, Buffer);
1414     NewOp->Asl.Parent        = Op->Asl.Parent;
1415
1416     Op->Asl.Next = NewOp;
1417 }
1418
1419
1420 /*******************************************************************************
1421  *
1422  * FUNCTION:    OpcGenerateAmlOpcode
1423  *
1424  * PARAMETERS:  Op                  - Parse node
1425  *
1426  * RETURN:      None
1427  *
1428  * DESCRIPTION: Generate the AML opcode associated with the node and its
1429  *              parse (lex/flex) keyword opcode. Essentially implements
1430  *              a mapping between the parse opcodes and the actual AML opcodes.
1431  *
1432  ******************************************************************************/
1433
1434 void
1435 OpcGenerateAmlOpcode (
1436     ACPI_PARSE_OBJECT       *Op)
1437 {
1438     UINT16                  Index;
1439
1440
1441     Index = (UINT16) (Op->Asl.ParseOpcode - ASL_PARSE_OPCODE_BASE);
1442
1443     Op->Asl.AmlOpcode     = AslKeywordMapping[Index].AmlOpcode;
1444     Op->Asl.AcpiBtype     = AslKeywordMapping[Index].AcpiBtype;
1445     Op->Asl.CompileFlags |= AslKeywordMapping[Index].Flags;
1446
1447     if (!Op->Asl.Value.Integer)
1448     {
1449         Op->Asl.Value.Integer = AslKeywordMapping[Index].Value;
1450     }
1451
1452     /* Special handling for some opcodes */
1453
1454     switch (Op->Asl.ParseOpcode)
1455     {
1456     case PARSEOP_INTEGER:
1457         /*
1458          * Set the opcode based on the size of the integer
1459          */
1460         (void) OpcSetOptimalIntegerSize (Op);
1461         break;
1462
1463     case PARSEOP_OFFSET:
1464
1465         Op->Asl.AmlOpcodeLength = 1;
1466         break;
1467
1468     case PARSEOP_ACCESSAS:
1469
1470         OpcDoAccessAs (Op);
1471         break;
1472
1473     case PARSEOP_CONNECTION:
1474
1475         OpcDoConnection (Op);
1476         break;
1477
1478     case PARSEOP_EISAID:
1479
1480         OpcDoEisaId (Op);
1481         break;
1482
1483     case PARSEOP_PRINTF:
1484
1485         OpcDoPrintf (Op);
1486         break;
1487
1488     case PARSEOP_FPRINTF:
1489
1490         OpcDoFprintf (Op);
1491         break;
1492
1493     case PARSEOP_TOPLD:
1494
1495         OpcDoPld (Op);
1496         break;
1497
1498     case PARSEOP_TOUUID:
1499
1500         OpcDoUuId (Op);
1501         break;
1502
1503     case PARSEOP_UNICODE:
1504
1505         OpcDoUnicode (Op);
1506         break;
1507
1508     case PARSEOP_INCLUDE:
1509
1510         Op->Asl.Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
1511         Gbl_HasIncludeFiles = TRUE;
1512         break;
1513
1514     case PARSEOP_EXTERNAL:
1515
1516         Op->Asl.Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
1517         Op->Asl.Child->Asl.Next->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
1518         break;
1519
1520     case PARSEOP_TIMER:
1521
1522         if (AcpiGbl_IntegerBitWidth == 32)
1523         {
1524             AslError (ASL_REMARK, ASL_MSG_TRUNCATION, Op, NULL);
1525         }
1526         break;
1527
1528     default:
1529
1530         /* Nothing to do for other opcodes */
1531
1532         break;
1533     }
1534
1535     return;
1536 }