1 /****************************************************************************** 2 * 3 * Module Name: dttable2.c - handling for specific ACPI tables 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2021, 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 /* Compile all complex data tables, signatures starting with L-Z */ 45 46 #include "aslcompiler.h" 47 48 #define _COMPONENT DT_COMPILER 49 ACPI_MODULE_NAME ("dttable2") 50 51 52 /****************************************************************************** 53 * 54 * FUNCTION: DtCompileLpit 55 * 56 * PARAMETERS: List - Current field list pointer 57 * 58 * RETURN: Status 59 * 60 * DESCRIPTION: Compile LPIT. 61 * 62 *****************************************************************************/ 63 64 ACPI_STATUS 65 DtCompileLpit ( 66 void **List) 67 { 68 ACPI_STATUS Status; 69 DT_SUBTABLE *Subtable; 70 DT_SUBTABLE *ParentTable; 71 DT_FIELD **PFieldList = (DT_FIELD **) List; 72 DT_FIELD *SubtableStart; 73 ACPI_DMTABLE_INFO *InfoTable; 74 ACPI_LPIT_HEADER *LpitHeader; 75 76 77 /* Note: Main table consists only of the standard ACPI table header */ 78 79 while (*PFieldList) 80 { 81 SubtableStart = *PFieldList; 82 83 /* LPIT Subtable header */ 84 85 Status = DtCompileTable (PFieldList, AcpiDmTableInfoLpitHdr, 86 &Subtable); 87 if (ACPI_FAILURE (Status)) 88 { 89 return (Status); 90 } 91 92 ParentTable = DtPeekSubtable (); 93 DtInsertSubtable (ParentTable, Subtable); 94 DtPushSubtable (Subtable); 95 96 LpitHeader = ACPI_CAST_PTR (ACPI_LPIT_HEADER, Subtable->Buffer); 97 98 switch (LpitHeader->Type) 99 { 100 case ACPI_LPIT_TYPE_NATIVE_CSTATE: 101 102 InfoTable = AcpiDmTableInfoLpit0; 103 break; 104 105 default: 106 107 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "LPIT"); 108 return (AE_ERROR); 109 } 110 111 /* LPIT Subtable */ 112 113 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 114 if (ACPI_FAILURE (Status)) 115 { 116 return (Status); 117 } 118 119 ParentTable = DtPeekSubtable (); 120 DtInsertSubtable (ParentTable, Subtable); 121 DtPopSubtable (); 122 } 123 124 return (AE_OK); 125 } 126 127 128 /****************************************************************************** 129 * 130 * FUNCTION: DtCompileMadt 131 * 132 * PARAMETERS: List - Current field list pointer 133 * 134 * RETURN: Status 135 * 136 * DESCRIPTION: Compile MADT. 137 * 138 *****************************************************************************/ 139 140 ACPI_STATUS 141 DtCompileMadt ( 142 void **List) 143 { 144 ACPI_STATUS Status; 145 DT_SUBTABLE *Subtable; 146 DT_SUBTABLE *ParentTable; 147 DT_FIELD **PFieldList = (DT_FIELD **) List; 148 DT_FIELD *SubtableStart; 149 ACPI_SUBTABLE_HEADER *MadtHeader; 150 ACPI_DMTABLE_INFO *InfoTable; 151 152 153 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadt, 154 &Subtable); 155 if (ACPI_FAILURE (Status)) 156 { 157 return (Status); 158 } 159 160 ParentTable = DtPeekSubtable (); 161 DtInsertSubtable (ParentTable, Subtable); 162 163 while (*PFieldList) 164 { 165 SubtableStart = *PFieldList; 166 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadtHdr, 167 &Subtable); 168 if (ACPI_FAILURE (Status)) 169 { 170 return (Status); 171 } 172 173 ParentTable = DtPeekSubtable (); 174 DtInsertSubtable (ParentTable, Subtable); 175 DtPushSubtable (Subtable); 176 177 MadtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); 178 179 switch (MadtHeader->Type) 180 { 181 case ACPI_MADT_TYPE_LOCAL_APIC: 182 183 InfoTable = AcpiDmTableInfoMadt0; 184 break; 185 186 case ACPI_MADT_TYPE_IO_APIC: 187 188 InfoTable = AcpiDmTableInfoMadt1; 189 break; 190 191 case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE: 192 193 InfoTable = AcpiDmTableInfoMadt2; 194 break; 195 196 case ACPI_MADT_TYPE_NMI_SOURCE: 197 198 InfoTable = AcpiDmTableInfoMadt3; 199 break; 200 201 case ACPI_MADT_TYPE_LOCAL_APIC_NMI: 202 203 InfoTable = AcpiDmTableInfoMadt4; 204 break; 205 206 case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE: 207 208 InfoTable = AcpiDmTableInfoMadt5; 209 break; 210 211 case ACPI_MADT_TYPE_IO_SAPIC: 212 213 InfoTable = AcpiDmTableInfoMadt6; 214 break; 215 216 case ACPI_MADT_TYPE_LOCAL_SAPIC: 217 218 InfoTable = AcpiDmTableInfoMadt7; 219 break; 220 221 case ACPI_MADT_TYPE_INTERRUPT_SOURCE: 222 223 InfoTable = AcpiDmTableInfoMadt8; 224 break; 225 226 case ACPI_MADT_TYPE_LOCAL_X2APIC: 227 228 InfoTable = AcpiDmTableInfoMadt9; 229 break; 230 231 case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI: 232 233 InfoTable = AcpiDmTableInfoMadt10; 234 break; 235 236 case ACPI_MADT_TYPE_GENERIC_INTERRUPT: 237 238 InfoTable = AcpiDmTableInfoMadt11; 239 break; 240 241 case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR: 242 243 InfoTable = AcpiDmTableInfoMadt12; 244 break; 245 246 case ACPI_MADT_TYPE_GENERIC_MSI_FRAME: 247 248 InfoTable = AcpiDmTableInfoMadt13; 249 break; 250 251 case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR: 252 253 InfoTable = AcpiDmTableInfoMadt14; 254 break; 255 256 case ACPI_MADT_TYPE_GENERIC_TRANSLATOR: 257 258 InfoTable = AcpiDmTableInfoMadt15; 259 break; 260 261 case ACPI_MADT_TYPE_MULTIPROC_WAKEUP: 262 263 InfoTable = AcpiDmTableInfoMadt16; 264 break; 265 266 default: 267 268 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "MADT"); 269 return (AE_ERROR); 270 } 271 272 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 273 if (ACPI_FAILURE (Status)) 274 { 275 return (Status); 276 } 277 278 ParentTable = DtPeekSubtable (); 279 DtInsertSubtable (ParentTable, Subtable); 280 DtPopSubtable (); 281 } 282 283 return (AE_OK); 284 } 285 286 287 /****************************************************************************** 288 * 289 * FUNCTION: DtCompileMcfg 290 * 291 * PARAMETERS: List - Current field list pointer 292 * 293 * RETURN: Status 294 * 295 * DESCRIPTION: Compile MCFG. 296 * 297 *****************************************************************************/ 298 299 ACPI_STATUS 300 DtCompileMcfg ( 301 void **List) 302 { 303 ACPI_STATUS Status; 304 305 306 Status = DtCompileTwoSubtables (List, 307 AcpiDmTableInfoMcfg, AcpiDmTableInfoMcfg0); 308 return (Status); 309 } 310 311 312 /****************************************************************************** 313 * 314 * FUNCTION: DtCompileMpst 315 * 316 * PARAMETERS: List - Current field list pointer 317 * 318 * RETURN: Status 319 * 320 * DESCRIPTION: Compile MPST. 321 * 322 *****************************************************************************/ 323 324 ACPI_STATUS 325 DtCompileMpst ( 326 void **List) 327 { 328 ACPI_STATUS Status; 329 DT_SUBTABLE *Subtable; 330 DT_SUBTABLE *ParentTable; 331 DT_FIELD **PFieldList = (DT_FIELD **) List; 332 ACPI_MPST_CHANNEL *MpstChannelInfo; 333 ACPI_MPST_POWER_NODE *MpstPowerNode; 334 ACPI_MPST_DATA_HDR *MpstDataHeader; 335 UINT16 SubtableCount; 336 UINT32 PowerStateCount; 337 UINT32 ComponentCount; 338 339 340 /* Main table */ 341 342 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst, &Subtable); 343 if (ACPI_FAILURE (Status)) 344 { 345 return (Status); 346 } 347 348 ParentTable = DtPeekSubtable (); 349 DtInsertSubtable (ParentTable, Subtable); 350 DtPushSubtable (Subtable); 351 352 MpstChannelInfo = ACPI_CAST_PTR (ACPI_MPST_CHANNEL, Subtable->Buffer); 353 SubtableCount = MpstChannelInfo->PowerNodeCount; 354 355 while (*PFieldList && SubtableCount) 356 { 357 /* Subtable: Memory Power Node(s) */ 358 359 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0, 360 &Subtable); 361 if (ACPI_FAILURE (Status)) 362 { 363 return (Status); 364 } 365 366 ParentTable = DtPeekSubtable (); 367 DtInsertSubtable (ParentTable, Subtable); 368 DtPushSubtable (Subtable); 369 370 MpstPowerNode = ACPI_CAST_PTR (ACPI_MPST_POWER_NODE, Subtable->Buffer); 371 PowerStateCount = MpstPowerNode->NumPowerStates; 372 ComponentCount = MpstPowerNode->NumPhysicalComponents; 373 374 ParentTable = DtPeekSubtable (); 375 376 /* Sub-subtables - Memory Power State Structure(s) */ 377 378 while (*PFieldList && PowerStateCount) 379 { 380 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0A, 381 &Subtable); 382 if (ACPI_FAILURE (Status)) 383 { 384 return (Status); 385 } 386 387 DtInsertSubtable (ParentTable, Subtable); 388 PowerStateCount--; 389 } 390 391 /* Sub-subtables - Physical Component ID Structure(s) */ 392 393 while (*PFieldList && ComponentCount) 394 { 395 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0B, 396 &Subtable); 397 if (ACPI_FAILURE (Status)) 398 { 399 return (Status); 400 } 401 402 DtInsertSubtable (ParentTable, Subtable); 403 ComponentCount--; 404 } 405 406 SubtableCount--; 407 DtPopSubtable (); 408 } 409 410 /* Subtable: Count of Memory Power State Characteristic structures */ 411 412 DtPopSubtable (); 413 414 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst1, &Subtable); 415 if (ACPI_FAILURE (Status)) 416 { 417 return (Status); 418 } 419 420 ParentTable = DtPeekSubtable (); 421 DtInsertSubtable (ParentTable, Subtable); 422 DtPushSubtable (Subtable); 423 424 MpstDataHeader = ACPI_CAST_PTR (ACPI_MPST_DATA_HDR, Subtable->Buffer); 425 SubtableCount = MpstDataHeader->CharacteristicsCount; 426 427 ParentTable = DtPeekSubtable (); 428 429 /* Subtable: Memory Power State Characteristics structure(s) */ 430 431 while (*PFieldList && SubtableCount) 432 { 433 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst2, 434 &Subtable); 435 if (ACPI_FAILURE (Status)) 436 { 437 return (Status); 438 } 439 440 DtInsertSubtable (ParentTable, Subtable); 441 SubtableCount--; 442 } 443 444 DtPopSubtable (); 445 return (AE_OK); 446 } 447 448 449 /****************************************************************************** 450 * 451 * FUNCTION: DtCompileMsct 452 * 453 * PARAMETERS: List - Current field list pointer 454 * 455 * RETURN: Status 456 * 457 * DESCRIPTION: Compile MSCT. 458 * 459 *****************************************************************************/ 460 461 ACPI_STATUS 462 DtCompileMsct ( 463 void **List) 464 { 465 ACPI_STATUS Status; 466 467 468 Status = DtCompileTwoSubtables (List, 469 AcpiDmTableInfoMsct, AcpiDmTableInfoMsct0); 470 return (Status); 471 } 472 473 474 /****************************************************************************** 475 * 476 * FUNCTION: DtCompileNfit 477 * 478 * PARAMETERS: List - Current field list pointer 479 * 480 * RETURN: Status 481 * 482 * DESCRIPTION: Compile NFIT. 483 * 484 *****************************************************************************/ 485 486 ACPI_STATUS 487 DtCompileNfit ( 488 void **List) 489 { 490 ACPI_STATUS Status; 491 DT_SUBTABLE *Subtable; 492 DT_SUBTABLE *ParentTable; 493 DT_FIELD **PFieldList = (DT_FIELD **) List; 494 DT_FIELD *SubtableStart; 495 ACPI_NFIT_HEADER *NfitHeader; 496 ACPI_DMTABLE_INFO *InfoTable; 497 UINT32 Count; 498 ACPI_NFIT_INTERLEAVE *Interleave = NULL; 499 ACPI_NFIT_FLUSH_ADDRESS *Hint = NULL; 500 501 502 /* Main table */ 503 504 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit, 505 &Subtable); 506 if (ACPI_FAILURE (Status)) 507 { 508 return (Status); 509 } 510 511 ParentTable = DtPeekSubtable (); 512 DtInsertSubtable (ParentTable, Subtable); 513 DtPushSubtable (Subtable); 514 515 /* Subtables */ 516 517 while (*PFieldList) 518 { 519 SubtableStart = *PFieldList; 520 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfitHdr, 521 &Subtable); 522 if (ACPI_FAILURE (Status)) 523 { 524 return (Status); 525 } 526 527 ParentTable = DtPeekSubtable (); 528 DtInsertSubtable (ParentTable, Subtable); 529 DtPushSubtable (Subtable); 530 531 NfitHeader = ACPI_CAST_PTR (ACPI_NFIT_HEADER, Subtable->Buffer); 532 533 switch (NfitHeader->Type) 534 { 535 case ACPI_NFIT_TYPE_SYSTEM_ADDRESS: 536 537 InfoTable = AcpiDmTableInfoNfit0; 538 break; 539 540 case ACPI_NFIT_TYPE_MEMORY_MAP: 541 542 InfoTable = AcpiDmTableInfoNfit1; 543 break; 544 545 case ACPI_NFIT_TYPE_INTERLEAVE: 546 547 Interleave = ACPI_CAST_PTR (ACPI_NFIT_INTERLEAVE, Subtable->Buffer); 548 InfoTable = AcpiDmTableInfoNfit2; 549 break; 550 551 case ACPI_NFIT_TYPE_SMBIOS: 552 553 InfoTable = AcpiDmTableInfoNfit3; 554 break; 555 556 case ACPI_NFIT_TYPE_CONTROL_REGION: 557 558 InfoTable = AcpiDmTableInfoNfit4; 559 break; 560 561 case ACPI_NFIT_TYPE_DATA_REGION: 562 563 InfoTable = AcpiDmTableInfoNfit5; 564 break; 565 566 case ACPI_NFIT_TYPE_FLUSH_ADDRESS: 567 568 Hint = ACPI_CAST_PTR (ACPI_NFIT_FLUSH_ADDRESS, Subtable->Buffer); 569 InfoTable = AcpiDmTableInfoNfit6; 570 break; 571 572 case ACPI_NFIT_TYPE_CAPABILITIES: 573 574 InfoTable = AcpiDmTableInfoNfit7; 575 break; 576 577 default: 578 579 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "NFIT"); 580 return (AE_ERROR); 581 } 582 583 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 584 if (ACPI_FAILURE (Status)) 585 { 586 return (Status); 587 } 588 589 ParentTable = DtPeekSubtable (); 590 DtInsertSubtable (ParentTable, Subtable); 591 DtPopSubtable (); 592 593 switch (NfitHeader->Type) 594 { 595 case ACPI_NFIT_TYPE_INTERLEAVE: 596 597 Count = 0; 598 DtPushSubtable (Subtable); 599 while (*PFieldList) 600 { 601 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit2a, 602 &Subtable); 603 if (ACPI_FAILURE (Status)) 604 { 605 return (Status); 606 } 607 608 if (!Subtable) 609 { 610 DtPopSubtable (); 611 break; 612 } 613 614 ParentTable = DtPeekSubtable (); 615 DtInsertSubtable (ParentTable, Subtable); 616 Count++; 617 } 618 619 Interleave->LineCount = Count; 620 break; 621 622 case ACPI_NFIT_TYPE_SMBIOS: 623 624 if (*PFieldList) 625 { 626 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit3a, 627 &Subtable); 628 if (ACPI_FAILURE (Status)) 629 { 630 return (Status); 631 } 632 633 if (Subtable) 634 { 635 DtInsertSubtable (ParentTable, Subtable); 636 } 637 } 638 break; 639 640 case ACPI_NFIT_TYPE_FLUSH_ADDRESS: 641 642 Count = 0; 643 DtPushSubtable (Subtable); 644 while (*PFieldList) 645 { 646 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit6a, 647 &Subtable); 648 if (ACPI_FAILURE (Status)) 649 { 650 return (Status); 651 } 652 653 if (!Subtable) 654 { 655 DtPopSubtable (); 656 break; 657 } 658 659 ParentTable = DtPeekSubtable (); 660 DtInsertSubtable (ParentTable, Subtable); 661 Count++; 662 } 663 664 Hint->HintCount = (UINT16) Count; 665 break; 666 667 default: 668 break; 669 } 670 } 671 672 return (AE_OK); 673 } 674 675 676 /****************************************************************************** 677 * 678 * FUNCTION: DtCompilePcct 679 * 680 * PARAMETERS: List - Current field list pointer 681 * 682 * RETURN: Status 683 * 684 * DESCRIPTION: Compile PCCT. 685 * 686 *****************************************************************************/ 687 688 ACPI_STATUS 689 DtCompilePcct ( 690 void **List) 691 { 692 ACPI_STATUS Status; 693 DT_SUBTABLE *Subtable; 694 DT_SUBTABLE *ParentTable; 695 DT_FIELD **PFieldList = (DT_FIELD **) List; 696 DT_FIELD *SubtableStart; 697 ACPI_SUBTABLE_HEADER *PcctHeader; 698 ACPI_DMTABLE_INFO *InfoTable; 699 700 701 /* Main table */ 702 703 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcct, 704 &Subtable); 705 if (ACPI_FAILURE (Status)) 706 { 707 return (Status); 708 } 709 710 ParentTable = DtPeekSubtable (); 711 DtInsertSubtable (ParentTable, Subtable); 712 713 /* Subtables */ 714 715 while (*PFieldList) 716 { 717 SubtableStart = *PFieldList; 718 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcctHdr, 719 &Subtable); 720 if (ACPI_FAILURE (Status)) 721 { 722 return (Status); 723 } 724 725 ParentTable = DtPeekSubtable (); 726 DtInsertSubtable (ParentTable, Subtable); 727 DtPushSubtable (Subtable); 728 729 PcctHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); 730 731 switch (PcctHeader->Type) 732 { 733 case ACPI_PCCT_TYPE_GENERIC_SUBSPACE: 734 735 InfoTable = AcpiDmTableInfoPcct0; 736 break; 737 738 case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE: 739 740 InfoTable = AcpiDmTableInfoPcct1; 741 break; 742 743 case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2: 744 745 InfoTable = AcpiDmTableInfoPcct2; 746 break; 747 748 case ACPI_PCCT_TYPE_EXT_PCC_MASTER_SUBSPACE: 749 750 InfoTable = AcpiDmTableInfoPcct3; 751 break; 752 753 case ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE: 754 755 InfoTable = AcpiDmTableInfoPcct4; 756 break; 757 758 case ACPI_PCCT_TYPE_HW_REG_COMM_SUBSPACE: 759 760 InfoTable = AcpiDmTableInfoPcct5; 761 break; 762 763 default: 764 765 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PCCT"); 766 return (AE_ERROR); 767 } 768 769 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 770 if (ACPI_FAILURE (Status)) 771 { 772 return (Status); 773 } 774 775 ParentTable = DtPeekSubtable (); 776 DtInsertSubtable (ParentTable, Subtable); 777 DtPopSubtable (); 778 } 779 780 return (AE_OK); 781 } 782 783 784 /****************************************************************************** 785 * 786 * FUNCTION: DtCompilePdtt 787 * 788 * PARAMETERS: List - Current field list pointer 789 * 790 * RETURN: Status 791 * 792 * DESCRIPTION: Compile PDTT. 793 * 794 *****************************************************************************/ 795 796 ACPI_STATUS 797 DtCompilePdtt ( 798 void **List) 799 { 800 ACPI_STATUS Status; 801 DT_SUBTABLE *Subtable; 802 DT_SUBTABLE *ParentTable; 803 DT_FIELD **PFieldList = (DT_FIELD **) List; 804 ACPI_TABLE_PDTT *PdttHeader; 805 UINT32 Count = 0; 806 807 808 /* Main table */ 809 810 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPdtt, &Subtable); 811 if (ACPI_FAILURE (Status)) 812 { 813 return (Status); 814 } 815 816 ParentTable = DtPeekSubtable (); 817 DtInsertSubtable (ParentTable, Subtable); 818 819 PdttHeader = ACPI_CAST_PTR (ACPI_TABLE_PDTT, ParentTable->Buffer); 820 PdttHeader->ArrayOffset = sizeof (ACPI_TABLE_PDTT); 821 822 /* There is only one type of subtable at this time, no need to decode */ 823 824 while (*PFieldList) 825 { 826 /* List of subchannel IDs, each 2 bytes */ 827 828 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPdtt0, 829 &Subtable); 830 if (ACPI_FAILURE (Status)) 831 { 832 return (Status); 833 } 834 835 DtInsertSubtable (ParentTable, Subtable); 836 Count++; 837 } 838 839 PdttHeader->TriggerCount = (UINT8) Count; 840 return (AE_OK); 841 } 842 843 844 /****************************************************************************** 845 * 846 * FUNCTION: DtCompilePhat 847 * 848 * PARAMETERS: List - Current field list pointer 849 * 850 * RETURN: Status 851 * 852 * DESCRIPTION: Compile Phat. 853 * 854 *****************************************************************************/ 855 856 ACPI_STATUS 857 DtCompilePhat ( 858 void **List) 859 { 860 ACPI_STATUS Status = AE_OK; 861 DT_SUBTABLE *Subtable; 862 DT_SUBTABLE *ParentTable; 863 DT_FIELD **PFieldList = (DT_FIELD **) List; 864 ACPI_PHAT_HEADER *PhatHeader; 865 ACPI_DMTABLE_INFO *Info; 866 ACPI_PHAT_VERSION_DATA *VersionData; 867 UINT32 RecordCount; 868 869 870 /* The table consist of subtables */ 871 872 while (*PFieldList) 873 { 874 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhatHdr, &Subtable); 875 if (ACPI_FAILURE (Status)) 876 { 877 return (Status); 878 } 879 880 ParentTable = DtPeekSubtable (); 881 DtInsertSubtable (ParentTable, Subtable); 882 DtPushSubtable (Subtable); 883 884 PhatHeader = ACPI_CAST_PTR (ACPI_PHAT_HEADER, Subtable->Buffer); 885 886 switch (PhatHeader->Type) 887 { 888 case ACPI_PHAT_TYPE_FW_VERSION_DATA: 889 890 Info = AcpiDmTableInfoPhat0; 891 PhatHeader->Length = sizeof (ACPI_PHAT_VERSION_DATA); 892 break; 893 894 case ACPI_PHAT_TYPE_FW_HEALTH_DATA: 895 896 Info = AcpiDmTableInfoPhat1; 897 PhatHeader->Length = sizeof (ACPI_PHAT_HEALTH_DATA); 898 break; 899 900 default: 901 902 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, *PFieldList, "PHAT"); 903 return (AE_ERROR); 904 905 break; 906 } 907 908 Status = DtCompileTable (PFieldList, Info, &Subtable); 909 if (ACPI_FAILURE (Status)) 910 { 911 return (Status); 912 } 913 914 ParentTable = DtPeekSubtable (); 915 DtInsertSubtable (ParentTable, Subtable); 916 917 switch (PhatHeader->Type) 918 { 919 case ACPI_PHAT_TYPE_FW_VERSION_DATA: 920 921 VersionData = ACPI_CAST_PTR (ACPI_PHAT_VERSION_DATA, 922 (Subtable->Buffer - sizeof (ACPI_PHAT_HEADER))); 923 RecordCount = VersionData->ElementCount; 924 925 while (RecordCount) 926 { 927 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhat0a, 928 &Subtable); 929 if (ACPI_FAILURE (Status)) 930 { 931 return (Status); 932 } 933 ParentTable = DtPeekSubtable (); 934 DtInsertSubtable (ParentTable, Subtable); 935 936 RecordCount--; 937 PhatHeader->Length += sizeof (ACPI_PHAT_VERSION_ELEMENT); 938 } 939 break; 940 941 case ACPI_PHAT_TYPE_FW_HEALTH_DATA: 942 943 /* Compile device path */ 944 945 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhat1a, &Subtable); 946 if (ACPI_FAILURE (Status)) 947 { 948 return (Status); 949 } 950 ParentTable = DtPeekSubtable (); 951 DtInsertSubtable (ParentTable, Subtable); 952 953 PhatHeader->Length += (UINT16) Subtable->Length; 954 955 /* Compile vendor specific data */ 956 957 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhat1b, &Subtable); 958 if (ACPI_FAILURE (Status)) 959 { 960 return (Status); 961 } 962 ParentTable = DtPeekSubtable (); 963 DtInsertSubtable (ParentTable, Subtable); 964 965 PhatHeader->Length += (UINT16) Subtable->Length; 966 967 break; 968 969 default: 970 971 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, *PFieldList, "PHAT"); 972 return (AE_ERROR); 973 } 974 } 975 976 return (Status); 977 } 978 979 980 /****************************************************************************** 981 * 982 * FUNCTION: DtCompilePmtt 983 * 984 * PARAMETERS: List - Current field list pointer 985 * 986 * RETURN: Status 987 * 988 * DESCRIPTION: Compile PMTT. 989 * 990 *****************************************************************************/ 991 992 ACPI_STATUS 993 DtCompilePmtt ( 994 void **List) 995 { 996 ACPI_STATUS Status; 997 DT_SUBTABLE *Subtable; 998 DT_SUBTABLE *ParentTable; 999 DT_FIELD **PFieldList = (DT_FIELD **) List; 1000 DT_FIELD *SubtableStart; 1001 UINT16 Type; 1002 1003 1004 /* Main table */ 1005 1006 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt, &Subtable); 1007 if (ACPI_FAILURE (Status)) 1008 { 1009 return (Status); 1010 } 1011 1012 ParentTable = DtPeekSubtable (); 1013 DtInsertSubtable (ParentTable, Subtable); 1014 DtPushSubtable (Subtable); 1015 1016 /* Subtables */ 1017 1018 while (*PFieldList) 1019 { 1020 SubtableStart = *PFieldList; 1021 DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0); 1022 1023 switch (Type) 1024 { 1025 case ACPI_PMTT_TYPE_SOCKET: 1026 1027 /* Subtable: Socket Structure */ 1028 1029 DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_SOCKET (0)\n"); 1030 1031 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt0, 1032 &Subtable); 1033 if (ACPI_FAILURE (Status)) 1034 { 1035 return (Status); 1036 } 1037 1038 break; 1039 1040 case ACPI_PMTT_TYPE_CONTROLLER: 1041 1042 /* Subtable: Memory Controller Structure */ 1043 1044 DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_CONTROLLER (1)\n"); 1045 1046 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1, 1047 &Subtable); 1048 if (ACPI_FAILURE (Status)) 1049 { 1050 return (Status); 1051 } 1052 1053 break; 1054 1055 case ACPI_PMTT_TYPE_DIMM: 1056 1057 /* Subtable: Physical Component (DIMM) Structure */ 1058 1059 DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_DIMM (2)\n"); 1060 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt2, 1061 &Subtable); 1062 if (ACPI_FAILURE (Status)) 1063 { 1064 return (Status); 1065 } 1066 1067 break; 1068 1069 case ACPI_PMTT_TYPE_VENDOR: 1070 1071 /* Subtable: Vendor-specific Structure */ 1072 1073 DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_VENDOR(FF)\n"); 1074 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmttVendor, 1075 &Subtable); 1076 if (ACPI_FAILURE (Status)) 1077 { 1078 return (Status); 1079 } 1080 1081 break; 1082 1083 default: 1084 1085 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PMTT"); 1086 return (AE_ERROR); 1087 } 1088 1089 DtInsertSubtable (ParentTable, Subtable); 1090 } 1091 1092 return (Status); 1093 } 1094 1095 1096 /****************************************************************************** 1097 * 1098 * FUNCTION: DtCompilePptt 1099 * 1100 * PARAMETERS: List - Current field list pointer 1101 * 1102 * RETURN: Status 1103 * 1104 * DESCRIPTION: Compile PPTT. 1105 * 1106 *****************************************************************************/ 1107 1108 ACPI_STATUS 1109 DtCompilePptt ( 1110 void **List) 1111 { 1112 ACPI_STATUS Status; 1113 ACPI_SUBTABLE_HEADER *PpttHeader; 1114 ACPI_PPTT_PROCESSOR *PpttProcessor = NULL; 1115 DT_SUBTABLE *Subtable; 1116 DT_SUBTABLE *ParentTable; 1117 ACPI_DMTABLE_INFO *InfoTable; 1118 DT_FIELD **PFieldList = (DT_FIELD **) List; 1119 DT_FIELD *SubtableStart; 1120 ACPI_TABLE_HEADER *PpttAcpiHeader; 1121 1122 1123 ParentTable = DtPeekSubtable (); 1124 while (*PFieldList) 1125 { 1126 SubtableStart = *PFieldList; 1127 1128 /* Compile PPTT subtable header */ 1129 1130 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPpttHdr, 1131 &Subtable); 1132 if (ACPI_FAILURE (Status)) 1133 { 1134 return (Status); 1135 } 1136 DtInsertSubtable (ParentTable, Subtable); 1137 PpttHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); 1138 PpttHeader->Length = (UINT8)(Subtable->Length); 1139 1140 switch (PpttHeader->Type) 1141 { 1142 case ACPI_PPTT_TYPE_PROCESSOR: 1143 1144 InfoTable = AcpiDmTableInfoPptt0; 1145 break; 1146 1147 case ACPI_PPTT_TYPE_CACHE: 1148 1149 InfoTable = AcpiDmTableInfoPptt1; 1150 break; 1151 1152 case ACPI_PPTT_TYPE_ID: 1153 1154 InfoTable = AcpiDmTableInfoPptt2; 1155 break; 1156 1157 default: 1158 1159 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PPTT"); 1160 return (AE_ERROR); 1161 } 1162 1163 /* Compile PPTT subtable body */ 1164 1165 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 1166 if (ACPI_FAILURE (Status)) 1167 { 1168 return (Status); 1169 } 1170 DtInsertSubtable (ParentTable, Subtable); 1171 PpttHeader->Length += (UINT8)(Subtable->Length); 1172 1173 /* Compile PPTT subtable additionals */ 1174 1175 switch (PpttHeader->Type) 1176 { 1177 case ACPI_PPTT_TYPE_PROCESSOR: 1178 1179 PpttProcessor = ACPI_SUB_PTR (ACPI_PPTT_PROCESSOR, 1180 Subtable->Buffer, sizeof (ACPI_SUBTABLE_HEADER)); 1181 if (PpttProcessor) 1182 { 1183 /* Compile initiator proximity domain list */ 1184 1185 PpttProcessor->NumberOfPrivResources = 0; 1186 while (*PFieldList) 1187 { 1188 Status = DtCompileTable (PFieldList, 1189 AcpiDmTableInfoPptt0a, &Subtable); 1190 if (ACPI_FAILURE (Status)) 1191 { 1192 return (Status); 1193 } 1194 if (!Subtable) 1195 { 1196 break; 1197 } 1198 1199 DtInsertSubtable (ParentTable, Subtable); 1200 PpttHeader->Length += (UINT8)(Subtable->Length); 1201 PpttProcessor->NumberOfPrivResources++; 1202 } 1203 } 1204 break; 1205 1206 case ACPI_PPTT_TYPE_CACHE: 1207 1208 PpttAcpiHeader = ACPI_CAST_PTR (ACPI_TABLE_HEADER, 1209 AslGbl_RootTable->Buffer); 1210 if (PpttAcpiHeader->Revision < 3) 1211 { 1212 break; 1213 } 1214 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPptt1a, 1215 &Subtable); 1216 DtInsertSubtable (ParentTable, Subtable); 1217 PpttHeader->Length += (UINT8)(Subtable->Length); 1218 break; 1219 1220 default: 1221 1222 break; 1223 } 1224 } 1225 1226 return (AE_OK); 1227 } 1228 1229 1230 /****************************************************************************** 1231 * 1232 * FUNCTION: DtCompilePrmt 1233 * 1234 * PARAMETERS: List - Current field list pointer 1235 * 1236 * RETURN: Status 1237 * 1238 * DESCRIPTION: Compile PRMT. 1239 * 1240 *****************************************************************************/ 1241 1242 ACPI_STATUS 1243 DtCompilePrmt ( 1244 void **List) 1245 { 1246 ACPI_STATUS Status; 1247 ACPI_TABLE_PRMT_HEADER *PrmtHeader; 1248 ACPI_PRMT_MODULE_INFO *PrmtModuleInfo; 1249 DT_SUBTABLE *Subtable; 1250 DT_SUBTABLE *ParentTable; 1251 DT_FIELD **PFieldList = (DT_FIELD **) List; 1252 UINT32 i, j; 1253 1254 ParentTable = DtPeekSubtable (); 1255 1256 /* Compile PRMT subtable header */ 1257 1258 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPrmtHdr, 1259 &Subtable); 1260 if (ACPI_FAILURE (Status)) 1261 { 1262 return (Status); 1263 } 1264 DtInsertSubtable (ParentTable, Subtable); 1265 PrmtHeader = ACPI_CAST_PTR (ACPI_TABLE_PRMT_HEADER, Subtable->Buffer); 1266 1267 for (i = 0; i < PrmtHeader->ModuleInfoCount; i++) 1268 { 1269 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPrmtModule, 1270 &Subtable); 1271 if (ACPI_FAILURE (Status)) 1272 { 1273 return (Status); 1274 } 1275 DtInsertSubtable (ParentTable, Subtable); 1276 PrmtModuleInfo = ACPI_CAST_PTR (ACPI_PRMT_MODULE_INFO, Subtable->Buffer); 1277 1278 for (j = 0; j < PrmtModuleInfo->HandlerInfoCount; j++) 1279 { 1280 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPrmtHandler, 1281 &Subtable); 1282 if (ACPI_FAILURE (Status)) 1283 { 1284 return (Status); 1285 } 1286 DtInsertSubtable (ParentTable, Subtable); 1287 } 1288 } 1289 1290 return (AE_OK); 1291 } 1292 1293 1294 /****************************************************************************** 1295 * 1296 * FUNCTION: DtCompileRgrt 1297 * 1298 * PARAMETERS: List - Current field list pointer 1299 * 1300 * RETURN: Status 1301 * 1302 * DESCRIPTION: Compile RGRT. 1303 * 1304 *****************************************************************************/ 1305 1306 ACPI_STATUS 1307 DtCompileRgrt ( 1308 void **List) 1309 { 1310 ACPI_STATUS Status; 1311 DT_SUBTABLE *Subtable; 1312 DT_SUBTABLE *ParentTable; 1313 DT_FIELD **PFieldList = (DT_FIELD **) List; 1314 1315 1316 /* Compile the main table */ 1317 1318 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRgrt, 1319 &Subtable); 1320 if (ACPI_FAILURE (Status)) 1321 { 1322 return (Status); 1323 } 1324 1325 ParentTable = DtPeekSubtable (); 1326 DtInsertSubtable (ParentTable, Subtable); 1327 1328 /* Compile the "Subtable" -- actually just the binary (PNG) image */ 1329 1330 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRgrt0, 1331 &Subtable); 1332 if (ACPI_FAILURE (Status)) 1333 { 1334 return (Status); 1335 } 1336 1337 DtInsertSubtable (ParentTable, Subtable); 1338 return (AE_OK); 1339 } 1340 1341 1342 /****************************************************************************** 1343 * 1344 * FUNCTION: DtCompileRsdt 1345 * 1346 * PARAMETERS: List - Current field list pointer 1347 * 1348 * RETURN: Status 1349 * 1350 * DESCRIPTION: Compile RSDT. 1351 * 1352 *****************************************************************************/ 1353 1354 ACPI_STATUS 1355 DtCompileRsdt ( 1356 void **List) 1357 { 1358 DT_SUBTABLE *Subtable; 1359 DT_SUBTABLE *ParentTable; 1360 DT_FIELD *FieldList = *(DT_FIELD **) List; 1361 UINT32 Address; 1362 1363 1364 ParentTable = DtPeekSubtable (); 1365 1366 while (FieldList) 1367 { 1368 DtCompileInteger ((UINT8 *) &Address, FieldList, 4, DT_NON_ZERO); 1369 1370 DtCreateSubtable ((UINT8 *) &Address, 4, &Subtable); 1371 DtInsertSubtable (ParentTable, Subtable); 1372 FieldList = FieldList->Next; 1373 } 1374 1375 return (AE_OK); 1376 } 1377 1378 1379 /****************************************************************************** 1380 * 1381 * FUNCTION: DtCompileS3pt 1382 * 1383 * PARAMETERS: PFieldList - Current field list pointer 1384 * 1385 * RETURN: Status 1386 * 1387 * DESCRIPTION: Compile S3PT (Pointed to by FPDT) 1388 * 1389 *****************************************************************************/ 1390 1391 ACPI_STATUS 1392 DtCompileS3pt ( 1393 DT_FIELD **PFieldList) 1394 { 1395 ACPI_STATUS Status; 1396 ACPI_FPDT_HEADER *S3ptHeader; 1397 DT_SUBTABLE *Subtable; 1398 DT_SUBTABLE *ParentTable; 1399 ACPI_DMTABLE_INFO *InfoTable; 1400 DT_FIELD *SubtableStart; 1401 1402 1403 Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3pt, 1404 &AslGbl_RootTable); 1405 if (ACPI_FAILURE (Status)) 1406 { 1407 return (Status); 1408 } 1409 1410 DtPushSubtable (AslGbl_RootTable); 1411 1412 while (*PFieldList) 1413 { 1414 SubtableStart = *PFieldList; 1415 Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3ptHdr, 1416 &Subtable); 1417 if (ACPI_FAILURE (Status)) 1418 { 1419 return (Status); 1420 } 1421 1422 ParentTable = DtPeekSubtable (); 1423 DtInsertSubtable (ParentTable, Subtable); 1424 DtPushSubtable (Subtable); 1425 1426 S3ptHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer); 1427 1428 switch (S3ptHeader->Type) 1429 { 1430 case ACPI_S3PT_TYPE_RESUME: 1431 1432 InfoTable = AcpiDmTableInfoS3pt0; 1433 break; 1434 1435 case ACPI_S3PT_TYPE_SUSPEND: 1436 1437 InfoTable = AcpiDmTableInfoS3pt1; 1438 break; 1439 1440 default: 1441 1442 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "S3PT"); 1443 return (AE_ERROR); 1444 } 1445 1446 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 1447 if (ACPI_FAILURE (Status)) 1448 { 1449 return (Status); 1450 } 1451 1452 ParentTable = DtPeekSubtable (); 1453 DtInsertSubtable (ParentTable, Subtable); 1454 DtPopSubtable (); 1455 } 1456 1457 return (AE_OK); 1458 } 1459 1460 1461 /****************************************************************************** 1462 * 1463 * FUNCTION: DtCompileSdev 1464 * 1465 * PARAMETERS: List - Current field list pointer 1466 * 1467 * RETURN: Status 1468 * 1469 * DESCRIPTION: Compile SDEV. 1470 * 1471 *****************************************************************************/ 1472 1473 ACPI_STATUS 1474 DtCompileSdev ( 1475 void **List) 1476 { 1477 ACPI_STATUS Status; 1478 ACPI_SDEV_HEADER *SdevHeader; 1479 ACPI_SDEV_HEADER *SecureComponentHeader; 1480 DT_SUBTABLE *Subtable; 1481 DT_SUBTABLE *ParentTable; 1482 ACPI_DMTABLE_INFO *InfoTable; 1483 ACPI_DMTABLE_INFO *SecureComponentInfoTable = NULL; 1484 DT_FIELD **PFieldList = (DT_FIELD **) List; 1485 DT_FIELD *SubtableStart; 1486 ACPI_SDEV_PCIE *Pcie = NULL; 1487 ACPI_SDEV_NAMESPACE *Namesp = NULL; 1488 UINT32 EntryCount; 1489 ACPI_SDEV_SECURE_COMPONENT *SecureComponent = NULL; 1490 UINT16 ComponentLength = 0; 1491 1492 1493 /* Subtables */ 1494 1495 while (*PFieldList) 1496 { 1497 /* Compile common SDEV subtable header */ 1498 1499 SubtableStart = *PFieldList; 1500 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdevHdr, 1501 &Subtable); 1502 if (ACPI_FAILURE (Status)) 1503 { 1504 return (Status); 1505 } 1506 1507 ParentTable = DtPeekSubtable (); 1508 DtInsertSubtable (ParentTable, Subtable); 1509 DtPushSubtable (Subtable); 1510 1511 SdevHeader = ACPI_CAST_PTR (ACPI_SDEV_HEADER, Subtable->Buffer); 1512 SdevHeader->Length = (UINT8)(sizeof (ACPI_SDEV_HEADER)); 1513 1514 switch (SdevHeader->Type) 1515 { 1516 case ACPI_SDEV_TYPE_NAMESPACE_DEVICE: 1517 1518 InfoTable = AcpiDmTableInfoSdev0; 1519 Namesp = ACPI_CAST_PTR (ACPI_SDEV_NAMESPACE, Subtable->Buffer); 1520 SecureComponent = ACPI_CAST_PTR (ACPI_SDEV_SECURE_COMPONENT, 1521 ACPI_ADD_PTR (UINT8, Subtable->Buffer, sizeof(ACPI_SDEV_NAMESPACE))); 1522 break; 1523 1524 case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE: 1525 1526 InfoTable = AcpiDmTableInfoSdev1; 1527 Pcie = ACPI_CAST_PTR (ACPI_SDEV_PCIE, Subtable->Buffer); 1528 break; 1529 1530 default: 1531 1532 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SDEV"); 1533 return (AE_ERROR); 1534 } 1535 1536 /* Compile SDEV subtable body */ 1537 1538 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 1539 if (ACPI_FAILURE (Status)) 1540 { 1541 return (Status); 1542 } 1543 1544 ParentTable = DtPeekSubtable (); 1545 DtInsertSubtable (ParentTable, Subtable); 1546 1547 /* Optional data fields are appended to the main subtable body */ 1548 1549 switch (SdevHeader->Type) 1550 { 1551 case ACPI_SDEV_TYPE_NAMESPACE_DEVICE: 1552 1553 /* 1554 * Device Id Offset will be be calculated differently depending on 1555 * the presence of secure access components. 1556 */ 1557 Namesp->DeviceIdOffset = 0; 1558 ComponentLength = 0; 1559 1560 /* If the secure access component exists, get the structures */ 1561 1562 if (SdevHeader->Flags & ACPI_SDEV_SECURE_COMPONENTS_PRESENT) 1563 { 1564 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev0b, 1565 &Subtable); 1566 if (ACPI_FAILURE (Status)) 1567 { 1568 return (Status); 1569 } 1570 ParentTable = DtPeekSubtable (); 1571 DtInsertSubtable (ParentTable, Subtable); 1572 1573 Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_SECURE_COMPONENT); 1574 1575 /* Compile a secure access component header */ 1576 1577 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdevSecCompHdr, 1578 &Subtable); 1579 if (ACPI_FAILURE (Status)) 1580 { 1581 return (Status); 1582 } 1583 ParentTable = DtPeekSubtable (); 1584 DtInsertSubtable (ParentTable, Subtable); 1585 1586 /* Compile the secure access component */ 1587 1588 SecureComponentHeader = ACPI_CAST_PTR (ACPI_SDEV_HEADER, Subtable->Buffer); 1589 switch (SecureComponentHeader->Type) 1590 { 1591 case ACPI_SDEV_TYPE_ID_COMPONENT: 1592 1593 SecureComponentInfoTable = AcpiDmTableInfoSdevSecCompId; 1594 Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_ID_COMPONENT); 1595 ComponentLength = sizeof (ACPI_SDEV_ID_COMPONENT); 1596 break; 1597 1598 case ACPI_SDEV_TYPE_MEM_COMPONENT: 1599 1600 SecureComponentInfoTable = AcpiDmTableInfoSdevSecCompMem; 1601 Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_MEM_COMPONENT); 1602 ComponentLength = sizeof (ACPI_SDEV_MEM_COMPONENT); 1603 break; 1604 1605 default: 1606 1607 /* Any other secure component types are undefined */ 1608 1609 return (AE_ERROR); 1610 } 1611 1612 Status = DtCompileTable (PFieldList, SecureComponentInfoTable, 1613 &Subtable); 1614 if (ACPI_FAILURE (Status)) 1615 { 1616 return (Status); 1617 } 1618 ParentTable = DtPeekSubtable (); 1619 DtInsertSubtable (ParentTable, Subtable); 1620 1621 SecureComponent->SecureComponentOffset = 1622 sizeof (ACPI_SDEV_NAMESPACE) + sizeof (ACPI_SDEV_SECURE_COMPONENT); 1623 SecureComponent->SecureComponentLength = ComponentLength; 1624 1625 1626 /* 1627 * Add the secure component to the subtable to be added for the 1628 * the namespace subtable's length 1629 */ 1630 ComponentLength += sizeof (ACPI_SDEV_SECURE_COMPONENT); 1631 } 1632 1633 /* Append DeviceId namespace string */ 1634 1635 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev0a, 1636 &Subtable); 1637 if (ACPI_FAILURE (Status)) 1638 { 1639 return (Status); 1640 } 1641 1642 if (!Subtable) 1643 { 1644 break; 1645 } 1646 1647 ParentTable = DtPeekSubtable (); 1648 DtInsertSubtable (ParentTable, Subtable); 1649 1650 Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_NAMESPACE); 1651 1652 Namesp->DeviceIdLength = (UINT16) Subtable->Length; 1653 1654 /* Append Vendor data */ 1655 1656 Namesp->VendorDataLength = 0; 1657 Namesp->VendorDataOffset = 0; 1658 1659 if (*PFieldList) 1660 { 1661 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1b, 1662 &Subtable); 1663 if (ACPI_FAILURE (Status)) 1664 { 1665 return (Status); 1666 } 1667 1668 if (Subtable) 1669 { 1670 ParentTable = DtPeekSubtable (); 1671 DtInsertSubtable (ParentTable, Subtable); 1672 1673 Namesp->VendorDataOffset = 1674 Namesp->DeviceIdOffset + Namesp->DeviceIdLength; 1675 Namesp->VendorDataLength = 1676 (UINT16) Subtable->Length; 1677 1678 /* Final size of entire namespace structure */ 1679 1680 SdevHeader->Length = (UINT16)(sizeof(ACPI_SDEV_NAMESPACE) + 1681 Subtable->Length + Namesp->DeviceIdLength) + ComponentLength; 1682 } 1683 } 1684 1685 break; 1686 1687 case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE: 1688 1689 /* Append the PCIe path info first */ 1690 1691 EntryCount = 0; 1692 while (*PFieldList && !strcmp ((*PFieldList)->Name, "Device")) 1693 { 1694 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1a, 1695 &Subtable); 1696 if (ACPI_FAILURE (Status)) 1697 { 1698 return (Status); 1699 } 1700 1701 if (!Subtable) 1702 { 1703 DtPopSubtable (); 1704 break; 1705 } 1706 1707 ParentTable = DtPeekSubtable (); 1708 DtInsertSubtable (ParentTable, Subtable); 1709 EntryCount++; 1710 } 1711 1712 /* Path offset will point immediately after the main subtable */ 1713 1714 Pcie->PathOffset = sizeof (ACPI_SDEV_PCIE); 1715 Pcie->PathLength = (UINT16) 1716 (EntryCount * sizeof (ACPI_SDEV_PCIE_PATH)); 1717 1718 /* Append the Vendor Data last */ 1719 1720 Pcie->VendorDataLength = 0; 1721 Pcie->VendorDataOffset = 0; 1722 1723 if (*PFieldList) 1724 { 1725 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1b, 1726 &Subtable); 1727 if (ACPI_FAILURE (Status)) 1728 { 1729 return (Status); 1730 } 1731 1732 if (Subtable) 1733 { 1734 ParentTable = DtPeekSubtable (); 1735 DtInsertSubtable (ParentTable, Subtable); 1736 1737 Pcie->VendorDataOffset = 1738 Pcie->PathOffset + Pcie->PathLength; 1739 Pcie->VendorDataLength = (UINT16) 1740 Subtable->Length; 1741 } 1742 } 1743 1744 SdevHeader->Length = 1745 sizeof (ACPI_SDEV_PCIE) + 1746 Pcie->PathLength + Pcie->VendorDataLength; 1747 break; 1748 1749 default: 1750 1751 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SDEV"); 1752 return (AE_ERROR); 1753 } 1754 1755 DtPopSubtable (); 1756 } 1757 1758 return (AE_OK); 1759 } 1760 1761 1762 /****************************************************************************** 1763 * 1764 * FUNCTION: DtCompileSlic 1765 * 1766 * PARAMETERS: List - Current field list pointer 1767 * 1768 * RETURN: Status 1769 * 1770 * DESCRIPTION: Compile SLIC. 1771 * 1772 *****************************************************************************/ 1773 1774 ACPI_STATUS 1775 DtCompileSlic ( 1776 void **List) 1777 { 1778 ACPI_STATUS Status; 1779 DT_SUBTABLE *Subtable; 1780 DT_SUBTABLE *ParentTable; 1781 DT_FIELD **PFieldList = (DT_FIELD **) List; 1782 1783 1784 while (*PFieldList) 1785 { 1786 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlic, 1787 &Subtable); 1788 if (ACPI_FAILURE (Status)) 1789 { 1790 return (Status); 1791 } 1792 1793 ParentTable = DtPeekSubtable (); 1794 DtInsertSubtable (ParentTable, Subtable); 1795 DtPushSubtable (Subtable); 1796 DtPopSubtable (); 1797 } 1798 1799 return (AE_OK); 1800 } 1801 1802 1803 /****************************************************************************** 1804 * 1805 * FUNCTION: DtCompileSlit 1806 * 1807 * PARAMETERS: List - Current field list pointer 1808 * 1809 * RETURN: Status 1810 * 1811 * DESCRIPTION: Compile SLIT. 1812 * 1813 *****************************************************************************/ 1814 1815 ACPI_STATUS 1816 DtCompileSlit ( 1817 void **List) 1818 { 1819 ACPI_STATUS Status; 1820 DT_SUBTABLE *Subtable; 1821 DT_SUBTABLE *ParentTable; 1822 DT_FIELD **PFieldList = (DT_FIELD **) List; 1823 DT_FIELD *FieldList; 1824 DT_FIELD *EndOfFieldList = NULL; 1825 UINT32 Localities; 1826 UINT32 LocalityListLength; 1827 UINT8 *LocalityBuffer; 1828 1829 1830 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlit, 1831 &Subtable); 1832 if (ACPI_FAILURE (Status)) 1833 { 1834 return (Status); 1835 } 1836 1837 ParentTable = DtPeekSubtable (); 1838 DtInsertSubtable (ParentTable, Subtable); 1839 1840 Localities = *ACPI_CAST_PTR (UINT32, Subtable->Buffer); 1841 LocalityBuffer = UtLocalCalloc (Localities); 1842 LocalityListLength = 0; 1843 1844 /* Compile each locality buffer */ 1845 1846 FieldList = *PFieldList; 1847 while (FieldList) 1848 { 1849 DtCompileBuffer (LocalityBuffer, 1850 FieldList->Value, FieldList, Localities); 1851 1852 LocalityListLength++; 1853 DtCreateSubtable (LocalityBuffer, Localities, &Subtable); 1854 DtInsertSubtable (ParentTable, Subtable); 1855 EndOfFieldList = FieldList; 1856 FieldList = FieldList->Next; 1857 } 1858 1859 if (LocalityListLength != Localities) 1860 { 1861 sprintf(AslGbl_MsgBuffer, 1862 "Found %u entries, must match LocalityCount: %u", 1863 LocalityListLength, Localities); 1864 DtError (ASL_ERROR, ASL_MSG_ENTRY_LIST, EndOfFieldList, AslGbl_MsgBuffer); 1865 ACPI_FREE (LocalityBuffer); 1866 return (AE_LIMIT); 1867 } 1868 1869 ACPI_FREE (LocalityBuffer); 1870 return (AE_OK); 1871 } 1872 1873 1874 /****************************************************************************** 1875 * 1876 * FUNCTION: DtCompileSrat 1877 * 1878 * PARAMETERS: List - Current field list pointer 1879 * 1880 * RETURN: Status 1881 * 1882 * DESCRIPTION: Compile SRAT. 1883 * 1884 *****************************************************************************/ 1885 1886 ACPI_STATUS 1887 DtCompileSrat ( 1888 void **List) 1889 { 1890 ACPI_STATUS Status; 1891 DT_SUBTABLE *Subtable; 1892 DT_SUBTABLE *ParentTable; 1893 DT_FIELD **PFieldList = (DT_FIELD **) List; 1894 DT_FIELD *SubtableStart; 1895 ACPI_SUBTABLE_HEADER *SratHeader; 1896 ACPI_DMTABLE_INFO *InfoTable; 1897 1898 1899 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSrat, 1900 &Subtable); 1901 if (ACPI_FAILURE (Status)) 1902 { 1903 return (Status); 1904 } 1905 1906 ParentTable = DtPeekSubtable (); 1907 DtInsertSubtable (ParentTable, Subtable); 1908 1909 while (*PFieldList) 1910 { 1911 SubtableStart = *PFieldList; 1912 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSratHdr, 1913 &Subtable); 1914 if (ACPI_FAILURE (Status)) 1915 { 1916 return (Status); 1917 } 1918 1919 ParentTable = DtPeekSubtable (); 1920 DtInsertSubtable (ParentTable, Subtable); 1921 DtPushSubtable (Subtable); 1922 1923 SratHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); 1924 1925 switch (SratHeader->Type) 1926 { 1927 case ACPI_SRAT_TYPE_CPU_AFFINITY: 1928 1929 InfoTable = AcpiDmTableInfoSrat0; 1930 break; 1931 1932 case ACPI_SRAT_TYPE_MEMORY_AFFINITY: 1933 1934 InfoTable = AcpiDmTableInfoSrat1; 1935 break; 1936 1937 case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY: 1938 1939 InfoTable = AcpiDmTableInfoSrat2; 1940 break; 1941 1942 case ACPI_SRAT_TYPE_GICC_AFFINITY: 1943 1944 InfoTable = AcpiDmTableInfoSrat3; 1945 break; 1946 1947 case ACPI_SRAT_TYPE_GIC_ITS_AFFINITY: 1948 1949 InfoTable = AcpiDmTableInfoSrat4; 1950 break; 1951 1952 case ACPI_SRAT_TYPE_GENERIC_AFFINITY: 1953 1954 InfoTable = AcpiDmTableInfoSrat5; 1955 break; 1956 1957 case ACPI_SRAT_TYPE_GENERIC_PORT_AFFINITY: 1958 1959 InfoTable = AcpiDmTableInfoSrat6; 1960 break; 1961 1962 default: 1963 1964 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SRAT"); 1965 return (AE_ERROR); 1966 } 1967 1968 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 1969 if (ACPI_FAILURE (Status)) 1970 { 1971 return (Status); 1972 } 1973 1974 ParentTable = DtPeekSubtable (); 1975 DtInsertSubtable (ParentTable, Subtable); 1976 DtPopSubtable (); 1977 } 1978 1979 return (AE_OK); 1980 } 1981 1982 1983 /****************************************************************************** 1984 * 1985 * FUNCTION: DtCompileStao 1986 * 1987 * PARAMETERS: PFieldList - Current field list pointer 1988 * 1989 * RETURN: Status 1990 * 1991 * DESCRIPTION: Compile STAO. 1992 * 1993 *****************************************************************************/ 1994 1995 ACPI_STATUS 1996 DtCompileStao ( 1997 void **List) 1998 { 1999 DT_FIELD **PFieldList = (DT_FIELD **) List; 2000 DT_SUBTABLE *Subtable; 2001 DT_SUBTABLE *ParentTable; 2002 ACPI_STATUS Status; 2003 2004 2005 /* Compile the main table */ 2006 2007 Status = DtCompileTable (PFieldList, AcpiDmTableInfoStao, 2008 &Subtable); 2009 if (ACPI_FAILURE (Status)) 2010 { 2011 return (Status); 2012 } 2013 2014 ParentTable = DtPeekSubtable (); 2015 DtInsertSubtable (ParentTable, Subtable); 2016 2017 /* Compile each ASCII namestring as a subtable */ 2018 2019 while (*PFieldList) 2020 { 2021 Status = DtCompileTable (PFieldList, AcpiDmTableInfoStaoStr, 2022 &Subtable); 2023 if (ACPI_FAILURE (Status)) 2024 { 2025 return (Status); 2026 } 2027 2028 ParentTable = DtPeekSubtable (); 2029 DtInsertSubtable (ParentTable, Subtable); 2030 } 2031 2032 return (AE_OK); 2033 } 2034 2035 2036 2037 /****************************************************************************** 2038 * 2039 * FUNCTION: DtCompileSvkl 2040 * 2041 * PARAMETERS: PFieldList - Current field list pointer 2042 * 2043 * RETURN: Status 2044 * 2045 * DESCRIPTION: Compile SVKL. 2046 * 2047 * NOTES: SVKL is essentially a flat table, with a small main table and 2048 * a variable number of a single type of subtable. 2049 * 2050 *****************************************************************************/ 2051 2052 ACPI_STATUS 2053 DtCompileSvkl ( 2054 void **List) 2055 { 2056 DT_FIELD **PFieldList = (DT_FIELD **) List; 2057 DT_SUBTABLE *Subtable; 2058 DT_SUBTABLE *ParentTable; 2059 ACPI_STATUS Status; 2060 2061 2062 /* Compile the main table */ 2063 2064 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSvkl, 2065 &Subtable); 2066 if (ACPI_FAILURE (Status)) 2067 { 2068 return (Status); 2069 } 2070 2071 ParentTable = DtPeekSubtable (); 2072 DtInsertSubtable (ParentTable, Subtable); 2073 2074 /* Compile each subtable */ 2075 2076 while (*PFieldList) 2077 { 2078 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSvkl0, 2079 &Subtable); 2080 if (ACPI_FAILURE (Status)) 2081 { 2082 return (Status); 2083 } 2084 2085 ParentTable = DtPeekSubtable (); 2086 DtInsertSubtable (ParentTable, Subtable); 2087 } 2088 2089 return (AE_OK); 2090 } 2091 2092 2093 /****************************************************************************** 2094 * 2095 * FUNCTION: DtCompileTcpa 2096 * 2097 * PARAMETERS: PFieldList - Current field list pointer 2098 * 2099 * RETURN: Status 2100 * 2101 * DESCRIPTION: Compile TCPA. 2102 * 2103 *****************************************************************************/ 2104 2105 ACPI_STATUS 2106 DtCompileTcpa ( 2107 void **List) 2108 { 2109 DT_FIELD **PFieldList = (DT_FIELD **) List; 2110 DT_SUBTABLE *Subtable; 2111 ACPI_TABLE_TCPA_HDR *TcpaHeader; 2112 DT_SUBTABLE *ParentTable; 2113 ACPI_STATUS Status; 2114 2115 2116 /* Compile the main table */ 2117 2118 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaHdr, 2119 &Subtable); 2120 if (ACPI_FAILURE (Status)) 2121 { 2122 return (Status); 2123 } 2124 2125 ParentTable = DtPeekSubtable (); 2126 DtInsertSubtable (ParentTable, Subtable); 2127 2128 /* 2129 * Examine the PlatformClass field to determine the table type. 2130 * Either a client or server table. Only one. 2131 */ 2132 TcpaHeader = ACPI_CAST_PTR (ACPI_TABLE_TCPA_HDR, ParentTable->Buffer); 2133 2134 switch (TcpaHeader->PlatformClass) 2135 { 2136 case ACPI_TCPA_CLIENT_TABLE: 2137 2138 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaClient, 2139 &Subtable); 2140 break; 2141 2142 case ACPI_TCPA_SERVER_TABLE: 2143 2144 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaServer, 2145 &Subtable); 2146 break; 2147 2148 default: 2149 2150 AcpiOsPrintf ("\n**** Unknown TCPA Platform Class 0x%X\n", 2151 TcpaHeader->PlatformClass); 2152 Status = AE_ERROR; 2153 break; 2154 } 2155 2156 ParentTable = DtPeekSubtable (); 2157 DtInsertSubtable (ParentTable, Subtable); 2158 return (Status); 2159 } 2160 2161 2162 /****************************************************************************** 2163 * 2164 * FUNCTION: DtCompileTpm2Rev3 2165 * 2166 * PARAMETERS: PFieldList - Current field list pointer 2167 * 2168 * RETURN: Status 2169 * 2170 * DESCRIPTION: Compile TPM2 revision 3 2171 * 2172 *****************************************************************************/ 2173 static ACPI_STATUS 2174 DtCompileTpm2Rev3 ( 2175 void **List) 2176 { 2177 DT_FIELD **PFieldList = (DT_FIELD **) List; 2178 DT_SUBTABLE *Subtable; 2179 ACPI_TABLE_TPM23 *Tpm23Header; 2180 DT_SUBTABLE *ParentTable; 2181 ACPI_STATUS Status = AE_OK; 2182 2183 2184 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm23, 2185 &Subtable); 2186 2187 ParentTable = DtPeekSubtable (); 2188 DtInsertSubtable (ParentTable, Subtable); 2189 Tpm23Header = ACPI_CAST_PTR (ACPI_TABLE_TPM23, ParentTable->Buffer); 2190 2191 /* Subtable type depends on the StartMethod */ 2192 2193 switch (Tpm23Header->StartMethod) 2194 { 2195 case ACPI_TPM23_ACPI_START_METHOD: 2196 2197 /* Subtable specific to to ARM_SMC */ 2198 2199 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm23a, 2200 &Subtable); 2201 if (ACPI_FAILURE (Status)) 2202 { 2203 return (Status); 2204 } 2205 2206 ParentTable = DtPeekSubtable (); 2207 DtInsertSubtable (ParentTable, Subtable); 2208 break; 2209 2210 default: 2211 break; 2212 } 2213 2214 return (Status); 2215 } 2216 2217 2218 /****************************************************************************** 2219 * 2220 * FUNCTION: DtCompileTpm2 2221 * 2222 * PARAMETERS: PFieldList - Current field list pointer 2223 * 2224 * RETURN: Status 2225 * 2226 * DESCRIPTION: Compile TPM2. 2227 * 2228 *****************************************************************************/ 2229 2230 ACPI_STATUS 2231 DtCompileTpm2 ( 2232 void **List) 2233 { 2234 DT_FIELD **PFieldList = (DT_FIELD **) List; 2235 DT_SUBTABLE *Subtable; 2236 ACPI_TABLE_TPM2 *Tpm2Header; 2237 DT_SUBTABLE *ParentTable; 2238 ACPI_STATUS Status = AE_OK; 2239 ACPI_TABLE_HEADER *Header; 2240 2241 2242 ParentTable = DtPeekSubtable (); 2243 2244 Header = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer); 2245 2246 if (Header->Revision == 3) 2247 { 2248 return (DtCompileTpm2Rev3 (List)); 2249 } 2250 2251 /* Compile the main table */ 2252 2253 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm2, 2254 &Subtable); 2255 if (ACPI_FAILURE (Status)) 2256 { 2257 return (Status); 2258 } 2259 2260 ParentTable = DtPeekSubtable (); 2261 DtInsertSubtable (ParentTable, Subtable); 2262 2263 Tpm2Header = ACPI_CAST_PTR (ACPI_TABLE_TPM2, ParentTable->Buffer); 2264 2265 /* Method parameters */ 2266 /* Optional: Log area minimum length */ 2267 /* Optional: Log area start address */ 2268 /* TBD: Optional fields above not fully implemented (not optional at this time) */ 2269 2270 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm2a, 2271 &Subtable); 2272 if (ACPI_FAILURE (Status)) 2273 { 2274 return (Status); 2275 } 2276 2277 ParentTable = DtPeekSubtable (); 2278 DtInsertSubtable (ParentTable, Subtable); 2279 2280 2281 /* Subtable type depends on the StartMethod */ 2282 2283 switch (Tpm2Header->StartMethod) 2284 { 2285 case ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC: 2286 2287 /* Subtable specific to to ARM_SMC */ 2288 2289 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm211, 2290 &Subtable); 2291 if (ACPI_FAILURE (Status)) 2292 { 2293 return (Status); 2294 } 2295 2296 ParentTable = DtPeekSubtable (); 2297 DtInsertSubtable (ParentTable, Subtable); 2298 break; 2299 2300 case ACPI_TPM2_START_METHOD: 2301 case ACPI_TPM2_MEMORY_MAPPED: 2302 case ACPI_TPM2_COMMAND_BUFFER: 2303 case ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD: 2304 break; 2305 2306 case ACPI_TPM2_RESERVED1: 2307 case ACPI_TPM2_RESERVED3: 2308 case ACPI_TPM2_RESERVED4: 2309 case ACPI_TPM2_RESERVED5: 2310 case ACPI_TPM2_RESERVED9: 2311 case ACPI_TPM2_RESERVED10: 2312 2313 AcpiOsPrintf ("\n**** Reserved TPM2 Start Method type 0x%X\n", 2314 Tpm2Header->StartMethod); 2315 Status = AE_ERROR; 2316 break; 2317 2318 case ACPI_TPM2_NOT_ALLOWED: 2319 default: 2320 2321 AcpiOsPrintf ("\n**** Unknown TPM2 Start Method type 0x%X\n", 2322 Tpm2Header->StartMethod); 2323 Status = AE_ERROR; 2324 break; 2325 } 2326 2327 return (Status); 2328 } 2329 2330 2331 /****************************************************************************** 2332 * 2333 * FUNCTION: DtGetGenericTableInfo 2334 * 2335 * PARAMETERS: Name - Generic type name 2336 * 2337 * RETURN: Info entry 2338 * 2339 * DESCRIPTION: Obtain table info for a generic name entry 2340 * 2341 *****************************************************************************/ 2342 2343 ACPI_DMTABLE_INFO * 2344 DtGetGenericTableInfo ( 2345 char *Name) 2346 { 2347 ACPI_DMTABLE_INFO *Info; 2348 UINT32 i; 2349 2350 2351 if (!Name) 2352 { 2353 return (NULL); 2354 } 2355 2356 /* Search info table for name match */ 2357 2358 for (i = 0; ; i++) 2359 { 2360 Info = AcpiDmTableInfoGeneric[i]; 2361 if (Info->Opcode == ACPI_DMT_EXIT) 2362 { 2363 Info = NULL; 2364 break; 2365 } 2366 2367 /* Use caseless compare for generic keywords */ 2368 2369 if (!AcpiUtStricmp (Name, Info->Name)) 2370 { 2371 break; 2372 } 2373 } 2374 2375 return (Info); 2376 } 2377 2378 2379 /****************************************************************************** 2380 * 2381 * FUNCTION: DtCompileUefi 2382 * 2383 * PARAMETERS: List - Current field list pointer 2384 * 2385 * RETURN: Status 2386 * 2387 * DESCRIPTION: Compile UEFI. 2388 * 2389 *****************************************************************************/ 2390 2391 ACPI_STATUS 2392 DtCompileUefi ( 2393 void **List) 2394 { 2395 ACPI_STATUS Status; 2396 DT_SUBTABLE *Subtable; 2397 DT_SUBTABLE *ParentTable; 2398 DT_FIELD **PFieldList = (DT_FIELD **) List; 2399 UINT16 *DataOffset; 2400 2401 2402 /* Compile the predefined portion of the UEFI table */ 2403 2404 Status = DtCompileTable (PFieldList, AcpiDmTableInfoUefi, 2405 &Subtable); 2406 if (ACPI_FAILURE (Status)) 2407 { 2408 return (Status); 2409 } 2410 2411 DataOffset = (UINT16 *) (Subtable->Buffer + 16); 2412 *DataOffset = sizeof (ACPI_TABLE_UEFI); 2413 2414 ParentTable = DtPeekSubtable (); 2415 DtInsertSubtable (ParentTable, Subtable); 2416 2417 /* 2418 * Compile the "generic" portion of the UEFI table. This 2419 * part of the table is not predefined and any of the generic 2420 * operators may be used. 2421 */ 2422 DtCompileGeneric ((void **) PFieldList, NULL, NULL); 2423 return (AE_OK); 2424 } 2425 2426 2427 /****************************************************************************** 2428 * 2429 * FUNCTION: DtCompileViot 2430 * 2431 * PARAMETERS: List - Current field list pointer 2432 * 2433 * RETURN: Status 2434 * 2435 * DESCRIPTION: Compile VIOT. 2436 * 2437 *****************************************************************************/ 2438 2439 ACPI_STATUS 2440 DtCompileViot ( 2441 void **List) 2442 { 2443 ACPI_STATUS Status; 2444 DT_SUBTABLE *Subtable; 2445 DT_SUBTABLE *ParentTable; 2446 DT_FIELD **PFieldList = (DT_FIELD **) List; 2447 DT_FIELD *SubtableStart; 2448 ACPI_TABLE_VIOT *Viot; 2449 ACPI_VIOT_HEADER *ViotHeader; 2450 ACPI_DMTABLE_INFO *InfoTable; 2451 UINT16 NodeCount; 2452 2453 ParentTable = DtPeekSubtable (); 2454 2455 Status = DtCompileTable (PFieldList, AcpiDmTableInfoViot, &Subtable); 2456 if (ACPI_FAILURE (Status)) 2457 { 2458 return (Status); 2459 } 2460 DtInsertSubtable (ParentTable, Subtable); 2461 2462 /* 2463 * Using ACPI_SUB_PTR, We needn't define a separate structure. Care 2464 * should be taken to avoid accessing ACPI_TABLE_HEADER fields. 2465 */ 2466 Viot = ACPI_SUB_PTR (ACPI_TABLE_VIOT, Subtable->Buffer, 2467 sizeof (ACPI_TABLE_HEADER)); 2468 2469 Viot->NodeOffset = sizeof (ACPI_TABLE_VIOT); 2470 2471 NodeCount = 0; 2472 while (*PFieldList) { 2473 SubtableStart = *PFieldList; 2474 Status = DtCompileTable (PFieldList, AcpiDmTableInfoViotHeader, 2475 &Subtable); 2476 if (ACPI_FAILURE (Status)) 2477 { 2478 return (Status); 2479 } 2480 2481 ParentTable = DtPeekSubtable (); 2482 DtInsertSubtable (ParentTable, Subtable); 2483 DtPushSubtable (Subtable); 2484 2485 ViotHeader = ACPI_CAST_PTR (ACPI_VIOT_HEADER, Subtable->Buffer); 2486 2487 switch (ViotHeader->Type) 2488 { 2489 case ACPI_VIOT_NODE_PCI_RANGE: 2490 2491 InfoTable = AcpiDmTableInfoViot1; 2492 break; 2493 2494 case ACPI_VIOT_NODE_MMIO: 2495 2496 InfoTable = AcpiDmTableInfoViot2; 2497 break; 2498 2499 case ACPI_VIOT_NODE_VIRTIO_IOMMU_PCI: 2500 2501 InfoTable = AcpiDmTableInfoViot3; 2502 break; 2503 2504 case ACPI_VIOT_NODE_VIRTIO_IOMMU_MMIO: 2505 2506 InfoTable = AcpiDmTableInfoViot4; 2507 break; 2508 2509 default: 2510 2511 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "VIOT"); 2512 return (AE_ERROR); 2513 } 2514 2515 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 2516 if (ACPI_FAILURE (Status)) 2517 { 2518 return (Status); 2519 } 2520 2521 ParentTable = DtPeekSubtable (); 2522 DtInsertSubtable (ParentTable, Subtable); 2523 DtPopSubtable (); 2524 NodeCount++; 2525 } 2526 2527 Viot->NodeCount = NodeCount; 2528 return (AE_OK); 2529 } 2530 2531 2532 /****************************************************************************** 2533 * 2534 * FUNCTION: DtCompileWdat 2535 * 2536 * PARAMETERS: List - Current field list pointer 2537 * 2538 * RETURN: Status 2539 * 2540 * DESCRIPTION: Compile WDAT. 2541 * 2542 *****************************************************************************/ 2543 2544 ACPI_STATUS 2545 DtCompileWdat ( 2546 void **List) 2547 { 2548 ACPI_STATUS Status; 2549 2550 2551 Status = DtCompileTwoSubtables (List, 2552 AcpiDmTableInfoWdat, AcpiDmTableInfoWdat0); 2553 return (Status); 2554 } 2555 2556 2557 /****************************************************************************** 2558 * 2559 * FUNCTION: DtCompileWpbt 2560 * 2561 * PARAMETERS: List - Current field list pointer 2562 * 2563 * RETURN: Status 2564 * 2565 * DESCRIPTION: Compile WPBT. 2566 * 2567 *****************************************************************************/ 2568 2569 ACPI_STATUS 2570 DtCompileWpbt ( 2571 void **List) 2572 { 2573 DT_FIELD **PFieldList = (DT_FIELD **) List; 2574 DT_SUBTABLE *Subtable; 2575 DT_SUBTABLE *ParentTable; 2576 ACPI_TABLE_WPBT *Table; 2577 ACPI_STATUS Status; 2578 2579 2580 /* Compile the main table */ 2581 2582 Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt, &Subtable); 2583 if (ACPI_FAILURE (Status)) 2584 { 2585 return (Status); 2586 } 2587 2588 ParentTable = DtPeekSubtable (); 2589 DtInsertSubtable (ParentTable, Subtable); 2590 Table = ACPI_CAST_PTR (ACPI_TABLE_WPBT, ParentTable->Buffer); 2591 2592 /* 2593 * Exit now if there are no arguments specified. This is indicated by: 2594 * The "Command-line Arguments" field has not been specified (if specified, 2595 * it will be the last field in the field list -- after the main table). 2596 * Set the Argument Length in the main table to zero. 2597 */ 2598 if (!*PFieldList) 2599 { 2600 Table->ArgumentsLength = 0; 2601 return (AE_OK); 2602 } 2603 2604 /* Compile the argument list subtable */ 2605 2606 Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt0, &Subtable); 2607 if (ACPI_FAILURE (Status)) 2608 { 2609 return (Status); 2610 } 2611 2612 /* Extract the length of the Arguments buffer, insert into main table */ 2613 2614 Table->ArgumentsLength = (UINT16) Subtable->TotalLength; 2615 DtInsertSubtable (ParentTable, Subtable); 2616 return (AE_OK); 2617 } 2618 2619 2620 /****************************************************************************** 2621 * 2622 * FUNCTION: DtCompileXsdt 2623 * 2624 * PARAMETERS: List - Current field list pointer 2625 * 2626 * RETURN: Status 2627 * 2628 * DESCRIPTION: Compile XSDT. 2629 * 2630 *****************************************************************************/ 2631 2632 ACPI_STATUS 2633 DtCompileXsdt ( 2634 void **List) 2635 { 2636 DT_SUBTABLE *Subtable; 2637 DT_SUBTABLE *ParentTable; 2638 DT_FIELD *FieldList = *(DT_FIELD **) List; 2639 UINT64 Address; 2640 2641 2642 ParentTable = DtPeekSubtable (); 2643 2644 while (FieldList) 2645 { 2646 DtCompileInteger ((UINT8 *) &Address, FieldList, 8, DT_NON_ZERO); 2647 2648 DtCreateSubtable ((UINT8 *) &Address, 8, &Subtable); 2649 DtInsertSubtable (ParentTable, Subtable); 2650 FieldList = FieldList->Next; 2651 } 2652 2653 return (AE_OK); 2654 } 2655 2656 2657 /****************************************************************************** 2658 * 2659 * FUNCTION: DtCompileGeneric 2660 * 2661 * PARAMETERS: List - Current field list pointer 2662 * Name - Field name to end generic compiling 2663 * Length - Compiled table length to return 2664 * 2665 * RETURN: Status 2666 * 2667 * DESCRIPTION: Compile generic unknown table. 2668 * 2669 *****************************************************************************/ 2670 2671 ACPI_STATUS 2672 DtCompileGeneric ( 2673 void **List, 2674 char *Name, 2675 UINT32 *Length) 2676 { 2677 ACPI_STATUS Status; 2678 DT_SUBTABLE *Subtable; 2679 DT_SUBTABLE *ParentTable; 2680 DT_FIELD **PFieldList = (DT_FIELD **) List; 2681 ACPI_DMTABLE_INFO *Info; 2682 2683 2684 ParentTable = DtPeekSubtable (); 2685 2686 /* 2687 * Compile the "generic" portion of the table. This 2688 * part of the table is not predefined and any of the generic 2689 * operators may be used. 2690 */ 2691 2692 /* Find any and all labels in the entire generic portion */ 2693 2694 DtDetectAllLabels (*PFieldList); 2695 2696 /* Now we can actually compile the parse tree */ 2697 2698 if (Length && *Length) 2699 { 2700 *Length = 0; 2701 } 2702 while (*PFieldList) 2703 { 2704 if (Name && !strcmp ((*PFieldList)->Name, Name)) 2705 { 2706 break; 2707 } 2708 2709 Info = DtGetGenericTableInfo ((*PFieldList)->Name); 2710 if (!Info) 2711 { 2712 sprintf (AslGbl_MsgBuffer, "Generic data type \"%s\" not found", 2713 (*PFieldList)->Name); 2714 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME, 2715 (*PFieldList), AslGbl_MsgBuffer); 2716 2717 *PFieldList = (*PFieldList)->Next; 2718 continue; 2719 } 2720 2721 Status = DtCompileTable (PFieldList, Info, 2722 &Subtable); 2723 if (ACPI_SUCCESS (Status)) 2724 { 2725 DtInsertSubtable (ParentTable, Subtable); 2726 if (Length) 2727 { 2728 *Length += Subtable->Length; 2729 } 2730 } 2731 else 2732 { 2733 *PFieldList = (*PFieldList)->Next; 2734 2735 if (Status == AE_NOT_FOUND) 2736 { 2737 sprintf (AslGbl_MsgBuffer, "Generic data type \"%s\" not found", 2738 (*PFieldList)->Name); 2739 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME, 2740 (*PFieldList), AslGbl_MsgBuffer); 2741 } 2742 } 2743 } 2744 2745 return (AE_OK); 2746 } 2747