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