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