Home | History | Annotate | Line # | Download | only in compiler
aslopcodes.c revision 1.3
      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 (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:    OpcFindName
    795  *
    796  * PARAMETERS:  List                - Array of char strings to be searched
    797  *              Name                - Char string to string for
    798  *              Index               - Index value to set if found
    799  *
    800  * RETURN:      TRUE if any names matched, FALSE otherwise
    801  *
    802  * DESCRIPTION: Match PLD name to value in lookup table. Sets Value to
    803  *              equivalent parameter value.
    804  *
    805  ******************************************************************************/
    806 
    807 static BOOLEAN
    808 OpcFindName (
    809     char                    **List,
    810     char                    *Name,
    811     UINT64                  *Index)
    812 {
    813     char                     *Str;
    814     UINT32                   i;
    815 
    816 
    817     AcpiUtStrupr (Name);
    818 
    819     for (i = 0, Str = List[0]; Str; i++, Str = List[i])
    820     {
    821         if (!(strncmp (Str, Name, strlen (Name))))
    822         {
    823             *Index = i;
    824             return (TRUE);
    825         }
    826     }
    827 
    828     return (FALSE);
    829 }
    830 
    831 
    832 /*******************************************************************************
    833  *
    834  * FUNCTION:    OpcDoPld
    835  *
    836  * PARAMETERS:  Op                  - Parse node
    837  *
    838  * RETURN:      None
    839  *
    840  * DESCRIPTION: Convert ToPLD macro to 20-byte buffer
    841  *
    842  ******************************************************************************/
    843 
    844 static void
    845 OpcDoPld (
    846     ACPI_PARSE_OBJECT       *Op)
    847 {
    848     UINT8                   *Buffer;
    849     ACPI_PARSE_OBJECT       *Node;
    850     ACPI_PLD_INFO           PldInfo;
    851     ACPI_PARSE_OBJECT       *NewOp;
    852 
    853 
    854     if (!Op)
    855     {
    856         AslError(ASL_ERROR, ASL_MSG_NOT_EXIST, Op, NULL);
    857         return;
    858     }
    859 
    860     if (Op->Asl.ParseOpcode != PARSEOP_TOPLD)
    861     {
    862         AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Op, NULL);
    863         return;
    864     }
    865 
    866     memset (&PldInfo, 0, sizeof (ACPI_PLD_INFO));
    867 
    868     Node = Op->Asl.Child;
    869     while (Node)
    870     {
    871         switch (Node->Asl.ParseOpcode)
    872         {
    873         case PARSEOP_PLD_REVISION:
    874 
    875             if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
    876             {
    877                 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
    878                 break;
    879             }
    880 
    881             if (Node->Asl.Child->Asl.Value.Integer > 127)
    882             {
    883                 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
    884                 break;
    885             }
    886 
    887             PldInfo.Revision = (UINT8) Node->Asl.Child->Asl.Value.Integer;
    888             break;
    889 
    890         case PARSEOP_PLD_IGNORECOLOR:
    891 
    892             if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
    893             {
    894                 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
    895                 break;
    896             }
    897 
    898             if (Node->Asl.Child->Asl.Value.Integer > 1)
    899             {
    900                 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
    901                 break;
    902             }
    903 
    904             PldInfo.IgnoreColor = (UINT8) Node->Asl.Child->Asl.Value.Integer;
    905             break;
    906 
    907         case PARSEOP_PLD_RED:
    908         case PARSEOP_PLD_GREEN:
    909         case PARSEOP_PLD_BLUE:
    910 
    911             if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
    912             {
    913                 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
    914                 break;
    915             }
    916 
    917             if (Node->Asl.Child->Asl.Value.Integer > 255)
    918             {
    919                 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
    920                 break;
    921             }
    922 
    923             if (Node->Asl.ParseOpcode == PARSEOP_PLD_RED)
    924             {
    925                 PldInfo.Red = (UINT8) Node->Asl.Child->Asl.Value.Integer;
    926             }
    927             else if (Node->Asl.ParseOpcode == PARSEOP_PLD_GREEN)
    928             {
    929                 PldInfo.Green = (UINT8) Node->Asl.Child->Asl.Value.Integer;
    930             }
    931             else /* PARSEOP_PLD_BLUE */
    932             {
    933                 PldInfo.Blue = (UINT8) Node->Asl.Child->Asl.Value.Integer;
    934             }
    935             break;
    936 
    937         case PARSEOP_PLD_WIDTH:
    938         case PARSEOP_PLD_HEIGHT:
    939 
    940             if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
    941             {
    942                 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
    943                 break;
    944             }
    945 
    946             if (Node->Asl.Child->Asl.Value.Integer > 65535)
    947             {
    948                 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
    949                 break;
    950             }
    951 
    952             if (Node->Asl.ParseOpcode == PARSEOP_PLD_WIDTH)
    953             {
    954                 PldInfo.Width = (UINT16) Node->Asl.Child->Asl.Value.Integer;
    955             }
    956             else /* PARSEOP_PLD_HEIGHT */
    957             {
    958                 PldInfo.Height = (UINT16) Node->Asl.Child->Asl.Value.Integer;
    959             }
    960 
    961             break;
    962 
    963         case PARSEOP_PLD_USERVISIBLE:
    964         case PARSEOP_PLD_DOCK:
    965         case PARSEOP_PLD_LID:
    966 
    967             if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
    968             {
    969                 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
    970                 break;
    971             }
    972 
    973             if (Node->Asl.Child->Asl.Value.Integer > 1)
    974             {
    975                 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
    976                 break;
    977             }
    978 
    979             if (Node->Asl.ParseOpcode == PARSEOP_PLD_USERVISIBLE)
    980             {
    981                 PldInfo.UserVisible = (UINT8) Node->Asl.Child->Asl.Value.Integer;
    982             }
    983             else if (Node->Asl.ParseOpcode == PARSEOP_PLD_DOCK)
    984             {
    985                 PldInfo.Dock = (UINT8) Node->Asl.Child->Asl.Value.Integer;
    986             }
    987             else
    988             {
    989                 PldInfo.Lid = (UINT8) Node->Asl.Child->Asl.Value.Integer;
    990             }
    991 
    992             break;
    993 
    994         case PARSEOP_PLD_PANEL:
    995 
    996             if (Node->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER)
    997             {
    998                 if (Node->Asl.Child->Asl.Value.Integer > 6)
    999                 {
   1000                     AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
   1001                     break;
   1002                 }
   1003             }
   1004             else /* PARSEOP_STRING */
   1005             {
   1006                 if (!OpcFindName(AslPldPanelList,
   1007                     Node->Asl.Child->Asl.Value.String,
   1008                     &Node->Asl.Child->Asl.Value.Integer))
   1009                 {
   1010                     AslError(ASL_ERROR, ASL_MSG_INVALID_OPERAND, Node, NULL);
   1011                     break;
   1012                 }
   1013             }
   1014 
   1015             PldInfo.Panel = (UINT8) Node->Asl.Child->Asl.Value.Integer;
   1016             break;
   1017 
   1018         case PARSEOP_PLD_VERTICALPOSITION:
   1019 
   1020             if (Node->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER)
   1021             {
   1022                 if (Node->Asl.Child->Asl.Value.Integer > 2)
   1023                 {
   1024                     AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
   1025                     break;
   1026                 }
   1027             }
   1028             else /* PARSEOP_STRING */
   1029             {
   1030                 if (!OpcFindName(AslPldVerticalPositionList,
   1031                     Node->Asl.Child->Asl.Value.String,
   1032                     &Node->Asl.Child->Asl.Value.Integer))
   1033                 {
   1034                     AslError(ASL_ERROR, ASL_MSG_INVALID_OPERAND, Node, NULL);
   1035                     break;
   1036                 }
   1037             }
   1038 
   1039             PldInfo.VerticalPosition = (UINT8) Node->Asl.Child->Asl.Value.Integer;
   1040             break;
   1041 
   1042         case PARSEOP_PLD_HORIZONTALPOSITION:
   1043 
   1044             if (Node->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER)
   1045             {
   1046                 if (Node->Asl.Child->Asl.Value.Integer > 2)
   1047                 {
   1048                     AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
   1049                     break;
   1050                 }
   1051             }
   1052             else /* PARSEOP_STRING */
   1053             {
   1054                 if (!OpcFindName(AslPldHorizontalPositionList,
   1055                     Node->Asl.Child->Asl.Value.String,
   1056                     &Node->Asl.Child->Asl.Value.Integer))
   1057                 {
   1058                     AslError(ASL_ERROR, ASL_MSG_INVALID_OPERAND, Node, NULL);
   1059                     break;
   1060                 }
   1061             }
   1062 
   1063             PldInfo.HorizontalPosition = (UINT8) Node->Asl.Child->Asl.Value.Integer;
   1064             break;
   1065 
   1066         case PARSEOP_PLD_SHAPE:
   1067 
   1068             if (Node->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER)
   1069             {
   1070                 if (Node->Asl.Child->Asl.Value.Integer > 8)
   1071                 {
   1072                     AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
   1073                     break;
   1074                 }
   1075             }
   1076             else /* PARSEOP_STRING */
   1077             {
   1078                 if (!OpcFindName(AslPldShapeList,
   1079                     Node->Asl.Child->Asl.Value.String,
   1080                     &Node->Asl.Child->Asl.Value.Integer))
   1081                 {
   1082                     AslError(ASL_ERROR, ASL_MSG_INVALID_OPERAND, Node, NULL);
   1083                     break;
   1084                 }
   1085             }
   1086 
   1087             PldInfo.Shape = (UINT8) Node->Asl.Child->Asl.Value.Integer;
   1088             break;
   1089 
   1090         case PARSEOP_PLD_GROUPORIENTATION:
   1091 
   1092             if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
   1093             {
   1094                 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
   1095                 break;
   1096             }
   1097 
   1098             if (Node->Asl.Child->Asl.Value.Integer > 1)
   1099             {
   1100                 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
   1101                 break;
   1102             }
   1103 
   1104             PldInfo.GroupOrientation = (UINT8) Node->Asl.Child->Asl.Value.Integer;
   1105             break;
   1106 
   1107         case PARSEOP_PLD_GROUPTOKEN:
   1108         case PARSEOP_PLD_GROUPPOSITION:
   1109 
   1110             if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
   1111             {
   1112                 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
   1113                 break;
   1114             }
   1115 
   1116             if (Node->Asl.Child->Asl.Value.Integer > 255)
   1117             {
   1118                 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
   1119                 break;
   1120             }
   1121 
   1122 
   1123             if (Node->Asl.ParseOpcode == PARSEOP_PLD_GROUPTOKEN)
   1124             {
   1125                 PldInfo.GroupToken = (UINT8) Node->Asl.Child->Asl.Value.Integer;
   1126             }
   1127             else /* PARSEOP_PLD_GROUPPOSITION */
   1128             {
   1129                 PldInfo.GroupPosition = (UINT8) Node->Asl.Child->Asl.Value.Integer;
   1130             }
   1131 
   1132             break;
   1133 
   1134         case PARSEOP_PLD_BAY:
   1135         case PARSEOP_PLD_EJECTABLE:
   1136         case PARSEOP_PLD_EJECTREQUIRED:
   1137 
   1138             if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
   1139             {
   1140                 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
   1141                 break;
   1142             }
   1143 
   1144             if (Node->Asl.Child->Asl.Value.Integer > 1)
   1145             {
   1146                 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
   1147                 break;
   1148             }
   1149 
   1150             if (Node->Asl.ParseOpcode == PARSEOP_PLD_BAY)
   1151             {
   1152                 PldInfo.Bay = (UINT8) Node->Asl.Child->Asl.Value.Integer;
   1153             }
   1154             else if (Node->Asl.ParseOpcode == PARSEOP_PLD_EJECTABLE)
   1155             {
   1156                 PldInfo.Ejectable = (UINT8) Node->Asl.Child->Asl.Value.Integer;
   1157             }
   1158             else /* PARSEOP_PLD_EJECTREQUIRED */
   1159             {
   1160                 PldInfo.OspmEjectRequired = (UINT8) Node->Asl.Child->Asl.Value.Integer;
   1161             }
   1162 
   1163             break;
   1164 
   1165         case PARSEOP_PLD_CABINETNUMBER:
   1166         case PARSEOP_PLD_CARDCAGENUMBER:
   1167 
   1168             if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
   1169             {
   1170                 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
   1171                 break;
   1172             }
   1173 
   1174             if (Node->Asl.Child->Asl.Value.Integer > 255)
   1175             {
   1176                 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
   1177                 break;
   1178             }
   1179 
   1180             if (Node->Asl.ParseOpcode == PARSEOP_PLD_CABINETNUMBER)
   1181             {
   1182                 PldInfo.CabinetNumber = (UINT8) Node->Asl.Child->Asl.Value.Integer;
   1183             }
   1184             else /* PARSEOP_PLD_CARDCAGENUMBER */
   1185             {
   1186                 PldInfo.CardCageNumber = (UINT8) Node->Asl.Child->Asl.Value.Integer;
   1187             }
   1188 
   1189             break;
   1190 
   1191         case PARSEOP_PLD_REFERENCE:
   1192 
   1193             if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
   1194             {
   1195                 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
   1196                 break;
   1197             }
   1198 
   1199             if (Node->Asl.Child->Asl.Value.Integer > 1)
   1200             {
   1201                 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
   1202                 break;
   1203             }
   1204 
   1205             PldInfo.Reference = (UINT8) Node->Asl.Child->Asl.Value.Integer;
   1206             break;
   1207 
   1208         case PARSEOP_PLD_ROTATION:
   1209 
   1210             if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
   1211             {
   1212                 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
   1213                 break;
   1214             }
   1215 
   1216             if (Node->Asl.Child->Asl.Value.Integer > 7)
   1217             {
   1218                 switch (Node->Asl.Child->Asl.Value.Integer)
   1219                 {
   1220                 case 45:
   1221 
   1222                     Node->Asl.Child->Asl.Value.Integer = 1;
   1223                     break;
   1224 
   1225                 case 90:
   1226 
   1227                     Node->Asl.Child->Asl.Value.Integer = 2;
   1228                     break;
   1229 
   1230                 case 135:
   1231 
   1232                     Node->Asl.Child->Asl.Value.Integer = 3;
   1233                     break;
   1234 
   1235                 case 180:
   1236 
   1237                     Node->Asl.Child->Asl.Value.Integer = 4;
   1238                     break;
   1239 
   1240                 case 225:
   1241 
   1242                     Node->Asl.Child->Asl.Value.Integer = 5;
   1243                     break;
   1244 
   1245                 case 270:
   1246 
   1247                     Node->Asl.Child->Asl.Value.Integer = 6;
   1248                     break;
   1249 
   1250                 case 315:
   1251 
   1252                     Node->Asl.Child->Asl.Value.Integer = 7;
   1253                     break;
   1254 
   1255                 default:
   1256 
   1257                     AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
   1258                     break;
   1259                 }
   1260             }
   1261 
   1262             PldInfo.Rotation = (UINT8) Node->Asl.Child->Asl.Value.Integer;
   1263             break;
   1264 
   1265         case PARSEOP_PLD_ORDER:
   1266 
   1267             if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
   1268             {
   1269                 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
   1270                 break;
   1271             }
   1272 
   1273             if (Node->Asl.Child->Asl.Value.Integer > 31)
   1274             {
   1275                 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
   1276                 break;
   1277             }
   1278 
   1279             PldInfo.Order = (UINT8) Node->Asl.Child->Asl.Value.Integer;
   1280             break;
   1281 
   1282         case PARSEOP_PLD_VERTICALOFFSET:
   1283         case PARSEOP_PLD_HORIZONTALOFFSET:
   1284 
   1285             if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER)
   1286             {
   1287                 AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
   1288                 break;
   1289             }
   1290 
   1291             if (Node->Asl.Child->Asl.Value.Integer > 65535)
   1292             {
   1293                 AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL);
   1294                 break;
   1295             }
   1296 
   1297             if (Node->Asl.ParseOpcode == PARSEOP_PLD_VERTICALOFFSET)
   1298             {
   1299                 PldInfo.VerticalOffset = (UINT16) Node->Asl.Child->Asl.Value.Integer;
   1300             }
   1301             else /* PARSEOP_PLD_HORIZONTALOFFSET */
   1302             {
   1303                 PldInfo.HorizontalOffset = (UINT16) Node->Asl.Child->Asl.Value.Integer;
   1304             }
   1305 
   1306             break;
   1307 
   1308         default:
   1309 
   1310             AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL);
   1311             break;
   1312         }
   1313 
   1314         Node = Node->Asl.Next;
   1315     }
   1316 
   1317     UtLocalFree (Buffer, ACPI_PLD_BUFFER_SIZE);
   1318     Buffer = OpcEncodePldBuffer(&PldInfo);
   1319 
   1320     /* Change Op to a Buffer */
   1321 
   1322     Op->Asl.ParseOpcode = PARSEOP_BUFFER;
   1323     Op->Common.AmlOpcode = AML_BUFFER_OP;
   1324 
   1325     /* Disable further optimization */
   1326 
   1327     Op->Asl.CompileFlags &= ~NODE_COMPILE_TIME_CONST;
   1328     UtSetParseOpName (Op);
   1329 
   1330     /* Child node is the buffer length */
   1331 
   1332     NewOp = TrAllocateNode (PARSEOP_INTEGER);
   1333 
   1334     NewOp->Asl.AmlOpcode     = AML_BYTE_OP;
   1335     NewOp->Asl.Value.Integer = 20;
   1336     NewOp->Asl.Parent        = Op;
   1337 
   1338     Op->Asl.Child = NewOp;
   1339     Op = NewOp;
   1340 
   1341     /* Peer to the child is the raw buffer data */
   1342 
   1343     NewOp = TrAllocateNode (PARSEOP_RAW_DATA);
   1344     NewOp->Asl.AmlOpcode     = AML_RAW_DATA_BUFFER;
   1345     NewOp->Asl.AmlLength     = 20;
   1346     NewOp->Asl.Value.String  = ACPI_CAST_PTR (char, Buffer);
   1347     NewOp->Asl.Parent        = Op->Asl.Parent;
   1348 
   1349     Op->Asl.Next = NewOp;
   1350 }
   1351 
   1352 
   1353 /*******************************************************************************
   1354  *
   1355  * FUNCTION:    OpcDoUuId
   1356  *
   1357  * PARAMETERS:  Op                  - Parse node
   1358  *
   1359  * RETURN:      None
   1360  *
   1361  * DESCRIPTION: Convert UUID string to 16-byte buffer
   1362  *
   1363  ******************************************************************************/
   1364 
   1365 static void
   1366 OpcDoUuId (
   1367     ACPI_PARSE_OBJECT       *Op)
   1368 {
   1369     char                    *InString;
   1370     UINT8                   *Buffer;
   1371     ACPI_STATUS             Status = AE_OK;
   1372     ACPI_PARSE_OBJECT       *NewOp;
   1373 
   1374 
   1375     InString = ACPI_CAST_PTR (char, Op->Asl.Value.String);
   1376     Buffer = UtLocalCalloc (16);
   1377 
   1378     Status = AuValidateUuid (InString);
   1379     if (ACPI_FAILURE (Status))
   1380     {
   1381         AslError (ASL_ERROR, ASL_MSG_INVALID_UUID, Op, Op->Asl.Value.String);
   1382     }
   1383     else
   1384     {
   1385         AcpiUtConvertStringToUuid (InString, Buffer);
   1386     }
   1387 
   1388     /* Change Op to a Buffer */
   1389 
   1390     Op->Asl.ParseOpcode = PARSEOP_BUFFER;
   1391     Op->Common.AmlOpcode = AML_BUFFER_OP;
   1392 
   1393     /* Disable further optimization */
   1394 
   1395     Op->Asl.CompileFlags &= ~NODE_COMPILE_TIME_CONST;
   1396     UtSetParseOpName (Op);
   1397 
   1398     /* Child node is the buffer length */
   1399 
   1400     NewOp = TrAllocateNode (PARSEOP_INTEGER);
   1401 
   1402     NewOp->Asl.AmlOpcode     = AML_BYTE_OP;
   1403     NewOp->Asl.Value.Integer = 16;
   1404     NewOp->Asl.Parent        = Op;
   1405 
   1406     Op->Asl.Child = NewOp;
   1407     Op = NewOp;
   1408 
   1409     /* Peer to the child is the raw buffer data */
   1410 
   1411     NewOp = TrAllocateNode (PARSEOP_RAW_DATA);
   1412     NewOp->Asl.AmlOpcode     = AML_RAW_DATA_BUFFER;
   1413     NewOp->Asl.AmlLength     = 16;
   1414     NewOp->Asl.Value.String  = ACPI_CAST_PTR (char, Buffer);
   1415     NewOp->Asl.Parent        = Op->Asl.Parent;
   1416 
   1417     Op->Asl.Next = NewOp;
   1418 }
   1419 
   1420 
   1421 /*******************************************************************************
   1422  *
   1423  * FUNCTION:    OpcGenerateAmlOpcode
   1424  *
   1425  * PARAMETERS:  Op                  - Parse node
   1426  *
   1427  * RETURN:      None
   1428  *
   1429  * DESCRIPTION: Generate the AML opcode associated with the node and its
   1430  *              parse (lex/flex) keyword opcode. Essentially implements
   1431  *              a mapping between the parse opcodes and the actual AML opcodes.
   1432  *
   1433  ******************************************************************************/
   1434 
   1435 void
   1436 OpcGenerateAmlOpcode (
   1437     ACPI_PARSE_OBJECT       *Op)
   1438 {
   1439     UINT16                  Index;
   1440 
   1441 
   1442     Index = (UINT16) (Op->Asl.ParseOpcode - ASL_PARSE_OPCODE_BASE);
   1443 
   1444     Op->Asl.AmlOpcode     = AslKeywordMapping[Index].AmlOpcode;
   1445     Op->Asl.AcpiBtype     = AslKeywordMapping[Index].AcpiBtype;
   1446     Op->Asl.CompileFlags |= AslKeywordMapping[Index].Flags;
   1447 
   1448     if (!Op->Asl.Value.Integer)
   1449     {
   1450         Op->Asl.Value.Integer = AslKeywordMapping[Index].Value;
   1451     }
   1452 
   1453     /* Special handling for some opcodes */
   1454 
   1455     switch (Op->Asl.ParseOpcode)
   1456     {
   1457     case PARSEOP_INTEGER:
   1458         /*
   1459          * Set the opcode based on the size of the integer
   1460          */
   1461         (void) OpcSetOptimalIntegerSize (Op);
   1462         break;
   1463 
   1464     case PARSEOP_OFFSET:
   1465 
   1466         Op->Asl.AmlOpcodeLength = 1;
   1467         break;
   1468 
   1469     case PARSEOP_ACCESSAS:
   1470 
   1471         OpcDoAccessAs (Op);
   1472         break;
   1473 
   1474     case PARSEOP_CONNECTION:
   1475 
   1476         OpcDoConnection (Op);
   1477         break;
   1478 
   1479     case PARSEOP_EISAID:
   1480 
   1481         OpcDoEisaId (Op);
   1482         break;
   1483 
   1484     case PARSEOP_PRINTF:
   1485 
   1486         OpcDoPrintf (Op);
   1487         break;
   1488 
   1489     case PARSEOP_FPRINTF:
   1490 
   1491         OpcDoFprintf (Op);
   1492         break;
   1493 
   1494     case PARSEOP_TOPLD:
   1495 
   1496         OpcDoPld (Op);
   1497         break;
   1498 
   1499     case PARSEOP_TOUUID:
   1500 
   1501         OpcDoUuId (Op);
   1502         break;
   1503 
   1504     case PARSEOP_UNICODE:
   1505 
   1506         OpcDoUnicode (Op);
   1507         break;
   1508 
   1509     case PARSEOP_INCLUDE:
   1510 
   1511         Op->Asl.Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
   1512         Gbl_HasIncludeFiles = TRUE;
   1513         break;
   1514 
   1515     case PARSEOP_EXTERNAL:
   1516 
   1517         Op->Asl.Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
   1518         Op->Asl.Child->Asl.Next->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
   1519         break;
   1520 
   1521     case PARSEOP_TIMER:
   1522 
   1523         if (AcpiGbl_IntegerBitWidth == 32)
   1524         {
   1525             AslError (ASL_REMARK, ASL_MSG_TRUNCATION, Op, NULL);
   1526         }
   1527         break;
   1528 
   1529     default:
   1530 
   1531         /* Nothing to do for other opcodes */
   1532 
   1533         break;
   1534     }
   1535 
   1536     return;
   1537 }
   1538