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