Home | History | Annotate | Line # | Download | only in debugger
dbutils.c revision 1.4
      1 /*******************************************************************************
      2  *
      3  * Module Name: dbutils - AML debugger utilities
      4  *
      5  ******************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2011, 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 
     45 #include "acpi.h"
     46 #include "accommon.h"
     47 #include "acnamesp.h"
     48 #include "acdebug.h"
     49 #include "acdisasm.h"
     50 
     51 
     52 #ifdef ACPI_DEBUGGER
     53 
     54 #define _COMPONENT          ACPI_CA_DEBUGGER
     55         ACPI_MODULE_NAME    ("dbutils")
     56 
     57 /* Local prototypes */
     58 
     59 #ifdef ACPI_OBSOLETE_FUNCTIONS
     60 ACPI_STATUS
     61 AcpiDbSecondPassParse (
     62     ACPI_PARSE_OBJECT       *Root);
     63 
     64 void
     65 AcpiDbDumpBuffer (
     66     UINT32                  Address);
     67 #endif
     68 
     69 static const char           *Converter = "0123456789ABCDEF";
     70 
     71 
     72 /*******************************************************************************
     73  *
     74  * FUNCTION:    AcpiDbMatchArgument
     75  *
     76  * PARAMETERS:  UserArgument            - User command line
     77  *              Arguments               - Array of commands to match against
     78  *
     79  * RETURN:      Index into command array or ACPI_TYPE_NOT_FOUND if not found
     80  *
     81  * DESCRIPTION: Search command array for a command match
     82  *
     83  ******************************************************************************/
     84 
     85 ACPI_OBJECT_TYPE
     86 AcpiDbMatchArgument (
     87     char                    *UserArgument,
     88     ARGUMENT_INFO           *Arguments)
     89 {
     90     UINT32                  i;
     91 
     92 
     93     if (!UserArgument || UserArgument[0] == 0)
     94     {
     95         return (ACPI_TYPE_NOT_FOUND);
     96     }
     97 
     98     for (i = 0; Arguments[i].Name; i++)
     99     {
    100         if (ACPI_STRSTR (Arguments[i].Name, UserArgument) == Arguments[i].Name)
    101         {
    102             return (i);
    103         }
    104     }
    105 
    106     /* Argument not recognized */
    107 
    108     return (ACPI_TYPE_NOT_FOUND);
    109 }
    110 
    111 
    112 /*******************************************************************************
    113  *
    114  * FUNCTION:    AcpiDbSetOutputDestination
    115  *
    116  * PARAMETERS:  OutputFlags         - Current flags word
    117  *
    118  * RETURN:      None
    119  *
    120  * DESCRIPTION: Set the current destination for debugger output.  Also sets
    121  *              the debug output level accordingly.
    122  *
    123  ******************************************************************************/
    124 
    125 void
    126 AcpiDbSetOutputDestination (
    127     UINT32                  OutputFlags)
    128 {
    129 
    130     AcpiGbl_DbOutputFlags = (UINT8) OutputFlags;
    131 
    132     if ((OutputFlags & ACPI_DB_REDIRECTABLE_OUTPUT) && AcpiGbl_DbOutputToFile)
    133     {
    134         AcpiDbgLevel = AcpiGbl_DbDebugLevel;
    135     }
    136     else
    137     {
    138         AcpiDbgLevel = AcpiGbl_DbConsoleDebugLevel;
    139     }
    140 }
    141 
    142 
    143 /*******************************************************************************
    144  *
    145  * FUNCTION:    AcpiDbDumpExternalObject
    146  *
    147  * PARAMETERS:  ObjDesc         - External ACPI object to dump
    148  *              Level           - Nesting level.
    149  *
    150  * RETURN:      None
    151  *
    152  * DESCRIPTION: Dump the contents of an ACPI external object
    153  *
    154  ******************************************************************************/
    155 
    156 void
    157 AcpiDbDumpExternalObject (
    158     ACPI_OBJECT             *ObjDesc,
    159     UINT32                  Level)
    160 {
    161     UINT32                  i;
    162 
    163 
    164     if (!ObjDesc)
    165     {
    166         AcpiOsPrintf ("[Null Object]\n");
    167         return;
    168     }
    169 
    170     for (i = 0; i < Level; i++)
    171     {
    172         AcpiOsPrintf ("  ");
    173     }
    174 
    175     switch (ObjDesc->Type)
    176     {
    177     case ACPI_TYPE_ANY:
    178 
    179         AcpiOsPrintf ("[Null Object] (Type=0)\n");
    180         break;
    181 
    182 
    183     case ACPI_TYPE_INTEGER:
    184 
    185         AcpiOsPrintf ("[Integer] = %8.8X%8.8X\n",
    186                     ACPI_FORMAT_UINT64 (ObjDesc->Integer.Value));
    187         break;
    188 
    189 
    190     case ACPI_TYPE_STRING:
    191 
    192         AcpiOsPrintf ("[String] Length %.2X = ", ObjDesc->String.Length);
    193         for (i = 0; i < ObjDesc->String.Length; i++)
    194         {
    195             AcpiOsPrintf ("%c", ObjDesc->String.Pointer[i]);
    196         }
    197         AcpiOsPrintf ("\n");
    198         break;
    199 
    200 
    201     case ACPI_TYPE_BUFFER:
    202 
    203         AcpiOsPrintf ("[Buffer] Length %.2X = ", ObjDesc->Buffer.Length);
    204         if (ObjDesc->Buffer.Length)
    205         {
    206             if (ObjDesc->Buffer.Length > 16)
    207             {
    208                 AcpiOsPrintf ("\n");
    209             }
    210             AcpiUtDumpBuffer (ACPI_CAST_PTR (UINT8, ObjDesc->Buffer.Pointer),
    211                     ObjDesc->Buffer.Length, DB_DWORD_DISPLAY, _COMPONENT);
    212         }
    213         else
    214         {
    215             AcpiOsPrintf ("\n");
    216         }
    217         break;
    218 
    219 
    220     case ACPI_TYPE_PACKAGE:
    221 
    222         AcpiOsPrintf ("[Package] Contains %u Elements:\n",
    223                 ObjDesc->Package.Count);
    224 
    225         for (i = 0; i < ObjDesc->Package.Count; i++)
    226         {
    227             AcpiDbDumpExternalObject (&ObjDesc->Package.Elements[i], Level+1);
    228         }
    229         break;
    230 
    231 
    232     case ACPI_TYPE_LOCAL_REFERENCE:
    233 
    234         AcpiOsPrintf ("[Object Reference] = ");
    235         AcpiDmDisplayInternalObject (ObjDesc->Reference.Handle, NULL);
    236         break;
    237 
    238 
    239     case ACPI_TYPE_PROCESSOR:
    240 
    241         AcpiOsPrintf ("[Processor]\n");
    242         break;
    243 
    244 
    245     case ACPI_TYPE_POWER:
    246 
    247         AcpiOsPrintf ("[Power Resource]\n");
    248         break;
    249 
    250 
    251     default:
    252 
    253         AcpiOsPrintf ("[Unknown Type] %X\n", ObjDesc->Type);
    254         break;
    255     }
    256 }
    257 
    258 
    259 /*******************************************************************************
    260  *
    261  * FUNCTION:    AcpiDbPrepNamestring
    262  *
    263  * PARAMETERS:  Name            - String to prepare
    264  *
    265  * RETURN:      None
    266  *
    267  * DESCRIPTION: Translate all forward slashes and dots to backslashes.
    268  *
    269  ******************************************************************************/
    270 
    271 void
    272 AcpiDbPrepNamestring (
    273     char                    *Name)
    274 {
    275 
    276     if (!Name)
    277     {
    278         return;
    279     }
    280 
    281     AcpiUtStrupr (Name);
    282 
    283     /* Convert a leading forward slash to a backslash */
    284 
    285     if (*Name == '/')
    286     {
    287         *Name = '\\';
    288     }
    289 
    290     /* Ignore a leading backslash, this is the root prefix */
    291 
    292     if (*Name == '\\')
    293     {
    294         Name++;
    295     }
    296 
    297     /* Convert all slash path separators to dots */
    298 
    299     while (*Name)
    300     {
    301         if ((*Name == '/') ||
    302             (*Name == '\\'))
    303         {
    304             *Name = '.';
    305         }
    306 
    307         Name++;
    308     }
    309 }
    310 
    311 
    312 /*******************************************************************************
    313  *
    314  * FUNCTION:    AcpiDbLocalNsLookup
    315  *
    316  * PARAMETERS:  Name            - Name to lookup
    317  *
    318  * RETURN:      Pointer to a namespace node, null on failure
    319  *
    320  * DESCRIPTION: Lookup a name in the ACPI namespace
    321  *
    322  * Note: Currently begins search from the root.  Could be enhanced to use
    323  * the current prefix (scope) node as the search beginning point.
    324  *
    325  ******************************************************************************/
    326 
    327 ACPI_NAMESPACE_NODE *
    328 AcpiDbLocalNsLookup (
    329     char                    *Name)
    330 {
    331     char                    *InternalPath;
    332     ACPI_STATUS             Status;
    333     ACPI_NAMESPACE_NODE     *Node = NULL;
    334 
    335 
    336     AcpiDbPrepNamestring (Name);
    337 
    338     /* Build an internal namestring */
    339 
    340     Status = AcpiNsInternalizeName (Name, &InternalPath);
    341     if (ACPI_FAILURE (Status))
    342     {
    343         AcpiOsPrintf ("Invalid namestring: %s\n", Name);
    344         return (NULL);
    345     }
    346 
    347     /*
    348      * Lookup the name.
    349      * (Uses root node as the search starting point)
    350      */
    351     Status = AcpiNsLookup (NULL, InternalPath, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
    352                     ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE, NULL, &Node);
    353     if (ACPI_FAILURE (Status))
    354     {
    355         AcpiOsPrintf ("Could not locate name: %s, %s\n",
    356                 Name, AcpiFormatException (Status));
    357     }
    358 
    359     ACPI_FREE (InternalPath);
    360     return (Node);
    361 }
    362 
    363 
    364 /*******************************************************************************
    365  *
    366  * FUNCTION:    AcpiDbUInt32ToHexString
    367  *
    368  * PARAMETERS:  Value           - The value to be converted to string
    369  *              Buffer          - Buffer for result (not less than 11 bytes)
    370  *
    371  * RETURN:      None
    372  *
    373  * DESCRIPTION: Convert the unsigned 32-bit value to the hexadecimal image
    374  *
    375  * NOTE: It is the caller's responsibility to ensure that the length of buffer
    376  *       is sufficient.
    377  *
    378  ******************************************************************************/
    379 
    380 void
    381 AcpiDbUInt32ToHexString (
    382     UINT32                  Value,
    383     char                    *Buffer)
    384 {
    385     int                     i;
    386 
    387 
    388     if (Value == 0)
    389     {
    390         ACPI_STRCPY (Buffer, "0");
    391         return;
    392     }
    393 
    394     Buffer[8] = '\0';
    395 
    396     for (i = 7; i >= 0; i--)
    397     {
    398         Buffer[i] = Converter [Value & 0x0F];
    399         Value = Value >> 4;
    400     }
    401 }
    402 
    403 
    404 #ifdef ACPI_OBSOLETE_FUNCTIONS
    405 /*******************************************************************************
    406  *
    407  * FUNCTION:    AcpiDbSecondPassParse
    408  *
    409  * PARAMETERS:  Root            - Root of the parse tree
    410  *
    411  * RETURN:      Status
    412  *
    413  * DESCRIPTION: Second pass parse of the ACPI tables.  We need to wait until
    414  *              second pass to parse the control methods
    415  *
    416  ******************************************************************************/
    417 
    418 ACPI_STATUS
    419 AcpiDbSecondPassParse (
    420     ACPI_PARSE_OBJECT       *Root)
    421 {
    422     ACPI_PARSE_OBJECT       *Op = Root;
    423     ACPI_PARSE_OBJECT       *Method;
    424     ACPI_PARSE_OBJECT       *SearchOp;
    425     ACPI_PARSE_OBJECT       *StartOp;
    426     ACPI_STATUS             Status = AE_OK;
    427     UINT32                  BaseAmlOffset;
    428     ACPI_WALK_STATE         *WalkState;
    429 
    430 
    431     ACPI_FUNCTION_ENTRY ();
    432 
    433 
    434     AcpiOsPrintf ("Pass two parse ....\n");
    435 
    436     while (Op)
    437     {
    438         if (Op->Common.AmlOpcode == AML_METHOD_OP)
    439         {
    440             Method = Op;
    441 
    442             /* Create a new walk state for the parse */
    443 
    444             WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
    445             if (!WalkState)
    446             {
    447                 return (AE_NO_MEMORY);
    448             }
    449 
    450             /* Init the Walk State */
    451 
    452             WalkState->ParserState.Aml          =
    453             WalkState->ParserState.AmlStart     = Method->Named.Data;
    454             WalkState->ParserState.AmlEnd       =
    455             WalkState->ParserState.PkgEnd       = Method->Named.Data +
    456                                                   Method->Named.Length;
    457             WalkState->ParserState.StartScope   = Op;
    458 
    459             WalkState->DescendingCallback       = AcpiDsLoad1BeginOp;
    460             WalkState->AscendingCallback        = AcpiDsLoad1EndOp;
    461 
    462             /* Perform the AML parse */
    463 
    464             Status = AcpiPsParseAml (WalkState);
    465 
    466             BaseAmlOffset = (Method->Common.Value.Arg)->Common.AmlOffset + 1;
    467             StartOp = (Method->Common.Value.Arg)->Common.Next;
    468             SearchOp = StartOp;
    469 
    470             while (SearchOp)
    471             {
    472                 SearchOp->Common.AmlOffset += BaseAmlOffset;
    473                 SearchOp = AcpiPsGetDepthNext (StartOp, SearchOp);
    474             }
    475         }
    476 
    477         if (Op->Common.AmlOpcode == AML_REGION_OP)
    478         {
    479             /* TBD: [Investigate] this isn't quite the right thing to do! */
    480             /*
    481              *
    482              * Method = (ACPI_DEFERRED_OP *) Op;
    483              * Status = AcpiPsParseAml (Op, Method->Body, Method->BodyLength);
    484              */
    485         }
    486 
    487         if (ACPI_FAILURE (Status))
    488         {
    489             break;
    490         }
    491 
    492         Op = AcpiPsGetDepthNext (Root, Op);
    493     }
    494 
    495     return (Status);
    496 }
    497 
    498 
    499 /*******************************************************************************
    500  *
    501  * FUNCTION:    AcpiDbDumpBuffer
    502  *
    503  * PARAMETERS:  Address             - Pointer to the buffer
    504  *
    505  * RETURN:      None
    506  *
    507  * DESCRIPTION: Print a portion of a buffer
    508  *
    509  ******************************************************************************/
    510 
    511 void
    512 AcpiDbDumpBuffer (
    513     UINT32                  Address)
    514 {
    515 
    516     AcpiOsPrintf ("\nLocation %X:\n", Address);
    517 
    518     AcpiDbgLevel |= ACPI_LV_TABLES;
    519     AcpiUtDumpBuffer (ACPI_TO_POINTER (Address), 64, DB_BYTE_DISPLAY,
    520             ACPI_UINT32_MAX);
    521 }
    522 #endif
    523 
    524 #endif /* ACPI_DEBUGGER */
    525 
    526 
    527