mkdep(1) seems to want the current directory on the include path,
[dragonfly.git] / sys / contrib / dev / acpica-unix-20031203 / disassembler / dmwalk.c
1 /*******************************************************************************
2  *
3  * Module Name: dmwalk - AML disassembly tree walk
4  *              $Revision: 10 $
5  *
6  ******************************************************************************/
7
8 /******************************************************************************
9  *
10  * 1. Copyright Notice
11  *
12  * Some or all of this work - Copyright (c) 1999 - 2003, 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
438
439     if (Op->Common.DisasmFlags & ACPI_PARSEOP_IGNORE)
440     {
441         /* Ignore this op -- it was handled elsewhere */
442
443         return (AE_CTRL_DEPTH);
444     }
445
446
447     if (Level == 0)
448     {
449         /* In verbose mode, print the AML offset, opcode and depth count */
450
451         VERBOSE_PRINT ((DB_FULL_OP_INFO, (UINT32) Op->Common.AmlOffset,
452                     Op->Common.AmlOpcode));
453
454         if (Op->Common.AmlOpcode == AML_SCOPE_OP)
455         {
456             AcpiOsPrintf ("{\n");
457             return (AE_OK);
458         }
459     }
460     else if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
461              (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) &&
462              (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP))
463     {
464             /* This is a first-level element of a term list, indent a new line */
465
466             AcpiDmIndent (Level);
467     }
468
469     /* Print the opcode name */
470
471     AcpiDmDisassembleOneOp (NULL, Info, Op);
472
473     if ((Op->Common.AmlOpcode == AML_NAME_OP) ||
474         (Op->Common.AmlOpcode == AML_RETURN_OP))
475     {
476         Info->Level--;
477     }
478
479     /* Start the opcode argument list if necessary */
480
481     OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
482
483     if ((OpInfo->Flags & AML_HAS_ARGS) ||
484         (Op->Common.AmlOpcode == AML_EVENT_OP))
485     {
486         /* This opcode has an argument list */
487
488         if (AcpiDmBlockType (Op) & BLOCK_PAREN)
489         {
490             AcpiOsPrintf (" (");
491         }
492
493         /* If this is a named opcode, print the associated name value */
494
495         if (OpInfo->Flags & AML_NAMED)
496         {
497             switch (Op->Common.AmlOpcode)
498             {
499             case AML_ALIAS_OP:
500
501                 NextOp = AcpiPsGetDepthNext (NULL, Op);
502                 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
503                 AcpiDmNamestring (NextOp->Common.Value.Name);
504                 AcpiOsPrintf (", ");
505
506                 /*lint -fallthrough */
507
508             default:
509
510                 Name = AcpiPsGetName (Op);
511                 if (Op->Named.Path)
512                 {
513                     AcpiDmNamestring ((char *) Op->Named.Path);
514                 }
515                 else
516                 {
517                     AcpiDmDumpName ((char *) &Name);
518                 }
519
520
521                 if (Op->Common.AmlOpcode != AML_INT_NAMEDFIELD_OP)
522                 {
523                     AcpiDmValidateName ((char *) &Name, Op);
524                     if (AcpiGbl_DbOpt_verbose)
525                     {
526                         (void) AcpiPsDisplayObjectPathname (NULL, Op);
527                     }
528                 }
529                 break;
530             }
531
532             switch (Op->Common.AmlOpcode)
533             {
534             case AML_METHOD_OP:
535
536                 AcpiDmMethodFlags (Op);
537                 AcpiOsPrintf (")");
538                 break;
539
540
541             case AML_NAME_OP:
542
543                 /* Check for _HID and related EISAID() */
544
545                 AcpiIsEisaId (Op);
546                 AcpiOsPrintf (", ");
547                 break;
548
549
550             case AML_REGION_OP:
551
552                 AcpiDmRegionFlags (Op);
553                 break;
554
555
556             case AML_POWER_RES_OP:
557
558                 /* Mark the next two Ops as part of the parameter list */
559
560                 AcpiOsPrintf (", ");
561                 NextOp = AcpiPsGetDepthNext (NULL, Op);
562                 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
563
564                 NextOp = NextOp->Common.Next;
565                 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
566                 return (AE_OK);
567
568
569             case AML_PROCESSOR_OP:
570
571                 /* Mark the next three Ops as part of the parameter list */
572
573                 AcpiOsPrintf (", ");
574                 NextOp = AcpiPsGetDepthNext (NULL, Op);
575                 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
576
577                 NextOp = NextOp->Common.Next;
578                 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
579
580                 NextOp = NextOp->Common.Next;
581                 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
582                 return (AE_OK);
583
584
585             case AML_MUTEX_OP:
586
587                 AcpiOsPrintf (", ");
588                 return (AE_OK);
589
590
591             case AML_EVENT_OP:
592             case AML_ALIAS_OP:
593
594                 return (AE_OK);
595
596
597             case AML_SCOPE_OP:
598             case AML_DEVICE_OP:
599             case AML_THERMAL_ZONE_OP:
600
601                 AcpiOsPrintf (")");
602                 break;
603
604
605             default:
606
607                 AcpiOsPrintf ("*** Unhandled named opcode\n");
608                 break;
609             }
610         }
611
612         else switch (Op->Common.AmlOpcode)
613         {
614         case AML_FIELD_OP:
615         case AML_BANK_FIELD_OP:
616         case AML_INDEX_FIELD_OP:
617
618             Info->BitOffset = 0;
619
620             /* Name of the parent OperationRegion */
621
622             NextOp = AcpiPsGetDepthNext (NULL, Op);
623             AcpiDmNamestring (NextOp->Common.Value.Name);
624             AcpiOsPrintf (", ");
625             NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
626
627             switch (Op->Common.AmlOpcode)
628             {
629             case AML_BANK_FIELD_OP:
630
631                 /* Namestring */
632
633                 NextOp = AcpiPsGetDepthNext (NULL, NextOp);
634                 AcpiDmNamestring (NextOp->Common.Value.Name);
635                 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
636                 AcpiOsPrintf (", ");
637
638
639                 NextOp = NextOp->Common.Next;
640                 AcpiDmDisassembleOneOp (NULL, Info, NextOp);
641                 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
642                 AcpiOsPrintf (", ");
643                 break;
644
645             case AML_INDEX_FIELD_OP:
646
647                 /* Namestring */
648
649                 NextOp = AcpiPsGetDepthNext (NULL, NextOp);
650                 AcpiDmNamestring (NextOp->Common.Value.Name);
651                 AcpiOsPrintf (", ");
652                 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
653                 break;
654
655             default:
656
657                 break;
658             }
659
660             AcpiDmFieldFlags (NextOp);
661             break;
662
663
664         case AML_BUFFER_OP:
665
666             /* The next op is the size parameter */
667
668             NextOp = AcpiPsGetDepthNext (NULL, Op);
669             if (!NextOp)
670             {
671                 /* Single-step support */
672
673                 return (AE_OK);
674             }
675
676             if (Op->Common.DisasmOpcode == ACPI_DASM_RESOURCE)
677             {
678                 /*
679                  * We have a resource list.  Don't need to output
680                  * the buffer size Op.  Open up a new block
681                  */
682                 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
683                 NextOp = NextOp->Common.Next;
684                 AcpiOsPrintf (")\n");
685                 AcpiDmIndent (Info->Level);
686                 AcpiOsPrintf ("{\n");
687                 return (AE_OK);
688             }
689
690             /* Normal Buffer, mark size as in the parameter list */
691
692             NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
693             return (AE_OK);
694
695
696         case AML_VAR_PACKAGE_OP:
697         case AML_IF_OP:
698         case AML_WHILE_OP:
699
700             /* The next op is the size or predicate parameter */
701
702             NextOp = AcpiPsGetDepthNext (NULL, Op);
703             if (NextOp)
704             {
705                 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
706             }
707             return (AE_OK);
708
709
710         case AML_PACKAGE_OP:
711
712             /* The next op is the size or predicate parameter */
713
714             NextOp = AcpiPsGetDepthNext (NULL, Op);
715             if (NextOp)
716             {
717                 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
718             }
719             return (AE_OK);
720
721
722         case AML_MATCH_OP:
723
724             AcpiDmMatchOp (Op);
725             break;
726
727
728         default:
729
730             break;
731         }
732
733         if (AcpiDmBlockType (Op) & BLOCK_BRACE)
734         {
735             AcpiOsPrintf ("\n");
736             AcpiDmIndent (Level);
737             AcpiOsPrintf ("{\n");
738         }
739     }
740
741     return (AE_OK);
742 }
743
744
745 /*******************************************************************************
746  *
747  * FUNCTION:    AcpiDmAscendingOp
748  *
749  * PARAMETERS:  ASL_WALK_CALLBACK
750  *
751  * RETURN:      Status
752  *
753  * DESCRIPTION: Second visitation of a parse object, during ascent of parse
754  *              tree.  Close out any parameter lists and complete the opcode.
755  *
756  ******************************************************************************/
757
758 ACPI_STATUS
759 AcpiDmAscendingOp (
760     ACPI_PARSE_OBJECT       *Op,
761     UINT32                  Level,
762     void                    *Context)
763 {
764     ACPI_OP_WALK_INFO       *Info = Context;
765
766
767     if (Op->Common.DisasmFlags & ACPI_PARSEOP_IGNORE)
768     {
769         /* Ignore this op -- it was handled elsewhere */
770
771         return (AE_OK);
772     }
773
774     if ((Level == 0) && (Op->Common.AmlOpcode == AML_SCOPE_OP))
775     {
776         /* Indicates the end of the current descriptor block (table) */
777
778         AcpiOsPrintf ("}\n\n");
779         return (AE_OK);
780     }
781
782     switch (AcpiDmBlockType (Op))
783     {
784     case BLOCK_PAREN:
785
786         /* Completed an op that has arguments, add closing paren */
787
788         AcpiOsPrintf (")");
789
790         /* Could be a nested operator, check if comma required */
791
792         if (!AcpiDmCommaIfListMember (Op))
793         {
794             if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
795                      (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) &&
796                      (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP))
797             {
798                 /* This is a first-level element of a term list, start a new line */
799
800                 AcpiOsPrintf ("\n");
801             }
802         }
803         break;
804
805
806     case BLOCK_BRACE:
807     case (BLOCK_BRACE | BLOCK_PAREN):
808
809         /* Completed an op that has a term list, add closing brace */
810
811         if (Op->Common.DisasmFlags & ACPI_PARSEOP_EMPTY_TERMLIST)
812         {
813             AcpiOsPrintf ("}");
814         }
815         else
816         {
817             AcpiDmIndent (Level);
818             AcpiOsPrintf ("}");
819         }
820
821         AcpiDmCommaIfListMember (Op);
822
823         if (AcpiDmBlockType (Op->Common.Parent) != BLOCK_PAREN)
824         {
825             AcpiOsPrintf ("\n");
826             if (!(Op->Common.DisasmFlags & ACPI_PARSEOP_EMPTY_TERMLIST))
827             {
828                 if ((Op->Common.AmlOpcode == AML_IF_OP)  &&
829                     (Op->Common.Next) &&
830                     (Op->Common.Next->Common.AmlOpcode == AML_ELSE_OP))
831                 {
832                     break;
833                 }
834
835                 if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
836                     (!Op->Common.Next))
837                 {
838                     break;
839                 }
840                 AcpiOsPrintf ("\n");
841             }
842         }
843         break;
844
845
846     case BLOCK_NONE:
847     default:
848
849         /* Could be a nested operator, check if comma required */
850
851         if (!AcpiDmCommaIfListMember (Op))
852         {
853             if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
854                      (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) &&
855                      (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP))
856             {
857                 /* This is a first-level element of a term list, start a new line */
858
859                 AcpiOsPrintf ("\n");
860             }
861         }
862         else if (Op->Common.Parent)
863         {
864             switch (Op->Common.Parent->Common.AmlOpcode)
865             {
866             case AML_PACKAGE_OP:
867             case AML_VAR_PACKAGE_OP:
868
869                 if (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST))
870                 {
871                     AcpiOsPrintf ("\n");
872                 }
873                 break;
874
875             default:
876
877                 break;
878             }
879         }
880         break;
881     }
882
883     if (Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)
884     {
885         if ((Op->Common.Next) &&
886             (Op->Common.Next->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST))
887         {
888             return (AE_OK);
889         }
890
891         /*
892          * Just completed a parameter node for something like "Buffer (param)".
893          * Close the paren and open up the term list block with a brace
894          */
895         if (Op->Common.Next)
896         {
897             AcpiOsPrintf (")\n");
898             AcpiDmIndent (Level - 1);
899             AcpiOsPrintf ("{\n");
900         }
901         else
902         {
903             Op->Common.Parent->Common.DisasmFlags |= ACPI_PARSEOP_EMPTY_TERMLIST;
904             AcpiOsPrintf (") {");
905         }
906     }
907
908     if ((Op->Common.AmlOpcode == AML_NAME_OP) ||
909         (Op->Common.AmlOpcode == AML_RETURN_OP))
910     {
911         Info->Level++;
912     }
913     return (AE_OK);
914 }
915
916
917 #endif  /* ACPI_DISASSEMBLER */