1 /******************************************************************************
2  *
3  * Module Name: ahdecode - Miscellaneous decoding for acpihelp utility
4  *
5  *****************************************************************************/
6 
7 /******************************************************************************
8  *
9  * 1. Copyright Notice
10  *
11  * Some or all of this work - Copyright (c) 1999 - 2019, Intel Corp.
12  * All rights reserved.
13  *
14  * 2. License
15  *
16  * 2.1. This is your license from Intel Corp. under its intellectual property
17  * rights. You may have additional license terms from the party that provided
18  * you this software, covering your right to use that party's intellectual
19  * property rights.
20  *
21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22  * copy of the source code appearing in this file ("Covered Code") an
23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24  * base code distributed originally by Intel ("Original Intel Code") to copy,
25  * make derivatives, distribute, use and display any portion of the Covered
26  * Code in any form, with the right to sublicense such rights; and
27  *
28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29  * license (with the right to sublicense), under only those claims of Intel
30  * patents that are infringed by the Original Intel Code, to make, use, sell,
31  * offer to sell, and import the Covered Code and derivative works thereof
32  * solely to the minimum extent necessary to exercise the above copyright
33  * license, and in no event shall the patent license extend to any additions
34  * to or modifications of the Original Intel Code. No other license or right
35  * is granted directly or by implication, estoppel or otherwise;
36  *
37  * The above copyright and patent license is granted only if the following
38  * conditions are met:
39  *
40  * 3. Conditions
41  *
42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43  * Redistribution of source code of any substantial portion of the Covered
44  * Code or modification with rights to further distribute source must include
45  * the above Copyright Notice, the above License, this list of Conditions,
46  * and the following Disclaimer and Export Compliance provision. In addition,
47  * Licensee must cause all Covered Code to which Licensee contributes to
48  * contain a file documenting the changes Licensee made to create that Covered
49  * Code and the date of any change. Licensee must include in that file the
50  * documentation of any changes made by any predecessor Licensee. Licensee
51  * must include a prominent statement that the modification is derived,
52  * directly or indirectly, from Original Intel Code.
53  *
54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55  * Redistribution of source code of any substantial portion of the Covered
56  * Code or modification without rights to further distribute source must
57  * include the following Disclaimer and Export Compliance provision in the
58  * documentation and/or other materials provided with distribution. In
59  * addition, Licensee may not authorize further sublicense of source of any
60  * portion of the Covered Code, and must include terms to the effect that the
61  * license from Licensee to its licensee is limited to the intellectual
62  * property embodied in the software Licensee provides to its licensee, and
63  * not to intellectual property embodied in modifications its licensee may
64  * make.
65  *
66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
67  * substantial portion of the Covered Code or modification must reproduce the
68  * above Copyright Notice, and the following Disclaimer and Export Compliance
69  * provision in the documentation and/or other materials provided with the
70  * distribution.
71  *
72  * 3.4. Intel retains all right, title, and interest in and to the Original
73  * Intel Code.
74  *
75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76  * Intel shall be used in advertising or otherwise to promote the sale, use or
77  * other dealings in products derived from or relating to the Covered Code
78  * without prior written authorization from Intel.
79  *
80  * 4. Disclaimer and Export Compliance
81  *
82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88  * PARTICULAR PURPOSE.
89  *
90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97  * LIMITED REMEDY.
98  *
99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
100  * software or system incorporating such software without first obtaining any
101  * required license or other approval from the U. S. Department of Commerce or
102  * any other agency or department of the United States Government. In the
103  * event Licensee exports any such software from the United States or
104  * re-exports any such software from a foreign destination, Licensee shall
105  * ensure that the distribution and export/re-export of the software is in
106  * compliance with all laws, regulations, orders, or other restrictions of the
107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108  * any of its subsidiaries will export/re-export any technical data, process,
109  * software, or service, directly or indirectly, to any country for which the
110  * United States government or any agency thereof requires an export license,
111  * other governmental approval, or letter of assurance, without first obtaining
112  * such license, approval or letter.
113  *
114  *****************************************************************************
115  *
116  * Alternatively, you may choose to be licensed under the terms of the
117  * following license:
118  *
119  * Redistribution and use in source and binary forms, with or without
120  * modification, are permitted provided that the following conditions
121  * are met:
122  * 1. Redistributions of source code must retain the above copyright
123  *    notice, this list of conditions, and the following disclaimer,
124  *    without modification.
125  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126  *    substantially similar to the "NO WARRANTY" disclaimer below
127  *    ("Disclaimer") and any redistribution must be conditioned upon
128  *    including a substantially similar Disclaimer requirement for further
129  *    binary redistribution.
130  * 3. Neither the names of the above-listed copyright holders nor the names
131  *    of any contributors may be used to endorse or promote products derived
132  *    from this software without specific prior written permission.
133  *
134  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145  *
146  * Alternatively, you may choose to be licensed under the terms of the
147  * GNU General Public License ("GPL") version 2 as published by the Free
148  * Software Foundation.
149  *
150  *****************************************************************************/
151 
152 #define ACPI_CREATE_PREDEFINED_TABLE
153 #define ACPI_CREATE_RESOURCE_TABLE
154 
155 #include "acpihelp.h"
156 #include "acpredef.h"
157 
158 
159 /* Local prototypes */
160 
161 static BOOLEAN
162 AhDisplayPredefinedName (
163     char                    *Name,
164     UINT32                  Length);
165 
166 static void
167 AhDisplayPredefinedInfo (
168     char                    *Name);
169 
170 static void
171 AhDoSpecialNames (
172     char                    *Name);
173 
174 static void
175 AhDisplayResourceName (
176     const ACPI_PREDEFINED_INFO  *ThisName);
177 
178 
179 /*******************************************************************************
180  *
181  * FUNCTION:    AhPrintOneField
182  *
183  * PARAMETERS:  Indent              - Indent length for new line(s)
184  *              CurrentPosition     - Position on current line
185  *              MaxPosition         - Max allowed line length
186  *              Field               - Data to output
187  *
188  * RETURN:      Line position after field is written
189  *
190  * DESCRIPTION: Split long lines appropriately for ease of reading.
191  *
192  ******************************************************************************/
193 
194 void
195 AhPrintOneField (
196     UINT32                  Indent,
197     UINT32                  CurrentPosition,
198     UINT32                  MaxPosition,
199     const char              *Field)
200 {
201     UINT32                  Position;
202     UINT32                  TokenLength;
203     const char              *This;
204     const char              *Next;
205     const char              *Last;
206 
207 
208     This = Field;
209     Position = CurrentPosition;
210 
211     if (Position == 0)
212     {
213         printf ("%*s", (int) Indent, " ");
214         Position = Indent;
215     }
216 
217     Last = This + strlen (This);
218     while ((Next = strpbrk (This, " ")))
219     {
220         TokenLength = Next - This;
221         Position += TokenLength;
222 
223         /* Split long lines */
224 
225         if (Position > MaxPosition)
226         {
227             printf ("\n%*s", (int) Indent, " ");
228             Position = TokenLength;
229         }
230 
231         printf ("%.*s ", (int) TokenLength, This);
232         This = Next + 1;
233     }
234 
235     /* Handle last token on the input line */
236 
237     TokenLength = Last - This;
238     if (TokenLength > 0)
239     {
240         Position += TokenLength;
241         if (Position > MaxPosition)
242         {
243             printf ("\n%*s", (int) Indent, " ");
244         }
245 
246         printf ("%s", This);
247     }
248 }
249 
250 
251 /*******************************************************************************
252  *
253  * FUNCTION:    AhDisplayDirectives
254  *
255  * PARAMETERS:  None
256  *
257  * RETURN:      None
258  *
259  * DESCRIPTION: Display all iASL preprocessor directives.
260  *
261  ******************************************************************************/
262 
263 void
264 AhDisplayDirectives (
265     void)
266 {
267     const AH_DIRECTIVE_INFO *Info;
268 
269 
270     printf ("iASL Preprocessor Directives\n\n");
271 
272     for (Info = Gbl_PreprocessorDirectives; Info->Name; Info++)
273     {
274         printf ("  %-36s : %s\n", Info->Name, Info->Description);
275     }
276 }
277 
278 
279 /*******************************************************************************
280  *
281  * FUNCTION:    AhFindPredefinedNames (entry point for predefined name search)
282  *
283  * PARAMETERS:  NamePrefix          - Name or prefix to find. Must start with
284  *                                    an underscore. NULL means "find all"
285  *
286  * RETURN:      None
287  *
288  * DESCRIPTION: Find and display all ACPI predefined names that match the
289  *              input name or prefix. Includes the required number of arguments
290  *              and the expected return type, if any.
291  *
292  ******************************************************************************/
293 
294 void
295 AhFindPredefinedNames (
296     char                    *NamePrefix)
297 {
298     UINT32                  Length;
299     BOOLEAN                 Found;
300     char                    Name[ACPI_NAMESEG_SIZE + 1];
301 
302 
303     if (!NamePrefix || (*NamePrefix == '*'))
304     {
305         Found = AhDisplayPredefinedName (NULL, 0);
306         return;
307     }
308 
309     Length = strlen (NamePrefix);
310     if (Length > ACPI_NAMESEG_SIZE)
311     {
312         printf ("%.8s: Predefined name must be 4 characters maximum\n",
313             NamePrefix);
314         return;
315     }
316 
317     /* Construct a local name or name prefix */
318 
319     AcpiUtStrupr (NamePrefix);
320     if (*NamePrefix == '_')
321     {
322         NamePrefix++;
323     }
324 
325     Name[0] = '_';
326     AcpiUtSafeStrncpy (&Name[1], NamePrefix, 4);
327 
328     /* Check for special names such as _Exx, _ACx, etc. */
329 
330     AhDoSpecialNames (Name);
331 
332     /* Lookup and display the name(s) */
333 
334     Found = AhDisplayPredefinedName (Name, Length);
335     if (!Found)
336     {
337         printf ("%s, no matching predefined names\n", Name);
338     }
339 }
340 
341 
342 /*******************************************************************************
343  *
344  * FUNCTION:    AhDoSpecialNames
345  *
346  * PARAMETERS:  Name          - Name or prefix to find
347  *
348  * RETURN:      None
349  *
350  * DESCRIPTION: Detect and handle the "special" names such as _Exx, _ACx, etc.
351  *
352  * Current support:
353  *  _EJx
354  *  _Exx
355  *  _Lxx
356  *  _Qxx
357  *  _Wxx
358  *  _ACx
359  *  _ALx
360  *  _T_x
361  *
362  ******************************************************************************/
363 
364 static void
365 AhDoSpecialNames (
366     char                    *Name)
367 {
368 
369     /*
370      * Check for the special names that have one or more numeric
371      * suffixes. For example, _Lxx can have 256 different flavors,
372      * from _L00 to _LFF.
373      */
374     switch (Name[1])
375     {
376     case 'E':
377         if (Name[2] == 'J')
378         {
379             if (isdigit (Name[3]) || (Name[3] == 'X'))
380             {
381                 /* _EJx */
382 
383                 Name[3] = 'x';
384                 break;
385             }
386         }
387 
388         /* Fallthrough */
389 
390     case 'L':
391     case 'Q':
392     case 'W':
393         if ((isxdigit (Name[2]) && isxdigit (Name[3]))
394                 ||
395             ((Name[2] == 'X') && (Name[3] == 'X')))
396         {
397             /* _Exx, _Lxx, _Qxx, or _Wxx */
398 
399             Name[2] = 'x';
400             Name[3] = 'x';
401         }
402         break;
403 
404     case 'A':
405         if ((Name[2] == 'C') || (Name[2] == 'L'))
406         {
407             if (isdigit (Name[3]) || (Name[3] == 'X'))
408             {
409                 /* _ACx or _ALx */
410 
411                 Name[3] = 'x';
412             }
413         }
414         break;
415 
416     case 'T':
417         if (Name[2] == '_')
418         {
419             /* _T_x (Reserved for iASL compiler */
420 
421             Name[3] = 'x';
422         }
423         break;
424 
425     default:
426         break;
427     }
428 }
429 
430 
431 /*******************************************************************************
432  *
433  * FUNCTION:    AhDisplayPredefinedName
434  *
435  * PARAMETERS:  Name                - Name or name prefix
436  *
437  * RETURN:      TRUE if any names matched, FALSE otherwise
438  *
439  * DESCRIPTION: Display information about ACPI predefined names that match
440  *              the input name or name prefix.
441  *
442  ******************************************************************************/
443 
444 static BOOLEAN
445 AhDisplayPredefinedName (
446     char                    *Name,
447     UINT32                  Length)
448 {
449     const AH_PREDEFINED_NAME    *Info;
450     BOOLEAN                     Found = FALSE;
451     BOOLEAN                     Matched;
452     UINT32                      i = 0;
453 
454 
455     /* Find/display all names that match the input name prefix */
456 
457     for (Info = AslPredefinedInfo; Info->Name; Info++)
458     {
459         if (!Name)
460         {
461             Found = TRUE;
462             printf ("%s: <%s>\n", Info->Name, Info->Description);
463             printf ("%*s%s\n", 6, " ", Info->Action);
464 
465             AhDisplayPredefinedInfo (Info->Name);
466             i++;
467             continue;
468         }
469 
470         Matched = TRUE;
471         for (i = 0; i < Length; i++)
472         {
473             if (Info->Name[i] != Name[i])
474             {
475                 Matched = FALSE;
476                 break;
477             }
478         }
479 
480         if (Matched)
481         {
482             Found = TRUE;
483             printf ("%s: <%s>\n", Info->Name, Info->Description);
484             printf ("%*s%s\n", 6, " ", Info->Action);
485 
486             AhDisplayPredefinedInfo (Info->Name);
487         }
488     }
489 
490     if (!Name)
491     {
492         printf ("\nFound %d Predefined ACPI Names\n", i);
493     }
494     return (Found);
495 }
496 
497 
498 /*******************************************************************************
499  *
500  * FUNCTION:    AhDisplayPredefinedInfo
501  *
502  * PARAMETERS:  Name                - Exact 4-character ACPI name.
503  *
504  * RETURN:      None
505  *
506  * DESCRIPTION: Find the name in the main ACPICA predefined info table and
507  *              display the # of arguments and the return value type.
508  *
509  *              Note: Resource Descriptor field names do not appear in this
510  *              table -- thus, nothing will be displayed for them.
511  *
512  ******************************************************************************/
513 
514 static void
515 AhDisplayPredefinedInfo (
516     char                        *Name)
517 {
518     const ACPI_PREDEFINED_INFO  *ThisName;
519 
520 
521     /* NOTE: we check both tables always because there are some dupes */
522 
523     /* Check against the predefined methods first */
524 
525     ThisName = AcpiUtMatchPredefinedMethod (Name);
526     if (ThisName)
527     {
528         AcpiUtDisplayPredefinedMethod (Gbl_Buffer, ThisName, TRUE);
529     }
530 
531     /* Check against the predefined resource descriptor names */
532 
533     ThisName = AcpiUtMatchResourceName (Name);
534     if (ThisName)
535     {
536         AhDisplayResourceName (ThisName);
537     }
538 }
539 
540 
541 /*******************************************************************************
542  *
543  * FUNCTION:    AhDisplayResourceName
544  *
545  * PARAMETERS:  ThisName            - Entry in the predefined method/name table
546  *
547  * RETURN:      None
548  *
549  * DESCRIPTION: Display information about a resource descriptor name.
550  *
551  ******************************************************************************/
552 
553 static void
554 AhDisplayResourceName (
555     const ACPI_PREDEFINED_INFO  *ThisName)
556 {
557     UINT32                      NumTypes;
558 
559 
560     NumTypes = AcpiUtGetResourceBitWidth (Gbl_Buffer,
561         ThisName->Info.ArgumentList);
562 
563     printf ("      %4.4s resource descriptor field is %s bits wide%s\n",
564         ThisName->Info.Name,
565         Gbl_Buffer,
566         (NumTypes > 1) ? " (depending on descriptor type)" : "");
567 }
568 
569 
570 /*******************************************************************************
571  *
572  * FUNCTION:    AhDisplayDeviceIds
573  *
574  * PARAMETERS:  Name                - Device Hardware ID string.
575  *                                    NULL means "find all"
576  *
577  * RETURN:      None
578  *
579  * DESCRIPTION: Display PNP* and ACPI* device IDs.
580  *
581  ******************************************************************************/
582 
583 void
584 AhDisplayDeviceIds (
585     char                    *Name)
586 {
587     const AH_DEVICE_ID      *Info;
588     UINT32                  Length;
589     BOOLEAN                 Matched;
590     UINT32                  i;
591     BOOLEAN                 Found = FALSE;
592 
593 
594     /* Null input name indicates "display all" */
595 
596     if (!Name || (Name[0] == '*'))
597     {
598         printf ("ACPI and PNP Device/Hardware IDs:\n\n");
599         for (Info = AslDeviceIds; Info->Name; Info++)
600         {
601             printf ("%8s   %s\n", Info->Name, Info->Description);
602         }
603 
604         return;
605     }
606 
607     Length = strlen (Name);
608     if (Length > 8)
609     {
610         printf ("%.8s: Hardware ID must be 8 characters maximum\n", Name);
611         return;
612     }
613 
614     /* Find/display all names that match the input name prefix */
615 
616     AcpiUtStrupr (Name);
617     for (Info = AslDeviceIds; Info->Name; Info++)
618     {
619         Matched = TRUE;
620         for (i = 0; i < Length; i++)
621         {
622             if (Info->Name[i] != Name[i])
623             {
624                 Matched = FALSE;
625                 break;
626             }
627         }
628 
629         if (Matched)
630         {
631             Found = TRUE;
632             printf ("%8s   %s\n", Info->Name, Info->Description);
633         }
634     }
635 
636     if (!Found)
637     {
638         printf ("%s, Hardware ID not found\n", Name);
639     }
640 }
641 
642 
643 /*******************************************************************************
644  *
645  * FUNCTION:    AhDisplayUuids
646  *
647  * PARAMETERS:  None
648  *
649  * RETURN:      None
650  *
651  * DESCRIPTION: Display all known UUIDs.
652  *
653  ******************************************************************************/
654 
655 void
656 AhDisplayUuids (
657     void)
658 {
659     const AH_UUID           *Info;
660 
661 
662     printf ("ACPI-related UUIDs/GUIDs:\n");
663 
664     /* Display entire table of known ACPI-related UUIDs/GUIDs */
665 
666     for (Info = Gbl_AcpiUuids; Info->Description; Info++)
667     {
668         if (!Info->String) /* Null UUID string means group description */
669         {
670             printf ("\n%36s\n", Info->Description);
671         }
672         else
673         {
674             printf ("%32s : %s\n", Info->Description, Info->String);
675         }
676     }
677 
678     /* Help info on how UUIDs/GUIDs strings are encoded */
679 
680     printf ("\n\nByte encoding of UUID/GUID strings"
681         " into ACPI Buffer objects (use ToUUID from ASL):\n\n");
682 
683     printf ("%32s : %s\n", "Input UUID/GUID String format",
684         "aabbccdd-eeff-gghh-iijj-kkllmmnnoopp");
685 
686     printf ("%32s : %s\n", "Expected output ACPI buffer",
687         "dd,cc,bb,aa, ff,ee, hh,gg, ii,jj, kk,ll,mm,nn,oo,pp");
688 }
689 
690 
691 /*******************************************************************************
692  *
693  * FUNCTION:    AhDisplayTables
694  *
695  * PARAMETERS:  None
696  *
697  * RETURN:      None
698  *
699  * DESCRIPTION: Display all known ACPI tables
700  *
701  ******************************************************************************/
702 
703 void
704 AhDisplayTables (
705     void)
706 {
707     const AH_TABLE          *Info;
708     UINT32                  i = 0;
709 
710 
711     printf ("Known ACPI tables:\n");
712 
713     for (Info = AcpiGbl_SupportedTables; Info->Signature; Info++)
714     {
715         printf ("%8s : %s\n", Info->Signature, Info->Description);
716         i++;
717     }
718 
719     printf ("\nTotal %u ACPI tables\n\n", i);
720 }
721 
722 
723 /*******************************************************************************
724  *
725  * FUNCTION:    AhDecodeException
726  *
727  * PARAMETERS:  HexString           - ACPI status string from command line, in
728  *                                    hex. If null, display all exceptions.
729  *
730  * RETURN:      None
731  *
732  * DESCRIPTION: Decode and display an ACPI_STATUS exception code.
733  *
734  ******************************************************************************/
735 
736 void
737 AhDecodeException (
738     char                    *HexString)
739 {
740     const ACPI_EXCEPTION_INFO   *ExceptionInfo;
741     UINT32                      Status;
742     UINT32                      i;
743 
744 
745     /*
746      * A null input string means to decode and display all known
747      * exception codes.
748      */
749     if (!HexString)
750     {
751         printf ("All defined ACPICA exception codes:\n\n");
752         AH_DISPLAY_EXCEPTION (0,
753             "AE_OK                        (No error occurred)");
754 
755         /* Display codes in each block of exception types */
756 
757         for (i = 1; (i & AE_CODE_MASK) <= AE_CODE_MAX; i += 0x1000)
758         {
759             Status = i;
760             do
761             {
762                 ExceptionInfo = AcpiUtValidateException ((ACPI_STATUS) Status);
763                 if (ExceptionInfo)
764                 {
765                     AH_DISPLAY_EXCEPTION_TEXT (Status, ExceptionInfo);
766                 }
767 
768                 Status++;
769 
770             } while (ExceptionInfo);
771         }
772         return;
773     }
774 
775     /* Decode a single user-supplied exception code */
776 
777     Status = strtoul (HexString, NULL, 16);
778     if (!Status)
779     {
780         printf ("%s: Invalid hexadecimal exception code value\n", HexString);
781         return;
782     }
783 
784     if (Status > ACPI_UINT16_MAX)
785     {
786         AH_DISPLAY_EXCEPTION (Status, "Invalid exception code (more than 16 bits)");
787         return;
788     }
789 
790     ExceptionInfo = AcpiUtValidateException ((ACPI_STATUS) Status);
791     if (!ExceptionInfo)
792     {
793         AH_DISPLAY_EXCEPTION (Status, "Unknown exception code");
794         return;
795     }
796 
797     AH_DISPLAY_EXCEPTION_TEXT (Status, ExceptionInfo);
798 }
799