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