dmwalk.c revision 237412
1100966Siwasaki/*******************************************************************************
2100966Siwasaki *
3100966Siwasaki * Module Name: dmwalk - AML disassembly tree walk
4100966Siwasaki *
5100966Siwasaki ******************************************************************************/
6100966Siwasaki
7217365Sjkim/*
8229989Sjkim * Copyright (C) 2000 - 2012, 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++;
456237412Sjkim    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
467228110Sjkim    if ((Op->Common.DisasmOpcode == ACPI_DASM_LNOT_PREFIX) ||
468228110Sjkim        (Op->Common.AmlOpcode == AML_INT_CONNECTION_OP))
469167802Sjkim    {
470167802Sjkim        return (AE_OK);
471167802Sjkim    }
472167802Sjkim
473100966Siwasaki    if ((Op->Common.AmlOpcode == AML_NAME_OP) ||
474100966Siwasaki        (Op->Common.AmlOpcode == AML_RETURN_OP))
475100966Siwasaki    {
476100966Siwasaki        Info->Level--;
477100966Siwasaki    }
478100966Siwasaki
479117521Snjl    /* Start the opcode argument list if necessary */
480117521Snjl
481100966Siwasaki    OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
482100966Siwasaki
483102550Siwasaki    if ((OpInfo->Flags & AML_HAS_ARGS) ||
484100966Siwasaki        (Op->Common.AmlOpcode == AML_EVENT_OP))
485100966Siwasaki    {
486100966Siwasaki        /* This opcode has an argument list */
487100966Siwasaki
488100966Siwasaki        if (AcpiDmBlockType (Op) & BLOCK_PAREN)
489100966Siwasaki        {
490100966Siwasaki            AcpiOsPrintf (" (");
491100966Siwasaki        }
492100966Siwasaki
493117521Snjl        /* If this is a named opcode, print the associated name value */
494117521Snjl
495100966Siwasaki        if (OpInfo->Flags & AML_NAMED)
496100966Siwasaki        {
497100966Siwasaki            switch (Op->Common.AmlOpcode)
498100966Siwasaki            {
499100966Siwasaki            case AML_ALIAS_OP:
500100966Siwasaki
501100966Siwasaki                NextOp = AcpiPsGetDepthNext (NULL, Op);
502100966Siwasaki                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
503100966Siwasaki                AcpiDmNamestring (NextOp->Common.Value.Name);
504100966Siwasaki                AcpiOsPrintf (", ");
505100966Siwasaki
506100966Siwasaki                /*lint -fallthrough */
507100966Siwasaki
508100966Siwasaki            default:
509100966Siwasaki
510100966Siwasaki                Name = AcpiPsGetName (Op);
511100966Siwasaki                if (Op->Named.Path)
512100966Siwasaki                {
513100966Siwasaki                    AcpiDmNamestring ((char *) Op->Named.Path);
514100966Siwasaki                }
515100966Siwasaki                else
516100966Siwasaki                {
517193267Sjkim                    AcpiDmDumpName (Name);
518100966Siwasaki                }
519100966Siwasaki
520100966Siwasaki                if (Op->Common.AmlOpcode != AML_INT_NAMEDFIELD_OP)
521100966Siwasaki                {
522100966Siwasaki                    if (AcpiGbl_DbOpt_verbose)
523100966Siwasaki                    {
524100966Siwasaki                        (void) AcpiPsDisplayObjectPathname (NULL, Op);
525100966Siwasaki                    }
526100966Siwasaki                }
527100966Siwasaki                break;
528100966Siwasaki            }
529100966Siwasaki
530100966Siwasaki            switch (Op->Common.AmlOpcode)
531100966Siwasaki            {
532100966Siwasaki            case AML_METHOD_OP:
533100966Siwasaki
534100966Siwasaki                AcpiDmMethodFlags (Op);
535100966Siwasaki                AcpiOsPrintf (")");
536237412Sjkim
537237412Sjkim                /* Emit description comment for Method() with a predefined ACPI name */
538237412Sjkim
539237412Sjkim                AcpiDmPredefinedDescription (Op);
540100966Siwasaki                break;
541100966Siwasaki
542100966Siwasaki
543100966Siwasaki            case AML_NAME_OP:
544100966Siwasaki
545100966Siwasaki                /* Check for _HID and related EISAID() */
546100966Siwasaki
547151937Sjkim                AcpiDmIsEisaId (Op);
548100966Siwasaki                AcpiOsPrintf (", ");
549100966Siwasaki                break;
550100966Siwasaki
551100966Siwasaki
552100966Siwasaki            case AML_REGION_OP:
553100966Siwasaki
554100966Siwasaki                AcpiDmRegionFlags (Op);
555100966Siwasaki                break;
556100966Siwasaki
557100966Siwasaki
558100966Siwasaki            case AML_POWER_RES_OP:
559100966Siwasaki
560100966Siwasaki                /* Mark the next two Ops as part of the parameter list */
561100966Siwasaki
562100966Siwasaki                AcpiOsPrintf (", ");
563100966Siwasaki                NextOp = AcpiPsGetDepthNext (NULL, Op);
564100966Siwasaki                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
565100966Siwasaki
566100966Siwasaki                NextOp = NextOp->Common.Next;
567100966Siwasaki                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
568100966Siwasaki                return (AE_OK);
569100966Siwasaki
570100966Siwasaki
571100966Siwasaki            case AML_PROCESSOR_OP:
572100966Siwasaki
573100966Siwasaki                /* Mark the next three Ops as part of the parameter list */
574100966Siwasaki
575100966Siwasaki                AcpiOsPrintf (", ");
576100966Siwasaki                NextOp = AcpiPsGetDepthNext (NULL, Op);
577100966Siwasaki                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
578100966Siwasaki
579100966Siwasaki                NextOp = NextOp->Common.Next;
580100966Siwasaki                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
581100966Siwasaki
582100966Siwasaki                NextOp = NextOp->Common.Next;
583100966Siwasaki                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
584100966Siwasaki                return (AE_OK);
585100966Siwasaki
586100966Siwasaki
587100966Siwasaki            case AML_MUTEX_OP:
588167802Sjkim            case AML_DATA_REGION_OP:
589100966Siwasaki
590100966Siwasaki                AcpiOsPrintf (", ");
591100966Siwasaki                return (AE_OK);
592100966Siwasaki
593100966Siwasaki
594100966Siwasaki            case AML_EVENT_OP:
595100966Siwasaki            case AML_ALIAS_OP:
596100966Siwasaki
597100966Siwasaki                return (AE_OK);
598100966Siwasaki
599100966Siwasaki
600100966Siwasaki            case AML_SCOPE_OP:
601100966Siwasaki            case AML_DEVICE_OP:
602100966Siwasaki            case AML_THERMAL_ZONE_OP:
603100966Siwasaki
604100966Siwasaki                AcpiOsPrintf (")");
605100966Siwasaki                break;
606100966Siwasaki
607100966Siwasaki
608100966Siwasaki            default:
609100966Siwasaki
610237412Sjkim                AcpiOsPrintf ("*** Unhandled named opcode %X\n",
611237412Sjkim                    Op->Common.AmlOpcode);
612100966Siwasaki                break;
613100966Siwasaki            }
614100966Siwasaki        }
615100966Siwasaki
616100966Siwasaki        else switch (Op->Common.AmlOpcode)
617100966Siwasaki        {
618100966Siwasaki        case AML_FIELD_OP:
619100966Siwasaki        case AML_BANK_FIELD_OP:
620100966Siwasaki        case AML_INDEX_FIELD_OP:
621100966Siwasaki
622100966Siwasaki            Info->BitOffset = 0;
623100966Siwasaki
624100966Siwasaki            /* Name of the parent OperationRegion */
625100966Siwasaki
626100966Siwasaki            NextOp = AcpiPsGetDepthNext (NULL, Op);
627100966Siwasaki            AcpiDmNamestring (NextOp->Common.Value.Name);
628100966Siwasaki            AcpiOsPrintf (", ");
629100966Siwasaki            NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
630100966Siwasaki
631100966Siwasaki            switch (Op->Common.AmlOpcode)
632100966Siwasaki            {
633100966Siwasaki            case AML_BANK_FIELD_OP:
634100966Siwasaki
635167802Sjkim                /* Namestring - Bank Name */
636100966Siwasaki
637100966Siwasaki                NextOp = AcpiPsGetDepthNext (NULL, NextOp);
638100966Siwasaki                AcpiDmNamestring (NextOp->Common.Value.Name);
639100966Siwasaki                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
640100966Siwasaki                AcpiOsPrintf (", ");
641100966Siwasaki
642167802Sjkim                /*
643167802Sjkim                 * Bank Value. This is a TermArg in the middle of the parameter
644167802Sjkim                 * list, must handle it here.
645167802Sjkim                 *
646167802Sjkim                 * Disassemble the TermArg parse tree. ACPI_PARSEOP_PARAMLIST
647167802Sjkim                 * eliminates newline in the output.
648167802Sjkim                 */
649167802Sjkim                NextOp = NextOp->Common.Next;
650100966Siwasaki
651167802Sjkim                Info->Flags = ACPI_PARSEOP_PARAMLIST;
652237412Sjkim                AcpiDmWalkParseTree (NextOp, AcpiDmDescendingOp,
653237412Sjkim                    AcpiDmAscendingOp, Info);
654167802Sjkim                Info->Flags = 0;
655167802Sjkim                Info->Level = Level;
656167802Sjkim
657100966Siwasaki                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
658100966Siwasaki                AcpiOsPrintf (", ");
659100966Siwasaki                break;
660100966Siwasaki
661100966Siwasaki            case AML_INDEX_FIELD_OP:
662100966Siwasaki
663167802Sjkim                /* Namestring - Data Name */
664100966Siwasaki
665100966Siwasaki                NextOp = AcpiPsGetDepthNext (NULL, NextOp);
666100966Siwasaki                AcpiDmNamestring (NextOp->Common.Value.Name);
667100966Siwasaki                AcpiOsPrintf (", ");
668100966Siwasaki                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
669100966Siwasaki                break;
670100966Siwasaki
671100966Siwasaki            default:
672100966Siwasaki
673100966Siwasaki                break;
674100966Siwasaki            }
675100966Siwasaki
676100966Siwasaki            AcpiDmFieldFlags (NextOp);
677100966Siwasaki            break;
678100966Siwasaki
679100966Siwasaki
680100966Siwasaki        case AML_BUFFER_OP:
681100966Siwasaki
682100966Siwasaki            /* The next op is the size parameter */
683100966Siwasaki
684100966Siwasaki            NextOp = AcpiPsGetDepthNext (NULL, Op);
685100966Siwasaki            if (!NextOp)
686100966Siwasaki            {
687100966Siwasaki                /* Single-step support */
688100966Siwasaki
689100966Siwasaki                return (AE_OK);
690100966Siwasaki            }
691100966Siwasaki
692100966Siwasaki            if (Op->Common.DisasmOpcode == ACPI_DASM_RESOURCE)
693100966Siwasaki            {
694100966Siwasaki                /*
695237412Sjkim                 * We have a resource list. Don't need to output
696237412Sjkim                 * the buffer size Op. Open up a new block
697100966Siwasaki                 */
698100966Siwasaki                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
699100966Siwasaki                NextOp = NextOp->Common.Next;
700237412Sjkim                AcpiOsPrintf (")");
701237412Sjkim
702237412Sjkim                /* Emit description comment for Name() with a predefined ACPI name */
703237412Sjkim
704237412Sjkim                AcpiDmPredefinedDescription (Op->Asl.Parent);
705237412Sjkim
706237412Sjkim                AcpiOsPrintf ("\n");
707100966Siwasaki                AcpiDmIndent (Info->Level);
708100966Siwasaki                AcpiOsPrintf ("{\n");
709100966Siwasaki                return (AE_OK);
710100966Siwasaki            }
711100966Siwasaki
712100966Siwasaki            /* Normal Buffer, mark size as in the parameter list */
713100966Siwasaki
714100966Siwasaki            NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
715100966Siwasaki            return (AE_OK);
716100966Siwasaki
717100966Siwasaki
718100966Siwasaki        case AML_VAR_PACKAGE_OP:
719100966Siwasaki        case AML_IF_OP:
720100966Siwasaki        case AML_WHILE_OP:
721100966Siwasaki
722100966Siwasaki            /* The next op is the size or predicate parameter */
723100966Siwasaki
724100966Siwasaki            NextOp = AcpiPsGetDepthNext (NULL, Op);
725100966Siwasaki            if (NextOp)
726100966Siwasaki            {
727100966Siwasaki                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
728100966Siwasaki            }
729100966Siwasaki            return (AE_OK);
730100966Siwasaki
731100966Siwasaki
732100966Siwasaki        case AML_PACKAGE_OP:
733100966Siwasaki
734237412Sjkim            /* The next op is the size parameter */
735100966Siwasaki
736100966Siwasaki            NextOp = AcpiPsGetDepthNext (NULL, Op);
737100966Siwasaki            if (NextOp)
738100966Siwasaki            {
739100966Siwasaki                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
740100966Siwasaki            }
741100966Siwasaki            return (AE_OK);
742100966Siwasaki
743100966Siwasaki
744100966Siwasaki        case AML_MATCH_OP:
745100966Siwasaki
746100966Siwasaki            AcpiDmMatchOp (Op);
747100966Siwasaki            break;
748100966Siwasaki
749100966Siwasaki
750100966Siwasaki        default:
751100966Siwasaki
752100966Siwasaki            break;
753100966Siwasaki        }
754100966Siwasaki
755100966Siwasaki        if (AcpiDmBlockType (Op) & BLOCK_BRACE)
756100966Siwasaki        {
757100966Siwasaki            AcpiOsPrintf ("\n");
758100966Siwasaki            AcpiDmIndent (Level);
759100966Siwasaki            AcpiOsPrintf ("{\n");
760100966Siwasaki        }
761100966Siwasaki    }
762100966Siwasaki
763100966Siwasaki    return (AE_OK);
764100966Siwasaki}
765100966Siwasaki
766100966Siwasaki
767100966Siwasaki/*******************************************************************************
768100966Siwasaki *
769100966Siwasaki * FUNCTION:    AcpiDmAscendingOp
770100966Siwasaki *
771100966Siwasaki * PARAMETERS:  ASL_WALK_CALLBACK
772100966Siwasaki *
773100966Siwasaki * RETURN:      Status
774100966Siwasaki *
775100966Siwasaki * DESCRIPTION: Second visitation of a parse object, during ascent of parse
776100966Siwasaki *              tree.  Close out any parameter lists and complete the opcode.
777100966Siwasaki *
778100966Siwasaki ******************************************************************************/
779100966Siwasaki
780151937Sjkimstatic ACPI_STATUS
781100966SiwasakiAcpiDmAscendingOp (
782100966Siwasaki    ACPI_PARSE_OBJECT       *Op,
783100966Siwasaki    UINT32                  Level,
784100966Siwasaki    void                    *Context)
785100966Siwasaki{
786100966Siwasaki    ACPI_OP_WALK_INFO       *Info = Context;
787237412Sjkim    ACPI_PARSE_OBJECT       *ParentOp;
788100966Siwasaki
789100966Siwasaki
790100966Siwasaki    if (Op->Common.DisasmFlags & ACPI_PARSEOP_IGNORE)
791100966Siwasaki    {
792100966Siwasaki        /* Ignore this op -- it was handled elsewhere */
793100966Siwasaki
794100966Siwasaki        return (AE_OK);
795100966Siwasaki    }
796100966Siwasaki
797100966Siwasaki    if ((Level == 0) && (Op->Common.AmlOpcode == AML_SCOPE_OP))
798100966Siwasaki    {
799100966Siwasaki        /* Indicates the end of the current descriptor block (table) */
800100966Siwasaki
801100966Siwasaki        AcpiOsPrintf ("}\n\n");
802100966Siwasaki        return (AE_OK);
803100966Siwasaki    }
804100966Siwasaki
805100966Siwasaki    switch (AcpiDmBlockType (Op))
806100966Siwasaki    {
807100966Siwasaki    case BLOCK_PAREN:
808100966Siwasaki
809100966Siwasaki        /* Completed an op that has arguments, add closing paren */
810100966Siwasaki
811100966Siwasaki        AcpiOsPrintf (")");
812100966Siwasaki
813237412Sjkim        if (Op->Common.AmlOpcode == AML_NAME_OP)
814237412Sjkim        {
815237412Sjkim            /* Emit description comment for Name() with a predefined ACPI name */
816237412Sjkim
817237412Sjkim            AcpiDmPredefinedDescription (Op);
818237412Sjkim        }
819237412Sjkim        else
820237412Sjkim        {
821237412Sjkim            /* For Create* operators, attempt to emit resource tag description */
822237412Sjkim
823237412Sjkim            AcpiDmFieldPredefinedDescription (Op);
824237412Sjkim        }
825237412Sjkim
826100966Siwasaki        /* Could be a nested operator, check if comma required */
827100966Siwasaki
828100966Siwasaki        if (!AcpiDmCommaIfListMember (Op))
829100966Siwasaki        {
830100966Siwasaki            if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
831100966Siwasaki                     (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) &&
832100966Siwasaki                     (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP))
833100966Siwasaki            {
834151937Sjkim                /*
835151937Sjkim                 * This is a first-level element of a term list
836151937Sjkim                 * start a new line
837151937Sjkim                 */
838167802Sjkim                if (!(Info->Flags & ACPI_PARSEOP_PARAMLIST))
839167802Sjkim                {
840167802Sjkim                    AcpiOsPrintf ("\n");
841167802Sjkim                }
842100966Siwasaki            }
843100966Siwasaki        }
844100966Siwasaki        break;
845100966Siwasaki
846100966Siwasaki
847100966Siwasaki    case BLOCK_BRACE:
848100966Siwasaki    case (BLOCK_BRACE | BLOCK_PAREN):
849100966Siwasaki
850100966Siwasaki        /* Completed an op that has a term list, add closing brace */
851100966Siwasaki
852100966Siwasaki        if (Op->Common.DisasmFlags & ACPI_PARSEOP_EMPTY_TERMLIST)
853100966Siwasaki        {
854100966Siwasaki            AcpiOsPrintf ("}");
855100966Siwasaki        }
856100966Siwasaki        else
857100966Siwasaki        {
858100966Siwasaki            AcpiDmIndent (Level);
859100966Siwasaki            AcpiOsPrintf ("}");
860100966Siwasaki        }
861100966Siwasaki
862100966Siwasaki        AcpiDmCommaIfListMember (Op);
863100966Siwasaki
864100966Siwasaki        if (AcpiDmBlockType (Op->Common.Parent) != BLOCK_PAREN)
865100966Siwasaki        {
866100966Siwasaki            AcpiOsPrintf ("\n");
867100966Siwasaki            if (!(Op->Common.DisasmFlags & ACPI_PARSEOP_EMPTY_TERMLIST))
868100966Siwasaki            {
869100966Siwasaki                if ((Op->Common.AmlOpcode == AML_IF_OP)  &&
870100966Siwasaki                    (Op->Common.Next) &&
871100966Siwasaki                    (Op->Common.Next->Common.AmlOpcode == AML_ELSE_OP))
872100966Siwasaki                {
873100966Siwasaki                    break;
874100966Siwasaki                }
875100966Siwasaki
876100966Siwasaki                if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
877100966Siwasaki                    (!Op->Common.Next))
878100966Siwasaki                {
879100966Siwasaki                    break;
880100966Siwasaki                }
881100966Siwasaki                AcpiOsPrintf ("\n");
882100966Siwasaki            }
883100966Siwasaki        }
884100966Siwasaki        break;
885100966Siwasaki
886100966Siwasaki
887100966Siwasaki    case BLOCK_NONE:
888100966Siwasaki    default:
889100966Siwasaki
890100966Siwasaki        /* Could be a nested operator, check if comma required */
891100966Siwasaki
892100966Siwasaki        if (!AcpiDmCommaIfListMember (Op))
893100966Siwasaki        {
894100966Siwasaki            if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
895100966Siwasaki                     (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) &&
896100966Siwasaki                     (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP))
897100966Siwasaki            {
898151937Sjkim                /*
899151937Sjkim                 * This is a first-level element of a term list
900151937Sjkim                 * start a new line
901151937Sjkim                 */
902100966Siwasaki                AcpiOsPrintf ("\n");
903100966Siwasaki            }
904100966Siwasaki        }
905100966Siwasaki        else if (Op->Common.Parent)
906100966Siwasaki        {
907100966Siwasaki            switch (Op->Common.Parent->Common.AmlOpcode)
908100966Siwasaki            {
909100966Siwasaki            case AML_PACKAGE_OP:
910100966Siwasaki            case AML_VAR_PACKAGE_OP:
911100966Siwasaki
912100966Siwasaki                if (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST))
913100966Siwasaki                {
914100966Siwasaki                    AcpiOsPrintf ("\n");
915100966Siwasaki                }
916100966Siwasaki                break;
917100966Siwasaki
918100966Siwasaki            default:
919100966Siwasaki
920100966Siwasaki                break;
921100966Siwasaki            }
922100966Siwasaki        }
923100966Siwasaki        break;
924100966Siwasaki    }
925100966Siwasaki
926100966Siwasaki    if (Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)
927100966Siwasaki    {
928100966Siwasaki        if ((Op->Common.Next) &&
929100966Siwasaki            (Op->Common.Next->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST))
930100966Siwasaki        {
931100966Siwasaki            return (AE_OK);
932100966Siwasaki        }
933100966Siwasaki
934100966Siwasaki        /*
935100966Siwasaki         * Just completed a parameter node for something like "Buffer (param)".
936100966Siwasaki         * Close the paren and open up the term list block with a brace
937100966Siwasaki         */
938100966Siwasaki        if (Op->Common.Next)
939100966Siwasaki        {
940237412Sjkim            AcpiOsPrintf (")");
941237412Sjkim
942237412Sjkim            /* Emit description comment for Name() with a predefined ACPI name */
943237412Sjkim
944237412Sjkim            ParentOp = Op->Common.Parent;
945237412Sjkim            if (ParentOp)
946237412Sjkim            {
947237412Sjkim                ParentOp = ParentOp->Common.Parent;
948237412Sjkim                if (ParentOp && ParentOp->Asl.AmlOpcode == AML_NAME_OP)
949237412Sjkim                {
950237412Sjkim                    AcpiDmPredefinedDescription (ParentOp);
951237412Sjkim                }
952237412Sjkim            }
953237412Sjkim            AcpiOsPrintf ("\n");
954100966Siwasaki            AcpiDmIndent (Level - 1);
955100966Siwasaki            AcpiOsPrintf ("{\n");
956100966Siwasaki        }
957100966Siwasaki        else
958100966Siwasaki        {
959151937Sjkim            Op->Common.Parent->Common.DisasmFlags |=
960151937Sjkim                                    ACPI_PARSEOP_EMPTY_TERMLIST;
961100966Siwasaki            AcpiOsPrintf (") {");
962100966Siwasaki        }
963100966Siwasaki    }
964100966Siwasaki
965100966Siwasaki    if ((Op->Common.AmlOpcode == AML_NAME_OP) ||
966100966Siwasaki        (Op->Common.AmlOpcode == AML_RETURN_OP))
967100966Siwasaki    {
968100966Siwasaki        Info->Level++;
969100966Siwasaki    }
970100966Siwasaki    return (AE_OK);
971100966Siwasaki}
972100966Siwasaki
973100966Siwasaki
974100966Siwasaki#endif  /* ACPI_DISASSEMBLER */
975