1 /******************************************************************************
3 * Module Name: ahdecode - Operator/Opcode decoding for acpihelp utility
5 *****************************************************************************/
8 * Copyright (C) 2000 - 2014, 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];
63 /* Local prototypes */
66 AhDisplayPredefinedName (
71 AhDisplayPredefinedInfo (
75 AhDisplayResourceName (
76 const ACPI_PREDEFINED_INFO *ThisName);
80 const AH_AML_OPCODE *Op);
83 AhDisplayAslOperator (
84 const AH_ASL_OPERATOR *Op);
87 AhDisplayOperatorKeywords (
88 const AH_ASL_OPERATOR *Op);
92 const AH_ASL_KEYWORD *Op);
97 UINT32 CurrentPosition,
102 /*******************************************************************************
104 * FUNCTION: AhFindPredefinedNames (entry point for predefined name search)
106 * PARAMETERS: NamePrefix - Name or prefix to find. Must start with
107 * an underscore. NULL means "find all"
111 * DESCRIPTION: Find and display all ACPI predefined names that match the
112 * input name or prefix. Includes the required number of arguments
113 * and the expected return type, if any.
115 ******************************************************************************/
118 AhFindPredefinedNames (
128 Found = AhDisplayPredefinedName (Name, 0);
132 /* Contruct a local name or name prefix */
134 AhStrupr (NamePrefix);
135 if (*NamePrefix == '_')
141 strncpy (&Name[1], NamePrefix, 7);
143 Length = strlen (Name);
146 printf ("%.8s: Predefined name must be 4 characters maximum\n", Name);
150 Found = AhDisplayPredefinedName (Name, Length);
153 printf ("%s, no matching predefined names\n", Name);
158 /*******************************************************************************
160 * FUNCTION: AhDisplayPredefinedName
162 * PARAMETERS: Name - Name or name prefix
164 * RETURN: TRUE if any names matched, FALSE otherwise
166 * DESCRIPTION: Display information about ACPI predefined names that match
167 * the input name or name prefix.
169 ******************************************************************************/
172 AhDisplayPredefinedName (
176 const AH_PREDEFINED_NAME *Info;
177 BOOLEAN Found = FALSE;
182 /* Find/display all names that match the input name prefix */
184 for (Info = AslPredefinedInfo; Info->Name; Info++)
189 printf ("%s: <%s>\n", Info->Name, Info->Description);
190 printf ("%*s%s\n", 6, " ", Info->Action);
192 AhDisplayPredefinedInfo (Info->Name);
197 for (i = 0; i < Length; i++)
199 if (Info->Name[i] != Name[i])
209 printf ("%s: <%s>\n", Info->Name, Info->Description);
210 printf ("%*s%s\n", 6, " ", Info->Action);
212 AhDisplayPredefinedInfo (Info->Name);
220 /*******************************************************************************
222 * FUNCTION: AhDisplayPredefinedInfo
224 * PARAMETERS: Name - Exact 4-character ACPI name.
228 * DESCRIPTION: Find the name in the main ACPICA predefined info table and
229 * display the # of arguments and the return value type.
231 * Note: Resource Descriptor field names do not appear in this
232 * table -- thus, nothing will be displayed for them.
234 ******************************************************************************/
237 AhDisplayPredefinedInfo (
240 const ACPI_PREDEFINED_INFO *ThisName;
243 /* NOTE: we check both tables always because there are some dupes */
245 /* Check against the predefine methods first */
247 ThisName = AcpiUtMatchPredefinedMethod (Name);
250 AcpiUtDisplayPredefinedMethod (Gbl_Buffer, ThisName, TRUE);
253 /* Check against the predefined resource descriptor names */
255 ThisName = AcpiUtMatchResourceName (Name);
258 AhDisplayResourceName (ThisName);
263 /*******************************************************************************
265 * FUNCTION: AhDisplayResourceName
267 * PARAMETERS: ThisName - Entry in the predefined method/name table
271 * DESCRIPTION: Display information about a resource descriptor name.
273 ******************************************************************************/
276 AhDisplayResourceName (
277 const ACPI_PREDEFINED_INFO *ThisName)
282 NumTypes = AcpiUtGetResourceBitWidth (Gbl_Buffer,
283 ThisName->Info.ArgumentList);
285 printf (" %4.4s resource descriptor field is %s bits wide%s\n",
288 (NumTypes > 1) ? " (depending on descriptor type)" : "");
292 /*******************************************************************************
294 * FUNCTION: AhFindAmlOpcode (entry point for AML opcode name search)
296 * PARAMETERS: Name - Name or prefix for an AML opcode.
297 * NULL means "find all"
301 * DESCRIPTION: Find all AML opcodes that match the input Name or name
304 ******************************************************************************/
310 const AH_AML_OPCODE *Op;
311 BOOLEAN Found = FALSE;
316 /* Find/display all opcode names that match the input name prefix */
318 for (Op = AmlOpcodeInfo; Op->OpcodeString; Op++)
320 if (!Op->OpcodeName) /* Unused opcodes */
327 AhDisplayAmlOpcode (Op);
332 /* Upper case the opcode name before substring compare */
334 strcpy (Gbl_Buffer, Op->OpcodeName);
335 AhStrupr (Gbl_Buffer);
337 if (strstr (Gbl_Buffer, Name) == Gbl_Buffer)
339 AhDisplayAmlOpcode (Op);
346 printf ("%s, no matching AML operators\n", Name);
351 /*******************************************************************************
353 * FUNCTION: AhDecodeAmlOpcode (entry point for AML opcode search)
355 * PARAMETERS: OpcodeString - String version of AML opcode
359 * DESCRIPTION: Display information about the input AML opcode
361 ******************************************************************************/
367 const AH_AML_OPCODE *Op;
374 AhFindAmlOpcode (NULL);
378 Opcode = ACPI_STRTOUL (OpcodeString, NULL, 16);
379 if (Opcode > ACPI_UINT16_MAX)
381 printf ("Invalid opcode (more than 16 bits)\n");
385 /* Only valid opcode extension is 0x5B */
387 Prefix = (Opcode & 0x0000FF00) >> 8;
388 if (Prefix && (Prefix != 0x5B))
390 printf ("Invalid opcode (invalid extension prefix 0x%X)\n",
395 /* Find/Display the opcode. May fall within an opcode range */
397 for (Op = AmlOpcodeInfo; Op->OpcodeString; Op++)
399 if ((Opcode >= Op->OpcodeRangeStart) &&
400 (Opcode <= Op->OpcodeRangeEnd))
402 AhDisplayAmlOpcode (Op);
408 /*******************************************************************************
410 * FUNCTION: AhDisplayAmlOpcode
412 * PARAMETERS: Op - An opcode info struct
416 * DESCRIPTION: Display the contents of an AML opcode information struct
418 ******************************************************************************/
422 const AH_AML_OPCODE *Op)
427 printf ("%18s: Opcode=%-9s\n", "Reserved opcode", Op->OpcodeString);
431 /* Opcode name and value(s) */
433 printf ("%18s: Opcode=%-9s Type (%s)",
434 Op->OpcodeName, Op->OpcodeString, Op->Type);
436 /* Optional fixed/static arguments */
438 if (Op->FixedArguments)
440 printf (" FixedArgs (");
441 AhPrintOneField (37, 36 + 7 + strlen (Op->Type) + 12,
442 AH_MAX_AML_LINE_LENGTH, Op->FixedArguments);
446 /* Optional variable-length argument list */
448 if (Op->VariableArguments)
450 if (Op->FixedArguments)
452 printf ("\n%*s", 36, " ");
454 printf (" VariableArgs (");
455 AhPrintOneField (37, 15, AH_MAX_AML_LINE_LENGTH, Op->VariableArguments);
460 /* Grammar specification */
464 AhPrintOneField (37, 0, AH_MAX_AML_LINE_LENGTH, Op->Grammar);
470 /*******************************************************************************
472 * FUNCTION: AhFindAslKeywords (entry point for ASL keyword search)
474 * PARAMETERS: Name - Name or prefix for an ASL keyword.
475 * NULL means "find all"
479 * DESCRIPTION: Find all ASL keywords that match the input Name or name
482 ******************************************************************************/
488 const AH_ASL_KEYWORD *Keyword;
489 BOOLEAN Found = FALSE;
494 for (Keyword = AslKeywordInfo; Keyword->Name; Keyword++)
498 AhDisplayAslKeyword (Keyword);
503 /* Upper case the operator name before substring compare */
505 strcpy (Gbl_Buffer, Keyword->Name);
506 AhStrupr (Gbl_Buffer);
508 if (strstr (Gbl_Buffer, Name) == Gbl_Buffer)
510 AhDisplayAslKeyword (Keyword);
517 printf ("%s, no matching ASL keywords\n", Name);
522 /*******************************************************************************
524 * FUNCTION: AhDisplayAslKeyword
526 * PARAMETERS: Op - Pointer to ASL keyword with syntax info
530 * DESCRIPTION: Format and display syntax info for an ASL keyword. Splits
531 * long lines appropriately for reading.
533 ******************************************************************************/
536 AhDisplayAslKeyword (
537 const AH_ASL_KEYWORD *Op)
540 /* ASL keyword name and description */
542 printf ("%22s: %s\n", Op->Name, Op->Description);
543 if (!Op->KeywordList)
548 /* List of actual keywords */
550 AhPrintOneField (24, 0, AH_MAX_ASL_LINE_LENGTH, Op->KeywordList);
555 /*******************************************************************************
557 * FUNCTION: AhFindAslAndAmlOperators
559 * PARAMETERS: Name - Name or prefix for an ASL operator.
560 * NULL means "find all"
564 * DESCRIPTION: Find all ASL operators that match the input Name or name
565 * prefix. Also displays the AML information if only one entry
568 ******************************************************************************/
571 AhFindAslAndAmlOperators (
577 MatchCount = AhFindAslOperators (Name);
580 AhFindAmlOpcode (Name);
585 /*******************************************************************************
587 * FUNCTION: AhFindAslOperators (entry point for ASL operator search)
589 * PARAMETERS: Name - Name or prefix for an ASL operator.
590 * NULL means "find all"
592 * RETURN: Number of operators that matched the name prefix.
594 * DESCRIPTION: Find all ASL operators that match the input Name or name
597 ******************************************************************************/
603 const AH_ASL_OPERATOR *Operator;
604 BOOLEAN MatchCount = 0;
609 /* Find/display all names that match the input name prefix */
611 for (Operator = AslOperatorInfo; Operator->Name; Operator++)
615 AhDisplayAslOperator (Operator);
620 /* Upper case the operator name before substring compare */
622 strcpy (Gbl_Buffer, Operator->Name);
623 AhStrupr (Gbl_Buffer);
625 if (strstr (Gbl_Buffer, Name) == Gbl_Buffer)
627 AhDisplayAslOperator (Operator);
634 printf ("%s, no matching ASL operators\n", Name);
641 /*******************************************************************************
643 * FUNCTION: AhDisplayAslOperator
645 * PARAMETERS: Op - Pointer to ASL operator with syntax info
649 * DESCRIPTION: Format and display syntax info for an ASL operator. Splits
650 * long lines appropriately for reading.
652 ******************************************************************************/
655 AhDisplayAslOperator (
656 const AH_ASL_OPERATOR *Op)
659 /* ASL operator name and description */
661 printf ("%16s: %s\n", Op->Name, Op->Description);
667 /* Syntax for the operator */
669 AhPrintOneField (18, 0, AH_MAX_ASL_LINE_LENGTH, Op->Syntax);
672 AhDisplayOperatorKeywords (Op);
677 /*******************************************************************************
679 * FUNCTION: AhDisplayOperatorKeywords
681 * PARAMETERS: Op - Pointer to ASL keyword with syntax info
685 * DESCRIPTION: Display any/all keywords that are associated with the ASL
688 ******************************************************************************/
691 AhDisplayOperatorKeywords (
692 const AH_ASL_OPERATOR *Op)
695 char *Separators = "(){}, ";
696 BOOLEAN FirstKeyword = TRUE;
699 if (!Op || !Op->Syntax)
705 * Find all parameters that have the word "keyword" within, and then
706 * display the info about that keyword
708 strcpy (Gbl_LineBuffer, Op->Syntax);
709 Token = strtok (Gbl_LineBuffer, Separators);
712 if (strstr (Token, "Keyword"))
717 FirstKeyword = FALSE;
720 /* Found a keyword, display keyword information */
722 AhFindAslKeywords (Token);
725 Token = strtok (NULL, Separators);
730 /*******************************************************************************
732 * FUNCTION: AhPrintOneField
734 * PARAMETERS: Indent - Indent length for new line(s)
735 * CurrentPosition - Position on current line
736 * MaxPosition - Max allowed line length
737 * Field - Data to output
739 * RETURN: Line position after field is written
741 * DESCRIPTION: Split long lines appropriately for ease of reading.
743 ******************************************************************************/
748 UINT32 CurrentPosition,
760 Position = CurrentPosition;
764 printf ("%*s", (int) Indent, " ");
768 Last = This + strlen (This);
769 while ((Next = strpbrk (This, " ")))
771 TokenLength = Next - This;
772 Position += TokenLength;
774 /* Split long lines */
776 if (Position > MaxPosition)
778 printf ("\n%*s", (int) Indent, " ");
779 Position = TokenLength;
782 printf ("%.*s ", (int) TokenLength, This);
786 /* Handle last token on the input line */
788 TokenLength = Last - This;
791 Position += TokenLength;
792 if (Position > MaxPosition)
794 printf ("\n%*s", (int) Indent, " ");
801 /*******************************************************************************
803 * FUNCTION: AhDisplayDeviceIds
805 * PARAMETERS: Name - Device Hardware ID string.
806 * NULL means "find all"
810 * DESCRIPTION: Display PNP* and ACPI* device IDs.
812 ******************************************************************************/
818 const AH_DEVICE_ID *Info;
822 BOOLEAN Found = FALSE;
825 /* Null input name indicates "display all" */
829 printf ("ACPI and PNP Device/Hardware IDs:\n\n");
830 for (Info = AslDeviceIds; Info->Name; Info++)
832 printf ("%8s %s\n", Info->Name, Info->Description);
838 Length = strlen (Name);
841 printf ("%.8s: Hardware ID must be 8 characters maximum\n", Name);
845 /* Find/display all names that match the input name prefix */
848 for (Info = AslDeviceIds; Info->Name; Info++)
851 for (i = 0; i < Length; i++)
853 if (Info->Name[i] != Name[i])
863 printf ("%8s %s\n", Info->Name, Info->Description);
869 printf ("%s, Hardware ID not found\n", Name);
874 /*******************************************************************************
876 * FUNCTION: AhDisplayUuids
882 * DESCRIPTION: Display all known UUIDs.
884 ******************************************************************************/
893 printf ("ACPI-related UUIDs:\n\n");
895 for (Info = AcpiUuids; Info->Description; Info++)
897 printf ("%32s : %s\n", Info->Description, Info->String);
902 /*******************************************************************************
904 * FUNCTION: AhDecodeException
906 * PARAMETERS: HexString - ACPI status string from command line, in
907 * hex. If null, display all exceptions.
911 * DESCRIPTION: Decode and display an ACPI_STATUS exception code.
913 ******************************************************************************/
919 const ACPI_EXCEPTION_INFO *ExceptionInfo;
925 * A null input string means to decode and display all known
930 printf ("All defined ACPICA exception codes:\n\n");
931 AH_DISPLAY_EXCEPTION (0, "AE_OK (No error occurred)");
933 /* Display codes in each block of exception types */
935 for (i = 1; (i & AE_CODE_MASK) <= AE_CODE_MAX; i += 0x1000)
940 ExceptionInfo = AcpiUtValidateException ((ACPI_STATUS) Status);
943 AH_DISPLAY_EXCEPTION_TEXT (Status, ExceptionInfo);
947 } while (ExceptionInfo);
952 /* Decode a single user-supplied exception code */
954 Status = ACPI_STRTOUL (HexString, NULL, 16);
957 printf ("%s: Invalid hexadecimal exception code value\n", HexString);
961 if (Status > ACPI_UINT16_MAX)
963 AH_DISPLAY_EXCEPTION (Status, "Invalid exception code (more than 16 bits)");
967 ExceptionInfo = AcpiUtValidateException ((ACPI_STATUS) Status);
970 AH_DISPLAY_EXCEPTION (Status, "Unknown exception code");
974 AH_DISPLAY_EXCEPTION_TEXT (Status, ExceptionInfo);