xref: /haiku/src/add-ons/kernel/bus_managers/acpi/acpica/components/parser/psargs.c (revision 529cd177b573aaba391c8adc9c9f5ad76a14bf81)
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 - 2014, 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 (ACPI_IS_ROOT_PREFIX (*End) ||
258            ACPI_IS_PARENT_PREFIX (*End))
259     {
260         End++;
261     }
262 
263     /* Decode the path prefix character */
264 
265     switch (*End)
266     {
267     case 0:
268 
269         /* NullName */
270 
271         if (End == Start)
272         {
273             Start = NULL;
274         }
275         End++;
276         break;
277 
278     case AML_DUAL_NAME_PREFIX:
279 
280         /* Two name segments */
281 
282         End += 1 + (2 * ACPI_NAME_SIZE);
283         break;
284 
285     case AML_MULTI_NAME_PREFIX_OP:
286 
287         /* Multiple name segments, 4 chars each, count in next byte */
288 
289         End += 2 + (*(End + 1) * ACPI_NAME_SIZE);
290         break;
291 
292     default:
293 
294         /* Single name segment */
295 
296         End += ACPI_NAME_SIZE;
297         break;
298     }
299 
300     ParserState->Aml = End;
301     return_PTR ((char *) Start);
302 }
303 
304 
305 /*******************************************************************************
306  *
307  * FUNCTION:    AcpiPsGetNextNamepath
308  *
309  * PARAMETERS:  ParserState         - Current parser state object
310  *              Arg                 - Where the namepath will be stored
311  *              ArgCount            - If the namepath points to a control method
312  *                                    the method's argument is returned here.
313  *              PossibleMethodCall  - Whether the namepath can possibly be the
314  *                                    start of a method call
315  *
316  * RETURN:      Status
317  *
318  * DESCRIPTION: Get next name (if method call, return # of required args).
319  *              Names are looked up in the internal namespace to determine
320  *              if the name represents a control method. If a method
321  *              is found, the number of arguments to the method is returned.
322  *              This information is critical for parsing to continue correctly.
323  *
324  ******************************************************************************/
325 
326 ACPI_STATUS
327 AcpiPsGetNextNamepath (
328     ACPI_WALK_STATE         *WalkState,
329     ACPI_PARSE_STATE        *ParserState,
330     ACPI_PARSE_OBJECT       *Arg,
331     BOOLEAN                 PossibleMethodCall)
332 {
333     ACPI_STATUS             Status;
334     char                    *Path;
335     ACPI_PARSE_OBJECT       *NameOp;
336     ACPI_OPERAND_OBJECT     *MethodDesc;
337     ACPI_NAMESPACE_NODE     *Node;
338     UINT8                   *Start = ParserState->Aml;
339 
340 
341     ACPI_FUNCTION_TRACE (PsGetNextNamepath);
342 
343 
344     Path = AcpiPsGetNextNamestring (ParserState);
345     AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP);
346 
347     /* Null path case is allowed, just exit */
348 
349     if (!Path)
350     {
351         Arg->Common.Value.Name = Path;
352         return_ACPI_STATUS (AE_OK);
353     }
354 
355     /*
356      * Lookup the name in the internal namespace, starting with the current
357      * scope. We don't want to add anything new to the namespace here,
358      * however, so we use MODE_EXECUTE.
359      * Allow searching of the parent tree, but don't open a new scope -
360      * we just want to lookup the object (must be mode EXECUTE to perform
361      * the upsearch)
362      */
363     Status = AcpiNsLookup (WalkState->ScopeInfo, Path,
364                 ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
365                 ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL, &Node);
366 
367     /*
368      * If this name is a control method invocation, we must
369      * setup the method call
370      */
371     if (ACPI_SUCCESS (Status) &&
372         PossibleMethodCall &&
373         (Node->Type == ACPI_TYPE_METHOD))
374     {
375         if (WalkState->Opcode == AML_UNLOAD_OP)
376         {
377             /*
378              * AcpiPsGetNextNamestring has increased the AML pointer,
379              * so we need to restore the saved AML pointer for method call.
380              */
381             WalkState->ParserState.Aml = Start;
382             WalkState->ArgCount = 1;
383             AcpiPsInitOp (Arg, AML_INT_METHODCALL_OP);
384             return_ACPI_STATUS (AE_OK);
385         }
386 
387         /* This name is actually a control method invocation */
388 
389         MethodDesc = AcpiNsGetAttachedObject (Node);
390         ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
391             "Control Method - %p Desc %p Path=%p\n", Node, MethodDesc, Path));
392 
393         NameOp = AcpiPsAllocOp (AML_INT_NAMEPATH_OP);
394         if (!NameOp)
395         {
396             return_ACPI_STATUS (AE_NO_MEMORY);
397         }
398 
399         /* Change Arg into a METHOD CALL and attach name to it */
400 
401         AcpiPsInitOp (Arg, AML_INT_METHODCALL_OP);
402         NameOp->Common.Value.Name = Path;
403 
404         /* Point METHODCALL/NAME to the METHOD Node */
405 
406         NameOp->Common.Node = Node;
407         AcpiPsAppendArg (Arg, NameOp);
408 
409         if (!MethodDesc)
410         {
411             ACPI_ERROR ((AE_INFO,
412                 "Control Method %p has no attached object",
413                 Node));
414             return_ACPI_STATUS (AE_AML_INTERNAL);
415         }
416 
417         ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
418             "Control Method - %p Args %X\n",
419             Node, MethodDesc->Method.ParamCount));
420 
421         /* Get the number of arguments to expect */
422 
423         WalkState->ArgCount = MethodDesc->Method.ParamCount;
424         return_ACPI_STATUS (AE_OK);
425     }
426 
427     /*
428      * Special handling if the name was not found during the lookup -
429      * some NotFound cases are allowed
430      */
431     if (Status == AE_NOT_FOUND)
432     {
433         /* 1) NotFound is ok during load pass 1/2 (allow forward references) */
434 
435         if ((WalkState->ParseFlags & ACPI_PARSE_MODE_MASK) !=
436                 ACPI_PARSE_EXECUTE)
437         {
438             Status = AE_OK;
439         }
440 
441         /* 2) NotFound during a CondRefOf(x) is ok by definition */
442 
443         else if (WalkState->Op->Common.AmlOpcode == AML_COND_REF_OF_OP)
444         {
445             Status = AE_OK;
446         }
447 
448         /*
449          * 3) NotFound while building a Package is ok at this point, we
450          * may flag as an error later if slack mode is not enabled.
451          * (Some ASL code depends on allowing this behavior)
452          */
453         else if ((Arg->Common.Parent) &&
454             ((Arg->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||
455              (Arg->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP)))
456         {
457             Status = AE_OK;
458         }
459     }
460 
461     /* Final exception check (may have been changed from code above) */
462 
463     if (ACPI_FAILURE (Status))
464     {
465         ACPI_ERROR_NAMESPACE (Path, Status);
466 
467         if ((WalkState->ParseFlags & ACPI_PARSE_MODE_MASK) ==
468                 ACPI_PARSE_EXECUTE)
469         {
470             /* Report a control method execution error */
471 
472             Status = AcpiDsMethodError (Status, WalkState);
473         }
474     }
475 
476     /* Save the namepath */
477 
478     Arg->Common.Value.Name = Path;
479     return_ACPI_STATUS (Status);
480 }
481 
482 
483 /*******************************************************************************
484  *
485  * FUNCTION:    AcpiPsGetNextSimpleArg
486  *
487  * PARAMETERS:  ParserState         - Current parser state object
488  *              ArgType             - The argument type (AML_*_ARG)
489  *              Arg                 - Where the argument is returned
490  *
491  * RETURN:      None
492  *
493  * DESCRIPTION: Get the next simple argument (constant, string, or namestring)
494  *
495  ******************************************************************************/
496 
497 void
498 AcpiPsGetNextSimpleArg (
499     ACPI_PARSE_STATE        *ParserState,
500     UINT32                  ArgType,
501     ACPI_PARSE_OBJECT       *Arg)
502 {
503     UINT32                  Length;
504     UINT16                  Opcode;
505     UINT8                   *Aml = ParserState->Aml;
506 
507 
508     ACPI_FUNCTION_TRACE_U32 (PsGetNextSimpleArg, ArgType);
509 
510 
511     switch (ArgType)
512     {
513     case ARGP_BYTEDATA:
514 
515         /* Get 1 byte from the AML stream */
516 
517         Opcode = AML_BYTE_OP;
518         Arg->Common.Value.Integer = (UINT64) *Aml;
519         Length = 1;
520         break;
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     case ARGP_DWORDDATA:
532 
533         /* Get 4 bytes from the AML stream */
534 
535         Opcode = AML_DWORD_OP;
536         ACPI_MOVE_32_TO_64 (&Arg->Common.Value.Integer, Aml);
537         Length = 4;
538         break;
539 
540     case ARGP_QWORDDATA:
541 
542         /* Get 8 bytes from the AML stream */
543 
544         Opcode = AML_QWORD_OP;
545         ACPI_MOVE_64_TO_64 (&Arg->Common.Value.Integer, Aml);
546         Length = 8;
547         break;
548 
549     case ARGP_CHARLIST:
550 
551         /* Get a pointer to the string, point past the string */
552 
553         Opcode = AML_STRING_OP;
554         Arg->Common.Value.String = ACPI_CAST_PTR (char, Aml);
555 
556         /* Find the null terminator */
557 
558         Length = 0;
559         while (Aml[Length])
560         {
561             Length++;
562         }
563         Length++;
564         break;
565 
566     case ARGP_NAME:
567     case ARGP_NAMESTRING:
568 
569         AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP);
570         Arg->Common.Value.Name = AcpiPsGetNextNamestring (ParserState);
571         return_VOID;
572 
573     default:
574 
575         ACPI_ERROR ((AE_INFO, "Invalid ArgType 0x%X", ArgType));
576         return_VOID;
577     }
578 
579     AcpiPsInitOp (Arg, Opcode);
580     ParserState->Aml += Length;
581     return_VOID;
582 }
583 
584 
585 /*******************************************************************************
586  *
587  * FUNCTION:    AcpiPsGetNextField
588  *
589  * PARAMETERS:  ParserState         - Current parser state object
590  *
591  * RETURN:      A newly allocated FIELD op
592  *
593  * DESCRIPTION: Get next field (NamedField, ReservedField, or AccessField)
594  *
595  ******************************************************************************/
596 
597 static ACPI_PARSE_OBJECT *
598 AcpiPsGetNextField (
599     ACPI_PARSE_STATE        *ParserState)
600 {
601     UINT32                  AmlOffset;
602     ACPI_PARSE_OBJECT       *Field;
603     ACPI_PARSE_OBJECT       *Arg = NULL;
604     UINT16                  Opcode;
605     UINT32                  Name;
606     UINT8                   AccessType;
607     UINT8                   AccessAttribute;
608     UINT8                   AccessLength;
609     UINT32                  PkgLength;
610     UINT8                   *PkgEnd;
611     UINT32                  BufferLength;
612 
613 
614     ACPI_FUNCTION_TRACE (PsGetNextField);
615 
616 
617     AmlOffset = (UINT32) ACPI_PTR_DIFF (
618         ParserState->Aml, ParserState->AmlStart);
619 
620     /* Determine field type */
621 
622     switch (ACPI_GET8 (ParserState->Aml))
623     {
624     case AML_FIELD_OFFSET_OP:
625 
626         Opcode = AML_INT_RESERVEDFIELD_OP;
627         ParserState->Aml++;
628         break;
629 
630     case AML_FIELD_ACCESS_OP:
631 
632         Opcode = AML_INT_ACCESSFIELD_OP;
633         ParserState->Aml++;
634         break;
635 
636     case AML_FIELD_CONNECTION_OP:
637 
638         Opcode = AML_INT_CONNECTION_OP;
639         ParserState->Aml++;
640         break;
641 
642     case AML_FIELD_EXT_ACCESS_OP:
643 
644         Opcode = AML_INT_EXTACCESSFIELD_OP;
645         ParserState->Aml++;
646         break;
647 
648     default:
649 
650         Opcode = AML_INT_NAMEDFIELD_OP;
651         break;
652     }
653 
654     /* Allocate a new field op */
655 
656     Field = AcpiPsAllocOp (Opcode);
657     if (!Field)
658     {
659         return_PTR (NULL);
660     }
661 
662     Field->Common.AmlOffset = AmlOffset;
663 
664     /* Decode the field type */
665 
666     switch (Opcode)
667     {
668     case AML_INT_NAMEDFIELD_OP:
669 
670         /* Get the 4-character name */
671 
672         ACPI_MOVE_32_TO_32 (&Name, ParserState->Aml);
673         AcpiPsSetName (Field, Name);
674         ParserState->Aml += ACPI_NAME_SIZE;
675 
676         /* Get the length which is encoded as a package length */
677 
678         Field->Common.Value.Size = AcpiPsGetNextPackageLength (ParserState);
679         break;
680 
681 
682     case AML_INT_RESERVEDFIELD_OP:
683 
684         /* Get the length which is encoded as a package length */
685 
686         Field->Common.Value.Size = AcpiPsGetNextPackageLength (ParserState);
687         break;
688 
689 
690     case AML_INT_ACCESSFIELD_OP:
691     case AML_INT_EXTACCESSFIELD_OP:
692 
693         /*
694          * Get AccessType and AccessAttrib and merge into the field Op
695          * AccessType is first operand, AccessAttribute is second. stuff
696          * these bytes into the node integer value for convenience.
697          */
698 
699         /* Get the two bytes (Type/Attribute) */
700 
701         AccessType = ACPI_GET8 (ParserState->Aml);
702         ParserState->Aml++;
703         AccessAttribute = ACPI_GET8 (ParserState->Aml);
704         ParserState->Aml++;
705 
706         Field->Common.Value.Integer = (UINT8) AccessType;
707         Field->Common.Value.Integer |= (UINT16) (AccessAttribute << 8);
708 
709         /* This opcode has a third byte, AccessLength */
710 
711         if (Opcode == AML_INT_EXTACCESSFIELD_OP)
712         {
713             AccessLength = ACPI_GET8 (ParserState->Aml);
714             ParserState->Aml++;
715 
716             Field->Common.Value.Integer |= (UINT32) (AccessLength << 16);
717         }
718         break;
719 
720 
721     case AML_INT_CONNECTION_OP:
722 
723         /*
724          * Argument for Connection operator can be either a Buffer
725          * (resource descriptor), or a NameString.
726          */
727         if (ACPI_GET8 (ParserState->Aml) == AML_BUFFER_OP)
728         {
729             ParserState->Aml++;
730 
731             PkgEnd = ParserState->Aml;
732             PkgLength = AcpiPsGetNextPackageLength (ParserState);
733             PkgEnd += PkgLength;
734 
735             if (ParserState->Aml < PkgEnd)
736             {
737                 /* Non-empty list */
738 
739                 Arg = AcpiPsAllocOp (AML_INT_BYTELIST_OP);
740                 if (!Arg)
741                 {
742                     AcpiPsFreeOp (Field);
743                     return_PTR (NULL);
744                 }
745 
746                 /* Get the actual buffer length argument */
747 
748                 Opcode = ACPI_GET8 (ParserState->Aml);
749                 ParserState->Aml++;
750 
751                 switch (Opcode)
752                 {
753                 case AML_BYTE_OP:       /* AML_BYTEDATA_ARG */
754 
755                     BufferLength = ACPI_GET8 (ParserState->Aml);
756                     ParserState->Aml += 1;
757                     break;
758 
759                 case AML_WORD_OP:       /* AML_WORDDATA_ARG */
760 
761                     BufferLength = ACPI_GET16 (ParserState->Aml);
762                     ParserState->Aml += 2;
763                     break;
764 
765                 case AML_DWORD_OP:      /* AML_DWORDATA_ARG */
766 
767                     BufferLength = ACPI_GET32 (ParserState->Aml);
768                     ParserState->Aml += 4;
769                     break;
770 
771                 default:
772 
773                     BufferLength = 0;
774                     break;
775                 }
776 
777                 /* Fill in bytelist data */
778 
779                 Arg->Named.Value.Size = BufferLength;
780                 Arg->Named.Data = ParserState->Aml;
781             }
782 
783             /* Skip to End of byte data */
784 
785             ParserState->Aml = PkgEnd;
786         }
787         else
788         {
789             Arg = AcpiPsAllocOp (AML_INT_NAMEPATH_OP);
790             if (!Arg)
791             {
792                 AcpiPsFreeOp (Field);
793                 return_PTR (NULL);
794             }
795 
796             /* Get the Namestring argument */
797 
798             Arg->Common.Value.Name = AcpiPsGetNextNamestring (ParserState);
799         }
800 
801         /* Link the buffer/namestring to parent (CONNECTION_OP) */
802 
803         AcpiPsAppendArg (Field, Arg);
804         break;
805 
806 
807     default:
808 
809         /* Opcode was set in previous switch */
810         break;
811     }
812 
813     return_PTR (Field);
814 }
815 
816 
817 /*******************************************************************************
818  *
819  * FUNCTION:    AcpiPsGetNextArg
820  *
821  * PARAMETERS:  WalkState           - Current state
822  *              ParserState         - Current parser state object
823  *              ArgType             - The argument type (AML_*_ARG)
824  *              ReturnArg           - Where the next arg is returned
825  *
826  * RETURN:      Status, and an op object containing the next argument.
827  *
828  * DESCRIPTION: Get next argument (including complex list arguments that require
829  *              pushing the parser stack)
830  *
831  ******************************************************************************/
832 
833 ACPI_STATUS
834 AcpiPsGetNextArg (
835     ACPI_WALK_STATE         *WalkState,
836     ACPI_PARSE_STATE        *ParserState,
837     UINT32                  ArgType,
838     ACPI_PARSE_OBJECT       **ReturnArg)
839 {
840     ACPI_PARSE_OBJECT       *Arg = NULL;
841     ACPI_PARSE_OBJECT       *Prev = NULL;
842     ACPI_PARSE_OBJECT       *Field;
843     UINT32                  Subop;
844     ACPI_STATUS             Status = AE_OK;
845 
846 
847     ACPI_FUNCTION_TRACE_PTR (PsGetNextArg, ParserState);
848 
849 
850     switch (ArgType)
851     {
852     case ARGP_BYTEDATA:
853     case ARGP_WORDDATA:
854     case ARGP_DWORDDATA:
855     case ARGP_CHARLIST:
856     case ARGP_NAME:
857     case ARGP_NAMESTRING:
858 
859         /* Constants, strings, and namestrings are all the same size */
860 
861         Arg = AcpiPsAllocOp (AML_BYTE_OP);
862         if (!Arg)
863         {
864             return_ACPI_STATUS (AE_NO_MEMORY);
865         }
866         AcpiPsGetNextSimpleArg (ParserState, ArgType, Arg);
867         break;
868 
869     case ARGP_PKGLENGTH:
870 
871         /* Package length, nothing returned */
872 
873         ParserState->PkgEnd = AcpiPsGetNextPackageEnd (ParserState);
874         break;
875 
876     case ARGP_FIELDLIST:
877 
878         if (ParserState->Aml < ParserState->PkgEnd)
879         {
880             /* Non-empty list */
881 
882             while (ParserState->Aml < ParserState->PkgEnd)
883             {
884                 Field = AcpiPsGetNextField (ParserState);
885                 if (!Field)
886                 {
887                     return_ACPI_STATUS (AE_NO_MEMORY);
888                 }
889 
890                 if (Prev)
891                 {
892                     Prev->Common.Next = Field;
893                 }
894                 else
895                 {
896                     Arg = Field;
897                 }
898                 Prev = Field;
899             }
900 
901             /* Skip to End of byte data */
902 
903             ParserState->Aml = ParserState->PkgEnd;
904         }
905         break;
906 
907     case ARGP_BYTELIST:
908 
909         if (ParserState->Aml < ParserState->PkgEnd)
910         {
911             /* Non-empty list */
912 
913             Arg = AcpiPsAllocOp (AML_INT_BYTELIST_OP);
914             if (!Arg)
915             {
916                 return_ACPI_STATUS (AE_NO_MEMORY);
917             }
918 
919             /* Fill in bytelist data */
920 
921             Arg->Common.Value.Size = (UINT32)
922                 ACPI_PTR_DIFF (ParserState->PkgEnd, ParserState->Aml);
923             Arg->Named.Data = ParserState->Aml;
924 
925             /* Skip to End of byte data */
926 
927             ParserState->Aml = ParserState->PkgEnd;
928         }
929         break;
930 
931     case ARGP_TARGET:
932     case ARGP_SUPERNAME:
933     case ARGP_SIMPLENAME:
934 
935         Subop = AcpiPsPeekOpcode (ParserState);
936         if (Subop == 0                  ||
937             AcpiPsIsLeadingChar (Subop) ||
938             ACPI_IS_ROOT_PREFIX (Subop) ||
939             ACPI_IS_PARENT_PREFIX (Subop))
940         {
941             /* NullName or NameString */
942 
943             Arg = AcpiPsAllocOp (AML_INT_NAMEPATH_OP);
944             if (!Arg)
945             {
946                 return_ACPI_STATUS (AE_NO_MEMORY);
947             }
948 
949             /* To support SuperName arg of Unload */
950 
951             if (WalkState->Opcode == AML_UNLOAD_OP)
952             {
953                 Status = AcpiPsGetNextNamepath (WalkState, ParserState, Arg, 1);
954 
955                 /*
956                  * If the SuperName arg of Unload is a method call,
957                  * we have restored the AML pointer, just free this Arg
958                  */
959                 if (Arg->Common.AmlOpcode == AML_INT_METHODCALL_OP)
960                 {
961                     AcpiPsFreeOp (Arg);
962                     Arg = NULL;
963                 }
964             }
965             else
966             {
967                 Status = AcpiPsGetNextNamepath (WalkState, ParserState, Arg, 0);
968             }
969         }
970         else
971         {
972             /* Single complex argument, nothing returned */
973 
974             WalkState->ArgCount = 1;
975         }
976         break;
977 
978     case ARGP_DATAOBJ:
979     case ARGP_TERMARG:
980 
981         /* Single complex argument, nothing returned */
982 
983         WalkState->ArgCount = 1;
984         break;
985 
986     case ARGP_DATAOBJLIST:
987     case ARGP_TERMLIST:
988     case ARGP_OBJLIST:
989 
990         if (ParserState->Aml < ParserState->PkgEnd)
991         {
992             /* Non-empty list of variable arguments, nothing returned */
993 
994             WalkState->ArgCount = ACPI_VAR_ARGS;
995         }
996         break;
997 
998     default:
999 
1000         ACPI_ERROR ((AE_INFO, "Invalid ArgType: 0x%X", ArgType));
1001         Status = AE_AML_OPERAND_TYPE;
1002         break;
1003     }
1004 
1005     *ReturnArg = Arg;
1006     return_ACPI_STATUS (Status);
1007 }
1008