xref: /freebsd/sys/contrib/dev/acpica/compiler/aslopcodes.c (revision f8146b882bc156c1d8ddf14bbea67253ebc064bb)
153289f6aSNate Lawson /******************************************************************************
253289f6aSNate Lawson  *
353289f6aSNate Lawson  * Module Name: aslopcode - AML opcode generation
453289f6aSNate Lawson  *
553289f6aSNate Lawson  *****************************************************************************/
653289f6aSNate Lawson 
7d244b227SJung-uk Kim /*
8*f8146b88SJung-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 &&
210*f8146b88SJung-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     }
280*f8146b88SJung-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     }
286*f8146b88SJung-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     }
29253289f6aSNate Lawson     else
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 */
302fba7fc7eSJung-uk Kim                 Op->Asl.AmlOpcode = AML_DWORD_OP;
3038ef1a331SJung-uk Kim                 return (4);
304fba7fc7eSJung-uk Kim             }
305fba7fc7eSJung-uk Kim         }
306fba7fc7eSJung-uk Kim 
30753289f6aSNate Lawson         Op->Asl.AmlOpcode = AML_QWORD_OP;
3088ef1a331SJung-uk Kim         return (8);
30953289f6aSNate Lawson     }
31053289f6aSNate Lawson }
31153289f6aSNate Lawson 
31253289f6aSNate Lawson 
31353289f6aSNate Lawson /*******************************************************************************
31453289f6aSNate Lawson  *
31553289f6aSNate Lawson  * FUNCTION:    OpcDoAccessAs
31653289f6aSNate Lawson  *
31753289f6aSNate Lawson  * PARAMETERS:  Op        - Parse node
31853289f6aSNate Lawson  *
31953289f6aSNate Lawson  * RETURN:      None
32053289f6aSNate Lawson  *
32153289f6aSNate Lawson  * DESCRIPTION: Implement the ACCESS_AS ASL keyword.
32253289f6aSNate Lawson  *
32353289f6aSNate Lawson  ******************************************************************************/
32453289f6aSNate Lawson 
325fba7fc7eSJung-uk Kim static void
32653289f6aSNate Lawson OpcDoAccessAs (
32753289f6aSNate Lawson     ACPI_PARSE_OBJECT       *Op)
32853289f6aSNate Lawson {
3293f0275a0SJung-uk Kim     ACPI_PARSE_OBJECT       *TypeOp;
3303f0275a0SJung-uk Kim     ACPI_PARSE_OBJECT       *AttribOp;
3313f0275a0SJung-uk Kim     ACPI_PARSE_OBJECT       *LengthOp;
3323f0275a0SJung-uk Kim     UINT8                   Attribute;
33353289f6aSNate Lawson 
33453289f6aSNate Lawson 
33553289f6aSNate Lawson     Op->Asl.AmlOpcodeLength = 1;
3363f0275a0SJung-uk Kim     TypeOp = Op->Asl.Child;
33753289f6aSNate Lawson 
33853289f6aSNate Lawson     /* First child is the access type */
33953289f6aSNate Lawson 
3403f0275a0SJung-uk Kim     TypeOp->Asl.AmlOpcode = AML_RAW_DATA_BYTE;
3413f0275a0SJung-uk Kim     TypeOp->Asl.ParseOpcode = PARSEOP_RAW_DATA;
34253289f6aSNate Lawson 
34353289f6aSNate Lawson     /* Second child is the optional access attribute */
34453289f6aSNate Lawson 
3453f0275a0SJung-uk Kim     AttribOp = TypeOp->Asl.Next;
3463f0275a0SJung-uk Kim     if (AttribOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
34753289f6aSNate Lawson     {
3483f0275a0SJung-uk Kim         AttribOp->Asl.Value.Integer = 0;
34953289f6aSNate Lawson     }
350*f8146b88SJung-uk Kim 
3513f0275a0SJung-uk Kim     AttribOp->Asl.AmlOpcode = AML_RAW_DATA_BYTE;
3523f0275a0SJung-uk Kim     AttribOp->Asl.ParseOpcode = PARSEOP_RAW_DATA;
3533f0275a0SJung-uk Kim 
3543f0275a0SJung-uk Kim     /* Only a few AccessAttributes support AccessLength */
3553f0275a0SJung-uk Kim 
3563f0275a0SJung-uk Kim     Attribute = (UINT8) AttribOp->Asl.Value.Integer;
3573f0275a0SJung-uk Kim     if ((Attribute != AML_FIELD_ATTRIB_MULTIBYTE) &&
3583f0275a0SJung-uk Kim         (Attribute != AML_FIELD_ATTRIB_RAW_BYTES) &&
3593f0275a0SJung-uk Kim         (Attribute != AML_FIELD_ATTRIB_RAW_PROCESS))
3603f0275a0SJung-uk Kim     {
3613f0275a0SJung-uk Kim         return;
3623f0275a0SJung-uk Kim     }
3633f0275a0SJung-uk Kim 
3643f0275a0SJung-uk Kim     Op->Asl.AmlOpcode = AML_FIELD_EXT_ACCESS_OP;
3653f0275a0SJung-uk Kim 
3663f0275a0SJung-uk Kim     /*
3673f0275a0SJung-uk Kim      * Child of Attributes is the AccessLength (required for Multibyte,
3683f0275a0SJung-uk Kim      * RawBytes, RawProcess.)
3693f0275a0SJung-uk Kim      */
3703f0275a0SJung-uk Kim     LengthOp = AttribOp->Asl.Child;
3713f0275a0SJung-uk Kim     if (!LengthOp)
3723f0275a0SJung-uk Kim     {
3733f0275a0SJung-uk Kim         return;
3743f0275a0SJung-uk Kim     }
3753f0275a0SJung-uk Kim 
3763f0275a0SJung-uk Kim     /* TBD: probably can remove */
3773f0275a0SJung-uk Kim 
3783f0275a0SJung-uk Kim     if (LengthOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
3793f0275a0SJung-uk Kim     {
3803f0275a0SJung-uk Kim         LengthOp->Asl.Value.Integer = 16;
3813f0275a0SJung-uk Kim     }
3823f0275a0SJung-uk Kim 
3833f0275a0SJung-uk Kim     LengthOp->Asl.AmlOpcode = AML_RAW_DATA_BYTE;
3843f0275a0SJung-uk Kim     LengthOp->Asl.ParseOpcode = PARSEOP_RAW_DATA;
3853f0275a0SJung-uk Kim }
3863f0275a0SJung-uk Kim 
3873f0275a0SJung-uk Kim 
3883f0275a0SJung-uk Kim /*******************************************************************************
3893f0275a0SJung-uk Kim  *
3903f0275a0SJung-uk Kim  * FUNCTION:    OpcDoConnection
3913f0275a0SJung-uk Kim  *
3923f0275a0SJung-uk Kim  * PARAMETERS:  Op        - Parse node
3933f0275a0SJung-uk Kim  *
3943f0275a0SJung-uk Kim  * RETURN:      None
3953f0275a0SJung-uk Kim  *
3963f0275a0SJung-uk Kim  * DESCRIPTION: Implement the Connection ASL keyword.
3973f0275a0SJung-uk Kim  *
3983f0275a0SJung-uk Kim  ******************************************************************************/
3993f0275a0SJung-uk Kim 
4003f0275a0SJung-uk Kim static void
4013f0275a0SJung-uk Kim OpcDoConnection (
4023f0275a0SJung-uk Kim     ACPI_PARSE_OBJECT       *Op)
4033f0275a0SJung-uk Kim {
4043f0275a0SJung-uk Kim     ASL_RESOURCE_NODE       *Rnode;
4053f0275a0SJung-uk Kim     ACPI_PARSE_OBJECT       *BufferOp;
4063f0275a0SJung-uk Kim     ACPI_PARSE_OBJECT       *BufferLengthOp;
4073f0275a0SJung-uk Kim     ACPI_PARSE_OBJECT       *BufferDataOp;
408313a0c13SJung-uk Kim     ASL_RESOURCE_INFO       Info;
4093f0275a0SJung-uk Kim     UINT8                   State;
4103f0275a0SJung-uk Kim 
4113f0275a0SJung-uk Kim 
4123f0275a0SJung-uk Kim     Op->Asl.AmlOpcodeLength = 1;
4133f0275a0SJung-uk Kim 
4143f0275a0SJung-uk Kim     if (Op->Asl.Child->Asl.AmlOpcode == AML_INT_NAMEPATH_OP)
4153f0275a0SJung-uk Kim     {
4163f0275a0SJung-uk Kim         return;
4173f0275a0SJung-uk Kim     }
4183f0275a0SJung-uk Kim 
4193f0275a0SJung-uk Kim     BufferOp = Op->Asl.Child;
4203f0275a0SJung-uk Kim     BufferLengthOp = BufferOp->Asl.Child;
4213f0275a0SJung-uk Kim     BufferDataOp = BufferLengthOp->Asl.Next;
4223f0275a0SJung-uk Kim 
423313a0c13SJung-uk Kim     Info.DescriptorTypeOp = BufferDataOp->Asl.Next;
424313a0c13SJung-uk Kim     Info.CurrentByteOffset = 0;
4253f0275a0SJung-uk Kim     State = ACPI_RSTATE_NORMAL;
426313a0c13SJung-uk Kim     Rnode = RsDoOneResourceDescriptor (&Info, &State);
4273f0275a0SJung-uk Kim     if (!Rnode)
4283f0275a0SJung-uk Kim     {
4293f0275a0SJung-uk Kim         return; /* error */
4303f0275a0SJung-uk Kim     }
4313f0275a0SJung-uk Kim 
4323f0275a0SJung-uk Kim     /*
4333f0275a0SJung-uk Kim      * Transform the nodes into the following
4343f0275a0SJung-uk Kim      *
4353f0275a0SJung-uk Kim      * Op           -> AML_BUFFER_OP
4363f0275a0SJung-uk Kim      * First Child  -> BufferLength
4373f0275a0SJung-uk Kim      * Second Child -> Descriptor Buffer (raw byte data)
4383f0275a0SJung-uk Kim      */
4393f0275a0SJung-uk Kim     BufferOp->Asl.ParseOpcode = PARSEOP_BUFFER;
4403f0275a0SJung-uk Kim     BufferOp->Asl.AmlOpcode = AML_BUFFER_OP;
4413f0275a0SJung-uk Kim     BufferOp->Asl.CompileFlags = NODE_AML_PACKAGE | NODE_IS_RESOURCE_DESC;
4423f0275a0SJung-uk Kim     UtSetParseOpName (BufferOp);
4433f0275a0SJung-uk Kim 
4443f0275a0SJung-uk Kim     BufferLengthOp->Asl.ParseOpcode = PARSEOP_INTEGER;
4453f0275a0SJung-uk Kim     BufferLengthOp->Asl.Value.Integer = Rnode->BufferLength;
4463f0275a0SJung-uk Kim     (void) OpcSetOptimalIntegerSize (BufferLengthOp);
4473f0275a0SJung-uk Kim     UtSetParseOpName (BufferLengthOp);
4483f0275a0SJung-uk Kim 
4493f0275a0SJung-uk Kim     BufferDataOp->Asl.ParseOpcode = PARSEOP_RAW_DATA;
4503f0275a0SJung-uk Kim     BufferDataOp->Asl.AmlOpcode = AML_RAW_DATA_CHAIN;
4513f0275a0SJung-uk Kim     BufferDataOp->Asl.AmlOpcodeLength = 0;
4523f0275a0SJung-uk Kim     BufferDataOp->Asl.AmlLength = Rnode->BufferLength;
4533f0275a0SJung-uk Kim     BufferDataOp->Asl.Value.Buffer = (UINT8 *) Rnode;
4543f0275a0SJung-uk Kim     UtSetParseOpName (BufferDataOp);
45553289f6aSNate Lawson }
45653289f6aSNate Lawson 
45753289f6aSNate Lawson 
45853289f6aSNate Lawson /*******************************************************************************
45953289f6aSNate Lawson  *
46053289f6aSNate Lawson  * FUNCTION:    OpcDoUnicode
46153289f6aSNate Lawson  *
46253289f6aSNate Lawson  * PARAMETERS:  Op        - Parse node
46353289f6aSNate Lawson  *
46453289f6aSNate Lawson  * RETURN:      None
46553289f6aSNate Lawson  *
46653289f6aSNate Lawson  * DESCRIPTION: Implement the UNICODE ASL "macro".  Convert the input string
46753289f6aSNate Lawson  *              to a unicode buffer. There is no Unicode AML opcode.
46853289f6aSNate Lawson  *
46953289f6aSNate Lawson  * Note:  The Unicode string is 16 bits per character, no leading signature,
47053289f6aSNate Lawson  *        with a 16-bit terminating NULL.
47153289f6aSNate Lawson  *
47253289f6aSNate Lawson  ******************************************************************************/
47353289f6aSNate Lawson 
474fba7fc7eSJung-uk Kim static void
47553289f6aSNate Lawson OpcDoUnicode (
47653289f6aSNate Lawson     ACPI_PARSE_OBJECT       *Op)
47753289f6aSNate Lawson {
47853289f6aSNate Lawson     ACPI_PARSE_OBJECT       *InitializerOp;
47953289f6aSNate Lawson     UINT32                  Length;
48053289f6aSNate Lawson     UINT32                  Count;
48153289f6aSNate Lawson     UINT32                  i;
48253289f6aSNate Lawson     UINT8                   *AsciiString;
48353289f6aSNate Lawson     UINT16                  *UnicodeString;
48453289f6aSNate Lawson     ACPI_PARSE_OBJECT       *BufferLengthOp;
48553289f6aSNate Lawson 
48653289f6aSNate Lawson 
48753289f6aSNate Lawson     /* Change op into a buffer object */
48853289f6aSNate Lawson 
48953289f6aSNate Lawson     Op->Asl.CompileFlags &= ~NODE_COMPILE_TIME_CONST;
49053289f6aSNate Lawson     Op->Asl.ParseOpcode = PARSEOP_BUFFER;
49153289f6aSNate Lawson     UtSetParseOpName (Op);
49253289f6aSNate Lawson 
49353289f6aSNate Lawson     /* Buffer Length is first, followed by the string */
49453289f6aSNate Lawson 
49553289f6aSNate Lawson     BufferLengthOp = Op->Asl.Child;
49653289f6aSNate Lawson     InitializerOp = BufferLengthOp->Asl.Next;
49753289f6aSNate Lawson 
49853289f6aSNate Lawson     AsciiString = (UINT8 *) InitializerOp->Asl.Value.String;
49953289f6aSNate Lawson 
50053289f6aSNate Lawson     /* Create a new buffer for the Unicode string */
50153289f6aSNate Lawson 
50253289f6aSNate Lawson     Count = strlen (InitializerOp->Asl.Value.String) + 1;
50353289f6aSNate Lawson     Length = Count * sizeof (UINT16);
50453289f6aSNate Lawson     UnicodeString = UtLocalCalloc (Length);
50553289f6aSNate Lawson 
50653289f6aSNate Lawson     /* Convert to Unicode string (including null terminator) */
50753289f6aSNate Lawson 
50853289f6aSNate Lawson     for (i = 0; i < Count; i++)
50953289f6aSNate Lawson     {
51053289f6aSNate Lawson         UnicodeString[i] = (UINT16) AsciiString[i];
51153289f6aSNate Lawson     }
51253289f6aSNate Lawson 
51353289f6aSNate Lawson     /*
51453289f6aSNate Lawson      * Just set the buffer size node to be the buffer length, regardless
51553289f6aSNate Lawson      * of whether it was previously an integer or a default_arg placeholder
51653289f6aSNate Lawson      */
51753289f6aSNate Lawson     BufferLengthOp->Asl.ParseOpcode = PARSEOP_INTEGER;
51853289f6aSNate Lawson     BufferLengthOp->Asl.AmlOpcode = AML_DWORD_OP;
51953289f6aSNate Lawson     BufferLengthOp->Asl.Value.Integer = Length;
52053289f6aSNate Lawson     UtSetParseOpName (BufferLengthOp);
52153289f6aSNate Lawson 
52253289f6aSNate Lawson     (void) OpcSetOptimalIntegerSize (BufferLengthOp);
52353289f6aSNate Lawson 
52453289f6aSNate Lawson     /* The Unicode string is a raw data buffer */
52553289f6aSNate Lawson 
52653289f6aSNate Lawson     InitializerOp->Asl.Value.Buffer = (UINT8 *) UnicodeString;
52753289f6aSNate Lawson     InitializerOp->Asl.AmlOpcode = AML_RAW_DATA_BUFFER;
52853289f6aSNate Lawson     InitializerOp->Asl.AmlLength = Length;
52953289f6aSNate Lawson     InitializerOp->Asl.ParseOpcode = PARSEOP_RAW_DATA;
53053289f6aSNate Lawson     InitializerOp->Asl.Child = NULL;
53153289f6aSNate Lawson     UtSetParseOpName (InitializerOp);
53253289f6aSNate Lawson }
53353289f6aSNate Lawson 
53453289f6aSNate Lawson 
53553289f6aSNate Lawson /*******************************************************************************
53653289f6aSNate Lawson  *
53753289f6aSNate Lawson  * FUNCTION:    OpcDoEisaId
53853289f6aSNate Lawson  *
53953289f6aSNate Lawson  * PARAMETERS:  Op        - Parse node
54053289f6aSNate Lawson  *
54153289f6aSNate Lawson  * RETURN:      None
54253289f6aSNate Lawson  *
54353289f6aSNate Lawson  * DESCRIPTION: Convert a string EISA ID to numeric representation. See the
54453289f6aSNate Lawson  *              Pnp BIOS Specification for details. Here is an excerpt:
54553289f6aSNate Lawson  *
54653289f6aSNate Lawson  *              A seven character ASCII representation of the product
54753289f6aSNate Lawson  *              identifier compressed into a 32-bit identifier. The seven
54853289f6aSNate Lawson  *              character ID consists of a three character manufacturer code,
54953289f6aSNate Lawson  *              a three character hexadecimal product identifier, and a one
55053289f6aSNate Lawson  *              character hexadecimal revision number. The manufacturer code
55153289f6aSNate Lawson  *              is a 3 uppercase character code that is compressed into 3 5-bit
55253289f6aSNate Lawson  *              values as follows:
55353289f6aSNate Lawson  *                  1) Find hex ASCII value for each letter
55453289f6aSNate Lawson  *                  2) Subtract 40h from each ASCII value
5558ef1a331SJung-uk Kim  *                  3) Retain 5 least significant bits for each letter by
55653289f6aSNate Lawson  *                     discarding upper 3 bits because they are always 0.
55753289f6aSNate Lawson  *                  4) Compressed code = concatenate 0 and the 3 5-bit values
55853289f6aSNate Lawson  *
55953289f6aSNate Lawson  *              The format of the compressed product identifier is as follows:
56053289f6aSNate Lawson  *              Byte 0: Bit 7       - Reserved (0)
56153289f6aSNate Lawson  *                      Bits 6-2:   - 1st character of compressed mfg code
56253289f6aSNate Lawson  *                      Bits 1-0    - Upper 2 bits of 2nd character of mfg code
56353289f6aSNate Lawson  *              Byte 1: Bits 7-5    - Lower 3 bits of 2nd character of mfg code
56453289f6aSNate Lawson  *                      Bits 4-0    - 3rd character of mfg code
56553289f6aSNate Lawson  *              Byte 2: Bits 7-4    - 1st hex digit of product number
56653289f6aSNate Lawson  *                      Bits 3-0    - 2nd hex digit of product number
56753289f6aSNate Lawson  *              Byte 3: Bits 7-4    - 3st hex digit of product number
56853289f6aSNate Lawson  *                      Bits 3-0    - Hex digit of the revision number
56953289f6aSNate Lawson  *
57053289f6aSNate Lawson  ******************************************************************************/
57153289f6aSNate Lawson 
572fba7fc7eSJung-uk Kim static void
57353289f6aSNate Lawson OpcDoEisaId (
57453289f6aSNate Lawson     ACPI_PARSE_OBJECT       *Op)
57553289f6aSNate Lawson {
57653289f6aSNate Lawson     UINT32                  EisaId = 0;
57753289f6aSNate Lawson     UINT32                  BigEndianId;
57853289f6aSNate Lawson     char                    *InString;
57953289f6aSNate Lawson     ACPI_STATUS             Status = AE_OK;
580a9f12690SJung-uk Kim     UINT32                  i;
58153289f6aSNate Lawson 
58253289f6aSNate Lawson 
58353289f6aSNate Lawson     InString = (char *) Op->Asl.Value.String;
58453289f6aSNate Lawson 
58553289f6aSNate Lawson     /*
58653289f6aSNate Lawson      * The EISAID string must be exactly 7 characters and of the form
587fba7fc7eSJung-uk Kim      * "UUUXXXX" -- 3 uppercase letters and 4 hex digits (e.g., "PNP0001")
58853289f6aSNate Lawson      */
5895ef50723SJung-uk Kim     if (strlen (InString) != 7)
59053289f6aSNate Lawson     {
59153289f6aSNate Lawson         Status = AE_BAD_PARAMETER;
59253289f6aSNate Lawson     }
59353289f6aSNate Lawson     else
59453289f6aSNate Lawson     {
59553289f6aSNate Lawson         /* Check all 7 characters for correct format */
59653289f6aSNate Lawson 
59753289f6aSNate Lawson         for (i = 0; i < 7; i++)
59853289f6aSNate Lawson         {
599c8466860SMark Santcroos             /* First 3 characters must be uppercase letters */
60053289f6aSNate Lawson 
60153289f6aSNate Lawson             if (i < 3)
60253289f6aSNate Lawson             {
6039a179dd8SJung-uk Kim                 if (!isupper ((int) InString[i]))
60453289f6aSNate Lawson                 {
60553289f6aSNate Lawson                     Status = AE_BAD_PARAMETER;
60653289f6aSNate Lawson                 }
60753289f6aSNate Lawson             }
60853289f6aSNate Lawson 
60953289f6aSNate Lawson             /* Last 4 characters must be hex digits */
61053289f6aSNate Lawson 
6119a179dd8SJung-uk Kim             else if (!isxdigit ((int) InString[i]))
61253289f6aSNate Lawson             {
61353289f6aSNate Lawson                 Status = AE_BAD_PARAMETER;
61453289f6aSNate Lawson             }
61553289f6aSNate Lawson         }
61653289f6aSNate Lawson     }
61753289f6aSNate Lawson 
61853289f6aSNate Lawson     if (ACPI_FAILURE (Status))
61953289f6aSNate Lawson     {
62053289f6aSNate Lawson         AslError (ASL_ERROR, ASL_MSG_INVALID_EISAID, Op, Op->Asl.Value.String);
62153289f6aSNate Lawson     }
62253289f6aSNate Lawson     else
62353289f6aSNate Lawson     {
62453289f6aSNate Lawson         /* Create ID big-endian first (bits are contiguous) */
62553289f6aSNate Lawson 
6261a39cfb0SJung-uk Kim         BigEndianId =
62742fecd12SJung-uk Kim             (UINT32) ((UINT8) (InString[0] - 0x40)) << 26 |
62842fecd12SJung-uk Kim             (UINT32) ((UINT8) (InString[1] - 0x40)) << 21 |
62942fecd12SJung-uk Kim             (UINT32) ((UINT8) (InString[2] - 0x40)) << 16 |
63053289f6aSNate Lawson 
631313a0c13SJung-uk Kim             (AcpiUtAsciiCharToHex (InString[3])) << 12 |
632313a0c13SJung-uk Kim             (AcpiUtAsciiCharToHex (InString[4])) << 8  |
633313a0c13SJung-uk Kim             (AcpiUtAsciiCharToHex (InString[5])) << 4  |
634313a0c13SJung-uk Kim              AcpiUtAsciiCharToHex (InString[6]);
63553289f6aSNate Lawson 
63653289f6aSNate Lawson         /* Swap to little-endian to get final ID (see function header) */
63753289f6aSNate Lawson 
63853289f6aSNate Lawson         EisaId = AcpiUtDwordByteSwap (BigEndianId);
63953289f6aSNate Lawson     }
64053289f6aSNate Lawson 
64153289f6aSNate Lawson     /*
64253289f6aSNate Lawson      * Morph the Op into an integer, regardless of whether there
64353289f6aSNate Lawson      * was an error in the EISAID string
64453289f6aSNate Lawson      */
64553289f6aSNate Lawson     Op->Asl.Value.Integer = EisaId;
64653289f6aSNate Lawson 
64753289f6aSNate Lawson     Op->Asl.CompileFlags &= ~NODE_COMPILE_TIME_CONST;
64853289f6aSNate Lawson     Op->Asl.ParseOpcode = PARSEOP_INTEGER;
64953289f6aSNate Lawson     (void) OpcSetOptimalIntegerSize (Op);
65053289f6aSNate Lawson 
65153289f6aSNate Lawson     /* Op is now an integer */
65253289f6aSNate Lawson 
65353289f6aSNate Lawson     UtSetParseOpName (Op);
65453289f6aSNate Lawson }
65553289f6aSNate Lawson 
65653289f6aSNate Lawson 
65753289f6aSNate Lawson /*******************************************************************************
65853289f6aSNate Lawson  *
6593f0275a0SJung-uk Kim  * FUNCTION:    OpcDoUuId
660c8466860SMark Santcroos  *
661c8466860SMark Santcroos  * PARAMETERS:  Op                  - Parse node
662c8466860SMark Santcroos  *
663c8466860SMark Santcroos  * RETURN:      None
664c8466860SMark Santcroos  *
665fba7fc7eSJung-uk Kim  * DESCRIPTION: Convert UUID string to 16-byte buffer
666c8466860SMark Santcroos  *
667c8466860SMark Santcroos  ******************************************************************************/
668c8466860SMark Santcroos 
669fba7fc7eSJung-uk Kim static void
670c8466860SMark Santcroos OpcDoUuId (
671c8466860SMark Santcroos     ACPI_PARSE_OBJECT       *Op)
672c8466860SMark Santcroos {
673c8466860SMark Santcroos     char                    *InString;
674313a0c13SJung-uk Kim     UINT8                   *Buffer;
675c8466860SMark Santcroos     ACPI_STATUS             Status = AE_OK;
676c8466860SMark Santcroos     ACPI_PARSE_OBJECT       *NewOp;
677c8466860SMark Santcroos 
678c8466860SMark Santcroos 
6791c0e1b6dSJung-uk Kim     InString = ACPI_CAST_PTR (char, Op->Asl.Value.String);
680c8466860SMark Santcroos     Buffer = UtLocalCalloc (16);
681c8466860SMark Santcroos 
682d244b227SJung-uk Kim     Status = AuValidateUuid (InString);
683c8466860SMark Santcroos     if (ACPI_FAILURE (Status))
684c8466860SMark Santcroos     {
685c8466860SMark Santcroos         AslError (ASL_ERROR, ASL_MSG_INVALID_UUID, Op, Op->Asl.Value.String);
686c8466860SMark Santcroos     }
687d244b227SJung-uk Kim     else
688c8466860SMark Santcroos     {
689313a0c13SJung-uk Kim         AcpiUtConvertStringToUuid (InString, Buffer);
690c8466860SMark Santcroos     }
691c8466860SMark Santcroos 
692c8466860SMark Santcroos     /* Change Op to a Buffer */
693c8466860SMark Santcroos 
694c8466860SMark Santcroos     Op->Asl.ParseOpcode = PARSEOP_BUFFER;
695c8466860SMark Santcroos     Op->Common.AmlOpcode = AML_BUFFER_OP;
696fba7fc7eSJung-uk Kim 
697fba7fc7eSJung-uk Kim     /* Disable further optimization */
698fba7fc7eSJung-uk Kim 
699fba7fc7eSJung-uk Kim     Op->Asl.CompileFlags &= ~NODE_COMPILE_TIME_CONST;
700c8466860SMark Santcroos     UtSetParseOpName (Op);
701c8466860SMark Santcroos 
702c8466860SMark Santcroos     /* Child node is the buffer length */
703c8466860SMark Santcroos 
704c8466860SMark Santcroos     NewOp = TrAllocateNode (PARSEOP_INTEGER);
705c8466860SMark Santcroos 
706c8466860SMark Santcroos     NewOp->Asl.AmlOpcode = AML_BYTE_OP;
707c8466860SMark Santcroos     NewOp->Asl.Value.Integer = 16;
708c8466860SMark Santcroos     NewOp->Asl.Parent = Op;
709c8466860SMark Santcroos 
710c8466860SMark Santcroos     Op->Asl.Child = NewOp;
711c8466860SMark Santcroos     Op = NewOp;
712c8466860SMark Santcroos 
713c8466860SMark Santcroos     /* Peer to the child is the raw buffer data */
714c8466860SMark Santcroos 
715c8466860SMark Santcroos     NewOp = TrAllocateNode (PARSEOP_RAW_DATA);
716c8466860SMark Santcroos     NewOp->Asl.AmlOpcode = AML_RAW_DATA_BUFFER;
717c8466860SMark Santcroos     NewOp->Asl.AmlLength = 16;
7181c0e1b6dSJung-uk Kim     NewOp->Asl.Value.String = ACPI_CAST_PTR (char, Buffer);
719c8466860SMark Santcroos     NewOp->Asl.Parent = Op->Asl.Parent;
720c8466860SMark Santcroos 
721c8466860SMark Santcroos     Op->Asl.Next = NewOp;
722c8466860SMark Santcroos }
723c8466860SMark Santcroos 
724c8466860SMark Santcroos 
725c8466860SMark Santcroos /*******************************************************************************
726c8466860SMark Santcroos  *
72753289f6aSNate Lawson  * FUNCTION:    OpcGenerateAmlOpcode
72853289f6aSNate Lawson  *
72953289f6aSNate Lawson  * PARAMETERS:  Op                  - Parse node
73053289f6aSNate Lawson  *
73153289f6aSNate Lawson  * RETURN:      None
73253289f6aSNate Lawson  *
73353289f6aSNate Lawson  * DESCRIPTION: Generate the AML opcode associated with the node and its
73453289f6aSNate Lawson  *              parse (lex/flex) keyword opcode. Essentially implements
73553289f6aSNate Lawson  *              a mapping between the parse opcodes and the actual AML opcodes.
73653289f6aSNate Lawson  *
73753289f6aSNate Lawson  ******************************************************************************/
73853289f6aSNate Lawson 
73953289f6aSNate Lawson void
74053289f6aSNate Lawson OpcGenerateAmlOpcode (
74153289f6aSNate Lawson     ACPI_PARSE_OBJECT       *Op)
74253289f6aSNate Lawson {
74353289f6aSNate Lawson     UINT16                  Index;
74453289f6aSNate Lawson 
74553289f6aSNate Lawson 
74653289f6aSNate Lawson     Index = (UINT16) (Op->Asl.ParseOpcode - ASL_PARSE_OPCODE_BASE);
74753289f6aSNate Lawson 
74853289f6aSNate Lawson     Op->Asl.AmlOpcode     = AslKeywordMapping[Index].AmlOpcode;
74953289f6aSNate Lawson     Op->Asl.AcpiBtype     = AslKeywordMapping[Index].AcpiBtype;
75053289f6aSNate Lawson     Op->Asl.CompileFlags |= AslKeywordMapping[Index].Flags;
75153289f6aSNate Lawson 
75253289f6aSNate Lawson     if (!Op->Asl.Value.Integer)
75353289f6aSNate Lawson     {
75453289f6aSNate Lawson         Op->Asl.Value.Integer = AslKeywordMapping[Index].Value;
75553289f6aSNate Lawson     }
75653289f6aSNate Lawson 
75753289f6aSNate Lawson     /* Special handling for some opcodes */
75853289f6aSNate Lawson 
75953289f6aSNate Lawson     switch (Op->Asl.ParseOpcode)
76053289f6aSNate Lawson     {
76153289f6aSNate Lawson     case PARSEOP_INTEGER:
76253289f6aSNate Lawson         /*
76353289f6aSNate Lawson          * Set the opcode based on the size of the integer
76453289f6aSNate Lawson          */
76553289f6aSNate Lawson         (void) OpcSetOptimalIntegerSize (Op);
76653289f6aSNate Lawson         break;
76753289f6aSNate Lawson 
76853289f6aSNate Lawson     case PARSEOP_OFFSET:
76953289f6aSNate Lawson 
77053289f6aSNate Lawson         Op->Asl.AmlOpcodeLength = 1;
77153289f6aSNate Lawson         break;
77253289f6aSNate Lawson 
77353289f6aSNate Lawson     case PARSEOP_ACCESSAS:
77453289f6aSNate Lawson 
77553289f6aSNate Lawson         OpcDoAccessAs (Op);
77653289f6aSNate Lawson         break;
77753289f6aSNate Lawson 
7783f0275a0SJung-uk Kim     case PARSEOP_CONNECTION:
7793f0275a0SJung-uk Kim 
7803f0275a0SJung-uk Kim         OpcDoConnection (Op);
7813f0275a0SJung-uk Kim         break;
7823f0275a0SJung-uk Kim 
78353289f6aSNate Lawson     case PARSEOP_EISAID:
78453289f6aSNate Lawson 
78553289f6aSNate Lawson         OpcDoEisaId (Op);
78653289f6aSNate Lawson         break;
78753289f6aSNate Lawson 
7881c0e1b6dSJung-uk Kim     case PARSEOP_PRINTF:
7891c0e1b6dSJung-uk Kim 
7901c0e1b6dSJung-uk Kim         OpcDoPrintf (Op);
7911c0e1b6dSJung-uk Kim         break;
7921c0e1b6dSJung-uk Kim 
7931c0e1b6dSJung-uk Kim     case PARSEOP_FPRINTF:
7941c0e1b6dSJung-uk Kim 
7951c0e1b6dSJung-uk Kim         OpcDoFprintf (Op);
7961c0e1b6dSJung-uk Kim         break;
7971c0e1b6dSJung-uk Kim 
7981c0e1b6dSJung-uk Kim     case PARSEOP_TOPLD:
7991c0e1b6dSJung-uk Kim 
8001c0e1b6dSJung-uk Kim         OpcDoPld (Op);
8011c0e1b6dSJung-uk Kim         break;
8021c0e1b6dSJung-uk Kim 
803c8466860SMark Santcroos     case PARSEOP_TOUUID:
804c8466860SMark Santcroos 
805c8466860SMark Santcroos         OpcDoUuId (Op);
806c8466860SMark Santcroos         break;
807c8466860SMark Santcroos 
80853289f6aSNate Lawson     case PARSEOP_UNICODE:
80953289f6aSNate Lawson 
81053289f6aSNate Lawson         OpcDoUnicode (Op);
81153289f6aSNate Lawson         break;
81253289f6aSNate Lawson 
81353289f6aSNate Lawson     case PARSEOP_INCLUDE:
81453289f6aSNate Lawson 
81553289f6aSNate Lawson         Gbl_HasIncludeFiles = TRUE;
81653289f6aSNate Lawson         break;
81753289f6aSNate Lawson 
81853289f6aSNate Lawson     case PARSEOP_EXTERNAL:
81953289f6aSNate Lawson 
820*f8146b88SJung-uk Kim         if (Gbl_DoExternals == FALSE)
821*f8146b88SJung-uk Kim         {
82253289f6aSNate Lawson             Op->Asl.Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
82353289f6aSNate Lawson             Op->Asl.Child->Asl.Next->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
824*f8146b88SJung-uk Kim         }
82553289f6aSNate Lawson         break;
82653289f6aSNate Lawson 
827efcc2a30SJung-uk Kim     case PARSEOP_TIMER:
828efcc2a30SJung-uk Kim 
829efcc2a30SJung-uk Kim         if (AcpiGbl_IntegerBitWidth == 32)
830efcc2a30SJung-uk Kim         {
831efcc2a30SJung-uk Kim             AslError (ASL_REMARK, ASL_MSG_TRUNCATION, Op, NULL);
832efcc2a30SJung-uk Kim         }
833efcc2a30SJung-uk Kim         break;
834efcc2a30SJung-uk Kim 
83553289f6aSNate Lawson     default:
836a9d8d09cSJung-uk Kim 
83753289f6aSNate Lawson         /* Nothing to do for other opcodes */
838a9d8d09cSJung-uk Kim 
83953289f6aSNate Lawson         break;
84053289f6aSNate Lawson     }
84153289f6aSNate Lawson 
84253289f6aSNate Lawson     return;
84353289f6aSNate Lawson }
844