Home | History | Annotate | Line # | Download | only in parser
psargs.c revision 1.1.1.4.2.2
      1 /******************************************************************************
      2  *
      3  * Module Name: psargs - Parse AML opcode arguments
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2015, Intel Corp.
      9  * All rights reserved.
     10  *
     11  * Redistribution and use in source and binary forms, with or without
     12  * modification, are permitted provided that the following conditions
     13  * are met:
     14  * 1. Redistributions of source code must retain the above copyright
     15  *    notice, this list of conditions, and the following disclaimer,
     16  *    without modification.
     17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
     18  *    substantially similar to the "NO WARRANTY" disclaimer below
     19  *    ("Disclaimer") and any redistribution must be conditioned upon
     20  *    including a substantially similar Disclaimer requirement for further
     21  *    binary redistribution.
     22  * 3. Neither the names of the above-listed copyright holders nor the names
     23  *    of any contributors may be used to endorse or promote products derived
     24  *    from this software without specific prior written permission.
     25  *
     26  * Alternatively, this software may be distributed under the terms of the
     27  * GNU General Public License ("GPL") version 2 as published by the Free
     28  * Software Foundation.
     29  *
     30  * NO WARRANTY
     31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
     34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
     40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     41  * POSSIBILITY OF SUCH DAMAGES.
     42  */
     43 
     44 #include "acpi.h"
     45 #include "accommon.h"
     46 #include "acparser.h"
     47 #include "amlcode.h"
     48 #include "acnamesp.h"
     49 #include "acdispat.h"
     50 
     51 #define _COMPONENT          ACPI_PARSER
     52         ACPI_MODULE_NAME    ("psargs")
     53 
     54 /* Local prototypes */
     55 
     56 static UINT32
     57 AcpiPsGetNextPackageLength (
     58     ACPI_PARSE_STATE        *ParserState);
     59 
     60 static ACPI_PARSE_OBJECT *
     61 AcpiPsGetNextField (
     62     ACPI_PARSE_STATE        *ParserState);
     63 
     64 
     65 /*******************************************************************************
     66  *
     67  * FUNCTION:    AcpiPsGetNextPackageLength
     68  *
     69  * PARAMETERS:  ParserState         - Current parser state object
     70  *
     71  * RETURN:      Decoded package length. On completion, the AML pointer points
     72  *              past the length byte or bytes.
     73  *
     74  * DESCRIPTION: Decode and return a package length field.
     75  *              Note: Largest package length is 28 bits, from ACPI specification
     76  *
     77  ******************************************************************************/
     78 
     79 static UINT32
     80 AcpiPsGetNextPackageLength (
     81     ACPI_PARSE_STATE        *ParserState)
     82 {
     83     UINT8                   *Aml = ParserState->Aml;
     84     UINT32                  PackageLength = 0;
     85     UINT32                  ByteCount;
     86     UINT8                   ByteZeroMask = 0x3F; /* Default [0:5] */
     87 
     88 
     89     ACPI_FUNCTION_TRACE (PsGetNextPackageLength);
     90 
     91 
     92     /*
     93      * Byte 0 bits [6:7] contain the number of additional bytes
     94      * used to encode the package length, either 0,1,2, or 3
     95      */
     96     ByteCount = (Aml[0] >> 6);
     97     ParserState->Aml += ((ACPI_SIZE) ByteCount + 1);
     98 
     99     /* Get bytes 3, 2, 1 as needed */
    100 
    101     while (ByteCount)
    102     {
    103         /*
    104          * Final bit positions for the package length bytes:
    105          *      Byte3->[20:27]
    106          *      Byte2->[12:19]
    107          *      Byte1->[04:11]
    108          *      Byte0->[00:03]
    109          */
    110         PackageLength |= (Aml[ByteCount] << ((ByteCount << 3) - 4));
    111 
    112         ByteZeroMask = 0x0F; /* Use bits [0:3] of byte 0 */
    113         ByteCount--;
    114     }
    115 
    116     /* Byte 0 is a special case, either bits [0:3] or [0:5] are used */
    117 
    118     PackageLength |= (Aml[0] & ByteZeroMask);
    119     return_UINT32 (PackageLength);
    120 }
    121 
    122 
    123 /*******************************************************************************
    124  *
    125  * FUNCTION:    AcpiPsGetNextPackageEnd
    126  *
    127  * PARAMETERS:  ParserState         - Current parser state object
    128  *
    129  * RETURN:      Pointer to end-of-package +1
    130  *
    131  * DESCRIPTION: Get next package length and return a pointer past the end of
    132  *              the package. Consumes the package length field
    133  *
    134  ******************************************************************************/
    135 
    136 UINT8 *
    137 AcpiPsGetNextPackageEnd (
    138     ACPI_PARSE_STATE        *ParserState)
    139 {
    140     UINT8                   *Start = ParserState->Aml;
    141     UINT32                  PackageLength;
    142 
    143 
    144     ACPI_FUNCTION_TRACE (PsGetNextPackageEnd);
    145 
    146 
    147     /* Function below updates ParserState->Aml */
    148 
    149     PackageLength = AcpiPsGetNextPackageLength (ParserState);
    150 
    151     return_PTR (Start + PackageLength); /* end of package */
    152 }
    153 
    154 
    155 /*******************************************************************************
    156  *
    157  * FUNCTION:    AcpiPsGetNextNamestring
    158  *
    159  * PARAMETERS:  ParserState         - Current parser state object
    160  *
    161  * RETURN:      Pointer to the start of the name string (pointer points into
    162  *              the AML.
    163  *
    164  * DESCRIPTION: Get next raw namestring within the AML stream. Handles all name
    165  *              prefix characters. Set parser state to point past the string.
    166  *              (Name is consumed from the AML.)
    167  *
    168  ******************************************************************************/
    169 
    170 char *
    171 AcpiPsGetNextNamestring (
    172     ACPI_PARSE_STATE        *ParserState)
    173 {
    174     UINT8                   *Start = ParserState->Aml;
    175     UINT8                   *End = ParserState->Aml;
    176 
    177 
    178     ACPI_FUNCTION_TRACE (PsGetNextNamestring);
    179 
    180 
    181     /* Point past any namestring prefix characters (backslash or carat) */
    182 
    183     while (ACPI_IS_ROOT_PREFIX (*End) ||
    184            ACPI_IS_PARENT_PREFIX (*End))
    185     {
    186         End++;
    187     }
    188 
    189     /* Decode the path prefix character */
    190 
    191     switch (*End)
    192     {
    193     case 0:
    194 
    195         /* NullName */
    196 
    197         if (End == Start)
    198         {
    199             Start = NULL;
    200         }
    201         End++;
    202         break;
    203 
    204     case AML_DUAL_NAME_PREFIX:
    205 
    206         /* Two name segments */
    207 
    208         End += 1 + (2 * ACPI_NAME_SIZE);
    209         break;
    210 
    211     case AML_MULTI_NAME_PREFIX_OP:
    212 
    213         /* Multiple name segments, 4 chars each, count in next byte */
    214 
    215         End += 2 + (*(End + 1) * ACPI_NAME_SIZE);
    216         break;
    217 
    218     default:
    219 
    220         /* Single name segment */
    221 
    222         End += ACPI_NAME_SIZE;
    223         break;
    224     }
    225 
    226     ParserState->Aml = End;
    227     return_PTR ((char *) Start);
    228 }
    229 
    230 
    231 /*******************************************************************************
    232  *
    233  * FUNCTION:    AcpiPsGetNextNamepath
    234  *
    235  * PARAMETERS:  ParserState         - Current parser state object
    236  *              Arg                 - Where the namepath will be stored
    237  *              ArgCount            - If the namepath points to a control method
    238  *                                    the method's argument is returned here.
    239  *              PossibleMethodCall  - Whether the namepath can possibly be the
    240  *                                    start of a method call
    241  *
    242  * RETURN:      Status
    243  *
    244  * DESCRIPTION: Get next name (if method call, return # of required args).
    245  *              Names are looked up in the internal namespace to determine
    246  *              if the name represents a control method. If a method
    247  *              is found, the number of arguments to the method is returned.
    248  *              This information is critical for parsing to continue correctly.
    249  *
    250  ******************************************************************************/
    251 
    252 ACPI_STATUS
    253 AcpiPsGetNextNamepath (
    254     ACPI_WALK_STATE         *WalkState,
    255     ACPI_PARSE_STATE        *ParserState,
    256     ACPI_PARSE_OBJECT       *Arg,
    257     BOOLEAN                 PossibleMethodCall)
    258 {
    259     ACPI_STATUS             Status;
    260     char                    *Path;
    261     ACPI_PARSE_OBJECT       *NameOp;
    262     ACPI_OPERAND_OBJECT     *MethodDesc;
    263     ACPI_NAMESPACE_NODE     *Node;
    264     UINT8                   *Start = ParserState->Aml;
    265 
    266 
    267     ACPI_FUNCTION_TRACE (PsGetNextNamepath);
    268 
    269 
    270     Path = AcpiPsGetNextNamestring (ParserState);
    271     AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP);
    272 
    273     /* Null path case is allowed, just exit */
    274 
    275     if (!Path)
    276     {
    277         Arg->Common.Value.Name = Path;
    278         return_ACPI_STATUS (AE_OK);
    279     }
    280 
    281     /*
    282      * Lookup the name in the internal namespace, starting with the current
    283      * scope. We don't want to add anything new to the namespace here,
    284      * however, so we use MODE_EXECUTE.
    285      * Allow searching of the parent tree, but don't open a new scope -
    286      * we just want to lookup the object (must be mode EXECUTE to perform
    287      * the upsearch)
    288      */
    289     Status = AcpiNsLookup (WalkState->ScopeInfo, Path,
    290                 ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
    291                 ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL, &Node);
    292 
    293     /*
    294      * If this name is a control method invocation, we must
    295      * setup the method call
    296      */
    297     if (ACPI_SUCCESS (Status) &&
    298         PossibleMethodCall &&
    299         (Node->Type == ACPI_TYPE_METHOD))
    300     {
    301         if (WalkState->Opcode == AML_UNLOAD_OP)
    302         {
    303             /*
    304              * AcpiPsGetNextNamestring has increased the AML pointer,
    305              * so we need to restore the saved AML pointer for method call.
    306              */
    307             WalkState->ParserState.Aml = Start;
    308             WalkState->ArgCount = 1;
    309             AcpiPsInitOp (Arg, AML_INT_METHODCALL_OP);
    310             return_ACPI_STATUS (AE_OK);
    311         }
    312 
    313         /* This name is actually a control method invocation */
    314 
    315         MethodDesc = AcpiNsGetAttachedObject (Node);
    316         ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
    317             "Control Method - %p Desc %p Path=%p\n", Node, MethodDesc, Path));
    318 
    319         NameOp = AcpiPsAllocOp (AML_INT_NAMEPATH_OP, Start);
    320         if (!NameOp)
    321         {
    322             return_ACPI_STATUS (AE_NO_MEMORY);
    323         }
    324 
    325         /* Change Arg into a METHOD CALL and attach name to it */
    326 
    327         AcpiPsInitOp (Arg, AML_INT_METHODCALL_OP);
    328         NameOp->Common.Value.Name = Path;
    329 
    330         /* Point METHODCALL/NAME to the METHOD Node */
    331 
    332         NameOp->Common.Node = Node;
    333         AcpiPsAppendArg (Arg, NameOp);
    334 
    335         if (!MethodDesc)
    336         {
    337             ACPI_ERROR ((AE_INFO,
    338                 "Control Method %p has no attached object",
    339                 Node));
    340             return_ACPI_STATUS (AE_AML_INTERNAL);
    341         }
    342 
    343         ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
    344             "Control Method - %p Args %X\n",
    345             Node, MethodDesc->Method.ParamCount));
    346 
    347         /* Get the number of arguments to expect */
    348 
    349         WalkState->ArgCount = MethodDesc->Method.ParamCount;
    350         return_ACPI_STATUS (AE_OK);
    351     }
    352 
    353     /*
    354      * Special handling if the name was not found during the lookup -
    355      * some NotFound cases are allowed
    356      */
    357     if (Status == AE_NOT_FOUND)
    358     {
    359         /* 1) NotFound is ok during load pass 1/2 (allow forward references) */
    360 
    361         if ((WalkState->ParseFlags & ACPI_PARSE_MODE_MASK) !=
    362                 ACPI_PARSE_EXECUTE)
    363         {
    364             Status = AE_OK;
    365         }
    366 
    367         /* 2) NotFound during a CondRefOf(x) is ok by definition */
    368 
    369         else if (WalkState->Op->Common.AmlOpcode == AML_COND_REF_OF_OP)
    370         {
    371             Status = AE_OK;
    372         }
    373 
    374         /*
    375          * 3) NotFound while building a Package is ok at this point, we
    376          * may flag as an error later if slack mode is not enabled.
    377          * (Some ASL code depends on allowing this behavior)
    378          */
    379         else if ((Arg->Common.Parent) &&
    380             ((Arg->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||
    381              (Arg->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP)))
    382         {
    383             Status = AE_OK;
    384         }
    385     }
    386 
    387     /* Final exception check (may have been changed from code above) */
    388 
    389     if (ACPI_FAILURE (Status))
    390     {
    391         ACPI_ERROR_NAMESPACE (Path, Status);
    392 
    393         if ((WalkState->ParseFlags & ACPI_PARSE_MODE_MASK) ==
    394                 ACPI_PARSE_EXECUTE)
    395         {
    396             /* Report a control method execution error */
    397 
    398             Status = AcpiDsMethodError (Status, WalkState);
    399         }
    400     }
    401 
    402     /* Save the namepath */
    403 
    404     Arg->Common.Value.Name = Path;
    405     return_ACPI_STATUS (Status);
    406 }
    407 
    408 
    409 /*******************************************************************************
    410  *
    411  * FUNCTION:    AcpiPsGetNextSimpleArg
    412  *
    413  * PARAMETERS:  ParserState         - Current parser state object
    414  *              ArgType             - The argument type (AML_*_ARG)
    415  *              Arg                 - Where the argument is returned
    416  *
    417  * RETURN:      None
    418  *
    419  * DESCRIPTION: Get the next simple argument (constant, string, or namestring)
    420  *
    421  ******************************************************************************/
    422 
    423 void
    424 AcpiPsGetNextSimpleArg (
    425     ACPI_PARSE_STATE        *ParserState,
    426     UINT32                  ArgType,
    427     ACPI_PARSE_OBJECT       *Arg)
    428 {
    429     UINT32                  Length;
    430     UINT16                  Opcode;
    431     UINT8                   *Aml = ParserState->Aml;
    432 
    433 
    434     ACPI_FUNCTION_TRACE_U32 (PsGetNextSimpleArg, ArgType);
    435 
    436 
    437     switch (ArgType)
    438     {
    439     case ARGP_BYTEDATA:
    440 
    441         /* Get 1 byte from the AML stream */
    442 
    443         Opcode = AML_BYTE_OP;
    444         Arg->Common.Value.Integer = (UINT64) *Aml;
    445         Length = 1;
    446         break;
    447 
    448     case ARGP_WORDDATA:
    449 
    450         /* Get 2 bytes from the AML stream */
    451 
    452         Opcode = AML_WORD_OP;
    453         ACPI_MOVE_16_TO_64 (&Arg->Common.Value.Integer, Aml);
    454         Length = 2;
    455         break;
    456 
    457     case ARGP_DWORDDATA:
    458 
    459         /* Get 4 bytes from the AML stream */
    460 
    461         Opcode = AML_DWORD_OP;
    462         ACPI_MOVE_32_TO_64 (&Arg->Common.Value.Integer, Aml);
    463         Length = 4;
    464         break;
    465 
    466     case ARGP_QWORDDATA:
    467 
    468         /* Get 8 bytes from the AML stream */
    469 
    470         Opcode = AML_QWORD_OP;
    471         ACPI_MOVE_64_TO_64 (&Arg->Common.Value.Integer, Aml);
    472         Length = 8;
    473         break;
    474 
    475     case ARGP_CHARLIST:
    476 
    477         /* Get a pointer to the string, point past the string */
    478 
    479         Opcode = AML_STRING_OP;
    480         Arg->Common.Value.String = ACPI_CAST_PTR (char, Aml);
    481 
    482         /* Find the null terminator */
    483 
    484         Length = 0;
    485         while (Aml[Length])
    486         {
    487             Length++;
    488         }
    489         Length++;
    490         break;
    491 
    492     case ARGP_NAME:
    493     case ARGP_NAMESTRING:
    494 
    495         AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP);
    496         Arg->Common.Value.Name = AcpiPsGetNextNamestring (ParserState);
    497         return_VOID;
    498 
    499     default:
    500 
    501         ACPI_ERROR ((AE_INFO, "Invalid ArgType 0x%X", ArgType));
    502         return_VOID;
    503     }
    504 
    505     AcpiPsInitOp (Arg, Opcode);
    506     ParserState->Aml += Length;
    507     return_VOID;
    508 }
    509 
    510 
    511 /*******************************************************************************
    512  *
    513  * FUNCTION:    AcpiPsGetNextField
    514  *
    515  * PARAMETERS:  ParserState         - Current parser state object
    516  *
    517  * RETURN:      A newly allocated FIELD op
    518  *
    519  * DESCRIPTION: Get next field (NamedField, ReservedField, or AccessField)
    520  *
    521  ******************************************************************************/
    522 
    523 static ACPI_PARSE_OBJECT *
    524 AcpiPsGetNextField (
    525     ACPI_PARSE_STATE        *ParserState)
    526 {
    527     UINT8                   *Aml;
    528     ACPI_PARSE_OBJECT       *Field;
    529     ACPI_PARSE_OBJECT       *Arg = NULL;
    530     UINT16                  Opcode;
    531     UINT32                  Name;
    532     UINT8                   AccessType;
    533     UINT8                   AccessAttribute;
    534     UINT8                   AccessLength;
    535     UINT32                  PkgLength;
    536     UINT8                   *PkgEnd;
    537     UINT32                  BufferLength;
    538 
    539 
    540     ACPI_FUNCTION_TRACE (PsGetNextField);
    541 
    542 
    543     Aml = ParserState->Aml;
    544 
    545     /* Determine field type */
    546 
    547     switch (ACPI_GET8 (ParserState->Aml))
    548     {
    549     case AML_FIELD_OFFSET_OP:
    550 
    551         Opcode = AML_INT_RESERVEDFIELD_OP;
    552         ParserState->Aml++;
    553         break;
    554 
    555     case AML_FIELD_ACCESS_OP:
    556 
    557         Opcode = AML_INT_ACCESSFIELD_OP;
    558         ParserState->Aml++;
    559         break;
    560 
    561     case AML_FIELD_CONNECTION_OP:
    562 
    563         Opcode = AML_INT_CONNECTION_OP;
    564         ParserState->Aml++;
    565         break;
    566 
    567     case AML_FIELD_EXT_ACCESS_OP:
    568 
    569         Opcode = AML_INT_EXTACCESSFIELD_OP;
    570         ParserState->Aml++;
    571         break;
    572 
    573     default:
    574 
    575         Opcode = AML_INT_NAMEDFIELD_OP;
    576         break;
    577     }
    578 
    579     /* Allocate a new field op */
    580 
    581     Field = AcpiPsAllocOp (Opcode, Aml);
    582     if (!Field)
    583     {
    584         return_PTR (NULL);
    585     }
    586 
    587     /* Decode the field type */
    588 
    589     switch (Opcode)
    590     {
    591     case AML_INT_NAMEDFIELD_OP:
    592 
    593         /* Get the 4-character name */
    594 
    595         ACPI_MOVE_32_TO_32 (&Name, ParserState->Aml);
    596         AcpiPsSetName (Field, Name);
    597         ParserState->Aml += ACPI_NAME_SIZE;
    598 
    599         /* Get the length which is encoded as a package length */
    600 
    601         Field->Common.Value.Size = AcpiPsGetNextPackageLength (ParserState);
    602         break;
    603 
    604 
    605     case AML_INT_RESERVEDFIELD_OP:
    606 
    607         /* Get the length which is encoded as a package length */
    608 
    609         Field->Common.Value.Size = AcpiPsGetNextPackageLength (ParserState);
    610         break;
    611 
    612 
    613     case AML_INT_ACCESSFIELD_OP:
    614     case AML_INT_EXTACCESSFIELD_OP:
    615 
    616         /*
    617          * Get AccessType and AccessAttrib and merge into the field Op
    618          * AccessType is first operand, AccessAttribute is second. stuff
    619          * these bytes into the node integer value for convenience.
    620          */
    621 
    622         /* Get the two bytes (Type/Attribute) */
    623 
    624         AccessType = ACPI_GET8 (ParserState->Aml);
    625         ParserState->Aml++;
    626         AccessAttribute = ACPI_GET8 (ParserState->Aml);
    627         ParserState->Aml++;
    628 
    629         Field->Common.Value.Integer = (UINT8) AccessType;
    630         Field->Common.Value.Integer |= (UINT16) (AccessAttribute << 8);
    631 
    632         /* This opcode has a third byte, AccessLength */
    633 
    634         if (Opcode == AML_INT_EXTACCESSFIELD_OP)
    635         {
    636             AccessLength = ACPI_GET8 (ParserState->Aml);
    637             ParserState->Aml++;
    638 
    639             Field->Common.Value.Integer |= (UINT32) (AccessLength << 16);
    640         }
    641         break;
    642 
    643 
    644     case AML_INT_CONNECTION_OP:
    645 
    646         /*
    647          * Argument for Connection operator can be either a Buffer
    648          * (resource descriptor), or a NameString.
    649          */
    650         Aml = ParserState->Aml;
    651         if (ACPI_GET8 (ParserState->Aml) == AML_BUFFER_OP)
    652         {
    653             ParserState->Aml++;
    654 
    655             PkgEnd = ParserState->Aml;
    656             PkgLength = AcpiPsGetNextPackageLength (ParserState);
    657             PkgEnd += PkgLength;
    658 
    659             if (ParserState->Aml < PkgEnd)
    660             {
    661                 /* Non-empty list */
    662 
    663                 Arg = AcpiPsAllocOp (AML_INT_BYTELIST_OP, Aml);
    664                 if (!Arg)
    665                 {
    666                     AcpiPsFreeOp (Field);
    667                     return_PTR (NULL);
    668                 }
    669 
    670                 /* Get the actual buffer length argument */
    671 
    672                 Opcode = ACPI_GET8 (ParserState->Aml);
    673                 ParserState->Aml++;
    674 
    675                 switch (Opcode)
    676                 {
    677                 case AML_BYTE_OP:       /* AML_BYTEDATA_ARG */
    678 
    679                     BufferLength = ACPI_GET8 (ParserState->Aml);
    680                     ParserState->Aml += 1;
    681                     break;
    682 
    683                 case AML_WORD_OP:       /* AML_WORDDATA_ARG */
    684 
    685                     BufferLength = ACPI_GET16 (ParserState->Aml);
    686                     ParserState->Aml += 2;
    687                     break;
    688 
    689                 case AML_DWORD_OP:      /* AML_DWORDATA_ARG */
    690 
    691                     BufferLength = ACPI_GET32 (ParserState->Aml);
    692                     ParserState->Aml += 4;
    693                     break;
    694 
    695                 default:
    696 
    697                     BufferLength = 0;
    698                     break;
    699                 }
    700 
    701                 /* Fill in bytelist data */
    702 
    703                 Arg->Named.Value.Size = BufferLength;
    704                 Arg->Named.Data = ParserState->Aml;
    705             }
    706 
    707             /* Skip to End of byte data */
    708 
    709             ParserState->Aml = PkgEnd;
    710         }
    711         else
    712         {
    713             Arg = AcpiPsAllocOp (AML_INT_NAMEPATH_OP, Aml);
    714             if (!Arg)
    715             {
    716                 AcpiPsFreeOp (Field);
    717                 return_PTR (NULL);
    718             }
    719 
    720             /* Get the Namestring argument */
    721 
    722             Arg->Common.Value.Name = AcpiPsGetNextNamestring (ParserState);
    723         }
    724 
    725         /* Link the buffer/namestring to parent (CONNECTION_OP) */
    726 
    727         AcpiPsAppendArg (Field, Arg);
    728         break;
    729 
    730 
    731     default:
    732 
    733         /* Opcode was set in previous switch */
    734         break;
    735     }
    736 
    737     return_PTR (Field);
    738 }
    739 
    740 
    741 /*******************************************************************************
    742  *
    743  * FUNCTION:    AcpiPsGetNextArg
    744  *
    745  * PARAMETERS:  WalkState           - Current state
    746  *              ParserState         - Current parser state object
    747  *              ArgType             - The argument type (AML_*_ARG)
    748  *              ReturnArg           - Where the next arg is returned
    749  *
    750  * RETURN:      Status, and an op object containing the next argument.
    751  *
    752  * DESCRIPTION: Get next argument (including complex list arguments that require
    753  *              pushing the parser stack)
    754  *
    755  ******************************************************************************/
    756 
    757 ACPI_STATUS
    758 AcpiPsGetNextArg (
    759     ACPI_WALK_STATE         *WalkState,
    760     ACPI_PARSE_STATE        *ParserState,
    761     UINT32                  ArgType,
    762     ACPI_PARSE_OBJECT       **ReturnArg)
    763 {
    764     ACPI_PARSE_OBJECT       *Arg = NULL;
    765     ACPI_PARSE_OBJECT       *Prev = NULL;
    766     ACPI_PARSE_OBJECT       *Field;
    767     UINT32                  Subop;
    768     ACPI_STATUS             Status = AE_OK;
    769 
    770 
    771     ACPI_FUNCTION_TRACE_PTR (PsGetNextArg, ParserState);
    772 
    773 
    774     switch (ArgType)
    775     {
    776     case ARGP_BYTEDATA:
    777     case ARGP_WORDDATA:
    778     case ARGP_DWORDDATA:
    779     case ARGP_CHARLIST:
    780     case ARGP_NAME:
    781     case ARGP_NAMESTRING:
    782 
    783         /* Constants, strings, and namestrings are all the same size */
    784 
    785         Arg = AcpiPsAllocOp (AML_BYTE_OP, ParserState->Aml);
    786         if (!Arg)
    787         {
    788             return_ACPI_STATUS (AE_NO_MEMORY);
    789         }
    790         AcpiPsGetNextSimpleArg (ParserState, ArgType, Arg);
    791         break;
    792 
    793     case ARGP_PKGLENGTH:
    794 
    795         /* Package length, nothing returned */
    796 
    797         ParserState->PkgEnd = AcpiPsGetNextPackageEnd (ParserState);
    798         break;
    799 
    800     case ARGP_FIELDLIST:
    801 
    802         if (ParserState->Aml < ParserState->PkgEnd)
    803         {
    804             /* Non-empty list */
    805 
    806             while (ParserState->Aml < ParserState->PkgEnd)
    807             {
    808                 Field = AcpiPsGetNextField (ParserState);
    809                 if (!Field)
    810                 {
    811                     return_ACPI_STATUS (AE_NO_MEMORY);
    812                 }
    813 
    814                 if (Prev)
    815                 {
    816                     Prev->Common.Next = Field;
    817                 }
    818                 else
    819                 {
    820                     Arg = Field;
    821                 }
    822                 Prev = Field;
    823             }
    824 
    825             /* Skip to End of byte data */
    826 
    827             ParserState->Aml = ParserState->PkgEnd;
    828         }
    829         break;
    830 
    831     case ARGP_BYTELIST:
    832 
    833         if (ParserState->Aml < ParserState->PkgEnd)
    834         {
    835             /* Non-empty list */
    836 
    837             Arg = AcpiPsAllocOp (AML_INT_BYTELIST_OP,
    838                     ParserState->Aml);
    839             if (!Arg)
    840             {
    841                 return_ACPI_STATUS (AE_NO_MEMORY);
    842             }
    843 
    844             /* Fill in bytelist data */
    845 
    846             Arg->Common.Value.Size = (UINT32)
    847                 ACPI_PTR_DIFF (ParserState->PkgEnd, ParserState->Aml);
    848             Arg->Named.Data = ParserState->Aml;
    849 
    850             /* Skip to End of byte data */
    851 
    852             ParserState->Aml = ParserState->PkgEnd;
    853         }
    854         break;
    855 
    856     case ARGP_TARGET:
    857     case ARGP_SUPERNAME:
    858     case ARGP_SIMPLENAME:
    859 
    860         Subop = AcpiPsPeekOpcode (ParserState);
    861         if (Subop == 0                  ||
    862             AcpiPsIsLeadingChar (Subop) ||
    863             ACPI_IS_ROOT_PREFIX (Subop) ||
    864             ACPI_IS_PARENT_PREFIX (Subop))
    865         {
    866             /* NullName or NameString */
    867 
    868             Arg = AcpiPsAllocOp (AML_INT_NAMEPATH_OP, ParserState->Aml);
    869             if (!Arg)
    870             {
    871                 return_ACPI_STATUS (AE_NO_MEMORY);
    872             }
    873 
    874             /* To support SuperName arg of Unload */
    875 
    876             if (WalkState->Opcode == AML_UNLOAD_OP)
    877             {
    878                 Status = AcpiPsGetNextNamepath (WalkState, ParserState, Arg, 1);
    879 
    880                 /*
    881                  * If the SuperName arg of Unload is a method call,
    882                  * we have restored the AML pointer, just free this Arg
    883                  */
    884                 if (Arg->Common.AmlOpcode == AML_INT_METHODCALL_OP)
    885                 {
    886                     AcpiPsFreeOp (Arg);
    887                     Arg = NULL;
    888                 }
    889             }
    890             else
    891             {
    892                 Status = AcpiPsGetNextNamepath (WalkState, ParserState, Arg, 0);
    893             }
    894         }
    895         else
    896         {
    897             /* Single complex argument, nothing returned */
    898 
    899             WalkState->ArgCount = 1;
    900         }
    901         break;
    902 
    903     case ARGP_DATAOBJ:
    904     case ARGP_TERMARG:
    905 
    906         /* Single complex argument, nothing returned */
    907 
    908         WalkState->ArgCount = 1;
    909         break;
    910 
    911     case ARGP_DATAOBJLIST:
    912     case ARGP_TERMLIST:
    913     case ARGP_OBJLIST:
    914 
    915         if (ParserState->Aml < ParserState->PkgEnd)
    916         {
    917             /* Non-empty list of variable arguments, nothing returned */
    918 
    919             WalkState->ArgCount = ACPI_VAR_ARGS;
    920         }
    921         break;
    922 
    923     default:
    924 
    925         ACPI_ERROR ((AE_INFO, "Invalid ArgType: 0x%X", ArgType));
    926         Status = AE_AML_OPERAND_TYPE;
    927         break;
    928     }
    929 
    930     *ReturnArg = Arg;
    931     return_ACPI_STATUS (Status);
    932 }
    933