1 /*******************************************************************************
3 * Module Name: dmopcode - AML disassembler, specific AML opcodes
5 ******************************************************************************/
8 * Copyright (C) 2000 - 2013, Intel Corp.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
50 #ifdef ACPI_DISASSEMBLER
52 #define _COMPONENT ACPI_CA_DEBUGGER
53 ACPI_MODULE_NAME ("dmopcode")
55 /* Local prototypes */
59 ACPI_PARSE_OBJECT
*Op
);
62 /*******************************************************************************
64 * FUNCTION: AcpiDmPredefinedDescription
66 * PARAMETERS: Op - Name() parse object
70 * DESCRIPTION: Emit a description comment for a predefined ACPI name.
71 * Used for iASL compiler only.
73 ******************************************************************************/
76 AcpiDmPredefinedDescription (
77 ACPI_PARSE_OBJECT
*Op
)
79 #ifdef ACPI_ASL_COMPILER
80 const AH_PREDEFINED_NAME
*Info
;
91 /* Ensure that the comment field is emitted only once */
93 if (Op
->Common
.DisasmFlags
& ACPI_PARSEOP_PREDEF_CHECKED
)
97 Op
->Common
.DisasmFlags
|= ACPI_PARSEOP_PREDEF_CHECKED
;
99 /* Predefined name must start with an underscore */
101 NameString
= ACPI_CAST_PTR (char, &Op
->Named
.Name
);
102 if (NameString
[0] != '_')
108 * Check for the special ACPI names:
109 * _ACd, _ALd, _EJd, _Exx, _Lxx, _Qxx, _Wxx, _T_a
110 * (where d=decimal_digit, x=hex_digit, a=anything)
112 * Convert these to the generic name for table lookup.
113 * Note: NameString is guaranteed to be upper case here.
116 (ACPI_IS_DIGIT (NameString
[3])); /* d */
118 (ACPI_IS_XDIGIT (NameString
[2]) && /* xx */
119 ACPI_IS_XDIGIT (NameString
[3]));
121 switch (NameString
[1])
125 if ((NameString
[2] == 'C') && (LastCharIsDigit
))
129 else if ((NameString
[2] == 'L') && (LastCharIsDigit
))
137 if ((NameString
[2] == 'J') && (LastCharIsDigit
))
141 else if (LastCharsAreHex
)
165 if (NameString
[2] == '_')
184 /* Match the name in the info table */
186 for (Info
= AslPredefinedInfo
; Info
->Name
; Info
++)
188 if (ACPI_COMPARE_NAME (NameString
, Info
->Name
))
190 AcpiOsPrintf (" // %4.4s: %s",
191 NameString
, ACPI_CAST_PTR (char, Info
->Description
));
201 /*******************************************************************************
203 * FUNCTION: AcpiDmFieldPredefinedDescription
205 * PARAMETERS: Op - Parse object
209 * DESCRIPTION: Emit a description comment for a resource descriptor tag
210 * (which is a predefined ACPI name.) Used for iASL compiler only.
212 ******************************************************************************/
215 AcpiDmFieldPredefinedDescription (
216 ACPI_PARSE_OBJECT
*Op
)
218 #ifdef ACPI_ASL_COMPILER
219 ACPI_PARSE_OBJECT
*IndexOp
;
221 const ACPI_OPCODE_INFO
*OpInfo
;
222 const AH_PREDEFINED_NAME
*Info
;
230 /* Ensure that the comment field is emitted only once */
232 if (Op
->Common
.DisasmFlags
& ACPI_PARSEOP_PREDEF_CHECKED
)
236 Op
->Common
.DisasmFlags
|= ACPI_PARSEOP_PREDEF_CHECKED
;
239 * Op must be one of the Create* operators: CreateField, CreateBitField,
240 * CreateByteField, CreateWordField, CreateDwordField, CreateQwordField
242 OpInfo
= AcpiPsGetOpcodeInfo (Op
->Common
.AmlOpcode
);
243 if (!(OpInfo
->Flags
& AML_CREATE
))
248 /* Second argument is the Index argument */
250 IndexOp
= Op
->Common
.Value
.Arg
;
251 IndexOp
= IndexOp
->Common
.Next
;
253 /* Index argument must be a namepath */
255 if (IndexOp
->Common
.AmlOpcode
!= AML_INT_NAMEPATH_OP
)
260 /* Major cheat: We previously put the Tag ptr in the Node field */
262 Tag
= ACPI_CAST_PTR (char, IndexOp
->Common
.Node
);
268 /* Match the name in the info table */
270 for (Info
= AslPredefinedInfo
; Info
->Name
; Info
++)
272 if (ACPI_COMPARE_NAME (Tag
, Info
->Name
))
274 AcpiOsPrintf (" // %4.4s: %s", Tag
,
275 ACPI_CAST_PTR (char, Info
->Description
));
285 /*******************************************************************************
287 * FUNCTION: AcpiDmMethodFlags
289 * PARAMETERS: Op - Method Object to be examined
293 * DESCRIPTION: Decode control method flags
295 ******************************************************************************/
299 ACPI_PARSE_OBJECT
*Op
)
305 /* The next Op contains the flags */
307 Op
= AcpiPsGetDepthNext (NULL
, Op
);
308 Flags
= (UINT8
) Op
->Common
.Value
.Integer
;
311 /* Mark the Op as completed */
313 Op
->Common
.DisasmFlags
|= ACPI_PARSEOP_IGNORE
;
315 /* 1) Method argument count */
317 AcpiOsPrintf (", %u, ", Args
);
319 /* 2) Serialize rule */
323 AcpiOsPrintf ("Not");
326 AcpiOsPrintf ("Serialized");
332 AcpiOsPrintf (", %u", Flags
>> 4);
337 /*******************************************************************************
339 * FUNCTION: AcpiDmFieldFlags
341 * PARAMETERS: Op - Field Object to be examined
345 * DESCRIPTION: Decode Field definition flags
347 ******************************************************************************/
351 ACPI_PARSE_OBJECT
*Op
)
356 Op
= Op
->Common
.Next
;
357 Flags
= (UINT8
) Op
->Common
.Value
.Integer
;
359 /* Mark the Op as completed */
361 Op
->Common
.DisasmFlags
|= ACPI_PARSEOP_IGNORE
;
363 AcpiOsPrintf ("%s, ", AcpiGbl_AccessTypes
[Flags
& 0x07]);
364 AcpiOsPrintf ("%s, ", AcpiGbl_LockRule
[(Flags
& 0x10) >> 4]);
365 AcpiOsPrintf ("%s)", AcpiGbl_UpdateRules
[(Flags
& 0x60) >> 5]);
369 /*******************************************************************************
371 * FUNCTION: AcpiDmAddressSpace
373 * PARAMETERS: SpaceId - ID to be translated
377 * DESCRIPTION: Decode a SpaceId to an AddressSpaceKeyword
379 ******************************************************************************/
386 if (SpaceId
>= ACPI_NUM_PREDEFINED_REGIONS
)
390 AcpiOsPrintf ("FFixedHW, ");
394 AcpiOsPrintf ("0x%.2X, ", SpaceId
);
399 AcpiOsPrintf ("%s, ", AcpiGbl_RegionTypes
[SpaceId
]);
404 /*******************************************************************************
406 * FUNCTION: AcpiDmRegionFlags
408 * PARAMETERS: Op - Object to be examined
412 * DESCRIPTION: Decode OperationRegion flags
414 ******************************************************************************/
418 ACPI_PARSE_OBJECT
*Op
)
422 /* The next Op contains the SpaceId */
424 Op
= AcpiPsGetDepthNext (NULL
, Op
);
426 /* Mark the Op as completed */
428 Op
->Common
.DisasmFlags
|= ACPI_PARSEOP_IGNORE
;
431 AcpiDmAddressSpace ((UINT8
) Op
->Common
.Value
.Integer
);
435 /*******************************************************************************
437 * FUNCTION: AcpiDmMatchOp
439 * PARAMETERS: Op - Match Object to be examined
443 * DESCRIPTION: Decode Match opcode operands
445 ******************************************************************************/
449 ACPI_PARSE_OBJECT
*Op
)
451 ACPI_PARSE_OBJECT
*NextOp
;
454 NextOp
= AcpiPsGetDepthNext (NULL
, Op
);
455 NextOp
= NextOp
->Common
.Next
;
459 /* Handle partial tree during single-step */
464 /* Mark the two nodes that contain the encoding for the match keywords */
466 NextOp
->Common
.DisasmOpcode
= ACPI_DASM_MATCHOP
;
468 NextOp
= NextOp
->Common
.Next
;
469 NextOp
= NextOp
->Common
.Next
;
470 NextOp
->Common
.DisasmOpcode
= ACPI_DASM_MATCHOP
;
474 /*******************************************************************************
476 * FUNCTION: AcpiDmMatchKeyword
478 * PARAMETERS: Op - Match Object to be examined
482 * DESCRIPTION: Decode Match opcode operands
484 ******************************************************************************/
488 ACPI_PARSE_OBJECT
*Op
)
492 if (((UINT32
) Op
->Common
.Value
.Integer
) > ACPI_MAX_MATCH_OPCODE
)
494 AcpiOsPrintf ("/* Unknown Match Keyword encoding */");
498 AcpiOsPrintf ("%s", ACPI_CAST_PTR (char,
499 AcpiGbl_MatchOps
[(ACPI_SIZE
) Op
->Common
.Value
.Integer
]));
504 /*******************************************************************************
506 * FUNCTION: AcpiDmDisassembleOneOp
508 * PARAMETERS: WalkState - Current walk info
509 * Info - Parse tree walk info
510 * Op - Op that is to be printed
514 * DESCRIPTION: Disassemble a single AML opcode
516 ******************************************************************************/
519 AcpiDmDisassembleOneOp (
520 ACPI_WALK_STATE
*WalkState
,
521 ACPI_OP_WALK_INFO
*Info
,
522 ACPI_PARSE_OBJECT
*Op
)
524 const ACPI_OPCODE_INFO
*OpInfo
= NULL
;
527 ACPI_PARSE_OBJECT
*Child
;
534 AcpiOsPrintf ("<NULL OP PTR>");
538 switch (Op
->Common
.DisasmOpcode
)
540 case ACPI_DASM_MATCHOP
:
542 AcpiDmMatchKeyword (Op
);
545 case ACPI_DASM_LNOT_SUFFIX
:
547 switch (Op
->Common
.AmlOpcode
)
551 AcpiOsPrintf ("LNotEqual");
554 case AML_LGREATER_OP
:
556 AcpiOsPrintf ("LLessEqual");
561 AcpiOsPrintf ("LGreaterEqual");
568 Op
->Common
.DisasmOpcode
= 0;
569 Op
->Common
.DisasmFlags
|= ACPI_PARSEOP_IGNORE
;
577 OpInfo
= AcpiPsGetOpcodeInfo (Op
->Common
.AmlOpcode
);
579 /* The op and arguments */
581 switch (Op
->Common
.AmlOpcode
)
585 Child
= Op
->Common
.Value
.Arg
;
586 if ((Child
->Common
.AmlOpcode
== AML_LEQUAL_OP
) ||
587 (Child
->Common
.AmlOpcode
== AML_LGREATER_OP
) ||
588 (Child
->Common
.AmlOpcode
== AML_LLESS_OP
))
590 Child
->Common
.DisasmOpcode
= ACPI_DASM_LNOT_SUFFIX
;
591 Op
->Common
.DisasmOpcode
= ACPI_DASM_LNOT_PREFIX
;
595 AcpiOsPrintf ("%s", OpInfo
->Name
);
601 AcpiOsPrintf ("0x%2.2X", (UINT32
) Op
->Common
.Value
.Integer
);
606 if (Op
->Common
.DisasmOpcode
== ACPI_DASM_EISAID
)
608 AcpiDmEisaId ((UINT32
) Op
->Common
.Value
.Integer
);
612 AcpiOsPrintf ("0x%4.4X", (UINT32
) Op
->Common
.Value
.Integer
);
618 if (Op
->Common
.DisasmOpcode
== ACPI_DASM_EISAID
)
620 AcpiDmEisaId ((UINT32
) Op
->Common
.Value
.Integer
);
624 AcpiOsPrintf ("0x%8.8X", (UINT32
) Op
->Common
.Value
.Integer
);
630 AcpiOsPrintf ("0x%8.8X%8.8X",
631 ACPI_FORMAT_UINT64 (Op
->Common
.Value
.Integer
));
636 AcpiUtPrintString (Op
->Common
.Value
.String
, ACPI_UINT16_MAX
);
641 * Determine the type of buffer. We can have one of the following:
643 * 1) ResourceTemplate containing Resource Descriptors.
644 * 2) Unicode String buffer
645 * 3) ASCII String buffer
646 * 4) Raw data buffer (if none of the above)
648 * Since there are no special AML opcodes to differentiate these
649 * types of buffers, we have to closely look at the data in the
650 * buffer to determine the type.
652 if (!AcpiGbl_NoResourceDisassembly
)
654 Status
= AcpiDmIsResourceTemplate (WalkState
, Op
);
655 if (ACPI_SUCCESS (Status
))
657 Op
->Common
.DisasmOpcode
= ACPI_DASM_RESOURCE
;
658 AcpiOsPrintf ("ResourceTemplate");
661 else if (Status
== AE_AML_NO_RESOURCE_END_TAG
)
663 AcpiOsPrintf ("/**** Is ResourceTemplate, but EndTag not at buffer end ****/ ");
667 if (AcpiDmIsUnicodeBuffer (Op
))
669 Op
->Common
.DisasmOpcode
= ACPI_DASM_UNICODE
;
670 AcpiOsPrintf ("Unicode (");
672 else if (AcpiDmIsStringBuffer (Op
))
674 Op
->Common
.DisasmOpcode
= ACPI_DASM_STRING
;
675 AcpiOsPrintf ("Buffer");
677 else if (AcpiDmIsPldBuffer (Op
))
679 Op
->Common
.DisasmOpcode
= ACPI_DASM_PLD_METHOD
;
680 AcpiOsPrintf ("Buffer");
684 Op
->Common
.DisasmOpcode
= ACPI_DASM_BUFFER
;
685 AcpiOsPrintf ("Buffer");
689 case AML_INT_STATICSTRING_OP
:
691 if (Op
->Common
.Value
.String
)
693 AcpiOsPrintf ("%s", Op
->Common
.Value
.String
);
697 AcpiOsPrintf ("\"<NULL STATIC STRING PTR>\"");
701 case AML_INT_NAMEPATH_OP
:
703 AcpiDmNamestring (Op
->Common
.Value
.Name
);
706 case AML_INT_NAMEDFIELD_OP
:
708 Length
= AcpiDmDumpName (Op
->Named
.Name
);
709 AcpiOsPrintf (",%*.s %u", (unsigned) (5 - Length
), " ",
710 (UINT32
) Op
->Common
.Value
.Integer
);
711 AcpiDmCommaIfFieldMember (Op
);
713 Info
->BitOffset
+= (UINT32
) Op
->Common
.Value
.Integer
;
716 case AML_INT_RESERVEDFIELD_OP
:
718 /* Offset() -- Must account for previous offsets */
720 Offset
= (UINT32
) Op
->Common
.Value
.Integer
;
721 Info
->BitOffset
+= Offset
;
723 if (Info
->BitOffset
% 8 == 0)
725 AcpiOsPrintf ("Offset (0x%.2X)", ACPI_DIV_8 (Info
->BitOffset
));
729 AcpiOsPrintf (" , %u", Offset
);
732 AcpiDmCommaIfFieldMember (Op
);
735 case AML_INT_ACCESSFIELD_OP
:
736 case AML_INT_EXTACCESSFIELD_OP
:
738 AcpiOsPrintf ("AccessAs (%s, ",
739 AcpiGbl_AccessTypes
[(UINT32
) (Op
->Common
.Value
.Integer
& 0x7)]);
741 AcpiDmDecodeAttribute ((UINT8
) (Op
->Common
.Value
.Integer
>> 8));
743 if (Op
->Common
.AmlOpcode
== AML_INT_EXTACCESSFIELD_OP
)
745 AcpiOsPrintf (" (0x%2.2X)", (unsigned) ((Op
->Common
.Value
.Integer
>> 16) & 0xFF));
749 AcpiDmCommaIfFieldMember (Op
);
752 case AML_INT_CONNECTION_OP
:
754 * Two types of Connection() - one with a buffer object, the
755 * other with a namestring that points to a buffer object.
757 AcpiOsPrintf ("Connection (");
758 Child
= Op
->Common
.Value
.Arg
;
760 if (Child
->Common
.AmlOpcode
== AML_INT_BYTELIST_OP
)
764 Aml
= Child
->Named
.Data
;
765 Length
= (UINT32
) Child
->Common
.Value
.Integer
;
768 Op
->Common
.DisasmOpcode
= ACPI_DASM_RESOURCE
;
769 AcpiDmResourceTemplate (Info
, Op
->Common
.Parent
, Aml
, Length
);
772 AcpiDmIndent (Info
->Level
);
776 AcpiDmNamestring (Child
->Common
.Value
.Name
);
780 AcpiDmCommaIfFieldMember (Op
);
783 Op
->Common
.DisasmFlags
|= ACPI_PARSEOP_IGNORE
; /* for now, ignore in AcpiDmAscendingOp */
784 Child
->Common
.DisasmFlags
|= ACPI_PARSEOP_IGNORE
;
787 case AML_INT_BYTELIST_OP
:
789 AcpiDmByteList (Info
, Op
);
792 case AML_INT_METHODCALL_OP
:
794 Op
= AcpiPsGetDepthNext (NULL
, Op
);
795 Op
->Common
.DisasmFlags
|= ACPI_PARSEOP_IGNORE
;
797 AcpiDmNamestring (Op
->Common
.Value
.Name
);
802 /* Just get the opcode name and print it */
804 AcpiOsPrintf ("%s", OpInfo
->Name
);
809 if ((Op
->Common
.AmlOpcode
== AML_INT_RETURN_VALUE_OP
) &&
811 (WalkState
->Results
) &&
812 (WalkState
->ResultCount
))
814 AcpiDmDecodeInternalObject (
815 WalkState
->Results
->Results
.ObjDesc
[
816 (WalkState
->ResultCount
- 1) %
817 ACPI_RESULTS_FRAME_OBJ_NUM
]);
825 #endif /* ACPI_DISASSEMBLER */