1 /****************************************************************************** 2 * 3 * Module Name: dmtbdump3 - Dump ACPI data tables that contain no AML code 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2023, 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 MERCHANTABILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 #include "acpi.h" 45 #include "accommon.h" 46 #include "acdisasm.h" 47 #include "actables.h" 48 49 /* This module used for application-level code only */ 50 51 #define _COMPONENT ACPI_CA_DISASSEMBLER 52 ACPI_MODULE_NAME ("dmtbdump3") 53 54 55 /******************************************************************************* 56 * 57 * FUNCTION: AcpiDmDumpSlic 58 * 59 * PARAMETERS: Table - A SLIC table 60 * 61 * RETURN: None 62 * 63 * DESCRIPTION: Format the contents of a SLIC 64 * 65 ******************************************************************************/ 66 67 void 68 AcpiDmDumpSlic ( 69 ACPI_TABLE_HEADER *Table) 70 { 71 72 (void) AcpiDmDumpTable (Table->Length, sizeof (ACPI_TABLE_HEADER), 73 (void *) (Table + sizeof (*Table)), 74 Table->Length - sizeof (*Table), AcpiDmTableInfoSlic); 75 } 76 77 78 /******************************************************************************* 79 * 80 * FUNCTION: AcpiDmDumpSlit 81 * 82 * PARAMETERS: Table - An SLIT 83 * 84 * RETURN: None 85 * 86 * DESCRIPTION: Format the contents of a SLIT 87 * 88 ******************************************************************************/ 89 90 void 91 AcpiDmDumpSlit ( 92 ACPI_TABLE_HEADER *Table) 93 { 94 ACPI_STATUS Status; 95 UINT32 Offset; 96 UINT8 *Row; 97 UINT32 Localities; 98 UINT32 i; 99 UINT32 j; 100 101 102 /* Main table */ 103 104 Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoSlit); 105 if (ACPI_FAILURE (Status)) 106 { 107 return; 108 } 109 110 /* Display the Locality NxN Matrix */ 111 112 Localities = (UINT32) ACPI_CAST_PTR (ACPI_TABLE_SLIT, Table)->LocalityCount; 113 Offset = ACPI_OFFSET (ACPI_TABLE_SLIT, Entry[0]); 114 Row = (UINT8 *) ACPI_CAST_PTR (ACPI_TABLE_SLIT, Table)->Entry; 115 116 for (i = 0; i < Localities; i++) 117 { 118 /* Display one row of the matrix */ 119 120 AcpiDmLineHeader2 (Offset, Localities, "Locality", i); 121 for (j = 0; j < Localities; j++) 122 { 123 /* Check for beyond EOT */ 124 125 if (Offset >= Table->Length) 126 { 127 AcpiOsPrintf ( 128 "\n**** Not enough room in table for all localities\n"); 129 return; 130 } 131 132 AcpiOsPrintf ("%2.2X", Row[j]); 133 Offset++; 134 135 /* Display up to 16 bytes per output row */ 136 137 if ((j+1) < Localities) 138 { 139 AcpiOsPrintf (" "); 140 141 if (j && (((j+1) % 16) == 0)) 142 { 143 AcpiOsPrintf ("\\\n"); /* With line continuation char */ 144 AcpiDmLineHeader (Offset, 0, NULL); 145 } 146 } 147 } 148 149 /* Point to next row */ 150 151 AcpiOsPrintf ("\n"); 152 Row += Localities; 153 } 154 } 155 156 157 /******************************************************************************* 158 * 159 * FUNCTION: AcpiDmDumpSrat 160 * 161 * PARAMETERS: Table - A SRAT table 162 * 163 * RETURN: None 164 * 165 * DESCRIPTION: Format the contents of a SRAT 166 * 167 ******************************************************************************/ 168 169 void 170 AcpiDmDumpSrat ( 171 ACPI_TABLE_HEADER *Table) 172 { 173 ACPI_STATUS Status; 174 UINT32 Offset = sizeof (ACPI_TABLE_SRAT); 175 ACPI_SUBTABLE_HEADER *Subtable; 176 ACPI_DMTABLE_INFO *InfoTable; 177 178 179 /* Main table */ 180 181 Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoSrat); 182 if (ACPI_FAILURE (Status)) 183 { 184 return; 185 } 186 187 /* Subtables */ 188 189 Subtable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, Table, Offset); 190 while (Offset < Table->Length) 191 { 192 /* Common subtable header */ 193 194 AcpiOsPrintf ("\n"); 195 Status = AcpiDmDumpTable (Table->Length, Offset, Subtable, 196 Subtable->Length, AcpiDmTableInfoSratHdr); 197 if (ACPI_FAILURE (Status)) 198 { 199 return; 200 } 201 202 switch (Subtable->Type) 203 { 204 case ACPI_SRAT_TYPE_CPU_AFFINITY: 205 206 InfoTable = AcpiDmTableInfoSrat0; 207 break; 208 209 case ACPI_SRAT_TYPE_MEMORY_AFFINITY: 210 211 InfoTable = AcpiDmTableInfoSrat1; 212 break; 213 214 case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY: 215 216 InfoTable = AcpiDmTableInfoSrat2; 217 break; 218 219 case ACPI_SRAT_TYPE_GICC_AFFINITY: 220 221 InfoTable = AcpiDmTableInfoSrat3; 222 break; 223 224 case ACPI_SRAT_TYPE_GIC_ITS_AFFINITY: 225 226 InfoTable = AcpiDmTableInfoSrat4; 227 break; 228 229 case ACPI_SRAT_TYPE_GENERIC_AFFINITY: 230 231 InfoTable = AcpiDmTableInfoSrat5; 232 break; 233 234 case ACPI_SRAT_TYPE_GENERIC_PORT_AFFINITY: 235 236 InfoTable = AcpiDmTableInfoSrat6; 237 break; 238 239 case ACPI_SRAT_TYPE_RINTC_AFFINITY: 240 241 InfoTable = AcpiDmTableInfoSrat7; 242 break; 243 244 default: 245 AcpiOsPrintf ("\n**** Unknown SRAT subtable type 0x%X\n", 246 Subtable->Type); 247 248 /* Attempt to continue */ 249 250 if (!Subtable->Length) 251 { 252 AcpiOsPrintf ("Invalid zero length subtable\n"); 253 return; 254 } 255 goto NextSubtable; 256 } 257 258 AcpiOsPrintf ("\n"); 259 Status = AcpiDmDumpTable (Table->Length, Offset, Subtable, 260 Subtable->Length, InfoTable); 261 if (ACPI_FAILURE (Status)) 262 { 263 return; 264 } 265 266 NextSubtable: 267 /* Point to next subtable */ 268 269 Offset += Subtable->Length; 270 Subtable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, Subtable, 271 Subtable->Length); 272 } 273 } 274 275 276 /******************************************************************************* 277 * 278 * FUNCTION: AcpiDmDumpStao 279 * 280 * PARAMETERS: Table - A STAO table 281 * 282 * RETURN: None 283 * 284 * DESCRIPTION: Format the contents of a STAO. This is a variable-length 285 * table that contains an open-ended number of ASCII strings 286 * at the end of the table. 287 * 288 ******************************************************************************/ 289 290 void 291 AcpiDmDumpStao ( 292 ACPI_TABLE_HEADER *Table) 293 { 294 ACPI_STATUS Status; 295 char *Namepath; 296 UINT32 Length = Table->Length; 297 UINT32 StringLength; 298 UINT32 Offset = sizeof (ACPI_TABLE_STAO); 299 300 301 /* Main table */ 302 303 Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoStao); 304 if (ACPI_FAILURE (Status)) 305 { 306 return; 307 } 308 309 /* The rest of the table consists of Namepath strings */ 310 311 while (Offset < Table->Length) 312 { 313 Namepath = ACPI_ADD_PTR (char, Table, Offset); 314 StringLength = strlen (Namepath) + 1; 315 316 AcpiDmLineHeader (Offset, StringLength, "Namepath"); 317 AcpiOsPrintf ("\"%s\"\n", Namepath); 318 319 /* Point to next namepath */ 320 321 Offset += StringLength; 322 } 323 } 324 325 326 /******************************************************************************* 327 * 328 * FUNCTION: AcpiDmDumpSvkl 329 * 330 * PARAMETERS: Table - A SVKL table 331 * 332 * RETURN: None 333 * 334 * DESCRIPTION: Format the contents of a SVKL. This is a variable-length 335 * table that contains an open-ended number of key subtables at 336 * the end of the header. 337 * 338 * NOTES: SVKL is essentially a flat table, with a small main table and 339 * a variable number of a single type of subtable. 340 * 341 ******************************************************************************/ 342 343 void 344 AcpiDmDumpSvkl ( 345 ACPI_TABLE_HEADER *Table) 346 { 347 ACPI_STATUS Status; 348 UINT32 Length = Table->Length; 349 UINT32 Offset = sizeof (ACPI_TABLE_SVKL); 350 ACPI_SVKL_KEY *Subtable; 351 352 353 /* Main table */ 354 355 Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoSvkl); 356 if (ACPI_FAILURE (Status)) 357 { 358 return; 359 } 360 361 /* The rest of the table consists of subtables (single type) */ 362 363 Subtable = ACPI_ADD_PTR (ACPI_SVKL_KEY, Table, Offset); 364 while (Offset < Table->Length) 365 { 366 /* Dump the subtable */ 367 368 AcpiOsPrintf ("\n"); 369 Status = AcpiDmDumpTable (Table->Length, Offset, Subtable, 370 sizeof (ACPI_SVKL_KEY), AcpiDmTableInfoSvkl0); 371 if (ACPI_FAILURE (Status)) 372 { 373 return; 374 } 375 376 /* Point to next subtable */ 377 378 Offset += sizeof (ACPI_SVKL_KEY); 379 Subtable = ACPI_ADD_PTR (ACPI_SVKL_KEY, Subtable, 380 sizeof (ACPI_SVKL_KEY)); 381 } 382 } 383 384 385 /******************************************************************************* 386 * 387 * FUNCTION: AcpiDmDumpTcpa 388 * 389 * PARAMETERS: Table - A TCPA table 390 * 391 * RETURN: None 392 * 393 * DESCRIPTION: Format the contents of a TCPA. 394 * 395 * NOTE: There are two versions of the table with the same signature: 396 * the client version and the server version. The common 397 * PlatformClass field is used to differentiate the two types of 398 * tables. 399 * 400 ******************************************************************************/ 401 402 void 403 AcpiDmDumpTcpa ( 404 ACPI_TABLE_HEADER *Table) 405 { 406 UINT32 Offset = sizeof (ACPI_TABLE_TCPA_HDR); 407 ACPI_TABLE_TCPA_HDR *CommonHeader = ACPI_CAST_PTR ( 408 ACPI_TABLE_TCPA_HDR, Table); 409 ACPI_TABLE_TCPA_HDR *Subtable = ACPI_ADD_PTR ( 410 ACPI_TABLE_TCPA_HDR, Table, Offset); 411 ACPI_STATUS Status; 412 413 414 /* Main table */ 415 416 Status = AcpiDmDumpTable (Table->Length, 0, Table, 417 0, AcpiDmTableInfoTcpaHdr); 418 if (ACPI_FAILURE (Status)) 419 { 420 return; 421 } 422 423 /* 424 * Examine the PlatformClass field to determine the table type. 425 * Either a client or server table. Only one. 426 */ 427 switch (CommonHeader->PlatformClass) 428 { 429 case ACPI_TCPA_CLIENT_TABLE: 430 431 Status = AcpiDmDumpTable (Table->Length, Offset, Subtable, 432 Table->Length - Offset, AcpiDmTableInfoTcpaClient); 433 break; 434 435 case ACPI_TCPA_SERVER_TABLE: 436 437 Status = AcpiDmDumpTable (Table->Length, Offset, Subtable, 438 Table->Length - Offset, AcpiDmTableInfoTcpaServer); 439 break; 440 441 default: 442 443 AcpiOsPrintf ("\n**** Unknown TCPA Platform Class 0x%X\n", 444 CommonHeader->PlatformClass); 445 Status = AE_ERROR; 446 break; 447 } 448 449 if (ACPI_FAILURE (Status)) 450 { 451 AcpiOsPrintf ("\n**** Cannot disassemble TCPA table\n"); 452 } 453 } 454 455 456 /******************************************************************************* 457 * 458 * FUNCTION: AcpiDmDumpTpm2 459 * 460 * PARAMETERS: Table - A TPM2 table 461 * 462 * RETURN: None 463 * 464 * DESCRIPTION: Format the contents of a TPM2. 465 * 466 ******************************************************************************/ 467 468 static void 469 AcpiDmDumpTpm2Rev3 ( 470 ACPI_TABLE_HEADER *Table) 471 { 472 UINT32 Offset = sizeof (ACPI_TABLE_TPM23); 473 ACPI_TABLE_TPM23 *CommonHeader = ACPI_CAST_PTR (ACPI_TABLE_TPM23, Table); 474 ACPI_TPM23_TRAILER *Subtable = ACPI_ADD_PTR (ACPI_TPM23_TRAILER, Table, Offset); 475 ACPI_STATUS Status; 476 477 478 /* Main table */ 479 480 Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoTpm23); 481 if (ACPI_FAILURE (Status)) 482 { 483 return; 484 } 485 486 /* Optional subtable if start method is ACPI start method */ 487 488 switch (CommonHeader->StartMethod) 489 { 490 case ACPI_TPM23_ACPI_START_METHOD: 491 492 (void) AcpiDmDumpTable (Table->Length, Offset, Subtable, 493 Table->Length - Offset, AcpiDmTableInfoTpm23a); 494 break; 495 496 default: 497 break; 498 } 499 } 500 501 502 /******************************************************************************* 503 * 504 * FUNCTION: AcpiDmDumpTpm2 505 * 506 * PARAMETERS: Table - A TPM2 table 507 * 508 * RETURN: None 509 * 510 * DESCRIPTION: Format the contents of a TPM2. 511 * 512 ******************************************************************************/ 513 514 void 515 AcpiDmDumpTpm2 ( 516 ACPI_TABLE_HEADER *Table) 517 { 518 UINT32 Offset = sizeof (ACPI_TABLE_TPM2); 519 ACPI_TABLE_TPM2 *CommonHeader = ACPI_CAST_PTR (ACPI_TABLE_TPM2, Table); 520 ACPI_TPM2_TRAILER *Subtable = ACPI_ADD_PTR (ACPI_TPM2_TRAILER, Table, Offset); 521 ACPI_TPM2_ARM_SMC *ArmSubtable; 522 ACPI_STATUS Status; 523 524 525 if (Table->Revision == 3) 526 { 527 AcpiDmDumpTpm2Rev3(Table); 528 return; 529 } 530 531 /* Main table */ 532 533 Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoTpm2); 534 535 if (ACPI_FAILURE (Status)) 536 { 537 return; 538 } 539 540 AcpiOsPrintf ("\n"); 541 Status = AcpiDmDumpTable (Table->Length, Offset, Subtable, 542 Table->Length - Offset, AcpiDmTableInfoTpm2a); 543 if (ACPI_FAILURE (Status)) 544 { 545 return; 546 } 547 548 switch (CommonHeader->StartMethod) 549 { 550 case ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC: 551 552 ArmSubtable = ACPI_ADD_PTR (ACPI_TPM2_ARM_SMC, Subtable, 553 sizeof (ACPI_TPM2_TRAILER)); 554 Offset += sizeof (ACPI_TPM2_TRAILER); 555 556 AcpiOsPrintf ("\n"); 557 (void) AcpiDmDumpTable (Table->Length, Offset, ArmSubtable, 558 Table->Length - Offset, AcpiDmTableInfoTpm211); 559 break; 560 561 default: 562 break; 563 } 564 } 565 566 567 /******************************************************************************* 568 * 569 * FUNCTION: AcpiDmDumpViot 570 * 571 * PARAMETERS: Table - A VIOT table 572 * 573 * RETURN: None 574 * 575 * DESCRIPTION: Format the contents of a VIOT 576 * 577 ******************************************************************************/ 578 579 void 580 AcpiDmDumpViot ( 581 ACPI_TABLE_HEADER *Table) 582 { 583 ACPI_STATUS Status; 584 ACPI_TABLE_VIOT *Viot; 585 ACPI_VIOT_HEADER *ViotHeader; 586 UINT16 Length; 587 UINT32 Offset; 588 ACPI_DMTABLE_INFO *InfoTable; 589 590 /* Main table */ 591 592 Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoViot); 593 if (ACPI_FAILURE (Status)) 594 { 595 return; 596 } 597 598 Viot = ACPI_CAST_PTR (ACPI_TABLE_VIOT, Table); 599 600 Offset = Viot->NodeOffset; 601 while (Offset < Table->Length) 602 { 603 /* Common subtable header */ 604 ViotHeader = ACPI_ADD_PTR (ACPI_VIOT_HEADER, Table, Offset); 605 AcpiOsPrintf ("\n"); 606 607 Length = sizeof (ACPI_VIOT_HEADER); 608 Status = AcpiDmDumpTable (Table->Length, Offset, ViotHeader, Length, 609 AcpiDmTableInfoViotHeader); 610 if (ACPI_FAILURE (Status)) 611 { 612 return; 613 } 614 615 Length = ViotHeader->Length; 616 switch (ViotHeader->Type) 617 { 618 case ACPI_VIOT_NODE_PCI_RANGE: 619 620 InfoTable = AcpiDmTableInfoViot1; 621 break; 622 623 case ACPI_VIOT_NODE_MMIO: 624 625 InfoTable = AcpiDmTableInfoViot2; 626 break; 627 628 case ACPI_VIOT_NODE_VIRTIO_IOMMU_PCI: 629 630 InfoTable = AcpiDmTableInfoViot3; 631 break; 632 633 case ACPI_VIOT_NODE_VIRTIO_IOMMU_MMIO: 634 635 InfoTable = AcpiDmTableInfoViot4; 636 break; 637 638 default: 639 640 AcpiOsPrintf ("\n*** Unknown VIOT node type 0x%X\n", 641 ViotHeader->Type); 642 643 /* Attempt to continue */ 644 645 if (!Length) 646 { 647 AcpiOsPrintf ("Invalid zero length VIOT node\n"); 648 return; 649 } 650 goto NextSubtable; 651 } 652 653 AcpiOsPrintf ("\n"); 654 Status = AcpiDmDumpTable (Table->Length, Offset, ViotHeader, Length, 655 InfoTable); 656 if (ACPI_FAILURE (Status)) 657 { 658 return; 659 } 660 661 NextSubtable: 662 Offset += Length; 663 } 664 } 665 666 667 /******************************************************************************* 668 * 669 * FUNCTION: AcpiDmDumpWdat 670 * 671 * PARAMETERS: Table - A WDAT table 672 * 673 * RETURN: None 674 * 675 * DESCRIPTION: Format the contents of a WDAT 676 * 677 ******************************************************************************/ 678 679 void 680 AcpiDmDumpWdat ( 681 ACPI_TABLE_HEADER *Table) 682 { 683 ACPI_STATUS Status; 684 UINT32 Offset = sizeof (ACPI_TABLE_WDAT); 685 ACPI_WDAT_ENTRY *Subtable; 686 687 688 /* Main table */ 689 690 Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoWdat); 691 if (ACPI_FAILURE (Status)) 692 { 693 return; 694 } 695 696 /* Subtables */ 697 698 Subtable = ACPI_ADD_PTR (ACPI_WDAT_ENTRY, Table, Offset); 699 while (Offset < Table->Length) 700 { 701 /* Common subtable header */ 702 703 AcpiOsPrintf ("\n"); 704 Status = AcpiDmDumpTable (Table->Length, Offset, Subtable, 705 sizeof (ACPI_WDAT_ENTRY), AcpiDmTableInfoWdat0); 706 if (ACPI_FAILURE (Status)) 707 { 708 return; 709 } 710 711 /* Point to next subtable */ 712 713 Offset += sizeof (ACPI_WDAT_ENTRY); 714 Subtable = ACPI_ADD_PTR (ACPI_WDAT_ENTRY, Subtable, 715 sizeof (ACPI_WDAT_ENTRY)); 716 } 717 } 718 719 720 /******************************************************************************* 721 * 722 * FUNCTION: AcpiDmDumpWpbt 723 * 724 * PARAMETERS: Table - A WPBT table 725 * 726 * RETURN: None 727 * 728 * DESCRIPTION: Format the contents of a WPBT. This table type consists 729 * of an open-ended arguments buffer at the end of the table. 730 * 731 ******************************************************************************/ 732 733 void 734 AcpiDmDumpWpbt ( 735 ACPI_TABLE_HEADER *Table) 736 { 737 ACPI_STATUS Status; 738 ACPI_TABLE_WPBT *Subtable; 739 UINT16 ArgumentsLength; 740 741 742 /* Dump the main table */ 743 744 Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoWpbt); 745 if (ACPI_FAILURE (Status)) 746 { 747 return; 748 } 749 750 /* Extract the arguments buffer length from the main table */ 751 752 Subtable = ACPI_CAST_PTR (ACPI_TABLE_WPBT, Table); 753 ArgumentsLength = Subtable->ArgumentsLength; 754 755 /* Dump the arguments buffer if present */ 756 757 if (ArgumentsLength) 758 { 759 (void) AcpiDmDumpTable (Table->Length, 0, Table, ArgumentsLength, 760 AcpiDmTableInfoWpbt0); 761 } 762 } 763