1 /****************************************************************************** 2 * 3 * Module Name: dttable2.c - handling for specific ACPI tables 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2019, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 /* 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 default: 262 263 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "MADT"); 264 return (AE_ERROR); 265 } 266 267 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 268 if (ACPI_FAILURE (Status)) 269 { 270 return (Status); 271 } 272 273 ParentTable = DtPeekSubtable (); 274 DtInsertSubtable (ParentTable, Subtable); 275 DtPopSubtable (); 276 } 277 278 return (AE_OK); 279 } 280 281 282 /****************************************************************************** 283 * 284 * FUNCTION: DtCompileMcfg 285 * 286 * PARAMETERS: List - Current field list pointer 287 * 288 * RETURN: Status 289 * 290 * DESCRIPTION: Compile MCFG. 291 * 292 *****************************************************************************/ 293 294 ACPI_STATUS 295 DtCompileMcfg ( 296 void **List) 297 { 298 ACPI_STATUS Status; 299 300 301 Status = DtCompileTwoSubtables (List, 302 AcpiDmTableInfoMcfg, AcpiDmTableInfoMcfg0); 303 return (Status); 304 } 305 306 307 /****************************************************************************** 308 * 309 * FUNCTION: DtCompileMpst 310 * 311 * PARAMETERS: List - Current field list pointer 312 * 313 * RETURN: Status 314 * 315 * DESCRIPTION: Compile MPST. 316 * 317 *****************************************************************************/ 318 319 ACPI_STATUS 320 DtCompileMpst ( 321 void **List) 322 { 323 ACPI_STATUS Status; 324 DT_SUBTABLE *Subtable; 325 DT_SUBTABLE *ParentTable; 326 DT_FIELD **PFieldList = (DT_FIELD **) List; 327 ACPI_MPST_CHANNEL *MpstChannelInfo; 328 ACPI_MPST_POWER_NODE *MpstPowerNode; 329 ACPI_MPST_DATA_HDR *MpstDataHeader; 330 UINT16 SubtableCount; 331 UINT32 PowerStateCount; 332 UINT32 ComponentCount; 333 334 335 /* Main table */ 336 337 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst, &Subtable); 338 if (ACPI_FAILURE (Status)) 339 { 340 return (Status); 341 } 342 343 ParentTable = DtPeekSubtable (); 344 DtInsertSubtable (ParentTable, Subtable); 345 DtPushSubtable (Subtable); 346 347 MpstChannelInfo = ACPI_CAST_PTR (ACPI_MPST_CHANNEL, Subtable->Buffer); 348 SubtableCount = MpstChannelInfo->PowerNodeCount; 349 350 while (*PFieldList && SubtableCount) 351 { 352 /* Subtable: Memory Power Node(s) */ 353 354 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0, 355 &Subtable); 356 if (ACPI_FAILURE (Status)) 357 { 358 return (Status); 359 } 360 361 ParentTable = DtPeekSubtable (); 362 DtInsertSubtable (ParentTable, Subtable); 363 DtPushSubtable (Subtable); 364 365 MpstPowerNode = ACPI_CAST_PTR (ACPI_MPST_POWER_NODE, Subtable->Buffer); 366 PowerStateCount = MpstPowerNode->NumPowerStates; 367 ComponentCount = MpstPowerNode->NumPhysicalComponents; 368 369 ParentTable = DtPeekSubtable (); 370 371 /* Sub-subtables - Memory Power State Structure(s) */ 372 373 while (*PFieldList && PowerStateCount) 374 { 375 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0A, 376 &Subtable); 377 if (ACPI_FAILURE (Status)) 378 { 379 return (Status); 380 } 381 382 DtInsertSubtable (ParentTable, Subtable); 383 PowerStateCount--; 384 } 385 386 /* Sub-subtables - Physical Component ID Structure(s) */ 387 388 while (*PFieldList && ComponentCount) 389 { 390 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0B, 391 &Subtable); 392 if (ACPI_FAILURE (Status)) 393 { 394 return (Status); 395 } 396 397 DtInsertSubtable (ParentTable, Subtable); 398 ComponentCount--; 399 } 400 401 SubtableCount--; 402 DtPopSubtable (); 403 } 404 405 /* Subtable: Count of Memory Power State Characteristic structures */ 406 407 DtPopSubtable (); 408 409 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst1, &Subtable); 410 if (ACPI_FAILURE (Status)) 411 { 412 return (Status); 413 } 414 415 ParentTable = DtPeekSubtable (); 416 DtInsertSubtable (ParentTable, Subtable); 417 DtPushSubtable (Subtable); 418 419 MpstDataHeader = ACPI_CAST_PTR (ACPI_MPST_DATA_HDR, Subtable->Buffer); 420 SubtableCount = MpstDataHeader->CharacteristicsCount; 421 422 ParentTable = DtPeekSubtable (); 423 424 /* Subtable: Memory Power State Characteristics structure(s) */ 425 426 while (*PFieldList && SubtableCount) 427 { 428 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst2, 429 &Subtable); 430 if (ACPI_FAILURE (Status)) 431 { 432 return (Status); 433 } 434 435 DtInsertSubtable (ParentTable, Subtable); 436 SubtableCount--; 437 } 438 439 DtPopSubtable (); 440 return (AE_OK); 441 } 442 443 444 /****************************************************************************** 445 * 446 * FUNCTION: DtCompileMsct 447 * 448 * PARAMETERS: List - Current field list pointer 449 * 450 * RETURN: Status 451 * 452 * DESCRIPTION: Compile MSCT. 453 * 454 *****************************************************************************/ 455 456 ACPI_STATUS 457 DtCompileMsct ( 458 void **List) 459 { 460 ACPI_STATUS Status; 461 462 463 Status = DtCompileTwoSubtables (List, 464 AcpiDmTableInfoMsct, AcpiDmTableInfoMsct0); 465 return (Status); 466 } 467 468 469 /****************************************************************************** 470 * 471 * FUNCTION: DtCompileMtmr 472 * 473 * PARAMETERS: List - Current field list pointer 474 * 475 * RETURN: Status 476 * 477 * DESCRIPTION: Compile MTMR. 478 * 479 *****************************************************************************/ 480 481 ACPI_STATUS 482 DtCompileMtmr ( 483 void **List) 484 { 485 ACPI_STATUS Status; 486 487 488 Status = DtCompileTwoSubtables (List, 489 AcpiDmTableInfoMtmr, AcpiDmTableInfoMtmr0); 490 return (Status); 491 } 492 493 494 /****************************************************************************** 495 * 496 * FUNCTION: DtCompileNfit 497 * 498 * PARAMETERS: List - Current field list pointer 499 * 500 * RETURN: Status 501 * 502 * DESCRIPTION: Compile NFIT. 503 * 504 *****************************************************************************/ 505 506 ACPI_STATUS 507 DtCompileNfit ( 508 void **List) 509 { 510 ACPI_STATUS Status; 511 DT_SUBTABLE *Subtable; 512 DT_SUBTABLE *ParentTable; 513 DT_FIELD **PFieldList = (DT_FIELD **) List; 514 DT_FIELD *SubtableStart; 515 ACPI_NFIT_HEADER *NfitHeader; 516 ACPI_DMTABLE_INFO *InfoTable; 517 UINT32 Count; 518 ACPI_NFIT_INTERLEAVE *Interleave = NULL; 519 ACPI_NFIT_FLUSH_ADDRESS *Hint = NULL; 520 521 522 /* Main table */ 523 524 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit, 525 &Subtable); 526 if (ACPI_FAILURE (Status)) 527 { 528 return (Status); 529 } 530 531 ParentTable = DtPeekSubtable (); 532 DtInsertSubtable (ParentTable, Subtable); 533 DtPushSubtable (Subtable); 534 535 /* Subtables */ 536 537 while (*PFieldList) 538 { 539 SubtableStart = *PFieldList; 540 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfitHdr, 541 &Subtable); 542 if (ACPI_FAILURE (Status)) 543 { 544 return (Status); 545 } 546 547 ParentTable = DtPeekSubtable (); 548 DtInsertSubtable (ParentTable, Subtable); 549 DtPushSubtable (Subtable); 550 551 NfitHeader = ACPI_CAST_PTR (ACPI_NFIT_HEADER, Subtable->Buffer); 552 553 switch (NfitHeader->Type) 554 { 555 case ACPI_NFIT_TYPE_SYSTEM_ADDRESS: 556 557 InfoTable = AcpiDmTableInfoNfit0; 558 break; 559 560 case ACPI_NFIT_TYPE_MEMORY_MAP: 561 562 InfoTable = AcpiDmTableInfoNfit1; 563 break; 564 565 case ACPI_NFIT_TYPE_INTERLEAVE: 566 567 Interleave = ACPI_CAST_PTR (ACPI_NFIT_INTERLEAVE, Subtable->Buffer); 568 InfoTable = AcpiDmTableInfoNfit2; 569 break; 570 571 case ACPI_NFIT_TYPE_SMBIOS: 572 573 InfoTable = AcpiDmTableInfoNfit3; 574 break; 575 576 case ACPI_NFIT_TYPE_CONTROL_REGION: 577 578 InfoTable = AcpiDmTableInfoNfit4; 579 break; 580 581 case ACPI_NFIT_TYPE_DATA_REGION: 582 583 InfoTable = AcpiDmTableInfoNfit5; 584 break; 585 586 case ACPI_NFIT_TYPE_FLUSH_ADDRESS: 587 588 Hint = ACPI_CAST_PTR (ACPI_NFIT_FLUSH_ADDRESS, Subtable->Buffer); 589 InfoTable = AcpiDmTableInfoNfit6; 590 break; 591 592 case ACPI_NFIT_TYPE_CAPABILITIES: 593 594 InfoTable = AcpiDmTableInfoNfit7; 595 break; 596 597 default: 598 599 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "NFIT"); 600 return (AE_ERROR); 601 } 602 603 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 604 if (ACPI_FAILURE (Status)) 605 { 606 return (Status); 607 } 608 609 ParentTable = DtPeekSubtable (); 610 DtInsertSubtable (ParentTable, Subtable); 611 DtPopSubtable (); 612 613 switch (NfitHeader->Type) 614 { 615 case ACPI_NFIT_TYPE_INTERLEAVE: 616 617 Count = 0; 618 DtPushSubtable (Subtable); 619 while (*PFieldList) 620 { 621 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit2a, 622 &Subtable); 623 if (ACPI_FAILURE (Status)) 624 { 625 return (Status); 626 } 627 628 if (!Subtable) 629 { 630 DtPopSubtable (); 631 break; 632 } 633 634 ParentTable = DtPeekSubtable (); 635 DtInsertSubtable (ParentTable, Subtable); 636 Count++; 637 } 638 639 Interleave->LineCount = Count; 640 break; 641 642 case ACPI_NFIT_TYPE_SMBIOS: 643 644 if (*PFieldList) 645 { 646 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit3a, 647 &Subtable); 648 if (ACPI_FAILURE (Status)) 649 { 650 return (Status); 651 } 652 653 if (Subtable) 654 { 655 DtInsertSubtable (ParentTable, Subtable); 656 } 657 } 658 break; 659 660 case ACPI_NFIT_TYPE_FLUSH_ADDRESS: 661 662 Count = 0; 663 DtPushSubtable (Subtable); 664 while (*PFieldList) 665 { 666 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit6a, 667 &Subtable); 668 if (ACPI_FAILURE (Status)) 669 { 670 return (Status); 671 } 672 673 if (!Subtable) 674 { 675 DtPopSubtable (); 676 break; 677 } 678 679 ParentTable = DtPeekSubtable (); 680 DtInsertSubtable (ParentTable, Subtable); 681 Count++; 682 } 683 684 Hint->HintCount = (UINT16) Count; 685 break; 686 687 default: 688 break; 689 } 690 } 691 692 return (AE_OK); 693 } 694 695 696 /****************************************************************************** 697 * 698 * FUNCTION: DtCompilePcct 699 * 700 * PARAMETERS: List - Current field list pointer 701 * 702 * RETURN: Status 703 * 704 * DESCRIPTION: Compile PCCT. 705 * 706 *****************************************************************************/ 707 708 ACPI_STATUS 709 DtCompilePcct ( 710 void **List) 711 { 712 ACPI_STATUS Status; 713 DT_SUBTABLE *Subtable; 714 DT_SUBTABLE *ParentTable; 715 DT_FIELD **PFieldList = (DT_FIELD **) List; 716 DT_FIELD *SubtableStart; 717 ACPI_SUBTABLE_HEADER *PcctHeader; 718 ACPI_DMTABLE_INFO *InfoTable; 719 720 721 /* Main table */ 722 723 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcct, 724 &Subtable); 725 if (ACPI_FAILURE (Status)) 726 { 727 return (Status); 728 } 729 730 ParentTable = DtPeekSubtable (); 731 DtInsertSubtable (ParentTable, Subtable); 732 733 /* Subtables */ 734 735 while (*PFieldList) 736 { 737 SubtableStart = *PFieldList; 738 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcctHdr, 739 &Subtable); 740 if (ACPI_FAILURE (Status)) 741 { 742 return (Status); 743 } 744 745 ParentTable = DtPeekSubtable (); 746 DtInsertSubtable (ParentTable, Subtable); 747 DtPushSubtable (Subtable); 748 749 PcctHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); 750 751 switch (PcctHeader->Type) 752 { 753 case ACPI_PCCT_TYPE_GENERIC_SUBSPACE: 754 755 InfoTable = AcpiDmTableInfoPcct0; 756 break; 757 758 case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE: 759 760 InfoTable = AcpiDmTableInfoPcct1; 761 break; 762 763 case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2: 764 765 InfoTable = AcpiDmTableInfoPcct2; 766 break; 767 768 case ACPI_PCCT_TYPE_EXT_PCC_MASTER_SUBSPACE: 769 770 InfoTable = AcpiDmTableInfoPcct3; 771 break; 772 773 case ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE: 774 775 InfoTable = AcpiDmTableInfoPcct4; 776 break; 777 778 default: 779 780 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PCCT"); 781 return (AE_ERROR); 782 } 783 784 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 785 if (ACPI_FAILURE (Status)) 786 { 787 return (Status); 788 } 789 790 ParentTable = DtPeekSubtable (); 791 DtInsertSubtable (ParentTable, Subtable); 792 DtPopSubtable (); 793 } 794 795 return (AE_OK); 796 } 797 798 799 /****************************************************************************** 800 * 801 * FUNCTION: DtCompilePdtt 802 * 803 * PARAMETERS: List - Current field list pointer 804 * 805 * RETURN: Status 806 * 807 * DESCRIPTION: Compile PDTT. 808 * 809 *****************************************************************************/ 810 811 ACPI_STATUS 812 DtCompilePdtt ( 813 void **List) 814 { 815 ACPI_STATUS Status; 816 DT_SUBTABLE *Subtable; 817 DT_SUBTABLE *ParentTable; 818 DT_FIELD **PFieldList = (DT_FIELD **) List; 819 ACPI_TABLE_PDTT *PdttHeader; 820 UINT32 Count = 0; 821 822 823 /* Main table */ 824 825 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPdtt, &Subtable); 826 if (ACPI_FAILURE (Status)) 827 { 828 return (Status); 829 } 830 831 ParentTable = DtPeekSubtable (); 832 DtInsertSubtable (ParentTable, Subtable); 833 834 PdttHeader = ACPI_CAST_PTR (ACPI_TABLE_PDTT, ParentTable->Buffer); 835 PdttHeader->ArrayOffset = sizeof (ACPI_TABLE_PDTT); 836 837 /* There is only one type of subtable at this time, no need to decode */ 838 839 while (*PFieldList) 840 { 841 /* List of subchannel IDs, each 2 bytes */ 842 843 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPdtt0, 844 &Subtable); 845 if (ACPI_FAILURE (Status)) 846 { 847 return (Status); 848 } 849 850 DtInsertSubtable (ParentTable, Subtable); 851 Count++; 852 } 853 854 PdttHeader->TriggerCount = (UINT8) Count; 855 return (AE_OK); 856 } 857 858 859 /****************************************************************************** 860 * 861 * FUNCTION: DtCompilePmtt 862 * 863 * PARAMETERS: List - Current field list pointer 864 * 865 * RETURN: Status 866 * 867 * DESCRIPTION: Compile PMTT. 868 * 869 *****************************************************************************/ 870 871 ACPI_STATUS 872 DtCompilePmtt ( 873 void **List) 874 { 875 ACPI_STATUS Status; 876 DT_SUBTABLE *Subtable; 877 DT_SUBTABLE *ParentTable; 878 DT_FIELD **PFieldList = (DT_FIELD **) List; 879 DT_FIELD *SubtableStart; 880 ACPI_PMTT_HEADER *PmttHeader; 881 ACPI_PMTT_CONTROLLER *PmttController; 882 UINT16 DomainCount; 883 UINT8 PrevType = ACPI_PMTT_TYPE_SOCKET; 884 885 886 /* Main table */ 887 888 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt, &Subtable); 889 if (ACPI_FAILURE (Status)) 890 { 891 return (Status); 892 } 893 894 ParentTable = DtPeekSubtable (); 895 DtInsertSubtable (ParentTable, Subtable); 896 DtPushSubtable (Subtable); 897 898 while (*PFieldList) 899 { 900 SubtableStart = *PFieldList; 901 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmttHdr, 902 &Subtable); 903 if (ACPI_FAILURE (Status)) 904 { 905 return (Status); 906 } 907 908 PmttHeader = ACPI_CAST_PTR (ACPI_PMTT_HEADER, Subtable->Buffer); 909 while (PrevType >= PmttHeader->Type) 910 { 911 DtPopSubtable (); 912 913 if (PrevType == ACPI_PMTT_TYPE_SOCKET) 914 { 915 break; 916 } 917 918 PrevType--; 919 } 920 921 PrevType = PmttHeader->Type; 922 923 ParentTable = DtPeekSubtable (); 924 DtInsertSubtable (ParentTable, Subtable); 925 DtPushSubtable (Subtable); 926 927 switch (PmttHeader->Type) 928 { 929 case ACPI_PMTT_TYPE_SOCKET: 930 931 /* Subtable: Socket Structure */ 932 933 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt0, 934 &Subtable); 935 if (ACPI_FAILURE (Status)) 936 { 937 return (Status); 938 } 939 940 ParentTable = DtPeekSubtable (); 941 DtInsertSubtable (ParentTable, Subtable); 942 break; 943 944 case ACPI_PMTT_TYPE_CONTROLLER: 945 946 /* Subtable: Memory Controller Structure */ 947 948 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1, 949 &Subtable); 950 if (ACPI_FAILURE (Status)) 951 { 952 return (Status); 953 } 954 955 ParentTable = DtPeekSubtable (); 956 DtInsertSubtable (ParentTable, Subtable); 957 958 PmttController = ACPI_CAST_PTR (ACPI_PMTT_CONTROLLER, 959 (Subtable->Buffer - sizeof (ACPI_PMTT_HEADER))); 960 DomainCount = PmttController->DomainCount; 961 962 while (DomainCount) 963 { 964 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1a, 965 &Subtable); 966 if (ACPI_FAILURE (Status)) 967 { 968 return (Status); 969 } 970 971 DtInsertSubtable (ParentTable, Subtable); 972 DomainCount--; 973 } 974 break; 975 976 case ACPI_PMTT_TYPE_DIMM: 977 978 /* Subtable: Physical Component Structure */ 979 980 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt2, 981 &Subtable); 982 if (ACPI_FAILURE (Status)) 983 { 984 return (Status); 985 } 986 987 ParentTable = DtPeekSubtable (); 988 DtInsertSubtable (ParentTable, Subtable); 989 break; 990 991 default: 992 993 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PMTT"); 994 return (AE_ERROR); 995 } 996 } 997 998 return (Status); 999 } 1000 1001 1002 /****************************************************************************** 1003 * 1004 * FUNCTION: DtCompilePptt 1005 * 1006 * PARAMETERS: List - Current field list pointer 1007 * 1008 * RETURN: Status 1009 * 1010 * DESCRIPTION: Compile PPTT. 1011 * 1012 *****************************************************************************/ 1013 1014 ACPI_STATUS 1015 DtCompilePptt ( 1016 void **List) 1017 { 1018 ACPI_STATUS Status; 1019 ACPI_SUBTABLE_HEADER *PpttHeader; 1020 ACPI_PPTT_PROCESSOR *PpttProcessor = NULL; 1021 DT_SUBTABLE *Subtable; 1022 DT_SUBTABLE *ParentTable; 1023 ACPI_DMTABLE_INFO *InfoTable; 1024 DT_FIELD **PFieldList = (DT_FIELD **) List; 1025 DT_FIELD *SubtableStart; 1026 1027 1028 ParentTable = DtPeekSubtable (); 1029 while (*PFieldList) 1030 { 1031 SubtableStart = *PFieldList; 1032 1033 /* Compile PPTT subtable header */ 1034 1035 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPpttHdr, 1036 &Subtable); 1037 if (ACPI_FAILURE (Status)) 1038 { 1039 return (Status); 1040 } 1041 DtInsertSubtable (ParentTable, Subtable); 1042 PpttHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); 1043 PpttHeader->Length = (UINT8)(Subtable->Length); 1044 1045 switch (PpttHeader->Type) 1046 { 1047 case ACPI_PPTT_TYPE_PROCESSOR: 1048 1049 InfoTable = AcpiDmTableInfoPptt0; 1050 break; 1051 1052 case ACPI_PPTT_TYPE_CACHE: 1053 1054 InfoTable = AcpiDmTableInfoPptt1; 1055 break; 1056 1057 case ACPI_PPTT_TYPE_ID: 1058 1059 InfoTable = AcpiDmTableInfoPptt2; 1060 break; 1061 1062 default: 1063 1064 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PPTT"); 1065 return (AE_ERROR); 1066 } 1067 1068 /* Compile PPTT subtable body */ 1069 1070 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 1071 if (ACPI_FAILURE (Status)) 1072 { 1073 return (Status); 1074 } 1075 DtInsertSubtable (ParentTable, Subtable); 1076 PpttHeader->Length += (UINT8)(Subtable->Length); 1077 1078 /* Compile PPTT subtable additionals */ 1079 1080 switch (PpttHeader->Type) 1081 { 1082 case ACPI_PPTT_TYPE_PROCESSOR: 1083 1084 PpttProcessor = ACPI_SUB_PTR (ACPI_PPTT_PROCESSOR, 1085 Subtable->Buffer, sizeof (ACPI_SUBTABLE_HEADER)); 1086 if (PpttProcessor) 1087 { 1088 /* Compile initiator proximity domain list */ 1089 1090 PpttProcessor->NumberOfPrivResources = 0; 1091 while (*PFieldList) 1092 { 1093 Status = DtCompileTable (PFieldList, 1094 AcpiDmTableInfoPptt0a, &Subtable); 1095 if (ACPI_FAILURE (Status)) 1096 { 1097 return (Status); 1098 } 1099 if (!Subtable) 1100 { 1101 break; 1102 } 1103 1104 DtInsertSubtable (ParentTable, Subtable); 1105 PpttHeader->Length += (UINT8)(Subtable->Length); 1106 PpttProcessor->NumberOfPrivResources++; 1107 } 1108 } 1109 break; 1110 1111 default: 1112 1113 break; 1114 } 1115 } 1116 1117 return (AE_OK); 1118 } 1119 1120 1121 /****************************************************************************** 1122 * 1123 * FUNCTION: DtCompileRsdt 1124 * 1125 * PARAMETERS: List - Current field list pointer 1126 * 1127 * RETURN: Status 1128 * 1129 * DESCRIPTION: Compile RSDT. 1130 * 1131 *****************************************************************************/ 1132 1133 ACPI_STATUS 1134 DtCompileRsdt ( 1135 void **List) 1136 { 1137 DT_SUBTABLE *Subtable; 1138 DT_SUBTABLE *ParentTable; 1139 DT_FIELD *FieldList = *(DT_FIELD **) List; 1140 UINT32 Address; 1141 1142 1143 ParentTable = DtPeekSubtable (); 1144 1145 while (FieldList) 1146 { 1147 DtCompileInteger ((UINT8 *) &Address, FieldList, 4, DT_NON_ZERO); 1148 1149 DtCreateSubtable ((UINT8 *) &Address, 4, &Subtable); 1150 DtInsertSubtable (ParentTable, Subtable); 1151 FieldList = FieldList->Next; 1152 } 1153 1154 return (AE_OK); 1155 } 1156 1157 1158 /****************************************************************************** 1159 * 1160 * FUNCTION: DtCompileS3pt 1161 * 1162 * PARAMETERS: PFieldList - Current field list pointer 1163 * 1164 * RETURN: Status 1165 * 1166 * DESCRIPTION: Compile S3PT (Pointed to by FPDT) 1167 * 1168 *****************************************************************************/ 1169 1170 ACPI_STATUS 1171 DtCompileS3pt ( 1172 DT_FIELD **PFieldList) 1173 { 1174 ACPI_STATUS Status; 1175 ACPI_FPDT_HEADER *S3ptHeader; 1176 DT_SUBTABLE *Subtable; 1177 DT_SUBTABLE *ParentTable; 1178 ACPI_DMTABLE_INFO *InfoTable; 1179 DT_FIELD *SubtableStart; 1180 1181 1182 Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3pt, 1183 &AslGbl_RootTable); 1184 if (ACPI_FAILURE (Status)) 1185 { 1186 return (Status); 1187 } 1188 1189 DtPushSubtable (AslGbl_RootTable); 1190 1191 while (*PFieldList) 1192 { 1193 SubtableStart = *PFieldList; 1194 Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3ptHdr, 1195 &Subtable); 1196 if (ACPI_FAILURE (Status)) 1197 { 1198 return (Status); 1199 } 1200 1201 ParentTable = DtPeekSubtable (); 1202 DtInsertSubtable (ParentTable, Subtable); 1203 DtPushSubtable (Subtable); 1204 1205 S3ptHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer); 1206 1207 switch (S3ptHeader->Type) 1208 { 1209 case ACPI_S3PT_TYPE_RESUME: 1210 1211 InfoTable = AcpiDmTableInfoS3pt0; 1212 break; 1213 1214 case ACPI_S3PT_TYPE_SUSPEND: 1215 1216 InfoTable = AcpiDmTableInfoS3pt1; 1217 break; 1218 1219 default: 1220 1221 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "S3PT"); 1222 return (AE_ERROR); 1223 } 1224 1225 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 1226 if (ACPI_FAILURE (Status)) 1227 { 1228 return (Status); 1229 } 1230 1231 ParentTable = DtPeekSubtable (); 1232 DtInsertSubtable (ParentTable, Subtable); 1233 DtPopSubtable (); 1234 } 1235 1236 return (AE_OK); 1237 } 1238 1239 1240 /****************************************************************************** 1241 * 1242 * FUNCTION: DtCompileSdev 1243 * 1244 * PARAMETERS: List - Current field list pointer 1245 * 1246 * RETURN: Status 1247 * 1248 * DESCRIPTION: Compile SDEV. 1249 * 1250 *****************************************************************************/ 1251 1252 ACPI_STATUS 1253 DtCompileSdev ( 1254 void **List) 1255 { 1256 ACPI_STATUS Status; 1257 ACPI_SDEV_HEADER *SdevHeader; 1258 DT_SUBTABLE *Subtable; 1259 DT_SUBTABLE *ParentTable; 1260 ACPI_DMTABLE_INFO *InfoTable; 1261 DT_FIELD **PFieldList = (DT_FIELD **) List; 1262 DT_FIELD *SubtableStart; 1263 ACPI_SDEV_PCIE *Pcie = NULL; 1264 ACPI_SDEV_NAMESPACE *Namesp = NULL; 1265 UINT32 EntryCount; 1266 1267 1268 /* Subtables */ 1269 1270 while (*PFieldList) 1271 { 1272 /* Compile common SDEV subtable header */ 1273 1274 SubtableStart = *PFieldList; 1275 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdevHdr, 1276 &Subtable); 1277 if (ACPI_FAILURE (Status)) 1278 { 1279 return (Status); 1280 } 1281 1282 ParentTable = DtPeekSubtable (); 1283 DtInsertSubtable (ParentTable, Subtable); 1284 DtPushSubtable (Subtable); 1285 1286 SdevHeader = ACPI_CAST_PTR (ACPI_SDEV_HEADER, Subtable->Buffer); 1287 SdevHeader->Length = (UINT8)(sizeof (ACPI_SDEV_HEADER)); 1288 1289 switch (SdevHeader->Type) 1290 { 1291 case ACPI_SDEV_TYPE_NAMESPACE_DEVICE: 1292 1293 InfoTable = AcpiDmTableInfoSdev0; 1294 Namesp = ACPI_CAST_PTR (ACPI_SDEV_NAMESPACE, Subtable->Buffer); 1295 break; 1296 1297 case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE: 1298 1299 InfoTable = AcpiDmTableInfoSdev1; 1300 Pcie = ACPI_CAST_PTR (ACPI_SDEV_PCIE, Subtable->Buffer); 1301 break; 1302 1303 default: 1304 1305 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SDEV"); 1306 return (AE_ERROR); 1307 } 1308 1309 /* Compile SDEV subtable body */ 1310 1311 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 1312 if (ACPI_FAILURE (Status)) 1313 { 1314 return (Status); 1315 } 1316 1317 ParentTable = DtPeekSubtable (); 1318 DtInsertSubtable (ParentTable, Subtable); 1319 1320 /* Optional data fields are appended to the main subtable body */ 1321 1322 switch (SdevHeader->Type) 1323 { 1324 case ACPI_SDEV_TYPE_NAMESPACE_DEVICE: 1325 1326 /* Append DeviceId namespace string */ 1327 1328 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev0a, 1329 &Subtable); 1330 if (ACPI_FAILURE (Status)) 1331 { 1332 return (Status); 1333 } 1334 1335 if (!Subtable) 1336 { 1337 break; 1338 } 1339 1340 ParentTable = DtPeekSubtable (); 1341 DtInsertSubtable (ParentTable, Subtable); 1342 1343 Namesp->DeviceIdOffset = sizeof (ACPI_SDEV_NAMESPACE); 1344 Namesp->DeviceIdLength = (UINT16) Subtable->Length; 1345 1346 /* Append Vendor data */ 1347 1348 Namesp->VendorDataLength = 0; 1349 Namesp->VendorDataOffset = 0; 1350 1351 if (*PFieldList) 1352 { 1353 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1b, 1354 &Subtable); 1355 if (ACPI_FAILURE (Status)) 1356 { 1357 return (Status); 1358 } 1359 1360 if (Subtable) 1361 { 1362 ParentTable = DtPeekSubtable (); 1363 DtInsertSubtable (ParentTable, Subtable); 1364 1365 Namesp->VendorDataOffset = 1366 Namesp->DeviceIdOffset + Namesp->DeviceIdLength; 1367 Namesp->VendorDataLength = 1368 (UINT16) Subtable->Length; 1369 } 1370 } 1371 1372 /* Final size of entire namespace structure */ 1373 1374 SdevHeader->Length = (UINT16) (sizeof (ACPI_SDEV_NAMESPACE) + 1375 Subtable->Length + Namesp->DeviceIdLength); 1376 break; 1377 1378 case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE: 1379 1380 /* Append the PCIe path info first */ 1381 1382 EntryCount = 0; 1383 while (*PFieldList && !strcmp ((*PFieldList)->Name, "Device")) 1384 { 1385 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1a, 1386 &Subtable); 1387 if (ACPI_FAILURE (Status)) 1388 { 1389 return (Status); 1390 } 1391 1392 if (!Subtable) 1393 { 1394 DtPopSubtable (); 1395 break; 1396 } 1397 1398 ParentTable = DtPeekSubtable (); 1399 DtInsertSubtable (ParentTable, Subtable); 1400 EntryCount++; 1401 } 1402 1403 /* Path offset will point immediately after the main subtable */ 1404 1405 Pcie->PathOffset = sizeof (ACPI_SDEV_PCIE); 1406 Pcie->PathLength = (UINT16) 1407 (EntryCount * sizeof (ACPI_SDEV_PCIE_PATH)); 1408 1409 /* Append the Vendor Data last */ 1410 1411 Pcie->VendorDataLength = 0; 1412 Pcie->VendorDataOffset = 0; 1413 1414 if (*PFieldList) 1415 { 1416 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1b, 1417 &Subtable); 1418 if (ACPI_FAILURE (Status)) 1419 { 1420 return (Status); 1421 } 1422 1423 if (Subtable) 1424 { 1425 ParentTable = DtPeekSubtable (); 1426 DtInsertSubtable (ParentTable, Subtable); 1427 1428 Pcie->VendorDataOffset = 1429 Pcie->PathOffset + Pcie->PathLength; 1430 Pcie->VendorDataLength = (UINT16) 1431 Subtable->Length; 1432 } 1433 } 1434 1435 SdevHeader->Length = 1436 sizeof (ACPI_SDEV_PCIE) + 1437 Pcie->PathLength + Pcie->VendorDataLength; 1438 break; 1439 1440 default: 1441 1442 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SDEV"); 1443 return (AE_ERROR); 1444 } 1445 1446 DtPopSubtable (); 1447 } 1448 1449 return (AE_OK); 1450 } 1451 1452 1453 /****************************************************************************** 1454 * 1455 * FUNCTION: DtCompileSlic 1456 * 1457 * PARAMETERS: List - Current field list pointer 1458 * 1459 * RETURN: Status 1460 * 1461 * DESCRIPTION: Compile SLIC. 1462 * 1463 *****************************************************************************/ 1464 1465 ACPI_STATUS 1466 DtCompileSlic ( 1467 void **List) 1468 { 1469 ACPI_STATUS Status; 1470 DT_SUBTABLE *Subtable; 1471 DT_SUBTABLE *ParentTable; 1472 DT_FIELD **PFieldList = (DT_FIELD **) List; 1473 1474 1475 while (*PFieldList) 1476 { 1477 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlic, 1478 &Subtable); 1479 if (ACPI_FAILURE (Status)) 1480 { 1481 return (Status); 1482 } 1483 1484 ParentTable = DtPeekSubtable (); 1485 DtInsertSubtable (ParentTable, Subtable); 1486 DtPushSubtable (Subtable); 1487 DtPopSubtable (); 1488 } 1489 1490 return (AE_OK); 1491 } 1492 1493 1494 /****************************************************************************** 1495 * 1496 * FUNCTION: DtCompileSlit 1497 * 1498 * PARAMETERS: List - Current field list pointer 1499 * 1500 * RETURN: Status 1501 * 1502 * DESCRIPTION: Compile SLIT. 1503 * 1504 *****************************************************************************/ 1505 1506 ACPI_STATUS 1507 DtCompileSlit ( 1508 void **List) 1509 { 1510 ACPI_STATUS Status; 1511 DT_SUBTABLE *Subtable; 1512 DT_SUBTABLE *ParentTable; 1513 DT_FIELD **PFieldList = (DT_FIELD **) List; 1514 DT_FIELD *FieldList; 1515 UINT32 Localities; 1516 UINT8 *LocalityBuffer; 1517 1518 1519 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlit, 1520 &Subtable); 1521 if (ACPI_FAILURE (Status)) 1522 { 1523 return (Status); 1524 } 1525 1526 ParentTable = DtPeekSubtable (); 1527 DtInsertSubtable (ParentTable, Subtable); 1528 1529 Localities = *ACPI_CAST_PTR (UINT32, Subtable->Buffer); 1530 LocalityBuffer = UtLocalCalloc (Localities); 1531 1532 /* Compile each locality buffer */ 1533 1534 FieldList = *PFieldList; 1535 while (FieldList) 1536 { 1537 DtCompileBuffer (LocalityBuffer, 1538 FieldList->Value, FieldList, Localities); 1539 1540 DtCreateSubtable (LocalityBuffer, Localities, &Subtable); 1541 DtInsertSubtable (ParentTable, Subtable); 1542 FieldList = FieldList->Next; 1543 } 1544 1545 ACPI_FREE (LocalityBuffer); 1546 return (AE_OK); 1547 } 1548 1549 1550 /****************************************************************************** 1551 * 1552 * FUNCTION: DtCompileSrat 1553 * 1554 * PARAMETERS: List - Current field list pointer 1555 * 1556 * RETURN: Status 1557 * 1558 * DESCRIPTION: Compile SRAT. 1559 * 1560 *****************************************************************************/ 1561 1562 ACPI_STATUS 1563 DtCompileSrat ( 1564 void **List) 1565 { 1566 ACPI_STATUS Status; 1567 DT_SUBTABLE *Subtable; 1568 DT_SUBTABLE *ParentTable; 1569 DT_FIELD **PFieldList = (DT_FIELD **) List; 1570 DT_FIELD *SubtableStart; 1571 ACPI_SUBTABLE_HEADER *SratHeader; 1572 ACPI_DMTABLE_INFO *InfoTable; 1573 1574 1575 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSrat, 1576 &Subtable); 1577 if (ACPI_FAILURE (Status)) 1578 { 1579 return (Status); 1580 } 1581 1582 ParentTable = DtPeekSubtable (); 1583 DtInsertSubtable (ParentTable, Subtable); 1584 1585 while (*PFieldList) 1586 { 1587 SubtableStart = *PFieldList; 1588 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSratHdr, 1589 &Subtable); 1590 if (ACPI_FAILURE (Status)) 1591 { 1592 return (Status); 1593 } 1594 1595 ParentTable = DtPeekSubtable (); 1596 DtInsertSubtable (ParentTable, Subtable); 1597 DtPushSubtable (Subtable); 1598 1599 SratHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); 1600 1601 switch (SratHeader->Type) 1602 { 1603 case ACPI_SRAT_TYPE_CPU_AFFINITY: 1604 1605 InfoTable = AcpiDmTableInfoSrat0; 1606 break; 1607 1608 case ACPI_SRAT_TYPE_MEMORY_AFFINITY: 1609 1610 InfoTable = AcpiDmTableInfoSrat1; 1611 break; 1612 1613 case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY: 1614 1615 InfoTable = AcpiDmTableInfoSrat2; 1616 break; 1617 1618 case ACPI_SRAT_TYPE_GICC_AFFINITY: 1619 1620 InfoTable = AcpiDmTableInfoSrat3; 1621 break; 1622 1623 case ACPI_SRAT_TYPE_GIC_ITS_AFFINITY: 1624 1625 InfoTable = AcpiDmTableInfoSrat4; 1626 break; 1627 1628 case ACPI_SRAT_TYPE_GENERIC_AFFINITY: 1629 1630 InfoTable = AcpiDmTableInfoSrat5; 1631 break; 1632 1633 default: 1634 1635 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SRAT"); 1636 return (AE_ERROR); 1637 } 1638 1639 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 1640 if (ACPI_FAILURE (Status)) 1641 { 1642 return (Status); 1643 } 1644 1645 ParentTable = DtPeekSubtable (); 1646 DtInsertSubtable (ParentTable, Subtable); 1647 DtPopSubtable (); 1648 } 1649 1650 return (AE_OK); 1651 } 1652 1653 1654 /****************************************************************************** 1655 * 1656 * FUNCTION: DtCompileStao 1657 * 1658 * PARAMETERS: PFieldList - Current field list pointer 1659 * 1660 * RETURN: Status 1661 * 1662 * DESCRIPTION: Compile STAO. 1663 * 1664 *****************************************************************************/ 1665 1666 ACPI_STATUS 1667 DtCompileStao ( 1668 void **List) 1669 { 1670 DT_FIELD **PFieldList = (DT_FIELD **) List; 1671 DT_SUBTABLE *Subtable; 1672 DT_SUBTABLE *ParentTable; 1673 ACPI_STATUS Status; 1674 1675 1676 /* Compile the main table */ 1677 1678 Status = DtCompileTable (PFieldList, AcpiDmTableInfoStao, 1679 &Subtable); 1680 if (ACPI_FAILURE (Status)) 1681 { 1682 return (Status); 1683 } 1684 1685 ParentTable = DtPeekSubtable (); 1686 DtInsertSubtable (ParentTable, Subtable); 1687 1688 /* Compile each ASCII namestring as a subtable */ 1689 1690 while (*PFieldList) 1691 { 1692 Status = DtCompileTable (PFieldList, AcpiDmTableInfoStaoStr, 1693 &Subtable); 1694 if (ACPI_FAILURE (Status)) 1695 { 1696 return (Status); 1697 } 1698 1699 ParentTable = DtPeekSubtable (); 1700 DtInsertSubtable (ParentTable, Subtable); 1701 } 1702 1703 return (AE_OK); 1704 } 1705 1706 1707 /****************************************************************************** 1708 * 1709 * FUNCTION: DtCompileTcpa 1710 * 1711 * PARAMETERS: PFieldList - Current field list pointer 1712 * 1713 * RETURN: Status 1714 * 1715 * DESCRIPTION: Compile TCPA. 1716 * 1717 *****************************************************************************/ 1718 1719 ACPI_STATUS 1720 DtCompileTcpa ( 1721 void **List) 1722 { 1723 DT_FIELD **PFieldList = (DT_FIELD **) List; 1724 DT_SUBTABLE *Subtable; 1725 ACPI_TABLE_TCPA_HDR *TcpaHeader; 1726 DT_SUBTABLE *ParentTable; 1727 ACPI_STATUS Status; 1728 1729 1730 /* Compile the main table */ 1731 1732 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaHdr, 1733 &Subtable); 1734 if (ACPI_FAILURE (Status)) 1735 { 1736 return (Status); 1737 } 1738 1739 ParentTable = DtPeekSubtable (); 1740 DtInsertSubtable (ParentTable, Subtable); 1741 1742 /* 1743 * Examine the PlatformClass field to determine the table type. 1744 * Either a client or server table. Only one. 1745 */ 1746 TcpaHeader = ACPI_CAST_PTR (ACPI_TABLE_TCPA_HDR, ParentTable->Buffer); 1747 1748 switch (TcpaHeader->PlatformClass) 1749 { 1750 case ACPI_TCPA_CLIENT_TABLE: 1751 1752 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaClient, 1753 &Subtable); 1754 break; 1755 1756 case ACPI_TCPA_SERVER_TABLE: 1757 1758 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaServer, 1759 &Subtable); 1760 break; 1761 1762 default: 1763 1764 AcpiOsPrintf ("\n**** Unknown TCPA Platform Class 0x%X\n", 1765 TcpaHeader->PlatformClass); 1766 Status = AE_ERROR; 1767 break; 1768 } 1769 1770 ParentTable = DtPeekSubtable (); 1771 DtInsertSubtable (ParentTable, Subtable); 1772 return (Status); 1773 } 1774 1775 1776 /****************************************************************************** 1777 * 1778 * FUNCTION: DtCompileTpm2Rev3 1779 * 1780 * PARAMETERS: PFieldList - Current field list pointer 1781 * 1782 * RETURN: Status 1783 * 1784 * DESCRIPTION: Compile TPM2 revision 3 1785 * 1786 *****************************************************************************/ 1787 static ACPI_STATUS 1788 DtCompileTpm2Rev3 ( 1789 void **List) 1790 { 1791 DT_FIELD **PFieldList = (DT_FIELD **) List; 1792 DT_SUBTABLE *Subtable; 1793 ACPI_TABLE_TPM23 *Tpm23Header; 1794 DT_SUBTABLE *ParentTable; 1795 ACPI_STATUS Status = AE_OK; 1796 1797 1798 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm23, 1799 &Subtable); 1800 1801 ParentTable = DtPeekSubtable (); 1802 DtInsertSubtable (ParentTable, Subtable); 1803 Tpm23Header = ACPI_CAST_PTR (ACPI_TABLE_TPM23, ParentTable->Buffer); 1804 1805 /* Subtable type depends on the StartMethod */ 1806 1807 switch (Tpm23Header->StartMethod) 1808 { 1809 case ACPI_TPM23_ACPI_START_METHOD: 1810 1811 /* Subtable specific to to ARM_SMC */ 1812 1813 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm23a, 1814 &Subtable); 1815 if (ACPI_FAILURE (Status)) 1816 { 1817 return (Status); 1818 } 1819 1820 ParentTable = DtPeekSubtable (); 1821 DtInsertSubtable (ParentTable, Subtable); 1822 break; 1823 1824 default: 1825 break; 1826 } 1827 1828 return (Status); 1829 } 1830 1831 1832 /****************************************************************************** 1833 * 1834 * FUNCTION: DtCompileTpm2 1835 * 1836 * PARAMETERS: PFieldList - Current field list pointer 1837 * 1838 * RETURN: Status 1839 * 1840 * DESCRIPTION: Compile TPM2. 1841 * 1842 *****************************************************************************/ 1843 1844 ACPI_STATUS 1845 DtCompileTpm2 ( 1846 void **List) 1847 { 1848 DT_FIELD **PFieldList = (DT_FIELD **) List; 1849 DT_SUBTABLE *Subtable; 1850 ACPI_TABLE_TPM2 *Tpm2Header; 1851 DT_SUBTABLE *ParentTable; 1852 ACPI_STATUS Status = AE_OK; 1853 ACPI_TABLE_HEADER *Header; 1854 1855 1856 ParentTable = DtPeekSubtable (); 1857 1858 Header = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer); 1859 1860 if (Header->Revision == 3) 1861 { 1862 return (DtCompileTpm2Rev3 (List)); 1863 } 1864 1865 /* Compile the main table */ 1866 1867 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm2, 1868 &Subtable); 1869 if (ACPI_FAILURE (Status)) 1870 { 1871 return (Status); 1872 } 1873 1874 ParentTable = DtPeekSubtable (); 1875 DtInsertSubtable (ParentTable, Subtable); 1876 1877 Tpm2Header = ACPI_CAST_PTR (ACPI_TABLE_TPM2, ParentTable->Buffer); 1878 1879 /* Method parameters */ 1880 /* Optional: Log area minimum length */ 1881 /* Optional: Log area start address */ 1882 /* TBD: Optional fields above not fully implemented (not optional at this time) */ 1883 1884 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm2a, 1885 &Subtable); 1886 if (ACPI_FAILURE (Status)) 1887 { 1888 return (Status); 1889 } 1890 1891 ParentTable = DtPeekSubtable (); 1892 DtInsertSubtable (ParentTable, Subtable); 1893 1894 1895 /* Subtable type depends on the StartMethod */ 1896 1897 switch (Tpm2Header->StartMethod) 1898 { 1899 case ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC: 1900 1901 /* Subtable specific to to ARM_SMC */ 1902 1903 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm211, 1904 &Subtable); 1905 if (ACPI_FAILURE (Status)) 1906 { 1907 return (Status); 1908 } 1909 1910 ParentTable = DtPeekSubtable (); 1911 DtInsertSubtable (ParentTable, Subtable); 1912 break; 1913 1914 case ACPI_TPM2_START_METHOD: 1915 case ACPI_TPM2_MEMORY_MAPPED: 1916 case ACPI_TPM2_COMMAND_BUFFER: 1917 case ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD: 1918 break; 1919 1920 case ACPI_TPM2_RESERVED1: 1921 case ACPI_TPM2_RESERVED3: 1922 case ACPI_TPM2_RESERVED4: 1923 case ACPI_TPM2_RESERVED5: 1924 case ACPI_TPM2_RESERVED9: 1925 case ACPI_TPM2_RESERVED10: 1926 1927 AcpiOsPrintf ("\n**** Reserved TPM2 Start Method type 0x%X\n", 1928 Tpm2Header->StartMethod); 1929 Status = AE_ERROR; 1930 break; 1931 1932 case ACPI_TPM2_NOT_ALLOWED: 1933 default: 1934 1935 AcpiOsPrintf ("\n**** Unknown TPM2 Start Method type 0x%X\n", 1936 Tpm2Header->StartMethod); 1937 Status = AE_ERROR; 1938 break; 1939 } 1940 1941 return (Status); 1942 } 1943 1944 1945 /****************************************************************************** 1946 * 1947 * FUNCTION: DtGetGenericTableInfo 1948 * 1949 * PARAMETERS: Name - Generic type name 1950 * 1951 * RETURN: Info entry 1952 * 1953 * DESCRIPTION: Obtain table info for a generic name entry 1954 * 1955 *****************************************************************************/ 1956 1957 ACPI_DMTABLE_INFO * 1958 DtGetGenericTableInfo ( 1959 char *Name) 1960 { 1961 ACPI_DMTABLE_INFO *Info; 1962 UINT32 i; 1963 1964 1965 if (!Name) 1966 { 1967 return (NULL); 1968 } 1969 1970 /* Search info table for name match */ 1971 1972 for (i = 0; ; i++) 1973 { 1974 Info = AcpiDmTableInfoGeneric[i]; 1975 if (Info->Opcode == ACPI_DMT_EXIT) 1976 { 1977 Info = NULL; 1978 break; 1979 } 1980 1981 /* Use caseless compare for generic keywords */ 1982 1983 if (!AcpiUtStricmp (Name, Info->Name)) 1984 { 1985 break; 1986 } 1987 } 1988 1989 return (Info); 1990 } 1991 1992 1993 /****************************************************************************** 1994 * 1995 * FUNCTION: DtCompileUefi 1996 * 1997 * PARAMETERS: List - Current field list pointer 1998 * 1999 * RETURN: Status 2000 * 2001 * DESCRIPTION: Compile UEFI. 2002 * 2003 *****************************************************************************/ 2004 2005 ACPI_STATUS 2006 DtCompileUefi ( 2007 void **List) 2008 { 2009 ACPI_STATUS Status; 2010 DT_SUBTABLE *Subtable; 2011 DT_SUBTABLE *ParentTable; 2012 DT_FIELD **PFieldList = (DT_FIELD **) List; 2013 UINT16 *DataOffset; 2014 2015 2016 /* Compile the predefined portion of the UEFI table */ 2017 2018 Status = DtCompileTable (PFieldList, AcpiDmTableInfoUefi, 2019 &Subtable); 2020 if (ACPI_FAILURE (Status)) 2021 { 2022 return (Status); 2023 } 2024 2025 DataOffset = (UINT16 *) (Subtable->Buffer + 16); 2026 *DataOffset = sizeof (ACPI_TABLE_UEFI); 2027 2028 ParentTable = DtPeekSubtable (); 2029 DtInsertSubtable (ParentTable, Subtable); 2030 2031 /* 2032 * Compile the "generic" portion of the UEFI table. This 2033 * part of the table is not predefined and any of the generic 2034 * operators may be used. 2035 */ 2036 DtCompileGeneric ((void **) PFieldList, NULL, NULL); 2037 return (AE_OK); 2038 } 2039 2040 2041 /****************************************************************************** 2042 * 2043 * FUNCTION: DtCompileVrtc 2044 * 2045 * PARAMETERS: List - Current field list pointer 2046 * 2047 * RETURN: Status 2048 * 2049 * DESCRIPTION: Compile VRTC. 2050 * 2051 *****************************************************************************/ 2052 2053 ACPI_STATUS 2054 DtCompileVrtc ( 2055 void **List) 2056 { 2057 ACPI_STATUS Status; 2058 2059 2060 Status = DtCompileTwoSubtables (List, 2061 AcpiDmTableInfoVrtc, AcpiDmTableInfoVrtc0); 2062 return (Status); 2063 } 2064 2065 2066 /****************************************************************************** 2067 * 2068 * FUNCTION: DtCompileWdat 2069 * 2070 * PARAMETERS: List - Current field list pointer 2071 * 2072 * RETURN: Status 2073 * 2074 * DESCRIPTION: Compile WDAT. 2075 * 2076 *****************************************************************************/ 2077 2078 ACPI_STATUS 2079 DtCompileWdat ( 2080 void **List) 2081 { 2082 ACPI_STATUS Status; 2083 2084 2085 Status = DtCompileTwoSubtables (List, 2086 AcpiDmTableInfoWdat, AcpiDmTableInfoWdat0); 2087 return (Status); 2088 } 2089 2090 2091 /****************************************************************************** 2092 * 2093 * FUNCTION: DtCompileWpbt 2094 * 2095 * PARAMETERS: List - Current field list pointer 2096 * 2097 * RETURN: Status 2098 * 2099 * DESCRIPTION: Compile WPBT. 2100 * 2101 *****************************************************************************/ 2102 2103 ACPI_STATUS 2104 DtCompileWpbt ( 2105 void **List) 2106 { 2107 DT_FIELD **PFieldList = (DT_FIELD **) List; 2108 DT_SUBTABLE *Subtable; 2109 DT_SUBTABLE *ParentTable; 2110 ACPI_TABLE_WPBT *Table; 2111 ACPI_STATUS Status; 2112 UINT16 Length; 2113 2114 2115 /* Compile the main table */ 2116 2117 Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt, 2118 &Subtable); 2119 if (ACPI_FAILURE (Status)) 2120 { 2121 return (Status); 2122 } 2123 2124 ParentTable = DtPeekSubtable (); 2125 DtInsertSubtable (ParentTable, Subtable); 2126 2127 /* Compile the argument list subtable */ 2128 2129 Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt0, 2130 &Subtable); 2131 if (ACPI_FAILURE (Status)) 2132 { 2133 return (Status); 2134 } 2135 2136 /* Extract the length of the Arguments buffer, insert into main table */ 2137 2138 Length = (UINT16) Subtable->TotalLength; 2139 Table = ACPI_CAST_PTR (ACPI_TABLE_WPBT, ParentTable->Buffer); 2140 Table->ArgumentsLength = Length; 2141 2142 ParentTable = DtPeekSubtable (); 2143 DtInsertSubtable (ParentTable, Subtable); 2144 return (AE_OK); 2145 } 2146 2147 2148 /****************************************************************************** 2149 * 2150 * FUNCTION: DtCompileXsdt 2151 * 2152 * PARAMETERS: List - Current field list pointer 2153 * 2154 * RETURN: Status 2155 * 2156 * DESCRIPTION: Compile XSDT. 2157 * 2158 *****************************************************************************/ 2159 2160 ACPI_STATUS 2161 DtCompileXsdt ( 2162 void **List) 2163 { 2164 DT_SUBTABLE *Subtable; 2165 DT_SUBTABLE *ParentTable; 2166 DT_FIELD *FieldList = *(DT_FIELD **) List; 2167 UINT64 Address; 2168 2169 2170 ParentTable = DtPeekSubtable (); 2171 2172 while (FieldList) 2173 { 2174 DtCompileInteger ((UINT8 *) &Address, FieldList, 8, DT_NON_ZERO); 2175 2176 DtCreateSubtable ((UINT8 *) &Address, 8, &Subtable); 2177 DtInsertSubtable (ParentTable, Subtable); 2178 FieldList = FieldList->Next; 2179 } 2180 2181 return (AE_OK); 2182 } 2183 2184 2185 /****************************************************************************** 2186 * 2187 * FUNCTION: DtCompileGeneric 2188 * 2189 * PARAMETERS: List - Current field list pointer 2190 * Name - Field name to end generic compiling 2191 * Length - Compiled table length to return 2192 * 2193 * RETURN: Status 2194 * 2195 * DESCRIPTION: Compile generic unknown table. 2196 * 2197 *****************************************************************************/ 2198 2199 ACPI_STATUS 2200 DtCompileGeneric ( 2201 void **List, 2202 char *Name, 2203 UINT32 *Length) 2204 { 2205 ACPI_STATUS Status; 2206 DT_SUBTABLE *Subtable; 2207 DT_SUBTABLE *ParentTable; 2208 DT_FIELD **PFieldList = (DT_FIELD **) List; 2209 ACPI_DMTABLE_INFO *Info; 2210 2211 2212 ParentTable = DtPeekSubtable (); 2213 2214 /* 2215 * Compile the "generic" portion of the table. This 2216 * part of the table is not predefined and any of the generic 2217 * operators may be used. 2218 */ 2219 2220 /* Find any and all labels in the entire generic portion */ 2221 2222 DtDetectAllLabels (*PFieldList); 2223 2224 /* Now we can actually compile the parse tree */ 2225 2226 if (Length && *Length) 2227 { 2228 *Length = 0; 2229 } 2230 while (*PFieldList) 2231 { 2232 if (Name && !strcmp ((*PFieldList)->Name, Name)) 2233 { 2234 break; 2235 } 2236 2237 Info = DtGetGenericTableInfo ((*PFieldList)->Name); 2238 if (!Info) 2239 { 2240 sprintf (AslGbl_MsgBuffer, "Generic data type \"%s\" not found", 2241 (*PFieldList)->Name); 2242 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME, 2243 (*PFieldList), AslGbl_MsgBuffer); 2244 2245 *PFieldList = (*PFieldList)->Next; 2246 continue; 2247 } 2248 2249 Status = DtCompileTable (PFieldList, Info, 2250 &Subtable); 2251 if (ACPI_SUCCESS (Status)) 2252 { 2253 DtInsertSubtable (ParentTable, Subtable); 2254 if (Length) 2255 { 2256 *Length += Subtable->Length; 2257 } 2258 } 2259 else 2260 { 2261 *PFieldList = (*PFieldList)->Next; 2262 2263 if (Status == AE_NOT_FOUND) 2264 { 2265 sprintf (AslGbl_MsgBuffer, "Generic data type \"%s\" not found", 2266 (*PFieldList)->Name); 2267 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME, 2268 (*PFieldList), AslGbl_MsgBuffer); 2269 } 2270 } 2271 } 2272 2273 return (AE_OK); 2274 } 2275