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