1 /******************************************************************************
3 * Module Name: psargs - Parse AML opcode arguments
6 *****************************************************************************/
8 /******************************************************************************
12 * Some or all of this work - Copyright (c) 1999, 2000, 2001, 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 *****************************************************************************/
120 #include "acparser.h"
122 #include "acnamesp.h"
124 #define _COMPONENT ACPI_PARSER
125 MODULE_NAME ("psargs")
128 /*******************************************************************************
130 * FUNCTION: AcpiPsGetNextPackageLength
132 * PARAMETERS: ParserState - Current parser state object
134 * RETURN: Decoded package length. On completion, the AML pointer points
135 * past the length byte or bytes.
137 * DESCRIPTION: Decode and return a package length field
139 ******************************************************************************/
142 AcpiPsGetNextPackageLength (
143 ACPI_PARSE_STATE *ParserState)
145 UINT32 EncodedLength;
149 FUNCTION_TRACE ("PsGetNextPackageLength");
152 EncodedLength = (UINT32) GET8 (ParserState->Aml);
156 switch (EncodedLength >> 6) /* bits 6-7 contain encoding scheme */
158 case 0: /* 1-byte encoding (bits 0-5) */
160 Length = (EncodedLength & 0x3F);
164 case 1: /* 2-byte encoding (next byte + bits 0-3) */
166 Length = ((GET8 (ParserState->Aml) << 04) |
167 (EncodedLength & 0x0F));
172 case 2: /* 3-byte encoding (next 2 bytes + bits 0-3) */
174 Length = ((GET8 (ParserState->Aml + 1) << 12) |
175 (GET8 (ParserState->Aml) << 04) |
176 (EncodedLength & 0x0F));
177 ParserState->Aml += 2;
181 case 3: /* 4-byte encoding (next 3 bytes + bits 0-3) */
183 Length = ((GET8 (ParserState->Aml + 2) << 20) |
184 (GET8 (ParserState->Aml + 1) << 12) |
185 (GET8 (ParserState->Aml) << 04) |
186 (EncodedLength & 0x0F));
187 ParserState->Aml += 3;
191 return_VALUE (Length);
195 /*******************************************************************************
197 * FUNCTION: AcpiPsGetNextPackageEnd
199 * PARAMETERS: ParserState - Current parser state object
201 * RETURN: Pointer to end-of-package +1
203 * DESCRIPTION: Get next package length and return a pointer past the end of
204 * the package. Consumes the package length field
206 ******************************************************************************/
209 AcpiPsGetNextPackageEnd (
210 ACPI_PARSE_STATE *ParserState)
212 UINT8 *Start = ParserState->Aml;
216 FUNCTION_TRACE ("PsGetNextPackageEnd");
219 Length = (NATIVE_UINT) AcpiPsGetNextPackageLength (ParserState);
221 return_PTR (Start + Length); /* end of package */
225 /*******************************************************************************
227 * FUNCTION: AcpiPsGetNextNamestring
229 * PARAMETERS: ParserState - Current parser state object
231 * RETURN: Pointer to the start of the name string (pointer points into
234 * DESCRIPTION: Get next raw namestring within the AML stream. Handles all name
235 * prefix characters. Set parser state to point past the string.
236 * (Name is consumed from the AML.)
238 ******************************************************************************/
241 AcpiPsGetNextNamestring (
242 ACPI_PARSE_STATE *ParserState)
244 UINT8 *Start = ParserState->Aml;
245 UINT8 *End = ParserState->Aml;
249 FUNCTION_TRACE ("PsGetNextNamestring");
252 /* Handle multiple prefix characters */
254 while (AcpiPsIsPrefixChar (GET8 (End)))
256 /* include prefix '\\' or '^' */
261 /* Decode the path */
277 case AML_DUAL_NAME_PREFIX:
279 /* two name segments */
285 case AML_MULTI_NAME_PREFIX_OP:
287 /* multiple name segments */
289 Length = (UINT32) GET8 (End + 1) * 4;
296 /* single name segment */
297 /* assert (AcpiPsIsLead (GET8 (End))); */
303 ParserState->Aml = (UINT8*) End;
305 return_PTR ((NATIVE_CHAR *) Start);
309 /*******************************************************************************
311 * FUNCTION: AcpiPsGetNextNamepath
313 * PARAMETERS: ParserState - Current parser state object
314 * Arg - Where the namepath will be stored
315 * ArgCount - If the namepath points to a control method
316 * the method's argument is returned here.
317 * MethodCall - Whether the namepath can be the start
322 * DESCRIPTION: Get next name (if method call, push appropriate # args). Names
323 * are looked up in either the parsed or internal namespace to
324 * determine if the name represents a control method. If a method
325 * is found, the number of arguments to the method is returned.
326 * This information is critical for parsing to continue correctly.
328 ******************************************************************************/
334 AcpiPsGetNextNamepath (
335 ACPI_PARSE_STATE *ParserState,
336 ACPI_PARSE_OBJECT *Arg,
341 ACPI_PARSE_OBJECT *NameOp;
342 ACPI_PARSE_OBJECT *Op;
343 ACPI_PARSE_OBJECT *Count;
346 FUNCTION_TRACE ("PsGetNextNamepath");
349 Path = AcpiPsGetNextNamestring (ParserState);
350 if (!Path || !MethodCall)
352 /* Null name case, create a null namepath object */
354 AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP);
355 Arg->Value.Name = Path;
360 if (AcpiGbl_ParsedNamespaceRoot)
363 * Lookup the name in the parsed namespace
369 Op = AcpiPsFind (AcpiPsGetParentScope (ParserState),
370 Path, AML_METHOD_OP, 0);
375 if (Op->Opcode == AML_METHOD_OP)
378 * The name refers to a control method, so this namepath is a
379 * method invocation. We need to 1) Get the number of arguments
380 * associated with this method, and 2) Change the NAMEPATH
381 * object into a METHODCALL object.
384 Count = AcpiPsGetArg (Op, 0);
385 if (Count && Count->Opcode == AML_BYTE_OP)
387 NameOp = AcpiPsAllocOp (AML_INT_NAMEPATH_OP);
390 /* Change arg into a METHOD CALL and attach the name */
392 AcpiPsInitOp (Arg, AML_INT_METHODCALL_OP);
394 NameOp->Value.Name = Path;
396 /* Point METHODCALL/NAME to the METHOD Node */
398 NameOp->Node = (ACPI_NAMESPACE_NODE *) Op;
399 AcpiPsAppendArg (Arg, NameOp);
401 *ArgCount = (UINT32) Count->Value.Integer &
402 METHOD_FLAGS_ARG_COUNT;
410 * Else this is normal named object reference.
411 * Just init the NAMEPATH object with the pathname.
419 * Either we didn't find the object in the namespace, or the object is
420 * something other than a control method. Just initialize the Op with the
424 AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP);
425 Arg->Value.Name = Path;
436 AcpiPsGetNextNamepath (
437 ACPI_PARSE_STATE *ParserState,
438 ACPI_PARSE_OBJECT *Arg,
443 ACPI_PARSE_OBJECT *NameOp;
445 ACPI_NAMESPACE_NODE *MethodNode = NULL;
446 ACPI_NAMESPACE_NODE *Node;
447 ACPI_GENERIC_STATE ScopeInfo;
450 FUNCTION_TRACE ("PsGetNextNamepath");
453 Path = AcpiPsGetNextNamestring (ParserState);
454 if (!Path || !MethodCall)
456 /* Null name case, create a null namepath object */
458 AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP);
459 Arg->Value.Name = Path;
467 * Lookup the name in the internal namespace
469 ScopeInfo.Scope.Node = NULL;
470 Node = ParserState->StartNode;
473 ScopeInfo.Scope.Node = Node;
477 * Lookup object. We don't want to add anything new to the namespace
478 * here, however. So we use MODE_EXECUTE. Allow searching of the
479 * parent tree, but don't open a new scope -- we just want to lookup the
480 * object (MUST BE mode EXECUTE to perform upsearch)
483 Status = AcpiNsLookup (&ScopeInfo, Path, ACPI_TYPE_ANY, IMODE_EXECUTE,
484 NS_SEARCH_PARENT | NS_DONT_OPEN_SCOPE, NULL,
486 if (ACPI_SUCCESS (Status))
488 if (Node->Type == ACPI_TYPE_METHOD)
491 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "method - %p Path=%p\n",
494 NameOp = AcpiPsAllocOp (AML_INT_NAMEPATH_OP);
497 /* Change arg into a METHOD CALL and attach name to it */
499 AcpiPsInitOp (Arg, AML_INT_METHODCALL_OP);
501 NameOp->Value.Name = Path;
503 /* Point METHODCALL/NAME to the METHOD Node */
505 NameOp->Node = MethodNode;
506 AcpiPsAppendArg (Arg, NameOp);
508 if (!(ACPI_OPERAND_OBJECT *) MethodNode->Object)
513 *ArgCount = ((ACPI_OPERAND_OBJECT *) MethodNode->Object)->Method.ParamCount;
520 * Else this is normal named object reference.
521 * Just init the NAMEPATH object with the pathname.
528 * Either we didn't find the object in the namespace, or the object is
529 * something other than a control method. Just initialize the Op with the
533 AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP);
534 Arg->Value.Name = Path;
542 /*******************************************************************************
544 * FUNCTION: AcpiPsGetNextSimpleArg
546 * PARAMETERS: ParserState - Current parser state object
547 * ArgType - The argument type (AML_*_ARG)
548 * Arg - Where the argument is returned
552 * DESCRIPTION: Get the next simple argument (constant, string, or namestring)
554 ******************************************************************************/
557 AcpiPsGetNextSimpleArg (
558 ACPI_PARSE_STATE *ParserState,
560 ACPI_PARSE_OBJECT *Arg)
564 FUNCTION_TRACE_U32 ("PsGetNextSimpleArg", ArgType);
572 AcpiPsInitOp (Arg, AML_BYTE_OP);
573 Arg->Value.Integer = (UINT32) GET8 (ParserState->Aml);
580 AcpiPsInitOp (Arg, AML_WORD_OP);
582 /* Get 2 bytes from the AML stream */
584 MOVE_UNALIGNED16_TO_32 (&Arg->Value.Integer, ParserState->Aml);
585 ParserState->Aml += 2;
591 AcpiPsInitOp (Arg, AML_DWORD_OP);
593 /* Get 4 bytes from the AML stream */
595 MOVE_UNALIGNED32_TO_32 (&Arg->Value.Integer, ParserState->Aml);
596 ParserState->Aml += 4;
602 AcpiPsInitOp (Arg, AML_QWORD_OP);
604 /* Get 8 bytes from the AML stream */
606 MOVE_UNALIGNED64_TO_64 (&Arg->Value.Integer, ParserState->Aml);
607 ParserState->Aml += 8;
613 AcpiPsInitOp (Arg, AML_STRING_OP);
614 Arg->Value.String = (char*) ParserState->Aml;
616 while (GET8 (ParserState->Aml) != '\0')
625 case ARGP_NAMESTRING:
627 AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP);
628 Arg->Value.Name = AcpiPsGetNextNamestring (ParserState);
636 /*******************************************************************************
638 * FUNCTION: AcpiPsGetNextField
640 * PARAMETERS: ParserState - Current parser state object
642 * RETURN: A newly allocated FIELD op
644 * DESCRIPTION: Get next field (NamedField, ReservedField, or AccessField)
646 ******************************************************************************/
650 ACPI_PARSE_STATE *ParserState)
652 UINT32 AmlOffset = ParserState->Aml -
653 ParserState->AmlStart;
654 ACPI_PARSE_OBJECT *Field;
659 FUNCTION_TRACE ("PsGetNextField");
662 /* determine field type */
664 switch (GET8 (ParserState->Aml))
669 Opcode = AML_INT_NAMEDFIELD_OP;
675 Opcode = AML_INT_RESERVEDFIELD_OP;
682 Opcode = AML_INT_ACCESSFIELD_OP;
688 /* Allocate a new field op */
690 Field = AcpiPsAllocOp (Opcode);
693 Field->AmlOffset = AmlOffset;
695 /* Decode the field type */
699 case AML_INT_NAMEDFIELD_OP:
701 /* Get the 4-character name */
703 MOVE_UNALIGNED32_TO_32 (&Name, ParserState->Aml);
704 AcpiPsSetName (Field, Name);
705 ParserState->Aml += 4;
707 /* Get the length which is encoded as a package length */
709 Field->Value.Size = AcpiPsGetNextPackageLength (ParserState);
713 case AML_INT_RESERVEDFIELD_OP:
715 /* Get the length which is encoded as a package length */
717 Field->Value.Size = AcpiPsGetNextPackageLength (ParserState);
721 case AML_INT_ACCESSFIELD_OP:
723 /* Get AccessType and AccessAtrib and merge into the field Op */
725 Field->Value.Integer = ((GET8 (ParserState->Aml) << 8) |
726 GET8 (ParserState->Aml));
727 ParserState->Aml += 2;
736 /*******************************************************************************
738 * FUNCTION: AcpiPsGetNextArg
740 * PARAMETERS: ParserState - Current parser state object
741 * ArgType - The argument type (AML_*_ARG)
742 * ArgCount - If the argument points to a control method
743 * the method's argument is returned here.
745 * RETURN: An op object containing the next argument.
747 * DESCRIPTION: Get next argument (including complex list arguments that require
748 * pushing the parser stack)
750 ******************************************************************************/
754 ACPI_PARSE_STATE *ParserState,
758 ACPI_PARSE_OBJECT *Arg = NULL;
759 ACPI_PARSE_OBJECT *Prev = NULL;
760 ACPI_PARSE_OBJECT *Field;
764 FUNCTION_TRACE_PTR ("PsGetNextArg", ParserState);
774 case ARGP_NAMESTRING:
776 /* constants, strings, and namestrings are all the same size */
778 Arg = AcpiPsAllocOp (AML_BYTE_OP);
781 AcpiPsGetNextSimpleArg (ParserState, ArgType, Arg);
788 /* package length, nothing returned */
790 ParserState->PkgEnd = AcpiPsGetNextPackageEnd (ParserState);
796 if (ParserState->Aml < ParserState->PkgEnd)
800 while (ParserState->Aml < ParserState->PkgEnd)
802 Field = AcpiPsGetNextField (ParserState);
821 /* skip to End of byte data */
823 ParserState->Aml = ParserState->PkgEnd;
830 if (ParserState->Aml < ParserState->PkgEnd)
834 Arg = AcpiPsAllocOp (AML_INT_BYTELIST_OP);
837 /* fill in bytelist data */
839 Arg->Value.Size = (ParserState->PkgEnd - ParserState->Aml);
840 ((ACPI_PARSE2_OBJECT *) Arg)->Data = ParserState->Aml;
843 /* skip to End of byte data */
845 ParserState->Aml = ParserState->PkgEnd;
853 Subop = AcpiPsPeekOpcode (ParserState);
855 AcpiPsIsLeadingChar (Subop) ||
856 AcpiPsIsPrefixChar (Subop))
858 /* NullName or NameString */
860 Arg = AcpiPsAllocOp (AML_INT_NAMEPATH_OP);
863 AcpiPsGetNextNamepath (ParserState, Arg, ArgCount, 0);
869 /* single complex argument, nothing returned */
880 /* single complex argument, nothing returned */
886 case ARGP_DATAOBJLIST:
890 if (ParserState->Aml < ParserState->PkgEnd)
892 /* non-empty list of variable arguments, nothing returned */
894 *ArgCount = ACPI_VAR_ARGS;