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 "Generic Interrupt Controller", /* ACPI_MADT_GENERIC_INTERRUPT */ 200 "Generic Interrupt Distributor",/* ACPI_MADT_GENERIC_DISTRIBUTOR */ 201 "Unknown SubTable Type" /* Reserved */ 202 }; 203 204 static const char *AcpiDmPmttSubnames[] = 205 { 206 "Socket", /* ACPI_PMTT_TYPE_SOCKET */ 207 "Memory Controller", /* ACPI_PMTT_TYPE_CONTROLLER */ 208 "Physical Component (DIMM)", /* ACPI_PMTT_TYPE_DIMM */ 209 "Unknown SubTable Type" /* Reserved */ 210 }; 211 212 static const char *AcpiDmSlicSubnames[] = 213 { 214 "Public Key Structure", 215 "Windows Marker Structure", 216 "Unknown SubTable Type" /* Reserved */ 217 }; 218 219 static const char *AcpiDmSratSubnames[] = 220 { 221 "Processor Local APIC/SAPIC Affinity", 222 "Memory Affinity", 223 "Processor Local x2APIC Affinity", 224 "Unknown SubTable Type" /* Reserved */ 225 }; 226 227 static const char *AcpiDmIvrsSubnames[] = 228 { 229 "Hardware Definition Block", 230 "Memory Definition Block", 231 "Unknown SubTable Type" /* Reserved */ 232 }; 233 234 235 #define ACPI_FADT_PM_RESERVED 8 236 237 static const char *AcpiDmFadtProfiles[] = 238 { 239 "Unspecified", 240 "Desktop", 241 "Mobile", 242 "Workstation", 243 "Enterprise Server", 244 "SOHO Server", 245 "Appliance PC", 246 "Performance Server", 247 "Unknown Profile Type" 248 }; 249 250 #define ACPI_GAS_WIDTH_RESERVED 5 251 252 static const char *AcpiDmGasAccessWidth[] = 253 { 254 "Undefined/Legacy", 255 "Byte Access:8", 256 "Word Access:16", 257 "DWord Access:32", 258 "QWord Access:64", 259 "Unknown Width Encoding" 260 }; 261 262 263 /******************************************************************************* 264 * 265 * ACPI Table Data, indexed by signature. 266 * 267 * Each entry contains: Signature, Table Info, Handler, DtHandler, 268 * Template, Description 269 * 270 * Simple tables have only a TableInfo structure, complex tables have a 271 * handler. This table must be NULL terminated. RSDP and FACS are 272 * special-cased elsewhere. 273 * 274 ******************************************************************************/ 275 276 ACPI_DMTABLE_DATA AcpiDmTableData[] = 277 { 278 {ACPI_SIG_ASF, NULL, AcpiDmDumpAsf, DtCompileAsf, TemplateAsf, "Alert Standard Format table"}, 279 {ACPI_SIG_BOOT, AcpiDmTableInfoBoot, NULL, NULL, TemplateBoot, "Simple Boot Flag Table"}, 280 {ACPI_SIG_BERT, AcpiDmTableInfoBert, NULL, NULL, TemplateBert, "Boot Error Record Table"}, 281 {ACPI_SIG_BGRT, AcpiDmTableInfoBgrt, NULL, NULL, TemplateBgrt, "Boot Graphics Resource Table"}, 282 {ACPI_SIG_CPEP, NULL, AcpiDmDumpCpep, DtCompileCpep, TemplateCpep, "Corrected Platform Error Polling table"}, 283 {ACPI_SIG_DBGP, AcpiDmTableInfoDbgp, NULL, NULL, TemplateDbgp, "Debug Port table"}, 284 {ACPI_SIG_DMAR, NULL, AcpiDmDumpDmar, DtCompileDmar, TemplateDmar, "DMA Remapping table"}, 285 {ACPI_SIG_ECDT, AcpiDmTableInfoEcdt, NULL, NULL, TemplateEcdt, "Embedded Controller Boot Resources Table"}, 286 {ACPI_SIG_EINJ, NULL, AcpiDmDumpEinj, DtCompileEinj, TemplateEinj, "Error Injection table"}, 287 {ACPI_SIG_ERST, NULL, AcpiDmDumpErst, DtCompileErst, TemplateErst, "Error Record Serialization Table"}, 288 {ACPI_SIG_FADT, NULL, AcpiDmDumpFadt, DtCompileFadt, TemplateFadt, "Fixed ACPI Description Table"}, 289 {ACPI_SIG_FPDT, NULL, AcpiDmDumpFpdt, DtCompileFpdt, TemplateFpdt, "Firmware Performance Data Table"}, 290 {ACPI_SIG_GTDT, AcpiDmTableInfoGtdt, NULL, NULL, TemplateGtdt, "Generic Timer Description Table"}, 291 {ACPI_SIG_HEST, NULL, AcpiDmDumpHest, DtCompileHest, TemplateHest, "Hardware Error Source Table"}, 292 {ACPI_SIG_HPET, AcpiDmTableInfoHpet, NULL, NULL, TemplateHpet, "High Precision Event Timer table"}, 293 {ACPI_SIG_IVRS, NULL, AcpiDmDumpIvrs, DtCompileIvrs, TemplateIvrs, "I/O Virtualization Reporting Structure"}, 294 {ACPI_SIG_MADT, NULL, AcpiDmDumpMadt, DtCompileMadt, TemplateMadt, "Multiple APIC Description Table"}, 295 {ACPI_SIG_MCFG, NULL, AcpiDmDumpMcfg, DtCompileMcfg, TemplateMcfg, "Memory Mapped Configuration table"}, 296 {ACPI_SIG_MCHI, AcpiDmTableInfoMchi, NULL, NULL, TemplateMchi, "Management Controller Host Interface table"}, 297 {ACPI_SIG_MPST, AcpiDmTableInfoMpst, AcpiDmDumpMpst, DtCompileMpst, TemplateMpst, "Memory Power State Table"}, 298 {ACPI_SIG_MSCT, NULL, AcpiDmDumpMsct, DtCompileMsct, TemplateMsct, "Maximum System Characteristics Table"}, 299 {ACPI_SIG_PCCT, NULL, AcpiDmDumpPcct, NULL, NULL, "Platform Communications Channel Table"}, 300 {ACPI_SIG_PMTT, NULL, AcpiDmDumpPmtt, DtCompilePmtt, TemplatePmtt, "Platform Memory Topology Table"}, 301 {ACPI_SIG_RSDT, NULL, AcpiDmDumpRsdt, DtCompileRsdt, TemplateRsdt, "Root System Description Table"}, 302 {ACPI_SIG_S3PT, NULL, NULL, NULL, TemplateS3pt, "S3 Performance Table"}, 303 {ACPI_SIG_SBST, AcpiDmTableInfoSbst, NULL, NULL, TemplateSbst, "Smart Battery Specification Table"}, 304 {ACPI_SIG_SLIC, NULL, AcpiDmDumpSlic, DtCompileSlic, TemplateSlic, "Software Licensing Description Table"}, 305 {ACPI_SIG_SLIT, NULL, AcpiDmDumpSlit, DtCompileSlit, TemplateSlit, "System Locality Information Table"}, 306 {ACPI_SIG_SPCR, AcpiDmTableInfoSpcr, NULL, NULL, TemplateSpcr, "Serial Port Console Redirection table"}, 307 {ACPI_SIG_SPMI, AcpiDmTableInfoSpmi, NULL, NULL, TemplateSpmi, "Server Platform Management Interface table"}, 308 {ACPI_SIG_SRAT, NULL, AcpiDmDumpSrat, DtCompileSrat, TemplateSrat, "System Resource Affinity Table"}, 309 {ACPI_SIG_TCPA, AcpiDmTableInfoTcpa, NULL, NULL, TemplateTcpa, "Trusted Computing Platform Alliance table"}, 310 {ACPI_SIG_UEFI, AcpiDmTableInfoUefi, NULL, DtCompileUefi, TemplateUefi, "UEFI Boot Optimization Table"}, 311 {ACPI_SIG_WAET, AcpiDmTableInfoWaet, NULL, NULL, TemplateWaet, "Windows ACPI Emulated Devices Table"}, 312 {ACPI_SIG_WDAT, NULL, AcpiDmDumpWdat, DtCompileWdat, TemplateWdat, "Watchdog Action Table"}, 313 {ACPI_SIG_WDDT, AcpiDmTableInfoWddt, NULL, NULL, TemplateWddt, "Watchdog Description Table"}, 314 {ACPI_SIG_WDRT, AcpiDmTableInfoWdrt, NULL, NULL, TemplateWdrt, "Watchdog Resource Table"}, 315 {ACPI_SIG_XSDT, NULL, AcpiDmDumpXsdt, DtCompileXsdt, TemplateXsdt, "Extended System Description Table"}, 316 {NULL, NULL, NULL, NULL, NULL, NULL} 317 }; 318 319 320 /******************************************************************************* 321 * 322 * FUNCTION: AcpiDmGenerateChecksum 323 * 324 * PARAMETERS: Table - Pointer to table to be checksummed 325 * Length - Length of the table 326 * OriginalChecksum - Value of the checksum field 327 * 328 * RETURN: 8 bit checksum of buffer 329 * 330 * DESCRIPTION: Computes an 8 bit checksum of the table. 331 * 332 ******************************************************************************/ 333 334 UINT8 335 AcpiDmGenerateChecksum ( 336 void *Table, 337 UINT32 Length, 338 UINT8 OriginalChecksum) 339 { 340 UINT8 Checksum; 341 342 343 /* Sum the entire table as-is */ 344 345 Checksum = AcpiTbChecksum ((UINT8 *) Table, Length); 346 347 /* Subtract off the existing checksum value in the table */ 348 349 Checksum = (UINT8) (Checksum - OriginalChecksum); 350 351 /* Compute the final checksum */ 352 353 Checksum = (UINT8) (0 - Checksum); 354 return (Checksum); 355 } 356 357 358 /******************************************************************************* 359 * 360 * FUNCTION: AcpiDmGetTableData 361 * 362 * PARAMETERS: Signature - ACPI signature (4 chars) to match 363 * 364 * RETURN: Pointer to a valid ACPI_DMTABLE_DATA. Null if no match found. 365 * 366 * DESCRIPTION: Find a match in the global table of supported ACPI tables 367 * 368 ******************************************************************************/ 369 370 ACPI_DMTABLE_DATA * 371 AcpiDmGetTableData ( 372 char *Signature) 373 { 374 ACPI_DMTABLE_DATA *TableData; 375 376 377 for (TableData = AcpiDmTableData; TableData->Signature; TableData++) 378 { 379 if (ACPI_COMPARE_NAME (Signature, TableData->Signature)) 380 { 381 return (TableData); 382 } 383 } 384 385 return (NULL); 386 } 387 388 389 /******************************************************************************* 390 * 391 * FUNCTION: AcpiDmDumpDataTable 392 * 393 * PARAMETERS: Table - An ACPI table 394 * 395 * RETURN: None. 396 * 397 * DESCRIPTION: Format the contents of an ACPI data table (any table other 398 * than an SSDT or DSDT that does not contain executable AML code) 399 * 400 ******************************************************************************/ 401 402 void 403 AcpiDmDumpDataTable ( 404 ACPI_TABLE_HEADER *Table) 405 { 406 ACPI_STATUS Status; 407 ACPI_DMTABLE_DATA *TableData; 408 UINT32 Length; 409 410 411 /* Ignore tables that contain AML */ 412 413 if (AcpiUtIsAmlTable (Table)) 414 { 415 return; 416 } 417 418 /* 419 * Handle tables that don't use the common ACPI table header structure. 420 * Currently, these are the FACS, RSDP, and S3PT. 421 */ 422 if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_FACS)) 423 { 424 Length = Table->Length; 425 AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoFacs); 426 } 427 else if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_RSDP)) 428 { 429 Length = AcpiDmDumpRsdp (Table); 430 } 431 else if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_S3PT)) 432 { 433 Length = AcpiDmDumpS3pt (Table); 434 } 435 else 436 { 437 /* 438 * All other tables must use the common ACPI table header, dump it now 439 */ 440 Length = Table->Length; 441 Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoHeader); 442 if (ACPI_FAILURE (Status)) 443 { 444 return; 445 } 446 AcpiOsPrintf ("\n"); 447 448 /* Match signature and dispatch appropriately */ 449 450 TableData = AcpiDmGetTableData (Table->Signature); 451 if (!TableData) 452 { 453 if (!ACPI_STRNCMP (Table->Signature, "OEM", 3)) 454 { 455 AcpiOsPrintf ("\n**** OEM-defined ACPI table [%4.4s], unknown contents\n\n", 456 Table->Signature); 457 } 458 else 459 { 460 AcpiOsPrintf ("\n**** Unknown ACPI table type [%4.4s]\n\n", 461 Table->Signature); 462 } 463 } 464 else if (TableData->TableHandler) 465 { 466 /* Complex table, has a handler */ 467 468 TableData->TableHandler (Table); 469 } 470 else if (TableData->TableInfo) 471 { 472 /* Simple table, just walk the info table */ 473 474 AcpiDmDumpTable (Length, 0, Table, 0, TableData->TableInfo); 475 } 476 } 477 478 if (!Gbl_DoTemplates || Gbl_VerboseTemplates) 479 { 480 /* Dump the raw table data */ 481 482 AcpiOsPrintf ("\n%s: Length %d (0x%X)\n\n", 483 ACPI_RAW_TABLE_DATA_HEADER, Length, Length); 484 AcpiUtDumpBuffer2 (ACPI_CAST_PTR (UINT8, Table), Length, DB_BYTE_DISPLAY); 485 } 486 } 487 488 489 /******************************************************************************* 490 * 491 * FUNCTION: AcpiDmLineHeader 492 * 493 * PARAMETERS: Offset - Current byte offset, from table start 494 * ByteLength - Length of the field in bytes, 0 for flags 495 * Name - Name of this field 496 * Value - Optional value, displayed on left of ':' 497 * 498 * RETURN: None 499 * 500 * DESCRIPTION: Utility routines for formatting output lines. Displays the 501 * current table offset in hex and decimal, the field length, 502 * and the field name. 503 * 504 ******************************************************************************/ 505 506 void 507 AcpiDmLineHeader ( 508 UINT32 Offset, 509 UINT32 ByteLength, 510 char *Name) 511 { 512 513 /* Allow a null name for fields that span multiple lines (large buffers) */ 514 515 if (!Name) 516 { 517 Name = ""; 518 } 519 520 if (Gbl_DoTemplates && !Gbl_VerboseTemplates) /* Terse template */ 521 { 522 if (ByteLength) 523 { 524 AcpiOsPrintf ("[%.4d] %34s : ", ByteLength, Name); 525 } 526 else 527 { 528 if (*Name) 529 { 530 AcpiOsPrintf ("%41s : ", Name); 531 } 532 else 533 { 534 AcpiOsPrintf ("%41s ", Name); 535 } 536 } 537 } 538 else /* Normal disassembler or verbose template */ 539 { 540 if (ByteLength) 541 { 542 AcpiOsPrintf ("[%3.3Xh %4.4d% 4d] %28s : ", 543 Offset, Offset, ByteLength, Name); 544 } 545 else 546 { 547 if (*Name) 548 { 549 AcpiOsPrintf ("%44s : ", Name); 550 } 551 else 552 { 553 AcpiOsPrintf ("%44s ", Name); 554 } 555 } 556 } 557 } 558 559 void 560 AcpiDmLineHeader2 ( 561 UINT32 Offset, 562 UINT32 ByteLength, 563 char *Name, 564 UINT32 Value) 565 { 566 567 if (Gbl_DoTemplates && !Gbl_VerboseTemplates) /* Terse template */ 568 { 569 if (ByteLength) 570 { 571 AcpiOsPrintf ("[%.4d] %30s %3d : ", 572 ByteLength, Name, Value); 573 } 574 else 575 { 576 AcpiOsPrintf ("%36s % 3d : ", 577 Name, Value); 578 } 579 } 580 else /* Normal disassembler or verbose template */ 581 { 582 if (ByteLength) 583 { 584 AcpiOsPrintf ("[%3.3Xh %4.4d %3d] %24s %3d : ", 585 Offset, Offset, ByteLength, Name, Value); 586 } 587 else 588 { 589 AcpiOsPrintf ("[%3.3Xh %4.4d ] %24s %3d : ", 590 Offset, Offset, Name, Value); 591 } 592 } 593 } 594 595 596 /******************************************************************************* 597 * 598 * FUNCTION: AcpiDmDumpTable 599 * 600 * PARAMETERS: TableLength - Length of the entire ACPI table 601 * TableOffset - Starting offset within the table for this 602 * sub-descriptor (0 if main table) 603 * Table - The ACPI table 604 * SubtableLength - Length of this sub-descriptor 605 * Info - Info table for this ACPI table 606 * 607 * RETURN: None 608 * 609 * DESCRIPTION: Display ACPI table contents by walking the Info table. 610 * 611 * Note: This function must remain in sync with DtGetFieldLength. 612 * 613 ******************************************************************************/ 614 615 ACPI_STATUS 616 AcpiDmDumpTable ( 617 UINT32 TableLength, 618 UINT32 TableOffset, 619 void *Table, 620 UINT32 SubtableLength, 621 ACPI_DMTABLE_INFO *Info) 622 { 623 UINT8 *Target; 624 UINT32 CurrentOffset; 625 UINT32 ByteLength; 626 UINT8 Temp8; 627 UINT16 Temp16; 628 ACPI_DMTABLE_DATA *TableData; 629 const char *Name; 630 BOOLEAN LastOutputBlankLine = FALSE; 631 char RepairedName[8]; 632 633 634 if (!Info) 635 { 636 AcpiOsPrintf ("Display not implemented\n"); 637 return (AE_NOT_IMPLEMENTED); 638 } 639 640 /* Walk entire Info table; Null name terminates */ 641 642 for (; Info->Name; Info++) 643 { 644 /* 645 * Target points to the field within the ACPI Table. CurrentOffset is 646 * the offset of the field from the start of the main table. 647 */ 648 Target = ACPI_ADD_PTR (UINT8, Table, Info->Offset); 649 CurrentOffset = TableOffset + Info->Offset; 650 651 /* Check for beyond EOT or beyond subtable end */ 652 653 if ((CurrentOffset >= TableLength) || 654 (SubtableLength && (Info->Offset >= SubtableLength))) 655 { 656 AcpiOsPrintf ("**** ACPI table terminates in the middle of a data structure!\n"); 657 return (AE_BAD_DATA); 658 } 659 660 /* Generate the byte length for this field */ 661 662 switch (Info->Opcode) 663 { 664 case ACPI_DMT_UINT8: 665 case ACPI_DMT_CHKSUM: 666 case ACPI_DMT_SPACEID: 667 case ACPI_DMT_ACCWIDTH: 668 case ACPI_DMT_IVRS: 669 case ACPI_DMT_MADT: 670 case ACPI_DMT_PMTT: 671 case ACPI_DMT_SRAT: 672 case ACPI_DMT_ASF: 673 case ACPI_DMT_HESTNTYP: 674 case ACPI_DMT_FADTPM: 675 case ACPI_DMT_EINJACT: 676 case ACPI_DMT_EINJINST: 677 case ACPI_DMT_ERSTACT: 678 case ACPI_DMT_ERSTINST: 679 ByteLength = 1; 680 break; 681 case ACPI_DMT_UINT16: 682 case ACPI_DMT_DMAR: 683 case ACPI_DMT_HEST: 684 ByteLength = 2; 685 break; 686 case ACPI_DMT_UINT24: 687 ByteLength = 3; 688 break; 689 case ACPI_DMT_UINT32: 690 case ACPI_DMT_NAME4: 691 case ACPI_DMT_SIG: 692 case ACPI_DMT_SLIC: 693 ByteLength = 4; 694 break; 695 case ACPI_DMT_UINT40: 696 ByteLength = 5; 697 break; 698 case ACPI_DMT_UINT48: 699 case ACPI_DMT_NAME6: 700 ByteLength = 6; 701 break; 702 case ACPI_DMT_UINT56: 703 case ACPI_DMT_BUF7: 704 ByteLength = 7; 705 break; 706 case ACPI_DMT_UINT64: 707 case ACPI_DMT_NAME8: 708 ByteLength = 8; 709 break; 710 case ACPI_DMT_BUF16: 711 case ACPI_DMT_UUID: 712 ByteLength = 16; 713 break; 714 case ACPI_DMT_BUF128: 715 ByteLength = 128; 716 break; 717 case ACPI_DMT_STRING: 718 ByteLength = ACPI_STRLEN (ACPI_CAST_PTR (char, Target)) + 1; 719 break; 720 case ACPI_DMT_GAS: 721 if (!LastOutputBlankLine) 722 { 723 AcpiOsPrintf ("\n"); 724 LastOutputBlankLine = TRUE; 725 } 726 ByteLength = sizeof (ACPI_GENERIC_ADDRESS); 727 break; 728 case ACPI_DMT_HESTNTFY: 729 if (!LastOutputBlankLine) 730 { 731 AcpiOsPrintf ("\n"); 732 LastOutputBlankLine = TRUE; 733 } 734 ByteLength = sizeof (ACPI_HEST_NOTIFY); 735 break; 736 default: 737 ByteLength = 0; 738 break; 739 } 740 741 if (CurrentOffset + ByteLength > TableLength) 742 { 743 AcpiOsPrintf ("**** ACPI table terminates in the middle of a data structure!\n"); 744 return (AE_BAD_DATA); 745 } 746 747 if (Info->Opcode == ACPI_DMT_EXTRA_TEXT) 748 { 749 AcpiOsPrintf ("%s", Info->Name); 750 continue; 751 } 752 753 /* Start a new line and decode the opcode */ 754 755 AcpiDmLineHeader (CurrentOffset, ByteLength, Info->Name); 756 757 switch (Info->Opcode) 758 { 759 /* Single-bit Flag fields. Note: Opcode is the bit position */ 760 761 case ACPI_DMT_FLAG0: 762 case ACPI_DMT_FLAG1: 763 case ACPI_DMT_FLAG2: 764 case ACPI_DMT_FLAG3: 765 case ACPI_DMT_FLAG4: 766 case ACPI_DMT_FLAG5: 767 case ACPI_DMT_FLAG6: 768 case ACPI_DMT_FLAG7: 769 770 AcpiOsPrintf ("%1.1X\n", (*Target >> Info->Opcode) & 0x01); 771 break; 772 773 /* 2-bit Flag fields */ 774 775 case ACPI_DMT_FLAGS0: 776 777 AcpiOsPrintf ("%1.1X\n", *Target & 0x03); 778 break; 779 780 case ACPI_DMT_FLAGS1: 781 782 AcpiOsPrintf ("%1.1X\n", (*Target >> 1) & 0x03); 783 break; 784 785 case ACPI_DMT_FLAGS2: 786 787 AcpiOsPrintf ("%1.1X\n", (*Target >> 2) & 0x03); 788 break; 789 790 case ACPI_DMT_FLAGS4: 791 792 AcpiOsPrintf ("%1.1X\n", (*Target >> 4) & 0x03); 793 break; 794 795 /* Integer Data Types */ 796 797 case ACPI_DMT_UINT8: 798 case ACPI_DMT_UINT16: 799 case ACPI_DMT_UINT24: 800 case ACPI_DMT_UINT32: 801 case ACPI_DMT_UINT40: 802 case ACPI_DMT_UINT48: 803 case ACPI_DMT_UINT56: 804 case ACPI_DMT_UINT64: 805 /* 806 * Dump bytes - high byte first, low byte last. 807 * Note: All ACPI tables are little-endian. 808 */ 809 for (Temp8 = (UINT8) ByteLength; Temp8 > 0; Temp8--) 810 { 811 AcpiOsPrintf ("%2.2X", Target[Temp8 - 1]); 812 } 813 AcpiOsPrintf ("\n"); 814 break; 815 816 case ACPI_DMT_BUF7: 817 case ACPI_DMT_BUF16: 818 case ACPI_DMT_BUF128: 819 820 /* 821 * Buffer: Size depends on the opcode and was set above. 822 * Each hex byte is separated with a space. 823 * Multiple lines are separated by line continuation char. 824 */ 825 for (Temp16 = 0; Temp16 < ByteLength; Temp16++) 826 { 827 AcpiOsPrintf ("%2.2X", Target[Temp16]); 828 if ((UINT32) (Temp16 + 1) < ByteLength) 829 { 830 if ((Temp16 > 0) && (!((Temp16+1) % 16))) 831 { 832 AcpiOsPrintf (" \\\n"); /* Line continuation */ 833 AcpiDmLineHeader (0, 0, NULL); 834 } 835 else 836 { 837 AcpiOsPrintf (" "); 838 } 839 } 840 } 841 AcpiOsPrintf ("\n"); 842 break; 843 844 case ACPI_DMT_UUID: 845 846 /* Convert 16-byte UUID buffer to 36-byte formatted UUID string */ 847 848 (void) AuConvertUuidToString ((char *) Target, MsgBuffer); 849 850 AcpiOsPrintf ("%s\n", MsgBuffer); 851 break; 852 853 case ACPI_DMT_STRING: 854 855 AcpiOsPrintf ("\"%s\"\n", ACPI_CAST_PTR (char, Target)); 856 break; 857 858 /* Fixed length ASCII name fields */ 859 860 case ACPI_DMT_SIG: 861 862 AcpiDmCheckAscii (Target, RepairedName, 4); 863 AcpiOsPrintf ("\"%.4s\" ", RepairedName); 864 TableData = AcpiDmGetTableData (ACPI_CAST_PTR (char, Target)); 865 if (TableData) 866 { 867 AcpiOsPrintf (STRING_FORMAT, TableData->Name); 868 } 869 else 870 { 871 AcpiOsPrintf ("\n"); 872 } 873 break; 874 875 case ACPI_DMT_NAME4: 876 877 AcpiDmCheckAscii (Target, RepairedName, 4); 878 AcpiOsPrintf ("\"%.4s\"\n", RepairedName); 879 break; 880 881 case ACPI_DMT_NAME6: 882 883 AcpiDmCheckAscii (Target, RepairedName, 6); 884 AcpiOsPrintf ("\"%.6s\"\n", RepairedName); 885 break; 886 887 case ACPI_DMT_NAME8: 888 889 AcpiDmCheckAscii (Target, RepairedName, 8); 890 AcpiOsPrintf ("\"%.8s\"\n", RepairedName); 891 break; 892 893 /* Special Data Types */ 894 895 case ACPI_DMT_CHKSUM: 896 897 /* Checksum, display and validate */ 898 899 AcpiOsPrintf ("%2.2X", *Target); 900 Temp8 = AcpiDmGenerateChecksum (Table, 901 ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Length, 902 ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Checksum); 903 if (Temp8 != ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Checksum) 904 { 905 AcpiOsPrintf ( 906 " /* Incorrect checksum, should be %2.2X */", Temp8); 907 } 908 AcpiOsPrintf ("\n"); 909 break; 910 911 case ACPI_DMT_SPACEID: 912 913 /* Address Space ID */ 914 915 AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiUtGetRegionName (*Target)); 916 break; 917 918 case ACPI_DMT_ACCWIDTH: 919 920 /* Encoded Access Width */ 921 922 Temp8 = *Target; 923 if (Temp8 > ACPI_GAS_WIDTH_RESERVED) 924 { 925 Temp8 = ACPI_GAS_WIDTH_RESERVED; 926 } 927 928 AcpiOsPrintf (UINT8_FORMAT, Temp8, AcpiDmGasAccessWidth[Temp8]); 929 break; 930 931 case ACPI_DMT_GAS: 932 933 /* Generic Address Structure */ 934 935 AcpiOsPrintf (STRING_FORMAT, "Generic Address Structure"); 936 AcpiDmDumpTable (TableLength, CurrentOffset, Target, 937 sizeof (ACPI_GENERIC_ADDRESS), AcpiDmTableInfoGas); 938 AcpiOsPrintf ("\n"); 939 LastOutputBlankLine = TRUE; 940 break; 941 942 case ACPI_DMT_ASF: 943 944 /* ASF subtable types */ 945 946 Temp16 = (UINT16) ((*Target) & 0x7F); /* Top bit can be zero or one */ 947 if (Temp16 > ACPI_ASF_TYPE_RESERVED) 948 { 949 Temp16 = ACPI_ASF_TYPE_RESERVED; 950 } 951 952 AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmAsfSubnames[Temp16]); 953 break; 954 955 case ACPI_DMT_DMAR: 956 957 /* DMAR subtable types */ 958 959 Temp16 = ACPI_GET16 (Target); 960 if (Temp16 > ACPI_DMAR_TYPE_RESERVED) 961 { 962 Temp16 = ACPI_DMAR_TYPE_RESERVED; 963 } 964 965 AcpiOsPrintf (UINT16_FORMAT, ACPI_GET16 (Target), AcpiDmDmarSubnames[Temp16]); 966 break; 967 968 case ACPI_DMT_EINJACT: 969 970 /* EINJ Action types */ 971 972 Temp8 = *Target; 973 if (Temp8 > ACPI_EINJ_ACTION_RESERVED) 974 { 975 Temp8 = ACPI_EINJ_ACTION_RESERVED; 976 } 977 978 AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmEinjActions[Temp8]); 979 break; 980 981 case ACPI_DMT_EINJINST: 982 983 /* EINJ Instruction types */ 984 985 Temp8 = *Target; 986 if (Temp8 > ACPI_EINJ_INSTRUCTION_RESERVED) 987 { 988 Temp8 = ACPI_EINJ_INSTRUCTION_RESERVED; 989 } 990 991 AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmEinjInstructions[Temp8]); 992 break; 993 994 case ACPI_DMT_ERSTACT: 995 996 /* ERST Action types */ 997 998 Temp8 = *Target; 999 if (Temp8 > ACPI_ERST_ACTION_RESERVED) 1000 { 1001 Temp8 = ACPI_ERST_ACTION_RESERVED; 1002 } 1003 1004 AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmErstActions[Temp8]); 1005 break; 1006 1007 case ACPI_DMT_ERSTINST: 1008 1009 /* ERST Instruction types */ 1010 1011 Temp8 = *Target; 1012 if (Temp8 > ACPI_ERST_INSTRUCTION_RESERVED) 1013 { 1014 Temp8 = ACPI_ERST_INSTRUCTION_RESERVED; 1015 } 1016 1017 AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmErstInstructions[Temp8]); 1018 break; 1019 1020 case ACPI_DMT_HEST: 1021 1022 /* HEST subtable types */ 1023 1024 Temp16 = ACPI_GET16 (Target); 1025 if (Temp16 > ACPI_HEST_TYPE_RESERVED) 1026 { 1027 Temp16 = ACPI_HEST_TYPE_RESERVED; 1028 } 1029 1030 AcpiOsPrintf (UINT16_FORMAT, ACPI_GET16 (Target), AcpiDmHestSubnames[Temp16]); 1031 break; 1032 1033 case ACPI_DMT_HESTNTFY: 1034 1035 AcpiOsPrintf (STRING_FORMAT, "Hardware Error Notification Structure"); 1036 AcpiDmDumpTable (TableLength, CurrentOffset, Target, 1037 sizeof (ACPI_HEST_NOTIFY), AcpiDmTableInfoHestNotify); 1038 AcpiOsPrintf ("\n"); 1039 LastOutputBlankLine = TRUE; 1040 break; 1041 1042 case ACPI_DMT_HESTNTYP: 1043 1044 /* HEST Notify types */ 1045 1046 Temp8 = *Target; 1047 if (Temp8 > ACPI_HEST_NOTIFY_RESERVED) 1048 { 1049 Temp8 = ACPI_HEST_NOTIFY_RESERVED; 1050 } 1051 1052 AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmHestNotifySubnames[Temp8]); 1053 break; 1054 1055 case ACPI_DMT_MADT: 1056 1057 /* MADT subtable types */ 1058 1059 Temp8 = *Target; 1060 if (Temp8 > ACPI_MADT_TYPE_RESERVED) 1061 { 1062 Temp8 = ACPI_MADT_TYPE_RESERVED; 1063 } 1064 1065 AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmMadtSubnames[Temp8]); 1066 break; 1067 1068 case ACPI_DMT_PMTT: 1069 1070 /* PMTT subtable types */ 1071 1072 Temp8 = *Target; 1073 if (Temp8 > ACPI_PMTT_TYPE_RESERVED) 1074 { 1075 Temp8 = ACPI_PMTT_TYPE_RESERVED; 1076 } 1077 1078 AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmPmttSubnames[Temp8]); 1079 break; 1080 1081 case ACPI_DMT_SLIC: 1082 1083 /* SLIC subtable types */ 1084 1085 Temp8 = *Target; 1086 if (Temp8 > ACPI_SLIC_TYPE_RESERVED) 1087 { 1088 Temp8 = ACPI_SLIC_TYPE_RESERVED; 1089 } 1090 1091 AcpiOsPrintf (UINT32_FORMAT, *Target, AcpiDmSlicSubnames[Temp8]); 1092 break; 1093 1094 case ACPI_DMT_SRAT: 1095 1096 /* SRAT subtable types */ 1097 1098 Temp8 = *Target; 1099 if (Temp8 > ACPI_SRAT_TYPE_RESERVED) 1100 { 1101 Temp8 = ACPI_SRAT_TYPE_RESERVED; 1102 } 1103 1104 AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmSratSubnames[Temp8]); 1105 break; 1106 1107 case ACPI_DMT_FADTPM: 1108 1109 /* FADT Preferred PM Profile names */ 1110 1111 Temp8 = *Target; 1112 if (Temp8 > ACPI_FADT_PM_RESERVED) 1113 { 1114 Temp8 = ACPI_FADT_PM_RESERVED; 1115 } 1116 1117 AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmFadtProfiles[Temp8]); 1118 break; 1119 1120 case ACPI_DMT_IVRS: 1121 1122 /* IVRS subtable types */ 1123 1124 Temp8 = *Target; 1125 switch (Temp8) 1126 { 1127 case ACPI_IVRS_TYPE_HARDWARE: 1128 Name = AcpiDmIvrsSubnames[0]; 1129 break; 1130 1131 case ACPI_IVRS_TYPE_MEMORY1: 1132 case ACPI_IVRS_TYPE_MEMORY2: 1133 case ACPI_IVRS_TYPE_MEMORY3: 1134 Name = AcpiDmIvrsSubnames[1]; 1135 break; 1136 1137 default: 1138 Name = AcpiDmIvrsSubnames[2]; 1139 break; 1140 } 1141 1142 AcpiOsPrintf (UINT8_FORMAT, *Target, Name); 1143 break; 1144 1145 case ACPI_DMT_EXIT: 1146 return (AE_OK); 1147 1148 default: 1149 ACPI_ERROR ((AE_INFO, 1150 "**** Invalid table opcode [0x%X] ****\n", Info->Opcode)); 1151 return (AE_SUPPORT); 1152 } 1153 } 1154 1155 if (TableOffset && !SubtableLength) 1156 { 1157 /* If this table is not the main table, subtable must have valid length */ 1158 1159 AcpiOsPrintf ("Invalid zero length subtable\n"); 1160 return (AE_BAD_DATA); 1161 } 1162 1163 return (AE_OK); 1164 } 1165 1166 1167 /******************************************************************************* 1168 * 1169 * FUNCTION: AcpiDmCheckAscii 1170 * 1171 * PARAMETERS: Name - Ascii string 1172 * Count - Number of characters to check 1173 * 1174 * RETURN: None 1175 * 1176 * DESCRIPTION: Ensure that the requested number of characters are printable 1177 * Ascii characters. Sets non-printable and null chars to <space>. 1178 * 1179 ******************************************************************************/ 1180 1181 static void 1182 AcpiDmCheckAscii ( 1183 UINT8 *Name, 1184 char *RepairedName, 1185 UINT32 Count) 1186 { 1187 UINT32 i; 1188 1189 1190 for (i = 0; i < Count; i++) 1191 { 1192 RepairedName[i] = (char) Name[i]; 1193 1194 if (!Name[i]) 1195 { 1196 return; 1197 } 1198 if (!isprint (Name[i])) 1199 { 1200 RepairedName[i] = ' '; 1201 } 1202 } 1203 } 1204