1100966Siwasaki/*******************************************************************************
2100966Siwasaki *
3100966Siwasaki * Module Name: dmnames - AML disassembler, names, namestrings, pathnames
4100966Siwasaki *
5100966Siwasaki ******************************************************************************/
6100966Siwasaki
7217365Sjkim/*
8306536Sjkim * Copyright (C) 2000 - 2016, Intel Corp.
9100966Siwasaki * All rights reserved.
10100966Siwasaki *
11217365Sjkim * Redistribution and use in source and binary forms, with or without
12217365Sjkim * modification, are permitted provided that the following conditions
13217365Sjkim * are met:
14217365Sjkim * 1. Redistributions of source code must retain the above copyright
15217365Sjkim *    notice, this list of conditions, and the following disclaimer,
16217365Sjkim *    without modification.
17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18217365Sjkim *    substantially similar to the "NO WARRANTY" disclaimer below
19217365Sjkim *    ("Disclaimer") and any redistribution must be conditioned upon
20217365Sjkim *    including a substantially similar Disclaimer requirement for further
21217365Sjkim *    binary redistribution.
22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names
23217365Sjkim *    of any contributors may be used to endorse or promote products derived
24217365Sjkim *    from this software without specific prior written permission.
25100966Siwasaki *
26217365Sjkim * Alternatively, this software may be distributed under the terms of the
27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free
28217365Sjkim * Software Foundation.
29100966Siwasaki *
30217365Sjkim * NO WARRANTY
31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41217365Sjkim * POSSIBILITY OF SUCH DAMAGES.
42217365Sjkim */
43100966Siwasaki
44193341Sjkim#include <contrib/dev/acpica/include/acpi.h>
45193341Sjkim#include <contrib/dev/acpica/include/accommon.h>
46193341Sjkim#include <contrib/dev/acpica/include/amlcode.h>
47193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h>
48193341Sjkim#include <contrib/dev/acpica/include/acdisasm.h>
49100966Siwasaki
50100966Siwasaki
51102550Siwasaki#define _COMPONENT          ACPI_CA_DEBUGGER
52100966Siwasaki        ACPI_MODULE_NAME    ("dmnames")
53100966Siwasaki
54151937Sjkim/* Local prototypes */
55100966Siwasaki
56151937Sjkim#ifdef ACPI_OBSOLETE_FUNCTIONS
57100966Siwasakivoid
58151937SjkimAcpiDmDisplayPath (
59151937Sjkim    ACPI_PARSE_OBJECT       *Op);
60100966Siwasaki#endif
61100966Siwasaki
62100966Siwasaki
63100966Siwasaki/*******************************************************************************
64100966Siwasaki *
65100966Siwasaki * FUNCTION:    AcpiDmDumpName
66100966Siwasaki *
67100966Siwasaki * PARAMETERS:  Name            - 4 character ACPI name
68100966Siwasaki *
69100966Siwasaki * RETURN:      Final length of name
70100966Siwasaki *
71100966Siwasaki * DESCRIPTION: Dump an ACPI name, minus any trailing underscores.
72100966Siwasaki *
73100966Siwasaki ******************************************************************************/
74100966Siwasaki
75100966SiwasakiUINT32
76100966SiwasakiAcpiDmDumpName (
77193267Sjkim    UINT32                  Name)
78100966Siwasaki{
79100966Siwasaki    UINT32                  i;
80100966Siwasaki    UINT32                  Length;
81167802Sjkim    char                    NewName[4];
82100966Siwasaki
83100966Siwasaki
84193267Sjkim    /* Copy name locally in case the original name is not writeable */
85193267Sjkim
86193267Sjkim    *ACPI_CAST_PTR (UINT32, &NewName[0]) = Name;
87193267Sjkim
88167802Sjkim    /* Ensure that the name is printable, even if we have to fix it */
89167802Sjkim
90193267Sjkim    AcpiUtRepairName (NewName);
91167802Sjkim
92167802Sjkim    /* Remove all trailing underscores from the name */
93167802Sjkim
94167802Sjkim    Length = ACPI_NAME_SIZE;
95167802Sjkim    for (i = (ACPI_NAME_SIZE - 1); i != 0; i--)
96100966Siwasaki    {
97167802Sjkim        if (NewName[i] == '_')
98100966Siwasaki        {
99167802Sjkim            Length--;
100100966Siwasaki        }
101167802Sjkim        else
102167802Sjkim        {
103167802Sjkim            break;
104167802Sjkim        }
105100966Siwasaki    }
106100966Siwasaki
107167802Sjkim    /* Dump the name, up to the start of the trailing underscores */
108167802Sjkim
109100966Siwasaki    for (i = 0; i < Length; i++)
110100966Siwasaki    {
111167802Sjkim        AcpiOsPrintf ("%c", NewName[i]);
112100966Siwasaki    }
113100966Siwasaki
114100966Siwasaki    return (Length);
115100966Siwasaki}
116100966Siwasaki
117100966Siwasaki
118100966Siwasaki/*******************************************************************************
119100966Siwasaki *
120100966Siwasaki * FUNCTION:    AcpiPsDisplayObjectPathname
121100966Siwasaki *
122100966Siwasaki * PARAMETERS:  WalkState       - Current walk state
123100966Siwasaki *              Op              - Object whose pathname is to be obtained
124100966Siwasaki *
125100966Siwasaki * RETURN:      Status
126100966Siwasaki *
127241973Sjkim * DESCRIPTION: Diplay the pathname associated with a named object. Two
128100966Siwasaki *              versions. One searches the parse tree (for parser-only
129100966Siwasaki *              applications suchas AcpiDump), and the other searches the
130100966Siwasaki *              ACPI namespace (the parse tree is probably deleted)
131100966Siwasaki *
132100966Siwasaki ******************************************************************************/
133100966Siwasaki
134100966SiwasakiACPI_STATUS
135100966SiwasakiAcpiPsDisplayObjectPathname (
136100966Siwasaki    ACPI_WALK_STATE         *WalkState,
137100966Siwasaki    ACPI_PARSE_OBJECT       *Op)
138100966Siwasaki{
139100966Siwasaki    ACPI_STATUS             Status;
140100966Siwasaki    ACPI_NAMESPACE_NODE     *Node;
141100966Siwasaki    ACPI_BUFFER             Buffer;
142100966Siwasaki    UINT32                  DebugLevel;
143100966Siwasaki
144100966Siwasaki
145100966Siwasaki    /* Save current debug level so we don't get extraneous debug output */
146100966Siwasaki
147100966Siwasaki    DebugLevel = AcpiDbgLevel;
148100966Siwasaki    AcpiDbgLevel = 0;
149100966Siwasaki
150100966Siwasaki    /* Just get the Node out of the Op object */
151100966Siwasaki
152100966Siwasaki    Node = Op->Common.Node;
153100966Siwasaki    if (!Node)
154100966Siwasaki    {
155100966Siwasaki        /* Node not defined in this scope, look it up */
156100966Siwasaki
157151937Sjkim        Status = AcpiNsLookup (WalkState->ScopeInfo, Op->Common.Value.String,
158306536Sjkim            ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
159306536Sjkim            WalkState, &(Node));
160100966Siwasaki
161100966Siwasaki        if (ACPI_FAILURE (Status))
162100966Siwasaki        {
163100966Siwasaki            /*
164306536Sjkim             * We can't get the pathname since the object is not in the
165306536Sjkim             * namespace. This can happen during single stepping
166306536Sjkim             * where a dynamic named object is *about* to be created.
167100966Siwasaki             */
168100966Siwasaki            AcpiOsPrintf ("  [Path not found]");
169100966Siwasaki            goto Exit;
170100966Siwasaki        }
171100966Siwasaki
172100966Siwasaki        /* Save it for next time. */
173100966Siwasaki
174100966Siwasaki        Op->Common.Node = Node;
175100966Siwasaki    }
176100966Siwasaki
177100966Siwasaki    /* Convert NamedDesc/handle to a full pathname */
178100966Siwasaki
179100966Siwasaki    Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
180306536Sjkim    Status = AcpiNsHandleToPathname (Node, &Buffer, FALSE);
181100966Siwasaki    if (ACPI_FAILURE (Status))
182100966Siwasaki    {
183100966Siwasaki        AcpiOsPrintf ("****Could not get pathname****)");
184100966Siwasaki        goto Exit;
185100966Siwasaki    }
186100966Siwasaki
187100966Siwasaki    AcpiOsPrintf ("  (Path %s)", (char *) Buffer.Pointer);
188167802Sjkim    ACPI_FREE (Buffer.Pointer);
189100966Siwasaki
190100966Siwasaki
191100966SiwasakiExit:
192100966Siwasaki    /* Restore the debug level */
193100966Siwasaki
194100966Siwasaki    AcpiDbgLevel = DebugLevel;
195100966Siwasaki    return (Status);
196100966Siwasaki}
197100966Siwasaki
198100966Siwasaki
199100966Siwasaki/*******************************************************************************
200100966Siwasaki *
201100966Siwasaki * FUNCTION:    AcpiDmNamestring
202100966Siwasaki *
203100966Siwasaki * PARAMETERS:  Name                - ACPI Name string to store
204100966Siwasaki *
205100966Siwasaki * RETURN:      None
206100966Siwasaki *
207151937Sjkim * DESCRIPTION: Decode and dump an ACPI namestring. Handles prefix characters
208100966Siwasaki *
209100966Siwasaki ******************************************************************************/
210100966Siwasaki
211100966Siwasakivoid
212100966SiwasakiAcpiDmNamestring (
213114237Snjl    char                    *Name)
214100966Siwasaki{
215100966Siwasaki    UINT32                  SegCount;
216100966Siwasaki
217100966Siwasaki
218100966Siwasaki    if (!Name)
219100966Siwasaki    {
220100966Siwasaki        return;
221100966Siwasaki    }
222100966Siwasaki
223100966Siwasaki    /* Handle all Scope Prefix operators */
224100966Siwasaki
225245582Sjkim    while (ACPI_IS_ROOT_PREFIX (ACPI_GET8 (Name)) ||
226245582Sjkim           ACPI_IS_PARENT_PREFIX (ACPI_GET8 (Name)))
227100966Siwasaki    {
228100966Siwasaki        /* Append prefix character */
229100966Siwasaki
230100966Siwasaki        AcpiOsPrintf ("%1c", ACPI_GET8 (Name));
231100966Siwasaki        Name++;
232100966Siwasaki    }
233100966Siwasaki
234100966Siwasaki    switch (ACPI_GET8 (Name))
235100966Siwasaki    {
236100966Siwasaki    case 0:
237250838Sjkim
238100966Siwasaki        SegCount = 0;
239100966Siwasaki        break;
240100966Siwasaki
241100966Siwasaki    case AML_DUAL_NAME_PREFIX:
242250838Sjkim
243100966Siwasaki        SegCount = 2;
244100966Siwasaki        Name++;
245100966Siwasaki        break;
246100966Siwasaki
247100966Siwasaki    case AML_MULTI_NAME_PREFIX_OP:
248250838Sjkim
249100966Siwasaki        SegCount = (UINT32) ACPI_GET8 (Name + 1);
250100966Siwasaki        Name += 2;
251100966Siwasaki        break;
252100966Siwasaki
253100966Siwasaki    default:
254250838Sjkim
255100966Siwasaki        SegCount = 1;
256100966Siwasaki        break;
257100966Siwasaki    }
258100966Siwasaki
259100966Siwasaki    while (SegCount)
260100966Siwasaki    {
261100966Siwasaki        /* Append Name segment */
262100966Siwasaki
263193267Sjkim        AcpiDmDumpName (*ACPI_CAST_PTR (UINT32, Name));
264100966Siwasaki
265100966Siwasaki        SegCount--;
266100966Siwasaki        if (SegCount)
267100966Siwasaki        {
268100966Siwasaki            /* Not last name, append dot separator */
269100966Siwasaki
270100966Siwasaki            AcpiOsPrintf (".");
271100966Siwasaki        }
272306536Sjkim
273100966Siwasaki        Name += ACPI_NAME_SIZE;
274100966Siwasaki    }
275100966Siwasaki}
276100966Siwasaki
277100966Siwasaki
278151937Sjkim#ifdef ACPI_OBSOLETE_FUNCTIONS
279100966Siwasaki/*******************************************************************************
280100966Siwasaki *
281100966Siwasaki * FUNCTION:    AcpiDmDisplayPath
282100966Siwasaki *
283100966Siwasaki * PARAMETERS:  Op                  - Named Op whose path is to be constructed
284100966Siwasaki *
285100966Siwasaki * RETURN:      None
286100966Siwasaki *
287100966Siwasaki * DESCRIPTION: Walk backwards from current scope and display the name
288100966Siwasaki *              of each previous level of scope up to the root scope
289100966Siwasaki *              (like "pwd" does with file systems)
290100966Siwasaki *
291100966Siwasaki ******************************************************************************/
292100966Siwasaki
293100966Siwasakivoid
294100966SiwasakiAcpiDmDisplayPath (
295100966Siwasaki    ACPI_PARSE_OBJECT       *Op)
296100966Siwasaki{
297100966Siwasaki    ACPI_PARSE_OBJECT       *Prev;
298100966Siwasaki    ACPI_PARSE_OBJECT       *Search;
299100966Siwasaki    UINT32                  Name;
300100966Siwasaki    BOOLEAN                 DoDot = FALSE;
301100966Siwasaki    ACPI_PARSE_OBJECT       *NamePath;
302100966Siwasaki    const ACPI_OPCODE_INFO  *OpInfo;
303100966Siwasaki
304100966Siwasaki
305100966Siwasaki    /* We are only interested in named objects */
306100966Siwasaki
307100966Siwasaki    OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
308100966Siwasaki    if (!(OpInfo->Flags & AML_NSNODE))
309100966Siwasaki    {
310100966Siwasaki        return;
311100966Siwasaki    }
312100966Siwasaki
313100966Siwasaki    if (OpInfo->Flags & AML_CREATE)
314100966Siwasaki    {
315100966Siwasaki        /* Field creation - check for a fully qualified namepath */
316100966Siwasaki
317100966Siwasaki        if (Op->Common.AmlOpcode == AML_CREATE_FIELD_OP)
318100966Siwasaki        {
319100966Siwasaki            NamePath = AcpiPsGetArg (Op, 3);
320100966Siwasaki        }
321100966Siwasaki        else
322100966Siwasaki        {
323100966Siwasaki            NamePath = AcpiPsGetArg (Op, 2);
324100966Siwasaki        }
325100966Siwasaki
326100966Siwasaki        if ((NamePath) &&
327100966Siwasaki            (NamePath->Common.Value.String) &&
328245582Sjkim            (ACPI_IS_ROOT_PREFIX (NamePath->Common.Value.String[0])))
329100966Siwasaki        {
330100966Siwasaki            AcpiDmNamestring (NamePath->Common.Value.String);
331100966Siwasaki            return;
332100966Siwasaki        }
333100966Siwasaki    }
334100966Siwasaki
335100966Siwasaki    Prev = NULL;            /* Start with Root Node */
336100966Siwasaki    while (Prev != Op)
337100966Siwasaki    {
338100966Siwasaki        /* Search upwards in the tree to find scope with "prev" as its parent */
339100966Siwasaki
340100966Siwasaki        Search = Op;
341100966Siwasaki        for (; ;)
342100966Siwasaki        {
343100966Siwasaki            if (Search->Common.Parent == Prev)
344100966Siwasaki            {
345100966Siwasaki                break;
346100966Siwasaki            }
347100966Siwasaki
348100966Siwasaki            /* Go up one level */
349100966Siwasaki
350100966Siwasaki            Search = Search->Common.Parent;
351100966Siwasaki        }
352100966Siwasaki
353100966Siwasaki        if (Prev)
354100966Siwasaki        {
355100966Siwasaki            OpInfo = AcpiPsGetOpcodeInfo (Search->Common.AmlOpcode);
356100966Siwasaki            if (!(OpInfo->Flags & AML_FIELD))
357100966Siwasaki            {
358100966Siwasaki                /* Below root scope, append scope name */
359100966Siwasaki
360100966Siwasaki                if (DoDot)
361100966Siwasaki                {
362100966Siwasaki                    /* Append dot */
363100966Siwasaki
364100966Siwasaki                    AcpiOsPrintf (".");
365100966Siwasaki                }
366100966Siwasaki
367100966Siwasaki                if (OpInfo->Flags & AML_CREATE)
368100966Siwasaki                {
369100966Siwasaki                    if (Op->Common.AmlOpcode == AML_CREATE_FIELD_OP)
370100966Siwasaki                    {
371100966Siwasaki                        NamePath = AcpiPsGetArg (Op, 3);
372100966Siwasaki                    }
373100966Siwasaki                    else
374100966Siwasaki                    {
375100966Siwasaki                        NamePath = AcpiPsGetArg (Op, 2);
376100966Siwasaki                    }
377100966Siwasaki
378100966Siwasaki                    if ((NamePath) &&
379100966Siwasaki                        (NamePath->Common.Value.String))
380100966Siwasaki                    {
381100966Siwasaki                        AcpiDmDumpName (NamePath->Common.Value.String);
382100966Siwasaki                    }
383100966Siwasaki                }
384100966Siwasaki                else
385100966Siwasaki                {
386100966Siwasaki                    Name = AcpiPsGetName (Search);
387100966Siwasaki                    AcpiDmDumpName ((char *) &Name);
388100966Siwasaki                }
389100966Siwasaki
390100966Siwasaki                DoDot = TRUE;
391100966Siwasaki            }
392100966Siwasaki        }
393306536Sjkim
394100966Siwasaki        Prev = Search;
395100966Siwasaki    }
396100966Siwasaki}
397100966Siwasaki
398151937Sjkim
399151937Sjkim/*******************************************************************************
400151937Sjkim *
401151937Sjkim * FUNCTION:    AcpiDmValidateName
402151937Sjkim *
403151937Sjkim * PARAMETERS:  Name            - 4 character ACPI name
404151937Sjkim *
405151937Sjkim * RETURN:      None
406151937Sjkim *
407151937Sjkim * DESCRIPTION: Lookup the name
408151937Sjkim *
409151937Sjkim ******************************************************************************/
410151937Sjkim
411151937Sjkimvoid
412151937SjkimAcpiDmValidateName (
413151937Sjkim    char                    *Name,
414151937Sjkim    ACPI_PARSE_OBJECT       *Op)
415151937Sjkim{
416306536Sjkim    ACPI_PARSE_OBJECT       *TargetOp;
417151937Sjkim
418306536Sjkim
419151937Sjkim    if ((!Name) ||
420151937Sjkim        (!Op->Common.Parent))
421151937Sjkim    {
422151937Sjkim        return;
423151937Sjkim    }
424151937Sjkim
425151937Sjkim    if (!Op->Common.Node)
426151937Sjkim    {
427151937Sjkim        AcpiOsPrintf (
428151937Sjkim            " /**** Name not found or not accessible from this scope ****/ ");
429151937Sjkim    }
430151937Sjkim
431151937Sjkim    if ((!Name) ||
432151937Sjkim        (!Op->Common.Parent))
433151937Sjkim    {
434151937Sjkim        return;
435151937Sjkim    }
436151937Sjkim
437151937Sjkim    TargetOp = AcpiPsFind (Op, Name, 0, 0);
438151937Sjkim    if (!TargetOp)
439151937Sjkim    {
440151937Sjkim        /*
441241973Sjkim         * Didn't find the name in the parse tree. This may be
442151937Sjkim         * a problem, or it may simply be one of the predefined names
443241973Sjkim         * (such as _OS_). Rather than worry about looking up all
444151937Sjkim         * the predefined names, just display the name as given
445151937Sjkim         */
446151937Sjkim        AcpiOsPrintf (
447151937Sjkim            " /**** Name not found or not accessible from this scope ****/ ");
448151937Sjkim    }
449151937Sjkim}
450100966Siwasaki#endif
451