1 /****************************************************************************** 2 * 3 * Module Name: dttable2.c - handling for specific ACPI tables 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2020, 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 /* Final size of entire namespace structure */ 1371 1372 SdevHeader->Length = (UINT16)(sizeof(ACPI_SDEV_NAMESPACE) + 1373 Subtable->Length + Namesp->DeviceIdLength); 1374 } 1375 } 1376 1377 break; 1378 1379 case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE: 1380 1381 /* Append the PCIe path info first */ 1382 1383 EntryCount = 0; 1384 while (*PFieldList && !strcmp ((*PFieldList)->Name, "Device")) 1385 { 1386 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1a, 1387 &Subtable); 1388 if (ACPI_FAILURE (Status)) 1389 { 1390 return (Status); 1391 } 1392 1393 if (!Subtable) 1394 { 1395 DtPopSubtable (); 1396 break; 1397 } 1398 1399 ParentTable = DtPeekSubtable (); 1400 DtInsertSubtable (ParentTable, Subtable); 1401 EntryCount++; 1402 } 1403 1404 /* Path offset will point immediately after the main subtable */ 1405 1406 Pcie->PathOffset = sizeof (ACPI_SDEV_PCIE); 1407 Pcie->PathLength = (UINT16) 1408 (EntryCount * sizeof (ACPI_SDEV_PCIE_PATH)); 1409 1410 /* Append the Vendor Data last */ 1411 1412 Pcie->VendorDataLength = 0; 1413 Pcie->VendorDataOffset = 0; 1414 1415 if (*PFieldList) 1416 { 1417 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1b, 1418 &Subtable); 1419 if (ACPI_FAILURE (Status)) 1420 { 1421 return (Status); 1422 } 1423 1424 if (Subtable) 1425 { 1426 ParentTable = DtPeekSubtable (); 1427 DtInsertSubtable (ParentTable, Subtable); 1428 1429 Pcie->VendorDataOffset = 1430 Pcie->PathOffset + Pcie->PathLength; 1431 Pcie->VendorDataLength = (UINT16) 1432 Subtable->Length; 1433 } 1434 } 1435 1436 SdevHeader->Length = 1437 sizeof (ACPI_SDEV_PCIE) + 1438 Pcie->PathLength + Pcie->VendorDataLength; 1439 break; 1440 1441 default: 1442 1443 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SDEV"); 1444 return (AE_ERROR); 1445 } 1446 1447 DtPopSubtable (); 1448 } 1449 1450 return (AE_OK); 1451 } 1452 1453 1454 /****************************************************************************** 1455 * 1456 * FUNCTION: DtCompileSlic 1457 * 1458 * PARAMETERS: List - Current field list pointer 1459 * 1460 * RETURN: Status 1461 * 1462 * DESCRIPTION: Compile SLIC. 1463 * 1464 *****************************************************************************/ 1465 1466 ACPI_STATUS 1467 DtCompileSlic ( 1468 void **List) 1469 { 1470 ACPI_STATUS Status; 1471 DT_SUBTABLE *Subtable; 1472 DT_SUBTABLE *ParentTable; 1473 DT_FIELD **PFieldList = (DT_FIELD **) List; 1474 1475 1476 while (*PFieldList) 1477 { 1478 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlic, 1479 &Subtable); 1480 if (ACPI_FAILURE (Status)) 1481 { 1482 return (Status); 1483 } 1484 1485 ParentTable = DtPeekSubtable (); 1486 DtInsertSubtable (ParentTable, Subtable); 1487 DtPushSubtable (Subtable); 1488 DtPopSubtable (); 1489 } 1490 1491 return (AE_OK); 1492 } 1493 1494 1495 /****************************************************************************** 1496 * 1497 * FUNCTION: DtCompileSlit 1498 * 1499 * PARAMETERS: List - Current field list pointer 1500 * 1501 * RETURN: Status 1502 * 1503 * DESCRIPTION: Compile SLIT. 1504 * 1505 *****************************************************************************/ 1506 1507 ACPI_STATUS 1508 DtCompileSlit ( 1509 void **List) 1510 { 1511 ACPI_STATUS Status; 1512 DT_SUBTABLE *Subtable; 1513 DT_SUBTABLE *ParentTable; 1514 DT_FIELD **PFieldList = (DT_FIELD **) List; 1515 DT_FIELD *FieldList; 1516 DT_FIELD *EndOfFieldList = NULL; 1517 UINT32 Localities; 1518 UINT32 LocalityListLength; 1519 UINT8 *LocalityBuffer; 1520 1521 1522 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlit, 1523 &Subtable); 1524 if (ACPI_FAILURE (Status)) 1525 { 1526 return (Status); 1527 } 1528 1529 ParentTable = DtPeekSubtable (); 1530 DtInsertSubtable (ParentTable, Subtable); 1531 1532 Localities = *ACPI_CAST_PTR (UINT32, Subtable->Buffer); 1533 LocalityBuffer = UtLocalCalloc (Localities); 1534 LocalityListLength = 0; 1535 1536 /* Compile each locality buffer */ 1537 1538 FieldList = *PFieldList; 1539 while (FieldList) 1540 { 1541 DtCompileBuffer (LocalityBuffer, 1542 FieldList->Value, FieldList, Localities); 1543 1544 LocalityListLength++; 1545 DtCreateSubtable (LocalityBuffer, Localities, &Subtable); 1546 DtInsertSubtable (ParentTable, Subtable); 1547 EndOfFieldList = FieldList; 1548 FieldList = FieldList->Next; 1549 } 1550 1551 if (LocalityListLength != Localities) 1552 { 1553 sprintf(AslGbl_MsgBuffer, 1554 "Found %u entries, must match LocalityCount: %u", 1555 LocalityListLength, Localities); 1556 DtError (ASL_ERROR, ASL_MSG_ENTRY_LIST, EndOfFieldList, AslGbl_MsgBuffer); 1557 ACPI_FREE (LocalityBuffer); 1558 return (AE_LIMIT); 1559 } 1560 1561 ACPI_FREE (LocalityBuffer); 1562 return (AE_OK); 1563 } 1564 1565 1566 /****************************************************************************** 1567 * 1568 * FUNCTION: DtCompileSrat 1569 * 1570 * PARAMETERS: List - Current field list pointer 1571 * 1572 * RETURN: Status 1573 * 1574 * DESCRIPTION: Compile SRAT. 1575 * 1576 *****************************************************************************/ 1577 1578 ACPI_STATUS 1579 DtCompileSrat ( 1580 void **List) 1581 { 1582 ACPI_STATUS Status; 1583 DT_SUBTABLE *Subtable; 1584 DT_SUBTABLE *ParentTable; 1585 DT_FIELD **PFieldList = (DT_FIELD **) List; 1586 DT_FIELD *SubtableStart; 1587 ACPI_SUBTABLE_HEADER *SratHeader; 1588 ACPI_DMTABLE_INFO *InfoTable; 1589 1590 1591 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSrat, 1592 &Subtable); 1593 if (ACPI_FAILURE (Status)) 1594 { 1595 return (Status); 1596 } 1597 1598 ParentTable = DtPeekSubtable (); 1599 DtInsertSubtable (ParentTable, Subtable); 1600 1601 while (*PFieldList) 1602 { 1603 SubtableStart = *PFieldList; 1604 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSratHdr, 1605 &Subtable); 1606 if (ACPI_FAILURE (Status)) 1607 { 1608 return (Status); 1609 } 1610 1611 ParentTable = DtPeekSubtable (); 1612 DtInsertSubtable (ParentTable, Subtable); 1613 DtPushSubtable (Subtable); 1614 1615 SratHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); 1616 1617 switch (SratHeader->Type) 1618 { 1619 case ACPI_SRAT_TYPE_CPU_AFFINITY: 1620 1621 InfoTable = AcpiDmTableInfoSrat0; 1622 break; 1623 1624 case ACPI_SRAT_TYPE_MEMORY_AFFINITY: 1625 1626 InfoTable = AcpiDmTableInfoSrat1; 1627 break; 1628 1629 case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY: 1630 1631 InfoTable = AcpiDmTableInfoSrat2; 1632 break; 1633 1634 case ACPI_SRAT_TYPE_GICC_AFFINITY: 1635 1636 InfoTable = AcpiDmTableInfoSrat3; 1637 break; 1638 1639 case ACPI_SRAT_TYPE_GIC_ITS_AFFINITY: 1640 1641 InfoTable = AcpiDmTableInfoSrat4; 1642 break; 1643 1644 case ACPI_SRAT_TYPE_GENERIC_AFFINITY: 1645 1646 InfoTable = AcpiDmTableInfoSrat5; 1647 break; 1648 1649 default: 1650 1651 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SRAT"); 1652 return (AE_ERROR); 1653 } 1654 1655 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 1656 if (ACPI_FAILURE (Status)) 1657 { 1658 return (Status); 1659 } 1660 1661 ParentTable = DtPeekSubtable (); 1662 DtInsertSubtable (ParentTable, Subtable); 1663 DtPopSubtable (); 1664 } 1665 1666 return (AE_OK); 1667 } 1668 1669 1670 /****************************************************************************** 1671 * 1672 * FUNCTION: DtCompileStao 1673 * 1674 * PARAMETERS: PFieldList - Current field list pointer 1675 * 1676 * RETURN: Status 1677 * 1678 * DESCRIPTION: Compile STAO. 1679 * 1680 *****************************************************************************/ 1681 1682 ACPI_STATUS 1683 DtCompileStao ( 1684 void **List) 1685 { 1686 DT_FIELD **PFieldList = (DT_FIELD **) List; 1687 DT_SUBTABLE *Subtable; 1688 DT_SUBTABLE *ParentTable; 1689 ACPI_STATUS Status; 1690 1691 1692 /* Compile the main table */ 1693 1694 Status = DtCompileTable (PFieldList, AcpiDmTableInfoStao, 1695 &Subtable); 1696 if (ACPI_FAILURE (Status)) 1697 { 1698 return (Status); 1699 } 1700 1701 ParentTable = DtPeekSubtable (); 1702 DtInsertSubtable (ParentTable, Subtable); 1703 1704 /* Compile each ASCII namestring as a subtable */ 1705 1706 while (*PFieldList) 1707 { 1708 Status = DtCompileTable (PFieldList, AcpiDmTableInfoStaoStr, 1709 &Subtable); 1710 if (ACPI_FAILURE (Status)) 1711 { 1712 return (Status); 1713 } 1714 1715 ParentTable = DtPeekSubtable (); 1716 DtInsertSubtable (ParentTable, Subtable); 1717 } 1718 1719 return (AE_OK); 1720 } 1721 1722 1723 /****************************************************************************** 1724 * 1725 * FUNCTION: DtCompileTcpa 1726 * 1727 * PARAMETERS: PFieldList - Current field list pointer 1728 * 1729 * RETURN: Status 1730 * 1731 * DESCRIPTION: Compile TCPA. 1732 * 1733 *****************************************************************************/ 1734 1735 ACPI_STATUS 1736 DtCompileTcpa ( 1737 void **List) 1738 { 1739 DT_FIELD **PFieldList = (DT_FIELD **) List; 1740 DT_SUBTABLE *Subtable; 1741 ACPI_TABLE_TCPA_HDR *TcpaHeader; 1742 DT_SUBTABLE *ParentTable; 1743 ACPI_STATUS Status; 1744 1745 1746 /* Compile the main table */ 1747 1748 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaHdr, 1749 &Subtable); 1750 if (ACPI_FAILURE (Status)) 1751 { 1752 return (Status); 1753 } 1754 1755 ParentTable = DtPeekSubtable (); 1756 DtInsertSubtable (ParentTable, Subtable); 1757 1758 /* 1759 * Examine the PlatformClass field to determine the table type. 1760 * Either a client or server table. Only one. 1761 */ 1762 TcpaHeader = ACPI_CAST_PTR (ACPI_TABLE_TCPA_HDR, ParentTable->Buffer); 1763 1764 switch (TcpaHeader->PlatformClass) 1765 { 1766 case ACPI_TCPA_CLIENT_TABLE: 1767 1768 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaClient, 1769 &Subtable); 1770 break; 1771 1772 case ACPI_TCPA_SERVER_TABLE: 1773 1774 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaServer, 1775 &Subtable); 1776 break; 1777 1778 default: 1779 1780 AcpiOsPrintf ("\n**** Unknown TCPA Platform Class 0x%X\n", 1781 TcpaHeader->PlatformClass); 1782 Status = AE_ERROR; 1783 break; 1784 } 1785 1786 ParentTable = DtPeekSubtable (); 1787 DtInsertSubtable (ParentTable, Subtable); 1788 return (Status); 1789 } 1790 1791 1792 /****************************************************************************** 1793 * 1794 * FUNCTION: DtCompileTpm2Rev3 1795 * 1796 * PARAMETERS: PFieldList - Current field list pointer 1797 * 1798 * RETURN: Status 1799 * 1800 * DESCRIPTION: Compile TPM2 revision 3 1801 * 1802 *****************************************************************************/ 1803 static ACPI_STATUS 1804 DtCompileTpm2Rev3 ( 1805 void **List) 1806 { 1807 DT_FIELD **PFieldList = (DT_FIELD **) List; 1808 DT_SUBTABLE *Subtable; 1809 ACPI_TABLE_TPM23 *Tpm23Header; 1810 DT_SUBTABLE *ParentTable; 1811 ACPI_STATUS Status = AE_OK; 1812 1813 1814 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm23, 1815 &Subtable); 1816 1817 ParentTable = DtPeekSubtable (); 1818 DtInsertSubtable (ParentTable, Subtable); 1819 Tpm23Header = ACPI_CAST_PTR (ACPI_TABLE_TPM23, ParentTable->Buffer); 1820 1821 /* Subtable type depends on the StartMethod */ 1822 1823 switch (Tpm23Header->StartMethod) 1824 { 1825 case ACPI_TPM23_ACPI_START_METHOD: 1826 1827 /* Subtable specific to to ARM_SMC */ 1828 1829 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm23a, 1830 &Subtable); 1831 if (ACPI_FAILURE (Status)) 1832 { 1833 return (Status); 1834 } 1835 1836 ParentTable = DtPeekSubtable (); 1837 DtInsertSubtable (ParentTable, Subtable); 1838 break; 1839 1840 default: 1841 break; 1842 } 1843 1844 return (Status); 1845 } 1846 1847 1848 /****************************************************************************** 1849 * 1850 * FUNCTION: DtCompileTpm2 1851 * 1852 * PARAMETERS: PFieldList - Current field list pointer 1853 * 1854 * RETURN: Status 1855 * 1856 * DESCRIPTION: Compile TPM2. 1857 * 1858 *****************************************************************************/ 1859 1860 ACPI_STATUS 1861 DtCompileTpm2 ( 1862 void **List) 1863 { 1864 DT_FIELD **PFieldList = (DT_FIELD **) List; 1865 DT_SUBTABLE *Subtable; 1866 ACPI_TABLE_TPM2 *Tpm2Header; 1867 DT_SUBTABLE *ParentTable; 1868 ACPI_STATUS Status = AE_OK; 1869 ACPI_TABLE_HEADER *Header; 1870 1871 1872 ParentTable = DtPeekSubtable (); 1873 1874 Header = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer); 1875 1876 if (Header->Revision == 3) 1877 { 1878 return (DtCompileTpm2Rev3 (List)); 1879 } 1880 1881 /* Compile the main table */ 1882 1883 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm2, 1884 &Subtable); 1885 if (ACPI_FAILURE (Status)) 1886 { 1887 return (Status); 1888 } 1889 1890 ParentTable = DtPeekSubtable (); 1891 DtInsertSubtable (ParentTable, Subtable); 1892 1893 Tpm2Header = ACPI_CAST_PTR (ACPI_TABLE_TPM2, ParentTable->Buffer); 1894 1895 /* Method parameters */ 1896 /* Optional: Log area minimum length */ 1897 /* Optional: Log area start address */ 1898 /* TBD: Optional fields above not fully implemented (not optional at this time) */ 1899 1900 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm2a, 1901 &Subtable); 1902 if (ACPI_FAILURE (Status)) 1903 { 1904 return (Status); 1905 } 1906 1907 ParentTable = DtPeekSubtable (); 1908 DtInsertSubtable (ParentTable, Subtable); 1909 1910 1911 /* Subtable type depends on the StartMethod */ 1912 1913 switch (Tpm2Header->StartMethod) 1914 { 1915 case ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC: 1916 1917 /* Subtable specific to to ARM_SMC */ 1918 1919 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm211, 1920 &Subtable); 1921 if (ACPI_FAILURE (Status)) 1922 { 1923 return (Status); 1924 } 1925 1926 ParentTable = DtPeekSubtable (); 1927 DtInsertSubtable (ParentTable, Subtable); 1928 break; 1929 1930 case ACPI_TPM2_START_METHOD: 1931 case ACPI_TPM2_MEMORY_MAPPED: 1932 case ACPI_TPM2_COMMAND_BUFFER: 1933 case ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD: 1934 break; 1935 1936 case ACPI_TPM2_RESERVED1: 1937 case ACPI_TPM2_RESERVED3: 1938 case ACPI_TPM2_RESERVED4: 1939 case ACPI_TPM2_RESERVED5: 1940 case ACPI_TPM2_RESERVED9: 1941 case ACPI_TPM2_RESERVED10: 1942 1943 AcpiOsPrintf ("\n**** Reserved TPM2 Start Method type 0x%X\n", 1944 Tpm2Header->StartMethod); 1945 Status = AE_ERROR; 1946 break; 1947 1948 case ACPI_TPM2_NOT_ALLOWED: 1949 default: 1950 1951 AcpiOsPrintf ("\n**** Unknown TPM2 Start Method type 0x%X\n", 1952 Tpm2Header->StartMethod); 1953 Status = AE_ERROR; 1954 break; 1955 } 1956 1957 return (Status); 1958 } 1959 1960 1961 /****************************************************************************** 1962 * 1963 * FUNCTION: DtGetGenericTableInfo 1964 * 1965 * PARAMETERS: Name - Generic type name 1966 * 1967 * RETURN: Info entry 1968 * 1969 * DESCRIPTION: Obtain table info for a generic name entry 1970 * 1971 *****************************************************************************/ 1972 1973 ACPI_DMTABLE_INFO * 1974 DtGetGenericTableInfo ( 1975 char *Name) 1976 { 1977 ACPI_DMTABLE_INFO *Info; 1978 UINT32 i; 1979 1980 1981 if (!Name) 1982 { 1983 return (NULL); 1984 } 1985 1986 /* Search info table for name match */ 1987 1988 for (i = 0; ; i++) 1989 { 1990 Info = AcpiDmTableInfoGeneric[i]; 1991 if (Info->Opcode == ACPI_DMT_EXIT) 1992 { 1993 Info = NULL; 1994 break; 1995 } 1996 1997 /* Use caseless compare for generic keywords */ 1998 1999 if (!AcpiUtStricmp (Name, Info->Name)) 2000 { 2001 break; 2002 } 2003 } 2004 2005 return (Info); 2006 } 2007 2008 2009 /****************************************************************************** 2010 * 2011 * FUNCTION: DtCompileUefi 2012 * 2013 * PARAMETERS: List - Current field list pointer 2014 * 2015 * RETURN: Status 2016 * 2017 * DESCRIPTION: Compile UEFI. 2018 * 2019 *****************************************************************************/ 2020 2021 ACPI_STATUS 2022 DtCompileUefi ( 2023 void **List) 2024 { 2025 ACPI_STATUS Status; 2026 DT_SUBTABLE *Subtable; 2027 DT_SUBTABLE *ParentTable; 2028 DT_FIELD **PFieldList = (DT_FIELD **) List; 2029 UINT16 *DataOffset; 2030 2031 2032 /* Compile the predefined portion of the UEFI table */ 2033 2034 Status = DtCompileTable (PFieldList, AcpiDmTableInfoUefi, 2035 &Subtable); 2036 if (ACPI_FAILURE (Status)) 2037 { 2038 return (Status); 2039 } 2040 2041 DataOffset = (UINT16 *) (Subtable->Buffer + 16); 2042 *DataOffset = sizeof (ACPI_TABLE_UEFI); 2043 2044 ParentTable = DtPeekSubtable (); 2045 DtInsertSubtable (ParentTable, Subtable); 2046 2047 /* 2048 * Compile the "generic" portion of the UEFI table. This 2049 * part of the table is not predefined and any of the generic 2050 * operators may be used. 2051 */ 2052 DtCompileGeneric ((void **) PFieldList, NULL, NULL); 2053 return (AE_OK); 2054 } 2055 2056 2057 /****************************************************************************** 2058 * 2059 * FUNCTION: DtCompileVrtc 2060 * 2061 * PARAMETERS: List - Current field list pointer 2062 * 2063 * RETURN: Status 2064 * 2065 * DESCRIPTION: Compile VRTC. 2066 * 2067 *****************************************************************************/ 2068 2069 ACPI_STATUS 2070 DtCompileVrtc ( 2071 void **List) 2072 { 2073 ACPI_STATUS Status; 2074 2075 2076 Status = DtCompileTwoSubtables (List, 2077 AcpiDmTableInfoVrtc, AcpiDmTableInfoVrtc0); 2078 return (Status); 2079 } 2080 2081 2082 /****************************************************************************** 2083 * 2084 * FUNCTION: DtCompileWdat 2085 * 2086 * PARAMETERS: List - Current field list pointer 2087 * 2088 * RETURN: Status 2089 * 2090 * DESCRIPTION: Compile WDAT. 2091 * 2092 *****************************************************************************/ 2093 2094 ACPI_STATUS 2095 DtCompileWdat ( 2096 void **List) 2097 { 2098 ACPI_STATUS Status; 2099 2100 2101 Status = DtCompileTwoSubtables (List, 2102 AcpiDmTableInfoWdat, AcpiDmTableInfoWdat0); 2103 return (Status); 2104 } 2105 2106 2107 /****************************************************************************** 2108 * 2109 * FUNCTION: DtCompileWpbt 2110 * 2111 * PARAMETERS: List - Current field list pointer 2112 * 2113 * RETURN: Status 2114 * 2115 * DESCRIPTION: Compile WPBT. 2116 * 2117 *****************************************************************************/ 2118 2119 ACPI_STATUS 2120 DtCompileWpbt ( 2121 void **List) 2122 { 2123 DT_FIELD **PFieldList = (DT_FIELD **) List; 2124 DT_SUBTABLE *Subtable; 2125 DT_SUBTABLE *ParentTable; 2126 ACPI_TABLE_WPBT *Table; 2127 ACPI_STATUS Status; 2128 UINT16 Length; 2129 2130 2131 /* Compile the main table */ 2132 2133 Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt, 2134 &Subtable); 2135 if (ACPI_FAILURE (Status)) 2136 { 2137 return (Status); 2138 } 2139 2140 ParentTable = DtPeekSubtable (); 2141 DtInsertSubtable (ParentTable, Subtable); 2142 2143 /* Compile the argument list subtable */ 2144 2145 Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt0, 2146 &Subtable); 2147 if (ACPI_FAILURE (Status)) 2148 { 2149 return (Status); 2150 } 2151 2152 /* Extract the length of the Arguments buffer, insert into main table */ 2153 2154 Length = (UINT16) Subtable->TotalLength; 2155 Table = ACPI_CAST_PTR (ACPI_TABLE_WPBT, ParentTable->Buffer); 2156 Table->ArgumentsLength = Length; 2157 2158 ParentTable = DtPeekSubtable (); 2159 DtInsertSubtable (ParentTable, Subtable); 2160 return (AE_OK); 2161 } 2162 2163 2164 /****************************************************************************** 2165 * 2166 * FUNCTION: DtCompileXsdt 2167 * 2168 * PARAMETERS: List - Current field list pointer 2169 * 2170 * RETURN: Status 2171 * 2172 * DESCRIPTION: Compile XSDT. 2173 * 2174 *****************************************************************************/ 2175 2176 ACPI_STATUS 2177 DtCompileXsdt ( 2178 void **List) 2179 { 2180 DT_SUBTABLE *Subtable; 2181 DT_SUBTABLE *ParentTable; 2182 DT_FIELD *FieldList = *(DT_FIELD **) List; 2183 UINT64 Address; 2184 2185 2186 ParentTable = DtPeekSubtable (); 2187 2188 while (FieldList) 2189 { 2190 DtCompileInteger ((UINT8 *) &Address, FieldList, 8, DT_NON_ZERO); 2191 2192 DtCreateSubtable ((UINT8 *) &Address, 8, &Subtable); 2193 DtInsertSubtable (ParentTable, Subtable); 2194 FieldList = FieldList->Next; 2195 } 2196 2197 return (AE_OK); 2198 } 2199 2200 2201 /****************************************************************************** 2202 * 2203 * FUNCTION: DtCompileGeneric 2204 * 2205 * PARAMETERS: List - Current field list pointer 2206 * Name - Field name to end generic compiling 2207 * Length - Compiled table length to return 2208 * 2209 * RETURN: Status 2210 * 2211 * DESCRIPTION: Compile generic unknown table. 2212 * 2213 *****************************************************************************/ 2214 2215 ACPI_STATUS 2216 DtCompileGeneric ( 2217 void **List, 2218 char *Name, 2219 UINT32 *Length) 2220 { 2221 ACPI_STATUS Status; 2222 DT_SUBTABLE *Subtable; 2223 DT_SUBTABLE *ParentTable; 2224 DT_FIELD **PFieldList = (DT_FIELD **) List; 2225 ACPI_DMTABLE_INFO *Info; 2226 2227 2228 ParentTable = DtPeekSubtable (); 2229 2230 /* 2231 * Compile the "generic" portion of the table. This 2232 * part of the table is not predefined and any of the generic 2233 * operators may be used. 2234 */ 2235 2236 /* Find any and all labels in the entire generic portion */ 2237 2238 DtDetectAllLabels (*PFieldList); 2239 2240 /* Now we can actually compile the parse tree */ 2241 2242 if (Length && *Length) 2243 { 2244 *Length = 0; 2245 } 2246 while (*PFieldList) 2247 { 2248 if (Name && !strcmp ((*PFieldList)->Name, Name)) 2249 { 2250 break; 2251 } 2252 2253 Info = DtGetGenericTableInfo ((*PFieldList)->Name); 2254 if (!Info) 2255 { 2256 sprintf (AslGbl_MsgBuffer, "Generic data type \"%s\" not found", 2257 (*PFieldList)->Name); 2258 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME, 2259 (*PFieldList), AslGbl_MsgBuffer); 2260 2261 *PFieldList = (*PFieldList)->Next; 2262 continue; 2263 } 2264 2265 Status = DtCompileTable (PFieldList, Info, 2266 &Subtable); 2267 if (ACPI_SUCCESS (Status)) 2268 { 2269 DtInsertSubtable (ParentTable, Subtable); 2270 if (Length) 2271 { 2272 *Length += Subtable->Length; 2273 } 2274 } 2275 else 2276 { 2277 *PFieldList = (*PFieldList)->Next; 2278 2279 if (Status == AE_NOT_FOUND) 2280 { 2281 sprintf (AslGbl_MsgBuffer, "Generic data type \"%s\" not found", 2282 (*PFieldList)->Name); 2283 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME, 2284 (*PFieldList), AslGbl_MsgBuffer); 2285 } 2286 } 2287 } 2288 2289 return (AE_OK); 2290 } 2291