ahdecode.c revision 1.1.1.12 1 /******************************************************************************
2 *
3 * Module Name: ahdecode - Miscellaneous decoding for acpihelp utility
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2019, 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