Subversion Repositories Kolibri OS

Rev

Rev 1498 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1498 serge 1
/*******************************************************************************
2
 *
3
 * Module Name: dmwalk - AML disassembly tree walk
4
 *
5
 ******************************************************************************/
6
 
7
/******************************************************************************
8
 *
9
 * 1. Copyright Notice
10
 *
2216 Serge 11
 * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
1498 serge 12
 * All rights reserved.
13
 *
14
 * 2. License
15
 *
16
 * 2.1. This is your license from Intel Corp. under its intellectual property
17
 * rights.  You may have additional license terms from the party that provided
18
 * you this software, covering your right to use that party's intellectual
19
 * property rights.
20
 *
21
 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22
 * copy of the source code appearing in this file ("Covered Code") an
23
 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24
 * base code distributed originally by Intel ("Original Intel Code") to copy,
25
 * make derivatives, distribute, use and display any portion of the Covered
26
 * Code in any form, with the right to sublicense such rights; and
27
 *
28
 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29
 * license (with the right to sublicense), under only those claims of Intel
30
 * patents that are infringed by the Original Intel Code, to make, use, sell,
31
 * offer to sell, and import the Covered Code and derivative works thereof
32
 * solely to the minimum extent necessary to exercise the above copyright
33
 * license, and in no event shall the patent license extend to any additions
34
 * to or modifications of the Original Intel Code.  No other license or right
35
 * is granted directly or by implication, estoppel or otherwise;
36
 *
37
 * The above copyright and patent license is granted only if the following
38
 * conditions are met:
39
 *
40
 * 3. Conditions
41
 *
42
 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43
 * Redistribution of source code of any substantial portion of the Covered
44
 * Code or modification with rights to further distribute source must include
45
 * the above Copyright Notice, the above License, this list of Conditions,
46
 * and the following Disclaimer and Export Compliance provision.  In addition,
47
 * Licensee must cause all Covered Code to which Licensee contributes to
48
 * contain a file documenting the changes Licensee made to create that Covered
49
 * Code and the date of any change.  Licensee must include in that file the
50
 * documentation of any changes made by any predecessor Licensee.  Licensee
51
 * must include a prominent statement that the modification is derived,
52
 * directly or indirectly, from Original Intel Code.
53
 *
54
 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55
 * Redistribution of source code of any substantial portion of the Covered
56
 * Code or modification without rights to further distribute source must
57
 * include the following Disclaimer and Export Compliance provision in the
58
 * documentation and/or other materials provided with distribution.  In
59
 * addition, Licensee may not authorize further sublicense of source of any
60
 * portion of the Covered Code, and must include terms to the effect that the
61
 * license from Licensee to its licensee is limited to the intellectual
62
 * property embodied in the software Licensee provides to its licensee, and
63
 * not to intellectual property embodied in modifications its licensee may
64
 * make.
65
 *
66
 * 3.3. Redistribution of Executable. Redistribution in executable form of any
67
 * substantial portion of the Covered Code or modification must reproduce the
68
 * above Copyright Notice, and the following Disclaimer and Export Compliance
69
 * provision in the documentation and/or other materials provided with the
70
 * distribution.
71
 *
72
 * 3.4. Intel retains all right, title, and interest in and to the Original
73
 * Intel Code.
74
 *
75
 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76
 * Intel shall be used in advertising or otherwise to promote the sale, use or
77
 * other dealings in products derived from or relating to the Covered Code
78
 * without prior written authorization from Intel.
79
 *
80
 * 4. Disclaimer and Export Compliance
81
 *
82
 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83
 * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84
 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
85
 * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
86
 * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
87
 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88
 * PARTICULAR PURPOSE.
89
 *
90
 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91
 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92
 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93
 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94
 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95
 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
96
 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97
 * LIMITED REMEDY.
98
 *
99
 * 4.3. Licensee shall not export, either directly or indirectly, any of this
100
 * software or system incorporating such software without first obtaining any
101
 * required license or other approval from the U. S. Department of Commerce or
102
 * any other agency or department of the United States Government.  In the
103
 * event Licensee exports any such software from the United States or
104
 * re-exports any such software from a foreign destination, Licensee shall
105
 * ensure that the distribution and export/re-export of the software is in
106
 * compliance with all laws, regulations, orders, or other restrictions of the
107
 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108
 * any of its subsidiaries will export/re-export any technical data, process,
109
 * software, or service, directly or indirectly, to any country for which the
110
 * United States government or any agency thereof requires an export license,
111
 * other governmental approval, or letter of assurance, without first obtaining
112
 * such license, approval or letter.
113
 *
114
 *****************************************************************************/
115
 
116
 
117
#include "acpi.h"
118
#include "accommon.h"
119
#include "acparser.h"
120
#include "amlcode.h"
121
#include "acdisasm.h"
122
#include "acdebug.h"
123
 
124
 
125
#ifdef ACPI_DISASSEMBLER
126
 
127
#define _COMPONENT          ACPI_CA_DEBUGGER
128
        ACPI_MODULE_NAME    ("dmwalk")
129
 
130
 
131
#define DB_FULL_OP_INFO     "[%4.4s] @%5.5X #%4.4X:  "
132
 
133
/* Stub for non-compiler code */
134
 
135
#ifndef ACPI_ASL_COMPILER
136
void
137
AcpiDmEmitExternals (
138
    void)
139
{
140
    return;
141
}
142
#endif
143
 
144
/* Local prototypes */
145
 
146
static ACPI_STATUS
147
AcpiDmDescendingOp (
148
    ACPI_PARSE_OBJECT       *Op,
149
    UINT32                  Level,
150
    void                    *Context);
151
 
152
static ACPI_STATUS
153
AcpiDmAscendingOp (
154
    ACPI_PARSE_OBJECT       *Op,
155
    UINT32                  Level,
156
    void                    *Context);
157
 
158
static UINT32
159
AcpiDmBlockType (
160
    ACPI_PARSE_OBJECT       *Op);
161
 
162
 
163
/*******************************************************************************
164
 *
165
 * FUNCTION:    AcpiDmDisassemble
166
 *
167
 * PARAMETERS:  WalkState       - Current state
168
 *              Origin          - Starting object
169
 *              NumOpcodes      - Max number of opcodes to be displayed
170
 *
171
 * RETURN:      None
172
 *
173
 * DESCRIPTION: Disassemble parser object and its children.  This is the
174
 *              main entry point of the disassembler.
175
 *
176
 ******************************************************************************/
177
 
178
void
179
AcpiDmDisassemble (
180
    ACPI_WALK_STATE         *WalkState,
181
    ACPI_PARSE_OBJECT       *Origin,
182
    UINT32                  NumOpcodes)
183
{
184
    ACPI_PARSE_OBJECT       *Op = Origin;
185
    ACPI_OP_WALK_INFO       Info;
186
 
187
 
188
    if (!Op)
189
    {
190
        return;
191
    }
192
 
193
    Info.Flags = 0;
194
    Info.Level = 0;
195
    Info.Count = 0;
196
    Info.WalkState = WalkState;
197
    AcpiDmWalkParseTree (Op, AcpiDmDescendingOp, AcpiDmAscendingOp, &Info);
198
    return;
199
}
200
 
201
 
202
/*******************************************************************************
203
 *
204
 * FUNCTION:    AcpiDmWalkParseTree
205
 *
206
 * PARAMETERS:  Op                      - Root Op object
207
 *              DescendingCallback      - Called during tree descent
208
 *              AscendingCallback       - Called during tree ascent
209
 *              Context                 - To be passed to the callbacks
210
 *
211
 * RETURN:      Status from callback(s)
212
 *
213
 * DESCRIPTION: Walk the entire parse tree.
214
 *
215
 ******************************************************************************/
216
 
217
void
218
AcpiDmWalkParseTree (
219
    ACPI_PARSE_OBJECT       *Op,
220
    ASL_WALK_CALLBACK       DescendingCallback,
221
    ASL_WALK_CALLBACK       AscendingCallback,
222
    void                    *Context)
223
{
224
    BOOLEAN                 NodePreviouslyVisited;
225
    ACPI_PARSE_OBJECT       *StartOp = Op;
226
    ACPI_STATUS             Status;
227
    ACPI_PARSE_OBJECT       *Next;
228
    ACPI_OP_WALK_INFO       *Info = Context;
229
 
230
 
231
    Info->Level = 0;
232
    NodePreviouslyVisited = FALSE;
233
 
234
    while (Op)
235
    {
236
        if (NodePreviouslyVisited)
237
        {
238
            if (AscendingCallback)
239
            {
240
                Status = AscendingCallback (Op, Info->Level, Context);
241
                if (ACPI_FAILURE (Status))
242
                {
243
                    return;
244
                }
245
            }
246
        }
247
        else
248
        {
249
            /* Let the callback process the node */
250
 
251
            Status = DescendingCallback (Op, Info->Level, Context);
252
            if (ACPI_SUCCESS (Status))
253
            {
254
                /* Visit children first, once */
255
 
256
                Next = AcpiPsGetArg (Op, 0);
257
                if (Next)
258
                {
259
                    Info->Level++;
260
                    Op = Next;
261
                    continue;
262
                }
263
            }
264
            else if (Status != AE_CTRL_DEPTH)
265
            {
266
                /* Exit immediately on any error */
267
 
268
                return;
269
            }
270
        }
271
 
272
        /* Terminate walk at start op */
273
 
274
        if (Op == StartOp)
275
        {
276
            break;
277
        }
278
 
279
        /* No more children, re-visit this node */
280
 
281
        if (!NodePreviouslyVisited)
282
        {
283
            NodePreviouslyVisited = TRUE;
284
            continue;
285
        }
286
 
287
        /* No more children, visit peers */
288
 
289
        if (Op->Common.Next)
290
        {
291
            Op = Op->Common.Next;
292
            NodePreviouslyVisited = FALSE;
293
        }
294
        else
295
        {
296
            /* No peers, re-visit parent */
297
 
298
            if (Info->Level != 0 )
299
            {
300
                Info->Level--;
301
            }
302
 
303
            Op = Op->Common.Parent;
304
            NodePreviouslyVisited = TRUE;
305
        }
306
    }
307
 
308
    /* If we get here, the walk completed with no errors */
309
 
310
    return;
311
}
312
 
313
 
314
/*******************************************************************************
315
 *
316
 * FUNCTION:    AcpiDmBlockType
317
 *
318
 * PARAMETERS:  Op              - Object to be examined
319
 *
320
 * RETURN:      BlockType - not a block, parens, braces, or even both.
321
 *
322
 * DESCRIPTION: Type of block for this op (parens or braces)
323
 *
324
 ******************************************************************************/
325
 
326
static UINT32
327
AcpiDmBlockType (
328
    ACPI_PARSE_OBJECT       *Op)
329
{
330
    const ACPI_OPCODE_INFO  *OpInfo;
331
 
332
 
333
    if (!Op)
334
    {
335
        return (BLOCK_NONE);
336
    }
337
 
338
    switch (Op->Common.AmlOpcode)
339
    {
340
    case AML_ELSE_OP:
341
 
342
        return (BLOCK_BRACE);
343
 
344
    case AML_METHOD_OP:
345
    case AML_DEVICE_OP:
346
    case AML_SCOPE_OP:
347
    case AML_PROCESSOR_OP:
348
    case AML_POWER_RES_OP:
349
    case AML_THERMAL_ZONE_OP:
350
    case AML_IF_OP:
351
    case AML_WHILE_OP:
352
    case AML_FIELD_OP:
353
    case AML_INDEX_FIELD_OP:
354
    case AML_BANK_FIELD_OP:
355
 
356
        return (BLOCK_PAREN | BLOCK_BRACE);
357
 
358
    case AML_BUFFER_OP:
359
 
360
        if (Op->Common.DisasmOpcode == ACPI_DASM_UNICODE)
361
        {
362
            return (BLOCK_NONE);
363
        }
364
 
365
        /*lint -fallthrough */
366
 
367
    case AML_PACKAGE_OP:
368
    case AML_VAR_PACKAGE_OP:
369
 
370
        return (BLOCK_PAREN | BLOCK_BRACE);
371
 
372
    case AML_EVENT_OP:
373
 
374
        return (BLOCK_PAREN);
375
 
376
    default:
377
 
378
        OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
379
        if (OpInfo->Flags & AML_HAS_ARGS)
380
        {
381
            return (BLOCK_PAREN);
382
        }
383
 
384
        return (BLOCK_NONE);
385
    }
386
}
387
 
388
 
389
/*******************************************************************************
390
 *
391
 * FUNCTION:    AcpiDmListType
392
 *
393
 * PARAMETERS:  Op              - Object to be examined
394
 *
395
 * RETURN:      ListType - has commas or not.
396
 *
397
 * DESCRIPTION: Type of block for this op (parens or braces)
398
 *
399
 ******************************************************************************/
400
 
401
UINT32
402
AcpiDmListType (
403
    ACPI_PARSE_OBJECT       *Op)
404
{
405
    const ACPI_OPCODE_INFO  *OpInfo;
406
 
407
 
408
    if (!Op)
409
    {
410
        return (BLOCK_NONE);
411
    }
412
 
413
    switch (Op->Common.AmlOpcode)
414
    {
415
 
416
    case AML_ELSE_OP:
417
    case AML_METHOD_OP:
418
    case AML_DEVICE_OP:
419
    case AML_SCOPE_OP:
420
    case AML_POWER_RES_OP:
421
    case AML_PROCESSOR_OP:
422
    case AML_THERMAL_ZONE_OP:
423
    case AML_IF_OP:
424
    case AML_WHILE_OP:
425
    case AML_FIELD_OP:
426
    case AML_INDEX_FIELD_OP:
427
    case AML_BANK_FIELD_OP:
428
 
429
        return (BLOCK_NONE);
430
 
431
    case AML_BUFFER_OP:
432
    case AML_PACKAGE_OP:
433
    case AML_VAR_PACKAGE_OP:
434
 
435
        return (BLOCK_COMMA_LIST);
436
 
437
    default:
438
 
439
        OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
440
        if (OpInfo->Flags & AML_HAS_ARGS)
441
        {
442
            return (BLOCK_COMMA_LIST);
443
        }
444
 
445
        return (BLOCK_NONE);
446
    }
447
}
448
 
449
 
450
/*******************************************************************************
451
 *
452
 * FUNCTION:    AcpiDmDescendingOp
453
 *
454
 * PARAMETERS:  ASL_WALK_CALLBACK
455
 *
456
 * RETURN:      Status
457
 *
458
 * DESCRIPTION: First visitation of a parse object during tree descent.
459
 *              Decode opcode name and begin parameter list(s), if any.
460
 *
461
 ******************************************************************************/
462
 
463
static ACPI_STATUS
464
AcpiDmDescendingOp (
465
    ACPI_PARSE_OBJECT       *Op,
466
    UINT32                  Level,
467
    void                    *Context)
468
{
469
    ACPI_OP_WALK_INFO       *Info = Context;
470
    const ACPI_OPCODE_INFO  *OpInfo;
471
    UINT32                  Name;
472
    ACPI_PARSE_OBJECT       *NextOp;
473
 
474
 
475
    if (Op->Common.DisasmFlags & ACPI_PARSEOP_IGNORE)
476
    {
477
        /* Ignore this op -- it was handled elsewhere */
478
 
479
        return (AE_CTRL_DEPTH);
480
    }
481
 
482
    /* Level 0 is at the Definition Block level */
483
 
484
    if (Level == 0)
485
    {
486
        /* In verbose mode, print the AML offset, opcode and depth count */
487
 
488
        if (Info->WalkState)
489
        {
490
            VERBOSE_PRINT ((DB_FULL_OP_INFO,
491
                (Info->WalkState->MethodNode ?
492
                    Info->WalkState->MethodNode->Name.Ascii : "   "),
493
                Op->Common.AmlOffset, (UINT32) Op->Common.AmlOpcode));
494
        }
495
 
496
        if (Op->Common.AmlOpcode == AML_SCOPE_OP)
497
        {
498
            /* This is the beginning of the Definition Block */
499
 
500
            AcpiOsPrintf ("{\n");
501
 
502
            /* Emit all External() declarations here */
503
 
504
            AcpiDmEmitExternals ();
505
            return (AE_OK);
506
        }
507
    }
508
    else if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
509
             (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) &&
510
             (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP))
511
    {
512
            /*
513
             * This is a first-level element of a term list,
514
             * indent a new line
515
             */
516
            AcpiDmIndent (Level);
517
            Info->LastLevel = Level;
518
            Info->Count = 0;
519
    }
520
 
521
    /*
522
     * This is an inexpensive mechanism to try and keep lines from getting
523
     * too long. When the limit is hit, start a new line at the previous
524
     * indent plus one. A better but more expensive mechanism would be to
525
     * keep track of the current column.
526
     */
527
    Info->Count++;
528
    if (Info->Count /*+Info->LastLevel*/ > 10)
529
    {
530
        Info->Count = 0;
531
        AcpiOsPrintf ("\n");
532
        AcpiDmIndent (Info->LastLevel + 1);
533
    }
534
 
535
    /* Print the opcode name */
536
 
537
    AcpiDmDisassembleOneOp (NULL, Info, Op);
538
 
539
    if (Op->Common.DisasmOpcode == ACPI_DASM_LNOT_PREFIX)
540
    {
541
        return (AE_OK);
542
    }
543
 
544
    if ((Op->Common.AmlOpcode == AML_NAME_OP) ||
545
        (Op->Common.AmlOpcode == AML_RETURN_OP))
546
    {
547
        Info->Level--;
548
    }
549
 
550
    /* Start the opcode argument list if necessary */
551
 
552
    OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
553
 
554
    if ((OpInfo->Flags & AML_HAS_ARGS) ||
555
        (Op->Common.AmlOpcode == AML_EVENT_OP))
556
    {
557
        /* This opcode has an argument list */
558
 
559
        if (AcpiDmBlockType (Op) & BLOCK_PAREN)
560
        {
561
            AcpiOsPrintf (" (");
562
        }
563
 
564
        /* If this is a named opcode, print the associated name value */
565
 
566
        if (OpInfo->Flags & AML_NAMED)
567
        {
568
            switch (Op->Common.AmlOpcode)
569
            {
570
            case AML_ALIAS_OP:
571
 
572
                NextOp = AcpiPsGetDepthNext (NULL, Op);
573
                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
574
                AcpiDmNamestring (NextOp->Common.Value.Name);
575
                AcpiOsPrintf (", ");
576
 
577
                /*lint -fallthrough */
578
 
579
            default:
580
 
581
                Name = AcpiPsGetName (Op);
582
                if (Op->Named.Path)
583
                {
584
                    AcpiDmNamestring ((char *) Op->Named.Path);
585
                }
586
                else
587
                {
588
                    AcpiDmDumpName (Name);
589
                }
590
 
591
                if (Op->Common.AmlOpcode != AML_INT_NAMEDFIELD_OP)
592
                {
593
                    if (AcpiGbl_DbOpt_verbose)
594
                    {
595
                        (void) AcpiPsDisplayObjectPathname (NULL, Op);
596
                    }
597
                }
598
                break;
599
            }
600
 
601
            switch (Op->Common.AmlOpcode)
602
            {
603
            case AML_METHOD_OP:
604
 
605
                AcpiDmMethodFlags (Op);
606
                AcpiOsPrintf (")");
607
                break;
608
 
609
 
610
            case AML_NAME_OP:
611
 
612
                /* Check for _HID and related EISAID() */
613
 
614
                AcpiDmIsEisaId (Op);
615
                AcpiOsPrintf (", ");
616
                break;
617
 
618
 
619
            case AML_REGION_OP:
620
 
621
                AcpiDmRegionFlags (Op);
622
                break;
623
 
624
 
625
            case AML_POWER_RES_OP:
626
 
627
                /* Mark the next two Ops as part of the parameter list */
628
 
629
                AcpiOsPrintf (", ");
630
                NextOp = AcpiPsGetDepthNext (NULL, Op);
631
                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
632
 
633
                NextOp = NextOp->Common.Next;
634
                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
635
                return (AE_OK);
636
 
637
 
638
            case AML_PROCESSOR_OP:
639
 
640
                /* Mark the next three Ops as part of the parameter list */
641
 
642
                AcpiOsPrintf (", ");
643
                NextOp = AcpiPsGetDepthNext (NULL, Op);
644
                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
645
 
646
                NextOp = NextOp->Common.Next;
647
                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
648
 
649
                NextOp = NextOp->Common.Next;
650
                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
651
                return (AE_OK);
652
 
653
 
654
            case AML_MUTEX_OP:
655
            case AML_DATA_REGION_OP:
656
 
657
                AcpiOsPrintf (", ");
658
                return (AE_OK);
659
 
660
 
661
            case AML_EVENT_OP:
662
            case AML_ALIAS_OP:
663
 
664
                return (AE_OK);
665
 
666
 
667
            case AML_SCOPE_OP:
668
            case AML_DEVICE_OP:
669
            case AML_THERMAL_ZONE_OP:
670
 
671
                AcpiOsPrintf (")");
672
                break;
673
 
674
 
675
            default:
676
 
677
                AcpiOsPrintf ("*** Unhandled named opcode %X\n", Op->Common.AmlOpcode);
678
                break;
679
            }
680
        }
681
 
682
        else switch (Op->Common.AmlOpcode)
683
        {
684
        case AML_FIELD_OP:
685
        case AML_BANK_FIELD_OP:
686
        case AML_INDEX_FIELD_OP:
687
 
688
            Info->BitOffset = 0;
689
 
690
            /* Name of the parent OperationRegion */
691
 
692
            NextOp = AcpiPsGetDepthNext (NULL, Op);
693
            AcpiDmNamestring (NextOp->Common.Value.Name);
694
            AcpiOsPrintf (", ");
695
            NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
696
 
697
            switch (Op->Common.AmlOpcode)
698
            {
699
            case AML_BANK_FIELD_OP:
700
 
701
                /* Namestring - Bank Name */
702
 
703
                NextOp = AcpiPsGetDepthNext (NULL, NextOp);
704
                AcpiDmNamestring (NextOp->Common.Value.Name);
705
                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
706
                AcpiOsPrintf (", ");
707
 
708
                /*
709
                 * Bank Value. This is a TermArg in the middle of the parameter
710
                 * list, must handle it here.
711
                 *
712
                 * Disassemble the TermArg parse tree. ACPI_PARSEOP_PARAMLIST
713
                 * eliminates newline in the output.
714
                 */
715
                NextOp = NextOp->Common.Next;
716
 
717
                Info->Flags = ACPI_PARSEOP_PARAMLIST;
718
                AcpiDmWalkParseTree (NextOp, AcpiDmDescendingOp, AcpiDmAscendingOp, Info);
719
                Info->Flags = 0;
720
                Info->Level = Level;
721
 
722
                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
723
                AcpiOsPrintf (", ");
724
                break;
725
 
726
            case AML_INDEX_FIELD_OP:
727
 
728
                /* Namestring - Data Name */
729
 
730
                NextOp = AcpiPsGetDepthNext (NULL, NextOp);
731
                AcpiDmNamestring (NextOp->Common.Value.Name);
732
                AcpiOsPrintf (", ");
733
                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
734
                break;
735
 
736
            default:
737
 
738
                break;
739
            }
740
 
741
            AcpiDmFieldFlags (NextOp);
742
            break;
743
 
744
 
745
        case AML_BUFFER_OP:
746
 
747
            /* The next op is the size parameter */
748
 
749
            NextOp = AcpiPsGetDepthNext (NULL, Op);
750
            if (!NextOp)
751
            {
752
                /* Single-step support */
753
 
754
                return (AE_OK);
755
            }
756
 
757
            if (Op->Common.DisasmOpcode == ACPI_DASM_RESOURCE)
758
            {
759
                /*
760
                 * We have a resource list.  Don't need to output
761
                 * the buffer size Op.  Open up a new block
762
                 */
763
                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
764
                NextOp = NextOp->Common.Next;
765
                AcpiOsPrintf (")\n");
766
                AcpiDmIndent (Info->Level);
767
                AcpiOsPrintf ("{\n");
768
                return (AE_OK);
769
            }
770
 
771
            /* Normal Buffer, mark size as in the parameter list */
772
 
773
            NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
774
            return (AE_OK);
775
 
776
 
777
        case AML_VAR_PACKAGE_OP:
778
        case AML_IF_OP:
779
        case AML_WHILE_OP:
780
 
781
            /* The next op is the size or predicate parameter */
782
 
783
            NextOp = AcpiPsGetDepthNext (NULL, Op);
784
            if (NextOp)
785
            {
786
                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
787
            }
788
            return (AE_OK);
789
 
790
 
791
        case AML_PACKAGE_OP:
792
 
793
            /* The next op is the size or predicate parameter */
794
 
795
            NextOp = AcpiPsGetDepthNext (NULL, Op);
796
            if (NextOp)
797
            {
798
                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
799
            }
800
            return (AE_OK);
801
 
802
 
803
        case AML_MATCH_OP:
804
 
805
            AcpiDmMatchOp (Op);
806
            break;
807
 
808
 
809
        default:
810
 
811
            break;
812
        }
813
 
814
        if (AcpiDmBlockType (Op) & BLOCK_BRACE)
815
        {
816
            AcpiOsPrintf ("\n");
817
            AcpiDmIndent (Level);
818
            AcpiOsPrintf ("{\n");
819
        }
820
    }
821
 
822
    return (AE_OK);
823
}
824
 
825
 
826
/*******************************************************************************
827
 *
828
 * FUNCTION:    AcpiDmAscendingOp
829
 *
830
 * PARAMETERS:  ASL_WALK_CALLBACK
831
 *
832
 * RETURN:      Status
833
 *
834
 * DESCRIPTION: Second visitation of a parse object, during ascent of parse
835
 *              tree.  Close out any parameter lists and complete the opcode.
836
 *
837
 ******************************************************************************/
838
 
839
static ACPI_STATUS
840
AcpiDmAscendingOp (
841
    ACPI_PARSE_OBJECT       *Op,
842
    UINT32                  Level,
843
    void                    *Context)
844
{
845
    ACPI_OP_WALK_INFO       *Info = Context;
846
 
847
 
848
    if (Op->Common.DisasmFlags & ACPI_PARSEOP_IGNORE)
849
    {
850
        /* Ignore this op -- it was handled elsewhere */
851
 
852
        return (AE_OK);
853
    }
854
 
855
    if ((Level == 0) && (Op->Common.AmlOpcode == AML_SCOPE_OP))
856
    {
857
        /* Indicates the end of the current descriptor block (table) */
858
 
859
        AcpiOsPrintf ("}\n\n");
860
        return (AE_OK);
861
    }
862
 
863
    switch (AcpiDmBlockType (Op))
864
    {
865
    case BLOCK_PAREN:
866
 
867
        /* Completed an op that has arguments, add closing paren */
868
 
869
        AcpiOsPrintf (")");
870
 
871
        /* Could be a nested operator, check if comma required */
872
 
873
        if (!AcpiDmCommaIfListMember (Op))
874
        {
875
            if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
876
                     (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) &&
877
                     (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP))
878
            {
879
                /*
880
                 * This is a first-level element of a term list
881
                 * start a new line
882
                 */
883
                if (!(Info->Flags & ACPI_PARSEOP_PARAMLIST))
884
                {
885
                    AcpiOsPrintf ("\n");
886
                }
887
            }
888
        }
889
        break;
890
 
891
 
892
    case BLOCK_BRACE:
893
    case (BLOCK_BRACE | BLOCK_PAREN):
894
 
895
        /* Completed an op that has a term list, add closing brace */
896
 
897
        if (Op->Common.DisasmFlags & ACPI_PARSEOP_EMPTY_TERMLIST)
898
        {
899
            AcpiOsPrintf ("}");
900
        }
901
        else
902
        {
903
            AcpiDmIndent (Level);
904
            AcpiOsPrintf ("}");
905
        }
906
 
907
        AcpiDmCommaIfListMember (Op);
908
 
909
        if (AcpiDmBlockType (Op->Common.Parent) != BLOCK_PAREN)
910
        {
911
            AcpiOsPrintf ("\n");
912
            if (!(Op->Common.DisasmFlags & ACPI_PARSEOP_EMPTY_TERMLIST))
913
            {
914
                if ((Op->Common.AmlOpcode == AML_IF_OP)  &&
915
                    (Op->Common.Next) &&
916
                    (Op->Common.Next->Common.AmlOpcode == AML_ELSE_OP))
917
                {
918
                    break;
919
                }
920
 
921
                if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
922
                    (!Op->Common.Next))
923
                {
924
                    break;
925
                }
926
                AcpiOsPrintf ("\n");
927
            }
928
        }
929
        break;
930
 
931
 
932
    case BLOCK_NONE:
933
    default:
934
 
935
        /* Could be a nested operator, check if comma required */
936
 
937
        if (!AcpiDmCommaIfListMember (Op))
938
        {
939
            if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
940
                     (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) &&
941
                     (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP))
942
            {
943
                /*
944
                 * This is a first-level element of a term list
945
                 * start a new line
946
                 */
947
                AcpiOsPrintf ("\n");
948
            }
949
        }
950
        else if (Op->Common.Parent)
951
        {
952
            switch (Op->Common.Parent->Common.AmlOpcode)
953
            {
954
            case AML_PACKAGE_OP:
955
            case AML_VAR_PACKAGE_OP:
956
 
957
                if (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST))
958
                {
959
                    AcpiOsPrintf ("\n");
960
                }
961
                break;
962
 
963
            default:
964
 
965
                break;
966
            }
967
        }
968
        break;
969
    }
970
 
971
    if (Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)
972
    {
973
        if ((Op->Common.Next) &&
974
            (Op->Common.Next->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST))
975
        {
976
            return (AE_OK);
977
        }
978
 
979
        /*
980
         * Just completed a parameter node for something like "Buffer (param)".
981
         * Close the paren and open up the term list block with a brace
982
         */
983
        if (Op->Common.Next)
984
        {
985
            AcpiOsPrintf (")\n");
986
            AcpiDmIndent (Level - 1);
987
            AcpiOsPrintf ("{\n");
988
        }
989
        else
990
        {
991
            Op->Common.Parent->Common.DisasmFlags |=
992
                                    ACPI_PARSEOP_EMPTY_TERMLIST;
993
            AcpiOsPrintf (") {");
994
        }
995
    }
996
 
997
    if ((Op->Common.AmlOpcode == AML_NAME_OP) ||
998
        (Op->Common.AmlOpcode == AML_RETURN_OP))
999
    {
1000
        Info->Level++;
1001
    }
1002
    return (AE_OK);
1003
}
1004
 
1005
 
1006
#endif  /* ACPI_DISASSEMBLER */