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