]> CyberLeo.Net >> Repos - FreeBSD/releng/7.2.git/blob - sys/contrib/dev/acpica/psargs.c
Create releng/7.2 from stable/7 in preparation for 7.2-RELEASE.
[FreeBSD/releng/7.2.git] / sys / contrib / dev / acpica / psargs.c
1 /******************************************************************************
2  *
3  * Module Name: psargs - Parse AML opcode arguments
4  *              $Revision: 1.92 $
5  *
6  *****************************************************************************/
7
8 /******************************************************************************
9  *
10  * 1. Copyright Notice
11  *
12  * Some or all of this work - Copyright (c) 1999 - 2007, Intel Corp.
13  * All rights reserved.
14  *
15  * 2. License
16  *
17  * 2.1. This is your license from Intel Corp. under its intellectual property
18  * rights.  You may have additional license terms from the party that provided
19  * you this software, covering your right to use that party's intellectual
20  * property rights.
21  *
22  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
23  * copy of the source code appearing in this file ("Covered Code") an
24  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25  * base code distributed originally by Intel ("Original Intel Code") to copy,
26  * make derivatives, distribute, use and display any portion of the Covered
27  * Code in any form, with the right to sublicense such rights; and
28  *
29  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30  * license (with the right to sublicense), under only those claims of Intel
31  * patents that are infringed by the Original Intel Code, to make, use, sell,
32  * offer to sell, and import the Covered Code and derivative works thereof
33  * solely to the minimum extent necessary to exercise the above copyright
34  * license, and in no event shall the patent license extend to any additions
35  * to or modifications of the Original Intel Code.  No other license or right
36  * is granted directly or by implication, estoppel or otherwise;
37  *
38  * The above copyright and patent license is granted only if the following
39  * conditions are met:
40  *
41  * 3. Conditions
42  *
43  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44  * Redistribution of source code of any substantial portion of the Covered
45  * Code or modification with rights to further distribute source must include
46  * the above Copyright Notice, the above License, this list of Conditions,
47  * and the following Disclaimer and Export Compliance provision.  In addition,
48  * Licensee must cause all Covered Code to which Licensee contributes to
49  * contain a file documenting the changes Licensee made to create that Covered
50  * Code and the date of any change.  Licensee must include in that file the
51  * documentation of any changes made by any predecessor Licensee.  Licensee
52  * must include a prominent statement that the modification is derived,
53  * directly or indirectly, from Original Intel Code.
54  *
55  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
56  * Redistribution of source code of any substantial portion of the Covered
57  * Code or modification without rights to further distribute source must
58  * include the following Disclaimer and Export Compliance provision in the
59  * documentation and/or other materials provided with distribution.  In
60  * addition, Licensee may not authorize further sublicense of source of any
61  * portion of the Covered Code, and must include terms to the effect that the
62  * license from Licensee to its licensee is limited to the intellectual
63  * property embodied in the software Licensee provides to its licensee, and
64  * not to intellectual property embodied in modifications its licensee may
65  * make.
66  *
67  * 3.3. Redistribution of Executable. Redistribution in executable form of any
68  * substantial portion of the Covered Code or modification must reproduce the
69  * above Copyright Notice, and the following Disclaimer and Export Compliance
70  * provision in the documentation and/or other materials provided with the
71  * distribution.
72  *
73  * 3.4. Intel retains all right, title, and interest in and to the Original
74  * Intel Code.
75  *
76  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
77  * Intel shall be used in advertising or otherwise to promote the sale, use or
78  * other dealings in products derived from or relating to the Covered Code
79  * without prior written authorization from Intel.
80  *
81  * 4. Disclaimer and Export Compliance
82  *
83  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
84  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
85  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
86  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
87  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
88  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
89  * PARTICULAR PURPOSE.
90  *
91  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
93  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
95  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
96  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
97  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
98  * LIMITED REMEDY.
99  *
100  * 4.3. Licensee shall not export, either directly or indirectly, any of this
101  * software or system incorporating such software without first obtaining any
102  * required license or other approval from the U. S. Department of Commerce or
103  * any other agency or department of the United States Government.  In the
104  * event Licensee exports any such software from the United States or
105  * re-exports any such software from a foreign destination, Licensee shall
106  * ensure that the distribution and export/re-export of the software is in
107  * compliance with all laws, regulations, orders, or other restrictions of the
108  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
109  * any of its subsidiaries will export/re-export any technical data, process,
110  * software, or service, directly or indirectly, to any country for which the
111  * United States government or any agency thereof requires an export license,
112  * other governmental approval, or letter of assurance, without first obtaining
113  * such license, approval or letter.
114  *
115  *****************************************************************************/
116
117 #define __PSARGS_C__
118
119 #include <contrib/dev/acpica/acpi.h>
120 #include <contrib/dev/acpica/acparser.h>
121 #include <contrib/dev/acpica/amlcode.h>
122 #include <contrib/dev/acpica/acnamesp.h>
123 #include <contrib/dev/acpica/acdispat.h>
124
125 #define _COMPONENT          ACPI_PARSER
126         ACPI_MODULE_NAME    ("psargs")
127
128 /* Local prototypes */
129
130 static UINT32
131 AcpiPsGetNextPackageLength (
132     ACPI_PARSE_STATE        *ParserState);
133
134 static ACPI_PARSE_OBJECT *
135 AcpiPsGetNextField (
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
153 static UINT32
154 AcpiPsGetNextPackageLength (
155     ACPI_PARSE_STATE        *ParserState)
156 {
157     UINT8                   *Aml = ParserState->Aml;
158     UINT32                  PackageLength = 0;
159     ACPI_NATIVE_UINT        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 += (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
210 UINT8 *
211 AcpiPsGetNextPackageEnd (
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
244 char *
245 AcpiPsGetNextNamestring (
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
325 ACPI_STATUS
326 AcpiPsGetNextNamepath (
327     ACPI_WALK_STATE         *WalkState,
328     ACPI_PARSE_STATE        *ParserState,
329     ACPI_PARSE_OBJECT       *Arg,
330     BOOLEAN                 PossibleMethodCall)
331 {
332     char                    *Path;
333     ACPI_PARSE_OBJECT       *NameOp;
334     ACPI_STATUS             Status;
335     ACPI_OPERAND_OBJECT     *MethodDesc;
336     ACPI_NAMESPACE_NODE     *Node;
337     ACPI_GENERIC_STATE      ScopeInfo;
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     /* Setup search scope info */
355
356     ScopeInfo.Scope.Node = NULL;
357     Node = ParserState->StartNode;
358     if (Node)
359     {
360         ScopeInfo.Scope.Node = Node;
361     }
362
363     /*
364      * Lookup the name in the internal namespace. We don't want to add
365      * anything new to the namespace here, however, so we use MODE_EXECUTE.
366      * Allow searching of the parent tree, but don't open a new scope -
367      * we just want to lookup the object (must be mode EXECUTE to perform
368      * the upsearch)
369      */
370     Status = AcpiNsLookup (&ScopeInfo, Path, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
371                 ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL, &Node);
372
373     /*
374      * If this name is a control method invocation, we must
375      * setup the method call
376      */
377     if (ACPI_SUCCESS (Status) &&
378         PossibleMethodCall &&
379         (Node->Type == ACPI_TYPE_METHOD))
380     {
381         /* This name is actually a control method invocation */
382
383         MethodDesc = AcpiNsGetAttachedObject (Node);
384         ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
385             "Control Method - %p Desc %p Path=%p\n", Node, MethodDesc, Path));
386
387         NameOp = AcpiPsAllocOp (AML_INT_NAMEPATH_OP);
388         if (!NameOp)
389         {
390             return_ACPI_STATUS (AE_NO_MEMORY);
391         }
392
393         /* Change Arg into a METHOD CALL and attach name to it */
394
395         AcpiPsInitOp (Arg, AML_INT_METHODCALL_OP);
396         NameOp->Common.Value.Name = Path;
397
398         /* Point METHODCALL/NAME to the METHOD Node */
399
400         NameOp->Common.Node = Node;
401         AcpiPsAppendArg (Arg, NameOp);
402
403         if (!MethodDesc)
404         {
405             ACPI_ERROR ((AE_INFO,
406                 "Control Method %p has no attached object",
407                 Node));
408             return_ACPI_STATUS (AE_AML_INTERNAL);
409         }
410
411         ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
412             "Control Method - %p Args %X\n",
413             Node, MethodDesc->Method.ParamCount));
414
415         /* Get the number of arguments to expect */
416
417         WalkState->ArgCount = MethodDesc->Method.ParamCount;
418         return_ACPI_STATUS (AE_OK);
419     }
420
421     /*
422      * Special handling if the name was not found during the lookup -
423      * some NotFound cases are allowed
424      */
425     if (Status == AE_NOT_FOUND)
426     {
427         /* 1) NotFound is ok during load pass 1/2 (allow forward references) */
428
429         if ((WalkState->ParseFlags & ACPI_PARSE_MODE_MASK) !=
430                 ACPI_PARSE_EXECUTE)
431         {
432             Status = AE_OK;
433         }
434
435         /* 2) NotFound during a CondRefOf(x) is ok by definition */
436
437         else if (WalkState->Op->Common.AmlOpcode == AML_COND_REF_OF_OP)
438         {
439             Status = AE_OK;
440         }
441
442         /*
443          * 3) NotFound while building a Package is ok at this point, we
444          * may flag as an error later if slack mode is not enabled.
445          * (Some ASL code depends on allowing this behavior)
446          */
447         else if ((Arg->Common.Parent) &&
448             ((Arg->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||
449              (Arg->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP)))
450         {
451             Status = AE_OK;
452         }
453     }
454
455     /* Final exception check (may have been changed from code above) */
456
457     if (ACPI_FAILURE (Status))
458     {
459         ACPI_ERROR_NAMESPACE (Path, Status);
460
461         if ((WalkState->ParseFlags & ACPI_PARSE_MODE_MASK) ==
462                 ACPI_PARSE_EXECUTE)
463         {
464             /* Report a control method execution error */
465
466             Status = AcpiDsMethodError (Status, WalkState);
467         }
468     }
469
470     /* Save the namepath */
471
472     Arg->Common.Value.Name = Path;
473     return_ACPI_STATUS (Status);
474 }
475
476
477 /*******************************************************************************
478  *
479  * FUNCTION:    AcpiPsGetNextSimpleArg
480  *
481  * PARAMETERS:  ParserState         - Current parser state object
482  *              ArgType             - The argument type (AML_*_ARG)
483  *              Arg                 - Where the argument is returned
484  *
485  * RETURN:      None
486  *
487  * DESCRIPTION: Get the next simple argument (constant, string, or namestring)
488  *
489  ******************************************************************************/
490
491 void
492 AcpiPsGetNextSimpleArg (
493     ACPI_PARSE_STATE        *ParserState,
494     UINT32                  ArgType,
495     ACPI_PARSE_OBJECT       *Arg)
496 {
497     UINT32                  Length;
498     UINT16                  Opcode;
499     UINT8                   *Aml = ParserState->Aml;
500
501
502     ACPI_FUNCTION_TRACE_U32 (PsGetNextSimpleArg, ArgType);
503
504
505     switch (ArgType)
506     {
507     case ARGP_BYTEDATA:
508
509         /* Get 1 byte from the AML stream */
510
511         Opcode = AML_BYTE_OP;
512         Arg->Common.Value.Integer = (ACPI_INTEGER) *Aml;
513         Length = 1;
514         break;
515
516
517     case ARGP_WORDDATA:
518
519         /* Get 2 bytes from the AML stream */
520
521         Opcode = AML_WORD_OP;
522         ACPI_MOVE_16_TO_64 (&Arg->Common.Value.Integer, Aml);
523         Length = 2;
524         break;
525
526
527     case ARGP_DWORDDATA:
528
529         /* Get 4 bytes from the AML stream */
530
531         Opcode = AML_DWORD_OP;
532         ACPI_MOVE_32_TO_64 (&Arg->Common.Value.Integer, Aml);
533         Length = 4;
534         break;
535
536
537     case ARGP_QWORDDATA:
538
539         /* Get 8 bytes from the AML stream */
540
541         Opcode = AML_QWORD_OP;
542         ACPI_MOVE_64_TO_64 (&Arg->Common.Value.Integer, Aml);
543         Length = 8;
544         break;
545
546
547     case ARGP_CHARLIST:
548
549         /* Get a pointer to the string, point past the string */
550
551         Opcode = AML_STRING_OP;
552         Arg->Common.Value.String = ACPI_CAST_PTR (char, Aml);
553
554         /* Find the null terminator */
555
556         Length = 0;
557         while (Aml[Length])
558         {
559             Length++;
560         }
561         Length++;
562         break;
563
564
565     case ARGP_NAME:
566     case ARGP_NAMESTRING:
567
568         AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP);
569         Arg->Common.Value.Name = AcpiPsGetNextNamestring (ParserState);
570         return_VOID;
571
572
573     default:
574
575         ACPI_ERROR ((AE_INFO, "Invalid ArgType %X", ArgType));
576         return_VOID;
577     }
578
579     AcpiPsInitOp (Arg, Opcode);
580     ParserState->Aml += Length;
581     return_VOID;
582 }
583
584
585 /*******************************************************************************
586  *
587  * FUNCTION:    AcpiPsGetNextField
588  *
589  * PARAMETERS:  ParserState         - Current parser state object
590  *
591  * RETURN:      A newly allocated FIELD op
592  *
593  * DESCRIPTION: Get next field (NamedField, ReservedField, or AccessField)
594  *
595  ******************************************************************************/
596
597 static ACPI_PARSE_OBJECT *
598 AcpiPsGetNextField (
599     ACPI_PARSE_STATE        *ParserState)
600 {
601     UINT32                  AmlOffset = (UINT32)
602                                 ACPI_PTR_DIFF (ParserState->Aml,
603                                                ParserState->AmlStart);
604     ACPI_PARSE_OBJECT       *Field;
605     UINT16                  Opcode;
606     UINT32                  Name;
607
608
609     ACPI_FUNCTION_TRACE (PsGetNextField);
610
611
612     /* Determine field type */
613
614     switch (ACPI_GET8 (ParserState->Aml))
615     {
616     default:
617
618         Opcode = AML_INT_NAMEDFIELD_OP;
619         break;
620
621     case 0x00:
622
623         Opcode = AML_INT_RESERVEDFIELD_OP;
624         ParserState->Aml++;
625         break;
626
627     case 0x01:
628
629         Opcode = AML_INT_ACCESSFIELD_OP;
630         ParserState->Aml++;
631         break;
632     }
633
634     /* Allocate a new field op */
635
636     Field = AcpiPsAllocOp (Opcode);
637     if (!Field)
638     {
639         return_PTR (NULL);
640     }
641
642     Field->Common.AmlOffset = AmlOffset;
643
644     /* Decode the field type */
645
646     switch (Opcode)
647     {
648     case AML_INT_NAMEDFIELD_OP:
649
650         /* Get the 4-character name */
651
652         ACPI_MOVE_32_TO_32 (&Name, ParserState->Aml);
653         AcpiPsSetName (Field, Name);
654         ParserState->Aml += ACPI_NAME_SIZE;
655
656         /* Get the length which is encoded as a package length */
657
658         Field->Common.Value.Size = AcpiPsGetNextPackageLength (ParserState);
659         break;
660
661
662     case AML_INT_RESERVEDFIELD_OP:
663
664         /* Get the length which is encoded as a package length */
665
666         Field->Common.Value.Size = AcpiPsGetNextPackageLength (ParserState);
667         break;
668
669
670     case AML_INT_ACCESSFIELD_OP:
671
672         /*
673          * Get AccessType and AccessAttrib and merge into the field Op
674          * AccessType is first operand, AccessAttribute is second
675          */
676         Field->Common.Value.Integer = (((UINT32) ACPI_GET8 (ParserState->Aml) << 8));
677         ParserState->Aml++;
678         Field->Common.Value.Integer |= ACPI_GET8 (ParserState->Aml);
679         ParserState->Aml++;
680         break;
681
682     default:
683
684         /* Opcode was set in previous switch */
685         break;
686     }
687
688     return_PTR (Field);
689 }
690
691
692 /*******************************************************************************
693  *
694  * FUNCTION:    AcpiPsGetNextArg
695  *
696  * PARAMETERS:  WalkState           - Current state
697  *              ParserState         - Current parser state object
698  *              ArgType             - The argument type (AML_*_ARG)
699  *              ReturnArg           - Where the next arg is returned
700  *
701  * RETURN:      Status, and an op object containing the next argument.
702  *
703  * DESCRIPTION: Get next argument (including complex list arguments that require
704  *              pushing the parser stack)
705  *
706  ******************************************************************************/
707
708 ACPI_STATUS
709 AcpiPsGetNextArg (
710     ACPI_WALK_STATE         *WalkState,
711     ACPI_PARSE_STATE        *ParserState,
712     UINT32                  ArgType,
713     ACPI_PARSE_OBJECT       **ReturnArg)
714 {
715     ACPI_PARSE_OBJECT       *Arg = NULL;
716     ACPI_PARSE_OBJECT       *Prev = NULL;
717     ACPI_PARSE_OBJECT       *Field;
718     UINT32                  Subop;
719     ACPI_STATUS             Status = AE_OK;
720
721
722     ACPI_FUNCTION_TRACE_PTR (PsGetNextArg, ParserState);
723
724
725     switch (ArgType)
726     {
727     case ARGP_BYTEDATA:
728     case ARGP_WORDDATA:
729     case ARGP_DWORDDATA:
730     case ARGP_CHARLIST:
731     case ARGP_NAME:
732     case ARGP_NAMESTRING:
733
734         /* Constants, strings, and namestrings are all the same size */
735
736         Arg = AcpiPsAllocOp (AML_BYTE_OP);
737         if (!Arg)
738         {
739             return_ACPI_STATUS (AE_NO_MEMORY);
740         }
741         AcpiPsGetNextSimpleArg (ParserState, ArgType, Arg);
742         break;
743
744
745     case ARGP_PKGLENGTH:
746
747         /* Package length, nothing returned */
748
749         ParserState->PkgEnd = AcpiPsGetNextPackageEnd (ParserState);
750         break;
751
752
753     case ARGP_FIELDLIST:
754
755         if (ParserState->Aml < ParserState->PkgEnd)
756         {
757             /* Non-empty list */
758
759             while (ParserState->Aml < ParserState->PkgEnd)
760             {
761                 Field = AcpiPsGetNextField (ParserState);
762                 if (!Field)
763                 {
764                     return_ACPI_STATUS (AE_NO_MEMORY);
765                 }
766
767                 if (Prev)
768                 {
769                     Prev->Common.Next = Field;
770                 }
771                 else
772                 {
773                     Arg = Field;
774                 }
775                 Prev = Field;
776             }
777
778             /* Skip to End of byte data */
779
780             ParserState->Aml = ParserState->PkgEnd;
781         }
782         break;
783
784
785     case ARGP_BYTELIST:
786
787         if (ParserState->Aml < ParserState->PkgEnd)
788         {
789             /* Non-empty list */
790
791             Arg = AcpiPsAllocOp (AML_INT_BYTELIST_OP);
792             if (!Arg)
793             {
794                 return_ACPI_STATUS (AE_NO_MEMORY);
795             }
796
797             /* Fill in bytelist data */
798
799             Arg->Common.Value.Size = (UINT32)
800                 ACPI_PTR_DIFF (ParserState->PkgEnd, ParserState->Aml);
801             Arg->Named.Data = ParserState->Aml;
802
803             /* Skip to End of byte data */
804
805             ParserState->Aml = ParserState->PkgEnd;
806         }
807         break;
808
809
810     case ARGP_TARGET:
811     case ARGP_SUPERNAME:
812     case ARGP_SIMPLENAME:
813
814         Subop = AcpiPsPeekOpcode (ParserState);
815         if (Subop == 0                  ||
816             AcpiPsIsLeadingChar (Subop) ||
817             AcpiPsIsPrefixChar (Subop))
818         {
819             /* NullName or NameString */
820
821             Arg = AcpiPsAllocOp (AML_INT_NAMEPATH_OP);
822             if (!Arg)
823             {
824                 return_ACPI_STATUS (AE_NO_MEMORY);
825             }
826
827             Status = AcpiPsGetNextNamepath (WalkState, ParserState, Arg, 0);
828         }
829         else
830         {
831             /* Single complex argument, nothing returned */
832
833             WalkState->ArgCount = 1;
834         }
835         break;
836
837
838     case ARGP_DATAOBJ:
839     case ARGP_TERMARG:
840
841         /* Single complex argument, nothing returned */
842
843         WalkState->ArgCount = 1;
844         break;
845
846
847     case ARGP_DATAOBJLIST:
848     case ARGP_TERMLIST:
849     case ARGP_OBJLIST:
850
851         if (ParserState->Aml < ParserState->PkgEnd)
852         {
853             /* Non-empty list of variable arguments, nothing returned */
854
855             WalkState->ArgCount = ACPI_VAR_ARGS;
856         }
857         break;
858
859
860     default:
861
862         ACPI_ERROR ((AE_INFO, "Invalid ArgType: %X", ArgType));
863         Status = AE_AML_OPERAND_TYPE;
864         break;
865     }
866
867     *ReturnArg = Arg;
868     return_ACPI_STATUS (Status);
869 }