psargs.c revision 204773
167754Smsmith/******************************************************************************
267754Smsmith *
367754Smsmith * Module Name: psargs - Parse AML opcode arguments
467754Smsmith *
567754Smsmith *****************************************************************************/
667754Smsmith
767754Smsmith/******************************************************************************
867754Smsmith *
967754Smsmith * 1. Copyright Notice
1067754Smsmith *
11202771Sjkim * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
1270243Smsmith * All rights reserved.
1367754Smsmith *
1467754Smsmith * 2. License
1567754Smsmith *
1667754Smsmith * 2.1. This is your license from Intel Corp. under its intellectual property
1767754Smsmith * rights.  You may have additional license terms from the party that provided
1867754Smsmith * you this software, covering your right to use that party's intellectual
1967754Smsmith * property rights.
2067754Smsmith *
2167754Smsmith * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
2267754Smsmith * copy of the source code appearing in this file ("Covered Code") an
2367754Smsmith * irrevocable, perpetual, worldwide license under Intel's copyrights in the
2467754Smsmith * base code distributed originally by Intel ("Original Intel Code") to copy,
2567754Smsmith * make derivatives, distribute, use and display any portion of the Covered
2667754Smsmith * Code in any form, with the right to sublicense such rights; and
2767754Smsmith *
2867754Smsmith * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
2967754Smsmith * license (with the right to sublicense), under only those claims of Intel
3067754Smsmith * patents that are infringed by the Original Intel Code, to make, use, sell,
3167754Smsmith * offer to sell, and import the Covered Code and derivative works thereof
3267754Smsmith * solely to the minimum extent necessary to exercise the above copyright
3367754Smsmith * license, and in no event shall the patent license extend to any additions
3467754Smsmith * to or modifications of the Original Intel Code.  No other license or right
3567754Smsmith * is granted directly or by implication, estoppel or otherwise;
3667754Smsmith *
3767754Smsmith * The above copyright and patent license is granted only if the following
3867754Smsmith * conditions are met:
3967754Smsmith *
4067754Smsmith * 3. Conditions
4167754Smsmith *
4267754Smsmith * 3.1. Redistribution of Source with Rights to Further Distribute Source.
4367754Smsmith * Redistribution of source code of any substantial portion of the Covered
4467754Smsmith * Code or modification with rights to further distribute source must include
4567754Smsmith * the above Copyright Notice, the above License, this list of Conditions,
4667754Smsmith * and the following Disclaimer and Export Compliance provision.  In addition,
4767754Smsmith * Licensee must cause all Covered Code to which Licensee contributes to
4867754Smsmith * contain a file documenting the changes Licensee made to create that Covered
4967754Smsmith * Code and the date of any change.  Licensee must include in that file the
5067754Smsmith * documentation of any changes made by any predecessor Licensee.  Licensee
5167754Smsmith * must include a prominent statement that the modification is derived,
5267754Smsmith * directly or indirectly, from Original Intel Code.
5367754Smsmith *
5467754Smsmith * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
5567754Smsmith * Redistribution of source code of any substantial portion of the Covered
5667754Smsmith * Code or modification without rights to further distribute source must
5767754Smsmith * include the following Disclaimer and Export Compliance provision in the
5867754Smsmith * documentation and/or other materials provided with distribution.  In
5967754Smsmith * addition, Licensee may not authorize further sublicense of source of any
6067754Smsmith * portion of the Covered Code, and must include terms to the effect that the
6167754Smsmith * license from Licensee to its licensee is limited to the intellectual
6267754Smsmith * property embodied in the software Licensee provides to its licensee, and
6367754Smsmith * not to intellectual property embodied in modifications its licensee may
6467754Smsmith * make.
6567754Smsmith *
6667754Smsmith * 3.3. Redistribution of Executable. Redistribution in executable form of any
6767754Smsmith * substantial portion of the Covered Code or modification must reproduce the
6867754Smsmith * above Copyright Notice, and the following Disclaimer and Export Compliance
6967754Smsmith * provision in the documentation and/or other materials provided with the
7067754Smsmith * distribution.
7167754Smsmith *
7267754Smsmith * 3.4. Intel retains all right, title, and interest in and to the Original
7367754Smsmith * Intel Code.
7467754Smsmith *
7567754Smsmith * 3.5. Neither the name Intel nor any other trademark owned or controlled by
7667754Smsmith * Intel shall be used in advertising or otherwise to promote the sale, use or
7767754Smsmith * other dealings in products derived from or relating to the Covered Code
7867754Smsmith * without prior written authorization from Intel.
7967754Smsmith *
8067754Smsmith * 4. Disclaimer and Export Compliance
8167754Smsmith *
8267754Smsmith * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
8367754Smsmith * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
8467754Smsmith * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
8567754Smsmith * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
8667754Smsmith * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
8767754Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
8867754Smsmith * PARTICULAR PURPOSE.
8967754Smsmith *
9067754Smsmith * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
9167754Smsmith * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
9267754Smsmith * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
9367754Smsmith * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
9467754Smsmith * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
9567754Smsmith * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
9667754Smsmith * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
9767754Smsmith * LIMITED REMEDY.
9867754Smsmith *
9967754Smsmith * 4.3. Licensee shall not export, either directly or indirectly, any of this
10067754Smsmith * software or system incorporating such software without first obtaining any
10167754Smsmith * required license or other approval from the U. S. Department of Commerce or
10267754Smsmith * any other agency or department of the United States Government.  In the
10367754Smsmith * event Licensee exports any such software from the United States or
10467754Smsmith * re-exports any such software from a foreign destination, Licensee shall
10567754Smsmith * ensure that the distribution and export/re-export of the software is in
10667754Smsmith * compliance with all laws, regulations, orders, or other restrictions of the
10767754Smsmith * U.S. Export Administration Regulations. Licensee agrees that neither it nor
10867754Smsmith * any of its subsidiaries will export/re-export any technical data, process,
10967754Smsmith * software, or service, directly or indirectly, to any country for which the
11067754Smsmith * United States government or any agency thereof requires an export license,
11167754Smsmith * other governmental approval, or letter of assurance, without first obtaining
11267754Smsmith * such license, approval or letter.
11367754Smsmith *
11467754Smsmith *****************************************************************************/
11567754Smsmith
11667754Smsmith#define __PSARGS_C__
11767754Smsmith
118193341Sjkim#include <contrib/dev/acpica/include/acpi.h>
119193341Sjkim#include <contrib/dev/acpica/include/accommon.h>
120193341Sjkim#include <contrib/dev/acpica/include/acparser.h>
121193341Sjkim#include <contrib/dev/acpica/include/amlcode.h>
122193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h>
123193341Sjkim#include <contrib/dev/acpica/include/acdispat.h>
12467754Smsmith
12577424Smsmith#define _COMPONENT          ACPI_PARSER
12691116Smsmith        ACPI_MODULE_NAME    ("psargs")
12767754Smsmith
128151937Sjkim/* Local prototypes */
12967754Smsmith
130151937Sjkimstatic UINT32
131151937SjkimAcpiPsGetNextPackageLength (
132151937Sjkim    ACPI_PARSE_STATE        *ParserState);
133151937Sjkim
134151937Sjkimstatic ACPI_PARSE_OBJECT *
135151937SjkimAcpiPsGetNextField (
136151937Sjkim    ACPI_PARSE_STATE        *ParserState);
137151937Sjkim
138151937Sjkim
13967754Smsmith/*******************************************************************************
14067754Smsmith *
14167754Smsmith * FUNCTION:    AcpiPsGetNextPackageLength
14267754Smsmith *
14367754Smsmith * PARAMETERS:  ParserState         - Current parser state object
14467754Smsmith *
145167802Sjkim * RETURN:      Decoded package length. On completion, the AML pointer points
14667754Smsmith *              past the length byte or bytes.
14767754Smsmith *
148167802Sjkim * DESCRIPTION: Decode and return a package length field.
149167802Sjkim *              Note: Largest package length is 28 bits, from ACPI specification
15067754Smsmith *
15167754Smsmith ******************************************************************************/
15267754Smsmith
153151937Sjkimstatic UINT32
15467754SmsmithAcpiPsGetNextPackageLength (
15567754Smsmith    ACPI_PARSE_STATE        *ParserState)
15667754Smsmith{
157167802Sjkim    UINT8                   *Aml = ParserState->Aml;
158167802Sjkim    UINT32                  PackageLength = 0;
159193267Sjkim    UINT32                  ByteCount;
160167802Sjkim    UINT8                   ByteZeroMask = 0x3F; /* Default [0:5] */
16167754Smsmith
16267754Smsmith
163167802Sjkim    ACPI_FUNCTION_TRACE (PsGetNextPackageLength);
16467754Smsmith
16567754Smsmith
166167802Sjkim    /*
167167802Sjkim     * Byte 0 bits [6:7] contain the number of additional bytes
168167802Sjkim     * used to encode the package length, either 0,1,2, or 3
169167802Sjkim     */
170167802Sjkim    ByteCount = (Aml[0] >> 6);
171193267Sjkim    ParserState->Aml += ((ACPI_SIZE) ByteCount + 1);
17267754Smsmith
173167802Sjkim    /* Get bytes 3, 2, 1 as needed */
174167802Sjkim
175167802Sjkim    while (ByteCount)
17667754Smsmith    {
177167802Sjkim        /*
178167802Sjkim         * Final bit positions for the package length bytes:
179167802Sjkim         *      Byte3->[20:27]
180167802Sjkim         *      Byte2->[12:19]
181167802Sjkim         *      Byte1->[04:11]
182167802Sjkim         *      Byte0->[00:03]
183167802Sjkim         */
184167802Sjkim        PackageLength |= (Aml[ByteCount] << ((ByteCount << 3) - 4));
18567754Smsmith
186167802Sjkim        ByteZeroMask = 0x0F; /* Use bits [0:3] of byte 0 */
187167802Sjkim        ByteCount--;
188167802Sjkim    }
18967754Smsmith
190167802Sjkim    /* Byte 0 is a special case, either bits [0:3] or [0:5] are used */
19167754Smsmith
192167802Sjkim    PackageLength |= (Aml[0] & ByteZeroMask);
193167802Sjkim    return_UINT32 (PackageLength);
19467754Smsmith}
19567754Smsmith
19667754Smsmith
19767754Smsmith/*******************************************************************************
19867754Smsmith *
19967754Smsmith * FUNCTION:    AcpiPsGetNextPackageEnd
20067754Smsmith *
20167754Smsmith * PARAMETERS:  ParserState         - Current parser state object
20267754Smsmith *
20367754Smsmith * RETURN:      Pointer to end-of-package +1
20467754Smsmith *
20567754Smsmith * DESCRIPTION: Get next package length and return a pointer past the end of
20667754Smsmith *              the package.  Consumes the package length field
20767754Smsmith *
20867754Smsmith ******************************************************************************/
20967754Smsmith
21067754SmsmithUINT8 *
21167754SmsmithAcpiPsGetNextPackageEnd (
21267754Smsmith    ACPI_PARSE_STATE        *ParserState)
21367754Smsmith{
21467754Smsmith    UINT8                   *Start = ParserState->Aml;
215167802Sjkim    UINT32                  PackageLength;
21667754Smsmith
21767754Smsmith
218167802Sjkim    ACPI_FUNCTION_TRACE (PsGetNextPackageEnd);
21967754Smsmith
22067754Smsmith
221167802Sjkim    /* Function below updates ParserState->Aml */
222107325Siwasaki
223167802Sjkim    PackageLength = AcpiPsGetNextPackageLength (ParserState);
22467754Smsmith
225167802Sjkim    return_PTR (Start + PackageLength); /* end of package */
22667754Smsmith}
22767754Smsmith
22867754Smsmith
22967754Smsmith/*******************************************************************************
23067754Smsmith *
23167754Smsmith * FUNCTION:    AcpiPsGetNextNamestring
23267754Smsmith *
23367754Smsmith * PARAMETERS:  ParserState         - Current parser state object
23467754Smsmith *
23567754Smsmith * RETURN:      Pointer to the start of the name string (pointer points into
23667754Smsmith *              the AML.
23767754Smsmith *
23867754Smsmith * DESCRIPTION: Get next raw namestring within the AML stream.  Handles all name
23967754Smsmith *              prefix characters.  Set parser state to point past the string.
24067754Smsmith *              (Name is consumed from the AML.)
24167754Smsmith *
24267754Smsmith ******************************************************************************/
24367754Smsmith
244114237Snjlchar *
24567754SmsmithAcpiPsGetNextNamestring (
24667754Smsmith    ACPI_PARSE_STATE        *ParserState)
24767754Smsmith{
24899679Siwasaki    UINT8                   *Start = ParserState->Aml;
24999679Siwasaki    UINT8                   *End = ParserState->Aml;
25067754Smsmith
25167754Smsmith
252167802Sjkim    ACPI_FUNCTION_TRACE (PsGetNextNamestring);
25367754Smsmith
25467754Smsmith
255167802Sjkim    /* Point past any namestring prefix characters (backslash or carat) */
25667754Smsmith
257167802Sjkim    while (AcpiPsIsPrefixChar (*End))
25867754Smsmith    {
25967754Smsmith        End++;
26067754Smsmith    }
26167754Smsmith
262167802Sjkim    /* Decode the path prefix character */
26367754Smsmith
264167802Sjkim    switch (*End)
26567754Smsmith    {
26667754Smsmith    case 0:
26767754Smsmith
26867754Smsmith        /* NullName */
26967754Smsmith
27067754Smsmith        if (End == Start)
27167754Smsmith        {
27267754Smsmith            Start = NULL;
27367754Smsmith        }
27467754Smsmith        End++;
27567754Smsmith        break;
27667754Smsmith
27767754Smsmith    case AML_DUAL_NAME_PREFIX:
27867754Smsmith
27999679Siwasaki        /* Two name segments */
28067754Smsmith
281107325Siwasaki        End += 1 + (2 * ACPI_NAME_SIZE);
28267754Smsmith        break;
28367754Smsmith
28467754Smsmith    case AML_MULTI_NAME_PREFIX_OP:
28567754Smsmith
286167802Sjkim        /* Multiple name segments, 4 chars each, count in next byte */
28767754Smsmith
288167802Sjkim        End += 2 + (*(End + 1) * ACPI_NAME_SIZE);
28967754Smsmith        break;
29067754Smsmith
29167754Smsmith    default:
29267754Smsmith
29399679Siwasaki        /* Single name segment */
29467754Smsmith
295107325Siwasaki        End += ACPI_NAME_SIZE;
29667754Smsmith        break;
29767754Smsmith    }
29867754Smsmith
299167802Sjkim    ParserState->Aml = End;
300114237Snjl    return_PTR ((char *) Start);
30167754Smsmith}
30267754Smsmith
30367754Smsmith
30467754Smsmith/*******************************************************************************
30567754Smsmith *
30667754Smsmith * FUNCTION:    AcpiPsGetNextNamepath
30767754Smsmith *
30867754Smsmith * PARAMETERS:  ParserState         - Current parser state object
30967754Smsmith *              Arg                 - Where the namepath will be stored
31067754Smsmith *              ArgCount            - If the namepath points to a control method
31167754Smsmith *                                    the method's argument is returned here.
312167802Sjkim *              PossibleMethodCall  - Whether the namepath can possibly be the
313107325Siwasaki *                                    start of a method call
31467754Smsmith *
315102550Siwasaki * RETURN:      Status
31667754Smsmith *
317102550Siwasaki * DESCRIPTION: Get next name (if method call, return # of required args).
318102550Siwasaki *              Names are looked up in the internal namespace to determine
319102550Siwasaki *              if the name represents a control method.  If a method
32067754Smsmith *              is found, the number of arguments to the method is returned.
32167754Smsmith *              This information is critical for parsing to continue correctly.
32267754Smsmith *
32367754Smsmith ******************************************************************************/
32467754Smsmith
325102550SiwasakiACPI_STATUS
32667754SmsmithAcpiPsGetNextNamepath (
327107325Siwasaki    ACPI_WALK_STATE         *WalkState,
32867754Smsmith    ACPI_PARSE_STATE        *ParserState,
32967754Smsmith    ACPI_PARSE_OBJECT       *Arg,
330167802Sjkim    BOOLEAN                 PossibleMethodCall)
33167754Smsmith{
332193267Sjkim    ACPI_STATUS             Status;
333114237Snjl    char                    *Path;
33467754Smsmith    ACPI_PARSE_OBJECT       *NameOp;
335102550Siwasaki    ACPI_OPERAND_OBJECT     *MethodDesc;
336102550Siwasaki    ACPI_NAMESPACE_NODE     *Node;
337193267Sjkim    UINT8                   *Start = ParserState->Aml;
33867754Smsmith
33967754Smsmith
340167802Sjkim    ACPI_FUNCTION_TRACE (PsGetNextNamepath);
34167754Smsmith
34267754Smsmith
34367754Smsmith    Path = AcpiPsGetNextNamestring (ParserState);
344167802Sjkim    AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP);
34567754Smsmith
346167802Sjkim    /* Null path case is allowed, just exit */
34767754Smsmith
348167802Sjkim    if (!Path)
34967754Smsmith    {
350167802Sjkim        Arg->Common.Value.Name = Path;
351167802Sjkim        return_ACPI_STATUS (AE_OK);
352167802Sjkim    }
353167802Sjkim
354167802Sjkim    /*
355193267Sjkim     * Lookup the name in the internal namespace, starting with the current
356193267Sjkim     * scope. We don't want to add anything new to the namespace here,
357193267Sjkim     * however, so we use MODE_EXECUTE.
358167802Sjkim     * Allow searching of the parent tree, but don't open a new scope -
359167802Sjkim     * we just want to lookup the object (must be mode EXECUTE to perform
360167802Sjkim     * the upsearch)
361167802Sjkim     */
362193267Sjkim    Status = AcpiNsLookup (WalkState->ScopeInfo, Path,
363193267Sjkim                ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
364167802Sjkim                ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL, &Node);
365167802Sjkim
366167802Sjkim    /*
367167802Sjkim     * If this name is a control method invocation, we must
368167802Sjkim     * setup the method call
369167802Sjkim     */
370167802Sjkim    if (ACPI_SUCCESS (Status) &&
371167802Sjkim        PossibleMethodCall &&
372167802Sjkim        (Node->Type == ACPI_TYPE_METHOD))
373167802Sjkim    {
374193267Sjkim        if (WalkState->Opcode == AML_UNLOAD_OP)
375193267Sjkim        {
376193267Sjkim            /*
377193267Sjkim             * AcpiPsGetNextNamestring has increased the AML pointer,
378193267Sjkim             * so we need to restore the saved AML pointer for method call.
379193267Sjkim             */
380193267Sjkim            WalkState->ParserState.Aml = Start;
381193267Sjkim            WalkState->ArgCount = 1;
382193267Sjkim            AcpiPsInitOp (Arg, AML_INT_METHODCALL_OP);
383193267Sjkim            return_ACPI_STATUS (AE_OK);
384193267Sjkim        }
385193267Sjkim
386167802Sjkim        /* This name is actually a control method invocation */
387167802Sjkim
388167802Sjkim        MethodDesc = AcpiNsGetAttachedObject (Node);
389167802Sjkim        ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
390167802Sjkim            "Control Method - %p Desc %p Path=%p\n", Node, MethodDesc, Path));
391167802Sjkim
392167802Sjkim        NameOp = AcpiPsAllocOp (AML_INT_NAMEPATH_OP);
393167802Sjkim        if (!NameOp)
39467754Smsmith        {
395167802Sjkim            return_ACPI_STATUS (AE_NO_MEMORY);
39667754Smsmith        }
39767754Smsmith
398167802Sjkim        /* Change Arg into a METHOD CALL and attach name to it */
399151937Sjkim
400167802Sjkim        AcpiPsInitOp (Arg, AML_INT_METHODCALL_OP);
401167802Sjkim        NameOp->Common.Value.Name = Path;
402102550Siwasaki
403167802Sjkim        /* Point METHODCALL/NAME to the METHOD Node */
40467754Smsmith
405167802Sjkim        NameOp->Common.Node = Node;
406167802Sjkim        AcpiPsAppendArg (Arg, NameOp);
40767754Smsmith
408167802Sjkim        if (!MethodDesc)
409167802Sjkim        {
410167802Sjkim            ACPI_ERROR ((AE_INFO,
411167802Sjkim                "Control Method %p has no attached object",
412167802Sjkim                Node));
413167802Sjkim            return_ACPI_STATUS (AE_AML_INTERNAL);
414167802Sjkim        }
41567754Smsmith
416167802Sjkim        ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
417167802Sjkim            "Control Method - %p Args %X\n",
418167802Sjkim            Node, MethodDesc->Method.ParamCount));
41967754Smsmith
420167802Sjkim        /* Get the number of arguments to expect */
421102550Siwasaki
422167802Sjkim        WalkState->ArgCount = MethodDesc->Method.ParamCount;
423167802Sjkim        return_ACPI_STATUS (AE_OK);
424167802Sjkim    }
42567754Smsmith
426167802Sjkim    /*
427167802Sjkim     * Special handling if the name was not found during the lookup -
428167802Sjkim     * some NotFound cases are allowed
429167802Sjkim     */
430167802Sjkim    if (Status == AE_NOT_FOUND)
431167802Sjkim    {
432167802Sjkim        /* 1) NotFound is ok during load pass 1/2 (allow forward references) */
433102550Siwasaki
434167802Sjkim        if ((WalkState->ParseFlags & ACPI_PARSE_MODE_MASK) !=
435167802Sjkim                ACPI_PARSE_EXECUTE)
436167802Sjkim        {
437167802Sjkim            Status = AE_OK;
438167802Sjkim        }
439107325Siwasaki
440167802Sjkim        /* 2) NotFound during a CondRefOf(x) is ok by definition */
44167754Smsmith
442167802Sjkim        else if (WalkState->Op->Common.AmlOpcode == AML_COND_REF_OF_OP)
443167802Sjkim        {
444167802Sjkim            Status = AE_OK;
44567754Smsmith        }
446107325Siwasaki
447167802Sjkim        /*
448167802Sjkim         * 3) NotFound while building a Package is ok at this point, we
449167802Sjkim         * may flag as an error later if slack mode is not enabled.
450167802Sjkim         * (Some ASL code depends on allowing this behavior)
451167802Sjkim         */
452167802Sjkim        else if ((Arg->Common.Parent) &&
453167802Sjkim            ((Arg->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||
454167802Sjkim             (Arg->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP)))
455107325Siwasaki        {
456167802Sjkim            Status = AE_OK;
457167802Sjkim        }
458167802Sjkim    }
459107325Siwasaki
460167802Sjkim    /* Final exception check (may have been changed from code above) */
461117521Snjl
462167802Sjkim    if (ACPI_FAILURE (Status))
463167802Sjkim    {
464167802Sjkim        ACPI_ERROR_NAMESPACE (Path, Status);
465117521Snjl
466167802Sjkim        if ((WalkState->ParseFlags & ACPI_PARSE_MODE_MASK) ==
467167802Sjkim                ACPI_PARSE_EXECUTE)
468167802Sjkim        {
469167802Sjkim            /* Report a control method execution error */
470117521Snjl
471167802Sjkim            Status = AcpiDsMethodError (Status, WalkState);
472107325Siwasaki        }
47367754Smsmith    }
47467754Smsmith
475167802Sjkim    /* Save the namepath */
476167802Sjkim
47799679Siwasaki    Arg->Common.Value.Name = Path;
478102550Siwasaki    return_ACPI_STATUS (Status);
47967754Smsmith}
48067754Smsmith
48167754Smsmith
48267754Smsmith/*******************************************************************************
48367754Smsmith *
48467754Smsmith * FUNCTION:    AcpiPsGetNextSimpleArg
48567754Smsmith *
48667754Smsmith * PARAMETERS:  ParserState         - Current parser state object
48767754Smsmith *              ArgType             - The argument type (AML_*_ARG)
48867754Smsmith *              Arg                 - Where the argument is returned
48967754Smsmith *
49067754Smsmith * RETURN:      None
49167754Smsmith *
49267754Smsmith * DESCRIPTION: Get the next simple argument (constant, string, or namestring)
49367754Smsmith *
49467754Smsmith ******************************************************************************/
49567754Smsmith
49667754Smsmithvoid
49767754SmsmithAcpiPsGetNextSimpleArg (
49867754Smsmith    ACPI_PARSE_STATE        *ParserState,
49967754Smsmith    UINT32                  ArgType,
50067754Smsmith    ACPI_PARSE_OBJECT       *Arg)
50167754Smsmith{
502167802Sjkim    UINT32                  Length;
503167802Sjkim    UINT16                  Opcode;
504167802Sjkim    UINT8                   *Aml = ParserState->Aml;
50567754Smsmith
50667754Smsmith
507167802Sjkim    ACPI_FUNCTION_TRACE_U32 (PsGetNextSimpleArg, ArgType);
50867754Smsmith
509167802Sjkim
51067754Smsmith    switch (ArgType)
51167754Smsmith    {
51267754Smsmith    case ARGP_BYTEDATA:
51367754Smsmith
514167802Sjkim        /* Get 1 byte from the AML stream */
515167802Sjkim
516167802Sjkim        Opcode = AML_BYTE_OP;
517202771Sjkim        Arg->Common.Value.Integer = (UINT64) *Aml;
518167802Sjkim        Length = 1;
51967754Smsmith        break;
52067754Smsmith
52167754Smsmith
52267754Smsmith    case ARGP_WORDDATA:
52367754Smsmith
52467754Smsmith        /* Get 2 bytes from the AML stream */
52567754Smsmith
526167802Sjkim        Opcode = AML_WORD_OP;
527167802Sjkim        ACPI_MOVE_16_TO_64 (&Arg->Common.Value.Integer, Aml);
528167802Sjkim        Length = 2;
52967754Smsmith        break;
53067754Smsmith
53167754Smsmith
53267754Smsmith    case ARGP_DWORDDATA:
53367754Smsmith
53467754Smsmith        /* Get 4 bytes from the AML stream */
53567754Smsmith
536167802Sjkim        Opcode = AML_DWORD_OP;
537167802Sjkim        ACPI_MOVE_32_TO_64 (&Arg->Common.Value.Integer, Aml);
538167802Sjkim        Length = 4;
53967754Smsmith        break;
54067754Smsmith
54167754Smsmith
54282367Smsmith    case ARGP_QWORDDATA:
54382367Smsmith
54482367Smsmith        /* Get 8 bytes from the AML stream */
54582367Smsmith
546167802Sjkim        Opcode = AML_QWORD_OP;
547167802Sjkim        ACPI_MOVE_64_TO_64 (&Arg->Common.Value.Integer, Aml);
548167802Sjkim        Length = 8;
54982367Smsmith        break;
55082367Smsmith
55182367Smsmith
55267754Smsmith    case ARGP_CHARLIST:
55367754Smsmith
554167802Sjkim        /* Get a pointer to the string, point past the string */
55567754Smsmith
556167802Sjkim        Opcode = AML_STRING_OP;
557167802Sjkim        Arg->Common.Value.String = ACPI_CAST_PTR (char, Aml);
558167802Sjkim
559167802Sjkim        /* Find the null terminator */
560167802Sjkim
561167802Sjkim        Length = 0;
562167802Sjkim        while (Aml[Length])
56367754Smsmith        {
564167802Sjkim            Length++;
56567754Smsmith        }
566167802Sjkim        Length++;
56767754Smsmith        break;
56867754Smsmith
56967754Smsmith
57067754Smsmith    case ARGP_NAME:
57167754Smsmith    case ARGP_NAMESTRING:
57267754Smsmith
57377424Smsmith        AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP);
57499679Siwasaki        Arg->Common.Value.Name = AcpiPsGetNextNamestring (ParserState);
575167802Sjkim        return_VOID;
57699679Siwasaki
57799679Siwasaki
57899679Siwasaki    default:
579107325Siwasaki
580204773Sjkim        ACPI_ERROR ((AE_INFO, "Invalid ArgType 0x%X", ArgType));
581167802Sjkim        return_VOID;
58267754Smsmith    }
58367754Smsmith
584167802Sjkim    AcpiPsInitOp (Arg, Opcode);
585167802Sjkim    ParserState->Aml += Length;
58667754Smsmith    return_VOID;
58767754Smsmith}
58867754Smsmith
58967754Smsmith
59067754Smsmith/*******************************************************************************
59167754Smsmith *
59267754Smsmith * FUNCTION:    AcpiPsGetNextField
59367754Smsmith *
59467754Smsmith * PARAMETERS:  ParserState         - Current parser state object
59567754Smsmith *
59667754Smsmith * RETURN:      A newly allocated FIELD op
59767754Smsmith *
59867754Smsmith * DESCRIPTION: Get next field (NamedField, ReservedField, or AccessField)
59967754Smsmith *
60067754Smsmith ******************************************************************************/
60167754Smsmith
602151937Sjkimstatic ACPI_PARSE_OBJECT *
60367754SmsmithAcpiPsGetNextField (
60467754Smsmith    ACPI_PARSE_STATE        *ParserState)
60567754Smsmith{
606151937Sjkim    UINT32                  AmlOffset = (UINT32)
607151937Sjkim                                ACPI_PTR_DIFF (ParserState->Aml,
608151937Sjkim                                               ParserState->AmlStart);
60967754Smsmith    ACPI_PARSE_OBJECT       *Field;
61067754Smsmith    UINT16                  Opcode;
61167754Smsmith    UINT32                  Name;
61267754Smsmith
61367754Smsmith
614167802Sjkim    ACPI_FUNCTION_TRACE (PsGetNextField);
61567754Smsmith
61667754Smsmith
617151937Sjkim    /* Determine field type */
61867754Smsmith
61991116Smsmith    switch (ACPI_GET8 (ParserState->Aml))
62067754Smsmith    {
62167754Smsmith    default:
62267754Smsmith
62377424Smsmith        Opcode = AML_INT_NAMEDFIELD_OP;
62467754Smsmith        break;
62567754Smsmith
62667754Smsmith    case 0x00:
62767754Smsmith
62877424Smsmith        Opcode = AML_INT_RESERVEDFIELD_OP;
62967754Smsmith        ParserState->Aml++;
63067754Smsmith        break;
63167754Smsmith
63267754Smsmith    case 0x01:
63367754Smsmith
63477424Smsmith        Opcode = AML_INT_ACCESSFIELD_OP;
63567754Smsmith        ParserState->Aml++;
63667754Smsmith        break;
63767754Smsmith    }
63867754Smsmith
63967754Smsmith    /* Allocate a new field op */
64067754Smsmith
64167754Smsmith    Field = AcpiPsAllocOp (Opcode);
64299679Siwasaki    if (!Field)
64367754Smsmith    {
64499679Siwasaki        return_PTR (NULL);
64599679Siwasaki    }
64667754Smsmith
64799679Siwasaki    Field->Common.AmlOffset = AmlOffset;
64867754Smsmith
64999679Siwasaki    /* Decode the field type */
65067754Smsmith
65199679Siwasaki    switch (Opcode)
65299679Siwasaki    {
65399679Siwasaki    case AML_INT_NAMEDFIELD_OP:
65467754Smsmith
65599679Siwasaki        /* Get the 4-character name */
65667754Smsmith
657117521Snjl        ACPI_MOVE_32_TO_32 (&Name, ParserState->Aml);
65899679Siwasaki        AcpiPsSetName (Field, Name);
659107325Siwasaki        ParserState->Aml += ACPI_NAME_SIZE;
66067754Smsmith
66199679Siwasaki        /* Get the length which is encoded as a package length */
66267754Smsmith
66399679Siwasaki        Field->Common.Value.Size = AcpiPsGetNextPackageLength (ParserState);
66499679Siwasaki        break;
66567754Smsmith
66667754Smsmith
66799679Siwasaki    case AML_INT_RESERVEDFIELD_OP:
66867754Smsmith
66999679Siwasaki        /* Get the length which is encoded as a package length */
67067754Smsmith
67199679Siwasaki        Field->Common.Value.Size = AcpiPsGetNextPackageLength (ParserState);
67299679Siwasaki        break;
67367754Smsmith
67467754Smsmith
67599679Siwasaki    case AML_INT_ACCESSFIELD_OP:
67699679Siwasaki
67799679Siwasaki        /*
67899679Siwasaki         * Get AccessType and AccessAttrib and merge into the field Op
67999679Siwasaki         * AccessType is first operand, AccessAttribute is second
68099679Siwasaki         */
681167802Sjkim        Field->Common.Value.Integer = (((UINT32) ACPI_GET8 (ParserState->Aml) << 8));
68299679Siwasaki        ParserState->Aml++;
683117521Snjl        Field->Common.Value.Integer |= ACPI_GET8 (ParserState->Aml);
68499679Siwasaki        ParserState->Aml++;
68599679Siwasaki        break;
68699679Siwasaki
68799679Siwasaki    default:
688107325Siwasaki
68999679Siwasaki        /* Opcode was set in previous switch */
69099679Siwasaki        break;
69167754Smsmith    }
69267754Smsmith
69367754Smsmith    return_PTR (Field);
69467754Smsmith}
69567754Smsmith
69667754Smsmith
69767754Smsmith/*******************************************************************************
69867754Smsmith *
69967754Smsmith * FUNCTION:    AcpiPsGetNextArg
70067754Smsmith *
701151937Sjkim * PARAMETERS:  WalkState           - Current state
702151937Sjkim *              ParserState         - Current parser state object
70367754Smsmith *              ArgType             - The argument type (AML_*_ARG)
704151937Sjkim *              ReturnArg           - Where the next arg is returned
70567754Smsmith *
706102550Siwasaki * RETURN:      Status, and an op object containing the next argument.
70767754Smsmith *
70867754Smsmith * DESCRIPTION: Get next argument (including complex list arguments that require
70967754Smsmith *              pushing the parser stack)
71067754Smsmith *
71167754Smsmith ******************************************************************************/
71267754Smsmith
713102550SiwasakiACPI_STATUS
71467754SmsmithAcpiPsGetNextArg (
715107325Siwasaki    ACPI_WALK_STATE         *WalkState,
71667754Smsmith    ACPI_PARSE_STATE        *ParserState,
71767754Smsmith    UINT32                  ArgType,
718102550Siwasaki    ACPI_PARSE_OBJECT       **ReturnArg)
71967754Smsmith{
72067754Smsmith    ACPI_PARSE_OBJECT       *Arg = NULL;
72167754Smsmith    ACPI_PARSE_OBJECT       *Prev = NULL;
72267754Smsmith    ACPI_PARSE_OBJECT       *Field;
72367754Smsmith    UINT32                  Subop;
724102550Siwasaki    ACPI_STATUS             Status = AE_OK;
72567754Smsmith
72667754Smsmith
727167802Sjkim    ACPI_FUNCTION_TRACE_PTR (PsGetNextArg, ParserState);
72867754Smsmith
72967754Smsmith
73067754Smsmith    switch (ArgType)
73167754Smsmith    {
73267754Smsmith    case ARGP_BYTEDATA:
73367754Smsmith    case ARGP_WORDDATA:
73467754Smsmith    case ARGP_DWORDDATA:
73567754Smsmith    case ARGP_CHARLIST:
73667754Smsmith    case ARGP_NAME:
73767754Smsmith    case ARGP_NAMESTRING:
73867754Smsmith
739151937Sjkim        /* Constants, strings, and namestrings are all the same size */
74067754Smsmith
74167754Smsmith        Arg = AcpiPsAllocOp (AML_BYTE_OP);
742102550Siwasaki        if (!Arg)
74367754Smsmith        {
744102550Siwasaki            return_ACPI_STATUS (AE_NO_MEMORY);
74567754Smsmith        }
746102550Siwasaki        AcpiPsGetNextSimpleArg (ParserState, ArgType, Arg);
74767754Smsmith        break;
74867754Smsmith
74967754Smsmith
75067754Smsmith    case ARGP_PKGLENGTH:
75167754Smsmith
752102550Siwasaki        /* Package length, nothing returned */
75367754Smsmith
75467754Smsmith        ParserState->PkgEnd = AcpiPsGetNextPackageEnd (ParserState);
75567754Smsmith        break;
75667754Smsmith
75767754Smsmith
75867754Smsmith    case ARGP_FIELDLIST:
75967754Smsmith
76067754Smsmith        if (ParserState->Aml < ParserState->PkgEnd)
76167754Smsmith        {
762102550Siwasaki            /* Non-empty list */
76367754Smsmith
76467754Smsmith            while (ParserState->Aml < ParserState->PkgEnd)
76567754Smsmith            {
76667754Smsmith                Field = AcpiPsGetNextField (ParserState);
76767754Smsmith                if (!Field)
76867754Smsmith                {
769102550Siwasaki                    return_ACPI_STATUS (AE_NO_MEMORY);
77067754Smsmith                }
77167754Smsmith
77267754Smsmith                if (Prev)
77367754Smsmith                {
77499679Siwasaki                    Prev->Common.Next = Field;
77567754Smsmith                }
77667754Smsmith                else
77767754Smsmith                {
77867754Smsmith                    Arg = Field;
77967754Smsmith                }
78067754Smsmith                Prev = Field;
78167754Smsmith            }
78267754Smsmith
783102550Siwasaki            /* Skip to End of byte data */
78467754Smsmith
78567754Smsmith            ParserState->Aml = ParserState->PkgEnd;
78667754Smsmith        }
78767754Smsmith        break;
78867754Smsmith
78967754Smsmith
79067754Smsmith    case ARGP_BYTELIST:
79167754Smsmith
79267754Smsmith        if (ParserState->Aml < ParserState->PkgEnd)
79367754Smsmith        {
794102550Siwasaki            /* Non-empty list */
79567754Smsmith
79677424Smsmith            Arg = AcpiPsAllocOp (AML_INT_BYTELIST_OP);
797102550Siwasaki            if (!Arg)
79867754Smsmith            {
799102550Siwasaki                return_ACPI_STATUS (AE_NO_MEMORY);
80067754Smsmith            }
80167754Smsmith
802102550Siwasaki            /* Fill in bytelist data */
80367754Smsmith
804151937Sjkim            Arg->Common.Value.Size = (UINT32)
805151937Sjkim                ACPI_PTR_DIFF (ParserState->PkgEnd, ParserState->Aml);
806102550Siwasaki            Arg->Named.Data = ParserState->Aml;
807102550Siwasaki
808102550Siwasaki            /* Skip to End of byte data */
809102550Siwasaki
81067754Smsmith            ParserState->Aml = ParserState->PkgEnd;
81167754Smsmith        }
81267754Smsmith        break;
81367754Smsmith
81467754Smsmith
81567754Smsmith    case ARGP_TARGET:
81667754Smsmith    case ARGP_SUPERNAME:
81791116Smsmith    case ARGP_SIMPLENAME:
818102550Siwasaki
819102550Siwasaki        Subop = AcpiPsPeekOpcode (ParserState);
820102550Siwasaki        if (Subop == 0                  ||
821102550Siwasaki            AcpiPsIsLeadingChar (Subop) ||
822102550Siwasaki            AcpiPsIsPrefixChar (Subop))
82367754Smsmith        {
824102550Siwasaki            /* NullName or NameString */
825102550Siwasaki
826102550Siwasaki            Arg = AcpiPsAllocOp (AML_INT_NAMEPATH_OP);
827102550Siwasaki            if (!Arg)
82867754Smsmith            {
829102550Siwasaki                return_ACPI_STATUS (AE_NO_MEMORY);
83067754Smsmith            }
83167754Smsmith
832193267Sjkim            /* To support SuperName arg of Unload */
833193267Sjkim
834193267Sjkim            if (WalkState->Opcode == AML_UNLOAD_OP)
835193267Sjkim            {
836193267Sjkim                Status = AcpiPsGetNextNamepath (WalkState, ParserState, Arg, 1);
837193267Sjkim
838193267Sjkim                /*
839193267Sjkim                 * If the SuperName arg of Unload is a method call,
840193267Sjkim                 * we have restored the AML pointer, just free this Arg
841193267Sjkim                 */
842193267Sjkim                if (Arg->Common.AmlOpcode == AML_INT_METHODCALL_OP)
843193267Sjkim                {
844193267Sjkim                    AcpiPsFreeOp (Arg);
845193267Sjkim                    Arg = NULL;
846193267Sjkim                }
847193267Sjkim            }
848193267Sjkim            else
849193267Sjkim            {
850193267Sjkim                Status = AcpiPsGetNextNamepath (WalkState, ParserState, Arg, 0);
851193267Sjkim            }
852102550Siwasaki        }
853102550Siwasaki        else
854102550Siwasaki        {
855151937Sjkim            /* Single complex argument, nothing returned */
85667754Smsmith
857107325Siwasaki            WalkState->ArgCount = 1;
85867754Smsmith        }
85967754Smsmith        break;
86067754Smsmith
86167754Smsmith
86267754Smsmith    case ARGP_DATAOBJ:
86367754Smsmith    case ARGP_TERMARG:
86467754Smsmith
865151937Sjkim        /* Single complex argument, nothing returned */
86667754Smsmith
867107325Siwasaki        WalkState->ArgCount = 1;
86867754Smsmith        break;
86967754Smsmith
87067754Smsmith
87167754Smsmith    case ARGP_DATAOBJLIST:
87267754Smsmith    case ARGP_TERMLIST:
87367754Smsmith    case ARGP_OBJLIST:
87467754Smsmith
87567754Smsmith        if (ParserState->Aml < ParserState->PkgEnd)
87667754Smsmith        {
877151937Sjkim            /* Non-empty list of variable arguments, nothing returned */
87867754Smsmith
879107325Siwasaki            WalkState->ArgCount = ACPI_VAR_ARGS;
88067754Smsmith        }
88167754Smsmith        break;
88299679Siwasaki
883102550Siwasaki
88499679Siwasaki    default:
885102550Siwasaki
886204773Sjkim        ACPI_ERROR ((AE_INFO, "Invalid ArgType: 0x%X", ArgType));
887102550Siwasaki        Status = AE_AML_OPERAND_TYPE;
88899679Siwasaki        break;
88967754Smsmith    }
89067754Smsmith
891102550Siwasaki    *ReturnArg = Arg;
892102550Siwasaki    return_ACPI_STATUS (Status);
89367754Smsmith}
894