1 /******************************************************************************
3 * Module Name: psargs - Parse AML opcode arguments
6 *****************************************************************************/
8 /******************************************************************************
12 * Some or all of this work - Copyright (c) 1999 - 2005, Intel Corp.
13 * All rights reserved.
17 * 2.1. This is your license from Intel Corp. under its intellectual property
18 * rights. You may have additional license terms from the party that provided
19 * you this software, covering your right to use that party's intellectual
22 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
23 * copy of the source code appearing in this file ("Covered Code") an
24 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25 * base code distributed originally by Intel ("Original Intel Code") to copy,
26 * make derivatives, distribute, use and display any portion of the Covered
27 * Code in any form, with the right to sublicense such rights; and
29 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30 * license (with the right to sublicense), under only those claims of Intel
31 * patents that are infringed by the Original Intel Code, to make, use, sell,
32 * offer to sell, and import the Covered Code and derivative works thereof
33 * solely to the minimum extent necessary to exercise the above copyright
34 * license, and in no event shall the patent license extend to any additions
35 * to or modifications of the Original Intel Code. No other license or right
36 * is granted directly or by implication, estoppel or otherwise;
38 * The above copyright and patent license is granted only if the following
43 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44 * Redistribution of source code of any substantial portion of the Covered
45 * Code or modification with rights to further distribute source must include
46 * the above Copyright Notice, the above License, this list of Conditions,
47 * and the following Disclaimer and Export Compliance provision. In addition,
48 * Licensee must cause all Covered Code to which Licensee contributes to
49 * contain a file documenting the changes Licensee made to create that Covered
50 * Code and the date of any change. Licensee must include in that file the
51 * documentation of any changes made by any predecessor Licensee. Licensee
52 * must include a prominent statement that the modification is derived,
53 * directly or indirectly, from Original Intel Code.
55 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
56 * Redistribution of source code of any substantial portion of the Covered
57 * Code or modification without rights to further distribute source must
58 * include the following Disclaimer and Export Compliance provision in the
59 * documentation and/or other materials provided with distribution. In
60 * addition, Licensee may not authorize further sublicense of source of any
61 * portion of the Covered Code, and must include terms to the effect that the
62 * license from Licensee to its licensee is limited to the intellectual
63 * property embodied in the software Licensee provides to its licensee, and
64 * not to intellectual property embodied in modifications its licensee may
67 * 3.3. Redistribution of Executable. Redistribution in executable form of any
68 * substantial portion of the Covered Code or modification must reproduce the
69 * above Copyright Notice, and the following Disclaimer and Export Compliance
70 * provision in the documentation and/or other materials provided with the
73 * 3.4. Intel retains all right, title, and interest in and to the Original
76 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
77 * Intel shall be used in advertising or otherwise to promote the sale, use or
78 * other dealings in products derived from or relating to the Covered Code
79 * without prior written authorization from Intel.
81 * 4. Disclaimer and Export Compliance
83 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
84 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
85 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
86 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
87 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
88 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
91 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
93 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
95 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
96 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
97 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
100 * 4.3. Licensee shall not export, either directly or indirectly, any of this
101 * software or system incorporating such software without first obtaining any
102 * required license or other approval from the U. S. Department of Commerce or
103 * any other agency or department of the United States Government. In the
104 * event Licensee exports any such software from the United States or
105 * re-exports any such software from a foreign destination, Licensee shall
106 * ensure that the distribution and export/re-export of the software is in
107 * compliance with all laws, regulations, orders, or other restrictions of the
108 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
109 * any of its subsidiaries will export/re-export any technical data, process,
110 * software, or service, directly or indirectly, to any country for which the
111 * United States government or any agency thereof requires an export license,
112 * other governmental approval, or letter of assurance, without first obtaining
113 * such license, approval or letter.
115 *****************************************************************************/
119 #include <contrib/dev/acpica/acpi.h>
120 #include <contrib/dev/acpica/acparser.h>
121 #include <contrib/dev/acpica/amlcode.h>
122 #include <contrib/dev/acpica/acnamesp.h>
124 #define _COMPONENT ACPI_PARSER
125 ACPI_MODULE_NAME ("psargs")
127 /* Local prototypes */
130 AcpiPsGetNextPackageLength (
131 ACPI_PARSE_STATE *ParserState);
133 static ACPI_PARSE_OBJECT *
135 ACPI_PARSE_STATE *ParserState);
138 /*******************************************************************************
140 * FUNCTION: AcpiPsGetNextPackageLength
142 * PARAMETERS: ParserState - Current parser state object
144 * RETURN: Decoded package length. On completion, the AML pointer points
145 * past the length byte or bytes.
147 * DESCRIPTION: Decode and return a package length field
149 ******************************************************************************/
152 AcpiPsGetNextPackageLength (
153 ACPI_PARSE_STATE *ParserState)
155 UINT32 EncodedLength;
159 ACPI_FUNCTION_TRACE ("PsGetNextPackageLength");
162 EncodedLength = (UINT32) ACPI_GET8 (ParserState->Aml);
165 switch (EncodedLength >> 6) /* bits 6-7 contain encoding scheme */
167 case 0: /* 1-byte encoding (bits 0-5) */
169 Length = (EncodedLength & 0x3F);
173 case 1: /* 2-byte encoding (next byte + bits 0-3) */
175 Length = ((ACPI_GET8 (ParserState->Aml) << 04) |
176 (EncodedLength & 0x0F));
181 case 2: /* 3-byte encoding (next 2 bytes + bits 0-3) */
183 Length = ((ACPI_GET8 (ParserState->Aml + 1) << 12) |
184 (ACPI_GET8 (ParserState->Aml) << 04) |
185 (EncodedLength & 0x0F));
186 ParserState->Aml += 2;
190 case 3: /* 4-byte encoding (next 3 bytes + bits 0-3) */
192 Length = ((ACPI_GET8 (ParserState->Aml + 2) << 20) |
193 (ACPI_GET8 (ParserState->Aml + 1) << 12) |
194 (ACPI_GET8 (ParserState->Aml) << 04) |
195 (EncodedLength & 0x0F));
196 ParserState->Aml += 3;
201 /* Can't get here, only 2 bits / 4 cases */
205 return_UINT32 (Length);
209 /*******************************************************************************
211 * FUNCTION: AcpiPsGetNextPackageEnd
213 * PARAMETERS: ParserState - Current parser state object
215 * RETURN: Pointer to end-of-package +1
217 * DESCRIPTION: Get next package length and return a pointer past the end of
218 * the package. Consumes the package length field
220 ******************************************************************************/
223 AcpiPsGetNextPackageEnd (
224 ACPI_PARSE_STATE *ParserState)
226 UINT8 *Start = ParserState->Aml;
227 ACPI_NATIVE_UINT Length;
230 ACPI_FUNCTION_TRACE ("PsGetNextPackageEnd");
233 /* Function below changes ParserState->Aml */
235 Length = (ACPI_NATIVE_UINT) AcpiPsGetNextPackageLength (ParserState);
237 return_PTR (Start + Length); /* end of package */
241 /*******************************************************************************
243 * FUNCTION: AcpiPsGetNextNamestring
245 * PARAMETERS: ParserState - Current parser state object
247 * RETURN: Pointer to the start of the name string (pointer points into
250 * DESCRIPTION: Get next raw namestring within the AML stream. Handles all name
251 * prefix characters. Set parser state to point past the string.
252 * (Name is consumed from the AML.)
254 ******************************************************************************/
257 AcpiPsGetNextNamestring (
258 ACPI_PARSE_STATE *ParserState)
260 UINT8 *Start = ParserState->Aml;
261 UINT8 *End = ParserState->Aml;
264 ACPI_FUNCTION_TRACE ("PsGetNextNamestring");
267 /* Handle multiple prefix characters */
269 while (AcpiPsIsPrefixChar (ACPI_GET8 (End)))
271 /* Include prefix '\\' or '^' */
276 /* Decode the path */
278 switch (ACPI_GET8 (End))
291 case AML_DUAL_NAME_PREFIX:
293 /* Two name segments */
295 End += 1 + (2 * ACPI_NAME_SIZE);
298 case AML_MULTI_NAME_PREFIX_OP:
300 /* Multiple name segments, 4 chars each */
302 End += 2 + ((ACPI_SIZE) ACPI_GET8 (End + 1) * ACPI_NAME_SIZE);
307 /* Single name segment */
309 End += ACPI_NAME_SIZE;
313 ParserState->Aml = (UINT8*) End;
314 return_PTR ((char *) Start);
318 /*******************************************************************************
320 * FUNCTION: AcpiPsGetNextNamepath
322 * PARAMETERS: ParserState - Current parser state object
323 * Arg - Where the namepath will be stored
324 * ArgCount - If the namepath points to a control method
325 * the method's argument is returned here.
326 * MethodCall - Whether the namepath can possibly be the
327 * start of a method call
331 * DESCRIPTION: Get next name (if method call, return # of required args).
332 * Names are looked up in the internal namespace to determine
333 * if the name represents a control method. If a method
334 * is found, the number of arguments to the method is returned.
335 * This information is critical for parsing to continue correctly.
337 ******************************************************************************/
340 AcpiPsGetNextNamepath (
341 ACPI_WALK_STATE *WalkState,
342 ACPI_PARSE_STATE *ParserState,
343 ACPI_PARSE_OBJECT *Arg,
347 ACPI_PARSE_OBJECT *NameOp;
348 ACPI_STATUS Status = AE_OK;
349 ACPI_OPERAND_OBJECT *MethodDesc;
350 ACPI_NAMESPACE_NODE *Node;
351 ACPI_GENERIC_STATE ScopeInfo;
354 ACPI_FUNCTION_TRACE ("PsGetNextNamepath");
357 Path = AcpiPsGetNextNamestring (ParserState);
359 /* Null path case is allowed */
364 * Lookup the name in the internal namespace
366 ScopeInfo.Scope.Node = NULL;
367 Node = ParserState->StartNode;
370 ScopeInfo.Scope.Node = Node;
374 * Lookup object. We don't want to add anything new to the namespace
375 * here, however. So we use MODE_EXECUTE. Allow searching of the
376 * parent tree, but don't open a new scope -- we just want to lookup the
377 * object (MUST BE mode EXECUTE to perform upsearch)
379 Status = AcpiNsLookup (&ScopeInfo, Path, ACPI_TYPE_ANY,
381 ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
383 if (ACPI_SUCCESS (Status) && MethodCall)
385 if (Node->Type == ACPI_TYPE_METHOD)
387 /* This name is actually a control method invocation */
389 MethodDesc = AcpiNsGetAttachedObject (Node);
390 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
391 "Control Method - %p Desc %p Path=%p\n",
392 Node, MethodDesc, Path));
394 NameOp = AcpiPsAllocOp (AML_INT_NAMEPATH_OP);
397 return_ACPI_STATUS (AE_NO_MEMORY);
400 /* Change arg into a METHOD CALL and attach name to it */
402 AcpiPsInitOp (Arg, AML_INT_METHODCALL_OP);
403 NameOp->Common.Value.Name = Path;
405 /* Point METHODCALL/NAME to the METHOD Node */
407 NameOp->Common.Node = Node;
408 AcpiPsAppendArg (Arg, NameOp);
413 "PsGetNextNamepath: Control Method %p has no attached object\n",
415 return_ACPI_STATUS (AE_AML_INTERNAL);
418 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
419 "Control Method - %p Args %X\n",
420 Node, MethodDesc->Method.ParamCount));
422 /* Get the number of arguments to expect */
424 WalkState->ArgCount = MethodDesc->Method.ParamCount;
425 return_ACPI_STATUS (AE_OK);
429 * Else this is normal named object reference.
430 * Just init the NAMEPATH object with the pathname.
435 if (ACPI_FAILURE (Status))
438 * 1) Any error other than NOT_FOUND is always severe
439 * 2) NOT_FOUND is only important if we are executing a method.
440 * 3) If executing a CondRefOf opcode, NOT_FOUND is ok.
442 if ((((WalkState->ParseFlags & ACPI_PARSE_MODE_MASK) == ACPI_PARSE_EXECUTE) &&
443 (Status == AE_NOT_FOUND) &&
444 (WalkState->Op->Common.AmlOpcode != AML_COND_REF_OF_OP)) ||
446 (Status != AE_NOT_FOUND))
448 ACPI_REPORT_NSERROR (Path, Status);
450 AcpiOsPrintf ("SearchNode %p StartNode %p ReturnNode %p\n",
451 ScopeInfo.Scope.Node, ParserState->StartNode, Node);
458 * We got a NOT_FOUND during table load or we encountered
459 * a CondRefOf(x) where the target does not exist.
468 * Regardless of success/failure above,
469 * Just initialize the Op with the pathname.
471 AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP);
472 Arg->Common.Value.Name = Path;
474 return_ACPI_STATUS (Status);
478 /*******************************************************************************
480 * FUNCTION: AcpiPsGetNextSimpleArg
482 * PARAMETERS: ParserState - Current parser state object
483 * ArgType - The argument type (AML_*_ARG)
484 * Arg - Where the argument is returned
488 * DESCRIPTION: Get the next simple argument (constant, string, or namestring)
490 ******************************************************************************/
493 AcpiPsGetNextSimpleArg (
494 ACPI_PARSE_STATE *ParserState,
496 ACPI_PARSE_OBJECT *Arg)
499 ACPI_FUNCTION_TRACE_U32 ("PsGetNextSimpleArg", ArgType);
506 AcpiPsInitOp (Arg, AML_BYTE_OP);
507 Arg->Common.Value.Integer = (UINT32) ACPI_GET8 (ParserState->Aml);
514 AcpiPsInitOp (Arg, AML_WORD_OP);
516 /* Get 2 bytes from the AML stream */
518 ACPI_MOVE_16_TO_32 (&Arg->Common.Value.Integer, ParserState->Aml);
519 ParserState->Aml += 2;
525 AcpiPsInitOp (Arg, AML_DWORD_OP);
527 /* Get 4 bytes from the AML stream */
529 ACPI_MOVE_32_TO_32 (&Arg->Common.Value.Integer, ParserState->Aml);
530 ParserState->Aml += 4;
536 AcpiPsInitOp (Arg, AML_QWORD_OP);
538 /* Get 8 bytes from the AML stream */
540 ACPI_MOVE_64_TO_64 (&Arg->Common.Value.Integer, ParserState->Aml);
541 ParserState->Aml += 8;
547 AcpiPsInitOp (Arg, AML_STRING_OP);
548 Arg->Common.Value.String = (char *) ParserState->Aml;
550 while (ACPI_GET8 (ParserState->Aml) != '\0')
559 case ARGP_NAMESTRING:
561 AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP);
562 Arg->Common.Value.Name = AcpiPsGetNextNamestring (ParserState);
568 ACPI_REPORT_ERROR (("Invalid ArgType %X\n", ArgType));
576 /*******************************************************************************
578 * FUNCTION: AcpiPsGetNextField
580 * PARAMETERS: ParserState - Current parser state object
582 * RETURN: A newly allocated FIELD op
584 * DESCRIPTION: Get next field (NamedField, ReservedField, or AccessField)
586 ******************************************************************************/
588 static ACPI_PARSE_OBJECT *
590 ACPI_PARSE_STATE *ParserState)
592 UINT32 AmlOffset = (UINT32)
593 ACPI_PTR_DIFF (ParserState->Aml,
594 ParserState->AmlStart);
595 ACPI_PARSE_OBJECT *Field;
600 ACPI_FUNCTION_TRACE ("PsGetNextField");
603 /* Determine field type */
605 switch (ACPI_GET8 (ParserState->Aml))
609 Opcode = AML_INT_NAMEDFIELD_OP;
614 Opcode = AML_INT_RESERVEDFIELD_OP;
620 Opcode = AML_INT_ACCESSFIELD_OP;
625 /* Allocate a new field op */
627 Field = AcpiPsAllocOp (Opcode);
633 Field->Common.AmlOffset = AmlOffset;
635 /* Decode the field type */
639 case AML_INT_NAMEDFIELD_OP:
641 /* Get the 4-character name */
643 ACPI_MOVE_32_TO_32 (&Name, ParserState->Aml);
644 AcpiPsSetName (Field, Name);
645 ParserState->Aml += ACPI_NAME_SIZE;
647 /* Get the length which is encoded as a package length */
649 Field->Common.Value.Size = AcpiPsGetNextPackageLength (ParserState);
653 case AML_INT_RESERVEDFIELD_OP:
655 /* Get the length which is encoded as a package length */
657 Field->Common.Value.Size = AcpiPsGetNextPackageLength (ParserState);
661 case AML_INT_ACCESSFIELD_OP:
664 * Get AccessType and AccessAttrib and merge into the field Op
665 * AccessType is first operand, AccessAttribute is second
667 Field->Common.Value.Integer = (ACPI_GET8 (ParserState->Aml) << 8);
669 Field->Common.Value.Integer |= ACPI_GET8 (ParserState->Aml);
675 /* Opcode was set in previous switch */
683 /*******************************************************************************
685 * FUNCTION: AcpiPsGetNextArg
687 * PARAMETERS: WalkState - Current state
688 * ParserState - Current parser state object
689 * ArgType - The argument type (AML_*_ARG)
690 * ReturnArg - Where the next arg is returned
692 * RETURN: Status, and an op object containing the next argument.
694 * DESCRIPTION: Get next argument (including complex list arguments that require
695 * pushing the parser stack)
697 ******************************************************************************/
701 ACPI_WALK_STATE *WalkState,
702 ACPI_PARSE_STATE *ParserState,
704 ACPI_PARSE_OBJECT **ReturnArg)
706 ACPI_PARSE_OBJECT *Arg = NULL;
707 ACPI_PARSE_OBJECT *Prev = NULL;
708 ACPI_PARSE_OBJECT *Field;
710 ACPI_STATUS Status = AE_OK;
713 ACPI_FUNCTION_TRACE_PTR ("PsGetNextArg", ParserState);
723 case ARGP_NAMESTRING:
725 /* Constants, strings, and namestrings are all the same size */
727 Arg = AcpiPsAllocOp (AML_BYTE_OP);
730 return_ACPI_STATUS (AE_NO_MEMORY);
732 AcpiPsGetNextSimpleArg (ParserState, ArgType, Arg);
738 /* Package length, nothing returned */
740 ParserState->PkgEnd = AcpiPsGetNextPackageEnd (ParserState);
746 if (ParserState->Aml < ParserState->PkgEnd)
750 while (ParserState->Aml < ParserState->PkgEnd)
752 Field = AcpiPsGetNextField (ParserState);
755 return_ACPI_STATUS (AE_NO_MEMORY);
760 Prev->Common.Next = Field;
769 /* Skip to End of byte data */
771 ParserState->Aml = ParserState->PkgEnd;
778 if (ParserState->Aml < ParserState->PkgEnd)
782 Arg = AcpiPsAllocOp (AML_INT_BYTELIST_OP);
785 return_ACPI_STATUS (AE_NO_MEMORY);
788 /* Fill in bytelist data */
790 Arg->Common.Value.Size = (UINT32)
791 ACPI_PTR_DIFF (ParserState->PkgEnd, ParserState->Aml);
792 Arg->Named.Data = ParserState->Aml;
794 /* Skip to End of byte data */
796 ParserState->Aml = ParserState->PkgEnd;
803 case ARGP_SIMPLENAME:
805 Subop = AcpiPsPeekOpcode (ParserState);
807 AcpiPsIsLeadingChar (Subop) ||
808 AcpiPsIsPrefixChar (Subop))
810 /* NullName or NameString */
812 Arg = AcpiPsAllocOp (AML_INT_NAMEPATH_OP);
815 return_ACPI_STATUS (AE_NO_MEMORY);
818 Status = AcpiPsGetNextNamepath (WalkState, ParserState, Arg, 0);
822 /* Single complex argument, nothing returned */
824 WalkState->ArgCount = 1;
832 /* Single complex argument, nothing returned */
834 WalkState->ArgCount = 1;
838 case ARGP_DATAOBJLIST:
842 if (ParserState->Aml < ParserState->PkgEnd)
844 /* Non-empty list of variable arguments, nothing returned */
846 WalkState->ArgCount = ACPI_VAR_ARGS;
853 ACPI_REPORT_ERROR (("Invalid ArgType: %X\n", ArgType));
854 Status = AE_AML_OPERAND_TYPE;
859 return_ACPI_STATUS (Status);