xref: /freebsd/sys/contrib/dev/acpica/components/disassembler/dmnames.c (revision 907b59d76938e654f0d040a888e8dfca3de1e222)
1 /*******************************************************************************
2  *
3  * Module Name: dmnames - AML disassembler, names, namestrings, pathnames
4  *
5  ******************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2016, Intel Corp.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions, and the following disclaimer,
16  *    without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  *    substantially similar to the "NO WARRANTY" disclaimer below
19  *    ("Disclaimer") and any redistribution must be conditioned upon
20  *    including a substantially similar Disclaimer requirement for further
21  *    binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  *    of any contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43 
44 #include <contrib/dev/acpica/include/acpi.h>
45 #include <contrib/dev/acpica/include/accommon.h>
46 #include <contrib/dev/acpica/include/amlcode.h>
47 #include <contrib/dev/acpica/include/acnamesp.h>
48 #include <contrib/dev/acpica/include/acdisasm.h>
49 
50 
51 #define _COMPONENT          ACPI_CA_DEBUGGER
52         ACPI_MODULE_NAME    ("dmnames")
53 
54 /* Local prototypes */
55 
56 #ifdef ACPI_OBSOLETE_FUNCTIONS
57 void
58 AcpiDmDisplayPath (
59     ACPI_PARSE_OBJECT       *Op);
60 #endif
61 
62 
63 /*******************************************************************************
64  *
65  * FUNCTION:    AcpiDmDumpName
66  *
67  * PARAMETERS:  Name            - 4 character ACPI name
68  *
69  * RETURN:      Final length of name
70  *
71  * DESCRIPTION: Dump an ACPI name, minus any trailing underscores.
72  *
73  ******************************************************************************/
74 
75 UINT32
76 AcpiDmDumpName (
77     UINT32                  Name)
78 {
79     UINT32                  i;
80     UINT32                  Length;
81     char                    NewName[4];
82 
83 
84     /* Copy name locally in case the original name is not writeable */
85 
86     *ACPI_CAST_PTR (UINT32, &NewName[0]) = Name;
87 
88     /* Ensure that the name is printable, even if we have to fix it */
89 
90     AcpiUtRepairName (NewName);
91 
92     /* Remove all trailing underscores from the name */
93 
94     Length = ACPI_NAME_SIZE;
95     for (i = (ACPI_NAME_SIZE - 1); i != 0; i--)
96     {
97         if (NewName[i] == '_')
98         {
99             Length--;
100         }
101         else
102         {
103             break;
104         }
105     }
106 
107     /* Dump the name, up to the start of the trailing underscores */
108 
109     for (i = 0; i < Length; i++)
110     {
111         AcpiOsPrintf ("%c", NewName[i]);
112     }
113 
114     return (Length);
115 }
116 
117 
118 /*******************************************************************************
119  *
120  * FUNCTION:    AcpiPsDisplayObjectPathname
121  *
122  * PARAMETERS:  WalkState       - Current walk state
123  *              Op              - Object whose pathname is to be obtained
124  *
125  * RETURN:      Status
126  *
127  * DESCRIPTION: Diplay the pathname associated with a named object. Two
128  *              versions. One searches the parse tree (for parser-only
129  *              applications suchas AcpiDump), and the other searches the
130  *              ACPI namespace (the parse tree is probably deleted)
131  *
132  ******************************************************************************/
133 
134 ACPI_STATUS
135 AcpiPsDisplayObjectPathname (
136     ACPI_WALK_STATE         *WalkState,
137     ACPI_PARSE_OBJECT       *Op)
138 {
139     ACPI_STATUS             Status;
140     ACPI_NAMESPACE_NODE     *Node;
141     ACPI_BUFFER             Buffer;
142     UINT32                  DebugLevel;
143 
144 
145     /* Save current debug level so we don't get extraneous debug output */
146 
147     DebugLevel = AcpiDbgLevel;
148     AcpiDbgLevel = 0;
149 
150     /* Just get the Node out of the Op object */
151 
152     Node = Op->Common.Node;
153     if (!Node)
154     {
155         /* Node not defined in this scope, look it up */
156 
157         Status = AcpiNsLookup (WalkState->ScopeInfo, Op->Common.Value.String,
158             ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
159             WalkState, &(Node));
160 
161         if (ACPI_FAILURE (Status))
162         {
163             /*
164              * We can't get the pathname since the object is not in the
165              * namespace. This can happen during single stepping
166              * where a dynamic named object is *about* to be created.
167              */
168             AcpiOsPrintf ("  [Path not found]");
169             goto Exit;
170         }
171 
172         /* Save it for next time. */
173 
174         Op->Common.Node = Node;
175     }
176 
177     /* Convert NamedDesc/handle to a full pathname */
178 
179     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
180     Status = AcpiNsHandleToPathname (Node, &Buffer, FALSE);
181     if (ACPI_FAILURE (Status))
182     {
183         AcpiOsPrintf ("****Could not get pathname****)");
184         goto Exit;
185     }
186 
187     AcpiOsPrintf ("  (Path %s)", (char *) Buffer.Pointer);
188     ACPI_FREE (Buffer.Pointer);
189 
190 
191 Exit:
192     /* Restore the debug level */
193 
194     AcpiDbgLevel = DebugLevel;
195     return (Status);
196 }
197 
198 
199 /*******************************************************************************
200  *
201  * FUNCTION:    AcpiDmNamestring
202  *
203  * PARAMETERS:  Name                - ACPI Name string to store
204  *
205  * RETURN:      None
206  *
207  * DESCRIPTION: Decode and dump an ACPI namestring. Handles prefix characters
208  *
209  ******************************************************************************/
210 
211 void
212 AcpiDmNamestring (
213     char                    *Name)
214 {
215     UINT32                  SegCount;
216 
217 
218     if (!Name)
219     {
220         return;
221     }
222 
223     /* Handle all Scope Prefix operators */
224 
225     while (ACPI_IS_ROOT_PREFIX (ACPI_GET8 (Name)) ||
226            ACPI_IS_PARENT_PREFIX (ACPI_GET8 (Name)))
227     {
228         /* Append prefix character */
229 
230         AcpiOsPrintf ("%1c", ACPI_GET8 (Name));
231         Name++;
232     }
233 
234     switch (ACPI_GET8 (Name))
235     {
236     case 0:
237 
238         SegCount = 0;
239         break;
240 
241     case AML_DUAL_NAME_PREFIX:
242 
243         SegCount = 2;
244         Name++;
245         break;
246 
247     case AML_MULTI_NAME_PREFIX_OP:
248 
249         SegCount = (UINT32) ACPI_GET8 (Name + 1);
250         Name += 2;
251         break;
252 
253     default:
254 
255         SegCount = 1;
256         break;
257     }
258 
259     while (SegCount)
260     {
261         /* Append Name segment */
262 
263         AcpiDmDumpName (*ACPI_CAST_PTR (UINT32, Name));
264 
265         SegCount--;
266         if (SegCount)
267         {
268             /* Not last name, append dot separator */
269 
270             AcpiOsPrintf (".");
271         }
272 
273         Name += ACPI_NAME_SIZE;
274     }
275 }
276 
277 
278 #ifdef ACPI_OBSOLETE_FUNCTIONS
279 /*******************************************************************************
280  *
281  * FUNCTION:    AcpiDmDisplayPath
282  *
283  * PARAMETERS:  Op                  - Named Op whose path is to be constructed
284  *
285  * RETURN:      None
286  *
287  * DESCRIPTION: Walk backwards from current scope and display the name
288  *              of each previous level of scope up to the root scope
289  *              (like "pwd" does with file systems)
290  *
291  ******************************************************************************/
292 
293 void
294 AcpiDmDisplayPath (
295     ACPI_PARSE_OBJECT       *Op)
296 {
297     ACPI_PARSE_OBJECT       *Prev;
298     ACPI_PARSE_OBJECT       *Search;
299     UINT32                  Name;
300     BOOLEAN                 DoDot = FALSE;
301     ACPI_PARSE_OBJECT       *NamePath;
302     const ACPI_OPCODE_INFO  *OpInfo;
303 
304 
305     /* We are only interested in named objects */
306 
307     OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
308     if (!(OpInfo->Flags & AML_NSNODE))
309     {
310         return;
311     }
312 
313     if (OpInfo->Flags & AML_CREATE)
314     {
315         /* Field creation - check for a fully qualified namepath */
316 
317         if (Op->Common.AmlOpcode == AML_CREATE_FIELD_OP)
318         {
319             NamePath = AcpiPsGetArg (Op, 3);
320         }
321         else
322         {
323             NamePath = AcpiPsGetArg (Op, 2);
324         }
325 
326         if ((NamePath) &&
327             (NamePath->Common.Value.String) &&
328             (ACPI_IS_ROOT_PREFIX (NamePath->Common.Value.String[0])))
329         {
330             AcpiDmNamestring (NamePath->Common.Value.String);
331             return;
332         }
333     }
334 
335     Prev = NULL;            /* Start with Root Node */
336     while (Prev != Op)
337     {
338         /* Search upwards in the tree to find scope with "prev" as its parent */
339 
340         Search = Op;
341         for (; ;)
342         {
343             if (Search->Common.Parent == Prev)
344             {
345                 break;
346             }
347 
348             /* Go up one level */
349 
350             Search = Search->Common.Parent;
351         }
352 
353         if (Prev)
354         {
355             OpInfo = AcpiPsGetOpcodeInfo (Search->Common.AmlOpcode);
356             if (!(OpInfo->Flags & AML_FIELD))
357             {
358                 /* Below root scope, append scope name */
359 
360                 if (DoDot)
361                 {
362                     /* Append dot */
363 
364                     AcpiOsPrintf (".");
365                 }
366 
367                 if (OpInfo->Flags & AML_CREATE)
368                 {
369                     if (Op->Common.AmlOpcode == AML_CREATE_FIELD_OP)
370                     {
371                         NamePath = AcpiPsGetArg (Op, 3);
372                     }
373                     else
374                     {
375                         NamePath = AcpiPsGetArg (Op, 2);
376                     }
377 
378                     if ((NamePath) &&
379                         (NamePath->Common.Value.String))
380                     {
381                         AcpiDmDumpName (NamePath->Common.Value.String);
382                     }
383                 }
384                 else
385                 {
386                     Name = AcpiPsGetName (Search);
387                     AcpiDmDumpName ((char *) &Name);
388                 }
389 
390                 DoDot = TRUE;
391             }
392         }
393 
394         Prev = Search;
395     }
396 }
397 
398 
399 /*******************************************************************************
400  *
401  * FUNCTION:    AcpiDmValidateName
402  *
403  * PARAMETERS:  Name            - 4 character ACPI name
404  *
405  * RETURN:      None
406  *
407  * DESCRIPTION: Lookup the name
408  *
409  ******************************************************************************/
410 
411 void
412 AcpiDmValidateName (
413     char                    *Name,
414     ACPI_PARSE_OBJECT       *Op)
415 {
416     ACPI_PARSE_OBJECT       *TargetOp;
417 
418 
419     if ((!Name) ||
420         (!Op->Common.Parent))
421     {
422         return;
423     }
424 
425     if (!Op->Common.Node)
426     {
427         AcpiOsPrintf (
428             " /**** Name not found or not accessible from this scope ****/ ");
429     }
430 
431     if ((!Name) ||
432         (!Op->Common.Parent))
433     {
434         return;
435     }
436 
437     TargetOp = AcpiPsFind (Op, Name, 0, 0);
438     if (!TargetOp)
439     {
440         /*
441          * Didn't find the name in the parse tree. This may be
442          * a problem, or it may simply be one of the predefined names
443          * (such as _OS_). Rather than worry about looking up all
444          * the predefined names, just display the name as given
445          */
446         AcpiOsPrintf (
447             " /**** Name not found or not accessible from this scope ****/ ");
448     }
449 }
450 #endif
451