1 /****************************************************************************** 2 * 3 * Module Name: ahdecode - Operator/Opcode decoding for acpihelp utility 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2011, 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 #include "acpihelp.h" 45 46 #define ACPI_CREATE_PREDEFINED_TABLE 47 #include "acpredef.h" 48 49 static char Gbl_Buffer[64]; 50 static const char *AcpiRtypeNames[] = 51 { 52 "/Integer", 53 "/String", 54 "/Buffer", 55 "/Package", 56 "/Reference", 57 }; 58 59 60 /* Local prototypes */ 61 62 static BOOLEAN 63 AhDisplayPredefinedName ( 64 char *Name, 65 UINT32 Length); 66 67 static void 68 AhDisplayPredefinedInfo ( 69 char *Name); 70 71 static void 72 AhGetExpectedTypes ( 73 char *Buffer, 74 UINT32 ExpectedBtypes); 75 76 static void 77 AhDisplayAmlOpcode ( 78 const AH_AML_OPCODE *Op); 79 80 static void 81 AhDisplayAslOperator ( 82 const AH_ASL_OPERATOR *Op); 83 84 static void 85 AhDisplayAslKeyword ( 86 const AH_ASL_KEYWORD *Op); 87 88 static void 89 AhPrintOneField ( 90 UINT32 Indent, 91 UINT32 CurrentPosition, 92 UINT32 MaxPosition, 93 const char *Field); 94 95 96 /******************************************************************************* 97 * 98 * FUNCTION: AhFindPredefinedNames (entry point for predefined name search) 99 * 100 * PARAMETERS: NamePrefix - Name or prefix to find. Must start with 101 * an underscore. NULL means "find all" 102 * 103 * RETURN: None 104 * 105 * DESCRIPTION: Find and display all ACPI predefined names that match the 106 * input name or prefix. Includes the required number of arguments 107 * and the expected return type, if any. 108 * 109 ******************************************************************************/ 110 111 void 112 AhFindPredefinedNames ( 113 char *NamePrefix) 114 { 115 UINT32 Length; 116 BOOLEAN Found; 117 char Name[9]; 118 119 120 if (!NamePrefix) 121 { 122 Found = AhDisplayPredefinedName (Name, 0); 123 return; 124 } 125 126 /* Contruct a local name or name prefix */ 127 128 AhStrupr (NamePrefix); 129 if (*NamePrefix == '_') 130 { 131 NamePrefix++; 132 } 133 134 Name[0] = '_'; 135 strncpy (&Name[1], NamePrefix, 7); 136 137 Length = strlen (Name); 138 if (Length > 4) 139 { 140 printf ("%.8s: Predefined name must be 4 characters maximum\n", Name); 141 return; 142 } 143 144 Found = AhDisplayPredefinedName (Name, Length); 145 if (!Found) 146 { 147 printf ("%s, no matching predefined names\n", Name); 148 } 149 } 150 151 152 /******************************************************************************* 153 * 154 * FUNCTION: AhDisplayPredefinedName 155 * 156 * PARAMETERS: Name - Name or name prefix 157 * 158 * RETURN: TRUE if any names matched, FALSE otherwise 159 * 160 * DESCRIPTION: Display information about ACPI predefined names that match 161 * the input name or name prefix. 162 * 163 ******************************************************************************/ 164 165 static BOOLEAN 166 AhDisplayPredefinedName ( 167 char *Name, 168 UINT32 Length) 169 { 170 const AH_PREDEFINED_NAME *Info; 171 BOOLEAN Found = FALSE; 172 BOOLEAN Matched; 173 UINT32 i; 174 175 176 /* Find/display all names that match the input name prefix */ 177 178 for (Info = AslPredefinedInfo; Info->Name; Info++) 179 { 180 if (!Name) 181 { 182 Found = TRUE; 183 printf ("%s: <%s>\n", Info->Name, Info->Description); 184 printf ("%*s%s\n", 6, " ", Info->Action); 185 186 AhDisplayPredefinedInfo (Info->Name); 187 continue; 188 } 189 190 Matched = TRUE; 191 for (i = 0; i < Length; i++) 192 { 193 if (Info->Name[i] != Name[i]) 194 { 195 Matched = FALSE; 196 break; 197 } 198 } 199 200 if (Matched) 201 { 202 Found = TRUE; 203 printf ("%s: <%s>\n", Info->Name, Info->Description); 204 printf ("%*s%s\n", 6, " ", Info->Action); 205 206 AhDisplayPredefinedInfo (Info->Name); 207 } 208 } 209 210 return (Found); 211 } 212 213 214 /******************************************************************************* 215 * 216 * FUNCTION: AhDisplayPredefinedInfo 217 * 218 * PARAMETERS: Name - Exact 4-character ACPI name. 219 * 220 * RETURN: None 221 * 222 * DESCRIPTION: Find the name in the main ACPICA predefined info table and 223 * display the # of arguments and the return value type. 224 * 225 * Note: Resource Descriptor field names do not appear in this 226 * table -- thus, nothing will be displayed for them. 227 * 228 ******************************************************************************/ 229 230 static void 231 AhDisplayPredefinedInfo ( 232 char *Name) 233 { 234 const ACPI_PREDEFINED_INFO *ThisName; 235 BOOLEAN Matched; 236 UINT32 i; 237 238 239 /* Find/display only the exact input name */ 240 241 for (ThisName = PredefinedNames; ThisName->Info.Name[0]; ThisName++) 242 { 243 Matched = TRUE; 244 for (i = 0; i < ACPI_NAME_SIZE; i++) 245 { 246 if (ThisName->Info.Name[i] != Name[i]) 247 { 248 Matched = FALSE; 249 break; 250 } 251 } 252 253 if (Matched) 254 { 255 AhGetExpectedTypes (Gbl_Buffer, ThisName->Info.ExpectedBtypes); 256 257 printf ("%*s%4.4s has %u arguments, returns: %s\n", 258 6, " ", ThisName->Info.Name, ThisName->Info.ParamCount, 259 ThisName->Info.ExpectedBtypes ? Gbl_Buffer : "-Nothing-"); 260 return; 261 } 262 263 if (ThisName->Info.ExpectedBtypes & ACPI_RTYPE_PACKAGE) 264 { 265 ThisName++; 266 } 267 } 268 } 269 270 271 /******************************************************************************* 272 * 273 * FUNCTION: AhGetExpectedTypes 274 * 275 * PARAMETERS: Buffer - Where the formatted string is returned 276 * ExpectedBTypes - Bitfield of expected data types 277 * 278 * RETURN: Formatted string in Buffer. 279 * 280 * DESCRIPTION: Format the expected object types into a printable string. 281 * 282 ******************************************************************************/ 283 284 static void 285 AhGetExpectedTypes ( 286 char *Buffer, 287 UINT32 ExpectedBtypes) 288 { 289 UINT32 ThisRtype; 290 UINT32 i; 291 UINT32 j; 292 293 294 j = 1; 295 Buffer[0] = 0; 296 ThisRtype = ACPI_RTYPE_INTEGER; 297 298 for (i = 0; i < ACPI_NUM_RTYPES; i++) 299 { 300 /* If one of the expected types, concatenate the name of this type */ 301 302 if (ExpectedBtypes & ThisRtype) 303 { 304 strcat (Buffer, &AcpiRtypeNames[i][j]); 305 j = 0; /* Use name separator from now on */ 306 } 307 ThisRtype <<= 1; /* Next Rtype */ 308 } 309 } 310 311 312 /******************************************************************************* 313 * 314 * FUNCTION: AhFindAmlOpcode (entry point for AML opcode name search) 315 * 316 * PARAMETERS: Name - Name or prefix for an AML opcode. 317 * NULL means "find all" 318 * 319 * RETURN: None 320 * 321 * DESCRIPTION: Find all AML opcodes that match the input Name or name 322 * prefix. 323 * 324 ******************************************************************************/ 325 326 void 327 AhFindAmlOpcode ( 328 char *Name) 329 { 330 const AH_AML_OPCODE *Op; 331 BOOLEAN Found = FALSE; 332 333 334 AhStrupr (Name); 335 336 /* Find/display all opcode names that match the input name prefix */ 337 338 for (Op = AmlOpcodeInfo; Op->OpcodeString; Op++) 339 { 340 if (!Op->OpcodeName) /* Unused opcodes */ 341 { 342 continue; 343 } 344 345 if (!Name) 346 { 347 AhDisplayAmlOpcode (Op); 348 Found = TRUE; 349 continue; 350 } 351 352 /* Upper case the opcode name before substring compare */ 353 354 strcpy (Gbl_Buffer, Op->OpcodeName); 355 AhStrupr (Gbl_Buffer); 356 357 if (strstr (Gbl_Buffer, Name) == Gbl_Buffer) 358 { 359 AhDisplayAmlOpcode (Op); 360 Found = TRUE; 361 } 362 } 363 364 if (!Found) 365 { 366 printf ("%s, no matching AML operators\n", Name); 367 } 368 } 369 370 371 /******************************************************************************* 372 * 373 * FUNCTION: AhDecodeAmlOpcode (entry point for AML opcode search) 374 * 375 * PARAMETERS: OpcodeString - String version of AML opcode 376 * 377 * RETURN: None 378 * 379 * DESCRIPTION: Display information about the input AML opcode 380 * 381 ******************************************************************************/ 382 383 void 384 AhDecodeAmlOpcode ( 385 char *OpcodeString) 386 { 387 const AH_AML_OPCODE *Op; 388 UINT32 Opcode; 389 BOOLEAN Found = FALSE; 390 UINT8 Prefix; 391 392 393 if (!OpcodeString) 394 { 395 AhFindAmlOpcode (NULL); 396 return; 397 } 398 399 Opcode = ACPI_STRTOUL (OpcodeString, NULL, 16); 400 if (Opcode > ACPI_UINT16_MAX) 401 { 402 printf ("Invalid opcode (more than 16 bits)\n"); 403 return; 404 } 405 406 /* Only valid opcode extension is 0x5B */ 407 408 Prefix = (Opcode & 0x0000FF00) >> 8; 409 if (Prefix && (Prefix != 0x5B)) 410 { 411 printf ("Invalid opcode (invalid extension prefix 0x%X)\n", 412 Prefix); 413 return; 414 } 415 416 /* Find/Display the opcode. May fall within an opcode range */ 417 418 for (Op = AmlOpcodeInfo; Op->OpcodeString; Op++) 419 { 420 if ((Opcode >= Op->OpcodeRangeStart) && 421 (Opcode <= Op->OpcodeRangeEnd)) 422 { 423 AhDisplayAmlOpcode (Op); 424 Found = TRUE; 425 } 426 } 427 } 428 429 430 /******************************************************************************* 431 * 432 * FUNCTION: AhDisplayAmlOpcode 433 * 434 * PARAMETERS: Op - An opcode info struct 435 * 436 * RETURN: None 437 * 438 * DESCRIPTION: Display the contents of an AML opcode information struct 439 * 440 ******************************************************************************/ 441 442 static void 443 AhDisplayAmlOpcode ( 444 const AH_AML_OPCODE *Op) 445 { 446 447 if (!Op->OpcodeName) 448 { 449 printf ("%18s: Opcode=%-9s\n", "Reserved opcode", Op->OpcodeString); 450 return; 451 } 452 453 /* Opcode name and value(s) */ 454 455 printf ("%18s: Opcode=%-9s Type (%s)", 456 Op->OpcodeName, Op->OpcodeString, Op->Type); 457 458 /* Optional fixed/static arguments */ 459 460 if (Op->FixedArguments) 461 { 462 printf (" FixedArgs ("); 463 AhPrintOneField (37, 36 + 7 + strlen (Op->Type) + 12, 464 AH_MAX_AML_LINE_LENGTH, Op->FixedArguments); 465 printf (")"); 466 } 467 468 /* Optional variable-length argument list */ 469 470 if (Op->VariableArguments) 471 { 472 if (Op->FixedArguments) 473 { 474 printf ("\n%*s", 36, " "); 475 } 476 printf (" VariableArgs ("); 477 AhPrintOneField (37, 15, AH_MAX_AML_LINE_LENGTH, Op->VariableArguments); 478 printf (")"); 479 } 480 printf ("\n"); 481 482 /* Grammar specification */ 483 484 if (Op->Grammar) 485 { 486 AhPrintOneField (37, 0, AH_MAX_AML_LINE_LENGTH, Op->Grammar); 487 printf ("\n"); 488 } 489 } 490 491 492 /******************************************************************************* 493 * 494 * FUNCTION: AhFindAslKeywords (entry point for ASL keyword search) 495 * 496 * PARAMETERS: Name - Name or prefix for an ASL keyword. 497 * NULL means "find all" 498 * 499 * RETURN: None 500 * 501 * DESCRIPTION: Find all ASL keywords that match the input Name or name 502 * prefix. 503 * 504 ******************************************************************************/ 505 506 void 507 AhFindAslKeywords ( 508 char *Name) 509 { 510 const AH_ASL_KEYWORD *Keyword; 511 BOOLEAN Found = FALSE; 512 513 514 AhStrupr (Name); 515 516 for (Keyword = AslKeywordInfo; Keyword->Name; Keyword++) 517 { 518 if (!Name) 519 { 520 AhDisplayAslKeyword (Keyword); 521 Found = TRUE; 522 continue; 523 } 524 525 /* Upper case the operator name before substring compare */ 526 527 strcpy (Gbl_Buffer, Keyword->Name); 528 AhStrupr (Gbl_Buffer); 529 530 if (strstr (Gbl_Buffer, Name) == Gbl_Buffer) 531 { 532 AhDisplayAslKeyword (Keyword); 533 Found = TRUE; 534 } 535 } 536 537 if (!Found) 538 { 539 printf ("%s, no matching ASL keywords\n", Name); 540 } 541 } 542 543 544 /******************************************************************************* 545 * 546 * FUNCTION: AhDisplayAslKeyword 547 * 548 * PARAMETERS: Op - Pointer to ASL keyword with syntax info 549 * 550 * RETURN: None 551 * 552 * DESCRIPTION: Format and display syntax info for an ASL keyword. Splits 553 * long lines appropriately for reading. 554 * 555 ******************************************************************************/ 556 557 static void 558 AhDisplayAslKeyword ( 559 const AH_ASL_KEYWORD *Op) 560 { 561 562 /* ASL keyword name and description */ 563 564 printf ("%20s: %s\n", Op->Name, Op->Description); 565 if (!Op->KeywordList) 566 { 567 return; 568 } 569 570 /* List of actual keywords */ 571 572 AhPrintOneField (22, 0, AH_MAX_ASL_LINE_LENGTH, Op->KeywordList); 573 printf ("\n"); 574 } 575 576 577 /******************************************************************************* 578 * 579 * FUNCTION: AhFindAslOperators (entry point for ASL operator search) 580 * 581 * PARAMETERS: Name - Name or prefix for an ASL operator. 582 * NULL means "find all" 583 * 584 * RETURN: None 585 * 586 * DESCRIPTION: Find all ASL operators that match the input Name or name 587 * prefix. 588 * 589 ******************************************************************************/ 590 591 void 592 AhFindAslOperators ( 593 char *Name) 594 { 595 const AH_ASL_OPERATOR *Operator; 596 BOOLEAN Found = FALSE; 597 598 599 AhStrupr (Name); 600 601 /* Find/display all names that match the input name prefix */ 602 603 for (Operator = AslOperatorInfo; Operator->Name; Operator++) 604 { 605 if (!Name) 606 { 607 AhDisplayAslOperator (Operator); 608 Found = TRUE; 609 continue; 610 } 611 612 /* Upper case the operator name before substring compare */ 613 614 strcpy (Gbl_Buffer, Operator->Name); 615 AhStrupr (Gbl_Buffer); 616 617 if (strstr (Gbl_Buffer, Name) == Gbl_Buffer) 618 { 619 AhDisplayAslOperator (Operator); 620 Found = TRUE; 621 } 622 } 623 624 if (!Found) 625 { 626 printf ("%s, no matching ASL operators\n", Name); 627 } 628 } 629 630 631 /******************************************************************************* 632 * 633 * FUNCTION: AhDisplayAslOperator 634 * 635 * PARAMETERS: Op - Pointer to ASL operator with syntax info 636 * 637 * RETURN: None 638 * 639 * DESCRIPTION: Format and display syntax info for an ASL operator. Splits 640 * long lines appropriately for reading. 641 * 642 ******************************************************************************/ 643 644 static void 645 AhDisplayAslOperator ( 646 const AH_ASL_OPERATOR *Op) 647 { 648 649 /* ASL operator name and description */ 650 651 printf ("%16s: %s\n", Op->Name, Op->Description); 652 if (!Op->Syntax) 653 { 654 return; 655 } 656 657 /* Syntax for the operator */ 658 659 AhPrintOneField (18, 0, AH_MAX_ASL_LINE_LENGTH, Op->Syntax); 660 printf ("\n"); 661 } 662 663 664 /******************************************************************************* 665 * 666 * FUNCTION: AhPrintOneField 667 * 668 * PARAMETERS: Indent - Indent length for new line(s) 669 * CurrentPosition - Position on current line 670 * MaxPosition - Max allowed line length 671 * Field - Data to output 672 * 673 * RETURN: Line position after field is written 674 * 675 * DESCRIPTION: Split long lines appropriately for ease of reading. 676 * 677 ******************************************************************************/ 678 679 static void 680 AhPrintOneField ( 681 UINT32 Indent, 682 UINT32 CurrentPosition, 683 UINT32 MaxPosition, 684 const char *Field) 685 { 686 UINT32 Position; 687 UINT32 TokenLength; 688 const char *This; 689 const char *Next; 690 const char *Last; 691 692 693 This = Field; 694 Position = CurrentPosition; 695 696 if (Position == 0) 697 { 698 printf ("%*s", (int) Indent, " "); 699 Position = Indent; 700 } 701 702 Last = This + strlen (This); 703 while ((Next = strpbrk (This, " "))) 704 { 705 TokenLength = Next - This; 706 Position += TokenLength; 707 708 /* Split long lines */ 709 710 if (Position > MaxPosition) 711 { 712 printf ("\n%*s", (int) Indent, " "); 713 Position = TokenLength; 714 } 715 716 printf ("%.*s ", (int) TokenLength, This); 717 This = Next + 1; 718 } 719 720 /* Handle last token on the input line */ 721 722 TokenLength = Last - This; 723 if (TokenLength > 0) 724 { 725 Position += TokenLength; 726 if (Position > MaxPosition) 727 { 728 printf ("\n%*s", (int) Indent, " "); 729 } 730 printf ("%s", This); 731 } 732 } 733