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