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