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