1100966Siwasaki/*******************************************************************************
2100966Siwasaki *
3100966Siwasaki * Module Name: dmwalk - AML disassembly tree walk
4100966Siwasaki *
5100966Siwasaki ******************************************************************************/
6100966Siwasaki
7217365Sjkim/*
8217365Sjkim * Copyright (C) 2000 - 2011, Intel Corp.
9100966Siwasaki * All rights reserved.
10100966Siwasaki *
11217365Sjkim * Redistribution and use in source and binary forms, with or without
12217365Sjkim * modification, are permitted provided that the following conditions
13217365Sjkim * are met:
14217365Sjkim * 1. Redistributions of source code must retain the above copyright
15217365Sjkim *    notice, this list of conditions, and the following disclaimer,
16217365Sjkim *    without modification.
17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18217365Sjkim *    substantially similar to the "NO WARRANTY" disclaimer below
19217365Sjkim *    ("Disclaimer") and any redistribution must be conditioned upon
20217365Sjkim *    including a substantially similar Disclaimer requirement for further
21217365Sjkim *    binary redistribution.
22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names
23217365Sjkim *    of any contributors may be used to endorse or promote products derived
24217365Sjkim *    from this software without specific prior written permission.
25100966Siwasaki *
26217365Sjkim * Alternatively, this software may be distributed under the terms of the
27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free
28217365Sjkim * Software Foundation.
29100966Siwasaki *
30217365Sjkim * NO WARRANTY
31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41217365Sjkim * POSSIBILITY OF SUCH DAMAGES.
42217365Sjkim */
43100966Siwasaki
44100966Siwasaki
45193341Sjkim#include <contrib/dev/acpica/include/acpi.h>
46193341Sjkim#include <contrib/dev/acpica/include/accommon.h>
47193341Sjkim#include <contrib/dev/acpica/include/acparser.h>
48193341Sjkim#include <contrib/dev/acpica/include/amlcode.h>
49193341Sjkim#include <contrib/dev/acpica/include/acdisasm.h>
50193341Sjkim#include <contrib/dev/acpica/include/acdebug.h>
51100966Siwasaki
52100966Siwasaki
53100966Siwasaki#ifdef ACPI_DISASSEMBLER
54100966Siwasaki
55102550Siwasaki#define _COMPONENT          ACPI_CA_DEBUGGER
56100966Siwasaki        ACPI_MODULE_NAME    ("dmwalk")
57100966Siwasaki
58100966Siwasaki
59151937Sjkim#define DB_FULL_OP_INFO     "[%4.4s] @%5.5X #%4.4X:  "
60100966Siwasaki
61198237Sjkim/* Stub for non-compiler code */
62198237Sjkim
63198237Sjkim#ifndef ACPI_ASL_COMPILER
64198237Sjkimvoid
65198237SjkimAcpiDmEmitExternals (
66198237Sjkim    void)
67198237Sjkim{
68198237Sjkim    return;
69198237Sjkim}
70198237Sjkim#endif
71198237Sjkim
72151937Sjkim/* Local prototypes */
73100966Siwasaki
74151937Sjkimstatic ACPI_STATUS
75151937SjkimAcpiDmDescendingOp (
76151937Sjkim    ACPI_PARSE_OBJECT       *Op,
77151937Sjkim    UINT32                  Level,
78151937Sjkim    void                    *Context);
79151937Sjkim
80151937Sjkimstatic ACPI_STATUS
81151937SjkimAcpiDmAscendingOp (
82151937Sjkim    ACPI_PARSE_OBJECT       *Op,
83151937Sjkim    UINT32                  Level,
84151937Sjkim    void                    *Context);
85151937Sjkim
86151937Sjkimstatic UINT32
87151937SjkimAcpiDmBlockType (
88151937Sjkim    ACPI_PARSE_OBJECT       *Op);
89151937Sjkim
90151937Sjkim
91100966Siwasaki/*******************************************************************************
92100966Siwasaki *
93100966Siwasaki * FUNCTION:    AcpiDmDisassemble
94100966Siwasaki *
95151937Sjkim * PARAMETERS:  WalkState       - Current state
96151937Sjkim *              Origin          - Starting object
97100966Siwasaki *              NumOpcodes      - Max number of opcodes to be displayed
98100966Siwasaki *
99100966Siwasaki * RETURN:      None
100100966Siwasaki *
101100966Siwasaki * DESCRIPTION: Disassemble parser object and its children.  This is the
102100966Siwasaki *              main entry point of the disassembler.
103100966Siwasaki *
104100966Siwasaki ******************************************************************************/
105100966Siwasaki
106100966Siwasakivoid
107100966SiwasakiAcpiDmDisassemble (
108100966Siwasaki    ACPI_WALK_STATE         *WalkState,
109100966Siwasaki    ACPI_PARSE_OBJECT       *Origin,
110100966Siwasaki    UINT32                  NumOpcodes)
111100966Siwasaki{
112100966Siwasaki    ACPI_PARSE_OBJECT       *Op = Origin;
113100966Siwasaki    ACPI_OP_WALK_INFO       Info;
114100966Siwasaki
115100966Siwasaki
116100966Siwasaki    if (!Op)
117100966Siwasaki    {
118100966Siwasaki        return;
119100966Siwasaki    }
120100966Siwasaki
121167802Sjkim    Info.Flags = 0;
122100966Siwasaki    Info.Level = 0;
123167802Sjkim    Info.Count = 0;
124151937Sjkim    Info.WalkState = WalkState;
125100966Siwasaki    AcpiDmWalkParseTree (Op, AcpiDmDescendingOp, AcpiDmAscendingOp, &Info);
126100966Siwasaki    return;
127100966Siwasaki}
128100966Siwasaki
129100966Siwasaki
130100966Siwasaki/*******************************************************************************
131100966Siwasaki *
132100966Siwasaki * FUNCTION:    AcpiDmWalkParseTree
133100966Siwasaki *
134151937Sjkim * PARAMETERS:  Op                      - Root Op object
135151937Sjkim *              DescendingCallback      - Called during tree descent
136100966Siwasaki *              AscendingCallback       - Called during tree ascent
137100966Siwasaki *              Context                 - To be passed to the callbacks
138100966Siwasaki *
139100966Siwasaki * RETURN:      Status from callback(s)
140100966Siwasaki *
141100966Siwasaki * DESCRIPTION: Walk the entire parse tree.
142100966Siwasaki *
143100966Siwasaki ******************************************************************************/
144100966Siwasaki
145167802Sjkimvoid
146100966SiwasakiAcpiDmWalkParseTree (
147100966Siwasaki    ACPI_PARSE_OBJECT       *Op,
148100966Siwasaki    ASL_WALK_CALLBACK       DescendingCallback,
149100966Siwasaki    ASL_WALK_CALLBACK       AscendingCallback,
150100966Siwasaki    void                    *Context)
151100966Siwasaki{
152100966Siwasaki    BOOLEAN                 NodePreviouslyVisited;
153100966Siwasaki    ACPI_PARSE_OBJECT       *StartOp = Op;
154100966Siwasaki    ACPI_STATUS             Status;
155100966Siwasaki    ACPI_PARSE_OBJECT       *Next;
156100966Siwasaki    ACPI_OP_WALK_INFO       *Info = Context;
157100966Siwasaki
158100966Siwasaki
159100966Siwasaki    Info->Level = 0;
160100966Siwasaki    NodePreviouslyVisited = FALSE;
161100966Siwasaki
162100966Siwasaki    while (Op)
163100966Siwasaki    {
164100966Siwasaki        if (NodePreviouslyVisited)
165100966Siwasaki        {
166167802Sjkim            if (AscendingCallback)
167100966Siwasaki            {
168167802Sjkim                Status = AscendingCallback (Op, Info->Level, Context);
169167802Sjkim                if (ACPI_FAILURE (Status))
170167802Sjkim                {
171167802Sjkim                    return;
172167802Sjkim                }
173100966Siwasaki            }
174100966Siwasaki        }
175100966Siwasaki        else
176100966Siwasaki        {
177117521Snjl            /* Let the callback process the node */
178117521Snjl
179100966Siwasaki            Status = DescendingCallback (Op, Info->Level, Context);
180100966Siwasaki            if (ACPI_SUCCESS (Status))
181100966Siwasaki            {
182100966Siwasaki                /* Visit children first, once */
183100966Siwasaki
184100966Siwasaki                Next = AcpiPsGetArg (Op, 0);
185100966Siwasaki                if (Next)
186100966Siwasaki                {
187100966Siwasaki                    Info->Level++;
188100966Siwasaki                    Op = Next;
189100966Siwasaki                    continue;
190100966Siwasaki                }
191100966Siwasaki            }
192100966Siwasaki            else if (Status != AE_CTRL_DEPTH)
193100966Siwasaki            {
194100966Siwasaki                /* Exit immediately on any error */
195100966Siwasaki
196100966Siwasaki                return;
197100966Siwasaki            }
198100966Siwasaki        }
199100966Siwasaki
200100966Siwasaki        /* Terminate walk at start op */
201100966Siwasaki
202100966Siwasaki        if (Op == StartOp)
203100966Siwasaki        {
204100966Siwasaki            break;
205100966Siwasaki        }
206100966Siwasaki
207100966Siwasaki        /* No more children, re-visit this node */
208100966Siwasaki
209100966Siwasaki        if (!NodePreviouslyVisited)
210100966Siwasaki        {
211100966Siwasaki            NodePreviouslyVisited = TRUE;
212100966Siwasaki            continue;
213100966Siwasaki        }
214100966Siwasaki
215100966Siwasaki        /* No more children, visit peers */
216100966Siwasaki
217100966Siwasaki        if (Op->Common.Next)
218100966Siwasaki        {
219100966Siwasaki            Op = Op->Common.Next;
220100966Siwasaki            NodePreviouslyVisited = FALSE;
221100966Siwasaki        }
222100966Siwasaki        else
223100966Siwasaki        {
224100966Siwasaki            /* No peers, re-visit parent */
225100966Siwasaki
226100966Siwasaki            if (Info->Level != 0 )
227100966Siwasaki            {
228100966Siwasaki                Info->Level--;
229100966Siwasaki            }
230100966Siwasaki
231100966Siwasaki            Op = Op->Common.Parent;
232100966Siwasaki            NodePreviouslyVisited = TRUE;
233100966Siwasaki        }
234100966Siwasaki    }
235100966Siwasaki
236100966Siwasaki    /* If we get here, the walk completed with no errors */
237100966Siwasaki
238100966Siwasaki    return;
239100966Siwasaki}
240100966Siwasaki
241100966Siwasaki
242100966Siwasaki/*******************************************************************************
243100966Siwasaki *
244100966Siwasaki * FUNCTION:    AcpiDmBlockType
245100966Siwasaki *
246100966Siwasaki * PARAMETERS:  Op              - Object to be examined
247100966Siwasaki *
248151937Sjkim * RETURN:      BlockType - not a block, parens, braces, or even both.
249100966Siwasaki *
250100966Siwasaki * DESCRIPTION: Type of block for this op (parens or braces)
251100966Siwasaki *
252100966Siwasaki ******************************************************************************/
253100966Siwasaki
254151937Sjkimstatic UINT32
255100966SiwasakiAcpiDmBlockType (
256100966Siwasaki    ACPI_PARSE_OBJECT       *Op)
257100966Siwasaki{
258100966Siwasaki    const ACPI_OPCODE_INFO  *OpInfo;
259100966Siwasaki
260100966Siwasaki
261100966Siwasaki    if (!Op)
262100966Siwasaki    {
263100966Siwasaki        return (BLOCK_NONE);
264100966Siwasaki    }
265100966Siwasaki
266100966Siwasaki    switch (Op->Common.AmlOpcode)
267100966Siwasaki    {
268100966Siwasaki    case AML_ELSE_OP:
269100966Siwasaki
270100966Siwasaki        return (BLOCK_BRACE);
271100966Siwasaki
272100966Siwasaki    case AML_METHOD_OP:
273100966Siwasaki    case AML_DEVICE_OP:
274100966Siwasaki    case AML_SCOPE_OP:
275100966Siwasaki    case AML_PROCESSOR_OP:
276100966Siwasaki    case AML_POWER_RES_OP:
277100966Siwasaki    case AML_THERMAL_ZONE_OP:
278100966Siwasaki    case AML_IF_OP:
279100966Siwasaki    case AML_WHILE_OP:
280100966Siwasaki    case AML_FIELD_OP:
281100966Siwasaki    case AML_INDEX_FIELD_OP:
282100966Siwasaki    case AML_BANK_FIELD_OP:
283100966Siwasaki
284100966Siwasaki        return (BLOCK_PAREN | BLOCK_BRACE);
285100966Siwasaki
286100966Siwasaki    case AML_BUFFER_OP:
287100966Siwasaki
288100966Siwasaki        if (Op->Common.DisasmOpcode == ACPI_DASM_UNICODE)
289100966Siwasaki        {
290100966Siwasaki            return (BLOCK_NONE);
291100966Siwasaki        }
292100966Siwasaki
293100966Siwasaki        /*lint -fallthrough */
294100966Siwasaki
295100966Siwasaki    case AML_PACKAGE_OP:
296100966Siwasaki    case AML_VAR_PACKAGE_OP:
297100966Siwasaki
298100966Siwasaki        return (BLOCK_PAREN | BLOCK_BRACE);
299100966Siwasaki
300100966Siwasaki    case AML_EVENT_OP:
301100966Siwasaki
302100966Siwasaki        return (BLOCK_PAREN);
303100966Siwasaki
304100966Siwasaki    default:
305100966Siwasaki
306100966Siwasaki        OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
307100966Siwasaki        if (OpInfo->Flags & AML_HAS_ARGS)
308100966Siwasaki        {
309100966Siwasaki            return (BLOCK_PAREN);
310100966Siwasaki        }
311100966Siwasaki
312100966Siwasaki        return (BLOCK_NONE);
313100966Siwasaki    }
314100966Siwasaki}
315100966Siwasaki
316100966Siwasaki
317100966Siwasaki/*******************************************************************************
318100966Siwasaki *
319100966Siwasaki * FUNCTION:    AcpiDmListType
320100966Siwasaki *
321100966Siwasaki * PARAMETERS:  Op              - Object to be examined
322100966Siwasaki *
323151937Sjkim * RETURN:      ListType - has commas or not.
324100966Siwasaki *
325100966Siwasaki * DESCRIPTION: Type of block for this op (parens or braces)
326100966Siwasaki *
327100966Siwasaki ******************************************************************************/
328100966Siwasaki
329100966SiwasakiUINT32
330100966SiwasakiAcpiDmListType (
331100966Siwasaki    ACPI_PARSE_OBJECT       *Op)
332100966Siwasaki{
333100966Siwasaki    const ACPI_OPCODE_INFO  *OpInfo;
334100966Siwasaki
335100966Siwasaki
336100966Siwasaki    if (!Op)
337100966Siwasaki    {
338100966Siwasaki        return (BLOCK_NONE);
339100966Siwasaki    }
340100966Siwasaki
341100966Siwasaki    switch (Op->Common.AmlOpcode)
342100966Siwasaki    {
343100966Siwasaki
344100966Siwasaki    case AML_ELSE_OP:
345100966Siwasaki    case AML_METHOD_OP:
346100966Siwasaki    case AML_DEVICE_OP:
347100966Siwasaki    case AML_SCOPE_OP:
348100966Siwasaki    case AML_POWER_RES_OP:
349100966Siwasaki    case AML_PROCESSOR_OP:
350100966Siwasaki    case AML_THERMAL_ZONE_OP:
351100966Siwasaki    case AML_IF_OP:
352100966Siwasaki    case AML_WHILE_OP:
353100966Siwasaki    case AML_FIELD_OP:
354100966Siwasaki    case AML_INDEX_FIELD_OP:
355100966Siwasaki    case AML_BANK_FIELD_OP:
356100966Siwasaki
357151937Sjkim        return (BLOCK_NONE);
358100966Siwasaki
359100966Siwasaki    case AML_BUFFER_OP:
360100966Siwasaki    case AML_PACKAGE_OP:
361100966Siwasaki    case AML_VAR_PACKAGE_OP:
362100966Siwasaki
363100966Siwasaki        return (BLOCK_COMMA_LIST);
364100966Siwasaki
365100966Siwasaki    default:
366100966Siwasaki
367100966Siwasaki        OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
368100966Siwasaki        if (OpInfo->Flags & AML_HAS_ARGS)
369100966Siwasaki        {
370100966Siwasaki            return (BLOCK_COMMA_LIST);
371100966Siwasaki        }
372100966Siwasaki
373100966Siwasaki        return (BLOCK_NONE);
374100966Siwasaki    }
375100966Siwasaki}
376100966Siwasaki
377100966Siwasaki
378100966Siwasaki/*******************************************************************************
379100966Siwasaki *
380100966Siwasaki * FUNCTION:    AcpiDmDescendingOp
381100966Siwasaki *
382100966Siwasaki * PARAMETERS:  ASL_WALK_CALLBACK
383100966Siwasaki *
384100966Siwasaki * RETURN:      Status
385100966Siwasaki *
386102550Siwasaki * DESCRIPTION: First visitation of a parse object during tree descent.
387100966Siwasaki *              Decode opcode name and begin parameter list(s), if any.
388100966Siwasaki *
389100966Siwasaki ******************************************************************************/
390100966Siwasaki
391151937Sjkimstatic ACPI_STATUS
392100966SiwasakiAcpiDmDescendingOp (
393100966Siwasaki    ACPI_PARSE_OBJECT       *Op,
394100966Siwasaki    UINT32                  Level,
395100966Siwasaki    void                    *Context)
396100966Siwasaki{
397100966Siwasaki    ACPI_OP_WALK_INFO       *Info = Context;
398100966Siwasaki    const ACPI_OPCODE_INFO  *OpInfo;
399100966Siwasaki    UINT32                  Name;
400100966Siwasaki    ACPI_PARSE_OBJECT       *NextOp;
401100966Siwasaki
402100966Siwasaki
403100966Siwasaki    if (Op->Common.DisasmFlags & ACPI_PARSEOP_IGNORE)
404100966Siwasaki    {
405100966Siwasaki        /* Ignore this op -- it was handled elsewhere */
406100966Siwasaki
407100966Siwasaki        return (AE_CTRL_DEPTH);
408100966Siwasaki    }
409100966Siwasaki
410128212Snjl    /* Level 0 is at the Definition Block level */
411100966Siwasaki
412100966Siwasaki    if (Level == 0)
413100966Siwasaki    {
414100966Siwasaki        /* In verbose mode, print the AML offset, opcode and depth count */
415100966Siwasaki
416151937Sjkim        if (Info->WalkState)
417151937Sjkim        {
418151937Sjkim            VERBOSE_PRINT ((DB_FULL_OP_INFO,
419151937Sjkim                (Info->WalkState->MethodNode ?
420151937Sjkim                    Info->WalkState->MethodNode->Name.Ascii : "   "),
421151937Sjkim                Op->Common.AmlOffset, (UINT32) Op->Common.AmlOpcode));
422151937Sjkim        }
423100966Siwasaki
424100966Siwasaki        if (Op->Common.AmlOpcode == AML_SCOPE_OP)
425100966Siwasaki        {
426128212Snjl            /* This is the beginning of the Definition Block */
427128212Snjl
428100966Siwasaki            AcpiOsPrintf ("{\n");
429128212Snjl
430128212Snjl            /* Emit all External() declarations here */
431128212Snjl
432198237Sjkim            AcpiDmEmitExternals ();
433100966Siwasaki            return (AE_OK);
434100966Siwasaki        }
435100966Siwasaki    }
436100966Siwasaki    else if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
437100966Siwasaki             (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) &&
438100966Siwasaki             (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP))
439100966Siwasaki    {
440151937Sjkim            /*
441151937Sjkim             * This is a first-level element of a term list,
442151937Sjkim             * indent a new line
443151937Sjkim             */
444100966Siwasaki            AcpiDmIndent (Level);
445167802Sjkim            Info->LastLevel = Level;
446167802Sjkim            Info->Count = 0;
447100966Siwasaki    }
448100966Siwasaki
449167802Sjkim    /*
450167802Sjkim     * This is an inexpensive mechanism to try and keep lines from getting
451167802Sjkim     * too long. When the limit is hit, start a new line at the previous
452167802Sjkim     * indent plus one. A better but more expensive mechanism would be to
453167802Sjkim     * keep track of the current column.
454167802Sjkim     */
455167802Sjkim    Info->Count++;
456167802Sjkim    if (Info->Count /*+Info->LastLevel*/ > 10)
457167802Sjkim    {
458167802Sjkim        Info->Count = 0;
459167802Sjkim        AcpiOsPrintf ("\n");
460167802Sjkim        AcpiDmIndent (Info->LastLevel + 1);
461167802Sjkim    }
462167802Sjkim
463100966Siwasaki    /* Print the opcode name */
464100966Siwasaki
465100966Siwasaki    AcpiDmDisassembleOneOp (NULL, Info, Op);
466100966Siwasaki
467167802Sjkim    if (Op->Common.DisasmOpcode == ACPI_DASM_LNOT_PREFIX)
468167802Sjkim    {
469167802Sjkim        return (AE_OK);
470167802Sjkim    }
471167802Sjkim
472100966Siwasaki    if ((Op->Common.AmlOpcode == AML_NAME_OP) ||
473100966Siwasaki        (Op->Common.AmlOpcode == AML_RETURN_OP))
474100966Siwasaki    {
475100966Siwasaki        Info->Level--;
476100966Siwasaki    }
477100966Siwasaki
478117521Snjl    /* Start the opcode argument list if necessary */
479117521Snjl
480100966Siwasaki    OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
481100966Siwasaki
482102550Siwasaki    if ((OpInfo->Flags & AML_HAS_ARGS) ||
483100966Siwasaki        (Op->Common.AmlOpcode == AML_EVENT_OP))
484100966Siwasaki    {
485100966Siwasaki        /* This opcode has an argument list */
486100966Siwasaki
487100966Siwasaki        if (AcpiDmBlockType (Op) & BLOCK_PAREN)
488100966Siwasaki        {
489100966Siwasaki            AcpiOsPrintf (" (");
490100966Siwasaki        }
491100966Siwasaki
492117521Snjl        /* If this is a named opcode, print the associated name value */
493117521Snjl
494100966Siwasaki        if (OpInfo->Flags & AML_NAMED)
495100966Siwasaki        {
496100966Siwasaki            switch (Op->Common.AmlOpcode)
497100966Siwasaki            {
498100966Siwasaki            case AML_ALIAS_OP:
499100966Siwasaki
500100966Siwasaki                NextOp = AcpiPsGetDepthNext (NULL, Op);
501100966Siwasaki                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
502100966Siwasaki                AcpiDmNamestring (NextOp->Common.Value.Name);
503100966Siwasaki                AcpiOsPrintf (", ");
504100966Siwasaki
505100966Siwasaki                /*lint -fallthrough */
506100966Siwasaki
507100966Siwasaki            default:
508100966Siwasaki
509100966Siwasaki                Name = AcpiPsGetName (Op);
510100966Siwasaki                if (Op->Named.Path)
511100966Siwasaki                {
512100966Siwasaki                    AcpiDmNamestring ((char *) Op->Named.Path);
513100966Siwasaki                }
514100966Siwasaki                else
515100966Siwasaki                {
516193267Sjkim                    AcpiDmDumpName (Name);
517100966Siwasaki                }
518100966Siwasaki
519100966Siwasaki                if (Op->Common.AmlOpcode != AML_INT_NAMEDFIELD_OP)
520100966Siwasaki                {
521100966Siwasaki                    if (AcpiGbl_DbOpt_verbose)
522100966Siwasaki                    {
523100966Siwasaki                        (void) AcpiPsDisplayObjectPathname (NULL, Op);
524100966Siwasaki                    }
525100966Siwasaki                }
526100966Siwasaki                break;
527100966Siwasaki            }
528100966Siwasaki
529100966Siwasaki            switch (Op->Common.AmlOpcode)
530100966Siwasaki            {
531100966Siwasaki            case AML_METHOD_OP:
532100966Siwasaki
533100966Siwasaki                AcpiDmMethodFlags (Op);
534100966Siwasaki                AcpiOsPrintf (")");
535100966Siwasaki                break;
536100966Siwasaki
537100966Siwasaki
538100966Siwasaki            case AML_NAME_OP:
539100966Siwasaki
540100966Siwasaki                /* Check for _HID and related EISAID() */
541100966Siwasaki
542151937Sjkim                AcpiDmIsEisaId (Op);
543100966Siwasaki                AcpiOsPrintf (", ");
544100966Siwasaki                break;
545100966Siwasaki
546100966Siwasaki
547100966Siwasaki            case AML_REGION_OP:
548100966Siwasaki
549100966Siwasaki                AcpiDmRegionFlags (Op);
550100966Siwasaki                break;
551100966Siwasaki
552100966Siwasaki
553100966Siwasaki            case AML_POWER_RES_OP:
554100966Siwasaki
555100966Siwasaki                /* Mark the next two Ops as part of the parameter list */
556100966Siwasaki
557100966Siwasaki                AcpiOsPrintf (", ");
558100966Siwasaki                NextOp = AcpiPsGetDepthNext (NULL, Op);
559100966Siwasaki                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
560100966Siwasaki
561100966Siwasaki                NextOp = NextOp->Common.Next;
562100966Siwasaki                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
563100966Siwasaki                return (AE_OK);
564100966Siwasaki
565100966Siwasaki
566100966Siwasaki            case AML_PROCESSOR_OP:
567100966Siwasaki
568100966Siwasaki                /* Mark the next three Ops as part of the parameter list */
569100966Siwasaki
570100966Siwasaki                AcpiOsPrintf (", ");
571100966Siwasaki                NextOp = AcpiPsGetDepthNext (NULL, Op);
572100966Siwasaki                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
573100966Siwasaki
574100966Siwasaki                NextOp = NextOp->Common.Next;
575100966Siwasaki                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
576100966Siwasaki
577100966Siwasaki                NextOp = NextOp->Common.Next;
578100966Siwasaki                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
579100966Siwasaki                return (AE_OK);
580100966Siwasaki
581100966Siwasaki
582100966Siwasaki            case AML_MUTEX_OP:
583167802Sjkim            case AML_DATA_REGION_OP:
584100966Siwasaki
585100966Siwasaki                AcpiOsPrintf (", ");
586100966Siwasaki                return (AE_OK);
587100966Siwasaki
588100966Siwasaki
589100966Siwasaki            case AML_EVENT_OP:
590100966Siwasaki            case AML_ALIAS_OP:
591100966Siwasaki
592100966Siwasaki                return (AE_OK);
593100966Siwasaki
594100966Siwasaki
595100966Siwasaki            case AML_SCOPE_OP:
596100966Siwasaki            case AML_DEVICE_OP:
597100966Siwasaki            case AML_THERMAL_ZONE_OP:
598100966Siwasaki
599100966Siwasaki                AcpiOsPrintf (")");
600100966Siwasaki                break;
601100966Siwasaki
602100966Siwasaki
603100966Siwasaki            default:
604100966Siwasaki
605167802Sjkim                AcpiOsPrintf ("*** Unhandled named opcode %X\n", Op->Common.AmlOpcode);
606100966Siwasaki                break;
607100966Siwasaki            }
608100966Siwasaki        }
609100966Siwasaki
610100966Siwasaki        else switch (Op->Common.AmlOpcode)
611100966Siwasaki        {
612100966Siwasaki        case AML_FIELD_OP:
613100966Siwasaki        case AML_BANK_FIELD_OP:
614100966Siwasaki        case AML_INDEX_FIELD_OP:
615100966Siwasaki
616100966Siwasaki            Info->BitOffset = 0;
617100966Siwasaki
618100966Siwasaki            /* Name of the parent OperationRegion */
619100966Siwasaki
620100966Siwasaki            NextOp = AcpiPsGetDepthNext (NULL, Op);
621100966Siwasaki            AcpiDmNamestring (NextOp->Common.Value.Name);
622100966Siwasaki            AcpiOsPrintf (", ");
623100966Siwasaki            NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
624100966Siwasaki
625100966Siwasaki            switch (Op->Common.AmlOpcode)
626100966Siwasaki            {
627100966Siwasaki            case AML_BANK_FIELD_OP:
628100966Siwasaki
629167802Sjkim                /* Namestring - Bank Name */
630100966Siwasaki
631100966Siwasaki                NextOp = AcpiPsGetDepthNext (NULL, NextOp);
632100966Siwasaki                AcpiDmNamestring (NextOp->Common.Value.Name);
633100966Siwasaki                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
634100966Siwasaki                AcpiOsPrintf (", ");
635100966Siwasaki
636167802Sjkim                /*
637167802Sjkim                 * Bank Value. This is a TermArg in the middle of the parameter
638167802Sjkim                 * list, must handle it here.
639167802Sjkim                 *
640167802Sjkim                 * Disassemble the TermArg parse tree. ACPI_PARSEOP_PARAMLIST
641167802Sjkim                 * eliminates newline in the output.
642167802Sjkim                 */
643167802Sjkim                NextOp = NextOp->Common.Next;
644100966Siwasaki
645167802Sjkim                Info->Flags = ACPI_PARSEOP_PARAMLIST;
646167802Sjkim                AcpiDmWalkParseTree (NextOp, AcpiDmDescendingOp, AcpiDmAscendingOp, Info);
647167802Sjkim                Info->Flags = 0;
648167802Sjkim                Info->Level = Level;
649167802Sjkim
650100966Siwasaki                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
651100966Siwasaki                AcpiOsPrintf (", ");
652100966Siwasaki                break;
653100966Siwasaki
654100966Siwasaki            case AML_INDEX_FIELD_OP:
655100966Siwasaki
656167802Sjkim                /* Namestring - Data Name */
657100966Siwasaki
658100966Siwasaki                NextOp = AcpiPsGetDepthNext (NULL, NextOp);
659100966Siwasaki                AcpiDmNamestring (NextOp->Common.Value.Name);
660100966Siwasaki                AcpiOsPrintf (", ");
661100966Siwasaki                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
662100966Siwasaki                break;
663100966Siwasaki
664100966Siwasaki            default:
665100966Siwasaki
666100966Siwasaki                break;
667100966Siwasaki            }
668100966Siwasaki
669100966Siwasaki            AcpiDmFieldFlags (NextOp);
670100966Siwasaki            break;
671100966Siwasaki
672100966Siwasaki
673100966Siwasaki        case AML_BUFFER_OP:
674100966Siwasaki
675100966Siwasaki            /* The next op is the size parameter */
676100966Siwasaki
677100966Siwasaki            NextOp = AcpiPsGetDepthNext (NULL, Op);
678100966Siwasaki            if (!NextOp)
679100966Siwasaki            {
680100966Siwasaki                /* Single-step support */
681100966Siwasaki
682100966Siwasaki                return (AE_OK);
683100966Siwasaki            }
684100966Siwasaki
685100966Siwasaki            if (Op->Common.DisasmOpcode == ACPI_DASM_RESOURCE)
686100966Siwasaki            {
687100966Siwasaki                /*
688102550Siwasaki                 * We have a resource list.  Don't need to output
689100966Siwasaki                 * the buffer size Op.  Open up a new block
690100966Siwasaki                 */
691100966Siwasaki                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
692100966Siwasaki                NextOp = NextOp->Common.Next;
693100966Siwasaki                AcpiOsPrintf (")\n");
694100966Siwasaki                AcpiDmIndent (Info->Level);
695100966Siwasaki                AcpiOsPrintf ("{\n");
696100966Siwasaki                return (AE_OK);
697100966Siwasaki            }
698100966Siwasaki
699100966Siwasaki            /* Normal Buffer, mark size as in the parameter list */
700100966Siwasaki
701100966Siwasaki            NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
702100966Siwasaki            return (AE_OK);
703100966Siwasaki
704100966Siwasaki
705100966Siwasaki        case AML_VAR_PACKAGE_OP:
706100966Siwasaki        case AML_IF_OP:
707100966Siwasaki        case AML_WHILE_OP:
708100966Siwasaki
709100966Siwasaki            /* The next op is the size or predicate parameter */
710100966Siwasaki
711100966Siwasaki            NextOp = AcpiPsGetDepthNext (NULL, Op);
712100966Siwasaki            if (NextOp)
713100966Siwasaki            {
714100966Siwasaki                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
715100966Siwasaki            }
716100966Siwasaki            return (AE_OK);
717100966Siwasaki
718100966Siwasaki
719100966Siwasaki        case AML_PACKAGE_OP:
720100966Siwasaki
721100966Siwasaki            /* The next op is the size or predicate parameter */
722100966Siwasaki
723100966Siwasaki            NextOp = AcpiPsGetDepthNext (NULL, Op);
724100966Siwasaki            if (NextOp)
725100966Siwasaki            {
726100966Siwasaki                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
727100966Siwasaki            }
728100966Siwasaki            return (AE_OK);
729100966Siwasaki
730100966Siwasaki
731100966Siwasaki        case AML_MATCH_OP:
732100966Siwasaki
733100966Siwasaki            AcpiDmMatchOp (Op);
734100966Siwasaki            break;
735100966Siwasaki
736100966Siwasaki
737100966Siwasaki        default:
738100966Siwasaki
739100966Siwasaki            break;
740100966Siwasaki        }
741100966Siwasaki
742100966Siwasaki        if (AcpiDmBlockType (Op) & BLOCK_BRACE)
743100966Siwasaki        {
744100966Siwasaki            AcpiOsPrintf ("\n");
745100966Siwasaki            AcpiDmIndent (Level);
746100966Siwasaki            AcpiOsPrintf ("{\n");
747100966Siwasaki        }
748100966Siwasaki    }
749100966Siwasaki
750100966Siwasaki    return (AE_OK);
751100966Siwasaki}
752100966Siwasaki
753100966Siwasaki
754100966Siwasaki/*******************************************************************************
755100966Siwasaki *
756100966Siwasaki * FUNCTION:    AcpiDmAscendingOp
757100966Siwasaki *
758100966Siwasaki * PARAMETERS:  ASL_WALK_CALLBACK
759100966Siwasaki *
760100966Siwasaki * RETURN:      Status
761100966Siwasaki *
762100966Siwasaki * DESCRIPTION: Second visitation of a parse object, during ascent of parse
763100966Siwasaki *              tree.  Close out any parameter lists and complete the opcode.
764100966Siwasaki *
765100966Siwasaki ******************************************************************************/
766100966Siwasaki
767151937Sjkimstatic ACPI_STATUS
768100966SiwasakiAcpiDmAscendingOp (
769100966Siwasaki    ACPI_PARSE_OBJECT       *Op,
770100966Siwasaki    UINT32                  Level,
771100966Siwasaki    void                    *Context)
772100966Siwasaki{
773100966Siwasaki    ACPI_OP_WALK_INFO       *Info = Context;
774100966Siwasaki
775100966Siwasaki
776100966Siwasaki    if (Op->Common.DisasmFlags & ACPI_PARSEOP_IGNORE)
777100966Siwasaki    {
778100966Siwasaki        /* Ignore this op -- it was handled elsewhere */
779100966Siwasaki
780100966Siwasaki        return (AE_OK);
781100966Siwasaki    }
782100966Siwasaki
783100966Siwasaki    if ((Level == 0) && (Op->Common.AmlOpcode == AML_SCOPE_OP))
784100966Siwasaki    {
785100966Siwasaki        /* Indicates the end of the current descriptor block (table) */
786100966Siwasaki
787100966Siwasaki        AcpiOsPrintf ("}\n\n");
788100966Siwasaki        return (AE_OK);
789100966Siwasaki    }
790100966Siwasaki
791100966Siwasaki    switch (AcpiDmBlockType (Op))
792100966Siwasaki    {
793100966Siwasaki    case BLOCK_PAREN:
794100966Siwasaki
795100966Siwasaki        /* Completed an op that has arguments, add closing paren */
796100966Siwasaki
797100966Siwasaki        AcpiOsPrintf (")");
798100966Siwasaki
799100966Siwasaki        /* Could be a nested operator, check if comma required */
800100966Siwasaki
801100966Siwasaki        if (!AcpiDmCommaIfListMember (Op))
802100966Siwasaki        {
803100966Siwasaki            if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
804100966Siwasaki                     (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) &&
805100966Siwasaki                     (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP))
806100966Siwasaki            {
807151937Sjkim                /*
808151937Sjkim                 * This is a first-level element of a term list
809151937Sjkim                 * start a new line
810151937Sjkim                 */
811167802Sjkim                if (!(Info->Flags & ACPI_PARSEOP_PARAMLIST))
812167802Sjkim                {
813167802Sjkim                    AcpiOsPrintf ("\n");
814167802Sjkim                }
815100966Siwasaki            }
816100966Siwasaki        }
817100966Siwasaki        break;
818100966Siwasaki
819100966Siwasaki
820100966Siwasaki    case BLOCK_BRACE:
821100966Siwasaki    case (BLOCK_BRACE | BLOCK_PAREN):
822100966Siwasaki
823100966Siwasaki        /* Completed an op that has a term list, add closing brace */
824100966Siwasaki
825100966Siwasaki        if (Op->Common.DisasmFlags & ACPI_PARSEOP_EMPTY_TERMLIST)
826100966Siwasaki        {
827100966Siwasaki            AcpiOsPrintf ("}");
828100966Siwasaki        }
829100966Siwasaki        else
830100966Siwasaki        {
831100966Siwasaki            AcpiDmIndent (Level);
832100966Siwasaki            AcpiOsPrintf ("}");
833100966Siwasaki        }
834100966Siwasaki
835100966Siwasaki        AcpiDmCommaIfListMember (Op);
836100966Siwasaki
837100966Siwasaki        if (AcpiDmBlockType (Op->Common.Parent) != BLOCK_PAREN)
838100966Siwasaki        {
839100966Siwasaki            AcpiOsPrintf ("\n");
840100966Siwasaki            if (!(Op->Common.DisasmFlags & ACPI_PARSEOP_EMPTY_TERMLIST))
841100966Siwasaki            {
842100966Siwasaki                if ((Op->Common.AmlOpcode == AML_IF_OP)  &&
843100966Siwasaki                    (Op->Common.Next) &&
844100966Siwasaki                    (Op->Common.Next->Common.AmlOpcode == AML_ELSE_OP))
845100966Siwasaki                {
846100966Siwasaki                    break;
847100966Siwasaki                }
848100966Siwasaki
849100966Siwasaki                if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
850100966Siwasaki                    (!Op->Common.Next))
851100966Siwasaki                {
852100966Siwasaki                    break;
853100966Siwasaki                }
854100966Siwasaki                AcpiOsPrintf ("\n");
855100966Siwasaki            }
856100966Siwasaki        }
857100966Siwasaki        break;
858100966Siwasaki
859100966Siwasaki
860100966Siwasaki    case BLOCK_NONE:
861100966Siwasaki    default:
862100966Siwasaki
863100966Siwasaki        /* Could be a nested operator, check if comma required */
864100966Siwasaki
865100966Siwasaki        if (!AcpiDmCommaIfListMember (Op))
866100966Siwasaki        {
867100966Siwasaki            if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
868100966Siwasaki                     (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) &&
869100966Siwasaki                     (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP))
870100966Siwasaki            {
871151937Sjkim                /*
872151937Sjkim                 * This is a first-level element of a term list
873151937Sjkim                 * start a new line
874151937Sjkim                 */
875100966Siwasaki                AcpiOsPrintf ("\n");
876100966Siwasaki            }
877100966Siwasaki        }
878100966Siwasaki        else if (Op->Common.Parent)
879100966Siwasaki        {
880100966Siwasaki            switch (Op->Common.Parent->Common.AmlOpcode)
881100966Siwasaki            {
882100966Siwasaki            case AML_PACKAGE_OP:
883100966Siwasaki            case AML_VAR_PACKAGE_OP:
884100966Siwasaki
885100966Siwasaki                if (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST))
886100966Siwasaki                {
887100966Siwasaki                    AcpiOsPrintf ("\n");
888100966Siwasaki                }
889100966Siwasaki                break;
890100966Siwasaki
891100966Siwasaki            default:
892100966Siwasaki
893100966Siwasaki                break;
894100966Siwasaki            }
895100966Siwasaki        }
896100966Siwasaki        break;
897100966Siwasaki    }
898100966Siwasaki
899100966Siwasaki    if (Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)
900100966Siwasaki    {
901100966Siwasaki        if ((Op->Common.Next) &&
902100966Siwasaki            (Op->Common.Next->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST))
903100966Siwasaki        {
904100966Siwasaki            return (AE_OK);
905100966Siwasaki        }
906100966Siwasaki
907100966Siwasaki        /*
908100966Siwasaki         * Just completed a parameter node for something like "Buffer (param)".
909100966Siwasaki         * Close the paren and open up the term list block with a brace
910100966Siwasaki         */
911100966Siwasaki        if (Op->Common.Next)
912100966Siwasaki        {
913100966Siwasaki            AcpiOsPrintf (")\n");
914100966Siwasaki            AcpiDmIndent (Level - 1);
915100966Siwasaki            AcpiOsPrintf ("{\n");
916100966Siwasaki        }
917100966Siwasaki        else
918100966Siwasaki        {
919151937Sjkim            Op->Common.Parent->Common.DisasmFlags |=
920151937Sjkim                                    ACPI_PARSEOP_EMPTY_TERMLIST;
921100966Siwasaki            AcpiOsPrintf (") {");
922100966Siwasaki        }
923100966Siwasaki    }
924100966Siwasaki
925100966Siwasaki    if ((Op->Common.AmlOpcode == AML_NAME_OP) ||
926100966Siwasaki        (Op->Common.AmlOpcode == AML_RETURN_OP))
927100966Siwasaki    {
928100966Siwasaki        Info->Level++;
929100966Siwasaki    }
930100966Siwasaki    return (AE_OK);
931100966Siwasaki}
932100966Siwasaki
933100966Siwasaki
934100966Siwasaki#endif  /* ACPI_DISASSEMBLER */
935