1 /****************************************************************************** 2 * 3 * Module Name: dttable2.c - handling for specific ACPI tables 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2026, 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_TABLE_HEADER *Table; 150 ACPI_SUBTABLE_HEADER *MadtHeader; 151 ACPI_DMTABLE_INFO *InfoTable; 152 UINT8 Revision; 153 154 155 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadt, 156 &Subtable); 157 if (ACPI_FAILURE (Status)) 158 { 159 return (Status); 160 } 161 162 ParentTable = DtPeekSubtable (); 163 DtInsertSubtable (ParentTable, Subtable); 164 165 Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer); 166 Revision = Table->Revision; 167 168 while (*PFieldList) 169 { 170 SubtableStart = *PFieldList; 171 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadtHdr, 172 &Subtable); 173 if (ACPI_FAILURE (Status)) 174 { 175 return (Status); 176 } 177 178 ParentTable = DtPeekSubtable (); 179 DtInsertSubtable (ParentTable, Subtable); 180 DtPushSubtable (Subtable); 181 182 MadtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); 183 184 switch (MadtHeader->Type) 185 { 186 case ACPI_MADT_TYPE_LOCAL_APIC: 187 188 InfoTable = AcpiDmTableInfoMadt0; 189 break; 190 191 case ACPI_MADT_TYPE_IO_APIC: 192 193 InfoTable = AcpiDmTableInfoMadt1; 194 break; 195 196 case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE: 197 198 InfoTable = AcpiDmTableInfoMadt2; 199 break; 200 201 case ACPI_MADT_TYPE_NMI_SOURCE: 202 203 InfoTable = AcpiDmTableInfoMadt3; 204 break; 205 206 case ACPI_MADT_TYPE_LOCAL_APIC_NMI: 207 208 InfoTable = AcpiDmTableInfoMadt4; 209 break; 210 211 case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE: 212 213 InfoTable = AcpiDmTableInfoMadt5; 214 break; 215 216 case ACPI_MADT_TYPE_IO_SAPIC: 217 218 InfoTable = AcpiDmTableInfoMadt6; 219 break; 220 221 case ACPI_MADT_TYPE_LOCAL_SAPIC: 222 223 InfoTable = AcpiDmTableInfoMadt7; 224 break; 225 226 case ACPI_MADT_TYPE_INTERRUPT_SOURCE: 227 228 InfoTable = AcpiDmTableInfoMadt8; 229 break; 230 231 case ACPI_MADT_TYPE_LOCAL_X2APIC: 232 233 InfoTable = AcpiDmTableInfoMadt9; 234 break; 235 236 case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI: 237 238 InfoTable = AcpiDmTableInfoMadt10; 239 break; 240 241 case ACPI_MADT_TYPE_GENERIC_INTERRUPT: 242 243 if (Revision > 6) 244 InfoTable = AcpiDmTableInfoMadt11b; 245 else if (Revision == 6) 246 InfoTable = AcpiDmTableInfoMadt11a; 247 else 248 InfoTable = AcpiDmTableInfoMadt11; 249 break; 250 251 case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR: 252 253 InfoTable = AcpiDmTableInfoMadt12; 254 break; 255 256 case ACPI_MADT_TYPE_GENERIC_MSI_FRAME: 257 258 InfoTable = AcpiDmTableInfoMadt13; 259 break; 260 261 case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR: 262 263 InfoTable = Revision > 6 ? AcpiDmTableInfoMadt14a 264 : AcpiDmTableInfoMadt14; 265 break; 266 267 case ACPI_MADT_TYPE_GENERIC_TRANSLATOR: 268 269 InfoTable = Revision > 6 ? AcpiDmTableInfoMadt15a 270 : AcpiDmTableInfoMadt15; 271 272 break; 273 274 case ACPI_MADT_TYPE_MULTIPROC_WAKEUP: 275 276 InfoTable = AcpiDmTableInfoMadt16; 277 break; 278 279 case ACPI_MADT_TYPE_CORE_PIC: 280 281 InfoTable = AcpiDmTableInfoMadt17; 282 break; 283 284 case ACPI_MADT_TYPE_LIO_PIC: 285 286 InfoTable = AcpiDmTableInfoMadt18; 287 break; 288 289 case ACPI_MADT_TYPE_HT_PIC: 290 291 InfoTable = AcpiDmTableInfoMadt19; 292 break; 293 294 case ACPI_MADT_TYPE_EIO_PIC: 295 296 InfoTable = AcpiDmTableInfoMadt20; 297 break; 298 299 case ACPI_MADT_TYPE_MSI_PIC: 300 301 InfoTable = AcpiDmTableInfoMadt21; 302 break; 303 304 case ACPI_MADT_TYPE_BIO_PIC: 305 306 InfoTable = AcpiDmTableInfoMadt22; 307 break; 308 309 case ACPI_MADT_TYPE_LPC_PIC: 310 311 InfoTable = AcpiDmTableInfoMadt23; 312 break; 313 314 case ACPI_MADT_TYPE_RINTC: 315 316 InfoTable = AcpiDmTableInfoMadt24; 317 break; 318 319 case ACPI_MADT_TYPE_IMSIC: 320 321 InfoTable = AcpiDmTableInfoMadt25; 322 break; 323 324 case ACPI_MADT_TYPE_APLIC: 325 326 InfoTable = AcpiDmTableInfoMadt26; 327 break; 328 329 case ACPI_MADT_TYPE_PLIC: 330 331 InfoTable = AcpiDmTableInfoMadt27; 332 break; 333 334 case ACPI_MADT_TYPE_GICV5_IRS: 335 336 InfoTable = AcpiDmTableInfoMadt28; 337 break; 338 339 case ACPI_MADT_TYPE_GICV5_ITS: 340 341 InfoTable = AcpiDmTableInfoMadt29; 342 break; 343 344 case ACPI_MADT_TYPE_GICV5_ITS_TRANSLATE: 345 346 InfoTable = AcpiDmTableInfoMadt30; 347 break; 348 349 default: 350 351 if (MadtHeader->Type >= ACPI_MADT_TYPE_OEM_RESERVED) 352 { 353 InfoTable = AcpiDmTableInfoMadt128; 354 } 355 else 356 { 357 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "MADT"); 358 return (AE_ERROR); 359 } 360 361 break; 362 } 363 364 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 365 if (ACPI_FAILURE (Status)) 366 { 367 return (Status); 368 } 369 370 ParentTable = DtPeekSubtable (); 371 DtInsertSubtable (ParentTable, Subtable); 372 DtPopSubtable (); 373 } 374 375 return (AE_OK); 376 } 377 378 379 /****************************************************************************** 380 * 381 * FUNCTION: DtCompileMcfg 382 * 383 * PARAMETERS: List - Current field list pointer 384 * 385 * RETURN: Status 386 * 387 * DESCRIPTION: Compile MCFG. 388 * 389 *****************************************************************************/ 390 391 ACPI_STATUS 392 DtCompileMcfg ( 393 void **List) 394 { 395 ACPI_STATUS Status; 396 397 398 Status = DtCompileTwoSubtables (List, 399 AcpiDmTableInfoMcfg, AcpiDmTableInfoMcfg0); 400 return (Status); 401 } 402 403 /****************************************************************************** 404 * 405 * FUNCTION: DtCompileMpam 406 * 407 * PARAMETERS: List - Current field list pointer 408 * 409 * RETURN: Status 410 * 411 * DESCRIPTION: Compile MPAM. 412 * 413 *****************************************************************************/ 414 415 ACPI_STATUS 416 DtCompileMpam ( 417 void **List) 418 { 419 ACPI_STATUS Status; 420 DT_SUBTABLE *ParentTable; 421 DT_SUBTABLE *Subtable; 422 DT_FIELD *SubtableStart; 423 DT_FIELD **PFieldList = (DT_FIELD **) List; 424 ACPI_MPAM_MSC_NODE *MpamMscNode; 425 ACPI_MPAM_RESOURCE_NODE *MpamResourceNode; 426 UINT32 FuncDepsCount; 427 UINT32 RisLength; 428 ACPI_DMTABLE_INFO *InfoTable; 429 430 ParentTable = DtPeekSubtable (); 431 432 while (*PFieldList) 433 { 434 SubtableStart = *PFieldList; 435 436 /* Main MSC Node table */ 437 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpam0, 438 &Subtable); 439 if (ACPI_FAILURE (Status)) 440 { 441 return (Status); 442 } 443 444 MpamMscNode = ACPI_CAST_PTR (ACPI_MPAM_MSC_NODE, Subtable->Buffer); 445 446 ParentTable = DtPeekSubtable (); 447 DtInsertSubtable (ParentTable, Subtable); 448 DtPushSubtable (Subtable); 449 450 ParentTable = DtPeekSubtable (); 451 452 /* 453 * RIS(es) per MSC node have variable lengths depending on how many RISes there and 454 * any how many functional dependencies per RIS. Calculate it in order 455 * to properly set the overall MSC length. 456 */ 457 RisLength = 0; 458 459 /* Iterate over RIS subtables per MSC node */ 460 for (UINT32 ris = 0; ris < MpamMscNode->NumResourceNodes; ris++) 461 { 462 /* Compile RIS subtable */ 463 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpam1, 464 &Subtable); 465 if (ACPI_FAILURE (Status)) 466 { 467 return (Status); 468 } 469 470 MpamResourceNode = ACPI_CAST_PTR (ACPI_MPAM_RESOURCE_NODE, Subtable->Buffer); 471 DtInsertSubtable (ParentTable, Subtable); 472 DtPushSubtable (Subtable); 473 474 ParentTable = DtPeekSubtable (); 475 476 switch (MpamResourceNode->LocatorType) 477 { 478 case ACPI_MPAM_LOCATION_TYPE_PROCESSOR_CACHE: 479 InfoTable = AcpiDmTableInfoMpam1A; 480 break; 481 case ACPI_MPAM_LOCATION_TYPE_MEMORY: 482 InfoTable = AcpiDmTableInfoMpam1B; 483 break; 484 case ACPI_MPAM_LOCATION_TYPE_SMMU: 485 InfoTable = AcpiDmTableInfoMpam1C; 486 break; 487 case ACPI_MPAM_LOCATION_TYPE_MEMORY_CACHE: 488 InfoTable = AcpiDmTableInfoMpam1D; 489 break; 490 case ACPI_MPAM_LOCATION_TYPE_ACPI_DEVICE: 491 InfoTable = AcpiDmTableInfoMpam1E; 492 break; 493 case ACPI_MPAM_LOCATION_TYPE_INTERCONNECT: 494 InfoTable = AcpiDmTableInfoMpam1F; 495 break; 496 case ACPI_MPAM_LOCATION_TYPE_UNKNOWN: 497 InfoTable = AcpiDmTableInfoMpam1G; 498 default: 499 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "Resource Locator Type"); 500 return (AE_ERROR); 501 } 502 503 /* Compile Resource Locator Table */ 504 Status = DtCompileTable (PFieldList, InfoTable, 505 &Subtable); 506 507 if (ACPI_FAILURE (Status)) 508 { 509 return (Status); 510 } 511 512 DtInsertSubtable (ParentTable, Subtable); 513 514 /* Compile the number of functional dependencies per RIS */ 515 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpam1Deps, 516 &Subtable); 517 518 if (ACPI_FAILURE (Status)) 519 { 520 return (Status); 521 } 522 523 DtInsertSubtable (ParentTable, Subtable); 524 FuncDepsCount = *ACPI_CAST_PTR (UINT32, Subtable->Buffer); 525 526 RisLength += sizeof(ACPI_MPAM_RESOURCE_NODE) + 527 FuncDepsCount * sizeof(ACPI_MPAM_FUNC_DEPS); 528 529 /* Iterate over functional dependencies per RIS */ 530 for (UINT32 funcDep = 0; funcDep < FuncDepsCount; funcDep++) 531 { 532 /* Compiler functional dependencies table */ 533 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpam2, 534 &Subtable); 535 536 if (ACPI_FAILURE (Status)) 537 { 538 return (Status); 539 } 540 541 DtInsertSubtable (ParentTable, Subtable); 542 } 543 544 DtPopSubtable (); 545 } 546 547 /* Check if the length of the MSC is correct and override with the correct length */ 548 if (MpamMscNode->Length != sizeof(ACPI_MPAM_MSC_NODE) + RisLength) 549 { 550 MpamMscNode->Length = (UINT16) (sizeof(ACPI_MPAM_MSC_NODE) + RisLength); 551 DbgPrint (ASL_DEBUG_OUTPUT, "Overriding MSC->Length: %X\n", MpamMscNode->Length); 552 } 553 554 DtPopSubtable (); 555 } 556 557 return (AE_OK); 558 } 559 560 561 /****************************************************************************** 562 * 563 * FUNCTION: DtCompileMpst 564 * 565 * PARAMETERS: List - Current field list pointer 566 * 567 * RETURN: Status 568 * 569 * DESCRIPTION: Compile MPST. 570 * 571 *****************************************************************************/ 572 573 ACPI_STATUS 574 DtCompileMpst ( 575 void **List) 576 { 577 ACPI_STATUS Status; 578 DT_SUBTABLE *Subtable; 579 DT_SUBTABLE *ParentTable; 580 DT_FIELD **PFieldList = (DT_FIELD **) List; 581 ACPI_MPST_CHANNEL *MpstChannelInfo; 582 ACPI_MPST_POWER_NODE *MpstPowerNode; 583 ACPI_MPST_DATA_HDR *MpstDataHeader; 584 UINT16 SubtableCount; 585 UINT32 PowerStateCount; 586 UINT32 ComponentCount; 587 588 589 /* Main table */ 590 591 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst, &Subtable); 592 if (ACPI_FAILURE (Status)) 593 { 594 return (Status); 595 } 596 597 ParentTable = DtPeekSubtable (); 598 DtInsertSubtable (ParentTable, Subtable); 599 DtPushSubtable (Subtable); 600 601 MpstChannelInfo = ACPI_CAST_PTR (ACPI_MPST_CHANNEL, Subtable->Buffer); 602 SubtableCount = MpstChannelInfo->PowerNodeCount; 603 604 while (*PFieldList && SubtableCount) 605 { 606 /* Subtable: Memory Power Node(s) */ 607 608 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0, 609 &Subtable); 610 if (ACPI_FAILURE (Status)) 611 { 612 return (Status); 613 } 614 615 ParentTable = DtPeekSubtable (); 616 DtInsertSubtable (ParentTable, Subtable); 617 DtPushSubtable (Subtable); 618 619 MpstPowerNode = ACPI_CAST_PTR (ACPI_MPST_POWER_NODE, Subtable->Buffer); 620 PowerStateCount = MpstPowerNode->NumPowerStates; 621 ComponentCount = MpstPowerNode->NumPhysicalComponents; 622 623 ParentTable = DtPeekSubtable (); 624 625 /* Sub-subtables - Memory Power State Structure(s) */ 626 627 while (*PFieldList && PowerStateCount) 628 { 629 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0A, 630 &Subtable); 631 if (ACPI_FAILURE (Status)) 632 { 633 return (Status); 634 } 635 636 DtInsertSubtable (ParentTable, Subtable); 637 PowerStateCount--; 638 } 639 640 /* Sub-subtables - Physical Component ID Structure(s) */ 641 642 while (*PFieldList && ComponentCount) 643 { 644 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0B, 645 &Subtable); 646 if (ACPI_FAILURE (Status)) 647 { 648 return (Status); 649 } 650 651 DtInsertSubtable (ParentTable, Subtable); 652 ComponentCount--; 653 } 654 655 SubtableCount--; 656 DtPopSubtable (); 657 } 658 659 /* Subtable: Count of Memory Power State Characteristic structures */ 660 661 DtPopSubtable (); 662 663 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst1, &Subtable); 664 if (ACPI_FAILURE (Status)) 665 { 666 return (Status); 667 } 668 669 ParentTable = DtPeekSubtable (); 670 DtInsertSubtable (ParentTable, Subtable); 671 DtPushSubtable (Subtable); 672 673 MpstDataHeader = ACPI_CAST_PTR (ACPI_MPST_DATA_HDR, Subtable->Buffer); 674 SubtableCount = MpstDataHeader->CharacteristicsCount; 675 676 ParentTable = DtPeekSubtable (); 677 678 /* Subtable: Memory Power State Characteristics structure(s) */ 679 680 while (*PFieldList && SubtableCount) 681 { 682 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst2, 683 &Subtable); 684 if (ACPI_FAILURE (Status)) 685 { 686 return (Status); 687 } 688 689 DtInsertSubtable (ParentTable, Subtable); 690 SubtableCount--; 691 } 692 693 DtPopSubtable (); 694 return (AE_OK); 695 } 696 697 698 /****************************************************************************** 699 * 700 * FUNCTION: DtCompileMrrm 701 * 702 * PARAMETERS: List - Current field list pointer 703 * 704 * RETURN: Status 705 * 706 * DESCRIPTION: Compile MRRM. 707 * 708 *****************************************************************************/ 709 710 ACPI_STATUS 711 DtCompileMrrm ( 712 void **List) 713 { 714 ACPI_STATUS Status; 715 DT_SUBTABLE *Subtable; 716 DT_SUBTABLE *ParentTable; 717 DT_FIELD **PFieldList = (DT_FIELD **) List; 718 719 /* Main table */ 720 721 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMrrm, 722 &Subtable); 723 if (ACPI_FAILURE (Status)) 724 { 725 return (Status); 726 } 727 728 ParentTable = DtPeekSubtable (); 729 DtInsertSubtable (ParentTable, Subtable); 730 731 /* Subtables (all are same type) */ 732 733 while (*PFieldList) 734 { 735 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMrrm0, 736 &Subtable); 737 if (ACPI_FAILURE (Status)) 738 { 739 return (Status); 740 } 741 742 DtInsertSubtable (ParentTable, Subtable); 743 } 744 745 return (AE_OK); 746 } 747 748 749 /****************************************************************************** 750 * 751 * FUNCTION: DtCompileMsct 752 * 753 * PARAMETERS: List - Current field list pointer 754 * 755 * RETURN: Status 756 * 757 * DESCRIPTION: Compile MSCT. 758 * 759 *****************************************************************************/ 760 761 ACPI_STATUS 762 DtCompileMsct ( 763 void **List) 764 { 765 ACPI_STATUS Status; 766 767 768 Status = DtCompileTwoSubtables (List, 769 AcpiDmTableInfoMsct, AcpiDmTableInfoMsct0); 770 return (Status); 771 } 772 773 774 /****************************************************************************** 775 * 776 * FUNCTION: DtCompileNfit 777 * 778 * PARAMETERS: List - Current field list pointer 779 * 780 * RETURN: Status 781 * 782 * DESCRIPTION: Compile NFIT. 783 * 784 *****************************************************************************/ 785 786 ACPI_STATUS 787 DtCompileNfit ( 788 void **List) 789 { 790 ACPI_STATUS Status; 791 DT_SUBTABLE *Subtable; 792 DT_SUBTABLE *ParentTable; 793 DT_FIELD **PFieldList = (DT_FIELD **) List; 794 DT_FIELD *SubtableStart; 795 ACPI_NFIT_HEADER *NfitHeader; 796 ACPI_DMTABLE_INFO *InfoTable; 797 UINT32 Count; 798 ACPI_NFIT_INTERLEAVE *Interleave = NULL; 799 ACPI_NFIT_FLUSH_ADDRESS *Hint = NULL; 800 801 802 /* Main table */ 803 804 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit, 805 &Subtable); 806 if (ACPI_FAILURE (Status)) 807 { 808 return (Status); 809 } 810 811 ParentTable = DtPeekSubtable (); 812 DtInsertSubtable (ParentTable, Subtable); 813 DtPushSubtable (Subtable); 814 815 /* Subtables */ 816 817 while (*PFieldList) 818 { 819 SubtableStart = *PFieldList; 820 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfitHdr, 821 &Subtable); 822 if (ACPI_FAILURE (Status)) 823 { 824 return (Status); 825 } 826 827 ParentTable = DtPeekSubtable (); 828 DtInsertSubtable (ParentTable, Subtable); 829 DtPushSubtable (Subtable); 830 831 NfitHeader = ACPI_CAST_PTR (ACPI_NFIT_HEADER, Subtable->Buffer); 832 833 switch (NfitHeader->Type) 834 { 835 case ACPI_NFIT_TYPE_SYSTEM_ADDRESS: 836 837 InfoTable = AcpiDmTableInfoNfit0; 838 break; 839 840 case ACPI_NFIT_TYPE_MEMORY_MAP: 841 842 InfoTable = AcpiDmTableInfoNfit1; 843 break; 844 845 case ACPI_NFIT_TYPE_INTERLEAVE: 846 847 Interleave = ACPI_CAST_PTR (ACPI_NFIT_INTERLEAVE, Subtable->Buffer); 848 InfoTable = AcpiDmTableInfoNfit2; 849 break; 850 851 case ACPI_NFIT_TYPE_SMBIOS: 852 853 InfoTable = AcpiDmTableInfoNfit3; 854 break; 855 856 case ACPI_NFIT_TYPE_CONTROL_REGION: 857 858 InfoTable = AcpiDmTableInfoNfit4; 859 break; 860 861 case ACPI_NFIT_TYPE_DATA_REGION: 862 863 InfoTable = AcpiDmTableInfoNfit5; 864 break; 865 866 case ACPI_NFIT_TYPE_FLUSH_ADDRESS: 867 868 Hint = ACPI_CAST_PTR (ACPI_NFIT_FLUSH_ADDRESS, Subtable->Buffer); 869 InfoTable = AcpiDmTableInfoNfit6; 870 break; 871 872 case ACPI_NFIT_TYPE_CAPABILITIES: 873 874 InfoTable = AcpiDmTableInfoNfit7; 875 break; 876 877 default: 878 879 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "NFIT"); 880 return (AE_ERROR); 881 } 882 883 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 884 if (ACPI_FAILURE (Status)) 885 { 886 return (Status); 887 } 888 889 ParentTable = DtPeekSubtable (); 890 DtInsertSubtable (ParentTable, Subtable); 891 DtPopSubtable (); 892 893 switch (NfitHeader->Type) 894 { 895 case ACPI_NFIT_TYPE_INTERLEAVE: 896 897 Count = 0; 898 DtPushSubtable (Subtable); 899 while (*PFieldList) 900 { 901 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit2a, 902 &Subtable); 903 if (ACPI_FAILURE (Status)) 904 { 905 return (Status); 906 } 907 908 if (!Subtable) 909 { 910 DtPopSubtable (); 911 break; 912 } 913 914 ParentTable = DtPeekSubtable (); 915 DtInsertSubtable (ParentTable, Subtable); 916 Count++; 917 } 918 919 Interleave->LineCount = Count; 920 break; 921 922 case ACPI_NFIT_TYPE_SMBIOS: 923 924 if (*PFieldList) 925 { 926 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit3a, 927 &Subtable); 928 if (ACPI_FAILURE (Status)) 929 { 930 return (Status); 931 } 932 933 if (Subtable) 934 { 935 DtInsertSubtable (ParentTable, Subtable); 936 } 937 } 938 break; 939 940 case ACPI_NFIT_TYPE_FLUSH_ADDRESS: 941 942 Count = 0; 943 DtPushSubtable (Subtable); 944 while (*PFieldList) 945 { 946 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit6a, 947 &Subtable); 948 if (ACPI_FAILURE (Status)) 949 { 950 return (Status); 951 } 952 953 if (!Subtable) 954 { 955 DtPopSubtable (); 956 break; 957 } 958 959 ParentTable = DtPeekSubtable (); 960 DtInsertSubtable (ParentTable, Subtable); 961 Count++; 962 } 963 964 Hint->HintCount = (UINT16) Count; 965 break; 966 967 default: 968 break; 969 } 970 } 971 972 return (AE_OK); 973 } 974 975 976 /****************************************************************************** 977 * 978 * FUNCTION: DtCompilePcct 979 * 980 * PARAMETERS: List - Current field list pointer 981 * 982 * RETURN: Status 983 * 984 * DESCRIPTION: Compile PCCT. 985 * 986 *****************************************************************************/ 987 988 ACPI_STATUS 989 DtCompilePcct ( 990 void **List) 991 { 992 ACPI_STATUS Status; 993 DT_SUBTABLE *Subtable; 994 DT_SUBTABLE *ParentTable; 995 DT_FIELD **PFieldList = (DT_FIELD **) List; 996 DT_FIELD *SubtableStart; 997 ACPI_SUBTABLE_HEADER *PcctHeader; 998 ACPI_DMTABLE_INFO *InfoTable; 999 1000 1001 /* Main table */ 1002 1003 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcct, 1004 &Subtable); 1005 if (ACPI_FAILURE (Status)) 1006 { 1007 return (Status); 1008 } 1009 1010 ParentTable = DtPeekSubtable (); 1011 DtInsertSubtable (ParentTable, Subtable); 1012 1013 /* Subtables */ 1014 1015 while (*PFieldList) 1016 { 1017 SubtableStart = *PFieldList; 1018 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcctHdr, 1019 &Subtable); 1020 if (ACPI_FAILURE (Status)) 1021 { 1022 return (Status); 1023 } 1024 1025 ParentTable = DtPeekSubtable (); 1026 DtInsertSubtable (ParentTable, Subtable); 1027 DtPushSubtable (Subtable); 1028 1029 PcctHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); 1030 1031 switch (PcctHeader->Type) 1032 { 1033 case ACPI_PCCT_TYPE_GENERIC_SUBSPACE: 1034 1035 InfoTable = AcpiDmTableInfoPcct0; 1036 break; 1037 1038 case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE: 1039 1040 InfoTable = AcpiDmTableInfoPcct1; 1041 break; 1042 1043 case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2: 1044 1045 InfoTable = AcpiDmTableInfoPcct2; 1046 break; 1047 1048 case ACPI_PCCT_TYPE_EXT_PCC_MASTER_SUBSPACE: 1049 1050 InfoTable = AcpiDmTableInfoPcct3; 1051 break; 1052 1053 case ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE: 1054 1055 InfoTable = AcpiDmTableInfoPcct4; 1056 break; 1057 1058 case ACPI_PCCT_TYPE_HW_REG_COMM_SUBSPACE: 1059 1060 InfoTable = AcpiDmTableInfoPcct5; 1061 break; 1062 1063 default: 1064 1065 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PCCT"); 1066 return (AE_ERROR); 1067 } 1068 1069 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 1070 if (ACPI_FAILURE (Status)) 1071 { 1072 return (Status); 1073 } 1074 1075 ParentTable = DtPeekSubtable (); 1076 DtInsertSubtable (ParentTable, Subtable); 1077 DtPopSubtable (); 1078 } 1079 1080 return (AE_OK); 1081 } 1082 1083 1084 /****************************************************************************** 1085 * 1086 * FUNCTION: DtCompilePdtt 1087 * 1088 * PARAMETERS: List - Current field list pointer 1089 * 1090 * RETURN: Status 1091 * 1092 * DESCRIPTION: Compile PDTT. 1093 * 1094 *****************************************************************************/ 1095 1096 ACPI_STATUS 1097 DtCompilePdtt ( 1098 void **List) 1099 { 1100 ACPI_STATUS Status; 1101 DT_SUBTABLE *Subtable; 1102 DT_SUBTABLE *ParentTable; 1103 DT_FIELD **PFieldList = (DT_FIELD **) List; 1104 ACPI_TABLE_PDTT *PdttHeader; 1105 UINT32 Count = 0; 1106 1107 1108 /* Main table */ 1109 1110 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPdtt, &Subtable); 1111 if (ACPI_FAILURE (Status)) 1112 { 1113 return (Status); 1114 } 1115 1116 ParentTable = DtPeekSubtable (); 1117 DtInsertSubtable (ParentTable, Subtable); 1118 1119 PdttHeader = ACPI_CAST_PTR (ACPI_TABLE_PDTT, ParentTable->Buffer); 1120 PdttHeader->ArrayOffset = sizeof (ACPI_TABLE_PDTT); 1121 1122 /* There is only one type of subtable at this time, no need to decode */ 1123 1124 while (*PFieldList) 1125 { 1126 /* List of subchannel IDs, each 2 bytes */ 1127 1128 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPdtt0, 1129 &Subtable); 1130 if (ACPI_FAILURE (Status)) 1131 { 1132 return (Status); 1133 } 1134 1135 DtInsertSubtable (ParentTable, Subtable); 1136 Count++; 1137 } 1138 1139 PdttHeader->TriggerCount = (UINT8) Count; 1140 return (AE_OK); 1141 } 1142 1143 1144 /****************************************************************************** 1145 * 1146 * FUNCTION: DtCompilePhat 1147 * 1148 * PARAMETERS: List - Current field list pointer 1149 * 1150 * RETURN: Status 1151 * 1152 * DESCRIPTION: Compile Phat. 1153 * 1154 *****************************************************************************/ 1155 1156 ACPI_STATUS 1157 DtCompilePhat ( 1158 void **List) 1159 { 1160 ACPI_STATUS Status = AE_OK; 1161 DT_SUBTABLE *Subtable; 1162 DT_SUBTABLE *ParentTable; 1163 DT_FIELD **PFieldList = (DT_FIELD **) List; 1164 ACPI_PHAT_HEADER *PhatHeader; 1165 ACPI_DMTABLE_INFO *Info; 1166 ACPI_PHAT_VERSION_DATA *VersionData; 1167 UINT32 DeviceDataLength; 1168 UINT32 RecordCount; 1169 DT_FIELD *DataOffsetField; 1170 DT_FIELD *DevicePathField; 1171 UINT32 TableOffset = 0; 1172 UINT32 DataOffsetValue; 1173 UINT32 i; 1174 1175 1176 /* The table consists of subtables */ 1177 1178 while (*PFieldList) 1179 { 1180 /* Compile the common subtable header */ 1181 1182 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhatHdr, &Subtable); 1183 if (ACPI_FAILURE (Status)) 1184 { 1185 return (Status); 1186 } 1187 1188 TableOffset += Subtable->Length; 1189 DbgPrint (ASL_DEBUG_OUTPUT, "0 Subtable->Length: %X\n", Subtable->Length); 1190 1191 ParentTable = DtPeekSubtable (); 1192 DtInsertSubtable (ParentTable, Subtable); 1193 DtPushSubtable (Subtable); 1194 1195 PhatHeader = ACPI_CAST_PTR (ACPI_PHAT_HEADER, Subtable->Buffer); 1196 1197 switch (PhatHeader->Type) 1198 { 1199 case ACPI_PHAT_TYPE_FW_VERSION_DATA: 1200 1201 /* Compile the middle portion of the Firmware Version Data */ 1202 1203 Info = AcpiDmTableInfoPhat0; 1204 PhatHeader->Length = sizeof (ACPI_PHAT_VERSION_DATA); 1205 DataOffsetField = NULL; 1206 break; 1207 1208 case ACPI_PHAT_TYPE_FW_HEALTH_DATA: 1209 1210 DbgPrint (ASL_DEBUG_OUTPUT, "1 Offset: %X, Name: \"%s\" Length: %X\n", 1211 (*PFieldList)->TableOffset, (*PFieldList)->Name, Subtable->Length); 1212 1213 DataOffsetField = *PFieldList; 1214 1215 /* Walk the field list to get to the "Device-specific data Offset" field */ 1216 1217 TableOffset = sizeof (ACPI_PHAT_HEALTH_DATA); 1218 for (i = 0; i < 3; i++) 1219 { 1220 DataOffsetField = DataOffsetField->Next; 1221 DbgPrint (ASL_DEBUG_OUTPUT, "2 Offset: %X, Name: \"%s\" Length: %X Value: %s:\n", 1222 TableOffset, DataOffsetField->Name, DataOffsetField->StringLength, DataOffsetField->Value); 1223 } 1224 1225 /* Convert DataOffsetField->Value (a char * string) to an integer value */ 1226 1227 sscanf (DataOffsetField->Value, "%X", &DataOffsetValue); 1228 1229 /* 1230 * Get the next field (Device Path): 1231 * DataOffsetField points to "Device-Specific Offset", next field is 1232 * "Device Path". 1233 */ 1234 DevicePathField = DataOffsetField->Next; 1235 1236 /* Compute the size of the input ASCII string as a unicode string (*2 + 2) */ 1237 1238 DevicePathField->StringLength = (strlen ((const char *) DevicePathField->Value) * 2) + 2; 1239 TableOffset += DevicePathField->StringLength; 1240 1241 DbgPrint (ASL_DEBUG_OUTPUT, "3 Offset: %X, Length: %X devicepathLength: %X\n", 1242 TableOffset, Subtable->Length, DevicePathField->StringLength); 1243 1244 /* Set the DataOffsetField to the current TableOffset */ 1245 /* Must set the DataOffsetField here (not later) */ 1246 1247 if (DataOffsetValue != 0) 1248 { 1249 snprintf (DataOffsetField->Value, Subtable->Length, "%X", TableOffset); 1250 } 1251 1252 DbgPrint (ASL_DEBUG_OUTPUT, "4 Offset: %X, Length: %X\n", TableOffset, Subtable->Length); 1253 1254 DbgPrint (ASL_DEBUG_OUTPUT, "5 TableOffset: %X, DataOffsetField->StringLength: " 1255 "%X DevicePathField Length: %X DevicePathField->Value: %s, DataOffsetField->Value: %s DataOffsetField->ByteOffset %X\n", 1256 TableOffset, DataOffsetField->StringLength, DevicePathField->StringLength, 1257 DevicePathField->Value, DataOffsetField->Value, DataOffsetField->ByteOffset); 1258 1259 /* Compile the middle portion of the Health Data Record */ 1260 1261 Info = AcpiDmTableInfoPhat1; 1262 PhatHeader->Length = sizeof (ACPI_PHAT_HEALTH_DATA); 1263 break; 1264 1265 default: 1266 1267 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, *PFieldList, "PHAT"); 1268 return (AE_ERROR); 1269 } 1270 1271 /* Compile either the Version Data or the Health Data */ 1272 1273 Status = DtCompileTable (PFieldList, Info, &Subtable); 1274 if (ACPI_FAILURE (Status)) 1275 { 1276 return (Status); 1277 } 1278 1279 DbgPrint (ASL_DEBUG_OUTPUT, "6 Offset: %X, Name: \"%s\" SubtableLength: %X\n", 1280 TableOffset /* - StartTableOffset*/, (*PFieldList)->Name, Subtable->Length); 1281 1282 ParentTable = DtPeekSubtable (); 1283 DtInsertSubtable (ParentTable, Subtable); 1284 1285 switch (PhatHeader->Type) 1286 { 1287 case ACPI_PHAT_TYPE_FW_VERSION_DATA: 1288 1289 VersionData = ACPI_CAST_PTR (ACPI_PHAT_VERSION_DATA, 1290 (Subtable->Buffer - sizeof (ACPI_PHAT_HEADER))); 1291 RecordCount = VersionData->ElementCount; 1292 1293 /* Compile all of the Version Elements */ 1294 1295 while (RecordCount) 1296 { 1297 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhat0a, 1298 &Subtable); 1299 if (ACPI_FAILURE (Status)) 1300 { 1301 return (Status); 1302 } 1303 1304 ParentTable = DtPeekSubtable (); 1305 DtInsertSubtable (ParentTable, Subtable); 1306 1307 TableOffset += Subtable->Length; 1308 RecordCount--; 1309 PhatHeader->Length += sizeof (ACPI_PHAT_VERSION_ELEMENT); 1310 } 1311 1312 DtPopSubtable (); 1313 break; 1314 1315 case ACPI_PHAT_TYPE_FW_HEALTH_DATA: 1316 1317 /* Compile the Device Path */ 1318 1319 DeviceDataLength = Subtable->Length; 1320 TableOffset += Subtable->Length; 1321 1322 DbgPrint (ASL_DEBUG_OUTPUT, "7 Device Path Length: %X FieldName: \"%s\" FieldLength: " 1323 "%s FieldValue: %s SubtableLength: %X TableOffset: %X\n", DeviceDataLength, 1324 (*PFieldList)->Name, DataOffsetField->Value, (*PFieldList)->Value, 1325 Subtable->Length, TableOffset); 1326 1327 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhat1a, &Subtable); 1328 if (ACPI_FAILURE (Status)) 1329 { 1330 return (Status); 1331 } 1332 ParentTable = DtPeekSubtable (); 1333 DtInsertSubtable (ParentTable, Subtable); 1334 1335 /* *PFieldList will be null if previous field was at the end-of-ParseTree (EOF) */ 1336 1337 if (!*PFieldList) 1338 { 1339 DbgPrint (ASL_DEBUG_OUTPUT, "8 Exit on end-of-ParseTree\n"); 1340 return (AE_OK); 1341 } 1342 1343 DbgPrint (ASL_DEBUG_OUTPUT, "9 Device Data Length: %X FieldName: \"%s" 1344 " TableOffset: %X FieldLength: %X Field Value: %s SubtableLength: %X\n", 1345 DeviceDataLength, (*PFieldList)->Name, TableOffset, 1346 (*PFieldList)->StringLength, (*PFieldList)->Value, Subtable->Length); 1347 1348 PhatHeader->Length += (UINT16) Subtable->Length; 1349 1350 /* Convert DataOffsetField->Value (a hex char * string) to an integer value */ 1351 1352 sscanf (DataOffsetField->Value, "%X", &DataOffsetValue); 1353 1354 DbgPrint (ASL_DEBUG_OUTPUT, "10 Device-Specific Offset: %X Table Offset: %X\n", 1355 DataOffsetValue, TableOffset); 1356 if (DataOffsetValue != 0) 1357 { 1358 /* Compile Device-Specific Data - only if the Data Offset is non-zero */ 1359 1360 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhat1b, &Subtable); 1361 if (ACPI_FAILURE (Status)) 1362 { 1363 return (Status); 1364 } 1365 1366 DbgPrint (ASL_DEBUG_OUTPUT, "11 Subtable: %p Table Offset: %X\n", 1367 Subtable, TableOffset); 1368 if (Subtable) 1369 { 1370 DbgPrint (ASL_DEBUG_OUTPUT, "12 Device Specific Offset: " 1371 "%X FieldName \"%s\" SubtableLength %X\n", 1372 DeviceDataLength, DataOffsetField->Name, Subtable->Length); 1373 1374 DeviceDataLength += Subtable->Length; 1375 1376 ParentTable = DtPeekSubtable (); 1377 DtInsertSubtable (ParentTable, Subtable); 1378 1379 PhatHeader->Length += (UINT16) Subtable->Length; 1380 } 1381 } 1382 1383 DtPopSubtable (); 1384 1385 DbgPrint (ASL_DEBUG_OUTPUT, "13 FieldName: \"%s\" FieldLength: %X Field Value: %s\n", 1386 DataOffsetField->Name, DataOffsetField->StringLength, DataOffsetField->Value); 1387 break; 1388 1389 default: 1390 1391 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, *PFieldList, "PHAT"); 1392 return (AE_ERROR); 1393 } 1394 } 1395 1396 return (Status); 1397 } 1398 1399 1400 /****************************************************************************** 1401 * 1402 * FUNCTION: DtCompilePmtt 1403 * 1404 * PARAMETERS: List - Current field list pointer 1405 * 1406 * RETURN: Status 1407 * 1408 * DESCRIPTION: Compile PMTT. 1409 * 1410 *****************************************************************************/ 1411 1412 ACPI_STATUS 1413 DtCompilePmtt ( 1414 void **List) 1415 { 1416 ACPI_STATUS Status; 1417 DT_SUBTABLE *Subtable; 1418 DT_SUBTABLE *ParentTable; 1419 DT_FIELD **PFieldList = (DT_FIELD **) List; 1420 DT_FIELD *SubtableStart; 1421 UINT16 Type; 1422 1423 1424 /* Main table */ 1425 1426 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt, &Subtable); 1427 if (ACPI_FAILURE (Status)) 1428 { 1429 return (Status); 1430 } 1431 1432 ParentTable = DtPeekSubtable (); 1433 DtInsertSubtable (ParentTable, Subtable); 1434 DtPushSubtable (Subtable); 1435 1436 /* Subtables */ 1437 1438 while (*PFieldList) 1439 { 1440 SubtableStart = *PFieldList; 1441 DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0); 1442 1443 switch (Type) 1444 { 1445 case ACPI_PMTT_TYPE_SOCKET: 1446 1447 /* Subtable: Socket Structure */ 1448 1449 DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_SOCKET (0)\n"); 1450 1451 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt0, 1452 &Subtable); 1453 if (ACPI_FAILURE (Status)) 1454 { 1455 return (Status); 1456 } 1457 1458 break; 1459 1460 case ACPI_PMTT_TYPE_CONTROLLER: 1461 1462 /* Subtable: Memory Controller Structure */ 1463 1464 DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_CONTROLLER (1)\n"); 1465 1466 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1, 1467 &Subtable); 1468 if (ACPI_FAILURE (Status)) 1469 { 1470 return (Status); 1471 } 1472 1473 break; 1474 1475 case ACPI_PMTT_TYPE_DIMM: 1476 1477 /* Subtable: Physical Component (DIMM) Structure */ 1478 1479 DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_DIMM (2)\n"); 1480 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt2, 1481 &Subtable); 1482 if (ACPI_FAILURE (Status)) 1483 { 1484 return (Status); 1485 } 1486 1487 break; 1488 1489 case ACPI_PMTT_TYPE_VENDOR: 1490 1491 /* Subtable: Vendor-specific Structure */ 1492 1493 DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_VENDOR(FF)\n"); 1494 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmttVendor, 1495 &Subtable); 1496 if (ACPI_FAILURE (Status)) 1497 { 1498 return (Status); 1499 } 1500 1501 break; 1502 1503 default: 1504 1505 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PMTT"); 1506 return (AE_ERROR); 1507 } 1508 1509 DtInsertSubtable (ParentTable, Subtable); 1510 } 1511 1512 return (Status); 1513 } 1514 1515 1516 /****************************************************************************** 1517 * 1518 * FUNCTION: DtCompilePptt 1519 * 1520 * PARAMETERS: List - Current field list pointer 1521 * 1522 * RETURN: Status 1523 * 1524 * DESCRIPTION: Compile PPTT. 1525 * 1526 *****************************************************************************/ 1527 1528 ACPI_STATUS 1529 DtCompilePptt ( 1530 void **List) 1531 { 1532 ACPI_STATUS Status; 1533 ACPI_SUBTABLE_HEADER *PpttHeader; 1534 ACPI_PPTT_PROCESSOR *PpttProcessor = NULL; 1535 DT_SUBTABLE *Subtable; 1536 DT_SUBTABLE *ParentTable; 1537 ACPI_DMTABLE_INFO *InfoTable; 1538 DT_FIELD **PFieldList = (DT_FIELD **) List; 1539 DT_FIELD *SubtableStart; 1540 ACPI_TABLE_HEADER *PpttAcpiHeader; 1541 1542 1543 ParentTable = DtPeekSubtable (); 1544 1545 PpttAcpiHeader = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer); 1546 1547 while (*PFieldList) 1548 { 1549 SubtableStart = *PFieldList; 1550 1551 /* Compile PPTT subtable header */ 1552 1553 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPpttHdr, 1554 &Subtable); 1555 if (ACPI_FAILURE (Status)) 1556 { 1557 return (Status); 1558 } 1559 DtInsertSubtable (ParentTable, Subtable); 1560 PpttHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); 1561 PpttHeader->Length = (UINT8)(Subtable->Length); 1562 1563 switch (PpttHeader->Type) 1564 { 1565 case ACPI_PPTT_TYPE_PROCESSOR: 1566 1567 InfoTable = AcpiDmTableInfoPptt0; 1568 break; 1569 1570 case ACPI_PPTT_TYPE_CACHE: 1571 1572 if (PpttAcpiHeader->Revision < 3) 1573 { 1574 InfoTable = AcpiDmTableInfoPptt1; 1575 } 1576 else 1577 { 1578 InfoTable = AcpiDmTableInfoPptt1a; 1579 } 1580 break; 1581 1582 case ACPI_PPTT_TYPE_ID: 1583 1584 InfoTable = AcpiDmTableInfoPptt2; 1585 break; 1586 1587 default: 1588 1589 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PPTT"); 1590 return (AE_ERROR); 1591 } 1592 1593 /* Compile PPTT subtable body */ 1594 1595 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 1596 if (ACPI_FAILURE (Status)) 1597 { 1598 return (Status); 1599 } 1600 DtInsertSubtable (ParentTable, Subtable); 1601 PpttHeader->Length += (UINT8)(Subtable->Length); 1602 1603 /* Compile PPTT subtable additional */ 1604 1605 switch (PpttHeader->Type) 1606 { 1607 case ACPI_PPTT_TYPE_PROCESSOR: 1608 1609 PpttProcessor = ACPI_SUB_PTR (ACPI_PPTT_PROCESSOR, 1610 Subtable->Buffer, sizeof (ACPI_SUBTABLE_HEADER)); 1611 if (PpttProcessor) 1612 { 1613 /* Compile initiator proximity domain list */ 1614 1615 PpttProcessor->NumberOfPrivResources = 0; 1616 while (*PFieldList) 1617 { 1618 Status = DtCompileTable (PFieldList, 1619 AcpiDmTableInfoPptt0a, &Subtable); 1620 if (ACPI_FAILURE (Status)) 1621 { 1622 return (Status); 1623 } 1624 if (!Subtable) 1625 { 1626 break; 1627 } 1628 1629 DtInsertSubtable (ParentTable, Subtable); 1630 PpttHeader->Length += (UINT8)(Subtable->Length); 1631 PpttProcessor->NumberOfPrivResources++; 1632 } 1633 } 1634 break; 1635 default: 1636 1637 break; 1638 } 1639 } 1640 1641 return (AE_OK); 1642 } 1643 1644 1645 /****************************************************************************** 1646 * 1647 * FUNCTION: DtCompilePrmt 1648 * 1649 * PARAMETERS: List - Current field list pointer 1650 * 1651 * RETURN: Status 1652 * 1653 * DESCRIPTION: Compile PRMT. 1654 * 1655 *****************************************************************************/ 1656 1657 ACPI_STATUS 1658 DtCompilePrmt ( 1659 void **List) 1660 { 1661 ACPI_STATUS Status; 1662 ACPI_TABLE_PRMT_HEADER *PrmtHeader; 1663 ACPI_PRMT_MODULE_INFO *PrmtModuleInfo; 1664 DT_SUBTABLE *Subtable; 1665 DT_SUBTABLE *ParentTable; 1666 DT_FIELD **PFieldList = (DT_FIELD **) List; 1667 UINT32 i, j; 1668 1669 ParentTable = DtPeekSubtable (); 1670 1671 /* Compile PRMT subtable header */ 1672 1673 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPrmtHdr, 1674 &Subtable); 1675 if (ACPI_FAILURE (Status)) 1676 { 1677 return (Status); 1678 } 1679 DtInsertSubtable (ParentTable, Subtable); 1680 PrmtHeader = ACPI_CAST_PTR (ACPI_TABLE_PRMT_HEADER, Subtable->Buffer); 1681 1682 for (i = 0; i < PrmtHeader->ModuleInfoCount; i++) 1683 { 1684 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPrmtModule, 1685 &Subtable); 1686 if (ACPI_FAILURE (Status)) 1687 { 1688 return (Status); 1689 } 1690 DtInsertSubtable (ParentTable, Subtable); 1691 PrmtModuleInfo = ACPI_CAST_PTR (ACPI_PRMT_MODULE_INFO, Subtable->Buffer); 1692 1693 for (j = 0; j < PrmtModuleInfo->HandlerInfoCount; j++) 1694 { 1695 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPrmtHandler, 1696 &Subtable); 1697 if (ACPI_FAILURE (Status)) 1698 { 1699 return (Status); 1700 } 1701 DtInsertSubtable (ParentTable, Subtable); 1702 } 1703 } 1704 1705 return (AE_OK); 1706 } 1707 1708 1709 /****************************************************************************** 1710 * 1711 * FUNCTION: DtCompileRas2 1712 * 1713 * PARAMETERS: List - Current field list pointer 1714 * 1715 * RETURN: Status 1716 * 1717 * DESCRIPTION: Compile RAS2. 1718 * 1719 *****************************************************************************/ 1720 1721 ACPI_STATUS 1722 DtCompileRas2 ( 1723 void **List) 1724 { 1725 ACPI_STATUS Status; 1726 DT_SUBTABLE *Subtable; 1727 DT_SUBTABLE *ParentTable; 1728 DT_FIELD **PFieldList = (DT_FIELD **) List; 1729 ACPI_TABLE_RAS2 *Ras2Header; 1730 UINT32 Count = 0; 1731 1732 1733 /* Main table */ 1734 1735 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRas2, &Subtable); 1736 if (ACPI_FAILURE (Status)) 1737 { 1738 return (Status); 1739 } 1740 1741 ParentTable = DtPeekSubtable (); 1742 DtInsertSubtable (ParentTable, Subtable); 1743 1744 Ras2Header = ACPI_CAST_PTR (ACPI_TABLE_RAS2, ParentTable->Buffer); 1745 1746 /* There is only one type of subtable at this time, no need to decode */ 1747 1748 while (*PFieldList) 1749 { 1750 /* List of RAS2 PCC descriptors, each 8 bytes */ 1751 1752 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRas2PccDesc, 1753 &Subtable); 1754 if (ACPI_FAILURE (Status)) 1755 { 1756 return (Status); 1757 } 1758 1759 DtInsertSubtable (ParentTable, Subtable); 1760 Count++; 1761 } 1762 1763 Ras2Header->NumPccDescs = (UINT8) Count; 1764 return (AE_OK); 1765 } 1766 1767 1768 /****************************************************************************** 1769 * 1770 * FUNCTION: DtCompileRgrt 1771 * 1772 * PARAMETERS: List - Current field list pointer 1773 * 1774 * RETURN: Status 1775 * 1776 * DESCRIPTION: Compile RGRT. 1777 * 1778 *****************************************************************************/ 1779 1780 ACPI_STATUS 1781 DtCompileRgrt ( 1782 void **List) 1783 { 1784 ACPI_STATUS Status; 1785 DT_SUBTABLE *Subtable; 1786 DT_SUBTABLE *ParentTable; 1787 DT_FIELD **PFieldList = (DT_FIELD **) List; 1788 1789 1790 /* Compile the main table */ 1791 1792 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRgrt, 1793 &Subtable); 1794 if (ACPI_FAILURE (Status)) 1795 { 1796 return (Status); 1797 } 1798 1799 ParentTable = DtPeekSubtable (); 1800 DtInsertSubtable (ParentTable, Subtable); 1801 1802 /* Compile the "Subtable" -- actually just the binary (PNG) image */ 1803 1804 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRgrt0, 1805 &Subtable); 1806 if (ACPI_FAILURE (Status)) 1807 { 1808 return (Status); 1809 } 1810 1811 DtInsertSubtable (ParentTable, Subtable); 1812 return (AE_OK); 1813 } 1814 1815 1816 /****************************************************************************** 1817 * 1818 * FUNCTION: DtCompileRhct 1819 * 1820 * PARAMETERS: List - Current field list pointer 1821 * 1822 * RETURN: Status 1823 * 1824 * DESCRIPTION: Compile RHCT. 1825 * 1826 *****************************************************************************/ 1827 1828 ACPI_STATUS 1829 DtCompileRhct ( 1830 void **List) 1831 { 1832 ACPI_STATUS Status; 1833 ACPI_RHCT_NODE_HEADER *RhctHeader; 1834 ACPI_RHCT_HART_INFO *RhctHartInfo; 1835 DT_SUBTABLE *Subtable; 1836 DT_SUBTABLE *ParentTable; 1837 ACPI_DMTABLE_INFO *InfoTable; 1838 DT_FIELD **PFieldList = (DT_FIELD **) List; 1839 DT_FIELD *SubtableStart; 1840 ACPI_TABLE_RHCT *Table; 1841 BOOLEAN FirstNode = TRUE; 1842 1843 1844 /* Compile the main table */ 1845 1846 ParentTable = DtPeekSubtable (); 1847 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRhct, 1848 &Subtable); 1849 if (ACPI_FAILURE (Status)) 1850 { 1851 return (Status); 1852 } 1853 DtInsertSubtable (ParentTable, Subtable); 1854 Table = ACPI_CAST_PTR (ACPI_TABLE_RHCT, ParentTable->Buffer); 1855 Table->NodeCount = 0; 1856 Table->NodeOffset = sizeof (ACPI_TABLE_RHCT); 1857 1858 while (*PFieldList) 1859 { 1860 SubtableStart = *PFieldList; 1861 1862 /* Compile RHCT subtable header */ 1863 1864 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRhctNodeHdr, 1865 &Subtable); 1866 if (ACPI_FAILURE (Status)) 1867 { 1868 return (Status); 1869 } 1870 DtInsertSubtable (ParentTable, Subtable); 1871 RhctHeader = ACPI_CAST_PTR (ACPI_RHCT_NODE_HEADER, Subtable->Buffer); 1872 1873 DtPushSubtable (Subtable); 1874 ParentTable = DtPeekSubtable (); 1875 Table->NodeCount++; 1876 1877 switch (RhctHeader->Type) 1878 { 1879 case ACPI_RHCT_NODE_TYPE_ISA_STRING: 1880 1881 InfoTable = AcpiDmTableInfoRhctIsa1; 1882 break; 1883 1884 case ACPI_RHCT_NODE_TYPE_HART_INFO: 1885 1886 InfoTable = AcpiDmTableInfoRhctHartInfo1; 1887 break; 1888 1889 case ACPI_RHCT_NODE_TYPE_CMO: 1890 1891 InfoTable = AcpiDmTableInfoRhctCmo1; 1892 break; 1893 1894 case ACPI_RHCT_NODE_TYPE_MMU: 1895 1896 InfoTable = AcpiDmTableInfoRhctMmu1; 1897 break; 1898 1899 default: 1900 1901 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "RHCT"); 1902 return (AE_ERROR); 1903 } 1904 1905 /* Compile RHCT subtable body */ 1906 1907 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 1908 if (ACPI_FAILURE (Status)) 1909 { 1910 return (Status); 1911 } 1912 DtInsertSubtable (ParentTable, Subtable); 1913 if (FirstNode) 1914 { 1915 Table->NodeOffset = ACPI_PTR_DIFF(ParentTable->Buffer, Table); 1916 FirstNode = FALSE; 1917 } 1918 1919 /* Compile RHCT subtable additionals */ 1920 1921 switch (RhctHeader->Type) 1922 { 1923 case ACPI_RHCT_NODE_TYPE_ISA_STRING: 1924 1925 /* 1926 * Padding - Variable-length data 1927 * Optionally allows the padding of the ISA string to be used 1928 * for filling this field. 1929 */ 1930 Status = DtCompileTable (PFieldList, AcpiDmTableInfoRhctIsaPad, 1931 &Subtable); 1932 if (ACPI_FAILURE (Status)) 1933 { 1934 return (Status); 1935 } 1936 if (Subtable) 1937 { 1938 DtInsertSubtable (ParentTable, Subtable); 1939 } 1940 break; 1941 1942 case ACPI_RHCT_NODE_TYPE_HART_INFO: 1943 1944 RhctHartInfo = ACPI_CAST_PTR (ACPI_RHCT_HART_INFO, 1945 Subtable->Buffer); 1946 RhctHartInfo->NumOffsets = 0; 1947 while (*PFieldList) 1948 { 1949 Status = DtCompileTable (PFieldList, 1950 AcpiDmTableInfoRhctHartInfo2, &Subtable); 1951 if (ACPI_FAILURE (Status)) 1952 { 1953 return (Status); 1954 } 1955 if (!Subtable) 1956 { 1957 break; 1958 } 1959 DtInsertSubtable (ParentTable, Subtable); 1960 RhctHartInfo->NumOffsets++; 1961 } 1962 break; 1963 1964 default: 1965 1966 break; 1967 } 1968 1969 DtPopSubtable (); 1970 ParentTable = DtPeekSubtable (); 1971 } 1972 1973 return (AE_OK); 1974 } 1975 1976 1977 /****************************************************************************** 1978 * 1979 * FUNCTION: DtCompileRsdt 1980 * 1981 * PARAMETERS: List - Current field list pointer 1982 * 1983 * RETURN: Status 1984 * 1985 * DESCRIPTION: Compile RSDT. 1986 * 1987 *****************************************************************************/ 1988 1989 ACPI_STATUS 1990 DtCompileRsdt ( 1991 void **List) 1992 { 1993 DT_SUBTABLE *Subtable; 1994 DT_SUBTABLE *ParentTable; 1995 DT_FIELD *FieldList = *(DT_FIELD **) List; 1996 UINT32 Address; 1997 1998 1999 ParentTable = DtPeekSubtable (); 2000 2001 while (FieldList) 2002 { 2003 DtCompileInteger ((UINT8 *) &Address, FieldList, 4, DT_NON_ZERO); 2004 2005 DtCreateSubtable ((UINT8 *) &Address, 4, &Subtable); 2006 DtInsertSubtable (ParentTable, Subtable); 2007 FieldList = FieldList->Next; 2008 } 2009 2010 return (AE_OK); 2011 } 2012 2013 2014 /****************************************************************************** 2015 * 2016 * FUNCTION: DtCompileS3pt 2017 * 2018 * PARAMETERS: PFieldList - Current field list pointer 2019 * 2020 * RETURN: Status 2021 * 2022 * DESCRIPTION: Compile S3PT (Pointed to by FPDT) 2023 * 2024 *****************************************************************************/ 2025 2026 ACPI_STATUS 2027 DtCompileS3pt ( 2028 DT_FIELD **PFieldList) 2029 { 2030 ACPI_STATUS Status; 2031 ACPI_FPDT_HEADER *S3ptHeader; 2032 DT_SUBTABLE *Subtable; 2033 DT_SUBTABLE *ParentTable; 2034 ACPI_DMTABLE_INFO *InfoTable; 2035 DT_FIELD *SubtableStart; 2036 2037 2038 Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3pt, 2039 &AslGbl_RootTable); 2040 if (ACPI_FAILURE (Status)) 2041 { 2042 return (Status); 2043 } 2044 2045 DtPushSubtable (AslGbl_RootTable); 2046 2047 while (*PFieldList) 2048 { 2049 SubtableStart = *PFieldList; 2050 Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3ptHdr, 2051 &Subtable); 2052 if (ACPI_FAILURE (Status)) 2053 { 2054 return (Status); 2055 } 2056 2057 ParentTable = DtPeekSubtable (); 2058 DtInsertSubtable (ParentTable, Subtable); 2059 DtPushSubtable (Subtable); 2060 2061 S3ptHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer); 2062 2063 switch (S3ptHeader->Type) 2064 { 2065 case ACPI_S3PT_TYPE_RESUME: 2066 2067 InfoTable = AcpiDmTableInfoS3pt0; 2068 break; 2069 2070 case ACPI_S3PT_TYPE_SUSPEND: 2071 2072 InfoTable = AcpiDmTableInfoS3pt1; 2073 break; 2074 2075 default: 2076 2077 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "S3PT"); 2078 return (AE_ERROR); 2079 } 2080 2081 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 2082 if (ACPI_FAILURE (Status)) 2083 { 2084 return (Status); 2085 } 2086 2087 ParentTable = DtPeekSubtable (); 2088 DtInsertSubtable (ParentTable, Subtable); 2089 DtPopSubtable (); 2090 } 2091 2092 return (AE_OK); 2093 } 2094 2095 2096 /****************************************************************************** 2097 * 2098 * FUNCTION: DtCompileSdev 2099 * 2100 * PARAMETERS: List - Current field list pointer 2101 * 2102 * RETURN: Status 2103 * 2104 * DESCRIPTION: Compile SDEV. 2105 * 2106 *****************************************************************************/ 2107 2108 ACPI_STATUS 2109 DtCompileSdev ( 2110 void **List) 2111 { 2112 ACPI_STATUS Status; 2113 ACPI_SDEV_HEADER *SdevHeader; 2114 ACPI_SDEV_HEADER *SecureComponentHeader; 2115 DT_SUBTABLE *Subtable; 2116 DT_SUBTABLE *ParentTable; 2117 ACPI_DMTABLE_INFO *InfoTable; 2118 ACPI_DMTABLE_INFO *SecureComponentInfoTable = NULL; 2119 DT_FIELD **PFieldList = (DT_FIELD **) List; 2120 DT_FIELD *SubtableStart; 2121 ACPI_SDEV_PCIE *Pcie = NULL; 2122 ACPI_SDEV_NAMESPACE *Namesp = NULL; 2123 UINT32 EntryCount; 2124 ACPI_SDEV_SECURE_COMPONENT *SecureComponent = NULL; 2125 UINT16 ComponentLength = 0; 2126 2127 2128 /* Subtables */ 2129 2130 while (*PFieldList) 2131 { 2132 /* Compile common SDEV subtable header */ 2133 2134 SubtableStart = *PFieldList; 2135 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdevHdr, 2136 &Subtable); 2137 if (ACPI_FAILURE (Status)) 2138 { 2139 return (Status); 2140 } 2141 2142 ParentTable = DtPeekSubtable (); 2143 DtInsertSubtable (ParentTable, Subtable); 2144 DtPushSubtable (Subtable); 2145 2146 SdevHeader = ACPI_CAST_PTR (ACPI_SDEV_HEADER, Subtable->Buffer); 2147 SdevHeader->Length = (UINT8)(sizeof (ACPI_SDEV_HEADER)); 2148 2149 switch (SdevHeader->Type) 2150 { 2151 case ACPI_SDEV_TYPE_NAMESPACE_DEVICE: 2152 2153 InfoTable = AcpiDmTableInfoSdev0; 2154 Namesp = ACPI_CAST_PTR (ACPI_SDEV_NAMESPACE, Subtable->Buffer); 2155 SecureComponent = ACPI_CAST_PTR (ACPI_SDEV_SECURE_COMPONENT, 2156 ACPI_ADD_PTR (UINT8, Subtable->Buffer, sizeof(ACPI_SDEV_NAMESPACE))); 2157 break; 2158 2159 case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE: 2160 2161 InfoTable = AcpiDmTableInfoSdev1; 2162 Pcie = ACPI_CAST_PTR (ACPI_SDEV_PCIE, Subtable->Buffer); 2163 break; 2164 2165 default: 2166 2167 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SDEV"); 2168 return (AE_ERROR); 2169 } 2170 2171 /* Compile SDEV subtable body */ 2172 2173 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 2174 if (ACPI_FAILURE (Status)) 2175 { 2176 return (Status); 2177 } 2178 2179 ParentTable = DtPeekSubtable (); 2180 DtInsertSubtable (ParentTable, Subtable); 2181 2182 /* Optional data fields are appended to the main subtable body */ 2183 2184 switch (SdevHeader->Type) 2185 { 2186 case ACPI_SDEV_TYPE_NAMESPACE_DEVICE: 2187 2188 /* 2189 * Device Id Offset will be be calculated differently depending on 2190 * the presence of secure access components. 2191 */ 2192 Namesp->DeviceIdOffset = 0; 2193 ComponentLength = 0; 2194 2195 /* If the secure access component exists, get the structures */ 2196 2197 if (SdevHeader->Flags & ACPI_SDEV_SECURE_COMPONENTS_PRESENT) 2198 { 2199 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev0b, 2200 &Subtable); 2201 if (ACPI_FAILURE (Status)) 2202 { 2203 return (Status); 2204 } 2205 ParentTable = DtPeekSubtable (); 2206 DtInsertSubtable (ParentTable, Subtable); 2207 2208 Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_SECURE_COMPONENT); 2209 2210 /* Compile a secure access component header */ 2211 2212 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdevSecCompHdr, 2213 &Subtable); 2214 if (ACPI_FAILURE (Status)) 2215 { 2216 return (Status); 2217 } 2218 ParentTable = DtPeekSubtable (); 2219 DtInsertSubtable (ParentTable, Subtable); 2220 2221 /* Compile the secure access component */ 2222 2223 SecureComponentHeader = ACPI_CAST_PTR (ACPI_SDEV_HEADER, Subtable->Buffer); 2224 switch (SecureComponentHeader->Type) 2225 { 2226 case ACPI_SDEV_TYPE_ID_COMPONENT: 2227 2228 SecureComponentInfoTable = AcpiDmTableInfoSdevSecCompId; 2229 Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_ID_COMPONENT); 2230 ComponentLength = sizeof (ACPI_SDEV_ID_COMPONENT); 2231 break; 2232 2233 case ACPI_SDEV_TYPE_MEM_COMPONENT: 2234 2235 SecureComponentInfoTable = AcpiDmTableInfoSdevSecCompMem; 2236 Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_MEM_COMPONENT); 2237 ComponentLength = sizeof (ACPI_SDEV_MEM_COMPONENT); 2238 break; 2239 2240 default: 2241 2242 /* Any other secure component types are undefined */ 2243 2244 return (AE_ERROR); 2245 } 2246 2247 Status = DtCompileTable (PFieldList, SecureComponentInfoTable, 2248 &Subtable); 2249 if (ACPI_FAILURE (Status)) 2250 { 2251 return (Status); 2252 } 2253 ParentTable = DtPeekSubtable (); 2254 DtInsertSubtable (ParentTable, Subtable); 2255 2256 SecureComponent->SecureComponentOffset = 2257 sizeof (ACPI_SDEV_NAMESPACE) + sizeof (ACPI_SDEV_SECURE_COMPONENT); 2258 SecureComponent->SecureComponentLength = ComponentLength; 2259 2260 2261 /* 2262 * Add the secure component to the subtable to be added for the 2263 * the namespace subtable's length 2264 */ 2265 ComponentLength += sizeof (ACPI_SDEV_SECURE_COMPONENT); 2266 } 2267 2268 /* Append DeviceId namespace string */ 2269 2270 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev0a, 2271 &Subtable); 2272 if (ACPI_FAILURE (Status)) 2273 { 2274 return (Status); 2275 } 2276 2277 if (!Subtable) 2278 { 2279 break; 2280 } 2281 2282 ParentTable = DtPeekSubtable (); 2283 DtInsertSubtable (ParentTable, Subtable); 2284 2285 Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_NAMESPACE); 2286 2287 Namesp->DeviceIdLength = (UINT16) Subtable->Length; 2288 2289 /* Append Vendor data */ 2290 2291 Namesp->VendorDataLength = 0; 2292 Namesp->VendorDataOffset = 0; 2293 2294 if (*PFieldList) 2295 { 2296 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1b, 2297 &Subtable); 2298 if (ACPI_FAILURE (Status)) 2299 { 2300 return (Status); 2301 } 2302 2303 if (Subtable) 2304 { 2305 ParentTable = DtPeekSubtable (); 2306 DtInsertSubtable (ParentTable, Subtable); 2307 2308 Namesp->VendorDataOffset = 2309 Namesp->DeviceIdOffset + Namesp->DeviceIdLength; 2310 Namesp->VendorDataLength = 2311 (UINT16) Subtable->Length; 2312 2313 /* Final size of entire namespace structure */ 2314 2315 SdevHeader->Length = (UINT16)(sizeof(ACPI_SDEV_NAMESPACE) + 2316 Subtable->Length + Namesp->DeviceIdLength) + ComponentLength; 2317 } 2318 } 2319 2320 break; 2321 2322 case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE: 2323 2324 /* Append the PCIe path info first */ 2325 2326 EntryCount = 0; 2327 while (*PFieldList && !strcmp ((*PFieldList)->Name, "Device")) 2328 { 2329 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1a, 2330 &Subtable); 2331 if (ACPI_FAILURE (Status)) 2332 { 2333 return (Status); 2334 } 2335 2336 if (!Subtable) 2337 { 2338 DtPopSubtable (); 2339 break; 2340 } 2341 2342 ParentTable = DtPeekSubtable (); 2343 DtInsertSubtable (ParentTable, Subtable); 2344 EntryCount++; 2345 } 2346 2347 /* Path offset will point immediately after the main subtable */ 2348 2349 Pcie->PathOffset = sizeof (ACPI_SDEV_PCIE); 2350 Pcie->PathLength = (UINT16) 2351 (EntryCount * sizeof (ACPI_SDEV_PCIE_PATH)); 2352 2353 /* Append the Vendor Data last */ 2354 2355 Pcie->VendorDataLength = 0; 2356 Pcie->VendorDataOffset = 0; 2357 2358 if (*PFieldList) 2359 { 2360 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1b, 2361 &Subtable); 2362 if (ACPI_FAILURE (Status)) 2363 { 2364 return (Status); 2365 } 2366 2367 if (Subtable) 2368 { 2369 ParentTable = DtPeekSubtable (); 2370 DtInsertSubtable (ParentTable, Subtable); 2371 2372 Pcie->VendorDataOffset = 2373 Pcie->PathOffset + Pcie->PathLength; 2374 Pcie->VendorDataLength = (UINT16) 2375 Subtable->Length; 2376 } 2377 } 2378 2379 SdevHeader->Length = 2380 sizeof (ACPI_SDEV_PCIE) + 2381 Pcie->PathLength + Pcie->VendorDataLength; 2382 break; 2383 2384 default: 2385 2386 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SDEV"); 2387 return (AE_ERROR); 2388 } 2389 2390 DtPopSubtable (); 2391 } 2392 2393 return (AE_OK); 2394 } 2395 2396 2397 /****************************************************************************** 2398 * 2399 * FUNCTION: DtCompileSlic 2400 * 2401 * PARAMETERS: List - Current field list pointer 2402 * 2403 * RETURN: Status 2404 * 2405 * DESCRIPTION: Compile SLIC. 2406 * 2407 *****************************************************************************/ 2408 2409 ACPI_STATUS 2410 DtCompileSlic ( 2411 void **List) 2412 { 2413 ACPI_STATUS Status; 2414 DT_SUBTABLE *Subtable; 2415 DT_SUBTABLE *ParentTable; 2416 DT_FIELD **PFieldList = (DT_FIELD **) List; 2417 2418 2419 while (*PFieldList) 2420 { 2421 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlic, 2422 &Subtable); 2423 if (ACPI_FAILURE (Status)) 2424 { 2425 return (Status); 2426 } 2427 2428 ParentTable = DtPeekSubtable (); 2429 DtInsertSubtable (ParentTable, Subtable); 2430 DtPushSubtable (Subtable); 2431 DtPopSubtable (); 2432 } 2433 2434 return (AE_OK); 2435 } 2436 2437 2438 /****************************************************************************** 2439 * 2440 * FUNCTION: DtCompileSlit 2441 * 2442 * PARAMETERS: List - Current field list pointer 2443 * 2444 * RETURN: Status 2445 * 2446 * DESCRIPTION: Compile SLIT. 2447 * 2448 *****************************************************************************/ 2449 2450 ACPI_STATUS 2451 DtCompileSlit ( 2452 void **List) 2453 { 2454 ACPI_STATUS Status; 2455 DT_SUBTABLE *Subtable; 2456 DT_SUBTABLE *ParentTable; 2457 DT_FIELD **PFieldList = (DT_FIELD **) List; 2458 DT_FIELD *FieldList; 2459 DT_FIELD *EndOfFieldList = NULL; 2460 UINT32 Localities; 2461 UINT32 LocalityListLength; 2462 UINT8 *LocalityBuffer; 2463 2464 2465 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlit, 2466 &Subtable); 2467 if (ACPI_FAILURE (Status)) 2468 { 2469 return (Status); 2470 } 2471 2472 ParentTable = DtPeekSubtable (); 2473 DtInsertSubtable (ParentTable, Subtable); 2474 2475 Localities = *ACPI_CAST_PTR (UINT32, Subtable->Buffer); 2476 LocalityBuffer = UtLocalCalloc (Localities); 2477 LocalityListLength = 0; 2478 2479 /* Compile each locality buffer */ 2480 2481 FieldList = *PFieldList; 2482 while (FieldList) 2483 { 2484 DtCompileBuffer (LocalityBuffer, 2485 FieldList->Value, FieldList, Localities); 2486 2487 LocalityListLength++; 2488 DtCreateSubtable (LocalityBuffer, Localities, &Subtable); 2489 DtInsertSubtable (ParentTable, Subtable); 2490 EndOfFieldList = FieldList; 2491 FieldList = FieldList->Next; 2492 } 2493 2494 if (LocalityListLength != Localities) 2495 { 2496 sprintf(AslGbl_MsgBuffer, 2497 "Found %u entries, must match LocalityCount: %u", 2498 LocalityListLength, Localities); 2499 DtError (ASL_ERROR, ASL_MSG_ENTRY_LIST, EndOfFieldList, AslGbl_MsgBuffer); 2500 ACPI_FREE (LocalityBuffer); 2501 return (AE_LIMIT); 2502 } 2503 2504 ACPI_FREE (LocalityBuffer); 2505 return (AE_OK); 2506 } 2507 2508 2509 /****************************************************************************** 2510 * 2511 * FUNCTION: DtCompileSrat 2512 * 2513 * PARAMETERS: List - Current field list pointer 2514 * 2515 * RETURN: Status 2516 * 2517 * DESCRIPTION: Compile SRAT. 2518 * 2519 *****************************************************************************/ 2520 2521 ACPI_STATUS 2522 DtCompileSrat ( 2523 void **List) 2524 { 2525 ACPI_STATUS Status; 2526 DT_SUBTABLE *Subtable; 2527 DT_SUBTABLE *ParentTable; 2528 DT_FIELD **PFieldList = (DT_FIELD **) List; 2529 DT_FIELD *SubtableStart; 2530 ACPI_SUBTABLE_HEADER *SratHeader; 2531 ACPI_DMTABLE_INFO *InfoTable; 2532 2533 2534 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSrat, 2535 &Subtable); 2536 if (ACPI_FAILURE (Status)) 2537 { 2538 return (Status); 2539 } 2540 2541 ParentTable = DtPeekSubtable (); 2542 DtInsertSubtable (ParentTable, Subtable); 2543 2544 while (*PFieldList) 2545 { 2546 SubtableStart = *PFieldList; 2547 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSratHdr, 2548 &Subtable); 2549 if (ACPI_FAILURE (Status)) 2550 { 2551 return (Status); 2552 } 2553 2554 ParentTable = DtPeekSubtable (); 2555 DtInsertSubtable (ParentTable, Subtable); 2556 DtPushSubtable (Subtable); 2557 2558 SratHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); 2559 2560 switch (SratHeader->Type) 2561 { 2562 case ACPI_SRAT_TYPE_CPU_AFFINITY: 2563 2564 InfoTable = AcpiDmTableInfoSrat0; 2565 break; 2566 2567 case ACPI_SRAT_TYPE_MEMORY_AFFINITY: 2568 2569 InfoTable = AcpiDmTableInfoSrat1; 2570 break; 2571 2572 case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY: 2573 2574 InfoTable = AcpiDmTableInfoSrat2; 2575 break; 2576 2577 case ACPI_SRAT_TYPE_GICC_AFFINITY: 2578 2579 InfoTable = AcpiDmTableInfoSrat3; 2580 break; 2581 2582 case ACPI_SRAT_TYPE_GIC_ITS_AFFINITY: 2583 2584 InfoTable = AcpiDmTableInfoSrat4; 2585 break; 2586 2587 case ACPI_SRAT_TYPE_GENERIC_AFFINITY: 2588 2589 InfoTable = AcpiDmTableInfoSrat5; 2590 break; 2591 2592 case ACPI_SRAT_TYPE_GENERIC_PORT_AFFINITY: 2593 2594 InfoTable = AcpiDmTableInfoSrat6; 2595 break; 2596 2597 case ACPI_SRAT_TYPE_RINTC_AFFINITY: 2598 2599 InfoTable = AcpiDmTableInfoSrat7; 2600 break; 2601 2602 default: 2603 2604 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SRAT"); 2605 return (AE_ERROR); 2606 } 2607 2608 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 2609 if (ACPI_FAILURE (Status)) 2610 { 2611 return (Status); 2612 } 2613 2614 ParentTable = DtPeekSubtable (); 2615 DtInsertSubtable (ParentTable, Subtable); 2616 DtPopSubtable (); 2617 } 2618 2619 return (AE_OK); 2620 } 2621 2622 2623 /****************************************************************************** 2624 * 2625 * FUNCTION: DtCompileStao 2626 * 2627 * PARAMETERS: PFieldList - Current field list pointer 2628 * 2629 * RETURN: Status 2630 * 2631 * DESCRIPTION: Compile STAO. 2632 * 2633 *****************************************************************************/ 2634 2635 ACPI_STATUS 2636 DtCompileStao ( 2637 void **List) 2638 { 2639 DT_FIELD **PFieldList = (DT_FIELD **) List; 2640 DT_SUBTABLE *Subtable; 2641 DT_SUBTABLE *ParentTable; 2642 ACPI_STATUS Status; 2643 2644 2645 /* Compile the main table */ 2646 2647 Status = DtCompileTable (PFieldList, AcpiDmTableInfoStao, 2648 &Subtable); 2649 if (ACPI_FAILURE (Status)) 2650 { 2651 return (Status); 2652 } 2653 2654 ParentTable = DtPeekSubtable (); 2655 DtInsertSubtable (ParentTable, Subtable); 2656 2657 /* Compile each ASCII namestring as a subtable */ 2658 2659 while (*PFieldList) 2660 { 2661 Status = DtCompileTable (PFieldList, AcpiDmTableInfoStaoStr, 2662 &Subtable); 2663 if (ACPI_FAILURE (Status)) 2664 { 2665 return (Status); 2666 } 2667 2668 ParentTable = DtPeekSubtable (); 2669 DtInsertSubtable (ParentTable, Subtable); 2670 } 2671 2672 return (AE_OK); 2673 } 2674 2675 2676 /****************************************************************************** 2677 * 2678 * FUNCTION: DtCompileSvkl 2679 * 2680 * PARAMETERS: PFieldList - Current field list pointer 2681 * 2682 * RETURN: Status 2683 * 2684 * DESCRIPTION: Compile SVKL. 2685 * 2686 * NOTES: SVKL is essentially a flat table, with a small main table and 2687 * a variable number of a single type of subtable. 2688 * 2689 *****************************************************************************/ 2690 2691 ACPI_STATUS 2692 DtCompileSvkl ( 2693 void **List) 2694 { 2695 DT_FIELD **PFieldList = (DT_FIELD **) List; 2696 DT_SUBTABLE *Subtable; 2697 DT_SUBTABLE *ParentTable; 2698 ACPI_STATUS Status; 2699 2700 2701 /* Compile the main table */ 2702 2703 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSvkl, 2704 &Subtable); 2705 if (ACPI_FAILURE (Status)) 2706 { 2707 return (Status); 2708 } 2709 2710 ParentTable = DtPeekSubtable (); 2711 DtInsertSubtable (ParentTable, Subtable); 2712 2713 /* Compile each subtable */ 2714 2715 while (*PFieldList) 2716 { 2717 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSvkl0, 2718 &Subtable); 2719 if (ACPI_FAILURE (Status)) 2720 { 2721 return (Status); 2722 } 2723 2724 ParentTable = DtPeekSubtable (); 2725 DtInsertSubtable (ParentTable, Subtable); 2726 } 2727 2728 return (AE_OK); 2729 } 2730 2731 2732 /****************************************************************************** 2733 * 2734 * FUNCTION: DtCompileSwft 2735 * 2736 * PARAMETERS: PFieldList - Current field list pointer 2737 * 2738 * RETURN: Status 2739 * 2740 * DESCRIPTION: Compile SWFT. 2741 * 2742 *****************************************************************************/ 2743 2744 ACPI_STATUS 2745 DtCompileSwft ( 2746 void **List) 2747 { 2748 DT_FIELD **PFieldList = (DT_FIELD **) List; 2749 DT_SUBTABLE *HdrSub; 2750 DT_SUBTABLE *DataSub; 2751 DT_SUBTABLE *ParentTable; 2752 ACPI_STATUS Status; 2753 2754 /* Main SWFT header */ 2755 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSwft, &HdrSub); 2756 if (ACPI_FAILURE (Status)) 2757 { 2758 return (Status); 2759 } 2760 2761 ParentTable = DtPeekSubtable (); 2762 DtInsertSubtable (ParentTable, HdrSub); 2763 2764 while (*PFieldList) 2765 { 2766 /* File header */ 2767 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSwftFileHdr, 2768 &HdrSub); 2769 if (ACPI_FAILURE (Status)) 2770 { 2771 return (Status); 2772 } 2773 2774 DtInsertSubtable (ParentTable, HdrSub); 2775 2776 /* File data */ 2777 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSwftFileData, 2778 &DataSub); 2779 if (ACPI_FAILURE (Status)) 2780 { 2781 return (Status); 2782 } 2783 2784 DtInsertSubtable (ParentTable, DataSub); 2785 } 2786 2787 return (AE_OK); 2788 } 2789 2790 /****************************************************************************** 2791 * 2792 * FUNCTION: DtCompileTcpa 2793 * 2794 * PARAMETERS: PFieldList - Current field list pointer 2795 * 2796 * RETURN: Status 2797 * 2798 * DESCRIPTION: Compile TCPA. 2799 * 2800 *****************************************************************************/ 2801 2802 ACPI_STATUS 2803 DtCompileTcpa ( 2804 void **List) 2805 { 2806 DT_FIELD **PFieldList = (DT_FIELD **) List; 2807 DT_SUBTABLE *Subtable; 2808 ACPI_TABLE_TCPA_HDR *TcpaHeader; 2809 DT_SUBTABLE *ParentTable; 2810 ACPI_STATUS Status; 2811 2812 2813 /* Compile the main table */ 2814 2815 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaHdr, 2816 &Subtable); 2817 if (ACPI_FAILURE (Status)) 2818 { 2819 return (Status); 2820 } 2821 2822 ParentTable = DtPeekSubtable (); 2823 DtInsertSubtable (ParentTable, Subtable); 2824 2825 /* 2826 * Examine the PlatformClass field to determine the table type. 2827 * Either a client or server table. Only one. 2828 */ 2829 TcpaHeader = ACPI_CAST_PTR (ACPI_TABLE_TCPA_HDR, ParentTable->Buffer); 2830 2831 switch (TcpaHeader->PlatformClass) 2832 { 2833 case ACPI_TCPA_CLIENT_TABLE: 2834 2835 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaClient, 2836 &Subtable); 2837 break; 2838 2839 case ACPI_TCPA_SERVER_TABLE: 2840 2841 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaServer, 2842 &Subtable); 2843 break; 2844 2845 default: 2846 2847 AcpiOsPrintf ("\n**** Unknown TCPA Platform Class 0x%X\n", 2848 TcpaHeader->PlatformClass); 2849 Status = AE_ERROR; 2850 break; 2851 } 2852 2853 ParentTable = DtPeekSubtable (); 2854 DtInsertSubtable (ParentTable, Subtable); 2855 return (Status); 2856 } 2857 2858 2859 /****************************************************************************** 2860 * 2861 * FUNCTION: DtCompileTpm2Rev3 2862 * 2863 * PARAMETERS: PFieldList - Current field list pointer 2864 * 2865 * RETURN: Status 2866 * 2867 * DESCRIPTION: Compile TPM2 revision 3 2868 * 2869 *****************************************************************************/ 2870 static ACPI_STATUS 2871 DtCompileTpm2Rev3 ( 2872 void **List) 2873 { 2874 DT_FIELD **PFieldList = (DT_FIELD **) List; 2875 DT_SUBTABLE *Subtable; 2876 ACPI_TABLE_TPM23 *Tpm23Header; 2877 DT_SUBTABLE *ParentTable; 2878 ACPI_STATUS Status = AE_OK; 2879 2880 2881 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm23, 2882 &Subtable); 2883 2884 ParentTable = DtPeekSubtable (); 2885 DtInsertSubtable (ParentTable, Subtable); 2886 Tpm23Header = ACPI_CAST_PTR (ACPI_TABLE_TPM23, ParentTable->Buffer); 2887 2888 /* Subtable type depends on the StartMethod */ 2889 2890 switch (Tpm23Header->StartMethod) 2891 { 2892 case ACPI_TPM23_ACPI_START_METHOD: 2893 2894 /* Subtable specific to to ARM_SMC */ 2895 2896 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm23a, 2897 &Subtable); 2898 if (ACPI_FAILURE (Status)) 2899 { 2900 return (Status); 2901 } 2902 2903 ParentTable = DtPeekSubtable (); 2904 DtInsertSubtable (ParentTable, Subtable); 2905 break; 2906 2907 default: 2908 break; 2909 } 2910 2911 return (Status); 2912 } 2913 2914 2915 /****************************************************************************** 2916 * 2917 * FUNCTION: DtCompileTpm2 2918 * 2919 * PARAMETERS: PFieldList - Current field list pointer 2920 * 2921 * RETURN: Status 2922 * 2923 * DESCRIPTION: Compile TPM2. 2924 * 2925 *****************************************************************************/ 2926 2927 ACPI_STATUS 2928 DtCompileTpm2 ( 2929 void **List) 2930 { 2931 DT_FIELD **PFieldList = (DT_FIELD **) List; 2932 DT_SUBTABLE *Subtable; 2933 ACPI_TABLE_TPM2 *Tpm2Header; 2934 DT_SUBTABLE *ParentTable; 2935 ACPI_STATUS Status = AE_OK; 2936 ACPI_TABLE_HEADER *Header; 2937 2938 2939 ParentTable = DtPeekSubtable (); 2940 2941 Header = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer); 2942 2943 if (Header->Revision == 3) 2944 { 2945 return (DtCompileTpm2Rev3 (List)); 2946 } 2947 2948 /* Compile the main table */ 2949 2950 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm2, 2951 &Subtable); 2952 if (ACPI_FAILURE (Status)) 2953 { 2954 return (Status); 2955 } 2956 2957 ParentTable = DtPeekSubtable (); 2958 DtInsertSubtable (ParentTable, Subtable); 2959 2960 Tpm2Header = ACPI_CAST_PTR (ACPI_TABLE_TPM2, ParentTable->Buffer); 2961 2962 /* Method parameters */ 2963 /* Optional: Log area minimum length */ 2964 /* Optional: Log area start address */ 2965 /* TBD: Optional fields above not fully implemented (not optional at this time) */ 2966 2967 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm2a, 2968 &Subtable); 2969 if (ACPI_FAILURE (Status)) 2970 { 2971 return (Status); 2972 } 2973 2974 ParentTable = DtPeekSubtable (); 2975 DtInsertSubtable (ParentTable, Subtable); 2976 2977 2978 /* Subtable type depends on the StartMethod */ 2979 2980 switch (Tpm2Header->StartMethod) 2981 { 2982 case ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC: 2983 2984 /* Subtable specific to to ARM_SMC */ 2985 2986 Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm211, 2987 &Subtable); 2988 if (ACPI_FAILURE (Status)) 2989 { 2990 return (Status); 2991 } 2992 2993 ParentTable = DtPeekSubtable (); 2994 DtInsertSubtable (ParentTable, Subtable); 2995 break; 2996 2997 case ACPI_TPM2_START_METHOD: 2998 case ACPI_TPM2_MEMORY_MAPPED: 2999 case ACPI_TPM2_COMMAND_BUFFER: 3000 case ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD: 3001 break; 3002 3003 case ACPI_TPM2_RESERVED1: 3004 case ACPI_TPM2_RESERVED3: 3005 case ACPI_TPM2_RESERVED4: 3006 case ACPI_TPM2_RESERVED5: 3007 case ACPI_TPM2_RESERVED9: 3008 case ACPI_TPM2_RESERVED10: 3009 3010 AcpiOsPrintf ("\n**** Reserved TPM2 Start Method type 0x%X\n", 3011 Tpm2Header->StartMethod); 3012 Status = AE_ERROR; 3013 break; 3014 3015 case ACPI_TPM2_NOT_ALLOWED: 3016 default: 3017 3018 AcpiOsPrintf ("\n**** Unknown TPM2 Start Method type 0x%X\n", 3019 Tpm2Header->StartMethod); 3020 Status = AE_ERROR; 3021 break; 3022 } 3023 3024 return (Status); 3025 } 3026 3027 3028 /****************************************************************************** 3029 * 3030 * FUNCTION: DtGetGenericTableInfo 3031 * 3032 * PARAMETERS: Name - Generic type name 3033 * 3034 * RETURN: Info entry 3035 * 3036 * DESCRIPTION: Obtain table info for a generic name entry 3037 * 3038 *****************************************************************************/ 3039 3040 ACPI_DMTABLE_INFO * 3041 DtGetGenericTableInfo ( 3042 char *Name) 3043 { 3044 ACPI_DMTABLE_INFO *Info; 3045 UINT32 i; 3046 3047 3048 if (!Name) 3049 { 3050 return (NULL); 3051 } 3052 3053 /* Search info table for name match */ 3054 3055 for (i = 0; ; i++) 3056 { 3057 Info = AcpiDmTableInfoGeneric[i]; 3058 if (Info->Opcode == ACPI_DMT_EXIT) 3059 { 3060 Info = NULL; 3061 break; 3062 } 3063 3064 /* Use caseless compare for generic keywords */ 3065 3066 if (!AcpiUtStricmp (Name, Info->Name)) 3067 { 3068 break; 3069 } 3070 } 3071 3072 return (Info); 3073 } 3074 3075 3076 /****************************************************************************** 3077 * 3078 * FUNCTION: DtCompileUefi 3079 * 3080 * PARAMETERS: List - Current field list pointer 3081 * 3082 * RETURN: Status 3083 * 3084 * DESCRIPTION: Compile UEFI. 3085 * 3086 *****************************************************************************/ 3087 3088 ACPI_STATUS 3089 DtCompileUefi ( 3090 void **List) 3091 { 3092 ACPI_STATUS Status; 3093 DT_SUBTABLE *Subtable; 3094 DT_SUBTABLE *ParentTable; 3095 DT_FIELD **PFieldList = (DT_FIELD **) List; 3096 UINT16 *DataOffset; 3097 3098 3099 /* Compile the predefined portion of the UEFI table */ 3100 3101 Status = DtCompileTable (PFieldList, AcpiDmTableInfoUefi, 3102 &Subtable); 3103 if (ACPI_FAILURE (Status)) 3104 { 3105 return (Status); 3106 } 3107 3108 DataOffset = (UINT16 *) (Subtable->Buffer + 16); 3109 *DataOffset = sizeof (ACPI_TABLE_UEFI); 3110 3111 ParentTable = DtPeekSubtable (); 3112 DtInsertSubtable (ParentTable, Subtable); 3113 3114 /* 3115 * Compile the "generic" portion of the UEFI table. This 3116 * part of the table is not predefined and any of the generic 3117 * operators may be used. 3118 */ 3119 DtCompileGeneric ((void **) PFieldList, NULL, NULL); 3120 return (AE_OK); 3121 } 3122 3123 3124 /****************************************************************************** 3125 * 3126 * FUNCTION: DtCompileViot 3127 * 3128 * PARAMETERS: List - Current field list pointer 3129 * 3130 * RETURN: Status 3131 * 3132 * DESCRIPTION: Compile VIOT. 3133 * 3134 *****************************************************************************/ 3135 3136 ACPI_STATUS 3137 DtCompileViot ( 3138 void **List) 3139 { 3140 ACPI_STATUS Status; 3141 DT_SUBTABLE *Subtable; 3142 DT_SUBTABLE *ParentTable; 3143 DT_FIELD **PFieldList = (DT_FIELD **) List; 3144 DT_FIELD *SubtableStart; 3145 ACPI_TABLE_VIOT *Viot; 3146 ACPI_VIOT_HEADER *ViotHeader; 3147 ACPI_DMTABLE_INFO *InfoTable; 3148 UINT16 NodeCount; 3149 3150 ParentTable = DtPeekSubtable (); 3151 3152 Status = DtCompileTable (PFieldList, AcpiDmTableInfoViot, &Subtable); 3153 if (ACPI_FAILURE (Status)) 3154 { 3155 return (Status); 3156 } 3157 DtInsertSubtable (ParentTable, Subtable); 3158 3159 /* 3160 * Using ACPI_SUB_PTR, We needn't define a separate structure. Care 3161 * should be taken to avoid accessing ACPI_TABLE_HEADER fields. 3162 */ 3163 Viot = ACPI_SUB_PTR (ACPI_TABLE_VIOT, Subtable->Buffer, 3164 sizeof (ACPI_TABLE_HEADER)); 3165 3166 Viot->NodeOffset = sizeof (ACPI_TABLE_VIOT); 3167 3168 NodeCount = 0; 3169 while (*PFieldList) { 3170 SubtableStart = *PFieldList; 3171 Status = DtCompileTable (PFieldList, AcpiDmTableInfoViotHeader, 3172 &Subtable); 3173 if (ACPI_FAILURE (Status)) 3174 { 3175 return (Status); 3176 } 3177 3178 ParentTable = DtPeekSubtable (); 3179 DtInsertSubtable (ParentTable, Subtable); 3180 DtPushSubtable (Subtable); 3181 3182 ViotHeader = ACPI_CAST_PTR (ACPI_VIOT_HEADER, Subtable->Buffer); 3183 3184 switch (ViotHeader->Type) 3185 { 3186 case ACPI_VIOT_NODE_PCI_RANGE: 3187 3188 InfoTable = AcpiDmTableInfoViot1; 3189 break; 3190 3191 case ACPI_VIOT_NODE_MMIO: 3192 3193 InfoTable = AcpiDmTableInfoViot2; 3194 break; 3195 3196 case ACPI_VIOT_NODE_VIRTIO_IOMMU_PCI: 3197 3198 InfoTable = AcpiDmTableInfoViot3; 3199 break; 3200 3201 case ACPI_VIOT_NODE_VIRTIO_IOMMU_MMIO: 3202 3203 InfoTable = AcpiDmTableInfoViot4; 3204 break; 3205 3206 default: 3207 3208 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "VIOT"); 3209 return (AE_ERROR); 3210 } 3211 3212 Status = DtCompileTable (PFieldList, InfoTable, &Subtable); 3213 if (ACPI_FAILURE (Status)) 3214 { 3215 return (Status); 3216 } 3217 3218 ParentTable = DtPeekSubtable (); 3219 DtInsertSubtable (ParentTable, Subtable); 3220 DtPopSubtable (); 3221 NodeCount++; 3222 } 3223 3224 Viot->NodeCount = NodeCount; 3225 return (AE_OK); 3226 } 3227 3228 3229 /****************************************************************************** 3230 * 3231 * FUNCTION: DtCompileWdat 3232 * 3233 * PARAMETERS: List - Current field list pointer 3234 * 3235 * RETURN: Status 3236 * 3237 * DESCRIPTION: Compile WDAT. 3238 * 3239 *****************************************************************************/ 3240 3241 ACPI_STATUS 3242 DtCompileWdat ( 3243 void **List) 3244 { 3245 ACPI_STATUS Status; 3246 3247 3248 Status = DtCompileTwoSubtables (List, 3249 AcpiDmTableInfoWdat, AcpiDmTableInfoWdat0); 3250 return (Status); 3251 } 3252 3253 3254 /****************************************************************************** 3255 * 3256 * FUNCTION: DtCompileWpbt 3257 * 3258 * PARAMETERS: List - Current field list pointer 3259 * 3260 * RETURN: Status 3261 * 3262 * DESCRIPTION: Compile WPBT. 3263 * 3264 *****************************************************************************/ 3265 3266 ACPI_STATUS 3267 DtCompileWpbt ( 3268 void **List) 3269 { 3270 DT_FIELD **PFieldList = (DT_FIELD **) List; 3271 DT_SUBTABLE *Subtable; 3272 DT_SUBTABLE *ParentTable; 3273 ACPI_TABLE_WPBT *Table; 3274 ACPI_STATUS Status; 3275 3276 3277 /* Compile the main table */ 3278 3279 Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt, &Subtable); 3280 if (ACPI_FAILURE (Status)) 3281 { 3282 return (Status); 3283 } 3284 3285 ParentTable = DtPeekSubtable (); 3286 DtInsertSubtable (ParentTable, Subtable); 3287 Table = ACPI_CAST_PTR (ACPI_TABLE_WPBT, ParentTable->Buffer); 3288 3289 /* 3290 * Exit now if there are no arguments specified. This is indicated by: 3291 * The "Command-line Arguments" field has not been specified (if specified, 3292 * it will be the last field in the field list -- after the main table). 3293 * Set the Argument Length in the main table to zero. 3294 */ 3295 if (!*PFieldList) 3296 { 3297 Table->ArgumentsLength = 0; 3298 return (AE_OK); 3299 } 3300 3301 /* Compile the argument list subtable */ 3302 3303 Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt0, &Subtable); 3304 if (ACPI_FAILURE (Status)) 3305 { 3306 return (Status); 3307 } 3308 3309 /* Extract the length of the Arguments buffer, insert into main table */ 3310 3311 Table->ArgumentsLength = (UINT16) Subtable->TotalLength; 3312 DtInsertSubtable (ParentTable, Subtable); 3313 return (AE_OK); 3314 } 3315 3316 3317 /****************************************************************************** 3318 * 3319 * FUNCTION: DtCompileXsdt 3320 * 3321 * PARAMETERS: List - Current field list pointer 3322 * 3323 * RETURN: Status 3324 * 3325 * DESCRIPTION: Compile XSDT. 3326 * 3327 *****************************************************************************/ 3328 3329 ACPI_STATUS 3330 DtCompileXsdt ( 3331 void **List) 3332 { 3333 DT_SUBTABLE *Subtable; 3334 DT_SUBTABLE *ParentTable; 3335 DT_FIELD *FieldList = *(DT_FIELD **) List; 3336 UINT64 Address; 3337 3338 3339 ParentTable = DtPeekSubtable (); 3340 3341 while (FieldList) 3342 { 3343 DtCompileInteger ((UINT8 *) &Address, FieldList, 8, DT_NON_ZERO); 3344 3345 DtCreateSubtable ((UINT8 *) &Address, 8, &Subtable); 3346 DtInsertSubtable (ParentTable, Subtable); 3347 FieldList = FieldList->Next; 3348 } 3349 3350 return (AE_OK); 3351 } 3352 3353 3354 /****************************************************************************** 3355 * 3356 * FUNCTION: DtCompileGeneric 3357 * 3358 * PARAMETERS: List - Current field list pointer 3359 * Name - Field name to end generic compiling 3360 * Length - Compiled table length to return 3361 * 3362 * RETURN: Status 3363 * 3364 * DESCRIPTION: Compile generic unknown table. 3365 * 3366 *****************************************************************************/ 3367 3368 ACPI_STATUS 3369 DtCompileGeneric ( 3370 void **List, 3371 char *Name, 3372 UINT32 *Length) 3373 { 3374 ACPI_STATUS Status; 3375 DT_SUBTABLE *Subtable; 3376 DT_SUBTABLE *ParentTable; 3377 DT_FIELD **PFieldList = (DT_FIELD **) List; 3378 ACPI_DMTABLE_INFO *Info; 3379 3380 3381 ParentTable = DtPeekSubtable (); 3382 3383 /* 3384 * Compile the "generic" portion of the table. This 3385 * part of the table is not predefined and any of the generic 3386 * operators may be used. 3387 */ 3388 3389 /* Find any and all labels in the entire generic portion */ 3390 3391 DtDetectAllLabels (*PFieldList); 3392 3393 /* Now we can actually compile the parse tree */ 3394 3395 if (Length && *Length) 3396 { 3397 *Length = 0; 3398 } 3399 while (*PFieldList) 3400 { 3401 if (Name && !strcmp ((*PFieldList)->Name, Name)) 3402 { 3403 break; 3404 } 3405 3406 Info = DtGetGenericTableInfo ((*PFieldList)->Name); 3407 if (!Info) 3408 { 3409 sprintf (AslGbl_MsgBuffer, "Generic data type \"%s\" not found", 3410 (*PFieldList)->Name); 3411 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME, 3412 (*PFieldList), AslGbl_MsgBuffer); 3413 3414 *PFieldList = (*PFieldList)->Next; 3415 continue; 3416 } 3417 3418 Status = DtCompileTable (PFieldList, Info, 3419 &Subtable); 3420 if (ACPI_SUCCESS (Status)) 3421 { 3422 DtInsertSubtable (ParentTable, Subtable); 3423 if (Length) 3424 { 3425 *Length += Subtable->Length; 3426 } 3427 } 3428 else 3429 { 3430 *PFieldList = (*PFieldList)->Next; 3431 3432 if (Status == AE_NOT_FOUND) 3433 { 3434 sprintf (AslGbl_MsgBuffer, "Generic data type \"%s\" not found", 3435 (*PFieldList)->Name); 3436 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME, 3437 (*PFieldList), AslGbl_MsgBuffer); 3438 } 3439 } 3440 } 3441 3442 return (AE_OK); 3443 } 3444