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