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