asllookup.c revision 281075
1210284Sjmallett/******************************************************************************
2232812Sjmallett *
3215990Sjmallett * Module Name: asllookup- Namespace lookup functions
4210284Sjmallett *
5210284Sjmallett *****************************************************************************/
6215990Sjmallett
7215990Sjmallett/*
8215990Sjmallett * Copyright (C) 2000 - 2015, Intel Corp.
9210284Sjmallett * All rights reserved.
10215990Sjmallett *
11215990Sjmallett * Redistribution and use in source and binary forms, with or without
12210284Sjmallett * modification, are permitted provided that the following conditions
13215990Sjmallett * are met:
14215990Sjmallett * 1. Redistributions of source code must retain the above copyright
15215990Sjmallett *    notice, this list of conditions, and the following disclaimer,
16215990Sjmallett *    without modification.
17215990Sjmallett * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18232812Sjmallett *    substantially similar to the "NO WARRANTY" disclaimer below
19215990Sjmallett *    ("Disclaimer") and any redistribution must be conditioned upon
20215990Sjmallett *    including a substantially similar Disclaimer requirement for further
21215990Sjmallett *    binary redistribution.
22215990Sjmallett * 3. Neither the names of the above-listed copyright holders nor the names
23215990Sjmallett *    of any contributors may be used to endorse or promote products derived
24215990Sjmallett *    from this software without specific prior written permission.
25215990Sjmallett *
26215990Sjmallett * Alternatively, this software may be distributed under the terms of the
27215990Sjmallett * GNU General Public License ("GPL") version 2 as published by the Free
28215990Sjmallett * Software Foundation.
29232812Sjmallett *
30215990Sjmallett * NO WARRANTY
31215990Sjmallett * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32215990Sjmallett * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33215990Sjmallett * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34215990Sjmallett * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35215990Sjmallett * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36215990Sjmallett * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37215990Sjmallett * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38210284Sjmallett * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39210284Sjmallett * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40210284Sjmallett * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41210284Sjmallett * POSSIBILITY OF SUCH DAMAGES.
42210284Sjmallett */
43210284Sjmallett
44210284Sjmallett#include <contrib/dev/acpica/compiler/aslcompiler.h>
45215990Sjmallett#include "aslcompiler.y.h"
46210284Sjmallett#include <contrib/dev/acpica/include/acparser.h>
47210284Sjmallett#include <contrib/dev/acpica/include/amlcode.h>
48210284Sjmallett#include <contrib/dev/acpica/include/acnamesp.h>
49210284Sjmallett#include <contrib/dev/acpica/include/acdispat.h>
50210284Sjmallett
51232812Sjmallett
52210284Sjmallett#define _COMPONENT          ACPI_COMPILER
53210284Sjmallett        ACPI_MODULE_NAME    ("asllookup")
54210284Sjmallett
55215990Sjmallett/* Local prototypes */
56215990Sjmallett
57215990Sjmallettstatic ACPI_STATUS
58215990SjmallettLkIsObjectUsed (
59215990Sjmallett    ACPI_HANDLE             ObjHandle,
60215990Sjmallett    UINT32                  Level,
61215990Sjmallett    void                    *Context,
62210284Sjmallett    void                    **ReturnValue);
63210284Sjmallett
64210284Sjmallettstatic ACPI_PARSE_OBJECT *
65215990SjmallettLkGetNameOp (
66210284Sjmallett    ACPI_PARSE_OBJECT       *Op);
67210284Sjmallett
68210284Sjmallett
69210284Sjmallett/*******************************************************************************
70210284Sjmallett *
71210284Sjmallett * FUNCTION:    LkFindUnreferencedObjects
72210284Sjmallett *
73210284Sjmallett * PARAMETERS:  None
74210284Sjmallett *
75210284Sjmallett * RETURN:      None
76210284Sjmallett *
77210284Sjmallett * DESCRIPTION: Namespace walk to find objects that are not referenced in any
78210284Sjmallett *              way. Must be called after the namespace has been cross
79210284Sjmallett *              referenced.
80210284Sjmallett *
81210284Sjmallett ******************************************************************************/
82210284Sjmallett
83210284Sjmallettvoid
84210284SjmallettLkFindUnreferencedObjects (
85210284Sjmallett    void)
86210284Sjmallett{
87210284Sjmallett
88215990Sjmallett    /* Walk entire namespace from the supplied root */
89210284Sjmallett
90210284Sjmallett    (void) AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
91210284Sjmallett                ACPI_UINT32_MAX, FALSE, LkIsObjectUsed, NULL,
92210284Sjmallett                NULL, NULL);
93210284Sjmallett}
94210284Sjmallett
95210284Sjmallett
96210284Sjmallett/*******************************************************************************
97210284Sjmallett *
98210284Sjmallett * FUNCTION:    LkIsObjectUsed
99210284Sjmallett *
100210284Sjmallett * PARAMETERS:  ACPI_WALK_CALLBACK
101210284Sjmallett *
102210284Sjmallett * RETURN:      Status
103210284Sjmallett *
104210284Sjmallett * DESCRIPTION: Check for an unreferenced namespace object and emit a warning.
105210284Sjmallett *              We have to be careful, because some types and names are
106210284Sjmallett *              typically or always unreferenced, we don't want to issue
107210284Sjmallett *              excessive warnings. Note: Names that are declared within a
108210284Sjmallett *              control method are temporary, so we always issue a remark
109210284Sjmallett *              if they are not referenced.
110210284Sjmallett *
111210284Sjmallett ******************************************************************************/
112210284Sjmallett
113210284Sjmallettstatic ACPI_STATUS
114210284SjmallettLkIsObjectUsed (
115210284Sjmallett    ACPI_HANDLE             ObjHandle,
116215990Sjmallett    UINT32                  Level,
117210284Sjmallett    void                    *Context,
118210284Sjmallett    void                    **ReturnValue)
119210284Sjmallett{
120232812Sjmallett    ACPI_NAMESPACE_NODE     *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle);
121232812Sjmallett    ACPI_NAMESPACE_NODE     *Next;
122232812Sjmallett
123232812Sjmallett
124232812Sjmallett    /* Referenced flag is set during the namespace xref */
125232812Sjmallett
126232812Sjmallett    if (Node->Flags & ANOBJ_IS_REFERENCED)
127232812Sjmallett    {
128232812Sjmallett        return (AE_OK);
129232812Sjmallett    }
130232812Sjmallett
131232812Sjmallett    if (!Node->Op)
132232812Sjmallett    {
133232812Sjmallett        return (AE_OK);
134232812Sjmallett    }
135232812Sjmallett
136232812Sjmallett    /* These types are typically never directly referenced, ignore them */
137232812Sjmallett
138232812Sjmallett    switch (Node->Type)
139232812Sjmallett    {
140232812Sjmallett    case ACPI_TYPE_DEVICE:
141215990Sjmallett    case ACPI_TYPE_PROCESSOR:
142215990Sjmallett    case ACPI_TYPE_POWER:
143215990Sjmallett    case ACPI_TYPE_THERMAL:
144210284Sjmallett    case ACPI_TYPE_LOCAL_RESOURCE:
145210284Sjmallett
146210284Sjmallett        return (AE_OK);
147210284Sjmallett
148210284Sjmallett    default:
149210284Sjmallett
150210284Sjmallett        break;
151210284Sjmallett    }
152210284Sjmallett
153210284Sjmallett    /* Determine if the name is within a control method */
154215990Sjmallett
155215990Sjmallett    Next = Node->Parent;
156215990Sjmallett    while (Next)
157210284Sjmallett    {
158210284Sjmallett        if (Next->Type == ACPI_TYPE_METHOD)
159210284Sjmallett        {
160210284Sjmallett            /*
161210284Sjmallett             * Name is within a method, therefore it is temporary.
162210284Sjmallett             * Issue a remark even if it is a reserved name (starts
163210284Sjmallett             * with an underscore).
164210284Sjmallett             */
165210284Sjmallett            sprintf (MsgBuffer, "Name is within method [%4.4s]",
166210284Sjmallett                Next->Name.Ascii);
167210284Sjmallett            AslError (ASL_REMARK, ASL_MSG_NOT_REFERENCED,
168210284Sjmallett                LkGetNameOp (Node->Op), MsgBuffer);
169215990Sjmallett            return (AE_OK);
170210284Sjmallett        }
171210284Sjmallett
172210284Sjmallett        Next = Next->Parent;
173210284Sjmallett    }
174210284Sjmallett
175215990Sjmallett    /* The name is not within a control method */
176210284Sjmallett
177210284Sjmallett    /*
178210284Sjmallett     * Ignore names that start with an underscore. These are the reserved
179210284Sjmallett     * ACPI names and are typically not referenced since they are meant
180210284Sjmallett     * to be called by the host OS.
181210284Sjmallett     */
182210284Sjmallett    if (Node->Name.Ascii[0] == '_')
183210284Sjmallett    {
184210284Sjmallett        return (AE_OK);
185210284Sjmallett    }
186210284Sjmallett
187210284Sjmallett    /*
188210284Sjmallett     * What remains is an unresolved user name that is not within a method.
189210284Sjmallett     * However, the object could be referenced via another table, so issue
190210284Sjmallett     * the warning at level 2.
191210284Sjmallett     */
192210284Sjmallett    AslError (ASL_WARNING2, ASL_MSG_NOT_REFERENCED,
193210284Sjmallett        LkGetNameOp (Node->Op), NULL);
194210284Sjmallett    return (AE_OK);
195210284Sjmallett}
196210284Sjmallett
197210284Sjmallett
198210284Sjmallett/*******************************************************************************
199210284Sjmallett *
200210284Sjmallett * FUNCTION:    LkGetNameOp
201210284Sjmallett *
202210284Sjmallett * PARAMETERS:  Op              - Current Op
203210284Sjmallett *
204210284Sjmallett * RETURN:      NameOp associated with the input op
205210284Sjmallett *
206210284Sjmallett * DESCRIPTION: Find the name declaration op associated with the operator
207210284Sjmallett *
208210284Sjmallett ******************************************************************************/
209210284Sjmallett
210210284Sjmallettstatic ACPI_PARSE_OBJECT *
211210284SjmallettLkGetNameOp (
212210284Sjmallett    ACPI_PARSE_OBJECT       *Op)
213210284Sjmallett{
214210284Sjmallett    const ACPI_OPCODE_INFO  *OpInfo;
215210284Sjmallett    ACPI_PARSE_OBJECT       *NameOp = Op;
216210284Sjmallett
217210284Sjmallett
218210284Sjmallett    OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
219232812Sjmallett
220210284Sjmallett
221215990Sjmallett    /* Get the NamePath from the appropriate place */
222210284Sjmallett
223210284Sjmallett    if (OpInfo->Flags & AML_NAMED)
224210284Sjmallett    {
225210284Sjmallett        /* For nearly all NAMED operators, the name reference is the first child */
226210284Sjmallett
227210284Sjmallett        NameOp = Op->Asl.Child;
228210284Sjmallett        if (Op->Asl.AmlOpcode == AML_ALIAS_OP)
229210284Sjmallett        {
230210284Sjmallett            /*
231210284Sjmallett             * ALIAS is the only oddball opcode, the name declaration
232210284Sjmallett             * (alias name) is the second operand
233210284Sjmallett             */
234210284Sjmallett            NameOp = Op->Asl.Child->Asl.Next;
235210284Sjmallett        }
236210284Sjmallett    }
237210284Sjmallett    else if (OpInfo->Flags & AML_CREATE)
238210284Sjmallett    {
239210284Sjmallett        /* Name must appear as the last parameter */
240210284Sjmallett
241210284Sjmallett        NameOp = Op->Asl.Child;
242210284Sjmallett        while (!(NameOp->Asl.CompileFlags & NODE_IS_NAME_DECLARATION))
243210284Sjmallett        {
244232812Sjmallett            NameOp = NameOp->Asl.Next;
245232812Sjmallett        }
246210284Sjmallett    }
247210284Sjmallett
248210284Sjmallett    return (NameOp);
249210284Sjmallett}
250210284Sjmallett