Home | History | Annotate | Line # | Download | only in debugger
dbutils.c revision 1.5
      1 /*******************************************************************************
      2  *
      3  * Module Name: dbutils - AML debugger utilities
      4  *
      5  ******************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2013, 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     ACPI_DB_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     case ACPI_TYPE_INTEGER:
    183 
    184         AcpiOsPrintf ("[Integer] = %8.8X%8.8X\n",
    185                     ACPI_FORMAT_UINT64 (ObjDesc->Integer.Value));
    186         break;
    187 
    188     case ACPI_TYPE_STRING:
    189 
    190         AcpiOsPrintf ("[String] Length %.2X = ", ObjDesc->String.Length);
    191         AcpiUtPrintString (ObjDesc->String.Pointer, ACPI_UINT8_MAX);
    192         AcpiOsPrintf ("\n");
    193         break;
    194 
    195     case ACPI_TYPE_BUFFER:
    196 
    197         AcpiOsPrintf ("[Buffer] Length %.2X = ", ObjDesc->Buffer.Length);
    198         if (ObjDesc->Buffer.Length)
    199         {
    200             if (ObjDesc->Buffer.Length > 16)
    201             {
    202                 AcpiOsPrintf ("\n");
    203             }
    204             AcpiUtDebugDumpBuffer (ACPI_CAST_PTR (UINT8, ObjDesc->Buffer.Pointer),
    205                     ObjDesc->Buffer.Length, DB_BYTE_DISPLAY, _COMPONENT);
    206         }
    207         else
    208         {
    209             AcpiOsPrintf ("\n");
    210         }
    211         break;
    212 
    213     case ACPI_TYPE_PACKAGE:
    214 
    215         AcpiOsPrintf ("[Package] Contains %u Elements:\n",
    216                 ObjDesc->Package.Count);
    217 
    218         for (i = 0; i < ObjDesc->Package.Count; i++)
    219         {
    220             AcpiDbDumpExternalObject (&ObjDesc->Package.Elements[i], Level+1);
    221         }
    222         break;
    223 
    224     case ACPI_TYPE_LOCAL_REFERENCE:
    225 
    226         AcpiOsPrintf ("[Object Reference] = ");
    227         AcpiDmDisplayInternalObject (ObjDesc->Reference.Handle, NULL);
    228         break;
    229 
    230     case ACPI_TYPE_PROCESSOR:
    231 
    232         AcpiOsPrintf ("[Processor]\n");
    233         break;
    234 
    235     case ACPI_TYPE_POWER:
    236 
    237         AcpiOsPrintf ("[Power Resource]\n");
    238         break;
    239 
    240     default:
    241 
    242         AcpiOsPrintf ("[Unknown Type] %X\n", ObjDesc->Type);
    243         break;
    244     }
    245 }
    246 
    247 
    248 /*******************************************************************************
    249  *
    250  * FUNCTION:    AcpiDbPrepNamestring
    251  *
    252  * PARAMETERS:  Name            - String to prepare
    253  *
    254  * RETURN:      None
    255  *
    256  * DESCRIPTION: Translate all forward slashes and dots to backslashes.
    257  *
    258  ******************************************************************************/
    259 
    260 void
    261 AcpiDbPrepNamestring (
    262     char                    *Name)
    263 {
    264 
    265     if (!Name)
    266     {
    267         return;
    268     }
    269 
    270     AcpiUtStrupr (Name);
    271 
    272     /* Convert a leading forward slash to a backslash */
    273 
    274     if (*Name == '/')
    275     {
    276         *Name = '\\';
    277     }
    278 
    279     /* Ignore a leading backslash, this is the root prefix */
    280 
    281     if (ACPI_IS_ROOT_PREFIX (*Name))
    282     {
    283         Name++;
    284     }
    285 
    286     /* Convert all slash path separators to dots */
    287 
    288     while (*Name)
    289     {
    290         if ((*Name == '/') ||
    291             (*Name == '\\'))
    292         {
    293             *Name = '.';
    294         }
    295 
    296         Name++;
    297     }
    298 }
    299 
    300 
    301 /*******************************************************************************
    302  *
    303  * FUNCTION:    AcpiDbLocalNsLookup
    304  *
    305  * PARAMETERS:  Name            - Name to lookup
    306  *
    307  * RETURN:      Pointer to a namespace node, null on failure
    308  *
    309  * DESCRIPTION: Lookup a name in the ACPI namespace
    310  *
    311  * Note: Currently begins search from the root. Could be enhanced to use
    312  * the current prefix (scope) node as the search beginning point.
    313  *
    314  ******************************************************************************/
    315 
    316 ACPI_NAMESPACE_NODE *
    317 AcpiDbLocalNsLookup (
    318     char                    *Name)
    319 {
    320     char                    *InternalPath;
    321     ACPI_STATUS             Status;
    322     ACPI_NAMESPACE_NODE     *Node = NULL;
    323 
    324 
    325     AcpiDbPrepNamestring (Name);
    326 
    327     /* Build an internal namestring */
    328 
    329     Status = AcpiNsInternalizeName (Name, &InternalPath);
    330     if (ACPI_FAILURE (Status))
    331     {
    332         AcpiOsPrintf ("Invalid namestring: %s\n", Name);
    333         return (NULL);
    334     }
    335 
    336     /*
    337      * Lookup the name.
    338      * (Uses root node as the search starting point)
    339      */
    340     Status = AcpiNsLookup (NULL, InternalPath, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
    341                     ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE, NULL, &Node);
    342     if (ACPI_FAILURE (Status))
    343     {
    344         AcpiOsPrintf ("Could not locate name: %s, %s\n",
    345                 Name, AcpiFormatException (Status));
    346     }
    347 
    348     ACPI_FREE (InternalPath);
    349     return (Node);
    350 }
    351 
    352 
    353 /*******************************************************************************
    354  *
    355  * FUNCTION:    AcpiDbUint32ToHexString
    356  *
    357  * PARAMETERS:  Value           - The value to be converted to string
    358  *              Buffer          - Buffer for result (not less than 11 bytes)
    359  *
    360  * RETURN:      None
    361  *
    362  * DESCRIPTION: Convert the unsigned 32-bit value to the hexadecimal image
    363  *
    364  * NOTE: It is the caller's responsibility to ensure that the length of buffer
    365  *       is sufficient.
    366  *
    367  ******************************************************************************/
    368 
    369 void
    370 AcpiDbUint32ToHexString (
    371     UINT32                  Value,
    372     char                    *Buffer)
    373 {
    374     int                     i;
    375 
    376 
    377     if (Value == 0)
    378     {
    379         ACPI_STRCPY (Buffer, "0");
    380         return;
    381     }
    382 
    383     Buffer[8] = '\0';
    384 
    385     for (i = 7; i >= 0; i--)
    386     {
    387         Buffer[i] = Converter [Value & 0x0F];
    388         Value = Value >> 4;
    389     }
    390 }
    391 
    392 
    393 #ifdef ACPI_OBSOLETE_FUNCTIONS
    394 /*******************************************************************************
    395  *
    396  * FUNCTION:    AcpiDbSecondPassParse
    397  *
    398  * PARAMETERS:  Root            - Root of the parse tree
    399  *
    400  * RETURN:      Status
    401  *
    402  * DESCRIPTION: Second pass parse of the ACPI tables. We need to wait until
    403  *              second pass to parse the control methods
    404  *
    405  ******************************************************************************/
    406 
    407 ACPI_STATUS
    408 AcpiDbSecondPassParse (
    409     ACPI_PARSE_OBJECT       *Root)
    410 {
    411     ACPI_PARSE_OBJECT       *Op = Root;
    412     ACPI_PARSE_OBJECT       *Method;
    413     ACPI_PARSE_OBJECT       *SearchOp;
    414     ACPI_PARSE_OBJECT       *StartOp;
    415     ACPI_STATUS             Status = AE_OK;
    416     UINT32                  BaseAmlOffset;
    417     ACPI_WALK_STATE         *WalkState;
    418 
    419 
    420     ACPI_FUNCTION_ENTRY ();
    421 
    422 
    423     AcpiOsPrintf ("Pass two parse ....\n");
    424 
    425     while (Op)
    426     {
    427         if (Op->Common.AmlOpcode == AML_METHOD_OP)
    428         {
    429             Method = Op;
    430 
    431             /* Create a new walk state for the parse */
    432 
    433             WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
    434             if (!WalkState)
    435             {
    436                 return (AE_NO_MEMORY);
    437             }
    438 
    439             /* Init the Walk State */
    440 
    441             WalkState->ParserState.Aml          =
    442             WalkState->ParserState.AmlStart     = Method->Named.Data;
    443             WalkState->ParserState.AmlEnd       =
    444             WalkState->ParserState.PkgEnd       = Method->Named.Data +
    445                                                   Method->Named.Length;
    446             WalkState->ParserState.StartScope   = Op;
    447 
    448             WalkState->DescendingCallback       = AcpiDsLoad1BeginOp;
    449             WalkState->AscendingCallback        = AcpiDsLoad1EndOp;
    450 
    451             /* Perform the AML parse */
    452 
    453             Status = AcpiPsParseAml (WalkState);
    454 
    455             BaseAmlOffset = (Method->Common.Value.Arg)->Common.AmlOffset + 1;
    456             StartOp = (Method->Common.Value.Arg)->Common.Next;
    457             SearchOp = StartOp;
    458 
    459             while (SearchOp)
    460             {
    461                 SearchOp->Common.AmlOffset += BaseAmlOffset;
    462                 SearchOp = AcpiPsGetDepthNext (StartOp, SearchOp);
    463             }
    464         }
    465 
    466         if (Op->Common.AmlOpcode == AML_REGION_OP)
    467         {
    468             /* TBD: [Investigate] this isn't quite the right thing to do! */
    469             /*
    470              *
    471              * Method = (ACPI_DEFERRED_OP *) Op;
    472              * Status = AcpiPsParseAml (Op, Method->Body, Method->BodyLength);
    473              */
    474         }
    475 
    476         if (ACPI_FAILURE (Status))
    477         {
    478             break;
    479         }
    480 
    481         Op = AcpiPsGetDepthNext (Root, Op);
    482     }
    483 
    484     return (Status);
    485 }
    486 
    487 
    488 /*******************************************************************************
    489  *
    490  * FUNCTION:    AcpiDbDumpBuffer
    491  *
    492  * PARAMETERS:  Address             - Pointer to the buffer
    493  *
    494  * RETURN:      None
    495  *
    496  * DESCRIPTION: Print a portion of a buffer
    497  *
    498  ******************************************************************************/
    499 
    500 void
    501 AcpiDbDumpBuffer (
    502     UINT32                  Address)
    503 {
    504 
    505     AcpiOsPrintf ("\nLocation %X:\n", Address);
    506 
    507     AcpiDbgLevel |= ACPI_LV_TABLES;
    508     AcpiUtDebugDumpBuffer (ACPI_TO_POINTER (Address), 64, DB_BYTE_DISPLAY,
    509             ACPI_UINT32_MAX);
    510 }
    511 #endif
    512 
    513 #endif /* ACPI_DEBUGGER */
    514