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