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