Home | History | Annotate | Line # | Download | only in acpihelp
ahdecode.c revision 1.1.1.1
      1 /******************************************************************************
      2  *
      3  * Module Name: ahdecode - Operator/Opcode decoding for acpihelp utility
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2011, Intel Corp.
      9  * All rights reserved.
     10  *
     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.
     25  *
     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.
     29  *
     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.
     42  */
     43 
     44 #include "acpihelp.h"
     45 
     46 #define ACPI_CREATE_PREDEFINED_TABLE
     47 #include "acpredef.h"
     48 
     49 static char         Gbl_Buffer[64];
     50 static const char   *AcpiRtypeNames[] =
     51 {
     52     "/Integer",
     53     "/String",
     54     "/Buffer",
     55     "/Package",
     56     "/Reference",
     57 };
     58 
     59 
     60 /* Local prototypes */
     61 
     62 static BOOLEAN
     63 AhDisplayPredefinedName (
     64     char                    *Name,
     65     UINT32                  Length);
     66 
     67 static void
     68 AhDisplayPredefinedInfo (
     69     char                    *Name);
     70 
     71 static void
     72 AhGetExpectedTypes (
     73     char                    *Buffer,
     74     UINT32                  ExpectedBtypes);
     75 
     76 static void
     77 AhDisplayAmlOpcode (
     78     const AH_AML_OPCODE     *Op);
     79 
     80 static void
     81 AhDisplayAslOperator (
     82     const AH_ASL_OPERATOR   *Op);
     83 
     84 static void
     85 AhDisplayAslKeyword (
     86     const AH_ASL_KEYWORD    *Op);
     87 
     88 static void
     89 AhPrintOneField (
     90     UINT32                  Indent,
     91     UINT32                  CurrentPosition,
     92     UINT32                  MaxPosition,
     93     const char              *Field);
     94 
     95 
     96 /*******************************************************************************
     97  *
     98  * FUNCTION:    AhFindPredefinedNames (entry point for predefined name search)
     99  *
    100  * PARAMETERS:  NamePrefix          - Name or prefix to find. Must start with
    101  *                                    an underscore. NULL means "find all"
    102  *
    103  * RETURN:      None
    104  *
    105  * DESCRIPTION: Find and display all ACPI predefined names that match the
    106  *              input name or prefix. Includes the required number of arguments
    107  *              and the expected return type, if any.
    108  *
    109  ******************************************************************************/
    110 
    111 void
    112 AhFindPredefinedNames (
    113     char                    *NamePrefix)
    114 {
    115     UINT32                  Length;
    116     BOOLEAN                 Found;
    117     char                    Name[9];
    118 
    119 
    120     if (!NamePrefix)
    121     {
    122         Found = AhDisplayPredefinedName (Name, 0);
    123         return;
    124     }
    125 
    126     /* Contruct a local name or name prefix */
    127 
    128     AhStrupr (NamePrefix);
    129     if (*NamePrefix == '_')
    130     {
    131         NamePrefix++;
    132     }
    133 
    134     Name[0] = '_';
    135     strncpy (&Name[1], NamePrefix, 7);
    136 
    137     Length = strlen (Name);
    138     if (Length > 4)
    139     {
    140         printf ("%.8s: Predefined name must be 4 characters maximum\n", Name);
    141         return;
    142     }
    143 
    144     Found = AhDisplayPredefinedName (Name, Length);
    145     if (!Found)
    146     {
    147         printf ("%s, no matching predefined names\n", Name);
    148     }
    149 }
    150 
    151 
    152 /*******************************************************************************
    153  *
    154  * FUNCTION:    AhDisplayPredefinedName
    155  *
    156  * PARAMETERS:  Name                - Name or name prefix
    157  *
    158  * RETURN:      TRUE if any names matched, FALSE otherwise
    159  *
    160  * DESCRIPTION: Display information about ACPI predefined names that match
    161  *              the input name or name prefix.
    162  *
    163  ******************************************************************************/
    164 
    165 static BOOLEAN
    166 AhDisplayPredefinedName (
    167     char                    *Name,
    168     UINT32                  Length)
    169 {
    170     const AH_PREDEFINED_NAME    *Info;
    171     BOOLEAN                     Found = FALSE;
    172     BOOLEAN                     Matched;
    173     UINT32                      i;
    174 
    175 
    176     /* Find/display all names that match the input name prefix */
    177 
    178     for (Info = AslPredefinedInfo; Info->Name; Info++)
    179     {
    180         if (!Name)
    181         {
    182             Found = TRUE;
    183             printf ("%s: <%s>\n", Info->Name, Info->Description);
    184             printf ("%*s%s\n", 6, " ", Info->Action);
    185 
    186             AhDisplayPredefinedInfo (Info->Name);
    187             continue;
    188         }
    189 
    190         Matched = TRUE;
    191         for (i = 0; i < Length; i++)
    192         {
    193             if (Info->Name[i] != Name[i])
    194             {
    195                 Matched = FALSE;
    196                 break;
    197             }
    198         }
    199 
    200         if (Matched)
    201         {
    202             Found = TRUE;
    203             printf ("%s: <%s>\n", Info->Name, Info->Description);
    204             printf ("%*s%s\n", 6, " ", Info->Action);
    205 
    206             AhDisplayPredefinedInfo (Info->Name);
    207         }
    208     }
    209 
    210     return (Found);
    211 }
    212 
    213 
    214 /*******************************************************************************
    215  *
    216  * FUNCTION:    AhDisplayPredefinedInfo
    217  *
    218  * PARAMETERS:  Name                - Exact 4-character ACPI name.
    219  *
    220  * RETURN:      None
    221  *
    222  * DESCRIPTION: Find the name in the main ACPICA predefined info table and
    223  *              display the # of arguments and the return value type.
    224  *
    225  *              Note: Resource Descriptor field names do not appear in this
    226  *              table -- thus, nothing will be displayed for them.
    227  *
    228  ******************************************************************************/
    229 
    230 static void
    231 AhDisplayPredefinedInfo (
    232     char                    *Name)
    233 {
    234     const ACPI_PREDEFINED_INFO  *ThisName;
    235     BOOLEAN                     Matched;
    236     UINT32                      i;
    237 
    238 
    239     /* Find/display only the exact input name */
    240 
    241     for (ThisName = PredefinedNames; ThisName->Info.Name[0]; ThisName++)
    242     {
    243         Matched = TRUE;
    244         for (i = 0; i < ACPI_NAME_SIZE; i++)
    245         {
    246             if (ThisName->Info.Name[i] != Name[i])
    247             {
    248                 Matched = FALSE;
    249                 break;
    250             }
    251         }
    252 
    253         if (Matched)
    254         {
    255             AhGetExpectedTypes (Gbl_Buffer, ThisName->Info.ExpectedBtypes);
    256 
    257             printf ("%*s%4.4s has %u arguments, returns: %s\n",
    258                 6, " ", ThisName->Info.Name, ThisName->Info.ParamCount,
    259                 ThisName->Info.ExpectedBtypes ? Gbl_Buffer : "-Nothing-");
    260             return;
    261         }
    262 
    263         if (ThisName->Info.ExpectedBtypes & ACPI_RTYPE_PACKAGE)
    264         {
    265             ThisName++;
    266         }
    267     }
    268 }
    269 
    270 
    271 /*******************************************************************************
    272  *
    273  * FUNCTION:    AhGetExpectedTypes
    274  *
    275  * PARAMETERS:  Buffer              - Where the formatted string is returned
    276  *              ExpectedBTypes      - Bitfield of expected data types
    277  *
    278  * RETURN:      Formatted string in Buffer.
    279  *
    280  * DESCRIPTION: Format the expected object types into a printable string.
    281  *
    282  ******************************************************************************/
    283 
    284 static void
    285 AhGetExpectedTypes (
    286     char                    *Buffer,
    287     UINT32                  ExpectedBtypes)
    288 {
    289     UINT32                  ThisRtype;
    290     UINT32                  i;
    291     UINT32                  j;
    292 
    293 
    294     j = 1;
    295     Buffer[0] = 0;
    296     ThisRtype = ACPI_RTYPE_INTEGER;
    297 
    298     for (i = 0; i < ACPI_NUM_RTYPES; i++)
    299     {
    300         /* If one of the expected types, concatenate the name of this type */
    301 
    302         if (ExpectedBtypes & ThisRtype)
    303         {
    304             strcat (Buffer, &AcpiRtypeNames[i][j]);
    305             j = 0;              /* Use name separator from now on */
    306         }
    307         ThisRtype <<= 1;    /* Next Rtype */
    308     }
    309 }
    310 
    311 
    312 /*******************************************************************************
    313  *
    314  * FUNCTION:    AhFindAmlOpcode (entry point for AML opcode name search)
    315  *
    316  * PARAMETERS:  Name                - Name or prefix for an AML opcode.
    317  *                                    NULL means "find all"
    318  *
    319  * RETURN:      None
    320  *
    321  * DESCRIPTION: Find all AML opcodes that match the input Name or name
    322  *              prefix.
    323  *
    324  ******************************************************************************/
    325 
    326 void
    327 AhFindAmlOpcode (
    328     char                    *Name)
    329 {
    330     const AH_AML_OPCODE     *Op;
    331     BOOLEAN                 Found = FALSE;
    332 
    333 
    334     AhStrupr (Name);
    335 
    336     /* Find/display all opcode names that match the input name prefix */
    337 
    338     for (Op = AmlOpcodeInfo; Op->OpcodeString; Op++)
    339     {
    340         if (!Op->OpcodeName) /* Unused opcodes */
    341         {
    342             continue;
    343         }
    344 
    345         if (!Name)
    346         {
    347             AhDisplayAmlOpcode (Op);
    348             Found = TRUE;
    349             continue;
    350         }
    351 
    352         /* Upper case the opcode name before substring compare */
    353 
    354         strcpy (Gbl_Buffer, Op->OpcodeName);
    355         AhStrupr (Gbl_Buffer);
    356 
    357         if (strstr (Gbl_Buffer, Name) == Gbl_Buffer)
    358         {
    359             AhDisplayAmlOpcode (Op);
    360             Found = TRUE;
    361         }
    362     }
    363 
    364     if (!Found)
    365     {
    366         printf ("%s, no matching AML operators\n", Name);
    367     }
    368 }
    369 
    370 
    371 /*******************************************************************************
    372  *
    373  * FUNCTION:    AhDecodeAmlOpcode (entry point for AML opcode search)
    374  *
    375  * PARAMETERS:  OpcodeString        - String version of AML opcode
    376  *
    377  * RETURN:      None
    378  *
    379  * DESCRIPTION: Display information about the input AML opcode
    380  *
    381  ******************************************************************************/
    382 
    383 void
    384 AhDecodeAmlOpcode (
    385     char                    *OpcodeString)
    386 {
    387     const AH_AML_OPCODE     *Op;
    388     UINT32                  Opcode;
    389     BOOLEAN                 Found = FALSE;
    390     UINT8                   Prefix;
    391 
    392 
    393     if (!OpcodeString)
    394     {
    395         AhFindAmlOpcode (NULL);
    396         return;
    397     }
    398 
    399     Opcode = ACPI_STRTOUL (OpcodeString, NULL, 16);
    400     if (Opcode > ACPI_UINT16_MAX)
    401     {
    402         printf ("Invalid opcode (more than 16 bits)\n");
    403         return;
    404     }
    405 
    406     /* Only valid opcode extension is 0x5B */
    407 
    408     Prefix = (Opcode & 0x0000FF00) >> 8;
    409     if (Prefix && (Prefix != 0x5B))
    410     {
    411         printf ("Invalid opcode (invalid extension prefix 0x%X)\n",
    412             Prefix);
    413         return;
    414     }
    415 
    416     /* Find/Display the opcode. May fall within an opcode range */
    417 
    418     for (Op = AmlOpcodeInfo; Op->OpcodeString; Op++)
    419     {
    420         if ((Opcode >= Op->OpcodeRangeStart) &&
    421             (Opcode <= Op->OpcodeRangeEnd))
    422         {
    423             AhDisplayAmlOpcode (Op);
    424             Found = TRUE;
    425         }
    426     }
    427 }
    428 
    429 
    430 /*******************************************************************************
    431  *
    432  * FUNCTION:    AhDisplayAmlOpcode
    433  *
    434  * PARAMETERS:  Op                  - An opcode info struct
    435  *
    436  * RETURN:      None
    437  *
    438  * DESCRIPTION: Display the contents of an AML opcode information struct
    439  *
    440  ******************************************************************************/
    441 
    442 static void
    443 AhDisplayAmlOpcode (
    444     const AH_AML_OPCODE     *Op)
    445 {
    446 
    447     if (!Op->OpcodeName)
    448     {
    449         printf ("%18s: Opcode=%-9s\n", "Reserved opcode", Op->OpcodeString);
    450         return;
    451     }
    452 
    453     /* Opcode name and value(s) */
    454 
    455     printf ("%18s: Opcode=%-9s Type (%s)",
    456         Op->OpcodeName, Op->OpcodeString, Op->Type);
    457 
    458     /* Optional fixed/static arguments */
    459 
    460     if (Op->FixedArguments)
    461     {
    462         printf (" FixedArgs (");
    463         AhPrintOneField (37, 36 + 7 + strlen (Op->Type) + 12,
    464             AH_MAX_AML_LINE_LENGTH, Op->FixedArguments);
    465         printf (")");
    466     }
    467 
    468     /* Optional variable-length argument list */
    469 
    470     if (Op->VariableArguments)
    471     {
    472         if (Op->FixedArguments)
    473         {
    474             printf ("\n%*s", 36, " ");
    475         }
    476         printf (" VariableArgs (");
    477         AhPrintOneField (37, 15, AH_MAX_AML_LINE_LENGTH, Op->VariableArguments);
    478         printf (")");
    479     }
    480     printf ("\n");
    481 
    482     /* Grammar specification */
    483 
    484     if (Op->Grammar)
    485     {
    486         AhPrintOneField (37, 0, AH_MAX_AML_LINE_LENGTH, Op->Grammar);
    487         printf ("\n");
    488     }
    489 }
    490 
    491 
    492 /*******************************************************************************
    493  *
    494  * FUNCTION:    AhFindAslKeywords (entry point for ASL keyword search)
    495  *
    496  * PARAMETERS:  Name                - Name or prefix for an ASL keyword.
    497  *                                    NULL means "find all"
    498  *
    499  * RETURN:      None
    500  *
    501  * DESCRIPTION: Find all ASL keywords that match the input Name or name
    502  *              prefix.
    503  *
    504  ******************************************************************************/
    505 
    506 void
    507 AhFindAslKeywords (
    508     char                    *Name)
    509 {
    510     const AH_ASL_KEYWORD    *Keyword;
    511     BOOLEAN                 Found = FALSE;
    512 
    513 
    514     AhStrupr (Name);
    515 
    516     for (Keyword = AslKeywordInfo; Keyword->Name; Keyword++)
    517     {
    518         if (!Name)
    519         {
    520             AhDisplayAslKeyword (Keyword);
    521             Found = TRUE;
    522             continue;
    523         }
    524 
    525         /* Upper case the operator name before substring compare */
    526 
    527         strcpy (Gbl_Buffer, Keyword->Name);
    528         AhStrupr (Gbl_Buffer);
    529 
    530         if (strstr (Gbl_Buffer, Name) == Gbl_Buffer)
    531         {
    532             AhDisplayAslKeyword (Keyword);
    533             Found = TRUE;
    534         }
    535     }
    536 
    537     if (!Found)
    538     {
    539         printf ("%s, no matching ASL keywords\n", Name);
    540     }
    541 }
    542 
    543 
    544 /*******************************************************************************
    545  *
    546  * FUNCTION:    AhDisplayAslKeyword
    547  *
    548  * PARAMETERS:  Op                  - Pointer to ASL keyword with syntax info
    549  *
    550  * RETURN:      None
    551  *
    552  * DESCRIPTION: Format and display syntax info for an ASL keyword. Splits
    553  *              long lines appropriately for reading.
    554  *
    555  ******************************************************************************/
    556 
    557 static void
    558 AhDisplayAslKeyword (
    559     const AH_ASL_KEYWORD    *Op)
    560 {
    561 
    562     /* ASL keyword name and description */
    563 
    564     printf ("%20s: %s\n", Op->Name, Op->Description);
    565     if (!Op->KeywordList)
    566     {
    567         return;
    568     }
    569 
    570     /* List of actual keywords */
    571 
    572     AhPrintOneField (22, 0, AH_MAX_ASL_LINE_LENGTH, Op->KeywordList);
    573     printf ("\n");
    574 }
    575 
    576 
    577 /*******************************************************************************
    578  *
    579  * FUNCTION:    AhFindAslOperators (entry point for ASL operator search)
    580  *
    581  * PARAMETERS:  Name                - Name or prefix for an ASL operator.
    582  *                                    NULL means "find all"
    583  *
    584  * RETURN:      None
    585  *
    586  * DESCRIPTION: Find all ASL operators that match the input Name or name
    587  *              prefix.
    588  *
    589  ******************************************************************************/
    590 
    591 void
    592 AhFindAslOperators (
    593     char                    *Name)
    594 {
    595     const AH_ASL_OPERATOR   *Operator;
    596     BOOLEAN                 Found = FALSE;
    597 
    598 
    599     AhStrupr (Name);
    600 
    601     /* Find/display all names that match the input name prefix */
    602 
    603     for (Operator = AslOperatorInfo; Operator->Name; Operator++)
    604     {
    605         if (!Name)
    606         {
    607             AhDisplayAslOperator (Operator);
    608             Found = TRUE;
    609             continue;
    610         }
    611 
    612         /* Upper case the operator name before substring compare */
    613 
    614         strcpy (Gbl_Buffer, Operator->Name);
    615         AhStrupr (Gbl_Buffer);
    616 
    617         if (strstr (Gbl_Buffer, Name) == Gbl_Buffer)
    618         {
    619             AhDisplayAslOperator (Operator);
    620             Found = TRUE;
    621         }
    622     }
    623 
    624     if (!Found)
    625     {
    626         printf ("%s, no matching ASL operators\n", Name);
    627     }
    628 }
    629 
    630 
    631 /*******************************************************************************
    632  *
    633  * FUNCTION:    AhDisplayAslOperator
    634  *
    635  * PARAMETERS:  Op                  - Pointer to ASL operator with syntax info
    636  *
    637  * RETURN:      None
    638  *
    639  * DESCRIPTION: Format and display syntax info for an ASL operator. Splits
    640  *              long lines appropriately for reading.
    641  *
    642  ******************************************************************************/
    643 
    644 static void
    645 AhDisplayAslOperator (
    646     const AH_ASL_OPERATOR   *Op)
    647 {
    648 
    649     /* ASL operator name and description */
    650 
    651     printf ("%16s: %s\n", Op->Name, Op->Description);
    652     if (!Op->Syntax)
    653     {
    654         return;
    655     }
    656 
    657     /* Syntax for the operator */
    658 
    659     AhPrintOneField (18, 0, AH_MAX_ASL_LINE_LENGTH, Op->Syntax);
    660     printf ("\n");
    661 }
    662 
    663 
    664 /*******************************************************************************
    665  *
    666  * FUNCTION:    AhPrintOneField
    667  *
    668  * PARAMETERS:  Indent              - Indent length for new line(s)
    669  *              CurrentPosition     - Position on current line
    670  *              MaxPosition         - Max allowed line length
    671  *              Field               - Data to output
    672  *
    673  * RETURN:      Line position after field is written
    674  *
    675  * DESCRIPTION: Split long lines appropriately for ease of reading.
    676  *
    677  ******************************************************************************/
    678 
    679 static void
    680 AhPrintOneField (
    681     UINT32                  Indent,
    682     UINT32                  CurrentPosition,
    683     UINT32                  MaxPosition,
    684     const char              *Field)
    685 {
    686     UINT32                  Position;
    687     UINT32                  TokenLength;
    688     const char              *This;
    689     const char              *Next;
    690     const char              *Last;
    691 
    692 
    693     This = Field;
    694     Position = CurrentPosition;
    695 
    696     if (Position == 0)
    697     {
    698         printf ("%*s", (int) Indent, " ");
    699         Position = Indent;
    700     }
    701 
    702     Last = This + strlen (This);
    703     while ((Next = strpbrk (This, " ")))
    704     {
    705         TokenLength = Next - This;
    706         Position += TokenLength;
    707 
    708         /* Split long lines */
    709 
    710         if (Position > MaxPosition)
    711         {
    712             printf ("\n%*s", (int) Indent, " ");
    713             Position = TokenLength;
    714         }
    715 
    716         printf ("%.*s ", (int) TokenLength, This);
    717         This = Next + 1;
    718     }
    719 
    720     /* Handle last token on the input line */
    721 
    722     TokenLength = Last - This;
    723     if (TokenLength > 0)
    724     {
    725         Position += TokenLength;
    726         if (Position > MaxPosition)
    727         {
    728             printf ("\n%*s", (int) Indent, " ");
    729         }
    730         printf ("%s", This);
    731     }
    732 }
    733