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