Home | History | Annotate | Line # | Download | only in parser
      1 /******************************************************************************
      2  *
      3  * Module Name: psargs - Parse AML opcode arguments
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2026, 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 MERCHANTABILITY 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 #include "acconvert.h"
     51 
     52 #define _COMPONENT          ACPI_PARSER
     53         ACPI_MODULE_NAME    ("psargs")
     54 
     55 /* Local prototypes */
     56 
     57 static UINT32
     58 AcpiPsGetNextPackageLength (
     59     ACPI_PARSE_STATE        *ParserState);
     60 
     61 static ACPI_PARSE_OBJECT *
     62 AcpiPsGetNextField (
     63     ACPI_PARSE_STATE        *ParserState);
     64 
     65 static void
     66 AcpiPsFreeFieldList (
     67     ACPI_PARSE_OBJECT       *Start);
     68 
     69 
     70 /*******************************************************************************
     71  *
     72  * FUNCTION:    AcpiPsGetNextPackageLength
     73  *
     74  * PARAMETERS:  ParserState         - Current parser state object
     75  *
     76  * RETURN:      Decoded package length. On completion, the AML pointer points
     77  *              past the length byte or bytes.
     78  *
     79  * DESCRIPTION: Decode and return a package length field.
     80  *              Note: Largest package length is 28 bits, from ACPI specification
     81  *
     82  ******************************************************************************/
     83 
     84 static UINT32
     85 AcpiPsGetNextPackageLength (
     86     ACPI_PARSE_STATE        *ParserState)
     87 {
     88     UINT8                   *Aml = ParserState->Aml;
     89     UINT32                  PackageLength = 0;
     90     UINT32                  ByteCount;
     91     UINT8                   ByteZeroMask = 0x3F; /* Default [0:5] */
     92     UINT32                  Remaining;
     93 
     94 
     95     ACPI_FUNCTION_TRACE (PsGetNextPackageLength);
     96 
     97 
     98     /*
     99      * Byte 0 bits [6:7] contain the number of additional bytes
    100      * used to encode the package length, either 0,1,2, or 3
    101      */
    102 
    103     /* Check if we have at least one byte to read */
    104     Remaining = (UINT32) ACPI_PTR_DIFF (ParserState->AmlEnd, Aml);
    105     if (Remaining == 0)
    106     {
    107         return_UINT32 (0);
    108     }
    109 
    110     ByteCount = (Aml[0] >> 6);
    111 
    112     /* Validate ByteCount and ensure we have enough bytes to read */
    113     if (ByteCount >= Remaining)
    114     {
    115         /* Clamp to available bytes and advance to end */
    116         ParserState->Aml = ParserState->AmlEnd;
    117         return_UINT32 (0);
    118     }
    119 
    120     ParserState->Aml += ((ACPI_SIZE) ByteCount + 1);
    121 
    122     /* Get bytes 3, 2, 1 as needed */
    123 
    124     while (ByteCount)
    125     {
    126         /*
    127          * Final bit positions for the package length bytes:
    128          *      Byte3->[20:27]
    129          *      Byte2->[12:19]
    130          *      Byte1->[04:11]
    131          *      Byte0->[00:03]
    132          */
    133         PackageLength |= (Aml[ByteCount] << ((ByteCount << 3) - 4));
    134 
    135         ByteZeroMask = 0x0F; /* Use bits [0:3] of byte 0 */
    136         ByteCount--;
    137     }
    138 
    139     /* Byte 0 is a special case, either bits [0:3] or [0:5] are used */
    140 
    141     PackageLength |= (Aml[0] & ByteZeroMask);
    142     return_UINT32 (PackageLength);
    143 }
    144 
    145 
    146 /*******************************************************************************
    147  *
    148  * FUNCTION:    AcpiPsGetNextPackageEnd
    149  *
    150  * PARAMETERS:  ParserState         - Current parser state object
    151  *
    152  * RETURN:      Pointer to end-of-package +1
    153  *
    154  * DESCRIPTION: Get next package length and return a pointer past the end of
    155  *              the package. Consumes the package length field
    156  *
    157  ******************************************************************************/
    158 
    159 UINT8 *
    160 AcpiPsGetNextPackageEnd (
    161     ACPI_PARSE_STATE        *ParserState)
    162 {
    163     UINT8                   *Start = ParserState->Aml;
    164     UINT32                  PackageLength;
    165 
    166 
    167     ACPI_FUNCTION_TRACE (PsGetNextPackageEnd);
    168 
    169 
    170     /* Function below updates ParserState->Aml */
    171 
    172     PackageLength = AcpiPsGetNextPackageLength (ParserState);
    173 
    174     return_PTR (Start + PackageLength); /* end of package */
    175 }
    176 
    177 
    178 /*******************************************************************************
    179  *
    180  * FUNCTION:    AcpiPsGetNextNamestring
    181  *
    182  * PARAMETERS:  ParserState         - Current parser state object
    183  *
    184  * RETURN:      Pointer to the start of the name string (pointer points into
    185  *              the AML.
    186  *
    187  * DESCRIPTION: Get next raw namestring within the AML stream. Handles all name
    188  *              prefix characters. Set parser state to point past the string.
    189  *              (Name is consumed from the AML.)
    190  *
    191  ******************************************************************************/
    192 
    193 char *
    194 AcpiPsGetNextNamestring (
    195     ACPI_PARSE_STATE        *ParserState)
    196 {
    197     UINT8                   *Start = ParserState->Aml;
    198     UINT8                   *End = ParserState->Aml;
    199 
    200 
    201     ACPI_FUNCTION_TRACE (PsGetNextNamestring);
    202 
    203 
    204     /* Point past any namestring prefix characters (backslash or carat) */
    205 
    206     while (ACPI_IS_ROOT_PREFIX (*End) ||
    207            ACPI_IS_PARENT_PREFIX (*End))
    208     {
    209         End++;
    210     }
    211 
    212     /* Decode the path prefix character */
    213 
    214     switch (*End)
    215     {
    216     case 0:
    217 
    218         /* NullName */
    219 
    220         if (End == Start)
    221         {
    222             Start = NULL;
    223         }
    224         End++;
    225         break;
    226 
    227     case AML_DUAL_NAME_PREFIX:
    228 
    229         /* Two name segments */
    230 
    231         End += 1 + (2 * ACPI_NAMESEG_SIZE);
    232         break;
    233 
    234     case AML_MULTI_NAME_PREFIX:
    235 
    236         /* Multiple name segments, 4 chars each, count in next byte */
    237 
    238         End += 2 + (*(End + 1) * ACPI_NAMESEG_SIZE);
    239         break;
    240 
    241     default:
    242 
    243         /* Single name segment */
    244 
    245         End += ACPI_NAMESEG_SIZE;
    246         break;
    247     }
    248 
    249     ParserState->Aml = End;
    250     return_PTR ((char *) Start);
    251 }
    252 
    253 
    254 /*******************************************************************************
    255  *
    256  * FUNCTION:    AcpiPsGetNextNamepath
    257  *
    258  * PARAMETERS:  ParserState         - Current parser state object
    259  *              Arg                 - Where the namepath will be stored
    260  *              ArgCount            - If the namepath points to a control method
    261  *                                    the method's argument is returned here.
    262  *              PossibleMethodCall  - Whether the namepath can possibly be the
    263  *                                    start of a method call
    264  *
    265  * RETURN:      Status
    266  *
    267  * DESCRIPTION: Get next name (if method call, return # of required args).
    268  *              Names are looked up in the internal namespace to determine
    269  *              if the name represents a control method. If a method
    270  *              is found, the number of arguments to the method is returned.
    271  *              This information is critical for parsing to continue correctly.
    272  *
    273  ******************************************************************************/
    274 
    275 ACPI_STATUS
    276 AcpiPsGetNextNamepath (
    277     ACPI_WALK_STATE         *WalkState,
    278     ACPI_PARSE_STATE        *ParserState,
    279     ACPI_PARSE_OBJECT       *Arg,
    280     BOOLEAN                 PossibleMethodCall)
    281 {
    282     ACPI_STATUS             Status;
    283     char                    *Path;
    284     ACPI_PARSE_OBJECT       *NameOp;
    285     ACPI_OPERAND_OBJECT     *MethodDesc;
    286     ACPI_NAMESPACE_NODE     *Node;
    287     UINT8                   *Start = ParserState->Aml;
    288 
    289 
    290     ACPI_FUNCTION_TRACE (PsGetNextNamepath);
    291 
    292 
    293     Path = AcpiPsGetNextNamestring (ParserState);
    294     AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP);
    295 
    296     /* Null path case is allowed, just exit */
    297 
    298     if (!Path)
    299     {
    300         Arg->Common.Value.Name = Path;
    301         return_ACPI_STATUS (AE_OK);
    302     }
    303 
    304     /*
    305      * Lookup the name in the internal namespace, starting with the current
    306      * scope. We don't want to add anything new to the namespace here,
    307      * however, so we use MODE_EXECUTE.
    308      * Allow searching of the parent tree, but don't open a new scope -
    309      * we just want to lookup the object (must be mode EXECUTE to perform
    310      * the upsearch)
    311      */
    312     Status = AcpiNsLookup (WalkState->ScopeInfo, Path,
    313         ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
    314         ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL, &Node);
    315 
    316     /*
    317      * If this name is a control method invocation, we must
    318      * setup the method call
    319      */
    320     if (ACPI_SUCCESS (Status) &&
    321         PossibleMethodCall &&
    322         (Node->Type == ACPI_TYPE_METHOD))
    323     {
    324         if ((GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) == ARGP_SUPERNAME) ||
    325             (GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) == ARGP_TARGET))
    326         {
    327             /*
    328              * AcpiPsGetNextNamestring has increased the AML pointer past
    329              * the method invocation namestring, so we need to restore the
    330              * saved AML pointer back to the original method invocation
    331              * namestring.
    332              */
    333             WalkState->ParserState.Aml = Start;
    334             WalkState->ArgCount = 1;
    335             AcpiPsInitOp (Arg, AML_INT_METHODCALL_OP);
    336         }
    337 
    338         /* This name is actually a control method invocation */
    339 
    340         MethodDesc = AcpiNsGetAttachedObject (Node);
    341         ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
    342             "Control Method invocation %4.4s - %p Desc %p Path=%p\n",
    343             Node->Name.Ascii, Node, MethodDesc, Path));
    344 
    345         NameOp = AcpiPsAllocOp (AML_INT_NAMEPATH_OP, Start);
    346         if (!NameOp)
    347         {
    348             return_ACPI_STATUS (AE_NO_MEMORY);
    349         }
    350 
    351         /* Change Arg into a METHOD CALL and attach name to it */
    352 
    353         AcpiPsInitOp (Arg, AML_INT_METHODCALL_OP);
    354         NameOp->Common.Value.Name = Path;
    355 
    356         /* Point METHODCALL/NAME to the METHOD Node */
    357 
    358         NameOp->Common.Node = Node;
    359         AcpiPsAppendArg (Arg, NameOp);
    360 
    361         if (!MethodDesc)
    362         {
    363             ACPI_ERROR ((AE_INFO,
    364                 "Control Method %p has no attached object",
    365                 Node));
    366             return_ACPI_STATUS (AE_AML_INTERNAL);
    367         }
    368 
    369         ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
    370             "Control Method - %p Args %X\n",
    371             Node, MethodDesc->Method.ParamCount));
    372 
    373         /* Get the number of arguments to expect */
    374 
    375         WalkState->ArgCount = MethodDesc->Method.ParamCount;
    376         return_ACPI_STATUS (AE_OK);
    377     }
    378 
    379     /*
    380      * Special handling if the name was not found during the lookup -
    381      * some NotFound cases are allowed
    382      */
    383     if (Status == AE_NOT_FOUND)
    384     {
    385         /* 1) NotFound is ok during load pass 1/2 (allow forward references) */
    386 
    387         if ((WalkState->ParseFlags & ACPI_PARSE_MODE_MASK) !=
    388             ACPI_PARSE_EXECUTE)
    389         {
    390             Status = AE_OK;
    391         }
    392 
    393         /* 2) NotFound during a CondRefOf(x) is ok by definition */
    394 
    395         else if (WalkState->Op->Common.AmlOpcode == AML_CONDITIONAL_REF_OF_OP)
    396         {
    397             Status = AE_OK;
    398         }
    399 
    400         /*
    401          * 3) NotFound while building a Package is ok at this point, we
    402          * may flag as an error later if slack mode is not enabled.
    403          * (Some ASL code depends on allowing this behavior)
    404          */
    405         else if ((Arg->Common.Parent) &&
    406             ((Arg->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||
    407              (Arg->Common.Parent->Common.AmlOpcode == AML_VARIABLE_PACKAGE_OP)))
    408         {
    409             Status = AE_OK;
    410         }
    411     }
    412 
    413     /* Final exception check (may have been changed from code above) */
    414 
    415     if (ACPI_FAILURE (Status))
    416     {
    417         ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo, Path, Status);
    418 
    419         if ((WalkState->ParseFlags & ACPI_PARSE_MODE_MASK) ==
    420             ACPI_PARSE_EXECUTE)
    421         {
    422             /* Report a control method execution error */
    423 
    424             Status = AcpiDsMethodError (Status, WalkState);
    425         }
    426     }
    427 
    428     /* Save the namepath */
    429 
    430     Arg->Common.Value.Name = Path;
    431     return_ACPI_STATUS (Status);
    432 }
    433 
    434 
    435 /*******************************************************************************
    436  *
    437  * FUNCTION:    AcpiPsGetNextSimpleArg
    438  *
    439  * PARAMETERS:  ParserState         - Current parser state object
    440  *              ArgType             - The argument type (AML_*_ARG)
    441  *              Arg                 - Where the argument is returned
    442  *
    443  * RETURN:      None
    444  *
    445  * DESCRIPTION: Get the next simple argument (constant, string, or namestring)
    446  *
    447  ******************************************************************************/
    448 
    449 void
    450 AcpiPsGetNextSimpleArg (
    451     ACPI_PARSE_STATE        *ParserState,
    452     UINT32                  ArgType,
    453     ACPI_PARSE_OBJECT       *Arg)
    454 {
    455     UINT32                  Length;
    456     UINT16                  Opcode;
    457     UINT8                   *Aml = ParserState->Aml;
    458     UINT32                  Remaining = (UINT32) ACPI_PTR_DIFF (ParserState->AmlEnd, Aml);
    459     UINT64                  PartialValue;
    460 
    461 
    462     ACPI_FUNCTION_TRACE_U32 (PsGetNextSimpleArg, ArgType);
    463 
    464 
    465     switch (ArgType)
    466     {
    467     case ARGP_BYTEDATA:
    468 
    469         /* Get 1 byte from the AML stream */
    470 
    471         Opcode = AML_BYTE_OP;
    472         if (Remaining >= 1)
    473         {
    474             Arg->Common.Value.Integer = (UINT64) *Aml;
    475             Length = 1;
    476         }
    477         else
    478         {
    479             Arg->Common.Value.Integer = 0;
    480             Length = 0;
    481         }
    482         break;
    483 
    484     case ARGP_WORDDATA:
    485 
    486         /* Get 2 bytes from the AML stream */
    487 
    488         Opcode = AML_WORD_OP;
    489         if (Remaining >= 2)
    490         {
    491             ACPI_MOVE_16_TO_64 (&Arg->Common.Value.Integer, Aml);
    492             Length = 2;
    493         }
    494         else
    495         {
    496             Arg->Common.Value.Integer = 0;
    497             Length = 0;
    498             if (Remaining > 0)
    499             {
    500                 PartialValue = 0;
    501                 memcpy (&PartialValue, Aml, Remaining);
    502                 Arg->Common.Value.Integer = PartialValue;
    503                 Length = Remaining;
    504             }
    505         }
    506         break;
    507 
    508     case ARGP_DWORDDATA:
    509 
    510         /* Get 4 bytes from the AML stream */
    511 
    512         Opcode = AML_DWORD_OP;
    513         if (Remaining >= 4)
    514         {
    515             ACPI_MOVE_32_TO_64 (&Arg->Common.Value.Integer, Aml);
    516             Length = 4;
    517         }
    518         else
    519         {
    520             Arg->Common.Value.Integer = 0;
    521             Length = 0;
    522             if (Remaining > 0)
    523             {
    524                 PartialValue = 0;
    525                 memcpy (&PartialValue, Aml, Remaining);
    526                 Arg->Common.Value.Integer = PartialValue;
    527                 Length = Remaining;
    528             }
    529         }
    530         break;
    531 
    532     case ARGP_QWORDDATA:
    533 
    534         /* Get 8 bytes from the AML stream */
    535 
    536         Opcode = AML_QWORD_OP;
    537         if (Remaining >= 8)
    538         {
    539             ACPI_MOVE_64_TO_64 (&Arg->Common.Value.Integer, Aml);
    540             Length = 8;
    541         }
    542         else
    543         {
    544             Arg->Common.Value.Integer = 0;
    545             Length = 0;
    546             if (Remaining > 0)
    547             {
    548                 PartialValue = 0;
    549                 memcpy (&PartialValue, Aml, Remaining);
    550                 Arg->Common.Value.Integer = PartialValue;
    551                 Length = Remaining;
    552             }
    553         }
    554         break;
    555 
    556     case ARGP_CHARLIST:
    557 
    558         /* Get a pointer to the string, point past the string */
    559 
    560         Opcode = AML_STRING_OP;
    561         Arg->Common.Value.String = ACPI_CAST_PTR (char, Aml);
    562 
    563         /* Find the null terminator */
    564 
    565         Length = 0;
    566         while ((Length < Remaining) && Aml[Length])
    567         {
    568             Length++;
    569         }
    570         if (Length < Remaining)
    571         {
    572             /* Account for the terminating null */
    573             Length++;
    574         }
    575         else
    576         {
    577             /*
    578              * No terminator found - add null at buffer boundary
    579              * and report a warning
    580              */
    581             ACPI_WARNING ((AE_INFO,
    582                 "Invalid AML string: no null terminator, truncating at offset %u",
    583                 (UINT32) (Aml - ParserState->Aml)));
    584 
    585             /* Add null terminator at the boundary */
    586             if (Remaining > 0)
    587             {
    588                 Aml[Remaining - 1] = 0;
    589                 Length = Remaining;
    590             }
    591         }
    592         break;
    593 
    594     case ARGP_NAME:
    595     case ARGP_NAMESTRING:
    596 
    597         AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP);
    598         Arg->Common.Value.Name = AcpiPsGetNextNamestring (ParserState);
    599         return_VOID;
    600 
    601     default:
    602 
    603         ACPI_ERROR ((AE_INFO, "Invalid ArgType 0x%X", ArgType));
    604         return_VOID;
    605     }
    606 
    607     AcpiPsInitOp (Arg, Opcode);
    608     ParserState->Aml += Length;
    609     return_VOID;
    610 }
    611 
    612 
    613 /*******************************************************************************
    614  *
    615  * FUNCTION:    AcpiPsGetNextField
    616  *
    617  * PARAMETERS:  ParserState         - Current parser state object
    618  *
    619  * RETURN:      A newly allocated FIELD op
    620  *
    621  * DESCRIPTION: Get next field (NamedField, ReservedField, or AccessField)
    622  *
    623  ******************************************************************************/
    624 
    625 static ACPI_PARSE_OBJECT *
    626 AcpiPsGetNextField (
    627     ACPI_PARSE_STATE        *ParserState)
    628 {
    629     UINT8                   *Aml;
    630     ACPI_PARSE_OBJECT       *Field;
    631     ACPI_PARSE_OBJECT       *Arg = NULL;
    632     UINT16                  Opcode;
    633     UINT32                  Name;
    634     UINT8                   AccessType;
    635     UINT8                   AccessAttribute;
    636     UINT8                   AccessLength;
    637     UINT32                  PkgLength;
    638     UINT8                   *PkgEnd;
    639     UINT32                  BufferLength;
    640 
    641 
    642     ACPI_FUNCTION_TRACE (PsGetNextField);
    643 
    644 
    645     ASL_CV_CAPTURE_COMMENTS_ONLY (ParserState);
    646     Aml = ParserState->Aml;
    647 
    648     if (Aml >= ParserState->AmlEnd)
    649     {
    650         return_PTR (NULL);
    651     }
    652 
    653     /* Determine field type */
    654 
    655     switch (ACPI_GET8 (ParserState->Aml))
    656     {
    657     case AML_FIELD_OFFSET_OP:
    658 
    659         Opcode = AML_INT_RESERVEDFIELD_OP;
    660         ParserState->Aml++;
    661         break;
    662 
    663     case AML_FIELD_ACCESS_OP:
    664 
    665         Opcode = AML_INT_ACCESSFIELD_OP;
    666         ParserState->Aml++;
    667         break;
    668 
    669     case AML_FIELD_CONNECTION_OP:
    670 
    671         Opcode = AML_INT_CONNECTION_OP;
    672         ParserState->Aml++;
    673         break;
    674 
    675     case AML_FIELD_EXT_ACCESS_OP:
    676 
    677         Opcode = AML_INT_EXTACCESSFIELD_OP;
    678         ParserState->Aml++;
    679         break;
    680 
    681     default:
    682 
    683         Opcode = AML_INT_NAMEDFIELD_OP;
    684         break;
    685     }
    686 
    687     /* Allocate a new field op */
    688 
    689     Field = AcpiPsAllocOp (Opcode, Aml);
    690     if (!Field)
    691     {
    692         return_PTR (NULL);
    693     }
    694 
    695     /* Decode the field type */
    696 
    697     ASL_CV_CAPTURE_COMMENTS_ONLY (ParserState);
    698     switch (Opcode)
    699     {
    700     case AML_INT_NAMEDFIELD_OP:
    701 
    702         /* Get the 4-character name */
    703 
    704         if ((ParserState->Aml + ACPI_NAMESEG_SIZE) > ParserState->AmlEnd)
    705         {
    706             AcpiPsFreeOp (Field);
    707             return_PTR (NULL);
    708         }
    709         ACPI_MOVE_32_TO_32 (&Name, ParserState->Aml);
    710         AcpiPsSetName (Field, Name);
    711         ParserState->Aml += ACPI_NAMESEG_SIZE;
    712 
    713 
    714         ASL_CV_CAPTURE_COMMENTS_ONLY (ParserState);
    715 
    716 #ifdef ACPI_ASL_COMPILER
    717         /*
    718          * Because the package length isn't represented as a parse tree object,
    719          * take comments surrounding this and add to the previously created
    720          * parse node.
    721          */
    722         if (Field->Common.InlineComment)
    723         {
    724             Field->Common.NameComment = Field->Common.InlineComment;
    725         }
    726         Field->Common.InlineComment  = AcpiGbl_CurrentInlineComment;
    727         AcpiGbl_CurrentInlineComment = NULL;
    728 #endif
    729 
    730         /* Get the length which is encoded as a package length */
    731 
    732         Field->Common.Value.Size = AcpiPsGetNextPackageLength (ParserState);
    733         break;
    734 
    735 
    736     case AML_INT_RESERVEDFIELD_OP:
    737 
    738         /* Get the length which is encoded as a package length */
    739 
    740         Field->Common.Value.Size = AcpiPsGetNextPackageLength (ParserState);
    741         break;
    742 
    743 
    744     case AML_INT_ACCESSFIELD_OP:
    745     case AML_INT_EXTACCESSFIELD_OP:
    746 
    747         /*
    748          * Get AccessType and AccessAttrib and merge into the field Op
    749          * AccessType is first operand, AccessAttribute is second. stuff
    750          * these bytes into the node integer value for convenience.
    751          */
    752 
    753         /* Get the two bytes (Type/Attribute) */
    754 
    755         if ((ParserState->Aml + 2) > ParserState->AmlEnd)
    756         {
    757             AcpiPsFreeOp (Field);
    758             return_PTR (NULL);
    759         }
    760         AccessType = ACPI_GET8 (ParserState->Aml);
    761         ParserState->Aml++;
    762         AccessAttribute = ACPI_GET8 (ParserState->Aml);
    763         ParserState->Aml++;
    764 
    765         Field->Common.Value.Integer = (UINT8) AccessType;
    766         Field->Common.Value.Integer |= (UINT16) (AccessAttribute << 8);
    767 
    768         /* This opcode has a third byte, AccessLength */
    769 
    770         if (Opcode == AML_INT_EXTACCESSFIELD_OP)
    771         {
    772             if (ParserState->Aml >= ParserState->AmlEnd)
    773             {
    774                 AcpiPsFreeOp (Field);
    775                 return_PTR (NULL);
    776             }
    777             AccessLength = ACPI_GET8 (ParserState->Aml);
    778             ParserState->Aml++;
    779 
    780             Field->Common.Value.Integer |= (UINT32) (AccessLength << 16);
    781         }
    782         break;
    783 
    784 
    785     case AML_INT_CONNECTION_OP:
    786 
    787         /*
    788          * Argument for Connection operator can be either a Buffer
    789          * (resource descriptor), or a NameString.
    790          */
    791         Aml = ParserState->Aml;
    792         if (ACPI_GET8 (ParserState->Aml) == AML_BUFFER_OP)
    793         {
    794             ParserState->Aml++;
    795 
    796             ASL_CV_CAPTURE_COMMENTS_ONLY (ParserState);
    797             PkgEnd = ParserState->Aml;
    798             PkgLength = AcpiPsGetNextPackageLength (ParserState);
    799             PkgEnd += PkgLength;
    800 
    801             ASL_CV_CAPTURE_COMMENTS_ONLY (ParserState);
    802             if (ParserState->Aml < PkgEnd)
    803             {
    804                 /* Non-empty list */
    805 
    806                 Arg = AcpiPsAllocOp (AML_INT_BYTELIST_OP, Aml);
    807                 if (!Arg)
    808                 {
    809                     AcpiPsFreeOp (Field);
    810                     return_PTR (NULL);
    811                 }
    812 
    813                 /* Get the actual buffer length argument */
    814 
    815                 Opcode = ACPI_GET8 (ParserState->Aml);
    816                 ParserState->Aml++;
    817 
    818                 ASL_CV_CAPTURE_COMMENTS_ONLY (ParserState);
    819                 switch (Opcode)
    820                 {
    821                 case AML_BYTE_OP:       /* AML_BYTEDATA_ARG */
    822 
    823                     BufferLength = ACPI_GET8 (ParserState->Aml);
    824                     ParserState->Aml += 1;
    825                     break;
    826 
    827                 case AML_WORD_OP:       /* AML_WORDDATA_ARG */
    828 
    829                     BufferLength = ACPI_GET16 (ParserState->Aml);
    830                     ParserState->Aml += 2;
    831                     break;
    832 
    833                 case AML_DWORD_OP:      /* AML_DWORDATA_ARG */
    834 
    835                     BufferLength = ACPI_GET32 (ParserState->Aml);
    836                     ParserState->Aml += 4;
    837                     break;
    838 
    839                 default:
    840 
    841                     BufferLength = 0;
    842                     break;
    843                 }
    844 
    845                 /* Fill in bytelist data */
    846 
    847                 ASL_CV_CAPTURE_COMMENTS_ONLY (ParserState);
    848                 Arg->Named.Value.Size = BufferLength;
    849                 Arg->Named.Data = ParserState->Aml;
    850             }
    851 
    852             /* Skip to End of byte data */
    853 
    854             ParserState->Aml = PkgEnd;
    855         }
    856         else
    857         {
    858             Arg = AcpiPsAllocOp (AML_INT_NAMEPATH_OP, Aml);
    859             if (!Arg)
    860             {
    861                 AcpiPsFreeOp (Field);
    862                 return_PTR (NULL);
    863             }
    864 
    865             /* Get the Namestring argument */
    866 
    867             Arg->Common.Value.Name = AcpiPsGetNextNamestring (ParserState);
    868         }
    869 
    870         /* Link the buffer/namestring to parent (CONNECTION_OP) */
    871 
    872         AcpiPsAppendArg (Field, Arg);
    873         break;
    874 
    875 
    876     default:
    877 
    878         /* Opcode was set in previous switch */
    879         break;
    880     }
    881 
    882     return_PTR (Field);
    883 }
    884 
    885 /*******************************************************************************
    886  *
    887  * FUNCTION:    AcpiPsFreeFieldList
    888  *
    889  * PARAMETERS:  Start               - First Op in field list
    890  *
    891  * RETURN:      None.
    892  *
    893  * DESCRIPTION: Free all Op objects inside a field list.
    894  *
    895  ******************************************************************************/
    896 
    897 static void
    898 AcpiPsFreeFieldList (
    899     ACPI_PARSE_OBJECT	*Start)
    900 {
    901     ACPI_PARSE_OBJECT *Current = Start;
    902     ACPI_PARSE_OBJECT *Next;
    903     ACPI_PARSE_OBJECT *Arg;
    904 
    905     while (Current)
    906     {
    907         Next = Current->Common.Next;
    908 
    909         /* AML_INT_CONNECTION_OP can have a single argument */
    910 
    911         Arg = AcpiPsGetArg (Current, 0);
    912         if (Arg)
    913         {
    914             AcpiPsFreeOp (Arg);
    915         }
    916 
    917         AcpiPsFreeOp(Current);
    918         Current = Next;
    919     }
    920 }
    921 
    922 
    923 /*******************************************************************************
    924  *
    925  * FUNCTION:    AcpiPsGetNextArg
    926  *
    927  * PARAMETERS:  WalkState           - Current state
    928  *              ParserState         - Current parser state object
    929  *              ArgType             - The argument type (AML_*_ARG)
    930  *              ReturnArg           - Where the next arg is returned
    931  *
    932  * RETURN:      Status, and an op object containing the next argument.
    933  *
    934  * DESCRIPTION: Get next argument (including complex list arguments that require
    935  *              pushing the parser stack)
    936  *
    937  ******************************************************************************/
    938 
    939 ACPI_STATUS
    940 AcpiPsGetNextArg (
    941     ACPI_WALK_STATE         *WalkState,
    942     ACPI_PARSE_STATE        *ParserState,
    943     UINT32                  ArgType,
    944     ACPI_PARSE_OBJECT       **ReturnArg)
    945 {
    946     ACPI_PARSE_OBJECT       *Arg = NULL;
    947     ACPI_PARSE_OBJECT       *Prev = NULL;
    948     ACPI_PARSE_OBJECT       *Field;
    949     UINT32                  Subop;
    950     ACPI_STATUS             Status = AE_OK;
    951 
    952 
    953     ACPI_FUNCTION_TRACE_PTR (PsGetNextArg, ParserState);
    954 
    955 
    956     ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
    957         "Expected argument type ARGP: %s (%2.2X)\n",
    958         AcpiUtGetArgumentTypeName (ArgType), ArgType));
    959 
    960     switch (ArgType)
    961     {
    962     case ARGP_BYTEDATA:
    963     case ARGP_WORDDATA:
    964     case ARGP_DWORDDATA:
    965     case ARGP_CHARLIST:
    966     case ARGP_NAME:
    967     case ARGP_NAMESTRING:
    968 
    969         /* Constants, strings, and namestrings are all the same size */
    970 
    971         Arg = AcpiPsAllocOp (AML_BYTE_OP, ParserState->Aml);
    972         if (!Arg)
    973         {
    974             return_ACPI_STATUS (AE_NO_MEMORY);
    975         }
    976 
    977         AcpiPsGetNextSimpleArg (ParserState, ArgType, Arg);
    978         break;
    979 
    980     case ARGP_PKGLENGTH:
    981 
    982         /* Package length, nothing returned */
    983 
    984         ParserState->PkgEnd = AcpiPsGetNextPackageEnd (ParserState);
    985         break;
    986 
    987     case ARGP_FIELDLIST:
    988 
    989         if (ParserState->Aml < ParserState->PkgEnd)
    990         {
    991             /* Non-empty list */
    992 
    993             while (ParserState->Aml < ParserState->PkgEnd)
    994             {
    995                 Field = AcpiPsGetNextField (ParserState);
    996                 if (!Field)
    997                 {
    998                     if (Arg)
    999                     {
   1000                         AcpiPsFreeFieldList(Arg);
   1001                     }
   1002 
   1003                     return_ACPI_STATUS (AE_NO_MEMORY);
   1004                 }
   1005 
   1006                 if (Prev)
   1007                 {
   1008                     Prev->Common.Next = Field;
   1009                 }
   1010                 else
   1011                 {
   1012                     Arg = Field;
   1013                 }
   1014                 Prev = Field;
   1015             }
   1016 
   1017             /* Skip to End of byte data */
   1018 
   1019             ParserState->Aml = ParserState->PkgEnd;
   1020         }
   1021         break;
   1022 
   1023     case ARGP_BYTELIST:
   1024 
   1025         if (ParserState->Aml < ParserState->PkgEnd)
   1026         {
   1027             /* Non-empty list */
   1028 
   1029             Arg = AcpiPsAllocOp (AML_INT_BYTELIST_OP,
   1030                 ParserState->Aml);
   1031             if (!Arg)
   1032             {
   1033                 return_ACPI_STATUS (AE_NO_MEMORY);
   1034             }
   1035 
   1036             /* Fill in bytelist data */
   1037 
   1038             Arg->Common.Value.Size = (UINT32)
   1039                 ACPI_PTR_DIFF (ParserState->PkgEnd, ParserState->Aml);
   1040             Arg->Named.Data = ParserState->Aml;
   1041 
   1042             /* Skip to End of byte data */
   1043 
   1044             ParserState->Aml = ParserState->PkgEnd;
   1045         }
   1046         break;
   1047 
   1048     case ARGP_SIMPLENAME:
   1049     case ARGP_NAME_OR_REF:
   1050 
   1051         ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
   1052             "**** SimpleName/NameOrRef: %s (%2.2X)\n",
   1053             AcpiUtGetArgumentTypeName (ArgType), ArgType));
   1054 
   1055         Subop = AcpiPsPeekOpcode (ParserState);
   1056         if (Subop == 0                  ||
   1057             AcpiPsIsLeadingChar (Subop) ||
   1058             ACPI_IS_ROOT_PREFIX (Subop) ||
   1059             ACPI_IS_PARENT_PREFIX (Subop))
   1060         {
   1061             /* NullName or NameString */
   1062 
   1063             Arg = AcpiPsAllocOp (AML_INT_NAMEPATH_OP, ParserState->Aml);
   1064             if (!Arg)
   1065             {
   1066                 return_ACPI_STATUS (AE_NO_MEMORY);
   1067             }
   1068 
   1069             Status = AcpiPsGetNextNamepath (WalkState, ParserState,
   1070                 Arg, ACPI_NOT_METHOD_CALL);
   1071             if (ACPI_FAILURE(Status))
   1072             {
   1073                 AcpiPsFreeOp (Arg);
   1074                 return_ACPI_STATUS (Status);
   1075             }
   1076         }
   1077         else
   1078         {
   1079             /* Single complex argument, nothing returned */
   1080 
   1081             WalkState->ArgCount = 1;
   1082         }
   1083         break;
   1084 
   1085     case ARGP_TARGET:
   1086     case ARGP_SUPERNAME:
   1087 
   1088         ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
   1089             "**** Target/Supername: %s (%2.2X)\n",
   1090             AcpiUtGetArgumentTypeName (ArgType), ArgType));
   1091 
   1092         Subop = AcpiPsPeekOpcode (ParserState);
   1093         if (Subop == 0                  ||
   1094             AcpiPsIsLeadingChar (Subop) ||
   1095             ACPI_IS_ROOT_PREFIX (Subop) ||
   1096             ACPI_IS_PARENT_PREFIX (Subop))
   1097         {
   1098             /* NULL target (zero). Convert to a NULL namepath */
   1099 
   1100             Arg = AcpiPsAllocOp (AML_INT_NAMEPATH_OP, ParserState->Aml);
   1101             if (!Arg)
   1102             {
   1103                 return_ACPI_STATUS (AE_NO_MEMORY);
   1104             }
   1105 
   1106             Status = AcpiPsGetNextNamepath (WalkState, ParserState,
   1107                 Arg, ACPI_POSSIBLE_METHOD_CALL);
   1108             if (ACPI_FAILURE(Status))
   1109             {
   1110                 AcpiPsFreeOp (Arg);
   1111                 return_ACPI_STATUS (Status);
   1112             }
   1113 
   1114             if (Arg->Common.AmlOpcode == AML_INT_METHODCALL_OP)
   1115             {
   1116                 /* Free method call op and corresponding namestring sub-ob */
   1117 
   1118                 AcpiPsFreeOp (Arg->Common.Value.Arg);
   1119                 AcpiPsFreeOp (Arg);
   1120                 Arg = NULL;
   1121                 WalkState->ArgCount = 1;
   1122             }
   1123         }
   1124         else
   1125         {
   1126             /* Single complex argument, nothing returned */
   1127 
   1128             WalkState->ArgCount = 1;
   1129         }
   1130         break;
   1131 
   1132     case ARGP_DATAOBJ:
   1133     case ARGP_TERMARG:
   1134 
   1135         ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
   1136             "**** TermArg/DataObj: %s (%2.2X)\n",
   1137             AcpiUtGetArgumentTypeName (ArgType), ArgType));
   1138 
   1139         /* Single complex argument, nothing returned */
   1140 
   1141         WalkState->ArgCount = 1;
   1142         break;
   1143 
   1144     case ARGP_DATAOBJLIST:
   1145     case ARGP_TERMLIST:
   1146     case ARGP_OBJLIST:
   1147 
   1148         if (ParserState->Aml < ParserState->PkgEnd)
   1149         {
   1150             /* Non-empty list of variable arguments, nothing returned */
   1151 
   1152             WalkState->ArgCount = ACPI_VAR_ARGS;
   1153         }
   1154         break;
   1155 
   1156     default:
   1157 
   1158         ACPI_ERROR ((AE_INFO, "Invalid ArgType: 0x%X", ArgType));
   1159         Status = AE_AML_OPERAND_TYPE;
   1160         break;
   1161     }
   1162 
   1163     *ReturnArg = Arg;
   1164     return_ACPI_STATUS (Status);
   1165 }
   1166