167754Smsmith/*******************************************************************************
267754Smsmith *
367754Smsmith * Module Name: dbutils - AML debugger utilities
467754Smsmith *
567754Smsmith ******************************************************************************/
667754Smsmith
7217365Sjkim/*
8217365Sjkim * Copyright (C) 2000 - 2011, 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
4467754Smsmith
45193341Sjkim#include <contrib/dev/acpica/include/acpi.h>
46193341Sjkim#include <contrib/dev/acpica/include/accommon.h>
47193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h>
48193341Sjkim#include <contrib/dev/acpica/include/acdebug.h>
49193341Sjkim#include <contrib/dev/acpica/include/acdisasm.h>
5067754Smsmith
5167754Smsmith
52102550Siwasaki#ifdef ACPI_DEBUGGER
5367754Smsmith
54102550Siwasaki#define _COMPONENT          ACPI_CA_DEBUGGER
5591116Smsmith        ACPI_MODULE_NAME    ("dbutils")
5667754Smsmith
57151937Sjkim/* Local prototypes */
5867754Smsmith
59151937Sjkim#ifdef ACPI_OBSOLETE_FUNCTIONS
60151937SjkimACPI_STATUS
61151937SjkimAcpiDbSecondPassParse (
62151937Sjkim    ACPI_PARSE_OBJECT       *Root);
63151937Sjkim
64151937Sjkimvoid
65151937SjkimAcpiDbDumpBuffer (
66151937Sjkim    UINT32                  Address);
67151937Sjkim#endif
68151937Sjkim
69167802Sjkimstatic char                 *Converter = "0123456789ABCDEF";
70151937Sjkim
71167802Sjkim
7267754Smsmith/*******************************************************************************
7367754Smsmith *
74114237Snjl * FUNCTION:    AcpiDbMatchArgument
75114237Snjl *
76114237Snjl * PARAMETERS:  UserArgument            - User command line
77114237Snjl *              Arguments               - Array of commands to match against
78114237Snjl *
79114237Snjl * RETURN:      Index into command array or ACPI_TYPE_NOT_FOUND if not found
80114237Snjl *
81114237Snjl * DESCRIPTION: Search command array for a command match
82114237Snjl *
83114237Snjl ******************************************************************************/
84114237Snjl
85114237SnjlACPI_OBJECT_TYPE
86114237SnjlAcpiDbMatchArgument (
87114237Snjl    char                    *UserArgument,
88114237Snjl    ARGUMENT_INFO           *Arguments)
89114237Snjl{
90114237Snjl    UINT32                  i;
91114237Snjl
92114237Snjl
93114237Snjl    if (!UserArgument || UserArgument[0] == 0)
94114237Snjl    {
95114237Snjl        return (ACPI_TYPE_NOT_FOUND);
96114237Snjl    }
97114237Snjl
98114237Snjl    for (i = 0; Arguments[i].Name; i++)
99114237Snjl    {
100114237Snjl        if (ACPI_STRSTR (Arguments[i].Name, UserArgument) == Arguments[i].Name)
101114237Snjl        {
102114237Snjl            return (i);
103114237Snjl        }
104114237Snjl    }
105114237Snjl
106114237Snjl    /* Argument not recognized */
107114237Snjl
108114237Snjl    return (ACPI_TYPE_NOT_FOUND);
109114237Snjl}
110114237Snjl
111114237Snjl
112114237Snjl/*******************************************************************************
113114237Snjl *
11467754Smsmith * FUNCTION:    AcpiDbSetOutputDestination
11567754Smsmith *
11667754Smsmith * PARAMETERS:  OutputFlags         - Current flags word
11767754Smsmith *
11867754Smsmith * RETURN:      None
11967754Smsmith *
120151937Sjkim * DESCRIPTION: Set the current destination for debugger output.  Also sets
12167754Smsmith *              the debug output level accordingly.
12267754Smsmith *
12367754Smsmith ******************************************************************************/
12467754Smsmith
12567754Smsmithvoid
12667754SmsmithAcpiDbSetOutputDestination (
12767754Smsmith    UINT32                  OutputFlags)
12867754Smsmith{
12967754Smsmith
13067754Smsmith    AcpiGbl_DbOutputFlags = (UINT8) OutputFlags;
13167754Smsmith
13291116Smsmith    if ((OutputFlags & ACPI_DB_REDIRECTABLE_OUTPUT) && AcpiGbl_DbOutputToFile)
13367754Smsmith    {
13491116Smsmith        AcpiDbgLevel = AcpiGbl_DbDebugLevel;
13567754Smsmith    }
13667754Smsmith    else
13767754Smsmith    {
13867754Smsmith        AcpiDbgLevel = AcpiGbl_DbConsoleDebugLevel;
13967754Smsmith    }
14067754Smsmith}
14167754Smsmith
14267754Smsmith
14367754Smsmith/*******************************************************************************
14467754Smsmith *
145151937Sjkim * FUNCTION:    AcpiDbDumpExternalObject
14667754Smsmith *
14767754Smsmith * PARAMETERS:  ObjDesc         - External ACPI object to dump
14867754Smsmith *              Level           - Nesting level.
14967754Smsmith *
15067754Smsmith * RETURN:      None
15167754Smsmith *
15267754Smsmith * DESCRIPTION: Dump the contents of an ACPI external object
15367754Smsmith *
15467754Smsmith ******************************************************************************/
15567754Smsmith
15667754Smsmithvoid
157151937SjkimAcpiDbDumpExternalObject (
15867754Smsmith    ACPI_OBJECT             *ObjDesc,
15967754Smsmith    UINT32                  Level)
16067754Smsmith{
16167754Smsmith    UINT32                  i;
16267754Smsmith
16367754Smsmith
16467754Smsmith    if (!ObjDesc)
16567754Smsmith    {
16667754Smsmith        AcpiOsPrintf ("[Null Object]\n");
16767754Smsmith        return;
16867754Smsmith    }
16967754Smsmith
17067754Smsmith    for (i = 0; i < Level; i++)
17167754Smsmith    {
17267754Smsmith        AcpiOsPrintf ("  ");
17367754Smsmith    }
17467754Smsmith
17567754Smsmith    switch (ObjDesc->Type)
17667754Smsmith    {
17767754Smsmith    case ACPI_TYPE_ANY:
17867754Smsmith
179193267Sjkim        AcpiOsPrintf ("[Null Object] (Type=0)\n");
18067754Smsmith        break;
18167754Smsmith
18267754Smsmith
18371867Smsmith    case ACPI_TYPE_INTEGER:
18482367Smsmith
18591116Smsmith        AcpiOsPrintf ("[Integer] = %8.8X%8.8X\n",
186123315Snjl                    ACPI_FORMAT_UINT64 (ObjDesc->Integer.Value));
18767754Smsmith        break;
18867754Smsmith
18967754Smsmith
19067754Smsmith    case ACPI_TYPE_STRING:
19167754Smsmith
192167802Sjkim        AcpiOsPrintf ("[String] Length %.2X = ", ObjDesc->String.Length);
19367754Smsmith        for (i = 0; i < ObjDesc->String.Length; i++)
19467754Smsmith        {
19567754Smsmith            AcpiOsPrintf ("%c", ObjDesc->String.Pointer[i]);
19667754Smsmith        }
19767754Smsmith        AcpiOsPrintf ("\n");
19867754Smsmith        break;
19967754Smsmith
20067754Smsmith
20167754Smsmith    case ACPI_TYPE_BUFFER:
20267754Smsmith
20399146Siwasaki        AcpiOsPrintf ("[Buffer] Length %.2X = ", ObjDesc->Buffer.Length);
204114237Snjl        if (ObjDesc->Buffer.Length)
205114237Snjl        {
206200553Sjkim            if (ObjDesc->Buffer.Length > 16)
207200553Sjkim            {
208200553Sjkim                AcpiOsPrintf ("\n");
209200553Sjkim            }
210167802Sjkim            AcpiUtDumpBuffer (ACPI_CAST_PTR (UINT8, ObjDesc->Buffer.Pointer),
211117521Snjl                    ObjDesc->Buffer.Length, DB_DWORD_DISPLAY, _COMPONENT);
212114237Snjl        }
213114237Snjl        else
214114237Snjl        {
215114237Snjl            AcpiOsPrintf ("\n");
216114237Snjl        }
21767754Smsmith        break;
21867754Smsmith
21967754Smsmith
22067754Smsmith    case ACPI_TYPE_PACKAGE:
22167754Smsmith
222209746Sjkim        AcpiOsPrintf ("[Package] Contains %u Elements:\n",
223117521Snjl                ObjDesc->Package.Count);
22467754Smsmith
22567754Smsmith        for (i = 0; i < ObjDesc->Package.Count; i++)
22667754Smsmith        {
227151937Sjkim            AcpiDbDumpExternalObject (&ObjDesc->Package.Elements[i], Level+1);
22867754Smsmith        }
22967754Smsmith        break;
23067754Smsmith
23167754Smsmith
232107325Siwasaki    case ACPI_TYPE_LOCAL_REFERENCE:
23382367Smsmith
234193267Sjkim        AcpiOsPrintf ("[Object Reference] = ");
235138287Smarks        AcpiDmDisplayInternalObject (ObjDesc->Reference.Handle, NULL);
23667754Smsmith        break;
23767754Smsmith
23882367Smsmith
23967754Smsmith    case ACPI_TYPE_PROCESSOR:
24082367Smsmith
24167754Smsmith        AcpiOsPrintf ("[Processor]\n");
24267754Smsmith        break;
24367754Smsmith
24482367Smsmith
24567754Smsmith    case ACPI_TYPE_POWER:
24682367Smsmith
24767754Smsmith        AcpiOsPrintf ("[Power Resource]\n");
24867754Smsmith        break;
24967754Smsmith
25082367Smsmith
25167754Smsmith    default:
25267754Smsmith
253151937Sjkim        AcpiOsPrintf ("[Unknown Type] %X\n", ObjDesc->Type);
25467754Smsmith        break;
25567754Smsmith    }
25667754Smsmith}
25767754Smsmith
25867754Smsmith
25967754Smsmith/*******************************************************************************
26067754Smsmith *
26167754Smsmith * FUNCTION:    AcpiDbPrepNamestring
26267754Smsmith *
26367754Smsmith * PARAMETERS:  Name            - String to prepare
26467754Smsmith *
26567754Smsmith * RETURN:      None
26667754Smsmith *
26767754Smsmith * DESCRIPTION: Translate all forward slashes and dots to backslashes.
26867754Smsmith *
26967754Smsmith ******************************************************************************/
27067754Smsmith
27167754Smsmithvoid
27267754SmsmithAcpiDbPrepNamestring (
273114237Snjl    char                    *Name)
27467754Smsmith{
27567754Smsmith
27667754Smsmith    if (!Name)
27767754Smsmith    {
27867754Smsmith        return;
27967754Smsmith    }
28067754Smsmith
281151937Sjkim    AcpiUtStrupr (Name);
28267754Smsmith
28367754Smsmith    /* Convert a leading forward slash to a backslash */
28467754Smsmith
28567754Smsmith    if (*Name == '/')
28667754Smsmith    {
28767754Smsmith        *Name = '\\';
28867754Smsmith    }
28967754Smsmith
29067754Smsmith    /* Ignore a leading backslash, this is the root prefix */
29167754Smsmith
29267754Smsmith    if (*Name == '\\')
29367754Smsmith    {
29467754Smsmith        Name++;
29567754Smsmith    }
29667754Smsmith
29767754Smsmith    /* Convert all slash path separators to dots */
29867754Smsmith
29967754Smsmith    while (*Name)
30067754Smsmith    {
30167754Smsmith        if ((*Name == '/') ||
30267754Smsmith            (*Name == '\\'))
30367754Smsmith        {
30467754Smsmith            *Name = '.';
30567754Smsmith        }
30667754Smsmith
30767754Smsmith        Name++;
30867754Smsmith    }
30967754Smsmith}
31067754Smsmith
31167754Smsmith
31267754Smsmith/*******************************************************************************
31367754Smsmith *
314151937Sjkim * FUNCTION:    AcpiDbLocalNsLookup
315151937Sjkim *
316151937Sjkim * PARAMETERS:  Name            - Name to lookup
317151937Sjkim *
318151937Sjkim * RETURN:      Pointer to a namespace node, null on failure
319151937Sjkim *
320151937Sjkim * DESCRIPTION: Lookup a name in the ACPI namespace
321151937Sjkim *
322151937Sjkim * Note: Currently begins search from the root.  Could be enhanced to use
323151937Sjkim * the current prefix (scope) node as the search beginning point.
324151937Sjkim *
325151937Sjkim ******************************************************************************/
326151937Sjkim
327151937SjkimACPI_NAMESPACE_NODE *
328151937SjkimAcpiDbLocalNsLookup (
329151937Sjkim    char                    *Name)
330151937Sjkim{
331151937Sjkim    char                    *InternalPath;
332151937Sjkim    ACPI_STATUS             Status;
333151937Sjkim    ACPI_NAMESPACE_NODE     *Node = NULL;
334151937Sjkim
335151937Sjkim
336151937Sjkim    AcpiDbPrepNamestring (Name);
337151937Sjkim
338151937Sjkim    /* Build an internal namestring */
339151937Sjkim
340151937Sjkim    Status = AcpiNsInternalizeName (Name, &InternalPath);
341151937Sjkim    if (ACPI_FAILURE (Status))
342151937Sjkim    {
343151937Sjkim        AcpiOsPrintf ("Invalid namestring: %s\n", Name);
344151937Sjkim        return (NULL);
345151937Sjkim    }
346151937Sjkim
347151937Sjkim    /*
348151937Sjkim     * Lookup the name.
349151937Sjkim     * (Uses root node as the search starting point)
350151937Sjkim     */
351151937Sjkim    Status = AcpiNsLookup (NULL, InternalPath, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
352151937Sjkim                    ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE, NULL, &Node);
353151937Sjkim    if (ACPI_FAILURE (Status))
354151937Sjkim    {
355167802Sjkim        AcpiOsPrintf ("Could not locate name: %s, %s\n",
356151937Sjkim                Name, AcpiFormatException (Status));
357151937Sjkim    }
358151937Sjkim
359167802Sjkim    ACPI_FREE (InternalPath);
360151937Sjkim    return (Node);
361151937Sjkim}
362151937Sjkim
363151937Sjkim
364167802Sjkim/*******************************************************************************
365167802Sjkim *
366167802Sjkim * FUNCTION:    AcpiDbUInt32ToHexString
367167802Sjkim *
368167802Sjkim * PARAMETERS:  Value           - The value to be converted to string
369167802Sjkim *              Buffer          - Buffer for result (not less than 11 bytes)
370167802Sjkim *
371167802Sjkim * RETURN:      None
372167802Sjkim *
373167802Sjkim * DESCRIPTION: Convert the unsigned 32-bit value to the hexadecimal image
374167802Sjkim *
375167802Sjkim * NOTE: It is the caller's responsibility to ensure that the length of buffer
376167802Sjkim *       is sufficient.
377167802Sjkim *
378167802Sjkim ******************************************************************************/
379167802Sjkim
380167802Sjkimvoid
381167802SjkimAcpiDbUInt32ToHexString (
382167802Sjkim    UINT32                  Value,
383167802Sjkim    char                    *Buffer)
384167802Sjkim{
385222544Sjkim    int                     i;
386167802Sjkim
387167802Sjkim
388167802Sjkim    if (Value == 0)
389167802Sjkim    {
390167802Sjkim        ACPI_STRCPY (Buffer, "0");
391167802Sjkim        return;
392167802Sjkim    }
393167802Sjkim
394222544Sjkim    Buffer[8] = '\0';
395167802Sjkim
396222544Sjkim    for (i = 7; i >= 0; i--)
397167802Sjkim    {
398167802Sjkim        Buffer[i] = Converter [Value & 0x0F];
399167802Sjkim        Value = Value >> 4;
400167802Sjkim    }
401167802Sjkim}
402167802Sjkim
403167802Sjkim
404151937Sjkim#ifdef ACPI_OBSOLETE_FUNCTIONS
405151937Sjkim/*******************************************************************************
406151937Sjkim *
40767754Smsmith * FUNCTION:    AcpiDbSecondPassParse
40867754Smsmith *
40967754Smsmith * PARAMETERS:  Root            - Root of the parse tree
41067754Smsmith *
41167754Smsmith * RETURN:      Status
41267754Smsmith *
41367754Smsmith * DESCRIPTION: Second pass parse of the ACPI tables.  We need to wait until
41467754Smsmith *              second pass to parse the control methods
41567754Smsmith *
41667754Smsmith ******************************************************************************/
41767754Smsmith
41867754SmsmithACPI_STATUS
41967754SmsmithAcpiDbSecondPassParse (
42067754Smsmith    ACPI_PARSE_OBJECT       *Root)
42167754Smsmith{
42267754Smsmith    ACPI_PARSE_OBJECT       *Op = Root;
42399679Siwasaki    ACPI_PARSE_OBJECT       *Method;
42467754Smsmith    ACPI_PARSE_OBJECT       *SearchOp;
42567754Smsmith    ACPI_PARSE_OBJECT       *StartOp;
42667754Smsmith    ACPI_STATUS             Status = AE_OK;
42767754Smsmith    UINT32                  BaseAmlOffset;
42884491Smsmith    ACPI_WALK_STATE         *WalkState;
42967754Smsmith
43067754Smsmith
43191116Smsmith    ACPI_FUNCTION_ENTRY ();
43284491Smsmith
43384491Smsmith
43467754Smsmith    AcpiOsPrintf ("Pass two parse ....\n");
43567754Smsmith
43667754Smsmith    while (Op)
43767754Smsmith    {
43899679Siwasaki        if (Op->Common.AmlOpcode == AML_METHOD_OP)
43967754Smsmith        {
44099679Siwasaki            Method = Op;
44167754Smsmith
44299679Siwasaki            /* Create a new walk state for the parse */
44399679Siwasaki
444117521Snjl            WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
44584491Smsmith            if (!WalkState)
44684491Smsmith            {
44784491Smsmith                return (AE_NO_MEMORY);
44884491Smsmith            }
44967754Smsmith
45099679Siwasaki            /* Init the Walk State */
45184491Smsmith
45284491Smsmith            WalkState->ParserState.Aml          =
45399679Siwasaki            WalkState->ParserState.AmlStart     = Method->Named.Data;
45484491Smsmith            WalkState->ParserState.AmlEnd       =
455151937Sjkim            WalkState->ParserState.PkgEnd       = Method->Named.Data +
456151937Sjkim                                                  Method->Named.Length;
45784491Smsmith            WalkState->ParserState.StartScope   = Op;
45884491Smsmith
45984491Smsmith            WalkState->DescendingCallback       = AcpiDsLoad1BeginOp;
46084491Smsmith            WalkState->AscendingCallback        = AcpiDsLoad1EndOp;
46184491Smsmith
46299679Siwasaki            /* Perform the AML parse */
46384491Smsmith
46484491Smsmith            Status = AcpiPsParseAml (WalkState);
46584491Smsmith
46699679Siwasaki            BaseAmlOffset = (Method->Common.Value.Arg)->Common.AmlOffset + 1;
46799679Siwasaki            StartOp = (Method->Common.Value.Arg)->Common.Next;
46867754Smsmith            SearchOp = StartOp;
46967754Smsmith
47067754Smsmith            while (SearchOp)
47167754Smsmith            {
47299679Siwasaki                SearchOp->Common.AmlOffset += BaseAmlOffset;
47367754Smsmith                SearchOp = AcpiPsGetDepthNext (StartOp, SearchOp);
47467754Smsmith            }
47567754Smsmith        }
47667754Smsmith
47799679Siwasaki        if (Op->Common.AmlOpcode == AML_REGION_OP)
47867754Smsmith        {
47967754Smsmith            /* TBD: [Investigate] this isn't quite the right thing to do! */
48067754Smsmith            /*
48167754Smsmith             *
48267754Smsmith             * Method = (ACPI_DEFERRED_OP *) Op;
48367754Smsmith             * Status = AcpiPsParseAml (Op, Method->Body, Method->BodyLength);
48467754Smsmith             */
48567754Smsmith        }
48667754Smsmith
48767754Smsmith        if (ACPI_FAILURE (Status))
48867754Smsmith        {
48984491Smsmith            break;
49067754Smsmith        }
49167754Smsmith
49267754Smsmith        Op = AcpiPsGetDepthNext (Root, Op);
49367754Smsmith    }
49467754Smsmith
49567754Smsmith    return (Status);
49667754Smsmith}
49767754Smsmith
49867754Smsmith
49967754Smsmith/*******************************************************************************
50067754Smsmith *
501151937Sjkim * FUNCTION:    AcpiDbDumpBuffer
50267754Smsmith *
503151937Sjkim * PARAMETERS:  Address             - Pointer to the buffer
50467754Smsmith *
505151937Sjkim * RETURN:      None
50667754Smsmith *
507151937Sjkim * DESCRIPTION: Print a portion of a buffer
50867754Smsmith *
50967754Smsmith ******************************************************************************/
51067754Smsmith
511151937Sjkimvoid
512151937SjkimAcpiDbDumpBuffer (
513151937Sjkim    UINT32                  Address)
51467754Smsmith{
51567754Smsmith
516151937Sjkim    AcpiOsPrintf ("\nLocation %X:\n", Address);
51767754Smsmith
518151937Sjkim    AcpiDbgLevel |= ACPI_LV_TABLES;
519151937Sjkim    AcpiUtDumpBuffer (ACPI_TO_POINTER (Address), 64, DB_BYTE_DISPLAY,
520151937Sjkim            ACPI_UINT32_MAX);
52167754Smsmith}
522151937Sjkim#endif
52367754Smsmith
524102550Siwasaki#endif /* ACPI_DEBUGGER */
52567754Smsmith
52667754Smsmith
527