Home | History | Annotate | Line # | Download | only in acpihelp
ahdecode.c revision 1.1.1.16
      1 /******************************************************************************
      2  *
      3  * Module Name: ahdecode - Miscellaneous decoding for acpihelp utility
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2021, 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 MERCHANTABILITY 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 #define ACPI_CREATE_PREDEFINED_TABLE
     45 #define ACPI_CREATE_RESOURCE_TABLE
     46 
     47 #include "acpihelp.h"
     48 #include "acpredef.h"
     49 
     50 BOOLEAN                  AslGbl_VerboseErrors = TRUE;
     51 
     52 /* Local prototypes */
     53 
     54 static BOOLEAN
     55 AhDisplayPredefinedName (
     56     char                    *Name,
     57     UINT32                  Length);
     58 
     59 static void
     60 AhDisplayPredefinedInfo (
     61     char                    *Name);
     62 
     63 static void
     64 AhDoSpecialNames (
     65     char                    *Name);
     66 
     67 static void
     68 AhDisplayResourceName (
     69     const ACPI_PREDEFINED_INFO  *ThisName);
     70 
     71 
     72 /*******************************************************************************
     73  *
     74  * FUNCTION:    AhPrintOneField
     75  *
     76  * PARAMETERS:  Indent              - Indent length for new line(s)
     77  *              CurrentPosition     - Position on current line
     78  *              MaxPosition         - Max allowed line length
     79  *              Field               - Data to output
     80  *
     81  * RETURN:      Line position after field is written
     82  *
     83  * DESCRIPTION: Split long lines appropriately for ease of reading.
     84  *
     85  ******************************************************************************/
     86 
     87 void
     88 AhPrintOneField (
     89     UINT32                  Indent,
     90     UINT32                  CurrentPosition,
     91     UINT32                  MaxPosition,
     92     const char              *Field)
     93 {
     94     UINT32                  Position;
     95     UINT32                  TokenLength;
     96     const char              *This;
     97     const char              *Next;
     98     const char              *Last;
     99 
    100 
    101     This = Field;
    102     Position = CurrentPosition;
    103 
    104     if (Position == 0)
    105     {
    106         printf ("%*s", (int) Indent, " ");
    107         Position = Indent;
    108     }
    109 
    110     Last = This + strlen (This);
    111     while ((Next = strpbrk (This, " ")))
    112     {
    113         TokenLength = Next - This;
    114         Position += TokenLength;
    115 
    116         /* Split long lines */
    117 
    118         if (Position > MaxPosition)
    119         {
    120             printf ("\n%*s", (int) Indent, " ");
    121             Position = TokenLength;
    122         }
    123 
    124         printf ("%.*s ", (int) TokenLength, This);
    125         This = Next + 1;
    126     }
    127 
    128     /* Handle last token on the input line */
    129 
    130     TokenLength = Last - This;
    131     if (TokenLength > 0)
    132     {
    133         Position += TokenLength;
    134         if (Position > MaxPosition)
    135         {
    136             printf ("\n%*s", (int) Indent, " ");
    137         }
    138 
    139         printf ("%s", This);
    140     }
    141 }
    142 
    143 
    144 /*******************************************************************************
    145  *
    146  * FUNCTION:    AhDisplayDirectives
    147  *
    148  * PARAMETERS:  None
    149  *
    150  * RETURN:      None
    151  *
    152  * DESCRIPTION: Display all iASL preprocessor directives.
    153  *
    154  ******************************************************************************/
    155 
    156 void
    157 AhDisplayDirectives (
    158     void)
    159 {
    160     const AH_DIRECTIVE_INFO *Info;
    161 
    162 
    163     printf ("iASL Preprocessor Directives\n\n");
    164 
    165     for (Info = Gbl_PreprocessorDirectives; Info->Name; Info++)
    166     {
    167         printf ("  %-36s : %s\n", Info->Name, Info->Description);
    168     }
    169 }
    170 
    171 
    172 /*******************************************************************************
    173  *
    174  * FUNCTION:    AhFindPredefinedNames (entry point for predefined name search)
    175  *
    176  * PARAMETERS:  NamePrefix          - Name or prefix to find. Must start with
    177  *                                    an underscore. NULL means "find all"
    178  *
    179  * RETURN:      None
    180  *
    181  * DESCRIPTION: Find and display all ACPI predefined names that match the
    182  *              input name or prefix. Includes the required number of arguments
    183  *              and the expected return type, if any.
    184  *
    185  ******************************************************************************/
    186 
    187 void
    188 AhFindPredefinedNames (
    189     char                    *NamePrefix)
    190 {
    191     UINT32                  Length;
    192     BOOLEAN                 Found;
    193     char                    Name[ACPI_NAMESEG_SIZE + 1];
    194 
    195 
    196     if (!NamePrefix || (*NamePrefix == '*'))
    197     {
    198         (void) AhDisplayPredefinedName (NULL, 0);
    199         return;
    200     }
    201 
    202     Length = strlen (NamePrefix);
    203     if (Length > ACPI_NAMESEG_SIZE)
    204     {
    205         printf ("%.8s: Predefined name must be 4 characters maximum\n",
    206             NamePrefix);
    207         return;
    208     }
    209 
    210     /* Construct a local name or name prefix */
    211 
    212     AcpiUtStrupr (NamePrefix);
    213     if (*NamePrefix == '_')
    214     {
    215         NamePrefix++;
    216     }
    217 
    218     Name[0] = '_';
    219     AcpiUtSafeStrncpy (&Name[1], NamePrefix, 4);
    220 
    221     /* Check for special names such as _Exx, _ACx, etc. */
    222 
    223     AhDoSpecialNames (Name);
    224 
    225     /* Lookup and display the name(s) */
    226 
    227     Found = AhDisplayPredefinedName (Name, Length);
    228     if (!Found)
    229     {
    230         printf ("%s, no matching predefined names\n", Name);
    231     }
    232 }
    233 
    234 
    235 /*******************************************************************************
    236  *
    237  * FUNCTION:    AhDoSpecialNames
    238  *
    239  * PARAMETERS:  Name          - Name or prefix to find
    240  *
    241  * RETURN:      None
    242  *
    243  * DESCRIPTION: Detect and handle the "special" names such as _Exx, _ACx, etc.
    244  *
    245  * Current support:
    246  *  _EJx
    247  *  _Exx
    248  *  _Lxx
    249  *  _Qxx
    250  *  _Wxx
    251  *  _ACx
    252  *  _ALx
    253  *  _T_x
    254  *
    255  ******************************************************************************/
    256 
    257 static void
    258 AhDoSpecialNames (
    259     char                    *Name)
    260 {
    261 
    262     /*
    263      * Check for the special names that have one or more numeric
    264      * suffixes. For example, _Lxx can have 256 different flavors,
    265      * from _L00 to _LFF.
    266      */
    267     switch (Name[1])
    268     {
    269     case 'E':
    270         if (Name[2] == 'J')
    271         {
    272             if (isdigit ((int) Name[3]) || (Name[3] == 'X'))
    273             {
    274                 /* _EJx */
    275 
    276                 Name[3] = 'x';
    277                 break;
    278             }
    279         }
    280 
    281         ACPI_FALLTHROUGH;
    282 
    283     case 'L':
    284     case 'Q':
    285     case 'W':
    286         if ((isxdigit ((int) Name[2]) && isxdigit ((int) Name[3]))
    287                 ||
    288             ((Name[2] == 'X') && (Name[3] == 'X')))
    289         {
    290             /* _Exx, _Lxx, _Qxx, or _Wxx */
    291 
    292             Name[2] = 'x';
    293             Name[3] = 'x';
    294         }
    295         break;
    296 
    297     case 'A':
    298         if ((Name[2] == 'C') || (Name[2] == 'L'))
    299         {
    300             if (isdigit ((int) Name[3]) || (Name[3] == 'X'))
    301             {
    302                 /* _ACx or _ALx */
    303 
    304                 Name[3] = 'x';
    305             }
    306         }
    307         break;
    308 
    309     case 'T':
    310         if (Name[2] == '_')
    311         {
    312             /* _T_x (Reserved for iASL compiler */
    313 
    314             Name[3] = 'x';
    315         }
    316         break;
    317 
    318     default:
    319         break;
    320     }
    321 }
    322 
    323 
    324 /*******************************************************************************
    325  *
    326  * FUNCTION:    AhDisplayPredefinedName
    327  *
    328  * PARAMETERS:  Name                - Name or name prefix
    329  *
    330  * RETURN:      TRUE if any names matched, FALSE otherwise
    331  *
    332  * DESCRIPTION: Display information about ACPI predefined names that match
    333  *              the input name or name prefix.
    334  *
    335  ******************************************************************************/
    336 
    337 static BOOLEAN
    338 AhDisplayPredefinedName (
    339     char                    *Name,
    340     UINT32                  Length)
    341 {
    342     const AH_PREDEFINED_NAME    *Info;
    343     BOOLEAN                     Found = FALSE;
    344     BOOLEAN                     Matched;
    345     UINT32                      i = 0;
    346 
    347 
    348     /* Find/display all names that match the input name prefix */
    349 
    350     for (Info = AslPredefinedInfo; Info->Name; Info++)
    351     {
    352         if (!Name)
    353         {
    354             Found = TRUE;
    355             printf ("%s: <%s>\n", Info->Name, Info->Description);
    356             printf ("%*s%s\n", 6, " ", Info->Action);
    357 
    358             AhDisplayPredefinedInfo (Info->Name);
    359             i++;
    360             continue;
    361         }
    362 
    363         Matched = TRUE;
    364         for (i = 0; i < Length; i++)
    365         {
    366             if (Info->Name[i] != Name[i])
    367             {
    368                 Matched = FALSE;
    369                 break;
    370             }
    371         }
    372 
    373         if (Matched)
    374         {
    375             Found = TRUE;
    376             printf ("%s: <%s>\n", Info->Name, Info->Description);
    377             printf ("%*s%s\n", 6, " ", Info->Action);
    378 
    379             AhDisplayPredefinedInfo (Info->Name);
    380         }
    381     }
    382 
    383     if (!Name)
    384     {
    385         printf ("\nFound %d Predefined ACPI Names\n", i);
    386     }
    387     return (Found);
    388 }
    389 
    390 
    391 /*******************************************************************************
    392  *
    393  * FUNCTION:    AhDisplayPredefinedInfo
    394  *
    395  * PARAMETERS:  Name                - Exact 4-character ACPI name.
    396  *
    397  * RETURN:      None
    398  *
    399  * DESCRIPTION: Find the name in the main ACPICA predefined info table and
    400  *              display the # of arguments and the return value type.
    401  *
    402  *              Note: Resource Descriptor field names do not appear in this
    403  *              table -- thus, nothing will be displayed for them.
    404  *
    405  ******************************************************************************/
    406 
    407 static void
    408 AhDisplayPredefinedInfo (
    409     char                        *Name)
    410 {
    411     const ACPI_PREDEFINED_INFO  *ThisName;
    412 
    413 
    414     /* NOTE: we check both tables always because there are some dupes */
    415 
    416     /* Check against the predefined methods first */
    417 
    418     ThisName = AcpiUtMatchPredefinedMethod (Name);
    419     if (ThisName)
    420     {
    421         AcpiUtDisplayPredefinedMethod (Gbl_Buffer, ThisName, TRUE);
    422     }
    423 
    424     /* Check against the predefined resource descriptor names */
    425 
    426     ThisName = AcpiUtMatchResourceName (Name);
    427     if (ThisName)
    428     {
    429         AhDisplayResourceName (ThisName);
    430     }
    431 }
    432 
    433 
    434 /*******************************************************************************
    435  *
    436  * FUNCTION:    AhDisplayResourceName
    437  *
    438  * PARAMETERS:  ThisName            - Entry in the predefined method/name table
    439  *
    440  * RETURN:      None
    441  *
    442  * DESCRIPTION: Display information about a resource descriptor name.
    443  *
    444  ******************************************************************************/
    445 
    446 static void
    447 AhDisplayResourceName (
    448     const ACPI_PREDEFINED_INFO  *ThisName)
    449 {
    450     UINT32                      NumTypes;
    451 
    452 
    453     NumTypes = AcpiUtGetResourceBitWidth (Gbl_Buffer,
    454         ThisName->Info.ArgumentList);
    455 
    456     printf ("      %4.4s resource descriptor field is %s bits wide%s\n",
    457         ThisName->Info.Name,
    458         Gbl_Buffer,
    459         (NumTypes > 1) ? " (depending on descriptor type)" : "");
    460 }
    461 
    462 
    463 /*******************************************************************************
    464  *
    465  * FUNCTION:    AhDisplayDeviceIds
    466  *
    467  * PARAMETERS:  Name                - Device Hardware ID string.
    468  *                                    NULL means "find all"
    469  *
    470  * RETURN:      None
    471  *
    472  * DESCRIPTION: Display PNP* and ACPI* device IDs.
    473  *
    474  ******************************************************************************/
    475 
    476 void
    477 AhDisplayDeviceIds (
    478     char                    *Name)
    479 {
    480     const AH_DEVICE_ID      *Info;
    481     UINT32                  Length;
    482     BOOLEAN                 Matched;
    483     UINT32                  i;
    484     BOOLEAN                 Found = FALSE;
    485 
    486 
    487     /* Null input name indicates "display all" */
    488 
    489     if (!Name || (Name[0] == '*'))
    490     {
    491         printf ("ACPI and PNP Device/Hardware IDs:\n\n");
    492         for (Info = AslDeviceIds; Info->Name; Info++)
    493         {
    494             printf ("%8s   %s\n", Info->Name, Info->Description);
    495         }
    496 
    497         return;
    498     }
    499 
    500     Length = strlen (Name);
    501     if (Length > 8)
    502     {
    503         printf ("%.8s: Hardware ID must be 8 characters maximum\n", Name);
    504         return;
    505     }
    506 
    507     /* Find/display all names that match the input name prefix */
    508 
    509     AcpiUtStrupr (Name);
    510     for (Info = AslDeviceIds; Info->Name; Info++)
    511     {
    512         Matched = TRUE;
    513         for (i = 0; i < Length; i++)
    514         {
    515             if (Info->Name[i] != Name[i])
    516             {
    517                 Matched = FALSE;
    518                 break;
    519             }
    520         }
    521 
    522         if (Matched)
    523         {
    524             Found = TRUE;
    525             printf ("%8s   %s\n", Info->Name, Info->Description);
    526         }
    527     }
    528 
    529     if (!Found)
    530     {
    531         printf ("%s, Hardware ID not found\n", Name);
    532     }
    533 }
    534 
    535 
    536 /*******************************************************************************
    537  *
    538  * FUNCTION:    AhDisplayUuids
    539  *
    540  * PARAMETERS:  None
    541  *
    542  * RETURN:      None
    543  *
    544  * DESCRIPTION: Display all known UUIDs.
    545  *
    546  ******************************************************************************/
    547 
    548 void
    549 AhDisplayUuids (
    550     void)
    551 {
    552     const AH_UUID           *Info;
    553 
    554 
    555     printf ("ACPI-related UUIDs/GUIDs:\n");
    556 
    557     /* Display entire table of known ACPI-related UUIDs/GUIDs */
    558 
    559     for (Info = Gbl_AcpiUuids; Info->Description; Info++)
    560     {
    561         if (!Info->String) /* Null UUID string means group description */
    562         {
    563             printf ("\n%36s\n", Info->Description);
    564         }
    565         else
    566         {
    567             printf ("%32s : %s\n", Info->Description, Info->String);
    568         }
    569     }
    570 
    571     /* Help info on how UUIDs/GUIDs strings are encoded */
    572 
    573     printf ("\n\nByte encoding of UUID/GUID strings"
    574         " into ACPI Buffer objects (use ToUUID from ASL):\n\n");
    575 
    576     printf ("%32s : %s\n", "Input UUID/GUID String format",
    577         "aabbccdd-eeff-gghh-iijj-kkllmmnnoopp");
    578 
    579     printf ("%32s : %s\n", "Expected output ACPI buffer",
    580         "dd,cc,bb,aa, ff,ee, hh,gg, ii,jj, kk,ll,mm,nn,oo,pp");
    581 }
    582 
    583 
    584 /*******************************************************************************
    585  *
    586  * FUNCTION:    AhDisplayTables
    587  *
    588  * PARAMETERS:  None
    589  *
    590  * RETURN:      None
    591  *
    592  * DESCRIPTION: Display all known ACPI tables
    593  *
    594  ******************************************************************************/
    595 
    596 void
    597 AhDisplayTables (
    598     void)
    599 {
    600     const AH_TABLE          *Info;
    601     UINT32                  i = 0;
    602 
    603 
    604     printf ("Known/Supported ACPI tables:\n");
    605 
    606     for (Info = AcpiGbl_SupportedTables; Info->Signature; Info++)
    607     {
    608         printf ("%8u) %s : %s\n", i + 1, Info->Signature, Info->Description);
    609         i++;
    610     }
    611 
    612     printf ("\nTotal %u ACPI tables\n\n", i);
    613 }
    614 
    615 
    616 /*******************************************************************************
    617  *
    618  * FUNCTION:    AhDecodeException
    619  *
    620  * PARAMETERS:  HexString           - ACPI status string from command line, in
    621  *                                    hex. If null, display all exceptions.
    622  *
    623  * RETURN:      None
    624  *
    625  * DESCRIPTION: Decode and display an ACPI_STATUS exception code.
    626  *
    627  ******************************************************************************/
    628 
    629 void
    630 AhDecodeException (
    631     char                    *HexString)
    632 {
    633     const ACPI_EXCEPTION_INFO   *ExceptionInfo;
    634     UINT32                      Status;
    635     UINT32                      i;
    636 
    637 
    638     /*
    639      * A null input string means to decode and display all known
    640      * exception codes.
    641      */
    642     if (!HexString)
    643     {
    644         printf ("All defined ACPICA exception codes:\n\n");
    645         AH_DISPLAY_EXCEPTION (0,
    646             "AE_OK                        (No error occurred)");
    647 
    648         /* Display codes in each block of exception types */
    649 
    650         for (i = 1; (i & AE_CODE_MASK) <= AE_CODE_MAX; i += 0x1000)
    651         {
    652             Status = i;
    653             do
    654             {
    655                 ExceptionInfo = AcpiUtValidateException ((ACPI_STATUS) Status);
    656                 if (ExceptionInfo)
    657                 {
    658                     AH_DISPLAY_EXCEPTION_TEXT (Status, ExceptionInfo);
    659                 }
    660 
    661                 Status++;
    662 
    663             } while (ExceptionInfo);
    664         }
    665         return;
    666     }
    667 
    668     /* Decode a single user-supplied exception code */
    669 
    670     Status = strtoul (HexString, NULL, 16);
    671     if (!Status)
    672     {
    673         printf ("%s: Invalid hexadecimal exception code value\n", HexString);
    674         return;
    675     }
    676 
    677     if (Status > ACPI_UINT16_MAX)
    678     {
    679         AH_DISPLAY_EXCEPTION (Status, "Invalid exception code (more than 16 bits)");
    680         return;
    681     }
    682 
    683     ExceptionInfo = AcpiUtValidateException ((ACPI_STATUS) Status);
    684     if (!ExceptionInfo)
    685     {
    686         AH_DISPLAY_EXCEPTION (Status, "Unknown exception code");
    687         return;
    688     }
    689 
    690     AH_DISPLAY_EXCEPTION_TEXT (Status, ExceptionInfo);
    691 }
    692