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