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