dmwalk.c revision 102550
1/*******************************************************************************
2 *
3 * Module Name: dmwalk - AML disassembly tree walk
4 *              $Revision: 8 $
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_CA_DEBUGGER
128        ACPI_MODULE_NAME    ("dmwalk")
129
130
131#define DB_FULL_OP_INFO     "%5.5X #%4.4hX "
132
133
134/*******************************************************************************
135 *
136 * FUNCTION:    AcpiDmDisassemble
137 *
138 * PARAMETERS:  Origin          - Starting object
139 *              NumOpcodes      - Max number of opcodes to be displayed
140 *
141 * RETURN:      None
142 *
143 * DESCRIPTION: Disassemble parser object and its children.  This is the
144 *              main entry point of the disassembler.
145 *
146 ******************************************************************************/
147
148void
149AcpiDmDisassemble (
150    ACPI_WALK_STATE         *WalkState,
151    ACPI_PARSE_OBJECT       *Origin,
152    UINT32                  NumOpcodes)
153{
154    ACPI_PARSE_OBJECT       *Op = Origin;
155    ACPI_OP_WALK_INFO       Info;
156
157
158    if (!Op)
159    {
160        return;
161    }
162
163    Info.Level = 0;
164    AcpiDmWalkParseTree (Op, AcpiDmDescendingOp, AcpiDmAscendingOp, &Info);
165
166    return;
167}
168
169
170/*******************************************************************************
171 *
172 * FUNCTION:    AcpiDmWalkParseTree
173 *
174 * PARAMETERS:  DescendingCallback      - Called during tree descent
175 *              AscendingCallback       - Called during tree ascent
176 *              Context                 - To be passed to the callbacks
177 *
178 * RETURN:      Status from callback(s)
179 *
180 * DESCRIPTION: Walk the entire parse tree.
181 *
182 ******************************************************************************/
183
184void
185AcpiDmWalkParseTree (
186    ACPI_PARSE_OBJECT       *Op,
187    ASL_WALK_CALLBACK       DescendingCallback,
188    ASL_WALK_CALLBACK       AscendingCallback,
189    void                    *Context)
190{
191    BOOLEAN                 NodePreviouslyVisited;
192    ACPI_PARSE_OBJECT       *StartOp = Op;
193    ACPI_STATUS             Status;
194    ACPI_PARSE_OBJECT       *Next;
195    ACPI_OP_WALK_INFO       *Info = Context;
196
197
198    Info->Level = 0;
199    NodePreviouslyVisited = FALSE;
200
201    while (Op)
202    {
203        if (NodePreviouslyVisited)
204        {
205            Status = AscendingCallback (Op, Info->Level, Context);
206            if (ACPI_FAILURE (Status))
207            {
208                return;
209            }
210        }
211        else
212        {
213            /*
214             * Let the callback process the node.
215             */
216            Status = DescendingCallback (Op, Info->Level, Context);
217            if (ACPI_SUCCESS (Status))
218            {
219                /* Visit children first, once */
220
221                Next = AcpiPsGetArg (Op, 0);
222                if (Next)
223                {
224                    Info->Level++;
225                    Op = Next;
226                    continue;
227                }
228            }
229            else if (Status != AE_CTRL_DEPTH)
230            {
231                /* Exit immediately on any error */
232
233                return;
234            }
235        }
236
237        /* Terminate walk at start op */
238
239        if (Op == StartOp)
240        {
241            break;
242        }
243
244        /* No more children, re-visit this node */
245
246        if (!NodePreviouslyVisited)
247        {
248            NodePreviouslyVisited = TRUE;
249            continue;
250        }
251
252        /* No more children, visit peers */
253
254        if (Op->Common.Next)
255        {
256            Op = Op->Common.Next;
257            NodePreviouslyVisited = FALSE;
258        }
259        else
260        {
261            /* No peers, re-visit parent */
262
263            if (Info->Level != 0 )
264            {
265                Info->Level--;
266            }
267
268            Op = Op->Common.Parent;
269            NodePreviouslyVisited = TRUE;
270        }
271    }
272
273    /* If we get here, the walk completed with no errors */
274
275    return;
276}
277
278
279/*******************************************************************************
280 *
281 * FUNCTION:    AcpiDmBlockType
282 *
283 * PARAMETERS:  Op              - Object to be examined
284 *
285 * RETURN:      Status
286 *
287 * DESCRIPTION: Type of block for this op (parens or braces)
288 *
289 ******************************************************************************/
290
291UINT32
292AcpiDmBlockType (
293    ACPI_PARSE_OBJECT       *Op)
294{
295    const ACPI_OPCODE_INFO  *OpInfo;
296
297
298    if (!Op)
299    {
300        return (BLOCK_NONE);
301    }
302
303    switch (Op->Common.AmlOpcode)
304    {
305    case AML_ELSE_OP:
306
307        return (BLOCK_BRACE);
308
309    case AML_METHOD_OP:
310    case AML_DEVICE_OP:
311    case AML_SCOPE_OP:
312    case AML_PROCESSOR_OP:
313    case AML_POWER_RES_OP:
314    case AML_THERMAL_ZONE_OP:
315    case AML_IF_OP:
316    case AML_WHILE_OP:
317    case AML_FIELD_OP:
318    case AML_INDEX_FIELD_OP:
319    case AML_BANK_FIELD_OP:
320
321        return (BLOCK_PAREN | BLOCK_BRACE);
322
323    case AML_BUFFER_OP:
324
325        if (Op->Common.DisasmOpcode == ACPI_DASM_UNICODE)
326        {
327            return (BLOCK_NONE);
328        }
329
330        /*lint -fallthrough */
331
332    case AML_PACKAGE_OP:
333    case AML_VAR_PACKAGE_OP:
334
335        return (BLOCK_PAREN | BLOCK_BRACE);
336
337    case AML_EVENT_OP:
338
339        return (BLOCK_PAREN);
340
341    default:
342
343        OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
344        if (OpInfo->Flags & AML_HAS_ARGS)
345        {
346            return (BLOCK_PAREN);
347        }
348
349        return (BLOCK_NONE);
350    }
351}
352
353
354/*******************************************************************************
355 *
356 * FUNCTION:    AcpiDmListType
357 *
358 * PARAMETERS:  Op              - Object to be examined
359 *
360 * RETURN:      Status
361 *
362 * DESCRIPTION: Type of block for this op (parens or braces)
363 *
364 ******************************************************************************/
365
366UINT32
367AcpiDmListType (
368    ACPI_PARSE_OBJECT       *Op)
369{
370    const ACPI_OPCODE_INFO  *OpInfo;
371
372
373    if (!Op)
374    {
375        return (BLOCK_NONE);
376    }
377
378    switch (Op->Common.AmlOpcode)
379    {
380
381    case AML_ELSE_OP:
382    case AML_METHOD_OP:
383    case AML_DEVICE_OP:
384    case AML_SCOPE_OP:
385    case AML_POWER_RES_OP:
386    case AML_PROCESSOR_OP:
387    case AML_THERMAL_ZONE_OP:
388    case AML_IF_OP:
389    case AML_WHILE_OP:
390    case AML_FIELD_OP:
391    case AML_INDEX_FIELD_OP:
392    case AML_BANK_FIELD_OP:
393
394        return (0);
395
396    case AML_BUFFER_OP:
397    case AML_PACKAGE_OP:
398    case AML_VAR_PACKAGE_OP:
399
400        return (BLOCK_COMMA_LIST);
401
402    default:
403
404        OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
405        if (OpInfo->Flags & AML_HAS_ARGS)
406        {
407            return (BLOCK_COMMA_LIST);
408        }
409
410        return (BLOCK_NONE);
411    }
412}
413
414
415/*******************************************************************************
416 *
417 * FUNCTION:    AcpiDmDescendingOp
418 *
419 * PARAMETERS:  ASL_WALK_CALLBACK
420 *
421 * RETURN:      Status
422 *
423 * DESCRIPTION: First visitation of a parse object during tree descent.
424 *              Decode opcode name and begin parameter list(s), if any.
425 *
426 ******************************************************************************/
427
428ACPI_STATUS
429AcpiDmDescendingOp (
430    ACPI_PARSE_OBJECT       *Op,
431    UINT32                  Level,
432    void                    *Context)
433{
434    ACPI_OP_WALK_INFO       *Info = Context;
435    const ACPI_OPCODE_INFO  *OpInfo;
436    UINT32                  Name;
437    ACPI_PARSE_OBJECT       *NextOp;
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
448    if (Level == 0)
449    {
450        /* In verbose mode, print the AML offset, opcode and depth count */
451
452        VERBOSE_PRINT ((DB_FULL_OP_INFO, (UINT32) Op->Common.AmlOffset,
453                    Op->Common.AmlOpcode));
454
455        if (Op->Common.AmlOpcode == AML_SCOPE_OP)
456        {
457            AcpiOsPrintf ("{\n");
458            return (AE_OK);
459        }
460    }
461    else if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
462             (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) &&
463             (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP))
464    {
465            /* This is a first-level element of a term list, indent a new line */
466
467            AcpiDmIndent (Level);
468    }
469
470    /* Print the opcode name */
471
472    AcpiDmDisassembleOneOp (NULL, Info, Op);
473
474    if ((Op->Common.AmlOpcode == AML_NAME_OP) ||
475        (Op->Common.AmlOpcode == AML_RETURN_OP))
476    {
477        Info->Level--;
478    }
479
480    /*
481     * Start the opcode argument list if necessary
482     */
483    OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
484
485    if ((OpInfo->Flags & AML_HAS_ARGS) ||
486        (Op->Common.AmlOpcode == AML_EVENT_OP))
487    {
488        /* This opcode has an argument list */
489
490        if (AcpiDmBlockType (Op) & BLOCK_PAREN)
491        {
492            AcpiOsPrintf (" (");
493        }
494
495        /*
496         * If this is a named opcode, print the associated name value
497         */
498        if (OpInfo->Flags & AML_NAMED)
499        {
500            switch (Op->Common.AmlOpcode)
501            {
502            case AML_ALIAS_OP:
503
504                NextOp = AcpiPsGetDepthNext (NULL, Op);
505                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
506                AcpiDmNamestring (NextOp->Common.Value.Name);
507                AcpiOsPrintf (", ");
508
509                /*lint -fallthrough */
510
511            default:
512
513                Name = AcpiPsGetName (Op);
514                if (Op->Named.Path)
515                {
516                    AcpiDmNamestring ((char *) Op->Named.Path);
517                }
518                else
519                {
520                    AcpiDmDumpName ((char *) &Name);
521                }
522
523
524                if (Op->Common.AmlOpcode != AML_INT_NAMEDFIELD_OP)
525                {
526                    AcpiDmValidateName ((char *) &Name, Op);
527                    if (AcpiGbl_DbOpt_verbose)
528                    {
529                        (void) AcpiPsDisplayObjectPathname (NULL, Op);
530                    }
531                }
532                break;
533            }
534
535            switch (Op->Common.AmlOpcode)
536            {
537            case AML_METHOD_OP:
538
539                AcpiDmMethodFlags (Op);
540                AcpiOsPrintf (")");
541                break;
542
543
544            case AML_NAME_OP:
545
546                /* Check for _HID and related EISAID() */
547
548                AcpiIsEisaId (Op);
549                AcpiOsPrintf (", ");
550                break;
551
552
553            case AML_REGION_OP:
554
555                AcpiDmRegionFlags (Op);
556                break;
557
558
559            case AML_POWER_RES_OP:
560
561                /* Mark the next two Ops as part of the parameter list */
562
563                AcpiOsPrintf (", ");
564                NextOp = AcpiPsGetDepthNext (NULL, Op);
565                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
566
567                NextOp = NextOp->Common.Next;
568                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
569                return (AE_OK);
570
571
572            case AML_PROCESSOR_OP:
573
574                /* Mark the next three Ops as part of the parameter list */
575
576                AcpiOsPrintf (", ");
577                NextOp = AcpiPsGetDepthNext (NULL, Op);
578                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
579
580                NextOp = NextOp->Common.Next;
581                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
582
583                NextOp = NextOp->Common.Next;
584                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
585                return (AE_OK);
586
587
588            case AML_MUTEX_OP:
589
590                AcpiOsPrintf (", ");
591                return (AE_OK);
592
593
594            case AML_EVENT_OP:
595            case AML_ALIAS_OP:
596
597                return (AE_OK);
598
599
600            case AML_SCOPE_OP:
601            case AML_DEVICE_OP:
602            case AML_THERMAL_ZONE_OP:
603
604                AcpiOsPrintf (")");
605                break;
606
607
608            default:
609
610                AcpiOsPrintf ("*** Unhandled named opcode\n");
611                break;
612            }
613        }
614
615        else switch (Op->Common.AmlOpcode)
616        {
617        case AML_FIELD_OP:
618        case AML_BANK_FIELD_OP:
619        case AML_INDEX_FIELD_OP:
620
621            Info->BitOffset = 0;
622
623            /* Name of the parent OperationRegion */
624
625            NextOp = AcpiPsGetDepthNext (NULL, Op);
626            AcpiDmNamestring (NextOp->Common.Value.Name);
627            AcpiOsPrintf (", ");
628            NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
629
630            switch (Op->Common.AmlOpcode)
631            {
632            case AML_BANK_FIELD_OP:
633
634                /* Namestring */
635
636                NextOp = AcpiPsGetDepthNext (NULL, NextOp);
637                AcpiDmNamestring (NextOp->Common.Value.Name);
638                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
639                AcpiOsPrintf (", ");
640
641
642                NextOp = NextOp->Common.Next;
643                AcpiDmDisassembleOneOp (NULL, Info, NextOp);
644                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
645                AcpiOsPrintf (", ");
646                break;
647
648            case AML_INDEX_FIELD_OP:
649
650                /* Namestring */
651
652                NextOp = AcpiPsGetDepthNext (NULL, NextOp);
653                AcpiDmNamestring (NextOp->Common.Value.Name);
654                AcpiOsPrintf (", ");
655                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
656                break;
657
658            default:
659
660                break;
661            }
662
663            AcpiDmFieldFlags (NextOp);
664            break;
665
666
667        case AML_BUFFER_OP:
668
669            /* The next op is the size parameter */
670
671            NextOp = AcpiPsGetDepthNext (NULL, Op);
672            if (!NextOp)
673            {
674                /* Single-step support */
675
676                return (AE_OK);
677            }
678
679            if (Op->Common.DisasmOpcode == ACPI_DASM_RESOURCE)
680            {
681                /*
682                 * We have a resource list.  Don't need to output
683                 * the buffer size Op.  Open up a new block
684                 */
685                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
686                NextOp = NextOp->Common.Next;
687                AcpiOsPrintf (")\n");
688                AcpiDmIndent (Info->Level);
689                AcpiOsPrintf ("{\n");
690                return (AE_OK);
691            }
692
693            /* Normal Buffer, mark size as in the parameter list */
694
695            NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
696            return (AE_OK);
697
698
699        case AML_VAR_PACKAGE_OP:
700        case AML_IF_OP:
701        case AML_WHILE_OP:
702
703            /* The next op is the size or predicate parameter */
704
705            NextOp = AcpiPsGetDepthNext (NULL, Op);
706            if (NextOp)
707            {
708                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
709            }
710            return (AE_OK);
711
712
713        case AML_PACKAGE_OP:
714
715            /* The next op is the size or predicate parameter */
716
717            NextOp = AcpiPsGetDepthNext (NULL, Op);
718            if (NextOp)
719            {
720                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
721            }
722            return (AE_OK);
723
724
725        case AML_MATCH_OP:
726
727            AcpiDmMatchOp (Op);
728            break;
729
730
731        default:
732
733            break;
734        }
735
736        if (AcpiDmBlockType (Op) & BLOCK_BRACE)
737        {
738            AcpiOsPrintf ("\n");
739            AcpiDmIndent (Level);
740            AcpiOsPrintf ("{\n");
741        }
742    }
743
744    return (AE_OK);
745}
746
747
748/*******************************************************************************
749 *
750 * FUNCTION:    AcpiDmAscendingOp
751 *
752 * PARAMETERS:  ASL_WALK_CALLBACK
753 *
754 * RETURN:      Status
755 *
756 * DESCRIPTION: Second visitation of a parse object, during ascent of parse
757 *              tree.  Close out any parameter lists and complete the opcode.
758 *
759 ******************************************************************************/
760
761ACPI_STATUS
762AcpiDmAscendingOp (
763    ACPI_PARSE_OBJECT       *Op,
764    UINT32                  Level,
765    void                    *Context)
766{
767    ACPI_OP_WALK_INFO       *Info = Context;
768
769
770    if (Op->Common.DisasmFlags & ACPI_PARSEOP_IGNORE)
771    {
772        /* Ignore this op -- it was handled elsewhere */
773
774        return (AE_OK);
775    }
776
777    if ((Level == 0) && (Op->Common.AmlOpcode == AML_SCOPE_OP))
778    {
779        /* Indicates the end of the current descriptor block (table) */
780
781        AcpiOsPrintf ("}\n\n");
782        return (AE_OK);
783    }
784
785    switch (AcpiDmBlockType (Op))
786    {
787    case BLOCK_PAREN:
788
789        /* Completed an op that has arguments, add closing paren */
790
791        AcpiOsPrintf (")");
792
793        /* Could be a nested operator, check if comma required */
794
795        if (!AcpiDmCommaIfListMember (Op))
796        {
797            if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
798                     (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) &&
799                     (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP))
800            {
801                /* This is a first-level element of a term list, start a new line */
802
803                AcpiOsPrintf ("\n");
804            }
805        }
806        break;
807
808
809    case BLOCK_BRACE:
810    case (BLOCK_BRACE | BLOCK_PAREN):
811
812        /* Completed an op that has a term list, add closing brace */
813
814        if (Op->Common.DisasmFlags & ACPI_PARSEOP_EMPTY_TERMLIST)
815        {
816            AcpiOsPrintf ("}");
817        }
818        else
819        {
820            AcpiDmIndent (Level);
821            AcpiOsPrintf ("}");
822        }
823
824        AcpiDmCommaIfListMember (Op);
825
826        if (AcpiDmBlockType (Op->Common.Parent) != BLOCK_PAREN)
827        {
828            AcpiOsPrintf ("\n");
829            if (!(Op->Common.DisasmFlags & ACPI_PARSEOP_EMPTY_TERMLIST))
830            {
831                if ((Op->Common.AmlOpcode == AML_IF_OP)  &&
832                    (Op->Common.Next) &&
833                    (Op->Common.Next->Common.AmlOpcode == AML_ELSE_OP))
834                {
835                    break;
836                }
837
838                if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
839                    (!Op->Common.Next))
840                {
841                    break;
842                }
843                AcpiOsPrintf ("\n");
844            }
845        }
846        break;
847
848
849    case BLOCK_NONE:
850    default:
851
852        /* Could be a nested operator, check if comma required */
853
854        if (!AcpiDmCommaIfListMember (Op))
855        {
856            if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
857                     (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) &&
858                     (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP))
859            {
860                /* This is a first-level element of a term list, start a new line */
861
862                AcpiOsPrintf ("\n");
863            }
864        }
865        else if (Op->Common.Parent)
866        {
867            switch (Op->Common.Parent->Common.AmlOpcode)
868            {
869            case AML_PACKAGE_OP:
870            case AML_VAR_PACKAGE_OP:
871
872                if (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST))
873                {
874                    AcpiOsPrintf ("\n");
875                }
876                break;
877
878            default:
879
880                break;
881            }
882        }
883        break;
884    }
885
886    if (Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)
887    {
888        if ((Op->Common.Next) &&
889            (Op->Common.Next->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST))
890        {
891            return (AE_OK);
892        }
893
894        /*
895         * Just completed a parameter node for something like "Buffer (param)".
896         * Close the paren and open up the term list block with a brace
897         */
898        if (Op->Common.Next)
899        {
900            AcpiOsPrintf (")\n");
901            AcpiDmIndent (Level - 1);
902            AcpiOsPrintf ("{\n");
903        }
904        else
905        {
906            Op->Common.Parent->Common.DisasmFlags |= ACPI_PARSEOP_EMPTY_TERMLIST;
907            AcpiOsPrintf (") {");
908        }
909    }
910
911    if ((Op->Common.AmlOpcode == AML_NAME_OP) ||
912        (Op->Common.AmlOpcode == AML_RETURN_OP))
913    {
914        Info->Level++;
915    }
916    return (AE_OK);
917}
918
919
920#endif  /* ACPI_DISASSEMBLER */
921