]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/contrib/dev/acpica/psargs.c
This commit was generated by cvs2svn to compensate for changes in r153872,
[FreeBSD/FreeBSD.git] / sys / contrib / dev / acpica / psargs.c
1 /******************************************************************************
2  *
3  * Module Name: psargs - Parse AML opcode arguments
4  *              $Revision: 1.81 $
5  *
6  *****************************************************************************/
7
8 /******************************************************************************
9  *
10  * 1. Copyright Notice
11  *
12  * Some or all of this work - Copyright (c) 1999 - 2005, 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
124 #define _COMPONENT          ACPI_PARSER
125         ACPI_MODULE_NAME    ("psargs")
126
127 /* Local prototypes */
128
129 static UINT32
130 AcpiPsGetNextPackageLength (
131     ACPI_PARSE_STATE        *ParserState);
132
133 static ACPI_PARSE_OBJECT *
134 AcpiPsGetNextField (
135     ACPI_PARSE_STATE        *ParserState);
136
137
138 /*******************************************************************************
139  *
140  * FUNCTION:    AcpiPsGetNextPackageLength
141  *
142  * PARAMETERS:  ParserState         - Current parser state object
143  *
144  * RETURN:      Decoded package length.  On completion, the AML pointer points
145  *              past the length byte or bytes.
146  *
147  * DESCRIPTION: Decode and return a package length field
148  *
149  ******************************************************************************/
150
151 static UINT32
152 AcpiPsGetNextPackageLength (
153     ACPI_PARSE_STATE        *ParserState)
154 {
155     UINT32                  EncodedLength;
156     UINT32                  Length = 0;
157
158
159     ACPI_FUNCTION_TRACE ("PsGetNextPackageLength");
160
161
162     EncodedLength = (UINT32) ACPI_GET8 (ParserState->Aml);
163     ParserState->Aml++;
164
165     switch (EncodedLength >> 6) /* bits 6-7 contain encoding scheme */
166     {
167     case 0: /* 1-byte encoding (bits 0-5) */
168
169         Length = (EncodedLength & 0x3F);
170         break;
171
172
173     case 1: /* 2-byte encoding (next byte + bits 0-3) */
174
175         Length = ((ACPI_GET8 (ParserState->Aml) << 04) |
176                  (EncodedLength & 0x0F));
177         ParserState->Aml++;
178         break;
179
180
181     case 2: /* 3-byte encoding (next 2 bytes + bits 0-3) */
182
183         Length = ((ACPI_GET8 (ParserState->Aml + 1) << 12) |
184                   (ACPI_GET8 (ParserState->Aml)     << 04) |
185                   (EncodedLength & 0x0F));
186         ParserState->Aml += 2;
187         break;
188
189
190     case 3: /* 4-byte encoding (next 3 bytes + bits 0-3) */
191
192         Length = ((ACPI_GET8 (ParserState->Aml + 2) << 20) |
193                   (ACPI_GET8 (ParserState->Aml + 1) << 12) |
194                   (ACPI_GET8 (ParserState->Aml)     << 04) |
195                   (EncodedLength & 0x0F));
196         ParserState->Aml += 3;
197         break;
198
199     default:
200
201         /* Can't get here, only 2 bits / 4 cases */
202         break;
203     }
204
205     return_UINT32 (Length);
206 }
207
208
209 /*******************************************************************************
210  *
211  * FUNCTION:    AcpiPsGetNextPackageEnd
212  *
213  * PARAMETERS:  ParserState         - Current parser state object
214  *
215  * RETURN:      Pointer to end-of-package +1
216  *
217  * DESCRIPTION: Get next package length and return a pointer past the end of
218  *              the package.  Consumes the package length field
219  *
220  ******************************************************************************/
221
222 UINT8 *
223 AcpiPsGetNextPackageEnd (
224     ACPI_PARSE_STATE        *ParserState)
225 {
226     UINT8                   *Start = ParserState->Aml;
227     ACPI_NATIVE_UINT        Length;
228
229
230     ACPI_FUNCTION_TRACE ("PsGetNextPackageEnd");
231
232
233     /* Function below changes ParserState->Aml */
234
235     Length = (ACPI_NATIVE_UINT) AcpiPsGetNextPackageLength (ParserState);
236
237     return_PTR (Start + Length); /* end of package */
238 }
239
240
241 /*******************************************************************************
242  *
243  * FUNCTION:    AcpiPsGetNextNamestring
244  *
245  * PARAMETERS:  ParserState         - Current parser state object
246  *
247  * RETURN:      Pointer to the start of the name string (pointer points into
248  *              the AML.
249  *
250  * DESCRIPTION: Get next raw namestring within the AML stream.  Handles all name
251  *              prefix characters.  Set parser state to point past the string.
252  *              (Name is consumed from the AML.)
253  *
254  ******************************************************************************/
255
256 char *
257 AcpiPsGetNextNamestring (
258     ACPI_PARSE_STATE        *ParserState)
259 {
260     UINT8                   *Start = ParserState->Aml;
261     UINT8                   *End = ParserState->Aml;
262
263
264     ACPI_FUNCTION_TRACE ("PsGetNextNamestring");
265
266
267     /* Handle multiple prefix characters */
268
269     while (AcpiPsIsPrefixChar (ACPI_GET8 (End)))
270     {
271         /* Include prefix '\\' or '^' */
272
273         End++;
274     }
275
276     /* Decode the path */
277
278     switch (ACPI_GET8 (End))
279     {
280     case 0:
281
282         /* NullName */
283
284         if (End == Start)
285         {
286             Start = NULL;
287         }
288         End++;
289         break;
290
291     case AML_DUAL_NAME_PREFIX:
292
293         /* Two name segments */
294
295         End += 1 + (2 * ACPI_NAME_SIZE);
296         break;
297
298     case AML_MULTI_NAME_PREFIX_OP:
299
300         /* Multiple name segments, 4 chars each */
301
302         End += 2 + ((ACPI_SIZE) ACPI_GET8 (End + 1) * ACPI_NAME_SIZE);
303         break;
304
305     default:
306
307         /* Single name segment */
308
309         End += ACPI_NAME_SIZE;
310         break;
311     }
312
313     ParserState->Aml = (UINT8*) End;
314     return_PTR ((char *) Start);
315 }
316
317
318 /*******************************************************************************
319  *
320  * FUNCTION:    AcpiPsGetNextNamepath
321  *
322  * PARAMETERS:  ParserState         - Current parser state object
323  *              Arg                 - Where the namepath will be stored
324  *              ArgCount            - If the namepath points to a control method
325  *                                    the method's argument is returned here.
326  *              MethodCall          - Whether the namepath can possibly be the
327  *                                    start of a method call
328  *
329  * RETURN:      Status
330  *
331  * DESCRIPTION: Get next name (if method call, return # of required args).
332  *              Names are looked up in the internal namespace to determine
333  *              if the name represents a control method.  If a method
334  *              is found, the number of arguments to the method is returned.
335  *              This information is critical for parsing to continue correctly.
336  *
337  ******************************************************************************/
338
339 ACPI_STATUS
340 AcpiPsGetNextNamepath (
341     ACPI_WALK_STATE         *WalkState,
342     ACPI_PARSE_STATE        *ParserState,
343     ACPI_PARSE_OBJECT       *Arg,
344     BOOLEAN                 MethodCall)
345 {
346     char                    *Path;
347     ACPI_PARSE_OBJECT       *NameOp;
348     ACPI_STATUS             Status = AE_OK;
349     ACPI_OPERAND_OBJECT     *MethodDesc;
350     ACPI_NAMESPACE_NODE     *Node;
351     ACPI_GENERIC_STATE      ScopeInfo;
352
353
354     ACPI_FUNCTION_TRACE ("PsGetNextNamepath");
355
356
357     Path = AcpiPsGetNextNamestring (ParserState);
358
359     /* Null path case is allowed */
360
361     if (Path)
362     {
363         /*
364          * Lookup the name in the internal namespace
365          */
366         ScopeInfo.Scope.Node = NULL;
367         Node = ParserState->StartNode;
368         if (Node)
369         {
370             ScopeInfo.Scope.Node = Node;
371         }
372
373         /*
374          * Lookup object.  We don't want to add anything new to the namespace
375          * here, however.  So we use MODE_EXECUTE.  Allow searching of the
376          * parent tree, but don't open a new scope -- we just want to lookup the
377          * object  (MUST BE mode EXECUTE to perform upsearch)
378          */
379         Status = AcpiNsLookup (&ScopeInfo, Path, ACPI_TYPE_ANY,
380                     ACPI_IMODE_EXECUTE,
381                     ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
382                     NULL, &Node);
383         if (ACPI_SUCCESS (Status) && MethodCall)
384         {
385             if (Node->Type == ACPI_TYPE_METHOD)
386             {
387                 /* This name is actually a control method invocation */
388
389                 MethodDesc = AcpiNsGetAttachedObject (Node);
390                 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
391                     "Control Method - %p Desc %p Path=%p\n",
392                     Node, MethodDesc, Path));
393
394                 NameOp = AcpiPsAllocOp (AML_INT_NAMEPATH_OP);
395                 if (!NameOp)
396                 {
397                     return_ACPI_STATUS (AE_NO_MEMORY);
398                 }
399
400                 /* Change arg into a METHOD CALL and attach name to it */
401
402                 AcpiPsInitOp (Arg, AML_INT_METHODCALL_OP);
403                 NameOp->Common.Value.Name = Path;
404
405                 /* Point METHODCALL/NAME to the METHOD Node */
406
407                 NameOp->Common.Node = Node;
408                 AcpiPsAppendArg (Arg, NameOp);
409
410                 if (!MethodDesc)
411                 {
412                     ACPI_REPORT_ERROR ((
413                         "PsGetNextNamepath: Control Method %p has no attached object\n",
414                         Node));
415                     return_ACPI_STATUS (AE_AML_INTERNAL);
416                 }
417
418                 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
419                     "Control Method - %p Args %X\n",
420                     Node, MethodDesc->Method.ParamCount));
421
422                 /* Get the number of arguments to expect */
423
424                 WalkState->ArgCount = MethodDesc->Method.ParamCount;
425                 return_ACPI_STATUS (AE_OK);
426             }
427
428             /*
429              * Else this is normal named object reference.
430              * Just init the NAMEPATH object with the pathname.
431              * (See code below)
432              */
433         }
434
435         if (ACPI_FAILURE (Status))
436         {
437             /*
438              * 1) Any error other than NOT_FOUND is always severe
439              * 2) NOT_FOUND is only important if we are executing a method.
440              * 3) If executing a CondRefOf opcode, NOT_FOUND is ok.
441              */
442             if ((((WalkState->ParseFlags & ACPI_PARSE_MODE_MASK) == ACPI_PARSE_EXECUTE) &&
443                 (Status == AE_NOT_FOUND)                                                &&
444                 (WalkState->Op->Common.AmlOpcode != AML_COND_REF_OF_OP)) ||
445
446                 (Status != AE_NOT_FOUND))
447             {
448                 ACPI_REPORT_NSERROR (Path, Status);
449
450                 AcpiOsPrintf ("SearchNode %p StartNode %p ReturnNode %p\n",
451                     ScopeInfo.Scope.Node, ParserState->StartNode, Node);
452
453
454             }
455             else
456             {
457                 /*
458                  * We got a NOT_FOUND during table load or we encountered
459                  * a CondRefOf(x) where the target does not exist.
460                  * Either case is ok
461                  */
462                 Status = AE_OK;
463             }
464         }
465     }
466
467     /*
468      * Regardless of success/failure above,
469      * Just initialize the Op with the pathname.
470      */
471     AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP);
472     Arg->Common.Value.Name = Path;
473
474     return_ACPI_STATUS (Status);
475 }
476
477
478 /*******************************************************************************
479  *
480  * FUNCTION:    AcpiPsGetNextSimpleArg
481  *
482  * PARAMETERS:  ParserState         - Current parser state object
483  *              ArgType             - The argument type (AML_*_ARG)
484  *              Arg                 - Where the argument is returned
485  *
486  * RETURN:      None
487  *
488  * DESCRIPTION: Get the next simple argument (constant, string, or namestring)
489  *
490  ******************************************************************************/
491
492 void
493 AcpiPsGetNextSimpleArg (
494     ACPI_PARSE_STATE        *ParserState,
495     UINT32                  ArgType,
496     ACPI_PARSE_OBJECT       *Arg)
497 {
498
499     ACPI_FUNCTION_TRACE_U32 ("PsGetNextSimpleArg", ArgType);
500
501
502     switch (ArgType)
503     {
504     case ARGP_BYTEDATA:
505
506         AcpiPsInitOp (Arg, AML_BYTE_OP);
507         Arg->Common.Value.Integer = (UINT32) ACPI_GET8 (ParserState->Aml);
508         ParserState->Aml++;
509         break;
510
511
512     case ARGP_WORDDATA:
513
514         AcpiPsInitOp (Arg, AML_WORD_OP);
515
516         /* Get 2 bytes from the AML stream */
517
518         ACPI_MOVE_16_TO_32 (&Arg->Common.Value.Integer, ParserState->Aml);
519         ParserState->Aml += 2;
520         break;
521
522
523     case ARGP_DWORDDATA:
524
525         AcpiPsInitOp (Arg, AML_DWORD_OP);
526
527         /* Get 4 bytes from the AML stream */
528
529         ACPI_MOVE_32_TO_32 (&Arg->Common.Value.Integer, ParserState->Aml);
530         ParserState->Aml += 4;
531         break;
532
533
534     case ARGP_QWORDDATA:
535
536         AcpiPsInitOp (Arg, AML_QWORD_OP);
537
538         /* Get 8 bytes from the AML stream */
539
540         ACPI_MOVE_64_TO_64 (&Arg->Common.Value.Integer, ParserState->Aml);
541         ParserState->Aml += 8;
542         break;
543
544
545     case ARGP_CHARLIST:
546
547         AcpiPsInitOp (Arg, AML_STRING_OP);
548         Arg->Common.Value.String = (char *) ParserState->Aml;
549
550         while (ACPI_GET8 (ParserState->Aml) != '\0')
551         {
552             ParserState->Aml++;
553         }
554         ParserState->Aml++;
555         break;
556
557
558     case ARGP_NAME:
559     case ARGP_NAMESTRING:
560
561         AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP);
562         Arg->Common.Value.Name = AcpiPsGetNextNamestring (ParserState);
563         break;
564
565
566     default:
567
568         ACPI_REPORT_ERROR (("Invalid ArgType %X\n", ArgType));
569         break;
570     }
571
572     return_VOID;
573 }
574
575
576 /*******************************************************************************
577  *
578  * FUNCTION:    AcpiPsGetNextField
579  *
580  * PARAMETERS:  ParserState         - Current parser state object
581  *
582  * RETURN:      A newly allocated FIELD op
583  *
584  * DESCRIPTION: Get next field (NamedField, ReservedField, or AccessField)
585  *
586  ******************************************************************************/
587
588 static ACPI_PARSE_OBJECT *
589 AcpiPsGetNextField (
590     ACPI_PARSE_STATE        *ParserState)
591 {
592     UINT32                  AmlOffset = (UINT32)
593                                 ACPI_PTR_DIFF (ParserState->Aml,
594                                                ParserState->AmlStart);
595     ACPI_PARSE_OBJECT       *Field;
596     UINT16                  Opcode;
597     UINT32                  Name;
598
599
600     ACPI_FUNCTION_TRACE ("PsGetNextField");
601
602
603     /* Determine field type */
604
605     switch (ACPI_GET8 (ParserState->Aml))
606     {
607     default:
608
609         Opcode = AML_INT_NAMEDFIELD_OP;
610         break;
611
612     case 0x00:
613
614         Opcode = AML_INT_RESERVEDFIELD_OP;
615         ParserState->Aml++;
616         break;
617
618     case 0x01:
619
620         Opcode = AML_INT_ACCESSFIELD_OP;
621         ParserState->Aml++;
622         break;
623     }
624
625     /* Allocate a new field op */
626
627     Field = AcpiPsAllocOp (Opcode);
628     if (!Field)
629     {
630         return_PTR (NULL);
631     }
632
633     Field->Common.AmlOffset = AmlOffset;
634
635     /* Decode the field type */
636
637     switch (Opcode)
638     {
639     case AML_INT_NAMEDFIELD_OP:
640
641         /* Get the 4-character name */
642
643         ACPI_MOVE_32_TO_32 (&Name, ParserState->Aml);
644         AcpiPsSetName (Field, Name);
645         ParserState->Aml += ACPI_NAME_SIZE;
646
647         /* Get the length which is encoded as a package length */
648
649         Field->Common.Value.Size = AcpiPsGetNextPackageLength (ParserState);
650         break;
651
652
653     case AML_INT_RESERVEDFIELD_OP:
654
655         /* Get the length which is encoded as a package length */
656
657         Field->Common.Value.Size = AcpiPsGetNextPackageLength (ParserState);
658         break;
659
660
661     case AML_INT_ACCESSFIELD_OP:
662
663         /*
664          * Get AccessType and AccessAttrib and merge into the field Op
665          * AccessType is first operand, AccessAttribute is second
666          */
667         Field->Common.Value.Integer = (ACPI_GET8 (ParserState->Aml) << 8);
668         ParserState->Aml++;
669         Field->Common.Value.Integer |= ACPI_GET8 (ParserState->Aml);
670         ParserState->Aml++;
671         break;
672
673     default:
674
675         /* Opcode was set in previous switch */
676         break;
677     }
678
679     return_PTR (Field);
680 }
681
682
683 /*******************************************************************************
684  *
685  * FUNCTION:    AcpiPsGetNextArg
686  *
687  * PARAMETERS:  WalkState           - Current state
688  *              ParserState         - Current parser state object
689  *              ArgType             - The argument type (AML_*_ARG)
690  *              ReturnArg           - Where the next arg is returned
691  *
692  * RETURN:      Status, and an op object containing the next argument.
693  *
694  * DESCRIPTION: Get next argument (including complex list arguments that require
695  *              pushing the parser stack)
696  *
697  ******************************************************************************/
698
699 ACPI_STATUS
700 AcpiPsGetNextArg (
701     ACPI_WALK_STATE         *WalkState,
702     ACPI_PARSE_STATE        *ParserState,
703     UINT32                  ArgType,
704     ACPI_PARSE_OBJECT       **ReturnArg)
705 {
706     ACPI_PARSE_OBJECT       *Arg = NULL;
707     ACPI_PARSE_OBJECT       *Prev = NULL;
708     ACPI_PARSE_OBJECT       *Field;
709     UINT32                  Subop;
710     ACPI_STATUS             Status = AE_OK;
711
712
713     ACPI_FUNCTION_TRACE_PTR ("PsGetNextArg", ParserState);
714
715
716     switch (ArgType)
717     {
718     case ARGP_BYTEDATA:
719     case ARGP_WORDDATA:
720     case ARGP_DWORDDATA:
721     case ARGP_CHARLIST:
722     case ARGP_NAME:
723     case ARGP_NAMESTRING:
724
725         /* Constants, strings, and namestrings are all the same size */
726
727         Arg = AcpiPsAllocOp (AML_BYTE_OP);
728         if (!Arg)
729         {
730             return_ACPI_STATUS (AE_NO_MEMORY);
731         }
732         AcpiPsGetNextSimpleArg (ParserState, ArgType, Arg);
733         break;
734
735
736     case ARGP_PKGLENGTH:
737
738         /* Package length, nothing returned */
739
740         ParserState->PkgEnd = AcpiPsGetNextPackageEnd (ParserState);
741         break;
742
743
744     case ARGP_FIELDLIST:
745
746         if (ParserState->Aml < ParserState->PkgEnd)
747         {
748             /* Non-empty list */
749
750             while (ParserState->Aml < ParserState->PkgEnd)
751             {
752                 Field = AcpiPsGetNextField (ParserState);
753                 if (!Field)
754                 {
755                     return_ACPI_STATUS (AE_NO_MEMORY);
756                 }
757
758                 if (Prev)
759                 {
760                     Prev->Common.Next = Field;
761                 }
762                 else
763                 {
764                     Arg = Field;
765                 }
766                 Prev = Field;
767             }
768
769             /* Skip to End of byte data */
770
771             ParserState->Aml = ParserState->PkgEnd;
772         }
773         break;
774
775
776     case ARGP_BYTELIST:
777
778         if (ParserState->Aml < ParserState->PkgEnd)
779         {
780             /* Non-empty list */
781
782             Arg = AcpiPsAllocOp (AML_INT_BYTELIST_OP);
783             if (!Arg)
784             {
785                 return_ACPI_STATUS (AE_NO_MEMORY);
786             }
787
788             /* Fill in bytelist data */
789
790             Arg->Common.Value.Size = (UINT32)
791                 ACPI_PTR_DIFF (ParserState->PkgEnd, ParserState->Aml);
792             Arg->Named.Data = ParserState->Aml;
793
794             /* Skip to End of byte data */
795
796             ParserState->Aml = ParserState->PkgEnd;
797         }
798         break;
799
800
801     case ARGP_TARGET:
802     case ARGP_SUPERNAME:
803     case ARGP_SIMPLENAME:
804
805         Subop = AcpiPsPeekOpcode (ParserState);
806         if (Subop == 0                  ||
807             AcpiPsIsLeadingChar (Subop) ||
808             AcpiPsIsPrefixChar (Subop))
809         {
810             /* NullName or NameString */
811
812             Arg = AcpiPsAllocOp (AML_INT_NAMEPATH_OP);
813             if (!Arg)
814             {
815                 return_ACPI_STATUS (AE_NO_MEMORY);
816             }
817
818             Status = AcpiPsGetNextNamepath (WalkState, ParserState, Arg, 0);
819         }
820         else
821         {
822             /* Single complex argument, nothing returned */
823
824             WalkState->ArgCount = 1;
825         }
826         break;
827
828
829     case ARGP_DATAOBJ:
830     case ARGP_TERMARG:
831
832         /* Single complex argument, nothing returned */
833
834         WalkState->ArgCount = 1;
835         break;
836
837
838     case ARGP_DATAOBJLIST:
839     case ARGP_TERMLIST:
840     case ARGP_OBJLIST:
841
842         if (ParserState->Aml < ParserState->PkgEnd)
843         {
844             /* Non-empty list of variable arguments, nothing returned */
845
846             WalkState->ArgCount = ACPI_VAR_ARGS;
847         }
848         break;
849
850
851     default:
852
853         ACPI_REPORT_ERROR (("Invalid ArgType: %X\n", ArgType));
854         Status = AE_AML_OPERAND_TYPE;
855         break;
856     }
857
858     *ReturnArg = Arg;
859     return_ACPI_STATUS (Status);
860 }