xref: /freebsd/sys/contrib/dev/acpica/compiler/asllookup.c (revision fe0f0bbb19f4f267df5c6249d1af4d6f665dfd52)
153289f6aSNate Lawson /******************************************************************************
253289f6aSNate Lawson  *
3efcc2a30SJung-uk Kim  * Module Name: asllookup- Namespace lookup functions
453289f6aSNate Lawson  *
553289f6aSNate Lawson  *****************************************************************************/
653289f6aSNate Lawson 
7d244b227SJung-uk Kim /*
81c0e1b6dSJung-uk Kim  * Copyright (C) 2000 - 2015, 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;
122*fe0f0bbbSJung-uk Kim     ASL_METHOD_LOCAL        *MethodLocals;
123*fe0f0bbbSJung-uk Kim     ASL_METHOD_LOCAL        *MethodArgs;
124*fe0f0bbbSJung-uk Kim     UINT32                  i;
1251a39cfb0SJung-uk Kim 
1261a39cfb0SJung-uk Kim 
127*fe0f0bbbSJung-uk Kim     if (Node->Type == ACPI_TYPE_METHOD)
128*fe0f0bbbSJung-uk Kim     {
129*fe0f0bbbSJung-uk Kim         if (!Node->Op || !Node->MethodLocals)
130*fe0f0bbbSJung-uk Kim         {
131*fe0f0bbbSJung-uk Kim             return (AE_OK);
132*fe0f0bbbSJung-uk Kim         }
133*fe0f0bbbSJung-uk Kim 
134*fe0f0bbbSJung-uk Kim         MethodLocals = (ASL_METHOD_LOCAL *) Node->MethodLocals;
135*fe0f0bbbSJung-uk Kim         MethodArgs = (ASL_METHOD_LOCAL *) Node->MethodArgs;
136*fe0f0bbbSJung-uk Kim 
137*fe0f0bbbSJung-uk Kim         /*
138*fe0f0bbbSJung-uk Kim          * Analysis of LocalX variables
139*fe0f0bbbSJung-uk Kim          */
140*fe0f0bbbSJung-uk Kim         for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++)
141*fe0f0bbbSJung-uk Kim         {
142*fe0f0bbbSJung-uk Kim             /* Warn for Locals that are set but never referenced */
143*fe0f0bbbSJung-uk Kim 
144*fe0f0bbbSJung-uk Kim             if ((MethodLocals[i].Flags & ASL_LOCAL_INITIALIZED) &&
145*fe0f0bbbSJung-uk Kim                 (!(MethodLocals[i].Flags & ASL_LOCAL_REFERENCED)))
146*fe0f0bbbSJung-uk Kim             {
147*fe0f0bbbSJung-uk Kim                 sprintf (MsgBuffer, "Local%u", i);
148*fe0f0bbbSJung-uk Kim                 AslError (ASL_WARNING, ASL_MSG_LOCAL_NOT_USED,
149*fe0f0bbbSJung-uk Kim                     MethodLocals[i].Op, MsgBuffer);
150*fe0f0bbbSJung-uk Kim             }
151*fe0f0bbbSJung-uk Kim         }
152*fe0f0bbbSJung-uk Kim 
153*fe0f0bbbSJung-uk Kim         /*
154*fe0f0bbbSJung-uk Kim          * Analysis of ArgX variables (standard method arguments,
155*fe0f0bbbSJung-uk Kim          * and remaining unused ArgX can also be used as locals)
156*fe0f0bbbSJung-uk Kim          */
157*fe0f0bbbSJung-uk Kim         for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++)
158*fe0f0bbbSJung-uk Kim         {
159*fe0f0bbbSJung-uk Kim             if (MethodArgs[i].Flags & ASL_ARG_IS_LOCAL)
160*fe0f0bbbSJung-uk Kim             {
161*fe0f0bbbSJung-uk Kim                 /* Warn if ArgX is being used as a local, but not referenced */
162*fe0f0bbbSJung-uk Kim 
163*fe0f0bbbSJung-uk Kim                 if ((MethodArgs[i].Flags & ASL_ARG_INITIALIZED) &&
164*fe0f0bbbSJung-uk Kim                     (!(MethodArgs[i].Flags & ASL_ARG_REFERENCED)))
165*fe0f0bbbSJung-uk Kim                 {
166*fe0f0bbbSJung-uk Kim                     sprintf (MsgBuffer, "Arg%u", i);
167*fe0f0bbbSJung-uk Kim                     AslError (ASL_WARNING, ASL_MSG_ARG_AS_LOCAL_NOT_USED,
168*fe0f0bbbSJung-uk Kim                         MethodArgs[i].Op, MsgBuffer);
169*fe0f0bbbSJung-uk Kim                 }
170*fe0f0bbbSJung-uk Kim             }
171*fe0f0bbbSJung-uk Kim             else
172*fe0f0bbbSJung-uk Kim             {
173*fe0f0bbbSJung-uk Kim                 /*
174*fe0f0bbbSJung-uk Kim                  * Remark if a normal method ArgX is not referenced.
175*fe0f0bbbSJung-uk Kim                  * We ignore the predefined methods since often, not
176*fe0f0bbbSJung-uk Kim                  * all arguments are needed or used.
177*fe0f0bbbSJung-uk Kim                  */
178*fe0f0bbbSJung-uk Kim                 if ((Node->Name.Ascii[0] != '_') &&
179*fe0f0bbbSJung-uk Kim                     (!(MethodArgs[i].Flags & ASL_ARG_REFERENCED)))
180*fe0f0bbbSJung-uk Kim                 {
181*fe0f0bbbSJung-uk Kim                     sprintf (MsgBuffer, "Arg%u", i);
182*fe0f0bbbSJung-uk Kim                     AslError (ASL_REMARK, ASL_MSG_ARG_NOT_USED,
183*fe0f0bbbSJung-uk Kim                         MethodArgs[i].Op, MsgBuffer);
184*fe0f0bbbSJung-uk Kim                 }
185*fe0f0bbbSJung-uk Kim             }
186*fe0f0bbbSJung-uk Kim         }
187*fe0f0bbbSJung-uk Kim     }
188*fe0f0bbbSJung-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:
210a9d8d09cSJung-uk Kim 
2111a39cfb0SJung-uk Kim         return (AE_OK);
2121a39cfb0SJung-uk Kim 
2131a39cfb0SJung-uk Kim     default:
214a9d8d09cSJung-uk Kim 
2151a39cfb0SJung-uk Kim         break;
2161a39cfb0SJung-uk Kim     }
2171a39cfb0SJung-uk Kim 
218313a0c13SJung-uk Kim     /* Determine if the name is within a control method */
2191a39cfb0SJung-uk Kim 
220313a0c13SJung-uk Kim     Next = Node->Parent;
221313a0c13SJung-uk Kim     while (Next)
2221a39cfb0SJung-uk Kim     {
223313a0c13SJung-uk Kim         if (Next->Type == ACPI_TYPE_METHOD)
224313a0c13SJung-uk Kim         {
225313a0c13SJung-uk Kim             /*
226313a0c13SJung-uk Kim              * Name is within a method, therefore it is temporary.
227313a0c13SJung-uk Kim              * Issue a remark even if it is a reserved name (starts
228313a0c13SJung-uk Kim              * with an underscore).
229313a0c13SJung-uk Kim              */
230313a0c13SJung-uk Kim             sprintf (MsgBuffer, "Name is within method [%4.4s]",
231313a0c13SJung-uk Kim                 Next->Name.Ascii);
232313a0c13SJung-uk Kim             AslError (ASL_REMARK, ASL_MSG_NOT_REFERENCED,
233313a0c13SJung-uk Kim                 LkGetNameOp (Node->Op), MsgBuffer);
234313a0c13SJung-uk Kim             return (AE_OK);
2351a39cfb0SJung-uk Kim         }
236313a0c13SJung-uk Kim 
237313a0c13SJung-uk Kim         Next = Next->Parent;
238313a0c13SJung-uk Kim     }
239313a0c13SJung-uk Kim 
240313a0c13SJung-uk Kim     /* The name is not within a control method */
241313a0c13SJung-uk Kim 
242313a0c13SJung-uk Kim     /*
243313a0c13SJung-uk Kim      * Ignore names that start with an underscore. These are the reserved
244313a0c13SJung-uk Kim      * ACPI names and are typically not referenced since they are meant
245313a0c13SJung-uk Kim      * to be called by the host OS.
246313a0c13SJung-uk Kim      */
247313a0c13SJung-uk Kim     if (Node->Name.Ascii[0] == '_')
248313a0c13SJung-uk Kim     {
249313a0c13SJung-uk Kim         return (AE_OK);
250313a0c13SJung-uk Kim     }
251313a0c13SJung-uk Kim 
252313a0c13SJung-uk Kim     /*
253313a0c13SJung-uk Kim      * What remains is an unresolved user name that is not within a method.
254313a0c13SJung-uk Kim      * However, the object could be referenced via another table, so issue
255313a0c13SJung-uk Kim      * the warning at level 2.
256313a0c13SJung-uk Kim      */
257313a0c13SJung-uk Kim     AslError (ASL_WARNING2, ASL_MSG_NOT_REFERENCED,
258313a0c13SJung-uk Kim         LkGetNameOp (Node->Op), NULL);
2591a39cfb0SJung-uk Kim     return (AE_OK);
2601a39cfb0SJung-uk Kim }
2611a39cfb0SJung-uk Kim 
2621a39cfb0SJung-uk Kim 
2631a39cfb0SJung-uk Kim /*******************************************************************************
2641a39cfb0SJung-uk Kim  *
265efcc2a30SJung-uk Kim  * FUNCTION:    LkGetNameOp
2661a39cfb0SJung-uk Kim  *
267efcc2a30SJung-uk Kim  * PARAMETERS:  Op              - Current Op
2681a39cfb0SJung-uk Kim  *
269efcc2a30SJung-uk Kim  * RETURN:      NameOp associated with the input op
2701a39cfb0SJung-uk Kim  *
271efcc2a30SJung-uk Kim  * DESCRIPTION: Find the name declaration op associated with the operator
2721a39cfb0SJung-uk Kim  *
2731a39cfb0SJung-uk Kim  ******************************************************************************/
2741a39cfb0SJung-uk Kim 
275efcc2a30SJung-uk Kim static ACPI_PARSE_OBJECT *
276efcc2a30SJung-uk Kim LkGetNameOp (
277efcc2a30SJung-uk Kim     ACPI_PARSE_OBJECT       *Op)
2781a39cfb0SJung-uk Kim {
27953289f6aSNate Lawson     const ACPI_OPCODE_INFO  *OpInfo;
280efcc2a30SJung-uk Kim     ACPI_PARSE_OBJECT       *NameOp = Op;
28153289f6aSNate Lawson 
28253289f6aSNate Lawson 
28353289f6aSNate Lawson     OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
28453289f6aSNate Lawson 
28553289f6aSNate Lawson 
28653289f6aSNate Lawson     /* Get the NamePath from the appropriate place */
28753289f6aSNate Lawson 
28853289f6aSNate Lawson     if (OpInfo->Flags & AML_NAMED)
28953289f6aSNate Lawson     {
2901a39cfb0SJung-uk Kim         /* For nearly all NAMED operators, the name reference is the first child */
29153289f6aSNate Lawson 
292efcc2a30SJung-uk Kim         NameOp = Op->Asl.Child;
29353289f6aSNate Lawson         if (Op->Asl.AmlOpcode == AML_ALIAS_OP)
29453289f6aSNate Lawson         {
29553289f6aSNate Lawson             /*
29653289f6aSNate Lawson              * ALIAS is the only oddball opcode, the name declaration
29753289f6aSNate Lawson              * (alias name) is the second operand
29853289f6aSNate Lawson              */
299efcc2a30SJung-uk Kim             NameOp = Op->Asl.Child->Asl.Next;
30053289f6aSNate Lawson         }
30153289f6aSNate Lawson     }
30253289f6aSNate Lawson     else if (OpInfo->Flags & AML_CREATE)
30353289f6aSNate Lawson     {
30453289f6aSNate Lawson         /* Name must appear as the last parameter */
30553289f6aSNate Lawson 
306efcc2a30SJung-uk Kim         NameOp = Op->Asl.Child;
307efcc2a30SJung-uk Kim         while (!(NameOp->Asl.CompileFlags & NODE_IS_NAME_DECLARATION))
30853289f6aSNate Lawson         {
309efcc2a30SJung-uk Kim             NameOp = NameOp->Asl.Next;
31053289f6aSNate Lawson         }
31153289f6aSNate Lawson     }
31253289f6aSNate Lawson 
313efcc2a30SJung-uk Kim     return (NameOp);
31453289f6aSNate Lawson }
315