Home | History | Annotate | Line # | Download | only in compiler
aslopcodes.c revision 1.2
      1 /******************************************************************************
      2  *
      3  * Module Name: aslopcode - AML opcode generation
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2015, 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_DEFINITIONBLOCK))
    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     if (Op->Asl.Value.Integer <= ACPI_UINT16_MAX)
    334     {
    335         Op->Asl.AmlOpcode = AML_WORD_OP;
    336         return (2);
    337     }
    338     if (Op->Asl.Value.Integer <= ACPI_UINT32_MAX)
    339     {
    340         Op->Asl.AmlOpcode = AML_DWORD_OP;
    341         return (4);
    342     }
    343     else
    344     {
    345         if (AcpiGbl_IntegerByteWidth == 4)
    346         {
    347             AslError (ASL_WARNING, ASL_MSG_INTEGER_LENGTH,
    348                 Op, NULL);
    349 
    350             if (!Gbl_IgnoreErrors)
    351             {
    352                 /* Truncate the integer to 32-bit */
    353                 Op->Asl.AmlOpcode = AML_DWORD_OP;
    354                 return (4);
    355             }
    356         }
    357 
    358         Op->Asl.AmlOpcode = AML_QWORD_OP;
    359         return (8);
    360     }
    361 }
    362 
    363 
    364 /*******************************************************************************
    365  *
    366  * FUNCTION:    OpcDoAccessAs
    367  *
    368  * PARAMETERS:  Op        - Parse node
    369  *
    370  * RETURN:      None
    371  *
    372  * DESCRIPTION: Implement the ACCESS_AS ASL keyword.
    373  *
    374  ******************************************************************************/
    375 
    376 static void
    377 OpcDoAccessAs (
    378     ACPI_PARSE_OBJECT       *Op)
    379 {
    380     ACPI_PARSE_OBJECT       *TypeOp;
    381     ACPI_PARSE_OBJECT       *AttribOp;
    382     ACPI_PARSE_OBJECT       *LengthOp;
    383     UINT8                   Attribute;
    384 
    385 
    386     Op->Asl.AmlOpcodeLength = 1;
    387     TypeOp = Op->Asl.Child;
    388 
    389     /* First child is the access type */
    390 
    391     TypeOp->Asl.AmlOpcode = AML_RAW_DATA_BYTE;
    392     TypeOp->Asl.ParseOpcode = PARSEOP_RAW_DATA;
    393 
    394     /* Second child is the optional access attribute */
    395 
    396     AttribOp = TypeOp->Asl.Next;
    397     if (AttribOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
    398     {
    399         AttribOp->Asl.Value.Integer = 0;
    400     }
    401     AttribOp->Asl.AmlOpcode = AML_RAW_DATA_BYTE;
    402     AttribOp->Asl.ParseOpcode = PARSEOP_RAW_DATA;
    403 
    404     /* Only a few AccessAttributes support AccessLength */
    405 
    406     Attribute = (UINT8) AttribOp->Asl.Value.Integer;
    407     if ((Attribute != AML_FIELD_ATTRIB_MULTIBYTE) &&
    408         (Attribute != AML_FIELD_ATTRIB_RAW_BYTES) &&
    409         (Attribute != AML_FIELD_ATTRIB_RAW_PROCESS))
    410     {
    411         return;
    412     }
    413 
    414     Op->Asl.AmlOpcode = AML_FIELD_EXT_ACCESS_OP;
    415 
    416     /*
    417      * Child of Attributes is the AccessLength (required for Multibyte,
    418      * RawBytes, RawProcess.)
    419      */
    420     LengthOp = AttribOp->Asl.Child;
    421     if (!LengthOp)
    422     {
    423         return;
    424     }
    425 
    426     /* TBD: probably can remove */
    427 
    428     if (LengthOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
    429     {
    430         LengthOp->Asl.Value.Integer = 16;
    431     }
    432 
    433     LengthOp->Asl.AmlOpcode = AML_RAW_DATA_BYTE;
    434     LengthOp->Asl.ParseOpcode = PARSEOP_RAW_DATA;
    435 }
    436 
    437 
    438 /*******************************************************************************
    439  *
    440  * FUNCTION:    OpcDoConnection
    441  *
    442  * PARAMETERS:  Op        - Parse node
    443  *
    444  * RETURN:      None
    445  *
    446  * DESCRIPTION: Implement the Connection ASL keyword.
    447  *
    448  ******************************************************************************/
    449 
    450 static void
    451 OpcDoConnection (
    452     ACPI_PARSE_OBJECT       *Op)
    453 {
    454     ASL_RESOURCE_NODE       *Rnode;
    455     ACPI_PARSE_OBJECT       *BufferOp;
    456     ACPI_PARSE_OBJECT       *BufferLengthOp;
    457     ACPI_PARSE_OBJECT       *BufferDataOp;
    458     ASL_RESOURCE_INFO       Info;
    459     UINT8                   State;
    460 
    461 
    462     Op->Asl.AmlOpcodeLength = 1;
    463 
    464     if (Op->Asl.Child->Asl.AmlOpcode == AML_INT_NAMEPATH_OP)
    465     {
    466         return;
    467     }
    468 
    469     BufferOp = Op->Asl.Child;
    470     BufferLengthOp = BufferOp->Asl.Child;
    471     BufferDataOp = BufferLengthOp->Asl.Next;
    472 
    473     Info.DescriptorTypeOp = BufferDataOp->Asl.Next;
    474     Info.CurrentByteOffset = 0;
    475     State = ACPI_RSTATE_NORMAL;
    476     Rnode = RsDoOneResourceDescriptor (&Info, &State);
    477     if (!Rnode)
    478     {
    479         return; /* error */
    480     }
    481 
    482     /*
    483      * Transform the nodes into the following
    484      *
    485      * Op           -> AML_BUFFER_OP
    486      * First Child  -> BufferLength
    487      * Second Child -> Descriptor Buffer (raw byte data)
    488      */
    489     BufferOp->Asl.ParseOpcode         = PARSEOP_BUFFER;
    490     BufferOp->Asl.AmlOpcode           = AML_BUFFER_OP;
    491     BufferOp->Asl.CompileFlags        = NODE_AML_PACKAGE | NODE_IS_RESOURCE_DESC;
    492     UtSetParseOpName (BufferOp);
    493 
    494     BufferLengthOp->Asl.ParseOpcode   = PARSEOP_INTEGER;
    495     BufferLengthOp->Asl.Value.Integer = Rnode->BufferLength;
    496     (void) OpcSetOptimalIntegerSize (BufferLengthOp);
    497     UtSetParseOpName (BufferLengthOp);
    498 
    499     BufferDataOp->Asl.ParseOpcode         = PARSEOP_RAW_DATA;
    500     BufferDataOp->Asl.AmlOpcode           = AML_RAW_DATA_CHAIN;
    501     BufferDataOp->Asl.AmlOpcodeLength     = 0;
    502     BufferDataOp->Asl.AmlLength           = Rnode->BufferLength;
    503     BufferDataOp->Asl.Value.Buffer        = (UINT8 *) Rnode;
    504     UtSetParseOpName (BufferDataOp);
    505 }
    506 
    507 
    508 /*******************************************************************************
    509  *
    510  * FUNCTION:    OpcDoUnicode
    511  *
    512  * PARAMETERS:  Op        - Parse node
    513  *
    514  * RETURN:      None
    515  *
    516  * DESCRIPTION: Implement the UNICODE ASL "macro".  Convert the input string
    517  *              to a unicode buffer. There is no Unicode AML opcode.
    518  *
    519  * Note:  The Unicode string is 16 bits per character, no leading signature,
    520  *        with a 16-bit terminating NULL.
    521  *
    522  ******************************************************************************/
    523 
    524 static void
    525 OpcDoUnicode (
    526     ACPI_PARSE_OBJECT       *Op)
    527 {
    528     ACPI_PARSE_OBJECT       *InitializerOp;
    529     UINT32                  Length;
    530     UINT32                  Count;
    531     UINT32                  i;
    532     UINT8                   *AsciiString;
    533     UINT16                  *UnicodeString;
    534     ACPI_PARSE_OBJECT       *BufferLengthOp;
    535 
    536 
    537     /* Change op into a buffer object */
    538 
    539     Op->Asl.CompileFlags &= ~NODE_COMPILE_TIME_CONST;
    540     Op->Asl.ParseOpcode = PARSEOP_BUFFER;
    541     UtSetParseOpName (Op);
    542 
    543     /* Buffer Length is first, followed by the string */
    544 
    545     BufferLengthOp = Op->Asl.Child;
    546     InitializerOp = BufferLengthOp->Asl.Next;
    547 
    548     AsciiString = (UINT8 *) InitializerOp->Asl.Value.String;
    549 
    550     /* Create a new buffer for the Unicode string */
    551 
    552     Count = strlen (InitializerOp->Asl.Value.String) + 1;
    553     Length = Count * sizeof (UINT16);
    554     UnicodeString = UtLocalCalloc (Length);
    555 
    556     /* Convert to Unicode string (including null terminator) */
    557 
    558     for (i = 0; i < Count; i++)
    559     {
    560         UnicodeString[i] = (UINT16) AsciiString[i];
    561     }
    562 
    563     /*
    564      * Just set the buffer size node to be the buffer length, regardless
    565      * of whether it was previously an integer or a default_arg placeholder
    566      */
    567     BufferLengthOp->Asl.ParseOpcode   = PARSEOP_INTEGER;
    568     BufferLengthOp->Asl.AmlOpcode     = AML_DWORD_OP;
    569     BufferLengthOp->Asl.Value.Integer = Length;
    570     UtSetParseOpName (BufferLengthOp);
    571 
    572     (void) OpcSetOptimalIntegerSize (BufferLengthOp);
    573 
    574     /* The Unicode string is a raw data buffer */
    575 
    576     InitializerOp->Asl.Value.Buffer   = (UINT8 *) UnicodeString;
    577     InitializerOp->Asl.AmlOpcode      = AML_RAW_DATA_BUFFER;
    578     InitializerOp->Asl.AmlLength      = Length;
    579     InitializerOp->Asl.ParseOpcode    = PARSEOP_RAW_DATA;
    580     InitializerOp->Asl.Child          = NULL;
    581     UtSetParseOpName (InitializerOp);
    582 }
    583 
    584 
    585 /*******************************************************************************
    586  *
    587  * FUNCTION:    OpcDoEisaId
    588  *
    589  * PARAMETERS:  Op        - Parse node
    590  *
    591  * RETURN:      None
    592  *
    593  * DESCRIPTION: Convert a string EISA ID to numeric representation. See the
    594  *              Pnp BIOS Specification for details. Here is an excerpt:
    595  *
    596  *              A seven character ASCII representation of the product
    597  *              identifier compressed into a 32-bit identifier. The seven
    598  *              character ID consists of a three character manufacturer code,
    599  *              a three character hexadecimal product identifier, and a one
    600  *              character hexadecimal revision number. The manufacturer code
    601  *              is a 3 uppercase character code that is compressed into 3 5-bit
    602  *              values as follows:
    603  *                  1) Find hex ASCII value for each letter
    604  *                  2) Subtract 40h from each ASCII value
    605  *                  3) Retain 5 least significant bits for each letter by
    606  *                     discarding upper 3 bits because they are always 0.
    607  *                  4) Compressed code = concatenate 0 and the 3 5-bit values
    608  *
    609  *              The format of the compressed product identifier is as follows:
    610  *              Byte 0: Bit 7       - Reserved (0)
    611  *                      Bits 6-2:   - 1st character of compressed mfg code
    612  *                      Bits 1-0    - Upper 2 bits of 2nd character of mfg code
    613  *              Byte 1: Bits 7-5    - Lower 3 bits of 2nd character of mfg code
    614  *                      Bits 4-0    - 3rd character of mfg code
    615  *              Byte 2: Bits 7-4    - 1st hex digit of product number
    616  *                      Bits 3-0    - 2nd hex digit of product number
    617  *              Byte 3: Bits 7-4    - 3st hex digit of product number
    618  *                      Bits 3-0    - Hex digit of the revision number
    619  *
    620  ******************************************************************************/
    621 
    622 static void
    623 OpcDoEisaId (
    624     ACPI_PARSE_OBJECT       *Op)
    625 {
    626     UINT32                  EisaId = 0;
    627     UINT32                  BigEndianId;
    628     char                    *InString;
    629     ACPI_STATUS             Status = AE_OK;
    630     UINT32                  i;
    631 
    632 
    633     InString = (char *) Op->Asl.Value.String;
    634 
    635     /*
    636      * The EISAID string must be exactly 7 characters and of the form
    637      * "UUUXXXX" -- 3 uppercase letters and 4 hex digits (e.g., "PNP0001")
    638      */
    639     if (ACPI_STRLEN (InString) != 7)
    640     {
    641         Status = AE_BAD_PARAMETER;
    642     }
    643     else
    644     {
    645         /* Check all 7 characters for correct format */
    646 
    647         for (i = 0; i < 7; i++)
    648         {
    649             /* First 3 characters must be uppercase letters */
    650 
    651             if (i < 3)
    652             {
    653                 if (!isupper ((int) InString[i]))
    654                 {
    655                     Status = AE_BAD_PARAMETER;
    656                 }
    657             }
    658 
    659             /* Last 4 characters must be hex digits */
    660 
    661             else if (!isxdigit ((int) InString[i]))
    662             {
    663                 Status = AE_BAD_PARAMETER;
    664             }
    665         }
    666     }
    667 
    668     if (ACPI_FAILURE (Status))
    669     {
    670         AslError (ASL_ERROR, ASL_MSG_INVALID_EISAID, Op, Op->Asl.Value.String);
    671     }
    672     else
    673     {
    674         /* Create ID big-endian first (bits are contiguous) */
    675 
    676         BigEndianId =
    677             (UINT32) ((UINT8) (InString[0] - 0x40)) << 26 |
    678             (UINT32) ((UINT8) (InString[1] - 0x40)) << 21 |
    679             (UINT32) ((UINT8) (InString[2] - 0x40)) << 16 |
    680 
    681             (AcpiUtAsciiCharToHex (InString[3])) << 12 |
    682             (AcpiUtAsciiCharToHex (InString[4])) << 8  |
    683             (AcpiUtAsciiCharToHex (InString[5])) << 4  |
    684              AcpiUtAsciiCharToHex (InString[6]);
    685 
    686         /* Swap to little-endian to get final ID (see function header) */
    687 
    688         EisaId = AcpiUtDwordByteSwap (BigEndianId);
    689     }
    690 
    691     /*
    692      * Morph the Op into an integer, regardless of whether there
    693      * was an error in the EISAID string
    694      */
    695     Op->Asl.Value.Integer = EisaId;
    696 
    697     Op->Asl.CompileFlags &= ~NODE_COMPILE_TIME_CONST;
    698     Op->Asl.ParseOpcode = PARSEOP_INTEGER;
    699     (void) OpcSetOptimalIntegerSize (Op);
    700 
    701     /* Op is now an integer */
    702 
    703     UtSetParseOpName (Op);
    704 }
    705 
    706 
    707 /*******************************************************************************
    708  *
    709  * FUNCTION:    OpcEncodePldBuffer
    710  *
    711  * PARAMETERS:  PldInfo             - _PLD buffer struct (Using local struct)
    712  *
    713  * RETURN:      Encode _PLD buffer suitable for return value from _PLD
    714  *
    715  * DESCRIPTION: Bit-packs a _PLD buffer struct.
    716  *
    717  ******************************************************************************/
    718 
    719 static UINT8 *
    720 OpcEncodePldBuffer (
    721     ACPI_PLD_INFO           *PldInfo)
    722 {
    723     UINT32                  *Buffer;
    724     UINT32                  Dword;
    725 
    726 
    727     Buffer = ACPI_ALLOCATE_ZEROED (ACPI_PLD_BUFFER_SIZE);
    728     if (!Buffer)
    729     {
    730         return (NULL);
    731     }
    732 
    733     /* First 32 bits */
    734 
    735     Dword = 0;
    736     ACPI_PLD_SET_REVISION       (&Dword, PldInfo->Revision);
    737     ACPI_PLD_SET_IGNORE_COLOR   (&Dword, PldInfo->IgnoreColor);
    738     ACPI_PLD_SET_RED            (&Dword, PldInfo->Red);
    739     ACPI_PLD_SET_GREEN          (&Dword, PldInfo->Green);
    740     ACPI_PLD_SET_BLUE           (&Dword, PldInfo->Blue);
    741     ACPI_MOVE_32_TO_32          (&Buffer[0], &Dword);
    742 
    743     /* Second 32 bits */
    744 
    745     Dword = 0;
    746     ACPI_PLD_SET_WIDTH          (&Dword, PldInfo->Width);
    747     ACPI_PLD_SET_HEIGHT         (&Dword, PldInfo->Height);
    748     ACPI_MOVE_32_TO_32          (&Buffer[1], &Dword);
    749 
    750     /* Third 32 bits */
    751 
    752     Dword = 0;
    753     ACPI_PLD_SET_USER_VISIBLE   (&Dword, PldInfo->UserVisible);
    754     ACPI_PLD_SET_DOCK           (&Dword, PldInfo->Dock);
    755     ACPI_PLD_SET_LID            (&Dword, PldInfo->Lid);
    756     ACPI_PLD_SET_PANEL          (&Dword, PldInfo->Panel);
    757     ACPI_PLD_SET_VERTICAL       (&Dword, PldInfo->VerticalPosition);
    758     ACPI_PLD_SET_HORIZONTAL     (&Dword, PldInfo->HorizontalPosition);
    759     ACPI_PLD_SET_SHAPE          (&Dword, PldInfo->Shape);
    760     ACPI_PLD_SET_ORIENTATION    (&Dword, PldInfo->GroupOrientation);
    761     ACPI_PLD_SET_TOKEN          (&Dword, PldInfo->GroupToken);
    762     ACPI_PLD_SET_POSITION       (&Dword, PldInfo->GroupPosition);
    763     ACPI_PLD_SET_BAY            (&Dword, PldInfo->Bay);
    764     ACPI_MOVE_32_TO_32          (&Buffer[2], &Dword);
    765 
    766     /* Fourth 32 bits */
    767 
    768     Dword = 0;
    769     ACPI_PLD_SET_EJECTABLE      (&Dword, PldInfo->Ejectable);
    770     ACPI_PLD_SET_OSPM_EJECT     (&Dword, PldInfo->OspmEjectRequired);
    771     ACPI_PLD_SET_CABINET        (&Dword, PldInfo->CabinetNumber);
    772     ACPI_PLD_SET_CARD_CAGE      (&Dword, PldInfo->CardCageNumber);
    773     ACPI_PLD_SET_REFERENCE      (&Dword, PldInfo->Reference);
    774     ACPI_PLD_SET_ROTATION       (&Dword, PldInfo->Rotation);
    775     ACPI_PLD_SET_ORDER          (&Dword, PldInfo->Order);
    776     ACPI_MOVE_32_TO_32          (&Buffer[3], &Dword);
    777 
    778     if (PldInfo->Revision >= 2)
    779     {
    780         /* Fifth 32 bits */
    781 
    782         Dword = 0;
    783         ACPI_PLD_SET_VERT_OFFSET    (&Dword, PldInfo->VerticalOffset);
    784         ACPI_PLD_SET_HORIZ_OFFSET   (&Dword, PldInfo->HorizontalOffset);
    785         ACPI_MOVE_32_TO_32          (&Buffer[4], &Dword);
    786     }
    787 
    788     return (ACPI_CAST_PTR (UINT8, Buffer));
    789 }
    790 
    791 
    792 /*******************************************************************************
    793  *
    794  * FUNCTION:    OpcStrupr (strupr)
    795  *
    796  * PARAMETERS:  SrcString           - The source string to convert
    797  *
    798  * RETURN:      None
    799  *
    800  * DESCRIPTION: Convert string to uppercase
    801  *
    802  * NOTE: This is not a POSIX function, so it appears here, not in utclib.c
    803  *
    804  ******************************************************************************/
    805 
    806 static void
    807 OpcStrupr (
    808     char                    *SrcString)
    809 {
    810     char                    *String;
    811 
    812 
    813     if (!SrcString)
    814     {
    815         return;
    816     }
    817 
    818     /* Walk entire string, uppercasing the letters */
    819 
    820     for (String = SrcString; *String; String++)
    821     {
    822         *String = (char) toupper ((int) *String);
    823     }
    824 
    825     return;
    826 }
    827 
    828 
    829 /*******************************************************************************
    830  *
    831  * FUNCTION:    OpcFindName
    832  *
    833  * PARAMETERS:  List                - Array of char strings to be searched
    834  *              Name                - Char string to string for
    835  *              Index               - Index value to set if found
    836  *
    837  * RETURN:      TRUE if any names matched, FALSE otherwise
    838  *
    839  * DESCRIPTION: Match PLD name to value in lookup table. Sets Value to
    840  *              equivalent parameter value.
    841  *
    842  ******************************************************************************/
    843 
    844 static BOOLEAN
    845 OpcFindName (
    846     char                    **List,
    847     char                    *Name,
    848     UINT64                  *Index)
    849 {
    850     char                     *Str;
    851     UINT32                   i;
    852 
    853 
    854     OpcStrupr (Name);
    855 
    856     for (i = 0, Str = List[0]; Str; i++, Str = List[i])
    857     {
    858         if (!(ACPI_STRNCMP (Str, Name, ACPI_STRLEN (Name))))
    859         {
    860             *Index = i;
    861             return (TRUE);
    862         }
    863     }
    864 
    865     return (FALSE);
    866 }
    867 
    868 
    869 /*******************************************************************************
    870  *
    871  * FUNCTION:    OpcDoPld
    872  *
    873  * PARAMETERS:  Op                  - Parse node
    874  *
    875  * RETURN:      None
    876  *
    877  * DESCRIPTION: Convert ToPLD macro to 20-byte buffer
    878  *
    879  ******************************************************************************/
    880 
    881 static void
    882 OpcDoPld (
    883     ACPI_PARSE_OBJECT       *Op)
    884 {
    885     UINT8                   *Buffer;
    886     ACPI_PARSE_OBJECT       *Node;
    887     ACPI_PLD_INFO           PldInfo;
    888     ACPI_PARSE_OBJECT       *NewOp;
    889 
    890 
    891     if (!Op)
    892     {
    893         AslError(ASL_ERROR, ASL_MSG_NOT_EXIST, Op, NULL);
    894         return;
    895     }
    896 
    897     if (Op->Asl.ParseOpcode != PARSEOP_TOPLD)
    898     {
    899         AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Op, NULL);
    900         return;
    901     }
    902 
    903     Buffer = UtLocalCalloc (ACPI_PLD_BUFFER_SIZE);
    904     if (!Buffer)
    905     {
    906         AslError(ASL_ERROR, ASL_MSG_BUFFER_ALLOCATION, Op, NULL);
    907         return;
    908     }
    909 
    910     ACPI_MEMSET (&PldInfo, 0, sizeof (ACPI_PLD_INFO));
    911 
    912     Node = Op->Asl.Child;
    913     while (Node)
    914     {
    915         switch (Node->Asl.ParseOpcode)
    916         {
    917         case PARSEOP_PLD_REVISION:
    918 
    919             if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
    920             {
    921                 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
    922                 break;
    923             }
    924 
    925             if (Node->Asl.Child->Asl.Value.Integer > 127)
    926             {
    927                 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
    928                 break;
    929             }
    930 
    931             PldInfo.Revision = (UINT8) Node->Asl.Child->Asl.Value.Integer;
    932             break;
    933 
    934         case PARSEOP_PLD_IGNORECOLOR:
    935 
    936             if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
    937             {
    938                 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
    939                 break;
    940             }
    941 
    942             if (Node->Asl.Child->Asl.Value.Integer > 1)
    943             {
    944                 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
    945                 break;
    946             }
    947 
    948             PldInfo.IgnoreColor = (UINT8) Node->Asl.Child->Asl.Value.Integer;
    949             break;
    950 
    951         case PARSEOP_PLD_RED:
    952         case PARSEOP_PLD_GREEN:
    953         case PARSEOP_PLD_BLUE:
    954 
    955             if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
    956             {
    957                 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
    958                 break;
    959             }
    960 
    961             if (Node->Asl.Child->Asl.Value.Integer > 255)
    962             {
    963                 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
    964                 break;
    965             }
    966 
    967             if (Node->Asl.ParseOpcode == PARSEOP_PLD_RED)
    968             {
    969                 PldInfo.Red = (UINT8) Node->Asl.Child->Asl.Value.Integer;
    970             }
    971             else if (Node->Asl.ParseOpcode == PARSEOP_PLD_GREEN)
    972             {
    973                 PldInfo.Green = (UINT8) Node->Asl.Child->Asl.Value.Integer;
    974             }
    975             else /* PARSEOP_PLD_BLUE */
    976             {
    977                 PldInfo.Blue = (UINT8) Node->Asl.Child->Asl.Value.Integer;
    978             }
    979             break;
    980 
    981         case PARSEOP_PLD_WIDTH:
    982         case PARSEOP_PLD_HEIGHT:
    983 
    984             if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
    985             {
    986                 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
    987                 break;
    988             }
    989 
    990             if (Node->Asl.Child->Asl.Value.Integer > 65535)
    991             {
    992                 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
    993                 break;
    994             }
    995 
    996             if (Node->Asl.ParseOpcode == PARSEOP_PLD_WIDTH)
    997             {
    998                 PldInfo.Width = (UINT16) Node->Asl.Child->Asl.Value.Integer;
    999             }
   1000             else /* PARSEOP_PLD_HEIGHT */
   1001             {
   1002                 PldInfo.Height = (UINT16) Node->Asl.Child->Asl.Value.Integer;
   1003             }
   1004 
   1005             break;
   1006 
   1007         case PARSEOP_PLD_USERVISIBLE:
   1008         case PARSEOP_PLD_DOCK:
   1009         case PARSEOP_PLD_LID:
   1010 
   1011             if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
   1012             {
   1013                 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
   1014                 break;
   1015             }
   1016 
   1017             if (Node->Asl.Child->Asl.Value.Integer > 1)
   1018             {
   1019                 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
   1020                 break;
   1021             }
   1022 
   1023             if (Node->Asl.ParseOpcode == PARSEOP_PLD_USERVISIBLE)
   1024             {
   1025                 PldInfo.UserVisible = (UINT8) Node->Asl.Child->Asl.Value.Integer;
   1026             }
   1027             else if (Node->Asl.ParseOpcode == PARSEOP_PLD_DOCK)
   1028             {
   1029                 PldInfo.Dock = (UINT8) Node->Asl.Child->Asl.Value.Integer;
   1030             }
   1031             else
   1032             {
   1033                 PldInfo.Lid = (UINT8) Node->Asl.Child->Asl.Value.Integer;
   1034             }
   1035 
   1036             break;
   1037 
   1038         case PARSEOP_PLD_PANEL:
   1039 
   1040             if (Node->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER)
   1041             {
   1042                 if (Node->Asl.Child->Asl.Value.Integer > 6)
   1043                 {
   1044                     AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
   1045                     break;
   1046                 }
   1047             }
   1048             else /* PARSEOP_STRING */
   1049             {
   1050                 if (!OpcFindName(AslPldPanelList,
   1051                     Node->Asl.Child->Asl.Value.String,
   1052                     &Node->Asl.Child->Asl.Value.Integer))
   1053                 {
   1054                     AslError(ASL_ERROR, ASL_MSG_INVALID_OPERAND, Node, NULL);
   1055                     break;
   1056                 }
   1057             }
   1058 
   1059             PldInfo.Panel = (UINT8) Node->Asl.Child->Asl.Value.Integer;
   1060             break;
   1061 
   1062         case PARSEOP_PLD_VERTICALPOSITION:
   1063 
   1064             if (Node->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER)
   1065             {
   1066                 if (Node->Asl.Child->Asl.Value.Integer > 2)
   1067                 {
   1068                     AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
   1069                     break;
   1070                 }
   1071             }
   1072             else /* PARSEOP_STRING */
   1073             {
   1074                 if (!OpcFindName(AslPldVerticalPositionList,
   1075                     Node->Asl.Child->Asl.Value.String,
   1076                     &Node->Asl.Child->Asl.Value.Integer))
   1077                 {
   1078                     AslError(ASL_ERROR, ASL_MSG_INVALID_OPERAND, Node, NULL);
   1079                     break;
   1080                 }
   1081             }
   1082 
   1083             PldInfo.VerticalPosition = (UINT8) Node->Asl.Child->Asl.Value.Integer;
   1084             break;
   1085 
   1086         case PARSEOP_PLD_HORIZONTALPOSITION:
   1087 
   1088             if (Node->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER)
   1089             {
   1090                 if (Node->Asl.Child->Asl.Value.Integer > 2)
   1091                 {
   1092                     AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
   1093                     break;
   1094                 }
   1095             }
   1096             else /* PARSEOP_STRING */
   1097             {
   1098                 if (!OpcFindName(AslPldHorizontalPositionList,
   1099                     Node->Asl.Child->Asl.Value.String,
   1100                     &Node->Asl.Child->Asl.Value.Integer))
   1101                 {
   1102                     AslError(ASL_ERROR, ASL_MSG_INVALID_OPERAND, Node, NULL);
   1103                     break;
   1104                 }
   1105             }
   1106 
   1107             PldInfo.HorizontalPosition = (UINT8) Node->Asl.Child->Asl.Value.Integer;
   1108             break;
   1109 
   1110         case PARSEOP_PLD_SHAPE:
   1111 
   1112             if (Node->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER)
   1113             {
   1114                 if (Node->Asl.Child->Asl.Value.Integer > 8)
   1115                 {
   1116                     AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
   1117                     break;
   1118                 }
   1119             }
   1120             else /* PARSEOP_STRING */
   1121             {
   1122                 if (!OpcFindName(AslPldShapeList,
   1123                     Node->Asl.Child->Asl.Value.String,
   1124                     &Node->Asl.Child->Asl.Value.Integer))
   1125                 {
   1126                     AslError(ASL_ERROR, ASL_MSG_INVALID_OPERAND, Node, NULL);
   1127                     break;
   1128                 }
   1129             }
   1130 
   1131             PldInfo.Shape = (UINT8) Node->Asl.Child->Asl.Value.Integer;
   1132             break;
   1133 
   1134         case PARSEOP_PLD_GROUPORIENTATION:
   1135 
   1136             if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
   1137             {
   1138                 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
   1139                 break;
   1140             }
   1141 
   1142             if (Node->Asl.Child->Asl.Value.Integer > 1)
   1143             {
   1144                 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
   1145                 break;
   1146             }
   1147 
   1148             PldInfo.GroupOrientation = (UINT8) Node->Asl.Child->Asl.Value.Integer;
   1149             break;
   1150 
   1151         case PARSEOP_PLD_GROUPTOKEN:
   1152         case PARSEOP_PLD_GROUPPOSITION:
   1153 
   1154             if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
   1155             {
   1156                 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
   1157                 break;
   1158             }
   1159 
   1160             if (Node->Asl.Child->Asl.Value.Integer > 255)
   1161             {
   1162                 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
   1163                 break;
   1164             }
   1165 
   1166 
   1167             if (Node->Asl.ParseOpcode == PARSEOP_PLD_GROUPTOKEN)
   1168             {
   1169                 PldInfo.GroupToken = (UINT8) Node->Asl.Child->Asl.Value.Integer;
   1170             }
   1171             else /* PARSEOP_PLD_GROUPPOSITION */
   1172             {
   1173                 PldInfo.GroupPosition = (UINT8) Node->Asl.Child->Asl.Value.Integer;
   1174             }
   1175 
   1176             break;
   1177 
   1178         case PARSEOP_PLD_BAY:
   1179         case PARSEOP_PLD_EJECTABLE:
   1180         case PARSEOP_PLD_EJECTREQUIRED:
   1181 
   1182             if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
   1183             {
   1184                 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
   1185                 break;
   1186             }
   1187 
   1188             if (Node->Asl.Child->Asl.Value.Integer > 1)
   1189             {
   1190                 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
   1191                 break;
   1192             }
   1193 
   1194             if (Node->Asl.ParseOpcode == PARSEOP_PLD_BAY)
   1195             {
   1196                 PldInfo.Bay = (UINT8) Node->Asl.Child->Asl.Value.Integer;
   1197             }
   1198             else if (Node->Asl.ParseOpcode == PARSEOP_PLD_EJECTABLE)
   1199             {
   1200                 PldInfo.Ejectable = (UINT8) Node->Asl.Child->Asl.Value.Integer;
   1201             }
   1202             else /* PARSEOP_PLD_EJECTREQUIRED */
   1203             {
   1204                 PldInfo.OspmEjectRequired = (UINT8) Node->Asl.Child->Asl.Value.Integer;
   1205             }
   1206 
   1207             break;
   1208 
   1209         case PARSEOP_PLD_CABINETNUMBER:
   1210         case PARSEOP_PLD_CARDCAGENUMBER:
   1211 
   1212             if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
   1213             {
   1214                 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
   1215                 break;
   1216             }
   1217 
   1218             if (Node->Asl.Child->Asl.Value.Integer > 255)
   1219             {
   1220                 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
   1221                 break;
   1222             }
   1223 
   1224             if (Node->Asl.ParseOpcode == PARSEOP_PLD_CABINETNUMBER)
   1225             {
   1226                 PldInfo.CabinetNumber = (UINT8) Node->Asl.Child->Asl.Value.Integer;
   1227             }
   1228             else /* PARSEOP_PLD_CARDCAGENUMBER */
   1229             {
   1230                 PldInfo.CardCageNumber = (UINT8) Node->Asl.Child->Asl.Value.Integer;
   1231             }
   1232 
   1233             break;
   1234 
   1235         case PARSEOP_PLD_REFERENCE:
   1236 
   1237             if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
   1238             {
   1239                 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
   1240                 break;
   1241             }
   1242 
   1243             if (Node->Asl.Child->Asl.Value.Integer > 1)
   1244             {
   1245                 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
   1246                 break;
   1247             }
   1248 
   1249             PldInfo.Reference = (UINT8) Node->Asl.Child->Asl.Value.Integer;
   1250             break;
   1251 
   1252         case PARSEOP_PLD_ROTATION:
   1253 
   1254             if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
   1255             {
   1256                 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
   1257                 break;
   1258             }
   1259 
   1260             if (Node->Asl.Child->Asl.Value.Integer > 7)
   1261             {
   1262                 switch (Node->Asl.Child->Asl.Value.Integer)
   1263                 {
   1264                 case 45:
   1265 
   1266                     Node->Asl.Child->Asl.Value.Integer = 1;
   1267                     break;
   1268 
   1269                 case 90:
   1270 
   1271                     Node->Asl.Child->Asl.Value.Integer = 2;
   1272                     break;
   1273 
   1274                 case 135:
   1275 
   1276                     Node->Asl.Child->Asl.Value.Integer = 3;
   1277                     break;
   1278 
   1279                 case 180:
   1280 
   1281                     Node->Asl.Child->Asl.Value.Integer = 4;
   1282                     break;
   1283 
   1284                 case 225:
   1285 
   1286                     Node->Asl.Child->Asl.Value.Integer = 5;
   1287                     break;
   1288 
   1289                 case 270:
   1290 
   1291                     Node->Asl.Child->Asl.Value.Integer = 6;
   1292                     break;
   1293 
   1294                 case 315:
   1295 
   1296                     Node->Asl.Child->Asl.Value.Integer = 7;
   1297                     break;
   1298 
   1299                 default:
   1300 
   1301                     AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
   1302                     break;
   1303                 }
   1304             }
   1305 
   1306             PldInfo.Rotation = (UINT8) Node->Asl.Child->Asl.Value.Integer;
   1307             break;
   1308 
   1309         case PARSEOP_PLD_ORDER:
   1310 
   1311             if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
   1312             {
   1313                 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
   1314                 break;
   1315             }
   1316 
   1317             if (Node->Asl.Child->Asl.Value.Integer > 31)
   1318             {
   1319                 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
   1320                 break;
   1321             }
   1322 
   1323             PldInfo.Order = (UINT8) Node->Asl.Child->Asl.Value.Integer;
   1324             break;
   1325 
   1326         case PARSEOP_PLD_VERTICALOFFSET:
   1327         case PARSEOP_PLD_HORIZONTALOFFSET:
   1328 
   1329             if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
   1330             {
   1331                 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
   1332                 break;
   1333             }
   1334 
   1335             if (Node->Asl.Child->Asl.Value.Integer > 65535)
   1336             {
   1337                 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
   1338                 break;
   1339             }
   1340 
   1341             if (Node->Asl.ParseOpcode == PARSEOP_PLD_VERTICALOFFSET)
   1342             {
   1343                 PldInfo.VerticalOffset = (UINT16) Node->Asl.Child->Asl.Value.Integer;
   1344             }
   1345             else /* PARSEOP_PLD_HORIZONTALOFFSET */
   1346             {
   1347                 PldInfo.HorizontalOffset = (UINT16) Node->Asl.Child->Asl.Value.Integer;
   1348             }
   1349 
   1350             break;
   1351 
   1352         default:
   1353 
   1354             AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
   1355             break;
   1356         }
   1357 
   1358         Node = Node->Asl.Next;
   1359     }
   1360 
   1361     UtLocalFree (Buffer, ACPI_PLD_BUFFER_SIZE);
   1362     Buffer = OpcEncodePldBuffer(&PldInfo);
   1363 
   1364     /* Change Op to a Buffer */
   1365 
   1366     Op->Asl.ParseOpcode = PARSEOP_BUFFER;
   1367     Op->Common.AmlOpcode = AML_BUFFER_OP;
   1368 
   1369     /* Disable further optimization */
   1370 
   1371     Op->Asl.CompileFlags &= ~NODE_COMPILE_TIME_CONST;
   1372     UtSetParseOpName (Op);
   1373 
   1374     /* Child node is the buffer length */
   1375 
   1376     NewOp = TrAllocateNode (PARSEOP_INTEGER);
   1377 
   1378     NewOp->Asl.AmlOpcode     = AML_BYTE_OP;
   1379     NewOp->Asl.Value.Integer = 20;
   1380     NewOp->Asl.Parent        = Op;
   1381 
   1382     Op->Asl.Child = NewOp;
   1383     Op = NewOp;
   1384 
   1385     /* Peer to the child is the raw buffer data */
   1386 
   1387     NewOp = TrAllocateNode (PARSEOP_RAW_DATA);
   1388     NewOp->Asl.AmlOpcode     = AML_RAW_DATA_BUFFER;
   1389     NewOp->Asl.AmlLength     = 20;
   1390     NewOp->Asl.Value.String  = ACPI_CAST_PTR (char, Buffer);
   1391     NewOp->Asl.Parent        = Op->Asl.Parent;
   1392 
   1393     Op->Asl.Next = NewOp;
   1394 }
   1395 
   1396 
   1397 /*******************************************************************************
   1398  *
   1399  * FUNCTION:    OpcDoUuId
   1400  *
   1401  * PARAMETERS:  Op                  - Parse node
   1402  *
   1403  * RETURN:      None
   1404  *
   1405  * DESCRIPTION: Convert UUID string to 16-byte buffer
   1406  *
   1407  ******************************************************************************/
   1408 
   1409 static void
   1410 OpcDoUuId (
   1411     ACPI_PARSE_OBJECT       *Op)
   1412 {
   1413     char                    *InString;
   1414     UINT8                   *Buffer;
   1415     ACPI_STATUS             Status = AE_OK;
   1416     ACPI_PARSE_OBJECT       *NewOp;
   1417 
   1418 
   1419     InString = ACPI_CAST_PTR (char, Op->Asl.Value.String);
   1420     Buffer = UtLocalCalloc (16);
   1421 
   1422     Status = AuValidateUuid (InString);
   1423     if (ACPI_FAILURE (Status))
   1424     {
   1425         AslError (ASL_ERROR, ASL_MSG_INVALID_UUID, Op, Op->Asl.Value.String);
   1426     }
   1427     else
   1428     {
   1429         AcpiUtConvertStringToUuid (InString, Buffer);
   1430     }
   1431 
   1432     /* Change Op to a Buffer */
   1433 
   1434     Op->Asl.ParseOpcode = PARSEOP_BUFFER;
   1435     Op->Common.AmlOpcode = AML_BUFFER_OP;
   1436 
   1437     /* Disable further optimization */
   1438 
   1439     Op->Asl.CompileFlags &= ~NODE_COMPILE_TIME_CONST;
   1440     UtSetParseOpName (Op);
   1441 
   1442     /* Child node is the buffer length */
   1443 
   1444     NewOp = TrAllocateNode (PARSEOP_INTEGER);
   1445 
   1446     NewOp->Asl.AmlOpcode     = AML_BYTE_OP;
   1447     NewOp->Asl.Value.Integer = 16;
   1448     NewOp->Asl.Parent        = Op;
   1449 
   1450     Op->Asl.Child = NewOp;
   1451     Op = NewOp;
   1452 
   1453     /* Peer to the child is the raw buffer data */
   1454 
   1455     NewOp = TrAllocateNode (PARSEOP_RAW_DATA);
   1456     NewOp->Asl.AmlOpcode     = AML_RAW_DATA_BUFFER;
   1457     NewOp->Asl.AmlLength     = 16;
   1458     NewOp->Asl.Value.String  = ACPI_CAST_PTR (char, Buffer);
   1459     NewOp->Asl.Parent        = Op->Asl.Parent;
   1460 
   1461     Op->Asl.Next = NewOp;
   1462 }
   1463 
   1464 
   1465 /*******************************************************************************
   1466  *
   1467  * FUNCTION:    OpcGenerateAmlOpcode
   1468  *
   1469  * PARAMETERS:  Op                  - Parse node
   1470  *
   1471  * RETURN:      None
   1472  *
   1473  * DESCRIPTION: Generate the AML opcode associated with the node and its
   1474  *              parse (lex/flex) keyword opcode. Essentially implements
   1475  *              a mapping between the parse opcodes and the actual AML opcodes.
   1476  *
   1477  ******************************************************************************/
   1478 
   1479 void
   1480 OpcGenerateAmlOpcode (
   1481     ACPI_PARSE_OBJECT       *Op)
   1482 {
   1483     UINT16                  Index;
   1484 
   1485 
   1486     Index = (UINT16) (Op->Asl.ParseOpcode - ASL_PARSE_OPCODE_BASE);
   1487 
   1488     Op->Asl.AmlOpcode     = AslKeywordMapping[Index].AmlOpcode;
   1489     Op->Asl.AcpiBtype     = AslKeywordMapping[Index].AcpiBtype;
   1490     Op->Asl.CompileFlags |= AslKeywordMapping[Index].Flags;
   1491 
   1492     if (!Op->Asl.Value.Integer)
   1493     {
   1494         Op->Asl.Value.Integer = AslKeywordMapping[Index].Value;
   1495     }
   1496 
   1497     /* Special handling for some opcodes */
   1498 
   1499     switch (Op->Asl.ParseOpcode)
   1500     {
   1501     case PARSEOP_INTEGER:
   1502         /*
   1503          * Set the opcode based on the size of the integer
   1504          */
   1505         (void) OpcSetOptimalIntegerSize (Op);
   1506         break;
   1507 
   1508     case PARSEOP_OFFSET:
   1509 
   1510         Op->Asl.AmlOpcodeLength = 1;
   1511         break;
   1512 
   1513     case PARSEOP_ACCESSAS:
   1514 
   1515         OpcDoAccessAs (Op);
   1516         break;
   1517 
   1518     case PARSEOP_CONNECTION:
   1519 
   1520         OpcDoConnection (Op);
   1521         break;
   1522 
   1523     case PARSEOP_EISAID:
   1524 
   1525         OpcDoEisaId (Op);
   1526         break;
   1527 
   1528     case PARSEOP_PRINTF:
   1529 
   1530         OpcDoPrintf (Op);
   1531         break;
   1532 
   1533     case PARSEOP_FPRINTF:
   1534 
   1535         OpcDoFprintf (Op);
   1536         break;
   1537 
   1538     case PARSEOP_TOPLD:
   1539 
   1540         OpcDoPld (Op);
   1541         break;
   1542 
   1543     case PARSEOP_TOUUID:
   1544 
   1545         OpcDoUuId (Op);
   1546         break;
   1547 
   1548     case PARSEOP_UNICODE:
   1549 
   1550         OpcDoUnicode (Op);
   1551         break;
   1552 
   1553     case PARSEOP_INCLUDE:
   1554 
   1555         Op->Asl.Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
   1556         Gbl_HasIncludeFiles = TRUE;
   1557         break;
   1558 
   1559     case PARSEOP_EXTERNAL:
   1560 
   1561         Op->Asl.Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
   1562         Op->Asl.Child->Asl.Next->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
   1563         break;
   1564 
   1565     case PARSEOP_TIMER:
   1566 
   1567         if (AcpiGbl_IntegerBitWidth == 32)
   1568         {
   1569             AslError (ASL_REMARK, ASL_MSG_TRUNCATION, Op, NULL);
   1570         }
   1571         break;
   1572 
   1573     default:
   1574 
   1575         /* Nothing to do for other opcodes */
   1576 
   1577         break;
   1578     }
   1579 
   1580     return;
   1581 }
   1582