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