167754Smsmith/*******************************************************************************
267754Smsmith *
367754Smsmith * Module Name: dbutils - AML debugger utilities
467754Smsmith *
567754Smsmith ******************************************************************************/
667754Smsmith
7217365Sjkim/*
8306536Sjkim * Copyright (C) 2000 - 2016, Intel Corp.
970243Smsmith * All rights reserved.
1067754Smsmith *
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.
2567754Smsmith *
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.
2967754Smsmith *
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 */
4367754Smsmith
44193341Sjkim#include <contrib/dev/acpica/include/acpi.h>
45193341Sjkim#include <contrib/dev/acpica/include/accommon.h>
46193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h>
47193341Sjkim#include <contrib/dev/acpica/include/acdebug.h>
4867754Smsmith
4967754Smsmith
50102550Siwasaki#define _COMPONENT          ACPI_CA_DEBUGGER
5191116Smsmith        ACPI_MODULE_NAME    ("dbutils")
5267754Smsmith
53306536Sjkim
54151937Sjkim/* Local prototypes */
5567754Smsmith
56151937Sjkim#ifdef ACPI_OBSOLETE_FUNCTIONS
57151937SjkimACPI_STATUS
58151937SjkimAcpiDbSecondPassParse (
59151937Sjkim    ACPI_PARSE_OBJECT       *Root);
60151937Sjkim
61151937Sjkimvoid
62151937SjkimAcpiDbDumpBuffer (
63151937Sjkim    UINT32                  Address);
64151937Sjkim#endif
65151937Sjkim
66151937Sjkim
6767754Smsmith/*******************************************************************************
6867754Smsmith *
69114237Snjl * FUNCTION:    AcpiDbMatchArgument
70114237Snjl *
71114237Snjl * PARAMETERS:  UserArgument            - User command line
72114237Snjl *              Arguments               - Array of commands to match against
73114237Snjl *
74114237Snjl * RETURN:      Index into command array or ACPI_TYPE_NOT_FOUND if not found
75114237Snjl *
76114237Snjl * DESCRIPTION: Search command array for a command match
77114237Snjl *
78114237Snjl ******************************************************************************/
79114237Snjl
80114237SnjlACPI_OBJECT_TYPE
81114237SnjlAcpiDbMatchArgument (
82114237Snjl    char                    *UserArgument,
83240716Sjkim    ACPI_DB_ARGUMENT_INFO   *Arguments)
84114237Snjl{
85114237Snjl    UINT32                  i;
86114237Snjl
87114237Snjl
88114237Snjl    if (!UserArgument || UserArgument[0] == 0)
89114237Snjl    {
90114237Snjl        return (ACPI_TYPE_NOT_FOUND);
91114237Snjl    }
92114237Snjl
93114237Snjl    for (i = 0; Arguments[i].Name; i++)
94114237Snjl    {
95306536Sjkim        if (strstr (
96306536Sjkim            ACPI_CAST_PTR (char, Arguments[i].Name),
97306536Sjkim            ACPI_CAST_PTR (char, UserArgument)) == Arguments[i].Name)
98114237Snjl        {
99114237Snjl            return (i);
100114237Snjl        }
101114237Snjl    }
102114237Snjl
103114237Snjl    /* Argument not recognized */
104114237Snjl
105114237Snjl    return (ACPI_TYPE_NOT_FOUND);
106114237Snjl}
107114237Snjl
108114237Snjl
109114237Snjl/*******************************************************************************
110114237Snjl *
11167754Smsmith * FUNCTION:    AcpiDbSetOutputDestination
11267754Smsmith *
11367754Smsmith * PARAMETERS:  OutputFlags         - Current flags word
11467754Smsmith *
11567754Smsmith * RETURN:      None
11667754Smsmith *
117241973Sjkim * DESCRIPTION: Set the current destination for debugger output. Also sets
11867754Smsmith *              the debug output level accordingly.
11967754Smsmith *
12067754Smsmith ******************************************************************************/
12167754Smsmith
12267754Smsmithvoid
12367754SmsmithAcpiDbSetOutputDestination (
12467754Smsmith    UINT32                  OutputFlags)
12567754Smsmith{
12667754Smsmith
12767754Smsmith    AcpiGbl_DbOutputFlags = (UINT8) OutputFlags;
12867754Smsmith
129306536Sjkim    if ((OutputFlags & ACPI_DB_REDIRECTABLE_OUTPUT) &&
130306536Sjkim        AcpiGbl_DbOutputToFile)
13167754Smsmith    {
13291116Smsmith        AcpiDbgLevel = AcpiGbl_DbDebugLevel;
13367754Smsmith    }
13467754Smsmith    else
13567754Smsmith    {
13667754Smsmith        AcpiDbgLevel = AcpiGbl_DbConsoleDebugLevel;
13767754Smsmith    }
13867754Smsmith}
13967754Smsmith
14067754Smsmith
14167754Smsmith/*******************************************************************************
14267754Smsmith *
143151937Sjkim * FUNCTION:    AcpiDbDumpExternalObject
14467754Smsmith *
14567754Smsmith * PARAMETERS:  ObjDesc         - External ACPI object to dump
14667754Smsmith *              Level           - Nesting level.
14767754Smsmith *
14867754Smsmith * RETURN:      None
14967754Smsmith *
15067754Smsmith * DESCRIPTION: Dump the contents of an ACPI external object
15167754Smsmith *
15267754Smsmith ******************************************************************************/
15367754Smsmith
15467754Smsmithvoid
155151937SjkimAcpiDbDumpExternalObject (
15667754Smsmith    ACPI_OBJECT             *ObjDesc,
15767754Smsmith    UINT32                  Level)
15867754Smsmith{
15967754Smsmith    UINT32                  i;
16067754Smsmith
16167754Smsmith
16267754Smsmith    if (!ObjDesc)
16367754Smsmith    {
16467754Smsmith        AcpiOsPrintf ("[Null Object]\n");
16567754Smsmith        return;
16667754Smsmith    }
16767754Smsmith
16867754Smsmith    for (i = 0; i < Level; i++)
16967754Smsmith    {
17067754Smsmith        AcpiOsPrintf ("  ");
17167754Smsmith    }
17267754Smsmith
17367754Smsmith    switch (ObjDesc->Type)
17467754Smsmith    {
17567754Smsmith    case ACPI_TYPE_ANY:
17667754Smsmith
177193267Sjkim        AcpiOsPrintf ("[Null Object] (Type=0)\n");
17867754Smsmith        break;
17967754Smsmith
18071867Smsmith    case ACPI_TYPE_INTEGER:
18182367Smsmith
18291116Smsmith        AcpiOsPrintf ("[Integer] = %8.8X%8.8X\n",
183306536Sjkim            ACPI_FORMAT_UINT64 (ObjDesc->Integer.Value));
18467754Smsmith        break;
18567754Smsmith
18667754Smsmith    case ACPI_TYPE_STRING:
18767754Smsmith
188167802Sjkim        AcpiOsPrintf ("[String] Length %.2X = ", ObjDesc->String.Length);
189234623Sjkim        AcpiUtPrintString (ObjDesc->String.Pointer, ACPI_UINT8_MAX);
19067754Smsmith        AcpiOsPrintf ("\n");
19167754Smsmith        break;
19267754Smsmith
19367754Smsmith    case ACPI_TYPE_BUFFER:
19467754Smsmith
19599146Siwasaki        AcpiOsPrintf ("[Buffer] Length %.2X = ", ObjDesc->Buffer.Length);
196114237Snjl        if (ObjDesc->Buffer.Length)
197114237Snjl        {
198200553Sjkim            if (ObjDesc->Buffer.Length > 16)
199200553Sjkim            {
200200553Sjkim                AcpiOsPrintf ("\n");
201200553Sjkim            }
202306536Sjkim
203306536Sjkim            AcpiUtDebugDumpBuffer (
204306536Sjkim                ACPI_CAST_PTR (UINT8, ObjDesc->Buffer.Pointer),
205306536Sjkim                ObjDesc->Buffer.Length, DB_BYTE_DISPLAY, _COMPONENT);
206114237Snjl        }
207114237Snjl        else
208114237Snjl        {
209114237Snjl            AcpiOsPrintf ("\n");
210114237Snjl        }
21167754Smsmith        break;
21267754Smsmith
21367754Smsmith    case ACPI_TYPE_PACKAGE:
21467754Smsmith
215209746Sjkim        AcpiOsPrintf ("[Package] Contains %u Elements:\n",
216306536Sjkim            ObjDesc->Package.Count);
21767754Smsmith
21867754Smsmith        for (i = 0; i < ObjDesc->Package.Count; i++)
21967754Smsmith        {
220306536Sjkim            AcpiDbDumpExternalObject (
221306536Sjkim                &ObjDesc->Package.Elements[i], Level+1);
22267754Smsmith        }
22367754Smsmith        break;
22467754Smsmith
225107325Siwasaki    case ACPI_TYPE_LOCAL_REFERENCE:
22682367Smsmith
227193267Sjkim        AcpiOsPrintf ("[Object Reference] = ");
228306536Sjkim        AcpiDbDisplayInternalObject (ObjDesc->Reference.Handle, NULL);
22967754Smsmith        break;
23067754Smsmith
23167754Smsmith    case ACPI_TYPE_PROCESSOR:
23282367Smsmith
23367754Smsmith        AcpiOsPrintf ("[Processor]\n");
23467754Smsmith        break;
23567754Smsmith
23667754Smsmith    case ACPI_TYPE_POWER:
23782367Smsmith
23867754Smsmith        AcpiOsPrintf ("[Power Resource]\n");
23967754Smsmith        break;
24067754Smsmith
24167754Smsmith    default:
24267754Smsmith
243151937Sjkim        AcpiOsPrintf ("[Unknown Type] %X\n", ObjDesc->Type);
24467754Smsmith        break;
24567754Smsmith    }
24667754Smsmith}
24767754Smsmith
24867754Smsmith
24967754Smsmith/*******************************************************************************
25067754Smsmith *
25167754Smsmith * FUNCTION:    AcpiDbPrepNamestring
25267754Smsmith *
25367754Smsmith * PARAMETERS:  Name            - String to prepare
25467754Smsmith *
25567754Smsmith * RETURN:      None
25667754Smsmith *
25767754Smsmith * DESCRIPTION: Translate all forward slashes and dots to backslashes.
25867754Smsmith *
25967754Smsmith ******************************************************************************/
26067754Smsmith
26167754Smsmithvoid
26267754SmsmithAcpiDbPrepNamestring (
263114237Snjl    char                    *Name)
26467754Smsmith{
26567754Smsmith
26667754Smsmith    if (!Name)
26767754Smsmith    {
26867754Smsmith        return;
26967754Smsmith    }
27067754Smsmith
271151937Sjkim    AcpiUtStrupr (Name);
27267754Smsmith
27367754Smsmith    /* Convert a leading forward slash to a backslash */
27467754Smsmith
27567754Smsmith    if (*Name == '/')
27667754Smsmith    {
27767754Smsmith        *Name = '\\';
27867754Smsmith    }
27967754Smsmith
28067754Smsmith    /* Ignore a leading backslash, this is the root prefix */
28167754Smsmith
282245582Sjkim    if (ACPI_IS_ROOT_PREFIX (*Name))
28367754Smsmith    {
28467754Smsmith        Name++;
28567754Smsmith    }
28667754Smsmith
28767754Smsmith    /* Convert all slash path separators to dots */
28867754Smsmith
28967754Smsmith    while (*Name)
29067754Smsmith    {
29167754Smsmith        if ((*Name == '/') ||
29267754Smsmith            (*Name == '\\'))
29367754Smsmith        {
29467754Smsmith            *Name = '.';
29567754Smsmith        }
29667754Smsmith
29767754Smsmith        Name++;
29867754Smsmith    }
29967754Smsmith}
30067754Smsmith
30167754Smsmith
30267754Smsmith/*******************************************************************************
30367754Smsmith *
304151937Sjkim * FUNCTION:    AcpiDbLocalNsLookup
305151937Sjkim *
306151937Sjkim * PARAMETERS:  Name            - Name to lookup
307151937Sjkim *
308151937Sjkim * RETURN:      Pointer to a namespace node, null on failure
309151937Sjkim *
310151937Sjkim * DESCRIPTION: Lookup a name in the ACPI namespace
311151937Sjkim *
312241973Sjkim * Note: Currently begins search from the root. Could be enhanced to use
313151937Sjkim * the current prefix (scope) node as the search beginning point.
314151937Sjkim *
315151937Sjkim ******************************************************************************/
316151937Sjkim
317151937SjkimACPI_NAMESPACE_NODE *
318151937SjkimAcpiDbLocalNsLookup (
319151937Sjkim    char                    *Name)
320151937Sjkim{
321151937Sjkim    char                    *InternalPath;
322151937Sjkim    ACPI_STATUS             Status;
323151937Sjkim    ACPI_NAMESPACE_NODE     *Node = NULL;
324151937Sjkim
325151937Sjkim
326151937Sjkim    AcpiDbPrepNamestring (Name);
327151937Sjkim
328151937Sjkim    /* Build an internal namestring */
329151937Sjkim
330151937Sjkim    Status = AcpiNsInternalizeName (Name, &InternalPath);
331151937Sjkim    if (ACPI_FAILURE (Status))
332151937Sjkim    {
333151937Sjkim        AcpiOsPrintf ("Invalid namestring: %s\n", Name);
334151937Sjkim        return (NULL);
335151937Sjkim    }
336151937Sjkim
337151937Sjkim    /*
338151937Sjkim     * Lookup the name.
339151937Sjkim     * (Uses root node as the search starting point)
340151937Sjkim     */
341306536Sjkim    Status = AcpiNsLookup (NULL, InternalPath, ACPI_TYPE_ANY,
342306536Sjkim        ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE,
343306536Sjkim        NULL, &Node);
344151937Sjkim    if (ACPI_FAILURE (Status))
345151937Sjkim    {
346167802Sjkim        AcpiOsPrintf ("Could not locate name: %s, %s\n",
347306536Sjkim            Name, AcpiFormatException (Status));
348151937Sjkim    }
349151937Sjkim
350167802Sjkim    ACPI_FREE (InternalPath);
351151937Sjkim    return (Node);
352151937Sjkim}
353151937Sjkim
354151937Sjkim
355167802Sjkim/*******************************************************************************
356167802Sjkim *
357237412Sjkim * FUNCTION:    AcpiDbUint32ToHexString
358167802Sjkim *
359167802Sjkim * PARAMETERS:  Value           - The value to be converted to string
360167802Sjkim *              Buffer          - Buffer for result (not less than 11 bytes)
361167802Sjkim *
362167802Sjkim * RETURN:      None
363167802Sjkim *
364167802Sjkim * DESCRIPTION: Convert the unsigned 32-bit value to the hexadecimal image
365167802Sjkim *
366167802Sjkim * NOTE: It is the caller's responsibility to ensure that the length of buffer
367167802Sjkim *       is sufficient.
368167802Sjkim *
369167802Sjkim ******************************************************************************/
370167802Sjkim
371167802Sjkimvoid
372237412SjkimAcpiDbUint32ToHexString (
373167802Sjkim    UINT32                  Value,
374167802Sjkim    char                    *Buffer)
375167802Sjkim{
376222544Sjkim    int                     i;
377167802Sjkim
378167802Sjkim
379167802Sjkim    if (Value == 0)
380167802Sjkim    {
381306536Sjkim        strcpy (Buffer, "0");
382167802Sjkim        return;
383167802Sjkim    }
384167802Sjkim
385222544Sjkim    Buffer[8] = '\0';
386167802Sjkim
387222544Sjkim    for (i = 7; i >= 0; i--)
388167802Sjkim    {
389306536Sjkim        Buffer[i] = AcpiGbl_UpperHexDigits [Value & 0x0F];
390167802Sjkim        Value = Value >> 4;
391167802Sjkim    }
392167802Sjkim}
393167802Sjkim
394167802Sjkim
395151937Sjkim#ifdef ACPI_OBSOLETE_FUNCTIONS
396151937Sjkim/*******************************************************************************
397151937Sjkim *
39867754Smsmith * FUNCTION:    AcpiDbSecondPassParse
39967754Smsmith *
40067754Smsmith * PARAMETERS:  Root            - Root of the parse tree
40167754Smsmith *
40267754Smsmith * RETURN:      Status
40367754Smsmith *
404241973Sjkim * DESCRIPTION: Second pass parse of the ACPI tables. We need to wait until
40567754Smsmith *              second pass to parse the control methods
40667754Smsmith *
40767754Smsmith ******************************************************************************/
40867754Smsmith
40967754SmsmithACPI_STATUS
41067754SmsmithAcpiDbSecondPassParse (
41167754Smsmith    ACPI_PARSE_OBJECT       *Root)
41267754Smsmith{
41367754Smsmith    ACPI_PARSE_OBJECT       *Op = Root;
41499679Siwasaki    ACPI_PARSE_OBJECT       *Method;
41567754Smsmith    ACPI_PARSE_OBJECT       *SearchOp;
41667754Smsmith    ACPI_PARSE_OBJECT       *StartOp;
41767754Smsmith    ACPI_STATUS             Status = AE_OK;
41867754Smsmith    UINT32                  BaseAmlOffset;
41984491Smsmith    ACPI_WALK_STATE         *WalkState;
42067754Smsmith
42167754Smsmith
42291116Smsmith    ACPI_FUNCTION_ENTRY ();
42384491Smsmith
42484491Smsmith
42567754Smsmith    AcpiOsPrintf ("Pass two parse ....\n");
42667754Smsmith
42767754Smsmith    while (Op)
42867754Smsmith    {
42999679Siwasaki        if (Op->Common.AmlOpcode == AML_METHOD_OP)
43067754Smsmith        {
43199679Siwasaki            Method = Op;
43267754Smsmith
43399679Siwasaki            /* Create a new walk state for the parse */
43499679Siwasaki
435117521Snjl            WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
43684491Smsmith            if (!WalkState)
43784491Smsmith            {
43884491Smsmith                return (AE_NO_MEMORY);
43984491Smsmith            }
44067754Smsmith
44199679Siwasaki            /* Init the Walk State */
44284491Smsmith
44384491Smsmith            WalkState->ParserState.Aml          =
44499679Siwasaki            WalkState->ParserState.AmlStart     = Method->Named.Data;
44584491Smsmith            WalkState->ParserState.AmlEnd       =
446151937Sjkim            WalkState->ParserState.PkgEnd       = Method->Named.Data +
447151937Sjkim                                                  Method->Named.Length;
44884491Smsmith            WalkState->ParserState.StartScope   = Op;
44984491Smsmith
45084491Smsmith            WalkState->DescendingCallback       = AcpiDsLoad1BeginOp;
45184491Smsmith            WalkState->AscendingCallback        = AcpiDsLoad1EndOp;
45284491Smsmith
45399679Siwasaki            /* Perform the AML parse */
45484491Smsmith
45584491Smsmith            Status = AcpiPsParseAml (WalkState);
45684491Smsmith
45799679Siwasaki            BaseAmlOffset = (Method->Common.Value.Arg)->Common.AmlOffset + 1;
45899679Siwasaki            StartOp = (Method->Common.Value.Arg)->Common.Next;
45967754Smsmith            SearchOp = StartOp;
46067754Smsmith
46167754Smsmith            while (SearchOp)
46267754Smsmith            {
46399679Siwasaki                SearchOp->Common.AmlOffset += BaseAmlOffset;
46467754Smsmith                SearchOp = AcpiPsGetDepthNext (StartOp, SearchOp);
46567754Smsmith            }
46667754Smsmith        }
46767754Smsmith
46899679Siwasaki        if (Op->Common.AmlOpcode == AML_REGION_OP)
46967754Smsmith        {
47067754Smsmith            /* TBD: [Investigate] this isn't quite the right thing to do! */
47167754Smsmith            /*
47267754Smsmith             *
47367754Smsmith             * Method = (ACPI_DEFERRED_OP *) Op;
47467754Smsmith             * Status = AcpiPsParseAml (Op, Method->Body, Method->BodyLength);
47567754Smsmith             */
47667754Smsmith        }
47767754Smsmith
47867754Smsmith        if (ACPI_FAILURE (Status))
47967754Smsmith        {
48084491Smsmith            break;
48167754Smsmith        }
48267754Smsmith
48367754Smsmith        Op = AcpiPsGetDepthNext (Root, Op);
48467754Smsmith    }
48567754Smsmith
48667754Smsmith    return (Status);
48767754Smsmith}
48867754Smsmith
48967754Smsmith
49067754Smsmith/*******************************************************************************
49167754Smsmith *
492151937Sjkim * FUNCTION:    AcpiDbDumpBuffer
49367754Smsmith *
494151937Sjkim * PARAMETERS:  Address             - Pointer to the buffer
49567754Smsmith *
496151937Sjkim * RETURN:      None
49767754Smsmith *
498151937Sjkim * DESCRIPTION: Print a portion of a buffer
49967754Smsmith *
50067754Smsmith ******************************************************************************/
50167754Smsmith
502151937Sjkimvoid
503151937SjkimAcpiDbDumpBuffer (
504151937Sjkim    UINT32                  Address)
50567754Smsmith{
50667754Smsmith
507151937Sjkim    AcpiOsPrintf ("\nLocation %X:\n", Address);
50867754Smsmith
509151937Sjkim    AcpiDbgLevel |= ACPI_LV_TABLES;
510241973Sjkim    AcpiUtDebugDumpBuffer (ACPI_TO_POINTER (Address), 64, DB_BYTE_DISPLAY,
511306536Sjkim        ACPI_UINT32_MAX);
51267754Smsmith}
513151937Sjkim#endif
514