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