dmwalk.c revision 138287
10Sstevel@tonic-gate/*******************************************************************************
20Sstevel@tonic-gate *
30Sstevel@tonic-gate * Module Name: dmwalk - AML disassembly tree walk
40Sstevel@tonic-gate *              $Revision: 14 $
50Sstevel@tonic-gate *
60Sstevel@tonic-gate ******************************************************************************/
70Sstevel@tonic-gate
80Sstevel@tonic-gate/******************************************************************************
90Sstevel@tonic-gate *
100Sstevel@tonic-gate * 1. Copyright Notice
110Sstevel@tonic-gate *
120Sstevel@tonic-gate * Some or all of this work - Copyright (c) 1999 - 2004, Intel Corp.
130Sstevel@tonic-gate * All rights reserved.
140Sstevel@tonic-gate *
150Sstevel@tonic-gate * 2. License
160Sstevel@tonic-gate *
170Sstevel@tonic-gate * 2.1. This is your license from Intel Corp. under its intellectual property
180Sstevel@tonic-gate * rights.  You may have additional license terms from the party that provided
190Sstevel@tonic-gate * you this software, covering your right to use that party's intellectual
200Sstevel@tonic-gate * property rights.
210Sstevel@tonic-gate *
220Sstevel@tonic-gate * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
230Sstevel@tonic-gate * copy of the source code appearing in this file ("Covered Code") an
240Sstevel@tonic-gate * irrevocable, perpetual, worldwide license under Intel's copyrights in the
250Sstevel@tonic-gate * base code distributed originally by Intel ("Original Intel Code") to copy,
260Sstevel@tonic-gate * make derivatives, distribute, use and display any portion of the Covered
270Sstevel@tonic-gate * Code in any form, with the right to sublicense such rights; and
280Sstevel@tonic-gate *
290Sstevel@tonic-gate * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
300Sstevel@tonic-gate * license (with the right to sublicense), under only those claims of Intel
310Sstevel@tonic-gate * patents that are infringed by the Original Intel Code, to make, use, sell,
320Sstevel@tonic-gate * offer to sell, and import the Covered Code and derivative works thereof
330Sstevel@tonic-gate * solely to the minimum extent necessary to exercise the above copyright
340Sstevel@tonic-gate * license, and in no event shall the patent license extend to any additions
350Sstevel@tonic-gate * to or modifications of the Original Intel Code.  No other license or right
360Sstevel@tonic-gate * is granted directly or by implication, estoppel or otherwise;
370Sstevel@tonic-gate *
380Sstevel@tonic-gate * The above copyright and patent license is granted only if the following
390Sstevel@tonic-gate * conditions are met:
400Sstevel@tonic-gate *
410Sstevel@tonic-gate * 3. Conditions
420Sstevel@tonic-gate *
430Sstevel@tonic-gate * 3.1. Redistribution of Source with Rights to Further Distribute Source.
440Sstevel@tonic-gate * Redistribution of source code of any substantial portion of the Covered
450Sstevel@tonic-gate * Code or modification with rights to further distribute source must include
460Sstevel@tonic-gate * the above Copyright Notice, the above License, this list of Conditions,
470Sstevel@tonic-gate * and the following Disclaimer and Export Compliance provision.  In addition,
480Sstevel@tonic-gate * Licensee must cause all Covered Code to which Licensee contributes to
490Sstevel@tonic-gate * contain a file documenting the changes Licensee made to create that Covered
500Sstevel@tonic-gate * Code and the date of any change.  Licensee must include in that file the
510Sstevel@tonic-gate * documentation of any changes made by any predecessor Licensee.  Licensee
520Sstevel@tonic-gate * must include a prominent statement that the modification is derived,
530Sstevel@tonic-gate * directly or indirectly, from Original Intel Code.
540Sstevel@tonic-gate *
550Sstevel@tonic-gate * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
560Sstevel@tonic-gate * Redistribution of source code of any substantial portion of the Covered
570Sstevel@tonic-gate * Code or modification without rights to further distribute source must
580Sstevel@tonic-gate * include the following Disclaimer and Export Compliance provision in the
590Sstevel@tonic-gate * documentation and/or other materials provided with distribution.  In
600Sstevel@tonic-gate * addition, Licensee may not authorize further sublicense of source of any
610Sstevel@tonic-gate * portion of the Covered Code, and must include terms to the effect that the
620Sstevel@tonic-gate * license from Licensee to its licensee is limited to the intellectual
630Sstevel@tonic-gate * property embodied in the software Licensee provides to its licensee, and
640Sstevel@tonic-gate * not to intellectual property embodied in modifications its licensee may
650Sstevel@tonic-gate * make.
660Sstevel@tonic-gate *
670Sstevel@tonic-gate * 3.3. Redistribution of Executable. Redistribution in executable form of any
680Sstevel@tonic-gate * substantial portion of the Covered Code or modification must reproduce the
690Sstevel@tonic-gate * above Copyright Notice, and the following Disclaimer and Export Compliance
700Sstevel@tonic-gate * provision in the documentation and/or other materials provided with the
710Sstevel@tonic-gate * distribution.
720Sstevel@tonic-gate *
730Sstevel@tonic-gate * 3.4. Intel retains all right, title, and interest in and to the Original
740Sstevel@tonic-gate * Intel Code.
750Sstevel@tonic-gate *
760Sstevel@tonic-gate * 3.5. Neither the name Intel nor any other trademark owned or controlled by
770Sstevel@tonic-gate * Intel shall be used in advertising or otherwise to promote the sale, use or
780Sstevel@tonic-gate * other dealings in products derived from or relating to the Covered Code
790Sstevel@tonic-gate * without prior written authorization from Intel.
800Sstevel@tonic-gate *
810Sstevel@tonic-gate * 4. Disclaimer and Export Compliance
820Sstevel@tonic-gate *
830Sstevel@tonic-gate * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
840Sstevel@tonic-gate * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
850Sstevel@tonic-gate * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
860Sstevel@tonic-gate * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
870Sstevel@tonic-gate * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
880Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
890Sstevel@tonic-gate * PARTICULAR PURPOSE.
900Sstevel@tonic-gate *
910Sstevel@tonic-gate * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
920Sstevel@tonic-gate * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
930Sstevel@tonic-gate * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
940Sstevel@tonic-gate * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
950Sstevel@tonic-gate * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
960Sstevel@tonic-gate * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
970Sstevel@tonic-gate * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
980Sstevel@tonic-gate * LIMITED REMEDY.
990Sstevel@tonic-gate *
1000Sstevel@tonic-gate * 4.3. Licensee shall not export, either directly or indirectly, any of this
1010Sstevel@tonic-gate * software or system incorporating such software without first obtaining any
1020Sstevel@tonic-gate * required license or other approval from the U. S. Department of Commerce or
1030Sstevel@tonic-gate * any other agency or department of the United States Government.  In the
1040Sstevel@tonic-gate * event Licensee exports any such software from the United States or
1050Sstevel@tonic-gate * re-exports any such software from a foreign destination, Licensee shall
1060Sstevel@tonic-gate * ensure that the distribution and export/re-export of the software is in
1070Sstevel@tonic-gate * compliance with all laws, regulations, orders, or other restrictions of the
1080Sstevel@tonic-gate * U.S. Export Administration Regulations. Licensee agrees that neither it nor
1090Sstevel@tonic-gate * any of its subsidiaries will export/re-export any technical data, process,
1100Sstevel@tonic-gate * software, or service, directly or indirectly, to any country for which the
1110Sstevel@tonic-gate * United States government or any agency thereof requires an export license,
1120Sstevel@tonic-gate * other governmental approval, or letter of assurance, without first obtaining
1130Sstevel@tonic-gate * such license, approval or letter.
1140Sstevel@tonic-gate *
1150Sstevel@tonic-gate *****************************************************************************/
1160Sstevel@tonic-gate
1170Sstevel@tonic-gate
1180Sstevel@tonic-gate#include "acpi.h"
1190Sstevel@tonic-gate#include "acparser.h"
1200Sstevel@tonic-gate#include "amlcode.h"
1210Sstevel@tonic-gate#include "acdisasm.h"
1220Sstevel@tonic-gate#include "acdebug.h"
1230Sstevel@tonic-gate
1240Sstevel@tonic-gate
1250Sstevel@tonic-gate#ifdef ACPI_DISASSEMBLER
1260Sstevel@tonic-gate
1270Sstevel@tonic-gate#define _COMPONENT          ACPI_CA_DEBUGGER
1280Sstevel@tonic-gate        ACPI_MODULE_NAME    ("dmwalk")
1290Sstevel@tonic-gate
1300Sstevel@tonic-gate
1310Sstevel@tonic-gate#define DB_FULL_OP_INFO     "%5.5X #%4.4hX "
1320Sstevel@tonic-gate
1330Sstevel@tonic-gate
1340Sstevel@tonic-gate/*******************************************************************************
1350Sstevel@tonic-gate *
1360Sstevel@tonic-gate * FUNCTION:    AcpiDmDisassemble
1370Sstevel@tonic-gate *
1380Sstevel@tonic-gate * PARAMETERS:  Origin          - Starting object
1390Sstevel@tonic-gate *              NumOpcodes      - Max number of opcodes to be displayed
1400Sstevel@tonic-gate *
1410Sstevel@tonic-gate * RETURN:      None
1420Sstevel@tonic-gate *
1430Sstevel@tonic-gate * DESCRIPTION: Disassemble parser object and its children.  This is the
1440Sstevel@tonic-gate *              main entry point of the disassembler.
1450Sstevel@tonic-gate *
1460Sstevel@tonic-gate ******************************************************************************/
1470Sstevel@tonic-gate
1480Sstevel@tonic-gatevoid
1490Sstevel@tonic-gateAcpiDmDisassemble (
1500Sstevel@tonic-gate    ACPI_WALK_STATE         *WalkState,
1510Sstevel@tonic-gate    ACPI_PARSE_OBJECT       *Origin,
1520Sstevel@tonic-gate    UINT32                  NumOpcodes)
1530Sstevel@tonic-gate{
1540Sstevel@tonic-gate    ACPI_PARSE_OBJECT       *Op = Origin;
1550Sstevel@tonic-gate    ACPI_OP_WALK_INFO       Info;
1560Sstevel@tonic-gate
1570Sstevel@tonic-gate
1580Sstevel@tonic-gate    if (!Op)
1590Sstevel@tonic-gate    {
1600Sstevel@tonic-gate        return;
1610Sstevel@tonic-gate    }
1620Sstevel@tonic-gate
1630Sstevel@tonic-gate    Info.Level = 0;
1640Sstevel@tonic-gate    AcpiDmWalkParseTree (Op, AcpiDmDescendingOp, AcpiDmAscendingOp, &Info);
1650Sstevel@tonic-gate
1660Sstevel@tonic-gate    return;
1670Sstevel@tonic-gate}
1680Sstevel@tonic-gate
1690Sstevel@tonic-gate
1700Sstevel@tonic-gate/*******************************************************************************
1710Sstevel@tonic-gate *
1720Sstevel@tonic-gate * FUNCTION:    AcpiDmWalkParseTree
1730Sstevel@tonic-gate *
1740Sstevel@tonic-gate * PARAMETERS:  DescendingCallback      - Called during tree descent
1750Sstevel@tonic-gate *              AscendingCallback       - Called during tree ascent
1760Sstevel@tonic-gate *              Context                 - To be passed to the callbacks
1770Sstevel@tonic-gate *
1780Sstevel@tonic-gate * RETURN:      Status from callback(s)
1790Sstevel@tonic-gate *
1800Sstevel@tonic-gate * DESCRIPTION: Walk the entire parse tree.
1810Sstevel@tonic-gate *
1820Sstevel@tonic-gate ******************************************************************************/
1830Sstevel@tonic-gate
1840Sstevel@tonic-gatevoid
1850Sstevel@tonic-gateAcpiDmWalkParseTree (
1860Sstevel@tonic-gate    ACPI_PARSE_OBJECT       *Op,
1870Sstevel@tonic-gate    ASL_WALK_CALLBACK       DescendingCallback,
1880Sstevel@tonic-gate    ASL_WALK_CALLBACK       AscendingCallback,
1890Sstevel@tonic-gate    void                    *Context)
1900Sstevel@tonic-gate{
1910Sstevel@tonic-gate    BOOLEAN                 NodePreviouslyVisited;
1920Sstevel@tonic-gate    ACPI_PARSE_OBJECT       *StartOp = Op;
1930Sstevel@tonic-gate    ACPI_STATUS             Status;
1940Sstevel@tonic-gate    ACPI_PARSE_OBJECT       *Next;
1950Sstevel@tonic-gate    ACPI_OP_WALK_INFO       *Info = Context;
1960Sstevel@tonic-gate
1970Sstevel@tonic-gate
1980Sstevel@tonic-gate    Info->Level = 0;
1990Sstevel@tonic-gate    NodePreviouslyVisited = FALSE;
2000Sstevel@tonic-gate
2010Sstevel@tonic-gate    while (Op)
2020Sstevel@tonic-gate    {
2030Sstevel@tonic-gate        if (NodePreviouslyVisited)
2040Sstevel@tonic-gate        {
2050Sstevel@tonic-gate            Status = AscendingCallback (Op, Info->Level, Context);
2060Sstevel@tonic-gate            if (ACPI_FAILURE (Status))
2070Sstevel@tonic-gate            {
2080Sstevel@tonic-gate                return;
2090Sstevel@tonic-gate            }
2100Sstevel@tonic-gate        }
2110Sstevel@tonic-gate        else
2120Sstevel@tonic-gate        {
2130Sstevel@tonic-gate            /* Let the callback process the node */
214
215            Status = DescendingCallback (Op, Info->Level, Context);
216            if (ACPI_SUCCESS (Status))
217            {
218                /* Visit children first, once */
219
220                Next = AcpiPsGetArg (Op, 0);
221                if (Next)
222                {
223                    Info->Level++;
224                    Op = Next;
225                    continue;
226                }
227            }
228            else if (Status != AE_CTRL_DEPTH)
229            {
230                /* Exit immediately on any error */
231
232                return;
233            }
234        }
235
236        /* Terminate walk at start op */
237
238        if (Op == StartOp)
239        {
240            break;
241        }
242
243        /* No more children, re-visit this node */
244
245        if (!NodePreviouslyVisited)
246        {
247            NodePreviouslyVisited = TRUE;
248            continue;
249        }
250
251        /* No more children, visit peers */
252
253        if (Op->Common.Next)
254        {
255            Op = Op->Common.Next;
256            NodePreviouslyVisited = FALSE;
257        }
258        else
259        {
260            /* No peers, re-visit parent */
261
262            if (Info->Level != 0 )
263            {
264                Info->Level--;
265            }
266
267            Op = Op->Common.Parent;
268            NodePreviouslyVisited = TRUE;
269        }
270    }
271
272    /* If we get here, the walk completed with no errors */
273
274    return;
275}
276
277
278/*******************************************************************************
279 *
280 * FUNCTION:    AcpiDmBlockType
281 *
282 * PARAMETERS:  Op              - Object to be examined
283 *
284 * RETURN:      Status
285 *
286 * DESCRIPTION: Type of block for this op (parens or braces)
287 *
288 ******************************************************************************/
289
290UINT32
291AcpiDmBlockType (
292    ACPI_PARSE_OBJECT       *Op)
293{
294    const ACPI_OPCODE_INFO  *OpInfo;
295
296
297    if (!Op)
298    {
299        return (BLOCK_NONE);
300    }
301
302    switch (Op->Common.AmlOpcode)
303    {
304    case AML_ELSE_OP:
305
306        return (BLOCK_BRACE);
307
308    case AML_METHOD_OP:
309    case AML_DEVICE_OP:
310    case AML_SCOPE_OP:
311    case AML_PROCESSOR_OP:
312    case AML_POWER_RES_OP:
313    case AML_THERMAL_ZONE_OP:
314    case AML_IF_OP:
315    case AML_WHILE_OP:
316    case AML_FIELD_OP:
317    case AML_INDEX_FIELD_OP:
318    case AML_BANK_FIELD_OP:
319
320        return (BLOCK_PAREN | BLOCK_BRACE);
321
322    case AML_BUFFER_OP:
323
324        if (Op->Common.DisasmOpcode == ACPI_DASM_UNICODE)
325        {
326            return (BLOCK_NONE);
327        }
328
329        /*lint -fallthrough */
330
331    case AML_PACKAGE_OP:
332    case AML_VAR_PACKAGE_OP:
333
334        return (BLOCK_PAREN | BLOCK_BRACE);
335
336    case AML_EVENT_OP:
337
338        return (BLOCK_PAREN);
339
340    default:
341
342        OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
343        if (OpInfo->Flags & AML_HAS_ARGS)
344        {
345            return (BLOCK_PAREN);
346        }
347
348        return (BLOCK_NONE);
349    }
350}
351
352
353/*******************************************************************************
354 *
355 * FUNCTION:    AcpiDmListType
356 *
357 * PARAMETERS:  Op              - Object to be examined
358 *
359 * RETURN:      Status
360 *
361 * DESCRIPTION: Type of block for this op (parens or braces)
362 *
363 ******************************************************************************/
364
365UINT32
366AcpiDmListType (
367    ACPI_PARSE_OBJECT       *Op)
368{
369    const ACPI_OPCODE_INFO  *OpInfo;
370
371
372    if (!Op)
373    {
374        return (BLOCK_NONE);
375    }
376
377    switch (Op->Common.AmlOpcode)
378    {
379
380    case AML_ELSE_OP:
381    case AML_METHOD_OP:
382    case AML_DEVICE_OP:
383    case AML_SCOPE_OP:
384    case AML_POWER_RES_OP:
385    case AML_PROCESSOR_OP:
386    case AML_THERMAL_ZONE_OP:
387    case AML_IF_OP:
388    case AML_WHILE_OP:
389    case AML_FIELD_OP:
390    case AML_INDEX_FIELD_OP:
391    case AML_BANK_FIELD_OP:
392
393        return (0);
394
395    case AML_BUFFER_OP:
396    case AML_PACKAGE_OP:
397    case AML_VAR_PACKAGE_OP:
398
399        return (BLOCK_COMMA_LIST);
400
401    default:
402
403        OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
404        if (OpInfo->Flags & AML_HAS_ARGS)
405        {
406            return (BLOCK_COMMA_LIST);
407        }
408
409        return (BLOCK_NONE);
410    }
411}
412
413
414/*******************************************************************************
415 *
416 * FUNCTION:    AcpiDmDescendingOp
417 *
418 * PARAMETERS:  ASL_WALK_CALLBACK
419 *
420 * RETURN:      Status
421 *
422 * DESCRIPTION: First visitation of a parse object during tree descent.
423 *              Decode opcode name and begin parameter list(s), if any.
424 *
425 ******************************************************************************/
426
427ACPI_STATUS
428AcpiDmDescendingOp (
429    ACPI_PARSE_OBJECT       *Op,
430    UINT32                  Level,
431    void                    *Context)
432{
433    ACPI_OP_WALK_INFO       *Info = Context;
434    const ACPI_OPCODE_INFO  *OpInfo;
435    UINT32                  Name;
436    ACPI_PARSE_OBJECT       *NextOp;
437    ACPI_EXTERNAL_LIST      *NextExternal;
438
439
440    if (Op->Common.DisasmFlags & ACPI_PARSEOP_IGNORE)
441    {
442        /* Ignore this op -- it was handled elsewhere */
443
444        return (AE_CTRL_DEPTH);
445    }
446
447    /* Level 0 is at the Definition Block level */
448
449    if (Level == 0)
450    {
451        /* In verbose mode, print the AML offset, opcode and depth count */
452
453        VERBOSE_PRINT ((DB_FULL_OP_INFO, (UINT32) Op->Common.AmlOffset,
454                    Op->Common.AmlOpcode));
455
456        if (Op->Common.AmlOpcode == AML_SCOPE_OP)
457        {
458            /* This is the beginning of the Definition Block */
459
460            AcpiOsPrintf ("{\n");
461
462            /* Emit all External() declarations here */
463
464            if (AcpiGbl_ExternalList)
465            {
466                AcpiOsPrintf ("    /*\n     * These objects were referenced but not defined in this table\n     */\n");
467
468                /* Walk the list of externals (unresolved references) found during parsing */
469
470                while (AcpiGbl_ExternalList)
471                {
472                    AcpiOsPrintf ("    External (%s, DeviceObj)\n", AcpiGbl_ExternalList->Path);
473
474                    NextExternal = AcpiGbl_ExternalList->Next;
475                    ACPI_MEM_FREE (AcpiGbl_ExternalList->Path);
476                    ACPI_MEM_FREE (AcpiGbl_ExternalList);
477                    AcpiGbl_ExternalList = NextExternal;
478                }
479                AcpiOsPrintf ("\n");
480            }
481
482            return (AE_OK);
483        }
484    }
485    else if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
486             (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) &&
487             (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP))
488    {
489            /* This is a first-level element of a term list, indent a new line */
490
491            AcpiDmIndent (Level);
492    }
493
494    /* Print the opcode name */
495
496    AcpiDmDisassembleOneOp (NULL, Info, Op);
497
498    if ((Op->Common.AmlOpcode == AML_NAME_OP) ||
499        (Op->Common.AmlOpcode == AML_RETURN_OP))
500    {
501        Info->Level--;
502    }
503
504    /* Start the opcode argument list if necessary */
505
506    OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
507
508    if ((OpInfo->Flags & AML_HAS_ARGS) ||
509        (Op->Common.AmlOpcode == AML_EVENT_OP))
510    {
511        /* This opcode has an argument list */
512
513        if (AcpiDmBlockType (Op) & BLOCK_PAREN)
514        {
515            AcpiOsPrintf (" (");
516        }
517
518        /* If this is a named opcode, print the associated name value */
519
520        if (OpInfo->Flags & AML_NAMED)
521        {
522            switch (Op->Common.AmlOpcode)
523            {
524            case AML_ALIAS_OP:
525
526                NextOp = AcpiPsGetDepthNext (NULL, Op);
527                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
528                AcpiDmNamestring (NextOp->Common.Value.Name);
529                AcpiOsPrintf (", ");
530
531                /*lint -fallthrough */
532
533            default:
534
535                Name = AcpiPsGetName (Op);
536                if (Op->Named.Path)
537                {
538                    AcpiDmNamestring ((char *) Op->Named.Path);
539                }
540                else
541                {
542                    AcpiDmDumpName ((char *) &Name);
543                }
544
545
546                if (Op->Common.AmlOpcode != AML_INT_NAMEDFIELD_OP)
547                {
548                    AcpiDmValidateName ((char *) &Name, Op);
549                    if (AcpiGbl_DbOpt_verbose)
550                    {
551                        (void) AcpiPsDisplayObjectPathname (NULL, Op);
552                    }
553                }
554                break;
555            }
556
557            switch (Op->Common.AmlOpcode)
558            {
559            case AML_METHOD_OP:
560
561                AcpiDmMethodFlags (Op);
562                AcpiOsPrintf (")");
563                break;
564
565
566            case AML_NAME_OP:
567
568                /* Check for _HID and related EISAID() */
569
570                AcpiIsEisaId (Op);
571                AcpiOsPrintf (", ");
572                break;
573
574
575            case AML_REGION_OP:
576
577                AcpiDmRegionFlags (Op);
578                break;
579
580
581            case AML_POWER_RES_OP:
582
583                /* Mark the next two Ops as part of the parameter list */
584
585                AcpiOsPrintf (", ");
586                NextOp = AcpiPsGetDepthNext (NULL, Op);
587                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
588
589                NextOp = NextOp->Common.Next;
590                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
591                return (AE_OK);
592
593
594            case AML_PROCESSOR_OP:
595
596                /* Mark the next three Ops as part of the parameter list */
597
598                AcpiOsPrintf (", ");
599                NextOp = AcpiPsGetDepthNext (NULL, Op);
600                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
601
602                NextOp = NextOp->Common.Next;
603                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
604
605                NextOp = NextOp->Common.Next;
606                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
607                return (AE_OK);
608
609
610            case AML_MUTEX_OP:
611
612                AcpiOsPrintf (", ");
613                return (AE_OK);
614
615
616            case AML_EVENT_OP:
617            case AML_ALIAS_OP:
618
619                return (AE_OK);
620
621
622            case AML_SCOPE_OP:
623            case AML_DEVICE_OP:
624            case AML_THERMAL_ZONE_OP:
625
626                AcpiOsPrintf (")");
627                break;
628
629
630            default:
631
632                AcpiOsPrintf ("*** Unhandled named opcode\n");
633                break;
634            }
635        }
636
637        else switch (Op->Common.AmlOpcode)
638        {
639        case AML_FIELD_OP:
640        case AML_BANK_FIELD_OP:
641        case AML_INDEX_FIELD_OP:
642
643            Info->BitOffset = 0;
644
645            /* Name of the parent OperationRegion */
646
647            NextOp = AcpiPsGetDepthNext (NULL, Op);
648            AcpiDmNamestring (NextOp->Common.Value.Name);
649            AcpiOsPrintf (", ");
650            NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
651
652            switch (Op->Common.AmlOpcode)
653            {
654            case AML_BANK_FIELD_OP:
655
656                /* Namestring */
657
658                NextOp = AcpiPsGetDepthNext (NULL, NextOp);
659                AcpiDmNamestring (NextOp->Common.Value.Name);
660                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
661                AcpiOsPrintf (", ");
662
663
664                NextOp = NextOp->Common.Next;
665                AcpiDmDisassembleOneOp (NULL, Info, NextOp);
666                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
667                AcpiOsPrintf (", ");
668                break;
669
670            case AML_INDEX_FIELD_OP:
671
672                /* Namestring */
673
674                NextOp = AcpiPsGetDepthNext (NULL, NextOp);
675                AcpiDmNamestring (NextOp->Common.Value.Name);
676                AcpiOsPrintf (", ");
677                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
678                break;
679
680            default:
681
682                break;
683            }
684
685            AcpiDmFieldFlags (NextOp);
686            break;
687
688
689        case AML_BUFFER_OP:
690
691            /* The next op is the size parameter */
692
693            NextOp = AcpiPsGetDepthNext (NULL, Op);
694            if (!NextOp)
695            {
696                /* Single-step support */
697
698                return (AE_OK);
699            }
700
701            if (Op->Common.DisasmOpcode == ACPI_DASM_RESOURCE)
702            {
703                /*
704                 * We have a resource list.  Don't need to output
705                 * the buffer size Op.  Open up a new block
706                 */
707                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
708                NextOp = NextOp->Common.Next;
709                AcpiOsPrintf (")\n");
710                AcpiDmIndent (Info->Level);
711                AcpiOsPrintf ("{\n");
712                return (AE_OK);
713            }
714
715            /* Normal Buffer, mark size as in the parameter list */
716
717            NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
718            return (AE_OK);
719
720
721        case AML_VAR_PACKAGE_OP:
722        case AML_IF_OP:
723        case AML_WHILE_OP:
724
725            /* The next op is the size or predicate parameter */
726
727            NextOp = AcpiPsGetDepthNext (NULL, Op);
728            if (NextOp)
729            {
730                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
731            }
732            return (AE_OK);
733
734
735        case AML_PACKAGE_OP:
736
737            /* The next op is the size or predicate parameter */
738
739            NextOp = AcpiPsGetDepthNext (NULL, Op);
740            if (NextOp)
741            {
742                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
743            }
744            return (AE_OK);
745
746
747        case AML_MATCH_OP:
748
749            AcpiDmMatchOp (Op);
750            break;
751
752
753        default:
754
755            break;
756        }
757
758        if (AcpiDmBlockType (Op) & BLOCK_BRACE)
759        {
760            AcpiOsPrintf ("\n");
761            AcpiDmIndent (Level);
762            AcpiOsPrintf ("{\n");
763        }
764    }
765
766    return (AE_OK);
767}
768
769
770/*******************************************************************************
771 *
772 * FUNCTION:    AcpiDmAscendingOp
773 *
774 * PARAMETERS:  ASL_WALK_CALLBACK
775 *
776 * RETURN:      Status
777 *
778 * DESCRIPTION: Second visitation of a parse object, during ascent of parse
779 *              tree.  Close out any parameter lists and complete the opcode.
780 *
781 ******************************************************************************/
782
783ACPI_STATUS
784AcpiDmAscendingOp (
785    ACPI_PARSE_OBJECT       *Op,
786    UINT32                  Level,
787    void                    *Context)
788{
789    ACPI_OP_WALK_INFO       *Info = Context;
790
791
792    if (Op->Common.DisasmFlags & ACPI_PARSEOP_IGNORE)
793    {
794        /* Ignore this op -- it was handled elsewhere */
795
796        return (AE_OK);
797    }
798
799    if ((Level == 0) && (Op->Common.AmlOpcode == AML_SCOPE_OP))
800    {
801        /* Indicates the end of the current descriptor block (table) */
802
803        AcpiOsPrintf ("}\n\n");
804        return (AE_OK);
805    }
806
807    switch (AcpiDmBlockType (Op))
808    {
809    case BLOCK_PAREN:
810
811        /* Completed an op that has arguments, add closing paren */
812
813        AcpiOsPrintf (")");
814
815        /* Could be a nested operator, check if comma required */
816
817        if (!AcpiDmCommaIfListMember (Op))
818        {
819            if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
820                     (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) &&
821                     (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP))
822            {
823                /* This is a first-level element of a term list, start a new line */
824
825                AcpiOsPrintf ("\n");
826            }
827        }
828        break;
829
830
831    case BLOCK_BRACE:
832    case (BLOCK_BRACE | BLOCK_PAREN):
833
834        /* Completed an op that has a term list, add closing brace */
835
836        if (Op->Common.DisasmFlags & ACPI_PARSEOP_EMPTY_TERMLIST)
837        {
838            AcpiOsPrintf ("}");
839        }
840        else
841        {
842            AcpiDmIndent (Level);
843            AcpiOsPrintf ("}");
844        }
845
846        AcpiDmCommaIfListMember (Op);
847
848        if (AcpiDmBlockType (Op->Common.Parent) != BLOCK_PAREN)
849        {
850            AcpiOsPrintf ("\n");
851            if (!(Op->Common.DisasmFlags & ACPI_PARSEOP_EMPTY_TERMLIST))
852            {
853                if ((Op->Common.AmlOpcode == AML_IF_OP)  &&
854                    (Op->Common.Next) &&
855                    (Op->Common.Next->Common.AmlOpcode == AML_ELSE_OP))
856                {
857                    break;
858                }
859
860                if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
861                    (!Op->Common.Next))
862                {
863                    break;
864                }
865                AcpiOsPrintf ("\n");
866            }
867        }
868        break;
869
870
871    case BLOCK_NONE:
872    default:
873
874        /* Could be a nested operator, check if comma required */
875
876        if (!AcpiDmCommaIfListMember (Op))
877        {
878            if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
879                     (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) &&
880                     (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP))
881            {
882                /* This is a first-level element of a term list, start a new line */
883
884                AcpiOsPrintf ("\n");
885            }
886        }
887        else if (Op->Common.Parent)
888        {
889            switch (Op->Common.Parent->Common.AmlOpcode)
890            {
891            case AML_PACKAGE_OP:
892            case AML_VAR_PACKAGE_OP:
893
894                if (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST))
895                {
896                    AcpiOsPrintf ("\n");
897                }
898                break;
899
900            default:
901
902                break;
903            }
904        }
905        break;
906    }
907
908    if (Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)
909    {
910        if ((Op->Common.Next) &&
911            (Op->Common.Next->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST))
912        {
913            return (AE_OK);
914        }
915
916        /*
917         * Just completed a parameter node for something like "Buffer (param)".
918         * Close the paren and open up the term list block with a brace
919         */
920        if (Op->Common.Next)
921        {
922            AcpiOsPrintf (")\n");
923            AcpiDmIndent (Level - 1);
924            AcpiOsPrintf ("{\n");
925        }
926        else
927        {
928            Op->Common.Parent->Common.DisasmFlags |= ACPI_PARSEOP_EMPTY_TERMLIST;
929            AcpiOsPrintf (") {");
930        }
931    }
932
933    if ((Op->Common.AmlOpcode == AML_NAME_OP) ||
934        (Op->Common.AmlOpcode == AML_RETURN_OP))
935    {
936        Info->Level++;
937    }
938    return (AE_OK);
939}
940
941
942#endif  /* ACPI_DISASSEMBLER */
943