1 /******************************************************************************
2  *
3  * Module Name: ahdecode - Operator/Opcode decoding for acpihelp utility
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2016, 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 #define AH_DISPLAY_EXCEPTION(Status, Name) \
52     printf ("%.4X: %s\n", Status, Name)
53 
54 #define AH_DISPLAY_EXCEPTION_TEXT(Status, Exception) \
55     printf ("%.4X: %-28s (%s)\n", Status, Exception->Name, Exception->Description)
56 
57 #define BUFFER_LENGTH           128
58 #define LINE_BUFFER_LENGTH      512
59 
60 static char         Gbl_Buffer[BUFFER_LENGTH];
61 static char         Gbl_LineBuffer[LINE_BUFFER_LENGTH];
62 
63 
64 /* Local prototypes */
65 
66 static BOOLEAN
67 AhDisplayPredefinedName (
68     char                    *Name,
69     UINT32                  Length);
70 
71 static void
72 AhDisplayPredefinedInfo (
73     char                    *Name);
74 
75 static void
76 AhDisplayResourceName (
77     const ACPI_PREDEFINED_INFO  *ThisName);
78 
79 static void
80 AhDisplayAmlOpcode (
81     const AH_AML_OPCODE     *Op);
82 
83 static void
84 AhDisplayAmlType (
85     const AH_AML_TYPE       *Op);
86 
87 static void
88 AhDisplayAslOperator (
89     const AH_ASL_OPERATOR   *Op);
90 
91 static void
92 AhDisplayOperatorKeywords (
93     const AH_ASL_OPERATOR   *Op);
94 
95 static void
96 AhDisplayAslKeyword (
97     const AH_ASL_KEYWORD    *Op);
98 
99 static void
100 AhPrintOneField (
101     UINT32                  Indent,
102     UINT32                  CurrentPosition,
103     UINT32                  MaxPosition,
104     const char              *Field);
105 
106 
107 /*******************************************************************************
108  *
109  * FUNCTION:    AhDisplayDirectives
110  *
111  * PARAMETERS:  None
112  *
113  * RETURN:      None
114  *
115  * DESCRIPTION: Display all iASL preprocessor directives.
116  *
117  ******************************************************************************/
118 
119 void
120 AhDisplayDirectives (
121     void)
122 {
123     const AH_DIRECTIVE_INFO *Info;
124 
125 
126     printf ("iASL Preprocessor Directives\n\n");
127 
128     for (Info = PreprocessorDirectives; Info->Name; Info++)
129     {
130         printf ("  %-36s : %s\n", Info->Name, Info->Description);
131     }
132 }
133 
134 
135 /*******************************************************************************
136  *
137  * FUNCTION:    AhFindPredefinedNames (entry point for predefined name search)
138  *
139  * PARAMETERS:  NamePrefix          - Name or prefix to find. Must start with
140  *                                    an underscore. NULL means "find all"
141  *
142  * RETURN:      None
143  *
144  * DESCRIPTION: Find and display all ACPI predefined names that match the
145  *              input name or prefix. Includes the required number of arguments
146  *              and the expected return type, if any.
147  *
148  ******************************************************************************/
149 
150 void
151 AhFindPredefinedNames (
152     char                    *NamePrefix)
153 {
154     UINT32                  Length;
155     BOOLEAN                 Found;
156     char                    Name[9];
157 
158 
159     if (!NamePrefix || (NamePrefix[0] == '*'))
160     {
161         Found = AhDisplayPredefinedName (NULL, 0);
162         return;
163     }
164 
165     /* Contruct a local name or name prefix */
166 
167     AcpiUtStrupr (NamePrefix);
168     if (*NamePrefix == '_')
169     {
170         NamePrefix++;
171     }
172 
173     Name[0] = '_';
174     strncpy (&Name[1], NamePrefix, 7);
175 
176     Length = strlen (Name);
177     if (Length > ACPI_NAME_SIZE)
178     {
179         printf ("%.8s: Predefined name must be 4 characters maximum\n", Name);
180         return;
181     }
182 
183     Found = AhDisplayPredefinedName (Name, Length);
184     if (!Found)
185     {
186         printf ("%s, no matching predefined names\n", Name);
187     }
188 }
189 
190 
191 /*******************************************************************************
192  *
193  * FUNCTION:    AhDisplayPredefinedName
194  *
195  * PARAMETERS:  Name                - Name or name prefix
196  *
197  * RETURN:      TRUE if any names matched, FALSE otherwise
198  *
199  * DESCRIPTION: Display information about ACPI predefined names that match
200  *              the input name or name prefix.
201  *
202  ******************************************************************************/
203 
204 static BOOLEAN
205 AhDisplayPredefinedName (
206     char                    *Name,
207     UINT32                  Length)
208 {
209     const AH_PREDEFINED_NAME    *Info;
210     BOOLEAN                     Found = FALSE;
211     BOOLEAN                     Matched;
212     UINT32                      i = 0;
213 
214 
215     /* Find/display all names that match the input name prefix */
216 
217     for (Info = AslPredefinedInfo; Info->Name; Info++)
218     {
219         if (!Name)
220         {
221             Found = TRUE;
222             printf ("%s: <%s>\n", Info->Name, Info->Description);
223             printf ("%*s%s\n", 6, " ", Info->Action);
224 
225             AhDisplayPredefinedInfo (Info->Name);
226             i++;
227             continue;
228         }
229 
230         Matched = TRUE;
231         for (i = 0; i < Length; i++)
232         {
233             if (Info->Name[i] != Name[i])
234             {
235                 Matched = FALSE;
236                 break;
237             }
238         }
239 
240         if (Matched)
241         {
242             Found = TRUE;
243             printf ("%s: <%s>\n", Info->Name, Info->Description);
244             printf ("%*s%s\n", 6, " ", Info->Action);
245 
246             AhDisplayPredefinedInfo (Info->Name);
247         }
248     }
249 
250     if (!Name)
251     {
252         printf ("\nFound %d Predefined ACPI Names\n", i);
253     }
254     return (Found);
255 }
256 
257 
258 /*******************************************************************************
259  *
260  * FUNCTION:    AhDisplayPredefinedInfo
261  *
262  * PARAMETERS:  Name                - Exact 4-character ACPI name.
263  *
264  * RETURN:      None
265  *
266  * DESCRIPTION: Find the name in the main ACPICA predefined info table and
267  *              display the # of arguments and the return value type.
268  *
269  *              Note: Resource Descriptor field names do not appear in this
270  *              table -- thus, nothing will be displayed for them.
271  *
272  ******************************************************************************/
273 
274 static void
275 AhDisplayPredefinedInfo (
276     char                        *Name)
277 {
278     const ACPI_PREDEFINED_INFO  *ThisName;
279 
280 
281     /* NOTE: we check both tables always because there are some dupes */
282 
283     /* Check against the predefine methods first */
284 
285     ThisName = AcpiUtMatchPredefinedMethod (Name);
286     if (ThisName)
287     {
288         AcpiUtDisplayPredefinedMethod (Gbl_Buffer, ThisName, TRUE);
289     }
290 
291     /* Check against the predefined resource descriptor names */
292 
293     ThisName = AcpiUtMatchResourceName (Name);
294     if (ThisName)
295     {
296         AhDisplayResourceName (ThisName);
297     }
298 }
299 
300 
301 /*******************************************************************************
302  *
303  * FUNCTION:    AhDisplayResourceName
304  *
305  * PARAMETERS:  ThisName            - Entry in the predefined method/name table
306  *
307  * RETURN:      None
308  *
309  * DESCRIPTION: Display information about a resource descriptor name.
310  *
311  ******************************************************************************/
312 
313 static void
314 AhDisplayResourceName (
315     const ACPI_PREDEFINED_INFO  *ThisName)
316 {
317     UINT32                      NumTypes;
318 
319 
320     NumTypes = AcpiUtGetResourceBitWidth (Gbl_Buffer,
321         ThisName->Info.ArgumentList);
322 
323     printf ("      %4.4s resource descriptor field is %s bits wide%s\n",
324         ThisName->Info.Name,
325         Gbl_Buffer,
326         (NumTypes > 1) ? " (depending on descriptor type)" : "");
327 }
328 
329 
330 /*******************************************************************************
331  *
332  * FUNCTION:    AhFindAmlOpcode (entry point for AML opcode name search)
333  *
334  * PARAMETERS:  Name                - Name or prefix for an AML opcode.
335  *                                    NULL means "find all"
336  *
337  * RETURN:      None
338  *
339  * DESCRIPTION: Find all AML opcodes that match the input Name or name
340  *              prefix.
341  *
342  ******************************************************************************/
343 
344 void
345 AhFindAmlOpcode (
346     char                    *Name)
347 {
348     const AH_AML_OPCODE     *Op;
349     BOOLEAN                 Found = FALSE;
350 
351 
352     AcpiUtStrupr (Name);
353 
354     /* Find/display all opcode names that match the input name prefix */
355 
356     for (Op = AmlOpcodeInfo; Op->OpcodeString; Op++)
357     {
358         if (!Op->OpcodeName) /* Unused opcodes */
359         {
360             continue;
361         }
362 
363         if (!Name || (Name[0] == '*'))
364         {
365             AhDisplayAmlOpcode (Op);
366             Found = TRUE;
367             continue;
368         }
369 
370         /* Upper case the opcode name before substring compare */
371 
372         strcpy (Gbl_Buffer, Op->OpcodeName);
373         AcpiUtStrupr (Gbl_Buffer);
374 
375         if (strstr (Gbl_Buffer, Name) == Gbl_Buffer)
376         {
377             AhDisplayAmlOpcode (Op);
378             Found = TRUE;
379         }
380     }
381 
382     if (!Found)
383     {
384         printf ("%s, no matching AML operators\n", Name);
385     }
386 }
387 
388 
389 /*******************************************************************************
390  *
391  * FUNCTION:    AhDecodeAmlOpcode (entry point for AML opcode search)
392  *
393  * PARAMETERS:  OpcodeString        - String version of AML opcode
394  *
395  * RETURN:      None
396  *
397  * DESCRIPTION: Display information about the input AML opcode
398  *
399  ******************************************************************************/
400 
401 void
402 AhDecodeAmlOpcode (
403     char                    *OpcodeString)
404 {
405     const AH_AML_OPCODE     *Op;
406     UINT32                  Opcode;
407     UINT8                   Prefix;
408 
409 
410     if (!OpcodeString)
411     {
412         AhFindAmlOpcode (NULL);
413         return;
414     }
415 
416     Opcode = strtoul (OpcodeString, NULL, 16);
417     if (Opcode > ACPI_UINT16_MAX)
418     {
419         printf ("Invalid opcode (more than 16 bits)\n");
420         return;
421     }
422 
423     /* Only valid opcode extension is 0x5B */
424 
425     Prefix = (Opcode & 0x0000FF00) >> 8;
426     if (Prefix && (Prefix != 0x5B))
427     {
428         printf ("Invalid opcode (invalid extension prefix 0x%X)\n",
429             Prefix);
430         return;
431     }
432 
433     /* Find/Display the opcode. May fall within an opcode range */
434 
435     for (Op = AmlOpcodeInfo; Op->OpcodeString; Op++)
436     {
437         if ((Opcode >= Op->OpcodeRangeStart) &&
438             (Opcode <= Op->OpcodeRangeEnd))
439         {
440             AhDisplayAmlOpcode (Op);
441         }
442     }
443 }
444 
445 
446 /*******************************************************************************
447  *
448  * FUNCTION:    AhDisplayAmlOpcode
449  *
450  * PARAMETERS:  Op                  - An opcode info struct
451  *
452  * RETURN:      None
453  *
454  * DESCRIPTION: Display the contents of an AML opcode information struct
455  *
456  ******************************************************************************/
457 
458 static void
459 AhDisplayAmlOpcode (
460     const AH_AML_OPCODE     *Op)
461 {
462 
463     if (!Op->OpcodeName)
464     {
465         printf ("%18s: Opcode=%-9s\n", "Reserved opcode", Op->OpcodeString);
466         return;
467     }
468 
469     /* Opcode name and value(s) */
470 
471     printf ("%18s: Opcode=%-9s Type (%s)",
472         Op->OpcodeName, Op->OpcodeString, Op->Type);
473 
474     /* Optional fixed/static arguments */
475 
476     if (Op->FixedArguments)
477     {
478         printf (" FixedArgs (");
479         AhPrintOneField (37, 36 + 7 + strlen (Op->Type) + 12,
480             AH_MAX_AML_LINE_LENGTH, Op->FixedArguments);
481         printf (")");
482     }
483 
484     /* Optional variable-length argument list */
485 
486     if (Op->VariableArguments)
487     {
488         if (Op->FixedArguments)
489         {
490             printf ("\n%*s", 36, " ");
491         }
492         printf (" VariableArgs (");
493         AhPrintOneField (37, 15, AH_MAX_AML_LINE_LENGTH, Op->VariableArguments);
494         printf (")");
495     }
496     printf ("\n");
497 
498     /* Grammar specification */
499 
500     if (Op->Grammar)
501     {
502         AhPrintOneField (37, 0, AH_MAX_AML_LINE_LENGTH, Op->Grammar);
503         printf ("\n");
504     }
505 }
506 
507 
508 /*******************************************************************************
509  *
510  * FUNCTION:    AhFindAmlTypes (entry point for AML grammar keyword search)
511  *
512  * PARAMETERS:  Name                - Name or prefix for an AML grammar element.
513  *                                    NULL means "find all"
514  *
515  * RETURN:      None
516  *
517  * DESCRIPTION: Find all AML grammar keywords that match the input Name or name
518  *              prefix.
519  *
520  ******************************************************************************/
521 
522 void
523 AhFindAmlTypes (
524     char                    *Name)
525 {
526     const AH_AML_TYPE       *Keyword;
527     BOOLEAN                 Found = FALSE;
528 
529 
530     AcpiUtStrupr (Name);
531 
532     for (Keyword = AmlTypesInfo; Keyword->Name; Keyword++)
533     {
534         if (!Name)
535         {
536             printf ("    %s\n", Keyword->Name);
537             Found = TRUE;
538             continue;
539         }
540 
541         if (*Name == '*')
542         {
543             AhDisplayAmlType (Keyword);
544             Found = TRUE;
545             continue;
546         }
547 
548         /* Upper case the operator name before substring compare */
549 
550         strcpy (Gbl_Buffer, Keyword->Name);
551         AcpiUtStrupr (Gbl_Buffer);
552 
553         if (strstr (Gbl_Buffer, Name) == Gbl_Buffer)
554         {
555             AhDisplayAmlType (Keyword);
556             Found = TRUE;
557         }
558     }
559 
560     if (!Found)
561     {
562         printf ("%s, no matching AML grammar type\n", Name);
563     }
564 }
565 
566 
567 /*******************************************************************************
568  *
569  * FUNCTION:    AhDisplayAmlType
570  *
571  * PARAMETERS:  Op                  - Pointer to AML grammar info
572  *
573  * RETURN:      None
574  *
575  * DESCRIPTION: Format and display info for an AML grammar element.
576  *
577  ******************************************************************************/
578 
579 static void
580 AhDisplayAmlType (
581     const AH_AML_TYPE       *Op)
582 {
583     char                    *Description;
584 
585 
586     Description = Op->Description;
587     printf ("%4s", " ");    /* Primary indent */
588 
589     /* Emit the entire description string */
590 
591     while (*Description)
592     {
593         /* Description can be multiple lines, must indent each */
594 
595         while (*Description != '\n')
596         {
597             printf ("%c", *Description);
598             Description++;
599         }
600 
601         printf ("\n");
602         Description++;
603 
604         /* Do indent */
605 
606         if (*Description)
607         {
608             printf ("%8s", " ");    /* Secondary indent */
609 
610             /* Index extra for a comment */
611 
612             if ((Description[0] == '/') &&
613                 (Description[1] == '/'))
614             {
615                 printf ("%4s", " ");
616             }
617         }
618     }
619 
620     printf ("\n");
621 }
622 
623 
624 /*******************************************************************************
625  *
626  * FUNCTION:    AhFindAslKeywords (entry point for ASL keyword search)
627  *
628  * PARAMETERS:  Name                - Name or prefix for an ASL keyword.
629  *                                    NULL means "find all"
630  *
631  * RETURN:      None
632  *
633  * DESCRIPTION: Find all ASL keywords that match the input Name or name
634  *              prefix.
635  *
636  ******************************************************************************/
637 
638 void
639 AhFindAslKeywords (
640     char                    *Name)
641 {
642     const AH_ASL_KEYWORD    *Keyword;
643     BOOLEAN                 Found = FALSE;
644 
645 
646     AcpiUtStrupr (Name);
647 
648     for (Keyword = AslKeywordInfo; Keyword->Name; Keyword++)
649     {
650         if (!Name || (Name[0] == '*'))
651         {
652             AhDisplayAslKeyword (Keyword);
653             Found = TRUE;
654             continue;
655         }
656 
657         /* Upper case the operator name before substring compare */
658 
659         strcpy (Gbl_Buffer, Keyword->Name);
660         AcpiUtStrupr (Gbl_Buffer);
661 
662         if (strstr (Gbl_Buffer, Name) == Gbl_Buffer)
663         {
664             AhDisplayAslKeyword (Keyword);
665             Found = TRUE;
666         }
667     }
668 
669     if (!Found)
670     {
671         printf ("%s, no matching ASL keywords\n", Name);
672     }
673 }
674 
675 
676 /*******************************************************************************
677  *
678  * FUNCTION:    AhDisplayAslKeyword
679  *
680  * PARAMETERS:  Op                  - Pointer to ASL keyword with syntax info
681  *
682  * RETURN:      None
683  *
684  * DESCRIPTION: Format and display syntax info for an ASL keyword. Splits
685  *              long lines appropriately for reading.
686  *
687  ******************************************************************************/
688 
689 static void
690 AhDisplayAslKeyword (
691     const AH_ASL_KEYWORD    *Op)
692 {
693 
694     /* ASL keyword name and description */
695 
696     printf ("%22s: %s\n", Op->Name, Op->Description);
697     if (!Op->KeywordList)
698     {
699         return;
700     }
701 
702     /* List of actual keywords */
703 
704     AhPrintOneField (24, 0, AH_MAX_ASL_LINE_LENGTH, Op->KeywordList);
705     printf ("\n");
706 }
707 
708 
709 /*******************************************************************************
710  *
711  * FUNCTION:    AhFindAslAndAmlOperators
712  *
713  * PARAMETERS:  Name                - Name or prefix for an ASL operator.
714  *                                    NULL means "find all"
715  *
716  * RETURN:      None
717  *
718  * DESCRIPTION: Find all ASL operators that match the input Name or name
719  *              prefix. Also displays the AML information if only one entry
720  *              matches.
721  *
722  ******************************************************************************/
723 
724 void
725 AhFindAslAndAmlOperators (
726     char                    *Name)
727 {
728     UINT32                  MatchCount;
729 
730 
731     MatchCount = AhFindAslOperators (Name);
732     if (MatchCount == 1)
733     {
734         AhFindAmlOpcode (Name);
735     }
736 }
737 
738 
739 /*******************************************************************************
740  *
741  * FUNCTION:    AhFindAslOperators (entry point for ASL operator search)
742  *
743  * PARAMETERS:  Name                - Name or prefix for an ASL operator.
744  *                                    NULL means "find all"
745  *
746  * RETURN:      Number of operators that matched the name prefix.
747  *
748  * DESCRIPTION: Find all ASL operators that match the input Name or name
749  *              prefix.
750  *
751  ******************************************************************************/
752 
753 UINT32
754 AhFindAslOperators (
755     char                    *Name)
756 {
757     const AH_ASL_OPERATOR   *Operator;
758     BOOLEAN                 MatchCount = 0;
759 
760 
761     AcpiUtStrupr (Name);
762 
763     /* Find/display all names that match the input name prefix */
764 
765     for (Operator = AslOperatorInfo; Operator->Name; Operator++)
766     {
767         if (!Name || (Name[0] == '*'))
768         {
769             AhDisplayAslOperator (Operator);
770             MatchCount++;
771             continue;
772         }
773 
774         /* Upper case the operator name before substring compare */
775 
776         strcpy (Gbl_Buffer, Operator->Name);
777         AcpiUtStrupr (Gbl_Buffer);
778 
779         if (strstr (Gbl_Buffer, Name) == Gbl_Buffer)
780         {
781             AhDisplayAslOperator (Operator);
782             MatchCount++;
783         }
784     }
785 
786     if (!MatchCount)
787     {
788         printf ("%s, no matching ASL operators\n", Name);
789     }
790 
791     return (MatchCount);
792 }
793 
794 
795 /*******************************************************************************
796  *
797  * FUNCTION:    AhDisplayAslOperator
798  *
799  * PARAMETERS:  Op                  - Pointer to ASL operator with syntax info
800  *
801  * RETURN:      None
802  *
803  * DESCRIPTION: Format and display syntax info for an ASL operator. Splits
804  *              long lines appropriately for reading.
805  *
806  ******************************************************************************/
807 
808 static void
809 AhDisplayAslOperator (
810     const AH_ASL_OPERATOR   *Op)
811 {
812 
813     /* ASL operator name and description */
814 
815     printf ("%16s: %s\n", Op->Name, Op->Description);
816     if (!Op->Syntax)
817     {
818         return;
819     }
820 
821     /* Syntax for the operator */
822 
823     AhPrintOneField (18, 0, AH_MAX_ASL_LINE_LENGTH, Op->Syntax);
824     printf ("\n");
825 
826     AhDisplayOperatorKeywords (Op);
827     printf ("\n");
828 }
829 
830 
831 /*******************************************************************************
832  *
833  * FUNCTION:    AhDisplayOperatorKeywords
834  *
835  * PARAMETERS:  Op                  - Pointer to ASL keyword with syntax info
836  *
837  * RETURN:      None
838  *
839  * DESCRIPTION: Display any/all keywords that are associated with the ASL
840  *              operator.
841  *
842  ******************************************************************************/
843 
844 static void
845 AhDisplayOperatorKeywords (
846     const AH_ASL_OPERATOR   *Op)
847 {
848     char                    *Token;
849     char                    *Separators = "(){}, ";
850     BOOLEAN                 FirstKeyword = TRUE;
851 
852 
853     if (!Op || !Op->Syntax)
854     {
855         return;
856     }
857 
858     /*
859      * Find all parameters that have the word "keyword" within, and then
860      * display the info about that keyword
861      */
862     strcpy (Gbl_LineBuffer, Op->Syntax);
863     Token = strtok (Gbl_LineBuffer, Separators);
864     while (Token)
865     {
866         if (strstr (Token, "Keyword"))
867         {
868             if (FirstKeyword)
869             {
870                 printf ("\n");
871                 FirstKeyword = FALSE;
872             }
873 
874             /* Found a keyword, display keyword information */
875 
876             AhFindAslKeywords (Token);
877         }
878 
879         Token = strtok (NULL, Separators);
880     }
881 }
882 
883 
884 /*******************************************************************************
885  *
886  * FUNCTION:    AhPrintOneField
887  *
888  * PARAMETERS:  Indent              - Indent length for new line(s)
889  *              CurrentPosition     - Position on current line
890  *              MaxPosition         - Max allowed line length
891  *              Field               - Data to output
892  *
893  * RETURN:      Line position after field is written
894  *
895  * DESCRIPTION: Split long lines appropriately for ease of reading.
896  *
897  ******************************************************************************/
898 
899 static void
900 AhPrintOneField (
901     UINT32                  Indent,
902     UINT32                  CurrentPosition,
903     UINT32                  MaxPosition,
904     const char              *Field)
905 {
906     UINT32                  Position;
907     UINT32                  TokenLength;
908     const char              *This;
909     const char              *Next;
910     const char              *Last;
911 
912 
913     This = Field;
914     Position = CurrentPosition;
915 
916     if (Position == 0)
917     {
918         printf ("%*s", (int) Indent, " ");
919         Position = Indent;
920     }
921 
922     Last = This + strlen (This);
923     while ((Next = strpbrk (This, " ")))
924     {
925         TokenLength = Next - This;
926         Position += TokenLength;
927 
928         /* Split long lines */
929 
930         if (Position > MaxPosition)
931         {
932             printf ("\n%*s", (int) Indent, " ");
933             Position = TokenLength;
934         }
935 
936         printf ("%.*s ", (int) TokenLength, This);
937         This = Next + 1;
938     }
939 
940     /* Handle last token on the input line */
941 
942     TokenLength = Last - This;
943     if (TokenLength > 0)
944     {
945         Position += TokenLength;
946         if (Position > MaxPosition)
947         {
948             printf ("\n%*s", (int) Indent, " ");
949         }
950 
951         printf ("%s", This);
952     }
953 }
954 
955 
956 /*******************************************************************************
957  *
958  * FUNCTION:    AhDisplayDeviceIds
959  *
960  * PARAMETERS:  Name                - Device Hardware ID string.
961  *                                    NULL means "find all"
962  *
963  * RETURN:      None
964  *
965  * DESCRIPTION: Display PNP* and ACPI* device IDs.
966  *
967  ******************************************************************************/
968 
969 void
970 AhDisplayDeviceIds (
971     char                    *Name)
972 {
973     const AH_DEVICE_ID      *Info;
974     UINT32                  Length;
975     BOOLEAN                 Matched;
976     UINT32                  i;
977     BOOLEAN                 Found = FALSE;
978 
979 
980     /* Null input name indicates "display all" */
981 
982     if (!Name || (Name[0] == '*'))
983     {
984         printf ("ACPI and PNP Device/Hardware IDs:\n\n");
985         for (Info = AslDeviceIds; Info->Name; Info++)
986         {
987             printf ("%8s   %s\n", Info->Name, Info->Description);
988         }
989 
990         return;
991     }
992 
993     Length = strlen (Name);
994     if (Length > 8)
995     {
996         printf ("%.8s: Hardware ID must be 8 characters maximum\n", Name);
997         return;
998     }
999 
1000     /* Find/display all names that match the input name prefix */
1001 
1002     AcpiUtStrupr (Name);
1003     for (Info = AslDeviceIds; Info->Name; Info++)
1004     {
1005         Matched = TRUE;
1006         for (i = 0; i < Length; i++)
1007         {
1008             if (Info->Name[i] != Name[i])
1009             {
1010                 Matched = FALSE;
1011                 break;
1012             }
1013         }
1014 
1015         if (Matched)
1016         {
1017             Found = TRUE;
1018             printf ("%8s   %s\n", Info->Name, Info->Description);
1019         }
1020     }
1021 
1022     if (!Found)
1023     {
1024         printf ("%s, Hardware ID not found\n", Name);
1025     }
1026 }
1027 
1028 
1029 /*******************************************************************************
1030  *
1031  * FUNCTION:    AhDisplayUuids
1032  *
1033  * PARAMETERS:  None
1034  *
1035  * RETURN:      None
1036  *
1037  * DESCRIPTION: Display all known UUIDs.
1038  *
1039  ******************************************************************************/
1040 
1041 void
1042 AhDisplayUuids (
1043     void)
1044 {
1045     const AH_UUID           *Info;
1046 
1047 
1048     printf ("ACPI-related UUIDs/GUIDs:\n");
1049 
1050     /* Display entire table of known ACPI-related UUIDs/GUIDs */
1051 
1052     for (Info = AcpiUuids; Info->Description; Info++)
1053     {
1054         if (!Info->String) /* Null UUID string means group description */
1055         {
1056             printf ("\n%36s\n", Info->Description);
1057         }
1058         else
1059         {
1060             printf ("%32s : %s\n", Info->Description, Info->String);
1061         }
1062     }
1063 
1064     /* Help info on how UUIDs/GUIDs strings are encoded */
1065 
1066     printf ("\n\nByte encoding of UUID/GUID strings"
1067         " into ACPI Buffer objects (use ToUUID from ASL):\n\n");
1068 
1069     printf ("%32s : %s\n", "Input UUID/GUID String format",
1070         "aabbccdd-eeff-gghh-iijj-kkllmmnnoopp");
1071 
1072     printf ("%32s : %s\n", "Expected output ACPI buffer",
1073         "dd,cc,bb,aa, ff,ee, hh,gg, ii,jj, kk,ll,mm,nn,oo,pp");
1074 }
1075 
1076 
1077 /*******************************************************************************
1078  *
1079  * FUNCTION:    AhDisplayTables
1080  *
1081  * PARAMETERS:  None
1082  *
1083  * RETURN:      None
1084  *
1085  * DESCRIPTION: Display all known ACPI tables
1086  *
1087  ******************************************************************************/
1088 
1089 void
1090 AhDisplayTables (
1091     void)
1092 {
1093     const AH_TABLE          *Info;
1094     UINT32                  i = 0;
1095 
1096 
1097     printf ("Known ACPI tables:\n");
1098 
1099     for (Info = AcpiSupportedTables; Info->Signature; Info++)
1100     {
1101         printf ("%8s : %s\n", Info->Signature, Info->Description);
1102         i++;
1103     }
1104 
1105     printf ("\nTotal %u ACPI tables\n\n", i);
1106 }
1107 
1108 
1109 /*******************************************************************************
1110  *
1111  * FUNCTION:    AhDecodeException
1112  *
1113  * PARAMETERS:  HexString           - ACPI status string from command line, in
1114  *                                    hex. If null, display all exceptions.
1115  *
1116  * RETURN:      None
1117  *
1118  * DESCRIPTION: Decode and display an ACPI_STATUS exception code.
1119  *
1120  ******************************************************************************/
1121 
1122 void
1123 AhDecodeException (
1124     char                    *HexString)
1125 {
1126     const ACPI_EXCEPTION_INFO   *ExceptionInfo;
1127     UINT32                      Status;
1128     UINT32                      i;
1129 
1130 
1131     /*
1132      * A null input string means to decode and display all known
1133      * exception codes.
1134      */
1135     if (!HexString)
1136     {
1137         printf ("All defined ACPICA exception codes:\n\n");
1138         AH_DISPLAY_EXCEPTION (0,
1139             "AE_OK                        (No error occurred)");
1140 
1141         /* Display codes in each block of exception types */
1142 
1143         for (i = 1; (i & AE_CODE_MASK) <= AE_CODE_MAX; i += 0x1000)
1144         {
1145             Status = i;
1146             do
1147             {
1148                 ExceptionInfo = AcpiUtValidateException ((ACPI_STATUS) Status);
1149                 if (ExceptionInfo)
1150                 {
1151                     AH_DISPLAY_EXCEPTION_TEXT (Status, ExceptionInfo);
1152                 }
1153 
1154                 Status++;
1155 
1156             } while (ExceptionInfo);
1157         }
1158         return;
1159     }
1160 
1161     /* Decode a single user-supplied exception code */
1162 
1163     Status = strtoul (HexString, NULL, 16);
1164     if (!Status)
1165     {
1166         printf ("%s: Invalid hexadecimal exception code value\n", HexString);
1167         return;
1168     }
1169 
1170     if (Status > ACPI_UINT16_MAX)
1171     {
1172         AH_DISPLAY_EXCEPTION (Status, "Invalid exception code (more than 16 bits)");
1173         return;
1174     }
1175 
1176     ExceptionInfo = AcpiUtValidateException ((ACPI_STATUS) Status);
1177     if (!ExceptionInfo)
1178     {
1179         AH_DISPLAY_EXCEPTION (Status, "Unknown exception code");
1180         return;
1181     }
1182 
1183     AH_DISPLAY_EXCEPTION_TEXT (Status, ExceptionInfo);
1184 }
1185