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