1 /****************************************************************************** 2 * 3 * Module Name: dmtable - Support for ACPI tables that contain no AML code 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2011, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 #include <contrib/dev/acpica/include/acpi.h> 45 #include <contrib/dev/acpica/include/accommon.h> 46 #include <contrib/dev/acpica/include/acdisasm.h> 47 #include <contrib/dev/acpica/include/actables.h> 48 #include <contrib/dev/acpica/compiler/aslcompiler.h> 49 #include <contrib/dev/acpica/compiler/dtcompiler.h> 50 51 /* This module used for application-level code only */ 52 53 #define _COMPONENT ACPI_CA_DISASSEMBLER 54 ACPI_MODULE_NAME ("dmtable") 55 56 /* Local Prototypes */ 57 58 static void 59 AcpiDmCheckAscii ( 60 UINT8 *Target, 61 char *RepairedName, 62 UINT32 Count); 63 64 65 /* Common format strings for commented values */ 66 67 #define UINT8_FORMAT "%2.2X [%s]\n" 68 #define UINT16_FORMAT "%4.4X [%s]\n" 69 #define UINT32_FORMAT "%8.8X [%s]\n" 70 #define STRING_FORMAT "[%s]\n" 71 72 /* These tables map a subtable type to a description string */ 73 74 static const char *AcpiDmAsfSubnames[] = 75 { 76 "ASF Information", 77 "ASF Alerts", 78 "ASF Remote Control", 79 "ASF RMCP Boot Options", 80 "ASF Address", 81 "Unknown SubTable Type" /* Reserved */ 82 }; 83 84 static const char *AcpiDmDmarSubnames[] = 85 { 86 "Hardware Unit Definition", 87 "Reserved Memory Region", 88 "Root Port ATS Capability", 89 "Remapping Hardware Static Affinity", 90 "Unknown SubTable Type" /* Reserved */ 91 }; 92 93 static const char *AcpiDmEinjActions[] = 94 { 95 "Begin Operation", 96 "Get Trigger Table", 97 "Set Error Type", 98 "Get Error Type", 99 "End Operation", 100 "Execute Operation", 101 "Check Busy Status", 102 "Get Command Status", 103 "Unknown Action" 104 }; 105 106 static const char *AcpiDmEinjInstructions[] = 107 { 108 "Read Register", 109 "Read Register Value", 110 "Write Register", 111 "Write Register Value", 112 "Noop", 113 "Unknown Instruction" 114 }; 115 116 static const char *AcpiDmErstActions[] = 117 { 118 "Begin Write Operation", 119 "Begin Read Operation", 120 "Begin Clear Operation", 121 "End Operation", 122 "Set Record Offset", 123 "Execute Operation", 124 "Check Busy Status", 125 "Get Command Status", 126 "Get Record Identifier", 127 "Set Record Identifier", 128 "Get Record Count", 129 "Begin Dummy Write", 130 "Unused/Unknown Action", 131 "Get Error Address Range", 132 "Get Error Address Length", 133 "Get Error Attributes", 134 "Unknown Action" 135 }; 136 137 static const char *AcpiDmErstInstructions[] = 138 { 139 "Read Register", 140 "Read Register Value", 141 "Write Register", 142 "Write Register Value", 143 "Noop", 144 "Load Var1", 145 "Load Var2", 146 "Store Var1", 147 "Add", 148 "Subtract", 149 "Add Value", 150 "Subtract Value", 151 "Stall", 152 "Stall While True", 153 "Skip Next If True", 154 "GoTo", 155 "Set Source Address", 156 "Set Destination Address", 157 "Move Data", 158 "Unknown Instruction" 159 }; 160 161 static const char *AcpiDmHestSubnames[] = 162 { 163 "IA-32 Machine Check Exception", 164 "IA-32 Corrected Machine Check", 165 "IA-32 Non-Maskable Interrupt", 166 "Unknown SubTable Type", /* 3 - Reserved */ 167 "Unknown SubTable Type", /* 4 - Reserved */ 168 "Unknown SubTable Type", /* 5 - Reserved */ 169 "PCI Express Root Port AER", 170 "PCI Express AER (AER Endpoint)", 171 "PCI Express/PCI-X Bridge AER", 172 "Generic Hardware Error Source", 173 "Unknown SubTable Type" /* Reserved */ 174 }; 175 176 static const char *AcpiDmHestNotifySubnames[] = 177 { 178 "Polled", 179 "External Interrupt", 180 "Local Interrupt", 181 "SCI", 182 "NMI", 183 "Unknown Notify Type" /* Reserved */ 184 }; 185 186 static const char *AcpiDmMadtSubnames[] = 187 { 188 "Processor Local APIC", /* ACPI_MADT_TYPE_LOCAL_APIC */ 189 "I/O APIC", /* ACPI_MADT_TYPE_IO_APIC */ 190 "Interrupt Source Override", /* ACPI_MADT_TYPE_INTERRUPT_OVERRIDE */ 191 "NMI Source", /* ACPI_MADT_TYPE_NMI_SOURCE */ 192 "Local APIC NMI", /* ACPI_MADT_TYPE_LOCAL_APIC_NMI */ 193 "Local APIC Address Override", /* ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE */ 194 "I/O SAPIC", /* ACPI_MADT_TYPE_IO_SAPIC */ 195 "Local SAPIC", /* ACPI_MADT_TYPE_LOCAL_SAPIC */ 196 "Platform Interrupt Sources", /* ACPI_MADT_TYPE_INTERRUPT_SOURCE */ 197 "Processor Local x2APIC", /* ACPI_MADT_TYPE_LOCAL_X2APIC */ 198 "Local x2APIC NMI", /* ACPI_MADT_TYPE_LOCAL_X2APIC_NMI */ 199 "Unknown SubTable Type" /* Reserved */ 200 }; 201 202 static const char *AcpiDmSlicSubnames[] = 203 { 204 "Public Key Structure", 205 "Windows Marker Structure", 206 "Unknown SubTable Type" /* Reserved */ 207 }; 208 209 static const char *AcpiDmSratSubnames[] = 210 { 211 "Processor Local APIC/SAPIC Affinity", 212 "Memory Affinity", 213 "Processor Local x2APIC Affinity", 214 "Unknown SubTable Type" /* Reserved */ 215 }; 216 217 static const char *AcpiDmIvrsSubnames[] = 218 { 219 "Hardware Definition Block", 220 "Memory Definition Block", 221 "Unknown SubTable Type" /* Reserved */ 222 }; 223 224 225 #define ACPI_FADT_PM_RESERVED 8 226 227 static const char *AcpiDmFadtProfiles[] = 228 { 229 "Unspecified", 230 "Desktop", 231 "Mobile", 232 "Workstation", 233 "Enterprise Server", 234 "SOHO Server", 235 "Appliance PC", 236 "Performance Server", 237 "Unknown Profile Type" 238 }; 239 240 #define ACPI_GAS_WIDTH_RESERVED 5 241 242 static const char *AcpiDmGasAccessWidth[] = 243 { 244 "Undefined/Legacy", 245 "Byte Access:8", 246 "Word Access:16", 247 "DWord Access:32", 248 "QWord Access:64", 249 "Unknown Width Encoding" 250 }; 251 252 253 /******************************************************************************* 254 * 255 * ACPI Table Data, indexed by signature. 256 * 257 * Each entry contains: Signature, Table Info, Handler, DtHandler, 258 * Template, Description 259 * 260 * Simple tables have only a TableInfo structure, complex tables have a 261 * handler. This table must be NULL terminated. RSDP and FACS are 262 * special-cased elsewhere. 263 * 264 ******************************************************************************/ 265 266 ACPI_DMTABLE_DATA AcpiDmTableData[] = 267 { 268 {ACPI_SIG_ASF, NULL, AcpiDmDumpAsf, DtCompileAsf, TemplateAsf, "Alert Standard Format table"}, 269 {ACPI_SIG_BOOT, AcpiDmTableInfoBoot, NULL, NULL, TemplateBoot, "Simple Boot Flag Table"}, 270 {ACPI_SIG_BERT, AcpiDmTableInfoBert, NULL, NULL, TemplateBert, "Boot Error Record Table"}, 271 {ACPI_SIG_CPEP, NULL, AcpiDmDumpCpep, DtCompileCpep, TemplateCpep, "Corrected Platform Error Polling table"}, 272 {ACPI_SIG_DBGP, AcpiDmTableInfoDbgp, NULL, NULL, TemplateDbgp, "Debug Port table"}, 273 {ACPI_SIG_DMAR, NULL, AcpiDmDumpDmar, DtCompileDmar, TemplateDmar, "DMA Remapping table"}, 274 {ACPI_SIG_ECDT, AcpiDmTableInfoEcdt, NULL, NULL, TemplateEcdt, "Embedded Controller Boot Resources Table"}, 275 {ACPI_SIG_EINJ, NULL, AcpiDmDumpEinj, DtCompileEinj, TemplateEinj, "Error Injection table"}, 276 {ACPI_SIG_ERST, NULL, AcpiDmDumpErst, DtCompileErst, TemplateErst, "Error Record Serialization Table"}, 277 {ACPI_SIG_FADT, NULL, AcpiDmDumpFadt, DtCompileFadt, TemplateFadt, "Fixed ACPI Description Table"}, 278 {ACPI_SIG_HEST, NULL, AcpiDmDumpHest, DtCompileHest, TemplateHest, "Hardware Error Source Table"}, 279 {ACPI_SIG_HPET, AcpiDmTableInfoHpet, NULL, NULL, TemplateHpet, "High Precision Event Timer table"}, 280 {ACPI_SIG_IVRS, NULL, AcpiDmDumpIvrs, DtCompileIvrs, TemplateIvrs, "I/O Virtualization Reporting Structure"}, 281 {ACPI_SIG_MADT, NULL, AcpiDmDumpMadt, DtCompileMadt, TemplateMadt, "Multiple APIC Description Table"}, 282 {ACPI_SIG_MCFG, NULL, AcpiDmDumpMcfg, DtCompileMcfg, TemplateMcfg, "Memory Mapped Configuration table"}, 283 {ACPI_SIG_MCHI, AcpiDmTableInfoMchi, NULL, NULL, TemplateMchi, "Management Controller Host Interface table"}, 284 {ACPI_SIG_MSCT, NULL, AcpiDmDumpMsct, DtCompileMsct, TemplateMsct, "Maximum System Characteristics Table"}, 285 {ACPI_SIG_RSDT, NULL, AcpiDmDumpRsdt, DtCompileRsdt, TemplateRsdt, "Root System Description Table"}, 286 {ACPI_SIG_SBST, AcpiDmTableInfoSbst, NULL, NULL, TemplateSbst, "Smart Battery Specification Table"}, 287 {ACPI_SIG_SLIC, NULL, AcpiDmDumpSlic, DtCompileSlic, TemplateSlic, "Software Licensing Description Table"}, 288 {ACPI_SIG_SLIT, NULL, AcpiDmDumpSlit, DtCompileSlit, TemplateSlit, "System Locality Information Table"}, 289 {ACPI_SIG_SPCR, AcpiDmTableInfoSpcr, NULL, NULL, TemplateSpcr, "Serial Port Console Redirection table"}, 290 {ACPI_SIG_SPMI, AcpiDmTableInfoSpmi, NULL, NULL, TemplateSpmi, "Server Platform Management Interface table"}, 291 {ACPI_SIG_SRAT, NULL, AcpiDmDumpSrat, DtCompileSrat, TemplateSrat, "System Resource Affinity Table"}, 292 {ACPI_SIG_TCPA, AcpiDmTableInfoTcpa, NULL, NULL, TemplateTcpa, "Trusted Computing Platform Alliance table"}, 293 {ACPI_SIG_UEFI, AcpiDmTableInfoUefi, NULL, DtCompileUefi, TemplateUefi, "UEFI Boot Optimization Table"}, 294 {ACPI_SIG_WAET, AcpiDmTableInfoWaet, NULL, NULL, TemplateWaet, "Windows ACPI Emulated Devices Table"}, 295 {ACPI_SIG_WDAT, NULL, AcpiDmDumpWdat, DtCompileWdat, TemplateWdat, "Watchdog Action Table"}, 296 {ACPI_SIG_WDDT, AcpiDmTableInfoWddt, NULL, NULL, TemplateWddt, "Watchdog Description Table"}, 297 {ACPI_SIG_WDRT, AcpiDmTableInfoWdrt, NULL, NULL, TemplateWdrt, "Watchdog Resource Table"}, 298 {ACPI_SIG_XSDT, NULL, AcpiDmDumpXsdt, DtCompileXsdt, TemplateXsdt, "Extended System Description Table"}, 299 {NULL, NULL, NULL, NULL, NULL, NULL} 300 }; 301 302 303 /******************************************************************************* 304 * 305 * FUNCTION: AcpiDmGenerateChecksum 306 * 307 * PARAMETERS: Table - Pointer to table to be checksummed 308 * Length - Length of the table 309 * OriginalChecksum - Value of the checksum field 310 * 311 * RETURN: 8 bit checksum of buffer 312 * 313 * DESCRIPTION: Computes an 8 bit checksum of the table. 314 * 315 ******************************************************************************/ 316 317 UINT8 318 AcpiDmGenerateChecksum ( 319 void *Table, 320 UINT32 Length, 321 UINT8 OriginalChecksum) 322 { 323 UINT8 Checksum; 324 325 326 /* Sum the entire table as-is */ 327 328 Checksum = AcpiTbChecksum ((UINT8 *) Table, Length); 329 330 /* Subtract off the existing checksum value in the table */ 331 332 Checksum = (UINT8) (Checksum - OriginalChecksum); 333 334 /* Compute the final checksum */ 335 336 Checksum = (UINT8) (0 - Checksum); 337 return (Checksum); 338 } 339 340 341 /******************************************************************************* 342 * 343 * FUNCTION: AcpiDmGetTableData 344 * 345 * PARAMETERS: Signature - ACPI signature (4 chars) to match 346 * 347 * RETURN: Pointer to a valid ACPI_DMTABLE_DATA. Null if no match found. 348 * 349 * DESCRIPTION: Find a match in the global table of supported ACPI tables 350 * 351 ******************************************************************************/ 352 353 ACPI_DMTABLE_DATA * 354 AcpiDmGetTableData ( 355 char *Signature) 356 { 357 ACPI_DMTABLE_DATA *TableData; 358 359 360 for (TableData = AcpiDmTableData; TableData->Signature; TableData++) 361 { 362 if (ACPI_COMPARE_NAME (Signature, TableData->Signature)) 363 { 364 return (TableData); 365 } 366 } 367 368 return (NULL); 369 } 370 371 372 /******************************************************************************* 373 * 374 * FUNCTION: AcpiDmDumpDataTable 375 * 376 * PARAMETERS: Table - An ACPI table 377 * 378 * RETURN: None. 379 * 380 * DESCRIPTION: Format the contents of an ACPI data table (any table other 381 * than an SSDT or DSDT that does not contain executable AML code) 382 * 383 ******************************************************************************/ 384 385 void 386 AcpiDmDumpDataTable ( 387 ACPI_TABLE_HEADER *Table) 388 { 389 ACPI_STATUS Status; 390 ACPI_DMTABLE_DATA *TableData; 391 UINT32 Length; 392 393 394 /* Ignore tables that contain AML */ 395 396 if (AcpiUtIsAmlTable (Table)) 397 { 398 return; 399 } 400 401 /* 402 * Handle tables that don't use the common ACPI table header structure. 403 * Currently, these are the FACS and RSDP. 404 */ 405 if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_FACS)) 406 { 407 Length = Table->Length; 408 AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoFacs); 409 } 410 else if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_RSDP)) 411 { 412 Length = AcpiDmDumpRsdp (Table); 413 } 414 else 415 { 416 /* 417 * All other tables must use the common ACPI table header, dump it now 418 */ 419 Length = Table->Length; 420 Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoHeader); 421 if (ACPI_FAILURE (Status)) 422 { 423 return; 424 } 425 AcpiOsPrintf ("\n"); 426 427 /* Match signature and dispatch appropriately */ 428 429 TableData = AcpiDmGetTableData (Table->Signature); 430 if (!TableData) 431 { 432 if (!ACPI_STRNCMP (Table->Signature, "OEM", 3)) 433 { 434 AcpiOsPrintf ("\n**** OEM-defined ACPI table [%4.4s], unknown contents\n\n", 435 Table->Signature); 436 } 437 else 438 { 439 AcpiOsPrintf ("\n**** Unknown ACPI table type [%4.4s]\n\n", 440 Table->Signature); 441 } 442 } 443 else if (TableData->TableHandler) 444 { 445 /* Complex table, has a handler */ 446 447 TableData->TableHandler (Table); 448 } 449 else if (TableData->TableInfo) 450 { 451 /* Simple table, just walk the info table */ 452 453 AcpiDmDumpTable (Length, 0, Table, 0, TableData->TableInfo); 454 } 455 } 456 457 if (!Gbl_DoTemplates || Gbl_VerboseTemplates) 458 { 459 /* Dump the raw table data */ 460 461 AcpiOsPrintf ("\n%s: Length %d (0x%X)\n\n", 462 ACPI_RAW_TABLE_DATA_HEADER, Length, Length); 463 AcpiUtDumpBuffer2 (ACPI_CAST_PTR (UINT8, Table), Length, DB_BYTE_DISPLAY); 464 } 465 } 466 467 468 /******************************************************************************* 469 * 470 * FUNCTION: AcpiDmLineHeader 471 * 472 * PARAMETERS: Offset - Current byte offset, from table start 473 * ByteLength - Length of the field in bytes, 0 for flags 474 * Name - Name of this field 475 * Value - Optional value, displayed on left of ':' 476 * 477 * RETURN: None 478 * 479 * DESCRIPTION: Utility routines for formatting output lines. Displays the 480 * current table offset in hex and decimal, the field length, 481 * and the field name. 482 * 483 ******************************************************************************/ 484 485 void 486 AcpiDmLineHeader ( 487 UINT32 Offset, 488 UINT32 ByteLength, 489 char *Name) 490 { 491 492 /* Allow a null name for fields that span multiple lines (large buffers) */ 493 494 if (!Name) 495 { 496 Name = ""; 497 } 498 499 if (Gbl_DoTemplates && !Gbl_VerboseTemplates) /* Terse template */ 500 { 501 if (ByteLength) 502 { 503 AcpiOsPrintf ("[%.4d] %34s : ", ByteLength, Name); 504 } 505 else 506 { 507 if (*Name) 508 { 509 AcpiOsPrintf ("%41s : ", Name); 510 } 511 else 512 { 513 AcpiOsPrintf ("%41s ", Name); 514 } 515 } 516 } 517 else /* Normal disassembler or verbose template */ 518 { 519 if (ByteLength) 520 { 521 AcpiOsPrintf ("[%3.3Xh %4.4d% 4d] %28s : ", 522 Offset, Offset, ByteLength, Name); 523 } 524 else 525 { 526 if (*Name) 527 { 528 AcpiOsPrintf ("%44s : ", Name); 529 } 530 else 531 { 532 AcpiOsPrintf ("%44s ", Name); 533 } 534 } 535 } 536 } 537 538 void 539 AcpiDmLineHeader2 ( 540 UINT32 Offset, 541 UINT32 ByteLength, 542 char *Name, 543 UINT32 Value) 544 { 545 546 if (Gbl_DoTemplates && !Gbl_VerboseTemplates) /* Terse template */ 547 { 548 if (ByteLength) 549 { 550 AcpiOsPrintf ("[%.4d] %30s %3d : ", 551 ByteLength, Name, Value); 552 } 553 else 554 { 555 AcpiOsPrintf ("%36s % 3d : ", 556 Name, Value); 557 } 558 } 559 else /* Normal disassembler or verbose template */ 560 { 561 if (ByteLength) 562 { 563 AcpiOsPrintf ("[%3.3Xh %4.4d %3d] %24s %3d : ", 564 Offset, Offset, ByteLength, Name, Value); 565 } 566 else 567 { 568 AcpiOsPrintf ("[%3.3Xh %4.4d ] %24s %3d : ", 569 Offset, Offset, Name, Value); 570 } 571 } 572 } 573 574 575 /******************************************************************************* 576 * 577 * FUNCTION: AcpiDmDumpTable 578 * 579 * PARAMETERS: TableLength - Length of the entire ACPI table 580 * TableOffset - Starting offset within the table for this 581 * sub-descriptor (0 if main table) 582 * Table - The ACPI table 583 * SubtableLength - Length of this sub-descriptor 584 * Info - Info table for this ACPI table 585 * 586 * RETURN: None 587 * 588 * DESCRIPTION: Display ACPI table contents by walking the Info table. 589 * 590 * Note: This function must remain in sync with DtGetFieldLength. 591 * 592 ******************************************************************************/ 593 594 ACPI_STATUS 595 AcpiDmDumpTable ( 596 UINT32 TableLength, 597 UINT32 TableOffset, 598 void *Table, 599 UINT32 SubtableLength, 600 ACPI_DMTABLE_INFO *Info) 601 { 602 UINT8 *Target; 603 UINT32 CurrentOffset; 604 UINT32 ByteLength; 605 UINT8 Temp8; 606 UINT16 Temp16; 607 ACPI_DMTABLE_DATA *TableData; 608 const char *Name; 609 BOOLEAN LastOutputBlankLine = FALSE; 610 char RepairedName[8]; 611 612 613 if (!Info) 614 { 615 AcpiOsPrintf ("Display not implemented\n"); 616 return (AE_NOT_IMPLEMENTED); 617 } 618 619 /* Walk entire Info table; Null name terminates */ 620 621 for (; Info->Name; Info++) 622 { 623 /* 624 * Target points to the field within the ACPI Table. CurrentOffset is 625 * the offset of the field from the start of the main table. 626 */ 627 Target = ACPI_ADD_PTR (UINT8, Table, Info->Offset); 628 CurrentOffset = TableOffset + Info->Offset; 629 630 /* Check for beyond EOT or beyond subtable end */ 631 632 if ((CurrentOffset >= TableLength) || 633 (SubtableLength && (Info->Offset >= SubtableLength))) 634 { 635 AcpiOsPrintf ("**** ACPI table terminates in the middle of a data structure!\n"); 636 return (AE_BAD_DATA); 637 } 638 639 /* Generate the byte length for this field */ 640 641 switch (Info->Opcode) 642 { 643 case ACPI_DMT_UINT8: 644 case ACPI_DMT_CHKSUM: 645 case ACPI_DMT_SPACEID: 646 case ACPI_DMT_ACCWIDTH: 647 case ACPI_DMT_IVRS: 648 case ACPI_DMT_MADT: 649 case ACPI_DMT_SRAT: 650 case ACPI_DMT_ASF: 651 case ACPI_DMT_HESTNTYP: 652 case ACPI_DMT_FADTPM: 653 case ACPI_DMT_EINJACT: 654 case ACPI_DMT_EINJINST: 655 case ACPI_DMT_ERSTACT: 656 case ACPI_DMT_ERSTINST: 657 ByteLength = 1; 658 break; 659 case ACPI_DMT_UINT16: 660 case ACPI_DMT_DMAR: 661 case ACPI_DMT_HEST: 662 ByteLength = 2; 663 break; 664 case ACPI_DMT_UINT24: 665 ByteLength = 3; 666 break; 667 case ACPI_DMT_UINT32: 668 case ACPI_DMT_NAME4: 669 case ACPI_DMT_SIG: 670 case ACPI_DMT_SLIC: 671 ByteLength = 4; 672 break; 673 case ACPI_DMT_NAME6: 674 ByteLength = 6; 675 break; 676 case ACPI_DMT_UINT56: 677 case ACPI_DMT_BUF7: 678 ByteLength = 7; 679 break; 680 case ACPI_DMT_UINT64: 681 case ACPI_DMT_NAME8: 682 ByteLength = 8; 683 break; 684 case ACPI_DMT_BUF16: 685 case ACPI_DMT_UUID: 686 ByteLength = 16; 687 break; 688 case ACPI_DMT_BUF128: 689 ByteLength = 128; 690 break; 691 case ACPI_DMT_STRING: 692 ByteLength = ACPI_STRLEN (ACPI_CAST_PTR (char, Target)) + 1; 693 break; 694 case ACPI_DMT_GAS: 695 if (!LastOutputBlankLine) 696 { 697 AcpiOsPrintf ("\n"); 698 LastOutputBlankLine = TRUE; 699 } 700 ByteLength = sizeof (ACPI_GENERIC_ADDRESS); 701 break; 702 case ACPI_DMT_HESTNTFY: 703 if (!LastOutputBlankLine) 704 { 705 AcpiOsPrintf ("\n"); 706 LastOutputBlankLine = TRUE; 707 } 708 ByteLength = sizeof (ACPI_HEST_NOTIFY); 709 break; 710 default: 711 ByteLength = 0; 712 break; 713 } 714 715 if (CurrentOffset + ByteLength > TableLength) 716 { 717 AcpiOsPrintf ("**** ACPI table terminates in the middle of a data structure!\n"); 718 return (AE_BAD_DATA); 719 } 720 721 /* Start a new line and decode the opcode */ 722 723 AcpiDmLineHeader (CurrentOffset, ByteLength, Info->Name); 724 725 switch (Info->Opcode) 726 { 727 /* Single-bit Flag fields. Note: Opcode is the bit position */ 728 729 case ACPI_DMT_FLAG0: 730 case ACPI_DMT_FLAG1: 731 case ACPI_DMT_FLAG2: 732 case ACPI_DMT_FLAG3: 733 case ACPI_DMT_FLAG4: 734 case ACPI_DMT_FLAG5: 735 case ACPI_DMT_FLAG6: 736 case ACPI_DMT_FLAG7: 737 738 AcpiOsPrintf ("%1.1X\n", (*Target >> Info->Opcode) & 0x01); 739 break; 740 741 /* 2-bit Flag fields */ 742 743 case ACPI_DMT_FLAGS0: 744 745 AcpiOsPrintf ("%1.1X\n", *Target & 0x03); 746 break; 747 748 case ACPI_DMT_FLAGS2: 749 750 AcpiOsPrintf ("%1.1X\n", (*Target >> 2) & 0x03); 751 break; 752 753 /* Standard Data Types */ 754 755 case ACPI_DMT_UINT8: 756 757 AcpiOsPrintf ("%2.2X\n", *Target); 758 break; 759 760 case ACPI_DMT_UINT16: 761 762 AcpiOsPrintf ("%4.4X\n", ACPI_GET16 (Target)); 763 break; 764 765 case ACPI_DMT_UINT24: 766 767 AcpiOsPrintf ("%2.2X%2.2X%2.2X\n", 768 *Target, *(Target + 1), *(Target + 2)); 769 break; 770 771 case ACPI_DMT_UINT32: 772 773 AcpiOsPrintf ("%8.8X\n", ACPI_GET32 (Target)); 774 break; 775 776 case ACPI_DMT_UINT56: 777 778 for (Temp8 = 0; Temp8 < 7; Temp8++) 779 { 780 AcpiOsPrintf ("%2.2X", Target[Temp8]); 781 } 782 AcpiOsPrintf ("\n"); 783 break; 784 785 case ACPI_DMT_UINT64: 786 787 AcpiOsPrintf ("%8.8X%8.8X\n", 788 ACPI_FORMAT_UINT64 (ACPI_GET64 (Target))); 789 break; 790 791 case ACPI_DMT_BUF7: 792 case ACPI_DMT_BUF16: 793 case ACPI_DMT_BUF128: 794 795 /* 796 * Buffer: Size depends on the opcode and was set above. 797 * Each hex byte is separated with a space. 798 * Multiple lines are separated by line continuation char. 799 */ 800 for (Temp16 = 0; Temp16 < ByteLength; Temp16++) 801 { 802 AcpiOsPrintf ("%2.2X", Target[Temp16]); 803 if ((UINT32) (Temp16 + 1) < ByteLength) 804 { 805 if ((Temp16 > 0) && (!((Temp16+1) % 16))) 806 { 807 AcpiOsPrintf (" \\\n"); /* Line continuation */ 808 AcpiDmLineHeader (0, 0, NULL); 809 } 810 else 811 { 812 AcpiOsPrintf (" "); 813 } 814 } 815 } 816 AcpiOsPrintf ("\n"); 817 break; 818 819 case ACPI_DMT_UUID: 820 821 /* Convert 16-byte UUID buffer to 36-byte formatted UUID string */ 822 823 (void) AuConvertUuidToString ((char *) Target, MsgBuffer); 824 825 AcpiOsPrintf ("%s\n", MsgBuffer); 826 break; 827 828 case ACPI_DMT_STRING: 829 830 AcpiOsPrintf ("\"%s\"\n", ACPI_CAST_PTR (char, Target)); 831 break; 832 833 /* Fixed length ASCII name fields */ 834 835 case ACPI_DMT_SIG: 836 837 AcpiDmCheckAscii (Target, RepairedName, 4); 838 AcpiOsPrintf ("\"%.4s\" ", RepairedName); 839 TableData = AcpiDmGetTableData (ACPI_CAST_PTR (char, Target)); 840 if (TableData) 841 { 842 AcpiOsPrintf (STRING_FORMAT, TableData->Name); 843 } 844 else 845 { 846 AcpiOsPrintf ("\n"); 847 } 848 break; 849 850 case ACPI_DMT_NAME4: 851 852 AcpiDmCheckAscii (Target, RepairedName, 4); 853 AcpiOsPrintf ("\"%.4s\"\n", RepairedName); 854 break; 855 856 case ACPI_DMT_NAME6: 857 858 AcpiDmCheckAscii (Target, RepairedName, 6); 859 AcpiOsPrintf ("\"%.6s\"\n", RepairedName); 860 break; 861 862 case ACPI_DMT_NAME8: 863 864 AcpiDmCheckAscii (Target, RepairedName, 8); 865 AcpiOsPrintf ("\"%.8s\"\n", RepairedName); 866 break; 867 868 /* Special Data Types */ 869 870 case ACPI_DMT_CHKSUM: 871 872 /* Checksum, display and validate */ 873 874 AcpiOsPrintf ("%2.2X", *Target); 875 Temp8 = AcpiDmGenerateChecksum (Table, 876 ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Length, 877 ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Checksum); 878 if (Temp8 != ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Checksum) 879 { 880 AcpiOsPrintf ( 881 " /* Incorrect checksum, should be %2.2X */", Temp8); 882 } 883 AcpiOsPrintf ("\n"); 884 break; 885 886 case ACPI_DMT_SPACEID: 887 888 /* Address Space ID */ 889 890 AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiUtGetRegionName (*Target)); 891 break; 892 893 case ACPI_DMT_ACCWIDTH: 894 895 /* Encoded Access Width */ 896 897 Temp8 = *Target; 898 if (Temp8 > ACPI_GAS_WIDTH_RESERVED) 899 { 900 Temp8 = ACPI_GAS_WIDTH_RESERVED; 901 } 902 903 AcpiOsPrintf (UINT8_FORMAT, Temp8, AcpiDmGasAccessWidth[Temp8]); 904 break; 905 906 case ACPI_DMT_GAS: 907 908 /* Generic Address Structure */ 909 910 AcpiOsPrintf (STRING_FORMAT, "Generic Address Structure"); 911 AcpiDmDumpTable (TableLength, CurrentOffset, Target, 912 sizeof (ACPI_GENERIC_ADDRESS), AcpiDmTableInfoGas); 913 AcpiOsPrintf ("\n"); 914 LastOutputBlankLine = TRUE; 915 break; 916 917 case ACPI_DMT_ASF: 918 919 /* ASF subtable types */ 920 921 Temp16 = (UINT16) ((*Target) & 0x7F); /* Top bit can be zero or one */ 922 if (Temp16 > ACPI_ASF_TYPE_RESERVED) 923 { 924 Temp16 = ACPI_ASF_TYPE_RESERVED; 925 } 926 927 AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmAsfSubnames[Temp16]); 928 break; 929 930 case ACPI_DMT_DMAR: 931 932 /* DMAR subtable types */ 933 934 Temp16 = ACPI_GET16 (Target); 935 if (Temp16 > ACPI_DMAR_TYPE_RESERVED) 936 { 937 Temp16 = ACPI_DMAR_TYPE_RESERVED; 938 } 939 940 AcpiOsPrintf (UINT16_FORMAT, ACPI_GET16 (Target), AcpiDmDmarSubnames[Temp16]); 941 break; 942 943 case ACPI_DMT_EINJACT: 944 945 /* EINJ Action types */ 946 947 Temp8 = *Target; 948 if (Temp8 > ACPI_EINJ_ACTION_RESERVED) 949 { 950 Temp8 = ACPI_EINJ_ACTION_RESERVED; 951 } 952 953 AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmEinjActions[Temp8]); 954 break; 955 956 case ACPI_DMT_EINJINST: 957 958 /* EINJ Instruction types */ 959 960 Temp8 = *Target; 961 if (Temp8 > ACPI_EINJ_INSTRUCTION_RESERVED) 962 { 963 Temp8 = ACPI_EINJ_INSTRUCTION_RESERVED; 964 } 965 966 AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmEinjInstructions[Temp8]); 967 break; 968 969 case ACPI_DMT_ERSTACT: 970 971 /* ERST Action types */ 972 973 Temp8 = *Target; 974 if (Temp8 > ACPI_ERST_ACTION_RESERVED) 975 { 976 Temp8 = ACPI_ERST_ACTION_RESERVED; 977 } 978 979 AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmErstActions[Temp8]); 980 break; 981 982 case ACPI_DMT_ERSTINST: 983 984 /* ERST Instruction types */ 985 986 Temp8 = *Target; 987 if (Temp8 > ACPI_ERST_INSTRUCTION_RESERVED) 988 { 989 Temp8 = ACPI_ERST_INSTRUCTION_RESERVED; 990 } 991 992 AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmErstInstructions[Temp8]); 993 break; 994 995 case ACPI_DMT_HEST: 996 997 /* HEST subtable types */ 998 999 Temp16 = ACPI_GET16 (Target); 1000 if (Temp16 > ACPI_HEST_TYPE_RESERVED) 1001 { 1002 Temp16 = ACPI_HEST_TYPE_RESERVED; 1003 } 1004 1005 AcpiOsPrintf (UINT16_FORMAT, ACPI_GET16 (Target), AcpiDmHestSubnames[Temp16]); 1006 break; 1007 1008 case ACPI_DMT_HESTNTFY: 1009 1010 AcpiOsPrintf (STRING_FORMAT, "Hardware Error Notification Structure"); 1011 AcpiDmDumpTable (TableLength, CurrentOffset, Target, 1012 sizeof (ACPI_HEST_NOTIFY), AcpiDmTableInfoHestNotify); 1013 AcpiOsPrintf ("\n"); 1014 LastOutputBlankLine = TRUE; 1015 break; 1016 1017 case ACPI_DMT_HESTNTYP: 1018 1019 /* HEST Notify types */ 1020 1021 Temp8 = *Target; 1022 if (Temp8 > ACPI_HEST_NOTIFY_RESERVED) 1023 { 1024 Temp8 = ACPI_HEST_NOTIFY_RESERVED; 1025 } 1026 1027 AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmHestNotifySubnames[Temp8]); 1028 break; 1029 1030 case ACPI_DMT_MADT: 1031 1032 /* MADT subtable types */ 1033 1034 Temp8 = *Target; 1035 if (Temp8 > ACPI_MADT_TYPE_RESERVED) 1036 { 1037 Temp8 = ACPI_MADT_TYPE_RESERVED; 1038 } 1039 1040 AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmMadtSubnames[Temp8]); 1041 break; 1042 1043 case ACPI_DMT_SLIC: 1044 1045 /* SLIC subtable types */ 1046 1047 Temp8 = *Target; 1048 if (Temp8 > ACPI_SLIC_TYPE_RESERVED) 1049 { 1050 Temp8 = ACPI_SLIC_TYPE_RESERVED; 1051 } 1052 1053 AcpiOsPrintf (UINT32_FORMAT, *Target, AcpiDmSlicSubnames[Temp8]); 1054 break; 1055 1056 case ACPI_DMT_SRAT: 1057 1058 /* SRAT subtable types */ 1059 1060 Temp8 = *Target; 1061 if (Temp8 > ACPI_SRAT_TYPE_RESERVED) 1062 { 1063 Temp8 = ACPI_SRAT_TYPE_RESERVED; 1064 } 1065 1066 AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmSratSubnames[Temp8]); 1067 break; 1068 1069 case ACPI_DMT_FADTPM: 1070 1071 /* FADT Preferred PM Profile names */ 1072 1073 Temp8 = *Target; 1074 if (Temp8 > ACPI_FADT_PM_RESERVED) 1075 { 1076 Temp8 = ACPI_FADT_PM_RESERVED; 1077 } 1078 1079 AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmFadtProfiles[Temp8]); 1080 break; 1081 1082 case ACPI_DMT_IVRS: 1083 1084 /* IVRS subtable types */ 1085 1086 Temp8 = *Target; 1087 switch (Temp8) 1088 { 1089 case ACPI_IVRS_TYPE_HARDWARE: 1090 Name = AcpiDmIvrsSubnames[0]; 1091 break; 1092 1093 case ACPI_IVRS_TYPE_MEMORY1: 1094 case ACPI_IVRS_TYPE_MEMORY2: 1095 case ACPI_IVRS_TYPE_MEMORY3: 1096 Name = AcpiDmIvrsSubnames[1]; 1097 break; 1098 1099 default: 1100 Name = AcpiDmIvrsSubnames[2]; 1101 break; 1102 } 1103 1104 AcpiOsPrintf (UINT8_FORMAT, *Target, Name); 1105 break; 1106 1107 case ACPI_DMT_EXIT: 1108 return (AE_OK); 1109 1110 default: 1111 ACPI_ERROR ((AE_INFO, 1112 "**** Invalid table opcode [0x%X] ****\n", Info->Opcode)); 1113 return (AE_SUPPORT); 1114 } 1115 } 1116 1117 if (TableOffset && !SubtableLength) 1118 { 1119 /* If this table is not the main table, subtable must have valid length */ 1120 1121 AcpiOsPrintf ("Invalid zero length subtable\n"); 1122 return (AE_BAD_DATA); 1123 } 1124 1125 return (AE_OK); 1126 } 1127 1128 1129 /******************************************************************************* 1130 * 1131 * FUNCTION: AcpiDmCheckAscii 1132 * 1133 * PARAMETERS: Name - Ascii string 1134 * Count - Number of characters to check 1135 * 1136 * RETURN: None 1137 * 1138 * DESCRIPTION: Ensure that the requested number of characters are printable 1139 * Ascii characters. Sets non-printable and null chars to <space>. 1140 * 1141 ******************************************************************************/ 1142 1143 static void 1144 AcpiDmCheckAscii ( 1145 UINT8 *Name, 1146 char *RepairedName, 1147 UINT32 Count) 1148 { 1149 UINT32 i; 1150 1151 1152 for (i = 0; i < Count; i++) 1153 { 1154 RepairedName[i] = (char) Name[i]; 1155 1156 if (!Name[i]) 1157 { 1158 return; 1159 } 1160 if (!isprint (Name[i])) 1161 { 1162 RepairedName[i] = ' '; 1163 } 1164 } 1165 } 1166