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