dmwalk.c revision 128212
1100966Siwasaki/*******************************************************************************
2100966Siwasaki *
3100966Siwasaki * Module Name: dmwalk - AML disassembly tree walk
4128212Snjl *              $Revision: 12 $
5100966Siwasaki *
6100966Siwasaki ******************************************************************************/
7100966Siwasaki
8100966Siwasaki/******************************************************************************
9100966Siwasaki *
10100966Siwasaki * 1. Copyright Notice
11100966Siwasaki *
12126372Snjl * Some or all of this work - Copyright (c) 1999 - 2004, Intel Corp.
13100966Siwasaki * All rights reserved.
14100966Siwasaki *
15100966Siwasaki * 2. License
16100966Siwasaki *
17100966Siwasaki * 2.1. This is your license from Intel Corp. under its intellectual property
18100966Siwasaki * rights.  You may have additional license terms from the party that provided
19100966Siwasaki * you this software, covering your right to use that party's intellectual
20100966Siwasaki * property rights.
21100966Siwasaki *
22100966Siwasaki * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
23100966Siwasaki * copy of the source code appearing in this file ("Covered Code") an
24100966Siwasaki * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25100966Siwasaki * base code distributed originally by Intel ("Original Intel Code") to copy,
26100966Siwasaki * make derivatives, distribute, use and display any portion of the Covered
27100966Siwasaki * Code in any form, with the right to sublicense such rights; and
28100966Siwasaki *
29100966Siwasaki * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30100966Siwasaki * license (with the right to sublicense), under only those claims of Intel
31100966Siwasaki * patents that are infringed by the Original Intel Code, to make, use, sell,
32100966Siwasaki * offer to sell, and import the Covered Code and derivative works thereof
33100966Siwasaki * solely to the minimum extent necessary to exercise the above copyright
34100966Siwasaki * license, and in no event shall the patent license extend to any additions
35100966Siwasaki * to or modifications of the Original Intel Code.  No other license or right
36100966Siwasaki * is granted directly or by implication, estoppel or otherwise;
37100966Siwasaki *
38100966Siwasaki * The above copyright and patent license is granted only if the following
39100966Siwasaki * conditions are met:
40100966Siwasaki *
41100966Siwasaki * 3. Conditions
42100966Siwasaki *
43100966Siwasaki * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44100966Siwasaki * Redistribution of source code of any substantial portion of the Covered
45100966Siwasaki * Code or modification with rights to further distribute source must include
46100966Siwasaki * the above Copyright Notice, the above License, this list of Conditions,
47100966Siwasaki * and the following Disclaimer and Export Compliance provision.  In addition,
48100966Siwasaki * Licensee must cause all Covered Code to which Licensee contributes to
49100966Siwasaki * contain a file documenting the changes Licensee made to create that Covered
50100966Siwasaki * Code and the date of any change.  Licensee must include in that file the
51100966Siwasaki * documentation of any changes made by any predecessor Licensee.  Licensee
52100966Siwasaki * must include a prominent statement that the modification is derived,
53100966Siwasaki * directly or indirectly, from Original Intel Code.
54100966Siwasaki *
55100966Siwasaki * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
56100966Siwasaki * Redistribution of source code of any substantial portion of the Covered
57100966Siwasaki * Code or modification without rights to further distribute source must
58100966Siwasaki * include the following Disclaimer and Export Compliance provision in the
59100966Siwasaki * documentation and/or other materials provided with distribution.  In
60100966Siwasaki * addition, Licensee may not authorize further sublicense of source of any
61100966Siwasaki * portion of the Covered Code, and must include terms to the effect that the
62100966Siwasaki * license from Licensee to its licensee is limited to the intellectual
63100966Siwasaki * property embodied in the software Licensee provides to its licensee, and
64100966Siwasaki * not to intellectual property embodied in modifications its licensee may
65100966Siwasaki * make.
66100966Siwasaki *
67100966Siwasaki * 3.3. Redistribution of Executable. Redistribution in executable form of any
68100966Siwasaki * substantial portion of the Covered Code or modification must reproduce the
69100966Siwasaki * above Copyright Notice, and the following Disclaimer and Export Compliance
70100966Siwasaki * provision in the documentation and/or other materials provided with the
71100966Siwasaki * distribution.
72100966Siwasaki *
73100966Siwasaki * 3.4. Intel retains all right, title, and interest in and to the Original
74100966Siwasaki * Intel Code.
75100966Siwasaki *
76100966Siwasaki * 3.5. Neither the name Intel nor any other trademark owned or controlled by
77100966Siwasaki * Intel shall be used in advertising or otherwise to promote the sale, use or
78100966Siwasaki * other dealings in products derived from or relating to the Covered Code
79100966Siwasaki * without prior written authorization from Intel.
80100966Siwasaki *
81100966Siwasaki * 4. Disclaimer and Export Compliance
82100966Siwasaki *
83100966Siwasaki * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
84100966Siwasaki * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
85100966Siwasaki * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
86100966Siwasaki * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
87100966Siwasaki * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
88100966Siwasaki * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
89100966Siwasaki * PARTICULAR PURPOSE.
90100966Siwasaki *
91100966Siwasaki * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92100966Siwasaki * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
93100966Siwasaki * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94100966Siwasaki * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
95100966Siwasaki * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
96100966Siwasaki * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
97100966Siwasaki * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
98100966Siwasaki * LIMITED REMEDY.
99100966Siwasaki *
100100966Siwasaki * 4.3. Licensee shall not export, either directly or indirectly, any of this
101100966Siwasaki * software or system incorporating such software without first obtaining any
102100966Siwasaki * required license or other approval from the U. S. Department of Commerce or
103100966Siwasaki * any other agency or department of the United States Government.  In the
104100966Siwasaki * event Licensee exports any such software from the United States or
105100966Siwasaki * re-exports any such software from a foreign destination, Licensee shall
106100966Siwasaki * ensure that the distribution and export/re-export of the software is in
107100966Siwasaki * compliance with all laws, regulations, orders, or other restrictions of the
108100966Siwasaki * U.S. Export Administration Regulations. Licensee agrees that neither it nor
109100966Siwasaki * any of its subsidiaries will export/re-export any technical data, process,
110100966Siwasaki * software, or service, directly or indirectly, to any country for which the
111100966Siwasaki * United States government or any agency thereof requires an export license,
112100966Siwasaki * other governmental approval, or letter of assurance, without first obtaining
113100966Siwasaki * such license, approval or letter.
114100966Siwasaki *
115100966Siwasaki *****************************************************************************/
116100966Siwasaki
117100966Siwasaki
118100966Siwasaki#include "acpi.h"
119100966Siwasaki#include "acparser.h"
120100966Siwasaki#include "amlcode.h"
121100966Siwasaki#include "acdisasm.h"
122100966Siwasaki#include "acdebug.h"
123100966Siwasaki
124100966Siwasaki
125100966Siwasaki#ifdef ACPI_DISASSEMBLER
126100966Siwasaki
127102550Siwasaki#define _COMPONENT          ACPI_CA_DEBUGGER
128100966Siwasaki        ACPI_MODULE_NAME    ("dmwalk")
129100966Siwasaki
130100966Siwasaki
131100966Siwasaki#define DB_FULL_OP_INFO     "%5.5X #%4.4hX "
132100966Siwasaki
133100966Siwasaki
134100966Siwasaki/*******************************************************************************
135100966Siwasaki *
136100966Siwasaki * FUNCTION:    AcpiDmDisassemble
137100966Siwasaki *
138100966Siwasaki * PARAMETERS:  Origin          - Starting object
139100966Siwasaki *              NumOpcodes      - Max number of opcodes to be displayed
140100966Siwasaki *
141100966Siwasaki * RETURN:      None
142100966Siwasaki *
143100966Siwasaki * DESCRIPTION: Disassemble parser object and its children.  This is the
144100966Siwasaki *              main entry point of the disassembler.
145100966Siwasaki *
146100966Siwasaki ******************************************************************************/
147100966Siwasaki
148100966Siwasakivoid
149100966SiwasakiAcpiDmDisassemble (
150100966Siwasaki    ACPI_WALK_STATE         *WalkState,
151100966Siwasaki    ACPI_PARSE_OBJECT       *Origin,
152100966Siwasaki    UINT32                  NumOpcodes)
153100966Siwasaki{
154100966Siwasaki    ACPI_PARSE_OBJECT       *Op = Origin;
155100966Siwasaki    ACPI_OP_WALK_INFO       Info;
156100966Siwasaki
157100966Siwasaki
158100966Siwasaki    if (!Op)
159100966Siwasaki    {
160100966Siwasaki        return;
161100966Siwasaki    }
162100966Siwasaki
163100966Siwasaki    Info.Level = 0;
164100966Siwasaki    AcpiDmWalkParseTree (Op, AcpiDmDescendingOp, AcpiDmAscendingOp, &Info);
165100966Siwasaki
166100966Siwasaki    return;
167100966Siwasaki}
168100966Siwasaki
169100966Siwasaki
170100966Siwasaki/*******************************************************************************
171100966Siwasaki *
172100966Siwasaki * FUNCTION:    AcpiDmWalkParseTree
173100966Siwasaki *
174100966Siwasaki * PARAMETERS:  DescendingCallback      - Called during tree descent
175100966Siwasaki *              AscendingCallback       - Called during tree ascent
176100966Siwasaki *              Context                 - To be passed to the callbacks
177100966Siwasaki *
178100966Siwasaki * RETURN:      Status from callback(s)
179100966Siwasaki *
180100966Siwasaki * DESCRIPTION: Walk the entire parse tree.
181100966Siwasaki *
182100966Siwasaki ******************************************************************************/
183100966Siwasaki
184100966Siwasakivoid
185100966SiwasakiAcpiDmWalkParseTree (
186100966Siwasaki    ACPI_PARSE_OBJECT       *Op,
187100966Siwasaki    ASL_WALK_CALLBACK       DescendingCallback,
188100966Siwasaki    ASL_WALK_CALLBACK       AscendingCallback,
189100966Siwasaki    void                    *Context)
190100966Siwasaki{
191100966Siwasaki    BOOLEAN                 NodePreviouslyVisited;
192100966Siwasaki    ACPI_PARSE_OBJECT       *StartOp = Op;
193100966Siwasaki    ACPI_STATUS             Status;
194100966Siwasaki    ACPI_PARSE_OBJECT       *Next;
195100966Siwasaki    ACPI_OP_WALK_INFO       *Info = Context;
196100966Siwasaki
197100966Siwasaki
198100966Siwasaki    Info->Level = 0;
199100966Siwasaki    NodePreviouslyVisited = FALSE;
200100966Siwasaki
201100966Siwasaki    while (Op)
202100966Siwasaki    {
203100966Siwasaki        if (NodePreviouslyVisited)
204100966Siwasaki        {
205100966Siwasaki            Status = AscendingCallback (Op, Info->Level, Context);
206100966Siwasaki            if (ACPI_FAILURE (Status))
207100966Siwasaki            {
208100966Siwasaki                return;
209100966Siwasaki            }
210100966Siwasaki        }
211100966Siwasaki        else
212100966Siwasaki        {
213117521Snjl            /* Let the callback process the node */
214117521Snjl
215100966Siwasaki            Status = DescendingCallback (Op, Info->Level, Context);
216100966Siwasaki            if (ACPI_SUCCESS (Status))
217100966Siwasaki            {
218100966Siwasaki                /* Visit children first, once */
219100966Siwasaki
220100966Siwasaki                Next = AcpiPsGetArg (Op, 0);
221100966Siwasaki                if (Next)
222100966Siwasaki                {
223100966Siwasaki                    Info->Level++;
224100966Siwasaki                    Op = Next;
225100966Siwasaki                    continue;
226100966Siwasaki                }
227100966Siwasaki            }
228100966Siwasaki            else if (Status != AE_CTRL_DEPTH)
229100966Siwasaki            {
230100966Siwasaki                /* Exit immediately on any error */
231100966Siwasaki
232100966Siwasaki                return;
233100966Siwasaki            }
234100966Siwasaki        }
235100966Siwasaki
236100966Siwasaki        /* Terminate walk at start op */
237100966Siwasaki
238100966Siwasaki        if (Op == StartOp)
239100966Siwasaki        {
240100966Siwasaki            break;
241100966Siwasaki        }
242100966Siwasaki
243100966Siwasaki        /* No more children, re-visit this node */
244100966Siwasaki
245100966Siwasaki        if (!NodePreviouslyVisited)
246100966Siwasaki        {
247100966Siwasaki            NodePreviouslyVisited = TRUE;
248100966Siwasaki            continue;
249100966Siwasaki        }
250100966Siwasaki
251100966Siwasaki        /* No more children, visit peers */
252100966Siwasaki
253100966Siwasaki        if (Op->Common.Next)
254100966Siwasaki        {
255100966Siwasaki            Op = Op->Common.Next;
256100966Siwasaki            NodePreviouslyVisited = FALSE;
257100966Siwasaki        }
258100966Siwasaki        else
259100966Siwasaki        {
260100966Siwasaki            /* No peers, re-visit parent */
261100966Siwasaki
262100966Siwasaki            if (Info->Level != 0 )
263100966Siwasaki            {
264100966Siwasaki                Info->Level--;
265100966Siwasaki            }
266100966Siwasaki
267100966Siwasaki            Op = Op->Common.Parent;
268100966Siwasaki            NodePreviouslyVisited = TRUE;
269100966Siwasaki        }
270100966Siwasaki    }
271100966Siwasaki
272100966Siwasaki    /* If we get here, the walk completed with no errors */
273100966Siwasaki
274100966Siwasaki    return;
275100966Siwasaki}
276100966Siwasaki
277100966Siwasaki
278100966Siwasaki/*******************************************************************************
279100966Siwasaki *
280100966Siwasaki * FUNCTION:    AcpiDmBlockType
281100966Siwasaki *
282100966Siwasaki * PARAMETERS:  Op              - Object to be examined
283100966Siwasaki *
284100966Siwasaki * RETURN:      Status
285100966Siwasaki *
286100966Siwasaki * DESCRIPTION: Type of block for this op (parens or braces)
287100966Siwasaki *
288100966Siwasaki ******************************************************************************/
289100966Siwasaki
290100966SiwasakiUINT32
291100966SiwasakiAcpiDmBlockType (
292100966Siwasaki    ACPI_PARSE_OBJECT       *Op)
293100966Siwasaki{
294100966Siwasaki    const ACPI_OPCODE_INFO  *OpInfo;
295100966Siwasaki
296100966Siwasaki
297100966Siwasaki    if (!Op)
298100966Siwasaki    {
299100966Siwasaki        return (BLOCK_NONE);
300100966Siwasaki    }
301100966Siwasaki
302100966Siwasaki    switch (Op->Common.AmlOpcode)
303100966Siwasaki    {
304100966Siwasaki    case AML_ELSE_OP:
305100966Siwasaki
306100966Siwasaki        return (BLOCK_BRACE);
307100966Siwasaki
308100966Siwasaki    case AML_METHOD_OP:
309100966Siwasaki    case AML_DEVICE_OP:
310100966Siwasaki    case AML_SCOPE_OP:
311100966Siwasaki    case AML_PROCESSOR_OP:
312100966Siwasaki    case AML_POWER_RES_OP:
313100966Siwasaki    case AML_THERMAL_ZONE_OP:
314100966Siwasaki    case AML_IF_OP:
315100966Siwasaki    case AML_WHILE_OP:
316100966Siwasaki    case AML_FIELD_OP:
317100966Siwasaki    case AML_INDEX_FIELD_OP:
318100966Siwasaki    case AML_BANK_FIELD_OP:
319100966Siwasaki
320100966Siwasaki        return (BLOCK_PAREN | BLOCK_BRACE);
321100966Siwasaki
322100966Siwasaki    case AML_BUFFER_OP:
323100966Siwasaki
324100966Siwasaki        if (Op->Common.DisasmOpcode == ACPI_DASM_UNICODE)
325100966Siwasaki        {
326100966Siwasaki            return (BLOCK_NONE);
327100966Siwasaki        }
328100966Siwasaki
329100966Siwasaki        /*lint -fallthrough */
330100966Siwasaki
331100966Siwasaki    case AML_PACKAGE_OP:
332100966Siwasaki    case AML_VAR_PACKAGE_OP:
333100966Siwasaki
334100966Siwasaki        return (BLOCK_PAREN | BLOCK_BRACE);
335100966Siwasaki
336100966Siwasaki    case AML_EVENT_OP:
337100966Siwasaki
338100966Siwasaki        return (BLOCK_PAREN);
339100966Siwasaki
340100966Siwasaki    default:
341100966Siwasaki
342100966Siwasaki        OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
343100966Siwasaki        if (OpInfo->Flags & AML_HAS_ARGS)
344100966Siwasaki        {
345100966Siwasaki            return (BLOCK_PAREN);
346100966Siwasaki        }
347100966Siwasaki
348100966Siwasaki        return (BLOCK_NONE);
349100966Siwasaki    }
350100966Siwasaki}
351100966Siwasaki
352100966Siwasaki
353100966Siwasaki/*******************************************************************************
354100966Siwasaki *
355100966Siwasaki * FUNCTION:    AcpiDmListType
356100966Siwasaki *
357100966Siwasaki * PARAMETERS:  Op              - Object to be examined
358100966Siwasaki *
359100966Siwasaki * RETURN:      Status
360100966Siwasaki *
361100966Siwasaki * DESCRIPTION: Type of block for this op (parens or braces)
362100966Siwasaki *
363100966Siwasaki ******************************************************************************/
364100966Siwasaki
365100966SiwasakiUINT32
366100966SiwasakiAcpiDmListType (
367100966Siwasaki    ACPI_PARSE_OBJECT       *Op)
368100966Siwasaki{
369100966Siwasaki    const ACPI_OPCODE_INFO  *OpInfo;
370100966Siwasaki
371100966Siwasaki
372100966Siwasaki    if (!Op)
373100966Siwasaki    {
374100966Siwasaki        return (BLOCK_NONE);
375100966Siwasaki    }
376100966Siwasaki
377100966Siwasaki    switch (Op->Common.AmlOpcode)
378100966Siwasaki    {
379100966Siwasaki
380100966Siwasaki    case AML_ELSE_OP:
381100966Siwasaki    case AML_METHOD_OP:
382100966Siwasaki    case AML_DEVICE_OP:
383100966Siwasaki    case AML_SCOPE_OP:
384100966Siwasaki    case AML_POWER_RES_OP:
385100966Siwasaki    case AML_PROCESSOR_OP:
386100966Siwasaki    case AML_THERMAL_ZONE_OP:
387100966Siwasaki    case AML_IF_OP:
388100966Siwasaki    case AML_WHILE_OP:
389100966Siwasaki    case AML_FIELD_OP:
390100966Siwasaki    case AML_INDEX_FIELD_OP:
391100966Siwasaki    case AML_BANK_FIELD_OP:
392100966Siwasaki
393100966Siwasaki        return (0);
394100966Siwasaki
395100966Siwasaki    case AML_BUFFER_OP:
396100966Siwasaki    case AML_PACKAGE_OP:
397100966Siwasaki    case AML_VAR_PACKAGE_OP:
398100966Siwasaki
399100966Siwasaki        return (BLOCK_COMMA_LIST);
400100966Siwasaki
401100966Siwasaki    default:
402100966Siwasaki
403100966Siwasaki        OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
404100966Siwasaki        if (OpInfo->Flags & AML_HAS_ARGS)
405100966Siwasaki        {
406100966Siwasaki            return (BLOCK_COMMA_LIST);
407100966Siwasaki        }
408100966Siwasaki
409100966Siwasaki        return (BLOCK_NONE);
410100966Siwasaki    }
411100966Siwasaki}
412100966Siwasaki
413100966Siwasaki
414100966Siwasaki/*******************************************************************************
415100966Siwasaki *
416100966Siwasaki * FUNCTION:    AcpiDmDescendingOp
417100966Siwasaki *
418100966Siwasaki * PARAMETERS:  ASL_WALK_CALLBACK
419100966Siwasaki *
420100966Siwasaki * RETURN:      Status
421100966Siwasaki *
422102550Siwasaki * DESCRIPTION: First visitation of a parse object during tree descent.
423100966Siwasaki *              Decode opcode name and begin parameter list(s), if any.
424100966Siwasaki *
425100966Siwasaki ******************************************************************************/
426100966Siwasaki
427100966SiwasakiACPI_STATUS
428100966SiwasakiAcpiDmDescendingOp (
429100966Siwasaki    ACPI_PARSE_OBJECT       *Op,
430100966Siwasaki    UINT32                  Level,
431100966Siwasaki    void                    *Context)
432100966Siwasaki{
433100966Siwasaki    ACPI_OP_WALK_INFO       *Info = Context;
434100966Siwasaki    const ACPI_OPCODE_INFO  *OpInfo;
435100966Siwasaki    UINT32                  Name;
436100966Siwasaki    ACPI_PARSE_OBJECT       *NextOp;
437128212Snjl    ACPI_EXTERNAL_LIST      *NextExternal;
438100966Siwasaki
439100966Siwasaki
440100966Siwasaki    if (Op->Common.DisasmFlags & ACPI_PARSEOP_IGNORE)
441100966Siwasaki    {
442100966Siwasaki        /* Ignore this op -- it was handled elsewhere */
443100966Siwasaki
444100966Siwasaki        return (AE_CTRL_DEPTH);
445100966Siwasaki    }
446100966Siwasaki
447128212Snjl    /* Level 0 is at the Definition Block level */
448100966Siwasaki
449100966Siwasaki    if (Level == 0)
450100966Siwasaki    {
451100966Siwasaki        /* In verbose mode, print the AML offset, opcode and depth count */
452100966Siwasaki
453100966Siwasaki        VERBOSE_PRINT ((DB_FULL_OP_INFO, (UINT32) Op->Common.AmlOffset,
454100966Siwasaki                    Op->Common.AmlOpcode));
455100966Siwasaki
456100966Siwasaki        if (Op->Common.AmlOpcode == AML_SCOPE_OP)
457100966Siwasaki        {
458128212Snjl            /* This is the beginning of the Definition Block */
459128212Snjl
460100966Siwasaki            AcpiOsPrintf ("{\n");
461128212Snjl
462128212Snjl            /* Emit all External() declarations here */
463128212Snjl
464128212Snjl            if (AcpiGbl_ExternalList)
465128212Snjl            {
466128212Snjl                AcpiOsPrintf ("    /*\n     * These objects were referenced but not defined in this table\n     */\n");
467128212Snjl
468128212Snjl                /* Walk the list of externals (unresolved references) found during parsing */
469128212Snjl
470128212Snjl                while (AcpiGbl_ExternalList)
471128212Snjl                {
472128212Snjl                    AcpiOsPrintf ("    External (%s)\n", AcpiGbl_ExternalList->Path);
473128212Snjl
474128212Snjl                    NextExternal = AcpiGbl_ExternalList->Next;
475128212Snjl                    ACPI_MEM_FREE (AcpiGbl_ExternalList->Path);
476128212Snjl                    ACPI_MEM_FREE (AcpiGbl_ExternalList);
477128212Snjl                    AcpiGbl_ExternalList = NextExternal;
478128212Snjl                }
479128212Snjl                AcpiOsPrintf ("\n");
480128212Snjl            }
481128212Snjl
482100966Siwasaki            return (AE_OK);
483100966Siwasaki        }
484100966Siwasaki    }
485100966Siwasaki    else if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
486100966Siwasaki             (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) &&
487100966Siwasaki             (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP))
488100966Siwasaki    {
489100966Siwasaki            /* This is a first-level element of a term list, indent a new line */
490100966Siwasaki
491100966Siwasaki            AcpiDmIndent (Level);
492100966Siwasaki    }
493100966Siwasaki
494100966Siwasaki    /* Print the opcode name */
495100966Siwasaki
496100966Siwasaki    AcpiDmDisassembleOneOp (NULL, Info, Op);
497100966Siwasaki
498100966Siwasaki    if ((Op->Common.AmlOpcode == AML_NAME_OP) ||
499100966Siwasaki        (Op->Common.AmlOpcode == AML_RETURN_OP))
500100966Siwasaki    {
501100966Siwasaki        Info->Level--;
502100966Siwasaki    }
503100966Siwasaki
504117521Snjl    /* Start the opcode argument list if necessary */
505117521Snjl
506100966Siwasaki    OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
507100966Siwasaki
508102550Siwasaki    if ((OpInfo->Flags & AML_HAS_ARGS) ||
509100966Siwasaki        (Op->Common.AmlOpcode == AML_EVENT_OP))
510100966Siwasaki    {
511100966Siwasaki        /* This opcode has an argument list */
512100966Siwasaki
513100966Siwasaki        if (AcpiDmBlockType (Op) & BLOCK_PAREN)
514100966Siwasaki        {
515100966Siwasaki            AcpiOsPrintf (" (");
516100966Siwasaki        }
517100966Siwasaki
518117521Snjl        /* If this is a named opcode, print the associated name value */
519117521Snjl
520100966Siwasaki        if (OpInfo->Flags & AML_NAMED)
521100966Siwasaki        {
522100966Siwasaki            switch (Op->Common.AmlOpcode)
523100966Siwasaki            {
524100966Siwasaki            case AML_ALIAS_OP:
525100966Siwasaki
526100966Siwasaki                NextOp = AcpiPsGetDepthNext (NULL, Op);
527100966Siwasaki                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
528100966Siwasaki                AcpiDmNamestring (NextOp->Common.Value.Name);
529100966Siwasaki                AcpiOsPrintf (", ");
530100966Siwasaki
531100966Siwasaki                /*lint -fallthrough */
532100966Siwasaki
533100966Siwasaki            default:
534100966Siwasaki
535100966Siwasaki                Name = AcpiPsGetName (Op);
536100966Siwasaki                if (Op->Named.Path)
537100966Siwasaki                {
538100966Siwasaki                    AcpiDmNamestring ((char *) Op->Named.Path);
539100966Siwasaki                }
540100966Siwasaki                else
541100966Siwasaki                {
542100966Siwasaki                    AcpiDmDumpName ((char *) &Name);
543100966Siwasaki                }
544100966Siwasaki
545100966Siwasaki
546100966Siwasaki                if (Op->Common.AmlOpcode != AML_INT_NAMEDFIELD_OP)
547100966Siwasaki                {
548100966Siwasaki                    AcpiDmValidateName ((char *) &Name, Op);
549100966Siwasaki                    if (AcpiGbl_DbOpt_verbose)
550100966Siwasaki                    {
551100966Siwasaki                        (void) AcpiPsDisplayObjectPathname (NULL, Op);
552100966Siwasaki                    }
553100966Siwasaki                }
554100966Siwasaki                break;
555100966Siwasaki            }
556100966Siwasaki
557100966Siwasaki            switch (Op->Common.AmlOpcode)
558100966Siwasaki            {
559100966Siwasaki            case AML_METHOD_OP:
560100966Siwasaki
561100966Siwasaki                AcpiDmMethodFlags (Op);
562100966Siwasaki                AcpiOsPrintf (")");
563100966Siwasaki                break;
564100966Siwasaki
565100966Siwasaki
566100966Siwasaki            case AML_NAME_OP:
567100966Siwasaki
568100966Siwasaki                /* Check for _HID and related EISAID() */
569100966Siwasaki
570100966Siwasaki                AcpiIsEisaId (Op);
571100966Siwasaki                AcpiOsPrintf (", ");
572100966Siwasaki                break;
573100966Siwasaki
574100966Siwasaki
575100966Siwasaki            case AML_REGION_OP:
576100966Siwasaki
577100966Siwasaki                AcpiDmRegionFlags (Op);
578100966Siwasaki                break;
579100966Siwasaki
580100966Siwasaki
581100966Siwasaki            case AML_POWER_RES_OP:
582100966Siwasaki
583100966Siwasaki                /* Mark the next two Ops as part of the parameter list */
584100966Siwasaki
585100966Siwasaki                AcpiOsPrintf (", ");
586100966Siwasaki                NextOp = AcpiPsGetDepthNext (NULL, Op);
587100966Siwasaki                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
588100966Siwasaki
589100966Siwasaki                NextOp = NextOp->Common.Next;
590100966Siwasaki                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
591100966Siwasaki                return (AE_OK);
592100966Siwasaki
593100966Siwasaki
594100966Siwasaki            case AML_PROCESSOR_OP:
595100966Siwasaki
596100966Siwasaki                /* Mark the next three Ops as part of the parameter list */
597100966Siwasaki
598100966Siwasaki                AcpiOsPrintf (", ");
599100966Siwasaki                NextOp = AcpiPsGetDepthNext (NULL, Op);
600100966Siwasaki                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
601100966Siwasaki
602100966Siwasaki                NextOp = NextOp->Common.Next;
603100966Siwasaki                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
604100966Siwasaki
605100966Siwasaki                NextOp = NextOp->Common.Next;
606100966Siwasaki                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
607100966Siwasaki                return (AE_OK);
608100966Siwasaki
609100966Siwasaki
610100966Siwasaki            case AML_MUTEX_OP:
611100966Siwasaki
612100966Siwasaki                AcpiOsPrintf (", ");
613100966Siwasaki                return (AE_OK);
614100966Siwasaki
615100966Siwasaki
616100966Siwasaki            case AML_EVENT_OP:
617100966Siwasaki            case AML_ALIAS_OP:
618100966Siwasaki
619100966Siwasaki                return (AE_OK);
620100966Siwasaki
621100966Siwasaki
622100966Siwasaki            case AML_SCOPE_OP:
623100966Siwasaki            case AML_DEVICE_OP:
624100966Siwasaki            case AML_THERMAL_ZONE_OP:
625100966Siwasaki
626100966Siwasaki                AcpiOsPrintf (")");
627100966Siwasaki                break;
628100966Siwasaki
629100966Siwasaki
630100966Siwasaki            default:
631100966Siwasaki
632100966Siwasaki                AcpiOsPrintf ("*** Unhandled named opcode\n");
633100966Siwasaki                break;
634100966Siwasaki            }
635100966Siwasaki        }
636100966Siwasaki
637100966Siwasaki        else switch (Op->Common.AmlOpcode)
638100966Siwasaki        {
639100966Siwasaki        case AML_FIELD_OP:
640100966Siwasaki        case AML_BANK_FIELD_OP:
641100966Siwasaki        case AML_INDEX_FIELD_OP:
642100966Siwasaki
643100966Siwasaki            Info->BitOffset = 0;
644100966Siwasaki
645100966Siwasaki            /* Name of the parent OperationRegion */
646100966Siwasaki
647100966Siwasaki            NextOp = AcpiPsGetDepthNext (NULL, Op);
648100966Siwasaki            AcpiDmNamestring (NextOp->Common.Value.Name);
649100966Siwasaki            AcpiOsPrintf (", ");
650100966Siwasaki            NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
651100966Siwasaki
652100966Siwasaki            switch (Op->Common.AmlOpcode)
653100966Siwasaki            {
654100966Siwasaki            case AML_BANK_FIELD_OP:
655100966Siwasaki
656100966Siwasaki                /* Namestring */
657100966Siwasaki
658100966Siwasaki                NextOp = AcpiPsGetDepthNext (NULL, NextOp);
659100966Siwasaki                AcpiDmNamestring (NextOp->Common.Value.Name);
660100966Siwasaki                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
661100966Siwasaki                AcpiOsPrintf (", ");
662100966Siwasaki
663100966Siwasaki
664100966Siwasaki                NextOp = NextOp->Common.Next;
665100966Siwasaki                AcpiDmDisassembleOneOp (NULL, Info, NextOp);
666100966Siwasaki                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
667100966Siwasaki                AcpiOsPrintf (", ");
668100966Siwasaki                break;
669100966Siwasaki
670100966Siwasaki            case AML_INDEX_FIELD_OP:
671100966Siwasaki
672100966Siwasaki                /* Namestring */
673100966Siwasaki
674100966Siwasaki                NextOp = AcpiPsGetDepthNext (NULL, NextOp);
675100966Siwasaki                AcpiDmNamestring (NextOp->Common.Value.Name);
676100966Siwasaki                AcpiOsPrintf (", ");
677100966Siwasaki                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
678100966Siwasaki                break;
679100966Siwasaki
680100966Siwasaki            default:
681100966Siwasaki
682100966Siwasaki                break;
683100966Siwasaki            }
684100966Siwasaki
685100966Siwasaki            AcpiDmFieldFlags (NextOp);
686100966Siwasaki            break;
687100966Siwasaki
688100966Siwasaki
689100966Siwasaki        case AML_BUFFER_OP:
690100966Siwasaki
691100966Siwasaki            /* The next op is the size parameter */
692100966Siwasaki
693100966Siwasaki            NextOp = AcpiPsGetDepthNext (NULL, Op);
694100966Siwasaki            if (!NextOp)
695100966Siwasaki            {
696100966Siwasaki                /* Single-step support */
697100966Siwasaki
698100966Siwasaki                return (AE_OK);
699100966Siwasaki            }
700100966Siwasaki
701100966Siwasaki            if (Op->Common.DisasmOpcode == ACPI_DASM_RESOURCE)
702100966Siwasaki            {
703100966Siwasaki                /*
704102550Siwasaki                 * We have a resource list.  Don't need to output
705100966Siwasaki                 * the buffer size Op.  Open up a new block
706100966Siwasaki                 */
707100966Siwasaki                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
708100966Siwasaki                NextOp = NextOp->Common.Next;
709100966Siwasaki                AcpiOsPrintf (")\n");
710100966Siwasaki                AcpiDmIndent (Info->Level);
711100966Siwasaki                AcpiOsPrintf ("{\n");
712100966Siwasaki                return (AE_OK);
713100966Siwasaki            }
714100966Siwasaki
715100966Siwasaki            /* Normal Buffer, mark size as in the parameter list */
716100966Siwasaki
717100966Siwasaki            NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
718100966Siwasaki            return (AE_OK);
719100966Siwasaki
720100966Siwasaki
721100966Siwasaki        case AML_VAR_PACKAGE_OP:
722100966Siwasaki        case AML_IF_OP:
723100966Siwasaki        case AML_WHILE_OP:
724100966Siwasaki
725100966Siwasaki            /* The next op is the size or predicate parameter */
726100966Siwasaki
727100966Siwasaki            NextOp = AcpiPsGetDepthNext (NULL, Op);
728100966Siwasaki            if (NextOp)
729100966Siwasaki            {
730100966Siwasaki                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
731100966Siwasaki            }
732100966Siwasaki            return (AE_OK);
733100966Siwasaki
734100966Siwasaki
735100966Siwasaki        case AML_PACKAGE_OP:
736100966Siwasaki
737100966Siwasaki            /* The next op is the size or predicate parameter */
738100966Siwasaki
739100966Siwasaki            NextOp = AcpiPsGetDepthNext (NULL, Op);
740100966Siwasaki            if (NextOp)
741100966Siwasaki            {
742100966Siwasaki                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
743100966Siwasaki            }
744100966Siwasaki            return (AE_OK);
745100966Siwasaki
746100966Siwasaki
747100966Siwasaki        case AML_MATCH_OP:
748100966Siwasaki
749100966Siwasaki            AcpiDmMatchOp (Op);
750100966Siwasaki            break;
751100966Siwasaki
752100966Siwasaki
753100966Siwasaki        default:
754100966Siwasaki
755100966Siwasaki            break;
756100966Siwasaki        }
757100966Siwasaki
758100966Siwasaki        if (AcpiDmBlockType (Op) & BLOCK_BRACE)
759100966Siwasaki        {
760100966Siwasaki            AcpiOsPrintf ("\n");
761100966Siwasaki            AcpiDmIndent (Level);
762100966Siwasaki            AcpiOsPrintf ("{\n");
763100966Siwasaki        }
764100966Siwasaki    }
765100966Siwasaki
766100966Siwasaki    return (AE_OK);
767100966Siwasaki}
768100966Siwasaki
769100966Siwasaki
770100966Siwasaki/*******************************************************************************
771100966Siwasaki *
772100966Siwasaki * FUNCTION:    AcpiDmAscendingOp
773100966Siwasaki *
774100966Siwasaki * PARAMETERS:  ASL_WALK_CALLBACK
775100966Siwasaki *
776100966Siwasaki * RETURN:      Status
777100966Siwasaki *
778100966Siwasaki * DESCRIPTION: Second visitation of a parse object, during ascent of parse
779100966Siwasaki *              tree.  Close out any parameter lists and complete the opcode.
780100966Siwasaki *
781100966Siwasaki ******************************************************************************/
782100966Siwasaki
783100966SiwasakiACPI_STATUS
784100966SiwasakiAcpiDmAscendingOp (
785100966Siwasaki    ACPI_PARSE_OBJECT       *Op,
786100966Siwasaki    UINT32                  Level,
787100966Siwasaki    void                    *Context)
788100966Siwasaki{
789100966Siwasaki    ACPI_OP_WALK_INFO       *Info = Context;
790100966Siwasaki
791100966Siwasaki
792100966Siwasaki    if (Op->Common.DisasmFlags & ACPI_PARSEOP_IGNORE)
793100966Siwasaki    {
794100966Siwasaki        /* Ignore this op -- it was handled elsewhere */
795100966Siwasaki
796100966Siwasaki        return (AE_OK);
797100966Siwasaki    }
798100966Siwasaki
799100966Siwasaki    if ((Level == 0) && (Op->Common.AmlOpcode == AML_SCOPE_OP))
800100966Siwasaki    {
801100966Siwasaki        /* Indicates the end of the current descriptor block (table) */
802100966Siwasaki
803100966Siwasaki        AcpiOsPrintf ("}\n\n");
804100966Siwasaki        return (AE_OK);
805100966Siwasaki    }
806100966Siwasaki
807100966Siwasaki    switch (AcpiDmBlockType (Op))
808100966Siwasaki    {
809100966Siwasaki    case BLOCK_PAREN:
810100966Siwasaki
811100966Siwasaki        /* Completed an op that has arguments, add closing paren */
812100966Siwasaki
813100966Siwasaki        AcpiOsPrintf (")");
814100966Siwasaki
815100966Siwasaki        /* Could be a nested operator, check if comma required */
816100966Siwasaki
817100966Siwasaki        if (!AcpiDmCommaIfListMember (Op))
818100966Siwasaki        {
819100966Siwasaki            if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
820100966Siwasaki                     (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) &&
821100966Siwasaki                     (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP))
822100966Siwasaki            {
823100966Siwasaki                /* This is a first-level element of a term list, start a new line */
824100966Siwasaki
825100966Siwasaki                AcpiOsPrintf ("\n");
826100966Siwasaki            }
827100966Siwasaki        }
828100966Siwasaki        break;
829100966Siwasaki
830100966Siwasaki
831100966Siwasaki    case BLOCK_BRACE:
832100966Siwasaki    case (BLOCK_BRACE | BLOCK_PAREN):
833100966Siwasaki
834100966Siwasaki        /* Completed an op that has a term list, add closing brace */
835100966Siwasaki
836100966Siwasaki        if (Op->Common.DisasmFlags & ACPI_PARSEOP_EMPTY_TERMLIST)
837100966Siwasaki        {
838100966Siwasaki            AcpiOsPrintf ("}");
839100966Siwasaki        }
840100966Siwasaki        else
841100966Siwasaki        {
842100966Siwasaki            AcpiDmIndent (Level);
843100966Siwasaki            AcpiOsPrintf ("}");
844100966Siwasaki        }
845100966Siwasaki
846100966Siwasaki        AcpiDmCommaIfListMember (Op);
847100966Siwasaki
848100966Siwasaki        if (AcpiDmBlockType (Op->Common.Parent) != BLOCK_PAREN)
849100966Siwasaki        {
850100966Siwasaki            AcpiOsPrintf ("\n");
851100966Siwasaki            if (!(Op->Common.DisasmFlags & ACPI_PARSEOP_EMPTY_TERMLIST))
852100966Siwasaki            {
853100966Siwasaki                if ((Op->Common.AmlOpcode == AML_IF_OP)  &&
854100966Siwasaki                    (Op->Common.Next) &&
855100966Siwasaki                    (Op->Common.Next->Common.AmlOpcode == AML_ELSE_OP))
856100966Siwasaki                {
857100966Siwasaki                    break;
858100966Siwasaki                }
859100966Siwasaki
860100966Siwasaki                if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
861100966Siwasaki                    (!Op->Common.Next))
862100966Siwasaki                {
863100966Siwasaki                    break;
864100966Siwasaki                }
865100966Siwasaki                AcpiOsPrintf ("\n");
866100966Siwasaki            }
867100966Siwasaki        }
868100966Siwasaki        break;
869100966Siwasaki
870100966Siwasaki
871100966Siwasaki    case BLOCK_NONE:
872100966Siwasaki    default:
873100966Siwasaki
874100966Siwasaki        /* Could be a nested operator, check if comma required */
875100966Siwasaki
876100966Siwasaki        if (!AcpiDmCommaIfListMember (Op))
877100966Siwasaki        {
878100966Siwasaki            if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
879100966Siwasaki                     (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) &&
880100966Siwasaki                     (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP))
881100966Siwasaki            {
882100966Siwasaki                /* This is a first-level element of a term list, start a new line */
883100966Siwasaki
884100966Siwasaki                AcpiOsPrintf ("\n");
885100966Siwasaki            }
886100966Siwasaki        }
887100966Siwasaki        else if (Op->Common.Parent)
888100966Siwasaki        {
889100966Siwasaki            switch (Op->Common.Parent->Common.AmlOpcode)
890100966Siwasaki            {
891100966Siwasaki            case AML_PACKAGE_OP:
892100966Siwasaki            case AML_VAR_PACKAGE_OP:
893100966Siwasaki
894100966Siwasaki                if (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST))
895100966Siwasaki                {
896100966Siwasaki                    AcpiOsPrintf ("\n");
897100966Siwasaki                }
898100966Siwasaki                break;
899100966Siwasaki
900100966Siwasaki            default:
901100966Siwasaki
902100966Siwasaki                break;
903100966Siwasaki            }
904100966Siwasaki        }
905100966Siwasaki        break;
906100966Siwasaki    }
907100966Siwasaki
908100966Siwasaki    if (Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)
909100966Siwasaki    {
910100966Siwasaki        if ((Op->Common.Next) &&
911100966Siwasaki            (Op->Common.Next->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST))
912100966Siwasaki        {
913100966Siwasaki            return (AE_OK);
914100966Siwasaki        }
915100966Siwasaki
916100966Siwasaki        /*
917100966Siwasaki         * Just completed a parameter node for something like "Buffer (param)".
918100966Siwasaki         * Close the paren and open up the term list block with a brace
919100966Siwasaki         */
920100966Siwasaki        if (Op->Common.Next)
921100966Siwasaki        {
922100966Siwasaki            AcpiOsPrintf (")\n");
923100966Siwasaki            AcpiDmIndent (Level - 1);
924100966Siwasaki            AcpiOsPrintf ("{\n");
925100966Siwasaki        }
926100966Siwasaki        else
927100966Siwasaki        {
928100966Siwasaki            Op->Common.Parent->Common.DisasmFlags |= ACPI_PARSEOP_EMPTY_TERMLIST;
929100966Siwasaki            AcpiOsPrintf (") {");
930100966Siwasaki        }
931100966Siwasaki    }
932100966Siwasaki
933100966Siwasaki    if ((Op->Common.AmlOpcode == AML_NAME_OP) ||
934100966Siwasaki        (Op->Common.AmlOpcode == AML_RETURN_OP))
935100966Siwasaki    {
936100966Siwasaki        Info->Level++;
937100966Siwasaki    }
938100966Siwasaki    return (AE_OK);
939100966Siwasaki}
940100966Siwasaki
941100966Siwasaki
942100966Siwasaki#endif  /* ACPI_DISASSEMBLER */
943