Import acpica-20050211 from Intel.
[dragonfly.git] / sys / contrib / dev / acpica-unix-20050211 / disassembler / dmwalk.c
1 /*******************************************************************************
2  *
3  * Module Name: dmwalk - AML disassembly tree walk
4  *              $Revision: 15 $
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 "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
148 void
149 AcpiDmDisassemble (
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
184 void
185 AcpiDmWalkParseTree (
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             /* 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
290 UINT32
291 AcpiDmBlockType (
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
365 UINT32
366 AcpiDmListType (
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
427 ACPI_STATUS
428 AcpiDmDescendingOp (
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
783 ACPI_STATUS
784 AcpiDmAscendingOp (
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 */