dmtable.c revision 218590
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 58static void 59AcpiDmCheckAscii ( 60 UINT8 *Target, 61 char *RepairedName, 62 UINT32 Count); 63 64 65/* These tables map a subtable type to a description string */ 66 67static 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 77static 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 86static 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 99static 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 109static 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 130static 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 154static 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 169static const char *AcpiDmHestNotifySubnames[] = 170{ 171 "Polled", 172 "External Interrupt", 173 "Local Interrupt", 174 "SCI", 175 "NMI", 176 "Unknown Notify Type" /* Reserved */ 177}; 178 179static 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 195static 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 203static 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 213static 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 228static 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 252ACPI_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 303UINT8 304AcpiDmGenerateChecksum ( 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 339ACPI_DMTABLE_DATA * 340AcpiDmGetTableData ( 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 371void 372AcpiDmDumpDataTable ( 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 471void 472AcpiDmLineHeader ( 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 506void 507AcpiDmLineHeader2 ( 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 562ACPI_STATUS 563AcpiDmDumpTable ( 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 case ACPI_DMT_BUF7: 645 ByteLength = 7; 646 break; 647 case ACPI_DMT_UINT64: 648 case ACPI_DMT_NAME8: 649 ByteLength = 8; 650 break; 651 case ACPI_DMT_BUF16: 652 case ACPI_DMT_UUID: 653 ByteLength = 16; 654 break; 655 case ACPI_DMT_STRING: 656 ByteLength = ACPI_STRLEN (ACPI_CAST_PTR (char, Target)) + 1; 657 break; 658 case ACPI_DMT_GAS: 659 if (!LastOutputBlankLine) 660 { 661 AcpiOsPrintf ("\n"); 662 LastOutputBlankLine = TRUE; 663 } 664 ByteLength = sizeof (ACPI_GENERIC_ADDRESS); 665 break; 666 case ACPI_DMT_HESTNTFY: 667 if (!LastOutputBlankLine) 668 { 669 AcpiOsPrintf ("\n"); 670 LastOutputBlankLine = TRUE; 671 } 672 ByteLength = sizeof (ACPI_HEST_NOTIFY); 673 break; 674 default: 675 ByteLength = 0; 676 break; 677 } 678 679 if (CurrentOffset + ByteLength > TableLength) 680 { 681 AcpiOsPrintf ("**** ACPI table terminates in the middle of a data structure!\n"); 682 return (AE_BAD_DATA); 683 } 684 685 /* Start a new line and decode the opcode */ 686 687 AcpiDmLineHeader (CurrentOffset, ByteLength, Info->Name); 688 689 switch (Info->Opcode) 690 { 691 /* Single-bit Flag fields. Note: Opcode is the bit position */ 692 693 case ACPI_DMT_FLAG0: 694 case ACPI_DMT_FLAG1: 695 case ACPI_DMT_FLAG2: 696 case ACPI_DMT_FLAG3: 697 case ACPI_DMT_FLAG4: 698 case ACPI_DMT_FLAG5: 699 case ACPI_DMT_FLAG6: 700 case ACPI_DMT_FLAG7: 701 702 AcpiOsPrintf ("%1.1X\n", (*Target >> Info->Opcode) & 0x01); 703 break; 704 705 /* 2-bit Flag fields */ 706 707 case ACPI_DMT_FLAGS0: 708 709 AcpiOsPrintf ("%1.1X\n", *Target & 0x03); 710 break; 711 712 case ACPI_DMT_FLAGS2: 713 714 AcpiOsPrintf ("%1.1X\n", (*Target >> 2) & 0x03); 715 break; 716 717 /* Standard Data Types */ 718 719 case ACPI_DMT_UINT8: 720 721 AcpiOsPrintf ("%2.2X\n", *Target); 722 break; 723 724 case ACPI_DMT_UINT16: 725 726 AcpiOsPrintf ("%4.4X\n", ACPI_GET16 (Target)); 727 break; 728 729 case ACPI_DMT_UINT24: 730 731 AcpiOsPrintf ("%2.2X%2.2X%2.2X\n", 732 *Target, *(Target + 1), *(Target + 2)); 733 break; 734 735 case ACPI_DMT_UINT32: 736 737 AcpiOsPrintf ("%8.8X\n", ACPI_GET32 (Target)); 738 break; 739 740 case ACPI_DMT_UINT56: 741 742 for (Temp8 = 0; Temp8 < 7; Temp8++) 743 { 744 AcpiOsPrintf ("%2.2X", Target[Temp8]); 745 } 746 AcpiOsPrintf ("\n"); 747 break; 748 749 case ACPI_DMT_UINT64: 750 751 AcpiOsPrintf ("%8.8X%8.8X\n", 752 ACPI_FORMAT_UINT64 (ACPI_GET64 (Target))); 753 break; 754 755 case ACPI_DMT_BUF7: 756 case ACPI_DMT_BUF16: 757 758 /* 759 * Buffer: Size depends on the opcode and was set above. 760 * Each hex byte is separated with a space. 761 */ 762 for (Temp8 = 0; Temp8 < ByteLength; Temp8++) 763 { 764 AcpiOsPrintf ("%2.2X", Target[Temp8]); 765 if ((UINT32) (Temp8 + 1) < ByteLength) 766 { 767 AcpiOsPrintf (" "); 768 } 769 } 770 AcpiOsPrintf ("\n"); 771 break; 772 773 case ACPI_DMT_UUID: 774 775 /* Convert 16-byte UUID buffer to 36-byte formatted UUID string */ 776 777 (void) AuConvertUuidToString ((char *) Target, MsgBuffer); 778 779 AcpiOsPrintf ("%s\n", MsgBuffer); 780 break; 781 782 case ACPI_DMT_STRING: 783 784 AcpiOsPrintf ("\"%s\"\n", ACPI_CAST_PTR (char, Target)); 785 break; 786 787 /* Fixed length ASCII name fields */ 788 789 case ACPI_DMT_SIG: 790 791 AcpiDmCheckAscii (Target, RepairedName, 4); 792 AcpiOsPrintf ("\"%.4s\" ", RepairedName); 793 TableData = AcpiDmGetTableData (ACPI_CAST_PTR (char, Target)); 794 if (TableData) 795 { 796 AcpiOsPrintf ("/* %s */", TableData->Name); 797 } 798 AcpiOsPrintf ("\n"); 799 break; 800 801 case ACPI_DMT_NAME4: 802 803 AcpiDmCheckAscii (Target, RepairedName, 4); 804 AcpiOsPrintf ("\"%.4s\"\n", RepairedName); 805 break; 806 807 case ACPI_DMT_NAME6: 808 809 AcpiDmCheckAscii (Target, RepairedName, 6); 810 AcpiOsPrintf ("\"%.6s\"\n", RepairedName); 811 break; 812 813 case ACPI_DMT_NAME8: 814 815 AcpiDmCheckAscii (Target, RepairedName, 8); 816 AcpiOsPrintf ("\"%.8s\"\n", RepairedName); 817 break; 818 819 /* Special Data Types */ 820 821 case ACPI_DMT_CHKSUM: 822 823 /* Checksum, display and validate */ 824 825 AcpiOsPrintf ("%2.2X", *Target); 826 Temp8 = AcpiDmGenerateChecksum (Table, 827 ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Length, 828 ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Checksum); 829 if (Temp8 != ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Checksum) 830 { 831 AcpiOsPrintf ( 832 " /* Incorrect checksum, should be %2.2X */", Temp8); 833 } 834 AcpiOsPrintf ("\n"); 835 break; 836 837 case ACPI_DMT_SPACEID: 838 839 /* Address Space ID */ 840 841 AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiUtGetRegionName (*Target)); 842 break; 843 844 case ACPI_DMT_ACCWIDTH: 845 846 /* Encoded Access Width */ 847 848 Temp8 = *Target; 849 if (Temp8 > ACPI_GAS_WIDTH_RESERVED) 850 { 851 Temp8 = ACPI_GAS_WIDTH_RESERVED; 852 } 853 854 AcpiOsPrintf ("%2.2X (%s)\n", Temp8, AcpiDmGasAccessWidth[Temp8]); 855 break; 856 857 case ACPI_DMT_GAS: 858 859 /* Generic Address Structure */ 860 861 AcpiOsPrintf ("<Generic Address Structure>\n"); 862 AcpiDmDumpTable (TableLength, CurrentOffset, Target, 863 sizeof (ACPI_GENERIC_ADDRESS), AcpiDmTableInfoGas); 864 AcpiOsPrintf ("\n"); 865 LastOutputBlankLine = TRUE; 866 break; 867 868 case ACPI_DMT_ASF: 869 870 /* ASF subtable types */ 871 872 Temp16 = (UINT16) ((*Target) & 0x7F); /* Top bit can be zero or one */ 873 if (Temp16 > ACPI_ASF_TYPE_RESERVED) 874 { 875 Temp16 = ACPI_ASF_TYPE_RESERVED; 876 } 877 878 AcpiOsPrintf ("%2.2X <%s>\n", *Target, AcpiDmAsfSubnames[Temp16]); 879 break; 880 881 case ACPI_DMT_DMAR: 882 883 /* DMAR subtable types */ 884 885 Temp16 = ACPI_GET16 (Target); 886 if (Temp16 > ACPI_DMAR_TYPE_RESERVED) 887 { 888 Temp16 = ACPI_DMAR_TYPE_RESERVED; 889 } 890 891 AcpiOsPrintf ("%4.4X <%s>\n", ACPI_GET16 (Target), AcpiDmDmarSubnames[Temp16]); 892 break; 893 894 case ACPI_DMT_EINJACT: 895 896 /* EINJ Action types */ 897 898 Temp8 = *Target; 899 if (Temp8 > ACPI_EINJ_ACTION_RESERVED) 900 { 901 Temp8 = ACPI_EINJ_ACTION_RESERVED; 902 } 903 904 AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiDmEinjActions[Temp8]); 905 break; 906 907 case ACPI_DMT_EINJINST: 908 909 /* EINJ Instruction types */ 910 911 Temp8 = *Target; 912 if (Temp8 > ACPI_EINJ_INSTRUCTION_RESERVED) 913 { 914 Temp8 = ACPI_EINJ_INSTRUCTION_RESERVED; 915 } 916 917 AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiDmEinjInstructions[Temp8]); 918 break; 919 920 case ACPI_DMT_ERSTACT: 921 922 /* ERST Action types */ 923 924 Temp8 = *Target; 925 if (Temp8 > ACPI_ERST_ACTION_RESERVED) 926 { 927 Temp8 = ACPI_ERST_ACTION_RESERVED; 928 } 929 930 AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiDmErstActions[Temp8]); 931 break; 932 933 case ACPI_DMT_ERSTINST: 934 935 /* ERST Instruction types */ 936 937 Temp8 = *Target; 938 if (Temp8 > ACPI_ERST_INSTRUCTION_RESERVED) 939 { 940 Temp8 = ACPI_ERST_INSTRUCTION_RESERVED; 941 } 942 943 AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiDmErstInstructions[Temp8]); 944 break; 945 946 case ACPI_DMT_HEST: 947 948 /* HEST subtable types */ 949 950 Temp16 = ACPI_GET16 (Target); 951 if (Temp16 > ACPI_HEST_TYPE_RESERVED) 952 { 953 Temp16 = ACPI_HEST_TYPE_RESERVED; 954 } 955 956 AcpiOsPrintf ("%4.4X (%s)\n", ACPI_GET16 (Target), AcpiDmHestSubnames[Temp16]); 957 break; 958 959 case ACPI_DMT_HESTNTFY: 960 961 AcpiOsPrintf ("<Hardware Error Notification Structure>\n"); 962 AcpiDmDumpTable (TableLength, CurrentOffset, Target, 963 sizeof (ACPI_HEST_NOTIFY), AcpiDmTableInfoHestNotify); 964 AcpiOsPrintf ("\n"); 965 LastOutputBlankLine = TRUE; 966 break; 967 968 case ACPI_DMT_HESTNTYP: 969 970 /* HEST Notify types */ 971 972 Temp8 = *Target; 973 if (Temp8 > ACPI_HEST_NOTIFY_RESERVED) 974 { 975 Temp8 = ACPI_HEST_NOTIFY_RESERVED; 976 } 977 978 AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiDmHestNotifySubnames[Temp8]); 979 break; 980 981 case ACPI_DMT_MADT: 982 983 /* MADT subtable types */ 984 985 Temp8 = *Target; 986 if (Temp8 > ACPI_MADT_TYPE_RESERVED) 987 { 988 Temp8 = ACPI_MADT_TYPE_RESERVED; 989 } 990 991 AcpiOsPrintf ("%2.2X <%s>\n", *Target, AcpiDmMadtSubnames[Temp8]); 992 break; 993 994 case ACPI_DMT_SRAT: 995 996 /* SRAT subtable types */ 997 998 Temp8 = *Target; 999 if (Temp8 > ACPI_SRAT_TYPE_RESERVED) 1000 { 1001 Temp8 = ACPI_SRAT_TYPE_RESERVED; 1002 } 1003 1004 AcpiOsPrintf ("%2.2X <%s>\n", *Target, AcpiDmSratSubnames[Temp8]); 1005 break; 1006 1007 case ACPI_DMT_FADTPM: 1008 1009 /* FADT Preferred PM Profile names */ 1010 1011 Temp8 = *Target; 1012 if (Temp8 > ACPI_FADT_PM_RESERVED) 1013 { 1014 Temp8 = ACPI_FADT_PM_RESERVED; 1015 } 1016 1017 AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiDmFadtProfiles[Temp8]); 1018 break; 1019 1020 case ACPI_DMT_IVRS: 1021 1022 /* IVRS subtable types */ 1023 1024 Temp8 = *Target; 1025 switch (Temp8) 1026 { 1027 case ACPI_IVRS_TYPE_HARDWARE: 1028 Name = AcpiDmIvrsSubnames[0]; 1029 break; 1030 1031 case ACPI_IVRS_TYPE_MEMORY1: 1032 case ACPI_IVRS_TYPE_MEMORY2: 1033 case ACPI_IVRS_TYPE_MEMORY3: 1034 Name = AcpiDmIvrsSubnames[1]; 1035 break; 1036 1037 default: 1038 Name = AcpiDmIvrsSubnames[2]; 1039 break; 1040 } 1041 1042 AcpiOsPrintf ("%2.2X <%s>\n", *Target, Name); 1043 break; 1044 1045 case ACPI_DMT_EXIT: 1046 return (AE_OK); 1047 1048 default: 1049 ACPI_ERROR ((AE_INFO, 1050 "**** Invalid table opcode [0x%X] ****\n", Info->Opcode)); 1051 return (AE_SUPPORT); 1052 } 1053 } 1054 1055 if (TableOffset && !SubtableLength) 1056 { 1057 /* If this table is not the main table, subtable must have valid length */ 1058 1059 AcpiOsPrintf ("Invalid zero length subtable\n"); 1060 return (AE_BAD_DATA); 1061 } 1062 1063 return (AE_OK); 1064} 1065 1066 1067/******************************************************************************* 1068 * 1069 * FUNCTION: AcpiDmCheckAscii 1070 * 1071 * PARAMETERS: Name - Ascii string 1072 * Count - Number of characters to check 1073 * 1074 * RETURN: None 1075 * 1076 * DESCRIPTION: Ensure that the requested number of characters are printable 1077 * Ascii characters. Sets non-printable and null chars to <space>. 1078 * 1079 ******************************************************************************/ 1080 1081static void 1082AcpiDmCheckAscii ( 1083 UINT8 *Name, 1084 char *RepairedName, 1085 UINT32 Count) 1086{ 1087 UINT32 i; 1088 1089 1090 for (i = 0; i < Count; i++) 1091 { 1092 RepairedName[i] = (char) Name[i]; 1093 1094 if (!Name[i]) 1095 { 1096 return; 1097 } 1098 if (!isprint (Name[i])) 1099 { 1100 RepairedName[i] = ' '; 1101 } 1102 } 1103} 1104