1 /*******************************************************************************
3 * Module Name: dmopcode - AML disassembler, specific AML opcodes
5 ******************************************************************************/
7 /******************************************************************************
11 * Some or all of this work - Copyright (c) 1999 - 2017, Intel Corp.
12 * All rights reserved.
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
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
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;
37 * The above copyright and patent license is granted only if the following
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.
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
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
72 * 3.4. Intel retains all right, title, and interest in and to the Original
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.
80 * 4. Disclaimer and Export Compliance
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
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
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.
114 *****************************************************************************
116 * Alternatively, you may choose to be licensed under the terms of the
119 * Redistribution and use in source and binary forms, with or without
120 * modification, are permitted provided that the following conditions
122 * 1. Redistributions of source code must retain the above copyright
123 * notice, this list of conditions, and the following disclaimer,
124 * without modification.
125 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126 * substantially similar to the "NO WARRANTY" disclaimer below
127 * ("Disclaimer") and any redistribution must be conditioned upon
128 * including a substantially similar Disclaimer requirement for further
129 * binary redistribution.
130 * 3. Neither the names of the above-listed copyright holders nor the names
131 * of any contributors may be used to endorse or promote products derived
132 * from this software without specific prior written permission.
134 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
146 * Alternatively, you may choose to be licensed under the terms of the
147 * GNU General Public License ("GPL") version 2 as published by the Free
148 * Software Foundation.
150 *****************************************************************************/
152 #include <contrib/dev/acpica/include/acpi.h>
153 #include <contrib/dev/acpica/include/accommon.h>
154 #include <contrib/dev/acpica/include/acparser.h>
155 #include <contrib/dev/acpica/include/amlcode.h>
156 #include <contrib/dev/acpica/include/acinterp.h>
157 #include <contrib/dev/acpica/include/acnamesp.h>
158 #include <contrib/dev/acpica/include/acdebug.h>
159 #include <contrib/dev/acpica/include/acconvert.h>
162 #define _COMPONENT ACPI_CA_DEBUGGER
163 ACPI_MODULE_NAME ("dmopcode")
166 /* Local prototypes */
170 ACPI_PARSE_OBJECT *Op);
173 AcpiDmConvertToElseIf (
174 ACPI_PARSE_OBJECT *Op);
177 AcpiDmPromoteSubtree (
178 ACPI_PARSE_OBJECT *StartOp);
180 /*******************************************************************************
182 * FUNCTION: AcpiDmDisplayTargetPathname
184 * PARAMETERS: Op - Parse object
188 * DESCRIPTION: For AML opcodes that have a target operand, display the full
189 * pathname for the target, in a comment field. Handles Return()
192 ******************************************************************************/
195 AcpiDmDisplayTargetPathname (
196 ACPI_PARSE_OBJECT *Op)
198 ACPI_PARSE_OBJECT *NextOp;
199 ACPI_PARSE_OBJECT *PrevOp = NULL;
201 const ACPI_OPCODE_INFO *OpInfo;
204 if (Op->Common.AmlOpcode == AML_RETURN_OP)
206 PrevOp = Op->Asl.Value.Arg;
210 OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
211 if (!(OpInfo->Flags & AML_HAS_TARGET))
216 /* Target is the last Op in the arg list */
218 NextOp = Op->Asl.Value.Arg;
222 NextOp = PrevOp->Asl.Next;
231 /* We must have a namepath AML opcode */
233 if (PrevOp->Asl.AmlOpcode != AML_INT_NAMEPATH_OP)
238 /* A null string is the "no target specified" case */
240 if (!PrevOp->Asl.Value.String)
245 /* No node means "unresolved external reference" */
247 if (!PrevOp->Asl.Node)
249 AcpiOsPrintf (" /* External reference */");
253 /* Ignore if path is already from the root */
255 if (*PrevOp->Asl.Value.String == '\\')
260 /* Now: we can get the full pathname */
262 Pathname = AcpiNsGetExternalPathname (PrevOp->Asl.Node);
268 AcpiOsPrintf (" /* %s */", Pathname);
269 ACPI_FREE (Pathname);
273 /*******************************************************************************
275 * FUNCTION: AcpiDmNotifyDescription
277 * PARAMETERS: Op - Name() parse object
281 * DESCRIPTION: Emit a description comment for the value associated with a
284 ******************************************************************************/
287 AcpiDmNotifyDescription (
288 ACPI_PARSE_OBJECT *Op)
290 ACPI_PARSE_OBJECT *NextOp;
291 ACPI_NAMESPACE_NODE *Node;
293 UINT8 Type = ACPI_TYPE_ANY;
296 /* The notify value is the second argument */
298 NextOp = Op->Asl.Value.Arg;
299 NextOp = NextOp->Asl.Next;
301 switch (NextOp->Common.AmlOpcode)
306 NotifyValue = (UINT8) NextOp->Common.AmlOpcode;
311 NotifyValue = (UINT8) NextOp->Asl.Value.Integer;
319 * Attempt to get the namespace node so we can determine the object type.
320 * Some notify values are dependent on the object type (Device, Thermal,
329 AcpiOsPrintf (" // %s", AcpiUtGetNotifyName (NotifyValue, Type));
333 /*******************************************************************************
335 * FUNCTION: AcpiDmPredefinedDescription
337 * PARAMETERS: Op - Name() parse object
341 * DESCRIPTION: Emit a description comment for a predefined ACPI name.
342 * Used for iASL compiler only.
344 ******************************************************************************/
347 AcpiDmPredefinedDescription (
348 ACPI_PARSE_OBJECT *Op)
350 #ifdef ACPI_ASL_COMPILER
351 const AH_PREDEFINED_NAME *Info;
362 /* Ensure that the comment field is emitted only once */
364 if (Op->Common.DisasmFlags & ACPI_PARSEOP_PREDEFINED_CHECKED)
368 Op->Common.DisasmFlags |= ACPI_PARSEOP_PREDEFINED_CHECKED;
370 /* Predefined name must start with an underscore */
372 NameString = ACPI_CAST_PTR (char, &Op->Named.Name);
373 if (NameString[0] != '_')
379 * Check for the special ACPI names:
380 * _ACd, _ALd, _EJd, _Exx, _Lxx, _Qxx, _Wxx, _T_a
381 * (where d=decimal_digit, x=hex_digit, a=anything)
383 * Convert these to the generic name for table lookup.
384 * Note: NameString is guaranteed to be upper case here.
387 (isdigit ((int) NameString[3])); /* d */
389 (isxdigit ((int) NameString[2]) && /* xx */
390 isxdigit ((int) NameString[3]));
392 switch (NameString[1])
396 if ((NameString[2] == 'C') && (LastCharIsDigit))
400 else if ((NameString[2] == 'L') && (LastCharIsDigit))
408 if ((NameString[2] == 'J') && (LastCharIsDigit))
412 else if (LastCharsAreHex)
436 if (NameString[2] == '_')
455 /* Match the name in the info table */
457 Info = AcpiAhMatchPredefinedName (NameString);
460 AcpiOsPrintf (" // %4.4s: %s",
461 NameString, ACPI_CAST_PTR (char, Info->Description));
469 /*******************************************************************************
471 * FUNCTION: AcpiDmFieldPredefinedDescription
473 * PARAMETERS: Op - Parse object
477 * DESCRIPTION: Emit a description comment for a resource descriptor tag
478 * (which is a predefined ACPI name.) Used for iASL compiler only.
480 ******************************************************************************/
483 AcpiDmFieldPredefinedDescription (
484 ACPI_PARSE_OBJECT *Op)
486 #ifdef ACPI_ASL_COMPILER
487 ACPI_PARSE_OBJECT *IndexOp;
489 const ACPI_OPCODE_INFO *OpInfo;
490 const AH_PREDEFINED_NAME *Info;
498 /* Ensure that the comment field is emitted only once */
500 if (Op->Common.DisasmFlags & ACPI_PARSEOP_PREDEFINED_CHECKED)
504 Op->Common.DisasmFlags |= ACPI_PARSEOP_PREDEFINED_CHECKED;
507 * Op must be one of the Create* operators: CreateField, CreateBitField,
508 * CreateByteField, CreateWordField, CreateDwordField, CreateQwordField
510 OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
511 if (!(OpInfo->Flags & AML_CREATE))
516 /* Second argument is the Index argument */
518 IndexOp = Op->Common.Value.Arg;
519 IndexOp = IndexOp->Common.Next;
521 /* Index argument must be a namepath */
523 if (IndexOp->Common.AmlOpcode != AML_INT_NAMEPATH_OP)
528 /* Major cheat: We previously put the Tag ptr in the Node field */
530 Tag = ACPI_CAST_PTR (char, IndexOp->Common.Node);
536 /* Match the name in the info table */
538 Info = AcpiAhMatchPredefinedName (Tag);
541 AcpiOsPrintf (" // %4.4s: %s", Tag,
542 ACPI_CAST_PTR (char, Info->Description));
545 /* AML buffer (String) was allocated in AcpiGetTagPathname */
547 ACPI_FREE (IndexOp->Common.Value.String);
554 /*******************************************************************************
556 * FUNCTION: AcpiDmMethodFlags
558 * PARAMETERS: Op - Method Object to be examined
562 * DESCRIPTION: Decode control method flags
564 ******************************************************************************/
568 ACPI_PARSE_OBJECT *Op)
574 /* The next Op contains the flags */
576 Op = AcpiPsGetDepthNext (NULL, Op);
577 Flags = (UINT8) Op->Common.Value.Integer;
580 /* Mark the Op as completed */
582 Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
584 /* 1) Method argument count */
586 AcpiOsPrintf (", %u, ", Args);
588 /* 2) Serialize rule */
592 AcpiOsPrintf ("Not");
595 AcpiOsPrintf ("Serialized");
601 AcpiOsPrintf (", %u", Flags >> 4);
606 /*******************************************************************************
608 * FUNCTION: AcpiDmFieldFlags
610 * PARAMETERS: Op - Field Object to be examined
614 * DESCRIPTION: Decode Field definition flags
616 ******************************************************************************/
620 ACPI_PARSE_OBJECT *Op)
625 Op = Op->Common.Next;
626 Flags = (UINT8) Op->Common.Value.Integer;
628 /* Mark the Op as completed */
630 Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
632 AcpiOsPrintf ("%s, ", AcpiGbl_AccessTypes [Flags & 0x07]);
633 AcpiOsPrintf ("%s, ", AcpiGbl_LockRule [(Flags & 0x10) >> 4]);
634 AcpiOsPrintf ("%s)", AcpiGbl_UpdateRules [(Flags & 0x60) >> 5]);
638 /*******************************************************************************
640 * FUNCTION: AcpiDmAddressSpace
642 * PARAMETERS: SpaceId - ID to be translated
646 * DESCRIPTION: Decode a SpaceId to an AddressSpaceKeyword
648 ******************************************************************************/
655 if (SpaceId >= ACPI_NUM_PREDEFINED_REGIONS)
659 AcpiOsPrintf ("FFixedHW, ");
663 AcpiOsPrintf ("0x%.2X, ", SpaceId);
668 AcpiOsPrintf ("%s, ", AcpiGbl_RegionTypes [SpaceId]);
673 /*******************************************************************************
675 * FUNCTION: AcpiDmRegionFlags
677 * PARAMETERS: Op - Object to be examined
681 * DESCRIPTION: Decode OperationRegion flags
683 ******************************************************************************/
687 ACPI_PARSE_OBJECT *Op)
690 /* The next Op contains the SpaceId */
692 Op = AcpiPsGetDepthNext (NULL, Op);
694 /* Mark the Op as completed */
696 Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
699 AcpiDmAddressSpace ((UINT8) Op->Common.Value.Integer);
703 /*******************************************************************************
705 * FUNCTION: AcpiDmMatchOp
707 * PARAMETERS: Op - Match Object to be examined
711 * DESCRIPTION: Decode Match opcode operands
713 ******************************************************************************/
717 ACPI_PARSE_OBJECT *Op)
719 ACPI_PARSE_OBJECT *NextOp;
722 NextOp = AcpiPsGetDepthNext (NULL, Op);
723 NextOp = NextOp->Common.Next;
727 /* Handle partial tree during single-step */
732 /* Mark the two nodes that contain the encoding for the match keywords */
734 NextOp->Common.DisasmOpcode = ACPI_DASM_MATCHOP;
736 NextOp = NextOp->Common.Next;
737 NextOp = NextOp->Common.Next;
738 NextOp->Common.DisasmOpcode = ACPI_DASM_MATCHOP;
742 /*******************************************************************************
744 * FUNCTION: AcpiDmMatchKeyword
746 * PARAMETERS: Op - Match Object to be examined
750 * DESCRIPTION: Decode Match opcode operands
752 ******************************************************************************/
756 ACPI_PARSE_OBJECT *Op)
759 if (((UINT32) Op->Common.Value.Integer) > ACPI_MAX_MATCH_OPCODE)
761 AcpiOsPrintf ("/* Unknown Match Keyword encoding */");
766 AcpiGbl_MatchOps[(ACPI_SIZE) Op->Common.Value.Integer]);
771 /*******************************************************************************
773 * FUNCTION: AcpiDmDisassembleOneOp
775 * PARAMETERS: WalkState - Current walk info
776 * Info - Parse tree walk info
777 * Op - Op that is to be printed
781 * DESCRIPTION: Disassemble a single AML opcode
783 ******************************************************************************/
786 AcpiDmDisassembleOneOp (
787 ACPI_WALK_STATE *WalkState,
788 ACPI_OP_WALK_INFO *Info,
789 ACPI_PARSE_OBJECT *Op)
791 const ACPI_OPCODE_INFO *OpInfo = NULL;
794 ACPI_PARSE_OBJECT *Child;
797 const AH_DEVICE_ID *IdInfo;
802 AcpiOsPrintf ("<NULL OP PTR>");
806 if (Op->Common.DisasmFlags & ACPI_PARSEOP_ELSEIF)
808 return; /* ElseIf macro was already emitted */
811 switch (Op->Common.DisasmOpcode)
813 case ACPI_DASM_MATCHOP:
815 AcpiDmMatchKeyword (Op);
818 case ACPI_DASM_LNOT_SUFFIX:
820 if (!AcpiGbl_CstyleDisassembly)
822 switch (Op->Common.AmlOpcode)
824 case AML_LOGICAL_EQUAL_OP:
825 AcpiOsPrintf ("LNotEqual");
828 case AML_LOGICAL_GREATER_OP:
829 AcpiOsPrintf ("LLessEqual");
832 case AML_LOGICAL_LESS_OP:
833 AcpiOsPrintf ("LGreaterEqual");
841 Op->Common.DisasmOpcode = 0;
842 Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
849 OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
851 /* The op and arguments */
853 switch (Op->Common.AmlOpcode)
855 case AML_LOGICAL_NOT_OP:
857 Child = Op->Common.Value.Arg;
858 if ((Child->Common.AmlOpcode == AML_LOGICAL_EQUAL_OP) ||
859 (Child->Common.AmlOpcode == AML_LOGICAL_GREATER_OP) ||
860 (Child->Common.AmlOpcode == AML_LOGICAL_LESS_OP))
862 Child->Common.DisasmOpcode = ACPI_DASM_LNOT_SUFFIX;
863 Op->Common.DisasmOpcode = ACPI_DASM_LNOT_PREFIX;
867 AcpiOsPrintf ("%s", OpInfo->Name);
873 AcpiOsPrintf ("0x%2.2X", (UINT32) Op->Common.Value.Integer);
878 if (Op->Common.DisasmOpcode == ACPI_DASM_EISAID)
880 AcpiDmDecompressEisaId ((UINT32) Op->Common.Value.Integer);
884 AcpiOsPrintf ("0x%4.4X", (UINT32) Op->Common.Value.Integer);
890 if (Op->Common.DisasmOpcode == ACPI_DASM_EISAID)
892 AcpiDmDecompressEisaId ((UINT32) Op->Common.Value.Integer);
896 AcpiOsPrintf ("0x%8.8X", (UINT32) Op->Common.Value.Integer);
902 AcpiOsPrintf ("0x%8.8X%8.8X",
903 ACPI_FORMAT_UINT64 (Op->Common.Value.Integer));
908 AcpiUtPrintString (Op->Common.Value.String, ACPI_UINT16_MAX);
910 /* For _HID/_CID strings, attempt to output a descriptive comment */
912 if (Op->Common.DisasmOpcode == ACPI_DASM_HID_STRING)
914 /* If we know about the ID, emit the description */
916 IdInfo = AcpiAhMatchHardwareId (Op->Common.Value.String);
919 AcpiOsPrintf (" /* %s */", IdInfo->Description);
926 * Determine the type of buffer. We can have one of the following:
928 * 1) ResourceTemplate containing Resource Descriptors.
929 * 2) Unicode String buffer
930 * 3) ASCII String buffer
931 * 4) Raw data buffer (if none of the above)
933 * Since there are no special AML opcodes to differentiate these
934 * types of buffers, we have to closely look at the data in the
935 * buffer to determine the type.
937 if (!AcpiGbl_NoResourceDisassembly)
939 Status = AcpiDmIsResourceTemplate (WalkState, Op);
940 if (ACPI_SUCCESS (Status))
942 Op->Common.DisasmOpcode = ACPI_DASM_RESOURCE;
943 AcpiOsPrintf ("ResourceTemplate");
946 else if (Status == AE_AML_NO_RESOURCE_END_TAG)
949 "/**** Is ResourceTemplate, "
950 "but EndTag not at buffer end ****/ ");
954 if (AcpiDmIsUuidBuffer (Op))
956 Op->Common.DisasmOpcode = ACPI_DASM_UUID;
957 AcpiOsPrintf ("ToUUID (");
959 else if (AcpiDmIsUnicodeBuffer (Op))
961 Op->Common.DisasmOpcode = ACPI_DASM_UNICODE;
962 AcpiOsPrintf ("Unicode (");
964 else if (AcpiDmIsStringBuffer (Op))
966 Op->Common.DisasmOpcode = ACPI_DASM_STRING;
967 AcpiOsPrintf ("Buffer");
969 else if (AcpiDmIsPldBuffer (Op))
971 Op->Common.DisasmOpcode = ACPI_DASM_PLD_METHOD;
972 AcpiOsPrintf ("ToPLD (");
976 Op->Common.DisasmOpcode = ACPI_DASM_BUFFER;
977 AcpiOsPrintf ("Buffer");
981 case AML_INT_NAMEPATH_OP:
983 AcpiDmNamestring (Op->Common.Value.Name);
986 case AML_INT_NAMEDFIELD_OP:
988 Length = AcpiDmDumpName (Op->Named.Name);
991 ASL_CV_PRINT_ONE_COMMENT (Op, AML_NAMECOMMENT, NULL, 0);
992 AcpiOsPrintf ("%*.s %u", (unsigned) (5 - Length), " ",
993 (UINT32) Op->Common.Value.Integer);
995 AcpiDmCommaIfFieldMember (Op);
997 Info->BitOffset += (UINT32) Op->Common.Value.Integer;
1000 case AML_INT_RESERVEDFIELD_OP:
1002 /* Offset() -- Must account for previous offsets */
1004 Offset = (UINT32) Op->Common.Value.Integer;
1005 Info->BitOffset += Offset;
1007 if (Info->BitOffset % 8 == 0)
1009 AcpiOsPrintf ("Offset (0x%.2X)", ACPI_DIV_8 (Info->BitOffset));
1013 AcpiOsPrintf (" , %u", Offset);
1016 AcpiDmCommaIfFieldMember (Op);
1019 case AML_INT_ACCESSFIELD_OP:
1020 case AML_INT_EXTACCESSFIELD_OP:
1022 AcpiOsPrintf ("AccessAs (%s, ",
1023 AcpiGbl_AccessTypes [(UINT32) (Op->Common.Value.Integer & 0x7)]);
1025 AcpiDmDecodeAttribute ((UINT8) (Op->Common.Value.Integer >> 8));
1027 if (Op->Common.AmlOpcode == AML_INT_EXTACCESSFIELD_OP)
1029 AcpiOsPrintf (" (0x%2.2X)", (unsigned)
1030 ((Op->Common.Value.Integer >> 16) & 0xFF));
1034 AcpiDmCommaIfFieldMember (Op);
1035 ASL_CV_PRINT_ONE_COMMENT (Op, AML_COMMENT_END_NODE, NULL, 0);
1038 case AML_INT_CONNECTION_OP:
1040 * Two types of Connection() - one with a buffer object, the
1041 * other with a namestring that points to a buffer object.
1043 AcpiOsPrintf ("Connection (");
1044 Child = Op->Common.Value.Arg;
1046 if (Child->Common.AmlOpcode == AML_INT_BYTELIST_OP)
1048 AcpiOsPrintf ("\n");
1050 Aml = Child->Named.Data;
1051 Length = (UINT32) Child->Common.Value.Integer;
1054 Info->MappingOp = Op;
1055 Op->Common.DisasmOpcode = ACPI_DASM_RESOURCE;
1057 AcpiDmResourceTemplate (Info, Op->Common.Parent, Aml, Length);
1060 AcpiDmIndent (Info->Level);
1064 AcpiDmNamestring (Child->Common.Value.Name);
1068 AcpiDmCommaIfFieldMember (Op);
1069 ASL_CV_PRINT_ONE_COMMENT (Op, AML_COMMENT_END_NODE, NULL, 0);
1070 ASL_CV_PRINT_ONE_COMMENT (Op, AMLCOMMENT_INLINE, NULL, 0);
1071 AcpiOsPrintf ("\n");
1073 Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; /* for now, ignore in AcpiDmAscendingOp */
1074 Child->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
1077 case AML_INT_BYTELIST_OP:
1079 AcpiDmByteList (Info, Op);
1082 case AML_INT_METHODCALL_OP:
1084 Op = AcpiPsGetDepthNext (NULL, Op);
1085 Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
1087 AcpiDmNamestring (Op->Common.Value.Name);
1092 if (Op->Common.DisasmOpcode == ACPI_DASM_SWITCH)
1094 AcpiOsPrintf ("%s", "Switch");
1098 AcpiOsPrintf ("%s", OpInfo->Name);
1103 if (Op->Common.DisasmOpcode == ACPI_DASM_CASE)
1105 AcpiOsPrintf ("%s", "Case");
1109 AcpiOsPrintf ("%s", OpInfo->Name);
1114 AcpiDmConvertToElseIf (Op);
1117 case AML_EXTERNAL_OP:
1119 if (AcpiGbl_DmEmitExternalOpcodes)
1121 AcpiDmEmitExternal (Op, AcpiPsGetArg(Op, 0));
1128 /* Just get the opcode name and print it */
1130 AcpiOsPrintf ("%s", OpInfo->Name);
1133 #ifdef ACPI_DEBUGGER
1135 if ((Op->Common.AmlOpcode == AML_INT_RETURN_VALUE_OP) &&
1137 (WalkState->Results) &&
1138 (WalkState->ResultCount))
1140 AcpiDbDecodeInternalObject (
1141 WalkState->Results->Results.ObjDesc [
1142 (WalkState->ResultCount - 1) %
1143 ACPI_RESULTS_FRAME_OBJ_NUM]);
1152 /*******************************************************************************
1154 * FUNCTION: AcpiDmConvertToElseIf
1156 * PARAMETERS: OriginalElseOp - ELSE Object to be examined
1158 * RETURN: None. Emits either an "Else" or an "ElseIf" ASL operator.
1160 * DESCRIPTION: Detect and convert an If..Else..If sequence to If..ElseIf
1164 * This If..Else..If nested sequence:
1178 * Is converted to this simpler If..ElseIf sequence:
1184 * ElseIf (Arg0 == 2)
1189 * NOTE: There is no actual ElseIf AML opcode. ElseIf is essentially an ASL
1190 * macro that emits an Else opcode followed by an If opcode. This function
1191 * reverses these AML sequences back to an ElseIf macro where possible. This
1192 * can make the disassembled ASL code simpler and more like the original code.
1194 ******************************************************************************/
1197 AcpiDmConvertToElseIf (
1198 ACPI_PARSE_OBJECT *OriginalElseOp)
1200 ACPI_PARSE_OBJECT *IfOp;
1201 ACPI_PARSE_OBJECT *ElseOp;
1205 * To be able to perform the conversion, two conditions must be satisfied:
1206 * 1) The first child of the Else must be an If statement.
1207 * 2) The If block can only be followed by an Else block and these must
1208 * be the only blocks under the original Else.
1210 IfOp = OriginalElseOp->Common.Value.Arg;
1213 (IfOp->Common.AmlOpcode != AML_IF_OP) ||
1214 (IfOp->Asl.Next && (IfOp->Asl.Next->Common.AmlOpcode != AML_ELSE_OP)))
1216 /* Not a proper Else..If sequence, cannot convert to ElseIf */
1218 if (OriginalElseOp->Common.DisasmOpcode == ACPI_DASM_DEFAULT)
1220 AcpiOsPrintf ("%s", "Default");
1224 AcpiOsPrintf ("%s", "Else");
1228 /* Cannot have anything following the If...Else block */
1230 ElseOp = IfOp->Common.Next;
1231 if (ElseOp && ElseOp->Common.Next)
1233 if (OriginalElseOp->Common.DisasmOpcode == ACPI_DASM_DEFAULT)
1235 AcpiOsPrintf ("%s", "Default");
1239 AcpiOsPrintf ("%s", "Else");
1243 if (OriginalElseOp->Common.DisasmOpcode == ACPI_DASM_DEFAULT)
1246 * There is an ElseIf but in this case the Else is actually
1247 * a Default block for a Switch/Case statement. No conversion.
1249 AcpiOsPrintf ("%s", "Default");
1253 if (OriginalElseOp->Common.DisasmOpcode == ACPI_DASM_CASE)
1256 * This ElseIf is actually a Case block for a Switch/Case
1257 * statement. Print Case but do not return so that we can
1258 * promote the subtree and keep the indentation level.
1260 AcpiOsPrintf ("%s", "Case");
1264 /* Emit ElseIf, mark the IF as now an ELSEIF */
1266 AcpiOsPrintf ("%s", "ElseIf");
1269 IfOp->Common.DisasmFlags |= ACPI_PARSEOP_ELSEIF;
1271 /* The IF parent will now be the same as the original ELSE parent */
1273 IfOp->Common.Parent = OriginalElseOp->Common.Parent;
1276 * Update the NEXT pointers to restructure the parse tree, essentially
1277 * promoting an If..Else block up to the same level as the original
1280 * Check if the IF has a corresponding ELSE peer
1282 ElseOp = IfOp->Common.Next;
1284 (ElseOp->Common.AmlOpcode == AML_ELSE_OP))
1286 /* If an ELSE matches the IF, promote it also */
1288 ElseOp->Common.Parent = OriginalElseOp->Common.Parent;
1290 /* Promote the entire block under the ElseIf (All Next OPs) */
1292 AcpiDmPromoteSubtree (OriginalElseOp);
1296 /* Otherwise, set the IF NEXT to the original ELSE NEXT */
1298 IfOp->Common.Next = OriginalElseOp->Common.Next;
1301 /* Detach the child IF block from the original ELSE */
1303 OriginalElseOp->Common.Value.Arg = NULL;
1305 /* Ignore the original ELSE from now on */
1307 OriginalElseOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
1308 OriginalElseOp->Common.DisasmOpcode = ACPI_DASM_LNOT_PREFIX;
1310 /* Insert IF (now ELSEIF) as next peer of the original ELSE */
1312 OriginalElseOp->Common.Next = IfOp;
1316 /*******************************************************************************
1318 * FUNCTION: AcpiDmPromoteSubtree
1320 * PARAMETERS: StartOpOp - Original parent of the entire subtree
1324 * DESCRIPTION: Promote an entire parse subtree up one level.
1326 ******************************************************************************/
1329 AcpiDmPromoteSubtree (
1330 ACPI_PARSE_OBJECT *StartOp)
1332 ACPI_PARSE_OBJECT *Op;
1333 ACPI_PARSE_OBJECT *ParentOp;
1336 /* New parent for subtree elements */
1338 ParentOp = StartOp->Common.Parent;
1340 /* First child starts the subtree */
1342 Op = StartOp->Common.Value.Arg;
1344 /* Walk the top-level elements of the subtree */
1348 Op->Common.Parent = ParentOp;
1349 if (!Op->Common.Next)
1351 /* Last Op in list, update its next field */
1353 Op->Common.Next = StartOp->Common.Next;
1356 Op = Op->Common.Next;