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