xref: /netbsd-src/sys/external/bsd/acpica/dist/parser/psargs.c (revision c7960b37466ae0fd417c32e6acbb4b956ac7a121)
1 /******************************************************************************
2  *
3  * Module Name: psargs - Parse AML opcode arguments
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2023, Intel Corp.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions, and the following disclaimer,
16  *    without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  *    substantially similar to the "NO WARRANTY" disclaimer below
19  *    ("Disclaimer") and any redistribution must be conditioned upon
20  *    including a substantially similar Disclaimer requirement for further
21  *    binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  *    of any contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43 
44 #include "acpi.h"
45 #include "accommon.h"
46 #include "acparser.h"
47 #include "amlcode.h"
48 #include "acnamesp.h"
49 #include "acdispat.h"
50 #include "acconvert.h"
51 
52 #define _COMPONENT          ACPI_PARSER
53         ACPI_MODULE_NAME    ("psargs")
54 
55 /* Local prototypes */
56 
57 static UINT32
58 AcpiPsGetNextPackageLength (
59     ACPI_PARSE_STATE        *ParserState);
60 
61 static ACPI_PARSE_OBJECT *
62 AcpiPsGetNextField (
63     ACPI_PARSE_STATE        *ParserState);
64 
65 static void
66 AcpiPsFreeFieldList (
67     ACPI_PARSE_OBJECT       *Start);
68 
69 
70 /*******************************************************************************
71  *
72  * FUNCTION:    AcpiPsGetNextPackageLength
73  *
74  * PARAMETERS:  ParserState         - Current parser state object
75  *
76  * RETURN:      Decoded package length. On completion, the AML pointer points
77  *              past the length byte or bytes.
78  *
79  * DESCRIPTION: Decode and return a package length field.
80  *              Note: Largest package length is 28 bits, from ACPI specification
81  *
82  ******************************************************************************/
83 
84 static UINT32
85 AcpiPsGetNextPackageLength (
86     ACPI_PARSE_STATE        *ParserState)
87 {
88     UINT8                   *Aml = ParserState->Aml;
89     UINT32                  PackageLength = 0;
90     UINT32                  ByteCount;
91     UINT8                   ByteZeroMask = 0x3F; /* Default [0:5] */
92 
93 
94     ACPI_FUNCTION_TRACE (PsGetNextPackageLength);
95 
96 
97     /*
98      * Byte 0 bits [6:7] contain the number of additional bytes
99      * used to encode the package length, either 0,1,2, or 3
100      */
101     ByteCount = (Aml[0] >> 6);
102     ParserState->Aml += ((ACPI_SIZE) ByteCount + 1);
103 
104     /* Get bytes 3, 2, 1 as needed */
105 
106     while (ByteCount)
107     {
108         /*
109          * Final bit positions for the package length bytes:
110          *      Byte3->[20:27]
111          *      Byte2->[12:19]
112          *      Byte1->[04:11]
113          *      Byte0->[00:03]
114          */
115         PackageLength |= (Aml[ByteCount] << ((ByteCount << 3) - 4));
116 
117         ByteZeroMask = 0x0F; /* Use bits [0:3] of byte 0 */
118         ByteCount--;
119     }
120 
121     /* Byte 0 is a special case, either bits [0:3] or [0:5] are used */
122 
123     PackageLength |= (Aml[0] & ByteZeroMask);
124     return_UINT32 (PackageLength);
125 }
126 
127 
128 /*******************************************************************************
129  *
130  * FUNCTION:    AcpiPsGetNextPackageEnd
131  *
132  * PARAMETERS:  ParserState         - Current parser state object
133  *
134  * RETURN:      Pointer to end-of-package +1
135  *
136  * DESCRIPTION: Get next package length and return a pointer past the end of
137  *              the package. Consumes the package length field
138  *
139  ******************************************************************************/
140 
141 UINT8 *
142 AcpiPsGetNextPackageEnd (
143     ACPI_PARSE_STATE        *ParserState)
144 {
145     UINT8                   *Start = ParserState->Aml;
146     UINT32                  PackageLength;
147 
148 
149     ACPI_FUNCTION_TRACE (PsGetNextPackageEnd);
150 
151 
152     /* Function below updates ParserState->Aml */
153 
154     PackageLength = AcpiPsGetNextPackageLength (ParserState);
155 
156     return_PTR (Start + PackageLength); /* end of package */
157 }
158 
159 
160 /*******************************************************************************
161  *
162  * FUNCTION:    AcpiPsGetNextNamestring
163  *
164  * PARAMETERS:  ParserState         - Current parser state object
165  *
166  * RETURN:      Pointer to the start of the name string (pointer points into
167  *              the AML.
168  *
169  * DESCRIPTION: Get next raw namestring within the AML stream. Handles all name
170  *              prefix characters. Set parser state to point past the string.
171  *              (Name is consumed from the AML.)
172  *
173  ******************************************************************************/
174 
175 char *
176 AcpiPsGetNextNamestring (
177     ACPI_PARSE_STATE        *ParserState)
178 {
179     UINT8                   *Start = ParserState->Aml;
180     UINT8                   *End = ParserState->Aml;
181 
182 
183     ACPI_FUNCTION_TRACE (PsGetNextNamestring);
184 
185 
186     /* Point past any namestring prefix characters (backslash or carat) */
187 
188     while (ACPI_IS_ROOT_PREFIX (*End) ||
189            ACPI_IS_PARENT_PREFIX (*End))
190     {
191         End++;
192     }
193 
194     /* Decode the path prefix character */
195 
196     switch (*End)
197     {
198     case 0:
199 
200         /* NullName */
201 
202         if (End == Start)
203         {
204             Start = NULL;
205         }
206         End++;
207         break;
208 
209     case AML_DUAL_NAME_PREFIX:
210 
211         /* Two name segments */
212 
213         End += 1 + (2 * ACPI_NAMESEG_SIZE);
214         break;
215 
216     case AML_MULTI_NAME_PREFIX:
217 
218         /* Multiple name segments, 4 chars each, count in next byte */
219 
220         End += 2 + (*(End + 1) * ACPI_NAMESEG_SIZE);
221         break;
222 
223     default:
224 
225         /* Single name segment */
226 
227         End += ACPI_NAMESEG_SIZE;
228         break;
229     }
230 
231     ParserState->Aml = End;
232     return_PTR ((char *) Start);
233 }
234 
235 
236 /*******************************************************************************
237  *
238  * FUNCTION:    AcpiPsGetNextNamepath
239  *
240  * PARAMETERS:  ParserState         - Current parser state object
241  *              Arg                 - Where the namepath will be stored
242  *              ArgCount            - If the namepath points to a control method
243  *                                    the method's argument is returned here.
244  *              PossibleMethodCall  - Whether the namepath can possibly be the
245  *                                    start of a method call
246  *
247  * RETURN:      Status
248  *
249  * DESCRIPTION: Get next name (if method call, return # of required args).
250  *              Names are looked up in the internal namespace to determine
251  *              if the name represents a control method. If a method
252  *              is found, the number of arguments to the method is returned.
253  *              This information is critical for parsing to continue correctly.
254  *
255  ******************************************************************************/
256 
257 ACPI_STATUS
258 AcpiPsGetNextNamepath (
259     ACPI_WALK_STATE         *WalkState,
260     ACPI_PARSE_STATE        *ParserState,
261     ACPI_PARSE_OBJECT       *Arg,
262     BOOLEAN                 PossibleMethodCall)
263 {
264     ACPI_STATUS             Status;
265     char                    *Path;
266     ACPI_PARSE_OBJECT       *NameOp;
267     ACPI_OPERAND_OBJECT     *MethodDesc;
268     ACPI_NAMESPACE_NODE     *Node;
269     UINT8                   *Start = ParserState->Aml;
270 
271 
272     ACPI_FUNCTION_TRACE (PsGetNextNamepath);
273 
274 
275     Path = AcpiPsGetNextNamestring (ParserState);
276     AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP);
277 
278     /* Null path case is allowed, just exit */
279 
280     if (!Path)
281     {
282         Arg->Common.Value.Name = Path;
283         return_ACPI_STATUS (AE_OK);
284     }
285 
286     /*
287      * Lookup the name in the internal namespace, starting with the current
288      * scope. We don't want to add anything new to the namespace here,
289      * however, so we use MODE_EXECUTE.
290      * Allow searching of the parent tree, but don't open a new scope -
291      * we just want to lookup the object (must be mode EXECUTE to perform
292      * the upsearch)
293      */
294     Status = AcpiNsLookup (WalkState->ScopeInfo, Path,
295         ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
296         ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL, &Node);
297 
298     /*
299      * If this name is a control method invocation, we must
300      * setup the method call
301      */
302     if (ACPI_SUCCESS (Status) &&
303         PossibleMethodCall &&
304         (Node->Type == ACPI_TYPE_METHOD))
305     {
306         if ((GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) == ARGP_SUPERNAME) ||
307             (GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) == ARGP_TARGET))
308         {
309             /*
310              * AcpiPsGetNextNamestring has increased the AML pointer past
311              * the method invocation namestring, so we need to restore the
312              * saved AML pointer back to the original method invocation
313              * namestring.
314              */
315             WalkState->ParserState.Aml = Start;
316             WalkState->ArgCount = 1;
317             AcpiPsInitOp (Arg, AML_INT_METHODCALL_OP);
318         }
319 
320         /* This name is actually a control method invocation */
321 
322         MethodDesc = AcpiNsGetAttachedObject (Node);
323         ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
324             "Control Method invocation %4.4s - %p Desc %p Path=%p\n",
325             Node->Name.Ascii, Node, MethodDesc, Path));
326 
327         NameOp = AcpiPsAllocOp (AML_INT_NAMEPATH_OP, Start);
328         if (!NameOp)
329         {
330             return_ACPI_STATUS (AE_NO_MEMORY);
331         }
332 
333         /* Change Arg into a METHOD CALL and attach name to it */
334 
335         AcpiPsInitOp (Arg, AML_INT_METHODCALL_OP);
336         NameOp->Common.Value.Name = Path;
337 
338         /* Point METHODCALL/NAME to the METHOD Node */
339 
340         NameOp->Common.Node = Node;
341         AcpiPsAppendArg (Arg, NameOp);
342 
343         if (!MethodDesc)
344         {
345             ACPI_ERROR ((AE_INFO,
346                 "Control Method %p has no attached object",
347                 Node));
348             return_ACPI_STATUS (AE_AML_INTERNAL);
349         }
350 
351         ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
352             "Control Method - %p Args %X\n",
353             Node, MethodDesc->Method.ParamCount));
354 
355         /* Get the number of arguments to expect */
356 
357         WalkState->ArgCount = MethodDesc->Method.ParamCount;
358         return_ACPI_STATUS (AE_OK);
359     }
360 
361     /*
362      * Special handling if the name was not found during the lookup -
363      * some NotFound cases are allowed
364      */
365     if (Status == AE_NOT_FOUND)
366     {
367         /* 1) NotFound is ok during load pass 1/2 (allow forward references) */
368 
369         if ((WalkState->ParseFlags & ACPI_PARSE_MODE_MASK) !=
370             ACPI_PARSE_EXECUTE)
371         {
372             Status = AE_OK;
373         }
374 
375         /* 2) NotFound during a CondRefOf(x) is ok by definition */
376 
377         else if (WalkState->Op->Common.AmlOpcode == AML_CONDITIONAL_REF_OF_OP)
378         {
379             Status = AE_OK;
380         }
381 
382         /*
383          * 3) NotFound while building a Package is ok at this point, we
384          * may flag as an error later if slack mode is not enabled.
385          * (Some ASL code depends on allowing this behavior)
386          */
387         else if ((Arg->Common.Parent) &&
388             ((Arg->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||
389              (Arg->Common.Parent->Common.AmlOpcode == AML_VARIABLE_PACKAGE_OP)))
390         {
391             Status = AE_OK;
392         }
393     }
394 
395     /* Final exception check (may have been changed from code above) */
396 
397     if (ACPI_FAILURE (Status))
398     {
399         ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo, Path, Status);
400 
401         if ((WalkState->ParseFlags & ACPI_PARSE_MODE_MASK) ==
402             ACPI_PARSE_EXECUTE)
403         {
404             /* Report a control method execution error */
405 
406             Status = AcpiDsMethodError (Status, WalkState);
407         }
408     }
409 
410     /* Save the namepath */
411 
412     Arg->Common.Value.Name = Path;
413     return_ACPI_STATUS (Status);
414 }
415 
416 
417 /*******************************************************************************
418  *
419  * FUNCTION:    AcpiPsGetNextSimpleArg
420  *
421  * PARAMETERS:  ParserState         - Current parser state object
422  *              ArgType             - The argument type (AML_*_ARG)
423  *              Arg                 - Where the argument is returned
424  *
425  * RETURN:      None
426  *
427  * DESCRIPTION: Get the next simple argument (constant, string, or namestring)
428  *
429  ******************************************************************************/
430 
431 void
432 AcpiPsGetNextSimpleArg (
433     ACPI_PARSE_STATE        *ParserState,
434     UINT32                  ArgType,
435     ACPI_PARSE_OBJECT       *Arg)
436 {
437     UINT32                  Length;
438     UINT16                  Opcode;
439     UINT8                   *Aml = ParserState->Aml;
440 
441 
442     ACPI_FUNCTION_TRACE_U32 (PsGetNextSimpleArg, ArgType);
443 
444 
445     switch (ArgType)
446     {
447     case ARGP_BYTEDATA:
448 
449         /* Get 1 byte from the AML stream */
450 
451         Opcode = AML_BYTE_OP;
452         Arg->Common.Value.Integer = (UINT64) *Aml;
453         Length = 1;
454         break;
455 
456     case ARGP_WORDDATA:
457 
458         /* Get 2 bytes from the AML stream */
459 
460         Opcode = AML_WORD_OP;
461         ACPI_MOVE_16_TO_64 (&Arg->Common.Value.Integer, Aml);
462         Length = 2;
463         break;
464 
465     case ARGP_DWORDDATA:
466 
467         /* Get 4 bytes from the AML stream */
468 
469         Opcode = AML_DWORD_OP;
470         ACPI_MOVE_32_TO_64 (&Arg->Common.Value.Integer, Aml);
471         Length = 4;
472         break;
473 
474     case ARGP_QWORDDATA:
475 
476         /* Get 8 bytes from the AML stream */
477 
478         Opcode = AML_QWORD_OP;
479         ACPI_MOVE_64_TO_64 (&Arg->Common.Value.Integer, Aml);
480         Length = 8;
481         break;
482 
483     case ARGP_CHARLIST:
484 
485         /* Get a pointer to the string, point past the string */
486 
487         Opcode = AML_STRING_OP;
488         Arg->Common.Value.String = ACPI_CAST_PTR (char, Aml);
489 
490         /* Find the null terminator */
491 
492         Length = 0;
493         while (Aml[Length])
494         {
495             Length++;
496         }
497         Length++;
498         break;
499 
500     case ARGP_NAME:
501     case ARGP_NAMESTRING:
502 
503         AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP);
504         Arg->Common.Value.Name = AcpiPsGetNextNamestring (ParserState);
505         return_VOID;
506 
507     default:
508 
509         ACPI_ERROR ((AE_INFO, "Invalid ArgType 0x%X", ArgType));
510         return_VOID;
511     }
512 
513     AcpiPsInitOp (Arg, Opcode);
514     ParserState->Aml += Length;
515     return_VOID;
516 }
517 
518 
519 /*******************************************************************************
520  *
521  * FUNCTION:    AcpiPsGetNextField
522  *
523  * PARAMETERS:  ParserState         - Current parser state object
524  *
525  * RETURN:      A newly allocated FIELD op
526  *
527  * DESCRIPTION: Get next field (NamedField, ReservedField, or AccessField)
528  *
529  ******************************************************************************/
530 
531 static ACPI_PARSE_OBJECT *
532 AcpiPsGetNextField (
533     ACPI_PARSE_STATE        *ParserState)
534 {
535     UINT8                   *Aml;
536     ACPI_PARSE_OBJECT       *Field;
537     ACPI_PARSE_OBJECT       *Arg = NULL;
538     UINT16                  Opcode;
539     UINT32                  Name;
540     UINT8                   AccessType;
541     UINT8                   AccessAttribute;
542     UINT8                   AccessLength;
543     UINT32                  PkgLength;
544     UINT8                   *PkgEnd;
545     UINT32                  BufferLength;
546 
547 
548     ACPI_FUNCTION_TRACE (PsGetNextField);
549 
550 
551     ASL_CV_CAPTURE_COMMENTS_ONLY (ParserState);
552     Aml = ParserState->Aml;
553 
554     /* Determine field type */
555 
556     switch (ACPI_GET8 (ParserState->Aml))
557     {
558     case AML_FIELD_OFFSET_OP:
559 
560         Opcode = AML_INT_RESERVEDFIELD_OP;
561         ParserState->Aml++;
562         break;
563 
564     case AML_FIELD_ACCESS_OP:
565 
566         Opcode = AML_INT_ACCESSFIELD_OP;
567         ParserState->Aml++;
568         break;
569 
570     case AML_FIELD_CONNECTION_OP:
571 
572         Opcode = AML_INT_CONNECTION_OP;
573         ParserState->Aml++;
574         break;
575 
576     case AML_FIELD_EXT_ACCESS_OP:
577 
578         Opcode = AML_INT_EXTACCESSFIELD_OP;
579         ParserState->Aml++;
580         break;
581 
582     default:
583 
584         Opcode = AML_INT_NAMEDFIELD_OP;
585         break;
586     }
587 
588     /* Allocate a new field op */
589 
590     Field = AcpiPsAllocOp (Opcode, Aml);
591     if (!Field)
592     {
593         return_PTR (NULL);
594     }
595 
596     /* Decode the field type */
597 
598     ASL_CV_CAPTURE_COMMENTS_ONLY (ParserState);
599     switch (Opcode)
600     {
601     case AML_INT_NAMEDFIELD_OP:
602 
603         /* Get the 4-character name */
604 
605         ACPI_MOVE_32_TO_32 (&Name, ParserState->Aml);
606         AcpiPsSetName (Field, Name);
607         ParserState->Aml += ACPI_NAMESEG_SIZE;
608 
609 
610         ASL_CV_CAPTURE_COMMENTS_ONLY (ParserState);
611 
612 #ifdef ACPI_ASL_COMPILER
613         /*
614          * Because the package length isn't represented as a parse tree object,
615          * take comments surrounding this and add to the previously created
616          * parse node.
617          */
618         if (Field->Common.InlineComment)
619         {
620             Field->Common.NameComment = Field->Common.InlineComment;
621         }
622         Field->Common.InlineComment  = AcpiGbl_CurrentInlineComment;
623         AcpiGbl_CurrentInlineComment = NULL;
624 #endif
625 
626         /* Get the length which is encoded as a package length */
627 
628         Field->Common.Value.Size = AcpiPsGetNextPackageLength (ParserState);
629         break;
630 
631 
632     case AML_INT_RESERVEDFIELD_OP:
633 
634         /* Get the length which is encoded as a package length */
635 
636         Field->Common.Value.Size = AcpiPsGetNextPackageLength (ParserState);
637         break;
638 
639 
640     case AML_INT_ACCESSFIELD_OP:
641     case AML_INT_EXTACCESSFIELD_OP:
642 
643         /*
644          * Get AccessType and AccessAttrib and merge into the field Op
645          * AccessType is first operand, AccessAttribute is second. stuff
646          * these bytes into the node integer value for convenience.
647          */
648 
649         /* Get the two bytes (Type/Attribute) */
650 
651         AccessType = ACPI_GET8 (ParserState->Aml);
652         ParserState->Aml++;
653         AccessAttribute = ACPI_GET8 (ParserState->Aml);
654         ParserState->Aml++;
655 
656         Field->Common.Value.Integer = (UINT8) AccessType;
657         Field->Common.Value.Integer |= (UINT16) (AccessAttribute << 8);
658 
659         /* This opcode has a third byte, AccessLength */
660 
661         if (Opcode == AML_INT_EXTACCESSFIELD_OP)
662         {
663             AccessLength = ACPI_GET8 (ParserState->Aml);
664             ParserState->Aml++;
665 
666             Field->Common.Value.Integer |= (UINT32) (AccessLength << 16);
667         }
668         break;
669 
670 
671     case AML_INT_CONNECTION_OP:
672 
673         /*
674          * Argument for Connection operator can be either a Buffer
675          * (resource descriptor), or a NameString.
676          */
677         Aml = ParserState->Aml;
678         if (ACPI_GET8 (ParserState->Aml) == AML_BUFFER_OP)
679         {
680             ParserState->Aml++;
681 
682             ASL_CV_CAPTURE_COMMENTS_ONLY (ParserState);
683             PkgEnd = ParserState->Aml;
684             PkgLength = AcpiPsGetNextPackageLength (ParserState);
685             PkgEnd += PkgLength;
686 
687             ASL_CV_CAPTURE_COMMENTS_ONLY (ParserState);
688             if (ParserState->Aml < PkgEnd)
689             {
690                 /* Non-empty list */
691 
692                 Arg = AcpiPsAllocOp (AML_INT_BYTELIST_OP, Aml);
693                 if (!Arg)
694                 {
695                     AcpiPsFreeOp (Field);
696                     return_PTR (NULL);
697                 }
698 
699                 /* Get the actual buffer length argument */
700 
701                 Opcode = ACPI_GET8 (ParserState->Aml);
702                 ParserState->Aml++;
703 
704                 ASL_CV_CAPTURE_COMMENTS_ONLY (ParserState);
705                 switch (Opcode)
706                 {
707                 case AML_BYTE_OP:       /* AML_BYTEDATA_ARG */
708 
709                     BufferLength = ACPI_GET8 (ParserState->Aml);
710                     ParserState->Aml += 1;
711                     break;
712 
713                 case AML_WORD_OP:       /* AML_WORDDATA_ARG */
714 
715                     BufferLength = ACPI_GET16 (ParserState->Aml);
716                     ParserState->Aml += 2;
717                     break;
718 
719                 case AML_DWORD_OP:      /* AML_DWORDATA_ARG */
720 
721                     BufferLength = ACPI_GET32 (ParserState->Aml);
722                     ParserState->Aml += 4;
723                     break;
724 
725                 default:
726 
727                     BufferLength = 0;
728                     break;
729                 }
730 
731                 /* Fill in bytelist data */
732 
733                 ASL_CV_CAPTURE_COMMENTS_ONLY (ParserState);
734                 Arg->Named.Value.Size = BufferLength;
735                 Arg->Named.Data = ParserState->Aml;
736             }
737 
738             /* Skip to End of byte data */
739 
740             ParserState->Aml = PkgEnd;
741         }
742         else
743         {
744             Arg = AcpiPsAllocOp (AML_INT_NAMEPATH_OP, Aml);
745             if (!Arg)
746             {
747                 AcpiPsFreeOp (Field);
748                 return_PTR (NULL);
749             }
750 
751             /* Get the Namestring argument */
752 
753             Arg->Common.Value.Name = AcpiPsGetNextNamestring (ParserState);
754         }
755 
756         /* Link the buffer/namestring to parent (CONNECTION_OP) */
757 
758         AcpiPsAppendArg (Field, Arg);
759         break;
760 
761 
762     default:
763 
764         /* Opcode was set in previous switch */
765         break;
766     }
767 
768     return_PTR (Field);
769 }
770 
771 /*******************************************************************************
772  *
773  * FUNCTION:    AcpiPsFreeFieldList
774  *
775  * PARAMETERS:  Start               - First Op in field list
776  *
777  * RETURN:      None.
778  *
779  * DESCRIPTION: Free all Op objects inside a field list.
780  *
781  ******************************************************************************/
782 
783 static void
784 AcpiPsFreeFieldList (
785     ACPI_PARSE_OBJECT	*Start)
786 {
787     ACPI_PARSE_OBJECT *Current = Start;
788     ACPI_PARSE_OBJECT *Next;
789     ACPI_PARSE_OBJECT *Arg;
790 
791     while (Current)
792     {
793         Next = Current->Common.Next;
794 
795         /* AML_INT_CONNECTION_OP can have a single argument */
796 
797         Arg = AcpiPsGetArg (Current, 0);
798         if (Arg)
799         {
800             AcpiPsFreeOp (Arg);
801         }
802 
803         AcpiPsFreeOp(Current);
804         Current = Next;
805     }
806 }
807 
808 
809 /*******************************************************************************
810  *
811  * FUNCTION:    AcpiPsGetNextArg
812  *
813  * PARAMETERS:  WalkState           - Current state
814  *              ParserState         - Current parser state object
815  *              ArgType             - The argument type (AML_*_ARG)
816  *              ReturnArg           - Where the next arg is returned
817  *
818  * RETURN:      Status, and an op object containing the next argument.
819  *
820  * DESCRIPTION: Get next argument (including complex list arguments that require
821  *              pushing the parser stack)
822  *
823  ******************************************************************************/
824 
825 ACPI_STATUS
826 AcpiPsGetNextArg (
827     ACPI_WALK_STATE         *WalkState,
828     ACPI_PARSE_STATE        *ParserState,
829     UINT32                  ArgType,
830     ACPI_PARSE_OBJECT       **ReturnArg)
831 {
832     ACPI_PARSE_OBJECT       *Arg = NULL;
833     ACPI_PARSE_OBJECT       *Prev = NULL;
834     ACPI_PARSE_OBJECT       *Field;
835     UINT32                  Subop;
836     ACPI_STATUS             Status = AE_OK;
837 
838 
839     ACPI_FUNCTION_TRACE_PTR (PsGetNextArg, ParserState);
840 
841 
842     ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
843         "Expected argument type ARGP: %s (%2.2X)\n",
844         AcpiUtGetArgumentTypeName (ArgType), ArgType));
845 
846     switch (ArgType)
847     {
848     case ARGP_BYTEDATA:
849     case ARGP_WORDDATA:
850     case ARGP_DWORDDATA:
851     case ARGP_CHARLIST:
852     case ARGP_NAME:
853     case ARGP_NAMESTRING:
854 
855         /* Constants, strings, and namestrings are all the same size */
856 
857         Arg = AcpiPsAllocOp (AML_BYTE_OP, ParserState->Aml);
858         if (!Arg)
859         {
860             return_ACPI_STATUS (AE_NO_MEMORY);
861         }
862 
863         AcpiPsGetNextSimpleArg (ParserState, ArgType, Arg);
864         break;
865 
866     case ARGP_PKGLENGTH:
867 
868         /* Package length, nothing returned */
869 
870         ParserState->PkgEnd = AcpiPsGetNextPackageEnd (ParserState);
871         break;
872 
873     case ARGP_FIELDLIST:
874 
875         if (ParserState->Aml < ParserState->PkgEnd)
876         {
877             /* Non-empty list */
878 
879             while (ParserState->Aml < ParserState->PkgEnd)
880             {
881                 Field = AcpiPsGetNextField (ParserState);
882                 if (!Field)
883                 {
884                     if (Arg)
885                     {
886                         AcpiPsFreeFieldList(Arg);
887                     }
888 
889                     return_ACPI_STATUS (AE_NO_MEMORY);
890                 }
891 
892                 if (Prev)
893                 {
894                     Prev->Common.Next = Field;
895                 }
896                 else
897                 {
898                     Arg = Field;
899                 }
900                 Prev = Field;
901             }
902 
903             /* Skip to End of byte data */
904 
905             ParserState->Aml = ParserState->PkgEnd;
906         }
907         break;
908 
909     case ARGP_BYTELIST:
910 
911         if (ParserState->Aml < ParserState->PkgEnd)
912         {
913             /* Non-empty list */
914 
915             Arg = AcpiPsAllocOp (AML_INT_BYTELIST_OP,
916                 ParserState->Aml);
917             if (!Arg)
918             {
919                 return_ACPI_STATUS (AE_NO_MEMORY);
920             }
921 
922             /* Fill in bytelist data */
923 
924             Arg->Common.Value.Size = (UINT32)
925                 ACPI_PTR_DIFF (ParserState->PkgEnd, ParserState->Aml);
926             Arg->Named.Data = ParserState->Aml;
927 
928             /* Skip to End of byte data */
929 
930             ParserState->Aml = ParserState->PkgEnd;
931         }
932         break;
933 
934     case ARGP_SIMPLENAME:
935     case ARGP_NAME_OR_REF:
936 
937         ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
938             "**** SimpleName/NameOrRef: %s (%2.2X)\n",
939             AcpiUtGetArgumentTypeName (ArgType), ArgType));
940 
941         Subop = AcpiPsPeekOpcode (ParserState);
942         if (Subop == 0                  ||
943             AcpiPsIsLeadingChar (Subop) ||
944             ACPI_IS_ROOT_PREFIX (Subop) ||
945             ACPI_IS_PARENT_PREFIX (Subop))
946         {
947             /* NullName or NameString */
948 
949             Arg = AcpiPsAllocOp (AML_INT_NAMEPATH_OP, ParserState->Aml);
950             if (!Arg)
951             {
952                 return_ACPI_STATUS (AE_NO_MEMORY);
953             }
954 
955             Status = AcpiPsGetNextNamepath (WalkState, ParserState,
956                 Arg, ACPI_NOT_METHOD_CALL);
957             if (ACPI_FAILURE(Status))
958             {
959                 AcpiPsFreeOp (Arg);
960                 return_ACPI_STATUS (Status);
961             }
962         }
963         else
964         {
965             /* Single complex argument, nothing returned */
966 
967             WalkState->ArgCount = 1;
968         }
969         break;
970 
971     case ARGP_TARGET:
972     case ARGP_SUPERNAME:
973 
974         ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
975             "**** Target/Supername: %s (%2.2X)\n",
976             AcpiUtGetArgumentTypeName (ArgType), ArgType));
977 
978         Subop = AcpiPsPeekOpcode (ParserState);
979         if (Subop == 0                  ||
980             AcpiPsIsLeadingChar (Subop) ||
981             ACPI_IS_ROOT_PREFIX (Subop) ||
982             ACPI_IS_PARENT_PREFIX (Subop))
983         {
984             /* NULL target (zero). Convert to a NULL namepath */
985 
986             Arg = AcpiPsAllocOp (AML_INT_NAMEPATH_OP, ParserState->Aml);
987             if (!Arg)
988             {
989                 return_ACPI_STATUS (AE_NO_MEMORY);
990             }
991 
992             Status = AcpiPsGetNextNamepath (WalkState, ParserState,
993                 Arg, ACPI_POSSIBLE_METHOD_CALL);
994             if (ACPI_FAILURE(Status))
995             {
996                 AcpiPsFreeOp (Arg);
997                 return_ACPI_STATUS (Status);
998             }
999 
1000             if (Arg->Common.AmlOpcode == AML_INT_METHODCALL_OP)
1001             {
1002                 /* Free method call op and corresponding namestring sub-ob */
1003 
1004                 AcpiPsFreeOp (Arg->Common.Value.Arg);
1005                 AcpiPsFreeOp (Arg);
1006                 Arg = NULL;
1007                 WalkState->ArgCount = 1;
1008             }
1009         }
1010         else
1011         {
1012             /* Single complex argument, nothing returned */
1013 
1014             WalkState->ArgCount = 1;
1015         }
1016         break;
1017 
1018     case ARGP_DATAOBJ:
1019     case ARGP_TERMARG:
1020 
1021         ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
1022             "**** TermArg/DataObj: %s (%2.2X)\n",
1023             AcpiUtGetArgumentTypeName (ArgType), ArgType));
1024 
1025         /* Single complex argument, nothing returned */
1026 
1027         WalkState->ArgCount = 1;
1028         break;
1029 
1030     case ARGP_DATAOBJLIST:
1031     case ARGP_TERMLIST:
1032     case ARGP_OBJLIST:
1033 
1034         if (ParserState->Aml < ParserState->PkgEnd)
1035         {
1036             /* Non-empty list of variable arguments, nothing returned */
1037 
1038             WalkState->ArgCount = ACPI_VAR_ARGS;
1039         }
1040         break;
1041 
1042     default:
1043 
1044         ACPI_ERROR ((AE_INFO, "Invalid ArgType: 0x%X", ArgType));
1045         Status = AE_AML_OPERAND_TYPE;
1046         break;
1047     }
1048 
1049     *ReturnArg = Arg;
1050     return_ACPI_STATUS (Status);
1051 }
1052