xref: /haiku/src/add-ons/kernel/bus_managers/acpi/acpica/components/parser/psargs.c (revision 90ae2e54f6ccaca73c011a2aa4cdd660417108ad)
1 /******************************************************************************
2  *
3  * Module Name: psargs - Parse AML opcode arguments
4  *
5  *****************************************************************************/
6 
7 /******************************************************************************
8  *
9  * 1. Copyright Notice
10  *
11  * Some or all of this work - Copyright (c) 1999 - 2012, Intel Corp.
12  * All rights reserved.
13  *
14  * 2. License
15  *
16  * 2.1. This is your license from Intel Corp. under its intellectual property
17  * rights. You may have additional license terms from the party that provided
18  * you this software, covering your right to use that party's intellectual
19  * property rights.
20  *
21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22  * copy of the source code appearing in this file ("Covered Code") an
23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24  * base code distributed originally by Intel ("Original Intel Code") to copy,
25  * make derivatives, distribute, use and display any portion of the Covered
26  * Code in any form, with the right to sublicense such rights; and
27  *
28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29  * license (with the right to sublicense), under only those claims of Intel
30  * patents that are infringed by the Original Intel Code, to make, use, sell,
31  * offer to sell, and import the Covered Code and derivative works thereof
32  * solely to the minimum extent necessary to exercise the above copyright
33  * license, and in no event shall the patent license extend to any additions
34  * to or modifications of the Original Intel Code. No other license or right
35  * is granted directly or by implication, estoppel or otherwise;
36  *
37  * The above copyright and patent license is granted only if the following
38  * conditions are met:
39  *
40  * 3. Conditions
41  *
42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43  * Redistribution of source code of any substantial portion of the Covered
44  * Code or modification with rights to further distribute source must include
45  * the above Copyright Notice, the above License, this list of Conditions,
46  * and the following Disclaimer and Export Compliance provision. In addition,
47  * Licensee must cause all Covered Code to which Licensee contributes to
48  * contain a file documenting the changes Licensee made to create that Covered
49  * Code and the date of any change. Licensee must include in that file the
50  * documentation of any changes made by any predecessor Licensee. Licensee
51  * must include a prominent statement that the modification is derived,
52  * directly or indirectly, from Original Intel Code.
53  *
54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55  * Redistribution of source code of any substantial portion of the Covered
56  * Code or modification without rights to further distribute source must
57  * include the following Disclaimer and Export Compliance provision in the
58  * documentation and/or other materials provided with distribution. In
59  * addition, Licensee may not authorize further sublicense of source of any
60  * portion of the Covered Code, and must include terms to the effect that the
61  * license from Licensee to its licensee is limited to the intellectual
62  * property embodied in the software Licensee provides to its licensee, and
63  * not to intellectual property embodied in modifications its licensee may
64  * make.
65  *
66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
67  * substantial portion of the Covered Code or modification must reproduce the
68  * above Copyright Notice, and the following Disclaimer and Export Compliance
69  * provision in the documentation and/or other materials provided with the
70  * distribution.
71  *
72  * 3.4. Intel retains all right, title, and interest in and to the Original
73  * Intel Code.
74  *
75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76  * Intel shall be used in advertising or otherwise to promote the sale, use or
77  * other dealings in products derived from or relating to the Covered Code
78  * without prior written authorization from Intel.
79  *
80  * 4. Disclaimer and Export Compliance
81  *
82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88  * PARTICULAR PURPOSE.
89  *
90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97  * LIMITED REMEDY.
98  *
99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
100  * software or system incorporating such software without first obtaining any
101  * required license or other approval from the U. S. Department of Commerce or
102  * any other agency or department of the United States Government. In the
103  * event Licensee exports any such software from the United States or
104  * re-exports any such software from a foreign destination, Licensee shall
105  * ensure that the distribution and export/re-export of the software is in
106  * compliance with all laws, regulations, orders, or other restrictions of the
107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108  * any of its subsidiaries will export/re-export any technical data, process,
109  * software, or service, directly or indirectly, to any country for which the
110  * United States government or any agency thereof requires an export license,
111  * other governmental approval, or letter of assurance, without first obtaining
112  * such license, approval or letter.
113  *
114  *****************************************************************************/
115 
116 #define __PSARGS_C__
117 
118 #include "acpi.h"
119 #include "accommon.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 = (UINT64) *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 0x%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;
607     ACPI_PARSE_OBJECT       *Field;
608     ACPI_PARSE_OBJECT       *Arg = NULL;
609     UINT16                  Opcode;
610     UINT32                  Name;
611     UINT8                   AccessType;
612     UINT8                   AccessAttribute;
613     UINT8                   AccessLength;
614     UINT32                  PkgLength;
615     UINT8                   *PkgEnd;
616     UINT32                  BufferLength;
617 
618 
619     ACPI_FUNCTION_TRACE (PsGetNextField);
620 
621 
622     AmlOffset = (UINT32) ACPI_PTR_DIFF (
623         ParserState->Aml, ParserState->AmlStart);
624 
625     /* Determine field type */
626 
627     switch (ACPI_GET8 (ParserState->Aml))
628     {
629     case AML_FIELD_OFFSET_OP:
630 
631         Opcode = AML_INT_RESERVEDFIELD_OP;
632         ParserState->Aml++;
633         break;
634 
635     case AML_FIELD_ACCESS_OP:
636 
637         Opcode = AML_INT_ACCESSFIELD_OP;
638         ParserState->Aml++;
639         break;
640 
641     case AML_FIELD_CONNECTION_OP:
642 
643         Opcode = AML_INT_CONNECTION_OP;
644         ParserState->Aml++;
645         break;
646 
647     case AML_FIELD_EXT_ACCESS_OP:
648 
649         Opcode = AML_INT_EXTACCESSFIELD_OP;
650         ParserState->Aml++;
651         break;
652 
653     default:
654 
655         Opcode = AML_INT_NAMEDFIELD_OP;
656         break;
657     }
658 
659     /* Allocate a new field op */
660 
661     Field = AcpiPsAllocOp (Opcode);
662     if (!Field)
663     {
664         return_PTR (NULL);
665     }
666 
667     Field->Common.AmlOffset = AmlOffset;
668 
669     /* Decode the field type */
670 
671     switch (Opcode)
672     {
673     case AML_INT_NAMEDFIELD_OP:
674 
675         /* Get the 4-character name */
676 
677         ACPI_MOVE_32_TO_32 (&Name, ParserState->Aml);
678         AcpiPsSetName (Field, Name);
679         ParserState->Aml += ACPI_NAME_SIZE;
680 
681         /* Get the length which is encoded as a package length */
682 
683         Field->Common.Value.Size = AcpiPsGetNextPackageLength (ParserState);
684         break;
685 
686 
687     case AML_INT_RESERVEDFIELD_OP:
688 
689         /* Get the length which is encoded as a package length */
690 
691         Field->Common.Value.Size = AcpiPsGetNextPackageLength (ParserState);
692         break;
693 
694 
695     case AML_INT_ACCESSFIELD_OP:
696     case AML_INT_EXTACCESSFIELD_OP:
697 
698         /*
699          * Get AccessType and AccessAttrib and merge into the field Op
700          * AccessType is first operand, AccessAttribute is second. stuff
701          * these bytes into the node integer value for convenience.
702          */
703 
704         /* Get the two bytes (Type/Attribute) */
705 
706         AccessType = ACPI_GET8 (ParserState->Aml);
707         ParserState->Aml++;
708         AccessAttribute = ACPI_GET8 (ParserState->Aml);
709         ParserState->Aml++;
710 
711         Field->Common.Value.Integer = (UINT8) AccessType;
712         Field->Common.Value.Integer |= (UINT16) (AccessAttribute << 8);
713 
714         /* This opcode has a third byte, AccessLength */
715 
716         if (Opcode == AML_INT_EXTACCESSFIELD_OP)
717         {
718             AccessLength = ACPI_GET8 (ParserState->Aml);
719             ParserState->Aml++;
720 
721             Field->Common.Value.Integer |= (UINT32) (AccessLength << 16);
722         }
723         break;
724 
725 
726     case AML_INT_CONNECTION_OP:
727 
728         /*
729          * Argument for Connection operator can be either a Buffer
730          * (resource descriptor), or a NameString.
731          */
732         if (ACPI_GET8 (ParserState->Aml) == AML_BUFFER_OP)
733         {
734             ParserState->Aml++;
735 
736             PkgEnd = ParserState->Aml;
737             PkgLength = AcpiPsGetNextPackageLength (ParserState);
738             PkgEnd += PkgLength;
739 
740             if (ParserState->Aml < PkgEnd)
741             {
742                 /* Non-empty list */
743 
744                 Arg = AcpiPsAllocOp (AML_INT_BYTELIST_OP);
745                 if (!Arg)
746                 {
747                     AcpiPsFreeOp (Field);
748                     return_PTR (NULL);
749                 }
750 
751                 /* Get the actual buffer length argument */
752 
753                 Opcode = ACPI_GET8 (ParserState->Aml);
754                 ParserState->Aml++;
755 
756                 switch (Opcode)
757                 {
758                 case AML_BYTE_OP:       /* AML_BYTEDATA_ARG */
759                     BufferLength = ACPI_GET8 (ParserState->Aml);
760                     ParserState->Aml += 1;
761                     break;
762 
763                 case AML_WORD_OP:       /* AML_WORDDATA_ARG */
764                     BufferLength = ACPI_GET16 (ParserState->Aml);
765                     ParserState->Aml += 2;
766                     break;
767 
768                 case AML_DWORD_OP:      /* AML_DWORDATA_ARG */
769                     BufferLength = ACPI_GET32 (ParserState->Aml);
770                     ParserState->Aml += 4;
771                     break;
772 
773                 default:
774                     BufferLength = 0;
775                     break;
776                 }
777 
778                 /* Fill in bytelist data */
779 
780                 Arg->Named.Value.Size = BufferLength;
781                 Arg->Named.Data = ParserState->Aml;
782             }
783 
784             /* Skip to End of byte data */
785 
786             ParserState->Aml = PkgEnd;
787         }
788         else
789         {
790             Arg = AcpiPsAllocOp (AML_INT_NAMEPATH_OP);
791             if (!Arg)
792             {
793                 AcpiPsFreeOp (Field);
794                 return_PTR (NULL);
795             }
796 
797             /* Get the Namestring argument */
798 
799             Arg->Common.Value.Name = AcpiPsGetNextNamestring (ParserState);
800         }
801 
802         /* Link the buffer/namestring to parent (CONNECTION_OP) */
803 
804         AcpiPsAppendArg (Field, Arg);
805         break;
806 
807 
808     default:
809 
810         /* Opcode was set in previous switch */
811         break;
812     }
813 
814     return_PTR (Field);
815 }
816 
817 
818 /*******************************************************************************
819  *
820  * FUNCTION:    AcpiPsGetNextArg
821  *
822  * PARAMETERS:  WalkState           - Current state
823  *              ParserState         - Current parser state object
824  *              ArgType             - The argument type (AML_*_ARG)
825  *              ReturnArg           - Where the next arg is returned
826  *
827  * RETURN:      Status, and an op object containing the next argument.
828  *
829  * DESCRIPTION: Get next argument (including complex list arguments that require
830  *              pushing the parser stack)
831  *
832  ******************************************************************************/
833 
834 ACPI_STATUS
835 AcpiPsGetNextArg (
836     ACPI_WALK_STATE         *WalkState,
837     ACPI_PARSE_STATE        *ParserState,
838     UINT32                  ArgType,
839     ACPI_PARSE_OBJECT       **ReturnArg)
840 {
841     ACPI_PARSE_OBJECT       *Arg = NULL;
842     ACPI_PARSE_OBJECT       *Prev = NULL;
843     ACPI_PARSE_OBJECT       *Field;
844     UINT32                  Subop;
845     ACPI_STATUS             Status = AE_OK;
846 
847 
848     ACPI_FUNCTION_TRACE_PTR (PsGetNextArg, ParserState);
849 
850 
851     switch (ArgType)
852     {
853     case ARGP_BYTEDATA:
854     case ARGP_WORDDATA:
855     case ARGP_DWORDDATA:
856     case ARGP_CHARLIST:
857     case ARGP_NAME:
858     case ARGP_NAMESTRING:
859 
860         /* Constants, strings, and namestrings are all the same size */
861 
862         Arg = AcpiPsAllocOp (AML_BYTE_OP);
863         if (!Arg)
864         {
865             return_ACPI_STATUS (AE_NO_MEMORY);
866         }
867         AcpiPsGetNextSimpleArg (ParserState, ArgType, Arg);
868         break;
869 
870 
871     case ARGP_PKGLENGTH:
872 
873         /* Package length, nothing returned */
874 
875         ParserState->PkgEnd = AcpiPsGetNextPackageEnd (ParserState);
876         break;
877 
878 
879     case ARGP_FIELDLIST:
880 
881         if (ParserState->Aml < ParserState->PkgEnd)
882         {
883             /* Non-empty list */
884 
885             while (ParserState->Aml < ParserState->PkgEnd)
886             {
887                 Field = AcpiPsGetNextField (ParserState);
888                 if (!Field)
889                 {
890                     return_ACPI_STATUS (AE_NO_MEMORY);
891                 }
892 
893                 if (Prev)
894                 {
895                     Prev->Common.Next = Field;
896                 }
897                 else
898                 {
899                     Arg = Field;
900                 }
901                 Prev = Field;
902             }
903 
904             /* Skip to End of byte data */
905 
906             ParserState->Aml = ParserState->PkgEnd;
907         }
908         break;
909 
910 
911     case ARGP_BYTELIST:
912 
913         if (ParserState->Aml < ParserState->PkgEnd)
914         {
915             /* Non-empty list */
916 
917             Arg = AcpiPsAllocOp (AML_INT_BYTELIST_OP);
918             if (!Arg)
919             {
920                 return_ACPI_STATUS (AE_NO_MEMORY);
921             }
922 
923             /* Fill in bytelist data */
924 
925             Arg->Common.Value.Size = (UINT32)
926                 ACPI_PTR_DIFF (ParserState->PkgEnd, ParserState->Aml);
927             Arg->Named.Data = ParserState->Aml;
928 
929             /* Skip to End of byte data */
930 
931             ParserState->Aml = ParserState->PkgEnd;
932         }
933         break;
934 
935 
936     case ARGP_TARGET:
937     case ARGP_SUPERNAME:
938     case ARGP_SIMPLENAME:
939 
940         Subop = AcpiPsPeekOpcode (ParserState);
941         if (Subop == 0                  ||
942             AcpiPsIsLeadingChar (Subop) ||
943             AcpiPsIsPrefixChar (Subop))
944         {
945             /* NullName or NameString */
946 
947             Arg = AcpiPsAllocOp (AML_INT_NAMEPATH_OP);
948             if (!Arg)
949             {
950                 return_ACPI_STATUS (AE_NO_MEMORY);
951             }
952 
953             /* To support SuperName arg of Unload */
954 
955             if (WalkState->Opcode == AML_UNLOAD_OP)
956             {
957                 Status = AcpiPsGetNextNamepath (WalkState, ParserState, Arg, 1);
958 
959                 /*
960                  * If the SuperName arg of Unload is a method call,
961                  * we have restored the AML pointer, just free this Arg
962                  */
963                 if (Arg->Common.AmlOpcode == AML_INT_METHODCALL_OP)
964                 {
965                     AcpiPsFreeOp (Arg);
966                     Arg = NULL;
967                 }
968             }
969             else
970             {
971                 Status = AcpiPsGetNextNamepath (WalkState, ParserState, Arg, 0);
972             }
973         }
974         else
975         {
976             /* Single complex argument, nothing returned */
977 
978             WalkState->ArgCount = 1;
979         }
980         break;
981 
982 
983     case ARGP_DATAOBJ:
984     case ARGP_TERMARG:
985 
986         /* Single complex argument, nothing returned */
987 
988         WalkState->ArgCount = 1;
989         break;
990 
991 
992     case ARGP_DATAOBJLIST:
993     case ARGP_TERMLIST:
994     case ARGP_OBJLIST:
995 
996         if (ParserState->Aml < ParserState->PkgEnd)
997         {
998             /* Non-empty list of variable arguments, nothing returned */
999 
1000             WalkState->ArgCount = ACPI_VAR_ARGS;
1001         }
1002         break;
1003 
1004 
1005     default:
1006 
1007         ACPI_ERROR ((AE_INFO, "Invalid ArgType: 0x%X", ArgType));
1008         Status = AE_AML_OPERAND_TYPE;
1009         break;
1010     }
1011 
1012     *ReturnArg = Arg;
1013     return_ACPI_STATUS (Status);
1014 }
1015