diff options
Diffstat (limited to 'tools/acpihelp/ahdecode.c')
| -rw-r--r-- | tools/acpihelp/ahdecode.c | 732 |
1 files changed, 732 insertions, 0 deletions
diff --git a/tools/acpihelp/ahdecode.c b/tools/acpihelp/ahdecode.c new file mode 100644 index 000000000000..aaeae4a03160 --- /dev/null +++ b/tools/acpihelp/ahdecode.c @@ -0,0 +1,732 @@ +/****************************************************************************** + * + * Module Name: ahdecode - Operator/Opcode decoding for acpihelp utility + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2011, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include "acpihelp.h" + +#define ACPI_CREATE_PREDEFINED_TABLE +#include "acpredef.h" + +static char Gbl_Buffer[64]; +static const char *AcpiRtypeNames[] = +{ + "/Integer", + "/String", + "/Buffer", + "/Package", + "/Reference", +}; + + +/* Local prototypes */ + +static BOOLEAN +AhDisplayPredefinedName ( + char *Name, + UINT32 Length); + +static void +AhDisplayPredefinedInfo ( + char *Name); + +static void +AhGetExpectedTypes ( + char *Buffer, + UINT32 ExpectedBtypes); + +static void +AhDisplayAmlOpcode ( + const AH_AML_OPCODE *Op); + +static void +AhDisplayAslOperator ( + const AH_ASL_OPERATOR *Op); + +static void +AhDisplayAslKeyword ( + const AH_ASL_KEYWORD *Op); + +static void +AhPrintOneField ( + UINT32 Indent, + UINT32 CurrentPosition, + UINT32 MaxPosition, + const char *Field); + + +/******************************************************************************* + * + * FUNCTION: AhFindPredefinedNames (entry point for predefined name search) + * + * PARAMETERS: NamePrefix - Name or prefix to find. Must start with + * an underscore. NULL means "find all" + * + * RETURN: None + * + * DESCRIPTION: Find and display all ACPI predefined names that match the + * input name or prefix. Includes the required number of arguments + * and the expected return type, if any. + * + ******************************************************************************/ + +void +AhFindPredefinedNames ( + char *NamePrefix) +{ + UINT32 Length; + BOOLEAN Found; + char Name[9]; + + + if (!NamePrefix) + { + Found = AhDisplayPredefinedName (Name, 0); + return; + } + + /* Contruct a local name or name prefix */ + + AhStrupr (NamePrefix); + if (*NamePrefix == '_') + { + NamePrefix++; + } + + Name[0] = '_'; + strncpy (&Name[1], NamePrefix, 7); + + Length = strlen (Name); + if (Length > 4) + { + printf ("%.8s: Predefined name must be 4 characters maximum\n", Name); + return; + } + + Found = AhDisplayPredefinedName (Name, Length); + if (!Found) + { + printf ("%s, no matching predefined names\n", Name); + } +} + + +/******************************************************************************* + * + * FUNCTION: AhDisplayPredefinedName + * + * PARAMETERS: Name - Name or name prefix + * + * RETURN: TRUE if any names matched, FALSE otherwise + * + * DESCRIPTION: Display information about ACPI predefined names that match + * the input name or name prefix. + * + ******************************************************************************/ + +static BOOLEAN +AhDisplayPredefinedName ( + char *Name, + UINT32 Length) +{ + const AH_PREDEFINED_NAME *Info; + BOOLEAN Found = FALSE; + BOOLEAN Matched; + UINT32 i; + + + /* Find/display all names that match the input name prefix */ + + for (Info = AslPredefinedInfo; Info->Name; Info++) + { + if (!Name) + { + Found = TRUE; + printf ("%s: <%s>\n", Info->Name, Info->Description); + printf ("%*s%s\n", 6, " ", Info->Action); + + AhDisplayPredefinedInfo (Info->Name); + continue; + } + + Matched = TRUE; + for (i = 0; i < Length; i++) + { + if (Info->Name[i] != Name[i]) + { + Matched = FALSE; + break; + } + } + + if (Matched) + { + Found = TRUE; + printf ("%s: <%s>\n", Info->Name, Info->Description); + printf ("%*s%s\n", 6, " ", Info->Action); + + AhDisplayPredefinedInfo (Info->Name); + } + } + + return (Found); +} + + +/******************************************************************************* + * + * FUNCTION: AhDisplayPredefinedInfo + * + * PARAMETERS: Name - Exact 4-character ACPI name. + * + * RETURN: None + * + * DESCRIPTION: Find the name in the main ACPICA predefined info table and + * display the # of arguments and the return value type. + * + * Note: Resource Descriptor field names do not appear in this + * table -- thus, nothing will be displayed for them. + * + ******************************************************************************/ + +static void +AhDisplayPredefinedInfo ( + char *Name) +{ + const ACPI_PREDEFINED_INFO *ThisName; + BOOLEAN Matched; + UINT32 i; + + + /* Find/display only the exact input name */ + + for (ThisName = PredefinedNames; ThisName->Info.Name[0]; ThisName++) + { + Matched = TRUE; + for (i = 0; i < ACPI_NAME_SIZE; i++) + { + if (ThisName->Info.Name[i] != Name[i]) + { + Matched = FALSE; + break; + } + } + + if (Matched) + { + AhGetExpectedTypes (Gbl_Buffer, ThisName->Info.ExpectedBtypes); + + printf ("%*s%4.4s has %u arguments, returns: %s\n", + 6, " ", ThisName->Info.Name, ThisName->Info.ParamCount, + ThisName->Info.ExpectedBtypes ? Gbl_Buffer : "-Nothing-"); + return; + } + + if (ThisName->Info.ExpectedBtypes & ACPI_RTYPE_PACKAGE) + { + ThisName++; + } + } +} + + +/******************************************************************************* + * + * FUNCTION: AhGetExpectedTypes + * + * PARAMETERS: Buffer - Where the formatted string is returned + * ExpectedBTypes - Bitfield of expected data types + * + * RETURN: Formatted string in Buffer. + * + * DESCRIPTION: Format the expected object types into a printable string. + * + ******************************************************************************/ + +static void +AhGetExpectedTypes ( + char *Buffer, + UINT32 ExpectedBtypes) +{ + UINT32 ThisRtype; + UINT32 i; + UINT32 j; + + + j = 1; + Buffer[0] = 0; + ThisRtype = ACPI_RTYPE_INTEGER; + + for (i = 0; i < ACPI_NUM_RTYPES; i++) + { + /* If one of the expected types, concatenate the name of this type */ + + if (ExpectedBtypes & ThisRtype) + { + strcat (Buffer, &AcpiRtypeNames[i][j]); + j = 0; /* Use name separator from now on */ + } + ThisRtype <<= 1; /* Next Rtype */ + } +} + + +/******************************************************************************* + * + * FUNCTION: AhFindAmlOpcode (entry point for AML opcode name search) + * + * PARAMETERS: Name - Name or prefix for an AML opcode. + * NULL means "find all" + * + * RETURN: None + * + * DESCRIPTION: Find all AML opcodes that match the input Name or name + * prefix. + * + ******************************************************************************/ + +void +AhFindAmlOpcode ( + char *Name) +{ + const AH_AML_OPCODE *Op; + BOOLEAN Found = FALSE; + + + AhStrupr (Name); + + /* Find/display all opcode names that match the input name prefix */ + + for (Op = AmlOpcodeInfo; Op->OpcodeString; Op++) + { + if (!Op->OpcodeName) /* Unused opcodes */ + { + continue; + } + + if (!Name) + { + AhDisplayAmlOpcode (Op); + Found = TRUE; + continue; + } + + /* Upper case the opcode name before substring compare */ + + strcpy (Gbl_Buffer, Op->OpcodeName); + AhStrupr (Gbl_Buffer); + + if (strstr (Gbl_Buffer, Name) == Gbl_Buffer) + { + AhDisplayAmlOpcode (Op); + Found = TRUE; + } + } + + if (!Found) + { + printf ("%s, no matching AML operators\n", Name); + } +} + + +/******************************************************************************* + * + * FUNCTION: AhDecodeAmlOpcode (entry point for AML opcode search) + * + * PARAMETERS: OpcodeString - String version of AML opcode + * + * RETURN: None + * + * DESCRIPTION: Display information about the input AML opcode + * + ******************************************************************************/ + +void +AhDecodeAmlOpcode ( + char *OpcodeString) +{ + const AH_AML_OPCODE *Op; + UINT32 Opcode; + BOOLEAN Found = FALSE; + UINT8 Prefix; + + + if (!OpcodeString) + { + AhFindAmlOpcode (NULL); + return; + } + + Opcode = ACPI_STRTOUL (OpcodeString, NULL, 16); + if (Opcode > ACPI_UINT16_MAX) + { + printf ("Invalid opcode (more than 16 bits)\n"); + return; + } + + /* Only valid opcode extension is 0x5B */ + + Prefix = (Opcode & 0x0000FF00) >> 8; + if (Prefix && (Prefix != 0x5B)) + { + printf ("Invalid opcode (invalid extension prefix 0x%X)\n", + Prefix); + return; + } + + /* Find/Display the opcode. May fall within an opcode range */ + + for (Op = AmlOpcodeInfo; Op->OpcodeString; Op++) + { + if ((Opcode >= Op->OpcodeRangeStart) && + (Opcode <= Op->OpcodeRangeEnd)) + { + AhDisplayAmlOpcode (Op); + Found = TRUE; + } + } +} + + +/******************************************************************************* + * + * FUNCTION: AhDisplayAmlOpcode + * + * PARAMETERS: Op - An opcode info struct + * + * RETURN: None + * + * DESCRIPTION: Display the contents of an AML opcode information struct + * + ******************************************************************************/ + +static void +AhDisplayAmlOpcode ( + const AH_AML_OPCODE *Op) +{ + + if (!Op->OpcodeName) + { + printf ("%18s: Opcode=%-9s\n", "Reserved opcode", Op->OpcodeString); + return; + } + + /* Opcode name and value(s) */ + + printf ("%18s: Opcode=%-9s Type (%s)", + Op->OpcodeName, Op->OpcodeString, Op->Type); + + /* Optional fixed/static arguments */ + + if (Op->FixedArguments) + { + printf (" FixedArgs ("); + AhPrintOneField (37, 36 + 7 + strlen (Op->Type) + 12, + AH_MAX_AML_LINE_LENGTH, Op->FixedArguments); + printf (")"); + } + + /* Optional variable-length argument list */ + + if (Op->VariableArguments) + { + if (Op->FixedArguments) + { + printf ("\n%*s", 36, " "); + } + printf (" VariableArgs ("); + AhPrintOneField (37, 15, AH_MAX_AML_LINE_LENGTH, Op->VariableArguments); + printf (")"); + } + printf ("\n"); + + /* Grammar specification */ + + if (Op->Grammar) + { + AhPrintOneField (37, 0, AH_MAX_AML_LINE_LENGTH, Op->Grammar); + printf ("\n"); + } +} + + +/******************************************************************************* + * + * FUNCTION: AhFindAslKeywords (entry point for ASL keyword search) + * + * PARAMETERS: Name - Name or prefix for an ASL keyword. + * NULL means "find all" + * + * RETURN: None + * + * DESCRIPTION: Find all ASL keywords that match the input Name or name + * prefix. + * + ******************************************************************************/ + +void +AhFindAslKeywords ( + char *Name) +{ + const AH_ASL_KEYWORD *Keyword; + BOOLEAN Found = FALSE; + + + AhStrupr (Name); + + for (Keyword = AslKeywordInfo; Keyword->Name; Keyword++) + { + if (!Name) + { + AhDisplayAslKeyword (Keyword); + Found = TRUE; + continue; + } + + /* Upper case the operator name before substring compare */ + + strcpy (Gbl_Buffer, Keyword->Name); + AhStrupr (Gbl_Buffer); + + if (strstr (Gbl_Buffer, Name) == Gbl_Buffer) + { + AhDisplayAslKeyword (Keyword); + Found = TRUE; + } + } + + if (!Found) + { + printf ("%s, no matching ASL keywords\n", Name); + } +} + + +/******************************************************************************* + * + * FUNCTION: AhDisplayAslKeyword + * + * PARAMETERS: Op - Pointer to ASL keyword with syntax info + * + * RETURN: None + * + * DESCRIPTION: Format and display syntax info for an ASL keyword. Splits + * long lines appropriately for reading. + * + ******************************************************************************/ + +static void +AhDisplayAslKeyword ( + const AH_ASL_KEYWORD *Op) +{ + + /* ASL keyword name and description */ + + printf ("%20s: %s\n", Op->Name, Op->Description); + if (!Op->KeywordList) + { + return; + } + + /* List of actual keywords */ + + AhPrintOneField (22, 0, AH_MAX_ASL_LINE_LENGTH, Op->KeywordList); + printf ("\n"); +} + + +/******************************************************************************* + * + * FUNCTION: AhFindAslOperators (entry point for ASL operator search) + * + * PARAMETERS: Name - Name or prefix for an ASL operator. + * NULL means "find all" + * + * RETURN: None + * + * DESCRIPTION: Find all ASL operators that match the input Name or name + * prefix. + * + ******************************************************************************/ + +void +AhFindAslOperators ( + char *Name) +{ + const AH_ASL_OPERATOR *Operator; + BOOLEAN Found = FALSE; + + + AhStrupr (Name); + + /* Find/display all names that match the input name prefix */ + + for (Operator = AslOperatorInfo; Operator->Name; Operator++) + { + if (!Name) + { + AhDisplayAslOperator (Operator); + Found = TRUE; + continue; + } + + /* Upper case the operator name before substring compare */ + + strcpy (Gbl_Buffer, Operator->Name); + AhStrupr (Gbl_Buffer); + + if (strstr (Gbl_Buffer, Name) == Gbl_Buffer) + { + AhDisplayAslOperator (Operator); + Found = TRUE; + } + } + + if (!Found) + { + printf ("%s, no matching ASL operators\n", Name); + } +} + + +/******************************************************************************* + * + * FUNCTION: AhDisplayAslOperator + * + * PARAMETERS: Op - Pointer to ASL operator with syntax info + * + * RETURN: None + * + * DESCRIPTION: Format and display syntax info for an ASL operator. Splits + * long lines appropriately for reading. + * + ******************************************************************************/ + +static void +AhDisplayAslOperator ( + const AH_ASL_OPERATOR *Op) +{ + + /* ASL operator name and description */ + + printf ("%16s: %s\n", Op->Name, Op->Description); + if (!Op->Syntax) + { + return; + } + + /* Syntax for the operator */ + + AhPrintOneField (18, 0, AH_MAX_ASL_LINE_LENGTH, Op->Syntax); + printf ("\n"); +} + + +/******************************************************************************* + * + * FUNCTION: AhPrintOneField + * + * PARAMETERS: Indent - Indent length for new line(s) + * CurrentPosition - Position on current line + * MaxPosition - Max allowed line length + * Field - Data to output + * + * RETURN: Line position after field is written + * + * DESCRIPTION: Split long lines appropriately for ease of reading. + * + ******************************************************************************/ + +static void +AhPrintOneField ( + UINT32 Indent, + UINT32 CurrentPosition, + UINT32 MaxPosition, + const char *Field) +{ + UINT32 Position; + UINT32 TokenLength; + const char *This; + const char *Next; + const char *Last; + + + This = Field; + Position = CurrentPosition; + + if (Position == 0) + { + printf ("%*s", (int) Indent, " "); + Position = Indent; + } + + Last = This + strlen (This); + while ((Next = strpbrk (This, " "))) + { + TokenLength = Next - This; + Position += TokenLength; + + /* Split long lines */ + + if (Position > MaxPosition) + { + printf ("\n%*s", (int) Indent, " "); + Position = TokenLength; + } + + printf ("%.*s ", (int) TokenLength, This); + This = Next + 1; + } + + /* Handle last token on the input line */ + + TokenLength = Last - This; + if (TokenLength > 0) + { + Position += TokenLength; + if (Position > MaxPosition) + { + printf ("\n%*s", (int) Indent, " "); + } + printf ("%s", This); + } +} |
