Home | History | Annotate | Line # | Download | only in debugger
dbmethod.c revision 1.1.1.3
      1 /*******************************************************************************
      2  *
      3  * Module Name: dbmethod - Debug commands for control methods
      4  *
      5  ******************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2014, 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 "acdispat.h"
     47 #include "acnamesp.h"
     48 #include "acdebug.h"
     49 #include "acdisasm.h"
     50 #include "acparser.h"
     51 #include "acpredef.h"
     52 
     53 
     54 #ifdef ACPI_DEBUGGER
     55 
     56 #define _COMPONENT          ACPI_CA_DEBUGGER
     57         ACPI_MODULE_NAME    ("dbmethod")
     58 
     59 
     60 /*******************************************************************************
     61  *
     62  * FUNCTION:    AcpiDbSetMethodBreakpoint
     63  *
     64  * PARAMETERS:  Location            - AML offset of breakpoint
     65  *              WalkState           - Current walk info
     66  *              Op                  - Current Op (from parse walk)
     67  *
     68  * RETURN:      None
     69  *
     70  * DESCRIPTION: Set a breakpoint in a control method at the specified
     71  *              AML offset
     72  *
     73  ******************************************************************************/
     74 
     75 void
     76 AcpiDbSetMethodBreakpoint (
     77     char                    *Location,
     78     ACPI_WALK_STATE         *WalkState,
     79     ACPI_PARSE_OBJECT       *Op)
     80 {
     81     UINT32                  Address;
     82 
     83 
     84     if (!Op)
     85     {
     86         AcpiOsPrintf ("There is no method currently executing\n");
     87         return;
     88     }
     89 
     90     /* Get and verify the breakpoint address */
     91 
     92     Address = ACPI_STRTOUL (Location, NULL, 16);
     93     if (Address <= Op->Common.AmlOffset)
     94     {
     95         AcpiOsPrintf ("Breakpoint %X is beyond current address %X\n",
     96             Address, Op->Common.AmlOffset);
     97     }
     98 
     99     /* Save breakpoint in current walk */
    100 
    101     WalkState->UserBreakpoint = Address;
    102     AcpiOsPrintf ("Breakpoint set at AML offset %X\n", Address);
    103 }
    104 
    105 
    106 /*******************************************************************************
    107  *
    108  * FUNCTION:    AcpiDbSetMethodCallBreakpoint
    109  *
    110  * PARAMETERS:  Op                  - Current Op (from parse walk)
    111  *
    112  * RETURN:      None
    113  *
    114  * DESCRIPTION: Set a breakpoint in a control method at the specified
    115  *              AML offset
    116  *
    117  ******************************************************************************/
    118 
    119 void
    120 AcpiDbSetMethodCallBreakpoint (
    121     ACPI_PARSE_OBJECT       *Op)
    122 {
    123 
    124 
    125     if (!Op)
    126     {
    127         AcpiOsPrintf ("There is no method currently executing\n");
    128         return;
    129     }
    130 
    131     AcpiGbl_StepToNextCall = TRUE;
    132 }
    133 
    134 
    135 /*******************************************************************************
    136  *
    137  * FUNCTION:    AcpiDbSetMethodData
    138  *
    139  * PARAMETERS:  TypeArg         - L for local, A for argument
    140  *              IndexArg        - which one
    141  *              ValueArg        - Value to set.
    142  *
    143  * RETURN:      None
    144  *
    145  * DESCRIPTION: Set a local or argument for the running control method.
    146  *              NOTE: only object supported is Number.
    147  *
    148  ******************************************************************************/
    149 
    150 void
    151 AcpiDbSetMethodData (
    152     char                    *TypeArg,
    153     char                    *IndexArg,
    154     char                    *ValueArg)
    155 {
    156     char                    Type;
    157     UINT32                  Index;
    158     UINT32                  Value;
    159     ACPI_WALK_STATE         *WalkState;
    160     ACPI_OPERAND_OBJECT     *ObjDesc;
    161     ACPI_STATUS             Status;
    162     ACPI_NAMESPACE_NODE     *Node;
    163 
    164 
    165     /* Validate TypeArg */
    166 
    167     AcpiUtStrupr (TypeArg);
    168     Type = TypeArg[0];
    169     if ((Type != 'L') &&
    170         (Type != 'A') &&
    171         (Type != 'N'))
    172     {
    173         AcpiOsPrintf ("Invalid SET operand: %s\n", TypeArg);
    174         return;
    175     }
    176 
    177     Value = ACPI_STRTOUL (ValueArg, NULL, 16);
    178 
    179     if (Type == 'N')
    180     {
    181         Node = AcpiDbConvertToNode (IndexArg);
    182         if (!Node)
    183         {
    184             return;
    185         }
    186 
    187         if (Node->Type != ACPI_TYPE_INTEGER)
    188         {
    189             AcpiOsPrintf ("Can only set Integer nodes\n");
    190             return;
    191         }
    192         ObjDesc = Node->Object;
    193         ObjDesc->Integer.Value = Value;
    194         return;
    195     }
    196 
    197     /* Get the index and value */
    198 
    199     Index = ACPI_STRTOUL (IndexArg, NULL, 16);
    200 
    201     WalkState = AcpiDsGetCurrentWalkState (AcpiGbl_CurrentWalkList);
    202     if (!WalkState)
    203     {
    204         AcpiOsPrintf ("There is no method currently executing\n");
    205         return;
    206     }
    207 
    208     /* Create and initialize the new object */
    209 
    210     ObjDesc = AcpiUtCreateIntegerObject ((UINT64) Value);
    211     if (!ObjDesc)
    212     {
    213         AcpiOsPrintf ("Could not create an internal object\n");
    214         return;
    215     }
    216 
    217     /* Store the new object into the target */
    218 
    219     switch (Type)
    220     {
    221     case 'A':
    222 
    223         /* Set a method argument */
    224 
    225         if (Index > ACPI_METHOD_MAX_ARG)
    226         {
    227             AcpiOsPrintf ("Arg%u - Invalid argument name\n", Index);
    228             goto Cleanup;
    229         }
    230 
    231         Status = AcpiDsStoreObjectToLocal (ACPI_REFCLASS_ARG, Index, ObjDesc,
    232                     WalkState);
    233         if (ACPI_FAILURE (Status))
    234         {
    235             goto Cleanup;
    236         }
    237 
    238         ObjDesc = WalkState->Arguments[Index].Object;
    239 
    240         AcpiOsPrintf ("Arg%u: ", Index);
    241         AcpiDmDisplayInternalObject (ObjDesc, WalkState);
    242         break;
    243 
    244     case 'L':
    245 
    246         /* Set a method local */
    247 
    248         if (Index > ACPI_METHOD_MAX_LOCAL)
    249         {
    250             AcpiOsPrintf ("Local%u - Invalid local variable name\n", Index);
    251             goto Cleanup;
    252         }
    253 
    254         Status = AcpiDsStoreObjectToLocal (ACPI_REFCLASS_LOCAL, Index, ObjDesc,
    255                     WalkState);
    256         if (ACPI_FAILURE (Status))
    257         {
    258             goto Cleanup;
    259         }
    260 
    261         ObjDesc = WalkState->LocalVariables[Index].Object;
    262 
    263         AcpiOsPrintf ("Local%u: ", Index);
    264         AcpiDmDisplayInternalObject (ObjDesc, WalkState);
    265         break;
    266 
    267     default:
    268 
    269         break;
    270     }
    271 
    272 Cleanup:
    273     AcpiUtRemoveReference (ObjDesc);
    274 }
    275 
    276 
    277 /*******************************************************************************
    278  *
    279  * FUNCTION:    AcpiDbDisassembleAml
    280  *
    281  * PARAMETERS:  Statements          - Number of statements to disassemble
    282  *              Op                  - Current Op (from parse walk)
    283  *
    284  * RETURN:      None
    285  *
    286  * DESCRIPTION: Display disassembled AML (ASL) starting from Op for the number
    287  *              of statements specified.
    288  *
    289  ******************************************************************************/
    290 
    291 void
    292 AcpiDbDisassembleAml (
    293     char                    *Statements,
    294     ACPI_PARSE_OBJECT       *Op)
    295 {
    296     UINT32                  NumStatements = 8;
    297 
    298 
    299     if (!Op)
    300     {
    301         AcpiOsPrintf ("There is no method currently executing\n");
    302         return;
    303     }
    304 
    305     if (Statements)
    306     {
    307         NumStatements = ACPI_STRTOUL (Statements, NULL, 0);
    308     }
    309 
    310     AcpiDmDisassemble (NULL, Op, NumStatements);
    311 }
    312 
    313 
    314 /*******************************************************************************
    315  *
    316  * FUNCTION:    AcpiDbDisassembleMethod
    317  *
    318  * PARAMETERS:  Name            - Name of control method
    319  *
    320  * RETURN:      None
    321  *
    322  * DESCRIPTION: Display disassembled AML (ASL) starting from Op for the number
    323  *              of statements specified.
    324  *
    325  ******************************************************************************/
    326 
    327 ACPI_STATUS
    328 AcpiDbDisassembleMethod (
    329     char                    *Name)
    330 {
    331     ACPI_STATUS             Status;
    332     ACPI_PARSE_OBJECT       *Op;
    333     ACPI_WALK_STATE         *WalkState;
    334     ACPI_OPERAND_OBJECT     *ObjDesc;
    335     ACPI_NAMESPACE_NODE     *Method;
    336 
    337 
    338     Method = AcpiDbConvertToNode (Name);
    339     if (!Method)
    340     {
    341         return (AE_BAD_PARAMETER);
    342     }
    343 
    344     if (Method->Type != ACPI_TYPE_METHOD)
    345     {
    346         ACPI_ERROR ((AE_INFO, "%s (%s): Object must be a control method",
    347             Name, AcpiUtGetTypeName (Method->Type)));
    348         return (AE_BAD_PARAMETER);
    349     }
    350 
    351     ObjDesc = Method->Object;
    352 
    353     Op = AcpiPsCreateScopeOp ();
    354     if (!Op)
    355     {
    356         return (AE_NO_MEMORY);
    357     }
    358 
    359     /* Create and initialize a new walk state */
    360 
    361     WalkState = AcpiDsCreateWalkState (0, Op, NULL, NULL);
    362     if (!WalkState)
    363     {
    364         return (AE_NO_MEMORY);
    365     }
    366 
    367     Status = AcpiDsInitAmlWalk (WalkState, Op, NULL,
    368         ObjDesc->Method.AmlStart,
    369         ObjDesc->Method.AmlLength, NULL, ACPI_IMODE_LOAD_PASS1);
    370     if (ACPI_FAILURE (Status))
    371     {
    372         return (Status);
    373     }
    374 
    375     Status = AcpiUtAllocateOwnerId (&ObjDesc->Method.OwnerId);
    376     WalkState->OwnerId = ObjDesc->Method.OwnerId;
    377 
    378     /* Push start scope on scope stack and make it current */
    379 
    380     Status = AcpiDsScopeStackPush (Method,
    381         Method->Type, WalkState);
    382     if (ACPI_FAILURE (Status))
    383     {
    384         return (Status);
    385     }
    386 
    387     /* Parse the entire method AML including deferred operators */
    388 
    389     WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE;
    390     WalkState->ParseFlags |= ACPI_PARSE_DISASSEMBLE;
    391 
    392     Status = AcpiPsParseAml (WalkState);
    393     (void) AcpiDmParseDeferredOps (Op);
    394 
    395     /* Now we can disassemble the method */
    396 
    397     AcpiGbl_DbOpt_verbose = FALSE;
    398     AcpiDmDisassemble (NULL, Op, 0);
    399     AcpiGbl_DbOpt_verbose = TRUE;
    400 
    401     AcpiPsDeleteParseTree (Op);
    402 
    403     /* Method cleanup */
    404 
    405     AcpiNsDeleteNamespaceSubtree (Method);
    406     AcpiNsDeleteNamespaceByOwner (ObjDesc->Method.OwnerId);
    407     AcpiUtReleaseOwnerId (&ObjDesc->Method.OwnerId);
    408     return (AE_OK);
    409 }
    410 
    411 #endif /* ACPI_DEBUGGER */
    412