xref: /freebsd/sys/contrib/dev/acpica/compiler/asllookup.c (revision f8146b882bc156c1d8ddf14bbea67253ebc064bb)
153289f6aSNate Lawson /******************************************************************************
253289f6aSNate Lawson  *
3efcc2a30SJung-uk Kim  * Module Name: asllookup- Namespace lookup functions
453289f6aSNate Lawson  *
553289f6aSNate Lawson  *****************************************************************************/
653289f6aSNate Lawson 
7d244b227SJung-uk Kim /*
8*f8146b88SJung-uk Kim  * Copyright (C) 2000 - 2016, Intel Corp.
953289f6aSNate Lawson  * All rights reserved.
1053289f6aSNate Lawson  *
11d244b227SJung-uk Kim  * Redistribution and use in source and binary forms, with or without
12d244b227SJung-uk Kim  * modification, are permitted provided that the following conditions
13d244b227SJung-uk Kim  * are met:
14d244b227SJung-uk Kim  * 1. Redistributions of source code must retain the above copyright
15d244b227SJung-uk Kim  *    notice, this list of conditions, and the following disclaimer,
16d244b227SJung-uk Kim  *    without modification.
17d244b227SJung-uk Kim  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18d244b227SJung-uk Kim  *    substantially similar to the "NO WARRANTY" disclaimer below
19d244b227SJung-uk Kim  *    ("Disclaimer") and any redistribution must be conditioned upon
20d244b227SJung-uk Kim  *    including a substantially similar Disclaimer requirement for further
21d244b227SJung-uk Kim  *    binary redistribution.
22d244b227SJung-uk Kim  * 3. Neither the names of the above-listed copyright holders nor the names
23d244b227SJung-uk Kim  *    of any contributors may be used to endorse or promote products derived
24d244b227SJung-uk Kim  *    from this software without specific prior written permission.
2553289f6aSNate Lawson  *
26d244b227SJung-uk Kim  * Alternatively, this software may be distributed under the terms of the
27d244b227SJung-uk Kim  * GNU General Public License ("GPL") version 2 as published by the Free
28d244b227SJung-uk Kim  * Software Foundation.
2953289f6aSNate Lawson  *
30d244b227SJung-uk Kim  * NO WARRANTY
31d244b227SJung-uk Kim  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32d244b227SJung-uk Kim  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33d244b227SJung-uk Kim  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34d244b227SJung-uk Kim  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35d244b227SJung-uk Kim  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36d244b227SJung-uk Kim  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37d244b227SJung-uk Kim  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38d244b227SJung-uk Kim  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39d244b227SJung-uk Kim  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40d244b227SJung-uk Kim  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41d244b227SJung-uk Kim  * POSSIBILITY OF SUCH DAMAGES.
42d244b227SJung-uk Kim  */
4353289f6aSNate Lawson 
44ab6f3bf9SJung-uk Kim #include <contrib/dev/acpica/compiler/aslcompiler.h>
4553289f6aSNate Lawson #include "aslcompiler.y.h"
46ab6f3bf9SJung-uk Kim #include <contrib/dev/acpica/include/acparser.h>
47ab6f3bf9SJung-uk Kim #include <contrib/dev/acpica/include/amlcode.h>
48ab6f3bf9SJung-uk Kim #include <contrib/dev/acpica/include/acnamesp.h>
49ab6f3bf9SJung-uk Kim #include <contrib/dev/acpica/include/acdispat.h>
5053289f6aSNate Lawson 
5153289f6aSNate Lawson 
5253289f6aSNate Lawson #define _COMPONENT          ACPI_COMPILER
5353289f6aSNate Lawson         ACPI_MODULE_NAME    ("asllookup")
5453289f6aSNate Lawson 
55fba7fc7eSJung-uk Kim /* Local prototypes */
56fba7fc7eSJung-uk Kim 
57fba7fc7eSJung-uk Kim static ACPI_STATUS
581a39cfb0SJung-uk Kim LkIsObjectUsed (
591a39cfb0SJung-uk Kim     ACPI_HANDLE             ObjHandle,
601a39cfb0SJung-uk Kim     UINT32                  Level,
611a39cfb0SJung-uk Kim     void                    *Context,
621a39cfb0SJung-uk Kim     void                    **ReturnValue);
631a39cfb0SJung-uk Kim 
6442fecd12SJung-uk Kim static ACPI_PARSE_OBJECT *
65a9f12690SJung-uk Kim LkGetNameOp (
66a9f12690SJung-uk Kim     ACPI_PARSE_OBJECT       *Op);
67a9f12690SJung-uk Kim 
6853289f6aSNate Lawson 
6953289f6aSNate Lawson /*******************************************************************************
7053289f6aSNate Lawson  *
71efcc2a30SJung-uk Kim  * FUNCTION:    LkFindUnreferencedObjects
7253289f6aSNate Lawson  *
73efcc2a30SJung-uk Kim  * PARAMETERS:  None
74a9f12690SJung-uk Kim  *
75a9f12690SJung-uk Kim  * RETURN:      None
76a9f12690SJung-uk Kim  *
77efcc2a30SJung-uk Kim  * DESCRIPTION: Namespace walk to find objects that are not referenced in any
78efcc2a30SJung-uk Kim  *              way. Must be called after the namespace has been cross
79efcc2a30SJung-uk Kim  *              referenced.
80a9f12690SJung-uk Kim  *
81a9f12690SJung-uk Kim  ******************************************************************************/
82a9f12690SJung-uk Kim 
831a39cfb0SJung-uk Kim void
84efcc2a30SJung-uk Kim LkFindUnreferencedObjects (
8553289f6aSNate Lawson     void)
8653289f6aSNate Lawson {
8753289f6aSNate Lawson 
8853289f6aSNate Lawson     /* Walk entire namespace from the supplied root */
8953289f6aSNate Lawson 
90efcc2a30SJung-uk Kim     (void) AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
91efcc2a30SJung-uk Kim                 ACPI_UINT32_MAX, FALSE, LkIsObjectUsed, NULL,
92efcc2a30SJung-uk Kim                 NULL, NULL);
931a39cfb0SJung-uk Kim }
941a39cfb0SJung-uk Kim 
951a39cfb0SJung-uk Kim 
961a39cfb0SJung-uk Kim /*******************************************************************************
971a39cfb0SJung-uk Kim  *
981a39cfb0SJung-uk Kim  * FUNCTION:    LkIsObjectUsed
991a39cfb0SJung-uk Kim  *
1001a39cfb0SJung-uk Kim  * PARAMETERS:  ACPI_WALK_CALLBACK
1011a39cfb0SJung-uk Kim  *
1021a39cfb0SJung-uk Kim  * RETURN:      Status
1031a39cfb0SJung-uk Kim  *
1041a39cfb0SJung-uk Kim  * DESCRIPTION: Check for an unreferenced namespace object and emit a warning.
1051a39cfb0SJung-uk Kim  *              We have to be careful, because some types and names are
1061a39cfb0SJung-uk Kim  *              typically or always unreferenced, we don't want to issue
107313a0c13SJung-uk Kim  *              excessive warnings. Note: Names that are declared within a
108313a0c13SJung-uk Kim  *              control method are temporary, so we always issue a remark
109313a0c13SJung-uk Kim  *              if they are not referenced.
1101a39cfb0SJung-uk Kim  *
1111a39cfb0SJung-uk Kim  ******************************************************************************/
1121a39cfb0SJung-uk Kim 
1131a39cfb0SJung-uk Kim static ACPI_STATUS
1141a39cfb0SJung-uk Kim LkIsObjectUsed (
1151a39cfb0SJung-uk Kim     ACPI_HANDLE             ObjHandle,
1161a39cfb0SJung-uk Kim     UINT32                  Level,
1171a39cfb0SJung-uk Kim     void                    *Context,
1181a39cfb0SJung-uk Kim     void                    **ReturnValue)
1191a39cfb0SJung-uk Kim {
1201a39cfb0SJung-uk Kim     ACPI_NAMESPACE_NODE     *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle);
121313a0c13SJung-uk Kim     ACPI_NAMESPACE_NODE     *Next;
122fe0f0bbbSJung-uk Kim     ASL_METHOD_LOCAL        *MethodLocals;
123fe0f0bbbSJung-uk Kim     ASL_METHOD_LOCAL        *MethodArgs;
124fe0f0bbbSJung-uk Kim     UINT32                  i;
1251a39cfb0SJung-uk Kim 
1261a39cfb0SJung-uk Kim 
127fe0f0bbbSJung-uk Kim     if (Node->Type == ACPI_TYPE_METHOD)
128fe0f0bbbSJung-uk Kim     {
129fe0f0bbbSJung-uk Kim         if (!Node->Op || !Node->MethodLocals)
130fe0f0bbbSJung-uk Kim         {
131fe0f0bbbSJung-uk Kim             return (AE_OK);
132fe0f0bbbSJung-uk Kim         }
133fe0f0bbbSJung-uk Kim 
134fe0f0bbbSJung-uk Kim         MethodLocals = (ASL_METHOD_LOCAL *) Node->MethodLocals;
135fe0f0bbbSJung-uk Kim         MethodArgs = (ASL_METHOD_LOCAL *) Node->MethodArgs;
136fe0f0bbbSJung-uk Kim 
137fe0f0bbbSJung-uk Kim         /*
138fe0f0bbbSJung-uk Kim          * Analysis of LocalX variables
139fe0f0bbbSJung-uk Kim          */
140fe0f0bbbSJung-uk Kim         for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++)
141fe0f0bbbSJung-uk Kim         {
142fe0f0bbbSJung-uk Kim             /* Warn for Locals that are set but never referenced */
143fe0f0bbbSJung-uk Kim 
144fe0f0bbbSJung-uk Kim             if ((MethodLocals[i].Flags & ASL_LOCAL_INITIALIZED) &&
145fe0f0bbbSJung-uk Kim                 (!(MethodLocals[i].Flags & ASL_LOCAL_REFERENCED)))
146fe0f0bbbSJung-uk Kim             {
147fe0f0bbbSJung-uk Kim                 sprintf (MsgBuffer, "Local%u", i);
148fe0f0bbbSJung-uk Kim                 AslError (ASL_WARNING, ASL_MSG_LOCAL_NOT_USED,
149fe0f0bbbSJung-uk Kim                     MethodLocals[i].Op, MsgBuffer);
150fe0f0bbbSJung-uk Kim             }
151fe0f0bbbSJung-uk Kim         }
152fe0f0bbbSJung-uk Kim 
153fe0f0bbbSJung-uk Kim         /*
154fe0f0bbbSJung-uk Kim          * Analysis of ArgX variables (standard method arguments,
155fe0f0bbbSJung-uk Kim          * and remaining unused ArgX can also be used as locals)
156fe0f0bbbSJung-uk Kim          */
157fe0f0bbbSJung-uk Kim         for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++)
158fe0f0bbbSJung-uk Kim         {
159fe0f0bbbSJung-uk Kim             if (MethodArgs[i].Flags & ASL_ARG_IS_LOCAL)
160fe0f0bbbSJung-uk Kim             {
161fe0f0bbbSJung-uk Kim                 /* Warn if ArgX is being used as a local, but not referenced */
162fe0f0bbbSJung-uk Kim 
163fe0f0bbbSJung-uk Kim                 if ((MethodArgs[i].Flags & ASL_ARG_INITIALIZED) &&
164fe0f0bbbSJung-uk Kim                     (!(MethodArgs[i].Flags & ASL_ARG_REFERENCED)))
165fe0f0bbbSJung-uk Kim                 {
166fe0f0bbbSJung-uk Kim                     sprintf (MsgBuffer, "Arg%u", i);
167fe0f0bbbSJung-uk Kim                     AslError (ASL_WARNING, ASL_MSG_ARG_AS_LOCAL_NOT_USED,
168fe0f0bbbSJung-uk Kim                         MethodArgs[i].Op, MsgBuffer);
169fe0f0bbbSJung-uk Kim                 }
170fe0f0bbbSJung-uk Kim             }
171fe0f0bbbSJung-uk Kim             else
172fe0f0bbbSJung-uk Kim             {
173fe0f0bbbSJung-uk Kim                 /*
174fe0f0bbbSJung-uk Kim                  * Remark if a normal method ArgX is not referenced.
175fe0f0bbbSJung-uk Kim                  * We ignore the predefined methods since often, not
176fe0f0bbbSJung-uk Kim                  * all arguments are needed or used.
177fe0f0bbbSJung-uk Kim                  */
178fe0f0bbbSJung-uk Kim                 if ((Node->Name.Ascii[0] != '_') &&
179fe0f0bbbSJung-uk Kim                     (!(MethodArgs[i].Flags & ASL_ARG_REFERENCED)))
180fe0f0bbbSJung-uk Kim                 {
181fe0f0bbbSJung-uk Kim                     sprintf (MsgBuffer, "Arg%u", i);
182fe0f0bbbSJung-uk Kim                     AslError (ASL_REMARK, ASL_MSG_ARG_NOT_USED,
183fe0f0bbbSJung-uk Kim                         MethodArgs[i].Op, MsgBuffer);
184fe0f0bbbSJung-uk Kim                 }
185fe0f0bbbSJung-uk Kim             }
186fe0f0bbbSJung-uk Kim         }
187fe0f0bbbSJung-uk Kim     }
188fe0f0bbbSJung-uk Kim 
1891a39cfb0SJung-uk Kim     /* Referenced flag is set during the namespace xref */
1901a39cfb0SJung-uk Kim 
1911a39cfb0SJung-uk Kim     if (Node->Flags & ANOBJ_IS_REFERENCED)
1921a39cfb0SJung-uk Kim     {
1931a39cfb0SJung-uk Kim         return (AE_OK);
1941a39cfb0SJung-uk Kim     }
1951a39cfb0SJung-uk Kim 
196313a0c13SJung-uk Kim     if (!Node->Op)
1971a39cfb0SJung-uk Kim     {
1981a39cfb0SJung-uk Kim         return (AE_OK);
1991a39cfb0SJung-uk Kim     }
2001a39cfb0SJung-uk Kim 
201313a0c13SJung-uk Kim     /* These types are typically never directly referenced, ignore them */
2021a39cfb0SJung-uk Kim 
2031a39cfb0SJung-uk Kim     switch (Node->Type)
2041a39cfb0SJung-uk Kim     {
2051a39cfb0SJung-uk Kim     case ACPI_TYPE_DEVICE:
2061a39cfb0SJung-uk Kim     case ACPI_TYPE_PROCESSOR:
2071a39cfb0SJung-uk Kim     case ACPI_TYPE_POWER:
208313a0c13SJung-uk Kim     case ACPI_TYPE_THERMAL:
2091a39cfb0SJung-uk Kim     case ACPI_TYPE_LOCAL_RESOURCE:
210*f8146b88SJung-uk Kim     case ACPI_TYPE_LOCAL_RESOURCE_FIELD: /* Names assigned to descriptor elements */
211a9d8d09cSJung-uk Kim 
2121a39cfb0SJung-uk Kim         return (AE_OK);
2131a39cfb0SJung-uk Kim 
2141a39cfb0SJung-uk Kim     default:
215a9d8d09cSJung-uk Kim 
2161a39cfb0SJung-uk Kim         break;
2171a39cfb0SJung-uk Kim     }
2181a39cfb0SJung-uk Kim 
219313a0c13SJung-uk Kim     /* Determine if the name is within a control method */
2201a39cfb0SJung-uk Kim 
221313a0c13SJung-uk Kim     Next = Node->Parent;
222313a0c13SJung-uk Kim     while (Next)
2231a39cfb0SJung-uk Kim     {
224313a0c13SJung-uk Kim         if (Next->Type == ACPI_TYPE_METHOD)
225313a0c13SJung-uk Kim         {
226313a0c13SJung-uk Kim             /*
227313a0c13SJung-uk Kim              * Name is within a method, therefore it is temporary.
228313a0c13SJung-uk Kim              * Issue a remark even if it is a reserved name (starts
229313a0c13SJung-uk Kim              * with an underscore).
230313a0c13SJung-uk Kim              */
231*f8146b88SJung-uk Kim             sprintf (MsgBuffer, "Name [%4.4s] is within a method [%4.4s]",
232*f8146b88SJung-uk Kim                 Node->Name.Ascii, Next->Name.Ascii);
233313a0c13SJung-uk Kim             AslError (ASL_REMARK, ASL_MSG_NOT_REFERENCED,
234313a0c13SJung-uk Kim                 LkGetNameOp (Node->Op), MsgBuffer);
235313a0c13SJung-uk Kim             return (AE_OK);
2361a39cfb0SJung-uk Kim         }
237313a0c13SJung-uk Kim 
238313a0c13SJung-uk Kim         Next = Next->Parent;
239313a0c13SJung-uk Kim     }
240313a0c13SJung-uk Kim 
241313a0c13SJung-uk Kim     /* The name is not within a control method */
242313a0c13SJung-uk Kim 
243313a0c13SJung-uk Kim     /*
244313a0c13SJung-uk Kim      * Ignore names that start with an underscore. These are the reserved
245313a0c13SJung-uk Kim      * ACPI names and are typically not referenced since they are meant
246313a0c13SJung-uk Kim      * to be called by the host OS.
247313a0c13SJung-uk Kim      */
248313a0c13SJung-uk Kim     if (Node->Name.Ascii[0] == '_')
249313a0c13SJung-uk Kim     {
250313a0c13SJung-uk Kim         return (AE_OK);
251313a0c13SJung-uk Kim     }
252313a0c13SJung-uk Kim 
253313a0c13SJung-uk Kim     /*
254313a0c13SJung-uk Kim      * What remains is an unresolved user name that is not within a method.
255313a0c13SJung-uk Kim      * However, the object could be referenced via another table, so issue
256313a0c13SJung-uk Kim      * the warning at level 2.
257313a0c13SJung-uk Kim      */
258313a0c13SJung-uk Kim     AslError (ASL_WARNING2, ASL_MSG_NOT_REFERENCED,
259313a0c13SJung-uk Kim         LkGetNameOp (Node->Op), NULL);
2601a39cfb0SJung-uk Kim     return (AE_OK);
2611a39cfb0SJung-uk Kim }
2621a39cfb0SJung-uk Kim 
2631a39cfb0SJung-uk Kim 
2641a39cfb0SJung-uk Kim /*******************************************************************************
2651a39cfb0SJung-uk Kim  *
266efcc2a30SJung-uk Kim  * FUNCTION:    LkGetNameOp
2671a39cfb0SJung-uk Kim  *
268efcc2a30SJung-uk Kim  * PARAMETERS:  Op              - Current Op
2691a39cfb0SJung-uk Kim  *
270efcc2a30SJung-uk Kim  * RETURN:      NameOp associated with the input op
2711a39cfb0SJung-uk Kim  *
272efcc2a30SJung-uk Kim  * DESCRIPTION: Find the name declaration op associated with the operator
2731a39cfb0SJung-uk Kim  *
2741a39cfb0SJung-uk Kim  ******************************************************************************/
2751a39cfb0SJung-uk Kim 
276efcc2a30SJung-uk Kim static ACPI_PARSE_OBJECT *
277efcc2a30SJung-uk Kim LkGetNameOp (
278efcc2a30SJung-uk Kim     ACPI_PARSE_OBJECT       *Op)
2791a39cfb0SJung-uk Kim {
28053289f6aSNate Lawson     const ACPI_OPCODE_INFO  *OpInfo;
281efcc2a30SJung-uk Kim     ACPI_PARSE_OBJECT       *NameOp = Op;
28253289f6aSNate Lawson 
28353289f6aSNate Lawson 
28453289f6aSNate Lawson     OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
28553289f6aSNate Lawson 
28653289f6aSNate Lawson 
28753289f6aSNate Lawson     /* Get the NamePath from the appropriate place */
28853289f6aSNate Lawson 
28953289f6aSNate Lawson     if (OpInfo->Flags & AML_NAMED)
29053289f6aSNate Lawson     {
2911a39cfb0SJung-uk Kim         /* For nearly all NAMED operators, the name reference is the first child */
29253289f6aSNate Lawson 
293efcc2a30SJung-uk Kim         NameOp = Op->Asl.Child;
29453289f6aSNate Lawson         if (Op->Asl.AmlOpcode == AML_ALIAS_OP)
29553289f6aSNate Lawson         {
29653289f6aSNate Lawson             /*
29753289f6aSNate Lawson              * ALIAS is the only oddball opcode, the name declaration
29853289f6aSNate Lawson              * (alias name) is the second operand
29953289f6aSNate Lawson              */
300efcc2a30SJung-uk Kim             NameOp = Op->Asl.Child->Asl.Next;
30153289f6aSNate Lawson         }
30253289f6aSNate Lawson     }
30353289f6aSNate Lawson     else if (OpInfo->Flags & AML_CREATE)
30453289f6aSNate Lawson     {
30553289f6aSNate Lawson         /* Name must appear as the last parameter */
30653289f6aSNate Lawson 
307efcc2a30SJung-uk Kim         NameOp = Op->Asl.Child;
308efcc2a30SJung-uk Kim         while (!(NameOp->Asl.CompileFlags & NODE_IS_NAME_DECLARATION))
30953289f6aSNate Lawson         {
310efcc2a30SJung-uk Kim             NameOp = NameOp->Asl.Next;
31153289f6aSNate Lawson         }
31253289f6aSNate Lawson     }
31353289f6aSNate Lawson 
314efcc2a30SJung-uk Kim     return (NameOp);
31553289f6aSNate Lawson }
316