1 /****************************************************************************** 2 * 3 * Module Name: dttable2.c - handling for specific ACPI tables 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2017, 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, TRUE); 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, TRUE); 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, TRUE); 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, TRUE); 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, TRUE); 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, TRUE); 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, TRUE); 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, TRUE); 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, TRUE); 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, TRUE); 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, TRUE); 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, TRUE); 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, TRUE); 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, TRUE); 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, FALSE); 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, TRUE); 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, FALSE); 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, TRUE); 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, TRUE); 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, TRUE); 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, TRUE); 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, TRUE); 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, TRUE); 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, TRUE); 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, TRUE); 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, TRUE); 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, TRUE); 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, TRUE); 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, TRUE); 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, TRUE); 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, TRUE); 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 &Gbl_RootTable, TRUE); 1184 if (ACPI_FAILURE (Status)) 1185 { 1186 return (Status); 1187 } 1188 1189 DtPushSubtable (Gbl_RootTable); 1190 1191 while (*PFieldList) 1192 { 1193 SubtableStart = *PFieldList; 1194 Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3ptHdr, 1195 &Subtable, TRUE); 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, TRUE); 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, TRUE); 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, TRUE); 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, TRUE); 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, TRUE); 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, FALSE); 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, TRUE); 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, TRUE); 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, TRUE); 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, TRUE); 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, TRUE); 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 default: 1629 1630 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SRAT"); 1631 return (AE_ERROR); 1632 } 1633 1634 Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); 1635 if (ACPI_FAILURE (Status)) 1636 { 1637 return (Status); 1638 } 1639 1640 ParentTable = DtPeekSubtable (); 1641 DtInsertSubtable (ParentTable, Subtable); 1642 DtPopSubtable (); 1643 } 1644 1645 return (AE_OK); 1646 } 1647 1648 1649 /****************************************************************************** 1650 * 1651 * FUNCTION: DtCompileStao 1652 * 1653 * PARAMETERS: PFieldList - Current field list pointer 1654 * 1655 * RETURN: Status 1656 * 1657 * DESCRIPTION: Compile STAO. 1658 * 1659 *****************************************************************************/ 1660 1661 ACPI_STATUS 1662 DtCompileStao ( 1663 void **List) 1664 { 1665 DT_FIELD **PFieldList = (DT_FIELD **) List; 1666 DT_SUBTABLE *Subtable; 1667 DT_SUBTABLE *ParentTable; 1668 ACPI_STATUS Status; 1669 1670 1671 /* Compile the main table */ 1672 1673 Status = DtCompileTable (PFieldList, AcpiDmTableInfoStao, 1674 &Subtable, TRUE); 1675 if (ACPI_FAILURE (Status)) 1676 { 1677 return (Status); 1678 } 1679 1680 ParentTable = DtPeekSubtable (); 1681 DtInsertSubtable (ParentTable, Subtable); 1682 1683 /* Compile each ASCII namestring as a subtable */ 1684 1685 while (*PFieldList) 1686 { 1687 Status = DtCompileTable (PFieldList, AcpiDmTableInfoStaoStr, 1688 &Subtable, TRUE); 1689 if (ACPI_FAILURE (Status)) 1690 { 1691 return (Status); 1692 } 1693 1694 ParentTable = DtPeekSubtable (); 1695 DtInsertSubtable (ParentTable, Subtable); 1696 } 1697 1698 return (AE_OK); 1699 } 1700 1701 1702 /****************************************************************************** 1703 * 1704 * FUNCTION: DtCompileTcpa 1705 * 1706 * PARAMETERS: PFieldList - Current field list pointer 1707 * 1708 * RETURN: Status 1709 * 1710 * DESCRIPTION: Compile TCPA. 1711 * 1712 *****************************************************************************/ 1713 1714 ACPI_STATUS 1715 DtCompileTcpa ( 1716 void **List) 1717 { 1718 DT_FIELD **PFieldList = (DT_FIELD **) List; 1719 DT_SUBTABLE *Subtable; 1720 ACPI_TABLE_TCPA_HDR *TcpaHeader; 1721 DT_SUBTABLE *ParentTable; 1722 ACPI_STATUS Status; 1723 1724 1725 /* Compile the main table */ 1726 1727 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaHdr, 1728 &Subtable, TRUE); 1729 if (ACPI_FAILURE (Status)) 1730 { 1731 return (Status); 1732 } 1733 1734 ParentTable = DtPeekSubtable (); 1735 DtInsertSubtable (ParentTable, Subtable); 1736 1737 /* 1738 * Examine the PlatformClass field to determine the table type. 1739 * Either a client or server table. Only one. 1740 */ 1741 TcpaHeader = ACPI_CAST_PTR (ACPI_TABLE_TCPA_HDR, ParentTable->Buffer); 1742 1743 switch (TcpaHeader->PlatformClass) 1744 { 1745 case ACPI_TCPA_CLIENT_TABLE: 1746 1747 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaClient, 1748 &Subtable, TRUE); 1749 break; 1750 1751 case ACPI_TCPA_SERVER_TABLE: 1752 1753 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaServer, 1754 &Subtable, TRUE); 1755 break; 1756 1757 default: 1758 1759 AcpiOsPrintf ("\n**** Unknown TCPA Platform Class 0x%X\n", 1760 TcpaHeader->PlatformClass); 1761 Status = AE_ERROR; 1762 break; 1763 } 1764 1765 ParentTable = DtPeekSubtable (); 1766 DtInsertSubtable (ParentTable, Subtable); 1767 return (Status); 1768 } 1769 1770 1771 /****************************************************************************** 1772 * 1773 * FUNCTION: DtCompileTpm2 1774 * 1775 * PARAMETERS: PFieldList - Current field list pointer 1776 * 1777 * RETURN: Status 1778 * 1779 * DESCRIPTION: Compile TPM2. 1780 * 1781 *****************************************************************************/ 1782 1783 ACPI_STATUS 1784 DtCompileTpm2 ( 1785 void **List) 1786 { 1787 DT_FIELD **PFieldList = (DT_FIELD **) List; 1788 DT_SUBTABLE *Subtable; 1789 ACPI_TABLE_TPM2 *Tpm2Header; 1790 DT_SUBTABLE *ParentTable; 1791 ACPI_STATUS Status = AE_OK; 1792 1793 1794 /* Compile the main table */ 1795 1796 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm2, 1797 &Subtable, TRUE); 1798 if (ACPI_FAILURE (Status)) 1799 { 1800 return (Status); 1801 } 1802 1803 ParentTable = DtPeekSubtable (); 1804 DtInsertSubtable (ParentTable, Subtable); 1805 1806 Tpm2Header = ACPI_CAST_PTR (ACPI_TABLE_TPM2, ParentTable->Buffer); 1807 1808 /* Method parameters */ 1809 /* Optional: Log area minimum length */ 1810 /* Optional: Log area start address */ 1811 /* TBD: Optional fields above not fully implemented (not optional at this time) */ 1812 1813 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm2a, 1814 &Subtable, TRUE); 1815 if (ACPI_FAILURE (Status)) 1816 { 1817 return (Status); 1818 } 1819 1820 ParentTable = DtPeekSubtable (); 1821 DtInsertSubtable (ParentTable, Subtable); 1822 1823 1824 /* Subtable type depends on the StartMethod */ 1825 1826 switch (Tpm2Header->StartMethod) 1827 { 1828 case ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC: 1829 1830 /* Subtable specific to to ARM_SMC */ 1831 1832 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm211, 1833 &Subtable, TRUE); 1834 if (ACPI_FAILURE (Status)) 1835 { 1836 return (Status); 1837 } 1838 1839 ParentTable = DtPeekSubtable (); 1840 DtInsertSubtable (ParentTable, Subtable); 1841 break; 1842 1843 case ACPI_TPM2_START_METHOD: 1844 case ACPI_TPM2_MEMORY_MAPPED: 1845 case ACPI_TPM2_COMMAND_BUFFER: 1846 case ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD: 1847 break; 1848 1849 case ACPI_TPM2_RESERVED1: 1850 case ACPI_TPM2_RESERVED3: 1851 case ACPI_TPM2_RESERVED4: 1852 case ACPI_TPM2_RESERVED5: 1853 case ACPI_TPM2_RESERVED9: 1854 case ACPI_TPM2_RESERVED10: 1855 1856 AcpiOsPrintf ("\n**** Reserved TPM2 Start Method type 0x%X\n", 1857 Tpm2Header->StartMethod); 1858 Status = AE_ERROR; 1859 break; 1860 1861 case ACPI_TPM2_NOT_ALLOWED: 1862 default: 1863 1864 AcpiOsPrintf ("\n**** Unknown TPM2 Start Method type 0x%X\n", 1865 Tpm2Header->StartMethod); 1866 Status = AE_ERROR; 1867 break; 1868 } 1869 1870 return (Status); 1871 } 1872 1873 1874 /****************************************************************************** 1875 * 1876 * FUNCTION: DtGetGenericTableInfo 1877 * 1878 * PARAMETERS: Name - Generic type name 1879 * 1880 * RETURN: Info entry 1881 * 1882 * DESCRIPTION: Obtain table info for a generic name entry 1883 * 1884 *****************************************************************************/ 1885 1886 ACPI_DMTABLE_INFO * 1887 DtGetGenericTableInfo ( 1888 char *Name) 1889 { 1890 ACPI_DMTABLE_INFO *Info; 1891 UINT32 i; 1892 1893 1894 if (!Name) 1895 { 1896 return (NULL); 1897 } 1898 1899 /* Search info table for name match */ 1900 1901 for (i = 0; ; i++) 1902 { 1903 Info = AcpiDmTableInfoGeneric[i]; 1904 if (Info->Opcode == ACPI_DMT_EXIT) 1905 { 1906 Info = NULL; 1907 break; 1908 } 1909 1910 /* Use caseless compare for generic keywords */ 1911 1912 if (!AcpiUtStricmp (Name, Info->Name)) 1913 { 1914 break; 1915 } 1916 } 1917 1918 return (Info); 1919 } 1920 1921 1922 /****************************************************************************** 1923 * 1924 * FUNCTION: DtCompileUefi 1925 * 1926 * PARAMETERS: List - Current field list pointer 1927 * 1928 * RETURN: Status 1929 * 1930 * DESCRIPTION: Compile UEFI. 1931 * 1932 *****************************************************************************/ 1933 1934 ACPI_STATUS 1935 DtCompileUefi ( 1936 void **List) 1937 { 1938 ACPI_STATUS Status; 1939 DT_SUBTABLE *Subtable; 1940 DT_SUBTABLE *ParentTable; 1941 DT_FIELD **PFieldList = (DT_FIELD **) List; 1942 UINT16 *DataOffset; 1943 1944 1945 /* Compile the predefined portion of the UEFI table */ 1946 1947 Status = DtCompileTable (PFieldList, AcpiDmTableInfoUefi, 1948 &Subtable, TRUE); 1949 if (ACPI_FAILURE (Status)) 1950 { 1951 return (Status); 1952 } 1953 1954 DataOffset = (UINT16 *) (Subtable->Buffer + 16); 1955 *DataOffset = sizeof (ACPI_TABLE_UEFI); 1956 1957 ParentTable = DtPeekSubtable (); 1958 DtInsertSubtable (ParentTable, Subtable); 1959 1960 /* 1961 * Compile the "generic" portion of the UEFI table. This 1962 * part of the table is not predefined and any of the generic 1963 * operators may be used. 1964 */ 1965 DtCompileGeneric ((void **) PFieldList, NULL, NULL); 1966 return (AE_OK); 1967 } 1968 1969 1970 /****************************************************************************** 1971 * 1972 * FUNCTION: DtCompileVrtc 1973 * 1974 * PARAMETERS: List - Current field list pointer 1975 * 1976 * RETURN: Status 1977 * 1978 * DESCRIPTION: Compile VRTC. 1979 * 1980 *****************************************************************************/ 1981 1982 ACPI_STATUS 1983 DtCompileVrtc ( 1984 void **List) 1985 { 1986 ACPI_STATUS Status; 1987 1988 1989 Status = DtCompileTwoSubtables (List, 1990 AcpiDmTableInfoVrtc, AcpiDmTableInfoVrtc0); 1991 return (Status); 1992 } 1993 1994 1995 /****************************************************************************** 1996 * 1997 * FUNCTION: DtCompileWdat 1998 * 1999 * PARAMETERS: List - Current field list pointer 2000 * 2001 * RETURN: Status 2002 * 2003 * DESCRIPTION: Compile WDAT. 2004 * 2005 *****************************************************************************/ 2006 2007 ACPI_STATUS 2008 DtCompileWdat ( 2009 void **List) 2010 { 2011 ACPI_STATUS Status; 2012 2013 2014 Status = DtCompileTwoSubtables (List, 2015 AcpiDmTableInfoWdat, AcpiDmTableInfoWdat0); 2016 return (Status); 2017 } 2018 2019 2020 /****************************************************************************** 2021 * 2022 * FUNCTION: DtCompileWpbt 2023 * 2024 * PARAMETERS: List - Current field list pointer 2025 * 2026 * RETURN: Status 2027 * 2028 * DESCRIPTION: Compile WPBT. 2029 * 2030 *****************************************************************************/ 2031 2032 ACPI_STATUS 2033 DtCompileWpbt ( 2034 void **List) 2035 { 2036 DT_FIELD **PFieldList = (DT_FIELD **) List; 2037 DT_SUBTABLE *Subtable; 2038 DT_SUBTABLE *ParentTable; 2039 ACPI_TABLE_WPBT *Table; 2040 ACPI_STATUS Status; 2041 UINT16 Length; 2042 2043 2044 /* Compile the main table */ 2045 2046 Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt, 2047 &Subtable, TRUE); 2048 if (ACPI_FAILURE (Status)) 2049 { 2050 return (Status); 2051 } 2052 2053 ParentTable = DtPeekSubtable (); 2054 DtInsertSubtable (ParentTable, Subtable); 2055 2056 /* Compile the argument list subtable */ 2057 2058 Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt0, 2059 &Subtable, TRUE); 2060 if (ACPI_FAILURE (Status)) 2061 { 2062 return (Status); 2063 } 2064 2065 /* Extract the length of the Arguments buffer, insert into main table */ 2066 2067 Length = (UINT16) Subtable->TotalLength; 2068 Table = ACPI_CAST_PTR (ACPI_TABLE_WPBT, ParentTable->Buffer); 2069 Table->ArgumentsLength = Length; 2070 2071 ParentTable = DtPeekSubtable (); 2072 DtInsertSubtable (ParentTable, Subtable); 2073 return (AE_OK); 2074 } 2075 2076 2077 /****************************************************************************** 2078 * 2079 * FUNCTION: DtCompileXsdt 2080 * 2081 * PARAMETERS: List - Current field list pointer 2082 * 2083 * RETURN: Status 2084 * 2085 * DESCRIPTION: Compile XSDT. 2086 * 2087 *****************************************************************************/ 2088 2089 ACPI_STATUS 2090 DtCompileXsdt ( 2091 void **List) 2092 { 2093 DT_SUBTABLE *Subtable; 2094 DT_SUBTABLE *ParentTable; 2095 DT_FIELD *FieldList = *(DT_FIELD **) List; 2096 UINT64 Address; 2097 2098 2099 ParentTable = DtPeekSubtable (); 2100 2101 while (FieldList) 2102 { 2103 DtCompileInteger ((UINT8 *) &Address, FieldList, 8, DT_NON_ZERO); 2104 2105 DtCreateSubtable ((UINT8 *) &Address, 8, &Subtable); 2106 DtInsertSubtable (ParentTable, Subtable); 2107 FieldList = FieldList->Next; 2108 } 2109 2110 return (AE_OK); 2111 } 2112 2113 2114 /****************************************************************************** 2115 * 2116 * FUNCTION: DtCompileGeneric 2117 * 2118 * PARAMETERS: List - Current field list pointer 2119 * Name - Field name to end generic compiling 2120 * Length - Compiled table length to return 2121 * 2122 * RETURN: Status 2123 * 2124 * DESCRIPTION: Compile generic unknown table. 2125 * 2126 *****************************************************************************/ 2127 2128 ACPI_STATUS 2129 DtCompileGeneric ( 2130 void **List, 2131 char *Name, 2132 UINT32 *Length) 2133 { 2134 ACPI_STATUS Status; 2135 DT_SUBTABLE *Subtable; 2136 DT_SUBTABLE *ParentTable; 2137 DT_FIELD **PFieldList = (DT_FIELD **) List; 2138 ACPI_DMTABLE_INFO *Info; 2139 2140 2141 ParentTable = DtPeekSubtable (); 2142 2143 /* 2144 * Compile the "generic" portion of the table. This 2145 * part of the table is not predefined and any of the generic 2146 * operators may be used. 2147 */ 2148 2149 /* Find any and all labels in the entire generic portion */ 2150 2151 DtDetectAllLabels (*PFieldList); 2152 2153 /* Now we can actually compile the parse tree */ 2154 2155 if (Length && *Length) 2156 { 2157 *Length = 0; 2158 } 2159 while (*PFieldList) 2160 { 2161 if (Name && !strcmp ((*PFieldList)->Name, Name)) 2162 { 2163 break; 2164 } 2165 2166 Info = DtGetGenericTableInfo ((*PFieldList)->Name); 2167 if (!Info) 2168 { 2169 sprintf (MsgBuffer, "Generic data type \"%s\" not found", 2170 (*PFieldList)->Name); 2171 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME, 2172 (*PFieldList), MsgBuffer); 2173 2174 *PFieldList = (*PFieldList)->Next; 2175 continue; 2176 } 2177 2178 Status = DtCompileTable (PFieldList, Info, 2179 &Subtable, TRUE); 2180 if (ACPI_SUCCESS (Status)) 2181 { 2182 DtInsertSubtable (ParentTable, Subtable); 2183 if (Length) 2184 { 2185 *Length += Subtable->Length; 2186 } 2187 } 2188 else 2189 { 2190 *PFieldList = (*PFieldList)->Next; 2191 2192 if (Status == AE_NOT_FOUND) 2193 { 2194 sprintf (MsgBuffer, "Generic data type \"%s\" not found", 2195 (*PFieldList)->Name); 2196 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME, 2197 (*PFieldList), MsgBuffer); 2198 } 2199 } 2200 } 2201 2202 return (AE_OK); 2203 } 2204