167754Smsmith/******************************************************************************
267754Smsmith *
367754Smsmith * Module Name: psargs - Parse AML opcode arguments
467754Smsmith *
567754Smsmith *****************************************************************************/
667754Smsmith
7217365Sjkim/*
8306536Sjkim * Copyright (C) 2000 - 2016, Intel Corp.
970243Smsmith * All rights reserved.
1067754Smsmith *
11217365Sjkim * Redistribution and use in source and binary forms, with or without
12217365Sjkim * modification, are permitted provided that the following conditions
13217365Sjkim * are met:
14217365Sjkim * 1. Redistributions of source code must retain the above copyright
15217365Sjkim *    notice, this list of conditions, and the following disclaimer,
16217365Sjkim *    without modification.
17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18217365Sjkim *    substantially similar to the "NO WARRANTY" disclaimer below
19217365Sjkim *    ("Disclaimer") and any redistribution must be conditioned upon
20217365Sjkim *    including a substantially similar Disclaimer requirement for further
21217365Sjkim *    binary redistribution.
22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names
23217365Sjkim *    of any contributors may be used to endorse or promote products derived
24217365Sjkim *    from this software without specific prior written permission.
2567754Smsmith *
26217365Sjkim * Alternatively, this software may be distributed under the terms of the
27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free
28217365Sjkim * Software Foundation.
2967754Smsmith *
30217365Sjkim * NO WARRANTY
31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41217365Sjkim * POSSIBILITY OF SUCH DAMAGES.
42217365Sjkim */
4367754Smsmith
44193341Sjkim#include <contrib/dev/acpica/include/acpi.h>
45193341Sjkim#include <contrib/dev/acpica/include/accommon.h>
46193341Sjkim#include <contrib/dev/acpica/include/acparser.h>
47193341Sjkim#include <contrib/dev/acpica/include/amlcode.h>
48193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h>
49193341Sjkim#include <contrib/dev/acpica/include/acdispat.h>
5067754Smsmith
5177424Smsmith#define _COMPONENT          ACPI_PARSER
5291116Smsmith        ACPI_MODULE_NAME    ("psargs")
5367754Smsmith
54151937Sjkim/* Local prototypes */
5567754Smsmith
56151937Sjkimstatic UINT32
57151937SjkimAcpiPsGetNextPackageLength (
58151937Sjkim    ACPI_PARSE_STATE        *ParserState);
59151937Sjkim
60151937Sjkimstatic ACPI_PARSE_OBJECT *
61151937SjkimAcpiPsGetNextField (
62151937Sjkim    ACPI_PARSE_STATE        *ParserState);
63151937Sjkim
64151937Sjkim
6567754Smsmith/*******************************************************************************
6667754Smsmith *
6767754Smsmith * FUNCTION:    AcpiPsGetNextPackageLength
6867754Smsmith *
6967754Smsmith * PARAMETERS:  ParserState         - Current parser state object
7067754Smsmith *
71167802Sjkim * RETURN:      Decoded package length. On completion, the AML pointer points
7267754Smsmith *              past the length byte or bytes.
7367754Smsmith *
74167802Sjkim * DESCRIPTION: Decode and return a package length field.
75167802Sjkim *              Note: Largest package length is 28 bits, from ACPI specification
7667754Smsmith *
7767754Smsmith ******************************************************************************/
7867754Smsmith
79151937Sjkimstatic UINT32
8067754SmsmithAcpiPsGetNextPackageLength (
8167754Smsmith    ACPI_PARSE_STATE        *ParserState)
8267754Smsmith{
83167802Sjkim    UINT8                   *Aml = ParserState->Aml;
84167802Sjkim    UINT32                  PackageLength = 0;
85193267Sjkim    UINT32                  ByteCount;
86167802Sjkim    UINT8                   ByteZeroMask = 0x3F; /* Default [0:5] */
8767754Smsmith
8867754Smsmith
89167802Sjkim    ACPI_FUNCTION_TRACE (PsGetNextPackageLength);
9067754Smsmith
9167754Smsmith
92167802Sjkim    /*
93167802Sjkim     * Byte 0 bits [6:7] contain the number of additional bytes
94167802Sjkim     * used to encode the package length, either 0,1,2, or 3
95167802Sjkim     */
96167802Sjkim    ByteCount = (Aml[0] >> 6);
97193267Sjkim    ParserState->Aml += ((ACPI_SIZE) ByteCount + 1);
9867754Smsmith
99167802Sjkim    /* Get bytes 3, 2, 1 as needed */
100167802Sjkim
101167802Sjkim    while (ByteCount)
10267754Smsmith    {
103167802Sjkim        /*
104167802Sjkim         * Final bit positions for the package length bytes:
105167802Sjkim         *      Byte3->[20:27]
106167802Sjkim         *      Byte2->[12:19]
107167802Sjkim         *      Byte1->[04:11]
108167802Sjkim         *      Byte0->[00:03]
109167802Sjkim         */
110167802Sjkim        PackageLength |= (Aml[ByteCount] << ((ByteCount << 3) - 4));
11167754Smsmith
112167802Sjkim        ByteZeroMask = 0x0F; /* Use bits [0:3] of byte 0 */
113167802Sjkim        ByteCount--;
114167802Sjkim    }
11567754Smsmith
116167802Sjkim    /* Byte 0 is a special case, either bits [0:3] or [0:5] are used */
11767754Smsmith
118167802Sjkim    PackageLength |= (Aml[0] & ByteZeroMask);
119246849Sjkim    return_UINT32 (PackageLength);
12067754Smsmith}
12167754Smsmith
12267754Smsmith
12367754Smsmith/*******************************************************************************
12467754Smsmith *
12567754Smsmith * FUNCTION:    AcpiPsGetNextPackageEnd
12667754Smsmith *
12767754Smsmith * PARAMETERS:  ParserState         - Current parser state object
12867754Smsmith *
12967754Smsmith * RETURN:      Pointer to end-of-package +1
13067754Smsmith *
13167754Smsmith * DESCRIPTION: Get next package length and return a pointer past the end of
132241973Sjkim *              the package. Consumes the package length field
13367754Smsmith *
13467754Smsmith ******************************************************************************/
13567754Smsmith
13667754SmsmithUINT8 *
13767754SmsmithAcpiPsGetNextPackageEnd (
13867754Smsmith    ACPI_PARSE_STATE        *ParserState)
13967754Smsmith{
14067754Smsmith    UINT8                   *Start = ParserState->Aml;
141167802Sjkim    UINT32                  PackageLength;
14267754Smsmith
14367754Smsmith
144167802Sjkim    ACPI_FUNCTION_TRACE (PsGetNextPackageEnd);
14567754Smsmith
14667754Smsmith
147167802Sjkim    /* Function below updates ParserState->Aml */
148107325Siwasaki
149167802Sjkim    PackageLength = AcpiPsGetNextPackageLength (ParserState);
15067754Smsmith
151167802Sjkim    return_PTR (Start + PackageLength); /* end of package */
15267754Smsmith}
15367754Smsmith
15467754Smsmith
15567754Smsmith/*******************************************************************************
15667754Smsmith *
15767754Smsmith * FUNCTION:    AcpiPsGetNextNamestring
15867754Smsmith *
15967754Smsmith * PARAMETERS:  ParserState         - Current parser state object
16067754Smsmith *
16167754Smsmith * RETURN:      Pointer to the start of the name string (pointer points into
16267754Smsmith *              the AML.
16367754Smsmith *
164241973Sjkim * DESCRIPTION: Get next raw namestring within the AML stream. Handles all name
165241973Sjkim *              prefix characters. Set parser state to point past the string.
16667754Smsmith *              (Name is consumed from the AML.)
16767754Smsmith *
16867754Smsmith ******************************************************************************/
16967754Smsmith
170114237Snjlchar *
17167754SmsmithAcpiPsGetNextNamestring (
17267754Smsmith    ACPI_PARSE_STATE        *ParserState)
17367754Smsmith{
17499679Siwasaki    UINT8                   *Start = ParserState->Aml;
17599679Siwasaki    UINT8                   *End = ParserState->Aml;
17667754Smsmith
17767754Smsmith
178167802Sjkim    ACPI_FUNCTION_TRACE (PsGetNextNamestring);
17967754Smsmith
18067754Smsmith
181167802Sjkim    /* Point past any namestring prefix characters (backslash or carat) */
18267754Smsmith
183245582Sjkim    while (ACPI_IS_ROOT_PREFIX (*End) ||
184245582Sjkim           ACPI_IS_PARENT_PREFIX (*End))
18567754Smsmith    {
18667754Smsmith        End++;
18767754Smsmith    }
18867754Smsmith
189167802Sjkim    /* Decode the path prefix character */
19067754Smsmith
191167802Sjkim    switch (*End)
19267754Smsmith    {
19367754Smsmith    case 0:
19467754Smsmith
19567754Smsmith        /* NullName */
19667754Smsmith
19767754Smsmith        if (End == Start)
19867754Smsmith        {
19967754Smsmith            Start = NULL;
20067754Smsmith        }
20167754Smsmith        End++;
20267754Smsmith        break;
20367754Smsmith
20467754Smsmith    case AML_DUAL_NAME_PREFIX:
20567754Smsmith
20699679Siwasaki        /* Two name segments */
20767754Smsmith
208107325Siwasaki        End += 1 + (2 * ACPI_NAME_SIZE);
20967754Smsmith        break;
21067754Smsmith
21167754Smsmith    case AML_MULTI_NAME_PREFIX_OP:
21267754Smsmith
213167802Sjkim        /* Multiple name segments, 4 chars each, count in next byte */
21467754Smsmith
215167802Sjkim        End += 2 + (*(End + 1) * ACPI_NAME_SIZE);
21667754Smsmith        break;
21767754Smsmith
21867754Smsmith    default:
21967754Smsmith
22099679Siwasaki        /* Single name segment */
22167754Smsmith
222107325Siwasaki        End += ACPI_NAME_SIZE;
22367754Smsmith        break;
22467754Smsmith    }
22567754Smsmith
226167802Sjkim    ParserState->Aml = End;
227114237Snjl    return_PTR ((char *) Start);
22867754Smsmith}
22967754Smsmith
23067754Smsmith
23167754Smsmith/*******************************************************************************
23267754Smsmith *
23367754Smsmith * FUNCTION:    AcpiPsGetNextNamepath
23467754Smsmith *
23567754Smsmith * PARAMETERS:  ParserState         - Current parser state object
23667754Smsmith *              Arg                 - Where the namepath will be stored
23767754Smsmith *              ArgCount            - If the namepath points to a control method
23867754Smsmith *                                    the method's argument is returned here.
239167802Sjkim *              PossibleMethodCall  - Whether the namepath can possibly be the
240107325Siwasaki *                                    start of a method call
24167754Smsmith *
242102550Siwasaki * RETURN:      Status
24367754Smsmith *
244102550Siwasaki * DESCRIPTION: Get next name (if method call, return # of required args).
245102550Siwasaki *              Names are looked up in the internal namespace to determine
246241973Sjkim *              if the name represents a control method. If a method
24767754Smsmith *              is found, the number of arguments to the method is returned.
24867754Smsmith *              This information is critical for parsing to continue correctly.
24967754Smsmith *
25067754Smsmith ******************************************************************************/
25167754Smsmith
252102550SiwasakiACPI_STATUS
25367754SmsmithAcpiPsGetNextNamepath (
254107325Siwasaki    ACPI_WALK_STATE         *WalkState,
25567754Smsmith    ACPI_PARSE_STATE        *ParserState,
25667754Smsmith    ACPI_PARSE_OBJECT       *Arg,
257167802Sjkim    BOOLEAN                 PossibleMethodCall)
25867754Smsmith{
259193267Sjkim    ACPI_STATUS             Status;
260114237Snjl    char                    *Path;
26167754Smsmith    ACPI_PARSE_OBJECT       *NameOp;
262102550Siwasaki    ACPI_OPERAND_OBJECT     *MethodDesc;
263102550Siwasaki    ACPI_NAMESPACE_NODE     *Node;
264193267Sjkim    UINT8                   *Start = ParserState->Aml;
26567754Smsmith
26667754Smsmith
267167802Sjkim    ACPI_FUNCTION_TRACE (PsGetNextNamepath);
26867754Smsmith
26967754Smsmith
27067754Smsmith    Path = AcpiPsGetNextNamestring (ParserState);
271167802Sjkim    AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP);
27267754Smsmith
273167802Sjkim    /* Null path case is allowed, just exit */
27467754Smsmith
275167802Sjkim    if (!Path)
27667754Smsmith    {
277167802Sjkim        Arg->Common.Value.Name = Path;
278167802Sjkim        return_ACPI_STATUS (AE_OK);
279167802Sjkim    }
280167802Sjkim
281167802Sjkim    /*
282193267Sjkim     * Lookup the name in the internal namespace, starting with the current
283193267Sjkim     * scope. We don't want to add anything new to the namespace here,
284193267Sjkim     * however, so we use MODE_EXECUTE.
285167802Sjkim     * Allow searching of the parent tree, but don't open a new scope -
286167802Sjkim     * we just want to lookup the object (must be mode EXECUTE to perform
287167802Sjkim     * the upsearch)
288167802Sjkim     */
289193267Sjkim    Status = AcpiNsLookup (WalkState->ScopeInfo, Path,
290306536Sjkim        ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
291306536Sjkim        ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL, &Node);
292167802Sjkim
293167802Sjkim    /*
294167802Sjkim     * If this name is a control method invocation, we must
295167802Sjkim     * setup the method call
296167802Sjkim     */
297167802Sjkim    if (ACPI_SUCCESS (Status) &&
298167802Sjkim        PossibleMethodCall &&
299167802Sjkim        (Node->Type == ACPI_TYPE_METHOD))
300167802Sjkim    {
301193267Sjkim        if (WalkState->Opcode == AML_UNLOAD_OP)
302193267Sjkim        {
303193267Sjkim            /*
304193267Sjkim             * AcpiPsGetNextNamestring has increased the AML pointer,
305193267Sjkim             * so we need to restore the saved AML pointer for method call.
306193267Sjkim             */
307193267Sjkim            WalkState->ParserState.Aml = Start;
308193267Sjkim            WalkState->ArgCount = 1;
309193267Sjkim            AcpiPsInitOp (Arg, AML_INT_METHODCALL_OP);
310193267Sjkim            return_ACPI_STATUS (AE_OK);
311193267Sjkim        }
312193267Sjkim
313167802Sjkim        /* This name is actually a control method invocation */
314167802Sjkim
315167802Sjkim        MethodDesc = AcpiNsGetAttachedObject (Node);
316167802Sjkim        ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
317167802Sjkim            "Control Method - %p Desc %p Path=%p\n", Node, MethodDesc, Path));
318167802Sjkim
319306536Sjkim        NameOp = AcpiPsAllocOp (AML_INT_NAMEPATH_OP, Start);
320167802Sjkim        if (!NameOp)
32167754Smsmith        {
322167802Sjkim            return_ACPI_STATUS (AE_NO_MEMORY);
32367754Smsmith        }
32467754Smsmith
325167802Sjkim        /* Change Arg into a METHOD CALL and attach name to it */
326151937Sjkim
327167802Sjkim        AcpiPsInitOp (Arg, AML_INT_METHODCALL_OP);
328167802Sjkim        NameOp->Common.Value.Name = Path;
329102550Siwasaki
330167802Sjkim        /* Point METHODCALL/NAME to the METHOD Node */
33167754Smsmith
332167802Sjkim        NameOp->Common.Node = Node;
333167802Sjkim        AcpiPsAppendArg (Arg, NameOp);
33467754Smsmith
335167802Sjkim        if (!MethodDesc)
336167802Sjkim        {
337167802Sjkim            ACPI_ERROR ((AE_INFO,
338167802Sjkim                "Control Method %p has no attached object",
339167802Sjkim                Node));
340167802Sjkim            return_ACPI_STATUS (AE_AML_INTERNAL);
341167802Sjkim        }
34267754Smsmith
343167802Sjkim        ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
344167802Sjkim            "Control Method - %p Args %X\n",
345167802Sjkim            Node, MethodDesc->Method.ParamCount));
34667754Smsmith
347167802Sjkim        /* Get the number of arguments to expect */
348102550Siwasaki
349167802Sjkim        WalkState->ArgCount = MethodDesc->Method.ParamCount;
350167802Sjkim        return_ACPI_STATUS (AE_OK);
351167802Sjkim    }
35267754Smsmith
353167802Sjkim    /*
354167802Sjkim     * Special handling if the name was not found during the lookup -
355167802Sjkim     * some NotFound cases are allowed
356167802Sjkim     */
357167802Sjkim    if (Status == AE_NOT_FOUND)
358167802Sjkim    {
359167802Sjkim        /* 1) NotFound is ok during load pass 1/2 (allow forward references) */
360102550Siwasaki
361167802Sjkim        if ((WalkState->ParseFlags & ACPI_PARSE_MODE_MASK) !=
362306536Sjkim            ACPI_PARSE_EXECUTE)
363167802Sjkim        {
364167802Sjkim            Status = AE_OK;
365167802Sjkim        }
366107325Siwasaki
367167802Sjkim        /* 2) NotFound during a CondRefOf(x) is ok by definition */
36867754Smsmith
369167802Sjkim        else if (WalkState->Op->Common.AmlOpcode == AML_COND_REF_OF_OP)
370167802Sjkim        {
371167802Sjkim            Status = AE_OK;
37267754Smsmith        }
373107325Siwasaki
374167802Sjkim        /*
375167802Sjkim         * 3) NotFound while building a Package is ok at this point, we
376167802Sjkim         * may flag as an error later if slack mode is not enabled.
377167802Sjkim         * (Some ASL code depends on allowing this behavior)
378167802Sjkim         */
379167802Sjkim        else if ((Arg->Common.Parent) &&
380167802Sjkim            ((Arg->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||
381167802Sjkim             (Arg->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP)))
382107325Siwasaki        {
383167802Sjkim            Status = AE_OK;
384167802Sjkim        }
385167802Sjkim    }
386107325Siwasaki
387167802Sjkim    /* Final exception check (may have been changed from code above) */
388117521Snjl
389167802Sjkim    if (ACPI_FAILURE (Status))
390167802Sjkim    {
391167802Sjkim        ACPI_ERROR_NAMESPACE (Path, Status);
392117521Snjl
393167802Sjkim        if ((WalkState->ParseFlags & ACPI_PARSE_MODE_MASK) ==
394306536Sjkim            ACPI_PARSE_EXECUTE)
395167802Sjkim        {
396167802Sjkim            /* Report a control method execution error */
397117521Snjl
398167802Sjkim            Status = AcpiDsMethodError (Status, WalkState);
399107325Siwasaki        }
40067754Smsmith    }
40167754Smsmith
402167802Sjkim    /* Save the namepath */
403167802Sjkim
40499679Siwasaki    Arg->Common.Value.Name = Path;
405102550Siwasaki    return_ACPI_STATUS (Status);
40667754Smsmith}
40767754Smsmith
40867754Smsmith
40967754Smsmith/*******************************************************************************
41067754Smsmith *
41167754Smsmith * FUNCTION:    AcpiPsGetNextSimpleArg
41267754Smsmith *
41367754Smsmith * PARAMETERS:  ParserState         - Current parser state object
41467754Smsmith *              ArgType             - The argument type (AML_*_ARG)
41567754Smsmith *              Arg                 - Where the argument is returned
41667754Smsmith *
41767754Smsmith * RETURN:      None
41867754Smsmith *
41967754Smsmith * DESCRIPTION: Get the next simple argument (constant, string, or namestring)
42067754Smsmith *
42167754Smsmith ******************************************************************************/
42267754Smsmith
42367754Smsmithvoid
42467754SmsmithAcpiPsGetNextSimpleArg (
42567754Smsmith    ACPI_PARSE_STATE        *ParserState,
42667754Smsmith    UINT32                  ArgType,
42767754Smsmith    ACPI_PARSE_OBJECT       *Arg)
42867754Smsmith{
429167802Sjkim    UINT32                  Length;
430167802Sjkim    UINT16                  Opcode;
431167802Sjkim    UINT8                   *Aml = ParserState->Aml;
43267754Smsmith
43367754Smsmith
434167802Sjkim    ACPI_FUNCTION_TRACE_U32 (PsGetNextSimpleArg, ArgType);
43567754Smsmith
436167802Sjkim
43767754Smsmith    switch (ArgType)
43867754Smsmith    {
43967754Smsmith    case ARGP_BYTEDATA:
44067754Smsmith
441167802Sjkim        /* Get 1 byte from the AML stream */
442167802Sjkim
443167802Sjkim        Opcode = AML_BYTE_OP;
444202771Sjkim        Arg->Common.Value.Integer = (UINT64) *Aml;
445167802Sjkim        Length = 1;
44667754Smsmith        break;
44767754Smsmith
44867754Smsmith    case ARGP_WORDDATA:
44967754Smsmith
45067754Smsmith        /* Get 2 bytes from the AML stream */
45167754Smsmith
452167802Sjkim        Opcode = AML_WORD_OP;
453167802Sjkim        ACPI_MOVE_16_TO_64 (&Arg->Common.Value.Integer, Aml);
454167802Sjkim        Length = 2;
45567754Smsmith        break;
45667754Smsmith
45767754Smsmith    case ARGP_DWORDDATA:
45867754Smsmith
45967754Smsmith        /* Get 4 bytes from the AML stream */
46067754Smsmith
461167802Sjkim        Opcode = AML_DWORD_OP;
462167802Sjkim        ACPI_MOVE_32_TO_64 (&Arg->Common.Value.Integer, Aml);
463167802Sjkim        Length = 4;
46467754Smsmith        break;
46567754Smsmith
46682367Smsmith    case ARGP_QWORDDATA:
46782367Smsmith
46882367Smsmith        /* Get 8 bytes from the AML stream */
46982367Smsmith
470167802Sjkim        Opcode = AML_QWORD_OP;
471167802Sjkim        ACPI_MOVE_64_TO_64 (&Arg->Common.Value.Integer, Aml);
472167802Sjkim        Length = 8;
47382367Smsmith        break;
47482367Smsmith
47567754Smsmith    case ARGP_CHARLIST:
47667754Smsmith
477167802Sjkim        /* Get a pointer to the string, point past the string */
47867754Smsmith
479167802Sjkim        Opcode = AML_STRING_OP;
480167802Sjkim        Arg->Common.Value.String = ACPI_CAST_PTR (char, Aml);
481167802Sjkim
482167802Sjkim        /* Find the null terminator */
483167802Sjkim
484167802Sjkim        Length = 0;
485167802Sjkim        while (Aml[Length])
48667754Smsmith        {
487167802Sjkim            Length++;
48867754Smsmith        }
489167802Sjkim        Length++;
49067754Smsmith        break;
49167754Smsmith
49267754Smsmith    case ARGP_NAME:
49367754Smsmith    case ARGP_NAMESTRING:
49467754Smsmith
49577424Smsmith        AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP);
49699679Siwasaki        Arg->Common.Value.Name = AcpiPsGetNextNamestring (ParserState);
497167802Sjkim        return_VOID;
49899679Siwasaki
49999679Siwasaki    default:
500107325Siwasaki
501204773Sjkim        ACPI_ERROR ((AE_INFO, "Invalid ArgType 0x%X", ArgType));
502167802Sjkim        return_VOID;
50367754Smsmith    }
50467754Smsmith
505167802Sjkim    AcpiPsInitOp (Arg, Opcode);
506167802Sjkim    ParserState->Aml += Length;
50767754Smsmith    return_VOID;
50867754Smsmith}
50967754Smsmith
51067754Smsmith
51167754Smsmith/*******************************************************************************
51267754Smsmith *
51367754Smsmith * FUNCTION:    AcpiPsGetNextField
51467754Smsmith *
51567754Smsmith * PARAMETERS:  ParserState         - Current parser state object
51667754Smsmith *
51767754Smsmith * RETURN:      A newly allocated FIELD op
51867754Smsmith *
51967754Smsmith * DESCRIPTION: Get next field (NamedField, ReservedField, or AccessField)
52067754Smsmith *
52167754Smsmith ******************************************************************************/
52267754Smsmith
523151937Sjkimstatic ACPI_PARSE_OBJECT *
52467754SmsmithAcpiPsGetNextField (
52567754Smsmith    ACPI_PARSE_STATE        *ParserState)
52667754Smsmith{
527306536Sjkim    UINT8                   *Aml;
52867754Smsmith    ACPI_PARSE_OBJECT       *Field;
529228110Sjkim    ACPI_PARSE_OBJECT       *Arg = NULL;
53067754Smsmith    UINT16                  Opcode;
53167754Smsmith    UINT32                  Name;
532228110Sjkim    UINT8                   AccessType;
533228110Sjkim    UINT8                   AccessAttribute;
534228110Sjkim    UINT8                   AccessLength;
535228110Sjkim    UINT32                  PkgLength;
536228110Sjkim    UINT8                   *PkgEnd;
537228110Sjkim    UINT32                  BufferLength;
53867754Smsmith
53967754Smsmith
540167802Sjkim    ACPI_FUNCTION_TRACE (PsGetNextField);
54167754Smsmith
54267754Smsmith
543306536Sjkim    Aml = ParserState->Aml;
544228110Sjkim
545151937Sjkim    /* Determine field type */
54667754Smsmith
54791116Smsmith    switch (ACPI_GET8 (ParserState->Aml))
54867754Smsmith    {
549228110Sjkim    case AML_FIELD_OFFSET_OP:
55067754Smsmith
551228110Sjkim        Opcode = AML_INT_RESERVEDFIELD_OP;
552228110Sjkim        ParserState->Aml++;
55367754Smsmith        break;
55467754Smsmith
555228110Sjkim    case AML_FIELD_ACCESS_OP:
55667754Smsmith
557228110Sjkim        Opcode = AML_INT_ACCESSFIELD_OP;
55867754Smsmith        ParserState->Aml++;
55967754Smsmith        break;
56067754Smsmith
561228110Sjkim    case AML_FIELD_CONNECTION_OP:
56267754Smsmith
563228110Sjkim        Opcode = AML_INT_CONNECTION_OP;
56467754Smsmith        ParserState->Aml++;
56567754Smsmith        break;
566228110Sjkim
567228110Sjkim    case AML_FIELD_EXT_ACCESS_OP:
568228110Sjkim
569228110Sjkim        Opcode = AML_INT_EXTACCESSFIELD_OP;
570228110Sjkim        ParserState->Aml++;
571228110Sjkim        break;
572228110Sjkim
573228110Sjkim    default:
574228110Sjkim
575228110Sjkim        Opcode = AML_INT_NAMEDFIELD_OP;
576228110Sjkim        break;
57767754Smsmith    }
57867754Smsmith
57967754Smsmith    /* Allocate a new field op */
58067754Smsmith
581306536Sjkim    Field = AcpiPsAllocOp (Opcode, Aml);
58299679Siwasaki    if (!Field)
58367754Smsmith    {
58499679Siwasaki        return_PTR (NULL);
58599679Siwasaki    }
58667754Smsmith
58799679Siwasaki    /* Decode the field type */
58867754Smsmith
58999679Siwasaki    switch (Opcode)
59099679Siwasaki    {
59199679Siwasaki    case AML_INT_NAMEDFIELD_OP:
59267754Smsmith
59399679Siwasaki        /* Get the 4-character name */
59467754Smsmith
595117521Snjl        ACPI_MOVE_32_TO_32 (&Name, ParserState->Aml);
59699679Siwasaki        AcpiPsSetName (Field, Name);
597107325Siwasaki        ParserState->Aml += ACPI_NAME_SIZE;
59867754Smsmith
59999679Siwasaki        /* Get the length which is encoded as a package length */
60067754Smsmith
60199679Siwasaki        Field->Common.Value.Size = AcpiPsGetNextPackageLength (ParserState);
60299679Siwasaki        break;
60367754Smsmith
60467754Smsmith
60599679Siwasaki    case AML_INT_RESERVEDFIELD_OP:
60667754Smsmith
60799679Siwasaki        /* Get the length which is encoded as a package length */
60867754Smsmith
60999679Siwasaki        Field->Common.Value.Size = AcpiPsGetNextPackageLength (ParserState);
61099679Siwasaki        break;
61167754Smsmith
61267754Smsmith
61399679Siwasaki    case AML_INT_ACCESSFIELD_OP:
614228110Sjkim    case AML_INT_EXTACCESSFIELD_OP:
61599679Siwasaki
61699679Siwasaki        /*
61799679Siwasaki         * Get AccessType and AccessAttrib and merge into the field Op
618228110Sjkim         * AccessType is first operand, AccessAttribute is second. stuff
619228110Sjkim         * these bytes into the node integer value for convenience.
62099679Siwasaki         */
621228110Sjkim
622228110Sjkim        /* Get the two bytes (Type/Attribute) */
623228110Sjkim
624228110Sjkim        AccessType = ACPI_GET8 (ParserState->Aml);
62599679Siwasaki        ParserState->Aml++;
626228110Sjkim        AccessAttribute = ACPI_GET8 (ParserState->Aml);
62799679Siwasaki        ParserState->Aml++;
628228110Sjkim
629228110Sjkim        Field->Common.Value.Integer = (UINT8) AccessType;
630228110Sjkim        Field->Common.Value.Integer |= (UINT16) (AccessAttribute << 8);
631228110Sjkim
632228110Sjkim        /* This opcode has a third byte, AccessLength */
633228110Sjkim
634228110Sjkim        if (Opcode == AML_INT_EXTACCESSFIELD_OP)
635228110Sjkim        {
636228110Sjkim            AccessLength = ACPI_GET8 (ParserState->Aml);
637228110Sjkim            ParserState->Aml++;
638228110Sjkim
639228110Sjkim            Field->Common.Value.Integer |= (UINT32) (AccessLength << 16);
640228110Sjkim        }
64199679Siwasaki        break;
64299679Siwasaki
643228110Sjkim
644228110Sjkim    case AML_INT_CONNECTION_OP:
645228110Sjkim
646228110Sjkim        /*
647228110Sjkim         * Argument for Connection operator can be either a Buffer
648228110Sjkim         * (resource descriptor), or a NameString.
649228110Sjkim         */
650306536Sjkim        Aml = ParserState->Aml;
651228110Sjkim        if (ACPI_GET8 (ParserState->Aml) == AML_BUFFER_OP)
652228110Sjkim        {
653228110Sjkim            ParserState->Aml++;
654228110Sjkim
655228110Sjkim            PkgEnd = ParserState->Aml;
656228110Sjkim            PkgLength = AcpiPsGetNextPackageLength (ParserState);
657228110Sjkim            PkgEnd += PkgLength;
658228110Sjkim
659228110Sjkim            if (ParserState->Aml < PkgEnd)
660228110Sjkim            {
661228110Sjkim                /* Non-empty list */
662228110Sjkim
663306536Sjkim                Arg = AcpiPsAllocOp (AML_INT_BYTELIST_OP, Aml);
664228110Sjkim                if (!Arg)
665228110Sjkim                {
666233558Sjkim                    AcpiPsFreeOp (Field);
667228110Sjkim                    return_PTR (NULL);
668228110Sjkim                }
669228110Sjkim
670228110Sjkim                /* Get the actual buffer length argument */
671228110Sjkim
672228110Sjkim                Opcode = ACPI_GET8 (ParserState->Aml);
673228110Sjkim                ParserState->Aml++;
674228110Sjkim
675228110Sjkim                switch (Opcode)
676228110Sjkim                {
677228110Sjkim                case AML_BYTE_OP:       /* AML_BYTEDATA_ARG */
678250838Sjkim
679228110Sjkim                    BufferLength = ACPI_GET8 (ParserState->Aml);
680228110Sjkim                    ParserState->Aml += 1;
681228110Sjkim                    break;
682228110Sjkim
683228110Sjkim                case AML_WORD_OP:       /* AML_WORDDATA_ARG */
684250838Sjkim
685228110Sjkim                    BufferLength = ACPI_GET16 (ParserState->Aml);
686228110Sjkim                    ParserState->Aml += 2;
687228110Sjkim                    break;
688228110Sjkim
689228110Sjkim                case AML_DWORD_OP:      /* AML_DWORDATA_ARG */
690250838Sjkim
691228110Sjkim                    BufferLength = ACPI_GET32 (ParserState->Aml);
692228110Sjkim                    ParserState->Aml += 4;
693228110Sjkim                    break;
694228110Sjkim
695228110Sjkim                default:
696250838Sjkim
697228110Sjkim                    BufferLength = 0;
698228110Sjkim                    break;
699228110Sjkim                }
700228110Sjkim
701228110Sjkim                /* Fill in bytelist data */
702228110Sjkim
703228110Sjkim                Arg->Named.Value.Size = BufferLength;
704228110Sjkim                Arg->Named.Data = ParserState->Aml;
705228110Sjkim            }
706228110Sjkim
707228110Sjkim            /* Skip to End of byte data */
708228110Sjkim
709228110Sjkim            ParserState->Aml = PkgEnd;
710228110Sjkim        }
711228110Sjkim        else
712228110Sjkim        {
713306536Sjkim            Arg = AcpiPsAllocOp (AML_INT_NAMEPATH_OP, Aml);
714228110Sjkim            if (!Arg)
715228110Sjkim            {
716233558Sjkim                AcpiPsFreeOp (Field);
717228110Sjkim                return_PTR (NULL);
718228110Sjkim            }
719228110Sjkim
720228110Sjkim            /* Get the Namestring argument */
721228110Sjkim
722228110Sjkim            Arg->Common.Value.Name = AcpiPsGetNextNamestring (ParserState);
723228110Sjkim        }
724228110Sjkim
725228110Sjkim        /* Link the buffer/namestring to parent (CONNECTION_OP) */
726228110Sjkim
727228110Sjkim        AcpiPsAppendArg (Field, Arg);
728228110Sjkim        break;
729228110Sjkim
730228110Sjkim
73199679Siwasaki    default:
732107325Siwasaki
73399679Siwasaki        /* Opcode was set in previous switch */
73499679Siwasaki        break;
73567754Smsmith    }
73667754Smsmith
73767754Smsmith    return_PTR (Field);
73867754Smsmith}
73967754Smsmith
74067754Smsmith
74167754Smsmith/*******************************************************************************
74267754Smsmith *
74367754Smsmith * FUNCTION:    AcpiPsGetNextArg
74467754Smsmith *
745151937Sjkim * PARAMETERS:  WalkState           - Current state
746151937Sjkim *              ParserState         - Current parser state object
74767754Smsmith *              ArgType             - The argument type (AML_*_ARG)
748151937Sjkim *              ReturnArg           - Where the next arg is returned
74967754Smsmith *
750102550Siwasaki * RETURN:      Status, and an op object containing the next argument.
75167754Smsmith *
75267754Smsmith * DESCRIPTION: Get next argument (including complex list arguments that require
75367754Smsmith *              pushing the parser stack)
75467754Smsmith *
75567754Smsmith ******************************************************************************/
75667754Smsmith
757102550SiwasakiACPI_STATUS
75867754SmsmithAcpiPsGetNextArg (
759107325Siwasaki    ACPI_WALK_STATE         *WalkState,
76067754Smsmith    ACPI_PARSE_STATE        *ParserState,
76167754Smsmith    UINT32                  ArgType,
762102550Siwasaki    ACPI_PARSE_OBJECT       **ReturnArg)
76367754Smsmith{
76467754Smsmith    ACPI_PARSE_OBJECT       *Arg = NULL;
76567754Smsmith    ACPI_PARSE_OBJECT       *Prev = NULL;
76667754Smsmith    ACPI_PARSE_OBJECT       *Field;
76767754Smsmith    UINT32                  Subop;
768102550Siwasaki    ACPI_STATUS             Status = AE_OK;
76967754Smsmith
77067754Smsmith
771167802Sjkim    ACPI_FUNCTION_TRACE_PTR (PsGetNextArg, ParserState);
77267754Smsmith
77367754Smsmith
77467754Smsmith    switch (ArgType)
77567754Smsmith    {
77667754Smsmith    case ARGP_BYTEDATA:
77767754Smsmith    case ARGP_WORDDATA:
77867754Smsmith    case ARGP_DWORDDATA:
77967754Smsmith    case ARGP_CHARLIST:
78067754Smsmith    case ARGP_NAME:
78167754Smsmith    case ARGP_NAMESTRING:
78267754Smsmith
783151937Sjkim        /* Constants, strings, and namestrings are all the same size */
78467754Smsmith
785306536Sjkim        Arg = AcpiPsAllocOp (AML_BYTE_OP, ParserState->Aml);
786102550Siwasaki        if (!Arg)
78767754Smsmith        {
788102550Siwasaki            return_ACPI_STATUS (AE_NO_MEMORY);
78967754Smsmith        }
790306536Sjkim
791102550Siwasaki        AcpiPsGetNextSimpleArg (ParserState, ArgType, Arg);
79267754Smsmith        break;
79367754Smsmith
79467754Smsmith    case ARGP_PKGLENGTH:
79567754Smsmith
796102550Siwasaki        /* Package length, nothing returned */
79767754Smsmith
79867754Smsmith        ParserState->PkgEnd = AcpiPsGetNextPackageEnd (ParserState);
79967754Smsmith        break;
80067754Smsmith
80167754Smsmith    case ARGP_FIELDLIST:
80267754Smsmith
80367754Smsmith        if (ParserState->Aml < ParserState->PkgEnd)
80467754Smsmith        {
805102550Siwasaki            /* Non-empty list */
80667754Smsmith
80767754Smsmith            while (ParserState->Aml < ParserState->PkgEnd)
80867754Smsmith            {
80967754Smsmith                Field = AcpiPsGetNextField (ParserState);
81067754Smsmith                if (!Field)
81167754Smsmith                {
812102550Siwasaki                    return_ACPI_STATUS (AE_NO_MEMORY);
81367754Smsmith                }
81467754Smsmith
81567754Smsmith                if (Prev)
81667754Smsmith                {
81799679Siwasaki                    Prev->Common.Next = Field;
81867754Smsmith                }
81967754Smsmith                else
82067754Smsmith                {
82167754Smsmith                    Arg = Field;
82267754Smsmith                }
82367754Smsmith                Prev = Field;
82467754Smsmith            }
82567754Smsmith
826102550Siwasaki            /* Skip to End of byte data */
82767754Smsmith
82867754Smsmith            ParserState->Aml = ParserState->PkgEnd;
82967754Smsmith        }
83067754Smsmith        break;
83167754Smsmith
83267754Smsmith    case ARGP_BYTELIST:
83367754Smsmith
83467754Smsmith        if (ParserState->Aml < ParserState->PkgEnd)
83567754Smsmith        {
836102550Siwasaki            /* Non-empty list */
83767754Smsmith
838306536Sjkim            Arg = AcpiPsAllocOp (AML_INT_BYTELIST_OP,
839306536Sjkim                ParserState->Aml);
840102550Siwasaki            if (!Arg)
84167754Smsmith            {
842102550Siwasaki                return_ACPI_STATUS (AE_NO_MEMORY);
84367754Smsmith            }
84467754Smsmith
845102550Siwasaki            /* Fill in bytelist data */
84667754Smsmith
847151937Sjkim            Arg->Common.Value.Size = (UINT32)
848151937Sjkim                ACPI_PTR_DIFF (ParserState->PkgEnd, ParserState->Aml);
849102550Siwasaki            Arg->Named.Data = ParserState->Aml;
850102550Siwasaki
851102550Siwasaki            /* Skip to End of byte data */
852102550Siwasaki
85367754Smsmith            ParserState->Aml = ParserState->PkgEnd;
85467754Smsmith        }
85567754Smsmith        break;
85667754Smsmith
85767754Smsmith    case ARGP_TARGET:
85867754Smsmith    case ARGP_SUPERNAME:
85991116Smsmith    case ARGP_SIMPLENAME:
860306536Sjkim    case ARGP_NAME_OR_REF:
861102550Siwasaki
862102550Siwasaki        Subop = AcpiPsPeekOpcode (ParserState);
863102550Siwasaki        if (Subop == 0                  ||
864102550Siwasaki            AcpiPsIsLeadingChar (Subop) ||
865245582Sjkim            ACPI_IS_ROOT_PREFIX (Subop) ||
866245582Sjkim            ACPI_IS_PARENT_PREFIX (Subop))
86767754Smsmith        {
868102550Siwasaki            /* NullName or NameString */
869102550Siwasaki
870306536Sjkim            Arg = AcpiPsAllocOp (AML_INT_NAMEPATH_OP, ParserState->Aml);
871102550Siwasaki            if (!Arg)
87267754Smsmith            {
873102550Siwasaki                return_ACPI_STATUS (AE_NO_MEMORY);
87467754Smsmith            }
87567754Smsmith
876193267Sjkim            /* To support SuperName arg of Unload */
877193267Sjkim
878193267Sjkim            if (WalkState->Opcode == AML_UNLOAD_OP)
879193267Sjkim            {
880306536Sjkim                Status = AcpiPsGetNextNamepath (WalkState, ParserState,
881306536Sjkim                    Arg, ACPI_POSSIBLE_METHOD_CALL);
882193267Sjkim
883193267Sjkim                /*
884306536Sjkim                 * If the SuperName argument is a method call, we have
885306536Sjkim                 * already restored the AML pointer, just free this Arg
886193267Sjkim                 */
887193267Sjkim                if (Arg->Common.AmlOpcode == AML_INT_METHODCALL_OP)
888193267Sjkim                {
889193267Sjkim                    AcpiPsFreeOp (Arg);
890193267Sjkim                    Arg = NULL;
891193267Sjkim                }
892193267Sjkim            }
893193267Sjkim            else
894193267Sjkim            {
895306536Sjkim                Status = AcpiPsGetNextNamepath (WalkState, ParserState,
896306536Sjkim                    Arg, ACPI_NOT_METHOD_CALL);
897193267Sjkim            }
898102550Siwasaki        }
899102550Siwasaki        else
900102550Siwasaki        {
901151937Sjkim            /* Single complex argument, nothing returned */
90267754Smsmith
903107325Siwasaki            WalkState->ArgCount = 1;
90467754Smsmith        }
90567754Smsmith        break;
90667754Smsmith
90767754Smsmith    case ARGP_DATAOBJ:
90867754Smsmith    case ARGP_TERMARG:
90967754Smsmith
910151937Sjkim        /* Single complex argument, nothing returned */
91167754Smsmith
912107325Siwasaki        WalkState->ArgCount = 1;
91367754Smsmith        break;
91467754Smsmith
91567754Smsmith    case ARGP_DATAOBJLIST:
91667754Smsmith    case ARGP_TERMLIST:
91767754Smsmith    case ARGP_OBJLIST:
91867754Smsmith
91967754Smsmith        if (ParserState->Aml < ParserState->PkgEnd)
92067754Smsmith        {
921151937Sjkim            /* Non-empty list of variable arguments, nothing returned */
92267754Smsmith
923107325Siwasaki            WalkState->ArgCount = ACPI_VAR_ARGS;
92467754Smsmith        }
92567754Smsmith        break;
92699679Siwasaki
92799679Siwasaki    default:
928102550Siwasaki
929204773Sjkim        ACPI_ERROR ((AE_INFO, "Invalid ArgType: 0x%X", ArgType));
930102550Siwasaki        Status = AE_AML_OPERAND_TYPE;
93199679Siwasaki        break;
93267754Smsmith    }
93367754Smsmith
934102550Siwasaki    *ReturnArg = Arg;
935102550Siwasaki    return_ACPI_STATUS (Status);
93667754Smsmith}
937