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 #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_REV1_BUFFER_SIZE) 777 { 778 AcpiOsPrintf (ACPI_PLD_OUTPUT08P, "PLD_Order", PldInfo->Order); 779 } 780 else 781 { 782 AcpiOsPrintf (ACPI_PLD_OUTPUT08, "PLD_Order", PldInfo->Order); 783 } 784 785 /* Fifth 32-bit dword */ 786 787 if (ByteCount >= ACPI_PLD_REV1_BUFFER_SIZE) 788 { 789 AcpiOsPrintf (ACPI_PLD_OUTPUT16, "PLD_VerticalOffset", PldInfo->VerticalOffset); 790 AcpiOsPrintf (ACPI_PLD_OUTPUT16P, "PLD_HorizontalOffset", PldInfo->HorizontalOffset); 791 } 792 793 ACPI_FREE (PldInfo); 794 } 795 796 797 /******************************************************************************* 798 * 799 * FUNCTION: AcpiDmUnicode 800 * 801 * PARAMETERS: Op - Byte List op containing Unicode string 802 * 803 * RETURN: None 804 * 805 * DESCRIPTION: Dump Unicode string as a standard ASCII string. (Remove 806 * the extra zero bytes). 807 * 808 ******************************************************************************/ 809 810 static void 811 AcpiDmUnicode ( 812 ACPI_PARSE_OBJECT *Op) 813 { 814 UINT16 *WordData; 815 UINT32 WordCount; 816 UINT32 i; 817 int OutputValue; 818 819 820 /* Extract the buffer info as a WORD buffer */ 821 822 WordData = ACPI_CAST_PTR (UINT16, Op->Named.Data); 823 WordCount = ACPI_DIV_2 (((UINT32) Op->Common.Value.Integer)); 824 825 /* Write every other byte as an ASCII character */ 826 827 AcpiOsPrintf ("\""); 828 for (i = 0; i < (WordCount - 1); i++) 829 { 830 OutputValue = (int) WordData[i]; 831 832 /* Handle values that must be escaped */ 833 834 if ((OutputValue == '\"') || 835 (OutputValue == '\\')) 836 { 837 AcpiOsPrintf ("\\%c", OutputValue); 838 } 839 else if (!isprint (OutputValue)) 840 { 841 AcpiOsPrintf ("\\x%2.2X", OutputValue); 842 } 843 else 844 { 845 AcpiOsPrintf ("%c", OutputValue); 846 } 847 } 848 849 AcpiOsPrintf ("\")"); 850 } 851 852 853 /******************************************************************************* 854 * 855 * FUNCTION: AcpiDmGetHardwareIdType 856 * 857 * PARAMETERS: Op - Op to be examined 858 * 859 * RETURN: None 860 * 861 * DESCRIPTION: Determine the type of the argument to a _HID or _CID 862 * 1) Strings are allowed 863 * 2) If Integer, determine if it is a valid EISAID 864 * 865 ******************************************************************************/ 866 867 static void 868 AcpiDmGetHardwareIdType ( 869 ACPI_PARSE_OBJECT *Op) 870 { 871 UINT32 BigEndianId; 872 UINT32 Prefix[3]; 873 UINT32 i; 874 875 876 switch (Op->Common.AmlOpcode) 877 { 878 case AML_STRING_OP: 879 880 /* Mark this string as an _HID/_CID string */ 881 882 Op->Common.DisasmOpcode = ACPI_DASM_HID_STRING; 883 break; 884 885 case AML_WORD_OP: 886 case AML_DWORD_OP: 887 888 /* Determine if a Word/Dword is a valid encoded EISAID */ 889 890 /* Swap from little-endian to big-endian to simplify conversion */ 891 892 BigEndianId = AcpiUtDwordByteSwap ((UINT32) Op->Common.Value.Integer); 893 894 /* Create the 3 leading ASCII letters */ 895 896 Prefix[0] = ((BigEndianId >> 26) & 0x1F) + 0x40; 897 Prefix[1] = ((BigEndianId >> 21) & 0x1F) + 0x40; 898 Prefix[2] = ((BigEndianId >> 16) & 0x1F) + 0x40; 899 900 /* Verify that all 3 are ascii and alpha */ 901 902 for (i = 0; i < 3; i++) 903 { 904 if (!ACPI_IS_ASCII (Prefix[i]) || 905 !isalpha (Prefix[i])) 906 { 907 return; 908 } 909 } 910 911 /* Mark this node as convertable to an EISA ID string */ 912 913 Op->Common.DisasmOpcode = ACPI_DASM_EISAID; 914 break; 915 916 default: 917 break; 918 } 919 } 920 921 922 /******************************************************************************* 923 * 924 * FUNCTION: AcpiDmCheckForHardwareId 925 * 926 * PARAMETERS: Op - Op to be examined 927 * 928 * RETURN: None 929 * 930 * DESCRIPTION: Determine if a Name() Op is a _HID/_CID. 931 * 932 ******************************************************************************/ 933 934 void 935 AcpiDmCheckForHardwareId ( 936 ACPI_PARSE_OBJECT *Op) 937 { 938 UINT32 Name; 939 ACPI_PARSE_OBJECT *NextOp; 940 941 942 /* Get the NameSegment */ 943 944 Name = AcpiPsGetName (Op); 945 if (!Name) 946 { 947 return; 948 } 949 950 NextOp = AcpiPsGetDepthNext (NULL, Op); 951 if (!NextOp) 952 { 953 return; 954 } 955 956 /* Check for _HID - has one argument */ 957 958 if (ACPI_COMPARE_NAME (&Name, METHOD_NAME__HID)) 959 { 960 AcpiDmGetHardwareIdType (NextOp); 961 return; 962 } 963 964 /* Exit if not _CID */ 965 966 if (!ACPI_COMPARE_NAME (&Name, METHOD_NAME__CID)) 967 { 968 return; 969 } 970 971 /* _CID can contain a single argument or a package */ 972 973 if (NextOp->Common.AmlOpcode != AML_PACKAGE_OP) 974 { 975 AcpiDmGetHardwareIdType (NextOp); 976 return; 977 } 978 979 /* _CID with Package: get the package length, check all elements */ 980 981 NextOp = AcpiPsGetDepthNext (NULL, NextOp); 982 if (!NextOp) 983 { 984 return; 985 } 986 987 /* Don't need to use the length, just walk the peer list */ 988 989 NextOp = NextOp->Common.Next; 990 while (NextOp) 991 { 992 AcpiDmGetHardwareIdType (NextOp); 993 NextOp = NextOp->Common.Next; 994 } 995 } 996 997 998 /******************************************************************************* 999 * 1000 * FUNCTION: AcpiDmDecompressEisaId 1001 * 1002 * PARAMETERS: EncodedId - Raw encoded EISA ID. 1003 * 1004 * RETURN: None 1005 * 1006 * DESCRIPTION: Convert an encoded EISAID back to the original ASCII String 1007 * and emit the correct ASL statement. If the ID is known, emit 1008 * a description of the ID as a comment. 1009 * 1010 ******************************************************************************/ 1011 1012 void 1013 AcpiDmDecompressEisaId ( 1014 UINT32 EncodedId) 1015 { 1016 char IdBuffer[ACPI_EISAID_STRING_SIZE]; 1017 const AH_DEVICE_ID *Info; 1018 1019 1020 /* Convert EISAID to a string an emit the statement */ 1021 1022 AcpiExEisaIdToString (IdBuffer, EncodedId); 1023 AcpiOsPrintf ("EisaId (\"%s\")", IdBuffer); 1024 1025 /* If we know about the ID, emit the description */ 1026 1027 Info = AcpiAhMatchHardwareId (IdBuffer); 1028 if (Info) 1029 { 1030 AcpiOsPrintf (" /* %s */", Info->Description); 1031 } 1032 } 1033 1034 #endif 1035