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);
181 AcpiDmIsSwitchBlock (
182 ACPI_PARSE_OBJECT *Op,
187 ACPI_PARSE_OBJECT *Op);
189 /*******************************************************************************
191 * FUNCTION: AcpiDmDisplayTargetPathname
193 * PARAMETERS: Op - Parse object
197 * DESCRIPTION: For AML opcodes that have a target operand, display the full
198 * pathname for the target, in a comment field. Handles Return()
201 ******************************************************************************/
204 AcpiDmDisplayTargetPathname (
205 ACPI_PARSE_OBJECT *Op)
207 ACPI_PARSE_OBJECT *NextOp;
208 ACPI_PARSE_OBJECT *PrevOp = NULL;
210 const ACPI_OPCODE_INFO *OpInfo;
213 if (Op->Common.AmlOpcode == AML_RETURN_OP)
215 PrevOp = Op->Asl.Value.Arg;
219 OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
220 if (!(OpInfo->Flags & AML_HAS_TARGET))
225 /* Target is the last Op in the arg list */
227 NextOp = Op->Asl.Value.Arg;
231 NextOp = PrevOp->Asl.Next;
240 /* We must have a namepath AML opcode */
242 if (PrevOp->Asl.AmlOpcode != AML_INT_NAMEPATH_OP)
247 /* A null string is the "no target specified" case */
249 if (!PrevOp->Asl.Value.String)
254 /* No node means "unresolved external reference" */
256 if (!PrevOp->Asl.Node)
258 AcpiOsPrintf (" /* External reference */");
262 /* Ignore if path is already from the root */
264 if (*PrevOp->Asl.Value.String == '\\')
269 /* Now: we can get the full pathname */
271 Pathname = AcpiNsGetExternalPathname (PrevOp->Asl.Node);
277 AcpiOsPrintf (" /* %s */", Pathname);
278 ACPI_FREE (Pathname);
282 /*******************************************************************************
284 * FUNCTION: AcpiDmNotifyDescription
286 * PARAMETERS: Op - Name() parse object
290 * DESCRIPTION: Emit a description comment for the value associated with a
293 ******************************************************************************/
296 AcpiDmNotifyDescription (
297 ACPI_PARSE_OBJECT *Op)
299 ACPI_PARSE_OBJECT *NextOp;
300 ACPI_NAMESPACE_NODE *Node;
302 UINT8 Type = ACPI_TYPE_ANY;
305 /* The notify value is the second argument */
307 NextOp = Op->Asl.Value.Arg;
308 NextOp = NextOp->Asl.Next;
310 switch (NextOp->Common.AmlOpcode)
315 NotifyValue = (UINT8) NextOp->Common.AmlOpcode;
320 NotifyValue = (UINT8) NextOp->Asl.Value.Integer;
328 * Attempt to get the namespace node so we can determine the object type.
329 * Some notify values are dependent on the object type (Device, Thermal,
338 AcpiOsPrintf (" // %s", AcpiUtGetNotifyName (NotifyValue, Type));
342 /*******************************************************************************
344 * FUNCTION: AcpiDmPredefinedDescription
346 * PARAMETERS: Op - Name() parse object
350 * DESCRIPTION: Emit a description comment for a predefined ACPI name.
351 * Used for iASL compiler only.
353 ******************************************************************************/
356 AcpiDmPredefinedDescription (
357 ACPI_PARSE_OBJECT *Op)
359 #ifdef ACPI_ASL_COMPILER
360 const AH_PREDEFINED_NAME *Info;
371 /* Ensure that the comment field is emitted only once */
373 if (Op->Common.DisasmFlags & ACPI_PARSEOP_PREDEFINED_CHECKED)
377 Op->Common.DisasmFlags |= ACPI_PARSEOP_PREDEFINED_CHECKED;
379 /* Predefined name must start with an underscore */
381 NameString = ACPI_CAST_PTR (char, &Op->Named.Name);
382 if (NameString[0] != '_')
388 * Check for the special ACPI names:
389 * _ACd, _ALd, _EJd, _Exx, _Lxx, _Qxx, _Wxx, _T_a
390 * (where d=decimal_digit, x=hex_digit, a=anything)
392 * Convert these to the generic name for table lookup.
393 * Note: NameString is guaranteed to be upper case here.
396 (isdigit ((int) NameString[3])); /* d */
398 (isxdigit ((int) NameString[2]) && /* xx */
399 isxdigit ((int) NameString[3]));
401 switch (NameString[1])
405 if ((NameString[2] == 'C') && (LastCharIsDigit))
409 else if ((NameString[2] == 'L') && (LastCharIsDigit))
417 if ((NameString[2] == 'J') && (LastCharIsDigit))
421 else if (LastCharsAreHex)
445 if (NameString[2] == '_')
464 /* Match the name in the info table */
466 Info = AcpiAhMatchPredefinedName (NameString);
469 AcpiOsPrintf (" // %4.4s: %s",
470 NameString, ACPI_CAST_PTR (char, Info->Description));
478 /*******************************************************************************
480 * FUNCTION: AcpiDmFieldPredefinedDescription
482 * PARAMETERS: Op - Parse object
486 * DESCRIPTION: Emit a description comment for a resource descriptor tag
487 * (which is a predefined ACPI name.) Used for iASL compiler only.
489 ******************************************************************************/
492 AcpiDmFieldPredefinedDescription (
493 ACPI_PARSE_OBJECT *Op)
495 #ifdef ACPI_ASL_COMPILER
496 ACPI_PARSE_OBJECT *IndexOp;
498 const ACPI_OPCODE_INFO *OpInfo;
499 const AH_PREDEFINED_NAME *Info;
507 /* Ensure that the comment field is emitted only once */
509 if (Op->Common.DisasmFlags & ACPI_PARSEOP_PREDEFINED_CHECKED)
513 Op->Common.DisasmFlags |= ACPI_PARSEOP_PREDEFINED_CHECKED;
516 * Op must be one of the Create* operators: CreateField, CreateBitField,
517 * CreateByteField, CreateWordField, CreateDwordField, CreateQwordField
519 OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
520 if (!(OpInfo->Flags & AML_CREATE))
525 /* Second argument is the Index argument */
527 IndexOp = Op->Common.Value.Arg;
528 IndexOp = IndexOp->Common.Next;
530 /* Index argument must be a namepath */
532 if (IndexOp->Common.AmlOpcode != AML_INT_NAMEPATH_OP)
537 /* Major cheat: We previously put the Tag ptr in the Node field */
539 Tag = ACPI_CAST_PTR (char, IndexOp->Common.Node);
545 /* Match the name in the info table */
547 Info = AcpiAhMatchPredefinedName (Tag);
550 AcpiOsPrintf (" // %4.4s: %s", Tag,
551 ACPI_CAST_PTR (char, Info->Description));
554 /* AML buffer (String) was allocated in AcpiGetTagPathname */
556 ACPI_FREE (IndexOp->Common.Value.String);
563 /*******************************************************************************
565 * FUNCTION: AcpiDmMethodFlags
567 * PARAMETERS: Op - Method Object to be examined
571 * DESCRIPTION: Decode control method flags
573 ******************************************************************************/
577 ACPI_PARSE_OBJECT *Op)
583 /* The next Op contains the flags */
585 Op = AcpiPsGetDepthNext (NULL, Op);
586 Flags = (UINT8) Op->Common.Value.Integer;
589 /* Mark the Op as completed */
591 Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
593 /* 1) Method argument count */
595 AcpiOsPrintf (", %u, ", Args);
597 /* 2) Serialize rule */
601 AcpiOsPrintf ("Not");
604 AcpiOsPrintf ("Serialized");
610 AcpiOsPrintf (", %u", Flags >> 4);
615 /*******************************************************************************
617 * FUNCTION: AcpiDmFieldFlags
619 * PARAMETERS: Op - Field Object to be examined
623 * DESCRIPTION: Decode Field definition flags
625 ******************************************************************************/
629 ACPI_PARSE_OBJECT *Op)
634 Op = Op->Common.Next;
635 Flags = (UINT8) Op->Common.Value.Integer;
637 /* Mark the Op as completed */
639 Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
641 AcpiOsPrintf ("%s, ", AcpiGbl_AccessTypes [Flags & 0x07]);
642 AcpiOsPrintf ("%s, ", AcpiGbl_LockRule [(Flags & 0x10) >> 4]);
643 AcpiOsPrintf ("%s)", AcpiGbl_UpdateRules [(Flags & 0x60) >> 5]);
647 /*******************************************************************************
649 * FUNCTION: AcpiDmAddressSpace
651 * PARAMETERS: SpaceId - ID to be translated
655 * DESCRIPTION: Decode a SpaceId to an AddressSpaceKeyword
657 ******************************************************************************/
664 if (SpaceId >= ACPI_NUM_PREDEFINED_REGIONS)
668 AcpiOsPrintf ("FFixedHW, ");
672 AcpiOsPrintf ("0x%.2X, ", SpaceId);
677 AcpiOsPrintf ("%s, ", AcpiGbl_RegionTypes [SpaceId]);
682 /*******************************************************************************
684 * FUNCTION: AcpiDmRegionFlags
686 * PARAMETERS: Op - Object to be examined
690 * DESCRIPTION: Decode OperationRegion flags
692 ******************************************************************************/
696 ACPI_PARSE_OBJECT *Op)
699 /* The next Op contains the SpaceId */
701 Op = AcpiPsGetDepthNext (NULL, Op);
703 /* Mark the Op as completed */
705 Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
708 AcpiDmAddressSpace ((UINT8) Op->Common.Value.Integer);
712 /*******************************************************************************
714 * FUNCTION: AcpiDmMatchOp
716 * PARAMETERS: Op - Match Object to be examined
720 * DESCRIPTION: Decode Match opcode operands
722 ******************************************************************************/
726 ACPI_PARSE_OBJECT *Op)
728 ACPI_PARSE_OBJECT *NextOp;
731 NextOp = AcpiPsGetDepthNext (NULL, Op);
732 NextOp = NextOp->Common.Next;
736 /* Handle partial tree during single-step */
741 /* Mark the two nodes that contain the encoding for the match keywords */
743 NextOp->Common.DisasmOpcode = ACPI_DASM_MATCHOP;
745 NextOp = NextOp->Common.Next;
746 NextOp = NextOp->Common.Next;
747 NextOp->Common.DisasmOpcode = ACPI_DASM_MATCHOP;
751 /*******************************************************************************
753 * FUNCTION: AcpiDmMatchKeyword
755 * PARAMETERS: Op - Match Object to be examined
759 * DESCRIPTION: Decode Match opcode operands
761 ******************************************************************************/
765 ACPI_PARSE_OBJECT *Op)
768 if (((UINT32) Op->Common.Value.Integer) > ACPI_MAX_MATCH_OPCODE)
770 AcpiOsPrintf ("/* Unknown Match Keyword encoding */");
775 AcpiGbl_MatchOps[(ACPI_SIZE) Op->Common.Value.Integer]);
780 /*******************************************************************************
782 * FUNCTION: AcpiDmDisassembleOneOp
784 * PARAMETERS: WalkState - Current walk info
785 * Info - Parse tree walk info
786 * Op - Op that is to be printed
790 * DESCRIPTION: Disassemble a single AML opcode
792 ******************************************************************************/
795 AcpiDmDisassembleOneOp (
796 ACPI_WALK_STATE *WalkState,
797 ACPI_OP_WALK_INFO *Info,
798 ACPI_PARSE_OBJECT *Op)
800 const ACPI_OPCODE_INFO *OpInfo = NULL;
803 ACPI_PARSE_OBJECT *Child;
806 const AH_DEVICE_ID *IdInfo;
811 AcpiOsPrintf ("<NULL OP PTR>");
815 if (Op->Common.DisasmFlags & ACPI_PARSEOP_ELSEIF)
817 return; /* ElseIf macro was already emitted */
820 switch (Op->Common.DisasmOpcode)
822 case ACPI_DASM_MATCHOP:
824 AcpiDmMatchKeyword (Op);
827 case ACPI_DASM_LNOT_SUFFIX:
829 if (!AcpiGbl_CstyleDisassembly)
831 switch (Op->Common.AmlOpcode)
833 case AML_LOGICAL_EQUAL_OP:
834 AcpiOsPrintf ("LNotEqual");
837 case AML_LOGICAL_GREATER_OP:
838 AcpiOsPrintf ("LLessEqual");
841 case AML_LOGICAL_LESS_OP:
842 AcpiOsPrintf ("LGreaterEqual");
850 Op->Common.DisasmOpcode = 0;
851 Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
858 OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
860 /* The op and arguments */
862 switch (Op->Common.AmlOpcode)
864 case AML_LOGICAL_NOT_OP:
866 Child = Op->Common.Value.Arg;
867 if ((Child->Common.AmlOpcode == AML_LOGICAL_EQUAL_OP) ||
868 (Child->Common.AmlOpcode == AML_LOGICAL_GREATER_OP) ||
869 (Child->Common.AmlOpcode == AML_LOGICAL_LESS_OP))
871 Child->Common.DisasmOpcode = ACPI_DASM_LNOT_SUFFIX;
872 Op->Common.DisasmOpcode = ACPI_DASM_LNOT_PREFIX;
876 AcpiOsPrintf ("%s", OpInfo->Name);
882 AcpiOsPrintf ("0x%2.2X", (UINT32) Op->Common.Value.Integer);
887 if (Op->Common.DisasmOpcode == ACPI_DASM_EISAID)
889 AcpiDmDecompressEisaId ((UINT32) Op->Common.Value.Integer);
893 AcpiOsPrintf ("0x%4.4X", (UINT32) Op->Common.Value.Integer);
899 if (Op->Common.DisasmOpcode == ACPI_DASM_EISAID)
901 AcpiDmDecompressEisaId ((UINT32) Op->Common.Value.Integer);
905 AcpiOsPrintf ("0x%8.8X", (UINT32) Op->Common.Value.Integer);
911 AcpiOsPrintf ("0x%8.8X%8.8X",
912 ACPI_FORMAT_UINT64 (Op->Common.Value.Integer));
917 AcpiUtPrintString (Op->Common.Value.String, ACPI_UINT16_MAX);
919 /* For _HID/_CID strings, attempt to output a descriptive comment */
921 if (Op->Common.DisasmOpcode == ACPI_DASM_HID_STRING)
923 /* If we know about the ID, emit the description */
925 IdInfo = AcpiAhMatchHardwareId (Op->Common.Value.String);
928 AcpiOsPrintf (" /* %s */", IdInfo->Description);
935 * Determine the type of buffer. We can have one of the following:
937 * 1) ResourceTemplate containing Resource Descriptors.
938 * 2) Unicode String buffer
939 * 3) ASCII String buffer
940 * 4) Raw data buffer (if none of the above)
942 * Since there are no special AML opcodes to differentiate these
943 * types of buffers, we have to closely look at the data in the
944 * buffer to determine the type.
946 if (!AcpiGbl_NoResourceDisassembly)
948 Status = AcpiDmIsResourceTemplate (WalkState, Op);
949 if (ACPI_SUCCESS (Status))
951 Op->Common.DisasmOpcode = ACPI_DASM_RESOURCE;
952 AcpiOsPrintf ("ResourceTemplate");
955 else if (Status == AE_AML_NO_RESOURCE_END_TAG)
958 "/**** Is ResourceTemplate, "
959 "but EndTag not at buffer end ****/ ");
963 if (AcpiDmIsUuidBuffer (Op))
965 Op->Common.DisasmOpcode = ACPI_DASM_UUID;
966 AcpiOsPrintf ("ToUUID (");
968 else if (AcpiDmIsUnicodeBuffer (Op))
970 Op->Common.DisasmOpcode = ACPI_DASM_UNICODE;
971 AcpiOsPrintf ("Unicode (");
973 else if (AcpiDmIsStringBuffer (Op))
975 Op->Common.DisasmOpcode = ACPI_DASM_STRING;
976 AcpiOsPrintf ("Buffer");
978 else if (AcpiDmIsPldBuffer (Op))
980 Op->Common.DisasmOpcode = ACPI_DASM_PLD_METHOD;
981 AcpiOsPrintf ("ToPLD (");
985 Op->Common.DisasmOpcode = ACPI_DASM_BUFFER;
986 AcpiOsPrintf ("Buffer");
990 case AML_INT_NAMEPATH_OP:
992 AcpiDmNamestring (Op->Common.Value.Name);
995 case AML_INT_NAMEDFIELD_OP:
997 Length = AcpiDmDumpName (Op->Named.Name);
1000 ASL_CV_PRINT_ONE_COMMENT (Op, AML_NAMECOMMENT, NULL, 0);
1001 AcpiOsPrintf ("%*.s %u", (unsigned) (5 - Length), " ",
1002 (UINT32) Op->Common.Value.Integer);
1004 AcpiDmCommaIfFieldMember (Op);
1006 Info->BitOffset += (UINT32) Op->Common.Value.Integer;
1009 case AML_INT_RESERVEDFIELD_OP:
1011 /* Offset() -- Must account for previous offsets */
1013 Offset = (UINT32) Op->Common.Value.Integer;
1014 Info->BitOffset += Offset;
1016 if (Info->BitOffset % 8 == 0)
1018 AcpiOsPrintf ("Offset (0x%.2X)", ACPI_DIV_8 (Info->BitOffset));
1022 AcpiOsPrintf (" , %u", Offset);
1025 AcpiDmCommaIfFieldMember (Op);
1028 case AML_INT_ACCESSFIELD_OP:
1029 case AML_INT_EXTACCESSFIELD_OP:
1031 AcpiOsPrintf ("AccessAs (%s, ",
1032 AcpiGbl_AccessTypes [(UINT32) (Op->Common.Value.Integer & 0x7)]);
1034 AcpiDmDecodeAttribute ((UINT8) (Op->Common.Value.Integer >> 8));
1036 if (Op->Common.AmlOpcode == AML_INT_EXTACCESSFIELD_OP)
1038 AcpiOsPrintf (" (0x%2.2X)", (unsigned)
1039 ((Op->Common.Value.Integer >> 16) & 0xFF));
1043 AcpiDmCommaIfFieldMember (Op);
1044 ASL_CV_PRINT_ONE_COMMENT (Op, AML_COMMENT_END_NODE, NULL, 0);
1047 case AML_INT_CONNECTION_OP:
1049 * Two types of Connection() - one with a buffer object, the
1050 * other with a namestring that points to a buffer object.
1052 AcpiOsPrintf ("Connection (");
1053 Child = Op->Common.Value.Arg;
1055 if (Child->Common.AmlOpcode == AML_INT_BYTELIST_OP)
1057 AcpiOsPrintf ("\n");
1059 Aml = Child->Named.Data;
1060 Length = (UINT32) Child->Common.Value.Integer;
1063 Info->MappingOp = Op;
1064 Op->Common.DisasmOpcode = ACPI_DASM_RESOURCE;
1066 AcpiDmResourceTemplate (Info, Op->Common.Parent, Aml, Length);
1069 AcpiDmIndent (Info->Level);
1073 AcpiDmNamestring (Child->Common.Value.Name);
1077 AcpiDmCommaIfFieldMember (Op);
1078 ASL_CV_PRINT_ONE_COMMENT (Op, AML_COMMENT_END_NODE, NULL, 0);
1079 ASL_CV_PRINT_ONE_COMMENT (Op, AMLCOMMENT_INLINE, NULL, 0);
1080 AcpiOsPrintf ("\n");
1082 Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; /* for now, ignore in AcpiDmAscendingOp */
1083 Child->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
1086 case AML_INT_BYTELIST_OP:
1088 AcpiDmByteList (Info, Op);
1091 case AML_INT_METHODCALL_OP:
1093 Op = AcpiPsGetDepthNext (NULL, Op);
1094 Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
1096 AcpiDmNamestring (Op->Common.Value.Name);
1101 if (Op->Common.DisasmOpcode == ACPI_DASM_SWITCH)
1103 AcpiOsPrintf ("%s", "Switch");
1107 AcpiOsPrintf ("%s", OpInfo->Name);
1112 if (Op->Common.DisasmOpcode == ACPI_DASM_CASE)
1114 AcpiOsPrintf ("%s", "Case");
1118 AcpiOsPrintf ("%s", OpInfo->Name);
1123 AcpiDmConvertToElseIf (Op);
1126 case AML_EXTERNAL_OP:
1128 if (AcpiGbl_DmEmitExternalOpcodes)
1130 AcpiDmEmitExternal (AcpiPsGetArg(Op, 0),
1131 AcpiPsGetArg(Op, 1));
1139 /* Just get the opcode name and print it */
1141 AcpiOsPrintf ("%s", OpInfo->Name);
1144 #ifdef ACPI_DEBUGGER
1146 if ((Op->Common.AmlOpcode == AML_INT_RETURN_VALUE_OP) &&
1148 (WalkState->Results) &&
1149 (WalkState->ResultCount))
1151 AcpiDbDecodeInternalObject (
1152 WalkState->Results->Results.ObjDesc [
1153 (WalkState->ResultCount - 1) %
1154 ACPI_RESULTS_FRAME_OBJ_NUM]);
1163 /*******************************************************************************
1165 * FUNCTION: AcpiDmConvertToElseIf
1167 * PARAMETERS: OriginalElseOp - ELSE Object to be examined
1169 * RETURN: None. Emits either an "Else" or an "ElseIf" ASL operator.
1171 * DESCRIPTION: Detect and convert an If..Else..If sequence to If..ElseIf
1175 * This If..Else..If nested sequence:
1189 * Is converted to this simpler If..ElseIf sequence:
1195 * ElseIf (Arg0 == 2)
1200 * NOTE: There is no actual ElseIf AML opcode. ElseIf is essentially an ASL
1201 * macro that emits an Else opcode followed by an If opcode. This function
1202 * reverses these AML sequences back to an ElseIf macro where possible. This
1203 * can make the disassembled ASL code simpler and more like the original code.
1205 ******************************************************************************/
1208 AcpiDmConvertToElseIf (
1209 ACPI_PARSE_OBJECT *OriginalElseOp)
1211 ACPI_PARSE_OBJECT *IfOp;
1212 ACPI_PARSE_OBJECT *ElseOp;
1216 * To be able to perform the conversion, two conditions must be satisfied:
1217 * 1) The first child of the Else must be an If statement.
1218 * 2) The If block can only be followed by an Else block and these must
1219 * be the only blocks under the original Else.
1221 IfOp = OriginalElseOp->Common.Value.Arg;
1224 (IfOp->Common.AmlOpcode != AML_IF_OP) ||
1225 (IfOp->Asl.Next && (IfOp->Asl.Next->Common.AmlOpcode != AML_ELSE_OP)))
1227 /* Not a proper Else..If sequence, cannot convert to ElseIf */
1229 if (OriginalElseOp->Common.DisasmOpcode == ACPI_DASM_DEFAULT)
1231 AcpiOsPrintf ("%s", "Default");
1235 AcpiOsPrintf ("%s", "Else");
1239 /* Cannot have anything following the If...Else block */
1241 ElseOp = IfOp->Common.Next;
1242 if (ElseOp && ElseOp->Common.Next)
1244 if (OriginalElseOp->Common.DisasmOpcode == ACPI_DASM_DEFAULT)
1246 AcpiOsPrintf ("%s", "Default");
1250 AcpiOsPrintf ("%s", "Else");
1254 if (OriginalElseOp->Common.DisasmOpcode == ACPI_DASM_DEFAULT)
1257 * There is an ElseIf but in this case the Else is actually
1258 * a Default block for a Switch/Case statement. No conversion.
1260 AcpiOsPrintf ("%s", "Default");
1264 if (OriginalElseOp->Common.DisasmOpcode == ACPI_DASM_CASE)
1267 * This ElseIf is actually a Case block for a Switch/Case
1268 * statement. Print Case but do not return so that we can
1269 * promote the subtree and keep the indentation level.
1271 AcpiOsPrintf ("%s", "Case");
1275 /* Emit ElseIf, mark the IF as now an ELSEIF */
1277 AcpiOsPrintf ("%s", "ElseIf");
1280 IfOp->Common.DisasmFlags |= ACPI_PARSEOP_ELSEIF;
1282 /* The IF parent will now be the same as the original ELSE parent */
1284 IfOp->Common.Parent = OriginalElseOp->Common.Parent;
1287 * Update the NEXT pointers to restructure the parse tree, essentially
1288 * promoting an If..Else block up to the same level as the original
1291 * Check if the IF has a corresponding ELSE peer
1293 ElseOp = IfOp->Common.Next;
1295 (ElseOp->Common.AmlOpcode == AML_ELSE_OP))
1297 /* If an ELSE matches the IF, promote it also */
1299 ElseOp->Common.Parent = OriginalElseOp->Common.Parent;
1301 /* Promote the entire block under the ElseIf (All Next OPs) */
1303 AcpiDmPromoteSubtree (OriginalElseOp);
1307 /* Otherwise, set the IF NEXT to the original ELSE NEXT */
1309 IfOp->Common.Next = OriginalElseOp->Common.Next;
1312 /* Detach the child IF block from the original ELSE */
1314 OriginalElseOp->Common.Value.Arg = NULL;
1316 /* Ignore the original ELSE from now on */
1318 OriginalElseOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
1319 OriginalElseOp->Common.DisasmOpcode = ACPI_DASM_LNOT_PREFIX;
1321 /* Insert IF (now ELSEIF) as next peer of the original ELSE */
1323 OriginalElseOp->Common.Next = IfOp;
1327 /*******************************************************************************
1329 * FUNCTION: AcpiDmPromoteSubtree
1331 * PARAMETERS: StartOpOp - Original parent of the entire subtree
1335 * DESCRIPTION: Promote an entire parse subtree up one level.
1337 ******************************************************************************/
1340 AcpiDmPromoteSubtree (
1341 ACPI_PARSE_OBJECT *StartOp)
1343 ACPI_PARSE_OBJECT *Op;
1344 ACPI_PARSE_OBJECT *ParentOp;
1347 /* New parent for subtree elements */
1349 ParentOp = StartOp->Common.Parent;
1351 /* First child starts the subtree */
1353 Op = StartOp->Common.Value.Arg;
1355 /* Walk the top-level elements of the subtree */
1359 Op->Common.Parent = ParentOp;
1360 if (!Op->Common.Next)
1362 /* Last Op in list, update its next field */
1364 Op->Common.Next = StartOp->Common.Next;
1367 Op = Op->Common.Next;
1371 /*******************************************************************************
1373 * FUNCTION: AcpiDmIsTempName
1375 * PARAMETERS: Op - Object to be examined
1377 * RETURN: TRUE if object is a temporary (_T_x) name for a matching While
1378 * loop that can be converted to a Switch.
1380 * DESCRIPTION: _T_X objects are only used for Switch statements. If a temporary
1381 * name exists, search the siblings for a matching While (One) loop
1382 * that can be converted to a Switch. Return TRUE if a match was
1383 * found, FALSE otherwise.
1385 ******************************************************************************/
1389 ACPI_PARSE_OBJECT *Op)
1391 ACPI_PARSE_OBJECT *CurrentOp;
1394 if (Op->Common.AmlOpcode != AML_NAME_OP)
1399 Temp = (char *)(Op->Common.Aml);
1402 if (strncmp(Temp, "_T_", 3))
1407 CurrentOp = Op->Common.Next;
1410 if (CurrentOp->Common.AmlOpcode == AML_WHILE_OP &&
1411 AcpiDmIsSwitchBlock(CurrentOp, Temp))
1413 Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
1414 CurrentOp->Common.DisasmOpcode = ACPI_DASM_SWITCH;
1418 CurrentOp = CurrentOp->Common.Next;
1424 /*******************************************************************************
1426 * FUNCTION: AcpiDmIsSwitchBlock
1428 * PARAMETERS: Op - While Object
1430 * RETURN: TRUE if While block can be converted to a Switch/Case block
1432 * DESCRIPTION: Determines if While block is a Switch/Case statement. Modifies
1433 * parse tree to allow for Switch/Case disassembly during walk.
1435 * EXAMPLE: Example of parse tree to be converted
1453 ******************************************************************************/
1456 AcpiDmIsSwitchBlock (
1457 ACPI_PARSE_OBJECT *Op,
1460 ACPI_PARSE_OBJECT *OneOp;
1461 ACPI_PARSE_OBJECT *StoreOp;
1462 ACPI_PARSE_OBJECT *NamePathOp;
1463 ACPI_PARSE_OBJECT *PredicateOp;
1464 ACPI_PARSE_OBJECT *CurrentOp;
1465 ACPI_PARSE_OBJECT *TempOp;
1467 /* Check for One Op Predicate */
1469 OneOp = AcpiPsGetArg (Op, 0);
1470 if (!OneOp || (OneOp->Common.AmlOpcode != AML_ONE_OP))
1475 /* Check for Store Op */
1477 StoreOp = OneOp->Common.Next;
1478 if (!StoreOp || (StoreOp->Common.AmlOpcode != AML_STORE_OP))
1483 /* Check for Name Op with _T_ string */
1485 NamePathOp = AcpiPsGetArg (StoreOp, 1);
1486 if (!NamePathOp || (NamePathOp->Common.AmlOpcode != AML_INT_NAMEPATH_OP))
1491 if (strncmp((char *)(NamePathOp->Common.Aml), Temp, 4))
1496 /* This is a Switch/Case control block */
1498 /* Ignore the One Op Predicate */
1500 OneOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
1502 /* Ignore the Store Op, but not the children */
1504 StoreOp->Common.DisasmOpcode = ACPI_DASM_IGNORE_SINGLE;
1507 * First arg of Store Op is the Switch condition.
1508 * Mark it as a Switch predicate and as a parameter list for paren
1509 * closing and correct indentation.
1511 PredicateOp = AcpiPsGetArg (StoreOp, 0);
1512 PredicateOp->Common.DisasmOpcode = ACPI_DASM_SWITCH_PREDICATE;
1513 PredicateOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST;
1515 /* Ignore the Name Op */
1517 NamePathOp->Common.DisasmFlags = ACPI_PARSEOP_IGNORE;
1519 /* Remaining opcodes are the Case statements (If/ElseIf's) */
1521 CurrentOp = StoreOp->Common.Next;
1522 while (AcpiDmIsCaseBlock (CurrentOp))
1524 /* Block is a Case structure */
1526 if (CurrentOp->Common.AmlOpcode == AML_ELSE_OP)
1530 CurrentOp->Common.DisasmOpcode = ACPI_DASM_CASE;
1531 CurrentOp = AcpiPsGetArg (CurrentOp, 0);
1536 CurrentOp->Common.DisasmOpcode = ACPI_DASM_CASE;
1539 * Mark the parse tree for Case disassembly. There are two
1540 * types of Case statements. The first type of statement begins with
1541 * an LEqual. The second starts with an LNot and uses a Match statement
1542 * on a Package of constants.
1544 TempOp = AcpiPsGetArg (CurrentOp, 0);
1545 switch (TempOp->Common.AmlOpcode)
1547 case (AML_LOGICAL_EQUAL_OP):
1549 /* Ignore just the LEqual Op */
1551 TempOp->Common.DisasmOpcode = ACPI_DASM_IGNORE_SINGLE;
1553 /* Ignore the NamePath Op */
1555 TempOp = AcpiPsGetArg (TempOp, 0);
1556 TempOp->Common.DisasmFlags = ACPI_PARSEOP_IGNORE;
1559 * Second arg of LEqual will be the Case predicate.
1560 * Mark it as a predicate and also as a parameter list for paren
1561 * closing and correct indentation.
1563 PredicateOp = TempOp->Common.Next;
1564 PredicateOp->Common.DisasmOpcode = ACPI_DASM_SWITCH_PREDICATE;
1565 PredicateOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST;
1569 case (AML_LOGICAL_NOT_OP):
1572 * The Package will be the predicate of the Case statement.
1580 /* Get the LEqual Op from LNot */
1582 TempOp = AcpiPsGetArg (TempOp, 0);
1584 /* Get the Match Op from LEqual */
1586 TempOp = AcpiPsGetArg (TempOp, 0);
1588 /* Get the Package Op from Match */
1590 PredicateOp = AcpiPsGetArg (TempOp, 0);
1592 /* Mark as parameter list for paren closing */
1594 PredicateOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST;
1597 * The Package list would be too deeply indented if we
1598 * chose to simply ignore the all the parent opcodes, so
1599 * we rearrange the parse tree instead.
1603 * Save the second arg of the If/Else Op which is the
1604 * block code of code for this Case statement.
1606 TempOp = AcpiPsGetArg (CurrentOp, 1);
1609 * Move the Package Op to the child (predicate) of the
1612 CurrentOp->Common.Value.Arg = PredicateOp;
1613 PredicateOp->Common.Parent = CurrentOp;
1615 /* Add the block code */
1617 PredicateOp->Common.Next = TempOp;
1623 /* Should never get here */
1628 /* Advance to next Case block */
1630 CurrentOp = CurrentOp->Common.Next;
1633 /* If CurrentOp is now an Else, then this is a Default block */
1635 if (CurrentOp && CurrentOp->Common.AmlOpcode == AML_ELSE_OP)
1637 CurrentOp->Common.DisasmOpcode = ACPI_DASM_DEFAULT;
1641 * From the first If advance to the Break op. It's possible to
1642 * have an Else (Default) op here when there is only one Case
1643 * statement, so check for it.
1645 CurrentOp = StoreOp->Common.Next->Common.Next;
1646 if (CurrentOp->Common.AmlOpcode == AML_ELSE_OP)
1648 CurrentOp = CurrentOp->Common.Next;
1651 /* Ignore the Break Op */
1653 CurrentOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
1658 /*******************************************************************************
1660 * FUNCTION: AcpiDmIsCaseBlock
1662 * PARAMETERS: Op - Object to test
1664 * RETURN: TRUE if Object is beginning of a Case block.
1666 * DESCRIPTION: Determines if an Object is the beginning of a Case block for a
1667 * Switch/Case statement. Parse tree must be one of the following
1684 ******************************************************************************/
1688 ACPI_PARSE_OBJECT *Op)
1690 ACPI_PARSE_OBJECT *CurrentOp;
1697 /* Look for an If or ElseIf */
1700 if (CurrentOp->Common.AmlOpcode == AML_ELSE_OP)
1702 CurrentOp = AcpiPsGetArg (CurrentOp, 0);
1709 if (!CurrentOp || CurrentOp->Common.AmlOpcode != AML_IF_OP)
1714 /* Child must be LEqual or LNot */
1716 CurrentOp = AcpiPsGetArg (CurrentOp, 0);
1722 switch (CurrentOp->Common.AmlOpcode)
1724 case (AML_LOGICAL_EQUAL_OP):
1726 /* Next child must be NamePath with string _T_ */
1728 CurrentOp = AcpiPsGetArg (CurrentOp, 0);
1729 if (!CurrentOp || !CurrentOp->Common.Value.Name ||
1730 strncmp(CurrentOp->Common.Value.Name, "_T_", 3))
1737 case (AML_LOGICAL_NOT_OP):
1739 /* Child of LNot must be LEqual op */
1741 CurrentOp = AcpiPsGetArg (CurrentOp, 0);
1742 if (!CurrentOp || (CurrentOp->Common.AmlOpcode != AML_LOGICAL_EQUAL_OP))
1747 /* Child of LNot must be Match op */
1749 CurrentOp = AcpiPsGetArg (CurrentOp, 0);
1750 if (!CurrentOp || (CurrentOp->Common.AmlOpcode != AML_MATCH_OP))
1755 /* First child of Match must be Package op */
1757 CurrentOp = AcpiPsGetArg (CurrentOp, 0);
1758 if (!CurrentOp || (CurrentOp->Common.AmlOpcode != AML_PACKAGE_OP))
1763 /* Third child of Match must be NamePath with string _T_ */
1765 CurrentOp = AcpiPsGetArg (CurrentOp->Common.Parent, 2);
1766 if (!CurrentOp || !CurrentOp->Common.Value.Name ||
1767 strncmp(CurrentOp->Common.Value.Name, "_T_", 3))