xref: /titanic_44/usr/src/uts/intel/io/acpica/disassembler/dmwalk.c (revision cb56572868bfc488bbd3ab847b09db2a25554d44)
1ae115bc7Smrj /*******************************************************************************
2ae115bc7Smrj  *
3ae115bc7Smrj  * Module Name: dmwalk - AML disassembly tree walk
4ae115bc7Smrj  *
5ae115bc7Smrj  ******************************************************************************/
6ae115bc7Smrj 
726f3cdf0SGordon Ross /*
8*cb565728SJerry Jelinek  * Copyright (C) 2000 - 2016, Intel Corp.
9ae115bc7Smrj  * All rights reserved.
10ae115bc7Smrj  *
1126f3cdf0SGordon Ross  * Redistribution and use in source and binary forms, with or without
1226f3cdf0SGordon Ross  * modification, are permitted provided that the following conditions
1326f3cdf0SGordon Ross  * are met:
1426f3cdf0SGordon Ross  * 1. Redistributions of source code must retain the above copyright
1526f3cdf0SGordon Ross  *    notice, this list of conditions, and the following disclaimer,
1626f3cdf0SGordon Ross  *    without modification.
1726f3cdf0SGordon Ross  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
1826f3cdf0SGordon Ross  *    substantially similar to the "NO WARRANTY" disclaimer below
1926f3cdf0SGordon Ross  *    ("Disclaimer") and any redistribution must be conditioned upon
2026f3cdf0SGordon Ross  *    including a substantially similar Disclaimer requirement for further
2126f3cdf0SGordon Ross  *    binary redistribution.
2226f3cdf0SGordon Ross  * 3. Neither the names of the above-listed copyright holders nor the names
2326f3cdf0SGordon Ross  *    of any contributors may be used to endorse or promote products derived
2426f3cdf0SGordon Ross  *    from this software without specific prior written permission.
25ae115bc7Smrj  *
2626f3cdf0SGordon Ross  * Alternatively, this software may be distributed under the terms of the
2726f3cdf0SGordon Ross  * GNU General Public License ("GPL") version 2 as published by the Free
2826f3cdf0SGordon Ross  * Software Foundation.
29ae115bc7Smrj  *
3026f3cdf0SGordon Ross  * NO WARRANTY
3126f3cdf0SGordon Ross  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
3226f3cdf0SGordon Ross  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3326f3cdf0SGordon Ross  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
3426f3cdf0SGordon Ross  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3526f3cdf0SGordon Ross  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3626f3cdf0SGordon Ross  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3726f3cdf0SGordon Ross  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3826f3cdf0SGordon Ross  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
3926f3cdf0SGordon Ross  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
4026f3cdf0SGordon Ross  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
4126f3cdf0SGordon Ross  * POSSIBILITY OF SUCH DAMAGES.
4226f3cdf0SGordon Ross  */
43ae115bc7Smrj 
44ae115bc7Smrj #include "acpi.h"
45aa2aa9a6SDana Myers #include "accommon.h"
46ae115bc7Smrj #include "acparser.h"
47ae115bc7Smrj #include "amlcode.h"
48ae115bc7Smrj #include "acdebug.h"
49ae115bc7Smrj 
50ae115bc7Smrj 
51ae115bc7Smrj #define _COMPONENT          ACPI_CA_DEBUGGER
52ae115bc7Smrj         ACPI_MODULE_NAME    ("dmwalk")
53ae115bc7Smrj 
54ae115bc7Smrj 
55ae115bc7Smrj #define DB_FULL_OP_INFO     "[%4.4s] @%5.5X #%4.4X:  "
56ae115bc7Smrj 
5757190917SDana Myers /* Stub for non-compiler code */
5857190917SDana Myers 
5957190917SDana Myers #ifndef ACPI_ASL_COMPILER
6057190917SDana Myers void
AcpiDmEmitExternals(void)6157190917SDana Myers AcpiDmEmitExternals (
6257190917SDana Myers     void)
6357190917SDana Myers {
6457190917SDana Myers     return;
6557190917SDana Myers }
6657190917SDana Myers #endif
6757190917SDana Myers 
68ae115bc7Smrj /* Local prototypes */
69ae115bc7Smrj 
70ae115bc7Smrj static ACPI_STATUS
71ae115bc7Smrj AcpiDmDescendingOp (
72ae115bc7Smrj     ACPI_PARSE_OBJECT       *Op,
73ae115bc7Smrj     UINT32                  Level,
74ae115bc7Smrj     void                    *Context);
75ae115bc7Smrj 
76ae115bc7Smrj static ACPI_STATUS
77ae115bc7Smrj AcpiDmAscendingOp (
78ae115bc7Smrj     ACPI_PARSE_OBJECT       *Op,
79ae115bc7Smrj     UINT32                  Level,
80ae115bc7Smrj     void                    *Context);
81ae115bc7Smrj 
82ae115bc7Smrj static UINT32
83ae115bc7Smrj AcpiDmBlockType (
84ae115bc7Smrj     ACPI_PARSE_OBJECT       *Op);
85ae115bc7Smrj 
86aa2aa9a6SDana Myers 
87ae115bc7Smrj /*******************************************************************************
88ae115bc7Smrj  *
89ae115bc7Smrj  * FUNCTION:    AcpiDmDisassemble
90ae115bc7Smrj  *
91ae115bc7Smrj  * PARAMETERS:  WalkState       - Current state
92ae115bc7Smrj  *              Origin          - Starting object
93ae115bc7Smrj  *              NumOpcodes      - Max number of opcodes to be displayed
94ae115bc7Smrj  *
95ae115bc7Smrj  * RETURN:      None
96ae115bc7Smrj  *
97ae115bc7Smrj  * DESCRIPTION: Disassemble parser object and its children. This is the
98ae115bc7Smrj  *              main entry point of the disassembler.
99ae115bc7Smrj  *
100ae115bc7Smrj  ******************************************************************************/
101ae115bc7Smrj 
102ae115bc7Smrj void
AcpiDmDisassemble(ACPI_WALK_STATE * WalkState,ACPI_PARSE_OBJECT * Origin,UINT32 NumOpcodes)103ae115bc7Smrj AcpiDmDisassemble (
104ae115bc7Smrj     ACPI_WALK_STATE         *WalkState,
105ae115bc7Smrj     ACPI_PARSE_OBJECT       *Origin,
106ae115bc7Smrj     UINT32                  NumOpcodes)
107ae115bc7Smrj {
108ae115bc7Smrj     ACPI_PARSE_OBJECT       *Op = Origin;
109ae115bc7Smrj     ACPI_OP_WALK_INFO       Info;
110ae115bc7Smrj 
111ae115bc7Smrj 
112ae115bc7Smrj     if (!Op)
113ae115bc7Smrj     {
114ae115bc7Smrj         return;
115ae115bc7Smrj     }
116ae115bc7Smrj 
117*cb565728SJerry Jelinek     memset (&Info, 0, sizeof (ACPI_OP_WALK_INFO));
118ae115bc7Smrj     Info.WalkState = WalkState;
119*cb565728SJerry Jelinek     Info.StartAml = Op->Common.Aml - sizeof (ACPI_TABLE_HEADER);
120*cb565728SJerry Jelinek     Info.AmlOffset = Op->Common.Aml - Info.StartAml;
121*cb565728SJerry Jelinek 
122ae115bc7Smrj     AcpiDmWalkParseTree (Op, AcpiDmDescendingOp, AcpiDmAscendingOp, &Info);
123ae115bc7Smrj     return;
124ae115bc7Smrj }
125ae115bc7Smrj 
126ae115bc7Smrj 
127ae115bc7Smrj /*******************************************************************************
128ae115bc7Smrj  *
129ae115bc7Smrj  * FUNCTION:    AcpiDmWalkParseTree
130ae115bc7Smrj  *
131ae115bc7Smrj  * PARAMETERS:  Op                      - Root Op object
132ae115bc7Smrj  *              DescendingCallback      - Called during tree descent
133ae115bc7Smrj  *              AscendingCallback       - Called during tree ascent
134ae115bc7Smrj  *              Context                 - To be passed to the callbacks
135ae115bc7Smrj  *
136ae115bc7Smrj  * RETURN:      Status from callback(s)
137ae115bc7Smrj  *
138ae115bc7Smrj  * DESCRIPTION: Walk the entire parse tree.
139ae115bc7Smrj  *
140ae115bc7Smrj  ******************************************************************************/
141ae115bc7Smrj 
142ae115bc7Smrj void
AcpiDmWalkParseTree(ACPI_PARSE_OBJECT * Op,ASL_WALK_CALLBACK DescendingCallback,ASL_WALK_CALLBACK AscendingCallback,void * Context)143ae115bc7Smrj AcpiDmWalkParseTree (
144ae115bc7Smrj     ACPI_PARSE_OBJECT       *Op,
145ae115bc7Smrj     ASL_WALK_CALLBACK       DescendingCallback,
146ae115bc7Smrj     ASL_WALK_CALLBACK       AscendingCallback,
147ae115bc7Smrj     void                    *Context)
148ae115bc7Smrj {
149ae115bc7Smrj     BOOLEAN                 NodePreviouslyVisited;
150ae115bc7Smrj     ACPI_PARSE_OBJECT       *StartOp = Op;
151ae115bc7Smrj     ACPI_STATUS             Status;
152ae115bc7Smrj     ACPI_PARSE_OBJECT       *Next;
153ae115bc7Smrj     ACPI_OP_WALK_INFO       *Info = Context;
154ae115bc7Smrj 
155ae115bc7Smrj 
156ae115bc7Smrj     Info->Level = 0;
157ae115bc7Smrj     NodePreviouslyVisited = FALSE;
158ae115bc7Smrj 
159ae115bc7Smrj     while (Op)
160ae115bc7Smrj     {
161ae115bc7Smrj         if (NodePreviouslyVisited)
162ae115bc7Smrj         {
163ae115bc7Smrj             if (AscendingCallback)
164ae115bc7Smrj             {
165ae115bc7Smrj                 Status = AscendingCallback (Op, Info->Level, Context);
166ae115bc7Smrj                 if (ACPI_FAILURE (Status))
167ae115bc7Smrj                 {
168ae115bc7Smrj                     return;
169ae115bc7Smrj                 }
170ae115bc7Smrj             }
171ae115bc7Smrj         }
172ae115bc7Smrj         else
173ae115bc7Smrj         {
174ae115bc7Smrj             /* Let the callback process the node */
175ae115bc7Smrj 
176ae115bc7Smrj             Status = DescendingCallback (Op, Info->Level, Context);
177ae115bc7Smrj             if (ACPI_SUCCESS (Status))
178ae115bc7Smrj             {
179ae115bc7Smrj                 /* Visit children first, once */
180ae115bc7Smrj 
181ae115bc7Smrj                 Next = AcpiPsGetArg (Op, 0);
182ae115bc7Smrj                 if (Next)
183ae115bc7Smrj                 {
184ae115bc7Smrj                     Info->Level++;
185ae115bc7Smrj                     Op = Next;
186ae115bc7Smrj                     continue;
187ae115bc7Smrj                 }
188ae115bc7Smrj             }
189ae115bc7Smrj             else if (Status != AE_CTRL_DEPTH)
190ae115bc7Smrj             {
191ae115bc7Smrj                 /* Exit immediately on any error */
192ae115bc7Smrj 
193ae115bc7Smrj                 return;
194ae115bc7Smrj             }
195ae115bc7Smrj         }
196ae115bc7Smrj 
197ae115bc7Smrj         /* Terminate walk at start op */
198ae115bc7Smrj 
199ae115bc7Smrj         if (Op == StartOp)
200ae115bc7Smrj         {
201ae115bc7Smrj             break;
202ae115bc7Smrj         }
203ae115bc7Smrj 
204ae115bc7Smrj         /* No more children, re-visit this node */
205ae115bc7Smrj 
206ae115bc7Smrj         if (!NodePreviouslyVisited)
207ae115bc7Smrj         {
208ae115bc7Smrj             NodePreviouslyVisited = TRUE;
209ae115bc7Smrj             continue;
210ae115bc7Smrj         }
211ae115bc7Smrj 
212ae115bc7Smrj         /* No more children, visit peers */
213ae115bc7Smrj 
214ae115bc7Smrj         if (Op->Common.Next)
215ae115bc7Smrj         {
216ae115bc7Smrj             Op = Op->Common.Next;
217ae115bc7Smrj             NodePreviouslyVisited = FALSE;
218ae115bc7Smrj         }
219ae115bc7Smrj         else
220ae115bc7Smrj         {
221ae115bc7Smrj             /* No peers, re-visit parent */
222ae115bc7Smrj 
223ae115bc7Smrj             if (Info->Level != 0 )
224ae115bc7Smrj             {
225ae115bc7Smrj                 Info->Level--;
226ae115bc7Smrj             }
227ae115bc7Smrj 
228ae115bc7Smrj             Op = Op->Common.Parent;
229ae115bc7Smrj             NodePreviouslyVisited = TRUE;
230ae115bc7Smrj         }
231ae115bc7Smrj     }
232ae115bc7Smrj 
233ae115bc7Smrj     /* If we get here, the walk completed with no errors */
234ae115bc7Smrj 
235ae115bc7Smrj     return;
236ae115bc7Smrj }
237ae115bc7Smrj 
238ae115bc7Smrj 
239ae115bc7Smrj /*******************************************************************************
240ae115bc7Smrj  *
241ae115bc7Smrj  * FUNCTION:    AcpiDmBlockType
242ae115bc7Smrj  *
243ae115bc7Smrj  * PARAMETERS:  Op              - Object to be examined
244ae115bc7Smrj  *
245ae115bc7Smrj  * RETURN:      BlockType - not a block, parens, braces, or even both.
246ae115bc7Smrj  *
247ae115bc7Smrj  * DESCRIPTION: Type of block for this op (parens or braces)
248ae115bc7Smrj  *
249ae115bc7Smrj  ******************************************************************************/
250ae115bc7Smrj 
251ae115bc7Smrj static UINT32
AcpiDmBlockType(ACPI_PARSE_OBJECT * Op)252ae115bc7Smrj AcpiDmBlockType (
253ae115bc7Smrj     ACPI_PARSE_OBJECT       *Op)
254ae115bc7Smrj {
255ae115bc7Smrj     const ACPI_OPCODE_INFO  *OpInfo;
256ae115bc7Smrj 
257ae115bc7Smrj 
258ae115bc7Smrj     if (!Op)
259ae115bc7Smrj     {
260ae115bc7Smrj         return (BLOCK_NONE);
261ae115bc7Smrj     }
262ae115bc7Smrj 
263ae115bc7Smrj     switch (Op->Common.AmlOpcode)
264ae115bc7Smrj     {
265ae115bc7Smrj     case AML_ELSE_OP:
266ae115bc7Smrj 
267ae115bc7Smrj         return (BLOCK_BRACE);
268ae115bc7Smrj 
269ae115bc7Smrj     case AML_METHOD_OP:
270ae115bc7Smrj     case AML_DEVICE_OP:
271ae115bc7Smrj     case AML_SCOPE_OP:
272ae115bc7Smrj     case AML_PROCESSOR_OP:
273ae115bc7Smrj     case AML_POWER_RES_OP:
274ae115bc7Smrj     case AML_THERMAL_ZONE_OP:
275ae115bc7Smrj     case AML_IF_OP:
276ae115bc7Smrj     case AML_WHILE_OP:
277ae115bc7Smrj     case AML_FIELD_OP:
278ae115bc7Smrj     case AML_INDEX_FIELD_OP:
279ae115bc7Smrj     case AML_BANK_FIELD_OP:
280ae115bc7Smrj 
281ae115bc7Smrj         return (BLOCK_PAREN | BLOCK_BRACE);
282ae115bc7Smrj 
283ae115bc7Smrj     case AML_BUFFER_OP:
284ae115bc7Smrj 
285*cb565728SJerry Jelinek         if ((Op->Common.DisasmOpcode == ACPI_DASM_UNICODE) ||
286*cb565728SJerry Jelinek             (Op->Common.DisasmOpcode == ACPI_DASM_UUID) ||
287*cb565728SJerry Jelinek             (Op->Common.DisasmOpcode == ACPI_DASM_PLD_METHOD))
288ae115bc7Smrj         {
289ae115bc7Smrj             return (BLOCK_NONE);
290ae115bc7Smrj         }
291ae115bc7Smrj 
292ae115bc7Smrj         /*lint -fallthrough */
293ae115bc7Smrj 
294ae115bc7Smrj     case AML_PACKAGE_OP:
295ae115bc7Smrj     case AML_VAR_PACKAGE_OP:
296ae115bc7Smrj 
297ae115bc7Smrj         return (BLOCK_PAREN | BLOCK_BRACE);
298ae115bc7Smrj 
299ae115bc7Smrj     case AML_EVENT_OP:
300ae115bc7Smrj 
301ae115bc7Smrj         return (BLOCK_PAREN);
302ae115bc7Smrj 
303*cb565728SJerry Jelinek     case AML_INT_METHODCALL_OP:
304*cb565728SJerry Jelinek 
305*cb565728SJerry Jelinek         if (Op->Common.Parent &&
306*cb565728SJerry Jelinek             ((Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||
307*cb565728SJerry Jelinek              (Op->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP)))
308*cb565728SJerry Jelinek         {
309*cb565728SJerry Jelinek             /* This is a reference to a method, not an invocation */
310*cb565728SJerry Jelinek 
311*cb565728SJerry Jelinek             return (BLOCK_NONE);
312*cb565728SJerry Jelinek         }
313*cb565728SJerry Jelinek 
314*cb565728SJerry Jelinek         /*lint -fallthrough */
315*cb565728SJerry Jelinek 
316ae115bc7Smrj     default:
317ae115bc7Smrj 
318ae115bc7Smrj         OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
319ae115bc7Smrj         if (OpInfo->Flags & AML_HAS_ARGS)
320ae115bc7Smrj         {
321ae115bc7Smrj             return (BLOCK_PAREN);
322ae115bc7Smrj         }
323ae115bc7Smrj 
324ae115bc7Smrj         return (BLOCK_NONE);
325ae115bc7Smrj     }
326ae115bc7Smrj }
327ae115bc7Smrj 
328ae115bc7Smrj 
329ae115bc7Smrj /*******************************************************************************
330ae115bc7Smrj  *
331ae115bc7Smrj  * FUNCTION:    AcpiDmListType
332ae115bc7Smrj  *
333ae115bc7Smrj  * PARAMETERS:  Op              - Object to be examined
334ae115bc7Smrj  *
335ae115bc7Smrj  * RETURN:      ListType - has commas or not.
336ae115bc7Smrj  *
337ae115bc7Smrj  * DESCRIPTION: Type of block for this op (parens or braces)
338ae115bc7Smrj  *
339ae115bc7Smrj  ******************************************************************************/
340ae115bc7Smrj 
341ae115bc7Smrj UINT32
AcpiDmListType(ACPI_PARSE_OBJECT * Op)342ae115bc7Smrj AcpiDmListType (
343ae115bc7Smrj     ACPI_PARSE_OBJECT       *Op)
344ae115bc7Smrj {
345ae115bc7Smrj     const ACPI_OPCODE_INFO  *OpInfo;
346ae115bc7Smrj 
347ae115bc7Smrj 
348ae115bc7Smrj     if (!Op)
349ae115bc7Smrj     {
350ae115bc7Smrj         return (BLOCK_NONE);
351ae115bc7Smrj     }
352ae115bc7Smrj 
353ae115bc7Smrj     switch (Op->Common.AmlOpcode)
354ae115bc7Smrj     {
355ae115bc7Smrj 
356ae115bc7Smrj     case AML_ELSE_OP:
357ae115bc7Smrj     case AML_METHOD_OP:
358ae115bc7Smrj     case AML_DEVICE_OP:
359ae115bc7Smrj     case AML_SCOPE_OP:
360ae115bc7Smrj     case AML_POWER_RES_OP:
361ae115bc7Smrj     case AML_PROCESSOR_OP:
362ae115bc7Smrj     case AML_THERMAL_ZONE_OP:
363ae115bc7Smrj     case AML_IF_OP:
364ae115bc7Smrj     case AML_WHILE_OP:
365ae115bc7Smrj     case AML_FIELD_OP:
366ae115bc7Smrj     case AML_INDEX_FIELD_OP:
367ae115bc7Smrj     case AML_BANK_FIELD_OP:
368ae115bc7Smrj 
369ae115bc7Smrj         return (BLOCK_NONE);
370ae115bc7Smrj 
371ae115bc7Smrj     case AML_BUFFER_OP:
372ae115bc7Smrj     case AML_PACKAGE_OP:
373ae115bc7Smrj     case AML_VAR_PACKAGE_OP:
374ae115bc7Smrj 
375ae115bc7Smrj         return (BLOCK_COMMA_LIST);
376ae115bc7Smrj 
377ae115bc7Smrj     default:
378ae115bc7Smrj 
379ae115bc7Smrj         OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
380ae115bc7Smrj         if (OpInfo->Flags & AML_HAS_ARGS)
381ae115bc7Smrj         {
382ae115bc7Smrj             return (BLOCK_COMMA_LIST);
383ae115bc7Smrj         }
384ae115bc7Smrj 
385ae115bc7Smrj         return (BLOCK_NONE);
386ae115bc7Smrj     }
387ae115bc7Smrj }
388ae115bc7Smrj 
389ae115bc7Smrj 
390ae115bc7Smrj /*******************************************************************************
391ae115bc7Smrj  *
392ae115bc7Smrj  * FUNCTION:    AcpiDmDescendingOp
393ae115bc7Smrj  *
394ae115bc7Smrj  * PARAMETERS:  ASL_WALK_CALLBACK
395ae115bc7Smrj  *
396ae115bc7Smrj  * RETURN:      Status
397ae115bc7Smrj  *
398ae115bc7Smrj  * DESCRIPTION: First visitation of a parse object during tree descent.
399ae115bc7Smrj  *              Decode opcode name and begin parameter list(s), if any.
400ae115bc7Smrj  *
401ae115bc7Smrj  ******************************************************************************/
402ae115bc7Smrj 
403ae115bc7Smrj static ACPI_STATUS
AcpiDmDescendingOp(ACPI_PARSE_OBJECT * Op,UINT32 Level,void * Context)404ae115bc7Smrj AcpiDmDescendingOp (
405ae115bc7Smrj     ACPI_PARSE_OBJECT       *Op,
406ae115bc7Smrj     UINT32                  Level,
407ae115bc7Smrj     void                    *Context)
408ae115bc7Smrj {
409ae115bc7Smrj     ACPI_OP_WALK_INFO       *Info = Context;
410ae115bc7Smrj     const ACPI_OPCODE_INFO  *OpInfo;
411ae115bc7Smrj     UINT32                  Name;
412ae115bc7Smrj     ACPI_PARSE_OBJECT       *NextOp;
413*cb565728SJerry Jelinek     ACPI_PARSE_OBJECT       *NextOp2;
414*cb565728SJerry Jelinek     UINT32                  AmlOffset;
415ae115bc7Smrj 
416ae115bc7Smrj 
417*cb565728SJerry Jelinek     OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
418*cb565728SJerry Jelinek 
419*cb565728SJerry Jelinek     /* Listing support to dump the AML code after the ASL statement */
420*cb565728SJerry Jelinek 
421*cb565728SJerry Jelinek     if (AcpiGbl_DmOpt_Listing)
422*cb565728SJerry Jelinek     {
423*cb565728SJerry Jelinek         /* We only care about these classes of objects */
424*cb565728SJerry Jelinek 
425*cb565728SJerry Jelinek         if ((OpInfo->Class == AML_CLASS_NAMED_OBJECT) ||
426*cb565728SJerry Jelinek             (OpInfo->Class == AML_CLASS_CONTROL) ||
427*cb565728SJerry Jelinek             (OpInfo->Class == AML_CLASS_CREATE) ||
428*cb565728SJerry Jelinek             ((OpInfo->Class == AML_CLASS_EXECUTE) && (!Op->Common.Next)))
429*cb565728SJerry Jelinek         {
430*cb565728SJerry Jelinek             if (AcpiGbl_DmOpt_Listing && Info->PreviousAml)
431*cb565728SJerry Jelinek             {
432*cb565728SJerry Jelinek                 /* Dump the AML byte code for the previous Op */
433*cb565728SJerry Jelinek 
434*cb565728SJerry Jelinek                 if (Op->Common.Aml > Info->PreviousAml)
435*cb565728SJerry Jelinek                 {
436*cb565728SJerry Jelinek                     AcpiOsPrintf ("\n");
437*cb565728SJerry Jelinek                     AcpiUtDumpBuffer (
438*cb565728SJerry Jelinek                         (Info->StartAml + Info->AmlOffset),
439*cb565728SJerry Jelinek                         (Op->Common.Aml - Info->PreviousAml),
440*cb565728SJerry Jelinek                         DB_BYTE_DISPLAY, Info->AmlOffset);
441*cb565728SJerry Jelinek                     AcpiOsPrintf ("\n");
442*cb565728SJerry Jelinek                 }
443*cb565728SJerry Jelinek 
444*cb565728SJerry Jelinek                 Info->AmlOffset = (Op->Common.Aml - Info->StartAml);
445*cb565728SJerry Jelinek             }
446*cb565728SJerry Jelinek 
447*cb565728SJerry Jelinek             Info->PreviousAml = Op->Common.Aml;
448*cb565728SJerry Jelinek         }
449*cb565728SJerry Jelinek     }
450*cb565728SJerry Jelinek 
451ae115bc7Smrj     if (Op->Common.DisasmFlags & ACPI_PARSEOP_IGNORE)
452ae115bc7Smrj     {
453ae115bc7Smrj         /* Ignore this op -- it was handled elsewhere */
454ae115bc7Smrj 
455ae115bc7Smrj         return (AE_CTRL_DEPTH);
456ae115bc7Smrj     }
457ae115bc7Smrj 
458*cb565728SJerry Jelinek     if (Op->Common.AmlOpcode == AML_IF_OP)
459*cb565728SJerry Jelinek     {
460*cb565728SJerry Jelinek         NextOp = AcpiPsGetDepthNext (NULL, Op);
461*cb565728SJerry Jelinek         if (NextOp)
462*cb565728SJerry Jelinek         {
463*cb565728SJerry Jelinek             NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST;
464*cb565728SJerry Jelinek 
465*cb565728SJerry Jelinek             /* Don't emit the actual embedded externals unless asked */
466*cb565728SJerry Jelinek 
467*cb565728SJerry Jelinek             if (!AcpiGbl_DmEmitExternalOpcodes)
468*cb565728SJerry Jelinek             {
469*cb565728SJerry Jelinek                 /*
470*cb565728SJerry Jelinek                  * A Zero predicate indicates the possibility of one or more
471*cb565728SJerry Jelinek                  * External() opcodes within the If() block.
472*cb565728SJerry Jelinek                  */
473*cb565728SJerry Jelinek                 if (NextOp->Common.AmlOpcode == AML_ZERO_OP)
474*cb565728SJerry Jelinek                 {
475*cb565728SJerry Jelinek                     NextOp2 = NextOp->Common.Next;
476*cb565728SJerry Jelinek 
477*cb565728SJerry Jelinek                     if (NextOp2 &&
478*cb565728SJerry Jelinek                         (NextOp2->Common.AmlOpcode == AML_EXTERNAL_OP))
479*cb565728SJerry Jelinek                     {
480*cb565728SJerry Jelinek                         /* Ignore the If 0 block and all children */
481*cb565728SJerry Jelinek 
482*cb565728SJerry Jelinek                         Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
483*cb565728SJerry Jelinek                         return (AE_CTRL_DEPTH);
484*cb565728SJerry Jelinek                     }
485*cb565728SJerry Jelinek                 }
486*cb565728SJerry Jelinek             }
487*cb565728SJerry Jelinek         }
488*cb565728SJerry Jelinek     }
489*cb565728SJerry Jelinek 
490ae115bc7Smrj     /* Level 0 is at the Definition Block level */
491ae115bc7Smrj 
492ae115bc7Smrj     if (Level == 0)
493ae115bc7Smrj     {
494ae115bc7Smrj         /* In verbose mode, print the AML offset, opcode and depth count */
495ae115bc7Smrj 
496ae115bc7Smrj         if (Info->WalkState)
497ae115bc7Smrj         {
498*cb565728SJerry Jelinek             AmlOffset = (UINT32) ACPI_PTR_DIFF (Op->Common.Aml,
499*cb565728SJerry Jelinek                 Info->WalkState->ParserState.AmlStart);
500*cb565728SJerry Jelinek             if (AcpiGbl_DmOpt_Verbose)
501*cb565728SJerry Jelinek             {
502*cb565728SJerry Jelinek                 AcpiOsPrintf (DB_FULL_OP_INFO,
503ae115bc7Smrj                     (Info->WalkState->MethodNode ?
504ae115bc7Smrj                         Info->WalkState->MethodNode->Name.Ascii : "   "),
505*cb565728SJerry Jelinek                     AmlOffset, (UINT32) Op->Common.AmlOpcode);
506*cb565728SJerry Jelinek             }
507ae115bc7Smrj         }
508ae115bc7Smrj 
509ae115bc7Smrj         if (Op->Common.AmlOpcode == AML_SCOPE_OP)
510ae115bc7Smrj         {
511ae115bc7Smrj             /* This is the beginning of the Definition Block */
512ae115bc7Smrj 
513ae115bc7Smrj             AcpiOsPrintf ("{\n");
514ae115bc7Smrj 
515ae115bc7Smrj             /* Emit all External() declarations here */
516ae115bc7Smrj 
51757190917SDana Myers             AcpiDmEmitExternals ();
518ae115bc7Smrj             return (AE_OK);
519ae115bc7Smrj         }
520ae115bc7Smrj     }
521ae115bc7Smrj     else if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
522*cb565728SJerry Jelinek          (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMETER_LIST)) &&
523*cb565728SJerry Jelinek          (!(Op->Common.DisasmFlags & ACPI_PARSEOP_ELSEIF)) &&
524ae115bc7Smrj          (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP))
525ae115bc7Smrj     {
526ae115bc7Smrj         /*
527ae115bc7Smrj          * This is a first-level element of a term list,
528ae115bc7Smrj          * indent a new line
529ae115bc7Smrj          */
530*cb565728SJerry Jelinek         switch (Op->Common.AmlOpcode)
531*cb565728SJerry Jelinek         {
532*cb565728SJerry Jelinek         case AML_NOOP_OP:
533*cb565728SJerry Jelinek             /*
534*cb565728SJerry Jelinek              * Optionally just ignore this opcode. Some tables use
535*cb565728SJerry Jelinek              * NoOp opcodes for "padding" out packages that the BIOS
536*cb565728SJerry Jelinek              * changes dynamically. This can leave hundreds or
537*cb565728SJerry Jelinek              * thousands of NoOp opcodes that if disassembled,
538*cb565728SJerry Jelinek              * cannot be compiled because they are syntactically
539*cb565728SJerry Jelinek              * incorrect.
540*cb565728SJerry Jelinek              */
541*cb565728SJerry Jelinek             if (AcpiGbl_IgnoreNoopOperator)
542*cb565728SJerry Jelinek             {
543*cb565728SJerry Jelinek                 Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
544*cb565728SJerry Jelinek                 return (AE_OK);
545*cb565728SJerry Jelinek             }
546*cb565728SJerry Jelinek 
547*cb565728SJerry Jelinek             /* Fallthrough */
548*cb565728SJerry Jelinek 
549*cb565728SJerry Jelinek         default:
550*cb565728SJerry Jelinek 
551ae115bc7Smrj             AcpiDmIndent (Level);
552*cb565728SJerry Jelinek             break;
553*cb565728SJerry Jelinek         }
554*cb565728SJerry Jelinek 
555ae115bc7Smrj         Info->LastLevel = Level;
556ae115bc7Smrj         Info->Count = 0;
557ae115bc7Smrj     }
558ae115bc7Smrj 
559ae115bc7Smrj     /*
560ae115bc7Smrj      * This is an inexpensive mechanism to try and keep lines from getting
561ae115bc7Smrj      * too long. When the limit is hit, start a new line at the previous
562ae115bc7Smrj      * indent plus one. A better but more expensive mechanism would be to
563ae115bc7Smrj      * keep track of the current column.
564ae115bc7Smrj      */
565ae115bc7Smrj     Info->Count++;
566*cb565728SJerry Jelinek     if (Info->Count /* +Info->LastLevel */ > 12)
567ae115bc7Smrj     {
568ae115bc7Smrj         Info->Count = 0;
569ae115bc7Smrj         AcpiOsPrintf ("\n");
570ae115bc7Smrj         AcpiDmIndent (Info->LastLevel + 1);
571ae115bc7Smrj     }
572ae115bc7Smrj 
573*cb565728SJerry Jelinek     /* If ASL+ is enabled, check for a C-style operator */
574*cb565728SJerry Jelinek 
575*cb565728SJerry Jelinek     if (AcpiDmCheckForSymbolicOpcode (Op, Info))
576*cb565728SJerry Jelinek     {
577*cb565728SJerry Jelinek         return (AE_OK);
578*cb565728SJerry Jelinek     }
579*cb565728SJerry Jelinek 
580ae115bc7Smrj     /* Print the opcode name */
581ae115bc7Smrj 
582ae115bc7Smrj     AcpiDmDisassembleOneOp (NULL, Info, Op);
583ae115bc7Smrj 
584*cb565728SJerry Jelinek     if ((Op->Common.DisasmOpcode == ACPI_DASM_LNOT_PREFIX) ||
585*cb565728SJerry Jelinek         (Op->Common.AmlOpcode == AML_INT_CONNECTION_OP))
586ae115bc7Smrj     {
587ae115bc7Smrj         return (AE_OK);
588ae115bc7Smrj     }
589ae115bc7Smrj 
590ae115bc7Smrj     if ((Op->Common.AmlOpcode == AML_NAME_OP) ||
591ae115bc7Smrj         (Op->Common.AmlOpcode == AML_RETURN_OP))
592ae115bc7Smrj     {
593ae115bc7Smrj         Info->Level--;
594ae115bc7Smrj     }
595ae115bc7Smrj 
596ae115bc7Smrj     /* Start the opcode argument list if necessary */
597ae115bc7Smrj 
598ae115bc7Smrj     if ((OpInfo->Flags & AML_HAS_ARGS) ||
599ae115bc7Smrj         (Op->Common.AmlOpcode == AML_EVENT_OP))
600ae115bc7Smrj     {
601ae115bc7Smrj         /* This opcode has an argument list */
602ae115bc7Smrj 
603ae115bc7Smrj         if (AcpiDmBlockType (Op) & BLOCK_PAREN)
604ae115bc7Smrj         {
605ae115bc7Smrj             AcpiOsPrintf (" (");
606ae115bc7Smrj         }
607ae115bc7Smrj 
608ae115bc7Smrj         /* If this is a named opcode, print the associated name value */
609ae115bc7Smrj 
610ae115bc7Smrj         if (OpInfo->Flags & AML_NAMED)
611ae115bc7Smrj         {
612ae115bc7Smrj             switch (Op->Common.AmlOpcode)
613ae115bc7Smrj             {
614ae115bc7Smrj             case AML_ALIAS_OP:
615ae115bc7Smrj 
616ae115bc7Smrj                 NextOp = AcpiPsGetDepthNext (NULL, Op);
617ae115bc7Smrj                 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
618ae115bc7Smrj                 AcpiDmNamestring (NextOp->Common.Value.Name);
619ae115bc7Smrj                 AcpiOsPrintf (", ");
620ae115bc7Smrj 
621ae115bc7Smrj                 /*lint -fallthrough */
622ae115bc7Smrj 
623ae115bc7Smrj             default:
624ae115bc7Smrj 
625ae115bc7Smrj                 Name = AcpiPsGetName (Op);
626ae115bc7Smrj                 if (Op->Named.Path)
627ae115bc7Smrj                 {
628ae115bc7Smrj                     AcpiDmNamestring ((char *) Op->Named.Path);
629ae115bc7Smrj                 }
630ae115bc7Smrj                 else
631ae115bc7Smrj                 {
632db2bae30SDana Myers                     AcpiDmDumpName (Name);
633ae115bc7Smrj                 }
634ae115bc7Smrj 
635ae115bc7Smrj                 if (Op->Common.AmlOpcode != AML_INT_NAMEDFIELD_OP)
636ae115bc7Smrj                 {
637*cb565728SJerry Jelinek                     if (AcpiGbl_DmOpt_Verbose)
638ae115bc7Smrj                     {
639ae115bc7Smrj                         (void) AcpiPsDisplayObjectPathname (NULL, Op);
640ae115bc7Smrj                     }
641ae115bc7Smrj                 }
642ae115bc7Smrj                 break;
643ae115bc7Smrj             }
644ae115bc7Smrj 
645ae115bc7Smrj             switch (Op->Common.AmlOpcode)
646ae115bc7Smrj             {
647ae115bc7Smrj             case AML_METHOD_OP:
648ae115bc7Smrj 
649ae115bc7Smrj                 AcpiDmMethodFlags (Op);
650ae115bc7Smrj                 AcpiOsPrintf (")");
651ae115bc7Smrj 
652*cb565728SJerry Jelinek                 /* Emit description comment for Method() with a predefined ACPI name */
653*cb565728SJerry Jelinek 
654*cb565728SJerry Jelinek                 AcpiDmPredefinedDescription (Op);
655*cb565728SJerry Jelinek                 break;
656ae115bc7Smrj 
657ae115bc7Smrj             case AML_NAME_OP:
658ae115bc7Smrj 
659ae115bc7Smrj                 /* Check for _HID and related EISAID() */
660ae115bc7Smrj 
661*cb565728SJerry Jelinek                 AcpiDmCheckForHardwareId (Op);
662ae115bc7Smrj                 AcpiOsPrintf (", ");
663ae115bc7Smrj                 break;
664ae115bc7Smrj 
665ae115bc7Smrj             case AML_REGION_OP:
666ae115bc7Smrj 
667ae115bc7Smrj                 AcpiDmRegionFlags (Op);
668ae115bc7Smrj                 break;
669ae115bc7Smrj 
670ae115bc7Smrj             case AML_POWER_RES_OP:
671ae115bc7Smrj 
672ae115bc7Smrj                 /* Mark the next two Ops as part of the parameter list */
673ae115bc7Smrj 
674ae115bc7Smrj                 AcpiOsPrintf (", ");
675ae115bc7Smrj                 NextOp = AcpiPsGetDepthNext (NULL, Op);
676*cb565728SJerry Jelinek                 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST;
677ae115bc7Smrj 
678ae115bc7Smrj                 NextOp = NextOp->Common.Next;
679*cb565728SJerry Jelinek                 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST;
680ae115bc7Smrj                 return (AE_OK);
681ae115bc7Smrj 
682ae115bc7Smrj             case AML_PROCESSOR_OP:
683ae115bc7Smrj 
684ae115bc7Smrj                 /* Mark the next three Ops as part of the parameter list */
685ae115bc7Smrj 
686ae115bc7Smrj                 AcpiOsPrintf (", ");
687ae115bc7Smrj                 NextOp = AcpiPsGetDepthNext (NULL, Op);
688*cb565728SJerry Jelinek                 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST;
689ae115bc7Smrj 
690ae115bc7Smrj                 NextOp = NextOp->Common.Next;
691*cb565728SJerry Jelinek                 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST;
692ae115bc7Smrj 
693ae115bc7Smrj                 NextOp = NextOp->Common.Next;
694*cb565728SJerry Jelinek                 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST;
695ae115bc7Smrj                 return (AE_OK);
696ae115bc7Smrj 
697ae115bc7Smrj             case AML_MUTEX_OP:
698ae115bc7Smrj             case AML_DATA_REGION_OP:
699ae115bc7Smrj 
700ae115bc7Smrj                 AcpiOsPrintf (", ");
701ae115bc7Smrj                 return (AE_OK);
702ae115bc7Smrj 
703ae115bc7Smrj             case AML_EVENT_OP:
704ae115bc7Smrj             case AML_ALIAS_OP:
705ae115bc7Smrj 
706ae115bc7Smrj                 return (AE_OK);
707ae115bc7Smrj 
708ae115bc7Smrj             case AML_SCOPE_OP:
709ae115bc7Smrj             case AML_DEVICE_OP:
710ae115bc7Smrj             case AML_THERMAL_ZONE_OP:
711ae115bc7Smrj 
712ae115bc7Smrj                 AcpiOsPrintf (")");
713ae115bc7Smrj                 break;
714ae115bc7Smrj 
715ae115bc7Smrj             default:
716ae115bc7Smrj 
717*cb565728SJerry Jelinek                 AcpiOsPrintf ("*** Unhandled named opcode %X\n",
718*cb565728SJerry Jelinek                     Op->Common.AmlOpcode);
719ae115bc7Smrj                 break;
720ae115bc7Smrj             }
721ae115bc7Smrj         }
722ae115bc7Smrj 
723ae115bc7Smrj         else switch (Op->Common.AmlOpcode)
724ae115bc7Smrj         {
725ae115bc7Smrj         case AML_FIELD_OP:
726ae115bc7Smrj         case AML_BANK_FIELD_OP:
727ae115bc7Smrj         case AML_INDEX_FIELD_OP:
728ae115bc7Smrj 
729ae115bc7Smrj             Info->BitOffset = 0;
730ae115bc7Smrj 
731ae115bc7Smrj             /* Name of the parent OperationRegion */
732ae115bc7Smrj 
733ae115bc7Smrj             NextOp = AcpiPsGetDepthNext (NULL, Op);
734ae115bc7Smrj             AcpiDmNamestring (NextOp->Common.Value.Name);
735ae115bc7Smrj             AcpiOsPrintf (", ");
736ae115bc7Smrj             NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
737ae115bc7Smrj 
738ae115bc7Smrj             switch (Op->Common.AmlOpcode)
739ae115bc7Smrj             {
740ae115bc7Smrj             case AML_BANK_FIELD_OP:
741ae115bc7Smrj 
742ae115bc7Smrj                 /* Namestring - Bank Name */
743ae115bc7Smrj 
744ae115bc7Smrj                 NextOp = AcpiPsGetDepthNext (NULL, NextOp);
745ae115bc7Smrj                 AcpiDmNamestring (NextOp->Common.Value.Name);
746ae115bc7Smrj                 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
747ae115bc7Smrj                 AcpiOsPrintf (", ");
748ae115bc7Smrj 
749ae115bc7Smrj                 /*
750ae115bc7Smrj                  * Bank Value. This is a TermArg in the middle of the parameter
751ae115bc7Smrj                  * list, must handle it here.
752ae115bc7Smrj                  *
753*cb565728SJerry Jelinek                  * Disassemble the TermArg parse tree. ACPI_PARSEOP_PARAMETER_LIST
754ae115bc7Smrj                  * eliminates newline in the output.
755ae115bc7Smrj                  */
756ae115bc7Smrj                 NextOp = NextOp->Common.Next;
757ae115bc7Smrj 
758*cb565728SJerry Jelinek                 Info->Flags = ACPI_PARSEOP_PARAMETER_LIST;
759*cb565728SJerry Jelinek                 AcpiDmWalkParseTree (NextOp, AcpiDmDescendingOp,
760*cb565728SJerry Jelinek                     AcpiDmAscendingOp, Info);
761ae115bc7Smrj                 Info->Flags = 0;
762ae115bc7Smrj                 Info->Level = Level;
763ae115bc7Smrj 
764ae115bc7Smrj                 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
765ae115bc7Smrj                 AcpiOsPrintf (", ");
766ae115bc7Smrj                 break;
767ae115bc7Smrj 
768ae115bc7Smrj             case AML_INDEX_FIELD_OP:
769ae115bc7Smrj 
770ae115bc7Smrj                 /* Namestring - Data Name */
771ae115bc7Smrj 
772ae115bc7Smrj                 NextOp = AcpiPsGetDepthNext (NULL, NextOp);
773ae115bc7Smrj                 AcpiDmNamestring (NextOp->Common.Value.Name);
774ae115bc7Smrj                 AcpiOsPrintf (", ");
775ae115bc7Smrj                 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
776ae115bc7Smrj                 break;
777ae115bc7Smrj 
778ae115bc7Smrj             default:
779ae115bc7Smrj 
780ae115bc7Smrj                 break;
781ae115bc7Smrj             }
782ae115bc7Smrj 
783ae115bc7Smrj             AcpiDmFieldFlags (NextOp);
784ae115bc7Smrj             break;
785ae115bc7Smrj 
786ae115bc7Smrj         case AML_BUFFER_OP:
787ae115bc7Smrj 
788ae115bc7Smrj             /* The next op is the size parameter */
789ae115bc7Smrj 
790ae115bc7Smrj             NextOp = AcpiPsGetDepthNext (NULL, Op);
791ae115bc7Smrj             if (!NextOp)
792ae115bc7Smrj             {
793ae115bc7Smrj                 /* Single-step support */
794ae115bc7Smrj 
795ae115bc7Smrj                 return (AE_OK);
796ae115bc7Smrj             }
797ae115bc7Smrj 
798ae115bc7Smrj             if (Op->Common.DisasmOpcode == ACPI_DASM_RESOURCE)
799ae115bc7Smrj             {
800ae115bc7Smrj                 /*
801ae115bc7Smrj                  * We have a resource list. Don't need to output
802ae115bc7Smrj                  * the buffer size Op. Open up a new block
803ae115bc7Smrj                  */
804ae115bc7Smrj                 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
805ae115bc7Smrj                 NextOp = NextOp->Common.Next;
806*cb565728SJerry Jelinek                 AcpiOsPrintf (")");
807*cb565728SJerry Jelinek 
808*cb565728SJerry Jelinek                 /* Emit description comment for Name() with a predefined ACPI name */
809*cb565728SJerry Jelinek 
810*cb565728SJerry Jelinek                 AcpiDmPredefinedDescription (Op->Asl.Parent);
811*cb565728SJerry Jelinek 
812*cb565728SJerry Jelinek                 AcpiOsPrintf ("\n");
813ae115bc7Smrj                 AcpiDmIndent (Info->Level);
814ae115bc7Smrj                 AcpiOsPrintf ("{\n");
815ae115bc7Smrj                 return (AE_OK);
816ae115bc7Smrj             }
817ae115bc7Smrj 
818ae115bc7Smrj             /* Normal Buffer, mark size as in the parameter list */
819ae115bc7Smrj 
820*cb565728SJerry Jelinek             NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST;
821ae115bc7Smrj             return (AE_OK);
822ae115bc7Smrj 
823ae115bc7Smrj         case AML_IF_OP:
824*cb565728SJerry Jelinek         case AML_VAR_PACKAGE_OP:
825ae115bc7Smrj         case AML_WHILE_OP:
826ae115bc7Smrj 
827ae115bc7Smrj             /* The next op is the size or predicate parameter */
828ae115bc7Smrj 
829ae115bc7Smrj             NextOp = AcpiPsGetDepthNext (NULL, Op);
830ae115bc7Smrj             if (NextOp)
831ae115bc7Smrj             {
832*cb565728SJerry Jelinek                 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST;
833ae115bc7Smrj             }
834ae115bc7Smrj             return (AE_OK);
835ae115bc7Smrj 
836ae115bc7Smrj         case AML_PACKAGE_OP:
837ae115bc7Smrj 
838*cb565728SJerry Jelinek             /* The next op is the size parameter */
839ae115bc7Smrj 
840ae115bc7Smrj             NextOp = AcpiPsGetDepthNext (NULL, Op);
841ae115bc7Smrj             if (NextOp)
842ae115bc7Smrj             {
843*cb565728SJerry Jelinek                 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST;
844ae115bc7Smrj             }
845ae115bc7Smrj             return (AE_OK);
846ae115bc7Smrj 
847ae115bc7Smrj         case AML_MATCH_OP:
848ae115bc7Smrj 
849ae115bc7Smrj             AcpiDmMatchOp (Op);
850ae115bc7Smrj             break;
851ae115bc7Smrj 
852ae115bc7Smrj         default:
853ae115bc7Smrj 
854ae115bc7Smrj             break;
855ae115bc7Smrj         }
856ae115bc7Smrj 
857ae115bc7Smrj         if (AcpiDmBlockType (Op) & BLOCK_BRACE)
858ae115bc7Smrj         {
859ae115bc7Smrj             AcpiOsPrintf ("\n");
860ae115bc7Smrj             AcpiDmIndent (Level);
861ae115bc7Smrj             AcpiOsPrintf ("{\n");
862ae115bc7Smrj         }
863ae115bc7Smrj     }
864ae115bc7Smrj 
865ae115bc7Smrj     return (AE_OK);
866ae115bc7Smrj }
867ae115bc7Smrj 
868ae115bc7Smrj 
869ae115bc7Smrj /*******************************************************************************
870ae115bc7Smrj  *
871ae115bc7Smrj  * FUNCTION:    AcpiDmAscendingOp
872ae115bc7Smrj  *
873ae115bc7Smrj  * PARAMETERS:  ASL_WALK_CALLBACK
874ae115bc7Smrj  *
875ae115bc7Smrj  * RETURN:      Status
876ae115bc7Smrj  *
877ae115bc7Smrj  * DESCRIPTION: Second visitation of a parse object, during ascent of parse
878ae115bc7Smrj  *              tree. Close out any parameter lists and complete the opcode.
879ae115bc7Smrj  *
880ae115bc7Smrj  ******************************************************************************/
881ae115bc7Smrj 
882ae115bc7Smrj static ACPI_STATUS
AcpiDmAscendingOp(ACPI_PARSE_OBJECT * Op,UINT32 Level,void * Context)883ae115bc7Smrj AcpiDmAscendingOp (
884ae115bc7Smrj     ACPI_PARSE_OBJECT       *Op,
885ae115bc7Smrj     UINT32                  Level,
886ae115bc7Smrj     void                    *Context)
887ae115bc7Smrj {
888ae115bc7Smrj     ACPI_OP_WALK_INFO       *Info = Context;
889*cb565728SJerry Jelinek     ACPI_PARSE_OBJECT       *ParentOp;
890ae115bc7Smrj 
891ae115bc7Smrj 
892ae115bc7Smrj     if (Op->Common.DisasmFlags & ACPI_PARSEOP_IGNORE)
893ae115bc7Smrj     {
894ae115bc7Smrj         /* Ignore this op -- it was handled elsewhere */
895ae115bc7Smrj 
896ae115bc7Smrj         return (AE_OK);
897ae115bc7Smrj     }
898ae115bc7Smrj 
899ae115bc7Smrj     if ((Level == 0) && (Op->Common.AmlOpcode == AML_SCOPE_OP))
900ae115bc7Smrj     {
901ae115bc7Smrj         /* Indicates the end of the current descriptor block (table) */
902ae115bc7Smrj 
903ae115bc7Smrj         AcpiOsPrintf ("}\n\n");
904ae115bc7Smrj         return (AE_OK);
905ae115bc7Smrj     }
906ae115bc7Smrj 
907ae115bc7Smrj     switch (AcpiDmBlockType (Op))
908ae115bc7Smrj     {
909ae115bc7Smrj     case BLOCK_PAREN:
910ae115bc7Smrj 
911*cb565728SJerry Jelinek         /* Completed an op that has arguments, add closing paren if needed */
912ae115bc7Smrj 
913*cb565728SJerry Jelinek         AcpiDmCloseOperator (Op);
914*cb565728SJerry Jelinek 
915*cb565728SJerry Jelinek         if (Op->Common.AmlOpcode == AML_NAME_OP)
916*cb565728SJerry Jelinek         {
917*cb565728SJerry Jelinek             /* Emit description comment for Name() with a predefined ACPI name */
918*cb565728SJerry Jelinek 
919*cb565728SJerry Jelinek             AcpiDmPredefinedDescription (Op);
920*cb565728SJerry Jelinek         }
921*cb565728SJerry Jelinek         else
922*cb565728SJerry Jelinek         {
923*cb565728SJerry Jelinek             /* For Create* operators, attempt to emit resource tag description */
924*cb565728SJerry Jelinek 
925*cb565728SJerry Jelinek             AcpiDmFieldPredefinedDescription (Op);
926*cb565728SJerry Jelinek         }
927*cb565728SJerry Jelinek 
928*cb565728SJerry Jelinek         /* Decode Notify() values */
929*cb565728SJerry Jelinek 
930*cb565728SJerry Jelinek         if (Op->Common.AmlOpcode == AML_NOTIFY_OP)
931*cb565728SJerry Jelinek         {
932*cb565728SJerry Jelinek             AcpiDmNotifyDescription (Op);
933*cb565728SJerry Jelinek         }
934*cb565728SJerry Jelinek 
935*cb565728SJerry Jelinek         AcpiDmDisplayTargetPathname (Op);
936ae115bc7Smrj 
937ae115bc7Smrj         /* Could be a nested operator, check if comma required */
938ae115bc7Smrj 
939ae115bc7Smrj         if (!AcpiDmCommaIfListMember (Op))
940ae115bc7Smrj         {
941ae115bc7Smrj             if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
942*cb565728SJerry Jelinek                  (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMETER_LIST)) &&
943ae115bc7Smrj                  (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP))
944ae115bc7Smrj             {
945ae115bc7Smrj                 /*
946ae115bc7Smrj                  * This is a first-level element of a term list
947ae115bc7Smrj                  * start a new line
948ae115bc7Smrj                  */
949*cb565728SJerry Jelinek                 if (!(Info->Flags & ACPI_PARSEOP_PARAMETER_LIST))
950ae115bc7Smrj                 {
951ae115bc7Smrj                     AcpiOsPrintf ("\n");
952ae115bc7Smrj                 }
953ae115bc7Smrj             }
954ae115bc7Smrj         }
955ae115bc7Smrj         break;
956ae115bc7Smrj 
957ae115bc7Smrj     case BLOCK_BRACE:
958ae115bc7Smrj     case (BLOCK_BRACE | BLOCK_PAREN):
959ae115bc7Smrj 
960ae115bc7Smrj         /* Completed an op that has a term list, add closing brace */
961ae115bc7Smrj 
962ae115bc7Smrj         if (Op->Common.DisasmFlags & ACPI_PARSEOP_EMPTY_TERMLIST)
963ae115bc7Smrj         {
964ae115bc7Smrj             AcpiOsPrintf ("}");
965ae115bc7Smrj         }
966ae115bc7Smrj         else
967ae115bc7Smrj         {
968ae115bc7Smrj             AcpiDmIndent (Level);
969ae115bc7Smrj             AcpiOsPrintf ("}");
970ae115bc7Smrj         }
971ae115bc7Smrj 
972ae115bc7Smrj         AcpiDmCommaIfListMember (Op);
973ae115bc7Smrj 
974ae115bc7Smrj         if (AcpiDmBlockType (Op->Common.Parent) != BLOCK_PAREN)
975ae115bc7Smrj         {
976ae115bc7Smrj             AcpiOsPrintf ("\n");
977ae115bc7Smrj             if (!(Op->Common.DisasmFlags & ACPI_PARSEOP_EMPTY_TERMLIST))
978ae115bc7Smrj             {
979ae115bc7Smrj                 if ((Op->Common.AmlOpcode == AML_IF_OP)  &&
980ae115bc7Smrj                     (Op->Common.Next) &&
981ae115bc7Smrj                     (Op->Common.Next->Common.AmlOpcode == AML_ELSE_OP))
982ae115bc7Smrj                 {
983ae115bc7Smrj                     break;
984ae115bc7Smrj                 }
985ae115bc7Smrj 
986ae115bc7Smrj                 if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
987ae115bc7Smrj                     (!Op->Common.Next))
988ae115bc7Smrj                 {
989ae115bc7Smrj                     break;
990ae115bc7Smrj                 }
991ae115bc7Smrj                 AcpiOsPrintf ("\n");
992ae115bc7Smrj             }
993ae115bc7Smrj         }
994ae115bc7Smrj         break;
995ae115bc7Smrj 
996ae115bc7Smrj     case BLOCK_NONE:
997ae115bc7Smrj     default:
998ae115bc7Smrj 
999ae115bc7Smrj         /* Could be a nested operator, check if comma required */
1000ae115bc7Smrj 
1001ae115bc7Smrj         if (!AcpiDmCommaIfListMember (Op))
1002ae115bc7Smrj         {
1003ae115bc7Smrj             if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
1004*cb565728SJerry Jelinek                  (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMETER_LIST)) &&
1005ae115bc7Smrj                  (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP))
1006ae115bc7Smrj             {
1007ae115bc7Smrj                 /*
1008ae115bc7Smrj                  * This is a first-level element of a term list
1009ae115bc7Smrj                  * start a new line
1010ae115bc7Smrj                  */
1011ae115bc7Smrj                 AcpiOsPrintf ("\n");
1012ae115bc7Smrj             }
1013ae115bc7Smrj         }
1014ae115bc7Smrj         else if (Op->Common.Parent)
1015ae115bc7Smrj         {
1016ae115bc7Smrj             switch (Op->Common.Parent->Common.AmlOpcode)
1017ae115bc7Smrj             {
1018ae115bc7Smrj             case AML_PACKAGE_OP:
1019ae115bc7Smrj             case AML_VAR_PACKAGE_OP:
1020ae115bc7Smrj 
1021*cb565728SJerry Jelinek                 if (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMETER_LIST))
1022ae115bc7Smrj                 {
1023ae115bc7Smrj                     AcpiOsPrintf ("\n");
1024ae115bc7Smrj                 }
1025ae115bc7Smrj                 break;
1026ae115bc7Smrj 
1027ae115bc7Smrj             default:
1028ae115bc7Smrj 
1029ae115bc7Smrj                 break;
1030ae115bc7Smrj             }
1031ae115bc7Smrj         }
1032ae115bc7Smrj         break;
1033ae115bc7Smrj     }
1034ae115bc7Smrj 
1035*cb565728SJerry Jelinek     if (Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMETER_LIST)
1036ae115bc7Smrj     {
1037ae115bc7Smrj         if ((Op->Common.Next) &&
1038*cb565728SJerry Jelinek             (Op->Common.Next->Common.DisasmFlags & ACPI_PARSEOP_PARAMETER_LIST))
1039ae115bc7Smrj         {
1040ae115bc7Smrj             return (AE_OK);
1041ae115bc7Smrj         }
1042ae115bc7Smrj 
1043ae115bc7Smrj         /*
1044*cb565728SJerry Jelinek          * The parent Op is guaranteed to be valid because of the flag
1045*cb565728SJerry Jelinek          * ACPI_PARSEOP_PARAMETER_LIST -- which means that this op is part of
1046*cb565728SJerry Jelinek          * a parameter list and thus has a valid parent.
1047*cb565728SJerry Jelinek          */
1048*cb565728SJerry Jelinek         ParentOp = Op->Common.Parent;
1049*cb565728SJerry Jelinek 
1050*cb565728SJerry Jelinek         /*
1051ae115bc7Smrj          * Just completed a parameter node for something like "Buffer (param)".
1052ae115bc7Smrj          * Close the paren and open up the term list block with a brace
1053ae115bc7Smrj          */
1054ae115bc7Smrj         if (Op->Common.Next)
1055ae115bc7Smrj         {
1056*cb565728SJerry Jelinek             AcpiOsPrintf (")");
1057*cb565728SJerry Jelinek 
1058*cb565728SJerry Jelinek             /*
1059*cb565728SJerry Jelinek              * Emit a description comment for a Name() operator that is a
1060*cb565728SJerry Jelinek              * predefined ACPI name. Must check the grandparent.
1061*cb565728SJerry Jelinek              */
1062*cb565728SJerry Jelinek             ParentOp = ParentOp->Common.Parent;
1063*cb565728SJerry Jelinek             if (ParentOp &&
1064*cb565728SJerry Jelinek                 (ParentOp->Asl.AmlOpcode == AML_NAME_OP))
1065*cb565728SJerry Jelinek             {
1066*cb565728SJerry Jelinek                 AcpiDmPredefinedDescription (ParentOp);
1067*cb565728SJerry Jelinek             }
1068*cb565728SJerry Jelinek 
1069*cb565728SJerry Jelinek             AcpiOsPrintf ("\n");
1070ae115bc7Smrj             AcpiDmIndent (Level - 1);
1071ae115bc7Smrj             AcpiOsPrintf ("{\n");
1072ae115bc7Smrj         }
1073ae115bc7Smrj         else
1074ae115bc7Smrj         {
1075*cb565728SJerry Jelinek             ParentOp->Common.DisasmFlags |= ACPI_PARSEOP_EMPTY_TERMLIST;
1076ae115bc7Smrj             AcpiOsPrintf (") {");
1077ae115bc7Smrj         }
1078ae115bc7Smrj     }
1079ae115bc7Smrj 
1080ae115bc7Smrj     if ((Op->Common.AmlOpcode == AML_NAME_OP) ||
1081ae115bc7Smrj         (Op->Common.AmlOpcode == AML_RETURN_OP))
1082ae115bc7Smrj     {
1083ae115bc7Smrj         Info->Level++;
1084ae115bc7Smrj     }
1085*cb565728SJerry Jelinek 
1086*cb565728SJerry Jelinek     /*
1087*cb565728SJerry Jelinek      * For ASL+, check for and emit a C-style symbol. If valid, the
1088*cb565728SJerry Jelinek      * symbol string has been deferred until after the first operand
1089*cb565728SJerry Jelinek      */
1090*cb565728SJerry Jelinek     if (AcpiGbl_CstyleDisassembly)
1091*cb565728SJerry Jelinek     {
1092*cb565728SJerry Jelinek         if (Op->Asl.OperatorSymbol)
1093*cb565728SJerry Jelinek         {
1094*cb565728SJerry Jelinek             AcpiOsPrintf ("%s", Op->Asl.OperatorSymbol);
1095*cb565728SJerry Jelinek             Op->Asl.OperatorSymbol = NULL;
1096*cb565728SJerry Jelinek         }
1097ae115bc7Smrj     }
1098ae115bc7Smrj 
1099*cb565728SJerry Jelinek     return (AE_OK);
1100*cb565728SJerry Jelinek }
1101