1 /******************************************************************************
3 * Module Name: asllookup- Namespace lookup
5 *****************************************************************************/
7 /******************************************************************************
11 * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp.
12 * All rights reserved.
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
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
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;
37 * The above copyright and patent license is granted only if the following
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.
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
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
72 * 3.4. Intel retains all right, title, and interest in and to the Original
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.
80 * 4. Disclaimer and Export Compliance
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
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
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.
114 *****************************************************************************/
117 #include "aslcompiler.h"
118 #include "aslcompiler.y.h"
120 #include "acparser.h"
122 #include "acnamesp.h"
123 #include "acdispat.h"
126 #define _COMPONENT ACPI_COMPILER
127 ACPI_MODULE_NAME ("asllookup")
129 /* Local prototypes */
132 LsCompareOneNamespaceObject (
133 ACPI_HANDLE ObjHandle
,
139 LsDoOneNamespaceObject (
140 ACPI_HANDLE ObjHandle
,
151 ACPI_PARSE_OBJECT
*Op
,
152 UINT32 RegionBitLength
,
153 UINT32 FieldBitOffset
,
154 UINT32 FieldBitLength
,
155 UINT32 AccessBitWidth
);
158 LkNamespaceLocateBegin (
159 ACPI_PARSE_OBJECT
*Op
,
164 LkNamespaceLocateEnd (
165 ACPI_PARSE_OBJECT
*Op
,
171 ACPI_HANDLE ObjHandle
,
178 ACPI_HANDLE ObjHandle
,
189 ACPI_PARSE_OBJECT
*Op
);
192 /*******************************************************************************
194 * FUNCTION: LsDoOneNamespaceObject
196 * PARAMETERS: ACPI_WALK_CALLBACK
200 * DESCRIPTION: Dump a namespace object to the namespace output file.
201 * Called during the walk of the namespace to dump all objects.
203 ******************************************************************************/
206 LsDoOneNamespaceObject (
207 ACPI_HANDLE ObjHandle
,
212 ACPI_NAMESPACE_NODE
*Node
= (ACPI_NAMESPACE_NODE
*) ObjHandle
;
213 ACPI_OPERAND_OBJECT
*ObjDesc
;
214 ACPI_PARSE_OBJECT
*Op
;
217 Gbl_NumNamespaceObjects
++;
219 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT
, "%5d [%d] %*s %4.4s - %s",
220 Gbl_NumNamespaceObjects
, Level
, (Level
* 3), " ",
222 AcpiUtGetTypeName (Node
->Type
));
225 ObjDesc
= ACPI_CAST_PTR (ACPI_OPERAND_OBJECT
, Node
->Object
);
229 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT
, "\n");
235 (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc
) == ACPI_DESC_TYPE_OPERAND
))
239 case ACPI_TYPE_INTEGER
:
241 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT
,
242 " [Initial Value 0x%8.8X%8.8X]",
243 ACPI_FORMAT_UINT64 (ObjDesc
->Integer
.Value
));
247 case ACPI_TYPE_STRING
:
249 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT
,
250 " [Initial Value \"%s\"]",
251 ObjDesc
->String
.Pointer
);
255 /* Nothing to do for other types */
264 case ACPI_TYPE_INTEGER
:
266 if (Op
->Asl
.ParseOpcode
== PARSEOP_NAME
)
270 if ((Op
->Asl
.ParseOpcode
== PARSEOP_NAMESEG
) ||
271 (Op
->Asl
.ParseOpcode
== PARSEOP_NAMESTRING
))
275 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT
,
276 " [Initial Value 0x%8.8X%8.8X]",
277 ACPI_FORMAT_UINT64 (Op
->Asl
.Value
.Integer
));
281 case ACPI_TYPE_STRING
:
283 if (Op
->Asl
.ParseOpcode
== PARSEOP_NAME
)
287 if ((Op
->Asl
.ParseOpcode
== PARSEOP_NAMESEG
) ||
288 (Op
->Asl
.ParseOpcode
== PARSEOP_NAMESTRING
))
292 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT
,
293 " [Initial Value \"%s\"]",
294 Op
->Asl
.Value
.String
);
298 case ACPI_TYPE_LOCAL_REGION_FIELD
:
300 if ((Op
->Asl
.ParseOpcode
== PARSEOP_NAMESEG
) ||
301 (Op
->Asl
.ParseOpcode
== PARSEOP_NAMESTRING
))
305 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT
,
306 " [Offset 0x%04X Length 0x%04X bits]",
307 Op
->Asl
.Parent
->Asl
.ExtraValue
, (UINT32
) Op
->Asl
.Value
.Integer
);
311 case ACPI_TYPE_BUFFER_FIELD
:
313 switch (Op
->Asl
.ParseOpcode
)
315 case PARSEOP_CREATEBYTEFIELD
:
316 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT
, " [BYTE ( 8 bit)]");
319 case PARSEOP_CREATEDWORDFIELD
:
320 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT
, " [DWORD (32 bit)]");
323 case PARSEOP_CREATEQWORDFIELD
:
324 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT
, " [QWORD (64 bit)]");
327 case PARSEOP_CREATEWORDFIELD
:
328 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT
, " [WORD (16 bit)]");
331 case PARSEOP_CREATEBITFIELD
:
332 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT
, " [BIT ( 1 bit)]");
335 case PARSEOP_CREATEFIELD
:
336 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT
, " [Arbitrary Bit Field]");
346 case ACPI_TYPE_PACKAGE
:
348 if (Op
->Asl
.ParseOpcode
== PARSEOP_NAME
)
352 if ((Op
->Asl
.ParseOpcode
== PARSEOP_NAMESEG
) ||
353 (Op
->Asl
.ParseOpcode
== PARSEOP_NAMESTRING
))
359 if ((Op
->Asl
.ParseOpcode
== PARSEOP_BYTECONST
) ||
360 (Op
->Asl
.ParseOpcode
== PARSEOP_RAW_DATA
))
362 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT
,
363 " [Initial Length 0x%.2X elements]",
364 Op
->Asl
.Value
.Integer
);
369 case ACPI_TYPE_BUFFER
:
371 if (Op
->Asl
.ParseOpcode
== PARSEOP_NAME
)
375 if ((Op
->Asl
.ParseOpcode
== PARSEOP_NAMESEG
) ||
376 (Op
->Asl
.ParseOpcode
== PARSEOP_NAMESTRING
))
382 if (Op
&& (Op
->Asl
.ParseOpcode
== PARSEOP_INTEGER
))
384 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT
,
385 " [Initial Length 0x%.2X bytes]",
386 Op
->Asl
.Value
.Integer
);
391 case ACPI_TYPE_METHOD
:
393 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT
,
394 " [Code Length 0x%.4X bytes]",
395 Op
->Asl
.AmlSubtreeLength
);
399 case ACPI_TYPE_LOCAL_RESOURCE
:
401 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT
,
402 " [Desc Offset 0x%.4X Bytes]", Node
->Value
);
406 case ACPI_TYPE_LOCAL_RESOURCE_FIELD
:
408 if (Node
->Flags
& 0x80)
410 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT
,
411 " [Field Offset 0x%.4X Bits 0x%.4X Bytes]",
412 Node
->Value
, Node
->Value
/ 8);
416 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT
,
417 " [Field Offset 0x%.4X Bytes]", Node
->Value
);
423 /* Nothing to do for other types */
428 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT
, "\n");
433 /*******************************************************************************
435 * FUNCTION: LsSetupNsList
437 * PARAMETERS: Handle - local file handle
441 * DESCRIPTION: Set the namespace output file to the input handle
443 ******************************************************************************/
450 Gbl_NsOutputFlag
= TRUE
;
451 Gbl_Files
[ASL_FILE_NAMESPACE_OUTPUT
].Handle
= Handle
;
455 /*******************************************************************************
457 * FUNCTION: LsDoOnePathname
459 * PARAMETERS: ACPI_WALK_CALLBACK
463 * DESCRIPTION: Print the full pathname for a namespace node.
465 ******************************************************************************/
469 ACPI_HANDLE ObjHandle
,
474 ACPI_NAMESPACE_NODE
*Node
= (ACPI_NAMESPACE_NODE
*) ObjHandle
;
476 ACPI_BUFFER TargetPath
;
479 TargetPath
.Length
= ACPI_ALLOCATE_LOCAL_BUFFER
;
480 Status
= AcpiNsHandleToPathname (Node
, &TargetPath
);
481 if (ACPI_FAILURE (Status
))
486 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT
, "%s\n", TargetPath
.Pointer
);
487 ACPI_FREE (TargetPath
.Pointer
);
493 /*******************************************************************************
495 * FUNCTION: LsDisplayNamespace
501 * DESCRIPTION: Walk the namespace an display information about each node
502 * in the tree. Information is written to the optional
503 * namespace output file.
505 ******************************************************************************/
514 if (!Gbl_NsOutputFlag
)
519 Gbl_NumNamespaceObjects
= 0;
523 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT
, "Contents of ACPI Namespace\n\n");
524 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT
, "Count Depth Name - Type\n\n");
526 /* Walk entire namespace from the root */
528 Status
= AcpiNsWalkNamespace (ACPI_TYPE_ANY
, ACPI_ROOT_OBJECT
,
529 ACPI_UINT32_MAX
, FALSE
, LsDoOneNamespaceObject
,
532 /* Print the full pathname for each namespace node */
534 FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT
, "\nNamespace pathnames\n\n");
536 Status
= AcpiNsWalkNamespace (ACPI_TYPE_ANY
, ACPI_ROOT_OBJECT
,
537 ACPI_UINT32_MAX
, FALSE
, LsDoOnePathname
,
544 /*******************************************************************************
546 * FUNCTION: LsCompareOneNamespaceObject
548 * PARAMETERS: ACPI_WALK_CALLBACK
552 * DESCRIPTION: Compare name of one object.
554 ******************************************************************************/
557 LsCompareOneNamespaceObject (
558 ACPI_HANDLE ObjHandle
,
563 ACPI_NAMESPACE_NODE
*Node
= (ACPI_NAMESPACE_NODE
*) ObjHandle
;
566 /* Simply check the name */
568 if (*((UINT32
*) (Context
)) == Node
->Name
.Integer
)
570 /* Abort walk if we found one instance */
572 return (AE_CTRL_TRUE
);
579 /*******************************************************************************
581 * FUNCTION: LkObjectExists
583 * PARAMETERS: Name - 4 char ACPI name
585 * RETURN: TRUE if name exists in namespace
587 * DESCRIPTION: Walk the namespace to find an object
589 ******************************************************************************/
598 /* Walk entire namespace from the supplied root */
600 Status
= AcpiNsWalkNamespace (ACPI_TYPE_ANY
, ACPI_ROOT_OBJECT
,
601 ACPI_UINT32_MAX
, FALSE
, LsCompareOneNamespaceObject
,
603 if (Status
== AE_CTRL_TRUE
)
605 /* At least one instance of the name was found */
614 /*******************************************************************************
616 * FUNCTION: LkGetNameOp
618 * PARAMETERS: Op - Current Op
620 * RETURN: NameOp associated with the input op
622 * DESCRIPTION: Find the name declaration op associated with the operator
624 ******************************************************************************/
628 ACPI_PARSE_OBJECT
*Op
)
630 const ACPI_OPCODE_INFO
*OpInfo
;
631 ACPI_PARSE_OBJECT
*NameOp
= Op
;
634 OpInfo
= AcpiPsGetOpcodeInfo (Op
->Asl
.AmlOpcode
);
637 /* Get the NamePath from the appropriate place */
639 if (OpInfo
->Flags
& AML_NAMED
)
641 /* For nearly all NAMED operators, the name reference is the first child */
643 NameOp
= Op
->Asl
.Child
;
644 if (Op
->Asl
.AmlOpcode
== AML_ALIAS_OP
)
647 * ALIAS is the only oddball opcode, the name declaration
648 * (alias name) is the second operand
650 NameOp
= Op
->Asl
.Child
->Asl
.Next
;
653 else if (OpInfo
->Flags
& AML_CREATE
)
655 /* Name must appear as the last parameter */
657 NameOp
= Op
->Asl
.Child
;
658 while (!(NameOp
->Asl
.CompileFlags
& NODE_IS_NAME_DECLARATION
))
660 NameOp
= NameOp
->Asl
.Next
;
668 /*******************************************************************************
670 * FUNCTION: LkIsObjectUsed
672 * PARAMETERS: ACPI_WALK_CALLBACK
676 * DESCRIPTION: Check for an unreferenced namespace object and emit a warning.
677 * We have to be careful, because some types and names are
678 * typically or always unreferenced, we don't want to issue
679 * excessive warnings.
681 ******************************************************************************/
685 ACPI_HANDLE ObjHandle
,
690 ACPI_NAMESPACE_NODE
*Node
= ACPI_CAST_PTR (ACPI_NAMESPACE_NODE
, ObjHandle
);
693 /* Referenced flag is set during the namespace xref */
695 if (Node
->Flags
& ANOBJ_IS_REFERENCED
)
701 * Ignore names that start with an underscore,
702 * these are the reserved ACPI names and are typically not referenced,
703 * they are called by the host OS.
705 if (Node
->Name
.Ascii
[0] == '_')
710 /* There are some types that are typically not referenced, ignore them */
714 case ACPI_TYPE_DEVICE
:
715 case ACPI_TYPE_PROCESSOR
:
716 case ACPI_TYPE_POWER
:
717 case ACPI_TYPE_LOCAL_RESOURCE
:
724 /* All others are valid unreferenced namespace objects */
728 AslError (ASL_WARNING2
, ASL_MSG_NOT_REFERENCED
, LkGetNameOp (Node
->Op
), NULL
);
734 /*******************************************************************************
736 * FUNCTION: LkFindUnreferencedObjects
742 * DESCRIPTION: Namespace walk to find objects that are not referenced in any
743 * way. Must be called after the namespace has been cross
746 ******************************************************************************/
749 LkFindUnreferencedObjects (
753 /* Walk entire namespace from the supplied root */
755 (void) AcpiNsWalkNamespace (ACPI_TYPE_ANY
, ACPI_ROOT_OBJECT
,
756 ACPI_UINT32_MAX
, FALSE
, LkIsObjectUsed
,
761 /*******************************************************************************
763 * FUNCTION: LkCrossReferenceNamespace
769 * DESCRIPTION: Perform a cross reference check of the parse tree against the
770 * namespace. Every named referenced within the parse tree
771 * should be get resolved with a namespace lookup. If not, the
772 * original reference in the ASL code is invalid -- i.e., refers
773 * to a non-existent object.
775 * NOTE: The ASL "External" operator causes the name to be inserted into the
776 * namespace so that references to the external name will be resolved
779 ******************************************************************************/
782 LkCrossReferenceNamespace (
785 ACPI_WALK_STATE
*WalkState
;
788 DbgPrint (ASL_DEBUG_OUTPUT
, "\nCross referencing namespace\n\n");
791 * Create a new walk state for use when looking up names
792 * within the namespace (Passed as context to the callbacks)
794 WalkState
= AcpiDsCreateWalkState (0, NULL
, NULL
, NULL
);
800 /* Walk the entire parse tree */
802 TrWalkParseTree (RootNode
, ASL_WALK_VISIT_TWICE
, LkNamespaceLocateBegin
,
803 LkNamespaceLocateEnd
, WalkState
);
808 /*******************************************************************************
810 * FUNCTION: LkCheckFieldRange
812 * PARAMETERS: RegionBitLength - Length of entire parent region
813 * FieldBitOffset - Start of the field unit (within region)
814 * FieldBitLength - Entire length of field unit
815 * AccessBitWidth - Access width of the field unit
819 * DESCRIPTION: Check one field unit to make sure it fits in the parent
822 * Note: AccessBitWidth must be either 8,16,32, or 64
824 ******************************************************************************/
828 ACPI_PARSE_OBJECT
*Op
,
829 UINT32 RegionBitLength
,
830 UINT32 FieldBitOffset
,
831 UINT32 FieldBitLength
,
832 UINT32 AccessBitWidth
)
834 UINT32 FieldEndBitOffset
;
838 * Check each field unit against the region size. The entire
839 * field unit (start offset plus length) must fit within the
842 FieldEndBitOffset
= FieldBitOffset
+ FieldBitLength
;
844 if (FieldEndBitOffset
> RegionBitLength
)
846 /* Field definition itself is beyond the end-of-region */
848 AslError (ASL_ERROR
, ASL_MSG_FIELD_UNIT_OFFSET
, Op
, NULL
);
853 * Now check that the field plus AccessWidth doesn't go beyond
854 * the end-of-region. Assumes AccessBitWidth is a power of 2
856 FieldEndBitOffset
= ACPI_ROUND_UP (FieldEndBitOffset
, AccessBitWidth
);
858 if (FieldEndBitOffset
> RegionBitLength
)
860 /* Field definition combined with the access is beyond EOR */
862 AslError (ASL_ERROR
, ASL_MSG_FIELD_UNIT_ACCESS_WIDTH
, Op
, NULL
);
866 /*******************************************************************************
868 * FUNCTION: LkNamespaceLocateBegin
870 * PARAMETERS: ASL_WALK_CALLBACK
874 * DESCRIPTION: Descending callback used during cross-reference. For named
875 * object references, attempt to locate the name in the
878 * NOTE: ASL references to named fields within resource descriptors are
879 * resolved to integer values here. Therefore, this step is an
880 * important part of the code generation. We don't know that the
881 * name refers to a resource descriptor until now.
883 ******************************************************************************/
886 LkNamespaceLocateBegin (
887 ACPI_PARSE_OBJECT
*Op
,
891 ACPI_WALK_STATE
*WalkState
= (ACPI_WALK_STATE
*) Context
;
892 ACPI_NAMESPACE_NODE
*Node
;
894 ACPI_OBJECT_TYPE ObjectType
;
897 ACPI_PARSE_OBJECT
*NextOp
;
898 ACPI_PARSE_OBJECT
*OwningOp
;
899 ACPI_PARSE_OBJECT
*SpaceIdOp
;
900 UINT32 MinimumLength
;
902 const ACPI_OPCODE_INFO
*OpInfo
;
906 ACPI_FUNCTION_TRACE_PTR (LkNamespaceLocateBegin
, Op
);
909 * If this node is the actual declaration of a name
910 * [such as the XXXX name in "Method (XXXX)"],
911 * we are not interested in it here. We only care about names that are
912 * references to other objects within the namespace and the parent objects
913 * of name declarations
915 if (Op
->Asl
.CompileFlags
& NODE_IS_NAME_DECLARATION
)
920 /* We are only interested in opcodes that have an associated name */
922 OpInfo
= AcpiPsGetOpcodeInfo (Op
->Asl
.AmlOpcode
);
924 if ((!(OpInfo
->Flags
& AML_NAMED
)) &&
925 (!(OpInfo
->Flags
& AML_CREATE
)) &&
926 (Op
->Asl
.ParseOpcode
!= PARSEOP_NAMESTRING
) &&
927 (Op
->Asl
.ParseOpcode
!= PARSEOP_NAMESEG
) &&
928 (Op
->Asl
.ParseOpcode
!= PARSEOP_METHODCALL
))
934 * One special case: CondRefOf operator - we don't care if the name exists
935 * or not at this point, just ignore it, the point of the operator is to
936 * determine if the name exists at runtime.
938 if ((Op
->Asl
.Parent
) &&
939 (Op
->Asl
.Parent
->Asl
.ParseOpcode
== PARSEOP_CONDREFOF
))
945 * We must enable the "search-to-root" for single NameSegs, but
946 * we have to be very careful about opening up scopes
948 Flags
= ACPI_NS_SEARCH_PARENT
;
949 if ((Op
->Asl
.ParseOpcode
== PARSEOP_NAMESTRING
) ||
950 (Op
->Asl
.ParseOpcode
== PARSEOP_NAMESEG
) ||
951 (Op
->Asl
.ParseOpcode
== PARSEOP_METHODCALL
))
954 * These are name references, do not push the scope stack
957 Flags
|= ACPI_NS_DONT_OPEN_SCOPE
;
960 /* Get the NamePath from the appropriate place */
962 if (OpInfo
->Flags
& AML_NAMED
)
964 /* For nearly all NAMED operators, the name reference is the first child */
966 Path
= Op
->Asl
.Child
->Asl
.Value
.String
;
967 if (Op
->Asl
.AmlOpcode
== AML_ALIAS_OP
)
970 * ALIAS is the only oddball opcode, the name declaration
971 * (alias name) is the second operand
973 Path
= Op
->Asl
.Child
->Asl
.Next
->Asl
.Value
.String
;
976 else if (OpInfo
->Flags
& AML_CREATE
)
978 /* Name must appear as the last parameter */
980 NextOp
= Op
->Asl
.Child
;
981 while (!(NextOp
->Asl
.CompileFlags
& NODE_IS_NAME_DECLARATION
))
983 NextOp
= NextOp
->Asl
.Next
;
985 Path
= NextOp
->Asl
.Value
.String
;
989 Path
= Op
->Asl
.Value
.String
;
992 ObjectType
= AslMapNamedOpcodeToDataType (Op
->Asl
.AmlOpcode
);
993 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH
,
994 "Type=%s\n", AcpiUtGetTypeName (ObjectType
)));
997 * Lookup the name in the namespace. Name must exist at this point, or it
998 * is an invalid reference.
1000 * The namespace is also used as a lookup table for references to resource
1001 * descriptors and the fields within them.
1003 Gbl_NsLookupCount
++;
1005 Status
= AcpiNsLookup (WalkState
->ScopeInfo
, Path
, ObjectType
,
1006 ACPI_IMODE_EXECUTE
, Flags
, WalkState
, &(Node
));
1007 if (ACPI_FAILURE (Status
))
1009 if (Status
== AE_NOT_FOUND
)
1012 * We didn't find the name reference by path -- we can qualify this
1013 * a little better before we print an error message
1015 if (strlen (Path
) == ACPI_NAME_SIZE
)
1017 /* A simple, one-segment ACPI name */
1019 if (LkObjectExists (Path
))
1022 * There exists such a name, but we couldn't get to it
1025 AslError (ASL_ERROR
, ASL_MSG_NOT_REACHABLE
, Op
,
1026 Op
->Asl
.ExternalName
);
1030 /* The name doesn't exist, period */
1032 AslError (ASL_ERROR
, ASL_MSG_NOT_EXIST
,
1033 Op
, Op
->Asl
.ExternalName
);
1038 /* Check for a fully qualified path */
1040 if (Path
[0] == AML_ROOT_PREFIX
)
1042 /* Gave full path, the object does not exist */
1044 AslError (ASL_ERROR
, ASL_MSG_NOT_EXIST
, Op
,
1045 Op
->Asl
.ExternalName
);
1050 * We can't tell whether it doesn't exist or just
1053 AslError (ASL_ERROR
, ASL_MSG_NOT_FOUND
, Op
,
1054 Op
->Asl
.ExternalName
);
1063 /* Check for a reference vs. name declaration */
1065 if (!(OpInfo
->Flags
& AML_NAMED
) &&
1066 !(OpInfo
->Flags
& AML_CREATE
))
1068 /* This node has been referenced, mark it for reference check */
1070 Node
->Flags
|= ANOBJ_IS_REFERENCED
;
1073 /* Attempt to optimize the NamePath */
1075 OptOptimizeNamePath (Op
, OpInfo
->Flags
, WalkState
, Path
, Node
);
1078 * 1) Dereference an alias (A name reference that is an alias)
1079 * Aliases are not nested, the alias always points to the final object
1081 if ((Op
->Asl
.ParseOpcode
!= PARSEOP_ALIAS
) &&
1082 (Node
->Type
== ACPI_TYPE_LOCAL_ALIAS
))
1084 /* This node points back to the original PARSEOP_ALIAS */
1088 /* The first child is the alias target op */
1090 NextOp
= NextOp
->Asl
.Child
;
1092 /* That in turn points back to original target alias node */
1094 if (NextOp
->Asl
.Node
)
1096 Node
= NextOp
->Asl
.Node
;
1099 /* Else - forward reference to alias, will be resolved later */
1102 /* 2) Check for a reference to a resource descriptor */
1104 if ((Node
->Type
== ACPI_TYPE_LOCAL_RESOURCE_FIELD
) ||
1105 (Node
->Type
== ACPI_TYPE_LOCAL_RESOURCE
))
1108 * This was a reference to a field within a resource descriptor. Extract
1109 * the associated field offset (either a bit or byte offset depending on
1110 * the field type) and change the named reference into an integer for
1111 * AML code generation
1114 if (Node
->Flags
& ANOBJ_IS_BIT_OFFSET
)
1116 Op
->Asl
.CompileFlags
|= NODE_IS_BIT_OFFSET
;
1119 /* Perform BitOffset <--> ByteOffset conversion if necessary */
1121 switch (Op
->Asl
.Parent
->Asl
.AmlOpcode
)
1123 case AML_CREATE_FIELD_OP
:
1125 /* We allow a Byte offset to Bit Offset conversion for this op */
1127 if (!(Op
->Asl
.CompileFlags
& NODE_IS_BIT_OFFSET
))
1129 /* Simply multiply byte offset times 8 to get bit offset */
1131 Temp
= ACPI_MUL_8 (Temp
);
1136 case AML_CREATE_BIT_FIELD_OP
:
1138 /* This op requires a Bit Offset */
1140 if (!(Op
->Asl
.CompileFlags
& NODE_IS_BIT_OFFSET
))
1142 AslError (ASL_ERROR
, ASL_MSG_BYTES_TO_BITS
, Op
, NULL
);
1147 case AML_CREATE_BYTE_FIELD_OP
:
1148 case AML_CREATE_WORD_FIELD_OP
:
1149 case AML_CREATE_DWORD_FIELD_OP
:
1150 case AML_CREATE_QWORD_FIELD_OP
:
1153 /* These Ops require Byte offsets */
1155 if (Op
->Asl
.CompileFlags
& NODE_IS_BIT_OFFSET
)
1157 AslError (ASL_ERROR
, ASL_MSG_BITS_TO_BYTES
, Op
, NULL
);
1163 /* Nothing to do for other opcodes */
1167 /* Now convert this node to an integer whose value is the field offset */
1169 Op
->Asl
.AmlLength
= 0;
1170 Op
->Asl
.ParseOpcode
= PARSEOP_INTEGER
;
1171 Op
->Asl
.Value
.Integer
= (UINT64
) Temp
;
1172 Op
->Asl
.CompileFlags
|= NODE_IS_RESOURCE_FIELD
;
1174 OpcGenerateAmlOpcode (Op
);
1177 /* 3) Check for a method invocation */
1179 else if ((((Op
->Asl
.ParseOpcode
== PARSEOP_NAMESTRING
) || (Op
->Asl
.ParseOpcode
== PARSEOP_NAMESEG
)) &&
1180 (Node
->Type
== ACPI_TYPE_METHOD
) &&
1182 (Op
->Asl
.Parent
->Asl
.ParseOpcode
!= PARSEOP_METHOD
)) ||
1184 (Op
->Asl
.ParseOpcode
== PARSEOP_METHODCALL
))
1188 * A reference to a method within one of these opcodes is not an
1189 * invocation of the method, it is simply a reference to the method.
1191 if ((Op
->Asl
.Parent
) &&
1192 ((Op
->Asl
.Parent
->Asl
.ParseOpcode
== PARSEOP_REFOF
) ||
1193 (Op
->Asl
.Parent
->Asl
.ParseOpcode
== PARSEOP_DEREFOF
) ||
1194 (Op
->Asl
.Parent
->Asl
.ParseOpcode
== PARSEOP_OBJECTTYPE
)))
1199 * There are two types of method invocation:
1200 * 1) Invocation with arguments -- the parser recognizes this
1202 * 2) Invocation with no arguments --the parser cannot determine that
1203 * this is a method invocation, therefore we have to figure it out
1206 if (Node
->Type
!= ACPI_TYPE_METHOD
)
1208 sprintf (MsgBuffer
, "%s is a %s",
1209 Op
->Asl
.ExternalName
, AcpiUtGetTypeName (Node
->Type
));
1211 AslError (ASL_ERROR
, ASL_MSG_NOT_METHOD
, Op
, MsgBuffer
);
1215 /* Save the method node in the caller's op */
1217 Op
->Asl
.Node
= Node
;
1218 if (Op
->Asl
.Parent
->Asl
.ParseOpcode
== PARSEOP_CONDREFOF
)
1224 * This is a method invocation, with or without arguments.
1225 * Count the number of arguments, each appears as a child
1226 * under the parent node
1228 Op
->Asl
.ParseOpcode
= PARSEOP_METHODCALL
;
1229 UtSetParseOpName (Op
);
1232 NextOp
= Op
->Asl
.Child
;
1237 NextOp
= NextOp
->Asl
.Next
;
1240 if (Node
->Value
!= ASL_EXTERNAL_METHOD
)
1243 * Check the parsed arguments with the number expected by the
1244 * method declaration itself
1246 if (PassedArgs
!= Node
->Value
)
1248 sprintf (MsgBuffer
, "%s requires %d", Op
->Asl
.ExternalName
,
1251 if (PassedArgs
< Node
->Value
)
1253 AslError (ASL_ERROR
, ASL_MSG_ARG_COUNT_LO
, Op
, MsgBuffer
);
1257 AslError (ASL_ERROR
, ASL_MSG_ARG_COUNT_HI
, Op
, MsgBuffer
);
1263 /* 4) Check for an ASL Field definition */
1265 else if ((Op
->Asl
.Parent
) &&
1266 ((Op
->Asl
.Parent
->Asl
.ParseOpcode
== PARSEOP_FIELD
) ||
1267 (Op
->Asl
.Parent
->Asl
.ParseOpcode
== PARSEOP_BANKFIELD
)))
1270 * Offset checking for fields. If the parent operation region has a
1271 * constant length (known at compile time), we can check fields
1272 * defined in that region against the region length. This will catch
1273 * fields and field units that cannot possibly fit within the region.
1275 * Note: Index fields do not directly reference an operation region,
1276 * thus they are not included in this check.
1278 if (Op
== Op
->Asl
.Parent
->Asl
.Child
)
1281 * This is the first child of the field node, which is
1282 * the name of the region. Get the parse node for the
1283 * region -- which contains the length of the region.
1285 OwningOp
= Node
->Op
;
1286 Op
->Asl
.Parent
->Asl
.ExtraValue
=
1287 ACPI_MUL_8 ((UINT32
) OwningOp
->Asl
.Value
.Integer
);
1289 /* Examine the field access width */
1291 switch ((UINT8
) Op
->Asl
.Parent
->Asl
.Value
.Integer
)
1293 case AML_FIELD_ACCESS_ANY
:
1294 case AML_FIELD_ACCESS_BYTE
:
1295 case AML_FIELD_ACCESS_BUFFER
:
1300 case AML_FIELD_ACCESS_WORD
:
1304 case AML_FIELD_ACCESS_DWORD
:
1308 case AML_FIELD_ACCESS_QWORD
:
1314 * Is the region at least as big as the access width?
1315 * Note: DataTableRegions have 0 length
1317 if (((UINT32
) OwningOp
->Asl
.Value
.Integer
) &&
1318 ((UINT32
) OwningOp
->Asl
.Value
.Integer
< MinimumLength
))
1320 AslError (ASL_ERROR
, ASL_MSG_FIELD_ACCESS_WIDTH
, Op
, NULL
);
1324 * Check EC/CMOS/SMBUS fields to make sure that the correct
1325 * access type is used (BYTE for EC/CMOS, BUFFER for SMBUS)
1327 SpaceIdOp
= OwningOp
->Asl
.Child
->Asl
.Next
;
1328 switch ((UINT32
) SpaceIdOp
->Asl
.Value
.Integer
)
1333 if ((UINT8
) Op
->Asl
.Parent
->Asl
.Value
.Integer
!= AML_FIELD_ACCESS_BYTE
)
1335 AslError (ASL_ERROR
, ASL_MSG_REGION_BYTE_ACCESS
, Op
, NULL
);
1342 if ((UINT8
) Op
->Asl
.Parent
->Asl
.Value
.Integer
!= AML_FIELD_ACCESS_BUFFER
)
1344 AslError (ASL_ERROR
, ASL_MSG_REGION_BUFFER_ACCESS
, Op
, NULL
);
1350 /* Nothing to do for other address spaces */
1357 * This is one element of the field list. Check to make sure
1358 * that it does not go beyond the end of the parent operation region.
1360 * In the code below:
1361 * Op->Asl.Parent->Asl.ExtraValue - Region Length (bits)
1362 * Op->Asl.ExtraValue - Field start offset (bits)
1363 * Op->Asl.Child->Asl.Value.Integer32 - Field length (bits)
1364 * Op->Asl.Child->Asl.ExtraValue - Field access width (bits)
1366 if (Op
->Asl
.Parent
->Asl
.ExtraValue
&& Op
->Asl
.Child
)
1368 LkCheckFieldRange (Op
,
1369 Op
->Asl
.Parent
->Asl
.ExtraValue
,
1371 (UINT32
) Op
->Asl
.Child
->Asl
.Value
.Integer
,
1372 Op
->Asl
.Child
->Asl
.ExtraValue
);
1377 Op
->Asl
.Node
= Node
;
1382 /*******************************************************************************
1384 * FUNCTION: LkNamespaceLocateEnd
1386 * PARAMETERS: ASL_WALK_CALLBACK
1390 * DESCRIPTION: Ascending callback used during cross reference. We only
1391 * need to worry about scope management here.
1393 ******************************************************************************/
1396 LkNamespaceLocateEnd (
1397 ACPI_PARSE_OBJECT
*Op
,
1401 ACPI_WALK_STATE
*WalkState
= (ACPI_WALK_STATE
*) Context
;
1402 const ACPI_OPCODE_INFO
*OpInfo
;
1405 ACPI_FUNCTION_TRACE (LkNamespaceLocateEnd
);
1408 /* We are only interested in opcodes that have an associated name */
1410 OpInfo
= AcpiPsGetOpcodeInfo (Op
->Asl
.AmlOpcode
);
1411 if (!(OpInfo
->Flags
& AML_NAMED
))
1416 /* Not interested in name references, we did not open a scope for them */
1418 if ((Op
->Asl
.ParseOpcode
== PARSEOP_NAMESTRING
) ||
1419 (Op
->Asl
.ParseOpcode
== PARSEOP_NAMESEG
) ||
1420 (Op
->Asl
.ParseOpcode
== PARSEOP_METHODCALL
))
1425 /* Pop the scope stack if necessary */
1427 if (AcpiNsOpensScope (AslMapNamedOpcodeToDataType (Op
->Asl
.AmlOpcode
)))
1430 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH
,
1431 "%s: Popping scope for Op %p\n",
1432 AcpiUtGetTypeName (OpInfo
->ObjectType
), Op
));
1434 (void) AcpiDsScopeStackPop (WalkState
);