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