xref: /titanic_41/usr/src/uts/intel/io/acpica/parser/psargs.c (revision 24a1f0af9f770e0e795ef1fa1c6dece8dd8dc959)
1 /******************************************************************************
2  *
3  * Module Name: psargs - Parse AML opcode arguments
4  *              $Revision: 1.95 $
5  *
6  *****************************************************************************/
7 
8 /******************************************************************************
9  *
10  * 1. Copyright Notice
11  *
12  * Some or all of this work - Copyright (c) 1999 - 2008, 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 #include "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     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 
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     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 
496 void
497 AcpiPsGetNextSimpleArg (
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 
602 static ACPI_PARSE_OBJECT *
603 AcpiPsGetNextField (
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 
713 ACPI_STATUS
714 AcpiPsGetNextArg (
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