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);
531 if (!Tag || (*Tag == 0))
536 /* Is the tag a predefined name? */
538 Info = AcpiAhMatchPredefinedName (Tag);
541 /* Not a predefined name (does not start with underscore) */
546 AcpiOsPrintf (" // %4.4s: %s", Tag,
547 ACPI_CAST_PTR (char, Info->Description));
549 /* String contains the prefix path, free it */
551 ACPI_FREE (IndexOp->Common.Value.String);
552 IndexOp->Common.Value.String = NULL;
559 /*******************************************************************************
561 * FUNCTION: AcpiDmMethodFlags
563 * PARAMETERS: Op - Method Object to be examined
567 * DESCRIPTION: Decode control method flags
569 ******************************************************************************/
573 ACPI_PARSE_OBJECT *Op)
579 /* The next Op contains the flags */
581 Op = AcpiPsGetDepthNext (NULL, Op);
582 Flags = (UINT8) Op->Common.Value.Integer;
585 /* Mark the Op as completed */
587 Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
589 /* 1) Method argument count */
591 AcpiOsPrintf (", %u, ", Args);
593 /* 2) Serialize rule */
597 AcpiOsPrintf ("Not");
600 AcpiOsPrintf ("Serialized");
606 AcpiOsPrintf (", %u", Flags >> 4);
611 /*******************************************************************************
613 * FUNCTION: AcpiDmFieldFlags
615 * PARAMETERS: Op - Field Object to be examined
619 * DESCRIPTION: Decode Field definition flags
621 ******************************************************************************/
625 ACPI_PARSE_OBJECT *Op)
630 Op = Op->Common.Next;
631 Flags = (UINT8) Op->Common.Value.Integer;
633 /* Mark the Op as completed */
635 Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
637 AcpiOsPrintf ("%s, ", AcpiGbl_AccessTypes [Flags & 0x07]);
638 AcpiOsPrintf ("%s, ", AcpiGbl_LockRule [(Flags & 0x10) >> 4]);
639 AcpiOsPrintf ("%s)", AcpiGbl_UpdateRules [(Flags & 0x60) >> 5]);
643 /*******************************************************************************
645 * FUNCTION: AcpiDmAddressSpace
647 * PARAMETERS: SpaceId - ID to be translated
651 * DESCRIPTION: Decode a SpaceId to an AddressSpaceKeyword
653 ******************************************************************************/
660 if (SpaceId >= ACPI_NUM_PREDEFINED_REGIONS)
664 AcpiOsPrintf ("FFixedHW, ");
668 AcpiOsPrintf ("0x%.2X, ", SpaceId);
673 AcpiOsPrintf ("%s, ", AcpiGbl_RegionTypes [SpaceId]);
678 /*******************************************************************************
680 * FUNCTION: AcpiDmRegionFlags
682 * PARAMETERS: Op - Object to be examined
686 * DESCRIPTION: Decode OperationRegion flags
688 ******************************************************************************/
692 ACPI_PARSE_OBJECT *Op)
695 /* The next Op contains the SpaceId */
697 Op = AcpiPsGetDepthNext (NULL, Op);
699 /* Mark the Op as completed */
701 Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
704 AcpiDmAddressSpace ((UINT8) Op->Common.Value.Integer);
708 /*******************************************************************************
710 * FUNCTION: AcpiDmMatchOp
712 * PARAMETERS: Op - Match Object to be examined
716 * DESCRIPTION: Decode Match opcode operands
718 ******************************************************************************/
722 ACPI_PARSE_OBJECT *Op)
724 ACPI_PARSE_OBJECT *NextOp;
727 NextOp = AcpiPsGetDepthNext (NULL, Op);
728 NextOp = NextOp->Common.Next;
732 /* Handle partial tree during single-step */
737 /* Mark the two nodes that contain the encoding for the match keywords */
739 NextOp->Common.DisasmOpcode = ACPI_DASM_MATCHOP;
741 NextOp = NextOp->Common.Next;
742 NextOp = NextOp->Common.Next;
743 NextOp->Common.DisasmOpcode = ACPI_DASM_MATCHOP;
747 /*******************************************************************************
749 * FUNCTION: AcpiDmMatchKeyword
751 * PARAMETERS: Op - Match Object to be examined
755 * DESCRIPTION: Decode Match opcode operands
757 ******************************************************************************/
761 ACPI_PARSE_OBJECT *Op)
764 if (((UINT32) Op->Common.Value.Integer) > ACPI_MAX_MATCH_OPCODE)
766 AcpiOsPrintf ("/* Unknown Match Keyword encoding */");
771 AcpiGbl_MatchOps[(ACPI_SIZE) Op->Common.Value.Integer]);
776 /*******************************************************************************
778 * FUNCTION: AcpiDmDisassembleOneOp
780 * PARAMETERS: WalkState - Current walk info
781 * Info - Parse tree walk info
782 * Op - Op that is to be printed
786 * DESCRIPTION: Disassemble a single AML opcode
788 ******************************************************************************/
791 AcpiDmDisassembleOneOp (
792 ACPI_WALK_STATE *WalkState,
793 ACPI_OP_WALK_INFO *Info,
794 ACPI_PARSE_OBJECT *Op)
796 const ACPI_OPCODE_INFO *OpInfo = NULL;
799 ACPI_PARSE_OBJECT *Child;
802 const AH_DEVICE_ID *IdInfo;
807 AcpiOsPrintf ("<NULL OP PTR>");
811 if (Op->Common.DisasmFlags & ACPI_PARSEOP_ELSEIF)
813 return; /* ElseIf macro was already emitted */
816 switch (Op->Common.DisasmOpcode)
818 case ACPI_DASM_MATCHOP:
820 AcpiDmMatchKeyword (Op);
823 case ACPI_DASM_LNOT_SUFFIX:
825 if (!AcpiGbl_CstyleDisassembly)
827 switch (Op->Common.AmlOpcode)
829 case AML_LOGICAL_EQUAL_OP:
830 AcpiOsPrintf ("LNotEqual");
833 case AML_LOGICAL_GREATER_OP:
834 AcpiOsPrintf ("LLessEqual");
837 case AML_LOGICAL_LESS_OP:
838 AcpiOsPrintf ("LGreaterEqual");
846 Op->Common.DisasmOpcode = 0;
847 Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
854 OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
856 /* The op and arguments */
858 switch (Op->Common.AmlOpcode)
860 case AML_LOGICAL_NOT_OP:
862 Child = Op->Common.Value.Arg;
863 if ((Child->Common.AmlOpcode == AML_LOGICAL_EQUAL_OP) ||
864 (Child->Common.AmlOpcode == AML_LOGICAL_GREATER_OP) ||
865 (Child->Common.AmlOpcode == AML_LOGICAL_LESS_OP))
867 Child->Common.DisasmOpcode = ACPI_DASM_LNOT_SUFFIX;
868 Op->Common.DisasmOpcode = ACPI_DASM_LNOT_PREFIX;
872 AcpiOsPrintf ("%s", OpInfo->Name);
878 AcpiOsPrintf ("0x%2.2X", (UINT32) Op->Common.Value.Integer);
883 if (Op->Common.DisasmOpcode == ACPI_DASM_EISAID)
885 AcpiDmDecompressEisaId ((UINT32) Op->Common.Value.Integer);
889 AcpiOsPrintf ("0x%4.4X", (UINT32) Op->Common.Value.Integer);
895 if (Op->Common.DisasmOpcode == ACPI_DASM_EISAID)
897 AcpiDmDecompressEisaId ((UINT32) Op->Common.Value.Integer);
901 AcpiOsPrintf ("0x%8.8X", (UINT32) Op->Common.Value.Integer);
907 AcpiOsPrintf ("0x%8.8X%8.8X",
908 ACPI_FORMAT_UINT64 (Op->Common.Value.Integer));
913 AcpiUtPrintString (Op->Common.Value.String, ACPI_UINT16_MAX);
915 /* For _HID/_CID strings, attempt to output a descriptive comment */
917 if (Op->Common.DisasmOpcode == ACPI_DASM_HID_STRING)
919 /* If we know about the ID, emit the description */
921 IdInfo = AcpiAhMatchHardwareId (Op->Common.Value.String);
924 AcpiOsPrintf (" /* %s */", IdInfo->Description);
931 * Determine the type of buffer. We can have one of the following:
933 * 1) ResourceTemplate containing Resource Descriptors.
934 * 2) Unicode String buffer
935 * 3) ASCII String buffer
936 * 4) Raw data buffer (if none of the above)
938 * Since there are no special AML opcodes to differentiate these
939 * types of buffers, we have to closely look at the data in the
940 * buffer to determine the type.
942 if (!AcpiGbl_NoResourceDisassembly)
944 Status = AcpiDmIsResourceTemplate (WalkState, Op);
945 if (ACPI_SUCCESS (Status))
947 Op->Common.DisasmOpcode = ACPI_DASM_RESOURCE;
948 AcpiOsPrintf ("ResourceTemplate");
951 else if (Status == AE_AML_NO_RESOURCE_END_TAG)
954 "/**** Is ResourceTemplate, "
955 "but EndTag not at buffer end ****/ ");
959 if (AcpiDmIsUuidBuffer (Op))
961 Op->Common.DisasmOpcode = ACPI_DASM_UUID;
962 AcpiOsPrintf ("ToUUID (");
964 else if (AcpiDmIsUnicodeBuffer (Op))
966 Op->Common.DisasmOpcode = ACPI_DASM_UNICODE;
967 AcpiOsPrintf ("Unicode (");
969 else if (AcpiDmIsStringBuffer (Op))
971 Op->Common.DisasmOpcode = ACPI_DASM_STRING;
972 AcpiOsPrintf ("Buffer");
974 else if (AcpiDmIsPldBuffer (Op))
976 Op->Common.DisasmOpcode = ACPI_DASM_PLD_METHOD;
977 AcpiOsPrintf ("ToPLD (");
981 Op->Common.DisasmOpcode = ACPI_DASM_BUFFER;
982 AcpiOsPrintf ("Buffer");
986 case AML_INT_NAMEPATH_OP:
988 AcpiDmNamestring (Op->Common.Value.Name);
991 case AML_INT_NAMEDFIELD_OP:
993 Length = AcpiDmDumpName (Op->Named.Name);
996 ASL_CV_PRINT_ONE_COMMENT (Op, AML_NAMECOMMENT, NULL, 0);
997 AcpiOsPrintf ("%*.s %u", (unsigned) (5 - Length), " ",
998 (UINT32) Op->Common.Value.Integer);
1000 AcpiDmCommaIfFieldMember (Op);
1002 Info->BitOffset += (UINT32) Op->Common.Value.Integer;
1005 case AML_INT_RESERVEDFIELD_OP:
1007 /* Offset() -- Must account for previous offsets */
1009 Offset = (UINT32) Op->Common.Value.Integer;
1010 Info->BitOffset += Offset;
1012 if (Info->BitOffset % 8 == 0)
1014 AcpiOsPrintf ("Offset (0x%.2X)", ACPI_DIV_8 (Info->BitOffset));
1018 AcpiOsPrintf (" , %u", Offset);
1021 AcpiDmCommaIfFieldMember (Op);
1024 case AML_INT_ACCESSFIELD_OP:
1025 case AML_INT_EXTACCESSFIELD_OP:
1027 AcpiOsPrintf ("AccessAs (%s, ",
1028 AcpiGbl_AccessTypes [(UINT32) (Op->Common.Value.Integer & 0x7)]);
1030 AcpiDmDecodeAttribute ((UINT8) (Op->Common.Value.Integer >> 8));
1032 if (Op->Common.AmlOpcode == AML_INT_EXTACCESSFIELD_OP)
1034 AcpiOsPrintf (" (0x%2.2X)", (unsigned)
1035 ((Op->Common.Value.Integer >> 16) & 0xFF));
1039 AcpiDmCommaIfFieldMember (Op);
1040 ASL_CV_PRINT_ONE_COMMENT (Op, AML_COMMENT_END_NODE, NULL, 0);
1043 case AML_INT_CONNECTION_OP:
1045 * Two types of Connection() - one with a buffer object, the
1046 * other with a namestring that points to a buffer object.
1048 AcpiOsPrintf ("Connection (");
1049 Child = Op->Common.Value.Arg;
1051 if (Child->Common.AmlOpcode == AML_INT_BYTELIST_OP)
1053 AcpiOsPrintf ("\n");
1055 Aml = Child->Named.Data;
1056 Length = (UINT32) Child->Common.Value.Integer;
1059 Info->MappingOp = Op;
1060 Op->Common.DisasmOpcode = ACPI_DASM_RESOURCE;
1062 AcpiDmResourceTemplate (Info, Op->Common.Parent, Aml, Length);
1065 AcpiDmIndent (Info->Level);
1069 AcpiDmNamestring (Child->Common.Value.Name);
1073 AcpiDmCommaIfFieldMember (Op);
1074 ASL_CV_PRINT_ONE_COMMENT (Op, AML_COMMENT_END_NODE, NULL, 0);
1075 ASL_CV_PRINT_ONE_COMMENT (Op, AMLCOMMENT_INLINE, NULL, 0);
1076 AcpiOsPrintf ("\n");
1078 Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; /* for now, ignore in AcpiDmAscendingOp */
1079 Child->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
1082 case AML_INT_BYTELIST_OP:
1084 AcpiDmByteList (Info, Op);
1087 case AML_INT_METHODCALL_OP:
1089 Op = AcpiPsGetDepthNext (NULL, Op);
1090 Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
1092 AcpiDmNamestring (Op->Common.Value.Name);
1097 if (Op->Common.DisasmOpcode == ACPI_DASM_SWITCH)
1099 AcpiOsPrintf ("%s", "Switch");
1103 AcpiOsPrintf ("%s", OpInfo->Name);
1108 if (Op->Common.DisasmOpcode == ACPI_DASM_CASE)
1110 AcpiOsPrintf ("%s", "Case");
1114 AcpiOsPrintf ("%s", OpInfo->Name);
1119 AcpiDmConvertToElseIf (Op);
1122 case AML_EXTERNAL_OP:
1124 if (AcpiGbl_DmEmitExternalOpcodes)
1126 AcpiDmEmitExternal (Op, AcpiPsGetArg(Op, 0));
1133 /* Just get the opcode name and print it */
1135 AcpiOsPrintf ("%s", OpInfo->Name);
1138 #ifdef ACPI_DEBUGGER
1140 if ((Op->Common.AmlOpcode == AML_INT_RETURN_VALUE_OP) &&
1142 (WalkState->Results) &&
1143 (WalkState->ResultCount))
1145 AcpiDbDecodeInternalObject (
1146 WalkState->Results->Results.ObjDesc [
1147 (WalkState->ResultCount - 1) %
1148 ACPI_RESULTS_FRAME_OBJ_NUM]);
1157 /*******************************************************************************
1159 * FUNCTION: AcpiDmConvertToElseIf
1161 * PARAMETERS: OriginalElseOp - ELSE Object to be examined
1163 * RETURN: None. Emits either an "Else" or an "ElseIf" ASL operator.
1165 * DESCRIPTION: Detect and convert an If..Else..If sequence to If..ElseIf
1169 * This If..Else..If nested sequence:
1183 * Is converted to this simpler If..ElseIf sequence:
1189 * ElseIf (Arg0 == 2)
1194 * NOTE: There is no actual ElseIf AML opcode. ElseIf is essentially an ASL
1195 * macro that emits an Else opcode followed by an If opcode. This function
1196 * reverses these AML sequences back to an ElseIf macro where possible. This
1197 * can make the disassembled ASL code simpler and more like the original code.
1199 ******************************************************************************/
1202 AcpiDmConvertToElseIf (
1203 ACPI_PARSE_OBJECT *OriginalElseOp)
1205 ACPI_PARSE_OBJECT *IfOp;
1206 ACPI_PARSE_OBJECT *ElseOp;
1210 * To be able to perform the conversion, two conditions must be satisfied:
1211 * 1) The first child of the Else must be an If statement.
1212 * 2) The If block can only be followed by an Else block and these must
1213 * be the only blocks under the original Else.
1215 IfOp = OriginalElseOp->Common.Value.Arg;
1218 (IfOp->Common.AmlOpcode != AML_IF_OP) ||
1219 (IfOp->Asl.Next && (IfOp->Asl.Next->Common.AmlOpcode != AML_ELSE_OP)))
1221 /* Not a proper Else..If sequence, cannot convert to ElseIf */
1223 if (OriginalElseOp->Common.DisasmOpcode == ACPI_DASM_DEFAULT)
1225 AcpiOsPrintf ("%s", "Default");
1229 AcpiOsPrintf ("%s", "Else");
1233 /* Cannot have anything following the If...Else block */
1235 ElseOp = IfOp->Common.Next;
1236 if (ElseOp && ElseOp->Common.Next)
1238 if (OriginalElseOp->Common.DisasmOpcode == ACPI_DASM_DEFAULT)
1240 AcpiOsPrintf ("%s", "Default");
1244 AcpiOsPrintf ("%s", "Else");
1248 if (OriginalElseOp->Common.DisasmOpcode == ACPI_DASM_DEFAULT)
1251 * There is an ElseIf but in this case the Else is actually
1252 * a Default block for a Switch/Case statement. No conversion.
1254 AcpiOsPrintf ("%s", "Default");
1258 if (OriginalElseOp->Common.DisasmOpcode == ACPI_DASM_CASE)
1261 * This ElseIf is actually a Case block for a Switch/Case
1262 * statement. Print Case but do not return so that we can
1263 * promote the subtree and keep the indentation level.
1265 AcpiOsPrintf ("%s", "Case");
1269 /* Emit ElseIf, mark the IF as now an ELSEIF */
1271 AcpiOsPrintf ("%s", "ElseIf");
1274 IfOp->Common.DisasmFlags |= ACPI_PARSEOP_ELSEIF;
1276 /* The IF parent will now be the same as the original ELSE parent */
1278 IfOp->Common.Parent = OriginalElseOp->Common.Parent;
1281 * Update the NEXT pointers to restructure the parse tree, essentially
1282 * promoting an If..Else block up to the same level as the original
1285 * Check if the IF has a corresponding ELSE peer
1287 ElseOp = IfOp->Common.Next;
1289 (ElseOp->Common.AmlOpcode == AML_ELSE_OP))
1291 /* If an ELSE matches the IF, promote it also */
1293 ElseOp->Common.Parent = OriginalElseOp->Common.Parent;
1295 /* Promote the entire block under the ElseIf (All Next OPs) */
1297 AcpiDmPromoteSubtree (OriginalElseOp);
1301 /* Otherwise, set the IF NEXT to the original ELSE NEXT */
1303 IfOp->Common.Next = OriginalElseOp->Common.Next;
1306 /* Detach the child IF block from the original ELSE */
1308 OriginalElseOp->Common.Value.Arg = NULL;
1310 /* Ignore the original ELSE from now on */
1312 OriginalElseOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
1313 OriginalElseOp->Common.DisasmOpcode = ACPI_DASM_LNOT_PREFIX;
1315 /* Insert IF (now ELSEIF) as next peer of the original ELSE */
1317 OriginalElseOp->Common.Next = IfOp;
1321 /*******************************************************************************
1323 * FUNCTION: AcpiDmPromoteSubtree
1325 * PARAMETERS: StartOpOp - Original parent of the entire subtree
1329 * DESCRIPTION: Promote an entire parse subtree up one level.
1331 ******************************************************************************/
1334 AcpiDmPromoteSubtree (
1335 ACPI_PARSE_OBJECT *StartOp)
1337 ACPI_PARSE_OBJECT *Op;
1338 ACPI_PARSE_OBJECT *ParentOp;
1341 /* New parent for subtree elements */
1343 ParentOp = StartOp->Common.Parent;
1345 /* First child starts the subtree */
1347 Op = StartOp->Common.Value.Arg;
1349 /* Walk the top-level elements of the subtree */
1353 Op->Common.Parent = ParentOp;
1354 if (!Op->Common.Next)
1356 /* Last Op in list, update its next field */
1358 Op->Common.Next = StartOp->Common.Next;
1361 Op = Op->Common.Next;