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