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