xref: /netbsd-src/sys/external/bsd/acpica/dist/tools/acpihelp/ahdecode.c (revision 046a29855e04359424fd074e8313af6b6be8cfb6)
1 /******************************************************************************
2  *
3  * Module Name: ahdecode - Miscellaneous decoding for acpihelp utility
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2023, 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
AhPrintOneField(UINT32 Indent,UINT32 CurrentPosition,UINT32 MaxPosition,const char * Field)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
AhDisplayDirectives(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
AhFindPredefinedNames(char * NamePrefix)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
AhDoSpecialNames(char * Name)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
AhDisplayPredefinedName(char * Name,UINT32 Length)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
AhDisplayPredefinedInfo(char * Name)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
AhDisplayResourceName(const ACPI_PREDEFINED_INFO * ThisName)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
AhDisplayDeviceIds(char * Name)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
AhDisplayUuids(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
AhDisplayTables(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
AhDecodeException(char * HexString)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