xref: /freebsd/sys/contrib/dev/acpica/compiler/aslopcodes.c (revision 1cc50d6b6a02d2c48cb9b812432a492d284c6dd1)
153289f6aSNate Lawson /******************************************************************************
253289f6aSNate Lawson  *
353289f6aSNate Lawson  * Module Name: aslopcode - AML opcode generation
453289f6aSNate Lawson  *
553289f6aSNate Lawson  *****************************************************************************/
653289f6aSNate Lawson 
7d244b227SJung-uk Kim /*
8f8146b88SJung-uk Kim  * Copyright (C) 2000 - 2016, Intel Corp.
953289f6aSNate Lawson  * All rights reserved.
1053289f6aSNate Lawson  *
11d244b227SJung-uk Kim  * Redistribution and use in source and binary forms, with or without
12d244b227SJung-uk Kim  * modification, are permitted provided that the following conditions
13d244b227SJung-uk Kim  * are met:
14d244b227SJung-uk Kim  * 1. Redistributions of source code must retain the above copyright
15d244b227SJung-uk Kim  *    notice, this list of conditions, and the following disclaimer,
16d244b227SJung-uk Kim  *    without modification.
17d244b227SJung-uk Kim  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18d244b227SJung-uk Kim  *    substantially similar to the "NO WARRANTY" disclaimer below
19d244b227SJung-uk Kim  *    ("Disclaimer") and any redistribution must be conditioned upon
20d244b227SJung-uk Kim  *    including a substantially similar Disclaimer requirement for further
21d244b227SJung-uk Kim  *    binary redistribution.
22d244b227SJung-uk Kim  * 3. Neither the names of the above-listed copyright holders nor the names
23d244b227SJung-uk Kim  *    of any contributors may be used to endorse or promote products derived
24d244b227SJung-uk Kim  *    from this software without specific prior written permission.
2553289f6aSNate Lawson  *
26d244b227SJung-uk Kim  * Alternatively, this software may be distributed under the terms of the
27d244b227SJung-uk Kim  * GNU General Public License ("GPL") version 2 as published by the Free
28d244b227SJung-uk Kim  * Software Foundation.
2953289f6aSNate Lawson  *
30d244b227SJung-uk Kim  * NO WARRANTY
31d244b227SJung-uk Kim  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32d244b227SJung-uk Kim  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33d244b227SJung-uk Kim  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34d244b227SJung-uk Kim  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35d244b227SJung-uk Kim  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36d244b227SJung-uk Kim  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37d244b227SJung-uk Kim  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38d244b227SJung-uk Kim  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39d244b227SJung-uk Kim  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40d244b227SJung-uk Kim  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41d244b227SJung-uk Kim  * POSSIBILITY OF SUCH DAMAGES.
42d244b227SJung-uk Kim  */
4353289f6aSNate Lawson 
44ab6f3bf9SJung-uk Kim #include <contrib/dev/acpica/compiler/aslcompiler.h>
4553289f6aSNate Lawson #include "aslcompiler.y.h"
46ab6f3bf9SJung-uk Kim #include <contrib/dev/acpica/include/amlcode.h>
4753289f6aSNate Lawson 
4853289f6aSNate Lawson #define _COMPONENT          ACPI_COMPILER
4953289f6aSNate Lawson         ACPI_MODULE_NAME    ("aslopcodes")
5053289f6aSNate Lawson 
5153289f6aSNate Lawson 
52fba7fc7eSJung-uk Kim /* Local prototypes */
53fba7fc7eSJung-uk Kim 
54fba7fc7eSJung-uk Kim static void
55fba7fc7eSJung-uk Kim OpcDoAccessAs (
56fba7fc7eSJung-uk Kim     ACPI_PARSE_OBJECT       *Op);
57fba7fc7eSJung-uk Kim 
58fba7fc7eSJung-uk Kim static void
593f0275a0SJung-uk Kim OpcDoConnection (
603f0275a0SJung-uk Kim     ACPI_PARSE_OBJECT       *Op);
613f0275a0SJung-uk Kim 
623f0275a0SJung-uk Kim static void
63fba7fc7eSJung-uk Kim OpcDoUnicode (
64fba7fc7eSJung-uk Kim     ACPI_PARSE_OBJECT       *Op);
65fba7fc7eSJung-uk Kim 
66fba7fc7eSJung-uk Kim static void
67fba7fc7eSJung-uk Kim OpcDoEisaId (
68fba7fc7eSJung-uk Kim     ACPI_PARSE_OBJECT       *Op);
69fba7fc7eSJung-uk Kim 
70fba7fc7eSJung-uk Kim static void
71fba7fc7eSJung-uk Kim OpcDoUuId (
72fba7fc7eSJung-uk Kim     ACPI_PARSE_OBJECT       *Op);
73fba7fc7eSJung-uk Kim 
74fba7fc7eSJung-uk Kim 
75fba7fc7eSJung-uk Kim /*******************************************************************************
76fba7fc7eSJung-uk Kim  *
77fba7fc7eSJung-uk Kim  * FUNCTION:    OpcAmlOpcodeUpdateWalk
78fba7fc7eSJung-uk Kim  *
79fba7fc7eSJung-uk Kim  * PARAMETERS:  ASL_WALK_CALLBACK
80fba7fc7eSJung-uk Kim  *
81fba7fc7eSJung-uk Kim  * RETURN:      Status
82fba7fc7eSJung-uk Kim  *
83fba7fc7eSJung-uk Kim  * DESCRIPTION: Opcode update walk, ascending callback
84fba7fc7eSJung-uk Kim  *
85fba7fc7eSJung-uk Kim  ******************************************************************************/
86fba7fc7eSJung-uk Kim 
87fba7fc7eSJung-uk Kim ACPI_STATUS
88fba7fc7eSJung-uk Kim OpcAmlOpcodeUpdateWalk (
89fba7fc7eSJung-uk Kim     ACPI_PARSE_OBJECT       *Op,
90fba7fc7eSJung-uk Kim     UINT32                  Level,
91fba7fc7eSJung-uk Kim     void                    *Context)
92fba7fc7eSJung-uk Kim {
93fba7fc7eSJung-uk Kim 
94fba7fc7eSJung-uk Kim     /*
95fba7fc7eSJung-uk Kim      * Handle the Package() case where the actual opcode cannot be determined
96fba7fc7eSJung-uk Kim      * until the PackageLength operand has been folded and minimized.
97fba7fc7eSJung-uk Kim      * (PackageOp versus VarPackageOp)
98fba7fc7eSJung-uk Kim      *
99fba7fc7eSJung-uk Kim      * This is (as of ACPI 3.0) the only case where the AML opcode can change
100fba7fc7eSJung-uk Kim      * based upon the value of a parameter.
101fba7fc7eSJung-uk Kim      *
102fba7fc7eSJung-uk Kim      * The parser always inserts a VarPackage opcode, which can possibly be
103fba7fc7eSJung-uk Kim      * optimized to a Package opcode.
104fba7fc7eSJung-uk Kim      */
105fba7fc7eSJung-uk Kim     if (Op->Asl.ParseOpcode == PARSEOP_VAR_PACKAGE)
106fba7fc7eSJung-uk Kim     {
107fba7fc7eSJung-uk Kim         OpnDoPackage (Op);
108fba7fc7eSJung-uk Kim     }
109fba7fc7eSJung-uk Kim 
110fba7fc7eSJung-uk Kim     return (AE_OK);
111fba7fc7eSJung-uk Kim }
112fba7fc7eSJung-uk Kim 
113fba7fc7eSJung-uk Kim 
11453289f6aSNate Lawson /*******************************************************************************
11553289f6aSNate Lawson  *
11653289f6aSNate Lawson  * FUNCTION:    OpcAmlOpcodeWalk
11753289f6aSNate Lawson  *
11853289f6aSNate Lawson  * PARAMETERS:  ASL_WALK_CALLBACK
11953289f6aSNate Lawson  *
12053289f6aSNate Lawson  * RETURN:      Status
12153289f6aSNate Lawson  *
12253289f6aSNate Lawson  * DESCRIPTION: Parse tree walk to generate both the AML opcodes and the AML
12353289f6aSNate Lawson  *              operands.
12453289f6aSNate Lawson  *
12553289f6aSNate Lawson  ******************************************************************************/
12653289f6aSNate Lawson 
12753289f6aSNate Lawson ACPI_STATUS
12853289f6aSNate Lawson OpcAmlOpcodeWalk (
12953289f6aSNate Lawson     ACPI_PARSE_OBJECT       *Op,
13053289f6aSNate Lawson     UINT32                  Level,
13153289f6aSNate Lawson     void                    *Context)
13253289f6aSNate Lawson {
13353289f6aSNate Lawson 
13453289f6aSNate Lawson     TotalParseNodes++;
13553289f6aSNate Lawson 
13653289f6aSNate Lawson     OpcGenerateAmlOpcode (Op);
13753289f6aSNate Lawson     OpnGenerateAmlOperands (Op);
13853289f6aSNate Lawson     return (AE_OK);
13953289f6aSNate Lawson }
14053289f6aSNate Lawson 
14153289f6aSNate Lawson 
14253289f6aSNate Lawson /*******************************************************************************
14353289f6aSNate Lawson  *
14453289f6aSNate Lawson  * FUNCTION:    OpcGetIntegerWidth
14553289f6aSNate Lawson  *
14653289f6aSNate Lawson  * PARAMETERS:  Op          - DEFINITION BLOCK op
14753289f6aSNate Lawson  *
14853289f6aSNate Lawson  * RETURN:      none
14953289f6aSNate Lawson  *
15053289f6aSNate Lawson  * DESCRIPTION: Extract integer width from the table revision
15153289f6aSNate Lawson  *
15253289f6aSNate Lawson  ******************************************************************************/
15353289f6aSNate Lawson 
15453289f6aSNate Lawson void
15553289f6aSNate Lawson OpcGetIntegerWidth (
15653289f6aSNate Lawson     ACPI_PARSE_OBJECT       *Op)
15753289f6aSNate Lawson {
15853289f6aSNate Lawson     ACPI_PARSE_OBJECT       *Child;
15953289f6aSNate Lawson 
160fba7fc7eSJung-uk Kim 
16153289f6aSNate Lawson     if (!Op)
16253289f6aSNate Lawson     {
16353289f6aSNate Lawson         return;
16453289f6aSNate Lawson     }
16553289f6aSNate Lawson 
166fba7fc7eSJung-uk Kim     if (Gbl_RevisionOverride)
167fba7fc7eSJung-uk Kim     {
168fba7fc7eSJung-uk Kim         AcpiUtSetIntegerWidth (Gbl_RevisionOverride);
169fba7fc7eSJung-uk Kim     }
170fba7fc7eSJung-uk Kim     else
171fba7fc7eSJung-uk Kim     {
17253289f6aSNate Lawson         Child = Op->Asl.Child;
17353289f6aSNate Lawson         Child = Child->Asl.Next;
17453289f6aSNate Lawson         Child = Child->Asl.Next;
17553289f6aSNate Lawson 
17653289f6aSNate Lawson         /* Use the revision to set the integer width */
17753289f6aSNate Lawson 
17853289f6aSNate Lawson         AcpiUtSetIntegerWidth ((UINT8) Child->Asl.Value.Integer);
17953289f6aSNate Lawson     }
180fba7fc7eSJung-uk Kim }
18153289f6aSNate Lawson 
18253289f6aSNate Lawson 
18353289f6aSNate Lawson /*******************************************************************************
18453289f6aSNate Lawson  *
18553289f6aSNate Lawson  * FUNCTION:    OpcSetOptimalIntegerSize
18653289f6aSNate Lawson  *
18753289f6aSNate Lawson  * PARAMETERS:  Op        - A parse tree node
18853289f6aSNate Lawson  *
18953289f6aSNate Lawson  * RETURN:      Integer width, in bytes. Also sets the node AML opcode to the
19053289f6aSNate Lawson  *              optimal integer AML prefix opcode.
19153289f6aSNate Lawson  *
19253289f6aSNate Lawson  * DESCRIPTION: Determine the optimal AML encoding of an integer. All leading
19353289f6aSNate Lawson  *              zeros can be truncated to squeeze the integer into the
19453289f6aSNate Lawson  *              minimal number of AML bytes.
19553289f6aSNate Lawson  *
19653289f6aSNate Lawson  ******************************************************************************/
19753289f6aSNate Lawson 
19853289f6aSNate Lawson UINT32
19953289f6aSNate Lawson OpcSetOptimalIntegerSize (
20053289f6aSNate Lawson     ACPI_PARSE_OBJECT       *Op)
20153289f6aSNate Lawson {
20253289f6aSNate Lawson 
203fba7fc7eSJung-uk Kim #if 0
20453289f6aSNate Lawson     /*
205fba7fc7eSJung-uk Kim      * TBD: - we don't want to optimize integers in the block header, but the
206fba7fc7eSJung-uk Kim      * code below does not work correctly.
207fba7fc7eSJung-uk Kim      */
208c8466860SMark Santcroos     if (Op->Asl.Parent &&
209c8466860SMark Santcroos         Op->Asl.Parent->Asl.Parent &&
210f8146b88SJung-uk Kim        (Op->Asl.Parent->Asl.Parent->Asl.ParseOpcode == PARSEOP_DEFINITION_BLOCK))
211c8466860SMark Santcroos     {
2128ef1a331SJung-uk Kim         return (0);
213c8466860SMark Santcroos     }
214fba7fc7eSJung-uk Kim #endif
215c8466860SMark Santcroos 
216c8466860SMark Santcroos     /*
21753289f6aSNate Lawson      * Check for the special AML integers first - Zero, One, Ones.
21853289f6aSNate Lawson      * These are single-byte opcodes that are the smallest possible
21953289f6aSNate Lawson      * representation of an integer.
22053289f6aSNate Lawson      *
22153289f6aSNate Lawson      * This optimization is optional.
22253289f6aSNate Lawson      */
22353289f6aSNate Lawson     if (Gbl_IntegerOptimizationFlag)
22453289f6aSNate Lawson     {
22553289f6aSNate Lawson         switch (Op->Asl.Value.Integer)
22653289f6aSNate Lawson         {
22753289f6aSNate Lawson         case 0:
22853289f6aSNate Lawson 
22953289f6aSNate Lawson             Op->Asl.AmlOpcode = AML_ZERO_OP;
230fba7fc7eSJung-uk Kim             AslError (ASL_OPTIMIZATION, ASL_MSG_INTEGER_OPTIMIZATION,
231fba7fc7eSJung-uk Kim                 Op, "Zero");
2328ef1a331SJung-uk Kim             return (1);
23353289f6aSNate Lawson 
23453289f6aSNate Lawson         case 1:
23553289f6aSNate Lawson 
23653289f6aSNate Lawson             Op->Asl.AmlOpcode = AML_ONE_OP;
237fba7fc7eSJung-uk Kim             AslError (ASL_OPTIMIZATION, ASL_MSG_INTEGER_OPTIMIZATION,
238fba7fc7eSJung-uk Kim                 Op, "One");
2398ef1a331SJung-uk Kim             return (1);
24053289f6aSNate Lawson 
24153289f6aSNate Lawson         case ACPI_UINT32_MAX:
24253289f6aSNate Lawson 
24353289f6aSNate Lawson             /* Check for table integer width (32 or 64) */
24453289f6aSNate Lawson 
24553289f6aSNate Lawson             if (AcpiGbl_IntegerByteWidth == 4)
24653289f6aSNate Lawson             {
24753289f6aSNate Lawson                 Op->Asl.AmlOpcode = AML_ONES_OP;
248fba7fc7eSJung-uk Kim                 AslError (ASL_OPTIMIZATION, ASL_MSG_INTEGER_OPTIMIZATION,
249fba7fc7eSJung-uk Kim                     Op, "Ones");
2508ef1a331SJung-uk Kim                 return (1);
25153289f6aSNate Lawson             }
25253289f6aSNate Lawson             break;
25353289f6aSNate Lawson 
2549a179dd8SJung-uk Kim         case ACPI_UINT64_MAX:
25553289f6aSNate Lawson 
25653289f6aSNate Lawson             /* Check for table integer width (32 or 64) */
25753289f6aSNate Lawson 
25853289f6aSNate Lawson             if (AcpiGbl_IntegerByteWidth == 8)
25953289f6aSNate Lawson             {
26053289f6aSNate Lawson                 Op->Asl.AmlOpcode = AML_ONES_OP;
261fba7fc7eSJung-uk Kim                 AslError (ASL_OPTIMIZATION, ASL_MSG_INTEGER_OPTIMIZATION,
262fba7fc7eSJung-uk Kim                     Op, "Ones");
2638ef1a331SJung-uk Kim                 return (1);
26453289f6aSNate Lawson             }
26553289f6aSNate Lawson             break;
26653289f6aSNate Lawson 
26753289f6aSNate Lawson         default:
268a9d8d09cSJung-uk Kim 
26953289f6aSNate Lawson             break;
27053289f6aSNate Lawson         }
27153289f6aSNate Lawson     }
27253289f6aSNate Lawson 
27353289f6aSNate Lawson     /* Find the best fit using the various AML integer prefixes */
27453289f6aSNate Lawson 
27553289f6aSNate Lawson     if (Op->Asl.Value.Integer <= ACPI_UINT8_MAX)
27653289f6aSNate Lawson     {
27753289f6aSNate Lawson         Op->Asl.AmlOpcode = AML_BYTE_OP;
2788ef1a331SJung-uk Kim         return (1);
27953289f6aSNate Lawson     }
280f8146b88SJung-uk Kim 
28153289f6aSNate Lawson     if (Op->Asl.Value.Integer <= ACPI_UINT16_MAX)
28253289f6aSNate Lawson     {
28353289f6aSNate Lawson         Op->Asl.AmlOpcode = AML_WORD_OP;
2848ef1a331SJung-uk Kim         return (2);
28553289f6aSNate Lawson     }
286f8146b88SJung-uk Kim 
28753289f6aSNate Lawson     if (Op->Asl.Value.Integer <= ACPI_UINT32_MAX)
28853289f6aSNate Lawson     {
28953289f6aSNate Lawson         Op->Asl.AmlOpcode = AML_DWORD_OP;
2908ef1a331SJung-uk Kim         return (4);
29153289f6aSNate Lawson     }
292*1cc50d6bSJung-uk Kim     else /* 64-bit integer */
29353289f6aSNate Lawson     {
294fba7fc7eSJung-uk Kim         if (AcpiGbl_IntegerByteWidth == 4)
295fba7fc7eSJung-uk Kim         {
296fba7fc7eSJung-uk Kim             AslError (ASL_WARNING, ASL_MSG_INTEGER_LENGTH,
297fba7fc7eSJung-uk Kim                 Op, NULL);
298fba7fc7eSJung-uk Kim 
299fba7fc7eSJung-uk Kim             if (!Gbl_IgnoreErrors)
300fba7fc7eSJung-uk Kim             {
301fba7fc7eSJung-uk Kim                 /* Truncate the integer to 32-bit */
302*1cc50d6bSJung-uk Kim 
303*1cc50d6bSJung-uk Kim                 Op->Asl.Value.Integer &= ACPI_UINT32_MAX;
304*1cc50d6bSJung-uk Kim 
305*1cc50d6bSJung-uk Kim                 /* Now set the optimal integer size */
306*1cc50d6bSJung-uk Kim 
307*1cc50d6bSJung-uk Kim                 return (OpcSetOptimalIntegerSize (Op));
308fba7fc7eSJung-uk Kim             }
309fba7fc7eSJung-uk Kim         }
310fba7fc7eSJung-uk Kim 
31153289f6aSNate Lawson         Op->Asl.AmlOpcode = AML_QWORD_OP;
3128ef1a331SJung-uk Kim         return (8);
31353289f6aSNate Lawson     }
31453289f6aSNate Lawson }
31553289f6aSNate Lawson 
31653289f6aSNate Lawson 
31753289f6aSNate Lawson /*******************************************************************************
31853289f6aSNate Lawson  *
31953289f6aSNate Lawson  * FUNCTION:    OpcDoAccessAs
32053289f6aSNate Lawson  *
32153289f6aSNate Lawson  * PARAMETERS:  Op        - Parse node
32253289f6aSNate Lawson  *
32353289f6aSNate Lawson  * RETURN:      None
32453289f6aSNate Lawson  *
32553289f6aSNate Lawson  * DESCRIPTION: Implement the ACCESS_AS ASL keyword.
32653289f6aSNate Lawson  *
32753289f6aSNate Lawson  ******************************************************************************/
32853289f6aSNate Lawson 
329fba7fc7eSJung-uk Kim static void
33053289f6aSNate Lawson OpcDoAccessAs (
33153289f6aSNate Lawson     ACPI_PARSE_OBJECT       *Op)
33253289f6aSNate Lawson {
3333f0275a0SJung-uk Kim     ACPI_PARSE_OBJECT       *TypeOp;
3343f0275a0SJung-uk Kim     ACPI_PARSE_OBJECT       *AttribOp;
3353f0275a0SJung-uk Kim     ACPI_PARSE_OBJECT       *LengthOp;
3363f0275a0SJung-uk Kim     UINT8                   Attribute;
33753289f6aSNate Lawson 
33853289f6aSNate Lawson 
33953289f6aSNate Lawson     Op->Asl.AmlOpcodeLength = 1;
3403f0275a0SJung-uk Kim     TypeOp = Op->Asl.Child;
34153289f6aSNate Lawson 
34253289f6aSNate Lawson     /* First child is the access type */
34353289f6aSNate Lawson 
3443f0275a0SJung-uk Kim     TypeOp->Asl.AmlOpcode = AML_RAW_DATA_BYTE;
3453f0275a0SJung-uk Kim     TypeOp->Asl.ParseOpcode = PARSEOP_RAW_DATA;
34653289f6aSNate Lawson 
34753289f6aSNate Lawson     /* Second child is the optional access attribute */
34853289f6aSNate Lawson 
3493f0275a0SJung-uk Kim     AttribOp = TypeOp->Asl.Next;
3503f0275a0SJung-uk Kim     if (AttribOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
35153289f6aSNate Lawson     {
3523f0275a0SJung-uk Kim         AttribOp->Asl.Value.Integer = 0;
35353289f6aSNate Lawson     }
354f8146b88SJung-uk Kim 
3553f0275a0SJung-uk Kim     AttribOp->Asl.AmlOpcode = AML_RAW_DATA_BYTE;
3563f0275a0SJung-uk Kim     AttribOp->Asl.ParseOpcode = PARSEOP_RAW_DATA;
3573f0275a0SJung-uk Kim 
3583f0275a0SJung-uk Kim     /* Only a few AccessAttributes support AccessLength */
3593f0275a0SJung-uk Kim 
3603f0275a0SJung-uk Kim     Attribute = (UINT8) AttribOp->Asl.Value.Integer;
3613f0275a0SJung-uk Kim     if ((Attribute != AML_FIELD_ATTRIB_MULTIBYTE) &&
3623f0275a0SJung-uk Kim         (Attribute != AML_FIELD_ATTRIB_RAW_BYTES) &&
3633f0275a0SJung-uk Kim         (Attribute != AML_FIELD_ATTRIB_RAW_PROCESS))
3643f0275a0SJung-uk Kim     {
3653f0275a0SJung-uk Kim         return;
3663f0275a0SJung-uk Kim     }
3673f0275a0SJung-uk Kim 
3683f0275a0SJung-uk Kim     Op->Asl.AmlOpcode = AML_FIELD_EXT_ACCESS_OP;
3693f0275a0SJung-uk Kim 
3703f0275a0SJung-uk Kim     /*
3713f0275a0SJung-uk Kim      * Child of Attributes is the AccessLength (required for Multibyte,
3723f0275a0SJung-uk Kim      * RawBytes, RawProcess.)
3733f0275a0SJung-uk Kim      */
3743f0275a0SJung-uk Kim     LengthOp = AttribOp->Asl.Child;
3753f0275a0SJung-uk Kim     if (!LengthOp)
3763f0275a0SJung-uk Kim     {
3773f0275a0SJung-uk Kim         return;
3783f0275a0SJung-uk Kim     }
3793f0275a0SJung-uk Kim 
3803f0275a0SJung-uk Kim     /* TBD: probably can remove */
3813f0275a0SJung-uk Kim 
3823f0275a0SJung-uk Kim     if (LengthOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
3833f0275a0SJung-uk Kim     {
3843f0275a0SJung-uk Kim         LengthOp->Asl.Value.Integer = 16;
3853f0275a0SJung-uk Kim     }
3863f0275a0SJung-uk Kim 
3873f0275a0SJung-uk Kim     LengthOp->Asl.AmlOpcode = AML_RAW_DATA_BYTE;
3883f0275a0SJung-uk Kim     LengthOp->Asl.ParseOpcode = PARSEOP_RAW_DATA;
3893f0275a0SJung-uk Kim }
3903f0275a0SJung-uk Kim 
3913f0275a0SJung-uk Kim 
3923f0275a0SJung-uk Kim /*******************************************************************************
3933f0275a0SJung-uk Kim  *
3943f0275a0SJung-uk Kim  * FUNCTION:    OpcDoConnection
3953f0275a0SJung-uk Kim  *
3963f0275a0SJung-uk Kim  * PARAMETERS:  Op        - Parse node
3973f0275a0SJung-uk Kim  *
3983f0275a0SJung-uk Kim  * RETURN:      None
3993f0275a0SJung-uk Kim  *
4003f0275a0SJung-uk Kim  * DESCRIPTION: Implement the Connection ASL keyword.
4013f0275a0SJung-uk Kim  *
4023f0275a0SJung-uk Kim  ******************************************************************************/
4033f0275a0SJung-uk Kim 
4043f0275a0SJung-uk Kim static void
4053f0275a0SJung-uk Kim OpcDoConnection (
4063f0275a0SJung-uk Kim     ACPI_PARSE_OBJECT       *Op)
4073f0275a0SJung-uk Kim {
4083f0275a0SJung-uk Kim     ASL_RESOURCE_NODE       *Rnode;
4093f0275a0SJung-uk Kim     ACPI_PARSE_OBJECT       *BufferOp;
4103f0275a0SJung-uk Kim     ACPI_PARSE_OBJECT       *BufferLengthOp;
4113f0275a0SJung-uk Kim     ACPI_PARSE_OBJECT       *BufferDataOp;
412313a0c13SJung-uk Kim     ASL_RESOURCE_INFO       Info;
4133f0275a0SJung-uk Kim     UINT8                   State;
4143f0275a0SJung-uk Kim 
4153f0275a0SJung-uk Kim 
4163f0275a0SJung-uk Kim     Op->Asl.AmlOpcodeLength = 1;
4173f0275a0SJung-uk Kim 
4183f0275a0SJung-uk Kim     if (Op->Asl.Child->Asl.AmlOpcode == AML_INT_NAMEPATH_OP)
4193f0275a0SJung-uk Kim     {
4203f0275a0SJung-uk Kim         return;
4213f0275a0SJung-uk Kim     }
4223f0275a0SJung-uk Kim 
4233f0275a0SJung-uk Kim     BufferOp = Op->Asl.Child;
4243f0275a0SJung-uk Kim     BufferLengthOp = BufferOp->Asl.Child;
4253f0275a0SJung-uk Kim     BufferDataOp = BufferLengthOp->Asl.Next;
4263f0275a0SJung-uk Kim 
427313a0c13SJung-uk Kim     Info.DescriptorTypeOp = BufferDataOp->Asl.Next;
428313a0c13SJung-uk Kim     Info.CurrentByteOffset = 0;
4293f0275a0SJung-uk Kim     State = ACPI_RSTATE_NORMAL;
430313a0c13SJung-uk Kim     Rnode = RsDoOneResourceDescriptor (&Info, &State);
4313f0275a0SJung-uk Kim     if (!Rnode)
4323f0275a0SJung-uk Kim     {
4333f0275a0SJung-uk Kim         return; /* error */
4343f0275a0SJung-uk Kim     }
4353f0275a0SJung-uk Kim 
4363f0275a0SJung-uk Kim     /*
4373f0275a0SJung-uk Kim      * Transform the nodes into the following
4383f0275a0SJung-uk Kim      *
4393f0275a0SJung-uk Kim      * Op           -> AML_BUFFER_OP
4403f0275a0SJung-uk Kim      * First Child  -> BufferLength
4413f0275a0SJung-uk Kim      * Second Child -> Descriptor Buffer (raw byte data)
4423f0275a0SJung-uk Kim      */
4433f0275a0SJung-uk Kim     BufferOp->Asl.ParseOpcode = PARSEOP_BUFFER;
4443f0275a0SJung-uk Kim     BufferOp->Asl.AmlOpcode = AML_BUFFER_OP;
4453f0275a0SJung-uk Kim     BufferOp->Asl.CompileFlags = NODE_AML_PACKAGE | NODE_IS_RESOURCE_DESC;
4463f0275a0SJung-uk Kim     UtSetParseOpName (BufferOp);
4473f0275a0SJung-uk Kim 
4483f0275a0SJung-uk Kim     BufferLengthOp->Asl.ParseOpcode = PARSEOP_INTEGER;
4493f0275a0SJung-uk Kim     BufferLengthOp->Asl.Value.Integer = Rnode->BufferLength;
4503f0275a0SJung-uk Kim     (void) OpcSetOptimalIntegerSize (BufferLengthOp);
4513f0275a0SJung-uk Kim     UtSetParseOpName (BufferLengthOp);
4523f0275a0SJung-uk Kim 
4533f0275a0SJung-uk Kim     BufferDataOp->Asl.ParseOpcode = PARSEOP_RAW_DATA;
4543f0275a0SJung-uk Kim     BufferDataOp->Asl.AmlOpcode = AML_RAW_DATA_CHAIN;
4553f0275a0SJung-uk Kim     BufferDataOp->Asl.AmlOpcodeLength = 0;
4563f0275a0SJung-uk Kim     BufferDataOp->Asl.AmlLength = Rnode->BufferLength;
4573f0275a0SJung-uk Kim     BufferDataOp->Asl.Value.Buffer = (UINT8 *) Rnode;
4583f0275a0SJung-uk Kim     UtSetParseOpName (BufferDataOp);
45953289f6aSNate Lawson }
46053289f6aSNate Lawson 
46153289f6aSNate Lawson 
46253289f6aSNate Lawson /*******************************************************************************
46353289f6aSNate Lawson  *
46453289f6aSNate Lawson  * FUNCTION:    OpcDoUnicode
46553289f6aSNate Lawson  *
46653289f6aSNate Lawson  * PARAMETERS:  Op        - Parse node
46753289f6aSNate Lawson  *
46853289f6aSNate Lawson  * RETURN:      None
46953289f6aSNate Lawson  *
47053289f6aSNate Lawson  * DESCRIPTION: Implement the UNICODE ASL "macro".  Convert the input string
47153289f6aSNate Lawson  *              to a unicode buffer. There is no Unicode AML opcode.
47253289f6aSNate Lawson  *
47353289f6aSNate Lawson  * Note:  The Unicode string is 16 bits per character, no leading signature,
47453289f6aSNate Lawson  *        with a 16-bit terminating NULL.
47553289f6aSNate Lawson  *
47653289f6aSNate Lawson  ******************************************************************************/
47753289f6aSNate Lawson 
478fba7fc7eSJung-uk Kim static void
47953289f6aSNate Lawson OpcDoUnicode (
48053289f6aSNate Lawson     ACPI_PARSE_OBJECT       *Op)
48153289f6aSNate Lawson {
48253289f6aSNate Lawson     ACPI_PARSE_OBJECT       *InitializerOp;
48353289f6aSNate Lawson     UINT32                  Length;
48453289f6aSNate Lawson     UINT32                  Count;
48553289f6aSNate Lawson     UINT32                  i;
48653289f6aSNate Lawson     UINT8                   *AsciiString;
48753289f6aSNate Lawson     UINT16                  *UnicodeString;
48853289f6aSNate Lawson     ACPI_PARSE_OBJECT       *BufferLengthOp;
48953289f6aSNate Lawson 
49053289f6aSNate Lawson 
49153289f6aSNate Lawson     /* Change op into a buffer object */
49253289f6aSNate Lawson 
49353289f6aSNate Lawson     Op->Asl.CompileFlags &= ~NODE_COMPILE_TIME_CONST;
49453289f6aSNate Lawson     Op->Asl.ParseOpcode = PARSEOP_BUFFER;
49553289f6aSNate Lawson     UtSetParseOpName (Op);
49653289f6aSNate Lawson 
49753289f6aSNate Lawson     /* Buffer Length is first, followed by the string */
49853289f6aSNate Lawson 
49953289f6aSNate Lawson     BufferLengthOp = Op->Asl.Child;
50053289f6aSNate Lawson     InitializerOp = BufferLengthOp->Asl.Next;
50153289f6aSNate Lawson 
50253289f6aSNate Lawson     AsciiString = (UINT8 *) InitializerOp->Asl.Value.String;
50353289f6aSNate Lawson 
50453289f6aSNate Lawson     /* Create a new buffer for the Unicode string */
50553289f6aSNate Lawson 
50653289f6aSNate Lawson     Count = strlen (InitializerOp->Asl.Value.String) + 1;
50753289f6aSNate Lawson     Length = Count * sizeof (UINT16);
50853289f6aSNate Lawson     UnicodeString = UtLocalCalloc (Length);
50953289f6aSNate Lawson 
51053289f6aSNate Lawson     /* Convert to Unicode string (including null terminator) */
51153289f6aSNate Lawson 
51253289f6aSNate Lawson     for (i = 0; i < Count; i++)
51353289f6aSNate Lawson     {
51453289f6aSNate Lawson         UnicodeString[i] = (UINT16) AsciiString[i];
51553289f6aSNate Lawson     }
51653289f6aSNate Lawson 
51753289f6aSNate Lawson     /*
51853289f6aSNate Lawson      * Just set the buffer size node to be the buffer length, regardless
51953289f6aSNate Lawson      * of whether it was previously an integer or a default_arg placeholder
52053289f6aSNate Lawson      */
52153289f6aSNate Lawson     BufferLengthOp->Asl.ParseOpcode = PARSEOP_INTEGER;
52253289f6aSNate Lawson     BufferLengthOp->Asl.AmlOpcode = AML_DWORD_OP;
52353289f6aSNate Lawson     BufferLengthOp->Asl.Value.Integer = Length;
52453289f6aSNate Lawson     UtSetParseOpName (BufferLengthOp);
52553289f6aSNate Lawson 
52653289f6aSNate Lawson     (void) OpcSetOptimalIntegerSize (BufferLengthOp);
52753289f6aSNate Lawson 
52853289f6aSNate Lawson     /* The Unicode string is a raw data buffer */
52953289f6aSNate Lawson 
53053289f6aSNate Lawson     InitializerOp->Asl.Value.Buffer = (UINT8 *) UnicodeString;
53153289f6aSNate Lawson     InitializerOp->Asl.AmlOpcode = AML_RAW_DATA_BUFFER;
53253289f6aSNate Lawson     InitializerOp->Asl.AmlLength = Length;
53353289f6aSNate Lawson     InitializerOp->Asl.ParseOpcode = PARSEOP_RAW_DATA;
53453289f6aSNate Lawson     InitializerOp->Asl.Child = NULL;
53553289f6aSNate Lawson     UtSetParseOpName (InitializerOp);
53653289f6aSNate Lawson }
53753289f6aSNate Lawson 
53853289f6aSNate Lawson 
53953289f6aSNate Lawson /*******************************************************************************
54053289f6aSNate Lawson  *
54153289f6aSNate Lawson  * FUNCTION:    OpcDoEisaId
54253289f6aSNate Lawson  *
54353289f6aSNate Lawson  * PARAMETERS:  Op        - Parse node
54453289f6aSNate Lawson  *
54553289f6aSNate Lawson  * RETURN:      None
54653289f6aSNate Lawson  *
54753289f6aSNate Lawson  * DESCRIPTION: Convert a string EISA ID to numeric representation. See the
54853289f6aSNate Lawson  *              Pnp BIOS Specification for details. Here is an excerpt:
54953289f6aSNate Lawson  *
55053289f6aSNate Lawson  *              A seven character ASCII representation of the product
55153289f6aSNate Lawson  *              identifier compressed into a 32-bit identifier. The seven
55253289f6aSNate Lawson  *              character ID consists of a three character manufacturer code,
55353289f6aSNate Lawson  *              a three character hexadecimal product identifier, and a one
55453289f6aSNate Lawson  *              character hexadecimal revision number. The manufacturer code
55553289f6aSNate Lawson  *              is a 3 uppercase character code that is compressed into 3 5-bit
55653289f6aSNate Lawson  *              values as follows:
55753289f6aSNate Lawson  *                  1) Find hex ASCII value for each letter
55853289f6aSNate Lawson  *                  2) Subtract 40h from each ASCII value
5598ef1a331SJung-uk Kim  *                  3) Retain 5 least significant bits for each letter by
56053289f6aSNate Lawson  *                     discarding upper 3 bits because they are always 0.
56153289f6aSNate Lawson  *                  4) Compressed code = concatenate 0 and the 3 5-bit values
56253289f6aSNate Lawson  *
56353289f6aSNate Lawson  *              The format of the compressed product identifier is as follows:
56453289f6aSNate Lawson  *              Byte 0: Bit 7       - Reserved (0)
56553289f6aSNate Lawson  *                      Bits 6-2:   - 1st character of compressed mfg code
56653289f6aSNate Lawson  *                      Bits 1-0    - Upper 2 bits of 2nd character of mfg code
56753289f6aSNate Lawson  *              Byte 1: Bits 7-5    - Lower 3 bits of 2nd character of mfg code
56853289f6aSNate Lawson  *                      Bits 4-0    - 3rd character of mfg code
56953289f6aSNate Lawson  *              Byte 2: Bits 7-4    - 1st hex digit of product number
57053289f6aSNate Lawson  *                      Bits 3-0    - 2nd hex digit of product number
57153289f6aSNate Lawson  *              Byte 3: Bits 7-4    - 3st hex digit of product number
57253289f6aSNate Lawson  *                      Bits 3-0    - Hex digit of the revision number
57353289f6aSNate Lawson  *
57453289f6aSNate Lawson  ******************************************************************************/
57553289f6aSNate Lawson 
576fba7fc7eSJung-uk Kim static void
57753289f6aSNate Lawson OpcDoEisaId (
57853289f6aSNate Lawson     ACPI_PARSE_OBJECT       *Op)
57953289f6aSNate Lawson {
58053289f6aSNate Lawson     UINT32                  EisaId = 0;
58153289f6aSNate Lawson     UINT32                  BigEndianId;
58253289f6aSNate Lawson     char                    *InString;
58353289f6aSNate Lawson     ACPI_STATUS             Status = AE_OK;
584a9f12690SJung-uk Kim     UINT32                  i;
58553289f6aSNate Lawson 
58653289f6aSNate Lawson 
58753289f6aSNate Lawson     InString = (char *) Op->Asl.Value.String;
58853289f6aSNate Lawson 
58953289f6aSNate Lawson     /*
59053289f6aSNate Lawson      * The EISAID string must be exactly 7 characters and of the form
591fba7fc7eSJung-uk Kim      * "UUUXXXX" -- 3 uppercase letters and 4 hex digits (e.g., "PNP0001")
59253289f6aSNate Lawson      */
5935ef50723SJung-uk Kim     if (strlen (InString) != 7)
59453289f6aSNate Lawson     {
59553289f6aSNate Lawson         Status = AE_BAD_PARAMETER;
59653289f6aSNate Lawson     }
59753289f6aSNate Lawson     else
59853289f6aSNate Lawson     {
59953289f6aSNate Lawson         /* Check all 7 characters for correct format */
60053289f6aSNate Lawson 
60153289f6aSNate Lawson         for (i = 0; i < 7; i++)
60253289f6aSNate Lawson         {
603c8466860SMark Santcroos             /* First 3 characters must be uppercase letters */
60453289f6aSNate Lawson 
60553289f6aSNate Lawson             if (i < 3)
60653289f6aSNate Lawson             {
6079a179dd8SJung-uk Kim                 if (!isupper ((int) InString[i]))
60853289f6aSNate Lawson                 {
60953289f6aSNate Lawson                     Status = AE_BAD_PARAMETER;
61053289f6aSNate Lawson                 }
61153289f6aSNate Lawson             }
61253289f6aSNate Lawson 
61353289f6aSNate Lawson             /* Last 4 characters must be hex digits */
61453289f6aSNate Lawson 
6159a179dd8SJung-uk Kim             else if (!isxdigit ((int) InString[i]))
61653289f6aSNate Lawson             {
61753289f6aSNate Lawson                 Status = AE_BAD_PARAMETER;
61853289f6aSNate Lawson             }
61953289f6aSNate Lawson         }
62053289f6aSNate Lawson     }
62153289f6aSNate Lawson 
62253289f6aSNate Lawson     if (ACPI_FAILURE (Status))
62353289f6aSNate Lawson     {
62453289f6aSNate Lawson         AslError (ASL_ERROR, ASL_MSG_INVALID_EISAID, Op, Op->Asl.Value.String);
62553289f6aSNate Lawson     }
62653289f6aSNate Lawson     else
62753289f6aSNate Lawson     {
62853289f6aSNate Lawson         /* Create ID big-endian first (bits are contiguous) */
62953289f6aSNate Lawson 
6301a39cfb0SJung-uk Kim         BigEndianId =
63142fecd12SJung-uk Kim             (UINT32) ((UINT8) (InString[0] - 0x40)) << 26 |
63242fecd12SJung-uk Kim             (UINT32) ((UINT8) (InString[1] - 0x40)) << 21 |
63342fecd12SJung-uk Kim             (UINT32) ((UINT8) (InString[2] - 0x40)) << 16 |
63453289f6aSNate Lawson 
635313a0c13SJung-uk Kim             (AcpiUtAsciiCharToHex (InString[3])) << 12 |
636313a0c13SJung-uk Kim             (AcpiUtAsciiCharToHex (InString[4])) << 8  |
637313a0c13SJung-uk Kim             (AcpiUtAsciiCharToHex (InString[5])) << 4  |
638313a0c13SJung-uk Kim              AcpiUtAsciiCharToHex (InString[6]);
63953289f6aSNate Lawson 
64053289f6aSNate Lawson         /* Swap to little-endian to get final ID (see function header) */
64153289f6aSNate Lawson 
64253289f6aSNate Lawson         EisaId = AcpiUtDwordByteSwap (BigEndianId);
64353289f6aSNate Lawson     }
64453289f6aSNate Lawson 
64553289f6aSNate Lawson     /*
64653289f6aSNate Lawson      * Morph the Op into an integer, regardless of whether there
64753289f6aSNate Lawson      * was an error in the EISAID string
64853289f6aSNate Lawson      */
64953289f6aSNate Lawson     Op->Asl.Value.Integer = EisaId;
65053289f6aSNate Lawson 
65153289f6aSNate Lawson     Op->Asl.CompileFlags &= ~NODE_COMPILE_TIME_CONST;
65253289f6aSNate Lawson     Op->Asl.ParseOpcode = PARSEOP_INTEGER;
65353289f6aSNate Lawson     (void) OpcSetOptimalIntegerSize (Op);
65453289f6aSNate Lawson 
65553289f6aSNate Lawson     /* Op is now an integer */
65653289f6aSNate Lawson 
65753289f6aSNate Lawson     UtSetParseOpName (Op);
65853289f6aSNate Lawson }
65953289f6aSNate Lawson 
66053289f6aSNate Lawson 
66153289f6aSNate Lawson /*******************************************************************************
66253289f6aSNate Lawson  *
6633f0275a0SJung-uk Kim  * FUNCTION:    OpcDoUuId
664c8466860SMark Santcroos  *
665c8466860SMark Santcroos  * PARAMETERS:  Op                  - Parse node
666c8466860SMark Santcroos  *
667c8466860SMark Santcroos  * RETURN:      None
668c8466860SMark Santcroos  *
669fba7fc7eSJung-uk Kim  * DESCRIPTION: Convert UUID string to 16-byte buffer
670c8466860SMark Santcroos  *
671c8466860SMark Santcroos  ******************************************************************************/
672c8466860SMark Santcroos 
673fba7fc7eSJung-uk Kim static void
674c8466860SMark Santcroos OpcDoUuId (
675c8466860SMark Santcroos     ACPI_PARSE_OBJECT       *Op)
676c8466860SMark Santcroos {
677c8466860SMark Santcroos     char                    *InString;
678313a0c13SJung-uk Kim     UINT8                   *Buffer;
679c8466860SMark Santcroos     ACPI_STATUS             Status = AE_OK;
680c8466860SMark Santcroos     ACPI_PARSE_OBJECT       *NewOp;
681c8466860SMark Santcroos 
682c8466860SMark Santcroos 
6831c0e1b6dSJung-uk Kim     InString = ACPI_CAST_PTR (char, Op->Asl.Value.String);
684c8466860SMark Santcroos     Buffer = UtLocalCalloc (16);
685c8466860SMark Santcroos 
686d244b227SJung-uk Kim     Status = AuValidateUuid (InString);
687c8466860SMark Santcroos     if (ACPI_FAILURE (Status))
688c8466860SMark Santcroos     {
689c8466860SMark Santcroos         AslError (ASL_ERROR, ASL_MSG_INVALID_UUID, Op, Op->Asl.Value.String);
690c8466860SMark Santcroos     }
691d244b227SJung-uk Kim     else
692c8466860SMark Santcroos     {
693313a0c13SJung-uk Kim         AcpiUtConvertStringToUuid (InString, Buffer);
694c8466860SMark Santcroos     }
695c8466860SMark Santcroos 
696c8466860SMark Santcroos     /* Change Op to a Buffer */
697c8466860SMark Santcroos 
698c8466860SMark Santcroos     Op->Asl.ParseOpcode = PARSEOP_BUFFER;
699c8466860SMark Santcroos     Op->Common.AmlOpcode = AML_BUFFER_OP;
700fba7fc7eSJung-uk Kim 
701fba7fc7eSJung-uk Kim     /* Disable further optimization */
702fba7fc7eSJung-uk Kim 
703fba7fc7eSJung-uk Kim     Op->Asl.CompileFlags &= ~NODE_COMPILE_TIME_CONST;
704c8466860SMark Santcroos     UtSetParseOpName (Op);
705c8466860SMark Santcroos 
706c8466860SMark Santcroos     /* Child node is the buffer length */
707c8466860SMark Santcroos 
708c8466860SMark Santcroos     NewOp = TrAllocateNode (PARSEOP_INTEGER);
709c8466860SMark Santcroos 
710c8466860SMark Santcroos     NewOp->Asl.AmlOpcode = AML_BYTE_OP;
711c8466860SMark Santcroos     NewOp->Asl.Value.Integer = 16;
712c8466860SMark Santcroos     NewOp->Asl.Parent = Op;
713c8466860SMark Santcroos 
714c8466860SMark Santcroos     Op->Asl.Child = NewOp;
715c8466860SMark Santcroos     Op = NewOp;
716c8466860SMark Santcroos 
717c8466860SMark Santcroos     /* Peer to the child is the raw buffer data */
718c8466860SMark Santcroos 
719c8466860SMark Santcroos     NewOp = TrAllocateNode (PARSEOP_RAW_DATA);
720c8466860SMark Santcroos     NewOp->Asl.AmlOpcode = AML_RAW_DATA_BUFFER;
721c8466860SMark Santcroos     NewOp->Asl.AmlLength = 16;
7221c0e1b6dSJung-uk Kim     NewOp->Asl.Value.String = ACPI_CAST_PTR (char, Buffer);
723c8466860SMark Santcroos     NewOp->Asl.Parent = Op->Asl.Parent;
724c8466860SMark Santcroos 
725c8466860SMark Santcroos     Op->Asl.Next = NewOp;
726c8466860SMark Santcroos }
727c8466860SMark Santcroos 
728c8466860SMark Santcroos 
729c8466860SMark Santcroos /*******************************************************************************
730c8466860SMark Santcroos  *
73153289f6aSNate Lawson  * FUNCTION:    OpcGenerateAmlOpcode
73253289f6aSNate Lawson  *
73353289f6aSNate Lawson  * PARAMETERS:  Op                  - Parse node
73453289f6aSNate Lawson  *
73553289f6aSNate Lawson  * RETURN:      None
73653289f6aSNate Lawson  *
73753289f6aSNate Lawson  * DESCRIPTION: Generate the AML opcode associated with the node and its
73853289f6aSNate Lawson  *              parse (lex/flex) keyword opcode. Essentially implements
73953289f6aSNate Lawson  *              a mapping between the parse opcodes and the actual AML opcodes.
74053289f6aSNate Lawson  *
74153289f6aSNate Lawson  ******************************************************************************/
74253289f6aSNate Lawson 
74353289f6aSNate Lawson void
74453289f6aSNate Lawson OpcGenerateAmlOpcode (
74553289f6aSNate Lawson     ACPI_PARSE_OBJECT       *Op)
74653289f6aSNate Lawson {
74753289f6aSNate Lawson     UINT16                  Index;
74853289f6aSNate Lawson 
74953289f6aSNate Lawson 
75053289f6aSNate Lawson     Index = (UINT16) (Op->Asl.ParseOpcode - ASL_PARSE_OPCODE_BASE);
75153289f6aSNate Lawson 
75253289f6aSNate Lawson     Op->Asl.AmlOpcode     = AslKeywordMapping[Index].AmlOpcode;
75353289f6aSNate Lawson     Op->Asl.AcpiBtype     = AslKeywordMapping[Index].AcpiBtype;
75453289f6aSNate Lawson     Op->Asl.CompileFlags |= AslKeywordMapping[Index].Flags;
75553289f6aSNate Lawson 
75653289f6aSNate Lawson     if (!Op->Asl.Value.Integer)
75753289f6aSNate Lawson     {
75853289f6aSNate Lawson         Op->Asl.Value.Integer = AslKeywordMapping[Index].Value;
75953289f6aSNate Lawson     }
76053289f6aSNate Lawson 
76153289f6aSNate Lawson     /* Special handling for some opcodes */
76253289f6aSNate Lawson 
76353289f6aSNate Lawson     switch (Op->Asl.ParseOpcode)
76453289f6aSNate Lawson     {
76553289f6aSNate Lawson     case PARSEOP_INTEGER:
76653289f6aSNate Lawson         /*
76753289f6aSNate Lawson          * Set the opcode based on the size of the integer
76853289f6aSNate Lawson          */
76953289f6aSNate Lawson         (void) OpcSetOptimalIntegerSize (Op);
77053289f6aSNate Lawson         break;
77153289f6aSNate Lawson 
77253289f6aSNate Lawson     case PARSEOP_OFFSET:
77353289f6aSNate Lawson 
77453289f6aSNate Lawson         Op->Asl.AmlOpcodeLength = 1;
77553289f6aSNate Lawson         break;
77653289f6aSNate Lawson 
77753289f6aSNate Lawson     case PARSEOP_ACCESSAS:
77853289f6aSNate Lawson 
77953289f6aSNate Lawson         OpcDoAccessAs (Op);
78053289f6aSNate Lawson         break;
78153289f6aSNate Lawson 
7823f0275a0SJung-uk Kim     case PARSEOP_CONNECTION:
7833f0275a0SJung-uk Kim 
7843f0275a0SJung-uk Kim         OpcDoConnection (Op);
7853f0275a0SJung-uk Kim         break;
7863f0275a0SJung-uk Kim 
78753289f6aSNate Lawson     case PARSEOP_EISAID:
78853289f6aSNate Lawson 
78953289f6aSNate Lawson         OpcDoEisaId (Op);
79053289f6aSNate Lawson         break;
79153289f6aSNate Lawson 
7921c0e1b6dSJung-uk Kim     case PARSEOP_PRINTF:
7931c0e1b6dSJung-uk Kim 
7941c0e1b6dSJung-uk Kim         OpcDoPrintf (Op);
7951c0e1b6dSJung-uk Kim         break;
7961c0e1b6dSJung-uk Kim 
7971c0e1b6dSJung-uk Kim     case PARSEOP_FPRINTF:
7981c0e1b6dSJung-uk Kim 
7991c0e1b6dSJung-uk Kim         OpcDoFprintf (Op);
8001c0e1b6dSJung-uk Kim         break;
8011c0e1b6dSJung-uk Kim 
8021c0e1b6dSJung-uk Kim     case PARSEOP_TOPLD:
8031c0e1b6dSJung-uk Kim 
8041c0e1b6dSJung-uk Kim         OpcDoPld (Op);
8051c0e1b6dSJung-uk Kim         break;
8061c0e1b6dSJung-uk Kim 
807c8466860SMark Santcroos     case PARSEOP_TOUUID:
808c8466860SMark Santcroos 
809c8466860SMark Santcroos         OpcDoUuId (Op);
810c8466860SMark Santcroos         break;
811c8466860SMark Santcroos 
81253289f6aSNate Lawson     case PARSEOP_UNICODE:
81353289f6aSNate Lawson 
81453289f6aSNate Lawson         OpcDoUnicode (Op);
81553289f6aSNate Lawson         break;
81653289f6aSNate Lawson 
81753289f6aSNate Lawson     case PARSEOP_INCLUDE:
81853289f6aSNate Lawson 
81953289f6aSNate Lawson         Gbl_HasIncludeFiles = TRUE;
82053289f6aSNate Lawson         break;
82153289f6aSNate Lawson 
82253289f6aSNate Lawson     case PARSEOP_EXTERNAL:
82353289f6aSNate Lawson 
824f8146b88SJung-uk Kim         if (Gbl_DoExternals == FALSE)
825f8146b88SJung-uk Kim         {
82653289f6aSNate Lawson             Op->Asl.Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
82753289f6aSNate Lawson             Op->Asl.Child->Asl.Next->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
828f8146b88SJung-uk Kim         }
82953289f6aSNate Lawson         break;
83053289f6aSNate Lawson 
831efcc2a30SJung-uk Kim     case PARSEOP_TIMER:
832efcc2a30SJung-uk Kim 
833efcc2a30SJung-uk Kim         if (AcpiGbl_IntegerBitWidth == 32)
834efcc2a30SJung-uk Kim         {
835efcc2a30SJung-uk Kim             AslError (ASL_REMARK, ASL_MSG_TRUNCATION, Op, NULL);
836efcc2a30SJung-uk Kim         }
837efcc2a30SJung-uk Kim         break;
838efcc2a30SJung-uk Kim 
83953289f6aSNate Lawson     default:
840a9d8d09cSJung-uk Kim 
84153289f6aSNate Lawson         /* Nothing to do for other opcodes */
842a9d8d09cSJung-uk Kim 
84353289f6aSNate Lawson         break;
84453289f6aSNate Lawson     }
84553289f6aSNate Lawson 
84653289f6aSNate Lawson     return;
84753289f6aSNate Lawson }
848