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