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