xref: /netbsd-src/sys/external/bsd/acpica/dist/compiler/aslxrefout.c (revision 046a29855e04359424fd074e8313af6b6be8cfb6)
1cfbb7280Schristos /******************************************************************************
2cfbb7280Schristos  *
3cfbb7280Schristos  * Module Name: aslxrefout.c - support for optional cross-reference file
4cfbb7280Schristos  *
5cfbb7280Schristos  *****************************************************************************/
6cfbb7280Schristos 
7cfbb7280Schristos /*
8*046a2985Schristos  * Copyright (C) 2000 - 2023, Intel Corp.
9cfbb7280Schristos  * All rights reserved.
10cfbb7280Schristos  *
11cfbb7280Schristos  * Redistribution and use in source and binary forms, with or without
12cfbb7280Schristos  * modification, are permitted provided that the following conditions
13cfbb7280Schristos  * are met:
14cfbb7280Schristos  * 1. Redistributions of source code must retain the above copyright
15cfbb7280Schristos  *    notice, this list of conditions, and the following disclaimer,
16cfbb7280Schristos  *    without modification.
17cfbb7280Schristos  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18cfbb7280Schristos  *    substantially similar to the "NO WARRANTY" disclaimer below
19cfbb7280Schristos  *    ("Disclaimer") and any redistribution must be conditioned upon
20cfbb7280Schristos  *    including a substantially similar Disclaimer requirement for further
21cfbb7280Schristos  *    binary redistribution.
22cfbb7280Schristos  * 3. Neither the names of the above-listed copyright holders nor the names
23cfbb7280Schristos  *    of any contributors may be used to endorse or promote products derived
24cfbb7280Schristos  *    from this software without specific prior written permission.
25cfbb7280Schristos  *
26cfbb7280Schristos  * Alternatively, this software may be distributed under the terms of the
27cfbb7280Schristos  * GNU General Public License ("GPL") version 2 as published by the Free
28cfbb7280Schristos  * Software Foundation.
29cfbb7280Schristos  *
30cfbb7280Schristos  * NO WARRANTY
31cfbb7280Schristos  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32cfbb7280Schristos  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3346a330b4Schristos  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34cfbb7280Schristos  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35cfbb7280Schristos  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36cfbb7280Schristos  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37cfbb7280Schristos  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38cfbb7280Schristos  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39cfbb7280Schristos  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40cfbb7280Schristos  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41cfbb7280Schristos  * POSSIBILITY OF SUCH DAMAGES.
42cfbb7280Schristos  */
43cfbb7280Schristos 
44cfbb7280Schristos #include "aslcompiler.h"
45cfbb7280Schristos #include "aslcompiler.y.h"
46cfbb7280Schristos #include "acnamesp.h"
47cfbb7280Schristos #include "acparser.h"
48cfbb7280Schristos #include "amlcode.h"
49cfbb7280Schristos 
50cfbb7280Schristos #define _COMPONENT          ACPI_COMPILER
51cfbb7280Schristos         ACPI_MODULE_NAME    ("aslxrefout")
52cfbb7280Schristos 
53cfbb7280Schristos 
54cfbb7280Schristos /* Local prototypes */
55cfbb7280Schristos 
56cfbb7280Schristos static ACPI_STATUS
57cfbb7280Schristos OtXrefWalkPart2 (
58cfbb7280Schristos     ACPI_PARSE_OBJECT       *Op,
59cfbb7280Schristos     UINT32                  Level,
60cfbb7280Schristos     void                    *Context);
61cfbb7280Schristos 
62cfbb7280Schristos static ACPI_STATUS
63cfbb7280Schristos OtXrefWalkPart3 (
64cfbb7280Schristos     ACPI_PARSE_OBJECT       *Op,
65cfbb7280Schristos     UINT32                  Level,
66cfbb7280Schristos     void                    *Context);
67cfbb7280Schristos 
68cfbb7280Schristos static ACPI_STATUS
69cfbb7280Schristos OtXrefAnalysisWalkPart1 (
70cfbb7280Schristos     ACPI_PARSE_OBJECT       *Op,
71cfbb7280Schristos     UINT32                  Level,
72cfbb7280Schristos     void                    *Context);
73cfbb7280Schristos 
74cfbb7280Schristos 
75cfbb7280Schristos static ACPI_STATUS
76cfbb7280Schristos OtXrefAnalysisWalkPart2 (
77cfbb7280Schristos     ACPI_PARSE_OBJECT       *Op,
78cfbb7280Schristos     UINT32                  Level,
79cfbb7280Schristos     void                    *Context);
80cfbb7280Schristos 
81cfbb7280Schristos static ACPI_STATUS
82cfbb7280Schristos OtXrefAnalysisWalkPart3 (
83cfbb7280Schristos     ACPI_PARSE_OBJECT       *Op,
84cfbb7280Schristos     UINT32                  Level,
85cfbb7280Schristos     void                    *Context);
86cfbb7280Schristos 
87cfbb7280Schristos 
88cfbb7280Schristos /*******************************************************************************
89cfbb7280Schristos  *
90cfbb7280Schristos  * FUNCTION:    OtPrintHeaders
91cfbb7280Schristos  *
92cfbb7280Schristos  * PARAMETERS:  Message             - Main header message
93cfbb7280Schristos  *
94cfbb7280Schristos  * RETURN:      None
95cfbb7280Schristos  *
96cfbb7280Schristos  * DESCRIPTION: Emits the main header message along with field descriptions
97cfbb7280Schristos  *
98cfbb7280Schristos  ******************************************************************************/
99cfbb7280Schristos 
100cfbb7280Schristos void
OtPrintHeaders(char * Message)101cfbb7280Schristos OtPrintHeaders (
102cfbb7280Schristos     char                    *Message)
103cfbb7280Schristos {
104cfbb7280Schristos     UINT32                  Length;
105cfbb7280Schristos 
106cfbb7280Schristos 
107cfbb7280Schristos     Length = strlen (Message);
108cfbb7280Schristos 
109cfbb7280Schristos     FlPrintFile (ASL_FILE_XREF_OUTPUT, "\n\n%s\n", Message);
110cfbb7280Schristos     while (Length)
111cfbb7280Schristos     {
112cfbb7280Schristos         FlPrintFile (ASL_FILE_XREF_OUTPUT, "-");
113cfbb7280Schristos         Length--;
114cfbb7280Schristos     }
115cfbb7280Schristos 
116cfbb7280Schristos     FlPrintFile (ASL_FILE_XREF_OUTPUT, "\n\nLineno   %-40s Description\n",
117cfbb7280Schristos         "Full Pathname");
118cfbb7280Schristos }
119cfbb7280Schristos 
120cfbb7280Schristos 
121cfbb7280Schristos /*******************************************************************************
122cfbb7280Schristos  *
123cfbb7280Schristos  * FUNCTION:    OtCreateXrefFile
124cfbb7280Schristos  *
125cfbb7280Schristos  * PARAMETERS:  None
126cfbb7280Schristos  *
127cfbb7280Schristos  * RETURN:      None
128cfbb7280Schristos  *
129cfbb7280Schristos  * DESCRIPTION  Main entry point for parts 2 and 3 of the cross-reference
130cfbb7280Schristos  *              file.
131cfbb7280Schristos  *
132cfbb7280Schristos  ******************************************************************************/
133cfbb7280Schristos 
134cfbb7280Schristos void
OtCreateXrefFile(void)135cfbb7280Schristos OtCreateXrefFile (
136cfbb7280Schristos     void)
137cfbb7280Schristos {
138cfbb7280Schristos     ASL_XREF_INFO           XrefInfo;
139cfbb7280Schristos 
140cfbb7280Schristos 
141cfbb7280Schristos     /* Build cross-reference output file if requested */
142cfbb7280Schristos 
1434c4e8184Schristos     if (!AslGbl_CrossReferenceOutput)
144cfbb7280Schristos     {
145cfbb7280Schristos         return;
146cfbb7280Schristos     }
147cfbb7280Schristos 
148cfbb7280Schristos     memset (&XrefInfo, 0, sizeof (ASL_XREF_INFO));
149cfbb7280Schristos 
150cfbb7280Schristos     /* Cross-reference output file, part 2 (Method invocations) */
151cfbb7280Schristos 
152cfbb7280Schristos     OtPrintHeaders ("Part 2: Method Reference Map "
153cfbb7280Schristos         "(Invocations of each user-defined control method)");
154cfbb7280Schristos 
1554c4e8184Schristos     TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_DOWNWARD,
156cfbb7280Schristos         OtXrefWalkPart2, NULL, &XrefInfo);
157cfbb7280Schristos 
158cfbb7280Schristos     /* Cross-reference output file, part 3 (All other object refs) */
159cfbb7280Schristos 
160cfbb7280Schristos     OtPrintHeaders ("Part 3: Full Object Reference Map "
161cfbb7280Schristos         "(Methods that reference each object in namespace");
162cfbb7280Schristos 
1634c4e8184Schristos     TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_DOWNWARD,
164cfbb7280Schristos         OtXrefWalkPart3, NULL, &XrefInfo);
165cfbb7280Schristos 
166cfbb7280Schristos     /* Cross-reference summary */
167cfbb7280Schristos 
168cfbb7280Schristos     FlPrintFile (ASL_FILE_XREF_OUTPUT, "\n\nObject Summary\n");
169cfbb7280Schristos 
170cfbb7280Schristos     FlPrintFile (ASL_FILE_XREF_OUTPUT,
171cfbb7280Schristos         "\nTotal methods:                   %u\n",
172cfbb7280Schristos         XrefInfo.TotalPredefinedMethods + XrefInfo.TotalUserMethods);
173cfbb7280Schristos     FlPrintFile (ASL_FILE_XREF_OUTPUT,
174cfbb7280Schristos         "Total predefined methods:        %u\n",
175cfbb7280Schristos         XrefInfo.TotalPredefinedMethods);
176cfbb7280Schristos 
177cfbb7280Schristos     FlPrintFile (ASL_FILE_XREF_OUTPUT,
178cfbb7280Schristos         "\nTotal user methods:              %u\n",
179cfbb7280Schristos         XrefInfo.TotalUserMethods);
180cfbb7280Schristos     FlPrintFile (ASL_FILE_XREF_OUTPUT,
181cfbb7280Schristos         "Total unreferenced user methods  %u\n",
182cfbb7280Schristos         XrefInfo.TotalUnreferenceUserMethods);
183cfbb7280Schristos 
184cfbb7280Schristos     FlPrintFile (ASL_FILE_XREF_OUTPUT,
185cfbb7280Schristos         "\nTotal defined objects:           %u\n",
186cfbb7280Schristos         XrefInfo.TotalObjects);
187cfbb7280Schristos     FlPrintFile (ASL_FILE_XREF_OUTPUT,
188cfbb7280Schristos         "Total unreferenced objects:      %u\n",
189cfbb7280Schristos         XrefInfo.TotalUnreferencedObjects);
190cfbb7280Schristos }
191cfbb7280Schristos 
192cfbb7280Schristos 
193cfbb7280Schristos /*
194cfbb7280Schristos  * Part 1 of the cross reference file. This part emits the namespace objects
195cfbb7280Schristos  * that are referenced by each control method in the namespace.
196cfbb7280Schristos  *
197cfbb7280Schristos  * Part 2 and 3 are below part 1.
198cfbb7280Schristos  */
199cfbb7280Schristos 
200cfbb7280Schristos /*******************************************************************************
201cfbb7280Schristos  *
202cfbb7280Schristos  * FUNCTION:    OtXrefWalkPart1
203cfbb7280Schristos  *
204cfbb7280Schristos  * PARAMETERS:  Op                      - Current parse Op
205cfbb7280Schristos  *              Level                   - Current tree nesting level
206cfbb7280Schristos  *              MethodInfo              - Info block for the current method
207cfbb7280Schristos  *
208cfbb7280Schristos  *
209cfbb7280Schristos  * RETURN:      None
210cfbb7280Schristos  *
211cfbb7280Schristos  * DESCRIPTION: Entry point for the creation of the method call reference map.
212cfbb7280Schristos  *              For each control method in the namespace, all other methods
213cfbb7280Schristos  *              that invoke the method are listed. Predefined names/methods
214cfbb7280Schristos  *              that start with an underscore are ignored, because these are
215cfbb7280Schristos  *              essentially external/public interfaces.
216cfbb7280Schristos 
217cfbb7280Schristos  * DESCRIPTION: Entry point for the creation of the object reference map.
218cfbb7280Schristos  *              For each control method in the namespace, all objects that
219cfbb7280Schristos  *              are referenced by the method are listed.
220cfbb7280Schristos  *
221cfbb7280Schristos  *              Called during a normal namespace walk, once per namespace
222cfbb7280Schristos  *              object. (MtMethodAnalysisWalkBegin)
223cfbb7280Schristos  *
224cfbb7280Schristos  ******************************************************************************/
225cfbb7280Schristos 
226cfbb7280Schristos void
OtXrefWalkPart1(ACPI_PARSE_OBJECT * Op,UINT32 Level,ASL_METHOD_INFO * MethodInfo)227cfbb7280Schristos OtXrefWalkPart1 (
228cfbb7280Schristos     ACPI_PARSE_OBJECT       *Op,
229cfbb7280Schristos     UINT32                  Level,
230cfbb7280Schristos     ASL_METHOD_INFO         *MethodInfo)
231cfbb7280Schristos {
232cfbb7280Schristos     ACPI_NAMESPACE_NODE     *Node;
233cfbb7280Schristos     ACPI_PARSE_OBJECT       *NextOp;
234cfbb7280Schristos     ACPI_PARSE_OBJECT       *FieldOp;
235cfbb7280Schristos     char                    *ParentPath;
236cfbb7280Schristos     UINT32                  Length;
237cfbb7280Schristos     ACPI_STATUS             Status;
238cfbb7280Schristos 
239cfbb7280Schristos 
240cfbb7280Schristos     switch (Op->Asl.ParseOpcode)
241cfbb7280Schristos     {
242cfbb7280Schristos     case PARSEOP_NAMESEG:
243cfbb7280Schristos     case PARSEOP_NAMESTRING:
244cfbb7280Schristos     case PARSEOP_METHODCALL:
245cfbb7280Schristos 
246cfbb7280Schristos         if (!MethodInfo ||
247cfbb7280Schristos             (MethodInfo->Op->Asl.Child == Op) ||
248cfbb7280Schristos             !Op->Asl.Node)
249cfbb7280Schristos         {
250cfbb7280Schristos             break;
251cfbb7280Schristos         }
252cfbb7280Schristos 
253cfbb7280Schristos         MethodInfo->CurrentOp = Op;
254cfbb7280Schristos         Node = Op->Asl.Node;
255cfbb7280Schristos 
256cfbb7280Schristos         /* Find all objects referenced by this method */
257cfbb7280Schristos 
258cfbb7280Schristos         Status = TrWalkParseTree (MethodInfo->Op, ASL_WALK_VISIT_DOWNWARD,
259cfbb7280Schristos             OtXrefAnalysisWalkPart1, NULL, MethodInfo);
260cfbb7280Schristos 
261cfbb7280Schristos         if (Status == AE_CTRL_TERMINATE)
262cfbb7280Schristos         {
263cfbb7280Schristos             ParentPath = AcpiNsGetNormalizedPathname (Node, TRUE);
264cfbb7280Schristos 
265cfbb7280Schristos             FlPrintFile (ASL_FILE_XREF_OUTPUT, "            %-40s %s",
266cfbb7280Schristos                 ParentPath, AcpiUtGetTypeName (Node->Type));
267cfbb7280Schristos             ACPI_FREE (ParentPath);
268cfbb7280Schristos 
269cfbb7280Schristos             switch (Node->Type)
270cfbb7280Schristos             {
271cfbb7280Schristos                 /* Handle externals */
272cfbb7280Schristos 
273cfbb7280Schristos             case ACPI_TYPE_ANY:
274cfbb7280Schristos             case ACPI_TYPE_FIELD_UNIT:
275cfbb7280Schristos 
276cfbb7280Schristos                 FlPrintFile (ASL_FILE_XREF_OUTPUT, " <External Object>");
277cfbb7280Schristos                 break;
278cfbb7280Schristos 
279cfbb7280Schristos             case ACPI_TYPE_INTEGER:
280cfbb7280Schristos 
281cfbb7280Schristos                 FlPrintFile (ASL_FILE_XREF_OUTPUT, " %8.8X%8.8X",
282cfbb7280Schristos                     ACPI_FORMAT_UINT64 (Op->Asl.Value.Integer));
283cfbb7280Schristos                 break;
284cfbb7280Schristos 
285cfbb7280Schristos             case ACPI_TYPE_METHOD:
286cfbb7280Schristos 
287cfbb7280Schristos                 FlPrintFile (ASL_FILE_XREF_OUTPUT, " Invocation (%u args)",
288cfbb7280Schristos                     Node->ArgCount);
289cfbb7280Schristos                 break;
290cfbb7280Schristos 
291cfbb7280Schristos             case ACPI_TYPE_BUFFER_FIELD:
292cfbb7280Schristos 
293cfbb7280Schristos                 NextOp = Node->Op;              /* Create Buffer Field Op */
294cfbb7280Schristos                 switch (NextOp->Asl.ParseOpcode)
295cfbb7280Schristos                 {
296cfbb7280Schristos                 case PARSEOP_CREATEBITFIELD:
297cfbb7280Schristos                     Length = 1;
298cfbb7280Schristos                     break;
299cfbb7280Schristos 
300cfbb7280Schristos                 case PARSEOP_CREATEBYTEFIELD:
301cfbb7280Schristos                     Length = 8;
302cfbb7280Schristos                     break;
303cfbb7280Schristos 
304cfbb7280Schristos                 case PARSEOP_CREATEWORDFIELD:
305cfbb7280Schristos                     Length = 16;
306cfbb7280Schristos                     break;
307cfbb7280Schristos 
308cfbb7280Schristos                 case PARSEOP_CREATEDWORDFIELD:
309cfbb7280Schristos                     Length = 32;
310cfbb7280Schristos                     break;
311cfbb7280Schristos 
312cfbb7280Schristos                 case PARSEOP_CREATEQWORDFIELD:
313cfbb7280Schristos                     Length = 64;
314cfbb7280Schristos                     break;
315cfbb7280Schristos 
316cfbb7280Schristos                 default:
317cfbb7280Schristos                     Length = 0;
318cfbb7280Schristos                     break;
319cfbb7280Schristos                 }
320cfbb7280Schristos 
321cfbb7280Schristos                 NextOp = NextOp->Asl.Child;     /* Buffer name */
322cfbb7280Schristos 
323cfbb7280Schristos                 if (!NextOp->Asl.ExternalName)
324cfbb7280Schristos                 {
325cfbb7280Schristos                     FlPrintFile (ASL_FILE_XREF_OUTPUT, " in Arg/Local");
326cfbb7280Schristos                 }
327cfbb7280Schristos                 else
328cfbb7280Schristos                 {
329cfbb7280Schristos                     ParentPath = AcpiNsGetNormalizedPathname (
330cfbb7280Schristos                         NextOp->Asl.Node, TRUE);
331cfbb7280Schristos 
332cfbb7280Schristos                     FlPrintFile (ASL_FILE_XREF_OUTPUT, " (%.2u bit) in Buffer %s",
333cfbb7280Schristos                         Length, ParentPath);
334cfbb7280Schristos                     ACPI_FREE (ParentPath);
335cfbb7280Schristos                 }
336cfbb7280Schristos                 break;
337cfbb7280Schristos 
338cfbb7280Schristos             case ACPI_TYPE_LOCAL_REGION_FIELD:
339cfbb7280Schristos 
340cfbb7280Schristos                 NextOp = Node->Op;
341cfbb7280Schristos                 FieldOp = NextOp->Asl.Parent;
342cfbb7280Schristos                 NextOp = FieldOp->Asl.Child;
343cfbb7280Schristos 
344cfbb7280Schristos                 ParentPath = AcpiNsGetNormalizedPathname (
345cfbb7280Schristos                     NextOp->Asl.Node, TRUE);
346cfbb7280Schristos 
347cfbb7280Schristos                 FlPrintFile (ASL_FILE_XREF_OUTPUT, " (%.2u bit) in Region %s",
348cfbb7280Schristos                     (UINT32) Node->Op->Asl.Child->Asl.Value.Integer,
349cfbb7280Schristos                     ParentPath);
350cfbb7280Schristos                 ACPI_FREE (ParentPath);
351cfbb7280Schristos 
352cfbb7280Schristos                 if (FieldOp->Asl.ParseOpcode == PARSEOP_FIELD)
353cfbb7280Schristos                 {
354cfbb7280Schristos                     Node = NextOp->Asl.Node;        /* Region node */
355cfbb7280Schristos                     NextOp = Node->Op;              /* PARSEOP_REGION */
356cfbb7280Schristos                     NextOp = NextOp->Asl.Child;     /* Region name */
357cfbb7280Schristos                     NextOp = NextOp->Asl.Next;
358cfbb7280Schristos 
359cfbb7280Schristos                     /* Get region space/addr/len? */
360cfbb7280Schristos 
361cfbb7280Schristos                     FlPrintFile (ASL_FILE_XREF_OUTPUT, " (%s)",
362cfbb7280Schristos                         AcpiUtGetRegionName ((UINT8)
363cfbb7280Schristos                         NextOp->Asl.Value.Integer));
364cfbb7280Schristos                 }
365cfbb7280Schristos                 break;
366cfbb7280Schristos 
367cfbb7280Schristos             default:
368cfbb7280Schristos                 break;
369cfbb7280Schristos             }
370cfbb7280Schristos 
371cfbb7280Schristos             FlPrintFile (ASL_FILE_XREF_OUTPUT, "\n");
372cfbb7280Schristos         }
373cfbb7280Schristos         break;
374cfbb7280Schristos 
375cfbb7280Schristos     case PARSEOP_METHOD:
376cfbb7280Schristos 
377cfbb7280Schristos         ParentPath = AcpiNsGetNormalizedPathname (Op->Asl.Node, TRUE);
378cfbb7280Schristos 
379cfbb7280Schristos         FlPrintFile (ASL_FILE_XREF_OUTPUT,
380cfbb7280Schristos             "\n[%5u]  %-40s %s Declaration (%u args)\n",
381cfbb7280Schristos             Op->Asl.LogicalLineNumber, ParentPath,
382cfbb7280Schristos             AcpiUtGetTypeName (Op->Asl.Node->Type), Op->Asl.Node->ArgCount);
383cfbb7280Schristos 
384cfbb7280Schristos         ACPI_FREE (ParentPath);
385cfbb7280Schristos         break;
386cfbb7280Schristos 
387cfbb7280Schristos     default:
388cfbb7280Schristos         break;
389cfbb7280Schristos     }
390cfbb7280Schristos }
391cfbb7280Schristos 
392cfbb7280Schristos 
393cfbb7280Schristos /*******************************************************************************
394cfbb7280Schristos  *
395cfbb7280Schristos  * FUNCTION:    OtXrefAnalysisWalkPart1
396cfbb7280Schristos  *
397cfbb7280Schristos  * PARAMETERS:  ASL_WALK_CALLBACK
398cfbb7280Schristos  *
399cfbb7280Schristos  * RETURN:      Status
400cfbb7280Schristos  *
401cfbb7280Schristos  * DESCRIPTION: Secondary walk for cross-reference part 1.
402cfbb7280Schristos  *
403cfbb7280Schristos  ******************************************************************************/
404cfbb7280Schristos 
405cfbb7280Schristos static ACPI_STATUS
OtXrefAnalysisWalkPart1(ACPI_PARSE_OBJECT * Op,UINT32 Level,void * Context)406cfbb7280Schristos OtXrefAnalysisWalkPart1 (
407cfbb7280Schristos     ACPI_PARSE_OBJECT       *Op,
408cfbb7280Schristos     UINT32                  Level,
409cfbb7280Schristos     void                    *Context)
410cfbb7280Schristos {
411cfbb7280Schristos     ASL_METHOD_INFO         *MethodInfo = (ASL_METHOD_INFO *) Context;
412cfbb7280Schristos     ACPI_PARSE_OBJECT       *Next;
413cfbb7280Schristos 
414cfbb7280Schristos 
415cfbb7280Schristos     /* Only interested in name string Ops -- ignore all others */
416cfbb7280Schristos 
417cfbb7280Schristos     if ((Op->Asl.ParseOpcode != PARSEOP_NAMESEG) &&
418cfbb7280Schristos         (Op->Asl.ParseOpcode != PARSEOP_NAMESTRING) &&
419cfbb7280Schristos         (Op->Asl.ParseOpcode != PARSEOP_METHODCALL))
420cfbb7280Schristos     {
421cfbb7280Schristos         return (AE_OK);
422cfbb7280Schristos     }
423cfbb7280Schristos 
424cfbb7280Schristos     /* No node means a locally declared object -- ignore */
425cfbb7280Schristos 
426cfbb7280Schristos     if (!Op->Asl.Node)
427cfbb7280Schristos     {
428cfbb7280Schristos         return (AE_OK);
429cfbb7280Schristos     }
430cfbb7280Schristos 
431cfbb7280Schristos     /* When we encounter the source Op, we are done */
432cfbb7280Schristos 
433cfbb7280Schristos     Next = MethodInfo->CurrentOp;
434cfbb7280Schristos     if (Next == Op)
435cfbb7280Schristos     {
436cfbb7280Schristos         return (AE_CTRL_TERMINATE);
437cfbb7280Schristos     }
438cfbb7280Schristos 
439cfbb7280Schristos     /* If we have a name match, this Op is a duplicate */
440cfbb7280Schristos 
441cfbb7280Schristos     if ((Next->Asl.ParseOpcode == PARSEOP_NAMESEG)      ||
442cfbb7280Schristos         (Next->Asl.ParseOpcode == PARSEOP_NAMESTRING)   ||
443cfbb7280Schristos         (Next->Asl.ParseOpcode == PARSEOP_METHODCALL))
444cfbb7280Schristos     {
445cfbb7280Schristos         if (!strcmp (Op->Asl.ExternalName, Next->Asl.ExternalName))
446cfbb7280Schristos         {
447cfbb7280Schristos             return (AE_ALREADY_EXISTS);
448cfbb7280Schristos         }
449cfbb7280Schristos     }
450cfbb7280Schristos 
451cfbb7280Schristos     return (AE_OK);
452cfbb7280Schristos }
453cfbb7280Schristos 
454cfbb7280Schristos 
455cfbb7280Schristos /*
456cfbb7280Schristos  * Part 2 of the cross reference file. This part emits the names of each
457cfbb7280Schristos  * non-predefined method in the namespace (user methods), along with the
458cfbb7280Schristos  * names of each control method that references that method.
459cfbb7280Schristos  */
460cfbb7280Schristos 
461cfbb7280Schristos /*******************************************************************************
462cfbb7280Schristos  *
463cfbb7280Schristos  * FUNCTION:    OtXrefWalkPart2
464cfbb7280Schristos  *
465cfbb7280Schristos  * PARAMETERS:  ASL_WALK_CALLBACK
466cfbb7280Schristos  *
467cfbb7280Schristos  * RETURN:      Status
468cfbb7280Schristos  *
469cfbb7280Schristos  * DESCRIPTION: For each control method in the namespace, we will re-walk the
470cfbb7280Schristos  *              namespace to find each and every invocation of that control
471cfbb7280Schristos  *              method. Brute force, but does not matter, even for large
472cfbb7280Schristos  *              namespaces. Ignore predefined names (start with underscore).
473cfbb7280Schristos  *
474cfbb7280Schristos  ******************************************************************************/
475cfbb7280Schristos 
476cfbb7280Schristos static ACPI_STATUS
OtXrefWalkPart2(ACPI_PARSE_OBJECT * Op,UINT32 Level,void * Context)477cfbb7280Schristos OtXrefWalkPart2 (
478cfbb7280Schristos     ACPI_PARSE_OBJECT       *Op,
479cfbb7280Schristos     UINT32                  Level,
480cfbb7280Schristos     void                    *Context)
481cfbb7280Schristos {
482cfbb7280Schristos     ASL_XREF_INFO           *XrefInfo = (ASL_XREF_INFO *) Context;
483cfbb7280Schristos     ACPI_NAMESPACE_NODE     *Node;
484cfbb7280Schristos     char                    *ParentPath;
485cfbb7280Schristos 
486cfbb7280Schristos 
487cfbb7280Schristos     /* Looking for Method Declaration Ops only */
488cfbb7280Schristos 
489cfbb7280Schristos     if (!Op->Asl.Node ||
490cfbb7280Schristos         (Op->Asl.ParseOpcode != PARSEOP_METHOD))
491cfbb7280Schristos     {
492cfbb7280Schristos         return (AE_OK);
493cfbb7280Schristos     }
494cfbb7280Schristos 
495cfbb7280Schristos     /* Ignore predefined names */
496cfbb7280Schristos 
497cfbb7280Schristos     if (Op->Asl.Node->Name.Ascii[0] == '_')
498cfbb7280Schristos     {
499cfbb7280Schristos         XrefInfo->TotalPredefinedMethods++;
500cfbb7280Schristos         return (AE_OK);
501cfbb7280Schristos     }
502cfbb7280Schristos 
503cfbb7280Schristos     Node = Op->Asl.Node;
504cfbb7280Schristos     ParentPath = AcpiNsGetNormalizedPathname (Node, TRUE);
505cfbb7280Schristos 
506cfbb7280Schristos     FlPrintFile (ASL_FILE_XREF_OUTPUT,
507cfbb7280Schristos         "\n[%5u]  %-40s %s Declaration (%u args)\n",
508cfbb7280Schristos         Op->Asl.LogicalLineNumber, ParentPath,
509cfbb7280Schristos         AcpiUtGetTypeName (Node->Type), Node->ArgCount);
510cfbb7280Schristos 
511cfbb7280Schristos     XrefInfo->TotalUserMethods++;
512cfbb7280Schristos     XrefInfo->ThisMethodInvocations = 0;
513cfbb7280Schristos     XrefInfo->MethodOp = Op;
514cfbb7280Schristos 
5154c4e8184Schristos     (void) TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_DOWNWARD,
516cfbb7280Schristos         OtXrefAnalysisWalkPart2, NULL, XrefInfo);
517cfbb7280Schristos 
518cfbb7280Schristos     if (!XrefInfo->ThisMethodInvocations)
519cfbb7280Schristos     {
520cfbb7280Schristos         FlPrintFile (ASL_FILE_XREF_OUTPUT,
521cfbb7280Schristos             "            Zero invocations of this method in this module\n");
522cfbb7280Schristos         XrefInfo->TotalUnreferenceUserMethods++;
523cfbb7280Schristos     }
524cfbb7280Schristos     else
525cfbb7280Schristos     {
526cfbb7280Schristos         FlPrintFile (ASL_FILE_XREF_OUTPUT,
527cfbb7280Schristos             "            %u invocations of method %s in this module\n",
528cfbb7280Schristos             XrefInfo->ThisMethodInvocations, ParentPath);
529cfbb7280Schristos     }
530cfbb7280Schristos 
531cfbb7280Schristos     ACPI_FREE (ParentPath);
532cfbb7280Schristos     return (AE_OK);
533cfbb7280Schristos }
534cfbb7280Schristos 
535cfbb7280Schristos 
536cfbb7280Schristos /*******************************************************************************
537cfbb7280Schristos  *
538cfbb7280Schristos  * FUNCTION:    OtXrefAnalysisWalkPart2
539cfbb7280Schristos  *
540cfbb7280Schristos  * PARAMETERS:  ASL_WALK_CALLBACK
541cfbb7280Schristos  *
542cfbb7280Schristos  * RETURN:      Status
543cfbb7280Schristos  *
544cfbb7280Schristos  * DESCRIPTION: For every Op that is a method invocation, emit a reference
545cfbb7280Schristos  *              line if the Op is invoking the target method.
546cfbb7280Schristos  *
547cfbb7280Schristos  ******************************************************************************/
548cfbb7280Schristos 
549cfbb7280Schristos static ACPI_STATUS
OtXrefAnalysisWalkPart2(ACPI_PARSE_OBJECT * Op,UINT32 Level,void * Context)550cfbb7280Schristos OtXrefAnalysisWalkPart2 (
551cfbb7280Schristos     ACPI_PARSE_OBJECT       *Op,
552cfbb7280Schristos     UINT32                  Level,
553cfbb7280Schristos     void                    *Context)
554cfbb7280Schristos {
555cfbb7280Schristos     ASL_XREF_INFO           *XrefInfo = (ASL_XREF_INFO *) Context;
556cfbb7280Schristos     ACPI_PARSE_OBJECT       *CallerOp;
557cfbb7280Schristos     char                    *CallerFullPathname;
558cfbb7280Schristos 
559cfbb7280Schristos 
560cfbb7280Schristos     /* Looking for MethodCall Ops only */
561cfbb7280Schristos 
562cfbb7280Schristos     if (!Op->Asl.Node ||
563cfbb7280Schristos         (Op->Asl.ParseOpcode != PARSEOP_METHODCALL))
564cfbb7280Schristos     {
565cfbb7280Schristos         return (AE_OK);
566cfbb7280Schristos     }
567cfbb7280Schristos 
568cfbb7280Schristos     /* If not a match to the target method, we are done */
569cfbb7280Schristos 
570cfbb7280Schristos     if (Op->Asl.Node != XrefInfo->MethodOp->Asl.Node)
571cfbb7280Schristos     {
572cfbb7280Schristos         return (AE_CTRL_DEPTH);
573cfbb7280Schristos     }
574cfbb7280Schristos 
575cfbb7280Schristos     /* Find parent method to get method caller namepath */
576cfbb7280Schristos 
577cfbb7280Schristos     CallerOp = Op->Asl.Parent;
578cfbb7280Schristos     while (CallerOp &&
579cfbb7280Schristos         (CallerOp->Asl.ParseOpcode != PARSEOP_METHOD))
580cfbb7280Schristos     {
581cfbb7280Schristos         CallerOp = CallerOp->Asl.Parent;
582cfbb7280Schristos     }
583cfbb7280Schristos 
584cfbb7280Schristos     /* There is no parent method for External() statements */
585cfbb7280Schristos 
586cfbb7280Schristos     if (!CallerOp)
587cfbb7280Schristos     {
588cfbb7280Schristos         return (AE_OK);
589cfbb7280Schristos     }
590cfbb7280Schristos 
591cfbb7280Schristos     CallerFullPathname = AcpiNsGetNormalizedPathname (
592cfbb7280Schristos         CallerOp->Asl.Node, TRUE);
593cfbb7280Schristos 
594cfbb7280Schristos     FlPrintFile (ASL_FILE_XREF_OUTPUT,
595cfbb7280Schristos         "[%5u]     %-40s Invocation path: %s\n",
596cfbb7280Schristos         Op->Asl.LogicalLineNumber, CallerFullPathname,
597cfbb7280Schristos         Op->Asl.ExternalName);
598cfbb7280Schristos 
599cfbb7280Schristos     ACPI_FREE (CallerFullPathname);
600cfbb7280Schristos     XrefInfo->ThisMethodInvocations++;
601cfbb7280Schristos     return (AE_OK);
602cfbb7280Schristos }
603cfbb7280Schristos 
604cfbb7280Schristos 
605cfbb7280Schristos /*
606cfbb7280Schristos  * Part 3 of the cross reference file. This part emits the names of each
607cfbb7280Schristos  * non-predefined method in the namespace (user methods), along with the
608cfbb7280Schristos  * names of each control method that references that method.
609cfbb7280Schristos  */
610cfbb7280Schristos 
611cfbb7280Schristos /*******************************************************************************
612cfbb7280Schristos  *
613cfbb7280Schristos  * FUNCTION:    OtXrefWalkPart3
614cfbb7280Schristos  *
615cfbb7280Schristos  * PARAMETERS:  ASL_WALK_CALLBACK
616cfbb7280Schristos  *
617cfbb7280Schristos  * RETURN:      Status
618cfbb7280Schristos  *
619cfbb7280Schristos  * DESCRIPTION: Cross-reference part 3. references to objects other than
620cfbb7280Schristos  *              control methods.
621cfbb7280Schristos  *
622cfbb7280Schristos  ******************************************************************************/
623cfbb7280Schristos 
624cfbb7280Schristos static ACPI_STATUS
OtXrefWalkPart3(ACPI_PARSE_OBJECT * Op,UINT32 Level,void * Context)625cfbb7280Schristos OtXrefWalkPart3 (
626cfbb7280Schristos     ACPI_PARSE_OBJECT       *Op,
627cfbb7280Schristos     UINT32                  Level,
628cfbb7280Schristos     void                    *Context)
629cfbb7280Schristos {
630cfbb7280Schristos     ASL_XREF_INFO           *XrefInfo = (ASL_XREF_INFO *) Context;
631cfbb7280Schristos     ACPI_NAMESPACE_NODE     *Node;
632cfbb7280Schristos     char                    *ParentPath;
633cfbb7280Schristos     const ACPI_OPCODE_INFO  *OpInfo;
634cfbb7280Schristos 
635cfbb7280Schristos 
636cfbb7280Schristos     /* Ignore method declarations */
637cfbb7280Schristos 
638cfbb7280Schristos     if (!Op->Asl.Node ||
639cfbb7280Schristos         (Op->Asl.ParseOpcode == PARSEOP_METHOD))
640cfbb7280Schristos     {
641cfbb7280Schristos         return (AE_OK);
642cfbb7280Schristos     }
643cfbb7280Schristos 
644cfbb7280Schristos     OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
645cfbb7280Schristos     if (!(OpInfo->Class & AML_CLASS_NAMED_OBJECT))
646cfbb7280Schristos     {
647cfbb7280Schristos         return (AE_OK);
648cfbb7280Schristos     }
649cfbb7280Schristos 
650cfbb7280Schristos     /* Only care about named object creation opcodes */
651cfbb7280Schristos 
652cfbb7280Schristos     if ((Op->Asl.ParseOpcode != PARSEOP_NAME) &&
653cfbb7280Schristos         (Op->Asl.ParseOpcode != PARSEOP_DEVICE) &&
654cfbb7280Schristos         (Op->Asl.ParseOpcode != PARSEOP_MUTEX) &&
655cfbb7280Schristos         (Op->Asl.ParseOpcode != PARSEOP_OPERATIONREGION) &&
656cfbb7280Schristos         (Op->Asl.ParseOpcode != PARSEOP_FIELD) &&
657cfbb7280Schristos         (Op->Asl.ParseOpcode != PARSEOP_EVENT))
658cfbb7280Schristos     {
659cfbb7280Schristos         return (AE_OK);
660cfbb7280Schristos     }
661cfbb7280Schristos 
662cfbb7280Schristos     /* Ignore predefined names */
663cfbb7280Schristos 
664cfbb7280Schristos     if (Op->Asl.Node->Name.Ascii[0] == '_')
665cfbb7280Schristos     {
666cfbb7280Schristos         return (AE_OK);
667cfbb7280Schristos     }
668cfbb7280Schristos 
669cfbb7280Schristos     Node = Op->Asl.Node;
670cfbb7280Schristos     ParentPath = AcpiNsGetNormalizedPathname (Node, TRUE);
671cfbb7280Schristos 
672cfbb7280Schristos     FlPrintFile (ASL_FILE_XREF_OUTPUT,
673cfbb7280Schristos         "\n[%5u]  %-40s %s Declaration\n",
674cfbb7280Schristos         Op->Asl.LogicalLineNumber, ParentPath,
675cfbb7280Schristos         AcpiUtGetTypeName (Node->Type));
676cfbb7280Schristos     ACPI_FREE (ParentPath);
677cfbb7280Schristos 
678cfbb7280Schristos     XrefInfo->MethodOp = Op;
679cfbb7280Schristos     XrefInfo->ThisObjectReferences = 0;
680cfbb7280Schristos     XrefInfo->TotalObjects = 0;
681cfbb7280Schristos 
6824c4e8184Schristos     (void) TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_DOWNWARD,
683cfbb7280Schristos         OtXrefAnalysisWalkPart3, NULL, XrefInfo);
684cfbb7280Schristos 
685cfbb7280Schristos     if (!XrefInfo->ThisObjectReferences)
686cfbb7280Schristos     {
687cfbb7280Schristos         FlPrintFile (ASL_FILE_XREF_OUTPUT,
688cfbb7280Schristos             "            Zero references to this object in this module\n");
689cfbb7280Schristos         XrefInfo->TotalUnreferencedObjects++;
690cfbb7280Schristos     }
691cfbb7280Schristos     else
692cfbb7280Schristos     {
693cfbb7280Schristos         FlPrintFile (ASL_FILE_XREF_OUTPUT,
694783af925Schristos             "            %u references to this object in this module [%s]\n",
695cfbb7280Schristos             XrefInfo->ThisObjectReferences, ParentPath);
696cfbb7280Schristos     }
697cfbb7280Schristos 
698cfbb7280Schristos     return (AE_OK);
699cfbb7280Schristos }
700cfbb7280Schristos 
701cfbb7280Schristos 
702cfbb7280Schristos /*******************************************************************************
703cfbb7280Schristos  *
704cfbb7280Schristos  * FUNCTION:    OtXrefAnalysisWalkPart3
705cfbb7280Schristos  *
706cfbb7280Schristos  * PARAMETERS:  ASL_WALK_CALLBACK
707cfbb7280Schristos  *
708cfbb7280Schristos  * RETURN:      Status
709cfbb7280Schristos  *
710cfbb7280Schristos  * DESCRIPTION: Secondary walk for cross-reference part 3.
711cfbb7280Schristos  *
712cfbb7280Schristos  ******************************************************************************/
713cfbb7280Schristos 
714cfbb7280Schristos static ACPI_STATUS
OtXrefAnalysisWalkPart3(ACPI_PARSE_OBJECT * Op,UINT32 Level,void * Context)715cfbb7280Schristos OtXrefAnalysisWalkPart3 (
716cfbb7280Schristos     ACPI_PARSE_OBJECT       *Op,
717cfbb7280Schristos     UINT32                  Level,
718cfbb7280Schristos     void                    *Context)
719cfbb7280Schristos {
720cfbb7280Schristos     ASL_XREF_INFO           *XrefInfo = (ASL_XREF_INFO *) Context;
721cfbb7280Schristos     char                    *CallerFullPathname = NULL;
722cfbb7280Schristos     ACPI_PARSE_OBJECT       *CallerOp;
723cfbb7280Schristos     const char              *Operator;
724cfbb7280Schristos 
725cfbb7280Schristos 
726cfbb7280Schristos     if (!Op->Asl.Node)
727cfbb7280Schristos     {
728cfbb7280Schristos         return (AE_OK);
729cfbb7280Schristos     }
730cfbb7280Schristos 
731cfbb7280Schristos     XrefInfo->TotalObjects++;
732cfbb7280Schristos 
733cfbb7280Schristos     /* Ignore Op that actually defined the object */
734cfbb7280Schristos 
735cfbb7280Schristos     if (Op == XrefInfo->MethodOp)
736cfbb7280Schristos     {
737cfbb7280Schristos         return (AE_OK);
738cfbb7280Schristos     }
739cfbb7280Schristos 
740cfbb7280Schristos     /* Only interested in Ops that reference the target node */
741cfbb7280Schristos 
742cfbb7280Schristos     if (Op->Asl.Node != XrefInfo->MethodOp->Asl.Node)
743cfbb7280Schristos     {
744cfbb7280Schristos         return (AE_OK);
745cfbb7280Schristos     }
746cfbb7280Schristos 
747cfbb7280Schristos     /* Find parent "open scope" object to get method caller namepath */
748cfbb7280Schristos 
749cfbb7280Schristos     CallerOp = Op->Asl.Parent;
750cfbb7280Schristos     while (CallerOp &&
751cfbb7280Schristos         (CallerOp->Asl.ParseOpcode != PARSEOP_NAME) &&
752cfbb7280Schristos         (CallerOp->Asl.ParseOpcode != PARSEOP_METHOD) &&
753cfbb7280Schristos         (CallerOp->Asl.ParseOpcode != PARSEOP_DEVICE) &&
754cfbb7280Schristos         (CallerOp->Asl.ParseOpcode != PARSEOP_POWERRESOURCE) &&
755cfbb7280Schristos         (CallerOp->Asl.ParseOpcode != PARSEOP_PROCESSOR) &&
756cfbb7280Schristos         (CallerOp->Asl.ParseOpcode != PARSEOP_THERMALZONE))
757cfbb7280Schristos     {
758cfbb7280Schristos         CallerOp = CallerOp->Asl.Parent;
759cfbb7280Schristos     }
760cfbb7280Schristos 
761cfbb7280Schristos     if (CallerOp == XrefInfo->CurrentMethodOp)
762cfbb7280Schristos     {
763cfbb7280Schristos         return (AE_OK);
764cfbb7280Schristos     }
765cfbb7280Schristos 
766cfbb7280Schristos     /* Null CallerOp means the caller is at the namespace root */
767cfbb7280Schristos 
768cfbb7280Schristos     if (CallerOp)
769cfbb7280Schristos     {
770cfbb7280Schristos         CallerFullPathname = AcpiNsGetNormalizedPathname (
771cfbb7280Schristos             CallerOp->Asl.Node, TRUE);
772cfbb7280Schristos     }
773cfbb7280Schristos 
774cfbb7280Schristos     /* There are some special cases for the oddball operators */
775cfbb7280Schristos 
776cfbb7280Schristos     if (Op->Asl.ParseOpcode == PARSEOP_SCOPE)
777cfbb7280Schristos     {
778cfbb7280Schristos         Operator = "Scope";
779cfbb7280Schristos     }
780cfbb7280Schristos     else if (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_ALIAS)
781cfbb7280Schristos     {
782cfbb7280Schristos         Operator = "Alias";
783cfbb7280Schristos     }
784cfbb7280Schristos     else if (!CallerOp)
785cfbb7280Schristos     {
786cfbb7280Schristos         Operator = "ModLevel";
787cfbb7280Schristos     }
788cfbb7280Schristos     else
789cfbb7280Schristos     {
790cfbb7280Schristos         Operator = AcpiUtGetTypeName (CallerOp->Asl.Node->Type);
791cfbb7280Schristos     }
792cfbb7280Schristos 
793cfbb7280Schristos     FlPrintFile (ASL_FILE_XREF_OUTPUT,
794cfbb7280Schristos         "[%5u]     %-40s %-8s via path: %s, Operator: %s\n",
795cfbb7280Schristos         Op->Asl.LogicalLineNumber,
796cfbb7280Schristos         CallerFullPathname ? CallerFullPathname : "<root>",
797cfbb7280Schristos         Operator,
798cfbb7280Schristos         Op->Asl.ExternalName,
799cfbb7280Schristos         Op->Asl.Parent->Asl.ParseOpName);
800cfbb7280Schristos 
801cfbb7280Schristos     if (!CallerOp)
802cfbb7280Schristos     {
803cfbb7280Schristos         CallerOp = ACPI_TO_POINTER (0xFFFFFFFF);
804cfbb7280Schristos     }
805cfbb7280Schristos 
806cfbb7280Schristos     if (CallerFullPathname)
807cfbb7280Schristos     {
808cfbb7280Schristos         ACPI_FREE (CallerFullPathname);
809cfbb7280Schristos     }
810cfbb7280Schristos 
811cfbb7280Schristos     XrefInfo->CurrentMethodOp = CallerOp;
812cfbb7280Schristos     XrefInfo->ThisObjectReferences++;
813cfbb7280Schristos     return (AE_OK);
814cfbb7280Schristos }
815