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