1 /******************************************************************************* 2 * 3 * Module Name: dmbuffer - AML disassembler, buffer and string support 4 * 5 ******************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2016, 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 "acpi.h" 45 #include "accommon.h" 46 #include "acutils.h" 47 #include "acdisasm.h" 48 #include "acparser.h" 49 #include "amlcode.h" 50 #include "acinterp.h" 51 52 53 #ifdef ACPI_DISASSEMBLER 54 55 #define _COMPONENT ACPI_CA_DEBUGGER 56 ACPI_MODULE_NAME ("dmbuffer") 57 58 /* Local prototypes */ 59 60 static void 61 AcpiDmUuid ( 62 ACPI_PARSE_OBJECT *Op); 63 64 static void 65 AcpiDmUnicode ( 66 ACPI_PARSE_OBJECT *Op); 67 68 static void 69 AcpiDmGetHardwareIdType ( 70 ACPI_PARSE_OBJECT *Op); 71 72 static void 73 AcpiDmPldBuffer ( 74 UINT32 Level, 75 UINT8 *ByteData, 76 UINT32 ByteCount); 77 78 79 #define ACPI_BUFFER_BYTES_PER_LINE 8 80 81 82 /* Strings for ToPld */ 83 84 static char *DmPanelList[] = 85 { 86 "TOP", 87 "BOTTOM", 88 "LEFT", 89 "RIGHT", 90 "FRONT", 91 "BACK", 92 "UNKNOWN", 93 NULL 94 }; 95 96 static char *DmVerticalPositionList[] = 97 { 98 "UPPER", 99 "CENTER", 100 "LOWER", 101 NULL 102 }; 103 104 static char *DmHorizontalPositionList[] = 105 { 106 "LEFT", 107 "CENTER", 108 "RIGHT", 109 NULL 110 }; 111 112 static char *DmShapeList[] = 113 { 114 "ROUND", 115 "OVAL", 116 "SQUARE", 117 "VERTICALRECTANGLE", 118 "HORIZONTALRECTANGLE", 119 "VERTICALTRAPEZOID", 120 "HORIZONTALTRAPEZOID", 121 "UNKNOWN", 122 "CHAMFERED", 123 NULL 124 }; 125 126 127 /******************************************************************************* 128 * 129 * FUNCTION: AcpiDmDisasmByteList 130 * 131 * PARAMETERS: Level - Current source code indentation level 132 * ByteData - Pointer to the byte list 133 * ByteCount - Length of the byte list 134 * 135 * RETURN: None 136 * 137 * DESCRIPTION: Dump an AML "ByteList" in Hex format. 8 bytes per line, prefixed 138 * with the hex buffer offset. 139 * 140 ******************************************************************************/ 141 142 void 143 AcpiDmDisasmByteList ( 144 UINT32 Level, 145 UINT8 *ByteData, 146 UINT32 ByteCount) 147 { 148 UINT32 i; 149 UINT32 j; 150 UINT32 CurrentIndex; 151 UINT8 BufChar; 152 153 154 if (!ByteCount) 155 { 156 return; 157 } 158 159 for (i = 0; i < ByteCount; i += ACPI_BUFFER_BYTES_PER_LINE) 160 { 161 /* Line indent and offset prefix for each new line */ 162 163 AcpiDmIndent (Level); 164 if (ByteCount > ACPI_BUFFER_BYTES_PER_LINE) 165 { 166 AcpiOsPrintf ("/* %04X */ ", i); 167 } 168 169 /* Dump the actual hex values */ 170 171 for (j = 0; j < ACPI_BUFFER_BYTES_PER_LINE; j++) 172 { 173 CurrentIndex = i + j; 174 if (CurrentIndex >= ByteCount) 175 { 176 /* Dump fill spaces */ 177 178 AcpiOsPrintf (" "); 179 continue; 180 } 181 182 AcpiOsPrintf (" 0x%2.2X", ByteData[CurrentIndex]); 183 184 /* Add comma if there are more bytes to display */ 185 186 if (CurrentIndex < (ByteCount - 1)) 187 { 188 AcpiOsPrintf (","); 189 } 190 else 191 { 192 AcpiOsPrintf (" "); 193 } 194 } 195 196 /* Dump the ASCII equivalents within a comment */ 197 198 AcpiOsPrintf (" /* "); 199 for (j = 0; j < ACPI_BUFFER_BYTES_PER_LINE; j++) 200 { 201 CurrentIndex = i + j; 202 if (CurrentIndex >= ByteCount) 203 { 204 break; 205 } 206 207 BufChar = ByteData[CurrentIndex]; 208 if (isprint (BufChar)) 209 { 210 AcpiOsPrintf ("%c", BufChar); 211 } 212 else 213 { 214 AcpiOsPrintf ("."); 215 } 216 } 217 218 /* Finished with this line */ 219 220 AcpiOsPrintf (" */\n"); 221 } 222 } 223 224 225 /******************************************************************************* 226 * 227 * FUNCTION: AcpiDmByteList 228 * 229 * PARAMETERS: Info - Parse tree walk info 230 * Op - Byte list op 231 * 232 * RETURN: None 233 * 234 * DESCRIPTION: Dump a buffer byte list, handling the various types of buffers. 235 * Buffer type must be already set in the Op DisasmOpcode. 236 * 237 ******************************************************************************/ 238 239 void 240 AcpiDmByteList ( 241 ACPI_OP_WALK_INFO *Info, 242 ACPI_PARSE_OBJECT *Op) 243 { 244 UINT8 *ByteData; 245 UINT32 ByteCount; 246 247 248 ByteData = Op->Named.Data; 249 ByteCount = (UINT32) Op->Common.Value.Integer; 250 251 /* 252 * The byte list belongs to a buffer, and can be produced by either 253 * a ResourceTemplate, Unicode, quoted string, or a plain byte list. 254 */ 255 switch (Op->Common.Parent->Common.DisasmOpcode) 256 { 257 case ACPI_DASM_RESOURCE: 258 259 AcpiDmResourceTemplate ( 260 Info, Op->Common.Parent, ByteData, ByteCount); 261 break; 262 263 case ACPI_DASM_STRING: 264 265 AcpiDmIndent (Info->Level); 266 AcpiUtPrintString ((char *) ByteData, ACPI_UINT16_MAX); 267 AcpiOsPrintf ("\n"); 268 break; 269 270 case ACPI_DASM_UUID: 271 272 AcpiDmUuid (Op); 273 break; 274 275 case ACPI_DASM_UNICODE: 276 277 AcpiDmUnicode (Op); 278 break; 279 280 case ACPI_DASM_PLD_METHOD: 281 #if 0 282 AcpiDmDisasmByteList (Info->Level, ByteData, ByteCount); 283 #endif 284 AcpiDmPldBuffer (Info->Level, ByteData, ByteCount); 285 break; 286 287 case ACPI_DASM_BUFFER: 288 default: 289 /* 290 * Not a resource, string, or unicode string. 291 * Just dump the buffer 292 */ 293 AcpiDmDisasmByteList (Info->Level, ByteData, ByteCount); 294 break; 295 } 296 } 297 298 299 /******************************************************************************* 300 * 301 * FUNCTION: AcpiDmIsUuidBuffer 302 * 303 * PARAMETERS: Op - Buffer Object to be examined 304 * 305 * RETURN: TRUE if buffer contains a UUID 306 * 307 * DESCRIPTION: Determine if a buffer Op contains a UUID 308 * 309 * To help determine whether the buffer is a UUID versus a raw data buffer, 310 * there a are a couple bytes we can look at: 311 * 312 * xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx 313 * 314 * The variant covered by the UUID specification is indicated by the two most 315 * significant bits of N being 1 0 (i.e., the hexadecimal N will always be 316 * 8, 9, A, or B). 317 * 318 * The variant covered by the UUID specification has five versions. For this 319 * variant, the four bits of M indicates the UUID version (i.e., the 320 * hexadecimal M will be either 1, 2, 3, 4, or 5). 321 * 322 ******************************************************************************/ 323 324 BOOLEAN 325 AcpiDmIsUuidBuffer ( 326 ACPI_PARSE_OBJECT *Op) 327 { 328 UINT8 *ByteData; 329 UINT32 ByteCount; 330 ACPI_PARSE_OBJECT *SizeOp; 331 ACPI_PARSE_OBJECT *NextOp; 332 333 334 /* Buffer size is the buffer argument */ 335 336 SizeOp = Op->Common.Value.Arg; 337 338 /* Next, the initializer byte list to examine */ 339 340 NextOp = SizeOp->Common.Next; 341 if (!NextOp) 342 { 343 return (FALSE); 344 } 345 346 /* Extract the byte list info */ 347 348 ByteData = NextOp->Named.Data; 349 ByteCount = (UINT32) NextOp->Common.Value.Integer; 350 351 /* Byte count must be exactly 16 */ 352 353 if (ByteCount != UUID_BUFFER_LENGTH) 354 { 355 return (FALSE); 356 } 357 358 /* Check for valid "M" and "N" values (see function header above) */ 359 360 if (((ByteData[7] & 0xF0) == 0x00) || /* M={1,2,3,4,5} */ 361 ((ByteData[7] & 0xF0) > 0x50) || 362 ((ByteData[8] & 0xF0) < 0x80) || /* N={8,9,A,B} */ 363 ((ByteData[8] & 0xF0) > 0xB0)) 364 { 365 return (FALSE); 366 } 367 368 /* Ignore the Size argument in the disassembly of this buffer op */ 369 370 SizeOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 371 return (TRUE); 372 } 373 374 375 /******************************************************************************* 376 * 377 * FUNCTION: AcpiDmUuid 378 * 379 * PARAMETERS: Op - Byte List op containing a UUID 380 * 381 * RETURN: None 382 * 383 * DESCRIPTION: Dump a buffer containing a UUID as a standard ASCII string. 384 * 385 * Output Format: 386 * In its canonical form, the UUID is represented by a string containing 32 387 * lowercase hexadecimal digits, displayed in 5 groups separated by hyphens. 388 * The complete form is 8-4-4-4-12 for a total of 36 characters (32 389 * alphanumeric characters representing hex digits and 4 hyphens). In bytes, 390 * 4-2-2-2-6. Example: 391 * 392 * ToUUID ("107ededd-d381-4fd7-8da9-08e9a6c79644") 393 * 394 ******************************************************************************/ 395 396 static void 397 AcpiDmUuid ( 398 ACPI_PARSE_OBJECT *Op) 399 { 400 UINT8 *Data; 401 const char *Description; 402 403 404 Data = ACPI_CAST_PTR (UINT8, Op->Named.Data); 405 406 /* Emit the 36-byte UUID string in the proper format/order */ 407 408 AcpiOsPrintf ( 409 "\"%2.2x%2.2x%2.2x%2.2x-" 410 "%2.2x%2.2x-" 411 "%2.2x%2.2x-" 412 "%2.2x%2.2x-" 413 "%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\")", 414 Data[3], Data[2], Data[1], Data[0], 415 Data[5], Data[4], 416 Data[7], Data[6], 417 Data[8], Data[9], 418 Data[10], Data[11], Data[12], Data[13], Data[14], Data[15]); 419 420 /* Dump the UUID description string if available */ 421 422 Description = AcpiAhMatchUuid (Data); 423 if (Description) 424 { 425 AcpiOsPrintf (" /* %s */", Description); 426 } 427 } 428 429 430 /******************************************************************************* 431 * 432 * FUNCTION: AcpiDmIsUnicodeBuffer 433 * 434 * PARAMETERS: Op - Buffer Object to be examined 435 * 436 * RETURN: TRUE if buffer contains a UNICODE string 437 * 438 * DESCRIPTION: Determine if a buffer Op contains a Unicode string 439 * 440 ******************************************************************************/ 441 442 BOOLEAN 443 AcpiDmIsUnicodeBuffer ( 444 ACPI_PARSE_OBJECT *Op) 445 { 446 UINT8 *ByteData; 447 UINT32 ByteCount; 448 UINT32 WordCount; 449 ACPI_PARSE_OBJECT *SizeOp; 450 ACPI_PARSE_OBJECT *NextOp; 451 UINT32 i; 452 453 454 /* Buffer size is the buffer argument */ 455 456 SizeOp = Op->Common.Value.Arg; 457 458 /* Next, the initializer byte list to examine */ 459 460 NextOp = SizeOp->Common.Next; 461 if (!NextOp) 462 { 463 return (FALSE); 464 } 465 466 /* Extract the byte list info */ 467 468 ByteData = NextOp->Named.Data; 469 ByteCount = (UINT32) NextOp->Common.Value.Integer; 470 WordCount = ACPI_DIV_2 (ByteCount); 471 472 /* 473 * Unicode string must have an even number of bytes and last 474 * word must be zero 475 */ 476 if ((!ByteCount) || 477 (ByteCount < 4) || 478 (ByteCount & 1) || 479 ((UINT16 *) (void *) ByteData)[WordCount - 1] != 0) 480 { 481 return (FALSE); 482 } 483 484 /* For each word, 1st byte must be ascii (1-0x7F), 2nd byte must be zero */ 485 486 for (i = 0; i < (ByteCount - 2); i += 2) 487 { 488 if ((ByteData[i] == 0) || 489 (ByteData[i] > 0x7F) || 490 (ByteData[(ACPI_SIZE) i + 1] != 0)) 491 { 492 return (FALSE); 493 } 494 } 495 496 /* Ignore the Size argument in the disassembly of this buffer op */ 497 498 SizeOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 499 return (TRUE); 500 } 501 502 503 /******************************************************************************* 504 * 505 * FUNCTION: AcpiDmIsStringBuffer 506 * 507 * PARAMETERS: Op - Buffer Object to be examined 508 * 509 * RETURN: TRUE if buffer contains a ASCII string, FALSE otherwise 510 * 511 * DESCRIPTION: Determine if a buffer Op contains a ASCII string 512 * 513 ******************************************************************************/ 514 515 BOOLEAN 516 AcpiDmIsStringBuffer ( 517 ACPI_PARSE_OBJECT *Op) 518 { 519 UINT8 *ByteData; 520 UINT32 ByteCount; 521 ACPI_PARSE_OBJECT *SizeOp; 522 ACPI_PARSE_OBJECT *NextOp; 523 UINT32 i; 524 525 526 /* Buffer size is the buffer argument */ 527 528 SizeOp = Op->Common.Value.Arg; 529 530 /* Next, the initializer byte list to examine */ 531 532 NextOp = SizeOp->Common.Next; 533 if (!NextOp) 534 { 535 return (FALSE); 536 } 537 538 /* Extract the byte list info */ 539 540 ByteData = NextOp->Named.Data; 541 ByteCount = (UINT32) NextOp->Common.Value.Integer; 542 543 /* Last byte must be the null terminator */ 544 545 if ((!ByteCount) || 546 (ByteCount < 2) || 547 (ByteData[ByteCount-1] != 0)) 548 { 549 return (FALSE); 550 } 551 552 for (i = 0; i < (ByteCount - 1); i++) 553 { 554 /* TBD: allow some escapes (non-ascii chars). 555 * they will be handled in the string output routine 556 */ 557 558 if (!isprint (ByteData[i])) 559 { 560 return (FALSE); 561 } 562 } 563 564 return (TRUE); 565 } 566 567 568 /******************************************************************************* 569 * 570 * FUNCTION: AcpiDmIsPldBuffer 571 * 572 * PARAMETERS: Op - Buffer Object to be examined 573 * 574 * RETURN: TRUE if buffer contains a ASCII string, FALSE otherwise 575 * 576 * DESCRIPTION: Determine if a buffer Op contains a _PLD structure 577 * 578 ******************************************************************************/ 579 580 BOOLEAN 581 AcpiDmIsPldBuffer ( 582 ACPI_PARSE_OBJECT *Op) 583 { 584 ACPI_NAMESPACE_NODE *Node; 585 ACPI_PARSE_OBJECT *SizeOp; 586 ACPI_PARSE_OBJECT *ParentOp; 587 588 589 /* Buffer size is the buffer argument */ 590 591 SizeOp = Op->Common.Value.Arg; 592 593 ParentOp = Op->Common.Parent; 594 if (!ParentOp) 595 { 596 return (FALSE); 597 } 598 599 /* Check for form: Name(_PLD, Buffer() {}). Not legal, however */ 600 601 if (ParentOp->Common.AmlOpcode == AML_NAME_OP) 602 { 603 Node = ParentOp->Common.Node; 604 605 if (ACPI_COMPARE_NAME (Node->Name.Ascii, METHOD_NAME__PLD)) 606 { 607 /* Ignore the Size argument in the disassembly of this buffer op */ 608 609 SizeOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 610 return (TRUE); 611 } 612 613 return (FALSE); 614 } 615 616 /* Check for proper form: Name(_PLD, Package() {Buffer() {}}) */ 617 618 if (ParentOp->Common.AmlOpcode == AML_PACKAGE_OP) 619 { 620 ParentOp = ParentOp->Common.Parent; 621 if (!ParentOp) 622 { 623 return (FALSE); 624 } 625 626 if (ParentOp->Common.AmlOpcode == AML_NAME_OP) 627 { 628 Node = ParentOp->Common.Node; 629 630 if (ACPI_COMPARE_NAME (Node->Name.Ascii, METHOD_NAME__PLD)) 631 { 632 /* Ignore the Size argument in the disassembly of this buffer op */ 633 634 SizeOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 635 return (TRUE); 636 } 637 } 638 } 639 640 return (FALSE); 641 } 642 643 644 /******************************************************************************* 645 * 646 * FUNCTION: AcpiDmFindNameByIndex 647 * 648 * PARAMETERS: Index - Index of array to check 649 * List - Array to reference 650 * 651 * RETURN: String from List or empty string 652 * 653 * DESCRIPTION: Finds and returns the char string located at the given index 654 * position in List. 655 * 656 ******************************************************************************/ 657 658 static char * 659 AcpiDmFindNameByIndex ( 660 UINT64 Index, 661 char **List) 662 { 663 char *Str; 664 UINT32 i; 665 666 667 /* Bounds check */ 668 669 Str = List[0]; 670 i = 0; 671 672 while(Str) 673 { 674 i++; 675 Str = List[i]; 676 } 677 678 if (Index >= i) 679 { 680 /* TBD: Add error msg */ 681 682 return (""); 683 } 684 685 return (List[Index]); 686 } 687 688 689 /******************************************************************************* 690 * 691 * FUNCTION: AcpiDmPldBuffer 692 * 693 * PARAMETERS: Level - Current source code indentation level 694 * ByteData - Pointer to the byte list 695 * ByteCount - Length of the byte list 696 * 697 * RETURN: None 698 * 699 * DESCRIPTION: Dump and format the contents of a _PLD buffer object 700 * 701 ******************************************************************************/ 702 703 #define ACPI_PLD_OUTPUT08 "%*.s%-18s = 0x%X,\n", ACPI_MUL_4 (Level), " " 704 #define ACPI_PLD_OUTPUT08P "%*.s%-18s = 0x%X)\n", ACPI_MUL_4 (Level), " " 705 #define ACPI_PLD_OUTPUT16 "%*.s%-18s = 0x%X,\n", ACPI_MUL_4 (Level), " " 706 #define ACPI_PLD_OUTPUT16P "%*.s%-18s = 0x%X)\n", ACPI_MUL_4 (Level), " " 707 #define ACPI_PLD_OUTPUT24 "%*.s%-18s = 0x%X,\n", ACPI_MUL_4 (Level), " " 708 #define ACPI_PLD_OUTPUTSTR "%*.s%-18s = \"%s\",\n", ACPI_MUL_4 (Level), " " 709 710 static void 711 AcpiDmPldBuffer ( 712 UINT32 Level, 713 UINT8 *ByteData, 714 UINT32 ByteCount) 715 { 716 ACPI_PLD_INFO *PldInfo; 717 ACPI_STATUS Status; 718 719 720 /* Check for valid byte count */ 721 722 if (ByteCount < ACPI_PLD_REV1_BUFFER_SIZE) 723 { 724 return; 725 } 726 727 /* Convert _PLD buffer to local _PLD struct */ 728 729 Status = AcpiDecodePldBuffer (ByteData, ByteCount, &PldInfo); 730 if (ACPI_FAILURE (Status)) 731 { 732 return; 733 } 734 735 AcpiOsPrintf ("\n"); 736 737 /* First 32-bit dword */ 738 739 AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_Revision", PldInfo->Revision); 740 AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_IgnoreColor", PldInfo->IgnoreColor); 741 AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_Red", PldInfo->Red); 742 AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_Green", PldInfo->Green); 743 AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_Blue", PldInfo->Blue); 744 745 /* Second 32-bit dword */ 746 747 AcpiOsPrintf (ACPI_PLD_OUTPUT16, "PLD_Width", PldInfo->Width); 748 AcpiOsPrintf (ACPI_PLD_OUTPUT16, "PLD_Height", PldInfo->Height); 749 750 /* Third 32-bit dword */ 751 752 AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_UserVisible", PldInfo->UserVisible); 753 AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_Dock", PldInfo->Dock); 754 AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_Lid", PldInfo->Lid); 755 AcpiOsPrintf (ACPI_PLD_OUTPUTSTR, "PLD_Panel", 756 AcpiDmFindNameByIndex(PldInfo->Panel, DmPanelList)); 757 758 AcpiOsPrintf (ACPI_PLD_OUTPUTSTR, "PLD_VerticalPosition", 759 AcpiDmFindNameByIndex(PldInfo->VerticalPosition, DmVerticalPositionList)); 760 761 AcpiOsPrintf (ACPI_PLD_OUTPUTSTR, "PLD_HorizontalPosition", 762 AcpiDmFindNameByIndex(PldInfo->HorizontalPosition, DmHorizontalPositionList)); 763 764 AcpiOsPrintf (ACPI_PLD_OUTPUTSTR, "PLD_Shape", 765 AcpiDmFindNameByIndex(PldInfo->Shape, DmShapeList)); 766 AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_GroupOrientation", PldInfo->GroupOrientation); 767 768 AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_GroupToken", PldInfo->GroupToken); 769 AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_GroupPosition", PldInfo->GroupPosition); 770 AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_Bay", PldInfo->Bay); 771 772 /* Fourth 32-bit dword */ 773 774 AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_Ejectable", PldInfo->Ejectable); 775 AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_EjectRequired", PldInfo->OspmEjectRequired); 776 AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_CabinetNumber", PldInfo->CabinetNumber); 777 AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_CardCageNumber", PldInfo->CardCageNumber); 778 AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_Reference", PldInfo->Reference); 779 AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_Rotation", PldInfo->Rotation); 780 781 if (ByteCount >= ACPI_PLD_REV2_BUFFER_SIZE) 782 { 783 AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_Order", PldInfo->Order); 784 785 /* Fifth 32-bit dword */ 786 787 AcpiOsPrintf (ACPI_PLD_OUTPUT16, "PLD_VerticalOffset", PldInfo->VerticalOffset); 788 AcpiOsPrintf (ACPI_PLD_OUTPUT16P, "PLD_HorizontalOffset", PldInfo->HorizontalOffset); 789 } 790 else /* Rev 1 buffer */ 791 { 792 AcpiOsPrintf (ACPI_PLD_OUTPUT08P, "PLD_Order", PldInfo->Order); 793 } 794 795 ACPI_FREE (PldInfo); 796 } 797 798 799 /******************************************************************************* 800 * 801 * FUNCTION: AcpiDmUnicode 802 * 803 * PARAMETERS: Op - Byte List op containing Unicode string 804 * 805 * RETURN: None 806 * 807 * DESCRIPTION: Dump Unicode string as a standard ASCII string. (Remove 808 * the extra zero bytes). 809 * 810 ******************************************************************************/ 811 812 static void 813 AcpiDmUnicode ( 814 ACPI_PARSE_OBJECT *Op) 815 { 816 UINT16 *WordData; 817 UINT32 WordCount; 818 UINT32 i; 819 int OutputValue; 820 821 822 /* Extract the buffer info as a WORD buffer */ 823 824 WordData = ACPI_CAST_PTR (UINT16, Op->Named.Data); 825 WordCount = ACPI_DIV_2 (((UINT32) Op->Common.Value.Integer)); 826 827 /* Write every other byte as an ASCII character */ 828 829 AcpiOsPrintf ("\""); 830 for (i = 0; i < (WordCount - 1); i++) 831 { 832 OutputValue = (int) WordData[i]; 833 834 /* Handle values that must be escaped */ 835 836 if ((OutputValue == '\"') || 837 (OutputValue == '\\')) 838 { 839 AcpiOsPrintf ("\\%c", OutputValue); 840 } 841 else if (!isprint (OutputValue)) 842 { 843 AcpiOsPrintf ("\\x%2.2X", OutputValue); 844 } 845 else 846 { 847 AcpiOsPrintf ("%c", OutputValue); 848 } 849 } 850 851 AcpiOsPrintf ("\")"); 852 } 853 854 855 /******************************************************************************* 856 * 857 * FUNCTION: AcpiDmGetHardwareIdType 858 * 859 * PARAMETERS: Op - Op to be examined 860 * 861 * RETURN: None 862 * 863 * DESCRIPTION: Determine the type of the argument to a _HID or _CID 864 * 1) Strings are allowed 865 * 2) If Integer, determine if it is a valid EISAID 866 * 867 ******************************************************************************/ 868 869 static void 870 AcpiDmGetHardwareIdType ( 871 ACPI_PARSE_OBJECT *Op) 872 { 873 UINT32 BigEndianId; 874 UINT32 Prefix[3]; 875 UINT32 i; 876 877 878 switch (Op->Common.AmlOpcode) 879 { 880 case AML_STRING_OP: 881 882 /* Mark this string as an _HID/_CID string */ 883 884 Op->Common.DisasmOpcode = ACPI_DASM_HID_STRING; 885 break; 886 887 case AML_WORD_OP: 888 case AML_DWORD_OP: 889 890 /* Determine if a Word/Dword is a valid encoded EISAID */ 891 892 /* Swap from little-endian to big-endian to simplify conversion */ 893 894 BigEndianId = AcpiUtDwordByteSwap ((UINT32) Op->Common.Value.Integer); 895 896 /* Create the 3 leading ASCII letters */ 897 898 Prefix[0] = ((BigEndianId >> 26) & 0x1F) + 0x40; 899 Prefix[1] = ((BigEndianId >> 21) & 0x1F) + 0x40; 900 Prefix[2] = ((BigEndianId >> 16) & 0x1F) + 0x40; 901 902 /* Verify that all 3 are ascii and alpha */ 903 904 for (i = 0; i < 3; i++) 905 { 906 if (!ACPI_IS_ASCII (Prefix[i]) || 907 !isalpha (Prefix[i])) 908 { 909 return; 910 } 911 } 912 913 /* Mark this node as convertable to an EISA ID string */ 914 915 Op->Common.DisasmOpcode = ACPI_DASM_EISAID; 916 break; 917 918 default: 919 break; 920 } 921 } 922 923 924 /******************************************************************************* 925 * 926 * FUNCTION: AcpiDmCheckForHardwareId 927 * 928 * PARAMETERS: Op - Op to be examined 929 * 930 * RETURN: None 931 * 932 * DESCRIPTION: Determine if a Name() Op is a _HID/_CID. 933 * 934 ******************************************************************************/ 935 936 void 937 AcpiDmCheckForHardwareId ( 938 ACPI_PARSE_OBJECT *Op) 939 { 940 UINT32 Name; 941 ACPI_PARSE_OBJECT *NextOp; 942 943 944 /* Get the NameSegment */ 945 946 Name = AcpiPsGetName (Op); 947 if (!Name) 948 { 949 return; 950 } 951 952 NextOp = AcpiPsGetDepthNext (NULL, Op); 953 if (!NextOp) 954 { 955 return; 956 } 957 958 /* Check for _HID - has one argument */ 959 960 if (ACPI_COMPARE_NAME (&Name, METHOD_NAME__HID)) 961 { 962 AcpiDmGetHardwareIdType (NextOp); 963 return; 964 } 965 966 /* Exit if not _CID */ 967 968 if (!ACPI_COMPARE_NAME (&Name, METHOD_NAME__CID)) 969 { 970 return; 971 } 972 973 /* _CID can contain a single argument or a package */ 974 975 if (NextOp->Common.AmlOpcode != AML_PACKAGE_OP) 976 { 977 AcpiDmGetHardwareIdType (NextOp); 978 return; 979 } 980 981 /* _CID with Package: get the package length, check all elements */ 982 983 NextOp = AcpiPsGetDepthNext (NULL, NextOp); 984 if (!NextOp) 985 { 986 return; 987 } 988 989 /* Don't need to use the length, just walk the peer list */ 990 991 NextOp = NextOp->Common.Next; 992 while (NextOp) 993 { 994 AcpiDmGetHardwareIdType (NextOp); 995 NextOp = NextOp->Common.Next; 996 } 997 } 998 999 1000 /******************************************************************************* 1001 * 1002 * FUNCTION: AcpiDmDecompressEisaId 1003 * 1004 * PARAMETERS: EncodedId - Raw encoded EISA ID. 1005 * 1006 * RETURN: None 1007 * 1008 * DESCRIPTION: Convert an encoded EISAID back to the original ASCII String 1009 * and emit the correct ASL statement. If the ID is known, emit 1010 * a description of the ID as a comment. 1011 * 1012 ******************************************************************************/ 1013 1014 void 1015 AcpiDmDecompressEisaId ( 1016 UINT32 EncodedId) 1017 { 1018 char IdBuffer[ACPI_EISAID_STRING_SIZE]; 1019 const AH_DEVICE_ID *Info; 1020 1021 1022 /* Convert EISAID to a string an emit the statement */ 1023 1024 AcpiExEisaIdToString (IdBuffer, EncodedId); 1025 AcpiOsPrintf ("EisaId (\"%s\")", IdBuffer); 1026 1027 /* If we know about the ID, emit the description */ 1028 1029 Info = AcpiAhMatchHardwareId (IdBuffer); 1030 if (Info) 1031 { 1032 AcpiOsPrintf (" /* %s */", Info->Description); 1033 } 1034 } 1035 1036 #endif 1037