1 /*******************************************************************************
2 *
3 * Module Name: dmwalk - AML disassembly tree walk
4 *
5 ******************************************************************************/
6
7 /******************************************************************************
8 *
9 * 1. Copyright Notice
10 *
11 * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp.
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
AcpiDmEmitExternals(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 *
166 * FUNCTION: AcpiDmDisassemble
167 *
168 * PARAMETERS: WalkState - Current state
169 * Origin - Starting object
170 * NumOpcodes - Max number of opcodes to be displayed
171 *
172 * RETURN: None
173 *
174 * DESCRIPTION: Disassemble parser object and its children. This is the
175 * main entry point of the disassembler.
176 *
177 ******************************************************************************/
178
179 void
AcpiDmDisassemble(ACPI_WALK_STATE * WalkState,ACPI_PARSE_OBJECT * Origin,UINT32 NumOpcodes)180 AcpiDmDisassemble (
181 ACPI_WALK_STATE *WalkState,
182 ACPI_PARSE_OBJECT *Origin,
183 UINT32 NumOpcodes)
184 {
185 ACPI_PARSE_OBJECT *Op = Origin;
186 ACPI_OP_WALK_INFO Info;
187
188
189 if (!Op)
190 {
191 return;
192 }
193
194 Info.Flags = 0;
195 Info.Level = 0;
196 Info.Count = 0;
197 Info.WalkState = WalkState;
198 AcpiDmWalkParseTree (Op, AcpiDmDescendingOp, AcpiDmAscendingOp, &Info);
199 return;
200 }
201
202
203 /*******************************************************************************
204 *
205 * FUNCTION: AcpiDmWalkParseTree
206 *
207 * PARAMETERS: Op - Root Op object
208 * DescendingCallback - Called during tree descent
209 * AscendingCallback - Called during tree ascent
210 * Context - To be passed to the callbacks
211 *
212 * RETURN: Status from callback(s)
213 *
214 * DESCRIPTION: Walk the entire parse tree.
215 *
216 ******************************************************************************/
217
218 void
AcpiDmWalkParseTree(ACPI_PARSE_OBJECT * Op,ASL_WALK_CALLBACK DescendingCallback,ASL_WALK_CALLBACK AscendingCallback,void * Context)219 AcpiDmWalkParseTree (
220 ACPI_PARSE_OBJECT *Op,
221 ASL_WALK_CALLBACK DescendingCallback,
222 ASL_WALK_CALLBACK AscendingCallback,
223 void *Context)
224 {
225 BOOLEAN NodePreviouslyVisited;
226 ACPI_PARSE_OBJECT *StartOp = Op;
227 ACPI_STATUS Status;
228 ACPI_PARSE_OBJECT *Next;
229 ACPI_OP_WALK_INFO *Info = Context;
230
231
232 Info->Level = 0;
233 NodePreviouslyVisited = FALSE;
234
235 while (Op)
236 {
237 if (NodePreviouslyVisited)
238 {
239 if (AscendingCallback)
240 {
241 Status = AscendingCallback (Op, Info->Level, Context);
242 if (ACPI_FAILURE (Status))
243 {
244 return;
245 }
246 }
247 }
248 else
249 {
250 /* Let the callback process the node */
251
252 Status = DescendingCallback (Op, Info->Level, Context);
253 if (ACPI_SUCCESS (Status))
254 {
255 /* Visit children first, once */
256
257 Next = AcpiPsGetArg (Op, 0);
258 if (Next)
259 {
260 Info->Level++;
261 Op = Next;
262 continue;
263 }
264 }
265 else if (Status != AE_CTRL_DEPTH)
266 {
267 /* Exit immediately on any error */
268
269 return;
270 }
271 }
272
273 /* Terminate walk at start op */
274
275 if (Op == StartOp)
276 {
277 break;
278 }
279
280 /* No more children, re-visit this node */
281
282 if (!NodePreviouslyVisited)
283 {
284 NodePreviouslyVisited = TRUE;
285 continue;
286 }
287
288 /* No more children, visit peers */
289
290 if (Op->Common.Next)
291 {
292 Op = Op->Common.Next;
293 NodePreviouslyVisited = FALSE;
294 }
295 else
296 {
297 /* No peers, re-visit parent */
298
299 if (Info->Level != 0 )
300 {
301 Info->Level--;
302 }
303
304 Op = Op->Common.Parent;
305 NodePreviouslyVisited = TRUE;
306 }
307 }
308
309 /* If we get here, the walk completed with no errors */
310
311 return;
312 }
313
314
315 /*******************************************************************************
316 *
317 * FUNCTION: AcpiDmBlockType
318 *
319 * PARAMETERS: Op - Object to be examined
320 *
321 * RETURN: BlockType - not a block, parens, braces, or even both.
322 *
323 * DESCRIPTION: Type of block for this op (parens or braces)
324 *
325 ******************************************************************************/
326
327 static UINT32
AcpiDmBlockType(ACPI_PARSE_OBJECT * Op)328 AcpiDmBlockType (
329 ACPI_PARSE_OBJECT *Op)
330 {
331 const ACPI_OPCODE_INFO *OpInfo;
332
333
334 if (!Op)
335 {
336 return (BLOCK_NONE);
337 }
338
339 switch (Op->Common.AmlOpcode)
340 {
341 case AML_ELSE_OP:
342
343 return (BLOCK_BRACE);
344
345 case AML_METHOD_OP:
346 case AML_DEVICE_OP:
347 case AML_SCOPE_OP:
348 case AML_PROCESSOR_OP:
349 case AML_POWER_RES_OP:
350 case AML_THERMAL_ZONE_OP:
351 case AML_IF_OP:
352 case AML_WHILE_OP:
353 case AML_FIELD_OP:
354 case AML_INDEX_FIELD_OP:
355 case AML_BANK_FIELD_OP:
356
357 return (BLOCK_PAREN | BLOCK_BRACE);
358
359 case AML_BUFFER_OP:
360
361 if (Op->Common.DisasmOpcode == ACPI_DASM_UNICODE)
362 {
363 return (BLOCK_NONE);
364 }
365
366 /*lint -fallthrough */
367
368 case AML_PACKAGE_OP:
369 case AML_VAR_PACKAGE_OP:
370
371 return (BLOCK_PAREN | BLOCK_BRACE);
372
373 case AML_EVENT_OP:
374
375 return (BLOCK_PAREN);
376
377 default:
378
379 OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
380 if (OpInfo->Flags & AML_HAS_ARGS)
381 {
382 return (BLOCK_PAREN);
383 }
384
385 return (BLOCK_NONE);
386 }
387 }
388
389
390 /*******************************************************************************
391 *
392 * FUNCTION: AcpiDmListType
393 *
394 * PARAMETERS: Op - Object to be examined
395 *
396 * RETURN: ListType - has commas or not.
397 *
398 * DESCRIPTION: Type of block for this op (parens or braces)
399 *
400 ******************************************************************************/
401
402 UINT32
AcpiDmListType(ACPI_PARSE_OBJECT * Op)403 AcpiDmListType (
404 ACPI_PARSE_OBJECT *Op)
405 {
406 const ACPI_OPCODE_INFO *OpInfo;
407
408
409 if (!Op)
410 {
411 return (BLOCK_NONE);
412 }
413
414 switch (Op->Common.AmlOpcode)
415 {
416
417 case AML_ELSE_OP:
418 case AML_METHOD_OP:
419 case AML_DEVICE_OP:
420 case AML_SCOPE_OP:
421 case AML_POWER_RES_OP:
422 case AML_PROCESSOR_OP:
423 case AML_THERMAL_ZONE_OP:
424 case AML_IF_OP:
425 case AML_WHILE_OP:
426 case AML_FIELD_OP:
427 case AML_INDEX_FIELD_OP:
428 case AML_BANK_FIELD_OP:
429
430 return (BLOCK_NONE);
431
432 case AML_BUFFER_OP:
433 case AML_PACKAGE_OP:
434 case AML_VAR_PACKAGE_OP:
435
436 return (BLOCK_COMMA_LIST);
437
438 default:
439
440 OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
441 if (OpInfo->Flags & AML_HAS_ARGS)
442 {
443 return (BLOCK_COMMA_LIST);
444 }
445
446 return (BLOCK_NONE);
447 }
448 }
449
450
451 /*******************************************************************************
452 *
453 * FUNCTION: AcpiDmDescendingOp
454 *
455 * PARAMETERS: ASL_WALK_CALLBACK
456 *
457 * RETURN: Status
458 *
459 * DESCRIPTION: First visitation of a parse object during tree descent.
460 * Decode opcode name and begin parameter list(s), if any.
461 *
462 ******************************************************************************/
463
464 static ACPI_STATUS
AcpiDmDescendingOp(ACPI_PARSE_OBJECT * Op,UINT32 Level,void * Context)465 AcpiDmDescendingOp (
466 ACPI_PARSE_OBJECT *Op,
467 UINT32 Level,
468 void *Context)
469 {
470 ACPI_OP_WALK_INFO *Info = Context;
471 const ACPI_OPCODE_INFO *OpInfo;
472 UINT32 Name;
473 ACPI_PARSE_OBJECT *NextOp;
474
475
476 if (Op->Common.DisasmFlags & ACPI_PARSEOP_IGNORE)
477 {
478 /* Ignore this op -- it was handled elsewhere */
479
480 return (AE_CTRL_DEPTH);
481 }
482
483 /* Level 0 is at the Definition Block level */
484
485 if (Level == 0)
486 {
487 /* In verbose mode, print the AML offset, opcode and depth count */
488
489 if (Info->WalkState)
490 {
491 VERBOSE_PRINT ((DB_FULL_OP_INFO,
492 (Info->WalkState->MethodNode ?
493 Info->WalkState->MethodNode->Name.Ascii : " "),
494 Op->Common.AmlOffset, (UINT32) Op->Common.AmlOpcode));
495 }
496
497 if (Op->Common.AmlOpcode == AML_SCOPE_OP)
498 {
499 /* This is the beginning of the Definition Block */
500
501 AcpiOsPrintf ("{\n");
502
503 /* Emit all External() declarations here */
504
505 AcpiDmEmitExternals ();
506 return (AE_OK);
507 }
508 }
509 else if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
510 (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) &&
511 (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP))
512 {
513 /*
514 * This is a first-level element of a term list,
515 * indent a new line
516 */
517 AcpiDmIndent (Level);
518 Info->LastLevel = Level;
519 Info->Count = 0;
520 }
521
522 /*
523 * This is an inexpensive mechanism to try and keep lines from getting
524 * too long. When the limit is hit, start a new line at the previous
525 * indent plus one. A better but more expensive mechanism would be to
526 * keep track of the current column.
527 */
528 Info->Count++;
529 if (Info->Count /*+Info->LastLevel*/ > 10)
530 {
531 Info->Count = 0;
532 AcpiOsPrintf ("\n");
533 AcpiDmIndent (Info->LastLevel + 1);
534 }
535
536 /* Print the opcode name */
537
538 AcpiDmDisassembleOneOp (NULL, Info, Op);
539
540 if (Op->Common.DisasmOpcode == ACPI_DASM_LNOT_PREFIX)
541 {
542 return (AE_OK);
543 }
544
545 if ((Op->Common.AmlOpcode == AML_NAME_OP) ||
546 (Op->Common.AmlOpcode == AML_RETURN_OP))
547 {
548 Info->Level--;
549 }
550
551 /* Start the opcode argument list if necessary */
552
553 OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
554
555 if ((OpInfo->Flags & AML_HAS_ARGS) ||
556 (Op->Common.AmlOpcode == AML_EVENT_OP))
557 {
558 /* This opcode has an argument list */
559
560 if (AcpiDmBlockType (Op) & BLOCK_PAREN)
561 {
562 AcpiOsPrintf (" (");
563 }
564
565 /* If this is a named opcode, print the associated name value */
566
567 if (OpInfo->Flags & AML_NAMED)
568 {
569 switch (Op->Common.AmlOpcode)
570 {
571 case AML_ALIAS_OP:
572
573 NextOp = AcpiPsGetDepthNext (NULL, Op);
574 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
575 AcpiDmNamestring (NextOp->Common.Value.Name);
576 AcpiOsPrintf (", ");
577
578 /*lint -fallthrough */
579
580 default:
581
582 Name = AcpiPsGetName (Op);
583 if (Op->Named.Path)
584 {
585 AcpiDmNamestring ((char *) Op->Named.Path);
586 }
587 else
588 {
589 AcpiDmDumpName (Name);
590 }
591
592 if (Op->Common.AmlOpcode != AML_INT_NAMEDFIELD_OP)
593 {
594 if (AcpiGbl_DbOpt_verbose)
595 {
596 (void) AcpiPsDisplayObjectPathname (NULL, Op);
597 }
598 }
599 break;
600 }
601
602 switch (Op->Common.AmlOpcode)
603 {
604 case AML_METHOD_OP:
605
606 AcpiDmMethodFlags (Op);
607 AcpiOsPrintf (")");
608 break;
609
610
611 case AML_NAME_OP:
612
613 /* Check for _HID and related EISAID() */
614
615 AcpiDmIsEisaId (Op);
616 AcpiOsPrintf (", ");
617 break;
618
619
620 case AML_REGION_OP:
621
622 AcpiDmRegionFlags (Op);
623 break;
624
625
626 case AML_POWER_RES_OP:
627
628 /* Mark the next two Ops as part of the parameter list */
629
630 AcpiOsPrintf (", ");
631 NextOp = AcpiPsGetDepthNext (NULL, Op);
632 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
633
634 NextOp = NextOp->Common.Next;
635 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
636 return (AE_OK);
637
638
639 case AML_PROCESSOR_OP:
640
641 /* Mark the next three Ops as part of the parameter list */
642
643 AcpiOsPrintf (", ");
644 NextOp = AcpiPsGetDepthNext (NULL, Op);
645 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
646
647 NextOp = NextOp->Common.Next;
648 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
649
650 NextOp = NextOp->Common.Next;
651 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
652 return (AE_OK);
653
654
655 case AML_MUTEX_OP:
656 case AML_DATA_REGION_OP:
657
658 AcpiOsPrintf (", ");
659 return (AE_OK);
660
661
662 case AML_EVENT_OP:
663 case AML_ALIAS_OP:
664
665 return (AE_OK);
666
667
668 case AML_SCOPE_OP:
669 case AML_DEVICE_OP:
670 case AML_THERMAL_ZONE_OP:
671
672 AcpiOsPrintf (")");
673 break;
674
675
676 default:
677
678 AcpiOsPrintf ("*** Unhandled named opcode %X\n", Op->Common.AmlOpcode);
679 break;
680 }
681 }
682
683 else switch (Op->Common.AmlOpcode)
684 {
685 case AML_FIELD_OP:
686 case AML_BANK_FIELD_OP:
687 case AML_INDEX_FIELD_OP:
688
689 Info->BitOffset = 0;
690
691 /* Name of the parent OperationRegion */
692
693 NextOp = AcpiPsGetDepthNext (NULL, Op);
694 AcpiDmNamestring (NextOp->Common.Value.Name);
695 AcpiOsPrintf (", ");
696 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
697
698 switch (Op->Common.AmlOpcode)
699 {
700 case AML_BANK_FIELD_OP:
701
702 /* Namestring - Bank Name */
703
704 NextOp = AcpiPsGetDepthNext (NULL, NextOp);
705 AcpiDmNamestring (NextOp->Common.Value.Name);
706 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
707 AcpiOsPrintf (", ");
708
709 /*
710 * Bank Value. This is a TermArg in the middle of the parameter
711 * list, must handle it here.
712 *
713 * Disassemble the TermArg parse tree. ACPI_PARSEOP_PARAMLIST
714 * eliminates newline in the output.
715 */
716 NextOp = NextOp->Common.Next;
717
718 Info->Flags = ACPI_PARSEOP_PARAMLIST;
719 AcpiDmWalkParseTree (NextOp, AcpiDmDescendingOp, AcpiDmAscendingOp, Info);
720 Info->Flags = 0;
721 Info->Level = Level;
722
723 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
724 AcpiOsPrintf (", ");
725 break;
726
727 case AML_INDEX_FIELD_OP:
728
729 /* Namestring - Data Name */
730
731 NextOp = AcpiPsGetDepthNext (NULL, NextOp);
732 AcpiDmNamestring (NextOp->Common.Value.Name);
733 AcpiOsPrintf (", ");
734 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
735 break;
736
737 default:
738
739 break;
740 }
741
742 AcpiDmFieldFlags (NextOp);
743 break;
744
745
746 case AML_BUFFER_OP:
747
748 /* The next op is the size parameter */
749
750 NextOp = AcpiPsGetDepthNext (NULL, Op);
751 if (!NextOp)
752 {
753 /* Single-step support */
754
755 return (AE_OK);
756 }
757
758 if (Op->Common.DisasmOpcode == ACPI_DASM_RESOURCE)
759 {
760 /*
761 * We have a resource list. Don't need to output
762 * the buffer size Op. Open up a new block
763 */
764 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
765 NextOp = NextOp->Common.Next;
766 AcpiOsPrintf (")\n");
767 AcpiDmIndent (Info->Level);
768 AcpiOsPrintf ("{\n");
769 return (AE_OK);
770 }
771
772 /* Normal Buffer, mark size as in the parameter list */
773
774 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
775 return (AE_OK);
776
777
778 case AML_VAR_PACKAGE_OP:
779 case AML_IF_OP:
780 case AML_WHILE_OP:
781
782 /* The next op is the size or predicate parameter */
783
784 NextOp = AcpiPsGetDepthNext (NULL, Op);
785 if (NextOp)
786 {
787 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
788 }
789 return (AE_OK);
790
791
792 case AML_PACKAGE_OP:
793
794 /* The next op is the size or predicate parameter */
795
796 NextOp = AcpiPsGetDepthNext (NULL, Op);
797 if (NextOp)
798 {
799 NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
800 }
801 return (AE_OK);
802
803
804 case AML_MATCH_OP:
805
806 AcpiDmMatchOp (Op);
807 break;
808
809
810 default:
811
812 break;
813 }
814
815 if (AcpiDmBlockType (Op) & BLOCK_BRACE)
816 {
817 AcpiOsPrintf ("\n");
818 AcpiDmIndent (Level);
819 AcpiOsPrintf ("{\n");
820 }
821 }
822
823 return (AE_OK);
824 }
825
826
827 /*******************************************************************************
828 *
829 * FUNCTION: AcpiDmAscendingOp
830 *
831 * PARAMETERS: ASL_WALK_CALLBACK
832 *
833 * RETURN: Status
834 *
835 * DESCRIPTION: Second visitation of a parse object, during ascent of parse
836 * tree. Close out any parameter lists and complete the opcode.
837 *
838 ******************************************************************************/
839
840 static ACPI_STATUS
AcpiDmAscendingOp(ACPI_PARSE_OBJECT * Op,UINT32 Level,void * Context)841 AcpiDmAscendingOp (
842 ACPI_PARSE_OBJECT *Op,
843 UINT32 Level,
844 void *Context)
845 {
846 ACPI_OP_WALK_INFO *Info = Context;
847
848
849 if (Op->Common.DisasmFlags & ACPI_PARSEOP_IGNORE)
850 {
851 /* Ignore this op -- it was handled elsewhere */
852
853 return (AE_OK);
854 }
855
856 if ((Level == 0) && (Op->Common.AmlOpcode == AML_SCOPE_OP))
857 {
858 /* Indicates the end of the current descriptor block (table) */
859
860 AcpiOsPrintf ("}\n\n");
861 return (AE_OK);
862 }
863
864 switch (AcpiDmBlockType (Op))
865 {
866 case BLOCK_PAREN:
867
868 /* Completed an op that has arguments, add closing paren */
869
870 AcpiOsPrintf (")");
871
872 /* Could be a nested operator, check if comma required */
873
874 if (!AcpiDmCommaIfListMember (Op))
875 {
876 if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
877 (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) &&
878 (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP))
879 {
880 /*
881 * This is a first-level element of a term list
882 * start a new line
883 */
884 if (!(Info->Flags & ACPI_PARSEOP_PARAMLIST))
885 {
886 AcpiOsPrintf ("\n");
887 }
888 }
889 }
890 break;
891
892
893 case BLOCK_BRACE:
894 case (BLOCK_BRACE | BLOCK_PAREN):
895
896 /* Completed an op that has a term list, add closing brace */
897
898 if (Op->Common.DisasmFlags & ACPI_PARSEOP_EMPTY_TERMLIST)
899 {
900 AcpiOsPrintf ("}");
901 }
902 else
903 {
904 AcpiDmIndent (Level);
905 AcpiOsPrintf ("}");
906 }
907
908 AcpiDmCommaIfListMember (Op);
909
910 if (AcpiDmBlockType (Op->Common.Parent) != BLOCK_PAREN)
911 {
912 AcpiOsPrintf ("\n");
913 if (!(Op->Common.DisasmFlags & ACPI_PARSEOP_EMPTY_TERMLIST))
914 {
915 if ((Op->Common.AmlOpcode == AML_IF_OP) &&
916 (Op->Common.Next) &&
917 (Op->Common.Next->Common.AmlOpcode == AML_ELSE_OP))
918 {
919 break;
920 }
921
922 if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
923 (!Op->Common.Next))
924 {
925 break;
926 }
927 AcpiOsPrintf ("\n");
928 }
929 }
930 break;
931
932
933 case BLOCK_NONE:
934 default:
935
936 /* Could be a nested operator, check if comma required */
937
938 if (!AcpiDmCommaIfListMember (Op))
939 {
940 if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
941 (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) &&
942 (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP))
943 {
944 /*
945 * This is a first-level element of a term list
946 * start a new line
947 */
948 AcpiOsPrintf ("\n");
949 }
950 }
951 else if (Op->Common.Parent)
952 {
953 switch (Op->Common.Parent->Common.AmlOpcode)
954 {
955 case AML_PACKAGE_OP:
956 case AML_VAR_PACKAGE_OP:
957
958 if (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST))
959 {
960 AcpiOsPrintf ("\n");
961 }
962 break;
963
964 default:
965
966 break;
967 }
968 }
969 break;
970 }
971
972 if (Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)
973 {
974 if ((Op->Common.Next) &&
975 (Op->Common.Next->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST))
976 {
977 return (AE_OK);
978 }
979
980 /*
981 * Just completed a parameter node for something like "Buffer (param)".
982 * Close the paren and open up the term list block with a brace
983 */
984 if (Op->Common.Next)
985 {
986 AcpiOsPrintf (")\n");
987 AcpiDmIndent (Level - 1);
988 AcpiOsPrintf ("{\n");
989 }
990 else
991 {
992 Op->Common.Parent->Common.DisasmFlags |=
993 ACPI_PARSEOP_EMPTY_TERMLIST;
994 AcpiOsPrintf (") {");
995 }
996 }
997
998 if ((Op->Common.AmlOpcode == AML_NAME_OP) ||
999 (Op->Common.AmlOpcode == AML_RETURN_OP))
1000 {
1001 Info->Level++;
1002 }
1003 return (AE_OK);
1004 }
1005
1006
1007 #endif /* ACPI_DISASSEMBLER */
1008