Indentation fix, cleanup.
[AROS.git] / arch / all-pc / acpica / source / components / disassembler / dmopcode.c
blobbbe5af391e86478705fb6ae55ac5ab3b67851be9
1 /*******************************************************************************
3 * Module Name: dmopcode - AML disassembler, specific AML opcodes
5 ******************************************************************************/
7 /*
8 * Copyright (C) 2000 - 2013, Intel Corp.
9 * All rights reserved.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
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.
30 * NO WARRANTY
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.
44 #include "acpi.h"
45 #include "accommon.h"
46 #include "acparser.h"
47 #include "amlcode.h"
48 #include "acdisasm.h"
50 #ifdef ACPI_DISASSEMBLER
52 #define _COMPONENT ACPI_CA_DEBUGGER
53 ACPI_MODULE_NAME ("dmopcode")
55 /* Local prototypes */
57 static void
58 AcpiDmMatchKeyword (
59 ACPI_PARSE_OBJECT *Op);
62 /*******************************************************************************
64 * FUNCTION: AcpiDmPredefinedDescription
66 * PARAMETERS: Op - Name() parse object
68 * RETURN: None
70 * DESCRIPTION: Emit a description comment for a predefined ACPI name.
71 * Used for iASL compiler only.
73 ******************************************************************************/
75 void
76 AcpiDmPredefinedDescription (
77 ACPI_PARSE_OBJECT *Op)
79 #ifdef ACPI_ASL_COMPILER
80 const AH_PREDEFINED_NAME *Info;
81 char *NameString;
82 int LastCharIsDigit;
83 int LastCharsAreHex;
86 if (!Op)
88 return;
91 /* Ensure that the comment field is emitted only once */
93 if (Op->Common.DisasmFlags & ACPI_PARSEOP_PREDEF_CHECKED)
95 return;
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] != '_')
104 return;
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.
115 LastCharIsDigit =
116 (ACPI_IS_DIGIT (NameString[3])); /* d */
117 LastCharsAreHex =
118 (ACPI_IS_XDIGIT (NameString[2]) && /* xx */
119 ACPI_IS_XDIGIT (NameString[3]));
121 switch (NameString[1])
123 case 'A':
125 if ((NameString[2] == 'C') && (LastCharIsDigit))
127 NameString = "_ACx";
129 else if ((NameString[2] == 'L') && (LastCharIsDigit))
131 NameString = "_ALx";
133 break;
135 case 'E':
137 if ((NameString[2] == 'J') && (LastCharIsDigit))
139 NameString = "_EJx";
141 else if (LastCharsAreHex)
143 NameString = "_Exx";
145 break;
147 case 'L':
149 if (LastCharsAreHex)
151 NameString = "_Lxx";
153 break;
155 case 'Q':
157 if (LastCharsAreHex)
159 NameString = "_Qxx";
161 break;
163 case 'T':
165 if (NameString[2] == '_')
167 NameString = "_T_x";
169 break;
171 case 'W':
173 if (LastCharsAreHex)
175 NameString = "_Wxx";
177 break;
179 default:
181 break;
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));
192 return;
196 #endif
197 return;
201 /*******************************************************************************
203 * FUNCTION: AcpiDmFieldPredefinedDescription
205 * PARAMETERS: Op - Parse object
207 * RETURN: None
209 * DESCRIPTION: Emit a description comment for a resource descriptor tag
210 * (which is a predefined ACPI name.) Used for iASL compiler only.
212 ******************************************************************************/
214 void
215 AcpiDmFieldPredefinedDescription (
216 ACPI_PARSE_OBJECT *Op)
218 #ifdef ACPI_ASL_COMPILER
219 ACPI_PARSE_OBJECT *IndexOp;
220 char *Tag;
221 const ACPI_OPCODE_INFO *OpInfo;
222 const AH_PREDEFINED_NAME *Info;
225 if (!Op)
227 return;
230 /* Ensure that the comment field is emitted only once */
232 if (Op->Common.DisasmFlags & ACPI_PARSEOP_PREDEF_CHECKED)
234 return;
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))
245 return;
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)
257 return;
260 /* Major cheat: We previously put the Tag ptr in the Node field */
262 Tag = ACPI_CAST_PTR (char, IndexOp->Common.Node);
263 if (!Tag)
265 return;
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));
276 return;
280 #endif
281 return;
285 /*******************************************************************************
287 * FUNCTION: AcpiDmMethodFlags
289 * PARAMETERS: Op - Method Object to be examined
291 * RETURN: None
293 * DESCRIPTION: Decode control method flags
295 ******************************************************************************/
297 void
298 AcpiDmMethodFlags (
299 ACPI_PARSE_OBJECT *Op)
301 UINT32 Flags;
302 UINT32 Args;
305 /* The next Op contains the flags */
307 Op = AcpiPsGetDepthNext (NULL, Op);
308 Flags = (UINT8) Op->Common.Value.Integer;
309 Args = Flags & 0x07;
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 */
321 if (!(Flags & 0x08))
323 AcpiOsPrintf ("Not");
326 AcpiOsPrintf ("Serialized");
328 /* 3) SyncLevel */
330 if (Flags & 0xF0)
332 AcpiOsPrintf (", %u", Flags >> 4);
337 /*******************************************************************************
339 * FUNCTION: AcpiDmFieldFlags
341 * PARAMETERS: Op - Field Object to be examined
343 * RETURN: None
345 * DESCRIPTION: Decode Field definition flags
347 ******************************************************************************/
349 void
350 AcpiDmFieldFlags (
351 ACPI_PARSE_OBJECT *Op)
353 UINT32 Flags;
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
375 * RETURN: None
377 * DESCRIPTION: Decode a SpaceId to an AddressSpaceKeyword
379 ******************************************************************************/
381 void
382 AcpiDmAddressSpace (
383 UINT8 SpaceId)
386 if (SpaceId >= ACPI_NUM_PREDEFINED_REGIONS)
388 if (SpaceId == 0x7F)
390 AcpiOsPrintf ("FFixedHW, ");
392 else
394 AcpiOsPrintf ("0x%.2X, ", SpaceId);
397 else
399 AcpiOsPrintf ("%s, ", AcpiGbl_RegionTypes [SpaceId]);
404 /*******************************************************************************
406 * FUNCTION: AcpiDmRegionFlags
408 * PARAMETERS: Op - Object to be examined
410 * RETURN: None
412 * DESCRIPTION: Decode OperationRegion flags
414 ******************************************************************************/
416 void
417 AcpiDmRegionFlags (
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;
430 AcpiOsPrintf (", ");
431 AcpiDmAddressSpace ((UINT8) Op->Common.Value.Integer);
435 /*******************************************************************************
437 * FUNCTION: AcpiDmMatchOp
439 * PARAMETERS: Op - Match Object to be examined
441 * RETURN: None
443 * DESCRIPTION: Decode Match opcode operands
445 ******************************************************************************/
447 void
448 AcpiDmMatchOp (
449 ACPI_PARSE_OBJECT *Op)
451 ACPI_PARSE_OBJECT *NextOp;
454 NextOp = AcpiPsGetDepthNext (NULL, Op);
455 NextOp = NextOp->Common.Next;
457 if (!NextOp)
459 /* Handle partial tree during single-step */
461 return;
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
480 * RETURN: None
482 * DESCRIPTION: Decode Match opcode operands
484 ******************************************************************************/
486 static void
487 AcpiDmMatchKeyword (
488 ACPI_PARSE_OBJECT *Op)
492 if (((UINT32) Op->Common.Value.Integer) > ACPI_MAX_MATCH_OPCODE)
494 AcpiOsPrintf ("/* Unknown Match Keyword encoding */");
496 else
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
512 * RETURN: None
514 * DESCRIPTION: Disassemble a single AML opcode
516 ******************************************************************************/
518 void
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;
525 UINT32 Offset;
526 UINT32 Length;
527 ACPI_PARSE_OBJECT *Child;
528 ACPI_STATUS Status;
529 UINT8 *Aml;
532 if (!Op)
534 AcpiOsPrintf ("<NULL OP PTR>");
535 return;
538 switch (Op->Common.DisasmOpcode)
540 case ACPI_DASM_MATCHOP:
542 AcpiDmMatchKeyword (Op);
543 return;
545 case ACPI_DASM_LNOT_SUFFIX:
547 switch (Op->Common.AmlOpcode)
549 case AML_LEQUAL_OP:
551 AcpiOsPrintf ("LNotEqual");
552 break;
554 case AML_LGREATER_OP:
556 AcpiOsPrintf ("LLessEqual");
557 break;
559 case AML_LLESS_OP:
561 AcpiOsPrintf ("LGreaterEqual");
562 break;
564 default:
566 break;
568 Op->Common.DisasmOpcode = 0;
569 Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
570 return;
572 default:
573 break;
577 OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
579 /* The op and arguments */
581 switch (Op->Common.AmlOpcode)
583 case AML_LNOT_OP:
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;
593 else
595 AcpiOsPrintf ("%s", OpInfo->Name);
597 break;
599 case AML_BYTE_OP:
601 AcpiOsPrintf ("0x%2.2X", (UINT32) Op->Common.Value.Integer);
602 break;
604 case AML_WORD_OP:
606 if (Op->Common.DisasmOpcode == ACPI_DASM_EISAID)
608 AcpiDmEisaId ((UINT32) Op->Common.Value.Integer);
610 else
612 AcpiOsPrintf ("0x%4.4X", (UINT32) Op->Common.Value.Integer);
614 break;
616 case AML_DWORD_OP:
618 if (Op->Common.DisasmOpcode == ACPI_DASM_EISAID)
620 AcpiDmEisaId ((UINT32) Op->Common.Value.Integer);
622 else
624 AcpiOsPrintf ("0x%8.8X", (UINT32) Op->Common.Value.Integer);
626 break;
628 case AML_QWORD_OP:
630 AcpiOsPrintf ("0x%8.8X%8.8X",
631 ACPI_FORMAT_UINT64 (Op->Common.Value.Integer));
632 break;
634 case AML_STRING_OP:
636 AcpiUtPrintString (Op->Common.Value.String, ACPI_UINT16_MAX);
637 break;
639 case AML_BUFFER_OP:
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");
659 break;
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");
682 else
684 Op->Common.DisasmOpcode = ACPI_DASM_BUFFER;
685 AcpiOsPrintf ("Buffer");
687 break;
689 case AML_INT_STATICSTRING_OP:
691 if (Op->Common.Value.String)
693 AcpiOsPrintf ("%s", Op->Common.Value.String);
695 else
697 AcpiOsPrintf ("\"<NULL STATIC STRING PTR>\"");
699 break;
701 case AML_INT_NAMEPATH_OP:
703 AcpiDmNamestring (Op->Common.Value.Name);
704 break;
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;
714 break;
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));
727 else
729 AcpiOsPrintf (" , %u", Offset);
732 AcpiDmCommaIfFieldMember (Op);
733 break;
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));
748 AcpiOsPrintf (")");
749 AcpiDmCommaIfFieldMember (Op);
750 break;
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)
762 AcpiOsPrintf ("\n");
764 Aml = Child->Named.Data;
765 Length = (UINT32) Child->Common.Value.Integer;
767 Info->Level += 1;
768 Op->Common.DisasmOpcode = ACPI_DASM_RESOURCE;
769 AcpiDmResourceTemplate (Info, Op->Common.Parent, Aml, Length);
771 Info->Level -= 1;
772 AcpiDmIndent (Info->Level);
774 else
776 AcpiDmNamestring (Child->Common.Value.Name);
779 AcpiOsPrintf (")");
780 AcpiDmCommaIfFieldMember (Op);
781 AcpiOsPrintf ("\n");
783 Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; /* for now, ignore in AcpiDmAscendingOp */
784 Child->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
785 break;
787 case AML_INT_BYTELIST_OP:
789 AcpiDmByteList (Info, Op);
790 break;
792 case AML_INT_METHODCALL_OP:
794 Op = AcpiPsGetDepthNext (NULL, Op);
795 Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
797 AcpiDmNamestring (Op->Common.Value.Name);
798 break;
800 default:
802 /* Just get the opcode name and print it */
804 AcpiOsPrintf ("%s", OpInfo->Name);
807 #ifdef ACPI_DEBUGGER
809 if ((Op->Common.AmlOpcode == AML_INT_RETURN_VALUE_OP) &&
810 (WalkState) &&
811 (WalkState->Results) &&
812 (WalkState->ResultCount))
814 AcpiDmDecodeInternalObject (
815 WalkState->Results->Results.ObjDesc [
816 (WalkState->ResultCount - 1) %
817 ACPI_RESULTS_FRAME_OBJ_NUM]);
819 #endif
821 break;
825 #endif /* ACPI_DISASSEMBLER */