psargs.c revision 233558
1247280Sdteske/******************************************************************************
2247280Sdteske *
3247280Sdteske * Module Name: psargs - Parse AML opcode arguments
4252980Sdteske *
5247280Sdteske *****************************************************************************/
6247280Sdteske
7247280Sdteske/*
8247280Sdteske * Copyright (C) 2000 - 2012, Intel Corp.
9247280Sdteske * All rights reserved.
10247280Sdteske *
11247280Sdteske * Redistribution and use in source and binary forms, with or without
12247280Sdteske * modification, are permitted provided that the following conditions
13247280Sdteske * are met:
14247280Sdteske * 1. Redistributions of source code must retain the above copyright
15247280Sdteske *    notice, this list of conditions, and the following disclaimer,
16252987Sdteske *    without modification.
17247280Sdteske * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18247280Sdteske *    substantially similar to the "NO WARRANTY" disclaimer below
19247280Sdteske *    ("Disclaimer") and any redistribution must be conditioned upon
20252987Sdteske *    including a substantially similar Disclaimer requirement for further
21247280Sdteske *    binary redistribution.
22247280Sdteske * 3. Neither the names of the above-listed copyright holders nor the names
23247280Sdteske *    of any contributors may be used to endorse or promote products derived
24247280Sdteske *    from this software without specific prior written permission.
25247280Sdteske *
26247280Sdteske * Alternatively, this software may be distributed under the terms of the
27247280Sdteske * GNU General Public License ("GPL") version 2 as published by the Free
28247280Sdteske * Software Foundation.
29247280Sdteske *
30247280Sdteske * NO WARRANTY
31247280Sdteske * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32247280Sdteske * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33247280Sdteske * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34247280Sdteske * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35247280Sdteske * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36247280Sdteske * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37247280Sdteske * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38247280Sdteske * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39247280Sdteske * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40247280Sdteske * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41247280Sdteske * POSSIBILITY OF SUCH DAMAGES.
42247280Sdteske */
43247280Sdteske
44247280Sdteske#define __PSARGS_C__
45247280Sdteske
46247280Sdteske#include <contrib/dev/acpica/include/acpi.h>
47247280Sdteske#include <contrib/dev/acpica/include/accommon.h>
48247280Sdteske#include <contrib/dev/acpica/include/acparser.h>
49247280Sdteske#include <contrib/dev/acpica/include/amlcode.h>
50247280Sdteske#include <contrib/dev/acpica/include/acnamesp.h>
51247280Sdteske#include <contrib/dev/acpica/include/acdispat.h>
52247280Sdteske
53247280Sdteske#define _COMPONENT          ACPI_PARSER
54247280Sdteske        ACPI_MODULE_NAME    ("psargs")
55247280Sdteske
56247280Sdteske/* Local prototypes */
57247280Sdteske
58247280Sdteskestatic UINT32
59247280SdteskeAcpiPsGetNextPackageLength (
60247280Sdteske    ACPI_PARSE_STATE        *ParserState);
61247280Sdteske
62247280Sdteskestatic ACPI_PARSE_OBJECT *
63247280SdteskeAcpiPsGetNextField (
64247280Sdteske    ACPI_PARSE_STATE        *ParserState);
65247280Sdteske
66247280Sdteske
67247280Sdteske/*******************************************************************************
68247280Sdteske *
69247280Sdteske * FUNCTION:    AcpiPsGetNextPackageLength
70247280Sdteske *
71247280Sdteske * PARAMETERS:  ParserState         - Current parser state object
72247280Sdteske *
73247280Sdteske * RETURN:      Decoded package length. On completion, the AML pointer points
74247280Sdteske *              past the length byte or bytes.
75247280Sdteske *
76247280Sdteske * DESCRIPTION: Decode and return a package length field.
77247280Sdteske *              Note: Largest package length is 28 bits, from ACPI specification
78247280Sdteske *
79247280Sdteske ******************************************************************************/
80247280Sdteske
81247280Sdteskestatic UINT32
82247280SdteskeAcpiPsGetNextPackageLength (
83247280Sdteske    ACPI_PARSE_STATE        *ParserState)
84247280Sdteske{
85247280Sdteske    UINT8                   *Aml = ParserState->Aml;
86247280Sdteske    UINT32                  PackageLength = 0;
87247280Sdteske    UINT32                  ByteCount;
88247280Sdteske    UINT8                   ByteZeroMask = 0x3F; /* Default [0:5] */
89247280Sdteske
90247280Sdteske
91247280Sdteske    ACPI_FUNCTION_TRACE (PsGetNextPackageLength);
92247280Sdteske
93247280Sdteske
94247280Sdteske    /*
95247280Sdteske     * Byte 0 bits [6:7] contain the number of additional bytes
96247280Sdteske     * used to encode the package length, either 0,1,2, or 3
97247280Sdteske     */
98247280Sdteske    ByteCount = (Aml[0] >> 6);
99247280Sdteske    ParserState->Aml += ((ACPI_SIZE) ByteCount + 1);
100247280Sdteske
101247280Sdteske    /* Get bytes 3, 2, 1 as needed */
102247280Sdteske
103247280Sdteske    while (ByteCount)
104247280Sdteske    {
105247280Sdteske        /*
106247280Sdteske         * Final bit positions for the package length bytes:
107247280Sdteske         *      Byte3->[20:27]
108247280Sdteske         *      Byte2->[12:19]
109247280Sdteske         *      Byte1->[04:11]
110247280Sdteske         *      Byte0->[00:03]
111247280Sdteske         */
112247280Sdteske        PackageLength |= (Aml[ByteCount] << ((ByteCount << 3) - 4));
113252795Sdteske
114247280Sdteske        ByteZeroMask = 0x0F; /* Use bits [0:3] of byte 0 */
115247280Sdteske        ByteCount--;
116247280Sdteske    }
117247280Sdteske
118247280Sdteske    /* Byte 0 is a special case, either bits [0:3] or [0:5] are used */
119247280Sdteske
120247280Sdteske    PackageLength |= (Aml[0] & ByteZeroMask);
121247280Sdteske    return_UINT32 (PackageLength);
122247280Sdteske}
123247280Sdteske
124252795Sdteske
125247280Sdteske/*******************************************************************************
126247280Sdteske *
127247280Sdteske * FUNCTION:    AcpiPsGetNextPackageEnd
128247280Sdteske *
129247280Sdteske * PARAMETERS:  ParserState         - Current parser state object
130247280Sdteske *
131247280Sdteske * RETURN:      Pointer to end-of-package +1
132247280Sdteske *
133247280Sdteske * DESCRIPTION: Get next package length and return a pointer past the end of
134247280Sdteske *              the package.  Consumes the package length field
135247280Sdteske *
136247280Sdteske ******************************************************************************/
137247280Sdteske
138247280SdteskeUINT8 *
139247280SdteskeAcpiPsGetNextPackageEnd (
140247280Sdteske    ACPI_PARSE_STATE        *ParserState)
141247280Sdteske{
142247280Sdteske    UINT8                   *Start = ParserState->Aml;
143247280Sdteske    UINT32                  PackageLength;
144247280Sdteske
145247280Sdteske
146247280Sdteske    ACPI_FUNCTION_TRACE (PsGetNextPackageEnd);
147247280Sdteske
148247280Sdteske
149247280Sdteske    /* Function below updates ParserState->Aml */
150247280Sdteske
151247280Sdteske    PackageLength = AcpiPsGetNextPackageLength (ParserState);
152247280Sdteske
153247280Sdteske    return_PTR (Start + PackageLength); /* end of package */
154247280Sdteske}
155247280Sdteske
156247280Sdteske
157247280Sdteske/*******************************************************************************
158247280Sdteske *
159247280Sdteske * FUNCTION:    AcpiPsGetNextNamestring
160247280Sdteske *
161247280Sdteske * PARAMETERS:  ParserState         - Current parser state object
162247280Sdteske *
163247280Sdteske * RETURN:      Pointer to the start of the name string (pointer points into
164247280Sdteske *              the AML.
165247280Sdteske *
166247280Sdteske * DESCRIPTION: Get next raw namestring within the AML stream.  Handles all name
167247280Sdteske *              prefix characters.  Set parser state to point past the string.
168247280Sdteske *              (Name is consumed from the AML.)
169247280Sdteske *
170247280Sdteske ******************************************************************************/
171247280Sdteske
172247280Sdteskechar *
173247280SdteskeAcpiPsGetNextNamestring (
174247280Sdteske    ACPI_PARSE_STATE        *ParserState)
175247280Sdteske{
176247280Sdteske    UINT8                   *Start = ParserState->Aml;
177247280Sdteske    UINT8                   *End = ParserState->Aml;
178247280Sdteske
179247280Sdteske
180247280Sdteske    ACPI_FUNCTION_TRACE (PsGetNextNamestring);
181247280Sdteske
182247280Sdteske
183    /* Point past any namestring prefix characters (backslash or carat) */
184
185    while (AcpiPsIsPrefixChar (*End))
186    {
187        End++;
188    }
189
190    /* Decode the path prefix character */
191
192    switch (*End)
193    {
194    case 0:
195
196        /* NullName */
197
198        if (End == Start)
199        {
200            Start = NULL;
201        }
202        End++;
203        break;
204
205    case AML_DUAL_NAME_PREFIX:
206
207        /* Two name segments */
208
209        End += 1 + (2 * ACPI_NAME_SIZE);
210        break;
211
212    case AML_MULTI_NAME_PREFIX_OP:
213
214        /* Multiple name segments, 4 chars each, count in next byte */
215
216        End += 2 + (*(End + 1) * ACPI_NAME_SIZE);
217        break;
218
219    default:
220
221        /* Single name segment */
222
223        End += ACPI_NAME_SIZE;
224        break;
225    }
226
227    ParserState->Aml = End;
228    return_PTR ((char *) Start);
229}
230
231
232/*******************************************************************************
233 *
234 * FUNCTION:    AcpiPsGetNextNamepath
235 *
236 * PARAMETERS:  ParserState         - Current parser state object
237 *              Arg                 - Where the namepath will be stored
238 *              ArgCount            - If the namepath points to a control method
239 *                                    the method's argument is returned here.
240 *              PossibleMethodCall  - Whether the namepath can possibly be the
241 *                                    start of a method call
242 *
243 * RETURN:      Status
244 *
245 * DESCRIPTION: Get next name (if method call, return # of required args).
246 *              Names are looked up in the internal namespace to determine
247 *              if the name represents a control method.  If a method
248 *              is found, the number of arguments to the method is returned.
249 *              This information is critical for parsing to continue correctly.
250 *
251 ******************************************************************************/
252
253ACPI_STATUS
254AcpiPsGetNextNamepath (
255    ACPI_WALK_STATE         *WalkState,
256    ACPI_PARSE_STATE        *ParserState,
257    ACPI_PARSE_OBJECT       *Arg,
258    BOOLEAN                 PossibleMethodCall)
259{
260    ACPI_STATUS             Status;
261    char                    *Path;
262    ACPI_PARSE_OBJECT       *NameOp;
263    ACPI_OPERAND_OBJECT     *MethodDesc;
264    ACPI_NAMESPACE_NODE     *Node;
265    UINT8                   *Start = ParserState->Aml;
266
267
268    ACPI_FUNCTION_TRACE (PsGetNextNamepath);
269
270
271    Path = AcpiPsGetNextNamestring (ParserState);
272    AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP);
273
274    /* Null path case is allowed, just exit */
275
276    if (!Path)
277    {
278        Arg->Common.Value.Name = Path;
279        return_ACPI_STATUS (AE_OK);
280    }
281
282    /*
283     * Lookup the name in the internal namespace, starting with the current
284     * scope. We don't want to add anything new to the namespace here,
285     * however, so we use MODE_EXECUTE.
286     * Allow searching of the parent tree, but don't open a new scope -
287     * we just want to lookup the object (must be mode EXECUTE to perform
288     * the upsearch)
289     */
290    Status = AcpiNsLookup (WalkState->ScopeInfo, Path,
291                ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
292                ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL, &Node);
293
294    /*
295     * If this name is a control method invocation, we must
296     * setup the method call
297     */
298    if (ACPI_SUCCESS (Status) &&
299        PossibleMethodCall &&
300        (Node->Type == ACPI_TYPE_METHOD))
301    {
302        if (WalkState->Opcode == AML_UNLOAD_OP)
303        {
304            /*
305             * AcpiPsGetNextNamestring has increased the AML pointer,
306             * so we need to restore the saved AML pointer for method call.
307             */
308            WalkState->ParserState.Aml = Start;
309            WalkState->ArgCount = 1;
310            AcpiPsInitOp (Arg, AML_INT_METHODCALL_OP);
311            return_ACPI_STATUS (AE_OK);
312        }
313
314        /* This name is actually a control method invocation */
315
316        MethodDesc = AcpiNsGetAttachedObject (Node);
317        ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
318            "Control Method - %p Desc %p Path=%p\n", Node, MethodDesc, Path));
319
320        NameOp = AcpiPsAllocOp (AML_INT_NAMEPATH_OP);
321        if (!NameOp)
322        {
323            return_ACPI_STATUS (AE_NO_MEMORY);
324        }
325
326        /* Change Arg into a METHOD CALL and attach name to it */
327
328        AcpiPsInitOp (Arg, AML_INT_METHODCALL_OP);
329        NameOp->Common.Value.Name = Path;
330
331        /* Point METHODCALL/NAME to the METHOD Node */
332
333        NameOp->Common.Node = Node;
334        AcpiPsAppendArg (Arg, NameOp);
335
336        if (!MethodDesc)
337        {
338            ACPI_ERROR ((AE_INFO,
339                "Control Method %p has no attached object",
340                Node));
341            return_ACPI_STATUS (AE_AML_INTERNAL);
342        }
343
344        ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
345            "Control Method - %p Args %X\n",
346            Node, MethodDesc->Method.ParamCount));
347
348        /* Get the number of arguments to expect */
349
350        WalkState->ArgCount = MethodDesc->Method.ParamCount;
351        return_ACPI_STATUS (AE_OK);
352    }
353
354    /*
355     * Special handling if the name was not found during the lookup -
356     * some NotFound cases are allowed
357     */
358    if (Status == AE_NOT_FOUND)
359    {
360        /* 1) NotFound is ok during load pass 1/2 (allow forward references) */
361
362        if ((WalkState->ParseFlags & ACPI_PARSE_MODE_MASK) !=
363                ACPI_PARSE_EXECUTE)
364        {
365            Status = AE_OK;
366        }
367
368        /* 2) NotFound during a CondRefOf(x) is ok by definition */
369
370        else if (WalkState->Op->Common.AmlOpcode == AML_COND_REF_OF_OP)
371        {
372            Status = AE_OK;
373        }
374
375        /*
376         * 3) NotFound while building a Package is ok at this point, we
377         * may flag as an error later if slack mode is not enabled.
378         * (Some ASL code depends on allowing this behavior)
379         */
380        else if ((Arg->Common.Parent) &&
381            ((Arg->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||
382             (Arg->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP)))
383        {
384            Status = AE_OK;
385        }
386    }
387
388    /* Final exception check (may have been changed from code above) */
389
390    if (ACPI_FAILURE (Status))
391    {
392        ACPI_ERROR_NAMESPACE (Path, Status);
393
394        if ((WalkState->ParseFlags & ACPI_PARSE_MODE_MASK) ==
395                ACPI_PARSE_EXECUTE)
396        {
397            /* Report a control method execution error */
398
399            Status = AcpiDsMethodError (Status, WalkState);
400        }
401    }
402
403    /* Save the namepath */
404
405    Arg->Common.Value.Name = Path;
406    return_ACPI_STATUS (Status);
407}
408
409
410/*******************************************************************************
411 *
412 * FUNCTION:    AcpiPsGetNextSimpleArg
413 *
414 * PARAMETERS:  ParserState         - Current parser state object
415 *              ArgType             - The argument type (AML_*_ARG)
416 *              Arg                 - Where the argument is returned
417 *
418 * RETURN:      None
419 *
420 * DESCRIPTION: Get the next simple argument (constant, string, or namestring)
421 *
422 ******************************************************************************/
423
424void
425AcpiPsGetNextSimpleArg (
426    ACPI_PARSE_STATE        *ParserState,
427    UINT32                  ArgType,
428    ACPI_PARSE_OBJECT       *Arg)
429{
430    UINT32                  Length;
431    UINT16                  Opcode;
432    UINT8                   *Aml = ParserState->Aml;
433
434
435    ACPI_FUNCTION_TRACE_U32 (PsGetNextSimpleArg, ArgType);
436
437
438    switch (ArgType)
439    {
440    case ARGP_BYTEDATA:
441
442        /* Get 1 byte from the AML stream */
443
444        Opcode = AML_BYTE_OP;
445        Arg->Common.Value.Integer = (UINT64) *Aml;
446        Length = 1;
447        break;
448
449
450    case ARGP_WORDDATA:
451
452        /* Get 2 bytes from the AML stream */
453
454        Opcode = AML_WORD_OP;
455        ACPI_MOVE_16_TO_64 (&Arg->Common.Value.Integer, Aml);
456        Length = 2;
457        break;
458
459
460    case ARGP_DWORDDATA:
461
462        /* Get 4 bytes from the AML stream */
463
464        Opcode = AML_DWORD_OP;
465        ACPI_MOVE_32_TO_64 (&Arg->Common.Value.Integer, Aml);
466        Length = 4;
467        break;
468
469
470    case ARGP_QWORDDATA:
471
472        /* Get 8 bytes from the AML stream */
473
474        Opcode = AML_QWORD_OP;
475        ACPI_MOVE_64_TO_64 (&Arg->Common.Value.Integer, Aml);
476        Length = 8;
477        break;
478
479
480    case ARGP_CHARLIST:
481
482        /* Get a pointer to the string, point past the string */
483
484        Opcode = AML_STRING_OP;
485        Arg->Common.Value.String = ACPI_CAST_PTR (char, Aml);
486
487        /* Find the null terminator */
488
489        Length = 0;
490        while (Aml[Length])
491        {
492            Length++;
493        }
494        Length++;
495        break;
496
497
498    case ARGP_NAME:
499    case ARGP_NAMESTRING:
500
501        AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP);
502        Arg->Common.Value.Name = AcpiPsGetNextNamestring (ParserState);
503        return_VOID;
504
505
506    default:
507
508        ACPI_ERROR ((AE_INFO, "Invalid ArgType 0x%X", ArgType));
509        return_VOID;
510    }
511
512    AcpiPsInitOp (Arg, Opcode);
513    ParserState->Aml += Length;
514    return_VOID;
515}
516
517
518/*******************************************************************************
519 *
520 * FUNCTION:    AcpiPsGetNextField
521 *
522 * PARAMETERS:  ParserState         - Current parser state object
523 *
524 * RETURN:      A newly allocated FIELD op
525 *
526 * DESCRIPTION: Get next field (NamedField, ReservedField, or AccessField)
527 *
528 ******************************************************************************/
529
530static ACPI_PARSE_OBJECT *
531AcpiPsGetNextField (
532    ACPI_PARSE_STATE        *ParserState)
533{
534    UINT32                  AmlOffset;
535    ACPI_PARSE_OBJECT       *Field;
536    ACPI_PARSE_OBJECT       *Arg = NULL;
537    UINT16                  Opcode;
538    UINT32                  Name;
539    UINT8                   AccessType;
540    UINT8                   AccessAttribute;
541    UINT8                   AccessLength;
542    UINT32                  PkgLength;
543    UINT8                   *PkgEnd;
544    UINT32                  BufferLength;
545
546
547    ACPI_FUNCTION_TRACE (PsGetNextField);
548
549
550    AmlOffset = (UINT32) ACPI_PTR_DIFF (
551        ParserState->Aml, ParserState->AmlStart);
552
553    /* Determine field type */
554
555    switch (ACPI_GET8 (ParserState->Aml))
556    {
557    case AML_FIELD_OFFSET_OP:
558
559        Opcode = AML_INT_RESERVEDFIELD_OP;
560        ParserState->Aml++;
561        break;
562
563    case AML_FIELD_ACCESS_OP:
564
565        Opcode = AML_INT_ACCESSFIELD_OP;
566        ParserState->Aml++;
567        break;
568
569    case AML_FIELD_CONNECTION_OP:
570
571        Opcode = AML_INT_CONNECTION_OP;
572        ParserState->Aml++;
573        break;
574
575    case AML_FIELD_EXT_ACCESS_OP:
576
577        Opcode = AML_INT_EXTACCESSFIELD_OP;
578        ParserState->Aml++;
579        break;
580
581    default:
582
583        Opcode = AML_INT_NAMEDFIELD_OP;
584        break;
585    }
586
587    /* Allocate a new field op */
588
589    Field = AcpiPsAllocOp (Opcode);
590    if (!Field)
591    {
592        return_PTR (NULL);
593    }
594
595    Field->Common.AmlOffset = AmlOffset;
596
597    /* Decode the field type */
598
599    switch (Opcode)
600    {
601    case AML_INT_NAMEDFIELD_OP:
602
603        /* Get the 4-character name */
604
605        ACPI_MOVE_32_TO_32 (&Name, ParserState->Aml);
606        AcpiPsSetName (Field, Name);
607        ParserState->Aml += ACPI_NAME_SIZE;
608
609        /* Get the length which is encoded as a package length */
610
611        Field->Common.Value.Size = AcpiPsGetNextPackageLength (ParserState);
612        break;
613
614
615    case AML_INT_RESERVEDFIELD_OP:
616
617        /* Get the length which is encoded as a package length */
618
619        Field->Common.Value.Size = AcpiPsGetNextPackageLength (ParserState);
620        break;
621
622
623    case AML_INT_ACCESSFIELD_OP:
624    case AML_INT_EXTACCESSFIELD_OP:
625
626        /*
627         * Get AccessType and AccessAttrib and merge into the field Op
628         * AccessType is first operand, AccessAttribute is second. stuff
629         * these bytes into the node integer value for convenience.
630         */
631
632        /* Get the two bytes (Type/Attribute) */
633
634        AccessType = ACPI_GET8 (ParserState->Aml);
635        ParserState->Aml++;
636        AccessAttribute = ACPI_GET8 (ParserState->Aml);
637        ParserState->Aml++;
638
639        Field->Common.Value.Integer = (UINT8) AccessType;
640        Field->Common.Value.Integer |= (UINT16) (AccessAttribute << 8);
641
642        /* This opcode has a third byte, AccessLength */
643
644        if (Opcode == AML_INT_EXTACCESSFIELD_OP)
645        {
646            AccessLength = ACPI_GET8 (ParserState->Aml);
647            ParserState->Aml++;
648
649            Field->Common.Value.Integer |= (UINT32) (AccessLength << 16);
650        }
651        break;
652
653
654    case AML_INT_CONNECTION_OP:
655
656        /*
657         * Argument for Connection operator can be either a Buffer
658         * (resource descriptor), or a NameString.
659         */
660        if (ACPI_GET8 (ParserState->Aml) == AML_BUFFER_OP)
661        {
662            ParserState->Aml++;
663
664            PkgEnd = ParserState->Aml;
665            PkgLength = AcpiPsGetNextPackageLength (ParserState);
666            PkgEnd += PkgLength;
667
668            if (ParserState->Aml < PkgEnd)
669            {
670                /* Non-empty list */
671
672                Arg = AcpiPsAllocOp (AML_INT_BYTELIST_OP);
673                if (!Arg)
674                {
675                    AcpiPsFreeOp (Field);
676                    return_PTR (NULL);
677                }
678
679                /* Get the actual buffer length argument */
680
681                Opcode = ACPI_GET8 (ParserState->Aml);
682                ParserState->Aml++;
683
684                switch (Opcode)
685                {
686                case AML_BYTE_OP:       /* AML_BYTEDATA_ARG */
687                    BufferLength = ACPI_GET8 (ParserState->Aml);
688                    ParserState->Aml += 1;
689                    break;
690
691                case AML_WORD_OP:       /* AML_WORDDATA_ARG */
692                    BufferLength = ACPI_GET16 (ParserState->Aml);
693                    ParserState->Aml += 2;
694                    break;
695
696                case AML_DWORD_OP:      /* AML_DWORDATA_ARG */
697                    BufferLength = ACPI_GET32 (ParserState->Aml);
698                    ParserState->Aml += 4;
699                    break;
700
701                default:
702                    BufferLength = 0;
703                    break;
704                }
705
706                /* Fill in bytelist data */
707
708                Arg->Named.Value.Size = BufferLength;
709                Arg->Named.Data = ParserState->Aml;
710            }
711
712            /* Skip to End of byte data */
713
714            ParserState->Aml = PkgEnd;
715        }
716        else
717        {
718            Arg = AcpiPsAllocOp (AML_INT_NAMEPATH_OP);
719            if (!Arg)
720            {
721                AcpiPsFreeOp (Field);
722                return_PTR (NULL);
723            }
724
725            /* Get the Namestring argument */
726
727            Arg->Common.Value.Name = AcpiPsGetNextNamestring (ParserState);
728        }
729
730        /* Link the buffer/namestring to parent (CONNECTION_OP) */
731
732        AcpiPsAppendArg (Field, Arg);
733        break;
734
735
736    default:
737
738        /* Opcode was set in previous switch */
739        break;
740    }
741
742    return_PTR (Field);
743}
744
745
746/*******************************************************************************
747 *
748 * FUNCTION:    AcpiPsGetNextArg
749 *
750 * PARAMETERS:  WalkState           - Current state
751 *              ParserState         - Current parser state object
752 *              ArgType             - The argument type (AML_*_ARG)
753 *              ReturnArg           - Where the next arg is returned
754 *
755 * RETURN:      Status, and an op object containing the next argument.
756 *
757 * DESCRIPTION: Get next argument (including complex list arguments that require
758 *              pushing the parser stack)
759 *
760 ******************************************************************************/
761
762ACPI_STATUS
763AcpiPsGetNextArg (
764    ACPI_WALK_STATE         *WalkState,
765    ACPI_PARSE_STATE        *ParserState,
766    UINT32                  ArgType,
767    ACPI_PARSE_OBJECT       **ReturnArg)
768{
769    ACPI_PARSE_OBJECT       *Arg = NULL;
770    ACPI_PARSE_OBJECT       *Prev = NULL;
771    ACPI_PARSE_OBJECT       *Field;
772    UINT32                  Subop;
773    ACPI_STATUS             Status = AE_OK;
774
775
776    ACPI_FUNCTION_TRACE_PTR (PsGetNextArg, ParserState);
777
778
779    switch (ArgType)
780    {
781    case ARGP_BYTEDATA:
782    case ARGP_WORDDATA:
783    case ARGP_DWORDDATA:
784    case ARGP_CHARLIST:
785    case ARGP_NAME:
786    case ARGP_NAMESTRING:
787
788        /* Constants, strings, and namestrings are all the same size */
789
790        Arg = AcpiPsAllocOp (AML_BYTE_OP);
791        if (!Arg)
792        {
793            return_ACPI_STATUS (AE_NO_MEMORY);
794        }
795        AcpiPsGetNextSimpleArg (ParserState, ArgType, Arg);
796        break;
797
798
799    case ARGP_PKGLENGTH:
800
801        /* Package length, nothing returned */
802
803        ParserState->PkgEnd = AcpiPsGetNextPackageEnd (ParserState);
804        break;
805
806
807    case ARGP_FIELDLIST:
808
809        if (ParserState->Aml < ParserState->PkgEnd)
810        {
811            /* Non-empty list */
812
813            while (ParserState->Aml < ParserState->PkgEnd)
814            {
815                Field = AcpiPsGetNextField (ParserState);
816                if (!Field)
817                {
818                    return_ACPI_STATUS (AE_NO_MEMORY);
819                }
820
821                if (Prev)
822                {
823                    Prev->Common.Next = Field;
824                }
825                else
826                {
827                    Arg = Field;
828                }
829                Prev = Field;
830            }
831
832            /* Skip to End of byte data */
833
834            ParserState->Aml = ParserState->PkgEnd;
835        }
836        break;
837
838
839    case ARGP_BYTELIST:
840
841        if (ParserState->Aml < ParserState->PkgEnd)
842        {
843            /* Non-empty list */
844
845            Arg = AcpiPsAllocOp (AML_INT_BYTELIST_OP);
846            if (!Arg)
847            {
848                return_ACPI_STATUS (AE_NO_MEMORY);
849            }
850
851            /* Fill in bytelist data */
852
853            Arg->Common.Value.Size = (UINT32)
854                ACPI_PTR_DIFF (ParserState->PkgEnd, ParserState->Aml);
855            Arg->Named.Data = ParserState->Aml;
856
857            /* Skip to End of byte data */
858
859            ParserState->Aml = ParserState->PkgEnd;
860        }
861        break;
862
863
864    case ARGP_TARGET:
865    case ARGP_SUPERNAME:
866    case ARGP_SIMPLENAME:
867
868        Subop = AcpiPsPeekOpcode (ParserState);
869        if (Subop == 0                  ||
870            AcpiPsIsLeadingChar (Subop) ||
871            AcpiPsIsPrefixChar (Subop))
872        {
873            /* NullName or NameString */
874
875            Arg = AcpiPsAllocOp (AML_INT_NAMEPATH_OP);
876            if (!Arg)
877            {
878                return_ACPI_STATUS (AE_NO_MEMORY);
879            }
880
881            /* To support SuperName arg of Unload */
882
883            if (WalkState->Opcode == AML_UNLOAD_OP)
884            {
885                Status = AcpiPsGetNextNamepath (WalkState, ParserState, Arg, 1);
886
887                /*
888                 * If the SuperName arg of Unload is a method call,
889                 * we have restored the AML pointer, just free this Arg
890                 */
891                if (Arg->Common.AmlOpcode == AML_INT_METHODCALL_OP)
892                {
893                    AcpiPsFreeOp (Arg);
894                    Arg = NULL;
895                }
896            }
897            else
898            {
899                Status = AcpiPsGetNextNamepath (WalkState, ParserState, Arg, 0);
900            }
901        }
902        else
903        {
904            /* Single complex argument, nothing returned */
905
906            WalkState->ArgCount = 1;
907        }
908        break;
909
910
911    case ARGP_DATAOBJ:
912    case ARGP_TERMARG:
913
914        /* Single complex argument, nothing returned */
915
916        WalkState->ArgCount = 1;
917        break;
918
919
920    case ARGP_DATAOBJLIST:
921    case ARGP_TERMLIST:
922    case ARGP_OBJLIST:
923
924        if (ParserState->Aml < ParserState->PkgEnd)
925        {
926            /* Non-empty list of variable arguments, nothing returned */
927
928            WalkState->ArgCount = ACPI_VAR_ARGS;
929        }
930        break;
931
932
933    default:
934
935        ACPI_ERROR ((AE_INFO, "Invalid ArgType: 0x%X", ArgType));
936        Status = AE_AML_OPERAND_TYPE;
937        break;
938    }
939
940    *ReturnArg = Arg;
941    return_ACPI_STATUS (Status);
942}
943