1 /*******************************************************************************
3 * Module Name: dmwalk - AML disassembly tree walk
5 ******************************************************************************/
8 * Copyright (C) 2000 - 2017, Intel Corp.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
49 #include "acconvert.h"
52 #ifdef ACPI_DISASSEMBLER
54 #define _COMPONENT ACPI_CA_DEBUGGER
55 ACPI_MODULE_NAME ("dmwalk")
58 #define DB_FULL_OP_INFO "[%4.4s] @%5.5X #%4.4X: "
60 /* Stub for non-compiler code */
62 #ifndef ACPI_ASL_COMPILER
72 ACPI_PARSE_OBJECT
*NameOp
,
73 ACPI_PARSE_OBJECT
*TypeOp
)
79 /* Local prototypes */
83 ACPI_PARSE_OBJECT
*Op
,
89 ACPI_PARSE_OBJECT
*Op
,
94 /*******************************************************************************
96 * FUNCTION: AcpiDmDisassemble
98 * PARAMETERS: WalkState - Current state
99 * Origin - Starting object
100 * NumOpcodes - Max number of opcodes to be displayed
104 * DESCRIPTION: Disassemble parser object and its children. This is the
105 * main entry point of the disassembler.
107 ******************************************************************************/
111 ACPI_WALK_STATE
*WalkState
,
112 ACPI_PARSE_OBJECT
*Origin
,
115 ACPI_PARSE_OBJECT
*Op
= Origin
;
116 ACPI_OP_WALK_INFO Info
;
124 memset (&Info
, 0, sizeof (ACPI_OP_WALK_INFO
));
125 Info
.WalkState
= WalkState
;
126 Info
.StartAml
= Op
->Common
.Aml
- sizeof (ACPI_TABLE_HEADER
);
127 Info
.AmlOffset
= Op
->Common
.Aml
- Info
.StartAml
;
129 AcpiDmWalkParseTree (Op
, AcpiDmDescendingOp
, AcpiDmAscendingOp
, &Info
);
134 /*******************************************************************************
136 * FUNCTION: AcpiDmWalkParseTree
138 * PARAMETERS: Op - Root Op object
139 * DescendingCallback - Called during tree descent
140 * AscendingCallback - Called during tree ascent
141 * Context - To be passed to the callbacks
143 * RETURN: Status from callback(s)
145 * DESCRIPTION: Walk the entire parse tree.
147 ******************************************************************************/
150 AcpiDmWalkParseTree (
151 ACPI_PARSE_OBJECT
*Op
,
152 ASL_WALK_CALLBACK DescendingCallback
,
153 ASL_WALK_CALLBACK AscendingCallback
,
156 BOOLEAN NodePreviouslyVisited
;
157 ACPI_PARSE_OBJECT
*StartOp
= Op
;
159 ACPI_PARSE_OBJECT
*Next
;
160 ACPI_OP_WALK_INFO
*Info
= Context
;
164 NodePreviouslyVisited
= FALSE
;
168 if (NodePreviouslyVisited
)
170 if (AscendingCallback
)
172 Status
= AscendingCallback (Op
, Info
->Level
, Context
);
173 if (ACPI_FAILURE (Status
))
181 /* Let the callback process the node */
183 Status
= DescendingCallback (Op
, Info
->Level
, Context
);
184 if (ACPI_SUCCESS (Status
))
186 /* Visit children first, once */
188 Next
= AcpiPsGetArg (Op
, 0);
196 else if (Status
!= AE_CTRL_DEPTH
)
198 /* Exit immediately on any error */
204 /* Terminate walk at start op */
211 /* No more children, re-visit this node */
213 if (!NodePreviouslyVisited
)
215 NodePreviouslyVisited
= TRUE
;
219 /* No more children, visit peers */
223 Op
= Op
->Common
.Next
;
224 NodePreviouslyVisited
= FALSE
;
228 /* No peers, re-visit parent */
230 if (Info
->Level
!= 0 )
235 Op
= Op
->Common
.Parent
;
236 NodePreviouslyVisited
= TRUE
;
240 /* If we get here, the walk completed with no errors */
246 /*******************************************************************************
248 * FUNCTION: AcpiDmBlockType
250 * PARAMETERS: Op - Object to be examined
252 * RETURN: BlockType - not a block, parens, braces, or even both.
254 * DESCRIPTION: Type of block for this op (parens or braces)
256 ******************************************************************************/
260 ACPI_PARSE_OBJECT
*Op
)
262 const ACPI_OPCODE_INFO
*OpInfo
;
270 switch (Op
->Common
.AmlOpcode
)
274 return (BLOCK_BRACE
);
279 case AML_PROCESSOR_OP
:
280 case AML_POWER_RESOURCE_OP
:
281 case AML_THERMAL_ZONE_OP
:
285 case AML_INDEX_FIELD_OP
:
286 case AML_BANK_FIELD_OP
:
288 return (BLOCK_PAREN
| BLOCK_BRACE
);
292 if ((Op
->Common
.DisasmOpcode
== ACPI_DASM_UNICODE
) ||
293 (Op
->Common
.DisasmOpcode
== ACPI_DASM_UUID
) ||
294 (Op
->Common
.DisasmOpcode
== ACPI_DASM_PLD_METHOD
))
299 /*lint -fallthrough */
302 case AML_VARIABLE_PACKAGE_OP
:
304 return (BLOCK_PAREN
| BLOCK_BRACE
);
308 return (BLOCK_PAREN
);
310 case AML_INT_METHODCALL_OP
:
312 if (Op
->Common
.Parent
&&
313 ((Op
->Common
.Parent
->Common
.AmlOpcode
== AML_PACKAGE_OP
) ||
314 (Op
->Common
.Parent
->Common
.AmlOpcode
== AML_VARIABLE_PACKAGE_OP
)))
316 /* This is a reference to a method, not an invocation */
321 /*lint -fallthrough */
325 OpInfo
= AcpiPsGetOpcodeInfo (Op
->Common
.AmlOpcode
);
326 if (OpInfo
->Flags
& AML_HAS_ARGS
)
328 return (BLOCK_PAREN
);
336 /*******************************************************************************
338 * FUNCTION: AcpiDmListType
340 * PARAMETERS: Op - Object to be examined
342 * RETURN: ListType - has commas or not.
344 * DESCRIPTION: Type of block for this op (parens or braces)
346 ******************************************************************************/
350 ACPI_PARSE_OBJECT
*Op
)
352 const ACPI_OPCODE_INFO
*OpInfo
;
360 switch (Op
->Common
.AmlOpcode
)
367 case AML_POWER_RESOURCE_OP
:
368 case AML_PROCESSOR_OP
:
369 case AML_THERMAL_ZONE_OP
:
373 case AML_INDEX_FIELD_OP
:
374 case AML_BANK_FIELD_OP
:
380 case AML_VARIABLE_PACKAGE_OP
:
382 return (BLOCK_COMMA_LIST
);
386 OpInfo
= AcpiPsGetOpcodeInfo (Op
->Common
.AmlOpcode
);
387 if (OpInfo
->Flags
& AML_HAS_ARGS
)
389 return (BLOCK_COMMA_LIST
);
397 /*******************************************************************************
399 * FUNCTION: AcpiDmDescendingOp
401 * PARAMETERS: ASL_WALK_CALLBACK
405 * DESCRIPTION: First visitation of a parse object during tree descent.
406 * Decode opcode name and begin parameter list(s), if any.
408 ******************************************************************************/
412 ACPI_PARSE_OBJECT
*Op
,
416 ACPI_OP_WALK_INFO
*Info
= Context
;
417 const ACPI_OPCODE_INFO
*OpInfo
;
419 ACPI_PARSE_OBJECT
*NextOp
;
420 ACPI_PARSE_OBJECT
*NextOp2
;
424 /* Determine which file this parse node is contained in. */
426 if (Gbl_CaptureComments
)
428 ASL_CV_LABEL_FILENODE (Op
);
430 if (Level
!= 0 && ASL_CV_FILE_HAS_SWITCHED (Op
))
432 ASL_CV_SWITCH_FILES (Level
, Op
);
435 /* If this parse node has regular comments, print them here. */
437 ASL_CV_PRINT_ONE_COMMENT (Op
, AML_COMMENT_STANDARD
, NULL
, Level
);
440 OpInfo
= AcpiPsGetOpcodeInfo (Op
->Common
.AmlOpcode
);
442 /* Listing support to dump the AML code after the ASL statement */
444 if (AcpiGbl_DmOpt_Listing
)
446 /* We only care about these classes of objects */
448 if ((OpInfo
->Class
== AML_CLASS_NAMED_OBJECT
) ||
449 (OpInfo
->Class
== AML_CLASS_CONTROL
) ||
450 (OpInfo
->Class
== AML_CLASS_CREATE
) ||
451 ((OpInfo
->Class
== AML_CLASS_EXECUTE
) && (!Op
->Common
.Next
)))
453 if (AcpiGbl_DmOpt_Listing
&& Info
->PreviousAml
)
455 /* Dump the AML byte code for the previous Op */
457 if (Op
->Common
.Aml
> Info
->PreviousAml
)
461 (Info
->StartAml
+ Info
->AmlOffset
),
462 (Op
->Common
.Aml
- Info
->PreviousAml
),
463 DB_BYTE_DISPLAY
, Info
->AmlOffset
);
467 Info
->AmlOffset
= (Op
->Common
.Aml
- Info
->StartAml
);
470 Info
->PreviousAml
= Op
->Common
.Aml
;
474 if (Op
->Common
.DisasmFlags
& ACPI_PARSEOP_IGNORE
)
476 /* Ignore this op -- it was handled elsewhere */
478 return (AE_CTRL_DEPTH
);
481 if (AcpiDmIsTempName(Op
))
483 /* Ignore compiler generated temporary names */
485 return (AE_CTRL_DEPTH
);
488 if (Op
->Common
.DisasmOpcode
== ACPI_DASM_IGNORE_SINGLE
)
490 /* Ignore this op, but not it's children */
495 if (Op
->Common
.AmlOpcode
== AML_IF_OP
)
497 NextOp
= AcpiPsGetDepthNext (NULL
, Op
);
500 NextOp
->Common
.DisasmFlags
|= ACPI_PARSEOP_PARAMETER_LIST
;
502 /* Don't emit the actual embedded externals unless asked */
504 if (!AcpiGbl_DmEmitExternalOpcodes
)
507 * A Zero predicate indicates the possibility of one or more
508 * External() opcodes within the If() block.
510 if (NextOp
->Common
.AmlOpcode
== AML_ZERO_OP
)
512 NextOp2
= NextOp
->Common
.Next
;
515 (NextOp2
->Common
.AmlOpcode
== AML_EXTERNAL_OP
))
517 /* Ignore the If 0 block and all children */
519 Op
->Common
.DisasmFlags
|= ACPI_PARSEOP_IGNORE
;
520 return (AE_CTRL_DEPTH
);
527 /* Level 0 is at the Definition Block level */
531 /* In verbose mode, print the AML offset, opcode and depth count */
535 AmlOffset
= (UINT32
) ACPI_PTR_DIFF (Op
->Common
.Aml
,
536 Info
->WalkState
->ParserState
.AmlStart
);
537 if (AcpiGbl_DmOpt_Verbose
)
539 AcpiOsPrintf (DB_FULL_OP_INFO
,
540 (Info
->WalkState
->MethodNode
?
541 Info
->WalkState
->MethodNode
->Name
.Ascii
: " "),
542 AmlOffset
, (UINT32
) Op
->Common
.AmlOpcode
);
546 if (Op
->Common
.AmlOpcode
== AML_SCOPE_OP
)
548 /* This is the beginning of the Definition Block */
550 AcpiOsPrintf ("{\n");
552 /* Emit all External() declarations here */
554 if (!AcpiGbl_DmEmitExternalOpcodes
)
556 AcpiDmEmitExternals ();
562 else if ((AcpiDmBlockType (Op
->Common
.Parent
) & BLOCK_BRACE
) &&
563 (!(Op
->Common
.DisasmFlags
& ACPI_PARSEOP_PARAMETER_LIST
)) &&
564 (!(Op
->Common
.DisasmFlags
& ACPI_PARSEOP_ELSEIF
)) &&
565 (Op
->Common
.AmlOpcode
!= AML_INT_BYTELIST_OP
))
568 * This is a first-level element of a term list,
571 switch (Op
->Common
.AmlOpcode
)
575 * Optionally just ignore this opcode. Some tables use
576 * NoOp opcodes for "padding" out packages that the BIOS
577 * changes dynamically. This can leave hundreds or
578 * thousands of NoOp opcodes that if disassembled,
579 * cannot be compiled because they are syntactically
582 if (AcpiGbl_IgnoreNoopOperator
)
584 Op
->Common
.DisasmFlags
|= ACPI_PARSEOP_IGNORE
;
592 AcpiDmIndent (Level
);
596 Info
->LastLevel
= Level
;
601 * This is an inexpensive mechanism to try and keep lines from getting
602 * too long. When the limit is hit, start a new line at the previous
603 * indent plus one. A better but more expensive mechanism would be to
604 * keep track of the current column.
607 if (Info
->Count
/* +Info->LastLevel */ > 12)
611 AcpiDmIndent (Info
->LastLevel
+ 1);
614 /* If ASL+ is enabled, check for a C-style operator */
616 if (AcpiDmCheckForSymbolicOpcode (Op
, Info
))
621 /* Print the opcode name */
623 AcpiDmDisassembleOneOp (NULL
, Info
, Op
);
625 if ((Op
->Common
.DisasmOpcode
== ACPI_DASM_LNOT_PREFIX
) ||
626 (Op
->Common
.AmlOpcode
== AML_INT_CONNECTION_OP
))
631 if ((Op
->Common
.AmlOpcode
== AML_NAME_OP
) ||
632 (Op
->Common
.AmlOpcode
== AML_RETURN_OP
))
637 if (Op
->Common
.AmlOpcode
== AML_EXTERNAL_OP
)
639 Op
->Common
.DisasmFlags
|= ACPI_PARSEOP_IGNORE
;
640 return (AE_CTRL_DEPTH
);
643 /* Start the opcode argument list if necessary */
645 if ((OpInfo
->Flags
& AML_HAS_ARGS
) ||
646 (Op
->Common
.AmlOpcode
== AML_EVENT_OP
))
648 /* This opcode has an argument list */
650 if (AcpiDmBlockType (Op
) & BLOCK_PAREN
)
653 if (!(AcpiDmBlockType (Op
) & BLOCK_BRACE
))
655 ASL_CV_PRINT_ONE_COMMENT (Op
, AMLCOMMENT_INLINE
, " ", 0);
659 /* If this is a named opcode, print the associated name value */
661 if (OpInfo
->Flags
& AML_NAMED
)
663 switch (Op
->Common
.AmlOpcode
)
667 NextOp
= AcpiPsGetDepthNext (NULL
, Op
);
668 NextOp
->Common
.DisasmFlags
|= ACPI_PARSEOP_IGNORE
;
669 AcpiDmNamestring (NextOp
->Common
.Value
.Name
);
672 /*lint -fallthrough */
676 Name
= AcpiPsGetName (Op
);
679 AcpiDmNamestring ((char *) Op
->Named
.Path
);
683 AcpiDmDumpName (Name
);
686 if (Op
->Common
.AmlOpcode
!= AML_INT_NAMEDFIELD_OP
)
688 if (AcpiGbl_DmOpt_Verbose
)
690 (void) AcpiPsDisplayObjectPathname (NULL
, Op
);
696 switch (Op
->Common
.AmlOpcode
)
700 AcpiDmMethodFlags (Op
);
701 ASL_CV_CLOSE_PAREN (Op
, Level
);
703 /* Emit description comment for Method() with a predefined ACPI name */
705 AcpiDmPredefinedDescription (Op
);
710 /* Check for _HID and related EISAID() */
712 AcpiDmCheckForHardwareId (Op
);
714 ASL_CV_PRINT_ONE_COMMENT (Op
, AML_NAMECOMMENT
, NULL
, 0);
719 AcpiDmRegionFlags (Op
);
722 case AML_POWER_RESOURCE_OP
:
724 /* Mark the next two Ops as part of the parameter list */
727 NextOp
= AcpiPsGetDepthNext (NULL
, Op
);
728 NextOp
->Common
.DisasmFlags
|= ACPI_PARSEOP_PARAMETER_LIST
;
730 NextOp
= NextOp
->Common
.Next
;
731 NextOp
->Common
.DisasmFlags
|= ACPI_PARSEOP_PARAMETER_LIST
;
734 case AML_PROCESSOR_OP
:
736 /* Mark the next three Ops as part of the parameter list */
739 NextOp
= AcpiPsGetDepthNext (NULL
, Op
);
740 NextOp
->Common
.DisasmFlags
|= ACPI_PARSEOP_PARAMETER_LIST
;
742 NextOp
= NextOp
->Common
.Next
;
743 NextOp
->Common
.DisasmFlags
|= ACPI_PARSEOP_PARAMETER_LIST
;
745 NextOp
= NextOp
->Common
.Next
;
746 NextOp
->Common
.DisasmFlags
|= ACPI_PARSEOP_PARAMETER_LIST
;
750 case AML_DATA_REGION_OP
:
762 case AML_THERMAL_ZONE_OP
:
764 ASL_CV_CLOSE_PAREN (Op
, Level
);
769 AcpiOsPrintf ("*** Unhandled named opcode %X\n",
770 Op
->Common
.AmlOpcode
);
775 else switch (Op
->Common
.AmlOpcode
)
778 case AML_BANK_FIELD_OP
:
779 case AML_INDEX_FIELD_OP
:
783 /* Name of the parent OperationRegion */
785 NextOp
= AcpiPsGetDepthNext (NULL
, Op
);
786 AcpiDmNamestring (NextOp
->Common
.Value
.Name
);
788 NextOp
->Common
.DisasmFlags
|= ACPI_PARSEOP_IGNORE
;
790 switch (Op
->Common
.AmlOpcode
)
792 case AML_BANK_FIELD_OP
:
794 /* Namestring - Bank Name */
796 NextOp
= AcpiPsGetDepthNext (NULL
, NextOp
);
797 AcpiDmNamestring (NextOp
->Common
.Value
.Name
);
798 NextOp
->Common
.DisasmFlags
|= ACPI_PARSEOP_IGNORE
;
802 * Bank Value. This is a TermArg in the middle of the parameter
803 * list, must handle it here.
805 * Disassemble the TermArg parse tree. ACPI_PARSEOP_PARAMETER_LIST
806 * eliminates newline in the output.
808 NextOp
= NextOp
->Common
.Next
;
810 Info
->Flags
= ACPI_PARSEOP_PARAMETER_LIST
;
811 AcpiDmWalkParseTree (NextOp
, AcpiDmDescendingOp
,
812 AcpiDmAscendingOp
, Info
);
816 NextOp
->Common
.DisasmFlags
|= ACPI_PARSEOP_IGNORE
;
820 case AML_INDEX_FIELD_OP
:
822 /* Namestring - Data Name */
824 NextOp
= AcpiPsGetDepthNext (NULL
, NextOp
);
825 AcpiDmNamestring (NextOp
->Common
.Value
.Name
);
827 NextOp
->Common
.DisasmFlags
|= ACPI_PARSEOP_IGNORE
;
835 AcpiDmFieldFlags (NextOp
);
840 /* The next op is the size parameter */
842 NextOp
= AcpiPsGetDepthNext (NULL
, Op
);
845 /* Single-step support */
850 if (Op
->Common
.DisasmOpcode
== ACPI_DASM_RESOURCE
)
853 * We have a resource list. Don't need to output
854 * the buffer size Op. Open up a new block
856 NextOp
->Common
.DisasmFlags
|= ACPI_PARSEOP_IGNORE
;
857 NextOp
= NextOp
->Common
.Next
;
858 ASL_CV_CLOSE_PAREN (Op
, Level
);
860 /* Emit description comment for Name() with a predefined ACPI name */
862 AcpiDmPredefinedDescription (Op
->Asl
.Parent
);
865 AcpiDmIndent (Info
->Level
);
866 AcpiOsPrintf ("{\n");
870 /* Normal Buffer, mark size as in the parameter list */
872 NextOp
->Common
.DisasmFlags
|= ACPI_PARSEOP_PARAMETER_LIST
;
876 case AML_VARIABLE_PACKAGE_OP
:
879 /* The next op is the size or predicate parameter */
881 NextOp
= AcpiPsGetDepthNext (NULL
, Op
);
884 NextOp
->Common
.DisasmFlags
|= ACPI_PARSEOP_PARAMETER_LIST
;
890 /* The next op is the size parameter */
892 NextOp
= AcpiPsGetDepthNext (NULL
, Op
);
895 NextOp
->Common
.DisasmFlags
|= ACPI_PARSEOP_PARAMETER_LIST
;
909 if (AcpiDmBlockType (Op
) & BLOCK_BRACE
)
912 AcpiDmIndent (Level
);
913 AcpiOsPrintf ("{\n");
921 /*******************************************************************************
923 * FUNCTION: AcpiDmAscendingOp
925 * PARAMETERS: ASL_WALK_CALLBACK
929 * DESCRIPTION: Second visitation of a parse object, during ascent of parse
930 * tree. Close out any parameter lists and complete the opcode.
932 ******************************************************************************/
936 ACPI_PARSE_OBJECT
*Op
,
940 ACPI_OP_WALK_INFO
*Info
= Context
;
941 ACPI_PARSE_OBJECT
*ParentOp
;
944 /* Point the Op's filename pointer to the proper file */
946 if (Gbl_CaptureComments
)
948 ASL_CV_LABEL_FILENODE (Op
);
950 /* Switch the output of these files if necessary */
952 if (ASL_CV_FILE_HAS_SWITCHED (Op
))
954 ASL_CV_SWITCH_FILES (Level
, Op
);
958 if (Op
->Common
.DisasmFlags
& ACPI_PARSEOP_IGNORE
||
959 Op
->Common
.DisasmOpcode
== ACPI_DASM_IGNORE_SINGLE
)
961 /* Ignore this op -- it was handled elsewhere */
966 if ((Level
== 0) && (Op
->Common
.AmlOpcode
== AML_SCOPE_OP
))
968 /* Indicates the end of the current descriptor block (table) */
970 ASL_CV_CLOSE_BRACE (Op
, Level
);
972 /* Print any comments that are at the end of the file here */
974 if (Gbl_CaptureComments
&& AcpiGbl_LastListHead
)
977 ASL_CV_PRINT_ONE_COMMENT_LIST (AcpiGbl_LastListHead
, 0);
979 AcpiOsPrintf ("\n\n");
984 switch (AcpiDmBlockType (Op
))
988 /* Completed an op that has arguments, add closing paren if needed */
990 AcpiDmCloseOperator (Op
);
992 if (Op
->Common
.AmlOpcode
== AML_NAME_OP
)
994 /* Emit description comment for Name() with a predefined ACPI name */
996 AcpiDmPredefinedDescription (Op
);
1000 /* For Create* operators, attempt to emit resource tag description */
1002 AcpiDmFieldPredefinedDescription (Op
);
1005 /* Decode Notify() values */
1007 if (Op
->Common
.AmlOpcode
== AML_NOTIFY_OP
)
1009 AcpiDmNotifyDescription (Op
);
1012 AcpiDmDisplayTargetPathname (Op
);
1014 /* Could be a nested operator, check if comma required */
1016 if (!AcpiDmCommaIfListMember (Op
))
1018 if ((AcpiDmBlockType (Op
->Common
.Parent
) & BLOCK_BRACE
) &&
1019 (!(Op
->Common
.DisasmFlags
& ACPI_PARSEOP_PARAMETER_LIST
)) &&
1020 (Op
->Common
.AmlOpcode
!= AML_INT_BYTELIST_OP
))
1023 * This is a first-level element of a term list
1026 if (!(Info
->Flags
& ACPI_PARSEOP_PARAMETER_LIST
))
1028 AcpiOsPrintf ("\n");
1035 case (BLOCK_BRACE
| BLOCK_PAREN
):
1037 /* Completed an op that has a term list, add closing brace */
1039 if (Op
->Common
.DisasmFlags
& ACPI_PARSEOP_EMPTY_TERMLIST
)
1041 ASL_CV_CLOSE_BRACE (Op
, Level
);
1045 AcpiDmIndent (Level
);
1046 ASL_CV_CLOSE_BRACE (Op
, Level
);
1049 AcpiDmCommaIfListMember (Op
);
1051 if (AcpiDmBlockType (Op
->Common
.Parent
) != BLOCK_PAREN
)
1053 AcpiOsPrintf ("\n");
1054 if (!(Op
->Common
.DisasmFlags
& ACPI_PARSEOP_EMPTY_TERMLIST
))
1056 if ((Op
->Common
.AmlOpcode
== AML_IF_OP
) &&
1057 (Op
->Common
.Next
) &&
1058 (Op
->Common
.Next
->Common
.AmlOpcode
== AML_ELSE_OP
))
1063 if ((AcpiDmBlockType (Op
->Common
.Parent
) & BLOCK_BRACE
) &&
1068 AcpiOsPrintf ("\n");
1076 /* Could be a nested operator, check if comma required */
1078 if (!AcpiDmCommaIfListMember (Op
))
1080 if ((AcpiDmBlockType (Op
->Common
.Parent
) & BLOCK_BRACE
) &&
1081 (!(Op
->Common
.DisasmFlags
& ACPI_PARSEOP_PARAMETER_LIST
)) &&
1082 (Op
->Common
.AmlOpcode
!= AML_INT_BYTELIST_OP
))
1085 * This is a first-level element of a term list
1088 AcpiOsPrintf ("\n");
1091 else if (Op
->Common
.Parent
)
1093 switch (Op
->Common
.Parent
->Common
.AmlOpcode
)
1095 case AML_PACKAGE_OP
:
1096 case AML_VARIABLE_PACKAGE_OP
:
1098 if (!(Op
->Common
.DisasmFlags
& ACPI_PARSEOP_PARAMETER_LIST
))
1100 AcpiOsPrintf ("\n");
1112 if (Op
->Common
.DisasmFlags
& ACPI_PARSEOP_PARAMETER_LIST
)
1114 if ((Op
->Common
.Next
) &&
1115 (Op
->Common
.Next
->Common
.DisasmFlags
& ACPI_PARSEOP_PARAMETER_LIST
))
1121 * The parent Op is guaranteed to be valid because of the flag
1122 * ACPI_PARSEOP_PARAMETER_LIST -- which means that this op is part of
1123 * a parameter list and thus has a valid parent.
1125 ParentOp
= Op
->Common
.Parent
;
1128 * Just completed a parameter node for something like "Buffer (param)".
1129 * Close the paren and open up the term list block with a brace.
1131 * Switch predicates don't have a Next node but require a closing paren
1132 * and opening brace.
1134 if (Op
->Common
.Next
|| Op
->Common
.DisasmOpcode
== ACPI_DASM_SWITCH_PREDICATE
)
1136 ASL_CV_CLOSE_PAREN (Op
, Level
);
1139 * Emit a description comment for a Name() operator that is a
1140 * predefined ACPI name. Must check the grandparent.
1142 ParentOp
= ParentOp
->Common
.Parent
;
1144 (ParentOp
->Asl
.AmlOpcode
== AML_NAME_OP
))
1146 AcpiDmPredefinedDescription (ParentOp
);
1149 /* Correct the indentation level for Switch and Case predicates */
1151 if (Op
->Common
.DisasmOpcode
== ACPI_DASM_SWITCH_PREDICATE
)
1156 AcpiOsPrintf ("\n");
1157 AcpiDmIndent (Level
- 1);
1158 AcpiOsPrintf ("{\n");
1162 ParentOp
->Common
.DisasmFlags
|= ACPI_PARSEOP_EMPTY_TERMLIST
;
1163 ASL_CV_CLOSE_PAREN (Op
, Level
);
1168 if ((Op
->Common
.AmlOpcode
== AML_NAME_OP
) ||
1169 (Op
->Common
.AmlOpcode
== AML_RETURN_OP
))
1175 * For ASL+, check for and emit a C-style symbol. If valid, the
1176 * symbol string has been deferred until after the first operand
1178 if (AcpiGbl_CstyleDisassembly
)
1180 if (Op
->Asl
.OperatorSymbol
)
1182 AcpiOsPrintf ("%s", Op
->Asl
.OperatorSymbol
);
1183 Op
->Asl
.OperatorSymbol
= NULL
;
1190 #endif /* ACPI_DISASSEMBLER */