Home | History | Annotate | Line # | Download | only in disassembler
dmwalk.c revision 1.1
      1 /*******************************************************************************
      2  *
      3  * Module Name: dmwalk - AML disassembly tree walk
      4  *
      5  ******************************************************************************/
      6 
      7 /******************************************************************************
      8  *
      9  * 1. Copyright Notice
     10  *
     11  * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
     12  * All rights reserved.
     13  *
     14  * 2. License
     15  *
     16  * 2.1. This is your license from Intel Corp. under its intellectual property
     17  * rights.  You may have additional license terms from the party that provided
     18  * you this software, covering your right to use that party's intellectual
     19  * property rights.
     20  *
     21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
     22  * copy of the source code appearing in this file ("Covered Code") an
     23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
     24  * base code distributed originally by Intel ("Original Intel Code") to copy,
     25  * make derivatives, distribute, use and display any portion of the Covered
     26  * Code in any form, with the right to sublicense such rights; and
     27  *
     28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
     29  * license (with the right to sublicense), under only those claims of Intel
     30  * patents that are infringed by the Original Intel Code, to make, use, sell,
     31  * offer to sell, and import the Covered Code and derivative works thereof
     32  * solely to the minimum extent necessary to exercise the above copyright
     33  * license, and in no event shall the patent license extend to any additions
     34  * to or modifications of the Original Intel Code.  No other license or right
     35  * is granted directly or by implication, estoppel or otherwise;
     36  *
     37  * The above copyright and patent license is granted only if the following
     38  * conditions are met:
     39  *
     40  * 3. Conditions
     41  *
     42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
     43  * Redistribution of source code of any substantial portion of the Covered
     44  * Code or modification with rights to further distribute source must include
     45  * the above Copyright Notice, the above License, this list of Conditions,
     46  * and the following Disclaimer and Export Compliance provision.  In addition,
     47  * Licensee must cause all Covered Code to which Licensee contributes to
     48  * contain a file documenting the changes Licensee made to create that Covered
     49  * Code and the date of any change.  Licensee must include in that file the
     50  * documentation of any changes made by any predecessor Licensee.  Licensee
     51  * must include a prominent statement that the modification is derived,
     52  * directly or indirectly, from Original Intel Code.
     53  *
     54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
     55  * Redistribution of source code of any substantial portion of the Covered
     56  * Code or modification without rights to further distribute source must
     57  * include the following Disclaimer and Export Compliance provision in the
     58  * documentation and/or other materials provided with distribution.  In
     59  * addition, Licensee may not authorize further sublicense of source of any
     60  * portion of the Covered Code, and must include terms to the effect that the
     61  * license from Licensee to its licensee is limited to the intellectual
     62  * property embodied in the software Licensee provides to its licensee, and
     63  * not to intellectual property embodied in modifications its licensee may
     64  * make.
     65  *
     66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
     67  * substantial portion of the Covered Code or modification must reproduce the
     68  * above Copyright Notice, and the following Disclaimer and Export Compliance
     69  * provision in the documentation and/or other materials provided with the
     70  * distribution.
     71  *
     72  * 3.4. Intel retains all right, title, and interest in and to the Original
     73  * Intel Code.
     74  *
     75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
     76  * Intel shall be used in advertising or otherwise to promote the sale, use or
     77  * other dealings in products derived from or relating to the Covered Code
     78  * without prior written authorization from Intel.
     79  *
     80  * 4. Disclaimer and Export Compliance
     81  *
     82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
     83  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
     84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
     85  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
     86  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
     87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
     88  * PARTICULAR PURPOSE.
     89  *
     90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
     91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
     92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
     93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
     94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
     95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
     96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
     97  * LIMITED REMEDY.
     98  *
     99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
    100  * software or system incorporating such software without first obtaining any
    101  * required license or other approval from the U. S. Department of Commerce or
    102  * any other agency or department of the United States Government.  In the
    103  * event Licensee exports any such software from the United States or
    104  * re-exports any such software from a foreign destination, Licensee shall
    105  * ensure that the distribution and export/re-export of the software is in
    106  * compliance with all laws, regulations, orders, or other restrictions of the
    107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
    108  * any of its subsidiaries will export/re-export any technical data, process,
    109  * software, or service, directly or indirectly, to any country for which the
    110  * United States government or any agency thereof requires an export license,
    111  * other governmental approval, or letter of assurance, without first obtaining
    112  * such license, approval or letter.
    113  *
    114  *****************************************************************************/
    115 
    116 
    117 #include "acpi.h"
    118 #include "accommon.h"
    119 #include "acparser.h"
    120 #include "amlcode.h"
    121 #include "acdisasm.h"
    122 #include "acdebug.h"
    123 
    124 
    125 #ifdef ACPI_DISASSEMBLER
    126 
    127 #define _COMPONENT          ACPI_CA_DEBUGGER
    128         ACPI_MODULE_NAME    ("dmwalk")
    129 
    130 
    131 #define DB_FULL_OP_INFO     "[%4.4s] @%5.5X #%4.4X:  "
    132 
    133 /* Stub for non-compiler code */
    134 
    135 #ifndef ACPI_ASL_COMPILER
    136 void
    137 AcpiDmEmitExternals (
    138     void)
    139 {
    140     return;
    141 }
    142 #endif
    143 
    144 /* Local prototypes */
    145 
    146 static ACPI_STATUS
    147 AcpiDmDescendingOp (
    148     ACPI_PARSE_OBJECT       *Op,
    149     UINT32                  Level,
    150     void                    *Context);
    151 
    152 static ACPI_STATUS
    153 AcpiDmAscendingOp (
    154     ACPI_PARSE_OBJECT       *Op,
    155     UINT32                  Level,
    156     void                    *Context);
    157 
    158 static UINT32
    159 AcpiDmBlockType (
    160     ACPI_PARSE_OBJECT       *Op);
    161 
    162 
    163 /*******************************************************************************
    164  *
    165  * FUNCTION:    AcpiDmDisassemble
    166  *
    167  * PARAMETERS:  WalkState       - Current state
    168  *              Origin          - Starting object
    169  *              NumOpcodes      - Max number of opcodes to be displayed
    170  *
    171  * RETURN:      None
    172  *
    173  * DESCRIPTION: Disassemble parser object and its children.  This is the
    174  *              main entry point of the disassembler.
    175  *
    176  ******************************************************************************/
    177 
    178 void
    179 AcpiDmDisassemble (
    180     ACPI_WALK_STATE         *WalkState,
    181     ACPI_PARSE_OBJECT       *Origin,
    182     UINT32                  NumOpcodes)
    183 {
    184     ACPI_PARSE_OBJECT       *Op = Origin;
    185     ACPI_OP_WALK_INFO       Info;
    186 
    187 
    188     if (!Op)
    189     {
    190         return;
    191     }
    192 
    193     Info.Flags = 0;
    194     Info.Level = 0;
    195     Info.Count = 0;
    196     Info.WalkState = WalkState;
    197     AcpiDmWalkParseTree (Op, AcpiDmDescendingOp, AcpiDmAscendingOp, &Info);
    198     return;
    199 }
    200 
    201 
    202 /*******************************************************************************
    203  *
    204  * FUNCTION:    AcpiDmWalkParseTree
    205  *
    206  * PARAMETERS:  Op                      - Root Op object
    207  *              DescendingCallback      - Called during tree descent
    208  *              AscendingCallback       - Called during tree ascent
    209  *              Context                 - To be passed to the callbacks
    210  *
    211  * RETURN:      Status from callback(s)
    212  *
    213  * DESCRIPTION: Walk the entire parse tree.
    214  *
    215  ******************************************************************************/
    216 
    217 void
    218 AcpiDmWalkParseTree (
    219     ACPI_PARSE_OBJECT       *Op,
    220     ASL_WALK_CALLBACK       DescendingCallback,
    221     ASL_WALK_CALLBACK       AscendingCallback,
    222     void                    *Context)
    223 {
    224     BOOLEAN                 NodePreviouslyVisited;
    225     ACPI_PARSE_OBJECT       *StartOp = Op;
    226     ACPI_STATUS             Status;
    227     ACPI_PARSE_OBJECT       *Next;
    228     ACPI_OP_WALK_INFO       *Info = Context;
    229 
    230 
    231     Info->Level = 0;
    232     NodePreviouslyVisited = FALSE;
    233 
    234     while (Op)
    235     {
    236         if (NodePreviouslyVisited)
    237         {
    238             if (AscendingCallback)
    239             {
    240                 Status = AscendingCallback (Op, Info->Level, Context);
    241                 if (ACPI_FAILURE (Status))
    242                 {
    243                     return;
    244                 }
    245             }
    246         }
    247         else
    248         {
    249             /* Let the callback process the node */
    250 
    251             Status = DescendingCallback (Op, Info->Level, Context);
    252             if (ACPI_SUCCESS (Status))
    253             {
    254                 /* Visit children first, once */
    255 
    256                 Next = AcpiPsGetArg (Op, 0);
    257                 if (Next)
    258                 {
    259                     Info->Level++;
    260                     Op = Next;
    261                     continue;
    262                 }
    263             }
    264             else if (Status != AE_CTRL_DEPTH)
    265             {
    266                 /* Exit immediately on any error */
    267 
    268                 return;
    269             }
    270         }
    271 
    272         /* Terminate walk at start op */
    273 
    274         if (Op == StartOp)
    275         {
    276             break;
    277         }
    278 
    279         /* No more children, re-visit this node */
    280 
    281         if (!NodePreviouslyVisited)
    282         {
    283             NodePreviouslyVisited = TRUE;
    284             continue;
    285         }
    286 
    287         /* No more children, visit peers */
    288 
    289         if (Op->Common.Next)
    290         {
    291             Op = Op->Common.Next;
    292             NodePreviouslyVisited = FALSE;
    293         }
    294         else
    295         {
    296             /* No peers, re-visit parent */
    297 
    298             if (Info->Level != 0 )
    299             {
    300                 Info->Level--;
    301             }
    302 
    303             Op = Op->Common.Parent;
    304             NodePreviouslyVisited = TRUE;
    305         }
    306     }
    307 
    308     /* If we get here, the walk completed with no errors */
    309 
    310     return;
    311 }
    312 
    313 
    314 /*******************************************************************************
    315  *
    316  * FUNCTION:    AcpiDmBlockType
    317  *
    318  * PARAMETERS:  Op              - Object to be examined
    319  *
    320  * RETURN:      BlockType - not a block, parens, braces, or even both.
    321  *
    322  * DESCRIPTION: Type of block for this op (parens or braces)
    323  *
    324  ******************************************************************************/
    325 
    326 static UINT32
    327 AcpiDmBlockType (
    328     ACPI_PARSE_OBJECT       *Op)
    329 {
    330     const ACPI_OPCODE_INFO  *OpInfo;
    331 
    332 
    333     if (!Op)
    334     {
    335         return (BLOCK_NONE);
    336     }
    337 
    338     switch (Op->Common.AmlOpcode)
    339     {
    340     case AML_ELSE_OP:
    341 
    342         return (BLOCK_BRACE);
    343 
    344     case AML_METHOD_OP:
    345     case AML_DEVICE_OP:
    346     case AML_SCOPE_OP:
    347     case AML_PROCESSOR_OP:
    348     case AML_POWER_RES_OP:
    349     case AML_THERMAL_ZONE_OP:
    350     case AML_IF_OP:
    351     case AML_WHILE_OP:
    352     case AML_FIELD_OP:
    353     case AML_INDEX_FIELD_OP:
    354     case AML_BANK_FIELD_OP:
    355 
    356         return (BLOCK_PAREN | BLOCK_BRACE);
    357 
    358     case AML_BUFFER_OP:
    359 
    360         if (Op->Common.DisasmOpcode == ACPI_DASM_UNICODE)
    361         {
    362             return (BLOCK_NONE);
    363         }
    364 
    365         /*lint -fallthrough */
    366 
    367     case AML_PACKAGE_OP:
    368     case AML_VAR_PACKAGE_OP:
    369 
    370         return (BLOCK_PAREN | BLOCK_BRACE);
    371 
    372     case AML_EVENT_OP:
    373 
    374         return (BLOCK_PAREN);
    375 
    376     default:
    377 
    378         OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
    379         if (OpInfo->Flags & AML_HAS_ARGS)
    380         {
    381             return (BLOCK_PAREN);
    382         }
    383 
    384         return (BLOCK_NONE);
    385     }
    386 }
    387 
    388 
    389 /*******************************************************************************
    390  *
    391  * FUNCTION:    AcpiDmListType
    392  *
    393  * PARAMETERS:  Op              - Object to be examined
    394  *
    395  * RETURN:      ListType - has commas or not.
    396  *
    397  * DESCRIPTION: Type of block for this op (parens or braces)
    398  *
    399  ******************************************************************************/
    400 
    401 UINT32
    402 AcpiDmListType (
    403     ACPI_PARSE_OBJECT       *Op)
    404 {
    405     const ACPI_OPCODE_INFO  *OpInfo;
    406 
    407 
    408     if (!Op)
    409     {
    410         return (BLOCK_NONE);
    411     }
    412 
    413     switch (Op->Common.AmlOpcode)
    414     {
    415 
    416     case AML_ELSE_OP:
    417     case AML_METHOD_OP:
    418     case AML_DEVICE_OP:
    419     case AML_SCOPE_OP:
    420     case AML_POWER_RES_OP:
    421     case AML_PROCESSOR_OP:
    422     case AML_THERMAL_ZONE_OP:
    423     case AML_IF_OP:
    424     case AML_WHILE_OP:
    425     case AML_FIELD_OP:
    426     case AML_INDEX_FIELD_OP:
    427     case AML_BANK_FIELD_OP:
    428 
    429         return (BLOCK_NONE);
    430 
    431     case AML_BUFFER_OP:
    432     case AML_PACKAGE_OP:
    433     case AML_VAR_PACKAGE_OP:
    434 
    435         return (BLOCK_COMMA_LIST);
    436 
    437     default:
    438 
    439         OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
    440         if (OpInfo->Flags & AML_HAS_ARGS)
    441         {
    442             return (BLOCK_COMMA_LIST);
    443         }
    444 
    445         return (BLOCK_NONE);
    446     }
    447 }
    448 
    449 
    450 /*******************************************************************************
    451  *
    452  * FUNCTION:    AcpiDmDescendingOp
    453  *
    454  * PARAMETERS:  ASL_WALK_CALLBACK
    455  *
    456  * RETURN:      Status
    457  *
    458  * DESCRIPTION: First visitation of a parse object during tree descent.
    459  *              Decode opcode name and begin parameter list(s), if any.
    460  *
    461  ******************************************************************************/
    462 
    463 static ACPI_STATUS
    464 AcpiDmDescendingOp (
    465     ACPI_PARSE_OBJECT       *Op,
    466     UINT32                  Level,
    467     void                    *Context)
    468 {
    469     ACPI_OP_WALK_INFO       *Info = Context;
    470     const ACPI_OPCODE_INFO  *OpInfo;
    471     UINT32                  Name;
    472     ACPI_PARSE_OBJECT       *NextOp;
    473 
    474 
    475     if (Op->Common.DisasmFlags & ACPI_PARSEOP_IGNORE)
    476     {
    477         /* Ignore this op -- it was handled elsewhere */
    478 
    479         return (AE_CTRL_DEPTH);
    480     }
    481 
    482     /* Level 0 is at the Definition Block level */
    483 
    484     if (Level == 0)
    485     {
    486         /* In verbose mode, print the AML offset, opcode and depth count */
    487 
    488         if (Info->WalkState)
    489         {
    490             VERBOSE_PRINT ((DB_FULL_OP_INFO,
    491                 (Info->WalkState->MethodNode ?
    492                     Info->WalkState->MethodNode->Name.Ascii : "   "),
    493                 Op->Common.AmlOffset, (UINT32) Op->Common.AmlOpcode));
    494         }
    495 
    496         if (Op->Common.AmlOpcode == AML_SCOPE_OP)
    497         {
    498             /* This is the beginning of the Definition Block */
    499 
    500             AcpiOsPrintf ("{\n");
    501 
    502             /* Emit all External() declarations here */
    503 
    504             AcpiDmEmitExternals ();
    505             return (AE_OK);
    506         }
    507     }
    508     else if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
    509              (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) &&
    510              (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP))
    511     {
    512             /*
    513              * This is a first-level element of a term list,
    514              * indent a new line
    515              */
    516             AcpiDmIndent (Level);
    517             Info->LastLevel = Level;
    518             Info->Count = 0;
    519     }
    520 
    521     /*
    522      * This is an inexpensive mechanism to try and keep lines from getting
    523      * too long. When the limit is hit, start a new line at the previous
    524      * indent plus one. A better but more expensive mechanism would be to
    525      * keep track of the current column.
    526      */
    527     Info->Count++;
    528     if (Info->Count /*+Info->LastLevel*/ > 10)
    529     {
    530         Info->Count = 0;
    531         AcpiOsPrintf ("\n");
    532         AcpiDmIndent (Info->LastLevel + 1);
    533     }
    534 
    535     /* Print the opcode name */
    536 
    537     AcpiDmDisassembleOneOp (NULL, Info, Op);
    538 
    539     if (Op->Common.DisasmOpcode == ACPI_DASM_LNOT_PREFIX)
    540     {
    541         return (AE_OK);
    542     }
    543 
    544     if ((Op->Common.AmlOpcode == AML_NAME_OP) ||
    545         (Op->Common.AmlOpcode == AML_RETURN_OP))
    546     {
    547         Info->Level--;
    548     }
    549 
    550     /* Start the opcode argument list if necessary */
    551 
    552     OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
    553 
    554     if ((OpInfo->Flags & AML_HAS_ARGS) ||
    555         (Op->Common.AmlOpcode == AML_EVENT_OP))
    556     {
    557         /* This opcode has an argument list */
    558 
    559         if (AcpiDmBlockType (Op) & BLOCK_PAREN)
    560         {
    561             AcpiOsPrintf (" (");
    562         }
    563 
    564         /* If this is a named opcode, print the associated name value */
    565 
    566         if (OpInfo->Flags & AML_NAMED)
    567         {
    568             switch (Op->Common.AmlOpcode)
    569             {
    570             case AML_ALIAS_OP:
    571 
    572                 NextOp = AcpiPsGetDepthNext (NULL, Op);
    573                 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
    574                 AcpiDmNamestring (NextOp->Common.Value.Name);
    575                 AcpiOsPrintf (", ");
    576 
    577                 /*lint -fallthrough */
    578 
    579             default:
    580 
    581                 Name = AcpiPsGetName (Op);
    582                 if (Op->Named.Path)
    583                 {
    584                     AcpiDmNamestring ((char *) Op->Named.Path);
    585                 }
    586                 else
    587                 {
    588                     AcpiDmDumpName (Name);
    589                 }
    590 
    591                 if (Op->Common.AmlOpcode != AML_INT_NAMEDFIELD_OP)
    592                 {
    593                     if (AcpiGbl_DbOpt_verbose)
    594                     {
    595                         (void) AcpiPsDisplayObjectPathname (NULL, Op);
    596                     }
    597                 }
    598                 break;
    599             }
    600 
    601             switch (Op->Common.AmlOpcode)
    602             {
    603             case AML_METHOD_OP:
    604 
    605                 AcpiDmMethodFlags (Op);
    606                 AcpiOsPrintf (")");
    607                 break;
    608 
    609 
    610             case AML_NAME_OP:
    611 
    612                 /* Check for _HID and related EISAID() */
    613 
    614                 AcpiDmIsEisaId (Op);
    615                 AcpiOsPrintf (", ");
    616                 break;
    617 
    618 
    619             case AML_REGION_OP:
    620 
    621                 AcpiDmRegionFlags (Op);
    622                 break;
    623 
    624 
    625             case AML_POWER_RES_OP:
    626 
    627                 /* Mark the next two Ops as part of the parameter list */
    628 
    629                 AcpiOsPrintf (", ");
    630                 NextOp = AcpiPsGetDepthNext (NULL, Op);
    631                 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
    632 
    633                 NextOp = NextOp->Common.Next;
    634                 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
    635                 return (AE_OK);
    636 
    637 
    638             case AML_PROCESSOR_OP:
    639 
    640                 /* Mark the next three Ops as part of the parameter list */
    641 
    642                 AcpiOsPrintf (", ");
    643                 NextOp = AcpiPsGetDepthNext (NULL, Op);
    644                 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
    645 
    646                 NextOp = NextOp->Common.Next;
    647                 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
    648 
    649                 NextOp = NextOp->Common.Next;
    650                 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
    651                 return (AE_OK);
    652 
    653 
    654             case AML_MUTEX_OP:
    655             case AML_DATA_REGION_OP:
    656 
    657                 AcpiOsPrintf (", ");
    658                 return (AE_OK);
    659 
    660 
    661             case AML_EVENT_OP:
    662             case AML_ALIAS_OP:
    663 
    664                 return (AE_OK);
    665 
    666 
    667             case AML_SCOPE_OP:
    668             case AML_DEVICE_OP:
    669             case AML_THERMAL_ZONE_OP:
    670 
    671                 AcpiOsPrintf (")");
    672                 break;
    673 
    674 
    675             default:
    676 
    677                 AcpiOsPrintf ("*** Unhandled named opcode %X\n", Op->Common.AmlOpcode);
    678                 break;
    679             }
    680         }
    681 
    682         else switch (Op->Common.AmlOpcode)
    683         {
    684         case AML_FIELD_OP:
    685         case AML_BANK_FIELD_OP:
    686         case AML_INDEX_FIELD_OP:
    687 
    688             Info->BitOffset = 0;
    689 
    690             /* Name of the parent OperationRegion */
    691 
    692             NextOp = AcpiPsGetDepthNext (NULL, Op);
    693             AcpiDmNamestring (NextOp->Common.Value.Name);
    694             AcpiOsPrintf (", ");
    695             NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
    696 
    697             switch (Op->Common.AmlOpcode)
    698             {
    699             case AML_BANK_FIELD_OP:
    700 
    701                 /* Namestring - Bank Name */
    702 
    703                 NextOp = AcpiPsGetDepthNext (NULL, NextOp);
    704                 AcpiDmNamestring (NextOp->Common.Value.Name);
    705                 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
    706                 AcpiOsPrintf (", ");
    707 
    708                 /*
    709                  * Bank Value. This is a TermArg in the middle of the parameter
    710                  * list, must handle it here.
    711                  *
    712                  * Disassemble the TermArg parse tree. ACPI_PARSEOP_PARAMLIST
    713                  * eliminates newline in the output.
    714                  */
    715                 NextOp = NextOp->Common.Next;
    716 
    717                 Info->Flags = ACPI_PARSEOP_PARAMLIST;
    718                 AcpiDmWalkParseTree (NextOp, AcpiDmDescendingOp, AcpiDmAscendingOp, Info);
    719                 Info->Flags = 0;
    720                 Info->Level = Level;
    721 
    722                 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
    723                 AcpiOsPrintf (", ");
    724                 break;
    725 
    726             case AML_INDEX_FIELD_OP:
    727 
    728                 /* Namestring - Data Name */
    729 
    730                 NextOp = AcpiPsGetDepthNext (NULL, NextOp);
    731                 AcpiDmNamestring (NextOp->Common.Value.Name);
    732                 AcpiOsPrintf (", ");
    733                 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
    734                 break;
    735 
    736             default:
    737 
    738                 break;
    739             }
    740 
    741             AcpiDmFieldFlags (NextOp);
    742             break;
    743 
    744 
    745         case AML_BUFFER_OP:
    746 
    747             /* The next op is the size parameter */
    748 
    749             NextOp = AcpiPsGetDepthNext (NULL, Op);
    750             if (!NextOp)
    751             {
    752                 /* Single-step support */
    753 
    754                 return (AE_OK);
    755             }
    756 
    757             if (Op->Common.DisasmOpcode == ACPI_DASM_RESOURCE)
    758             {
    759                 /*
    760                  * We have a resource list.  Don't need to output
    761                  * the buffer size Op.  Open up a new block
    762                  */
    763                 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
    764                 NextOp = NextOp->Common.Next;
    765                 AcpiOsPrintf (")\n");
    766                 AcpiDmIndent (Info->Level);
    767                 AcpiOsPrintf ("{\n");
    768                 return (AE_OK);
    769             }
    770 
    771             /* Normal Buffer, mark size as in the parameter list */
    772 
    773             NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
    774             return (AE_OK);
    775 
    776 
    777         case AML_VAR_PACKAGE_OP:
    778         case AML_IF_OP:
    779         case AML_WHILE_OP:
    780 
    781             /* The next op is the size or predicate parameter */
    782 
    783             NextOp = AcpiPsGetDepthNext (NULL, Op);
    784             if (NextOp)
    785             {
    786                 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
    787             }
    788             return (AE_OK);
    789 
    790 
    791         case AML_PACKAGE_OP:
    792 
    793             /* The next op is the size or predicate parameter */
    794 
    795             NextOp = AcpiPsGetDepthNext (NULL, Op);
    796             if (NextOp)
    797             {
    798                 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
    799             }
    800             return (AE_OK);
    801 
    802 
    803         case AML_MATCH_OP:
    804 
    805             AcpiDmMatchOp (Op);
    806             break;
    807 
    808 
    809         default:
    810 
    811             break;
    812         }
    813 
    814         if (AcpiDmBlockType (Op) & BLOCK_BRACE)
    815         {
    816             AcpiOsPrintf ("\n");
    817             AcpiDmIndent (Level);
    818             AcpiOsPrintf ("{\n");
    819         }
    820     }
    821 
    822     return (AE_OK);
    823 }
    824 
    825 
    826 /*******************************************************************************
    827  *
    828  * FUNCTION:    AcpiDmAscendingOp
    829  *
    830  * PARAMETERS:  ASL_WALK_CALLBACK
    831  *
    832  * RETURN:      Status
    833  *
    834  * DESCRIPTION: Second visitation of a parse object, during ascent of parse
    835  *              tree.  Close out any parameter lists and complete the opcode.
    836  *
    837  ******************************************************************************/
    838 
    839 static ACPI_STATUS
    840 AcpiDmAscendingOp (
    841     ACPI_PARSE_OBJECT       *Op,
    842     UINT32                  Level,
    843     void                    *Context)
    844 {
    845     ACPI_OP_WALK_INFO       *Info = Context;
    846 
    847 
    848     if (Op->Common.DisasmFlags & ACPI_PARSEOP_IGNORE)
    849     {
    850         /* Ignore this op -- it was handled elsewhere */
    851 
    852         return (AE_OK);
    853     }
    854 
    855     if ((Level == 0) && (Op->Common.AmlOpcode == AML_SCOPE_OP))
    856     {
    857         /* Indicates the end of the current descriptor block (table) */
    858 
    859         AcpiOsPrintf ("}\n\n");
    860         return (AE_OK);
    861     }
    862 
    863     switch (AcpiDmBlockType (Op))
    864     {
    865     case BLOCK_PAREN:
    866 
    867         /* Completed an op that has arguments, add closing paren */
    868 
    869         AcpiOsPrintf (")");
    870 
    871         /* Could be a nested operator, check if comma required */
    872 
    873         if (!AcpiDmCommaIfListMember (Op))
    874         {
    875             if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
    876                      (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) &&
    877                      (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP))
    878             {
    879                 /*
    880                  * This is a first-level element of a term list
    881                  * start a new line
    882                  */
    883                 if (!(Info->Flags & ACPI_PARSEOP_PARAMLIST))
    884                 {
    885                     AcpiOsPrintf ("\n");
    886                 }
    887             }
    888         }
    889         break;
    890 
    891 
    892     case BLOCK_BRACE:
    893     case (BLOCK_BRACE | BLOCK_PAREN):
    894 
    895         /* Completed an op that has a term list, add closing brace */
    896 
    897         if (Op->Common.DisasmFlags & ACPI_PARSEOP_EMPTY_TERMLIST)
    898         {
    899             AcpiOsPrintf ("}");
    900         }
    901         else
    902         {
    903             AcpiDmIndent (Level);
    904             AcpiOsPrintf ("}");
    905         }
    906 
    907         AcpiDmCommaIfListMember (Op);
    908 
    909         if (AcpiDmBlockType (Op->Common.Parent) != BLOCK_PAREN)
    910         {
    911             AcpiOsPrintf ("\n");
    912             if (!(Op->Common.DisasmFlags & ACPI_PARSEOP_EMPTY_TERMLIST))
    913             {
    914                 if ((Op->Common.AmlOpcode == AML_IF_OP)  &&
    915                     (Op->Common.Next) &&
    916                     (Op->Common.Next->Common.AmlOpcode == AML_ELSE_OP))
    917                 {
    918                     break;
    919                 }
    920 
    921                 if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
    922                     (!Op->Common.Next))
    923                 {
    924                     break;
    925                 }
    926                 AcpiOsPrintf ("\n");
    927             }
    928         }
    929         break;
    930 
    931 
    932     case BLOCK_NONE:
    933     default:
    934 
    935         /* Could be a nested operator, check if comma required */
    936 
    937         if (!AcpiDmCommaIfListMember (Op))
    938         {
    939             if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
    940                      (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) &&
    941                      (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP))
    942             {
    943                 /*
    944                  * This is a first-level element of a term list
    945                  * start a new line
    946                  */
    947                 AcpiOsPrintf ("\n");
    948             }
    949         }
    950         else if (Op->Common.Parent)
    951         {
    952             switch (Op->Common.Parent->Common.AmlOpcode)
    953             {
    954             case AML_PACKAGE_OP:
    955             case AML_VAR_PACKAGE_OP:
    956 
    957                 if (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST))
    958                 {
    959                     AcpiOsPrintf ("\n");
    960                 }
    961                 break;
    962 
    963             default:
    964 
    965                 break;
    966             }
    967         }
    968         break;
    969     }
    970 
    971     if (Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)
    972     {
    973         if ((Op->Common.Next) &&
    974             (Op->Common.Next->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST))
    975         {
    976             return (AE_OK);
    977         }
    978 
    979         /*
    980          * Just completed a parameter node for something like "Buffer (param)".
    981          * Close the paren and open up the term list block with a brace
    982          */
    983         if (Op->Common.Next)
    984         {
    985             AcpiOsPrintf (")\n");
    986             AcpiDmIndent (Level - 1);
    987             AcpiOsPrintf ("{\n");
    988         }
    989         else
    990         {
    991             Op->Common.Parent->Common.DisasmFlags |=
    992                                     ACPI_PARSEOP_EMPTY_TERMLIST;
    993             AcpiOsPrintf (") {");
    994         }
    995     }
    996 
    997     if ((Op->Common.AmlOpcode == AML_NAME_OP) ||
    998         (Op->Common.AmlOpcode == AML_RETURN_OP))
    999     {
   1000         Info->Level++;
   1001     }
   1002     return (AE_OK);
   1003 }
   1004 
   1005 
   1006 #endif  /* ACPI_DISASSEMBLER */
   1007