xref: /haiku/src/add-ons/kernel/bus_managers/acpi/acpica/components/parser/psargs.c (revision 385ee03ba83b7a40d315e17b03031b3ca37820c0)
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 - 2016, 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 #include "acpi.h"
117 #include "accommon.h"
118 #include "acparser.h"
119 #include "amlcode.h"
120 #include "acnamesp.h"
121 #include "acdispat.h"
122 
123 #define _COMPONENT          ACPI_PARSER
124         ACPI_MODULE_NAME    ("psargs")
125 
126 /* Local prototypes */
127 
128 static UINT32
129 AcpiPsGetNextPackageLength (
130     ACPI_PARSE_STATE        *ParserState);
131 
132 static ACPI_PARSE_OBJECT *
133 AcpiPsGetNextField (
134     ACPI_PARSE_STATE        *ParserState);
135 
136 
137 /*******************************************************************************
138  *
139  * FUNCTION:    AcpiPsGetNextPackageLength
140  *
141  * PARAMETERS:  ParserState         - Current parser state object
142  *
143  * RETURN:      Decoded package length. On completion, the AML pointer points
144  *              past the length byte or bytes.
145  *
146  * DESCRIPTION: Decode and return a package length field.
147  *              Note: Largest package length is 28 bits, from ACPI specification
148  *
149  ******************************************************************************/
150 
151 static UINT32
152 AcpiPsGetNextPackageLength (
153     ACPI_PARSE_STATE        *ParserState)
154 {
155     UINT8                   *Aml = ParserState->Aml;
156     UINT32                  PackageLength = 0;
157     UINT32                  ByteCount;
158     UINT8                   ByteZeroMask = 0x3F; /* Default [0:5] */
159 
160 
161     ACPI_FUNCTION_TRACE (PsGetNextPackageLength);
162 
163 
164     /*
165      * Byte 0 bits [6:7] contain the number of additional bytes
166      * used to encode the package length, either 0,1,2, or 3
167      */
168     ByteCount = (Aml[0] >> 6);
169     ParserState->Aml += ((ACPI_SIZE) ByteCount + 1);
170 
171     /* Get bytes 3, 2, 1 as needed */
172 
173     while (ByteCount)
174     {
175         /*
176          * Final bit positions for the package length bytes:
177          *      Byte3->[20:27]
178          *      Byte2->[12:19]
179          *      Byte1->[04:11]
180          *      Byte0->[00:03]
181          */
182         PackageLength |= (Aml[ByteCount] << ((ByteCount << 3) - 4));
183 
184         ByteZeroMask = 0x0F; /* Use bits [0:3] of byte 0 */
185         ByteCount--;
186     }
187 
188     /* Byte 0 is a special case, either bits [0:3] or [0:5] are used */
189 
190     PackageLength |= (Aml[0] & ByteZeroMask);
191     return_UINT32 (PackageLength);
192 }
193 
194 
195 /*******************************************************************************
196  *
197  * FUNCTION:    AcpiPsGetNextPackageEnd
198  *
199  * PARAMETERS:  ParserState         - Current parser state object
200  *
201  * RETURN:      Pointer to end-of-package +1
202  *
203  * DESCRIPTION: Get next package length and return a pointer past the end of
204  *              the package. Consumes the package length field
205  *
206  ******************************************************************************/
207 
208 UINT8 *
209 AcpiPsGetNextPackageEnd (
210     ACPI_PARSE_STATE        *ParserState)
211 {
212     UINT8                   *Start = ParserState->Aml;
213     UINT32                  PackageLength;
214 
215 
216     ACPI_FUNCTION_TRACE (PsGetNextPackageEnd);
217 
218 
219     /* Function below updates ParserState->Aml */
220 
221     PackageLength = AcpiPsGetNextPackageLength (ParserState);
222 
223     return_PTR (Start + PackageLength); /* end of package */
224 }
225 
226 
227 /*******************************************************************************
228  *
229  * FUNCTION:    AcpiPsGetNextNamestring
230  *
231  * PARAMETERS:  ParserState         - Current parser state object
232  *
233  * RETURN:      Pointer to the start of the name string (pointer points into
234  *              the AML.
235  *
236  * DESCRIPTION: Get next raw namestring within the AML stream. Handles all name
237  *              prefix characters. Set parser state to point past the string.
238  *              (Name is consumed from the AML.)
239  *
240  ******************************************************************************/
241 
242 char *
243 AcpiPsGetNextNamestring (
244     ACPI_PARSE_STATE        *ParserState)
245 {
246     UINT8                   *Start = ParserState->Aml;
247     UINT8                   *End = ParserState->Aml;
248 
249 
250     ACPI_FUNCTION_TRACE (PsGetNextNamestring);
251 
252 
253     /* Point past any namestring prefix characters (backslash or carat) */
254 
255     while (ACPI_IS_ROOT_PREFIX (*End) ||
256            ACPI_IS_PARENT_PREFIX (*End))
257     {
258         End++;
259     }
260 
261     /* Decode the path prefix character */
262 
263     switch (*End)
264     {
265     case 0:
266 
267         /* NullName */
268 
269         if (End == Start)
270         {
271             Start = NULL;
272         }
273         End++;
274         break;
275 
276     case AML_DUAL_NAME_PREFIX:
277 
278         /* Two name segments */
279 
280         End += 1 + (2 * ACPI_NAME_SIZE);
281         break;
282 
283     case AML_MULTI_NAME_PREFIX_OP:
284 
285         /* Multiple name segments, 4 chars each, count in next byte */
286 
287         End += 2 + (*(End + 1) * ACPI_NAME_SIZE);
288         break;
289 
290     default:
291 
292         /* Single name segment */
293 
294         End += ACPI_NAME_SIZE;
295         break;
296     }
297 
298     ParserState->Aml = End;
299     return_PTR ((char *) Start);
300 }
301 
302 
303 /*******************************************************************************
304  *
305  * FUNCTION:    AcpiPsGetNextNamepath
306  *
307  * PARAMETERS:  ParserState         - Current parser state object
308  *              Arg                 - Where the namepath will be stored
309  *              ArgCount            - If the namepath points to a control method
310  *                                    the method's argument is returned here.
311  *              PossibleMethodCall  - Whether the namepath can possibly be the
312  *                                    start of a method call
313  *
314  * RETURN:      Status
315  *
316  * DESCRIPTION: Get next name (if method call, return # of required args).
317  *              Names are looked up in the internal namespace to determine
318  *              if the name represents a control method. If a method
319  *              is found, the number of arguments to the method is returned.
320  *              This information is critical for parsing to continue correctly.
321  *
322  ******************************************************************************/
323 
324 ACPI_STATUS
325 AcpiPsGetNextNamepath (
326     ACPI_WALK_STATE         *WalkState,
327     ACPI_PARSE_STATE        *ParserState,
328     ACPI_PARSE_OBJECT       *Arg,
329     BOOLEAN                 PossibleMethodCall)
330 {
331     ACPI_STATUS             Status;
332     char                    *Path;
333     ACPI_PARSE_OBJECT       *NameOp;
334     ACPI_OPERAND_OBJECT     *MethodDesc;
335     ACPI_NAMESPACE_NODE     *Node;
336     UINT8                   *Start = ParserState->Aml;
337 
338 
339     ACPI_FUNCTION_TRACE (PsGetNextNamepath);
340 
341 
342     Path = AcpiPsGetNextNamestring (ParserState);
343     AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP);
344 
345     /* Null path case is allowed, just exit */
346 
347     if (!Path)
348     {
349         Arg->Common.Value.Name = Path;
350         return_ACPI_STATUS (AE_OK);
351     }
352 
353     /*
354      * Lookup the name in the internal namespace, starting with the current
355      * scope. We don't want to add anything new to the namespace here,
356      * however, so we use MODE_EXECUTE.
357      * Allow searching of the parent tree, but don't open a new scope -
358      * we just want to lookup the object (must be mode EXECUTE to perform
359      * the upsearch)
360      */
361     Status = AcpiNsLookup (WalkState->ScopeInfo, Path,
362         ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
363         ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL, &Node);
364 
365     /*
366      * If this name is a control method invocation, we must
367      * setup the method call
368      */
369     if (ACPI_SUCCESS (Status) &&
370         PossibleMethodCall &&
371         (Node->Type == ACPI_TYPE_METHOD))
372     {
373         if (WalkState->Opcode == AML_UNLOAD_OP)
374         {
375             /*
376              * AcpiPsGetNextNamestring has increased the AML pointer,
377              * so we need to restore the saved AML pointer for method call.
378              */
379             WalkState->ParserState.Aml = Start;
380             WalkState->ArgCount = 1;
381             AcpiPsInitOp (Arg, AML_INT_METHODCALL_OP);
382             return_ACPI_STATUS (AE_OK);
383         }
384 
385         /* This name is actually a control method invocation */
386 
387         MethodDesc = AcpiNsGetAttachedObject (Node);
388         ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
389             "Control Method - %p Desc %p Path=%p\n", Node, MethodDesc, Path));
390 
391         NameOp = AcpiPsAllocOp (AML_INT_NAMEPATH_OP, Start);
392         if (!NameOp)
393         {
394             return_ACPI_STATUS (AE_NO_MEMORY);
395         }
396 
397         /* Change Arg into a METHOD CALL and attach name to it */
398 
399         AcpiPsInitOp (Arg, AML_INT_METHODCALL_OP);
400         NameOp->Common.Value.Name = Path;
401 
402         /* Point METHODCALL/NAME to the METHOD Node */
403 
404         NameOp->Common.Node = Node;
405         AcpiPsAppendArg (Arg, NameOp);
406 
407         if (!MethodDesc)
408         {
409             ACPI_ERROR ((AE_INFO,
410                 "Control Method %p has no attached object",
411                 Node));
412             return_ACPI_STATUS (AE_AML_INTERNAL);
413         }
414 
415         ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
416             "Control Method - %p Args %X\n",
417             Node, MethodDesc->Method.ParamCount));
418 
419         /* Get the number of arguments to expect */
420 
421         WalkState->ArgCount = MethodDesc->Method.ParamCount;
422         return_ACPI_STATUS (AE_OK);
423     }
424 
425     /*
426      * Special handling if the name was not found during the lookup -
427      * some NotFound cases are allowed
428      */
429     if (Status == AE_NOT_FOUND)
430     {
431         /* 1) NotFound is ok during load pass 1/2 (allow forward references) */
432 
433         if ((WalkState->ParseFlags & ACPI_PARSE_MODE_MASK) !=
434             ACPI_PARSE_EXECUTE)
435         {
436             Status = AE_OK;
437         }
438 
439         /* 2) NotFound during a CondRefOf(x) is ok by definition */
440 
441         else if (WalkState->Op->Common.AmlOpcode == AML_COND_REF_OF_OP)
442         {
443             Status = AE_OK;
444         }
445 
446         /*
447          * 3) NotFound while building a Package is ok at this point, we
448          * may flag as an error later if slack mode is not enabled.
449          * (Some ASL code depends on allowing this behavior)
450          */
451         else if ((Arg->Common.Parent) &&
452             ((Arg->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||
453              (Arg->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP)))
454         {
455             Status = AE_OK;
456         }
457     }
458 
459     /* Final exception check (may have been changed from code above) */
460 
461     if (ACPI_FAILURE (Status))
462     {
463         ACPI_ERROR_NAMESPACE (Path, Status);
464 
465         if ((WalkState->ParseFlags & ACPI_PARSE_MODE_MASK) ==
466             ACPI_PARSE_EXECUTE)
467         {
468             /* Report a control method execution error */
469 
470             Status = AcpiDsMethodError (Status, WalkState);
471         }
472     }
473 
474     /* Save the namepath */
475 
476     Arg->Common.Value.Name = Path;
477     return_ACPI_STATUS (Status);
478 }
479 
480 
481 /*******************************************************************************
482  *
483  * FUNCTION:    AcpiPsGetNextSimpleArg
484  *
485  * PARAMETERS:  ParserState         - Current parser state object
486  *              ArgType             - The argument type (AML_*_ARG)
487  *              Arg                 - Where the argument is returned
488  *
489  * RETURN:      None
490  *
491  * DESCRIPTION: Get the next simple argument (constant, string, or namestring)
492  *
493  ******************************************************************************/
494 
495 void
496 AcpiPsGetNextSimpleArg (
497     ACPI_PARSE_STATE        *ParserState,
498     UINT32                  ArgType,
499     ACPI_PARSE_OBJECT       *Arg)
500 {
501     UINT32                  Length;
502     UINT16                  Opcode;
503     UINT8                   *Aml = ParserState->Aml;
504 
505 
506     ACPI_FUNCTION_TRACE_U32 (PsGetNextSimpleArg, ArgType);
507 
508 
509     switch (ArgType)
510     {
511     case ARGP_BYTEDATA:
512 
513         /* Get 1 byte from the AML stream */
514 
515         Opcode = AML_BYTE_OP;
516         Arg->Common.Value.Integer = (UINT64) *Aml;
517         Length = 1;
518         break;
519 
520     case ARGP_WORDDATA:
521 
522         /* Get 2 bytes from the AML stream */
523 
524         Opcode = AML_WORD_OP;
525         ACPI_MOVE_16_TO_64 (&Arg->Common.Value.Integer, Aml);
526         Length = 2;
527         break;
528 
529     case ARGP_DWORDDATA:
530 
531         /* Get 4 bytes from the AML stream */
532 
533         Opcode = AML_DWORD_OP;
534         ACPI_MOVE_32_TO_64 (&Arg->Common.Value.Integer, Aml);
535         Length = 4;
536         break;
537 
538     case ARGP_QWORDDATA:
539 
540         /* Get 8 bytes from the AML stream */
541 
542         Opcode = AML_QWORD_OP;
543         ACPI_MOVE_64_TO_64 (&Arg->Common.Value.Integer, Aml);
544         Length = 8;
545         break;
546 
547     case ARGP_CHARLIST:
548 
549         /* Get a pointer to the string, point past the string */
550 
551         Opcode = AML_STRING_OP;
552         Arg->Common.Value.String = ACPI_CAST_PTR (char, Aml);
553 
554         /* Find the null terminator */
555 
556         Length = 0;
557         while (Aml[Length])
558         {
559             Length++;
560         }
561         Length++;
562         break;
563 
564     case ARGP_NAME:
565     case ARGP_NAMESTRING:
566 
567         AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP);
568         Arg->Common.Value.Name = AcpiPsGetNextNamestring (ParserState);
569         return_VOID;
570 
571     default:
572 
573         ACPI_ERROR ((AE_INFO, "Invalid ArgType 0x%X", ArgType));
574         return_VOID;
575     }
576 
577     AcpiPsInitOp (Arg, Opcode);
578     ParserState->Aml += Length;
579     return_VOID;
580 }
581 
582 
583 /*******************************************************************************
584  *
585  * FUNCTION:    AcpiPsGetNextField
586  *
587  * PARAMETERS:  ParserState         - Current parser state object
588  *
589  * RETURN:      A newly allocated FIELD op
590  *
591  * DESCRIPTION: Get next field (NamedField, ReservedField, or AccessField)
592  *
593  ******************************************************************************/
594 
595 static ACPI_PARSE_OBJECT *
596 AcpiPsGetNextField (
597     ACPI_PARSE_STATE        *ParserState)
598 {
599     UINT8                   *Aml;
600     ACPI_PARSE_OBJECT       *Field;
601     ACPI_PARSE_OBJECT       *Arg = NULL;
602     UINT16                  Opcode;
603     UINT32                  Name;
604     UINT8                   AccessType;
605     UINT8                   AccessAttribute;
606     UINT8                   AccessLength;
607     UINT32                  PkgLength;
608     UINT8                   *PkgEnd;
609     UINT32                  BufferLength;
610 
611 
612     ACPI_FUNCTION_TRACE (PsGetNextField);
613 
614 
615     Aml = ParserState->Aml;
616 
617     /* Determine field type */
618 
619     switch (ACPI_GET8 (ParserState->Aml))
620     {
621     case AML_FIELD_OFFSET_OP:
622 
623         Opcode = AML_INT_RESERVEDFIELD_OP;
624         ParserState->Aml++;
625         break;
626 
627     case AML_FIELD_ACCESS_OP:
628 
629         Opcode = AML_INT_ACCESSFIELD_OP;
630         ParserState->Aml++;
631         break;
632 
633     case AML_FIELD_CONNECTION_OP:
634 
635         Opcode = AML_INT_CONNECTION_OP;
636         ParserState->Aml++;
637         break;
638 
639     case AML_FIELD_EXT_ACCESS_OP:
640 
641         Opcode = AML_INT_EXTACCESSFIELD_OP;
642         ParserState->Aml++;
643         break;
644 
645     default:
646 
647         Opcode = AML_INT_NAMEDFIELD_OP;
648         break;
649     }
650 
651     /* Allocate a new field op */
652 
653     Field = AcpiPsAllocOp (Opcode, Aml);
654     if (!Field)
655     {
656         return_PTR (NULL);
657     }
658 
659     /* Decode the field type */
660 
661     switch (Opcode)
662     {
663     case AML_INT_NAMEDFIELD_OP:
664 
665         /* Get the 4-character name */
666 
667         ACPI_MOVE_32_TO_32 (&Name, ParserState->Aml);
668         AcpiPsSetName (Field, Name);
669         ParserState->Aml += ACPI_NAME_SIZE;
670 
671         /* Get the length which is encoded as a package length */
672 
673         Field->Common.Value.Size = AcpiPsGetNextPackageLength (ParserState);
674         break;
675 
676 
677     case AML_INT_RESERVEDFIELD_OP:
678 
679         /* Get the length which is encoded as a package length */
680 
681         Field->Common.Value.Size = AcpiPsGetNextPackageLength (ParserState);
682         break;
683 
684 
685     case AML_INT_ACCESSFIELD_OP:
686     case AML_INT_EXTACCESSFIELD_OP:
687 
688         /*
689          * Get AccessType and AccessAttrib and merge into the field Op
690          * AccessType is first operand, AccessAttribute is second. stuff
691          * these bytes into the node integer value for convenience.
692          */
693 
694         /* Get the two bytes (Type/Attribute) */
695 
696         AccessType = ACPI_GET8 (ParserState->Aml);
697         ParserState->Aml++;
698         AccessAttribute = ACPI_GET8 (ParserState->Aml);
699         ParserState->Aml++;
700 
701         Field->Common.Value.Integer = (UINT8) AccessType;
702         Field->Common.Value.Integer |= (UINT16) (AccessAttribute << 8);
703 
704         /* This opcode has a third byte, AccessLength */
705 
706         if (Opcode == AML_INT_EXTACCESSFIELD_OP)
707         {
708             AccessLength = ACPI_GET8 (ParserState->Aml);
709             ParserState->Aml++;
710 
711             Field->Common.Value.Integer |= (UINT32) (AccessLength << 16);
712         }
713         break;
714 
715 
716     case AML_INT_CONNECTION_OP:
717 
718         /*
719          * Argument for Connection operator can be either a Buffer
720          * (resource descriptor), or a NameString.
721          */
722         Aml = ParserState->Aml;
723         if (ACPI_GET8 (ParserState->Aml) == AML_BUFFER_OP)
724         {
725             ParserState->Aml++;
726 
727             PkgEnd = ParserState->Aml;
728             PkgLength = AcpiPsGetNextPackageLength (ParserState);
729             PkgEnd += PkgLength;
730 
731             if (ParserState->Aml < PkgEnd)
732             {
733                 /* Non-empty list */
734 
735                 Arg = AcpiPsAllocOp (AML_INT_BYTELIST_OP, Aml);
736                 if (!Arg)
737                 {
738                     AcpiPsFreeOp (Field);
739                     return_PTR (NULL);
740                 }
741 
742                 /* Get the actual buffer length argument */
743 
744                 Opcode = ACPI_GET8 (ParserState->Aml);
745                 ParserState->Aml++;
746 
747                 switch (Opcode)
748                 {
749                 case AML_BYTE_OP:       /* AML_BYTEDATA_ARG */
750 
751                     BufferLength = ACPI_GET8 (ParserState->Aml);
752                     ParserState->Aml += 1;
753                     break;
754 
755                 case AML_WORD_OP:       /* AML_WORDDATA_ARG */
756 
757                     BufferLength = ACPI_GET16 (ParserState->Aml);
758                     ParserState->Aml += 2;
759                     break;
760 
761                 case AML_DWORD_OP:      /* AML_DWORDATA_ARG */
762 
763                     BufferLength = ACPI_GET32 (ParserState->Aml);
764                     ParserState->Aml += 4;
765                     break;
766 
767                 default:
768 
769                     BufferLength = 0;
770                     break;
771                 }
772 
773                 /* Fill in bytelist data */
774 
775                 Arg->Named.Value.Size = BufferLength;
776                 Arg->Named.Data = ParserState->Aml;
777             }
778 
779             /* Skip to End of byte data */
780 
781             ParserState->Aml = PkgEnd;
782         }
783         else
784         {
785             Arg = AcpiPsAllocOp (AML_INT_NAMEPATH_OP, Aml);
786             if (!Arg)
787             {
788                 AcpiPsFreeOp (Field);
789                 return_PTR (NULL);
790             }
791 
792             /* Get the Namestring argument */
793 
794             Arg->Common.Value.Name = AcpiPsGetNextNamestring (ParserState);
795         }
796 
797         /* Link the buffer/namestring to parent (CONNECTION_OP) */
798 
799         AcpiPsAppendArg (Field, Arg);
800         break;
801 
802 
803     default:
804 
805         /* Opcode was set in previous switch */
806         break;
807     }
808 
809     return_PTR (Field);
810 }
811 
812 
813 /*******************************************************************************
814  *
815  * FUNCTION:    AcpiPsGetNextArg
816  *
817  * PARAMETERS:  WalkState           - Current state
818  *              ParserState         - Current parser state object
819  *              ArgType             - The argument type (AML_*_ARG)
820  *              ReturnArg           - Where the next arg is returned
821  *
822  * RETURN:      Status, and an op object containing the next argument.
823  *
824  * DESCRIPTION: Get next argument (including complex list arguments that require
825  *              pushing the parser stack)
826  *
827  ******************************************************************************/
828 
829 ACPI_STATUS
830 AcpiPsGetNextArg (
831     ACPI_WALK_STATE         *WalkState,
832     ACPI_PARSE_STATE        *ParserState,
833     UINT32                  ArgType,
834     ACPI_PARSE_OBJECT       **ReturnArg)
835 {
836     ACPI_PARSE_OBJECT       *Arg = NULL;
837     ACPI_PARSE_OBJECT       *Prev = NULL;
838     ACPI_PARSE_OBJECT       *Field;
839     UINT32                  Subop;
840     ACPI_STATUS             Status = AE_OK;
841 
842 
843     ACPI_FUNCTION_TRACE_PTR (PsGetNextArg, ParserState);
844 
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                     return_ACPI_STATUS (AE_NO_MEMORY);
885                 }
886 
887                 if (Prev)
888                 {
889                     Prev->Common.Next = Field;
890                 }
891                 else
892                 {
893                     Arg = Field;
894                 }
895                 Prev = Field;
896             }
897 
898             /* Skip to End of byte data */
899 
900             ParserState->Aml = ParserState->PkgEnd;
901         }
902         break;
903 
904     case ARGP_BYTELIST:
905 
906         if (ParserState->Aml < ParserState->PkgEnd)
907         {
908             /* Non-empty list */
909 
910             Arg = AcpiPsAllocOp (AML_INT_BYTELIST_OP,
911                 ParserState->Aml);
912             if (!Arg)
913             {
914                 return_ACPI_STATUS (AE_NO_MEMORY);
915             }
916 
917             /* Fill in bytelist data */
918 
919             Arg->Common.Value.Size = (UINT32)
920                 ACPI_PTR_DIFF (ParserState->PkgEnd, ParserState->Aml);
921             Arg->Named.Data = ParserState->Aml;
922 
923             /* Skip to End of byte data */
924 
925             ParserState->Aml = ParserState->PkgEnd;
926         }
927         break;
928 
929     case ARGP_TARGET:
930     case ARGP_SUPERNAME:
931     case ARGP_SIMPLENAME:
932     case ARGP_NAME_OR_REF:
933 
934         Subop = AcpiPsPeekOpcode (ParserState);
935         if (Subop == 0                  ||
936             AcpiPsIsLeadingChar (Subop) ||
937             ACPI_IS_ROOT_PREFIX (Subop) ||
938             ACPI_IS_PARENT_PREFIX (Subop))
939         {
940             /* NullName or NameString */
941 
942             Arg = AcpiPsAllocOp (AML_INT_NAMEPATH_OP, ParserState->Aml);
943             if (!Arg)
944             {
945                 return_ACPI_STATUS (AE_NO_MEMORY);
946             }
947 
948             /* To support SuperName arg of Unload */
949 
950             if (WalkState->Opcode == AML_UNLOAD_OP)
951             {
952                 Status = AcpiPsGetNextNamepath (WalkState, ParserState,
953                     Arg, ACPI_POSSIBLE_METHOD_CALL);
954 
955                 /*
956                  * If the SuperName argument is a method call, we have
957                  * already 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,
968                     Arg, ACPI_NOT_METHOD_CALL);
969             }
970         }
971         else
972         {
973             /* Single complex argument, nothing returned */
974 
975             WalkState->ArgCount = 1;
976         }
977         break;
978 
979     case ARGP_DATAOBJ:
980     case ARGP_TERMARG:
981 
982         /* Single complex argument, nothing returned */
983 
984         WalkState->ArgCount = 1;
985         break;
986 
987     case ARGP_DATAOBJLIST:
988     case ARGP_TERMLIST:
989     case ARGP_OBJLIST:
990 
991         if (ParserState->Aml < ParserState->PkgEnd)
992         {
993             /* Non-empty list of variable arguments, nothing returned */
994 
995             WalkState->ArgCount = ACPI_VAR_ARGS;
996         }
997         break;
998 
999     default:
1000 
1001         ACPI_ERROR ((AE_INFO, "Invalid ArgType: 0x%X", ArgType));
1002         Status = AE_AML_OPERAND_TYPE;
1003         break;
1004     }
1005 
1006     *ReturnArg = Arg;
1007     return_ACPI_STATUS (Status);
1008 }
1009