1 /******************************************************************************
3 * Module Name: ahdecode - Operator/Opcode decoding for acpihelp utility
5 *****************************************************************************/
8 * Copyright (C) 2000 - 2016, 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.
44 #define ACPI_CREATE_PREDEFINED_TABLE
45 #define ACPI_CREATE_RESOURCE_TABLE
51 #define AH_DISPLAY_EXCEPTION(Status, Name) \
52 printf ("%.4X: %s\n", Status, Name)
54 #define AH_DISPLAY_EXCEPTION_TEXT(Status, Exception) \
55 printf ("%.4X: %-28s (%s)\n", Status, Exception->Name, Exception->Description)
57 #define BUFFER_LENGTH 128
58 #define LINE_BUFFER_LENGTH 512
60 static char Gbl_Buffer[BUFFER_LENGTH];
61 static char Gbl_LineBuffer[LINE_BUFFER_LENGTH];
64 /* Local prototypes */
67 AhDisplayPredefinedName (
72 AhDisplayPredefinedInfo (
76 AhDisplayResourceName (
77 const ACPI_PREDEFINED_INFO *ThisName);
81 const AH_AML_OPCODE *Op);
85 const AH_AML_TYPE *Op);
88 AhDisplayAslOperator (
89 const AH_ASL_OPERATOR *Op);
92 AhDisplayOperatorKeywords (
93 const AH_ASL_OPERATOR *Op);
97 const AH_ASL_KEYWORD *Op);
102 UINT32 CurrentPosition,
107 /*******************************************************************************
109 * FUNCTION: AhDisplayDirectives
115 * DESCRIPTION: Display all iASL preprocessor directives.
117 ******************************************************************************/
120 AhDisplayDirectives (
123 const AH_DIRECTIVE_INFO *Info;
126 printf ("iASL Preprocessor Directives\n\n");
128 for (Info = PreprocessorDirectives; Info->Name; Info++)
130 printf (" %-36s : %s\n", Info->Name, Info->Description);
135 /*******************************************************************************
137 * FUNCTION: AhFindPredefinedNames (entry point for predefined name search)
139 * PARAMETERS: NamePrefix - Name or prefix to find. Must start with
140 * an underscore. NULL means "find all"
144 * DESCRIPTION: Find and display all ACPI predefined names that match the
145 * input name or prefix. Includes the required number of arguments
146 * and the expected return type, if any.
148 ******************************************************************************/
151 AhFindPredefinedNames (
159 if (!NamePrefix || (NamePrefix[0] == '*'))
161 Found = AhDisplayPredefinedName (NULL, 0);
165 /* Contruct a local name or name prefix */
167 AcpiUtStrupr (NamePrefix);
168 if (*NamePrefix == '_')
174 strncpy (&Name[1], NamePrefix, 7);
176 Length = strlen (Name);
177 if (Length > ACPI_NAME_SIZE)
179 printf ("%.8s: Predefined name must be 4 characters maximum\n", Name);
183 Found = AhDisplayPredefinedName (Name, Length);
186 printf ("%s, no matching predefined names\n", Name);
191 /*******************************************************************************
193 * FUNCTION: AhDisplayPredefinedName
195 * PARAMETERS: Name - Name or name prefix
197 * RETURN: TRUE if any names matched, FALSE otherwise
199 * DESCRIPTION: Display information about ACPI predefined names that match
200 * the input name or name prefix.
202 ******************************************************************************/
205 AhDisplayPredefinedName (
209 const AH_PREDEFINED_NAME *Info;
210 BOOLEAN Found = FALSE;
215 /* Find/display all names that match the input name prefix */
217 for (Info = AslPredefinedInfo; Info->Name; Info++)
222 printf ("%s: <%s>\n", Info->Name, Info->Description);
223 printf ("%*s%s\n", 6, " ", Info->Action);
225 AhDisplayPredefinedInfo (Info->Name);
231 for (i = 0; i < Length; i++)
233 if (Info->Name[i] != Name[i])
243 printf ("%s: <%s>\n", Info->Name, Info->Description);
244 printf ("%*s%s\n", 6, " ", Info->Action);
246 AhDisplayPredefinedInfo (Info->Name);
252 printf ("\nFound %d Predefined ACPI Names\n", i);
258 /*******************************************************************************
260 * FUNCTION: AhDisplayPredefinedInfo
262 * PARAMETERS: Name - Exact 4-character ACPI name.
266 * DESCRIPTION: Find the name in the main ACPICA predefined info table and
267 * display the # of arguments and the return value type.
269 * Note: Resource Descriptor field names do not appear in this
270 * table -- thus, nothing will be displayed for them.
272 ******************************************************************************/
275 AhDisplayPredefinedInfo (
278 const ACPI_PREDEFINED_INFO *ThisName;
281 /* NOTE: we check both tables always because there are some dupes */
283 /* Check against the predefine methods first */
285 ThisName = AcpiUtMatchPredefinedMethod (Name);
288 AcpiUtDisplayPredefinedMethod (Gbl_Buffer, ThisName, TRUE);
291 /* Check against the predefined resource descriptor names */
293 ThisName = AcpiUtMatchResourceName (Name);
296 AhDisplayResourceName (ThisName);
301 /*******************************************************************************
303 * FUNCTION: AhDisplayResourceName
305 * PARAMETERS: ThisName - Entry in the predefined method/name table
309 * DESCRIPTION: Display information about a resource descriptor name.
311 ******************************************************************************/
314 AhDisplayResourceName (
315 const ACPI_PREDEFINED_INFO *ThisName)
320 NumTypes = AcpiUtGetResourceBitWidth (Gbl_Buffer,
321 ThisName->Info.ArgumentList);
323 printf (" %4.4s resource descriptor field is %s bits wide%s\n",
326 (NumTypes > 1) ? " (depending on descriptor type)" : "");
330 /*******************************************************************************
332 * FUNCTION: AhFindAmlOpcode (entry point for AML opcode name search)
334 * PARAMETERS: Name - Name or prefix for an AML opcode.
335 * NULL means "find all"
339 * DESCRIPTION: Find all AML opcodes that match the input Name or name
342 ******************************************************************************/
348 const AH_AML_OPCODE *Op;
349 BOOLEAN Found = FALSE;
354 /* Find/display all opcode names that match the input name prefix */
356 for (Op = AmlOpcodeInfo; Op->OpcodeString; Op++)
358 if (!Op->OpcodeName) /* Unused opcodes */
363 if (!Name || (Name[0] == '*'))
365 AhDisplayAmlOpcode (Op);
370 /* Upper case the opcode name before substring compare */
372 strcpy (Gbl_Buffer, Op->OpcodeName);
373 AcpiUtStrupr (Gbl_Buffer);
375 if (strstr (Gbl_Buffer, Name) == Gbl_Buffer)
377 AhDisplayAmlOpcode (Op);
384 printf ("%s, no matching AML operators\n", Name);
389 /*******************************************************************************
391 * FUNCTION: AhDecodeAmlOpcode (entry point for AML opcode search)
393 * PARAMETERS: OpcodeString - String version of AML opcode
397 * DESCRIPTION: Display information about the input AML opcode
399 ******************************************************************************/
405 const AH_AML_OPCODE *Op;
412 AhFindAmlOpcode (NULL);
416 Opcode = strtoul (OpcodeString, NULL, 16);
417 if (Opcode > ACPI_UINT16_MAX)
419 printf ("Invalid opcode (more than 16 bits)\n");
423 /* Only valid opcode extension is 0x5B */
425 Prefix = (Opcode & 0x0000FF00) >> 8;
426 if (Prefix && (Prefix != 0x5B))
428 printf ("Invalid opcode (invalid extension prefix 0x%X)\n",
433 /* Find/Display the opcode. May fall within an opcode range */
435 for (Op = AmlOpcodeInfo; Op->OpcodeString; Op++)
437 if ((Opcode >= Op->OpcodeRangeStart) &&
438 (Opcode <= Op->OpcodeRangeEnd))
440 AhDisplayAmlOpcode (Op);
446 /*******************************************************************************
448 * FUNCTION: AhDisplayAmlOpcode
450 * PARAMETERS: Op - An opcode info struct
454 * DESCRIPTION: Display the contents of an AML opcode information struct
456 ******************************************************************************/
460 const AH_AML_OPCODE *Op)
465 printf ("%18s: Opcode=%-9s\n", "Reserved opcode", Op->OpcodeString);
469 /* Opcode name and value(s) */
471 printf ("%18s: Opcode=%-9s Type (%s)",
472 Op->OpcodeName, Op->OpcodeString, Op->Type);
474 /* Optional fixed/static arguments */
476 if (Op->FixedArguments)
478 printf (" FixedArgs (");
479 AhPrintOneField (37, 36 + 7 + strlen (Op->Type) + 12,
480 AH_MAX_AML_LINE_LENGTH, Op->FixedArguments);
484 /* Optional variable-length argument list */
486 if (Op->VariableArguments)
488 if (Op->FixedArguments)
490 printf ("\n%*s", 36, " ");
492 printf (" VariableArgs (");
493 AhPrintOneField (37, 15, AH_MAX_AML_LINE_LENGTH, Op->VariableArguments);
498 /* Grammar specification */
502 AhPrintOneField (37, 0, AH_MAX_AML_LINE_LENGTH, Op->Grammar);
508 /*******************************************************************************
510 * FUNCTION: AhFindAmlTypes (entry point for AML grammar keyword search)
512 * PARAMETERS: Name - Name or prefix for an AML grammar element.
513 * NULL means "find all"
517 * DESCRIPTION: Find all AML grammar keywords that match the input Name or name
520 ******************************************************************************/
526 const AH_AML_TYPE *Keyword;
527 BOOLEAN Found = FALSE;
532 for (Keyword = AmlTypesInfo; Keyword->Name; Keyword++)
536 printf (" %s\n", Keyword->Name);
543 AhDisplayAmlType (Keyword);
548 /* Upper case the operator name before substring compare */
550 strcpy (Gbl_Buffer, Keyword->Name);
551 AcpiUtStrupr (Gbl_Buffer);
553 if (strstr (Gbl_Buffer, Name) == Gbl_Buffer)
555 AhDisplayAmlType (Keyword);
562 printf ("%s, no matching AML grammar type\n", Name);
567 /*******************************************************************************
569 * FUNCTION: AhDisplayAmlType
571 * PARAMETERS: Op - Pointer to AML grammar info
575 * DESCRIPTION: Format and display info for an AML grammar element.
577 ******************************************************************************/
581 const AH_AML_TYPE *Op)
586 Description = Op->Description;
587 printf ("%4s", " "); /* Primary indent */
589 /* Emit the entire description string */
593 /* Description can be multiple lines, must indent each */
595 while (*Description != '\n')
597 printf ("%c", *Description);
608 printf ("%8s", " "); /* Secondary indent */
610 /* Index extra for a comment */
612 if ((Description[0] == '/') &&
613 (Description[1] == '/'))
624 /*******************************************************************************
626 * FUNCTION: AhFindAslKeywords (entry point for ASL keyword search)
628 * PARAMETERS: Name - Name or prefix for an ASL keyword.
629 * NULL means "find all"
633 * DESCRIPTION: Find all ASL keywords that match the input Name or name
636 ******************************************************************************/
642 const AH_ASL_KEYWORD *Keyword;
643 BOOLEAN Found = FALSE;
648 for (Keyword = AslKeywordInfo; Keyword->Name; Keyword++)
650 if (!Name || (Name[0] == '*'))
652 AhDisplayAslKeyword (Keyword);
657 /* Upper case the operator name before substring compare */
659 strcpy (Gbl_Buffer, Keyword->Name);
660 AcpiUtStrupr (Gbl_Buffer);
662 if (strstr (Gbl_Buffer, Name) == Gbl_Buffer)
664 AhDisplayAslKeyword (Keyword);
671 printf ("%s, no matching ASL keywords\n", Name);
676 /*******************************************************************************
678 * FUNCTION: AhDisplayAslKeyword
680 * PARAMETERS: Op - Pointer to ASL keyword with syntax info
684 * DESCRIPTION: Format and display syntax info for an ASL keyword. Splits
685 * long lines appropriately for reading.
687 ******************************************************************************/
690 AhDisplayAslKeyword (
691 const AH_ASL_KEYWORD *Op)
694 /* ASL keyword name and description */
696 printf ("%22s: %s\n", Op->Name, Op->Description);
697 if (!Op->KeywordList)
702 /* List of actual keywords */
704 AhPrintOneField (24, 0, AH_MAX_ASL_LINE_LENGTH, Op->KeywordList);
709 /*******************************************************************************
711 * FUNCTION: AhFindAslAndAmlOperators
713 * PARAMETERS: Name - Name or prefix for an ASL operator.
714 * NULL means "find all"
718 * DESCRIPTION: Find all ASL operators that match the input Name or name
719 * prefix. Also displays the AML information if only one entry
722 ******************************************************************************/
725 AhFindAslAndAmlOperators (
731 MatchCount = AhFindAslOperators (Name);
734 AhFindAmlOpcode (Name);
739 /*******************************************************************************
741 * FUNCTION: AhFindAslOperators (entry point for ASL operator search)
743 * PARAMETERS: Name - Name or prefix for an ASL operator.
744 * NULL means "find all"
746 * RETURN: Number of operators that matched the name prefix.
748 * DESCRIPTION: Find all ASL operators that match the input Name or name
751 ******************************************************************************/
757 const AH_ASL_OPERATOR *Operator;
758 BOOLEAN MatchCount = 0;
763 /* Find/display all names that match the input name prefix */
765 for (Operator = AslOperatorInfo; Operator->Name; Operator++)
767 if (!Name || (Name[0] == '*'))
769 AhDisplayAslOperator (Operator);
774 /* Upper case the operator name before substring compare */
776 strcpy (Gbl_Buffer, Operator->Name);
777 AcpiUtStrupr (Gbl_Buffer);
779 if (strstr (Gbl_Buffer, Name) == Gbl_Buffer)
781 AhDisplayAslOperator (Operator);
788 printf ("%s, no matching ASL operators\n", Name);
795 /*******************************************************************************
797 * FUNCTION: AhDisplayAslOperator
799 * PARAMETERS: Op - Pointer to ASL operator with syntax info
803 * DESCRIPTION: Format and display syntax info for an ASL operator. Splits
804 * long lines appropriately for reading.
806 ******************************************************************************/
809 AhDisplayAslOperator (
810 const AH_ASL_OPERATOR *Op)
813 /* ASL operator name and description */
815 printf ("%16s: %s\n", Op->Name, Op->Description);
821 /* Syntax for the operator */
823 AhPrintOneField (18, 0, AH_MAX_ASL_LINE_LENGTH, Op->Syntax);
826 AhDisplayOperatorKeywords (Op);
831 /*******************************************************************************
833 * FUNCTION: AhDisplayOperatorKeywords
835 * PARAMETERS: Op - Pointer to ASL keyword with syntax info
839 * DESCRIPTION: Display any/all keywords that are associated with the ASL
842 ******************************************************************************/
845 AhDisplayOperatorKeywords (
846 const AH_ASL_OPERATOR *Op)
849 char *Separators = "(){}, ";
850 BOOLEAN FirstKeyword = TRUE;
853 if (!Op || !Op->Syntax)
859 * Find all parameters that have the word "keyword" within, and then
860 * display the info about that keyword
862 strcpy (Gbl_LineBuffer, Op->Syntax);
863 Token = strtok (Gbl_LineBuffer, Separators);
866 if (strstr (Token, "Keyword"))
871 FirstKeyword = FALSE;
874 /* Found a keyword, display keyword information */
876 AhFindAslKeywords (Token);
879 Token = strtok (NULL, Separators);
884 /*******************************************************************************
886 * FUNCTION: AhPrintOneField
888 * PARAMETERS: Indent - Indent length for new line(s)
889 * CurrentPosition - Position on current line
890 * MaxPosition - Max allowed line length
891 * Field - Data to output
893 * RETURN: Line position after field is written
895 * DESCRIPTION: Split long lines appropriately for ease of reading.
897 ******************************************************************************/
902 UINT32 CurrentPosition,
914 Position = CurrentPosition;
918 printf ("%*s", (int) Indent, " ");
922 Last = This + strlen (This);
923 while ((Next = strpbrk (This, " ")))
925 TokenLength = Next - This;
926 Position += TokenLength;
928 /* Split long lines */
930 if (Position > MaxPosition)
932 printf ("\n%*s", (int) Indent, " ");
933 Position = TokenLength;
936 printf ("%.*s ", (int) TokenLength, This);
940 /* Handle last token on the input line */
942 TokenLength = Last - This;
945 Position += TokenLength;
946 if (Position > MaxPosition)
948 printf ("\n%*s", (int) Indent, " ");
956 /*******************************************************************************
958 * FUNCTION: AhDisplayDeviceIds
960 * PARAMETERS: Name - Device Hardware ID string.
961 * NULL means "find all"
965 * DESCRIPTION: Display PNP* and ACPI* device IDs.
967 ******************************************************************************/
973 const AH_DEVICE_ID *Info;
977 BOOLEAN Found = FALSE;
980 /* Null input name indicates "display all" */
982 if (!Name || (Name[0] == '*'))
984 printf ("ACPI and PNP Device/Hardware IDs:\n\n");
985 for (Info = AslDeviceIds; Info->Name; Info++)
987 printf ("%8s %s\n", Info->Name, Info->Description);
993 Length = strlen (Name);
996 printf ("%.8s: Hardware ID must be 8 characters maximum\n", Name);
1000 /* Find/display all names that match the input name prefix */
1002 AcpiUtStrupr (Name);
1003 for (Info = AslDeviceIds; Info->Name; Info++)
1006 for (i = 0; i < Length; i++)
1008 if (Info->Name[i] != Name[i])
1018 printf ("%8s %s\n", Info->Name, Info->Description);
1024 printf ("%s, Hardware ID not found\n", Name);
1029 /*******************************************************************************
1031 * FUNCTION: AhDisplayUuids
1037 * DESCRIPTION: Display all known UUIDs.
1039 ******************************************************************************/
1045 const AH_UUID *Info;
1048 printf ("ACPI-related UUIDs/GUIDs:\n");
1050 /* Display entire table of known ACPI-related UUIDs/GUIDs */
1052 for (Info = AcpiUuids; Info->Description; Info++)
1054 if (!Info->String) /* Null UUID string means group description */
1056 printf ("\n%36s\n", Info->Description);
1060 printf ("%32s : %s\n", Info->Description, Info->String);
1064 /* Help info on how UUIDs/GUIDs strings are encoded */
1066 printf ("\n\nByte encoding of UUID/GUID strings"
1067 " into ACPI Buffer objects (use ToUUID from ASL):\n\n");
1069 printf ("%32s : %s\n", "Input UUID/GUID String format",
1070 "aabbccdd-eeff-gghh-iijj-kkllmmnnoopp");
1072 printf ("%32s : %s\n", "Expected output ACPI buffer",
1073 "dd,cc,bb,aa, ff,ee, hh,gg, ii,jj, kk,ll,mm,nn,oo,pp");
1077 /*******************************************************************************
1079 * FUNCTION: AhDisplayTables
1085 * DESCRIPTION: Display all known ACPI tables
1087 ******************************************************************************/
1093 const AH_TABLE *Info;
1097 printf ("Known ACPI tables:\n");
1099 for (Info = AcpiSupportedTables; Info->Signature; Info++)
1101 printf ("%8s : %s\n", Info->Signature, Info->Description);
1105 printf ("\nTotal %u ACPI tables\n\n", i);
1109 /*******************************************************************************
1111 * FUNCTION: AhDecodeException
1113 * PARAMETERS: HexString - ACPI status string from command line, in
1114 * hex. If null, display all exceptions.
1118 * DESCRIPTION: Decode and display an ACPI_STATUS exception code.
1120 ******************************************************************************/
1126 const ACPI_EXCEPTION_INFO *ExceptionInfo;
1132 * A null input string means to decode and display all known
1137 printf ("All defined ACPICA exception codes:\n\n");
1138 AH_DISPLAY_EXCEPTION (0,
1139 "AE_OK (No error occurred)");
1141 /* Display codes in each block of exception types */
1143 for (i = 1; (i & AE_CODE_MASK) <= AE_CODE_MAX; i += 0x1000)
1148 ExceptionInfo = AcpiUtValidateException ((ACPI_STATUS) Status);
1151 AH_DISPLAY_EXCEPTION_TEXT (Status, ExceptionInfo);
1156 } while (ExceptionInfo);
1161 /* Decode a single user-supplied exception code */
1163 Status = strtoul (HexString, NULL, 16);
1166 printf ("%s: Invalid hexadecimal exception code value\n", HexString);
1170 if (Status > ACPI_UINT16_MAX)
1172 AH_DISPLAY_EXCEPTION (Status, "Invalid exception code (more than 16 bits)");
1176 ExceptionInfo = AcpiUtValidateException ((ACPI_STATUS) Status);
1179 AH_DISPLAY_EXCEPTION (Status, "Unknown exception code");
1183 AH_DISPLAY_EXCEPTION_TEXT (Status, ExceptionInfo);