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