dmwalk.c revision 128212
1274955Ssvnmir/*******************************************************************************
2274955Ssvnmir *
3274955Ssvnmir * Module Name: dmwalk - AML disassembly tree walk
4274955Ssvnmir *              $Revision: 12 $
5274955Ssvnmir *
6274955Ssvnmir ******************************************************************************/
7274955Ssvnmir
8274955Ssvnmir/******************************************************************************
9274955Ssvnmir *
10274955Ssvnmir * 1. Copyright Notice
11274955Ssvnmir *
12274955Ssvnmir * Some or all of this work - Copyright (c) 1999 - 2004, Intel Corp.
13274955Ssvnmir * All rights reserved.
14274955Ssvnmir *
15274955Ssvnmir * 2. License
16280031Sdim *
17274955Ssvnmir * 2.1. This is your license from Intel Corp. under its intellectual property
18274955Ssvnmir * rights.  You may have additional license terms from the party that provided
19288943Sdim * you this software, covering your right to use that party's intellectual
20280031Sdim * property rights.
21274955Ssvnmir *
22274955Ssvnmir * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
23274955Ssvnmir * copy of the source code appearing in this file ("Covered Code") an
24274955Ssvnmir * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25274955Ssvnmir * base code distributed originally by Intel ("Original Intel Code") to copy,
26274955Ssvnmir * make derivatives, distribute, use and display any portion of the Covered
27274955Ssvnmir * Code in any form, with the right to sublicense such rights; and
28274955Ssvnmir *
29280031Sdim * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30280031Sdim * license (with the right to sublicense), under only those claims of Intel
31280031Sdim * patents that are infringed by the Original Intel Code, to make, use, sell,
32274955Ssvnmir * offer to sell, and import the Covered Code and derivative works thereof
33274955Ssvnmir * solely to the minimum extent necessary to exercise the above copyright
34274955Ssvnmir * license, and in no event shall the patent license extend to any additions
35274955Ssvnmir * to or modifications of the Original Intel Code.  No other license or right
36274955Ssvnmir * is granted directly or by implication, estoppel or otherwise;
37274955Ssvnmir *
38274955Ssvnmir * The above copyright and patent license is granted only if the following
39274955Ssvnmir * conditions are met:
40274955Ssvnmir *
41274955Ssvnmir * 3. Conditions
42274955Ssvnmir *
43274955Ssvnmir * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44296417Sdim * Redistribution of source code of any substantial portion of the Covered
45296417Sdim * Code or modification with rights to further distribute source must include
46296417Sdim * the above Copyright Notice, the above License, this list of Conditions,
47274955Ssvnmir * and the following Disclaimer and Export Compliance provision.  In addition,
48274955Ssvnmir * Licensee must cause all Covered Code to which Licensee contributes to
49274955Ssvnmir * contain a file documenting the changes Licensee made to create that Covered
50274955Ssvnmir * Code and the date of any change.  Licensee must include in that file the
51296417Sdim * documentation of any changes made by any predecessor Licensee.  Licensee
52296417Sdim * must include a prominent statement that the modification is derived,
53296417Sdim * directly or indirectly, from Original Intel Code.
54274955Ssvnmir *
55296417Sdim * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
56296417Sdim * Redistribution of source code of any substantial portion of the Covered
57274955Ssvnmir * Code or modification without rights to further distribute source must
58296417Sdim * include the following Disclaimer and Export Compliance provision in the
59296417Sdim * documentation and/or other materials provided with distribution.  In
60296417Sdim * addition, Licensee may not authorize further sublicense of source of any
61296417Sdim * portion of the Covered Code, and must include terms to the effect that the
62296417Sdim * license from Licensee to its licensee is limited to the intellectual
63296417Sdim * property embodied in the software Licensee provides to its licensee, and
64296417Sdim * not to intellectual property embodied in modifications its licensee may
65296417Sdim * make.
66296417Sdim *
67296417Sdim * 3.3. Redistribution of Executable. Redistribution in executable form of any
68296417Sdim * substantial portion of the Covered Code or modification must reproduce the
69296417Sdim * above Copyright Notice, and the following Disclaimer and Export Compliance
70296417Sdim * provision in the documentation and/or other materials provided with the
71296417Sdim * distribution.
72296417Sdim *
73296417Sdim * 3.4. Intel retains all right, title, and interest in and to the Original
74296417Sdim * Intel Code.
75296417Sdim *
76296417Sdim * 3.5. Neither the name Intel nor any other trademark owned or controlled by
77296417Sdim * Intel shall be used in advertising or otherwise to promote the sale, use or
78296417Sdim * other dealings in products derived from or relating to the Covered Code
79296417Sdim * without prior written authorization from Intel.
80296417Sdim *
81274955Ssvnmir * 4. Disclaimer and Export Compliance
82274955Ssvnmir *
83296417Sdim * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
84296417Sdim * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
85296417Sdim * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
86274955Ssvnmir * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
87274955Ssvnmir * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
88274955Ssvnmir * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
89296417Sdim * PARTICULAR PURPOSE.
90274955Ssvnmir *
91274955Ssvnmir * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92274955Ssvnmir * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
93274955Ssvnmir * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94274955Ssvnmir * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
95296417Sdim * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
96274955Ssvnmir * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
97296417Sdim * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
98296417Sdim * LIMITED REMEDY.
99296417Sdim *
100296417Sdim * 4.3. Licensee shall not export, either directly or indirectly, any of this
101296417Sdim * software or system incorporating such software without first obtaining any
102296417Sdim * required license or other approval from the U. S. Department of Commerce or
103274955Ssvnmir * any other agency or department of the United States Government.  In the
104274955Ssvnmir * event Licensee exports any such software from the United States or
105274955Ssvnmir * re-exports any such software from a foreign destination, Licensee shall
106274955Ssvnmir * ensure that the distribution and export/re-export of the software is in
107274955Ssvnmir * compliance with all laws, regulations, orders, or other restrictions of the
108274955Ssvnmir * U.S. Export Administration Regulations. Licensee agrees that neither it nor
109296417Sdim * any of its subsidiaries will export/re-export any technical data, process,
110296417Sdim * software, or service, directly or indirectly, to any country for which the
111274955Ssvnmir * United States government or any agency thereof requires an export license,
112296417Sdim * other governmental approval, or letter of assurance, without first obtaining
113296417Sdim * such license, approval or letter.
114296417Sdim *
115296417Sdim *****************************************************************************/
116296417Sdim
117274955Ssvnmir
118274955Ssvnmir#include "acpi.h"
119274955Ssvnmir#include "acparser.h"
120274955Ssvnmir#include "amlcode.h"
121274955Ssvnmir#include "acdisasm.h"
122296417Sdim#include "acdebug.h"
123274955Ssvnmir
124274955Ssvnmir
125274955Ssvnmir#ifdef ACPI_DISASSEMBLER
126274955Ssvnmir
127274955Ssvnmir#define _COMPONENT          ACPI_CA_DEBUGGER
128274955Ssvnmir        ACPI_MODULE_NAME    ("dmwalk")
129274955Ssvnmir
130296417Sdim
131296417Sdim#define DB_FULL_OP_INFO     "%5.5X #%4.4hX "
132296417Sdim
133296417Sdim
134274955Ssvnmir/*******************************************************************************
135296417Sdim *
136274955Ssvnmir * FUNCTION:    AcpiDmDisassemble
137296417Sdim *
138296417Sdim * PARAMETERS:  Origin          - Starting object
139274955Ssvnmir *              NumOpcodes      - Max number of opcodes to be displayed
140296417Sdim *
141296417Sdim * RETURN:      None
142274955Ssvnmir *
143296417Sdim * DESCRIPTION: Disassemble parser object and its children.  This is the
144296417Sdim *              main entry point of the disassembler.
145296417Sdim *
146296417Sdim ******************************************************************************/
147296417Sdim
148296417Sdimvoid
149296417SdimAcpiDmDisassemble (
150296417Sdim    ACPI_WALK_STATE         *WalkState,
151296417Sdim    ACPI_PARSE_OBJECT       *Origin,
152274955Ssvnmir    UINT32                  NumOpcodes)
153274955Ssvnmir{
154274955Ssvnmir    ACPI_PARSE_OBJECT       *Op = Origin;
155296417Sdim    ACPI_OP_WALK_INFO       Info;
156274955Ssvnmir
157274955Ssvnmir
158274955Ssvnmir    if (!Op)
159280031Sdim    {
160274955Ssvnmir        return;
161296417Sdim    }
162296417Sdim
163296417Sdim    Info.Level = 0;
164296417Sdim    AcpiDmWalkParseTree (Op, AcpiDmDescendingOp, AcpiDmAscendingOp, &Info);
165274955Ssvnmir
166274955Ssvnmir    return;
167274955Ssvnmir}
168274955Ssvnmir
169274955Ssvnmir
170274955Ssvnmir/*******************************************************************************
171296417Sdim *
172296417Sdim * FUNCTION:    AcpiDmWalkParseTree
173274955Ssvnmir *
174274955Ssvnmir * PARAMETERS:  DescendingCallback      - Called during tree descent
175274955Ssvnmir *              AscendingCallback       - Called during tree ascent
176274955Ssvnmir *              Context                 - To be passed to the callbacks
177274955Ssvnmir *
178274955Ssvnmir * RETURN:      Status from callback(s)
179274955Ssvnmir *
180288943Sdim * DESCRIPTION: Walk the entire parse tree.
181296417Sdim *
182296417Sdim ******************************************************************************/
183296417Sdim
184296417Sdimvoid
185288943SdimAcpiDmWalkParseTree (
186274955Ssvnmir    ACPI_PARSE_OBJECT       *Op,
187274955Ssvnmir    ASL_WALK_CALLBACK       DescendingCallback,
188274955Ssvnmir    ASL_WALK_CALLBACK       AscendingCallback,
189296417Sdim    void                    *Context)
190296417Sdim{
191296417Sdim    BOOLEAN                 NodePreviouslyVisited;
192296417Sdim    ACPI_PARSE_OBJECT       *StartOp = Op;
193296417Sdim    ACPI_STATUS             Status;
194296417Sdim    ACPI_PARSE_OBJECT       *Next;
195274955Ssvnmir    ACPI_OP_WALK_INFO       *Info = Context;
196296417Sdim
197296417Sdim
198296417Sdim    Info->Level = 0;
199296417Sdim    NodePreviouslyVisited = FALSE;
200296417Sdim
201296417Sdim    while (Op)
202296417Sdim    {
203296417Sdim        if (NodePreviouslyVisited)
204296417Sdim        {
205296417Sdim            Status = AscendingCallback (Op, Info->Level, Context);
206296417Sdim            if (ACPI_FAILURE (Status))
207296417Sdim            {
208296417Sdim                return;
209296417Sdim            }
210296417Sdim        }
211296417Sdim        else
212296417Sdim        {
213296417Sdim            /* Let the callback process the node */
214296417Sdim
215296417Sdim            Status = DescendingCallback (Op, Info->Level, Context);
216296417Sdim            if (ACPI_SUCCESS (Status))
217296417Sdim            {
218296417Sdim                /* Visit children first, once */
219296417Sdim
220296417Sdim                Next = AcpiPsGetArg (Op, 0);
221296417Sdim                if (Next)
222296417Sdim                {
223296417Sdim                    Info->Level++;
224296417Sdim                    Op = Next;
225296417Sdim                    continue;
226296417Sdim                }
227296417Sdim            }
228296417Sdim            else if (Status != AE_CTRL_DEPTH)
229296417Sdim            {
230296417Sdim                /* Exit immediately on any error */
231296417Sdim
232296417Sdim                return;
233296417Sdim            }
234296417Sdim        }
235296417Sdim
236296417Sdim        /* Terminate walk at start op */
237296417Sdim
238296417Sdim        if (Op == StartOp)
239296417Sdim        {
240296417Sdim            break;
241296417Sdim        }
242296417Sdim
243296417Sdim        /* No more children, re-visit this node */
244296417Sdim
245296417Sdim        if (!NodePreviouslyVisited)
246296417Sdim        {
247296417Sdim            NodePreviouslyVisited = TRUE;
248296417Sdim            continue;
249296417Sdim        }
250296417Sdim
251296417Sdim        /* No more children, visit peers */
252296417Sdim
253296417Sdim        if (Op->Common.Next)
254296417Sdim        {
255296417Sdim            Op = Op->Common.Next;
256296417Sdim            NodePreviouslyVisited = FALSE;
257296417Sdim        }
258296417Sdim        else
259296417Sdim        {
260296417Sdim            /* No peers, re-visit parent */
261296417Sdim
262296417Sdim            if (Info->Level != 0 )
263296417Sdim            {
264296417Sdim                Info->Level--;
265296417Sdim            }
266296417Sdim
267296417Sdim            Op = Op->Common.Parent;
268296417Sdim            NodePreviouslyVisited = TRUE;
269296417Sdim        }
270296417Sdim    }
271274955Ssvnmir
272274955Ssvnmir    /* If we get here, the walk completed with no errors */
273296417Sdim
274296417Sdim    return;
275296417Sdim}
276296417Sdim
277296417Sdim
278296417Sdim/*******************************************************************************
279296417Sdim *
280274955Ssvnmir * FUNCTION:    AcpiDmBlockType
281296417Sdim *
282296417Sdim * PARAMETERS:  Op              - Object to be examined
283296417Sdim *
284296417Sdim * RETURN:      Status
285274955Ssvnmir *
286274955Ssvnmir * DESCRIPTION: Type of block for this op (parens or braces)
287274955Ssvnmir *
288274955Ssvnmir ******************************************************************************/
289296417Sdim
290296417SdimUINT32
291296417SdimAcpiDmBlockType (
292296417Sdim    ACPI_PARSE_OBJECT       *Op)
293274955Ssvnmir{
294274955Ssvnmir    const ACPI_OPCODE_INFO  *OpInfo;
295274955Ssvnmir
296296417Sdim
297296417Sdim    if (!Op)
298296417Sdim    {
299296417Sdim        return (BLOCK_NONE);
300274955Ssvnmir    }
301274955Ssvnmir
302274955Ssvnmir    switch (Op->Common.AmlOpcode)
303274955Ssvnmir    {
304288943Sdim    case AML_ELSE_OP:
305288943Sdim
306288943Sdim        return (BLOCK_BRACE);
307288943Sdim
308288943Sdim    case AML_METHOD_OP:
309288943Sdim    case AML_DEVICE_OP:
310288943Sdim    case AML_SCOPE_OP:
311288943Sdim    case AML_PROCESSOR_OP:
312288943Sdim    case AML_POWER_RES_OP:
313288943Sdim    case AML_THERMAL_ZONE_OP:
314288943Sdim    case AML_IF_OP:
315288943Sdim    case AML_WHILE_OP:
316288943Sdim    case AML_FIELD_OP:
317296417Sdim    case AML_INDEX_FIELD_OP:
318296417Sdim    case AML_BANK_FIELD_OP:
319296417Sdim
320296417Sdim        return (BLOCK_PAREN | BLOCK_BRACE);
321288943Sdim
322288943Sdim    case AML_BUFFER_OP:
323288943Sdim
324288943Sdim        if (Op->Common.DisasmOpcode == ACPI_DASM_UNICODE)
325288943Sdim        {
326288943Sdim            return (BLOCK_NONE);
327288943Sdim        }
328288943Sdim
329288943Sdim        /*lint -fallthrough */
330288943Sdim
331288943Sdim    case AML_PACKAGE_OP:
332288943Sdim    case AML_VAR_PACKAGE_OP:
333288943Sdim
334288943Sdim        return (BLOCK_PAREN | BLOCK_BRACE);
335288943Sdim
336288943Sdim    case AML_EVENT_OP:
337296417Sdim
338296417Sdim        return (BLOCK_PAREN);
339296417Sdim
340296417Sdim    default:
341288943Sdim
342288943Sdim        OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
343288943Sdim        if (OpInfo->Flags & AML_HAS_ARGS)
344288943Sdim        {
345288943Sdim            return (BLOCK_PAREN);
346296417Sdim        }
347296417Sdim
348296417Sdim        return (BLOCK_NONE);
349296417Sdim    }
350296417Sdim}
351296417Sdim
352296417Sdim
353296417Sdim/*******************************************************************************
354288943Sdim *
355288943Sdim * FUNCTION:    AcpiDmListType
356288943Sdim *
357274955Ssvnmir * PARAMETERS:  Op              - Object to be examined
358274955Ssvnmir *
359274955Ssvnmir * RETURN:      Status
360274955Ssvnmir *
361274955Ssvnmir * DESCRIPTION: Type of block for this op (parens or braces)
362274955Ssvnmir *
363274955Ssvnmir ******************************************************************************/
364274955Ssvnmir
365274955SsvnmirUINT32
366274955SsvnmirAcpiDmListType (
367274955Ssvnmir    ACPI_PARSE_OBJECT       *Op)
368274955Ssvnmir{
369274955Ssvnmir    const ACPI_OPCODE_INFO  *OpInfo;
370296417Sdim
371296417Sdim
372296417Sdim    if (!Op)
373296417Sdim    {
374296417Sdim        return (BLOCK_NONE);
375296417Sdim    }
376296417Sdim
377296417Sdim    switch (Op->Common.AmlOpcode)
378274955Ssvnmir    {
379274955Ssvnmir
380274955Ssvnmir    case AML_ELSE_OP:
381274955Ssvnmir    case AML_METHOD_OP:
382274955Ssvnmir    case AML_DEVICE_OP:
383274955Ssvnmir    case AML_SCOPE_OP:
384274955Ssvnmir    case AML_POWER_RES_OP:
385274955Ssvnmir    case AML_PROCESSOR_OP:
386274955Ssvnmir    case AML_THERMAL_ZONE_OP:
387274955Ssvnmir    case AML_IF_OP:
388274955Ssvnmir    case AML_WHILE_OP:
389274955Ssvnmir    case AML_FIELD_OP:
390274955Ssvnmir    case AML_INDEX_FIELD_OP:
391274955Ssvnmir    case AML_BANK_FIELD_OP:
392274955Ssvnmir
393274955Ssvnmir        return (0);
394274955Ssvnmir
395274955Ssvnmir    case AML_BUFFER_OP:
396274955Ssvnmir    case AML_PACKAGE_OP:
397274955Ssvnmir    case AML_VAR_PACKAGE_OP:
398274955Ssvnmir
399288943Sdim        return (BLOCK_COMMA_LIST);
400288943Sdim
401288943Sdim    default:
402296417Sdim
403296417Sdim        OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
404296417Sdim        if (OpInfo->Flags & AML_HAS_ARGS)
405296417Sdim        {
406296417Sdim            return (BLOCK_COMMA_LIST);
407296417Sdim        }
408296417Sdim
409296417Sdim        return (BLOCK_NONE);
410296417Sdim    }
411296417Sdim}
412296417Sdim
413296417Sdim
414274955Ssvnmir/*******************************************************************************
415274955Ssvnmir *
416274955Ssvnmir * FUNCTION:    AcpiDmDescendingOp
417296417Sdim *
418296417Sdim * PARAMETERS:  ASL_WALK_CALLBACK
419296417Sdim *
420296417Sdim * RETURN:      Status
421296417Sdim *
422296417Sdim * DESCRIPTION: First visitation of a parse object during tree descent.
423296417Sdim *              Decode opcode name and begin parameter list(s), if any.
424296417Sdim *
425296417Sdim ******************************************************************************/
426296417Sdim
427296417SdimACPI_STATUS
428296417SdimAcpiDmDescendingOp (
429296417Sdim    ACPI_PARSE_OBJECT       *Op,
430296417Sdim    UINT32                  Level,
431296417Sdim    void                    *Context)
432296417Sdim{
433296417Sdim    ACPI_OP_WALK_INFO       *Info = Context;
434296417Sdim    const ACPI_OPCODE_INFO  *OpInfo;
435296417Sdim    UINT32                  Name;
436296417Sdim    ACPI_PARSE_OBJECT       *NextOp;
437296417Sdim    ACPI_EXTERNAL_LIST      *NextExternal;
438296417Sdim
439296417Sdim
440296417Sdim    if (Op->Common.DisasmFlags & ACPI_PARSEOP_IGNORE)
441296417Sdim    {
442296417Sdim        /* Ignore this op -- it was handled elsewhere */
443296417Sdim
444296417Sdim        return (AE_CTRL_DEPTH);
445296417Sdim    }
446296417Sdim
447274955Ssvnmir    /* Level 0 is at the Definition Block level */
448274955Ssvnmir
449274955Ssvnmir    if (Level == 0)
450274955Ssvnmir    {
451274955Ssvnmir        /* In verbose mode, print the AML offset, opcode and depth count */
452274955Ssvnmir
453274955Ssvnmir        VERBOSE_PRINT ((DB_FULL_OP_INFO, (UINT32) Op->Common.AmlOffset,
454274955Ssvnmir                    Op->Common.AmlOpcode));
455274955Ssvnmir
456274955Ssvnmir        if (Op->Common.AmlOpcode == AML_SCOPE_OP)
457296417Sdim        {
458296417Sdim            /* This is the beginning of the Definition Block */
459296417Sdim
460296417Sdim            AcpiOsPrintf ("{\n");
461274955Ssvnmir
462274955Ssvnmir            /* Emit all External() declarations here */
463274955Ssvnmir
464274955Ssvnmir            if (AcpiGbl_ExternalList)
465274955Ssvnmir            {
466274955Ssvnmir                AcpiOsPrintf ("    /*\n     * These objects were referenced but not defined in this table\n     */\n");
467274955Ssvnmir
468274955Ssvnmir                /* Walk the list of externals (unresolved references) found during parsing */
469274955Ssvnmir
470274955Ssvnmir                while (AcpiGbl_ExternalList)
471296417Sdim                {
472296417Sdim                    AcpiOsPrintf ("    External (%s)\n", AcpiGbl_ExternalList->Path);
473296417Sdim
474296417Sdim                    NextExternal = AcpiGbl_ExternalList->Next;
475274955Ssvnmir                    ACPI_MEM_FREE (AcpiGbl_ExternalList->Path);
476274955Ssvnmir                    ACPI_MEM_FREE (AcpiGbl_ExternalList);
477274955Ssvnmir                    AcpiGbl_ExternalList = NextExternal;
478274955Ssvnmir                }
479288943Sdim                AcpiOsPrintf ("\n");
480288943Sdim            }
481296417Sdim
482296417Sdim            return (AE_OK);
483296417Sdim        }
484296417Sdim    }
485296417Sdim    else if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
486296417Sdim             (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) &&
487296417Sdim             (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP))
488296417Sdim    {
489296417Sdim            /* This is a first-level element of a term list, indent a new line */
490296417Sdim
491296417Sdim            AcpiDmIndent (Level);
492296417Sdim    }
493296417Sdim
494296417Sdim    /* Print the opcode name */
495296417Sdim
496296417Sdim    AcpiDmDisassembleOneOp (NULL, Info, Op);
497296417Sdim
498296417Sdim    if ((Op->Common.AmlOpcode == AML_NAME_OP) ||
499296417Sdim        (Op->Common.AmlOpcode == AML_RETURN_OP))
500296417Sdim    {
501296417Sdim        Info->Level--;
502296417Sdim    }
503274955Ssvnmir
504274955Ssvnmir    /* Start the opcode argument list if necessary */
505274955Ssvnmir
506274955Ssvnmir    OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
507274955Ssvnmir
508274955Ssvnmir    if ((OpInfo->Flags & AML_HAS_ARGS) ||
509274955Ssvnmir        (Op->Common.AmlOpcode == AML_EVENT_OP))
510274955Ssvnmir    {
511274955Ssvnmir        /* This opcode has an argument list */
512274955Ssvnmir
513274955Ssvnmir        if (AcpiDmBlockType (Op) & BLOCK_PAREN)
514274955Ssvnmir        {
515274955Ssvnmir            AcpiOsPrintf (" (");
516296417Sdim        }
517296417Sdim
518296417Sdim        /* If this is a named opcode, print the associated name value */
519296417Sdim
520274955Ssvnmir        if (OpInfo->Flags & AML_NAMED)
521274955Ssvnmir        {
522274955Ssvnmir            switch (Op->Common.AmlOpcode)
523274955Ssvnmir            {
524274955Ssvnmir            case AML_ALIAS_OP:
525274955Ssvnmir
526274955Ssvnmir                NextOp = AcpiPsGetDepthNext (NULL, Op);
527274955Ssvnmir                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
528274955Ssvnmir                AcpiDmNamestring (NextOp->Common.Value.Name);
529274955Ssvnmir                AcpiOsPrintf (", ");
530296417Sdim
531296417Sdim                /*lint -fallthrough */
532296417Sdim
533296417Sdim            default:
534274955Ssvnmir
535274955Ssvnmir                Name = AcpiPsGetName (Op);
536274955Ssvnmir                if (Op->Named.Path)
537274955Ssvnmir                {
538288943Sdim                    AcpiDmNamestring ((char *) Op->Named.Path);
539288943Sdim                }
540296417Sdim                else
541296417Sdim                {
542296417Sdim                    AcpiDmDumpName ((char *) &Name);
543296417Sdim                }
544296417Sdim
545296417Sdim
546296417Sdim                if (Op->Common.AmlOpcode != AML_INT_NAMEDFIELD_OP)
547296417Sdim                {
548296417Sdim                    AcpiDmValidateName ((char *) &Name, Op);
549296417Sdim                    if (AcpiGbl_DbOpt_verbose)
550296417Sdim                    {
551296417Sdim                        (void) AcpiPsDisplayObjectPathname (NULL, Op);
552296417Sdim                    }
553296417Sdim                }
554296417Sdim                break;
555296417Sdim            }
556296417Sdim
557296417Sdim            switch (Op->Common.AmlOpcode)
558296417Sdim            {
559296417Sdim            case AML_METHOD_OP:
560296417Sdim
561296417Sdim                AcpiDmMethodFlags (Op);
562274955Ssvnmir                AcpiOsPrintf (")");
563274955Ssvnmir                break;
564274955Ssvnmir
565296417Sdim
566296417Sdim            case AML_NAME_OP:
567296417Sdim
568296417Sdim                /* Check for _HID and related EISAID() */
569296417Sdim
570296417Sdim                AcpiIsEisaId (Op);
571296417Sdim                AcpiOsPrintf (", ");
572296417Sdim                break;
573296417Sdim
574296417Sdim
575296417Sdim            case AML_REGION_OP:
576296417Sdim
577296417Sdim                AcpiDmRegionFlags (Op);
578296417Sdim                break;
579296417Sdim
580296417Sdim
581296417Sdim            case AML_POWER_RES_OP:
582296417Sdim
583296417Sdim                /* Mark the next two Ops as part of the parameter list */
584296417Sdim
585296417Sdim                AcpiOsPrintf (", ");
586296417Sdim                NextOp = AcpiPsGetDepthNext (NULL, Op);
587296417Sdim                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
588296417Sdim
589296417Sdim                NextOp = NextOp->Common.Next;
590296417Sdim                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
591296417Sdim                return (AE_OK);
592296417Sdim
593296417Sdim
594296417Sdim            case AML_PROCESSOR_OP:
595296417Sdim
596296417Sdim                /* Mark the next three Ops as part of the parameter list */
597296417Sdim
598296417Sdim                AcpiOsPrintf (", ");
599296417Sdim                NextOp = AcpiPsGetDepthNext (NULL, Op);
600296417Sdim                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
601296417Sdim
602296417Sdim                NextOp = NextOp->Common.Next;
603296417Sdim                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
604296417Sdim
605296417Sdim                NextOp = NextOp->Common.Next;
606296417Sdim                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
607296417Sdim                return (AE_OK);
608296417Sdim
609296417Sdim
610296417Sdim            case AML_MUTEX_OP:
611296417Sdim
612296417Sdim                AcpiOsPrintf (", ");
613296417Sdim                return (AE_OK);
614296417Sdim
615296417Sdim
616274955Ssvnmir            case AML_EVENT_OP:
617274955Ssvnmir            case AML_ALIAS_OP:
618274955Ssvnmir
619296417Sdim                return (AE_OK);
620274955Ssvnmir
621274955Ssvnmir
622274955Ssvnmir            case AML_SCOPE_OP:
623274955Ssvnmir            case AML_DEVICE_OP:
624274955Ssvnmir            case AML_THERMAL_ZONE_OP:
625274955Ssvnmir
626274955Ssvnmir                AcpiOsPrintf (")");
627274955Ssvnmir                break;
628274955Ssvnmir
629296417Sdim
630288943Sdim            default:
631288943Sdim
632296417Sdim                AcpiOsPrintf ("*** Unhandled named opcode\n");
633296417Sdim                break;
634274955Ssvnmir            }
635296417Sdim        }
636288943Sdim
637274955Ssvnmir        else switch (Op->Common.AmlOpcode)
638274955Ssvnmir        {
639274955Ssvnmir        case AML_FIELD_OP:
640274955Ssvnmir        case AML_BANK_FIELD_OP:
641274955Ssvnmir        case AML_INDEX_FIELD_OP:
642296417Sdim
643296417Sdim            Info->BitOffset = 0;
644274955Ssvnmir
645274955Ssvnmir            /* Name of the parent OperationRegion */
646274955Ssvnmir
647296417Sdim            NextOp = AcpiPsGetDepthNext (NULL, Op);
648296417Sdim            AcpiDmNamestring (NextOp->Common.Value.Name);
649274955Ssvnmir            AcpiOsPrintf (", ");
650274955Ssvnmir            NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
651288943Sdim
652288943Sdim            switch (Op->Common.AmlOpcode)
653288943Sdim            {
654288943Sdim            case AML_BANK_FIELD_OP:
655288943Sdim
656274955Ssvnmir                /* Namestring */
657274955Ssvnmir
658274955Ssvnmir                NextOp = AcpiPsGetDepthNext (NULL, NextOp);
659274955Ssvnmir                AcpiDmNamestring (NextOp->Common.Value.Name);
660274955Ssvnmir                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
661296417Sdim                AcpiOsPrintf (", ");
662296417Sdim
663296417Sdim
664296417Sdim                NextOp = NextOp->Common.Next;
665296417Sdim                AcpiDmDisassembleOneOp (NULL, Info, NextOp);
666296417Sdim                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
667296417Sdim                AcpiOsPrintf (", ");
668296417Sdim                break;
669296417Sdim
670296417Sdim            case AML_INDEX_FIELD_OP:
671296417Sdim
672296417Sdim                /* Namestring */
673296417Sdim
674296417Sdim                NextOp = AcpiPsGetDepthNext (NULL, NextOp);
675296417Sdim                AcpiDmNamestring (NextOp->Common.Value.Name);
676296417Sdim                AcpiOsPrintf (", ");
677296417Sdim                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
678296417Sdim                break;
679296417Sdim
680296417Sdim            default:
681296417Sdim
682296417Sdim                break;
683296417Sdim            }
684296417Sdim
685296417Sdim            AcpiDmFieldFlags (NextOp);
686296417Sdim            break;
687296417Sdim
688296417Sdim
689296417Sdim        case AML_BUFFER_OP:
690296417Sdim
691296417Sdim            /* The next op is the size parameter */
692296417Sdim
693296417Sdim            NextOp = AcpiPsGetDepthNext (NULL, Op);
694296417Sdim            if (!NextOp)
695296417Sdim            {
696296417Sdim                /* Single-step support */
697296417Sdim
698296417Sdim                return (AE_OK);
699296417Sdim            }
700296417Sdim
701296417Sdim            if (Op->Common.DisasmOpcode == ACPI_DASM_RESOURCE)
702296417Sdim            {
703296417Sdim                /*
704296417Sdim                 * We have a resource list.  Don't need to output
705296417Sdim                 * the buffer size Op.  Open up a new block
706296417Sdim                 */
707296417Sdim                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
708296417Sdim                NextOp = NextOp->Common.Next;
709296417Sdim                AcpiOsPrintf (")\n");
710296417Sdim                AcpiDmIndent (Info->Level);
711296417Sdim                AcpiOsPrintf ("{\n");
712296417Sdim                return (AE_OK);
713296417Sdim            }
714296417Sdim
715296417Sdim            /* Normal Buffer, mark size as in the parameter list */
716296417Sdim
717296417Sdim            NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
718296417Sdim            return (AE_OK);
719296417Sdim
720296417Sdim
721296417Sdim        case AML_VAR_PACKAGE_OP:
722296417Sdim        case AML_IF_OP:
723296417Sdim        case AML_WHILE_OP:
724296417Sdim
725296417Sdim            /* The next op is the size or predicate parameter */
726296417Sdim
727296417Sdim            NextOp = AcpiPsGetDepthNext (NULL, Op);
728296417Sdim            if (NextOp)
729296417Sdim            {
730296417Sdim                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
731296417Sdim            }
732296417Sdim            return (AE_OK);
733296417Sdim
734296417Sdim
735296417Sdim        case AML_PACKAGE_OP:
736296417Sdim
737296417Sdim            /* The next op is the size or predicate parameter */
738296417Sdim
739296417Sdim            NextOp = AcpiPsGetDepthNext (NULL, Op);
740296417Sdim            if (NextOp)
741296417Sdim            {
742296417Sdim                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
743296417Sdim            }
744296417Sdim            return (AE_OK);
745296417Sdim
746296417Sdim
747296417Sdim        case AML_MATCH_OP:
748296417Sdim
749296417Sdim            AcpiDmMatchOp (Op);
750296417Sdim            break;
751296417Sdim
752296417Sdim
753296417Sdim        default:
754296417Sdim
755296417Sdim            break;
756296417Sdim        }
757296417Sdim
758296417Sdim        if (AcpiDmBlockType (Op) & BLOCK_BRACE)
759296417Sdim        {
760274955Ssvnmir            AcpiOsPrintf ("\n");
761296417Sdim            AcpiDmIndent (Level);
762296417Sdim            AcpiOsPrintf ("{\n");
763296417Sdim        }
764296417Sdim    }
765296417Sdim
766296417Sdim    return (AE_OK);
767296417Sdim}
768296417Sdim
769296417Sdim
770296417Sdim/*******************************************************************************
771296417Sdim *
772296417Sdim * FUNCTION:    AcpiDmAscendingOp
773296417Sdim *
774296417Sdim * PARAMETERS:  ASL_WALK_CALLBACK
775296417Sdim *
776296417Sdim * RETURN:      Status
777296417Sdim *
778296417Sdim * DESCRIPTION: Second visitation of a parse object, during ascent of parse
779296417Sdim *              tree.  Close out any parameter lists and complete the opcode.
780296417Sdim *
781296417Sdim ******************************************************************************/
782296417Sdim
783296417SdimACPI_STATUS
784296417SdimAcpiDmAscendingOp (
785296417Sdim    ACPI_PARSE_OBJECT       *Op,
786274955Ssvnmir    UINT32                  Level,
787274955Ssvnmir    void                    *Context)
788274955Ssvnmir{
789274955Ssvnmir    ACPI_OP_WALK_INFO       *Info = Context;
790274955Ssvnmir
791274955Ssvnmir
792274955Ssvnmir    if (Op->Common.DisasmFlags & ACPI_PARSEOP_IGNORE)
793274955Ssvnmir    {
794274955Ssvnmir        /* Ignore this op -- it was handled elsewhere */
795274955Ssvnmir
796274955Ssvnmir        return (AE_OK);
797288943Sdim    }
798288943Sdim
799288943Sdim    if ((Level == 0) && (Op->Common.AmlOpcode == AML_SCOPE_OP))
800288943Sdim    {
801288943Sdim        /* Indicates the end of the current descriptor block (table) */
802288943Sdim
803288943Sdim        AcpiOsPrintf ("}\n\n");
804288943Sdim        return (AE_OK);
805288943Sdim    }
806288943Sdim
807288943Sdim    switch (AcpiDmBlockType (Op))
808288943Sdim    {
809288943Sdim    case BLOCK_PAREN:
810288943Sdim
811288943Sdim        /* Completed an op that has arguments, add closing paren */
812288943Sdim
813288943Sdim        AcpiOsPrintf (")");
814288943Sdim
815288943Sdim        /* Could be a nested operator, check if comma required */
816288943Sdim
817288943Sdim        if (!AcpiDmCommaIfListMember (Op))
818288943Sdim        {
819288943Sdim            if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
820288943Sdim                     (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) &&
821288943Sdim                     (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP))
822288943Sdim            {
823288943Sdim                /* This is a first-level element of a term list, start a new line */
824288943Sdim
825288943Sdim                AcpiOsPrintf ("\n");
826288943Sdim            }
827288943Sdim        }
828288943Sdim        break;
829288943Sdim
830288943Sdim
831288943Sdim    case BLOCK_BRACE:
832288943Sdim    case (BLOCK_BRACE | BLOCK_PAREN):
833288943Sdim
834288943Sdim        /* Completed an op that has a term list, add closing brace */
835288943Sdim
836288943Sdim        if (Op->Common.DisasmFlags & ACPI_PARSEOP_EMPTY_TERMLIST)
837288943Sdim        {
838274955Ssvnmir            AcpiOsPrintf ("}");
839274955Ssvnmir        }
840274955Ssvnmir        else
841274955Ssvnmir        {
842274955Ssvnmir            AcpiDmIndent (Level);
843274955Ssvnmir            AcpiOsPrintf ("}");
844274955Ssvnmir        }
845296417Sdim
846296417Sdim        AcpiDmCommaIfListMember (Op);
847296417Sdim
848296417Sdim        if (AcpiDmBlockType (Op->Common.Parent) != BLOCK_PAREN)
849296417Sdim        {
850296417Sdim            AcpiOsPrintf ("\n");
851296417Sdim            if (!(Op->Common.DisasmFlags & ACPI_PARSEOP_EMPTY_TERMLIST))
852296417Sdim            {
853296417Sdim                if ((Op->Common.AmlOpcode == AML_IF_OP)  &&
854296417Sdim                    (Op->Common.Next) &&
855296417Sdim                    (Op->Common.Next->Common.AmlOpcode == AML_ELSE_OP))
856296417Sdim                {
857296417Sdim                    break;
858296417Sdim                }
859296417Sdim
860296417Sdim                if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
861296417Sdim                    (!Op->Common.Next))
862296417Sdim                {
863296417Sdim                    break;
864296417Sdim                }
865296417Sdim                AcpiOsPrintf ("\n");
866296417Sdim            }
867296417Sdim        }
868296417Sdim        break;
869296417Sdim
870296417Sdim
871296417Sdim    case BLOCK_NONE:
872296417Sdim    default:
873296417Sdim
874296417Sdim        /* Could be a nested operator, check if comma required */
875296417Sdim
876296417Sdim        if (!AcpiDmCommaIfListMember (Op))
877296417Sdim        {
878296417Sdim            if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
879296417Sdim                     (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) &&
880296417Sdim                     (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP))
881296417Sdim            {
882296417Sdim                /* This is a first-level element of a term list, start a new line */
883296417Sdim
884296417Sdim                AcpiOsPrintf ("\n");
885296417Sdim            }
886296417Sdim        }
887296417Sdim        else if (Op->Common.Parent)
888296417Sdim        {
889296417Sdim            switch (Op->Common.Parent->Common.AmlOpcode)
890296417Sdim            {
891296417Sdim            case AML_PACKAGE_OP:
892296417Sdim            case AML_VAR_PACKAGE_OP:
893296417Sdim
894296417Sdim                if (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST))
895296417Sdim                {
896296417Sdim                    AcpiOsPrintf ("\n");
897296417Sdim                }
898296417Sdim                break;
899296417Sdim
900296417Sdim            default:
901296417Sdim
902296417Sdim                break;
903296417Sdim            }
904296417Sdim        }
905296417Sdim        break;
906296417Sdim    }
907296417Sdim
908296417Sdim    if (Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)
909296417Sdim    {
910296417Sdim        if ((Op->Common.Next) &&
911296417Sdim            (Op->Common.Next->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST))
912296417Sdim        {
913296417Sdim            return (AE_OK);
914296417Sdim        }
915296417Sdim
916296417Sdim        /*
917296417Sdim         * Just completed a parameter node for something like "Buffer (param)".
918296417Sdim         * Close the paren and open up the term list block with a brace
919296417Sdim         */
920296417Sdim        if (Op->Common.Next)
921296417Sdim        {
922296417Sdim            AcpiOsPrintf (")\n");
923296417Sdim            AcpiDmIndent (Level - 1);
924296417Sdim            AcpiOsPrintf ("{\n");
925296417Sdim        }
926296417Sdim        else
927296417Sdim        {
928296417Sdim            Op->Common.Parent->Common.DisasmFlags |= ACPI_PARSEOP_EMPTY_TERMLIST;
929296417Sdim            AcpiOsPrintf (") {");
930296417Sdim        }
931296417Sdim    }
932296417Sdim
933296417Sdim    if ((Op->Common.AmlOpcode == AML_NAME_OP) ||
934296417Sdim        (Op->Common.AmlOpcode == AML_RETURN_OP))
935296417Sdim    {
936296417Sdim        Info->Level++;
937296417Sdim    }
938296417Sdim    return (AE_OK);
939296417Sdim}
940296417Sdim
941296417Sdim
942296417Sdim#endif  /* ACPI_DISASSEMBLER */
943296417Sdim